mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-12 15:45:25 +01:00
File standardisation (#13131)
* Adds the check components * Adds in trailing newlines * Converts all CRLF to LF * Post merge EOF * Post merge line endings * Final commit
This commit is contained in:
@@ -150,4 +150,4 @@
|
||||
|
||||
/mob/living/proc/check_buckled()
|
||||
if(buckled && !(buckled in loc))
|
||||
buckled.unbuckle_mob(src, force = TRUE)
|
||||
buckled.unbuckle_mob(src, force = TRUE)
|
||||
|
||||
@@ -89,4 +89,4 @@
|
||||
if(8)
|
||||
visible_message("<span class='warning'>[target] is struggling to withstand the acid!</span>")
|
||||
if(4)
|
||||
visible_message("<span class='warning'>[target] begins to crumble under the acid!</span>")
|
||||
visible_message("<span class='warning'>[target] begins to crumble under the acid!</span>")
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
var/list/obj/effect/bump_teleporter/BUMP_TELEPORTERS = list()
|
||||
|
||||
/obj/effect/bump_teleporter
|
||||
name = "bump-teleporter"
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "x2"
|
||||
var/id = null //id of this bump_teleporter.
|
||||
var/id_target = null //id of bump_teleporter which this moves you to.
|
||||
invisibility = 101 //nope, can't see this
|
||||
anchored = 1
|
||||
density = 1
|
||||
opacity = 0
|
||||
|
||||
/obj/effect/bump_teleporter/New()
|
||||
..()
|
||||
BUMP_TELEPORTERS += src
|
||||
|
||||
/obj/effect/bump_teleporter/Destroy()
|
||||
BUMP_TELEPORTERS -= src
|
||||
return ..()
|
||||
|
||||
/obj/effect/bump_teleporter/singularity_act()
|
||||
return
|
||||
|
||||
/obj/effect/bump_teleporter/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/bump_teleporter/Bumped(atom/user)
|
||||
if(!ismob(user))
|
||||
//user.loc = src.loc //Stop at teleporter location
|
||||
return
|
||||
|
||||
if(!id_target)
|
||||
//user.loc = src.loc //Stop at teleporter location, there is nowhere to teleport to.
|
||||
return
|
||||
|
||||
for(var/obj/effect/bump_teleporter/BT in BUMP_TELEPORTERS)
|
||||
if(BT.id == src.id_target)
|
||||
usr.loc = BT.loc //Teleport to location with correct id.
|
||||
return
|
||||
var/list/obj/effect/bump_teleporter/BUMP_TELEPORTERS = list()
|
||||
|
||||
/obj/effect/bump_teleporter
|
||||
name = "bump-teleporter"
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "x2"
|
||||
var/id = null //id of this bump_teleporter.
|
||||
var/id_target = null //id of bump_teleporter which this moves you to.
|
||||
invisibility = 101 //nope, can't see this
|
||||
anchored = 1
|
||||
density = 1
|
||||
opacity = 0
|
||||
|
||||
/obj/effect/bump_teleporter/New()
|
||||
..()
|
||||
BUMP_TELEPORTERS += src
|
||||
|
||||
/obj/effect/bump_teleporter/Destroy()
|
||||
BUMP_TELEPORTERS -= src
|
||||
return ..()
|
||||
|
||||
/obj/effect/bump_teleporter/singularity_act()
|
||||
return
|
||||
|
||||
/obj/effect/bump_teleporter/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/bump_teleporter/Bumped(atom/user)
|
||||
if(!ismob(user))
|
||||
//user.loc = src.loc //Stop at teleporter location
|
||||
return
|
||||
|
||||
if(!id_target)
|
||||
//user.loc = src.loc //Stop at teleporter location, there is nowhere to teleport to.
|
||||
return
|
||||
|
||||
for(var/obj/effect/bump_teleporter/BT in BUMP_TELEPORTERS)
|
||||
if(BT.id == src.id_target)
|
||||
usr.loc = BT.loc //Teleport to location with correct id.
|
||||
return
|
||||
|
||||
@@ -211,4 +211,4 @@
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "xfloor1"
|
||||
random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7")
|
||||
anchored = TRUE
|
||||
anchored = TRUE
|
||||
|
||||
@@ -1,60 +1,60 @@
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot
|
||||
name = "robot debris"
|
||||
desc = "It's a useless heap of junk... <i>or is it?</i>"
|
||||
icon = 'icons/mob/robots.dmi'
|
||||
icon_state = "gib1"
|
||||
basecolor = "#030303"
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7")
|
||||
bloodiness = BLOOD_AMOUNT_PER_DECAL
|
||||
mergeable_decal = FALSE
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot/can_bloodcrawl_in()
|
||||
return FALSE
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot/update_icon()
|
||||
color = "#FFFFFF"
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot/dry() //pieces of robots do not dry up like
|
||||
return
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot/can_bloodcrawl_in()
|
||||
return FALSE
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot/streak(var/list/directions)
|
||||
spawn(0)
|
||||
var/direction = pick(directions)
|
||||
for(var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++)
|
||||
sleep(3)
|
||||
if(i > 0)
|
||||
if(prob(40))
|
||||
var/obj/effect/decal/cleanable/blood/oil/streak = new(src.loc)
|
||||
streak.update_icon()
|
||||
else if(prob(10))
|
||||
do_sparks(3, 1, src)
|
||||
if(step_to(src, get_step(src, direction), 0))
|
||||
break
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot/limb
|
||||
random_icon_states = list("gibarm", "gibleg")
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot/up
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7", "gibup1", "gibup1") //2:7 is close enough to 1:4
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot/down
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7", "gibdown1", "gibdown1") //2:7 is close enough to 1:4
|
||||
|
||||
/obj/effect/decal/cleanable/blood/oil
|
||||
name = "motor oil"
|
||||
desc = "It's black and greasy. Looks like Beepsky made another mess."
|
||||
basecolor = "#030303"
|
||||
bloodiness = MAX_SHOE_BLOODINESS
|
||||
|
||||
/obj/effect/decal/cleanable/blood/oil/can_bloodcrawl_in()
|
||||
return FALSE
|
||||
|
||||
/obj/effect/decal/cleanable/blood/oil/dry()
|
||||
return
|
||||
|
||||
/obj/effect/decal/cleanable/blood/oil/streak
|
||||
random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5")
|
||||
amount = 2
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot
|
||||
name = "robot debris"
|
||||
desc = "It's a useless heap of junk... <i>or is it?</i>"
|
||||
icon = 'icons/mob/robots.dmi'
|
||||
icon_state = "gib1"
|
||||
basecolor = "#030303"
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7")
|
||||
bloodiness = BLOOD_AMOUNT_PER_DECAL
|
||||
mergeable_decal = FALSE
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot/can_bloodcrawl_in()
|
||||
return FALSE
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot/update_icon()
|
||||
color = "#FFFFFF"
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot/dry() //pieces of robots do not dry up like
|
||||
return
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot/can_bloodcrawl_in()
|
||||
return FALSE
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot/streak(var/list/directions)
|
||||
spawn(0)
|
||||
var/direction = pick(directions)
|
||||
for(var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++)
|
||||
sleep(3)
|
||||
if(i > 0)
|
||||
if(prob(40))
|
||||
var/obj/effect/decal/cleanable/blood/oil/streak = new(src.loc)
|
||||
streak.update_icon()
|
||||
else if(prob(10))
|
||||
do_sparks(3, 1, src)
|
||||
if(step_to(src, get_step(src, direction), 0))
|
||||
break
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot/limb
|
||||
random_icon_states = list("gibarm", "gibleg")
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot/up
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7", "gibup1", "gibup1") //2:7 is close enough to 1:4
|
||||
|
||||
/obj/effect/decal/cleanable/blood/gibs/robot/down
|
||||
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7", "gibdown1", "gibdown1") //2:7 is close enough to 1:4
|
||||
|
||||
/obj/effect/decal/cleanable/blood/oil
|
||||
name = "motor oil"
|
||||
desc = "It's black and greasy. Looks like Beepsky made another mess."
|
||||
basecolor = "#030303"
|
||||
bloodiness = MAX_SHOE_BLOODINESS
|
||||
|
||||
/obj/effect/decal/cleanable/blood/oil/can_bloodcrawl_in()
|
||||
return FALSE
|
||||
|
||||
/obj/effect/decal/cleanable/blood/oil/dry()
|
||||
return
|
||||
|
||||
/obj/effect/decal/cleanable/blood/oil/streak
|
||||
random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5")
|
||||
amount = 2
|
||||
|
||||
@@ -135,4 +135,4 @@ var/global/list/image/fluidtrack_cache = list()
|
||||
/obj/effect/decal/cleanable/blood/footprints/replace_decal(obj/effect/decal/cleanable/blood/footprints/C)
|
||||
if(blood_state != C.blood_state) //We only replace footprints of the same type as us
|
||||
return
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -1,73 +1,73 @@
|
||||
/obj/effect/decal/cleanable
|
||||
anchored = TRUE
|
||||
var/list/random_icon_states = list()
|
||||
var/bloodiness = 0 //0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints
|
||||
var/mergeable_decal = TRUE //when two of these are on a same tile or do we need to merge them into just one?
|
||||
|
||||
/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal
|
||||
if(mergeable_decal)
|
||||
return TRUE
|
||||
|
||||
//Add "bloodiness" of this blood's type, to the human's shoes
|
||||
//This is on /cleanable because fuck this ancient mess
|
||||
/obj/effect/decal/cleanable/blood/Crossed(atom/movable/O)
|
||||
..()
|
||||
if(!off_floor && ishuman(O))
|
||||
var/mob/living/carbon/human/H = O
|
||||
var/obj/item/organ/external/l_foot = H.get_organ("l_foot")
|
||||
var/obj/item/organ/external/r_foot = H.get_organ("r_foot")
|
||||
var/hasfeet = TRUE
|
||||
if(!l_foot && !r_foot)
|
||||
hasfeet = FALSE
|
||||
if(H.shoes && blood_state && bloodiness)
|
||||
var/obj/item/clothing/shoes/S = H.shoes
|
||||
var/add_blood = 0
|
||||
if(bloodiness >= BLOOD_GAIN_PER_STEP)
|
||||
add_blood = BLOOD_GAIN_PER_STEP
|
||||
else
|
||||
add_blood = bloodiness
|
||||
bloodiness -= add_blood
|
||||
S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS, S.bloody_shoes[blood_state] + add_blood)
|
||||
if(blood_DNA && blood_DNA.len)
|
||||
S.add_blood(H.blood_DNA, basecolor)
|
||||
S.blood_state = blood_state
|
||||
S.blood_color = basecolor
|
||||
update_icon()
|
||||
H.update_inv_shoes()
|
||||
else if(hasfeet && blood_state && bloodiness)//Or feet
|
||||
var/add_blood = 0
|
||||
if(bloodiness >= BLOOD_GAIN_PER_STEP)
|
||||
add_blood = BLOOD_GAIN_PER_STEP
|
||||
else
|
||||
add_blood = bloodiness
|
||||
bloodiness -= add_blood
|
||||
H.bloody_feet[blood_state] = min(MAX_SHOE_BLOODINESS, H.bloody_feet[blood_state] + add_blood)
|
||||
if(!H.feet_blood_DNA)
|
||||
H.feet_blood_DNA = list()
|
||||
H.blood_state = blood_state
|
||||
H.feet_blood_DNA |= blood_DNA.Copy()
|
||||
H.feet_blood_color = basecolor
|
||||
update_icon()
|
||||
H.update_inv_shoes()
|
||||
|
||||
/obj/effect/decal/cleanable/proc/can_bloodcrawl_in()
|
||||
return FALSE
|
||||
|
||||
/obj/effect/decal/cleanable/Initialize(mapload)
|
||||
. = ..()
|
||||
if(loc && isturf(loc))
|
||||
for(var/obj/effect/decal/cleanable/C in loc)
|
||||
if(C != src && C.type == type && !QDELETED(C))
|
||||
if(replace_decal(C))
|
||||
qdel(src)
|
||||
return TRUE
|
||||
if(random_icon_states && length(src.random_icon_states) > 0)
|
||||
src.icon_state = pick(src.random_icon_states)
|
||||
if(smooth)
|
||||
queue_smooth(src)
|
||||
queue_smooth_neighbors(src)
|
||||
|
||||
/obj/effect/decal/cleanable/Destroy()
|
||||
if(smooth)
|
||||
queue_smooth_neighbors(src)
|
||||
return ..()
|
||||
/obj/effect/decal/cleanable
|
||||
anchored = TRUE
|
||||
var/list/random_icon_states = list()
|
||||
var/bloodiness = 0 //0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints
|
||||
var/mergeable_decal = TRUE //when two of these are on a same tile or do we need to merge them into just one?
|
||||
|
||||
/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal
|
||||
if(mergeable_decal)
|
||||
return TRUE
|
||||
|
||||
//Add "bloodiness" of this blood's type, to the human's shoes
|
||||
//This is on /cleanable because fuck this ancient mess
|
||||
/obj/effect/decal/cleanable/blood/Crossed(atom/movable/O)
|
||||
..()
|
||||
if(!off_floor && ishuman(O))
|
||||
var/mob/living/carbon/human/H = O
|
||||
var/obj/item/organ/external/l_foot = H.get_organ("l_foot")
|
||||
var/obj/item/organ/external/r_foot = H.get_organ("r_foot")
|
||||
var/hasfeet = TRUE
|
||||
if(!l_foot && !r_foot)
|
||||
hasfeet = FALSE
|
||||
if(H.shoes && blood_state && bloodiness)
|
||||
var/obj/item/clothing/shoes/S = H.shoes
|
||||
var/add_blood = 0
|
||||
if(bloodiness >= BLOOD_GAIN_PER_STEP)
|
||||
add_blood = BLOOD_GAIN_PER_STEP
|
||||
else
|
||||
add_blood = bloodiness
|
||||
bloodiness -= add_blood
|
||||
S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS, S.bloody_shoes[blood_state] + add_blood)
|
||||
if(blood_DNA && blood_DNA.len)
|
||||
S.add_blood(H.blood_DNA, basecolor)
|
||||
S.blood_state = blood_state
|
||||
S.blood_color = basecolor
|
||||
update_icon()
|
||||
H.update_inv_shoes()
|
||||
else if(hasfeet && blood_state && bloodiness)//Or feet
|
||||
var/add_blood = 0
|
||||
if(bloodiness >= BLOOD_GAIN_PER_STEP)
|
||||
add_blood = BLOOD_GAIN_PER_STEP
|
||||
else
|
||||
add_blood = bloodiness
|
||||
bloodiness -= add_blood
|
||||
H.bloody_feet[blood_state] = min(MAX_SHOE_BLOODINESS, H.bloody_feet[blood_state] + add_blood)
|
||||
if(!H.feet_blood_DNA)
|
||||
H.feet_blood_DNA = list()
|
||||
H.blood_state = blood_state
|
||||
H.feet_blood_DNA |= blood_DNA.Copy()
|
||||
H.feet_blood_color = basecolor
|
||||
update_icon()
|
||||
H.update_inv_shoes()
|
||||
|
||||
/obj/effect/decal/cleanable/proc/can_bloodcrawl_in()
|
||||
return FALSE
|
||||
|
||||
/obj/effect/decal/cleanable/Initialize(mapload)
|
||||
. = ..()
|
||||
if(loc && isturf(loc))
|
||||
for(var/obj/effect/decal/cleanable/C in loc)
|
||||
if(C != src && C.type == type && !QDELETED(C))
|
||||
if(replace_decal(C))
|
||||
qdel(src)
|
||||
return TRUE
|
||||
if(random_icon_states && length(src.random_icon_states) > 0)
|
||||
src.icon_state = pick(src.random_icon_states)
|
||||
if(smooth)
|
||||
queue_smooth(src)
|
||||
queue_smooth_neighbors(src)
|
||||
|
||||
/obj/effect/decal/cleanable/Destroy()
|
||||
if(smooth)
|
||||
queue_smooth_neighbors(src)
|
||||
return ..()
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/obj/effect/decal/cleanable/crayon
|
||||
name = "rune"
|
||||
desc = "A rune drawn in crayon."
|
||||
icon = 'icons/effects/crayondecal.dmi'
|
||||
icon_state = "rune1"
|
||||
layer = MID_TURF_LAYER
|
||||
plane = GAME_PLANE //makes the graffiti visible over a wall.
|
||||
anchored = TRUE
|
||||
mergeable_decal = FALSE // Allows crayon drawings to overlap one another.
|
||||
|
||||
|
||||
/obj/effect/decal/cleanable/crayon/Initialize(mapload, main = "#FFFFFF", var/type = "rune1", var/e_name = "rune")
|
||||
. = ..()
|
||||
|
||||
name = e_name
|
||||
desc = "A [name] drawn in crayon."
|
||||
|
||||
icon_state = type
|
||||
color = main
|
||||
/obj/effect/decal/cleanable/crayon
|
||||
name = "rune"
|
||||
desc = "A rune drawn in crayon."
|
||||
icon = 'icons/effects/crayondecal.dmi'
|
||||
icon_state = "rune1"
|
||||
layer = MID_TURF_LAYER
|
||||
plane = GAME_PLANE //makes the graffiti visible over a wall.
|
||||
anchored = TRUE
|
||||
mergeable_decal = FALSE // Allows crayon drawings to overlap one another.
|
||||
|
||||
|
||||
/obj/effect/decal/cleanable/crayon/Initialize(mapload, main = "#FFFFFF", var/type = "rune1", var/e_name = "rune")
|
||||
. = ..()
|
||||
|
||||
name = e_name
|
||||
desc = "A [name] drawn in crayon."
|
||||
|
||||
icon_state = type
|
||||
color = main
|
||||
|
||||
@@ -12,4 +12,4 @@
|
||||
var/turf/T = loc
|
||||
if(!istype(T)) //you know this will happen somehow
|
||||
CRASH("Turf decal initialized in an object/nullspace")
|
||||
T.AddComponent(/datum/component/decal, icon, icon_state, dir, CLEAN_GOD, color, null, null, alpha)
|
||||
T.AddComponent(/datum/component/decal, icon, icon_state, dir, CLEAN_GOD, color, null, null, alpha)
|
||||
|
||||
@@ -1,72 +1,72 @@
|
||||
// Used for spray that you spray at walls, tables, hydrovats etc
|
||||
/obj/effect/decal/spraystill
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
layer = 50
|
||||
plane = HUD_PLANE
|
||||
|
||||
/obj/effect/decal/chempuff
|
||||
name = "chemicals"
|
||||
icon = 'icons/obj/chempuff.dmi'
|
||||
pass_flags = PASSTABLE | PASSGRILLE
|
||||
|
||||
/obj/effect/decal/chempuff/blob_act(obj/structure/blob/B)
|
||||
return
|
||||
|
||||
/obj/effect/decal/snow
|
||||
name = "snow"
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
layer = TURF_DECAL_LAYER
|
||||
icon = 'icons/turf/snow.dmi'
|
||||
icon_state = "snow"
|
||||
|
||||
/obj/effect/decal/snow/clean/edge
|
||||
icon_state = "snow_corner"
|
||||
|
||||
/obj/effect/decal/snow/sand/edge
|
||||
icon_state = "gravsnow_corner"
|
||||
|
||||
/obj/effect/decal/snow/clean/surround
|
||||
icon_state = "snow_surround"
|
||||
|
||||
/obj/effect/decal/snow/sand/surround
|
||||
icon_state = "gravsnow_surround"
|
||||
|
||||
/obj/effect/decal/leaves
|
||||
name = "fall leaves"
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
layer = HIGH_TURF_LAYER
|
||||
icon = 'icons/obj/flora/plants.dmi'
|
||||
icon_state = "fallleaves"
|
||||
|
||||
/obj/effect/decal/straw
|
||||
name = "scattered straw"
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
layer = HIGH_TURF_LAYER
|
||||
icon = 'icons/obj/flora/plants.dmi'
|
||||
icon_state = "strawscattered"
|
||||
|
||||
/obj/effect/decal/straw/medium
|
||||
icon_state = "strawscattered3"
|
||||
|
||||
/obj/effect/decal/straw/light
|
||||
icon_state = "strawscattered2"
|
||||
|
||||
/obj/effect/decal/straw/edge
|
||||
icon_state = "strawscatterededge"
|
||||
|
||||
/obj/effect/decal/ants
|
||||
name = "space ants"
|
||||
desc = "A bunch of space ants."
|
||||
icon = 'icons/goonstation/effects/effects.dmi'
|
||||
icon_state = "spaceants"
|
||||
scoop_reagents = list("ants" = 20)
|
||||
|
||||
/obj/effect/decal/ants/Initialize(mapload)
|
||||
. = ..()
|
||||
var/scale = (rand(2, 10) / 10) + (rand(0, 5) / 100)
|
||||
transform = matrix(transform, scale, scale, MATRIX_SCALE)
|
||||
setDir(pick(NORTH, SOUTH, EAST, WEST))
|
||||
// Used for spray that you spray at walls, tables, hydrovats etc
|
||||
/obj/effect/decal/spraystill
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
layer = 50
|
||||
plane = HUD_PLANE
|
||||
|
||||
/obj/effect/decal/chempuff
|
||||
name = "chemicals"
|
||||
icon = 'icons/obj/chempuff.dmi'
|
||||
pass_flags = PASSTABLE | PASSGRILLE
|
||||
|
||||
/obj/effect/decal/chempuff/blob_act(obj/structure/blob/B)
|
||||
return
|
||||
|
||||
/obj/effect/decal/snow
|
||||
name = "snow"
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
layer = TURF_DECAL_LAYER
|
||||
icon = 'icons/turf/snow.dmi'
|
||||
icon_state = "snow"
|
||||
|
||||
/obj/effect/decal/snow/clean/edge
|
||||
icon_state = "snow_corner"
|
||||
|
||||
/obj/effect/decal/snow/sand/edge
|
||||
icon_state = "gravsnow_corner"
|
||||
|
||||
/obj/effect/decal/snow/clean/surround
|
||||
icon_state = "snow_surround"
|
||||
|
||||
/obj/effect/decal/snow/sand/surround
|
||||
icon_state = "gravsnow_surround"
|
||||
|
||||
/obj/effect/decal/leaves
|
||||
name = "fall leaves"
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
layer = HIGH_TURF_LAYER
|
||||
icon = 'icons/obj/flora/plants.dmi'
|
||||
icon_state = "fallleaves"
|
||||
|
||||
/obj/effect/decal/straw
|
||||
name = "scattered straw"
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
layer = HIGH_TURF_LAYER
|
||||
icon = 'icons/obj/flora/plants.dmi'
|
||||
icon_state = "strawscattered"
|
||||
|
||||
/obj/effect/decal/straw/medium
|
||||
icon_state = "strawscattered3"
|
||||
|
||||
/obj/effect/decal/straw/light
|
||||
icon_state = "strawscattered2"
|
||||
|
||||
/obj/effect/decal/straw/edge
|
||||
icon_state = "strawscatterededge"
|
||||
|
||||
/obj/effect/decal/ants
|
||||
name = "space ants"
|
||||
desc = "A bunch of space ants."
|
||||
icon = 'icons/goonstation/effects/effects.dmi'
|
||||
icon_state = "spaceants"
|
||||
scoop_reagents = list("ants" = 20)
|
||||
|
||||
/obj/effect/decal/ants/Initialize(mapload)
|
||||
. = ..()
|
||||
var/scale = (rand(2, 10) / 10) + (rand(0, 5) / 100)
|
||||
transform = matrix(transform, scale, scale, MATRIX_SCALE)
|
||||
setDir(pick(NORTH, SOUTH, EAST, WEST))
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
/obj/effect/decal/remains
|
||||
gender = PLURAL
|
||||
|
||||
/obj/effect/decal/remains/acid_act()
|
||||
visible_message("<span class='warning'>[src] dissolve[gender==PLURAL?"":"s"] into a puddle of sizzling goop!</span>")
|
||||
playsound(src, 'sound/items/welder.ogg', 150, TRUE)
|
||||
new /obj/effect/decal/cleanable/greenglow(drop_location())
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/decal/remains/human
|
||||
name = "remains"
|
||||
desc = "They look like human remains. They have a strange aura about them."
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "remains"
|
||||
anchored = TRUE
|
||||
|
||||
/obj/effect/decal/remains/xeno
|
||||
name = "remains"
|
||||
desc = "They look like the remains of something... alien. They have a strange aura about them."
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "remainsxeno"
|
||||
anchored = TRUE
|
||||
|
||||
/obj/effect/decal/remains/robot
|
||||
name = "remains"
|
||||
desc = "They look like the remains of something mechanical. They have a strange aura about them."
|
||||
icon = 'icons/mob/robots.dmi'
|
||||
icon_state = "remainsrobot"
|
||||
anchored = TRUE
|
||||
|
||||
/obj/effect/decal/remains/slime
|
||||
name = "You shouldn't see this"
|
||||
desc = "Noooooooooooooooooooooo"
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "remains"
|
||||
anchored = TRUE
|
||||
|
||||
/obj/effect/decal/remains/slime/New()
|
||||
..()
|
||||
var/datum/reagents/R = new/datum/reagents(5)
|
||||
var/obj/effect/particle_effect/water/W = new(get_turf(src))
|
||||
W.reagents = R
|
||||
R.my_atom = W
|
||||
R.add_reagent("water", 5)
|
||||
R.reaction(get_turf(src))
|
||||
qdel(src)
|
||||
/obj/effect/decal/remains
|
||||
gender = PLURAL
|
||||
|
||||
/obj/effect/decal/remains/acid_act()
|
||||
visible_message("<span class='warning'>[src] dissolve[gender==PLURAL?"":"s"] into a puddle of sizzling goop!</span>")
|
||||
playsound(src, 'sound/items/welder.ogg', 150, TRUE)
|
||||
new /obj/effect/decal/cleanable/greenglow(drop_location())
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/decal/remains/human
|
||||
name = "remains"
|
||||
desc = "They look like human remains. They have a strange aura about them."
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "remains"
|
||||
anchored = TRUE
|
||||
|
||||
/obj/effect/decal/remains/xeno
|
||||
name = "remains"
|
||||
desc = "They look like the remains of something... alien. They have a strange aura about them."
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "remainsxeno"
|
||||
anchored = TRUE
|
||||
|
||||
/obj/effect/decal/remains/robot
|
||||
name = "remains"
|
||||
desc = "They look like the remains of something mechanical. They have a strange aura about them."
|
||||
icon = 'icons/mob/robots.dmi'
|
||||
icon_state = "remainsrobot"
|
||||
anchored = TRUE
|
||||
|
||||
/obj/effect/decal/remains/slime
|
||||
name = "You shouldn't see this"
|
||||
desc = "Noooooooooooooooooooooo"
|
||||
icon = 'icons/effects/blood.dmi'
|
||||
icon_state = "remains"
|
||||
anchored = TRUE
|
||||
|
||||
/obj/effect/decal/remains/slime/New()
|
||||
..()
|
||||
var/datum/reagents/R = new/datum/reagents(5)
|
||||
var/obj/effect/particle_effect/water/W = new(get_turf(src))
|
||||
W.reagents = R
|
||||
R.my_atom = W
|
||||
R.add_reagent("water", 5)
|
||||
R.reaction(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
icon_state = "sandyfloor"
|
||||
|
||||
/obj/effect/turf_decal/sand/plating
|
||||
icon_state = "sandyplating"
|
||||
icon_state = "sandyplating"
|
||||
|
||||
@@ -149,4 +149,4 @@
|
||||
icon_state = "box_corners_red"
|
||||
|
||||
/obj/effect/turf_decal/plaque
|
||||
icon_state = "plaque"
|
||||
icon_state = "plaque"
|
||||
|
||||
@@ -36,4 +36,4 @@
|
||||
/obj/effect/turf_decal/tile/neutral
|
||||
name = "neutral corner"
|
||||
color = "#D4D4D4"
|
||||
alpha = 50
|
||||
alpha = 50
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
/obj/effect/turf_decal/weather/snow/corner
|
||||
name = "snow corner piece"
|
||||
icon = 'icons/turf/snow.dmi'
|
||||
icon_state = "snow_corner"
|
||||
icon_state = "snow_corner"
|
||||
|
||||
@@ -73,4 +73,4 @@ would spawn and follow the beaker, even if it is carried or thrown.
|
||||
/datum/effect_system/proc/decrement_total_effect()
|
||||
total_effects--
|
||||
if(autocleanup && total_effects <= 0)
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -123,4 +123,4 @@
|
||||
if(iscarbon(A))
|
||||
var/mob/living/carbon/C = A
|
||||
if(C.can_breathe_gas())
|
||||
chemholder.reagents.copy_to(C, chemholder.reagents.total_volume)
|
||||
chemholder.reagents.copy_to(C, chemholder.reagents.total_volume)
|
||||
|
||||
@@ -218,4 +218,4 @@
|
||||
return !density
|
||||
|
||||
/obj/structure/foamedmetal/CanAtmosPass()
|
||||
return !density
|
||||
return !density
|
||||
|
||||
@@ -89,4 +89,4 @@
|
||||
|
||||
/obj/effect/decal/blob_act(obj/structure/blob/B)
|
||||
if(B && B.loc == loc)
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -38,4 +38,4 @@
|
||||
/obj/effect/forcefield/mime/advanced
|
||||
name = "invisible blockade"
|
||||
desc = "You might be here a while."
|
||||
lifetime = 60 SECONDS
|
||||
lifetime = 60 SECONDS
|
||||
|
||||
@@ -1,53 +1,53 @@
|
||||
/proc/gibs(atom/location, datum/dna/MobDNA) //CARN MARKER
|
||||
new /obj/effect/gibspawner/generic(get_turf(location), MobDNA)
|
||||
|
||||
/proc/hgibs(atom/location, datum/dna/MobDNA)
|
||||
new /obj/effect/gibspawner/human(get_turf(location), MobDNA)
|
||||
|
||||
/proc/xgibs(atom/location)
|
||||
new /obj/effect/gibspawner/xeno(get_turf(location))
|
||||
|
||||
/proc/robogibs(atom/location)
|
||||
new /obj/effect/gibspawner/robot(get_turf(location))
|
||||
|
||||
/obj/effect/gibspawner
|
||||
var/sparks = 0 //whether sparks spread on Gib()
|
||||
var/list/gibtypes = list()
|
||||
var/list/gibamounts = list()
|
||||
var/list/gibdirections = list() //of lists
|
||||
|
||||
/obj/effect/gibspawner/New(location, datum/dna/MobDNA)
|
||||
..()
|
||||
|
||||
if(istype(loc,/turf)) //basically if a badmin spawns it
|
||||
Gib(loc, MobDNA)
|
||||
|
||||
/obj/effect/gibspawner/proc/Gib(atom/location, datum/dna/MobDNA = null)
|
||||
if(gibtypes.len != gibamounts.len || gibamounts.len != gibdirections.len)
|
||||
to_chat(world, "<span class='warning'>Gib list length mismatch!</span>")
|
||||
return
|
||||
|
||||
var/obj/effect/decal/cleanable/blood/gibs/gib = null
|
||||
|
||||
if(sparks)
|
||||
do_sparks(2, 1, location)
|
||||
|
||||
for(var/i = 1, i<= gibtypes.len, i++)
|
||||
if(gibamounts[i])
|
||||
for(var/j = 1, j<= gibamounts[i], j++)
|
||||
var/gibType = gibtypes[i]
|
||||
gib = new gibType(location)
|
||||
|
||||
|
||||
gib.blood_DNA = list()
|
||||
if(MobDNA)
|
||||
gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.blood_type
|
||||
else if(istype(src, /obj/effect/gibspawner/xeno))
|
||||
gib.blood_DNA["UNKNOWN DNA"] = "X*"
|
||||
else if(istype(src, /obj/effect/gibspawner/human)) // Probably a monkey
|
||||
gib.blood_DNA["Non-human DNA"] = "A+"
|
||||
var/list/directions = gibdirections[i]
|
||||
if(directions.len)
|
||||
gib.streak(directions)
|
||||
|
||||
qdel(src)
|
||||
/proc/gibs(atom/location, datum/dna/MobDNA) //CARN MARKER
|
||||
new /obj/effect/gibspawner/generic(get_turf(location), MobDNA)
|
||||
|
||||
/proc/hgibs(atom/location, datum/dna/MobDNA)
|
||||
new /obj/effect/gibspawner/human(get_turf(location), MobDNA)
|
||||
|
||||
/proc/xgibs(atom/location)
|
||||
new /obj/effect/gibspawner/xeno(get_turf(location))
|
||||
|
||||
/proc/robogibs(atom/location)
|
||||
new /obj/effect/gibspawner/robot(get_turf(location))
|
||||
|
||||
/obj/effect/gibspawner
|
||||
var/sparks = 0 //whether sparks spread on Gib()
|
||||
var/list/gibtypes = list()
|
||||
var/list/gibamounts = list()
|
||||
var/list/gibdirections = list() //of lists
|
||||
|
||||
/obj/effect/gibspawner/New(location, datum/dna/MobDNA)
|
||||
..()
|
||||
|
||||
if(istype(loc,/turf)) //basically if a badmin spawns it
|
||||
Gib(loc, MobDNA)
|
||||
|
||||
/obj/effect/gibspawner/proc/Gib(atom/location, datum/dna/MobDNA = null)
|
||||
if(gibtypes.len != gibamounts.len || gibamounts.len != gibdirections.len)
|
||||
to_chat(world, "<span class='warning'>Gib list length mismatch!</span>")
|
||||
return
|
||||
|
||||
var/obj/effect/decal/cleanable/blood/gibs/gib = null
|
||||
|
||||
if(sparks)
|
||||
do_sparks(2, 1, location)
|
||||
|
||||
for(var/i = 1, i<= gibtypes.len, i++)
|
||||
if(gibamounts[i])
|
||||
for(var/j = 1, j<= gibamounts[i], j++)
|
||||
var/gibType = gibtypes[i]
|
||||
gib = new gibType(location)
|
||||
|
||||
|
||||
gib.blood_DNA = list()
|
||||
if(MobDNA)
|
||||
gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.blood_type
|
||||
else if(istype(src, /obj/effect/gibspawner/xeno))
|
||||
gib.blood_DNA["UNKNOWN DNA"] = "X*"
|
||||
else if(istype(src, /obj/effect/gibspawner/human)) // Probably a monkey
|
||||
gib.blood_DNA["Non-human DNA"] = "A+"
|
||||
var/list/directions = gibdirections[i]
|
||||
if(directions.len)
|
||||
gib.streak(directions)
|
||||
|
||||
qdel(src)
|
||||
|
||||
@@ -1,169 +1,169 @@
|
||||
//separate dm since hydro is getting bloated already
|
||||
|
||||
/obj/structure/glowshroom
|
||||
name = "glowshroom"
|
||||
desc = "Mycena Bregprox, a species of mushroom that glows in the dark."
|
||||
anchored = TRUE
|
||||
opacity = 0
|
||||
density = FALSE
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
icon_state = "glowshroom" //replaced in New
|
||||
layer = ABOVE_NORMAL_TURF_LAYER
|
||||
max_integrity = 30
|
||||
var/delay = 1200
|
||||
var/floor = 0
|
||||
var/generation = 1
|
||||
var/spreadIntoAdjacentChance = 60
|
||||
var/obj/item/seeds/myseed = /obj/item/seeds/glowshroom
|
||||
|
||||
/obj/structure/glowshroom/glowcap
|
||||
name = "glowcap"
|
||||
desc = "Mycena Ruthenia, a species of mushroom that, while it does glow in the dark, is not actually bioluminescent."
|
||||
icon_state = "glowcap"
|
||||
myseed = /obj/item/seeds/glowshroom/glowcap
|
||||
|
||||
/obj/structure/glowshroom/shadowshroom
|
||||
name = "shadowshroom"
|
||||
desc = "Mycena Umbra, a species of mushroom that emits shadow instead of light."
|
||||
icon_state = "shadowshroom"
|
||||
myseed = /obj/item/seeds/glowshroom/shadowshroom
|
||||
|
||||
/obj/structure/glowshroom/single/Spread()
|
||||
return
|
||||
|
||||
/obj/structure/glowshroom/examine(mob/user)
|
||||
. = ..()
|
||||
. += "This is a [generation]\th generation [name]!"
|
||||
|
||||
/obj/structure/glowshroom/Destroy()
|
||||
QDEL_NULL(myseed)
|
||||
return ..()
|
||||
|
||||
/obj/structure/glowshroom/New(loc, obj/item/seeds/newseed, mutate_stats)
|
||||
..()
|
||||
if(newseed)
|
||||
myseed = newseed.Copy()
|
||||
myseed.forceMove(src)
|
||||
else
|
||||
myseed = new myseed(src)
|
||||
if(mutate_stats) //baby mushrooms have different stats :3
|
||||
myseed.adjust_potency(rand(-3,6))
|
||||
myseed.adjust_yield(rand(-1,2))
|
||||
myseed.adjust_production(rand(-3,6))
|
||||
myseed.adjust_endurance(rand(-3,6))
|
||||
delay = delay - myseed.production * 100 //So the delay goes DOWN with better stats instead of up. :I
|
||||
obj_integrity = myseed.endurance
|
||||
max_integrity = myseed.endurance
|
||||
if(myseed.get_gene(/datum/plant_gene/trait/glow))
|
||||
var/datum/plant_gene/trait/glow/G = myseed.get_gene(/datum/plant_gene/trait/glow)
|
||||
set_light(G.glow_range(myseed), G.glow_power(myseed), G.glow_color)
|
||||
setDir(CalcDir())
|
||||
var/base_icon_state = initial(icon_state)
|
||||
if(!floor)
|
||||
switch(dir) //offset to make it be on the wall rather than on the floor
|
||||
if(NORTH)
|
||||
pixel_y = 32
|
||||
if(SOUTH)
|
||||
pixel_y = -32
|
||||
if(EAST)
|
||||
pixel_x = 32
|
||||
if(WEST)
|
||||
pixel_x = -32
|
||||
icon_state = "[base_icon_state][rand(1,3)]"
|
||||
else //if on the floor, glowshroom on-floor sprite
|
||||
icon_state = "[base_icon_state]f"
|
||||
|
||||
addtimer(CALLBACK(src, .proc/Spread), delay)
|
||||
|
||||
/obj/structure/glowshroom/proc/Spread()
|
||||
var/turf/ownturf = get_turf(src)
|
||||
var/shrooms_planted = 0
|
||||
for(var/i in 1 to myseed.yield)
|
||||
if(prob(1/(generation * generation) * 100))//This formula gives you diminishing returns based on generation. 100% with 1st gen, decreasing to 25%, 11%, 6, 4, 2...
|
||||
var/list/possibleLocs = list()
|
||||
var/spreadsIntoAdjacent = FALSE
|
||||
|
||||
if(prob(spreadIntoAdjacentChance))
|
||||
spreadsIntoAdjacent = TRUE
|
||||
|
||||
for(var/turf/simulated/floor/earth in view(3,src))
|
||||
if(!ownturf.CanAtmosPass(earth))
|
||||
continue
|
||||
if(spreadsIntoAdjacent || !locate(/obj/structure/glowshroom) in view(1,earth))
|
||||
possibleLocs += earth
|
||||
CHECK_TICK
|
||||
|
||||
if(!possibleLocs.len)
|
||||
break
|
||||
|
||||
var/turf/newLoc = pick(possibleLocs)
|
||||
|
||||
var/shroomCount = 0 //hacky
|
||||
var/placeCount = 1
|
||||
for(var/obj/structure/glowshroom/shroom in newLoc)
|
||||
shroomCount++
|
||||
for(var/wallDir in cardinal)
|
||||
var/turf/isWall = get_step(newLoc,wallDir)
|
||||
if(isWall.density)
|
||||
placeCount++
|
||||
if(shroomCount >= placeCount)
|
||||
continue
|
||||
|
||||
var/obj/structure/glowshroom/child = new type(newLoc, myseed, TRUE)
|
||||
child.generation = generation + 1
|
||||
shrooms_planted++
|
||||
|
||||
CHECK_TICK
|
||||
else
|
||||
shrooms_planted++ //if we failed due to generation, don't try to plant one later
|
||||
if(shrooms_planted < myseed.yield) //if we didn't get all possible shrooms planted, try again later
|
||||
myseed.yield -= shrooms_planted
|
||||
addtimer(CALLBACK(src, .proc/Spread), delay)
|
||||
|
||||
/obj/structure/glowshroom/proc/CalcDir(turf/location = loc)
|
||||
var/direction = 16
|
||||
|
||||
for(var/wallDir in cardinal)
|
||||
var/turf/newTurf = get_step(location,wallDir)
|
||||
if(newTurf.density)
|
||||
direction |= wallDir
|
||||
|
||||
for(var/obj/structure/glowshroom/shroom in location)
|
||||
if(shroom == src)
|
||||
continue
|
||||
if(shroom.floor) //special
|
||||
direction &= ~16
|
||||
else
|
||||
direction &= ~shroom.dir
|
||||
|
||||
var/list/dirList = list()
|
||||
|
||||
for(var/i=1,i<=16,i <<= 1)
|
||||
if(direction & i)
|
||||
dirList += i
|
||||
|
||||
if(dirList.len)
|
||||
var/newDir = pick(dirList)
|
||||
if(newDir == 16)
|
||||
floor = 1
|
||||
newDir = 1
|
||||
return newDir
|
||||
|
||||
floor = 1
|
||||
return 1
|
||||
|
||||
/obj/structure/glowshroom/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
|
||||
if(damage_type == BURN && damage_amount)
|
||||
playsound(src.loc, 'sound/items/welder.ogg', 100, TRUE)
|
||||
|
||||
/obj/structure/glowshroom/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
..()
|
||||
if(exposed_temperature > 300)
|
||||
take_damage(5, BURN, 0, 0)
|
||||
|
||||
/obj/structure/glowshroom/acid_act(acidpwr, acid_volume)
|
||||
. = 1
|
||||
visible_message("<span class='danger'>[src] melts away!</span>")
|
||||
var/obj/effect/decal/cleanable/molten_object/I = new (get_turf(src))
|
||||
I.desc = "Looks like this was \an [src] some time ago."
|
||||
qdel(src)
|
||||
//separate dm since hydro is getting bloated already
|
||||
|
||||
/obj/structure/glowshroom
|
||||
name = "glowshroom"
|
||||
desc = "Mycena Bregprox, a species of mushroom that glows in the dark."
|
||||
anchored = TRUE
|
||||
opacity = 0
|
||||
density = FALSE
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
icon_state = "glowshroom" //replaced in New
|
||||
layer = ABOVE_NORMAL_TURF_LAYER
|
||||
max_integrity = 30
|
||||
var/delay = 1200
|
||||
var/floor = 0
|
||||
var/generation = 1
|
||||
var/spreadIntoAdjacentChance = 60
|
||||
var/obj/item/seeds/myseed = /obj/item/seeds/glowshroom
|
||||
|
||||
/obj/structure/glowshroom/glowcap
|
||||
name = "glowcap"
|
||||
desc = "Mycena Ruthenia, a species of mushroom that, while it does glow in the dark, is not actually bioluminescent."
|
||||
icon_state = "glowcap"
|
||||
myseed = /obj/item/seeds/glowshroom/glowcap
|
||||
|
||||
/obj/structure/glowshroom/shadowshroom
|
||||
name = "shadowshroom"
|
||||
desc = "Mycena Umbra, a species of mushroom that emits shadow instead of light."
|
||||
icon_state = "shadowshroom"
|
||||
myseed = /obj/item/seeds/glowshroom/shadowshroom
|
||||
|
||||
/obj/structure/glowshroom/single/Spread()
|
||||
return
|
||||
|
||||
/obj/structure/glowshroom/examine(mob/user)
|
||||
. = ..()
|
||||
. += "This is a [generation]\th generation [name]!"
|
||||
|
||||
/obj/structure/glowshroom/Destroy()
|
||||
QDEL_NULL(myseed)
|
||||
return ..()
|
||||
|
||||
/obj/structure/glowshroom/New(loc, obj/item/seeds/newseed, mutate_stats)
|
||||
..()
|
||||
if(newseed)
|
||||
myseed = newseed.Copy()
|
||||
myseed.forceMove(src)
|
||||
else
|
||||
myseed = new myseed(src)
|
||||
if(mutate_stats) //baby mushrooms have different stats :3
|
||||
myseed.adjust_potency(rand(-3,6))
|
||||
myseed.adjust_yield(rand(-1,2))
|
||||
myseed.adjust_production(rand(-3,6))
|
||||
myseed.adjust_endurance(rand(-3,6))
|
||||
delay = delay - myseed.production * 100 //So the delay goes DOWN with better stats instead of up. :I
|
||||
obj_integrity = myseed.endurance
|
||||
max_integrity = myseed.endurance
|
||||
if(myseed.get_gene(/datum/plant_gene/trait/glow))
|
||||
var/datum/plant_gene/trait/glow/G = myseed.get_gene(/datum/plant_gene/trait/glow)
|
||||
set_light(G.glow_range(myseed), G.glow_power(myseed), G.glow_color)
|
||||
setDir(CalcDir())
|
||||
var/base_icon_state = initial(icon_state)
|
||||
if(!floor)
|
||||
switch(dir) //offset to make it be on the wall rather than on the floor
|
||||
if(NORTH)
|
||||
pixel_y = 32
|
||||
if(SOUTH)
|
||||
pixel_y = -32
|
||||
if(EAST)
|
||||
pixel_x = 32
|
||||
if(WEST)
|
||||
pixel_x = -32
|
||||
icon_state = "[base_icon_state][rand(1,3)]"
|
||||
else //if on the floor, glowshroom on-floor sprite
|
||||
icon_state = "[base_icon_state]f"
|
||||
|
||||
addtimer(CALLBACK(src, .proc/Spread), delay)
|
||||
|
||||
/obj/structure/glowshroom/proc/Spread()
|
||||
var/turf/ownturf = get_turf(src)
|
||||
var/shrooms_planted = 0
|
||||
for(var/i in 1 to myseed.yield)
|
||||
if(prob(1/(generation * generation) * 100))//This formula gives you diminishing returns based on generation. 100% with 1st gen, decreasing to 25%, 11%, 6, 4, 2...
|
||||
var/list/possibleLocs = list()
|
||||
var/spreadsIntoAdjacent = FALSE
|
||||
|
||||
if(prob(spreadIntoAdjacentChance))
|
||||
spreadsIntoAdjacent = TRUE
|
||||
|
||||
for(var/turf/simulated/floor/earth in view(3,src))
|
||||
if(!ownturf.CanAtmosPass(earth))
|
||||
continue
|
||||
if(spreadsIntoAdjacent || !locate(/obj/structure/glowshroom) in view(1,earth))
|
||||
possibleLocs += earth
|
||||
CHECK_TICK
|
||||
|
||||
if(!possibleLocs.len)
|
||||
break
|
||||
|
||||
var/turf/newLoc = pick(possibleLocs)
|
||||
|
||||
var/shroomCount = 0 //hacky
|
||||
var/placeCount = 1
|
||||
for(var/obj/structure/glowshroom/shroom in newLoc)
|
||||
shroomCount++
|
||||
for(var/wallDir in cardinal)
|
||||
var/turf/isWall = get_step(newLoc,wallDir)
|
||||
if(isWall.density)
|
||||
placeCount++
|
||||
if(shroomCount >= placeCount)
|
||||
continue
|
||||
|
||||
var/obj/structure/glowshroom/child = new type(newLoc, myseed, TRUE)
|
||||
child.generation = generation + 1
|
||||
shrooms_planted++
|
||||
|
||||
CHECK_TICK
|
||||
else
|
||||
shrooms_planted++ //if we failed due to generation, don't try to plant one later
|
||||
if(shrooms_planted < myseed.yield) //if we didn't get all possible shrooms planted, try again later
|
||||
myseed.yield -= shrooms_planted
|
||||
addtimer(CALLBACK(src, .proc/Spread), delay)
|
||||
|
||||
/obj/structure/glowshroom/proc/CalcDir(turf/location = loc)
|
||||
var/direction = 16
|
||||
|
||||
for(var/wallDir in cardinal)
|
||||
var/turf/newTurf = get_step(location,wallDir)
|
||||
if(newTurf.density)
|
||||
direction |= wallDir
|
||||
|
||||
for(var/obj/structure/glowshroom/shroom in location)
|
||||
if(shroom == src)
|
||||
continue
|
||||
if(shroom.floor) //special
|
||||
direction &= ~16
|
||||
else
|
||||
direction &= ~shroom.dir
|
||||
|
||||
var/list/dirList = list()
|
||||
|
||||
for(var/i=1,i<=16,i <<= 1)
|
||||
if(direction & i)
|
||||
dirList += i
|
||||
|
||||
if(dirList.len)
|
||||
var/newDir = pick(dirList)
|
||||
if(newDir == 16)
|
||||
floor = 1
|
||||
newDir = 1
|
||||
return newDir
|
||||
|
||||
floor = 1
|
||||
return 1
|
||||
|
||||
/obj/structure/glowshroom/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
|
||||
if(damage_type == BURN && damage_amount)
|
||||
playsound(src.loc, 'sound/items/welder.ogg', 100, TRUE)
|
||||
|
||||
/obj/structure/glowshroom/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
..()
|
||||
if(exposed_temperature > 300)
|
||||
take_damage(5, BURN, 0, 0)
|
||||
|
||||
/obj/structure/glowshroom/acid_act(acidpwr, acid_volume)
|
||||
. = 1
|
||||
visible_message("<span class='danger'>[src] melts away!</span>")
|
||||
var/obj/effect/decal/cleanable/molten_object/I = new (get_turf(src))
|
||||
I.desc = "Looks like this was \an [src] some time ago."
|
||||
qdel(src)
|
||||
|
||||
@@ -1,306 +1,306 @@
|
||||
/obj/effect/landmark
|
||||
name = "landmark"
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "x2"
|
||||
anchored = 1.0
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
/obj/effect/landmark/New()
|
||||
|
||||
..()
|
||||
set_tag()
|
||||
invisibility = 101
|
||||
|
||||
switch(name) //some of these are probably obsolete
|
||||
if("start")
|
||||
newplayer_start += loc
|
||||
qdel(src)
|
||||
|
||||
if("wizard")
|
||||
wizardstart += loc
|
||||
qdel(src)
|
||||
|
||||
if("JoinLate")
|
||||
latejoin += loc
|
||||
qdel(src)
|
||||
|
||||
if("JoinLateGateway")
|
||||
latejoin_gateway += loc
|
||||
qdel(src)
|
||||
|
||||
if("JoinLateCryo")
|
||||
latejoin_cryo += loc
|
||||
qdel(src)
|
||||
|
||||
if("JoinLateCyborg")
|
||||
latejoin_cyborg += loc
|
||||
qdel(src)
|
||||
|
||||
if("prisonwarp")
|
||||
prisonwarp += loc
|
||||
qdel(src)
|
||||
|
||||
if("prisonsecuritywarp")
|
||||
prisonsecuritywarp += loc
|
||||
qdel(src)
|
||||
|
||||
if("tdome1")
|
||||
tdome1 += loc
|
||||
|
||||
if("tdome2")
|
||||
tdome2 += loc
|
||||
|
||||
if("tdomeadmin")
|
||||
tdomeadmin += loc
|
||||
|
||||
if("tdomeobserve")
|
||||
tdomeobserve += loc
|
||||
|
||||
if("aroomwarp")
|
||||
aroomwarp += loc
|
||||
|
||||
if("blobstart")
|
||||
blobstart += loc
|
||||
qdel(src)
|
||||
|
||||
if("xeno_spawn")
|
||||
xeno_spawn += loc
|
||||
qdel(src)
|
||||
|
||||
if("ninjastart")
|
||||
ninjastart += loc
|
||||
qdel(src)
|
||||
|
||||
if("carpspawn")
|
||||
carplist += loc
|
||||
|
||||
if("voxstart")
|
||||
raider_spawn += loc
|
||||
|
||||
if("ERT Director")
|
||||
ertdirector += loc
|
||||
qdel(src)
|
||||
|
||||
if("Response Team")
|
||||
emergencyresponseteamspawn += loc
|
||||
qdel(src)
|
||||
|
||||
if("Syndicate Officer")
|
||||
syndicateofficer += loc
|
||||
qdel(src)
|
||||
|
||||
GLOB.landmarks_list += src
|
||||
return 1
|
||||
|
||||
/obj/effect/landmark/Destroy()
|
||||
GLOB.landmarks_list -= src
|
||||
..()
|
||||
return QDEL_HINT_HARDDEL_NOW
|
||||
|
||||
/obj/effect/landmark/proc/set_tag()
|
||||
tag = text("landmark*[]", name)
|
||||
|
||||
|
||||
/obj/effect/landmark/singularity_act()
|
||||
return
|
||||
|
||||
// Please stop bombing the Observer-Start landmark.
|
||||
/obj/effect/landmark/ex_act()
|
||||
return
|
||||
|
||||
/obj/effect/landmark/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/landmark/start
|
||||
name = "start"
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "x"
|
||||
anchored = 1.0
|
||||
|
||||
/obj/effect/landmark/start/set_tag()
|
||||
tag = "start*[name]"
|
||||
|
||||
|
||||
//Costume spawner landmarks
|
||||
|
||||
/obj/effect/landmark/costume/New() //costume spawner, selects a random subclass and disappears
|
||||
|
||||
var/list/options = typesof(/obj/effect/landmark/costume)
|
||||
var/PICK= options[rand(1,options.len)]
|
||||
new PICK(src.loc)
|
||||
qdel(src)
|
||||
|
||||
//SUBCLASSES. Spawn a bunch of items and disappear likewise
|
||||
/obj/effect/landmark/costume/chicken/New()
|
||||
new /obj/item/clothing/suit/chickensuit(src.loc)
|
||||
new /obj/item/clothing/head/chicken(src.loc)
|
||||
new /obj/item/reagent_containers/food/snacks/egg(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/gladiator/New()
|
||||
new /obj/item/clothing/under/gladiator(src.loc)
|
||||
new /obj/item/clothing/head/helmet/gladiator(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/madscientist/New()
|
||||
new /obj/item/clothing/under/gimmick/rank/captain/suit(src.loc)
|
||||
new /obj/item/clothing/head/flatcap(src.loc)
|
||||
new /obj/item/clothing/suit/storage/labcoat/mad(src.loc)
|
||||
new /obj/item/clothing/glasses/gglasses(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/elpresidente/New()
|
||||
new /obj/item/clothing/under/gimmick/rank/captain/suit(src.loc)
|
||||
new /obj/item/clothing/head/flatcap(src.loc)
|
||||
new /obj/item/clothing/mask/cigarette/cigar/havana(src.loc)
|
||||
new /obj/item/clothing/shoes/jackboots(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/nyangirl/New()
|
||||
new /obj/item/clothing/under/schoolgirl(src.loc)
|
||||
new /obj/item/clothing/head/kitty(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/maid/New()
|
||||
new /obj/item/clothing/under/blackskirt(src.loc)
|
||||
var/CHOICE = pick( /obj/item/clothing/head/beret , /obj/item/clothing/head/rabbitears )
|
||||
new CHOICE(src.loc)
|
||||
new /obj/item/clothing/glasses/sunglasses/blindfold(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/butler/New()
|
||||
new /obj/item/clothing/suit/wcoat(src.loc)
|
||||
new /obj/item/clothing/under/suit_jacket(src.loc)
|
||||
new /obj/item/clothing/head/that(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/scratch/New()
|
||||
new /obj/item/clothing/gloves/color/white(src.loc)
|
||||
new /obj/item/clothing/shoes/white(src.loc)
|
||||
new /obj/item/clothing/under/scratch(src.loc)
|
||||
if(prob(30))
|
||||
new /obj/item/clothing/head/cueball(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/highlander/New()
|
||||
new /obj/item/clothing/under/kilt(src.loc)
|
||||
new /obj/item/clothing/head/beret(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/prig/New()
|
||||
new /obj/item/clothing/suit/wcoat(src.loc)
|
||||
new /obj/item/clothing/glasses/monocle(src.loc)
|
||||
var/CHOICE= pick( /obj/item/clothing/head/bowlerhat, /obj/item/clothing/head/that)
|
||||
new CHOICE(src.loc)
|
||||
new /obj/item/clothing/shoes/black(src.loc)
|
||||
new /obj/item/cane(src.loc)
|
||||
new /obj/item/clothing/under/sl_suit(src.loc)
|
||||
new /obj/item/clothing/mask/fakemoustache(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/plaguedoctor/New()
|
||||
new /obj/item/clothing/suit/bio_suit/plaguedoctorsuit(src.loc)
|
||||
new /obj/item/clothing/head/plaguedoctorhat(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/nightowl/New()
|
||||
new /obj/item/clothing/under/owl(src.loc)
|
||||
new /obj/item/clothing/mask/gas/owl_mask(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/waiter/New()
|
||||
new /obj/item/clothing/under/waiter(src.loc)
|
||||
var/CHOICE= pick( /obj/item/clothing/head/kitty, /obj/item/clothing/head/rabbitears)
|
||||
new CHOICE(src.loc)
|
||||
new /obj/item/clothing/suit/apron(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/pirate/New()
|
||||
new /obj/item/clothing/under/pirate(src.loc)
|
||||
new /obj/item/clothing/suit/pirate_black(src.loc)
|
||||
var/CHOICE = pick( /obj/item/clothing/head/pirate , /obj/item/clothing/head/bandana )
|
||||
new CHOICE(src.loc)
|
||||
new /obj/item/clothing/glasses/eyepatch(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/commie/New()
|
||||
new /obj/item/clothing/under/soviet(src.loc)
|
||||
new /obj/item/clothing/head/ushanka(src.loc)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/effect/landmark/costume/imperium_monk/New()
|
||||
new /obj/item/clothing/suit/imperium_monk(src.loc)
|
||||
if(prob(25))
|
||||
new /obj/item/clothing/mask/gas/cyborg(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/holiday_priest/New()
|
||||
new /obj/item/clothing/suit/holidaypriest(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/marisawizard/fake/New()
|
||||
new /obj/item/clothing/head/wizard/marisa/fake(src.loc)
|
||||
new/obj/item/clothing/suit/wizrobe/marisa/fake(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/cutewitch/New()
|
||||
new /obj/item/clothing/under/sundress(src.loc)
|
||||
new /obj/item/clothing/head/witchwig(src.loc)
|
||||
new /obj/item/twohanded/staff/broom(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/fakewizard/New()
|
||||
new /obj/item/clothing/suit/wizrobe/fake(src.loc)
|
||||
new /obj/item/clothing/head/wizard/fake(src.loc)
|
||||
new /obj/item/twohanded/staff/(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/sexyclown/New()
|
||||
new /obj/item/clothing/mask/gas/clown_hat/sexy(loc)
|
||||
new /obj/item/clothing/under/rank/clown/sexy(loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/sexymime/New()
|
||||
new /obj/item/clothing/mask/gas/sexymime(src.loc)
|
||||
new /obj/item/clothing/under/sexymime(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/ruin
|
||||
var/datum/map_template/ruin/ruin_template
|
||||
|
||||
/obj/effect/landmark/ruin/New(loc, my_ruin_template)
|
||||
name = "ruin_[GLOB.ruin_landmarks.len + 1]"
|
||||
..(loc)
|
||||
ruin_template = my_ruin_template
|
||||
GLOB.ruin_landmarks |= src
|
||||
|
||||
/obj/effect/landmark/ruin/Destroy()
|
||||
GLOB.ruin_landmarks -= src
|
||||
ruin_template = null
|
||||
. = ..()
|
||||
|
||||
// Damage tiles
|
||||
/obj/effect/landmark/damageturf
|
||||
icon_state = "damaged"
|
||||
|
||||
/obj/effect/landmark/damageturf/New()
|
||||
..()
|
||||
var/turf/simulated/T = get_turf(src)
|
||||
if(istype(T))
|
||||
T.break_tile()
|
||||
|
||||
/obj/effect/landmark/burnturf
|
||||
icon_state = "burned"
|
||||
|
||||
/obj/effect/landmark/burnturf/New()
|
||||
..()
|
||||
var/turf/simulated/T = get_turf(src)
|
||||
T.burn_tile()
|
||||
|
||||
|
||||
/obj/effect/landmark/battle_mob_point
|
||||
name = "Nanomob Battle Avatar Spawn Point"
|
||||
|
||||
/obj/effect/landmark/free_golem_spawn
|
||||
name = "Free Golem Spawn Point"
|
||||
/obj/effect/landmark
|
||||
name = "landmark"
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "x2"
|
||||
anchored = 1.0
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
/obj/effect/landmark/New()
|
||||
|
||||
..()
|
||||
set_tag()
|
||||
invisibility = 101
|
||||
|
||||
switch(name) //some of these are probably obsolete
|
||||
if("start")
|
||||
newplayer_start += loc
|
||||
qdel(src)
|
||||
|
||||
if("wizard")
|
||||
wizardstart += loc
|
||||
qdel(src)
|
||||
|
||||
if("JoinLate")
|
||||
latejoin += loc
|
||||
qdel(src)
|
||||
|
||||
if("JoinLateGateway")
|
||||
latejoin_gateway += loc
|
||||
qdel(src)
|
||||
|
||||
if("JoinLateCryo")
|
||||
latejoin_cryo += loc
|
||||
qdel(src)
|
||||
|
||||
if("JoinLateCyborg")
|
||||
latejoin_cyborg += loc
|
||||
qdel(src)
|
||||
|
||||
if("prisonwarp")
|
||||
prisonwarp += loc
|
||||
qdel(src)
|
||||
|
||||
if("prisonsecuritywarp")
|
||||
prisonsecuritywarp += loc
|
||||
qdel(src)
|
||||
|
||||
if("tdome1")
|
||||
tdome1 += loc
|
||||
|
||||
if("tdome2")
|
||||
tdome2 += loc
|
||||
|
||||
if("tdomeadmin")
|
||||
tdomeadmin += loc
|
||||
|
||||
if("tdomeobserve")
|
||||
tdomeobserve += loc
|
||||
|
||||
if("aroomwarp")
|
||||
aroomwarp += loc
|
||||
|
||||
if("blobstart")
|
||||
blobstart += loc
|
||||
qdel(src)
|
||||
|
||||
if("xeno_spawn")
|
||||
xeno_spawn += loc
|
||||
qdel(src)
|
||||
|
||||
if("ninjastart")
|
||||
ninjastart += loc
|
||||
qdel(src)
|
||||
|
||||
if("carpspawn")
|
||||
carplist += loc
|
||||
|
||||
if("voxstart")
|
||||
raider_spawn += loc
|
||||
|
||||
if("ERT Director")
|
||||
ertdirector += loc
|
||||
qdel(src)
|
||||
|
||||
if("Response Team")
|
||||
emergencyresponseteamspawn += loc
|
||||
qdel(src)
|
||||
|
||||
if("Syndicate Officer")
|
||||
syndicateofficer += loc
|
||||
qdel(src)
|
||||
|
||||
GLOB.landmarks_list += src
|
||||
return 1
|
||||
|
||||
/obj/effect/landmark/Destroy()
|
||||
GLOB.landmarks_list -= src
|
||||
..()
|
||||
return QDEL_HINT_HARDDEL_NOW
|
||||
|
||||
/obj/effect/landmark/proc/set_tag()
|
||||
tag = text("landmark*[]", name)
|
||||
|
||||
|
||||
/obj/effect/landmark/singularity_act()
|
||||
return
|
||||
|
||||
// Please stop bombing the Observer-Start landmark.
|
||||
/obj/effect/landmark/ex_act()
|
||||
return
|
||||
|
||||
/obj/effect/landmark/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/landmark/start
|
||||
name = "start"
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "x"
|
||||
anchored = 1.0
|
||||
|
||||
/obj/effect/landmark/start/set_tag()
|
||||
tag = "start*[name]"
|
||||
|
||||
|
||||
//Costume spawner landmarks
|
||||
|
||||
/obj/effect/landmark/costume/New() //costume spawner, selects a random subclass and disappears
|
||||
|
||||
var/list/options = typesof(/obj/effect/landmark/costume)
|
||||
var/PICK= options[rand(1,options.len)]
|
||||
new PICK(src.loc)
|
||||
qdel(src)
|
||||
|
||||
//SUBCLASSES. Spawn a bunch of items and disappear likewise
|
||||
/obj/effect/landmark/costume/chicken/New()
|
||||
new /obj/item/clothing/suit/chickensuit(src.loc)
|
||||
new /obj/item/clothing/head/chicken(src.loc)
|
||||
new /obj/item/reagent_containers/food/snacks/egg(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/gladiator/New()
|
||||
new /obj/item/clothing/under/gladiator(src.loc)
|
||||
new /obj/item/clothing/head/helmet/gladiator(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/madscientist/New()
|
||||
new /obj/item/clothing/under/gimmick/rank/captain/suit(src.loc)
|
||||
new /obj/item/clothing/head/flatcap(src.loc)
|
||||
new /obj/item/clothing/suit/storage/labcoat/mad(src.loc)
|
||||
new /obj/item/clothing/glasses/gglasses(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/elpresidente/New()
|
||||
new /obj/item/clothing/under/gimmick/rank/captain/suit(src.loc)
|
||||
new /obj/item/clothing/head/flatcap(src.loc)
|
||||
new /obj/item/clothing/mask/cigarette/cigar/havana(src.loc)
|
||||
new /obj/item/clothing/shoes/jackboots(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/nyangirl/New()
|
||||
new /obj/item/clothing/under/schoolgirl(src.loc)
|
||||
new /obj/item/clothing/head/kitty(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/maid/New()
|
||||
new /obj/item/clothing/under/blackskirt(src.loc)
|
||||
var/CHOICE = pick( /obj/item/clothing/head/beret , /obj/item/clothing/head/rabbitears )
|
||||
new CHOICE(src.loc)
|
||||
new /obj/item/clothing/glasses/sunglasses/blindfold(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/butler/New()
|
||||
new /obj/item/clothing/suit/wcoat(src.loc)
|
||||
new /obj/item/clothing/under/suit_jacket(src.loc)
|
||||
new /obj/item/clothing/head/that(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/scratch/New()
|
||||
new /obj/item/clothing/gloves/color/white(src.loc)
|
||||
new /obj/item/clothing/shoes/white(src.loc)
|
||||
new /obj/item/clothing/under/scratch(src.loc)
|
||||
if(prob(30))
|
||||
new /obj/item/clothing/head/cueball(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/highlander/New()
|
||||
new /obj/item/clothing/under/kilt(src.loc)
|
||||
new /obj/item/clothing/head/beret(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/prig/New()
|
||||
new /obj/item/clothing/suit/wcoat(src.loc)
|
||||
new /obj/item/clothing/glasses/monocle(src.loc)
|
||||
var/CHOICE= pick( /obj/item/clothing/head/bowlerhat, /obj/item/clothing/head/that)
|
||||
new CHOICE(src.loc)
|
||||
new /obj/item/clothing/shoes/black(src.loc)
|
||||
new /obj/item/cane(src.loc)
|
||||
new /obj/item/clothing/under/sl_suit(src.loc)
|
||||
new /obj/item/clothing/mask/fakemoustache(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/plaguedoctor/New()
|
||||
new /obj/item/clothing/suit/bio_suit/plaguedoctorsuit(src.loc)
|
||||
new /obj/item/clothing/head/plaguedoctorhat(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/nightowl/New()
|
||||
new /obj/item/clothing/under/owl(src.loc)
|
||||
new /obj/item/clothing/mask/gas/owl_mask(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/waiter/New()
|
||||
new /obj/item/clothing/under/waiter(src.loc)
|
||||
var/CHOICE= pick( /obj/item/clothing/head/kitty, /obj/item/clothing/head/rabbitears)
|
||||
new CHOICE(src.loc)
|
||||
new /obj/item/clothing/suit/apron(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/pirate/New()
|
||||
new /obj/item/clothing/under/pirate(src.loc)
|
||||
new /obj/item/clothing/suit/pirate_black(src.loc)
|
||||
var/CHOICE = pick( /obj/item/clothing/head/pirate , /obj/item/clothing/head/bandana )
|
||||
new CHOICE(src.loc)
|
||||
new /obj/item/clothing/glasses/eyepatch(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/commie/New()
|
||||
new /obj/item/clothing/under/soviet(src.loc)
|
||||
new /obj/item/clothing/head/ushanka(src.loc)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/effect/landmark/costume/imperium_monk/New()
|
||||
new /obj/item/clothing/suit/imperium_monk(src.loc)
|
||||
if(prob(25))
|
||||
new /obj/item/clothing/mask/gas/cyborg(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/holiday_priest/New()
|
||||
new /obj/item/clothing/suit/holidaypriest(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/marisawizard/fake/New()
|
||||
new /obj/item/clothing/head/wizard/marisa/fake(src.loc)
|
||||
new/obj/item/clothing/suit/wizrobe/marisa/fake(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/cutewitch/New()
|
||||
new /obj/item/clothing/under/sundress(src.loc)
|
||||
new /obj/item/clothing/head/witchwig(src.loc)
|
||||
new /obj/item/twohanded/staff/broom(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/fakewizard/New()
|
||||
new /obj/item/clothing/suit/wizrobe/fake(src.loc)
|
||||
new /obj/item/clothing/head/wizard/fake(src.loc)
|
||||
new /obj/item/twohanded/staff/(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/sexyclown/New()
|
||||
new /obj/item/clothing/mask/gas/clown_hat/sexy(loc)
|
||||
new /obj/item/clothing/under/rank/clown/sexy(loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/costume/sexymime/New()
|
||||
new /obj/item/clothing/mask/gas/sexymime(src.loc)
|
||||
new /obj/item/clothing/under/sexymime(src.loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/landmark/ruin
|
||||
var/datum/map_template/ruin/ruin_template
|
||||
|
||||
/obj/effect/landmark/ruin/New(loc, my_ruin_template)
|
||||
name = "ruin_[GLOB.ruin_landmarks.len + 1]"
|
||||
..(loc)
|
||||
ruin_template = my_ruin_template
|
||||
GLOB.ruin_landmarks |= src
|
||||
|
||||
/obj/effect/landmark/ruin/Destroy()
|
||||
GLOB.ruin_landmarks -= src
|
||||
ruin_template = null
|
||||
. = ..()
|
||||
|
||||
// Damage tiles
|
||||
/obj/effect/landmark/damageturf
|
||||
icon_state = "damaged"
|
||||
|
||||
/obj/effect/landmark/damageturf/New()
|
||||
..()
|
||||
var/turf/simulated/T = get_turf(src)
|
||||
if(istype(T))
|
||||
T.break_tile()
|
||||
|
||||
/obj/effect/landmark/burnturf
|
||||
icon_state = "burned"
|
||||
|
||||
/obj/effect/landmark/burnturf/New()
|
||||
..()
|
||||
var/turf/simulated/T = get_turf(src)
|
||||
T.burn_tile()
|
||||
|
||||
|
||||
/obj/effect/landmark/battle_mob_point
|
||||
name = "Nanomob Battle Avatar Spawn Point"
|
||||
|
||||
/obj/effect/landmark/free_golem_spawn
|
||||
name = "Free Golem Spawn Point"
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
/obj/effect/manifest
|
||||
name = "manifest"
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "x"
|
||||
|
||||
/obj/effect/manifest/New()
|
||||
|
||||
src.invisibility = 101
|
||||
return
|
||||
|
||||
/obj/effect/manifest/proc/manifest()
|
||||
var/dat = "<B>Crew Manifest</B>:<BR>"
|
||||
for(var/mob/living/carbon/human/M in GLOB.mob_list)
|
||||
dat += text(" <B>[]</B> - []<BR>", M.name, M.get_assignment())
|
||||
var/obj/item/paper/P = new /obj/item/paper( src.loc )
|
||||
P.info = dat
|
||||
P.name = "paper- 'Crew Manifest'"
|
||||
//SN src = null
|
||||
qdel(src)
|
||||
return
|
||||
/obj/effect/manifest
|
||||
name = "manifest"
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "x"
|
||||
|
||||
/obj/effect/manifest/New()
|
||||
|
||||
src.invisibility = 101
|
||||
return
|
||||
|
||||
/obj/effect/manifest/proc/manifest()
|
||||
var/dat = "<B>Crew Manifest</B>:<BR>"
|
||||
for(var/mob/living/carbon/human/M in GLOB.mob_list)
|
||||
dat += text(" <B>[]</B> - []<BR>", M.name, M.get_assignment())
|
||||
var/obj/item/paper/P = new /obj/item/paper( src.loc )
|
||||
P.info = dat
|
||||
P.name = "paper- 'Crew Manifest'"
|
||||
//SN src = null
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
@@ -87,4 +87,4 @@
|
||||
/obj/effect/mapping_helpers/no_lava/New()
|
||||
var/turf/T = get_turf(src)
|
||||
T.flags |= NO_LAVA_GEN
|
||||
. = ..()
|
||||
. = ..()
|
||||
|
||||
+185
-185
@@ -1,185 +1,185 @@
|
||||
/obj/effect/mine
|
||||
name = "dummy mine"
|
||||
desc = "I Better stay away from that thing."
|
||||
density = 0
|
||||
anchored = 1
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "uglyminearmed"
|
||||
var/triggered = 0
|
||||
var/faction = "syndicate"
|
||||
|
||||
/obj/effect/mine/proc/mineEffect(mob/living/victim)
|
||||
to_chat(victim, "<span class='danger'>*click*</span>")
|
||||
|
||||
/obj/effect/mine/Crossed(AM as mob|obj, oldloc)
|
||||
if(!isliving(AM))
|
||||
return
|
||||
var/mob/living/M = AM
|
||||
if(faction && (faction in M.faction))
|
||||
return
|
||||
if(M.flying)
|
||||
return
|
||||
triggermine(M)
|
||||
|
||||
/obj/effect/mine/proc/triggermine(mob/living/victim)
|
||||
if(triggered)
|
||||
return
|
||||
visible_message("<span class='danger'>[victim] sets off [bicon(src)] [src]!</span>")
|
||||
do_sparks(3, 1, src)
|
||||
mineEffect(victim)
|
||||
triggered = 1
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/mine/ex_act(severity)
|
||||
// Necessary because, as effects, they have infinite health, and wouldn't be destroyed otherwise.
|
||||
// Also, they're pressure-sensitive mines, it makes sense that an explosion (wave of pressure) triggers/destroys them.
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/mine/explosive
|
||||
name = "explosive mine"
|
||||
var/range_devastation = 0
|
||||
var/range_heavy = 1
|
||||
var/range_light = 2
|
||||
var/range_flash = 3
|
||||
|
||||
/obj/effect/mine/explosive/mineEffect(mob/living/victim)
|
||||
explosion(loc, range_devastation, range_heavy, range_light, range_flash)
|
||||
|
||||
/obj/effect/mine/stun
|
||||
name = "stun mine"
|
||||
var/stun_time = 8
|
||||
|
||||
/obj/effect/mine/stun/mineEffect(mob/living/victim)
|
||||
if(isliving(victim))
|
||||
victim.Weaken(stun_time)
|
||||
|
||||
/obj/effect/mine/depot
|
||||
name = "sentry mine"
|
||||
|
||||
/obj/effect/mine/depot/mineEffect(mob/living/victim)
|
||||
var/area/syndicate_depot/core/depotarea = areaMaster
|
||||
if(istype(depotarea))
|
||||
if(depotarea.mine_triggered(victim))
|
||||
explosion(loc, 1, 0, 0, 1) // devastate the tile you are on, but leave everything else untouched
|
||||
|
||||
/obj/effect/mine/dnascramble
|
||||
name = "Radiation Mine"
|
||||
var/radiation_amount
|
||||
|
||||
/obj/effect/mine/dnascramble/mineEffect(mob/living/victim)
|
||||
victim.apply_effect(radiation_amount, IRRADIATE, 0)
|
||||
if(ishuman(victim))
|
||||
var/mob/living/carbon/human/V = victim
|
||||
if(NO_DNA in V.dna.species.species_traits)
|
||||
return
|
||||
randmutb(victim)
|
||||
domutcheck(victim ,null)
|
||||
|
||||
/obj/effect/mine/gas
|
||||
name = "oxygen mine"
|
||||
var/gas_amount = 360
|
||||
var/gas_type = LINDA_SPAWN_OXYGEN
|
||||
|
||||
/obj/effect/mine/gas/mineEffect(mob/living/victim)
|
||||
atmos_spawn_air(gas_type, gas_amount)
|
||||
|
||||
/obj/effect/mine/gas/plasma
|
||||
name = "plasma mine"
|
||||
gas_type = LINDA_SPAWN_HEAT | LINDA_SPAWN_TOXINS
|
||||
|
||||
/obj/effect/mine/gas/n2o
|
||||
name = "\improper N2O mine"
|
||||
gas_type = LINDA_SPAWN_N2O
|
||||
|
||||
/obj/effect/mine/sound
|
||||
name = "honkblaster 1000"
|
||||
var/sound = 'sound/items/bikehorn.ogg'
|
||||
|
||||
/obj/effect/mine/sound/mineEffect(mob/living/victim)
|
||||
playsound(loc, sound, 100, 1)
|
||||
|
||||
/obj/effect/mine/sound/bwoink
|
||||
name = "bwoink mine"
|
||||
sound = 'sound/effects/adminhelp.ogg'
|
||||
|
||||
/obj/effect/mine/pickup
|
||||
name = "pickup"
|
||||
desc = "pick me up"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "electricity2"
|
||||
density = 0
|
||||
var/duration = 0
|
||||
|
||||
/obj/effect/mine/pickup/New()
|
||||
..()
|
||||
animate(src, pixel_y = 4, time = 20, loop = -1)
|
||||
|
||||
/obj/effect/mine/pickup/triggermine(mob/living/victim)
|
||||
if(triggered)
|
||||
return
|
||||
triggered = 1
|
||||
invisibility = 101
|
||||
mineEffect(victim)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/mine/pickup/bloodbath
|
||||
name = "Red Orb"
|
||||
desc = "You feel angry just looking at it."
|
||||
duration = 1200 //2min
|
||||
color = "red"
|
||||
|
||||
/obj/effect/mine/pickup/bloodbath/mineEffect(mob/living/carbon/victim)
|
||||
if(!istype(victim) || !victim.client)
|
||||
return
|
||||
to_chat(victim, "<span class='reallybig redtext'>RIP AND TEAR</span>")
|
||||
victim << 'sound/misc/e1m1.ogg'
|
||||
var/old_color = victim.client.color
|
||||
var/red_splash = list(1,0,0,0.8,0.2,0, 0.8,0,0.2,0.1,0,0)
|
||||
var/pure_red = list(0,0,0,0,0,0,0,0,0,1,0,0)
|
||||
|
||||
spawn(0)
|
||||
new /obj/effect/hallucination/delusion(victim.loc, victim, force_kind = "demon", duration = duration, skip_nearby = 0)
|
||||
|
||||
var/obj/item/twohanded/required/chainsaw/doomslayer/chainsaw = new(victim.loc)
|
||||
chainsaw.flags |= NODROP | DROPDEL
|
||||
victim.drop_l_hand()
|
||||
victim.drop_r_hand()
|
||||
victim.put_in_hands(chainsaw)
|
||||
chainsaw.attack_self(victim)
|
||||
chainsaw.wield(victim)
|
||||
victim.reagents.add_reagent("adminordrazine", 25)
|
||||
|
||||
victim.client.color = pure_red
|
||||
animate(victim.client,color = red_splash, time = 10, easing = SINE_EASING|EASE_OUT)
|
||||
spawn(10)
|
||||
animate(victim.client,color = old_color, time = duration)//, easing = SINE_EASING|EASE_OUT)
|
||||
spawn(duration)
|
||||
to_chat(victim, "<span class='notice'>Your bloodlust seeps back into the bog of your subconscious and you regain self control.</span>")
|
||||
qdel(chainsaw)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/mine/pickup/healing
|
||||
name = "Blue Orb"
|
||||
desc = "You feel better just looking at it."
|
||||
color = "blue"
|
||||
|
||||
/obj/effect/mine/pickup/healing/mineEffect(mob/living/carbon/victim)
|
||||
if(!victim.client || !istype(victim))
|
||||
return
|
||||
to_chat(victim, "<span class='notice'>You feel great!</span>")
|
||||
victim.revive()
|
||||
|
||||
/obj/effect/mine/pickup/speed
|
||||
name = "Yellow Orb"
|
||||
desc = "You feel faster just looking at it."
|
||||
color = "yellow"
|
||||
duration = 300
|
||||
|
||||
/obj/effect/mine/pickup/speed/mineEffect(mob/living/carbon/victim)
|
||||
if(!victim.client || !istype(victim))
|
||||
return
|
||||
to_chat(victim, "<span class='notice'>You feel fast!</span>")
|
||||
victim.status_flags |= GOTTAGOFAST
|
||||
spawn(duration)
|
||||
victim.status_flags &= ~GOTTAGOFAST
|
||||
to_chat(victim, "<span class='notice'>You slow down.</span>")
|
||||
/obj/effect/mine
|
||||
name = "dummy mine"
|
||||
desc = "I Better stay away from that thing."
|
||||
density = 0
|
||||
anchored = 1
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "uglyminearmed"
|
||||
var/triggered = 0
|
||||
var/faction = "syndicate"
|
||||
|
||||
/obj/effect/mine/proc/mineEffect(mob/living/victim)
|
||||
to_chat(victim, "<span class='danger'>*click*</span>")
|
||||
|
||||
/obj/effect/mine/Crossed(AM as mob|obj, oldloc)
|
||||
if(!isliving(AM))
|
||||
return
|
||||
var/mob/living/M = AM
|
||||
if(faction && (faction in M.faction))
|
||||
return
|
||||
if(M.flying)
|
||||
return
|
||||
triggermine(M)
|
||||
|
||||
/obj/effect/mine/proc/triggermine(mob/living/victim)
|
||||
if(triggered)
|
||||
return
|
||||
visible_message("<span class='danger'>[victim] sets off [bicon(src)] [src]!</span>")
|
||||
do_sparks(3, 1, src)
|
||||
mineEffect(victim)
|
||||
triggered = 1
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/mine/ex_act(severity)
|
||||
// Necessary because, as effects, they have infinite health, and wouldn't be destroyed otherwise.
|
||||
// Also, they're pressure-sensitive mines, it makes sense that an explosion (wave of pressure) triggers/destroys them.
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/mine/explosive
|
||||
name = "explosive mine"
|
||||
var/range_devastation = 0
|
||||
var/range_heavy = 1
|
||||
var/range_light = 2
|
||||
var/range_flash = 3
|
||||
|
||||
/obj/effect/mine/explosive/mineEffect(mob/living/victim)
|
||||
explosion(loc, range_devastation, range_heavy, range_light, range_flash)
|
||||
|
||||
/obj/effect/mine/stun
|
||||
name = "stun mine"
|
||||
var/stun_time = 8
|
||||
|
||||
/obj/effect/mine/stun/mineEffect(mob/living/victim)
|
||||
if(isliving(victim))
|
||||
victim.Weaken(stun_time)
|
||||
|
||||
/obj/effect/mine/depot
|
||||
name = "sentry mine"
|
||||
|
||||
/obj/effect/mine/depot/mineEffect(mob/living/victim)
|
||||
var/area/syndicate_depot/core/depotarea = areaMaster
|
||||
if(istype(depotarea))
|
||||
if(depotarea.mine_triggered(victim))
|
||||
explosion(loc, 1, 0, 0, 1) // devastate the tile you are on, but leave everything else untouched
|
||||
|
||||
/obj/effect/mine/dnascramble
|
||||
name = "Radiation Mine"
|
||||
var/radiation_amount
|
||||
|
||||
/obj/effect/mine/dnascramble/mineEffect(mob/living/victim)
|
||||
victim.apply_effect(radiation_amount, IRRADIATE, 0)
|
||||
if(ishuman(victim))
|
||||
var/mob/living/carbon/human/V = victim
|
||||
if(NO_DNA in V.dna.species.species_traits)
|
||||
return
|
||||
randmutb(victim)
|
||||
domutcheck(victim ,null)
|
||||
|
||||
/obj/effect/mine/gas
|
||||
name = "oxygen mine"
|
||||
var/gas_amount = 360
|
||||
var/gas_type = LINDA_SPAWN_OXYGEN
|
||||
|
||||
/obj/effect/mine/gas/mineEffect(mob/living/victim)
|
||||
atmos_spawn_air(gas_type, gas_amount)
|
||||
|
||||
/obj/effect/mine/gas/plasma
|
||||
name = "plasma mine"
|
||||
gas_type = LINDA_SPAWN_HEAT | LINDA_SPAWN_TOXINS
|
||||
|
||||
/obj/effect/mine/gas/n2o
|
||||
name = "\improper N2O mine"
|
||||
gas_type = LINDA_SPAWN_N2O
|
||||
|
||||
/obj/effect/mine/sound
|
||||
name = "honkblaster 1000"
|
||||
var/sound = 'sound/items/bikehorn.ogg'
|
||||
|
||||
/obj/effect/mine/sound/mineEffect(mob/living/victim)
|
||||
playsound(loc, sound, 100, 1)
|
||||
|
||||
/obj/effect/mine/sound/bwoink
|
||||
name = "bwoink mine"
|
||||
sound = 'sound/effects/adminhelp.ogg'
|
||||
|
||||
/obj/effect/mine/pickup
|
||||
name = "pickup"
|
||||
desc = "pick me up"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "electricity2"
|
||||
density = 0
|
||||
var/duration = 0
|
||||
|
||||
/obj/effect/mine/pickup/New()
|
||||
..()
|
||||
animate(src, pixel_y = 4, time = 20, loop = -1)
|
||||
|
||||
/obj/effect/mine/pickup/triggermine(mob/living/victim)
|
||||
if(triggered)
|
||||
return
|
||||
triggered = 1
|
||||
invisibility = 101
|
||||
mineEffect(victim)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/mine/pickup/bloodbath
|
||||
name = "Red Orb"
|
||||
desc = "You feel angry just looking at it."
|
||||
duration = 1200 //2min
|
||||
color = "red"
|
||||
|
||||
/obj/effect/mine/pickup/bloodbath/mineEffect(mob/living/carbon/victim)
|
||||
if(!istype(victim) || !victim.client)
|
||||
return
|
||||
to_chat(victim, "<span class='reallybig redtext'>RIP AND TEAR</span>")
|
||||
victim << 'sound/misc/e1m1.ogg'
|
||||
var/old_color = victim.client.color
|
||||
var/red_splash = list(1,0,0,0.8,0.2,0, 0.8,0,0.2,0.1,0,0)
|
||||
var/pure_red = list(0,0,0,0,0,0,0,0,0,1,0,0)
|
||||
|
||||
spawn(0)
|
||||
new /obj/effect/hallucination/delusion(victim.loc, victim, force_kind = "demon", duration = duration, skip_nearby = 0)
|
||||
|
||||
var/obj/item/twohanded/required/chainsaw/doomslayer/chainsaw = new(victim.loc)
|
||||
chainsaw.flags |= NODROP | DROPDEL
|
||||
victim.drop_l_hand()
|
||||
victim.drop_r_hand()
|
||||
victim.put_in_hands(chainsaw)
|
||||
chainsaw.attack_self(victim)
|
||||
chainsaw.wield(victim)
|
||||
victim.reagents.add_reagent("adminordrazine", 25)
|
||||
|
||||
victim.client.color = pure_red
|
||||
animate(victim.client,color = red_splash, time = 10, easing = SINE_EASING|EASE_OUT)
|
||||
spawn(10)
|
||||
animate(victim.client,color = old_color, time = duration)//, easing = SINE_EASING|EASE_OUT)
|
||||
spawn(duration)
|
||||
to_chat(victim, "<span class='notice'>Your bloodlust seeps back into the bog of your subconscious and you regain self control.</span>")
|
||||
qdel(chainsaw)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/mine/pickup/healing
|
||||
name = "Blue Orb"
|
||||
desc = "You feel better just looking at it."
|
||||
color = "blue"
|
||||
|
||||
/obj/effect/mine/pickup/healing/mineEffect(mob/living/carbon/victim)
|
||||
if(!victim.client || !istype(victim))
|
||||
return
|
||||
to_chat(victim, "<span class='notice'>You feel great!</span>")
|
||||
victim.revive()
|
||||
|
||||
/obj/effect/mine/pickup/speed
|
||||
name = "Yellow Orb"
|
||||
desc = "You feel faster just looking at it."
|
||||
color = "yellow"
|
||||
duration = 300
|
||||
|
||||
/obj/effect/mine/pickup/speed/mineEffect(mob/living/carbon/victim)
|
||||
if(!victim.client || !istype(victim))
|
||||
return
|
||||
to_chat(victim, "<span class='notice'>You feel fast!</span>")
|
||||
victim.status_flags |= GOTTAGOFAST
|
||||
spawn(duration)
|
||||
victim.status_flags &= ~GOTTAGOFAST
|
||||
to_chat(victim, "<span class='notice'>You slow down.</span>")
|
||||
|
||||
+123
-123
@@ -1,123 +1,123 @@
|
||||
//MISC EFFECTS
|
||||
|
||||
//This file is for effects that are less than 20 lines and don't fit very well in any other category.
|
||||
|
||||
/*CURRENT CONTENTS
|
||||
Strange Present
|
||||
Mark
|
||||
Beam
|
||||
Laser
|
||||
Begin
|
||||
Stop
|
||||
Projection
|
||||
Shut_controller
|
||||
Showcase
|
||||
Spawner
|
||||
List_container
|
||||
*/
|
||||
|
||||
//The effect when you wrap a dead body in gift wrap
|
||||
/obj/effect/spresent
|
||||
name = "strange present"
|
||||
desc = "It's a ... present?"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "strangepresent"
|
||||
density = 1
|
||||
anchored = 0
|
||||
|
||||
/obj/effect/mark
|
||||
var/mark = ""
|
||||
icon = 'icons/misc/mark.dmi'
|
||||
icon_state = "blank"
|
||||
anchored = 1
|
||||
layer = 99
|
||||
plane = HUD_PLANE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
/obj/effect/beam
|
||||
name = "beam"
|
||||
var/def_zone
|
||||
pass_flags = PASSTABLE
|
||||
|
||||
/obj/effect/laser
|
||||
name = "laser"
|
||||
desc = "IT BURNS!!!"
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
var/damage = 0.0
|
||||
var/range = 10.0
|
||||
|
||||
/obj/effect/begin
|
||||
name = "begin"
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "begin"
|
||||
anchored = 1.0
|
||||
|
||||
/obj/effect/projection
|
||||
name = "Projection"
|
||||
desc = "This looks like a projection of something."
|
||||
anchored = 1.0
|
||||
|
||||
|
||||
/obj/effect/shut_controller
|
||||
name = "shut controller"
|
||||
var/moving = null
|
||||
var/list/parts = list( )
|
||||
|
||||
/obj/structure/showcase
|
||||
name = "Showcase"
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "showcase_1"
|
||||
desc = "A stand with the empty body of a cyborg bolted to it."
|
||||
density = 1
|
||||
anchored = 1
|
||||
|
||||
/obj/effect/spawner
|
||||
name = "object spawner"
|
||||
|
||||
/obj/effect/list_container
|
||||
name = "list container"
|
||||
|
||||
/obj/effect/list_container/mobl
|
||||
name = "mobl"
|
||||
var/master = null
|
||||
|
||||
var/list/container = list( )
|
||||
|
||||
|
||||
/obj/structure/showcase/horrific_experiment
|
||||
name = "horrific experiment"
|
||||
desc = "Some sort of pod filled with blood and vicerea. You swear you can see it moving..."
|
||||
icon = 'icons/obj/cloning.dmi'
|
||||
icon_state = "pod_g"
|
||||
|
||||
|
||||
//Makes a tile fully lit no matter what
|
||||
/obj/effect/fullbright
|
||||
icon = 'icons/effects/alphacolors.dmi'
|
||||
icon_state = "white"
|
||||
plane = LIGHTING_PLANE
|
||||
layer = LIGHTING_LAYER
|
||||
blend_mode = BLEND_ADD
|
||||
|
||||
|
||||
/obj/effect/dummy/lighting_obj
|
||||
name = "lighting fx obj"
|
||||
desc = "Tell a coder if you're seeing this."
|
||||
icon_state = "nothing"
|
||||
light_color = "#FFFFFF"
|
||||
light_range = MINIMUM_USEFUL_LIGHT_RANGE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
/obj/effect/dummy/lighting_obj/Initialize(mapload, _color, _range, _power, _duration)
|
||||
. = ..()
|
||||
set_light(_range ? _range : light_range, _power ? _power : light_power, _color ? _color : light_color)
|
||||
if(_duration)
|
||||
QDEL_IN(src, _duration)
|
||||
|
||||
/obj/effect/dummy/lighting_obj/moblight
|
||||
name = "mob lighting fx"
|
||||
|
||||
/obj/effect/dummy/lighting_obj/moblight/Initialize(mapload, _color, _range, _power, _duration)
|
||||
. = ..()
|
||||
if(!ismob(loc))
|
||||
return INITIALIZE_HINT_QDEL
|
||||
//MISC EFFECTS
|
||||
|
||||
//This file is for effects that are less than 20 lines and don't fit very well in any other category.
|
||||
|
||||
/*CURRENT CONTENTS
|
||||
Strange Present
|
||||
Mark
|
||||
Beam
|
||||
Laser
|
||||
Begin
|
||||
Stop
|
||||
Projection
|
||||
Shut_controller
|
||||
Showcase
|
||||
Spawner
|
||||
List_container
|
||||
*/
|
||||
|
||||
//The effect when you wrap a dead body in gift wrap
|
||||
/obj/effect/spresent
|
||||
name = "strange present"
|
||||
desc = "It's a ... present?"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "strangepresent"
|
||||
density = 1
|
||||
anchored = 0
|
||||
|
||||
/obj/effect/mark
|
||||
var/mark = ""
|
||||
icon = 'icons/misc/mark.dmi'
|
||||
icon_state = "blank"
|
||||
anchored = 1
|
||||
layer = 99
|
||||
plane = HUD_PLANE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
/obj/effect/beam
|
||||
name = "beam"
|
||||
var/def_zone
|
||||
pass_flags = PASSTABLE
|
||||
|
||||
/obj/effect/laser
|
||||
name = "laser"
|
||||
desc = "IT BURNS!!!"
|
||||
icon = 'icons/obj/projectiles.dmi'
|
||||
var/damage = 0.0
|
||||
var/range = 10.0
|
||||
|
||||
/obj/effect/begin
|
||||
name = "begin"
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "begin"
|
||||
anchored = 1.0
|
||||
|
||||
/obj/effect/projection
|
||||
name = "Projection"
|
||||
desc = "This looks like a projection of something."
|
||||
anchored = 1.0
|
||||
|
||||
|
||||
/obj/effect/shut_controller
|
||||
name = "shut controller"
|
||||
var/moving = null
|
||||
var/list/parts = list( )
|
||||
|
||||
/obj/structure/showcase
|
||||
name = "Showcase"
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "showcase_1"
|
||||
desc = "A stand with the empty body of a cyborg bolted to it."
|
||||
density = 1
|
||||
anchored = 1
|
||||
|
||||
/obj/effect/spawner
|
||||
name = "object spawner"
|
||||
|
||||
/obj/effect/list_container
|
||||
name = "list container"
|
||||
|
||||
/obj/effect/list_container/mobl
|
||||
name = "mobl"
|
||||
var/master = null
|
||||
|
||||
var/list/container = list( )
|
||||
|
||||
|
||||
/obj/structure/showcase/horrific_experiment
|
||||
name = "horrific experiment"
|
||||
desc = "Some sort of pod filled with blood and vicerea. You swear you can see it moving..."
|
||||
icon = 'icons/obj/cloning.dmi'
|
||||
icon_state = "pod_g"
|
||||
|
||||
|
||||
//Makes a tile fully lit no matter what
|
||||
/obj/effect/fullbright
|
||||
icon = 'icons/effects/alphacolors.dmi'
|
||||
icon_state = "white"
|
||||
plane = LIGHTING_PLANE
|
||||
layer = LIGHTING_LAYER
|
||||
blend_mode = BLEND_ADD
|
||||
|
||||
|
||||
/obj/effect/dummy/lighting_obj
|
||||
name = "lighting fx obj"
|
||||
desc = "Tell a coder if you're seeing this."
|
||||
icon_state = "nothing"
|
||||
light_color = "#FFFFFF"
|
||||
light_range = MINIMUM_USEFUL_LIGHT_RANGE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
/obj/effect/dummy/lighting_obj/Initialize(mapload, _color, _range, _power, _duration)
|
||||
. = ..()
|
||||
set_light(_range ? _range : light_range, _power ? _power : light_power, _color ? _color : light_color)
|
||||
if(_duration)
|
||||
QDEL_IN(src, _duration)
|
||||
|
||||
/obj/effect/dummy/lighting_obj/moblight
|
||||
name = "mob lighting fx"
|
||||
|
||||
/obj/effect/dummy/lighting_obj/moblight/Initialize(mapload, _color, _range, _power, _duration)
|
||||
. = ..()
|
||||
if(!ismob(loc))
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
@@ -1,65 +1,65 @@
|
||||
/obj/effect/overlay
|
||||
name = "overlay"
|
||||
var/i_attached//Added for possible image attachments to objects. For hallucinations and the like.
|
||||
|
||||
/obj/effect/overlay/singularity_act()
|
||||
return
|
||||
|
||||
/obj/effect/overlay/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/overlay/beam//Not actually a projectile, just an effect.
|
||||
name = "beam"
|
||||
icon = 'icons/effects/beam.dmi'
|
||||
icon_state = "b_beam"
|
||||
var/tmp/atom/BeamSource
|
||||
|
||||
/obj/effect/overlay/beam/New()
|
||||
..()
|
||||
QDEL_IN(src, 10)
|
||||
|
||||
/obj/effect/overlay/palmtree_r
|
||||
name = "Palm tree"
|
||||
icon = 'icons/misc/beach2.dmi'
|
||||
icon_state = "palm1"
|
||||
density = 1
|
||||
layer = 5
|
||||
anchored = 1
|
||||
|
||||
/obj/effect/overlay/palmtree_l
|
||||
name = "Palm tree"
|
||||
icon = 'icons/misc/beach2.dmi'
|
||||
icon_state = "palm2"
|
||||
density = 1
|
||||
layer = 5
|
||||
anchored = 1
|
||||
|
||||
/obj/effect/overlay/coconut
|
||||
name = "Coconuts"
|
||||
icon = 'icons/misc/beach.dmi'
|
||||
icon_state = "coconuts"
|
||||
|
||||
/obj/effect/overlay/sparkles
|
||||
name = "sparkles"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "shieldsparkles"
|
||||
|
||||
/obj/effect/overlay/adminoverlay
|
||||
name = "adminoverlay"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "admin"
|
||||
layer = 4.1
|
||||
|
||||
/obj/effect/overlay/wall_rot
|
||||
name = "Wallrot"
|
||||
desc = "Ick..."
|
||||
icon = 'icons/effects/wallrot.dmi'
|
||||
anchored = 1
|
||||
density = 1
|
||||
layer = 5
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
/obj/effect/overlay/wall_rot/New()
|
||||
..()
|
||||
pixel_x += rand(-10, 10)
|
||||
pixel_y += rand(-10, 10)
|
||||
/obj/effect/overlay
|
||||
name = "overlay"
|
||||
var/i_attached//Added for possible image attachments to objects. For hallucinations and the like.
|
||||
|
||||
/obj/effect/overlay/singularity_act()
|
||||
return
|
||||
|
||||
/obj/effect/overlay/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/overlay/beam//Not actually a projectile, just an effect.
|
||||
name = "beam"
|
||||
icon = 'icons/effects/beam.dmi'
|
||||
icon_state = "b_beam"
|
||||
var/tmp/atom/BeamSource
|
||||
|
||||
/obj/effect/overlay/beam/New()
|
||||
..()
|
||||
QDEL_IN(src, 10)
|
||||
|
||||
/obj/effect/overlay/palmtree_r
|
||||
name = "Palm tree"
|
||||
icon = 'icons/misc/beach2.dmi'
|
||||
icon_state = "palm1"
|
||||
density = 1
|
||||
layer = 5
|
||||
anchored = 1
|
||||
|
||||
/obj/effect/overlay/palmtree_l
|
||||
name = "Palm tree"
|
||||
icon = 'icons/misc/beach2.dmi'
|
||||
icon_state = "palm2"
|
||||
density = 1
|
||||
layer = 5
|
||||
anchored = 1
|
||||
|
||||
/obj/effect/overlay/coconut
|
||||
name = "Coconuts"
|
||||
icon = 'icons/misc/beach.dmi'
|
||||
icon_state = "coconuts"
|
||||
|
||||
/obj/effect/overlay/sparkles
|
||||
name = "sparkles"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "shieldsparkles"
|
||||
|
||||
/obj/effect/overlay/adminoverlay
|
||||
name = "adminoverlay"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "admin"
|
||||
layer = 4.1
|
||||
|
||||
/obj/effect/overlay/wall_rot
|
||||
name = "Wallrot"
|
||||
desc = "Ick..."
|
||||
icon = 'icons/effects/wallrot.dmi'
|
||||
anchored = 1
|
||||
density = 1
|
||||
layer = 5
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
/obj/effect/overlay/wall_rot/New()
|
||||
..()
|
||||
pixel_x += rand(-10, 10)
|
||||
pixel_y += rand(-10, 10)
|
||||
|
||||
@@ -1,128 +1,128 @@
|
||||
/obj/effect/portal
|
||||
name = "portal"
|
||||
desc = "Looks unstable. Best to test it with the clown."
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "portal"
|
||||
anchored = TRUE
|
||||
|
||||
var/obj/item/target = null
|
||||
var/creator = null
|
||||
|
||||
var/failchance = 5
|
||||
var/fail_icon = "portal1"
|
||||
|
||||
var/precision = TRUE // how close to the portal you will teleport. FALSE = on the portal, TRUE = adjacent
|
||||
var/can_multitool_to_remove = FALSE
|
||||
var/ignore_tele_proof_area_setting = FALSE
|
||||
|
||||
/obj/effect/portal/New(loc, turf/target, creator = null, lifespan = 300)
|
||||
..()
|
||||
|
||||
GLOB.portals += src
|
||||
|
||||
src.target = target
|
||||
src.creator = creator
|
||||
|
||||
if(lifespan > 0)
|
||||
spawn(lifespan)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/portal/Destroy()
|
||||
GLOB.portals -= src
|
||||
|
||||
if(isobj(creator))
|
||||
var/obj/O = creator
|
||||
O.portal_destroyed(src)
|
||||
|
||||
creator = null
|
||||
target = null
|
||||
return ..()
|
||||
|
||||
/obj/effect/portal/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/portal/singularity_act()
|
||||
return
|
||||
|
||||
/obj/effect/portal/Crossed(atom/movable/AM, oldloc)
|
||||
if(isobserver(AM))
|
||||
return ..()
|
||||
|
||||
if(target && (get_turf(oldloc) == get_turf(target)))
|
||||
return ..()
|
||||
|
||||
if(!teleport(AM))
|
||||
return ..()
|
||||
|
||||
/obj/effect/portal/attack_tk(mob/user)
|
||||
return
|
||||
|
||||
/obj/effect/portal/attack_hand(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(get_turf(user) == get_turf(src))
|
||||
teleport(user)
|
||||
if(Adjacent(user))
|
||||
user.forceMove(get_turf(src))
|
||||
|
||||
/obj/effect/portal/attack_ghost(mob/dead/observer/O)
|
||||
if(target)
|
||||
O.forceMove(target)
|
||||
|
||||
/obj/effect/portal/multitool_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
|
||||
return
|
||||
if(can_multitool_to_remove)
|
||||
qdel(src)
|
||||
else
|
||||
user.forceMove(get_turf(src))
|
||||
|
||||
/obj/effect/portal/proc/can_teleport(atom/movable/M)
|
||||
. = TRUE
|
||||
|
||||
if(!istype(M))
|
||||
. = FALSE
|
||||
|
||||
if(!M.simulated || iseffect(M))
|
||||
. = FALSE
|
||||
|
||||
if(M.anchored && ismecha(M))
|
||||
. = FALSE
|
||||
|
||||
/obj/effect/portal/proc/teleport(atom/movable/M)
|
||||
if(!can_teleport(M))
|
||||
return FALSE
|
||||
|
||||
if(!target)
|
||||
qdel(src)
|
||||
return FALSE
|
||||
|
||||
if(ismegafauna(M))
|
||||
message_admins("[M] has used a portal at [ADMIN_VERBOSEJMP(src)] made by [key_name_admin(usr)].")
|
||||
|
||||
if(prob(failchance))
|
||||
icon_state = fail_icon
|
||||
if(!do_teleport(M, locate(rand(5, world.maxx - 5), rand(5, world.maxy -5), 3), 0, bypass_area_flag = ignore_tele_proof_area_setting)) // Try to send them to deep space.
|
||||
invalid_teleport()
|
||||
return FALSE
|
||||
else
|
||||
if(!do_teleport(M, target, precision, bypass_area_flag = ignore_tele_proof_area_setting)) // Try to send them to a turf adjacent to target.
|
||||
invalid_teleport()
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/effect/portal/proc/invalid_teleport()
|
||||
visible_message("<span class='warning'>[src] flickers and fails due to bluespace interference!</span>")
|
||||
do_sparks(5, 0, loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/portal/redspace
|
||||
name = "redspace portal"
|
||||
desc = "A portal capable of bypassing bluespace interference."
|
||||
icon_state = "portal1"
|
||||
failchance = 0
|
||||
precision = 0
|
||||
ignore_tele_proof_area_setting = TRUE
|
||||
/obj/effect/portal
|
||||
name = "portal"
|
||||
desc = "Looks unstable. Best to test it with the clown."
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "portal"
|
||||
anchored = TRUE
|
||||
|
||||
var/obj/item/target = null
|
||||
var/creator = null
|
||||
|
||||
var/failchance = 5
|
||||
var/fail_icon = "portal1"
|
||||
|
||||
var/precision = TRUE // how close to the portal you will teleport. FALSE = on the portal, TRUE = adjacent
|
||||
var/can_multitool_to_remove = FALSE
|
||||
var/ignore_tele_proof_area_setting = FALSE
|
||||
|
||||
/obj/effect/portal/New(loc, turf/target, creator = null, lifespan = 300)
|
||||
..()
|
||||
|
||||
GLOB.portals += src
|
||||
|
||||
src.target = target
|
||||
src.creator = creator
|
||||
|
||||
if(lifespan > 0)
|
||||
spawn(lifespan)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/portal/Destroy()
|
||||
GLOB.portals -= src
|
||||
|
||||
if(isobj(creator))
|
||||
var/obj/O = creator
|
||||
O.portal_destroyed(src)
|
||||
|
||||
creator = null
|
||||
target = null
|
||||
return ..()
|
||||
|
||||
/obj/effect/portal/singularity_pull()
|
||||
return
|
||||
|
||||
/obj/effect/portal/singularity_act()
|
||||
return
|
||||
|
||||
/obj/effect/portal/Crossed(atom/movable/AM, oldloc)
|
||||
if(isobserver(AM))
|
||||
return ..()
|
||||
|
||||
if(target && (get_turf(oldloc) == get_turf(target)))
|
||||
return ..()
|
||||
|
||||
if(!teleport(AM))
|
||||
return ..()
|
||||
|
||||
/obj/effect/portal/attack_tk(mob/user)
|
||||
return
|
||||
|
||||
/obj/effect/portal/attack_hand(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(get_turf(user) == get_turf(src))
|
||||
teleport(user)
|
||||
if(Adjacent(user))
|
||||
user.forceMove(get_turf(src))
|
||||
|
||||
/obj/effect/portal/attack_ghost(mob/dead/observer/O)
|
||||
if(target)
|
||||
O.forceMove(target)
|
||||
|
||||
/obj/effect/portal/multitool_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
|
||||
return
|
||||
if(can_multitool_to_remove)
|
||||
qdel(src)
|
||||
else
|
||||
user.forceMove(get_turf(src))
|
||||
|
||||
/obj/effect/portal/proc/can_teleport(atom/movable/M)
|
||||
. = TRUE
|
||||
|
||||
if(!istype(M))
|
||||
. = FALSE
|
||||
|
||||
if(!M.simulated || iseffect(M))
|
||||
. = FALSE
|
||||
|
||||
if(M.anchored && ismecha(M))
|
||||
. = FALSE
|
||||
|
||||
/obj/effect/portal/proc/teleport(atom/movable/M)
|
||||
if(!can_teleport(M))
|
||||
return FALSE
|
||||
|
||||
if(!target)
|
||||
qdel(src)
|
||||
return FALSE
|
||||
|
||||
if(ismegafauna(M))
|
||||
message_admins("[M] has used a portal at [ADMIN_VERBOSEJMP(src)] made by [key_name_admin(usr)].")
|
||||
|
||||
if(prob(failchance))
|
||||
icon_state = fail_icon
|
||||
if(!do_teleport(M, locate(rand(5, world.maxx - 5), rand(5, world.maxy -5), 3), 0, bypass_area_flag = ignore_tele_proof_area_setting)) // Try to send them to deep space.
|
||||
invalid_teleport()
|
||||
return FALSE
|
||||
else
|
||||
if(!do_teleport(M, target, precision, bypass_area_flag = ignore_tele_proof_area_setting)) // Try to send them to a turf adjacent to target.
|
||||
invalid_teleport()
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/obj/effect/portal/proc/invalid_teleport()
|
||||
visible_message("<span class='warning'>[src] flickers and fails due to bluespace interference!</span>")
|
||||
do_sparks(5, 0, loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/portal/redspace
|
||||
name = "redspace portal"
|
||||
desc = "A portal capable of bypassing bluespace interference."
|
||||
icon_state = "portal1"
|
||||
failchance = 0
|
||||
precision = 0
|
||||
ignore_tele_proof_area_setting = TRUE
|
||||
|
||||
@@ -1,65 +1,65 @@
|
||||
/obj/effect/spawner/newbomb
|
||||
name = "bomb"
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "x"
|
||||
var/btype = 0 // 0=radio, 1=prox, 2=time
|
||||
var/btemp1 = 1500
|
||||
var/btemp2 = 1000 // tank temperatures
|
||||
|
||||
timer
|
||||
btype = 2
|
||||
|
||||
syndicate
|
||||
btemp1 = 150
|
||||
btemp2 = 20
|
||||
|
||||
proximity
|
||||
btype = 1
|
||||
|
||||
radio
|
||||
btype = 0
|
||||
|
||||
|
||||
/obj/effect/spawner/newbomb/New()
|
||||
..()
|
||||
|
||||
var/obj/item/transfer_valve/V = new(src.loc)
|
||||
var/obj/item/tank/plasma/PT = new(V)
|
||||
var/obj/item/tank/oxygen/OT = new(V)
|
||||
|
||||
V.tank_one = PT
|
||||
V.tank_two = OT
|
||||
|
||||
PT.master = V
|
||||
OT.master = V
|
||||
|
||||
PT.air_contents.temperature = btemp1 + T0C
|
||||
OT.air_contents.temperature = btemp2 + T0C
|
||||
|
||||
var/obj/item/assembly/S
|
||||
|
||||
switch(src.btype)
|
||||
// radio
|
||||
if(0)
|
||||
|
||||
S = new/obj/item/assembly/signaler(V)
|
||||
|
||||
// proximity
|
||||
if(1)
|
||||
|
||||
S = new/obj/item/assembly/prox_sensor(V)
|
||||
|
||||
// timer
|
||||
if(2)
|
||||
|
||||
S = new/obj/item/assembly/timer(V)
|
||||
|
||||
|
||||
V.attached_device = S
|
||||
|
||||
S.holder = V
|
||||
S.toggle_secure()
|
||||
|
||||
V.update_icon()
|
||||
|
||||
qdel(src)
|
||||
/obj/effect/spawner/newbomb
|
||||
name = "bomb"
|
||||
icon = 'icons/mob/screen_gen.dmi'
|
||||
icon_state = "x"
|
||||
var/btype = 0 // 0=radio, 1=prox, 2=time
|
||||
var/btemp1 = 1500
|
||||
var/btemp2 = 1000 // tank temperatures
|
||||
|
||||
timer
|
||||
btype = 2
|
||||
|
||||
syndicate
|
||||
btemp1 = 150
|
||||
btemp2 = 20
|
||||
|
||||
proximity
|
||||
btype = 1
|
||||
|
||||
radio
|
||||
btype = 0
|
||||
|
||||
|
||||
/obj/effect/spawner/newbomb/New()
|
||||
..()
|
||||
|
||||
var/obj/item/transfer_valve/V = new(src.loc)
|
||||
var/obj/item/tank/plasma/PT = new(V)
|
||||
var/obj/item/tank/oxygen/OT = new(V)
|
||||
|
||||
V.tank_one = PT
|
||||
V.tank_two = OT
|
||||
|
||||
PT.master = V
|
||||
OT.master = V
|
||||
|
||||
PT.air_contents.temperature = btemp1 + T0C
|
||||
OT.air_contents.temperature = btemp2 + T0C
|
||||
|
||||
var/obj/item/assembly/S
|
||||
|
||||
switch(src.btype)
|
||||
// radio
|
||||
if(0)
|
||||
|
||||
S = new/obj/item/assembly/signaler(V)
|
||||
|
||||
// proximity
|
||||
if(1)
|
||||
|
||||
S = new/obj/item/assembly/prox_sensor(V)
|
||||
|
||||
// timer
|
||||
if(2)
|
||||
|
||||
S = new/obj/item/assembly/timer(V)
|
||||
|
||||
|
||||
V.attached_device = S
|
||||
|
||||
S.holder = V
|
||||
S.toggle_secure()
|
||||
|
||||
V.update_icon()
|
||||
|
||||
qdel(src)
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
/obj/effect/gibspawner/generic
|
||||
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/core)
|
||||
gibamounts = list(2,2,1)
|
||||
|
||||
/obj/effect/gibspawner/generic/New()
|
||||
gibdirections = list(list(WEST, NORTHWEST, SOUTHWEST, NORTH),list(EAST, NORTHEAST, SOUTHEAST, SOUTH), list())
|
||||
..()
|
||||
|
||||
/obj/effect/gibspawner/human
|
||||
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/down,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/core)
|
||||
gibamounts = list(1,1,1,1,1,1,1)
|
||||
|
||||
/obj/effect/gibspawner/human/New()
|
||||
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), alldirs, alldirs, list())
|
||||
gibamounts[6] = pick(0,1,2)
|
||||
..()
|
||||
|
||||
/obj/effect/gibspawner/xeno
|
||||
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno/up,/obj/effect/decal/cleanable/blood/gibs/xeno/down,/obj/effect/decal/cleanable/blood/gibs/xeno,/obj/effect/decal/cleanable/blood/gibs/xeno,/obj/effect/decal/cleanable/blood/gibs/xeno/body,/obj/effect/decal/cleanable/blood/gibs/xeno/limb,/obj/effect/decal/cleanable/blood/gibs/xeno/core)
|
||||
gibamounts = list(1,1,1,1,1,1,1)
|
||||
|
||||
/obj/effect/gibspawner/xeno/New()
|
||||
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), alldirs, alldirs, list())
|
||||
gibamounts[6] = pick(0,1,2)
|
||||
..()
|
||||
|
||||
/obj/effect/gibspawner/robot
|
||||
sparks = 1
|
||||
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/robot/up,/obj/effect/decal/cleanable/blood/gibs/robot/down,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot/limb)
|
||||
gibamounts = list(1,1,1,1,1,1)
|
||||
|
||||
/obj/effect/gibspawner/robot/New()
|
||||
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), alldirs, alldirs)
|
||||
gibamounts[6] = pick(0,1,2)
|
||||
..()
|
||||
/obj/effect/gibspawner/generic
|
||||
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/core)
|
||||
gibamounts = list(2,2,1)
|
||||
|
||||
/obj/effect/gibspawner/generic/New()
|
||||
gibdirections = list(list(WEST, NORTHWEST, SOUTHWEST, NORTH),list(EAST, NORTHEAST, SOUTHEAST, SOUTH), list())
|
||||
..()
|
||||
|
||||
/obj/effect/gibspawner/human
|
||||
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/down,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/core)
|
||||
gibamounts = list(1,1,1,1,1,1,1)
|
||||
|
||||
/obj/effect/gibspawner/human/New()
|
||||
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), alldirs, alldirs, list())
|
||||
gibamounts[6] = pick(0,1,2)
|
||||
..()
|
||||
|
||||
/obj/effect/gibspawner/xeno
|
||||
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno/up,/obj/effect/decal/cleanable/blood/gibs/xeno/down,/obj/effect/decal/cleanable/blood/gibs/xeno,/obj/effect/decal/cleanable/blood/gibs/xeno,/obj/effect/decal/cleanable/blood/gibs/xeno/body,/obj/effect/decal/cleanable/blood/gibs/xeno/limb,/obj/effect/decal/cleanable/blood/gibs/xeno/core)
|
||||
gibamounts = list(1,1,1,1,1,1,1)
|
||||
|
||||
/obj/effect/gibspawner/xeno/New()
|
||||
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), alldirs, alldirs, list())
|
||||
gibamounts[6] = pick(0,1,2)
|
||||
..()
|
||||
|
||||
/obj/effect/gibspawner/robot
|
||||
sparks = 1
|
||||
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/robot/up,/obj/effect/decal/cleanable/blood/gibs/robot/down,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot/limb)
|
||||
gibamounts = list(1,1,1,1,1,1)
|
||||
|
||||
/obj/effect/gibspawner/robot/New()
|
||||
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), alldirs, alldirs)
|
||||
gibamounts[6] = pick(0,1,2)
|
||||
..()
|
||||
|
||||
@@ -318,4 +318,4 @@
|
||||
/obj/effect/spawner/random_spawners/syndicate/layout/spacepod
|
||||
name = "50pc loot spacepod"
|
||||
result = list(/obj/spacepod/syndi = 1,
|
||||
/obj/spacepod/syndi/unlocked = 1)
|
||||
/obj/spacepod/syndi/unlocked = 1)
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
/obj/effect/vaultspawner
|
||||
var/maxX = 6
|
||||
var/maxY = 6
|
||||
var/minX = 2
|
||||
var/minY = 2
|
||||
|
||||
/obj/effect/vaultspawner/New(turf/location as turf,lX = minX,uX = maxX,lY = minY,uY = maxY,var/type = null)
|
||||
if(!type)
|
||||
type = pick("sandstone","rock","alien")
|
||||
|
||||
var/lowBoundX = location.x
|
||||
var/lowBoundY = location.y
|
||||
|
||||
var/hiBoundX = location.x + rand(lX,uX)
|
||||
var/hiBoundY = location.y + rand(lY,uY)
|
||||
|
||||
var/z = location.z
|
||||
|
||||
for(var/i = lowBoundX,i<=hiBoundX,i++)
|
||||
for(var/j = lowBoundY,j<=hiBoundY,j++)
|
||||
if(i == lowBoundX || i == hiBoundX || j == lowBoundY || j == hiBoundY)
|
||||
new /turf/simulated/wall/vault(locate(i,j,z),type)
|
||||
else
|
||||
new /turf/simulated/floor/vault(locate(i,j,z),type)
|
||||
|
||||
qdel(src)
|
||||
/obj/effect/vaultspawner
|
||||
var/maxX = 6
|
||||
var/maxY = 6
|
||||
var/minX = 2
|
||||
var/minY = 2
|
||||
|
||||
/obj/effect/vaultspawner/New(turf/location as turf,lX = minX,uX = maxX,lY = minY,uY = maxY,var/type = null)
|
||||
if(!type)
|
||||
type = pick("sandstone","rock","alien")
|
||||
|
||||
var/lowBoundX = location.x
|
||||
var/lowBoundY = location.y
|
||||
|
||||
var/hiBoundX = location.x + rand(lX,uX)
|
||||
var/hiBoundY = location.y + rand(lY,uY)
|
||||
|
||||
var/z = location.z
|
||||
|
||||
for(var/i = lowBoundX,i<=hiBoundX,i++)
|
||||
for(var/j = lowBoundY,j<=hiBoundY,j++)
|
||||
if(i == lowBoundX || i == hiBoundX || j == lowBoundY || j == hiBoundY)
|
||||
new /turf/simulated/wall/vault(locate(i,j,z),type)
|
||||
else
|
||||
new /turf/simulated/floor/vault(locate(i,j,z),type)
|
||||
|
||||
qdel(src)
|
||||
|
||||
@@ -1,213 +1,213 @@
|
||||
//generic procs copied from obj/effect/alien
|
||||
/obj/structure/spider
|
||||
name = "web"
|
||||
desc = "it's stringy and sticky"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
max_integrity = 15
|
||||
var/mob/living/carbon/human/master_commander = null
|
||||
|
||||
/obj/structure/spider/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
|
||||
if(damage_type == BURN)//the stickiness of the web mutes all attack sounds except fire damage type
|
||||
playsound(loc, 'sound/items/welder.ogg', 100, TRUE)
|
||||
|
||||
|
||||
/obj/structure/spider/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
|
||||
if(damage_flag == "melee")
|
||||
switch(damage_type)
|
||||
if(BURN)
|
||||
damage_amount *= 2
|
||||
if(BRUTE)
|
||||
damage_amount *= 0.25
|
||||
. = ..()
|
||||
|
||||
/obj/structure/spider/Destroy()
|
||||
master_commander = null
|
||||
return ..()
|
||||
|
||||
/obj/structure/spider/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
..()
|
||||
if(exposed_temperature > 300)
|
||||
take_damage(5, BURN, 0, 0)
|
||||
|
||||
/obj/structure/spider/stickyweb
|
||||
icon_state = "stickyweb1"
|
||||
|
||||
/obj/structure/spider/stickyweb/New()
|
||||
..()
|
||||
if(prob(50))
|
||||
icon_state = "stickyweb2"
|
||||
|
||||
/obj/structure/spider/stickyweb/CanPass(atom/movable/mover, turf/target, height=0)
|
||||
if(height == 0)
|
||||
return TRUE
|
||||
if(istype(mover, /mob/living/simple_animal/hostile/poison/giant_spider))
|
||||
return TRUE
|
||||
else if(istype(mover, /mob/living))
|
||||
if(prob(50))
|
||||
to_chat(mover, "<span class='danger'>You get stuck in [src] for a moment.</span>")
|
||||
return FALSE
|
||||
else if(istype(mover, /obj/item/projectile))
|
||||
return prob(30)
|
||||
return TRUE
|
||||
|
||||
/obj/structure/spider/eggcluster
|
||||
name = "egg cluster"
|
||||
desc = "They seem to pulse slightly with an inner life"
|
||||
icon_state = "eggs"
|
||||
var/amount_grown = 0
|
||||
var/player_spiders = 0
|
||||
var/list/faction = list()
|
||||
|
||||
/obj/structure/spider/eggcluster/New()
|
||||
..()
|
||||
pixel_x = rand(3,-3)
|
||||
pixel_y = rand(3,-3)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/structure/spider/eggcluster/process()
|
||||
amount_grown += rand(0,2)
|
||||
if(amount_grown >= 100)
|
||||
var/num = rand(3, 12)
|
||||
for(var/i in 1 to num)
|
||||
var/obj/structure/spider/spiderling/S = new /obj/structure/spider/spiderling(loc)
|
||||
S.faction = faction.Copy()
|
||||
S.master_commander = master_commander
|
||||
if(player_spiders)
|
||||
S.player_spiders = 1
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/spider/spiderling
|
||||
name = "spiderling"
|
||||
desc = "It never stays still for long."
|
||||
icon_state = "spiderling"
|
||||
anchored = 0
|
||||
layer = 2.75
|
||||
max_integrity = 3
|
||||
var/amount_grown = 0
|
||||
var/grow_as = null
|
||||
var/obj/machinery/atmospherics/unary/vent_pump/entry_vent
|
||||
var/travelling_in_vent = 0
|
||||
var/player_spiders = 0
|
||||
var/list/faction = list()
|
||||
var/selecting_player = 0
|
||||
|
||||
/obj/structure/spider/spiderling/New()
|
||||
..()
|
||||
pixel_x = rand(6,-6)
|
||||
pixel_y = rand(6,-6)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/structure/spider/spiderling/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
entry_vent = null
|
||||
new /obj/effect/decal/cleanable/spiderling_remains(get_turf(src))
|
||||
return ..()
|
||||
|
||||
/obj/structure/spider/spiderling/Bump(atom/user)
|
||||
if(istype(user, /obj/structure/table))
|
||||
loc = user.loc
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/structure/spider/spiderling/process()
|
||||
if(travelling_in_vent)
|
||||
if(istype(loc, /turf))
|
||||
travelling_in_vent = 0
|
||||
entry_vent = null
|
||||
else if(entry_vent)
|
||||
if(get_dist(src, entry_vent) <= 1)
|
||||
var/list/vents = list()
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in entry_vent.parent.other_atmosmch)
|
||||
vents.Add(temp_vent)
|
||||
if(!vents.len)
|
||||
entry_vent = null
|
||||
return
|
||||
var/obj/machinery/atmospherics/unary/vent_pump/exit_vent = pick(vents)
|
||||
if(prob(50))
|
||||
visible_message("<B>[src] scrambles into the ventilation ducts!</B>", \
|
||||
"<span class='notice'>You hear something squeezing through the ventilation ducts.</span>")
|
||||
|
||||
spawn(rand(20,60))
|
||||
loc = exit_vent
|
||||
var/travel_time = round(get_dist(loc, exit_vent.loc) / 2)
|
||||
spawn(travel_time)
|
||||
|
||||
if(!exit_vent || exit_vent.welded)
|
||||
loc = entry_vent
|
||||
entry_vent = null
|
||||
return
|
||||
|
||||
if(prob(50))
|
||||
audible_message("<span class='notice'>You hear something squeezing through the ventilation ducts.</span>")
|
||||
sleep(travel_time)
|
||||
|
||||
if(!exit_vent || exit_vent.welded)
|
||||
loc = entry_vent
|
||||
entry_vent = null
|
||||
return
|
||||
loc = exit_vent.loc
|
||||
entry_vent = null
|
||||
var/area/new_area = get_area(loc)
|
||||
if(new_area)
|
||||
new_area.Entered(src)
|
||||
//=================
|
||||
|
||||
else if(prob(33))
|
||||
var/list/nearby = oview(10, src)
|
||||
if(nearby.len)
|
||||
var/target_atom = pick(nearby)
|
||||
walk_to(src, target_atom)
|
||||
if(prob(40))
|
||||
visible_message("<span class='notice'>[src] skitters[pick(" away"," around","")].</span>")
|
||||
else if(prob(10))
|
||||
//ventcrawl!
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(7,src))
|
||||
if(!v.welded)
|
||||
entry_vent = v
|
||||
walk_to(src, entry_vent, 1)
|
||||
break
|
||||
if(isturf(loc))
|
||||
amount_grown += rand(0,2)
|
||||
if(amount_grown >= 100)
|
||||
if(!grow_as)
|
||||
grow_as = pick(typesof(/mob/living/simple_animal/hostile/poison/giant_spider))
|
||||
var/mob/living/simple_animal/hostile/poison/giant_spider/S = new grow_as(loc)
|
||||
S.faction = faction.Copy()
|
||||
S.master_commander = master_commander
|
||||
if(player_spiders && !selecting_player)
|
||||
selecting_player = 1
|
||||
spawn()
|
||||
var/list/candidates = pollCandidates("Do you want to play as a spider?", ROLE_GSPIDER, 1)
|
||||
|
||||
if(candidates.len)
|
||||
var/mob/C = pick(candidates)
|
||||
if(C)
|
||||
S.key = C.key
|
||||
if(S.master_commander)
|
||||
to_chat(S, "<span class='biggerdanger'>You are a spider who is loyal to [S.master_commander], obey [S.master_commander]'s every order and assist [S.master_commander.p_them()] in completing [S.master_commander.p_their()] goals at any cost.</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/decal/cleanable/spiderling_remains
|
||||
name = "spiderling remains"
|
||||
desc = "Green squishy mess."
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "greenshatter"
|
||||
anchored = 1
|
||||
|
||||
/obj/structure/spider/cocoon
|
||||
name = "cocoon"
|
||||
desc = "Something wrapped in silky spider web"
|
||||
icon_state = "cocoon1"
|
||||
max_integrity = 60
|
||||
|
||||
/obj/structure/spider/cocoon/New()
|
||||
..()
|
||||
icon_state = pick("cocoon1","cocoon2","cocoon3")
|
||||
|
||||
/obj/structure/spider/cocoon/Destroy()
|
||||
visible_message("<span class='danger'>[src] splits open.</span>")
|
||||
for(var/atom/movable/A in contents)
|
||||
A.forceMove(loc)
|
||||
return ..()
|
||||
//generic procs copied from obj/effect/alien
|
||||
/obj/structure/spider
|
||||
name = "web"
|
||||
desc = "it's stringy and sticky"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
anchored = TRUE
|
||||
density = FALSE
|
||||
max_integrity = 15
|
||||
var/mob/living/carbon/human/master_commander = null
|
||||
|
||||
/obj/structure/spider/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
|
||||
if(damage_type == BURN)//the stickiness of the web mutes all attack sounds except fire damage type
|
||||
playsound(loc, 'sound/items/welder.ogg', 100, TRUE)
|
||||
|
||||
|
||||
/obj/structure/spider/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
|
||||
if(damage_flag == "melee")
|
||||
switch(damage_type)
|
||||
if(BURN)
|
||||
damage_amount *= 2
|
||||
if(BRUTE)
|
||||
damage_amount *= 0.25
|
||||
. = ..()
|
||||
|
||||
/obj/structure/spider/Destroy()
|
||||
master_commander = null
|
||||
return ..()
|
||||
|
||||
/obj/structure/spider/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
..()
|
||||
if(exposed_temperature > 300)
|
||||
take_damage(5, BURN, 0, 0)
|
||||
|
||||
/obj/structure/spider/stickyweb
|
||||
icon_state = "stickyweb1"
|
||||
|
||||
/obj/structure/spider/stickyweb/New()
|
||||
..()
|
||||
if(prob(50))
|
||||
icon_state = "stickyweb2"
|
||||
|
||||
/obj/structure/spider/stickyweb/CanPass(atom/movable/mover, turf/target, height=0)
|
||||
if(height == 0)
|
||||
return TRUE
|
||||
if(istype(mover, /mob/living/simple_animal/hostile/poison/giant_spider))
|
||||
return TRUE
|
||||
else if(istype(mover, /mob/living))
|
||||
if(prob(50))
|
||||
to_chat(mover, "<span class='danger'>You get stuck in [src] for a moment.</span>")
|
||||
return FALSE
|
||||
else if(istype(mover, /obj/item/projectile))
|
||||
return prob(30)
|
||||
return TRUE
|
||||
|
||||
/obj/structure/spider/eggcluster
|
||||
name = "egg cluster"
|
||||
desc = "They seem to pulse slightly with an inner life"
|
||||
icon_state = "eggs"
|
||||
var/amount_grown = 0
|
||||
var/player_spiders = 0
|
||||
var/list/faction = list()
|
||||
|
||||
/obj/structure/spider/eggcluster/New()
|
||||
..()
|
||||
pixel_x = rand(3,-3)
|
||||
pixel_y = rand(3,-3)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/structure/spider/eggcluster/process()
|
||||
amount_grown += rand(0,2)
|
||||
if(amount_grown >= 100)
|
||||
var/num = rand(3, 12)
|
||||
for(var/i in 1 to num)
|
||||
var/obj/structure/spider/spiderling/S = new /obj/structure/spider/spiderling(loc)
|
||||
S.faction = faction.Copy()
|
||||
S.master_commander = master_commander
|
||||
if(player_spiders)
|
||||
S.player_spiders = 1
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/spider/spiderling
|
||||
name = "spiderling"
|
||||
desc = "It never stays still for long."
|
||||
icon_state = "spiderling"
|
||||
anchored = 0
|
||||
layer = 2.75
|
||||
max_integrity = 3
|
||||
var/amount_grown = 0
|
||||
var/grow_as = null
|
||||
var/obj/machinery/atmospherics/unary/vent_pump/entry_vent
|
||||
var/travelling_in_vent = 0
|
||||
var/player_spiders = 0
|
||||
var/list/faction = list()
|
||||
var/selecting_player = 0
|
||||
|
||||
/obj/structure/spider/spiderling/New()
|
||||
..()
|
||||
pixel_x = rand(6,-6)
|
||||
pixel_y = rand(6,-6)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/structure/spider/spiderling/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
entry_vent = null
|
||||
new /obj/effect/decal/cleanable/spiderling_remains(get_turf(src))
|
||||
return ..()
|
||||
|
||||
/obj/structure/spider/spiderling/Bump(atom/user)
|
||||
if(istype(user, /obj/structure/table))
|
||||
loc = user.loc
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/structure/spider/spiderling/process()
|
||||
if(travelling_in_vent)
|
||||
if(istype(loc, /turf))
|
||||
travelling_in_vent = 0
|
||||
entry_vent = null
|
||||
else if(entry_vent)
|
||||
if(get_dist(src, entry_vent) <= 1)
|
||||
var/list/vents = list()
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in entry_vent.parent.other_atmosmch)
|
||||
vents.Add(temp_vent)
|
||||
if(!vents.len)
|
||||
entry_vent = null
|
||||
return
|
||||
var/obj/machinery/atmospherics/unary/vent_pump/exit_vent = pick(vents)
|
||||
if(prob(50))
|
||||
visible_message("<B>[src] scrambles into the ventilation ducts!</B>", \
|
||||
"<span class='notice'>You hear something squeezing through the ventilation ducts.</span>")
|
||||
|
||||
spawn(rand(20,60))
|
||||
loc = exit_vent
|
||||
var/travel_time = round(get_dist(loc, exit_vent.loc) / 2)
|
||||
spawn(travel_time)
|
||||
|
||||
if(!exit_vent || exit_vent.welded)
|
||||
loc = entry_vent
|
||||
entry_vent = null
|
||||
return
|
||||
|
||||
if(prob(50))
|
||||
audible_message("<span class='notice'>You hear something squeezing through the ventilation ducts.</span>")
|
||||
sleep(travel_time)
|
||||
|
||||
if(!exit_vent || exit_vent.welded)
|
||||
loc = entry_vent
|
||||
entry_vent = null
|
||||
return
|
||||
loc = exit_vent.loc
|
||||
entry_vent = null
|
||||
var/area/new_area = get_area(loc)
|
||||
if(new_area)
|
||||
new_area.Entered(src)
|
||||
//=================
|
||||
|
||||
else if(prob(33))
|
||||
var/list/nearby = oview(10, src)
|
||||
if(nearby.len)
|
||||
var/target_atom = pick(nearby)
|
||||
walk_to(src, target_atom)
|
||||
if(prob(40))
|
||||
visible_message("<span class='notice'>[src] skitters[pick(" away"," around","")].</span>")
|
||||
else if(prob(10))
|
||||
//ventcrawl!
|
||||
for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(7,src))
|
||||
if(!v.welded)
|
||||
entry_vent = v
|
||||
walk_to(src, entry_vent, 1)
|
||||
break
|
||||
if(isturf(loc))
|
||||
amount_grown += rand(0,2)
|
||||
if(amount_grown >= 100)
|
||||
if(!grow_as)
|
||||
grow_as = pick(typesof(/mob/living/simple_animal/hostile/poison/giant_spider))
|
||||
var/mob/living/simple_animal/hostile/poison/giant_spider/S = new grow_as(loc)
|
||||
S.faction = faction.Copy()
|
||||
S.master_commander = master_commander
|
||||
if(player_spiders && !selecting_player)
|
||||
selecting_player = 1
|
||||
spawn()
|
||||
var/list/candidates = pollCandidates("Do you want to play as a spider?", ROLE_GSPIDER, 1)
|
||||
|
||||
if(candidates.len)
|
||||
var/mob/C = pick(candidates)
|
||||
if(C)
|
||||
S.key = C.key
|
||||
if(S.master_commander)
|
||||
to_chat(S, "<span class='biggerdanger'>You are a spider who is loyal to [S.master_commander], obey [S.master_commander]'s every order and assist [S.master_commander.p_them()] in completing [S.master_commander.p_their()] goals at any cost.</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/decal/cleanable/spiderling_remains
|
||||
name = "spiderling remains"
|
||||
desc = "Green squishy mess."
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "greenshatter"
|
||||
anchored = 1
|
||||
|
||||
/obj/structure/spider/cocoon
|
||||
name = "cocoon"
|
||||
desc = "Something wrapped in silky spider web"
|
||||
icon_state = "cocoon1"
|
||||
max_integrity = 60
|
||||
|
||||
/obj/structure/spider/cocoon/New()
|
||||
..()
|
||||
icon_state = pick("cocoon1","cocoon2","cocoon3")
|
||||
|
||||
/obj/structure/spider/cocoon/Destroy()
|
||||
visible_message("<span class='danger'>[src] splits open.</span>")
|
||||
for(var/atom/movable/A in contents)
|
||||
A.forceMove(loc)
|
||||
return ..()
|
||||
|
||||
@@ -195,4 +195,4 @@
|
||||
playsound(T, sound, volume, freq_vary, extra_range)
|
||||
|
||||
if(happens_once)
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -38,4 +38,4 @@
|
||||
/obj/effect/temp_visual/cult/turf/open/floor
|
||||
icon_state = "floorglow"
|
||||
duration = 5
|
||||
plane = FLOOR_PLANE
|
||||
plane = FLOOR_PLANE
|
||||
|
||||
@@ -353,4 +353,4 @@
|
||||
|
||||
/obj/effect/temp_visual/impact_effect/ion
|
||||
icon_state = "shieldsparkles"
|
||||
duration = 6
|
||||
duration = 6
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
/proc/empulse(turf/epicenter, heavy_range, light_range, log=0, cause = null)
|
||||
if(!epicenter) return
|
||||
|
||||
if(!istype(epicenter, /turf))
|
||||
epicenter = get_turf(epicenter.loc)
|
||||
|
||||
if(log)
|
||||
message_admins("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])": ""] [ADMIN_COORDJMP(epicenter)]</a>")
|
||||
log_game("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])" : ""] [COORD(epicenter)]")
|
||||
|
||||
if(heavy_range > 1)
|
||||
new/obj/effect/temp_visual/emp/pulse(epicenter)
|
||||
|
||||
if(heavy_range > light_range)
|
||||
light_range = heavy_range
|
||||
|
||||
for(var/mob/M in range(heavy_range, epicenter))
|
||||
M << 'sound/effects/empulse.ogg'
|
||||
for(var/atom/T in range(light_range, epicenter))
|
||||
var/distance = get_dist(epicenter, T)
|
||||
if(distance < 0)
|
||||
distance = 0
|
||||
if(distance < heavy_range)
|
||||
T.emp_act(1)
|
||||
else if(distance == heavy_range)
|
||||
if(prob(50))
|
||||
T.emp_act(1)
|
||||
else
|
||||
T.emp_act(2)
|
||||
else if(distance <= light_range)
|
||||
T.emp_act(2)
|
||||
return 1
|
||||
/proc/empulse(turf/epicenter, heavy_range, light_range, log=0, cause = null)
|
||||
if(!epicenter) return
|
||||
|
||||
if(!istype(epicenter, /turf))
|
||||
epicenter = get_turf(epicenter.loc)
|
||||
|
||||
if(log)
|
||||
message_admins("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])": ""] [ADMIN_COORDJMP(epicenter)]</a>")
|
||||
log_game("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])" : ""] [COORD(epicenter)]")
|
||||
|
||||
if(heavy_range > 1)
|
||||
new/obj/effect/temp_visual/emp/pulse(epicenter)
|
||||
|
||||
if(heavy_range > light_range)
|
||||
light_range = heavy_range
|
||||
|
||||
for(var/mob/M in range(heavy_range, epicenter))
|
||||
M << 'sound/effects/empulse.ogg'
|
||||
for(var/atom/T in range(light_range, epicenter))
|
||||
var/distance = get_dist(epicenter, T)
|
||||
if(distance < 0)
|
||||
distance = 0
|
||||
if(distance < heavy_range)
|
||||
T.emp_act(1)
|
||||
else if(distance == heavy_range)
|
||||
if(prob(50))
|
||||
T.emp_act(1)
|
||||
else
|
||||
T.emp_act(2)
|
||||
else if(distance <= light_range)
|
||||
T.emp_act(2)
|
||||
return 1
|
||||
|
||||
+241
-241
@@ -1,241 +1,241 @@
|
||||
//TODO: Flash range does nothing currently
|
||||
|
||||
/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range = 0, silent = 0, smoke = 1, cause = null, breach = TRUE)
|
||||
src = null //so we don't abort once src is deleted
|
||||
epicenter = get_turf(epicenter)
|
||||
|
||||
// Archive the uncapped explosion for the doppler array
|
||||
var/orig_dev_range = devastation_range
|
||||
var/orig_heavy_range = heavy_impact_range
|
||||
var/orig_light_range = light_impact_range
|
||||
|
||||
if(!ignorecap)
|
||||
// Clamp all values to MAX_EXPLOSION_RANGE
|
||||
devastation_range = min (MAX_EX_DEVASTATION_RANGE, devastation_range)
|
||||
heavy_impact_range = min (MAX_EX_HEAVY_RANGE, heavy_impact_range)
|
||||
light_impact_range = min (MAX_EX_LIGHT_RANGE, light_impact_range)
|
||||
flash_range = min (MAX_EX_FLASH_RANGE, flash_range)
|
||||
flame_range = min (MAX_EX_FLAME_RANGE, flame_range)
|
||||
|
||||
spawn(0)
|
||||
var/watch = start_watch()
|
||||
if(!epicenter) return
|
||||
|
||||
var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flame_range)
|
||||
var/list/cached_exp_block = list()
|
||||
|
||||
if(adminlog)
|
||||
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])" : ""] [ADMIN_COORDJMP(epicenter)] ")
|
||||
log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])" : ""] [COORD(epicenter)] ")
|
||||
|
||||
// Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves.
|
||||
// Stereo users will also hear the direction of the explosion!
|
||||
|
||||
// Calculate far explosion sound range. Only allow the sound effect for heavy/devastating explosions.
|
||||
// 3/7/14 will calculate to 80 + 35
|
||||
|
||||
var/far_dist = 0
|
||||
far_dist += heavy_impact_range * 5
|
||||
far_dist += devastation_range * 20
|
||||
|
||||
if(!silent)
|
||||
var/frequency = get_rand_frequency()
|
||||
var/sound/explosion_sound = sound(get_sfx("explosion"))
|
||||
var/sound/global_boom = sound('sound/effects/explosionfar.ogg')
|
||||
|
||||
for(var/P in GLOB.player_list)
|
||||
var/mob/M = P
|
||||
// Double check for client
|
||||
if(M && M.client)
|
||||
var/turf/M_turf = get_turf(M)
|
||||
if(M_turf && M_turf.z == epicenter.z)
|
||||
var/dist = get_dist(M_turf, epicenter)
|
||||
// If inside the blast radius + world.view - 2
|
||||
if(dist <= round(max_range + world.view - 2, 1))
|
||||
M.playsound_local(epicenter, null, 100, 1, frequency, falloff = 5, S = explosion_sound)
|
||||
// You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
|
||||
else if(M.can_hear() && !isspaceturf(M.loc))
|
||||
M << global_boom
|
||||
|
||||
if(heavy_impact_range > 1)
|
||||
if(smoke)
|
||||
var/datum/effect_system/explosion/smoke/E = new/datum/effect_system/explosion/smoke()
|
||||
E.set_up(epicenter)
|
||||
E.start()
|
||||
else
|
||||
var/datum/effect_system/explosion/E = new/datum/effect_system/explosion()
|
||||
E.set_up(epicenter)
|
||||
E.start()
|
||||
|
||||
var/x0 = epicenter.x
|
||||
var/y0 = epicenter.y
|
||||
var/z0 = epicenter.z
|
||||
|
||||
var/list/affected_turfs = spiral_range_turfs(max_range, epicenter)
|
||||
|
||||
if(config.reactionary_explosions)
|
||||
for(var/A in affected_turfs) // we cache the explosion block rating of every turf in the explosion area
|
||||
var/turf/T = A
|
||||
cached_exp_block[T] = 0
|
||||
if(T.density && T.explosion_block)
|
||||
cached_exp_block[T] += T.explosion_block
|
||||
|
||||
for(var/obj/O in T)
|
||||
var/the_block = O.explosion_block
|
||||
cached_exp_block[T] += the_block == EXPLOSION_BLOCK_PROC ? O.GetExplosionBlock() : the_block
|
||||
CHECK_TICK
|
||||
|
||||
for(var/A in affected_turfs)
|
||||
var/turf/T = A
|
||||
if(!T)
|
||||
continue
|
||||
var/dist = hypotenuse(T.x, T.y, x0, y0)
|
||||
|
||||
if(config.reactionary_explosions)
|
||||
var/turf/Trajectory = T
|
||||
while(Trajectory != epicenter)
|
||||
Trajectory = get_step_towards(Trajectory, epicenter)
|
||||
dist += cached_exp_block[Trajectory]
|
||||
|
||||
var/flame_dist = 0
|
||||
// var/throw_dist = max_range - dist
|
||||
|
||||
if(dist < flame_range)
|
||||
flame_dist = 1
|
||||
|
||||
if(dist < devastation_range) dist = 1
|
||||
else if(dist < heavy_impact_range) dist = 2
|
||||
else if(dist < light_impact_range) dist = 3
|
||||
else dist = 0
|
||||
|
||||
//------- TURF FIRES -------
|
||||
|
||||
if(T)
|
||||
if(flame_dist && prob(40) && !istype(T, /turf/space) && !T.density)
|
||||
new /obj/effect/hotspot(T) //Mostly for ambience!
|
||||
if(dist > 0)
|
||||
if(istype(T, /turf/simulated))
|
||||
var/turf/simulated/S = T
|
||||
var/affecting_level
|
||||
if(dist == 1)
|
||||
affecting_level = 1
|
||||
else
|
||||
affecting_level = S.is_shielded() ? 2 : (S.intact ? 2 : 1)
|
||||
for(var/atom in S.contents) //bypass type checking since only atom can be contained by turfs anyway
|
||||
var/atom/AM = atom
|
||||
if(AM && AM.simulated)
|
||||
if(AM.level >= affecting_level)
|
||||
AM.ex_act(dist)
|
||||
else
|
||||
for(var/atom in T.contents) //see above
|
||||
var/atom/AM = atom
|
||||
if(AM && AM.simulated)
|
||||
AM.ex_act(dist)
|
||||
CHECK_TICK
|
||||
if(breach)
|
||||
T.ex_act(dist)
|
||||
else
|
||||
T.ex_act(3)
|
||||
|
||||
CHECK_TICK
|
||||
//--- THROW ITEMS AROUND ---
|
||||
/*
|
||||
if(throw_dist > 0)
|
||||
var/throw_dir = get_dir(epicenter,T)
|
||||
for(var/obj/item/I in T)
|
||||
spawn(0) //Simultaneously not one at a time
|
||||
if(I && !I.anchored)
|
||||
var/throw_mult = 0.5 + (0.5 * rand()) // Between 0.5 and 1.0
|
||||
var/throw_range = round((throw_dist + 1) * throw_mult) // Roughly 50% to 100% of throw_dist
|
||||
if(throw_range > 0)
|
||||
var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range)
|
||||
I.throw_at(throw_at, throw_range, 2, no_spin = 1) //Throw it at 2 speed, this is purely visual anyway; don't spin the thrown items, it's very costly.
|
||||
*/
|
||||
var/took = stop_watch(watch)
|
||||
//You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare
|
||||
if(Debug2)
|
||||
log_world("## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds.")
|
||||
|
||||
//Machines which report explosions.
|
||||
for(var/i,i<=doppler_arrays.len,i++)
|
||||
var/obj/machinery/doppler_array/Array = doppler_arrays[i]
|
||||
if(Array)
|
||||
Array.sense_explosion(x0,y0,z0,devastation_range,heavy_impact_range,light_impact_range,took,orig_dev_range,orig_heavy_range,orig_light_range)
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/proc/secondaryexplosion(turf/epicenter, range)
|
||||
for(var/turf/tile in spiral_range_turfs(range, epicenter))
|
||||
tile.ex_act(2)
|
||||
|
||||
/client/proc/check_bomb_impacts()
|
||||
set name = "Check Bomb Impact"
|
||||
set category = "Debug"
|
||||
|
||||
var/newmode = alert("Use reactionary explosions?","Check Bomb Impact", "Yes", "No")
|
||||
var/turf/epicenter = get_turf(mob)
|
||||
if(!epicenter)
|
||||
return
|
||||
|
||||
var/dev = 0
|
||||
var/heavy = 0
|
||||
var/light = 0
|
||||
var/list/choices = list("Small Bomb","Medium Bomb","Big Bomb","Custom Bomb")
|
||||
var/choice = input("Bomb Size?") in choices
|
||||
switch(choice)
|
||||
if(null)
|
||||
return 0
|
||||
if("Small Bomb")
|
||||
dev = 1
|
||||
heavy = 2
|
||||
light = 3
|
||||
if("Medium Bomb")
|
||||
dev = 2
|
||||
heavy = 3
|
||||
light = 4
|
||||
if("Big Bomb")
|
||||
dev = 3
|
||||
heavy = 5
|
||||
light = 7
|
||||
if("Custom Bomb")
|
||||
dev = input("Devestation range (Tiles):") as num
|
||||
heavy = input("Heavy impact range (Tiles):") as num
|
||||
light = input("Light impact range (Tiles):") as num
|
||||
|
||||
var/max_range = max(dev, heavy, light)
|
||||
var/x0 = epicenter.x
|
||||
var/y0 = epicenter.y
|
||||
var/list/wipe_colours = list()
|
||||
for(var/turf/T in spiral_range_turfs(max_range, epicenter))
|
||||
wipe_colours += T
|
||||
var/dist = hypotenuse(T.x, T.y, x0, y0)
|
||||
|
||||
if(newmode == "Yes")
|
||||
var/turf/TT = T
|
||||
while(TT != epicenter)
|
||||
TT = get_step_towards(TT,epicenter)
|
||||
if(TT.density)
|
||||
dist += TT.explosion_block
|
||||
|
||||
for(var/obj/O in T)
|
||||
var/the_block = O.explosion_block
|
||||
dist += the_block == EXPLOSION_BLOCK_PROC ? O.GetExplosionBlock() : the_block
|
||||
|
||||
if(dist < dev)
|
||||
T.color = "red"
|
||||
T.maptext = "Dev"
|
||||
else if(dist < heavy)
|
||||
T.color = "yellow"
|
||||
T.maptext = "Heavy"
|
||||
else if(dist < light)
|
||||
T.color = "blue"
|
||||
T.maptext = "Light"
|
||||
else
|
||||
continue
|
||||
|
||||
sleep(100)
|
||||
for(var/turf/T in wipe_colours)
|
||||
T.color = null
|
||||
T.maptext = ""
|
||||
//TODO: Flash range does nothing currently
|
||||
|
||||
/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range = 0, silent = 0, smoke = 1, cause = null, breach = TRUE)
|
||||
src = null //so we don't abort once src is deleted
|
||||
epicenter = get_turf(epicenter)
|
||||
|
||||
// Archive the uncapped explosion for the doppler array
|
||||
var/orig_dev_range = devastation_range
|
||||
var/orig_heavy_range = heavy_impact_range
|
||||
var/orig_light_range = light_impact_range
|
||||
|
||||
if(!ignorecap)
|
||||
// Clamp all values to MAX_EXPLOSION_RANGE
|
||||
devastation_range = min (MAX_EX_DEVASTATION_RANGE, devastation_range)
|
||||
heavy_impact_range = min (MAX_EX_HEAVY_RANGE, heavy_impact_range)
|
||||
light_impact_range = min (MAX_EX_LIGHT_RANGE, light_impact_range)
|
||||
flash_range = min (MAX_EX_FLASH_RANGE, flash_range)
|
||||
flame_range = min (MAX_EX_FLAME_RANGE, flame_range)
|
||||
|
||||
spawn(0)
|
||||
var/watch = start_watch()
|
||||
if(!epicenter) return
|
||||
|
||||
var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flame_range)
|
||||
var/list/cached_exp_block = list()
|
||||
|
||||
if(adminlog)
|
||||
message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])" : ""] [ADMIN_COORDJMP(epicenter)] ")
|
||||
log_game("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] [cause ? "(Cause: [cause])" : ""] [COORD(epicenter)] ")
|
||||
|
||||
// Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves.
|
||||
// Stereo users will also hear the direction of the explosion!
|
||||
|
||||
// Calculate far explosion sound range. Only allow the sound effect for heavy/devastating explosions.
|
||||
// 3/7/14 will calculate to 80 + 35
|
||||
|
||||
var/far_dist = 0
|
||||
far_dist += heavy_impact_range * 5
|
||||
far_dist += devastation_range * 20
|
||||
|
||||
if(!silent)
|
||||
var/frequency = get_rand_frequency()
|
||||
var/sound/explosion_sound = sound(get_sfx("explosion"))
|
||||
var/sound/global_boom = sound('sound/effects/explosionfar.ogg')
|
||||
|
||||
for(var/P in GLOB.player_list)
|
||||
var/mob/M = P
|
||||
// Double check for client
|
||||
if(M && M.client)
|
||||
var/turf/M_turf = get_turf(M)
|
||||
if(M_turf && M_turf.z == epicenter.z)
|
||||
var/dist = get_dist(M_turf, epicenter)
|
||||
// If inside the blast radius + world.view - 2
|
||||
if(dist <= round(max_range + world.view - 2, 1))
|
||||
M.playsound_local(epicenter, null, 100, 1, frequency, falloff = 5, S = explosion_sound)
|
||||
// You hear a far explosion if you're outside the blast radius. Small bombs shouldn't be heard all over the station.
|
||||
else if(M.can_hear() && !isspaceturf(M.loc))
|
||||
M << global_boom
|
||||
|
||||
if(heavy_impact_range > 1)
|
||||
if(smoke)
|
||||
var/datum/effect_system/explosion/smoke/E = new/datum/effect_system/explosion/smoke()
|
||||
E.set_up(epicenter)
|
||||
E.start()
|
||||
else
|
||||
var/datum/effect_system/explosion/E = new/datum/effect_system/explosion()
|
||||
E.set_up(epicenter)
|
||||
E.start()
|
||||
|
||||
var/x0 = epicenter.x
|
||||
var/y0 = epicenter.y
|
||||
var/z0 = epicenter.z
|
||||
|
||||
var/list/affected_turfs = spiral_range_turfs(max_range, epicenter)
|
||||
|
||||
if(config.reactionary_explosions)
|
||||
for(var/A in affected_turfs) // we cache the explosion block rating of every turf in the explosion area
|
||||
var/turf/T = A
|
||||
cached_exp_block[T] = 0
|
||||
if(T.density && T.explosion_block)
|
||||
cached_exp_block[T] += T.explosion_block
|
||||
|
||||
for(var/obj/O in T)
|
||||
var/the_block = O.explosion_block
|
||||
cached_exp_block[T] += the_block == EXPLOSION_BLOCK_PROC ? O.GetExplosionBlock() : the_block
|
||||
CHECK_TICK
|
||||
|
||||
for(var/A in affected_turfs)
|
||||
var/turf/T = A
|
||||
if(!T)
|
||||
continue
|
||||
var/dist = hypotenuse(T.x, T.y, x0, y0)
|
||||
|
||||
if(config.reactionary_explosions)
|
||||
var/turf/Trajectory = T
|
||||
while(Trajectory != epicenter)
|
||||
Trajectory = get_step_towards(Trajectory, epicenter)
|
||||
dist += cached_exp_block[Trajectory]
|
||||
|
||||
var/flame_dist = 0
|
||||
// var/throw_dist = max_range - dist
|
||||
|
||||
if(dist < flame_range)
|
||||
flame_dist = 1
|
||||
|
||||
if(dist < devastation_range) dist = 1
|
||||
else if(dist < heavy_impact_range) dist = 2
|
||||
else if(dist < light_impact_range) dist = 3
|
||||
else dist = 0
|
||||
|
||||
//------- TURF FIRES -------
|
||||
|
||||
if(T)
|
||||
if(flame_dist && prob(40) && !istype(T, /turf/space) && !T.density)
|
||||
new /obj/effect/hotspot(T) //Mostly for ambience!
|
||||
if(dist > 0)
|
||||
if(istype(T, /turf/simulated))
|
||||
var/turf/simulated/S = T
|
||||
var/affecting_level
|
||||
if(dist == 1)
|
||||
affecting_level = 1
|
||||
else
|
||||
affecting_level = S.is_shielded() ? 2 : (S.intact ? 2 : 1)
|
||||
for(var/atom in S.contents) //bypass type checking since only atom can be contained by turfs anyway
|
||||
var/atom/AM = atom
|
||||
if(AM && AM.simulated)
|
||||
if(AM.level >= affecting_level)
|
||||
AM.ex_act(dist)
|
||||
else
|
||||
for(var/atom in T.contents) //see above
|
||||
var/atom/AM = atom
|
||||
if(AM && AM.simulated)
|
||||
AM.ex_act(dist)
|
||||
CHECK_TICK
|
||||
if(breach)
|
||||
T.ex_act(dist)
|
||||
else
|
||||
T.ex_act(3)
|
||||
|
||||
CHECK_TICK
|
||||
//--- THROW ITEMS AROUND ---
|
||||
/*
|
||||
if(throw_dist > 0)
|
||||
var/throw_dir = get_dir(epicenter,T)
|
||||
for(var/obj/item/I in T)
|
||||
spawn(0) //Simultaneously not one at a time
|
||||
if(I && !I.anchored)
|
||||
var/throw_mult = 0.5 + (0.5 * rand()) // Between 0.5 and 1.0
|
||||
var/throw_range = round((throw_dist + 1) * throw_mult) // Roughly 50% to 100% of throw_dist
|
||||
if(throw_range > 0)
|
||||
var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range)
|
||||
I.throw_at(throw_at, throw_range, 2, no_spin = 1) //Throw it at 2 speed, this is purely visual anyway; don't spin the thrown items, it's very costly.
|
||||
*/
|
||||
var/took = stop_watch(watch)
|
||||
//You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare
|
||||
if(Debug2)
|
||||
log_world("## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds.")
|
||||
|
||||
//Machines which report explosions.
|
||||
for(var/i,i<=doppler_arrays.len,i++)
|
||||
var/obj/machinery/doppler_array/Array = doppler_arrays[i]
|
||||
if(Array)
|
||||
Array.sense_explosion(x0,y0,z0,devastation_range,heavy_impact_range,light_impact_range,took,orig_dev_range,orig_heavy_range,orig_light_range)
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/proc/secondaryexplosion(turf/epicenter, range)
|
||||
for(var/turf/tile in spiral_range_turfs(range, epicenter))
|
||||
tile.ex_act(2)
|
||||
|
||||
/client/proc/check_bomb_impacts()
|
||||
set name = "Check Bomb Impact"
|
||||
set category = "Debug"
|
||||
|
||||
var/newmode = alert("Use reactionary explosions?","Check Bomb Impact", "Yes", "No")
|
||||
var/turf/epicenter = get_turf(mob)
|
||||
if(!epicenter)
|
||||
return
|
||||
|
||||
var/dev = 0
|
||||
var/heavy = 0
|
||||
var/light = 0
|
||||
var/list/choices = list("Small Bomb","Medium Bomb","Big Bomb","Custom Bomb")
|
||||
var/choice = input("Bomb Size?") in choices
|
||||
switch(choice)
|
||||
if(null)
|
||||
return 0
|
||||
if("Small Bomb")
|
||||
dev = 1
|
||||
heavy = 2
|
||||
light = 3
|
||||
if("Medium Bomb")
|
||||
dev = 2
|
||||
heavy = 3
|
||||
light = 4
|
||||
if("Big Bomb")
|
||||
dev = 3
|
||||
heavy = 5
|
||||
light = 7
|
||||
if("Custom Bomb")
|
||||
dev = input("Devestation range (Tiles):") as num
|
||||
heavy = input("Heavy impact range (Tiles):") as num
|
||||
light = input("Light impact range (Tiles):") as num
|
||||
|
||||
var/max_range = max(dev, heavy, light)
|
||||
var/x0 = epicenter.x
|
||||
var/y0 = epicenter.y
|
||||
var/list/wipe_colours = list()
|
||||
for(var/turf/T in spiral_range_turfs(max_range, epicenter))
|
||||
wipe_colours += T
|
||||
var/dist = hypotenuse(T.x, T.y, x0, y0)
|
||||
|
||||
if(newmode == "Yes")
|
||||
var/turf/TT = T
|
||||
while(TT != epicenter)
|
||||
TT = get_step_towards(TT,epicenter)
|
||||
if(TT.density)
|
||||
dist += TT.explosion_block
|
||||
|
||||
for(var/obj/O in T)
|
||||
var/the_block = O.explosion_block
|
||||
dist += the_block == EXPLOSION_BLOCK_PROC ? O.GetExplosionBlock() : the_block
|
||||
|
||||
if(dist < dev)
|
||||
T.color = "red"
|
||||
T.maptext = "Dev"
|
||||
else if(dist < heavy)
|
||||
T.color = "yellow"
|
||||
T.maptext = "Heavy"
|
||||
else if(dist < light)
|
||||
T.color = "blue"
|
||||
T.maptext = "Light"
|
||||
else
|
||||
continue
|
||||
|
||||
sleep(100)
|
||||
for(var/turf/T in wipe_colours)
|
||||
T.color = null
|
||||
T.maptext = ""
|
||||
|
||||
+681
-681
File diff suppressed because it is too large
Load Diff
@@ -91,4 +91,4 @@
|
||||
max_butts = 12
|
||||
max_integrity = 12
|
||||
materials = list(MAT_GLASS=60)
|
||||
throwforce = 6
|
||||
throwforce = 6
|
||||
|
||||
@@ -1,77 +1,77 @@
|
||||
//Also contains /obj/structure/closet/body_bag because I doubt anyone would think to look for bodybags in /object/structures
|
||||
|
||||
/obj/item/bodybag
|
||||
name = "body bag"
|
||||
desc = "A folded bag designed for the storage and transportation of cadavers."
|
||||
icon = 'icons/obj/bodybag.dmi'
|
||||
icon_state = "bodybag_folded"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
attack_self(mob/user)
|
||||
var/obj/structure/closet/body_bag/R = new /obj/structure/closet/body_bag(user.loc)
|
||||
R.add_fingerprint(user)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/closet/body_bag
|
||||
name = "body bag"
|
||||
desc = "A plastic bag designed for the storage and transportation of cadavers."
|
||||
icon = 'icons/obj/bodybag.dmi'
|
||||
icon_state = "bodybag_closed"
|
||||
icon_closed = "bodybag_closed"
|
||||
icon_opened = "bodybag_open"
|
||||
sound = 'sound/items/zip.ogg'
|
||||
var/item_path = /obj/item/bodybag
|
||||
density = 0
|
||||
integrity_failure = 0
|
||||
|
||||
|
||||
/obj/structure/closet/body_bag/attackby(W as obj, mob/user as mob, params)
|
||||
if(istype(W, /obj/item/pen))
|
||||
var/t = input(user, "What would you like the label to be?", text("[]", src.name), null) as text
|
||||
if(user.get_active_hand() != W)
|
||||
return
|
||||
if(!in_range(src, user) && src.loc != user)
|
||||
return
|
||||
t = sanitize(copytext(t,1,MAX_MESSAGE_LEN))
|
||||
if(t)
|
||||
src.name = "body bag - "
|
||||
src.name += t
|
||||
src.overlays += image(src.icon, "bodybag_label")
|
||||
else
|
||||
src.name = "body bag"
|
||||
return
|
||||
if(istype(W, /obj/item/wirecutters))
|
||||
to_chat(user, "You cut the tag off the bodybag")
|
||||
src.name = "body bag"
|
||||
src.overlays.Cut()
|
||||
return
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/closet/body_bag/close()
|
||||
if(..())
|
||||
density = 0
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/obj/structure/closet/body_bag/MouseDrop(over_object, src_location, over_location)
|
||||
..()
|
||||
if((over_object == usr && (in_range(src, usr) || usr.contents.Find(src))))
|
||||
if(!ishuman(usr)) return
|
||||
if(opened) return 0
|
||||
if(contents.len) return 0
|
||||
visible_message("[usr] folds up the [src.name]")
|
||||
new item_path(get_turf(src))
|
||||
spawn(0)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/structure/closet/body_bag/relaymove(mob/user as mob)
|
||||
if(user.stat)
|
||||
return
|
||||
|
||||
// Make it possible to escape from bodybags in morgues and crematoriums
|
||||
if(loc && (isturf(loc) || istype(loc, /obj/structure/morgue) || istype(loc, /obj/structure/crematorium)))
|
||||
if(!open())
|
||||
to_chat(user, "<span class='notice'>It won't budge!</span>")
|
||||
//Also contains /obj/structure/closet/body_bag because I doubt anyone would think to look for bodybags in /object/structures
|
||||
|
||||
/obj/item/bodybag
|
||||
name = "body bag"
|
||||
desc = "A folded bag designed for the storage and transportation of cadavers."
|
||||
icon = 'icons/obj/bodybag.dmi'
|
||||
icon_state = "bodybag_folded"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
attack_self(mob/user)
|
||||
var/obj/structure/closet/body_bag/R = new /obj/structure/closet/body_bag(user.loc)
|
||||
R.add_fingerprint(user)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/closet/body_bag
|
||||
name = "body bag"
|
||||
desc = "A plastic bag designed for the storage and transportation of cadavers."
|
||||
icon = 'icons/obj/bodybag.dmi'
|
||||
icon_state = "bodybag_closed"
|
||||
icon_closed = "bodybag_closed"
|
||||
icon_opened = "bodybag_open"
|
||||
sound = 'sound/items/zip.ogg'
|
||||
var/item_path = /obj/item/bodybag
|
||||
density = 0
|
||||
integrity_failure = 0
|
||||
|
||||
|
||||
/obj/structure/closet/body_bag/attackby(W as obj, mob/user as mob, params)
|
||||
if(istype(W, /obj/item/pen))
|
||||
var/t = input(user, "What would you like the label to be?", text("[]", src.name), null) as text
|
||||
if(user.get_active_hand() != W)
|
||||
return
|
||||
if(!in_range(src, user) && src.loc != user)
|
||||
return
|
||||
t = sanitize(copytext(t,1,MAX_MESSAGE_LEN))
|
||||
if(t)
|
||||
src.name = "body bag - "
|
||||
src.name += t
|
||||
src.overlays += image(src.icon, "bodybag_label")
|
||||
else
|
||||
src.name = "body bag"
|
||||
return
|
||||
if(istype(W, /obj/item/wirecutters))
|
||||
to_chat(user, "You cut the tag off the bodybag")
|
||||
src.name = "body bag"
|
||||
src.overlays.Cut()
|
||||
return
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/closet/body_bag/close()
|
||||
if(..())
|
||||
density = 0
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/obj/structure/closet/body_bag/MouseDrop(over_object, src_location, over_location)
|
||||
..()
|
||||
if((over_object == usr && (in_range(src, usr) || usr.contents.Find(src))))
|
||||
if(!ishuman(usr)) return
|
||||
if(opened) return 0
|
||||
if(contents.len) return 0
|
||||
visible_message("[usr] folds up the [src.name]")
|
||||
new item_path(get_turf(src))
|
||||
spawn(0)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/structure/closet/body_bag/relaymove(mob/user as mob)
|
||||
if(user.stat)
|
||||
return
|
||||
|
||||
// Make it possible to escape from bodybags in morgues and crematoriums
|
||||
if(loc && (isturf(loc) || istype(loc, /obj/structure/morgue) || istype(loc, /obj/structure/crematorium)))
|
||||
if(!open())
|
||||
to_chat(user, "<span class='notice'>It won't budge!</span>")
|
||||
|
||||
@@ -1,86 +1,86 @@
|
||||
/obj/item/candle
|
||||
name = "red candle"
|
||||
desc = "In Greek myth, Prometheus stole fire from the Gods and gave it to humankind. The jewelry he kept for himself."
|
||||
icon = 'icons/obj/candle.dmi'
|
||||
icon_state = "candle1"
|
||||
item_state = "candle1"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/wax = 200
|
||||
var/lit = 0
|
||||
var/infinite = 0
|
||||
var/start_lit = 0
|
||||
light_color = "#E09D37"
|
||||
|
||||
/obj/item/candle/New()
|
||||
..()
|
||||
if(start_lit)
|
||||
// No visible message
|
||||
light(show_message = 0)
|
||||
|
||||
/obj/item/candle/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/candle/update_icon()
|
||||
var/i
|
||||
if(wax>150)
|
||||
i = 1
|
||||
else if(wax>80)
|
||||
i = 2
|
||||
else i = 3
|
||||
icon_state = "candle[i][lit ? "_lit" : ""]"
|
||||
|
||||
|
||||
/obj/item/candle/attackby(obj/item/W, mob/user, params)
|
||||
if(is_hot(W))
|
||||
light("<span class='notice'>[user] lights [src] with [W].</span>")
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/candle/welder_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(I.tool_use_check(user, 0)) //Don't need to flash eyes because you are a badass
|
||||
light("<span class='notice'>[user] casually lights the [name] with [I], what a badass.</span>")
|
||||
|
||||
/obj/item/candle/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE)
|
||||
if(!lit)
|
||||
light() //honk
|
||||
return ..()
|
||||
|
||||
/obj/item/candle/proc/light(show_message)
|
||||
if(!lit)
|
||||
lit = 1
|
||||
if(show_message)
|
||||
usr.visible_message(show_message)
|
||||
set_light(CANDLE_LUM)
|
||||
START_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/candle/process()
|
||||
if(!lit)
|
||||
return
|
||||
if(!infinite)
|
||||
wax--
|
||||
if(!wax)
|
||||
new/obj/item/trash/candle(src.loc)
|
||||
if(istype(src.loc, /mob))
|
||||
var/mob/M = src.loc
|
||||
M.unEquip(src, 1) //src is being deleted anyway
|
||||
qdel(src)
|
||||
update_icon()
|
||||
if(isturf(loc)) //start a fire if possible
|
||||
var/turf/T = loc
|
||||
T.hotspot_expose(700, 5)
|
||||
|
||||
|
||||
/obj/item/candle/attack_self(mob/user)
|
||||
if(lit)
|
||||
user.visible_message("<span class='notice'>[user] snuffs out [src].</span>")
|
||||
lit = 0
|
||||
update_icon()
|
||||
set_light(0)
|
||||
|
||||
/obj/item/candle/eternal
|
||||
desc = "A candle. This one seems to have an odd quality about the wax."
|
||||
infinite = 1
|
||||
/obj/item/candle
|
||||
name = "red candle"
|
||||
desc = "In Greek myth, Prometheus stole fire from the Gods and gave it to humankind. The jewelry he kept for himself."
|
||||
icon = 'icons/obj/candle.dmi'
|
||||
icon_state = "candle1"
|
||||
item_state = "candle1"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/wax = 200
|
||||
var/lit = 0
|
||||
var/infinite = 0
|
||||
var/start_lit = 0
|
||||
light_color = "#E09D37"
|
||||
|
||||
/obj/item/candle/New()
|
||||
..()
|
||||
if(start_lit)
|
||||
// No visible message
|
||||
light(show_message = 0)
|
||||
|
||||
/obj/item/candle/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/candle/update_icon()
|
||||
var/i
|
||||
if(wax>150)
|
||||
i = 1
|
||||
else if(wax>80)
|
||||
i = 2
|
||||
else i = 3
|
||||
icon_state = "candle[i][lit ? "_lit" : ""]"
|
||||
|
||||
|
||||
/obj/item/candle/attackby(obj/item/W, mob/user, params)
|
||||
if(is_hot(W))
|
||||
light("<span class='notice'>[user] lights [src] with [W].</span>")
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/candle/welder_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(I.tool_use_check(user, 0)) //Don't need to flash eyes because you are a badass
|
||||
light("<span class='notice'>[user] casually lights the [name] with [I], what a badass.</span>")
|
||||
|
||||
/obj/item/candle/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE)
|
||||
if(!lit)
|
||||
light() //honk
|
||||
return ..()
|
||||
|
||||
/obj/item/candle/proc/light(show_message)
|
||||
if(!lit)
|
||||
lit = 1
|
||||
if(show_message)
|
||||
usr.visible_message(show_message)
|
||||
set_light(CANDLE_LUM)
|
||||
START_PROCESSING(SSobj, src)
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/candle/process()
|
||||
if(!lit)
|
||||
return
|
||||
if(!infinite)
|
||||
wax--
|
||||
if(!wax)
|
||||
new/obj/item/trash/candle(src.loc)
|
||||
if(istype(src.loc, /mob))
|
||||
var/mob/M = src.loc
|
||||
M.unEquip(src, 1) //src is being deleted anyway
|
||||
qdel(src)
|
||||
update_icon()
|
||||
if(isturf(loc)) //start a fire if possible
|
||||
var/turf/T = loc
|
||||
T.hotspot_expose(700, 5)
|
||||
|
||||
|
||||
/obj/item/candle/attack_self(mob/user)
|
||||
if(lit)
|
||||
user.visible_message("<span class='notice'>[user] snuffs out [src].</span>")
|
||||
lit = 0
|
||||
update_icon()
|
||||
set_light(0)
|
||||
|
||||
/obj/item/candle/eternal
|
||||
desc = "A candle. This one seems to have an odd quality about the wax."
|
||||
infinite = 1
|
||||
|
||||
+287
-287
@@ -1,287 +1,287 @@
|
||||
/*
|
||||
* Crayons
|
||||
*/
|
||||
|
||||
/obj/item/toy/crayon
|
||||
name = "crayon"
|
||||
desc = "A colourful crayon. Looks tasty. Mmmm..."
|
||||
icon = 'icons/obj/crayons.dmi'
|
||||
icon_state = "crayonred"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
slot_flags = SLOT_BELT | SLOT_EARS
|
||||
attack_verb = list("attacked", "coloured")
|
||||
toolspeed = 1
|
||||
var/colour = "#FF0000" //RGB
|
||||
var/drawtype = "rune"
|
||||
var/list/graffiti = list("body","amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa","up","down","left","right","heart","borgsrogue","voxpox","shitcurity","catbeast","hieroglyphs1","hieroglyphs2","hieroglyphs3","security","syndicate1","syndicate2","nanotrasen","lie","valid","arrowleft","arrowright","arrowup","arrowdown","chicken","hailcrab","brokenheart","peace","scribble","scribble2","scribble3","skrek","squish","tunnelsnake","yip","youaredead")
|
||||
var/list/letters = list("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")
|
||||
var/uses = 30 //0 for unlimited uses
|
||||
var/instant = 0
|
||||
var/colourName = "red" //for updateIcon purposes
|
||||
var/dat
|
||||
var/busy = FALSE
|
||||
var/list/validSurfaces = list(/turf/simulated/floor)
|
||||
|
||||
/obj/item/toy/crayon/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is jamming the [name] up [user.p_their()] nose and into [user.p_their()] brain. It looks like [user.p_theyre()] trying to commit suicide.</span>")
|
||||
return BRUTELOSS|OXYLOSS
|
||||
|
||||
/obj/item/toy/crayon/New()
|
||||
..()
|
||||
name = "[colourName] crayon" //Makes crayons identifiable in things like grinders
|
||||
drawtype = pick(pick(graffiti), pick(letters), "rune[rand(1,10)]")
|
||||
|
||||
/obj/item/toy/crayon/attack_self(mob/living/user as mob)
|
||||
update_window(user)
|
||||
|
||||
/obj/item/toy/crayon/proc/update_window(mob/living/user as mob)
|
||||
dat += "<center><h2>Currently selected: [drawtype]</h2><br>"
|
||||
dat += "<a href='?src=[UID()];type=random_letter'>Random letter</a><a href='?src=[UID()];type=letter'>Pick letter</a>"
|
||||
dat += "<hr>"
|
||||
dat += "<h3>Runes:</h3><br>"
|
||||
dat += "<a href='?src=[UID()];type=random_rune'>Random rune</a>"
|
||||
for(var/i = 1; i <= 10; i++)
|
||||
dat += "<a href='?src=[UID()];type=rune[i]'>Rune[i]</a>"
|
||||
if(!((i + 1) % 3)) //3 buttons in a row
|
||||
dat += "<br>"
|
||||
dat += "<hr>"
|
||||
graffiti.Find()
|
||||
dat += "<h3>Graffiti:</h3><br>"
|
||||
dat += "<a href='?src=[UID()];type=random_graffiti'>Random graffiti</a>"
|
||||
var/c = 1
|
||||
for(var/T in graffiti)
|
||||
dat += "<a href='?src=[UID()];type=[T]'>[T]</a>"
|
||||
if(!((c + 1) % 3)) //3 buttons in a row
|
||||
dat += "<br>"
|
||||
c++
|
||||
dat += "<hr>"
|
||||
var/datum/browser/popup = new(user, "crayon", name, 300, 500)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
dat = ""
|
||||
|
||||
/obj/item/toy/crayon/Topic(href, href_list, hsrc)
|
||||
var/temp = "a"
|
||||
switch(href_list["type"])
|
||||
if("random_letter")
|
||||
temp = pick(letters)
|
||||
if("letter")
|
||||
temp = input("Choose the letter.", "Scribbles") in letters
|
||||
if("random_rune")
|
||||
temp = "rune[rand(1,10)]"
|
||||
if("random_graffiti")
|
||||
temp = pick(graffiti)
|
||||
else
|
||||
temp = href_list["type"]
|
||||
if((usr.restrained() || usr.stat || !usr.is_in_active_hand(src)))
|
||||
return
|
||||
drawtype = temp
|
||||
update_window(usr)
|
||||
|
||||
/obj/item/toy/crayon/afterattack(atom/target, mob/user, proximity)
|
||||
if(!proximity) return
|
||||
if(busy) return
|
||||
if(is_type_in_list(target,validSurfaces))
|
||||
var/temp = "rune"
|
||||
if(letters.Find(drawtype))
|
||||
temp = "letter"
|
||||
else if(graffiti.Find(drawtype))
|
||||
temp = "graffiti"
|
||||
to_chat(user, "<span class='info'>You start drawing a [temp] on the [target.name].</span>")
|
||||
busy = TRUE
|
||||
if(instant || do_after(user, 50 * toolspeed, target = target))
|
||||
var/obj/effect/decal/cleanable/crayon/C = new /obj/effect/decal/cleanable/crayon(target,colour,drawtype,temp)
|
||||
C.add_hiddenprint(user)
|
||||
to_chat(user, "<span class='info'>You finish drawing [temp].</span>")
|
||||
if(uses)
|
||||
uses--
|
||||
if(!uses)
|
||||
to_chat(user, "<span class='danger'>You used up your [name]!</span>")
|
||||
qdel(src)
|
||||
busy = FALSE
|
||||
|
||||
/obj/item/toy/crayon/attack(mob/M, mob/user)
|
||||
var/huffable = istype(src,/obj/item/toy/crayon/spraycan)
|
||||
if(M == user)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!H.check_has_mouth())
|
||||
to_chat(user, "<span class='warning'>You do not have a mouth!</span>")
|
||||
return
|
||||
playsound(loc, 'sound/items/eatfood.ogg', 50, 0)
|
||||
to_chat(user, "<span class='notice'>You take a [huffable ? "huff" : "bite"] of the [name]. Delicious!</span>")
|
||||
user.adjust_nutrition(5)
|
||||
if(uses)
|
||||
uses -= 5
|
||||
if(uses <= 0)
|
||||
to_chat(user, "<span class='warning'>There is no more of [name] left!</span>")
|
||||
qdel(src)
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/toy/crayon/red
|
||||
icon_state = "crayonred"
|
||||
colour = "#DA0000"
|
||||
colourName = "red"
|
||||
|
||||
/obj/item/toy/crayon/orange
|
||||
icon_state = "crayonorange"
|
||||
colour = "#FF9300"
|
||||
colourName = "orange"
|
||||
|
||||
/obj/item/toy/crayon/yellow
|
||||
icon_state = "crayonyellow"
|
||||
colour = "#FFF200"
|
||||
colourName = "yellow"
|
||||
|
||||
/obj/item/toy/crayon/green
|
||||
icon_state = "crayongreen"
|
||||
colour = "#A8E61D"
|
||||
colourName = "green"
|
||||
|
||||
/obj/item/toy/crayon/blue
|
||||
icon_state = "crayonblue"
|
||||
colour = "#00B7EF"
|
||||
colourName = "blue"
|
||||
|
||||
/obj/item/toy/crayon/purple
|
||||
icon_state = "crayonpurple"
|
||||
colour = "#DA00FF"
|
||||
colourName = "purple"
|
||||
|
||||
/obj/item/toy/crayon/random/New()
|
||||
icon_state = pick(list("crayonred", "crayonorange", "crayonyellow", "crayongreen", "crayonblue", "crayonpurple"))
|
||||
switch(icon_state)
|
||||
if("crayonred")
|
||||
colour = "#DA0000"
|
||||
colourName = "red"
|
||||
if("crayonorange")
|
||||
colour = "#FF9300"
|
||||
colourName = "orange"
|
||||
if("crayonyellow")
|
||||
colour = "#FFF200"
|
||||
colourName = "yellow"
|
||||
if("crayongreen")
|
||||
colour = "#A8E61D"
|
||||
colourName = "green"
|
||||
if("crayonblue")
|
||||
colour = "#00B7EF"
|
||||
colourName = "blue"
|
||||
if("crayonpurple")
|
||||
colour = "#DA00FF"
|
||||
colourName = "purple"
|
||||
..()
|
||||
|
||||
/obj/item/toy/crayon/white
|
||||
icon_state = "crayonwhite"
|
||||
colour = "#FFFFFF"
|
||||
colourName = "white"
|
||||
|
||||
/obj/item/toy/crayon/mime
|
||||
icon_state = "crayonmime"
|
||||
desc = "A very sad-looking crayon."
|
||||
colour = "#FFFFFF"
|
||||
colourName = "mime"
|
||||
uses = 0
|
||||
|
||||
/obj/item/toy/crayon/mime/attack_self(mob/living/user as mob)
|
||||
update_window(user)
|
||||
|
||||
/obj/item/toy/crayon/mime/update_window(mob/living/user as mob)
|
||||
dat += "<center><span style='border:1px solid #161616; background-color: [colour];'> </span><a href='?src=[UID()];color=1'>Change color</a></center>"
|
||||
..()
|
||||
|
||||
/obj/item/toy/crayon/mime/Topic(href,href_list)
|
||||
if(!Adjacent(usr) || usr.incapacitated())
|
||||
return
|
||||
if(href_list["color"])
|
||||
if(colour != "#FFFFFF")
|
||||
colour = "#FFFFFF"
|
||||
else
|
||||
colour = "#000000"
|
||||
update_window(usr)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/toy/crayon/rainbow
|
||||
icon_state = "crayonrainbow"
|
||||
colour = "#FFF000"
|
||||
colourName = "rainbow"
|
||||
uses = 0
|
||||
|
||||
/obj/item/toy/crayon/rainbow/attack_self(mob/living/user as mob)
|
||||
update_window(user)
|
||||
|
||||
/obj/item/toy/crayon/rainbow/update_window(mob/living/user as mob)
|
||||
dat += "<center><span style='border:1px solid #161616; background-color: [colour];'> </span><a href='?src=[UID()];color=1'>Change color</a></center>"
|
||||
..()
|
||||
|
||||
/obj/item/toy/crayon/rainbow/Topic(href,href_list[])
|
||||
if(!Adjacent(usr) || usr.incapacitated())
|
||||
return
|
||||
if(href_list["color"])
|
||||
var/temp = input(usr, "Please select colour.", "Crayon colour") as color
|
||||
colour = temp
|
||||
update_window(usr)
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
//Spraycan stuff
|
||||
|
||||
/obj/item/toy/crayon/spraycan
|
||||
icon_state = "spraycan_cap"
|
||||
desc = "A metallic container containing tasty paint."
|
||||
var/capped = 1
|
||||
instant = 1
|
||||
validSurfaces = list(/turf/simulated/floor,/turf/simulated/wall)
|
||||
|
||||
/obj/item/toy/crayon/spraycan/New()
|
||||
..()
|
||||
name = "Nanotrasen-brand Rapid Paint Applicator"
|
||||
update_icon()
|
||||
|
||||
/obj/item/toy/crayon/spraycan/attack_self(mob/living/user as mob)
|
||||
var/choice = input(user,"Spraycan options") in list("Toggle Cap","Change Drawing","Change Color")
|
||||
switch(choice)
|
||||
if("Toggle Cap")
|
||||
to_chat(user, "<span class='notice'>You [capped ? "Remove" : "Replace"] the cap of the [src]</span>")
|
||||
capped = capped ? 0 : 1
|
||||
icon_state = "spraycan[capped ? "_cap" : ""]"
|
||||
update_icon()
|
||||
if("Change Drawing")
|
||||
..()
|
||||
if("Change Color")
|
||||
colour = input(user,"Choose Color") as color
|
||||
update_icon()
|
||||
|
||||
/obj/item/toy/crayon/spraycan/afterattack(atom/target, mob/user as mob, proximity)
|
||||
if(!proximity)
|
||||
return
|
||||
if(capped)
|
||||
return
|
||||
else
|
||||
if(iscarbon(target))
|
||||
if(uses-10 > 0)
|
||||
uses = uses - 10
|
||||
var/mob/living/carbon/human/C = target
|
||||
user.visible_message("<span class='danger'> [user] sprays [src] into the face of [target]!</span>")
|
||||
if(C.client)
|
||||
C.EyeBlurry(3)
|
||||
C.EyeBlind(1)
|
||||
if(C.check_eye_prot() <= 0) // no eye protection? ARGH IT BURNS.
|
||||
C.Confused(3)
|
||||
C.Weaken(3)
|
||||
C.lip_style = "spray_face"
|
||||
C.lip_color = colour
|
||||
C.update_body()
|
||||
playsound(user.loc, 'sound/effects/spray.ogg', 5, 1, 5)
|
||||
..()
|
||||
|
||||
/obj/item/toy/crayon/spraycan/update_icon()
|
||||
overlays.Cut()
|
||||
var/image/I = image('icons/obj/crayons.dmi',icon_state = "[capped ? "spraycan_cap_colors" : "spraycan_colors"]")
|
||||
I.color = colour
|
||||
overlays += I
|
||||
/*
|
||||
* Crayons
|
||||
*/
|
||||
|
||||
/obj/item/toy/crayon
|
||||
name = "crayon"
|
||||
desc = "A colourful crayon. Looks tasty. Mmmm..."
|
||||
icon = 'icons/obj/crayons.dmi'
|
||||
icon_state = "crayonred"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
slot_flags = SLOT_BELT | SLOT_EARS
|
||||
attack_verb = list("attacked", "coloured")
|
||||
toolspeed = 1
|
||||
var/colour = "#FF0000" //RGB
|
||||
var/drawtype = "rune"
|
||||
var/list/graffiti = list("body","amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa","up","down","left","right","heart","borgsrogue","voxpox","shitcurity","catbeast","hieroglyphs1","hieroglyphs2","hieroglyphs3","security","syndicate1","syndicate2","nanotrasen","lie","valid","arrowleft","arrowright","arrowup","arrowdown","chicken","hailcrab","brokenheart","peace","scribble","scribble2","scribble3","skrek","squish","tunnelsnake","yip","youaredead")
|
||||
var/list/letters = list("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")
|
||||
var/uses = 30 //0 for unlimited uses
|
||||
var/instant = 0
|
||||
var/colourName = "red" //for updateIcon purposes
|
||||
var/dat
|
||||
var/busy = FALSE
|
||||
var/list/validSurfaces = list(/turf/simulated/floor)
|
||||
|
||||
/obj/item/toy/crayon/suicide_act(mob/user)
|
||||
user.visible_message("<span class='suicide'>[user] is jamming the [name] up [user.p_their()] nose and into [user.p_their()] brain. It looks like [user.p_theyre()] trying to commit suicide.</span>")
|
||||
return BRUTELOSS|OXYLOSS
|
||||
|
||||
/obj/item/toy/crayon/New()
|
||||
..()
|
||||
name = "[colourName] crayon" //Makes crayons identifiable in things like grinders
|
||||
drawtype = pick(pick(graffiti), pick(letters), "rune[rand(1,10)]")
|
||||
|
||||
/obj/item/toy/crayon/attack_self(mob/living/user as mob)
|
||||
update_window(user)
|
||||
|
||||
/obj/item/toy/crayon/proc/update_window(mob/living/user as mob)
|
||||
dat += "<center><h2>Currently selected: [drawtype]</h2><br>"
|
||||
dat += "<a href='?src=[UID()];type=random_letter'>Random letter</a><a href='?src=[UID()];type=letter'>Pick letter</a>"
|
||||
dat += "<hr>"
|
||||
dat += "<h3>Runes:</h3><br>"
|
||||
dat += "<a href='?src=[UID()];type=random_rune'>Random rune</a>"
|
||||
for(var/i = 1; i <= 10; i++)
|
||||
dat += "<a href='?src=[UID()];type=rune[i]'>Rune[i]</a>"
|
||||
if(!((i + 1) % 3)) //3 buttons in a row
|
||||
dat += "<br>"
|
||||
dat += "<hr>"
|
||||
graffiti.Find()
|
||||
dat += "<h3>Graffiti:</h3><br>"
|
||||
dat += "<a href='?src=[UID()];type=random_graffiti'>Random graffiti</a>"
|
||||
var/c = 1
|
||||
for(var/T in graffiti)
|
||||
dat += "<a href='?src=[UID()];type=[T]'>[T]</a>"
|
||||
if(!((c + 1) % 3)) //3 buttons in a row
|
||||
dat += "<br>"
|
||||
c++
|
||||
dat += "<hr>"
|
||||
var/datum/browser/popup = new(user, "crayon", name, 300, 500)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
dat = ""
|
||||
|
||||
/obj/item/toy/crayon/Topic(href, href_list, hsrc)
|
||||
var/temp = "a"
|
||||
switch(href_list["type"])
|
||||
if("random_letter")
|
||||
temp = pick(letters)
|
||||
if("letter")
|
||||
temp = input("Choose the letter.", "Scribbles") in letters
|
||||
if("random_rune")
|
||||
temp = "rune[rand(1,10)]"
|
||||
if("random_graffiti")
|
||||
temp = pick(graffiti)
|
||||
else
|
||||
temp = href_list["type"]
|
||||
if((usr.restrained() || usr.stat || !usr.is_in_active_hand(src)))
|
||||
return
|
||||
drawtype = temp
|
||||
update_window(usr)
|
||||
|
||||
/obj/item/toy/crayon/afterattack(atom/target, mob/user, proximity)
|
||||
if(!proximity) return
|
||||
if(busy) return
|
||||
if(is_type_in_list(target,validSurfaces))
|
||||
var/temp = "rune"
|
||||
if(letters.Find(drawtype))
|
||||
temp = "letter"
|
||||
else if(graffiti.Find(drawtype))
|
||||
temp = "graffiti"
|
||||
to_chat(user, "<span class='info'>You start drawing a [temp] on the [target.name].</span>")
|
||||
busy = TRUE
|
||||
if(instant || do_after(user, 50 * toolspeed, target = target))
|
||||
var/obj/effect/decal/cleanable/crayon/C = new /obj/effect/decal/cleanable/crayon(target,colour,drawtype,temp)
|
||||
C.add_hiddenprint(user)
|
||||
to_chat(user, "<span class='info'>You finish drawing [temp].</span>")
|
||||
if(uses)
|
||||
uses--
|
||||
if(!uses)
|
||||
to_chat(user, "<span class='danger'>You used up your [name]!</span>")
|
||||
qdel(src)
|
||||
busy = FALSE
|
||||
|
||||
/obj/item/toy/crayon/attack(mob/M, mob/user)
|
||||
var/huffable = istype(src,/obj/item/toy/crayon/spraycan)
|
||||
if(M == user)
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(!H.check_has_mouth())
|
||||
to_chat(user, "<span class='warning'>You do not have a mouth!</span>")
|
||||
return
|
||||
playsound(loc, 'sound/items/eatfood.ogg', 50, 0)
|
||||
to_chat(user, "<span class='notice'>You take a [huffable ? "huff" : "bite"] of the [name]. Delicious!</span>")
|
||||
user.adjust_nutrition(5)
|
||||
if(uses)
|
||||
uses -= 5
|
||||
if(uses <= 0)
|
||||
to_chat(user, "<span class='warning'>There is no more of [name] left!</span>")
|
||||
qdel(src)
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/toy/crayon/red
|
||||
icon_state = "crayonred"
|
||||
colour = "#DA0000"
|
||||
colourName = "red"
|
||||
|
||||
/obj/item/toy/crayon/orange
|
||||
icon_state = "crayonorange"
|
||||
colour = "#FF9300"
|
||||
colourName = "orange"
|
||||
|
||||
/obj/item/toy/crayon/yellow
|
||||
icon_state = "crayonyellow"
|
||||
colour = "#FFF200"
|
||||
colourName = "yellow"
|
||||
|
||||
/obj/item/toy/crayon/green
|
||||
icon_state = "crayongreen"
|
||||
colour = "#A8E61D"
|
||||
colourName = "green"
|
||||
|
||||
/obj/item/toy/crayon/blue
|
||||
icon_state = "crayonblue"
|
||||
colour = "#00B7EF"
|
||||
colourName = "blue"
|
||||
|
||||
/obj/item/toy/crayon/purple
|
||||
icon_state = "crayonpurple"
|
||||
colour = "#DA00FF"
|
||||
colourName = "purple"
|
||||
|
||||
/obj/item/toy/crayon/random/New()
|
||||
icon_state = pick(list("crayonred", "crayonorange", "crayonyellow", "crayongreen", "crayonblue", "crayonpurple"))
|
||||
switch(icon_state)
|
||||
if("crayonred")
|
||||
colour = "#DA0000"
|
||||
colourName = "red"
|
||||
if("crayonorange")
|
||||
colour = "#FF9300"
|
||||
colourName = "orange"
|
||||
if("crayonyellow")
|
||||
colour = "#FFF200"
|
||||
colourName = "yellow"
|
||||
if("crayongreen")
|
||||
colour = "#A8E61D"
|
||||
colourName = "green"
|
||||
if("crayonblue")
|
||||
colour = "#00B7EF"
|
||||
colourName = "blue"
|
||||
if("crayonpurple")
|
||||
colour = "#DA00FF"
|
||||
colourName = "purple"
|
||||
..()
|
||||
|
||||
/obj/item/toy/crayon/white
|
||||
icon_state = "crayonwhite"
|
||||
colour = "#FFFFFF"
|
||||
colourName = "white"
|
||||
|
||||
/obj/item/toy/crayon/mime
|
||||
icon_state = "crayonmime"
|
||||
desc = "A very sad-looking crayon."
|
||||
colour = "#FFFFFF"
|
||||
colourName = "mime"
|
||||
uses = 0
|
||||
|
||||
/obj/item/toy/crayon/mime/attack_self(mob/living/user as mob)
|
||||
update_window(user)
|
||||
|
||||
/obj/item/toy/crayon/mime/update_window(mob/living/user as mob)
|
||||
dat += "<center><span style='border:1px solid #161616; background-color: [colour];'> </span><a href='?src=[UID()];color=1'>Change color</a></center>"
|
||||
..()
|
||||
|
||||
/obj/item/toy/crayon/mime/Topic(href,href_list)
|
||||
if(!Adjacent(usr) || usr.incapacitated())
|
||||
return
|
||||
if(href_list["color"])
|
||||
if(colour != "#FFFFFF")
|
||||
colour = "#FFFFFF"
|
||||
else
|
||||
colour = "#000000"
|
||||
update_window(usr)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/toy/crayon/rainbow
|
||||
icon_state = "crayonrainbow"
|
||||
colour = "#FFF000"
|
||||
colourName = "rainbow"
|
||||
uses = 0
|
||||
|
||||
/obj/item/toy/crayon/rainbow/attack_self(mob/living/user as mob)
|
||||
update_window(user)
|
||||
|
||||
/obj/item/toy/crayon/rainbow/update_window(mob/living/user as mob)
|
||||
dat += "<center><span style='border:1px solid #161616; background-color: [colour];'> </span><a href='?src=[UID()];color=1'>Change color</a></center>"
|
||||
..()
|
||||
|
||||
/obj/item/toy/crayon/rainbow/Topic(href,href_list[])
|
||||
if(!Adjacent(usr) || usr.incapacitated())
|
||||
return
|
||||
if(href_list["color"])
|
||||
var/temp = input(usr, "Please select colour.", "Crayon colour") as color
|
||||
colour = temp
|
||||
update_window(usr)
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
//Spraycan stuff
|
||||
|
||||
/obj/item/toy/crayon/spraycan
|
||||
icon_state = "spraycan_cap"
|
||||
desc = "A metallic container containing tasty paint."
|
||||
var/capped = 1
|
||||
instant = 1
|
||||
validSurfaces = list(/turf/simulated/floor,/turf/simulated/wall)
|
||||
|
||||
/obj/item/toy/crayon/spraycan/New()
|
||||
..()
|
||||
name = "Nanotrasen-brand Rapid Paint Applicator"
|
||||
update_icon()
|
||||
|
||||
/obj/item/toy/crayon/spraycan/attack_self(mob/living/user as mob)
|
||||
var/choice = input(user,"Spraycan options") in list("Toggle Cap","Change Drawing","Change Color")
|
||||
switch(choice)
|
||||
if("Toggle Cap")
|
||||
to_chat(user, "<span class='notice'>You [capped ? "Remove" : "Replace"] the cap of the [src]</span>")
|
||||
capped = capped ? 0 : 1
|
||||
icon_state = "spraycan[capped ? "_cap" : ""]"
|
||||
update_icon()
|
||||
if("Change Drawing")
|
||||
..()
|
||||
if("Change Color")
|
||||
colour = input(user,"Choose Color") as color
|
||||
update_icon()
|
||||
|
||||
/obj/item/toy/crayon/spraycan/afterattack(atom/target, mob/user as mob, proximity)
|
||||
if(!proximity)
|
||||
return
|
||||
if(capped)
|
||||
return
|
||||
else
|
||||
if(iscarbon(target))
|
||||
if(uses-10 > 0)
|
||||
uses = uses - 10
|
||||
var/mob/living/carbon/human/C = target
|
||||
user.visible_message("<span class='danger'> [user] sprays [src] into the face of [target]!</span>")
|
||||
if(C.client)
|
||||
C.EyeBlurry(3)
|
||||
C.EyeBlind(1)
|
||||
if(C.check_eye_prot() <= 0) // no eye protection? ARGH IT BURNS.
|
||||
C.Confused(3)
|
||||
C.Weaken(3)
|
||||
C.lip_style = "spray_face"
|
||||
C.lip_color = colour
|
||||
C.update_body()
|
||||
playsound(user.loc, 'sound/effects/spray.ogg', 5, 1, 5)
|
||||
..()
|
||||
|
||||
/obj/item/toy/crayon/spraycan/update_icon()
|
||||
overlays.Cut()
|
||||
var/image/I = image('icons/obj/crayons.dmi',icon_state = "[capped ? "spraycan_cap_colors" : "spraycan_colors"]")
|
||||
I.color = colour
|
||||
overlays += I
|
||||
|
||||
@@ -49,4 +49,4 @@
|
||||
var/mob/living/simple_animal/hostile/carp/C = new /mob/living/simple_animal/hostile/carp(get_turf(src))
|
||||
// Make carp non-hostile to user, yes this means
|
||||
C.faction |= list("syndicate", "\ref[owner]")
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -1,107 +1,107 @@
|
||||
/obj/item/aicard
|
||||
name = "inteliCard"
|
||||
icon = 'icons/obj/aicards.dmi'
|
||||
icon_state = "aicard" // aicard-full
|
||||
item_state = "electronic"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = SLOT_BELT
|
||||
flags = NOBLUDGEON
|
||||
var/flush = null
|
||||
origin_tech = "programming=3;materials=3"
|
||||
|
||||
|
||||
/obj/item/aicard/afterattack(atom/target, mob/user, proximity)
|
||||
..()
|
||||
if(!proximity || !target)
|
||||
return
|
||||
var/mob/living/silicon/ai/AI = locate(/mob/living/silicon/ai) in src
|
||||
if(AI) //AI is on the card, implies user wants to upload it.
|
||||
target.transfer_ai(AI_TRANS_FROM_CARD, user, AI, src)
|
||||
add_attack_logs(user, AI, "Carded with [src]")
|
||||
else //No AI on the card, therefore the user wants to download one.
|
||||
target.transfer_ai(AI_TRANS_TO_CARD, user, null, src)
|
||||
update_state() //Whatever happened, update the card's state (icon, name) to match.
|
||||
|
||||
/obj/item/aicard/proc/update_state()
|
||||
var/mob/living/silicon/ai/AI = locate(/mob/living/silicon/ai) in src //AI is inside.
|
||||
if(AI)
|
||||
name = "intelliCard - [AI.name]"
|
||||
if(AI.stat == DEAD)
|
||||
icon_state = "aicard-404"
|
||||
else
|
||||
icon_state = "aicard-full"
|
||||
AI.cancel_camera() //AI are forced to move when transferred, so do this whenver one is downloaded.
|
||||
else
|
||||
icon_state = "aicard"
|
||||
name = "intelliCard"
|
||||
overlays.Cut()
|
||||
|
||||
/obj/item/aicard/attack_self(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
|
||||
/obj/item/aicard/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = inventory_state)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "aicard.tmpl", "[name]", 600, 400, state = state)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
|
||||
/obj/item/aicard/ui_data(mob/user, ui_key = "main", datum/topic_state/state = inventory_state)
|
||||
var/data[0]
|
||||
|
||||
var/mob/living/silicon/ai/AI = locate() in src
|
||||
if(istype(AI))
|
||||
data["has_ai"] = 1
|
||||
data["name"] = AI.name
|
||||
data["hardware_integrity"] = ((AI.health + 100) / 2)
|
||||
data["radio"] = !AI.aiRadio.disabledAi
|
||||
data["wireless"] = !AI.control_disabled
|
||||
data["operational"] = AI.stat != DEAD
|
||||
data["flushing"] = flush
|
||||
|
||||
var/laws[0]
|
||||
for(var/datum/ai_law/AL in AI.laws.all_laws())
|
||||
laws[++laws.len] = list("index" = AL.get_index(), "law" = sanitize(AL.law))
|
||||
data["laws"] = laws
|
||||
data["has_laws"] = laws.len
|
||||
|
||||
return data
|
||||
|
||||
|
||||
/obj/item/aicard/Topic(href, href_list, nowindow, state)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
var/mob/living/silicon/ai/AI = locate() in src
|
||||
if(!istype(AI))
|
||||
return 1
|
||||
|
||||
var/user = usr
|
||||
|
||||
if(href_list["wipe"])
|
||||
var/confirm = alert("Are you sure you want to wipe this card's memory? This cannot be undone once started.", "Confirm Wipe", "Yes", "No")
|
||||
if(confirm == "Yes" && (CanUseTopic(user, state) == STATUS_INTERACTIVE))
|
||||
msg_admin_attack("[key_name_admin(user)] wiped [key_name_admin(AI)] with \the [src].", ATKLOG_FEW)
|
||||
add_attack_logs(user, AI, "Wiped with [src].")
|
||||
flush = 1
|
||||
AI.suiciding = 1
|
||||
to_chat(AI, "Your core files are being wiped!")
|
||||
while(AI && AI.stat != DEAD)
|
||||
AI.adjustOxyLoss(2)
|
||||
sleep(10)
|
||||
flush = 0
|
||||
|
||||
if(href_list["radio"])
|
||||
AI.aiRadio.disabledAi = text2num(href_list["radio"])
|
||||
to_chat(AI, "<span class='warning'>Your Subspace Transceiver has been [AI.aiRadio.disabledAi ? "disabled" : "enabled"]!</span>")
|
||||
to_chat(user, "<span class='notice'>You [AI.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.</span>")
|
||||
|
||||
if(href_list["wireless"])
|
||||
AI.control_disabled = text2num(href_list["wireless"])
|
||||
to_chat(AI, "<span class='warning'>Your wireless interface has been [AI.control_disabled ? "disabled" : "enabled"]!</span>")
|
||||
to_chat(user, "<span class='notice'>You [AI.control_disabled ? "disable" : "enable"] the AI's wireless interface.</span>")
|
||||
update_icon()
|
||||
|
||||
return 1
|
||||
/obj/item/aicard
|
||||
name = "inteliCard"
|
||||
icon = 'icons/obj/aicards.dmi'
|
||||
icon_state = "aicard" // aicard-full
|
||||
item_state = "electronic"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = SLOT_BELT
|
||||
flags = NOBLUDGEON
|
||||
var/flush = null
|
||||
origin_tech = "programming=3;materials=3"
|
||||
|
||||
|
||||
/obj/item/aicard/afterattack(atom/target, mob/user, proximity)
|
||||
..()
|
||||
if(!proximity || !target)
|
||||
return
|
||||
var/mob/living/silicon/ai/AI = locate(/mob/living/silicon/ai) in src
|
||||
if(AI) //AI is on the card, implies user wants to upload it.
|
||||
target.transfer_ai(AI_TRANS_FROM_CARD, user, AI, src)
|
||||
add_attack_logs(user, AI, "Carded with [src]")
|
||||
else //No AI on the card, therefore the user wants to download one.
|
||||
target.transfer_ai(AI_TRANS_TO_CARD, user, null, src)
|
||||
update_state() //Whatever happened, update the card's state (icon, name) to match.
|
||||
|
||||
/obj/item/aicard/proc/update_state()
|
||||
var/mob/living/silicon/ai/AI = locate(/mob/living/silicon/ai) in src //AI is inside.
|
||||
if(AI)
|
||||
name = "intelliCard - [AI.name]"
|
||||
if(AI.stat == DEAD)
|
||||
icon_state = "aicard-404"
|
||||
else
|
||||
icon_state = "aicard-full"
|
||||
AI.cancel_camera() //AI are forced to move when transferred, so do this whenver one is downloaded.
|
||||
else
|
||||
icon_state = "aicard"
|
||||
name = "intelliCard"
|
||||
overlays.Cut()
|
||||
|
||||
/obj/item/aicard/attack_self(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
|
||||
/obj/item/aicard/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = inventory_state)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "aicard.tmpl", "[name]", 600, 400, state = state)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
|
||||
/obj/item/aicard/ui_data(mob/user, ui_key = "main", datum/topic_state/state = inventory_state)
|
||||
var/data[0]
|
||||
|
||||
var/mob/living/silicon/ai/AI = locate() in src
|
||||
if(istype(AI))
|
||||
data["has_ai"] = 1
|
||||
data["name"] = AI.name
|
||||
data["hardware_integrity"] = ((AI.health + 100) / 2)
|
||||
data["radio"] = !AI.aiRadio.disabledAi
|
||||
data["wireless"] = !AI.control_disabled
|
||||
data["operational"] = AI.stat != DEAD
|
||||
data["flushing"] = flush
|
||||
|
||||
var/laws[0]
|
||||
for(var/datum/ai_law/AL in AI.laws.all_laws())
|
||||
laws[++laws.len] = list("index" = AL.get_index(), "law" = sanitize(AL.law))
|
||||
data["laws"] = laws
|
||||
data["has_laws"] = laws.len
|
||||
|
||||
return data
|
||||
|
||||
|
||||
/obj/item/aicard/Topic(href, href_list, nowindow, state)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
var/mob/living/silicon/ai/AI = locate() in src
|
||||
if(!istype(AI))
|
||||
return 1
|
||||
|
||||
var/user = usr
|
||||
|
||||
if(href_list["wipe"])
|
||||
var/confirm = alert("Are you sure you want to wipe this card's memory? This cannot be undone once started.", "Confirm Wipe", "Yes", "No")
|
||||
if(confirm == "Yes" && (CanUseTopic(user, state) == STATUS_INTERACTIVE))
|
||||
msg_admin_attack("[key_name_admin(user)] wiped [key_name_admin(AI)] with \the [src].", ATKLOG_FEW)
|
||||
add_attack_logs(user, AI, "Wiped with [src].")
|
||||
flush = 1
|
||||
AI.suiciding = 1
|
||||
to_chat(AI, "Your core files are being wiped!")
|
||||
while(AI && AI.stat != DEAD)
|
||||
AI.adjustOxyLoss(2)
|
||||
sleep(10)
|
||||
flush = 0
|
||||
|
||||
if(href_list["radio"])
|
||||
AI.aiRadio.disabledAi = text2num(href_list["radio"])
|
||||
to_chat(AI, "<span class='warning'>Your Subspace Transceiver has been [AI.aiRadio.disabledAi ? "disabled" : "enabled"]!</span>")
|
||||
to_chat(user, "<span class='notice'>You [AI.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.</span>")
|
||||
|
||||
if(href_list["wireless"])
|
||||
AI.control_disabled = text2num(href_list["wireless"])
|
||||
to_chat(AI, "<span class='warning'>Your wireless interface has been [AI.control_disabled ? "disabled" : "enabled"]!</span>")
|
||||
to_chat(user, "<span class='notice'>You [AI.control_disabled ? "disable" : "enable"] the AI's wireless interface.</span>")
|
||||
update_icon()
|
||||
|
||||
return 1
|
||||
|
||||
@@ -1,258 +1,258 @@
|
||||
/obj/item/chameleon
|
||||
name = "chameleon-projector"
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "shield0"
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
item_state = "electronic"
|
||||
throwforce = 5.0
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
origin_tech = "syndicate=4;magnets=4"
|
||||
var/can_use = 1
|
||||
var/obj/effect/dummy/chameleon/active_dummy = null
|
||||
var/saved_item = /obj/item/cigbutt
|
||||
var/saved_icon = 'icons/obj/clothing/masks.dmi'
|
||||
var/saved_icon_state = "cigbutt"
|
||||
var/saved_overlays = null
|
||||
var/saved_underlays = null
|
||||
|
||||
/obj/item/chameleon/dropped()
|
||||
disrupt()
|
||||
|
||||
/obj/item/chameleon/equipped()
|
||||
disrupt()
|
||||
|
||||
/obj/item/chameleon/attack_self()
|
||||
toggle()
|
||||
|
||||
/obj/item/chameleon/afterattack(atom/target, mob/user , proximity)
|
||||
if(!proximity) return
|
||||
if(!active_dummy)
|
||||
if(istype(target,/obj/item) && !istype(target, /obj/item/disk/nuclear))
|
||||
playsound(get_turf(src), 'sound/weapons/flash.ogg', 100, 1, -6)
|
||||
to_chat(user, "<span class='notice'>Scanned [target].</span>")
|
||||
saved_item = target.type
|
||||
saved_icon = target.icon
|
||||
saved_icon_state = target.icon_state
|
||||
saved_overlays = target.overlays
|
||||
saved_underlays = target.underlays
|
||||
|
||||
/obj/item/chameleon/proc/toggle()
|
||||
if(!can_use || !saved_item) return
|
||||
if(active_dummy)
|
||||
eject_all()
|
||||
playsound(get_turf(src), 'sound/effects/pop.ogg', 100, 1, -6)
|
||||
QDEL_NULL(active_dummy)
|
||||
to_chat(usr, "<span class='notice'>You deactivate [src].</span>")
|
||||
var/obj/effect/overlay/T = new/obj/effect/overlay(get_turf(src))
|
||||
T.icon = 'icons/effects/effects.dmi'
|
||||
flick("emppulse",T)
|
||||
spawn(8)
|
||||
qdel(T)
|
||||
else
|
||||
playsound(get_turf(src), 'sound/effects/pop.ogg', 100, 1, -6)
|
||||
var/obj/O = new saved_item(src)
|
||||
if(!O) return
|
||||
var/obj/effect/dummy/chameleon/C = new/obj/effect/dummy/chameleon(usr.loc)
|
||||
C.activate(O, usr, saved_icon, saved_icon_state, saved_overlays, saved_underlays, src)
|
||||
qdel(O)
|
||||
to_chat(usr, "<span class='notice'>You activate [src].</span>")
|
||||
var/obj/effect/overlay/T = new/obj/effect/overlay(get_turf(src))
|
||||
T.icon = 'icons/effects/effects.dmi'
|
||||
flick("emppulse",T)
|
||||
spawn(8)
|
||||
qdel(T)
|
||||
|
||||
/obj/item/chameleon/proc/disrupt(var/delete_dummy = 1)
|
||||
if(active_dummy)
|
||||
do_sparks(5, 0, src)
|
||||
eject_all()
|
||||
if(delete_dummy)
|
||||
qdel(active_dummy)
|
||||
active_dummy = null
|
||||
can_use = 0
|
||||
spawn(50) can_use = 1
|
||||
|
||||
/obj/item/chameleon/proc/eject_all()
|
||||
for(var/atom/movable/A in active_dummy)
|
||||
A.loc = active_dummy.loc
|
||||
if(ismob(A))
|
||||
var/mob/M = A
|
||||
M.reset_perspective(null)
|
||||
|
||||
/obj/effect/dummy/chameleon
|
||||
name = ""
|
||||
desc = ""
|
||||
density = 0
|
||||
anchored = 1
|
||||
var/can_move = 1
|
||||
var/obj/item/chameleon/master = null
|
||||
|
||||
/obj/effect/dummy/chameleon/proc/activate(var/obj/O, var/mob/M, new_icon, new_iconstate, new_overlays, new_underlays, var/obj/item/chameleon/C)
|
||||
name = O.name
|
||||
desc = O.desc
|
||||
icon = new_icon
|
||||
icon_state = new_iconstate
|
||||
overlays = new_overlays
|
||||
underlays = new_underlays
|
||||
dir = O.dir
|
||||
M.loc = src
|
||||
master = C
|
||||
master.active_dummy = src
|
||||
|
||||
/obj/effect/dummy/chameleon/attackby()
|
||||
for(var/mob/M in src)
|
||||
to_chat(M, "<span class='danger'>Your chameleon-projector deactivates.</span>")
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/attack_hand()
|
||||
for(var/mob/M in src)
|
||||
to_chat(M, "<span class='danger'>Your chameleon-projector deactivates.</span>")
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/attack_animal()
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/attack_slime()
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/attack_alien()
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/ex_act(severity) //no longer bomb-proof
|
||||
for(var/mob/M in src)
|
||||
to_chat(M, "<span class='danger'>Your chameleon-projector deactivates.</span>")
|
||||
spawn()
|
||||
M.ex_act(severity)
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/bullet_act()
|
||||
for(var/mob/M in src)
|
||||
to_chat(M, "<span class='danger'>Your chameleon-projector deactivates.</span>")
|
||||
..()
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/relaymove(var/mob/user, direction)
|
||||
if(istype(loc, /turf/space) || !direction)
|
||||
return //No magical space movement!
|
||||
|
||||
if(can_move)
|
||||
can_move = 0
|
||||
switch(user.bodytemperature)
|
||||
if(300 to INFINITY)
|
||||
spawn(10) can_move = 1
|
||||
if(295 to 300)
|
||||
spawn(13) can_move = 1
|
||||
if(280 to 295)
|
||||
spawn(16) can_move = 1
|
||||
if(260 to 280)
|
||||
spawn(20) can_move = 1
|
||||
else
|
||||
spawn(25) can_move = 1
|
||||
step(src, direction)
|
||||
return
|
||||
|
||||
/obj/effect/dummy/chameleon/Destroy()
|
||||
master.disrupt(0)
|
||||
return ..()
|
||||
|
||||
/obj/item/borg_chameleon
|
||||
name = "cyborg chameleon projector"
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "shield0"
|
||||
item_state = "electronic"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/active = FALSE
|
||||
var/activationCost = 300
|
||||
var/activationUpkeep = 50
|
||||
var/disguise = "landmate"
|
||||
var/mob/living/silicon/robot/syndicate/saboteur/S
|
||||
|
||||
/obj/item/borg_chameleon/Destroy()
|
||||
if(S)
|
||||
S.cham_proj = null
|
||||
return ..()
|
||||
|
||||
/obj/item/borg_chameleon/dropped(mob/user)
|
||||
. = ..()
|
||||
disrupt(user)
|
||||
|
||||
/obj/item/borg_chameleon/equipped(mob/user)
|
||||
. = ..()
|
||||
disrupt(user)
|
||||
|
||||
/obj/item/borg_chameleon/attack_self(mob/living/silicon/robot/syndicate/saboteur/user)
|
||||
if(user && user.cell && user.cell.charge > activationCost)
|
||||
if(isturf(user.loc))
|
||||
toggle(user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't use [src] while inside something!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need at least [activationCost] charge in your cell to use [src]!</span>")
|
||||
|
||||
/obj/item/borg_chameleon/proc/toggle(mob/living/silicon/robot/syndicate/saboteur/user)
|
||||
if(active)
|
||||
playsound(src, 'sound/effects/pop.ogg', 100, 1, -6)
|
||||
to_chat(user, "<span class='notice'>You deactivate [src].</span>")
|
||||
deactivate(user)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You activate [src].</span>")
|
||||
var/start = user.filters.len
|
||||
var/X
|
||||
var/Y
|
||||
var/rsq
|
||||
var/i
|
||||
var/f
|
||||
for(i in 1 to 7)
|
||||
do
|
||||
X = 60 * rand() - 30
|
||||
Y = 60 * rand() - 30
|
||||
rsq = X * X + Y * Y
|
||||
while(rsq < 100 || rsq > 900)
|
||||
user.filters += filter(type = "wave", x = X, y = Y, size = rand() * 2.5 + 0.5, offset = rand())
|
||||
for(i in 1 to 7)
|
||||
f = user.filters[start+i]
|
||||
animate(f, offset = f:offset, time = 0, loop = 3, flags = ANIMATION_PARALLEL)
|
||||
animate(offset = f:offset - 1, time = rand() * 20 + 10)
|
||||
if(do_after(user, 50, target = user) && user.cell.use(activationCost))
|
||||
playsound(src, 'sound/effects/bamf.ogg', 100, 1, -6)
|
||||
to_chat(user, "<span class='notice'>You are now disguised as a Nanotrasen engineering cyborg.</span>")
|
||||
activate(user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The chameleon field fizzles.</span>")
|
||||
do_sparks(3, FALSE, user)
|
||||
for(i in 1 to min(7, user.filters.len)) // removing filters that are animating does nothing, we gotta stop the animations first
|
||||
f = user.filters[start + i]
|
||||
animate(f)
|
||||
user.filters = null
|
||||
|
||||
/obj/item/borg_chameleon/process()
|
||||
if(S)
|
||||
if(!S.cell || !S.cell.use(activationUpkeep))
|
||||
disrupt(S)
|
||||
else
|
||||
return PROCESS_KILL
|
||||
|
||||
/obj/item/borg_chameleon/proc/activate(mob/living/silicon/robot/syndicate/saboteur/user)
|
||||
START_PROCESSING(SSobj, src)
|
||||
S = user
|
||||
user.base_icon = disguise
|
||||
user.icon_state = disguise
|
||||
user.cham_proj = src
|
||||
active = TRUE
|
||||
user.update_icons()
|
||||
|
||||
/obj/item/borg_chameleon/proc/deactivate(mob/living/silicon/robot/syndicate/saboteur/user)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
S = user
|
||||
user.base_icon = initial(user.base_icon)
|
||||
user.icon_state = initial(user.icon_state)
|
||||
active = FALSE
|
||||
user.update_icons()
|
||||
|
||||
/obj/item/borg_chameleon/proc/disrupt(mob/living/silicon/robot/syndicate/saboteur/user)
|
||||
if(active)
|
||||
to_chat(user, "<span class='danger'>Your chameleon field deactivates.</span>")
|
||||
deactivate(user)
|
||||
/obj/item/chameleon
|
||||
name = "chameleon-projector"
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "shield0"
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
item_state = "electronic"
|
||||
throwforce = 5.0
|
||||
throw_speed = 3
|
||||
throw_range = 5
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
origin_tech = "syndicate=4;magnets=4"
|
||||
var/can_use = 1
|
||||
var/obj/effect/dummy/chameleon/active_dummy = null
|
||||
var/saved_item = /obj/item/cigbutt
|
||||
var/saved_icon = 'icons/obj/clothing/masks.dmi'
|
||||
var/saved_icon_state = "cigbutt"
|
||||
var/saved_overlays = null
|
||||
var/saved_underlays = null
|
||||
|
||||
/obj/item/chameleon/dropped()
|
||||
disrupt()
|
||||
|
||||
/obj/item/chameleon/equipped()
|
||||
disrupt()
|
||||
|
||||
/obj/item/chameleon/attack_self()
|
||||
toggle()
|
||||
|
||||
/obj/item/chameleon/afterattack(atom/target, mob/user , proximity)
|
||||
if(!proximity) return
|
||||
if(!active_dummy)
|
||||
if(istype(target,/obj/item) && !istype(target, /obj/item/disk/nuclear))
|
||||
playsound(get_turf(src), 'sound/weapons/flash.ogg', 100, 1, -6)
|
||||
to_chat(user, "<span class='notice'>Scanned [target].</span>")
|
||||
saved_item = target.type
|
||||
saved_icon = target.icon
|
||||
saved_icon_state = target.icon_state
|
||||
saved_overlays = target.overlays
|
||||
saved_underlays = target.underlays
|
||||
|
||||
/obj/item/chameleon/proc/toggle()
|
||||
if(!can_use || !saved_item) return
|
||||
if(active_dummy)
|
||||
eject_all()
|
||||
playsound(get_turf(src), 'sound/effects/pop.ogg', 100, 1, -6)
|
||||
QDEL_NULL(active_dummy)
|
||||
to_chat(usr, "<span class='notice'>You deactivate [src].</span>")
|
||||
var/obj/effect/overlay/T = new/obj/effect/overlay(get_turf(src))
|
||||
T.icon = 'icons/effects/effects.dmi'
|
||||
flick("emppulse",T)
|
||||
spawn(8)
|
||||
qdel(T)
|
||||
else
|
||||
playsound(get_turf(src), 'sound/effects/pop.ogg', 100, 1, -6)
|
||||
var/obj/O = new saved_item(src)
|
||||
if(!O) return
|
||||
var/obj/effect/dummy/chameleon/C = new/obj/effect/dummy/chameleon(usr.loc)
|
||||
C.activate(O, usr, saved_icon, saved_icon_state, saved_overlays, saved_underlays, src)
|
||||
qdel(O)
|
||||
to_chat(usr, "<span class='notice'>You activate [src].</span>")
|
||||
var/obj/effect/overlay/T = new/obj/effect/overlay(get_turf(src))
|
||||
T.icon = 'icons/effects/effects.dmi'
|
||||
flick("emppulse",T)
|
||||
spawn(8)
|
||||
qdel(T)
|
||||
|
||||
/obj/item/chameleon/proc/disrupt(var/delete_dummy = 1)
|
||||
if(active_dummy)
|
||||
do_sparks(5, 0, src)
|
||||
eject_all()
|
||||
if(delete_dummy)
|
||||
qdel(active_dummy)
|
||||
active_dummy = null
|
||||
can_use = 0
|
||||
spawn(50) can_use = 1
|
||||
|
||||
/obj/item/chameleon/proc/eject_all()
|
||||
for(var/atom/movable/A in active_dummy)
|
||||
A.loc = active_dummy.loc
|
||||
if(ismob(A))
|
||||
var/mob/M = A
|
||||
M.reset_perspective(null)
|
||||
|
||||
/obj/effect/dummy/chameleon
|
||||
name = ""
|
||||
desc = ""
|
||||
density = 0
|
||||
anchored = 1
|
||||
var/can_move = 1
|
||||
var/obj/item/chameleon/master = null
|
||||
|
||||
/obj/effect/dummy/chameleon/proc/activate(var/obj/O, var/mob/M, new_icon, new_iconstate, new_overlays, new_underlays, var/obj/item/chameleon/C)
|
||||
name = O.name
|
||||
desc = O.desc
|
||||
icon = new_icon
|
||||
icon_state = new_iconstate
|
||||
overlays = new_overlays
|
||||
underlays = new_underlays
|
||||
dir = O.dir
|
||||
M.loc = src
|
||||
master = C
|
||||
master.active_dummy = src
|
||||
|
||||
/obj/effect/dummy/chameleon/attackby()
|
||||
for(var/mob/M in src)
|
||||
to_chat(M, "<span class='danger'>Your chameleon-projector deactivates.</span>")
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/attack_hand()
|
||||
for(var/mob/M in src)
|
||||
to_chat(M, "<span class='danger'>Your chameleon-projector deactivates.</span>")
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/attack_animal()
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/attack_slime()
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/attack_alien()
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/ex_act(severity) //no longer bomb-proof
|
||||
for(var/mob/M in src)
|
||||
to_chat(M, "<span class='danger'>Your chameleon-projector deactivates.</span>")
|
||||
spawn()
|
||||
M.ex_act(severity)
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/bullet_act()
|
||||
for(var/mob/M in src)
|
||||
to_chat(M, "<span class='danger'>Your chameleon-projector deactivates.</span>")
|
||||
..()
|
||||
master.disrupt()
|
||||
|
||||
/obj/effect/dummy/chameleon/relaymove(var/mob/user, direction)
|
||||
if(istype(loc, /turf/space) || !direction)
|
||||
return //No magical space movement!
|
||||
|
||||
if(can_move)
|
||||
can_move = 0
|
||||
switch(user.bodytemperature)
|
||||
if(300 to INFINITY)
|
||||
spawn(10) can_move = 1
|
||||
if(295 to 300)
|
||||
spawn(13) can_move = 1
|
||||
if(280 to 295)
|
||||
spawn(16) can_move = 1
|
||||
if(260 to 280)
|
||||
spawn(20) can_move = 1
|
||||
else
|
||||
spawn(25) can_move = 1
|
||||
step(src, direction)
|
||||
return
|
||||
|
||||
/obj/effect/dummy/chameleon/Destroy()
|
||||
master.disrupt(0)
|
||||
return ..()
|
||||
|
||||
/obj/item/borg_chameleon
|
||||
name = "cyborg chameleon projector"
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "shield0"
|
||||
item_state = "electronic"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
var/active = FALSE
|
||||
var/activationCost = 300
|
||||
var/activationUpkeep = 50
|
||||
var/disguise = "landmate"
|
||||
var/mob/living/silicon/robot/syndicate/saboteur/S
|
||||
|
||||
/obj/item/borg_chameleon/Destroy()
|
||||
if(S)
|
||||
S.cham_proj = null
|
||||
return ..()
|
||||
|
||||
/obj/item/borg_chameleon/dropped(mob/user)
|
||||
. = ..()
|
||||
disrupt(user)
|
||||
|
||||
/obj/item/borg_chameleon/equipped(mob/user)
|
||||
. = ..()
|
||||
disrupt(user)
|
||||
|
||||
/obj/item/borg_chameleon/attack_self(mob/living/silicon/robot/syndicate/saboteur/user)
|
||||
if(user && user.cell && user.cell.charge > activationCost)
|
||||
if(isturf(user.loc))
|
||||
toggle(user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't use [src] while inside something!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need at least [activationCost] charge in your cell to use [src]!</span>")
|
||||
|
||||
/obj/item/borg_chameleon/proc/toggle(mob/living/silicon/robot/syndicate/saboteur/user)
|
||||
if(active)
|
||||
playsound(src, 'sound/effects/pop.ogg', 100, 1, -6)
|
||||
to_chat(user, "<span class='notice'>You deactivate [src].</span>")
|
||||
deactivate(user)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You activate [src].</span>")
|
||||
var/start = user.filters.len
|
||||
var/X
|
||||
var/Y
|
||||
var/rsq
|
||||
var/i
|
||||
var/f
|
||||
for(i in 1 to 7)
|
||||
do
|
||||
X = 60 * rand() - 30
|
||||
Y = 60 * rand() - 30
|
||||
rsq = X * X + Y * Y
|
||||
while(rsq < 100 || rsq > 900)
|
||||
user.filters += filter(type = "wave", x = X, y = Y, size = rand() * 2.5 + 0.5, offset = rand())
|
||||
for(i in 1 to 7)
|
||||
f = user.filters[start+i]
|
||||
animate(f, offset = f:offset, time = 0, loop = 3, flags = ANIMATION_PARALLEL)
|
||||
animate(offset = f:offset - 1, time = rand() * 20 + 10)
|
||||
if(do_after(user, 50, target = user) && user.cell.use(activationCost))
|
||||
playsound(src, 'sound/effects/bamf.ogg', 100, 1, -6)
|
||||
to_chat(user, "<span class='notice'>You are now disguised as a Nanotrasen engineering cyborg.</span>")
|
||||
activate(user)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>The chameleon field fizzles.</span>")
|
||||
do_sparks(3, FALSE, user)
|
||||
for(i in 1 to min(7, user.filters.len)) // removing filters that are animating does nothing, we gotta stop the animations first
|
||||
f = user.filters[start + i]
|
||||
animate(f)
|
||||
user.filters = null
|
||||
|
||||
/obj/item/borg_chameleon/process()
|
||||
if(S)
|
||||
if(!S.cell || !S.cell.use(activationUpkeep))
|
||||
disrupt(S)
|
||||
else
|
||||
return PROCESS_KILL
|
||||
|
||||
/obj/item/borg_chameleon/proc/activate(mob/living/silicon/robot/syndicate/saboteur/user)
|
||||
START_PROCESSING(SSobj, src)
|
||||
S = user
|
||||
user.base_icon = disguise
|
||||
user.icon_state = disguise
|
||||
user.cham_proj = src
|
||||
active = TRUE
|
||||
user.update_icons()
|
||||
|
||||
/obj/item/borg_chameleon/proc/deactivate(mob/living/silicon/robot/syndicate/saboteur/user)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
S = user
|
||||
user.base_icon = initial(user.base_icon)
|
||||
user.icon_state = initial(user.icon_state)
|
||||
active = FALSE
|
||||
user.update_icons()
|
||||
|
||||
/obj/item/borg_chameleon/proc/disrupt(mob/living/silicon/robot/syndicate/saboteur/user)
|
||||
if(active)
|
||||
to_chat(user, "<span class='danger'>Your chameleon field deactivates.</span>")
|
||||
deactivate(user)
|
||||
|
||||
@@ -93,4 +93,4 @@
|
||||
|
||||
for(var/mob/living/M in T)
|
||||
M.visible_message("\The [M] gets obliterated!")
|
||||
M.gib()
|
||||
M.gib()
|
||||
|
||||
@@ -1,281 +1,281 @@
|
||||
/obj/item/flash
|
||||
name = "flash"
|
||||
desc = "A powerful and versatile flashbulb device, with applications ranging from disorienting attackers to acting as visual receptors in robot production."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "flash"
|
||||
item_state = "flashtool" //looks exactly like a flash (and nothing like a flashbang)
|
||||
throwforce = 0
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
flags = CONDUCT
|
||||
materials = list(MAT_METAL = 300, MAT_GLASS = 300)
|
||||
origin_tech = "magnets=2;combat=1"
|
||||
|
||||
var/times_used = 0 //Number of times it's been used.
|
||||
var/broken = 0 //Is the flash burnt out?
|
||||
var/last_used = 0 //last world.time it was used.
|
||||
var/battery_panel = 0 //whether the flash can be modified with a cell or not
|
||||
var/overcharged = 0 //if overcharged the flash will set people on fire then immediately burn out (does so even if it doesn't blind them).
|
||||
var/can_overcharge = TRUE //set this to FALSE if you don't want your flash to be overcharge capable
|
||||
var/use_sound = 'sound/weapons/flash.ogg'
|
||||
|
||||
/obj/item/flash/proc/clown_check(mob/user)
|
||||
if(user && (CLUMSY in user.mutations) && prob(50))
|
||||
flash_carbon(user, user, 15, 0)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/item/flash/attackby(obj/item/W, mob/user, params)
|
||||
if(can_overcharge)
|
||||
if(istype(W, /obj/item/screwdriver))
|
||||
if(battery_panel)
|
||||
to_chat(user, "<span class='notice'>You close the battery compartment on the [src].</span>")
|
||||
battery_panel = 0
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You open the battery compartment on the [src].</span>")
|
||||
battery_panel = 1
|
||||
if(battery_panel && !overcharged)
|
||||
if(istype(W, /obj/item/stock_parts/cell))
|
||||
to_chat(user, "<span class='notice'>You jam the cell into battery compartment on the [src].</span>")
|
||||
qdel(W)
|
||||
overcharged = 1
|
||||
overlays += "overcharge"
|
||||
|
||||
/obj/item/flash/random/New()
|
||||
..()
|
||||
if(prob(25))
|
||||
broken = 1
|
||||
icon_state = "[initial(icon_state)]burnt"
|
||||
|
||||
/obj/item/flash/proc/burn_out() //Made so you can override it if you want to have an invincible flash from R&D or something.
|
||||
broken = 1
|
||||
icon_state = "[initial(icon_state)]burnt"
|
||||
visible_message("<span class='notice'>The [src.name] burns out!</span>")
|
||||
|
||||
|
||||
/obj/item/flash/proc/flash_recharge(var/mob/user)
|
||||
if(prob(times_used * 2)) //if you use it 5 times in a minute it has a 10% chance to break!
|
||||
burn_out()
|
||||
return 0
|
||||
|
||||
var/deciseconds_passed = world.time - last_used
|
||||
for(var/seconds = deciseconds_passed/10, seconds>=10, seconds-=10) //get 1 charge every 10 seconds
|
||||
times_used--
|
||||
|
||||
last_used = world.time
|
||||
times_used = max(0, times_used) //sanity
|
||||
|
||||
|
||||
/obj/item/flash/proc/try_use_flash(var/mob/user = null)
|
||||
flash_recharge(user)
|
||||
|
||||
if(broken)
|
||||
return 0
|
||||
|
||||
playsound(src.loc, use_sound, 100, 1)
|
||||
flick("[initial(icon_state)]2", src)
|
||||
times_used++
|
||||
|
||||
if(user && !clown_check(user))
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/flash/proc/flash_carbon(var/mob/living/carbon/M, var/mob/user = null, var/power = 5, targeted = 1)
|
||||
add_attack_logs(user, M, "Flashed with [src]")
|
||||
if(user && targeted)
|
||||
if(M.weakeyes)
|
||||
M.Weaken(3) //quick weaken bypasses eye protection but has no eye flash
|
||||
if(M.flash_eyes(1, 1))
|
||||
M.AdjustConfused(power)
|
||||
terrible_conversion_proc(M, user)
|
||||
M.Stun(1)
|
||||
visible_message("<span class='disarm'>[user] blinds [M] with the flash!</span>")
|
||||
to_chat(user, "<span class='danger'>You blind [M] with the flash!</span>")
|
||||
to_chat(M, "<span class='userdanger'>[user] blinds you with the flash!</span>")
|
||||
if(M.weakeyes)
|
||||
M.Stun(2)
|
||||
M.visible_message("<span class='disarm'>[M] gasps and shields [M.p_their()] eyes!</span>", "<span class='userdanger'>You gasp and shields your eyes!</span>")
|
||||
else
|
||||
visible_message("<span class='disarm'>[user] fails to blind [M] with the flash!</span>")
|
||||
to_chat(user, "<span class='warning'>You fail to blind [M] with the flash!</span>")
|
||||
to_chat(M, "<span class='danger'>[user] fails to blind you with the flash!</span>")
|
||||
else
|
||||
if(M.flash_eyes())
|
||||
M.AdjustConfused(power)
|
||||
|
||||
/obj/item/flash/attack(mob/living/M, mob/user)
|
||||
if(!try_use_flash(user))
|
||||
return 0
|
||||
|
||||
if(iscarbon(M))
|
||||
flash_carbon(M, user, 5, 1)
|
||||
if(overcharged)
|
||||
M.adjust_fire_stacks(6)
|
||||
M.IgniteMob()
|
||||
burn_out()
|
||||
return 1
|
||||
|
||||
else if(issilicon(M))
|
||||
if(isrobot(M))
|
||||
var/mob/living/silicon/robot/R = M
|
||||
if(R.module) // Perhaps they didn't choose a module yet
|
||||
for(var/obj/item/borg/combat/shield/S in R.module.modules)
|
||||
if(R.activated(S))
|
||||
add_attack_logs(user, M, "Flashed with [src]")
|
||||
user.visible_message("<span class='disarm'>[user] tries to overloads [M]'s sensors with the [src.name], but is blocked by [M]'s shield!</span>", "<span class='danger'>You try to overload [M]'s sensors with the [src.name], but are blocked by [M.p_their()] shield!</span>")
|
||||
return 1
|
||||
add_attack_logs(user, M, "Flashed with [src]")
|
||||
if(M.flash_eyes(affect_silicon = 1))
|
||||
M.Weaken(rand(5,10))
|
||||
user.visible_message("<span class='disarm'>[user] overloads [M]'s sensors with the [src.name]!</span>", "<span class='danger'>You overload [M]'s sensors with the [src.name]!</span>")
|
||||
return 1
|
||||
|
||||
user.visible_message("<span class='disarm'>[user] fails to blind [M] with the [src.name]!</span>", "<span class='warning'>You fail to blind [M] with the [src.name]!</span>")
|
||||
|
||||
|
||||
/obj/item/flash/attack_self(mob/living/carbon/user, flag = 0, emp = 0)
|
||||
if(!try_use_flash(user))
|
||||
return 0
|
||||
user.visible_message("<span class='disarm'>[user]'s [src.name] emits a blinding light!</span>", "<span class='danger'>Your [src.name] emits a blinding light!</span>")
|
||||
for(var/mob/living/carbon/M in oviewers(3, null))
|
||||
flash_carbon(M, user, 3, 0)
|
||||
|
||||
|
||||
/obj/item/flash/emp_act(severity)
|
||||
if(!try_use_flash())
|
||||
return 0
|
||||
for(var/mob/living/carbon/M in viewers(3, null))
|
||||
flash_carbon(M, null, 10, 0)
|
||||
burn_out()
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/flash/proc/terrible_conversion_proc(mob/M, mob/user)
|
||||
if(ishuman(M) && ishuman(user) && M.stat != DEAD)
|
||||
if(user.mind && (user.mind in SSticker.mode.head_revolutionaries))
|
||||
if(M.client)
|
||||
if(M.stat == CONSCIOUS)
|
||||
M.mind_initialize() //give them a mind datum if they don't have one.
|
||||
var/resisted
|
||||
if(!ismindshielded(M))
|
||||
if(user.mind in SSticker.mode.head_revolutionaries)
|
||||
if(SSticker.mode.add_revolutionary(M.mind))
|
||||
times_used -- //Flashes less likely to burn out for headrevs when used for conversion
|
||||
else
|
||||
resisted = 1
|
||||
else
|
||||
resisted = 1
|
||||
|
||||
if(resisted)
|
||||
to_chat(user, "<span class='warning'>This mind seems resistant to the [name]!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>They must be conscious before you can convert [M.p_them()]!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>This mind is so vacant that it is not susceptible to influence!</span>")
|
||||
|
||||
|
||||
/obj/item/flash/cyborg
|
||||
origin_tech = null
|
||||
|
||||
/obj/item/flash/cyborg/attack(mob/living/M, mob/user)
|
||||
..()
|
||||
new /obj/effect/temp_visual/borgflash(get_turf(src))
|
||||
|
||||
/obj/item/flash/cyborg/attack_self(mob/user)
|
||||
..()
|
||||
new /obj/effect/temp_visual/borgflash(get_turf(src))
|
||||
|
||||
/obj/item/flash/cameraflash
|
||||
name = "camera"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
desc = "A polaroid camera. 10 photos left."
|
||||
icon_state = "camera"
|
||||
item_state = "electropack" //spelling, a coders worst enemy. This part gave me trouble for a while.
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = SLOT_BELT
|
||||
can_overcharge = FALSE
|
||||
var/flash_max_charges = 5
|
||||
var/flash_cur_charges = 5
|
||||
var/charge_tick = 0
|
||||
use_sound = 'sound/items/polaroid1.ogg'
|
||||
|
||||
/obj/item/flash/cameraflash/burn_out() //stops from burning out
|
||||
return
|
||||
|
||||
/obj/item/flash/cameraflash/New()
|
||||
..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/flash/cameraflash/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/flash/cameraflash/process() //this and the two parts above are part of the charge system.
|
||||
charge_tick++
|
||||
if(charge_tick < 10)
|
||||
return FALSE
|
||||
charge_tick = 0
|
||||
flash_cur_charges = min(flash_cur_charges+1, flash_max_charges)
|
||||
return TRUE
|
||||
|
||||
/obj/item/flash/cameraflash/attack(mob/living/M, mob/user)
|
||||
if(flash_cur_charges > 0)
|
||||
flash_cur_charges -= 1
|
||||
to_chat(user, "[src] now has [flash_cur_charges] charge\s.")
|
||||
..()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [src] needs time to recharge!</span>")
|
||||
return
|
||||
|
||||
/obj/item/flash/cameraflash/attack_self(mob/living/carbon/user, flag = 0)
|
||||
if(flash_cur_charges > 0)
|
||||
flash_cur_charges -= 1
|
||||
to_chat(user, "[src] now has [flash_cur_charges] charge\s.")
|
||||
..()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [src] needs time to recharge!</span>")
|
||||
return
|
||||
|
||||
/obj/item/flash/memorizer
|
||||
name = "memorizer"
|
||||
desc = "If you see this, you're not likely to remember it any time soon."
|
||||
icon_state = "memorizer"
|
||||
item_state = "nullrod"
|
||||
|
||||
/obj/item/flash/armimplant
|
||||
name = "photon projector"
|
||||
desc = "A high-powered photon projector implant normally used for lighting purposes, but also doubles as a flashbulb weapon. Self-repair protocols fix the flashbulb if it ever burns out."
|
||||
var/flashcd = 20
|
||||
var/overheat = 0
|
||||
var/obj/item/organ/internal/cyberimp/arm/flash/I = null
|
||||
|
||||
/obj/item/flash/armimplant/Destroy()
|
||||
I = null
|
||||
return ..()
|
||||
|
||||
/obj/item/flash/armimplant/burn_out()
|
||||
if(I && I.owner)
|
||||
to_chat(I.owner, "<span class='warning'>Your photon projector implant overheats and deactivates!</span>")
|
||||
I.Retract()
|
||||
overheat = FALSE
|
||||
addtimer(CALLBACK(src, .proc/cooldown), flashcd * 2)
|
||||
|
||||
/obj/item/flash/armimplant/try_use_flash(mob/user = null)
|
||||
if(overheat)
|
||||
if(I && I.owner)
|
||||
to_chat(I.owner, "<span class='warning'>Your photon projector is running too hot to be used again so quickly!</span>")
|
||||
return FALSE
|
||||
overheat = TRUE
|
||||
addtimer(CALLBACK(src, .proc/cooldown), flashcd)
|
||||
playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1)
|
||||
update_icon(1)
|
||||
return TRUE
|
||||
|
||||
/obj/item/flash/armimplant/proc/cooldown()
|
||||
overheat = FALSE
|
||||
|
||||
|
||||
/obj/item/flash/synthetic //just a regular flash now
|
||||
/obj/item/flash
|
||||
name = "flash"
|
||||
desc = "A powerful and versatile flashbulb device, with applications ranging from disorienting attackers to acting as visual receptors in robot production."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "flash"
|
||||
item_state = "flashtool" //looks exactly like a flash (and nothing like a flashbang)
|
||||
throwforce = 0
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
flags = CONDUCT
|
||||
materials = list(MAT_METAL = 300, MAT_GLASS = 300)
|
||||
origin_tech = "magnets=2;combat=1"
|
||||
|
||||
var/times_used = 0 //Number of times it's been used.
|
||||
var/broken = 0 //Is the flash burnt out?
|
||||
var/last_used = 0 //last world.time it was used.
|
||||
var/battery_panel = 0 //whether the flash can be modified with a cell or not
|
||||
var/overcharged = 0 //if overcharged the flash will set people on fire then immediately burn out (does so even if it doesn't blind them).
|
||||
var/can_overcharge = TRUE //set this to FALSE if you don't want your flash to be overcharge capable
|
||||
var/use_sound = 'sound/weapons/flash.ogg'
|
||||
|
||||
/obj/item/flash/proc/clown_check(mob/user)
|
||||
if(user && (CLUMSY in user.mutations) && prob(50))
|
||||
flash_carbon(user, user, 15, 0)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/item/flash/attackby(obj/item/W, mob/user, params)
|
||||
if(can_overcharge)
|
||||
if(istype(W, /obj/item/screwdriver))
|
||||
if(battery_panel)
|
||||
to_chat(user, "<span class='notice'>You close the battery compartment on the [src].</span>")
|
||||
battery_panel = 0
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You open the battery compartment on the [src].</span>")
|
||||
battery_panel = 1
|
||||
if(battery_panel && !overcharged)
|
||||
if(istype(W, /obj/item/stock_parts/cell))
|
||||
to_chat(user, "<span class='notice'>You jam the cell into battery compartment on the [src].</span>")
|
||||
qdel(W)
|
||||
overcharged = 1
|
||||
overlays += "overcharge"
|
||||
|
||||
/obj/item/flash/random/New()
|
||||
..()
|
||||
if(prob(25))
|
||||
broken = 1
|
||||
icon_state = "[initial(icon_state)]burnt"
|
||||
|
||||
/obj/item/flash/proc/burn_out() //Made so you can override it if you want to have an invincible flash from R&D or something.
|
||||
broken = 1
|
||||
icon_state = "[initial(icon_state)]burnt"
|
||||
visible_message("<span class='notice'>The [src.name] burns out!</span>")
|
||||
|
||||
|
||||
/obj/item/flash/proc/flash_recharge(var/mob/user)
|
||||
if(prob(times_used * 2)) //if you use it 5 times in a minute it has a 10% chance to break!
|
||||
burn_out()
|
||||
return 0
|
||||
|
||||
var/deciseconds_passed = world.time - last_used
|
||||
for(var/seconds = deciseconds_passed/10, seconds>=10, seconds-=10) //get 1 charge every 10 seconds
|
||||
times_used--
|
||||
|
||||
last_used = world.time
|
||||
times_used = max(0, times_used) //sanity
|
||||
|
||||
|
||||
/obj/item/flash/proc/try_use_flash(var/mob/user = null)
|
||||
flash_recharge(user)
|
||||
|
||||
if(broken)
|
||||
return 0
|
||||
|
||||
playsound(src.loc, use_sound, 100, 1)
|
||||
flick("[initial(icon_state)]2", src)
|
||||
times_used++
|
||||
|
||||
if(user && !clown_check(user))
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/flash/proc/flash_carbon(var/mob/living/carbon/M, var/mob/user = null, var/power = 5, targeted = 1)
|
||||
add_attack_logs(user, M, "Flashed with [src]")
|
||||
if(user && targeted)
|
||||
if(M.weakeyes)
|
||||
M.Weaken(3) //quick weaken bypasses eye protection but has no eye flash
|
||||
if(M.flash_eyes(1, 1))
|
||||
M.AdjustConfused(power)
|
||||
terrible_conversion_proc(M, user)
|
||||
M.Stun(1)
|
||||
visible_message("<span class='disarm'>[user] blinds [M] with the flash!</span>")
|
||||
to_chat(user, "<span class='danger'>You blind [M] with the flash!</span>")
|
||||
to_chat(M, "<span class='userdanger'>[user] blinds you with the flash!</span>")
|
||||
if(M.weakeyes)
|
||||
M.Stun(2)
|
||||
M.visible_message("<span class='disarm'>[M] gasps and shields [M.p_their()] eyes!</span>", "<span class='userdanger'>You gasp and shields your eyes!</span>")
|
||||
else
|
||||
visible_message("<span class='disarm'>[user] fails to blind [M] with the flash!</span>")
|
||||
to_chat(user, "<span class='warning'>You fail to blind [M] with the flash!</span>")
|
||||
to_chat(M, "<span class='danger'>[user] fails to blind you with the flash!</span>")
|
||||
else
|
||||
if(M.flash_eyes())
|
||||
M.AdjustConfused(power)
|
||||
|
||||
/obj/item/flash/attack(mob/living/M, mob/user)
|
||||
if(!try_use_flash(user))
|
||||
return 0
|
||||
|
||||
if(iscarbon(M))
|
||||
flash_carbon(M, user, 5, 1)
|
||||
if(overcharged)
|
||||
M.adjust_fire_stacks(6)
|
||||
M.IgniteMob()
|
||||
burn_out()
|
||||
return 1
|
||||
|
||||
else if(issilicon(M))
|
||||
if(isrobot(M))
|
||||
var/mob/living/silicon/robot/R = M
|
||||
if(R.module) // Perhaps they didn't choose a module yet
|
||||
for(var/obj/item/borg/combat/shield/S in R.module.modules)
|
||||
if(R.activated(S))
|
||||
add_attack_logs(user, M, "Flashed with [src]")
|
||||
user.visible_message("<span class='disarm'>[user] tries to overloads [M]'s sensors with the [src.name], but is blocked by [M]'s shield!</span>", "<span class='danger'>You try to overload [M]'s sensors with the [src.name], but are blocked by [M.p_their()] shield!</span>")
|
||||
return 1
|
||||
add_attack_logs(user, M, "Flashed with [src]")
|
||||
if(M.flash_eyes(affect_silicon = 1))
|
||||
M.Weaken(rand(5,10))
|
||||
user.visible_message("<span class='disarm'>[user] overloads [M]'s sensors with the [src.name]!</span>", "<span class='danger'>You overload [M]'s sensors with the [src.name]!</span>")
|
||||
return 1
|
||||
|
||||
user.visible_message("<span class='disarm'>[user] fails to blind [M] with the [src.name]!</span>", "<span class='warning'>You fail to blind [M] with the [src.name]!</span>")
|
||||
|
||||
|
||||
/obj/item/flash/attack_self(mob/living/carbon/user, flag = 0, emp = 0)
|
||||
if(!try_use_flash(user))
|
||||
return 0
|
||||
user.visible_message("<span class='disarm'>[user]'s [src.name] emits a blinding light!</span>", "<span class='danger'>Your [src.name] emits a blinding light!</span>")
|
||||
for(var/mob/living/carbon/M in oviewers(3, null))
|
||||
flash_carbon(M, user, 3, 0)
|
||||
|
||||
|
||||
/obj/item/flash/emp_act(severity)
|
||||
if(!try_use_flash())
|
||||
return 0
|
||||
for(var/mob/living/carbon/M in viewers(3, null))
|
||||
flash_carbon(M, null, 10, 0)
|
||||
burn_out()
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/flash/proc/terrible_conversion_proc(mob/M, mob/user)
|
||||
if(ishuman(M) && ishuman(user) && M.stat != DEAD)
|
||||
if(user.mind && (user.mind in SSticker.mode.head_revolutionaries))
|
||||
if(M.client)
|
||||
if(M.stat == CONSCIOUS)
|
||||
M.mind_initialize() //give them a mind datum if they don't have one.
|
||||
var/resisted
|
||||
if(!ismindshielded(M))
|
||||
if(user.mind in SSticker.mode.head_revolutionaries)
|
||||
if(SSticker.mode.add_revolutionary(M.mind))
|
||||
times_used -- //Flashes less likely to burn out for headrevs when used for conversion
|
||||
else
|
||||
resisted = 1
|
||||
else
|
||||
resisted = 1
|
||||
|
||||
if(resisted)
|
||||
to_chat(user, "<span class='warning'>This mind seems resistant to the [name]!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>They must be conscious before you can convert [M.p_them()]!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>This mind is so vacant that it is not susceptible to influence!</span>")
|
||||
|
||||
|
||||
/obj/item/flash/cyborg
|
||||
origin_tech = null
|
||||
|
||||
/obj/item/flash/cyborg/attack(mob/living/M, mob/user)
|
||||
..()
|
||||
new /obj/effect/temp_visual/borgflash(get_turf(src))
|
||||
|
||||
/obj/item/flash/cyborg/attack_self(mob/user)
|
||||
..()
|
||||
new /obj/effect/temp_visual/borgflash(get_turf(src))
|
||||
|
||||
/obj/item/flash/cameraflash
|
||||
name = "camera"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
desc = "A polaroid camera. 10 photos left."
|
||||
icon_state = "camera"
|
||||
item_state = "electropack" //spelling, a coders worst enemy. This part gave me trouble for a while.
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = SLOT_BELT
|
||||
can_overcharge = FALSE
|
||||
var/flash_max_charges = 5
|
||||
var/flash_cur_charges = 5
|
||||
var/charge_tick = 0
|
||||
use_sound = 'sound/items/polaroid1.ogg'
|
||||
|
||||
/obj/item/flash/cameraflash/burn_out() //stops from burning out
|
||||
return
|
||||
|
||||
/obj/item/flash/cameraflash/New()
|
||||
..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/flash/cameraflash/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/flash/cameraflash/process() //this and the two parts above are part of the charge system.
|
||||
charge_tick++
|
||||
if(charge_tick < 10)
|
||||
return FALSE
|
||||
charge_tick = 0
|
||||
flash_cur_charges = min(flash_cur_charges+1, flash_max_charges)
|
||||
return TRUE
|
||||
|
||||
/obj/item/flash/cameraflash/attack(mob/living/M, mob/user)
|
||||
if(flash_cur_charges > 0)
|
||||
flash_cur_charges -= 1
|
||||
to_chat(user, "[src] now has [flash_cur_charges] charge\s.")
|
||||
..()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [src] needs time to recharge!</span>")
|
||||
return
|
||||
|
||||
/obj/item/flash/cameraflash/attack_self(mob/living/carbon/user, flag = 0)
|
||||
if(flash_cur_charges > 0)
|
||||
flash_cur_charges -= 1
|
||||
to_chat(user, "[src] now has [flash_cur_charges] charge\s.")
|
||||
..()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [src] needs time to recharge!</span>")
|
||||
return
|
||||
|
||||
/obj/item/flash/memorizer
|
||||
name = "memorizer"
|
||||
desc = "If you see this, you're not likely to remember it any time soon."
|
||||
icon_state = "memorizer"
|
||||
item_state = "nullrod"
|
||||
|
||||
/obj/item/flash/armimplant
|
||||
name = "photon projector"
|
||||
desc = "A high-powered photon projector implant normally used for lighting purposes, but also doubles as a flashbulb weapon. Self-repair protocols fix the flashbulb if it ever burns out."
|
||||
var/flashcd = 20
|
||||
var/overheat = 0
|
||||
var/obj/item/organ/internal/cyberimp/arm/flash/I = null
|
||||
|
||||
/obj/item/flash/armimplant/Destroy()
|
||||
I = null
|
||||
return ..()
|
||||
|
||||
/obj/item/flash/armimplant/burn_out()
|
||||
if(I && I.owner)
|
||||
to_chat(I.owner, "<span class='warning'>Your photon projector implant overheats and deactivates!</span>")
|
||||
I.Retract()
|
||||
overheat = FALSE
|
||||
addtimer(CALLBACK(src, .proc/cooldown), flashcd * 2)
|
||||
|
||||
/obj/item/flash/armimplant/try_use_flash(mob/user = null)
|
||||
if(overheat)
|
||||
if(I && I.owner)
|
||||
to_chat(I.owner, "<span class='warning'>Your photon projector is running too hot to be used again so quickly!</span>")
|
||||
return FALSE
|
||||
overheat = TRUE
|
||||
addtimer(CALLBACK(src, .proc/cooldown), flashcd)
|
||||
playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1)
|
||||
update_icon(1)
|
||||
return TRUE
|
||||
|
||||
/obj/item/flash/armimplant/proc/cooldown()
|
||||
overheat = FALSE
|
||||
|
||||
|
||||
/obj/item/flash/synthetic //just a regular flash now
|
||||
|
||||
@@ -1,398 +1,398 @@
|
||||
/obj/item/flashlight
|
||||
name = "flashlight"
|
||||
desc = "A hand-held emergency light."
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
icon_state = "flashlight"
|
||||
item_state = "flashlight"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
materials = list(MAT_METAL=50, MAT_GLASS=20)
|
||||
actions_types = list(/datum/action/item_action/toggle_light)
|
||||
var/on = FALSE
|
||||
var/brightness_on = 4 //luminosity when on
|
||||
var/togglesound = 'sound/weapons/empty.ogg'
|
||||
|
||||
/obj/item/flashlight/Initialize()
|
||||
. = ..()
|
||||
if(on)
|
||||
icon_state = "[initial(icon_state)]-on"
|
||||
set_light(brightness_on)
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
set_light(0)
|
||||
|
||||
/obj/item/flashlight/proc/update_brightness(var/mob/user = null)
|
||||
if(on)
|
||||
icon_state = "[initial(icon_state)]-on"
|
||||
set_light(brightness_on)
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
set_light(0)
|
||||
|
||||
/obj/item/flashlight/attack_self(mob/user)
|
||||
if(!isturf(user.loc))
|
||||
to_chat(user, "You cannot turn the light on while in this [user.loc].")//To prevent some lighting anomalities.
|
||||
|
||||
return 0
|
||||
on = !on
|
||||
playsound(user, togglesound, 100, 1)
|
||||
update_brightness(user)
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/flashlight/attack(mob/living/M as mob, mob/living/user as mob)
|
||||
add_fingerprint(user)
|
||||
if(on && user.zone_selected == "eyes")
|
||||
|
||||
if(((CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50)) //too dumb to use flashlight properly
|
||||
return ..() //just hit them in the head
|
||||
|
||||
if(!(istype(user, /mob/living/carbon/human) || SSticker) && SSticker.mode.name != "monkey") //don't have dexterity
|
||||
to_chat(user, "<span class='notice'>You don't have the dexterity to do this!</span>")
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = M //mob has protective eyewear
|
||||
if(istype(H) && ((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES)))
|
||||
to_chat(user, "<span class='notice'>You're going to need to remove that [(H.head && H.head.flags_cover & HEADCOVERSEYES) ? "helmet" : (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) ? "mask" : "glasses"] first.</span>")
|
||||
return
|
||||
|
||||
if(M == user) //they're using it on themselves
|
||||
if(M.flash_eyes(visual = 1))
|
||||
M.visible_message("<span class='notice'>[M] directs [src] to [M.p_their()] eyes.</span>", \
|
||||
"<span class='notice'>You wave the light in front of your eyes! Trippy!</span>")
|
||||
else
|
||||
M.visible_message("<span class='notice'>[M] directs [src] to [M.p_their()] eyes.</span>", \
|
||||
"<span class='notice'>You wave the light in front of your eyes.</span>")
|
||||
else
|
||||
|
||||
user.visible_message("<span class='notice'>[user] directs [src] to [M]'s eyes.</span>", \
|
||||
"<span class='notice'>You direct [src] to [M]'s eyes.</span>")
|
||||
|
||||
if(istype(H)) //robots and aliens are unaffected
|
||||
var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes)
|
||||
if(M.stat == DEAD || !eyes || M.disabilities & BLIND) //mob is dead or fully blind
|
||||
to_chat(user, "<span class='notice'>[M]'s pupils are unresponsive to the light!</span>")
|
||||
else if((XRAY in M.mutations) || eyes.see_in_dark >= 8) //The mob's either got the X-RAY vision or has a tapetum lucidum (extreme nightvision, i.e. Vulp/Tajara with COLOURBLIND & their monkey forms).
|
||||
to_chat(user, "<span class='notice'>[M]'s pupils glow eerily!</span>")
|
||||
else //they're okay!
|
||||
if(M.flash_eyes(visual = 1))
|
||||
to_chat(user, "<span class='notice'>[M]'s pupils narrow.</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/flashlight/extinguish_light()
|
||||
if(on)
|
||||
on = FALSE
|
||||
update_brightness()
|
||||
|
||||
/obj/item/flashlight/pen
|
||||
name = "penlight"
|
||||
desc = "A pen-sized light, used by medical staff."
|
||||
icon_state = "penlight"
|
||||
item_state = ""
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
slot_flags = SLOT_BELT | SLOT_EARS
|
||||
flags = CONDUCT
|
||||
brightness_on = 2
|
||||
|
||||
/obj/item/flashlight/seclite
|
||||
name = "seclite"
|
||||
desc = "A robust flashlight used by security."
|
||||
icon_state = "seclite"
|
||||
item_state = "seclite"
|
||||
force = 9 // Not as good as a stun baton.
|
||||
brightness_on = 5 // A little better than the standard flashlight.
|
||||
hitsound = 'sound/weapons/genhit1.ogg'
|
||||
|
||||
/obj/item/flashlight/drone
|
||||
name = "low-power flashlight"
|
||||
desc = "A miniature lamp, that might be used by small robots."
|
||||
icon_state = "penlight"
|
||||
item_state = ""
|
||||
flags = CONDUCT
|
||||
brightness_on = 2
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
// the desk lamps are a bit special
|
||||
/obj/item/flashlight/lamp
|
||||
name = "desk lamp"
|
||||
desc = "A desk lamp with an adjustable mount."
|
||||
icon_state = "lamp"
|
||||
item_state = "lamp"
|
||||
brightness_on = 5
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
flags = CONDUCT
|
||||
materials = list()
|
||||
on = TRUE
|
||||
|
||||
|
||||
// green-shaded desk lamp
|
||||
/obj/item/flashlight/lamp/green
|
||||
desc = "A classic green-shaded desk lamp."
|
||||
icon_state = "lampgreen"
|
||||
item_state = "lampgreen"
|
||||
|
||||
|
||||
|
||||
/obj/item/flashlight/lamp/verb/toggle_light()
|
||||
set name = "Toggle light"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if(!usr.stat)
|
||||
attack_self(usr)
|
||||
|
||||
//Bananalamp
|
||||
/obj/item/flashlight/lamp/bananalamp
|
||||
name = "banana lamp"
|
||||
desc = "Only a clown would think to make a ghetto banana-shaped lamp. Even has a goofy pullstring."
|
||||
icon_state = "bananalamp"
|
||||
item_state = "bananalamp"
|
||||
|
||||
|
||||
// FLARES
|
||||
|
||||
/obj/item/flashlight/flare
|
||||
name = "flare"
|
||||
desc = "A red Nanotrasen issued flare. There are instructions on the side, it reads 'pull cord, make light'."
|
||||
brightness_on = 8
|
||||
light_color = "#ff0000"
|
||||
icon_state = "flare"
|
||||
item_state = "flare"
|
||||
togglesound = 'sound/goonstation/misc/matchstick_light.ogg'
|
||||
var/fuel = 0
|
||||
var/on_damage = 7
|
||||
var/produce_heat = 1500
|
||||
var/fuel_lower = 800
|
||||
var/fuel_upp = 1000
|
||||
|
||||
/obj/item/flashlight/flare/New()
|
||||
fuel = rand(fuel_lower, fuel_upp)
|
||||
..()
|
||||
|
||||
/obj/item/flashlight/flare/process()
|
||||
var/turf/pos = get_turf(src)
|
||||
if(pos && produce_heat)
|
||||
pos.hotspot_expose(produce_heat, 5)
|
||||
fuel = max(fuel - 1, 0)
|
||||
if(!fuel || !on)
|
||||
turn_off()
|
||||
if(!fuel)
|
||||
src.icon_state = "[initial(icon_state)]-empty"
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/flashlight/flare/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/flashlight/flare/proc/turn_off()
|
||||
on = 0
|
||||
src.force = initial(src.force)
|
||||
src.damtype = initial(src.damtype)
|
||||
if(ismob(loc))
|
||||
var/mob/U = loc
|
||||
update_brightness(U)
|
||||
else
|
||||
update_brightness(null)
|
||||
|
||||
/obj/item/flashlight/flare/update_brightness(var/mob/user = null)
|
||||
..()
|
||||
if(on)
|
||||
item_state = "[initial(item_state)]-on"
|
||||
else
|
||||
item_state = "[initial(item_state)]"
|
||||
|
||||
/obj/item/flashlight/flare/attack_self(mob/user)
|
||||
|
||||
// Usual checks
|
||||
if(!fuel)
|
||||
to_chat(user, "<span class='notice'>[src] is out of fuel.</span>")
|
||||
return
|
||||
if(on)
|
||||
to_chat(user, "<span class='notice'>[src] is already on.</span>")
|
||||
return
|
||||
|
||||
. = ..()
|
||||
// All good, turn it on.
|
||||
if(.)
|
||||
user.visible_message("<span class='notice'>[user] activates [src].</span>", "<span class='notice'>You activate [src].</span>")
|
||||
src.force = on_damage
|
||||
src.damtype = "fire"
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
// GLOWSTICKS
|
||||
|
||||
/obj/item/flashlight/flare/glowstick
|
||||
name = "green glowstick"
|
||||
desc = "A military-grade glowstick."
|
||||
brightness_on = 4
|
||||
color = LIGHT_COLOR_GREEN
|
||||
icon_state = "glowstick"
|
||||
item_state = "glowstick"
|
||||
togglesound = 'sound/effects/bone_break_1.ogg'
|
||||
produce_heat = 0
|
||||
fuel_lower = 1600
|
||||
fuel_upp = 2000
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/Initialize()
|
||||
light_color = color
|
||||
..()
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/update_icon()
|
||||
item_state = "glowstick"
|
||||
cut_overlays()
|
||||
if(!fuel)
|
||||
icon_state = "glowstick-empty"
|
||||
cut_overlays()
|
||||
update_brightness(0)
|
||||
else if(on)
|
||||
var/mutable_appearance/glowstick_overlay = mutable_appearance(icon, "glowstick-glow")
|
||||
glowstick_overlay.color = color
|
||||
add_overlay(glowstick_overlay)
|
||||
item_state = "glowstick-on"
|
||||
update_brightness(brightness_on)
|
||||
else
|
||||
icon_state = "glowstick"
|
||||
cut_overlays()
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/red
|
||||
name = "red glowstick"
|
||||
color = LIGHT_COLOR_RED
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/blue
|
||||
name = "blue glowstick"
|
||||
color = LIGHT_COLOR_BLUE
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/orange
|
||||
name = "orange glowstick"
|
||||
color = LIGHT_COLOR_ORANGE
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/yellow
|
||||
name = "yellow glowstick"
|
||||
color = LIGHT_COLOR_YELLOW
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/pink
|
||||
name = "pink glowstick"
|
||||
color = LIGHT_COLOR_PINK
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/emergency
|
||||
name = "emergency glowstick"
|
||||
desc = "A cheap looking, mass produced glowstick. You can practically feel it was made on a tight budget."
|
||||
color = LIGHT_COLOR_BLUE
|
||||
fuel_lower = 30
|
||||
fuel_upp = 90
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/random
|
||||
name = "random colored glowstick"
|
||||
icon_state = "random_glowstick"
|
||||
color = null
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/random/Initialize()
|
||||
. = ..()
|
||||
var/T = pick(typesof(/obj/item/flashlight/flare/glowstick) - /obj/item/flashlight/flare/glowstick/random - /obj/item/flashlight/flare/glowstick/emergency)
|
||||
new T(loc)
|
||||
qdel(src) // return INITIALIZE_HINT_QDEL <-- Doesn't work
|
||||
|
||||
/obj/item/flashlight/flare/extinguish_light()
|
||||
visible_message("<span class='danger'>[src] dims slightly before scattering the shadows around it.</span>")
|
||||
|
||||
/obj/item/flashlight/flare/torch
|
||||
name = "torch"
|
||||
desc = "A torch fashioned from some leaves and a log."
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
brightness_on = 7
|
||||
icon_state = "torch"
|
||||
item_state = "torch"
|
||||
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
|
||||
light_color = LIGHT_COLOR_ORANGE
|
||||
on_damage = 10
|
||||
|
||||
/obj/item/flashlight/slime
|
||||
gender = PLURAL
|
||||
name = "glowing slime extract"
|
||||
desc = "A glowing ball of what appears to be amber."
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
icon_state = "floor1" //not a slime extract sprite but... something close enough!
|
||||
item_state = "slime"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
brightness_on = 6
|
||||
light_color = "#FFBF00"
|
||||
materials = list()
|
||||
on = TRUE //Bio-luminesence has one setting, on.
|
||||
|
||||
/obj/item/flashlight/slime/New()
|
||||
..()
|
||||
set_light(brightness_on)
|
||||
spawn(1) //Might be sloppy, but seems to be necessary to prevent further runtimes and make these work as intended... don't judge me!
|
||||
update_brightness()
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/item/flashlight/slime/attack_self(mob/user)
|
||||
return //Bio-luminescence does not toggle.
|
||||
|
||||
/obj/item/flashlight/slime/extinguish_light()
|
||||
visible_message("<span class='danger'>[src] dims slightly before scattering the shadows around it.</span>")
|
||||
|
||||
/obj/item/flashlight/emp
|
||||
origin_tech = "magnets=3;syndicate=1"
|
||||
|
||||
var/emp_max_charges = 4
|
||||
var/emp_cur_charges = 4
|
||||
var/charge_tick = 0
|
||||
|
||||
|
||||
/obj/item/flashlight/emp/New()
|
||||
..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/flashlight/emp/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/flashlight/emp/process()
|
||||
charge_tick++
|
||||
if(charge_tick < 10)
|
||||
return FALSE
|
||||
charge_tick = 0
|
||||
emp_cur_charges = min(emp_cur_charges+1, emp_max_charges)
|
||||
return TRUE
|
||||
|
||||
/obj/item/flashlight/emp/attack(mob/living/M as mob, mob/living/user as mob)
|
||||
if(on && user.zone_selected == "eyes") // call original attack proc only if aiming at the eyes
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/flashlight/emp/afterattack(atom/A as mob|obj, mob/user, proximity)
|
||||
if(!proximity) return
|
||||
if(emp_cur_charges > 0)
|
||||
emp_cur_charges -= 1
|
||||
A.visible_message("<span class='danger'>[user] blinks \the [src] at \the [A].", \
|
||||
"<span class='userdanger'>[user] blinks \the [src] at \the [A].")
|
||||
if(ismob(A))
|
||||
var/mob/M = A
|
||||
add_attack_logs(user, M, "Hit with EMP-light")
|
||||
to_chat(user, "[src] now has [emp_cur_charges] charge\s.")
|
||||
A.emp_act(1)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [src] needs time to recharge!</span>")
|
||||
return
|
||||
|
||||
/obj/item/flashlight/spotlight //invisible lighting source
|
||||
name = "disco light"
|
||||
desc = "Groovy..."
|
||||
icon_state = null
|
||||
light_color = null
|
||||
brightness_on = 0
|
||||
light_range = 0
|
||||
light_power = 10
|
||||
alpha = 0
|
||||
layer = 0
|
||||
on = TRUE
|
||||
anchored = TRUE
|
||||
var/range = null
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
/obj/item/flashlight
|
||||
name = "flashlight"
|
||||
desc = "A hand-held emergency light."
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
icon_state = "flashlight"
|
||||
item_state = "flashlight"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
materials = list(MAT_METAL=50, MAT_GLASS=20)
|
||||
actions_types = list(/datum/action/item_action/toggle_light)
|
||||
var/on = FALSE
|
||||
var/brightness_on = 4 //luminosity when on
|
||||
var/togglesound = 'sound/weapons/empty.ogg'
|
||||
|
||||
/obj/item/flashlight/Initialize()
|
||||
. = ..()
|
||||
if(on)
|
||||
icon_state = "[initial(icon_state)]-on"
|
||||
set_light(brightness_on)
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
set_light(0)
|
||||
|
||||
/obj/item/flashlight/proc/update_brightness(var/mob/user = null)
|
||||
if(on)
|
||||
icon_state = "[initial(icon_state)]-on"
|
||||
set_light(brightness_on)
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
set_light(0)
|
||||
|
||||
/obj/item/flashlight/attack_self(mob/user)
|
||||
if(!isturf(user.loc))
|
||||
to_chat(user, "You cannot turn the light on while in this [user.loc].")//To prevent some lighting anomalities.
|
||||
|
||||
return 0
|
||||
on = !on
|
||||
playsound(user, togglesound, 100, 1)
|
||||
update_brightness(user)
|
||||
for(var/X in actions)
|
||||
var/datum/action/A = X
|
||||
A.UpdateButtonIcon()
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/flashlight/attack(mob/living/M as mob, mob/living/user as mob)
|
||||
add_fingerprint(user)
|
||||
if(on && user.zone_selected == "eyes")
|
||||
|
||||
if(((CLUMSY in user.mutations) || user.getBrainLoss() >= 60) && prob(50)) //too dumb to use flashlight properly
|
||||
return ..() //just hit them in the head
|
||||
|
||||
if(!(istype(user, /mob/living/carbon/human) || SSticker) && SSticker.mode.name != "monkey") //don't have dexterity
|
||||
to_chat(user, "<span class='notice'>You don't have the dexterity to do this!</span>")
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = M //mob has protective eyewear
|
||||
if(istype(H) && ((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES)))
|
||||
to_chat(user, "<span class='notice'>You're going to need to remove that [(H.head && H.head.flags_cover & HEADCOVERSEYES) ? "helmet" : (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) ? "mask" : "glasses"] first.</span>")
|
||||
return
|
||||
|
||||
if(M == user) //they're using it on themselves
|
||||
if(M.flash_eyes(visual = 1))
|
||||
M.visible_message("<span class='notice'>[M] directs [src] to [M.p_their()] eyes.</span>", \
|
||||
"<span class='notice'>You wave the light in front of your eyes! Trippy!</span>")
|
||||
else
|
||||
M.visible_message("<span class='notice'>[M] directs [src] to [M.p_their()] eyes.</span>", \
|
||||
"<span class='notice'>You wave the light in front of your eyes.</span>")
|
||||
else
|
||||
|
||||
user.visible_message("<span class='notice'>[user] directs [src] to [M]'s eyes.</span>", \
|
||||
"<span class='notice'>You direct [src] to [M]'s eyes.</span>")
|
||||
|
||||
if(istype(H)) //robots and aliens are unaffected
|
||||
var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes)
|
||||
if(M.stat == DEAD || !eyes || M.disabilities & BLIND) //mob is dead or fully blind
|
||||
to_chat(user, "<span class='notice'>[M]'s pupils are unresponsive to the light!</span>")
|
||||
else if((XRAY in M.mutations) || eyes.see_in_dark >= 8) //The mob's either got the X-RAY vision or has a tapetum lucidum (extreme nightvision, i.e. Vulp/Tajara with COLOURBLIND & their monkey forms).
|
||||
to_chat(user, "<span class='notice'>[M]'s pupils glow eerily!</span>")
|
||||
else //they're okay!
|
||||
if(M.flash_eyes(visual = 1))
|
||||
to_chat(user, "<span class='notice'>[M]'s pupils narrow.</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/flashlight/extinguish_light()
|
||||
if(on)
|
||||
on = FALSE
|
||||
update_brightness()
|
||||
|
||||
/obj/item/flashlight/pen
|
||||
name = "penlight"
|
||||
desc = "A pen-sized light, used by medical staff."
|
||||
icon_state = "penlight"
|
||||
item_state = ""
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
slot_flags = SLOT_BELT | SLOT_EARS
|
||||
flags = CONDUCT
|
||||
brightness_on = 2
|
||||
|
||||
/obj/item/flashlight/seclite
|
||||
name = "seclite"
|
||||
desc = "A robust flashlight used by security."
|
||||
icon_state = "seclite"
|
||||
item_state = "seclite"
|
||||
force = 9 // Not as good as a stun baton.
|
||||
brightness_on = 5 // A little better than the standard flashlight.
|
||||
hitsound = 'sound/weapons/genhit1.ogg'
|
||||
|
||||
/obj/item/flashlight/drone
|
||||
name = "low-power flashlight"
|
||||
desc = "A miniature lamp, that might be used by small robots."
|
||||
icon_state = "penlight"
|
||||
item_state = ""
|
||||
flags = CONDUCT
|
||||
brightness_on = 2
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
// the desk lamps are a bit special
|
||||
/obj/item/flashlight/lamp
|
||||
name = "desk lamp"
|
||||
desc = "A desk lamp with an adjustable mount."
|
||||
icon_state = "lamp"
|
||||
item_state = "lamp"
|
||||
brightness_on = 5
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
flags = CONDUCT
|
||||
materials = list()
|
||||
on = TRUE
|
||||
|
||||
|
||||
// green-shaded desk lamp
|
||||
/obj/item/flashlight/lamp/green
|
||||
desc = "A classic green-shaded desk lamp."
|
||||
icon_state = "lampgreen"
|
||||
item_state = "lampgreen"
|
||||
|
||||
|
||||
|
||||
/obj/item/flashlight/lamp/verb/toggle_light()
|
||||
set name = "Toggle light"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if(!usr.stat)
|
||||
attack_self(usr)
|
||||
|
||||
//Bananalamp
|
||||
/obj/item/flashlight/lamp/bananalamp
|
||||
name = "banana lamp"
|
||||
desc = "Only a clown would think to make a ghetto banana-shaped lamp. Even has a goofy pullstring."
|
||||
icon_state = "bananalamp"
|
||||
item_state = "bananalamp"
|
||||
|
||||
|
||||
// FLARES
|
||||
|
||||
/obj/item/flashlight/flare
|
||||
name = "flare"
|
||||
desc = "A red Nanotrasen issued flare. There are instructions on the side, it reads 'pull cord, make light'."
|
||||
brightness_on = 8
|
||||
light_color = "#ff0000"
|
||||
icon_state = "flare"
|
||||
item_state = "flare"
|
||||
togglesound = 'sound/goonstation/misc/matchstick_light.ogg'
|
||||
var/fuel = 0
|
||||
var/on_damage = 7
|
||||
var/produce_heat = 1500
|
||||
var/fuel_lower = 800
|
||||
var/fuel_upp = 1000
|
||||
|
||||
/obj/item/flashlight/flare/New()
|
||||
fuel = rand(fuel_lower, fuel_upp)
|
||||
..()
|
||||
|
||||
/obj/item/flashlight/flare/process()
|
||||
var/turf/pos = get_turf(src)
|
||||
if(pos && produce_heat)
|
||||
pos.hotspot_expose(produce_heat, 5)
|
||||
fuel = max(fuel - 1, 0)
|
||||
if(!fuel || !on)
|
||||
turn_off()
|
||||
if(!fuel)
|
||||
src.icon_state = "[initial(icon_state)]-empty"
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/flashlight/flare/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/flashlight/flare/proc/turn_off()
|
||||
on = 0
|
||||
src.force = initial(src.force)
|
||||
src.damtype = initial(src.damtype)
|
||||
if(ismob(loc))
|
||||
var/mob/U = loc
|
||||
update_brightness(U)
|
||||
else
|
||||
update_brightness(null)
|
||||
|
||||
/obj/item/flashlight/flare/update_brightness(var/mob/user = null)
|
||||
..()
|
||||
if(on)
|
||||
item_state = "[initial(item_state)]-on"
|
||||
else
|
||||
item_state = "[initial(item_state)]"
|
||||
|
||||
/obj/item/flashlight/flare/attack_self(mob/user)
|
||||
|
||||
// Usual checks
|
||||
if(!fuel)
|
||||
to_chat(user, "<span class='notice'>[src] is out of fuel.</span>")
|
||||
return
|
||||
if(on)
|
||||
to_chat(user, "<span class='notice'>[src] is already on.</span>")
|
||||
return
|
||||
|
||||
. = ..()
|
||||
// All good, turn it on.
|
||||
if(.)
|
||||
user.visible_message("<span class='notice'>[user] activates [src].</span>", "<span class='notice'>You activate [src].</span>")
|
||||
src.force = on_damage
|
||||
src.damtype = "fire"
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
// GLOWSTICKS
|
||||
|
||||
/obj/item/flashlight/flare/glowstick
|
||||
name = "green glowstick"
|
||||
desc = "A military-grade glowstick."
|
||||
brightness_on = 4
|
||||
color = LIGHT_COLOR_GREEN
|
||||
icon_state = "glowstick"
|
||||
item_state = "glowstick"
|
||||
togglesound = 'sound/effects/bone_break_1.ogg'
|
||||
produce_heat = 0
|
||||
fuel_lower = 1600
|
||||
fuel_upp = 2000
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/Initialize()
|
||||
light_color = color
|
||||
..()
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/update_icon()
|
||||
item_state = "glowstick"
|
||||
cut_overlays()
|
||||
if(!fuel)
|
||||
icon_state = "glowstick-empty"
|
||||
cut_overlays()
|
||||
update_brightness(0)
|
||||
else if(on)
|
||||
var/mutable_appearance/glowstick_overlay = mutable_appearance(icon, "glowstick-glow")
|
||||
glowstick_overlay.color = color
|
||||
add_overlay(glowstick_overlay)
|
||||
item_state = "glowstick-on"
|
||||
update_brightness(brightness_on)
|
||||
else
|
||||
icon_state = "glowstick"
|
||||
cut_overlays()
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/red
|
||||
name = "red glowstick"
|
||||
color = LIGHT_COLOR_RED
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/blue
|
||||
name = "blue glowstick"
|
||||
color = LIGHT_COLOR_BLUE
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/orange
|
||||
name = "orange glowstick"
|
||||
color = LIGHT_COLOR_ORANGE
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/yellow
|
||||
name = "yellow glowstick"
|
||||
color = LIGHT_COLOR_YELLOW
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/pink
|
||||
name = "pink glowstick"
|
||||
color = LIGHT_COLOR_PINK
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/emergency
|
||||
name = "emergency glowstick"
|
||||
desc = "A cheap looking, mass produced glowstick. You can practically feel it was made on a tight budget."
|
||||
color = LIGHT_COLOR_BLUE
|
||||
fuel_lower = 30
|
||||
fuel_upp = 90
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/random
|
||||
name = "random colored glowstick"
|
||||
icon_state = "random_glowstick"
|
||||
color = null
|
||||
|
||||
/obj/item/flashlight/flare/glowstick/random/Initialize()
|
||||
. = ..()
|
||||
var/T = pick(typesof(/obj/item/flashlight/flare/glowstick) - /obj/item/flashlight/flare/glowstick/random - /obj/item/flashlight/flare/glowstick/emergency)
|
||||
new T(loc)
|
||||
qdel(src) // return INITIALIZE_HINT_QDEL <-- Doesn't work
|
||||
|
||||
/obj/item/flashlight/flare/extinguish_light()
|
||||
visible_message("<span class='danger'>[src] dims slightly before scattering the shadows around it.</span>")
|
||||
|
||||
/obj/item/flashlight/flare/torch
|
||||
name = "torch"
|
||||
desc = "A torch fashioned from some leaves and a log."
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
brightness_on = 7
|
||||
icon_state = "torch"
|
||||
item_state = "torch"
|
||||
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
|
||||
light_color = LIGHT_COLOR_ORANGE
|
||||
on_damage = 10
|
||||
|
||||
/obj/item/flashlight/slime
|
||||
gender = PLURAL
|
||||
name = "glowing slime extract"
|
||||
desc = "A glowing ball of what appears to be amber."
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
icon_state = "floor1" //not a slime extract sprite but... something close enough!
|
||||
item_state = "slime"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
brightness_on = 6
|
||||
light_color = "#FFBF00"
|
||||
materials = list()
|
||||
on = TRUE //Bio-luminesence has one setting, on.
|
||||
|
||||
/obj/item/flashlight/slime/New()
|
||||
..()
|
||||
set_light(brightness_on)
|
||||
spawn(1) //Might be sloppy, but seems to be necessary to prevent further runtimes and make these work as intended... don't judge me!
|
||||
update_brightness()
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/item/flashlight/slime/attack_self(mob/user)
|
||||
return //Bio-luminescence does not toggle.
|
||||
|
||||
/obj/item/flashlight/slime/extinguish_light()
|
||||
visible_message("<span class='danger'>[src] dims slightly before scattering the shadows around it.</span>")
|
||||
|
||||
/obj/item/flashlight/emp
|
||||
origin_tech = "magnets=3;syndicate=1"
|
||||
|
||||
var/emp_max_charges = 4
|
||||
var/emp_cur_charges = 4
|
||||
var/charge_tick = 0
|
||||
|
||||
|
||||
/obj/item/flashlight/emp/New()
|
||||
..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/flashlight/emp/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/flashlight/emp/process()
|
||||
charge_tick++
|
||||
if(charge_tick < 10)
|
||||
return FALSE
|
||||
charge_tick = 0
|
||||
emp_cur_charges = min(emp_cur_charges+1, emp_max_charges)
|
||||
return TRUE
|
||||
|
||||
/obj/item/flashlight/emp/attack(mob/living/M as mob, mob/living/user as mob)
|
||||
if(on && user.zone_selected == "eyes") // call original attack proc only if aiming at the eyes
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/flashlight/emp/afterattack(atom/A as mob|obj, mob/user, proximity)
|
||||
if(!proximity) return
|
||||
if(emp_cur_charges > 0)
|
||||
emp_cur_charges -= 1
|
||||
A.visible_message("<span class='danger'>[user] blinks \the [src] at \the [A].", \
|
||||
"<span class='userdanger'>[user] blinks \the [src] at \the [A].")
|
||||
if(ismob(A))
|
||||
var/mob/M = A
|
||||
add_attack_logs(user, M, "Hit with EMP-light")
|
||||
to_chat(user, "[src] now has [emp_cur_charges] charge\s.")
|
||||
A.emp_act(1)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [src] needs time to recharge!</span>")
|
||||
return
|
||||
|
||||
/obj/item/flashlight/spotlight //invisible lighting source
|
||||
name = "disco light"
|
||||
desc = "Groovy..."
|
||||
icon_state = null
|
||||
light_color = null
|
||||
brightness_on = 0
|
||||
light_range = 0
|
||||
light_power = 10
|
||||
alpha = 0
|
||||
layer = 0
|
||||
on = TRUE
|
||||
anchored = TRUE
|
||||
var/range = null
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
@@ -88,4 +88,4 @@
|
||||
/obj/item/handheld_defibrillator/proc/recharge()
|
||||
cooldown = FALSE
|
||||
icon_state = "[icon_base]-on"
|
||||
playsound(loc, "sound/weapons/flash.ogg", 75, 1)
|
||||
playsound(loc, "sound/weapons/flash.ogg", 75, 1)
|
||||
|
||||
@@ -189,4 +189,4 @@
|
||||
/obj/item/stack/tape_roll = 5)
|
||||
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
|
||||
time = 80
|
||||
category = CAT_MISC
|
||||
category = CAT_MISC
|
||||
|
||||
@@ -1,269 +1,269 @@
|
||||
|
||||
// Light Replacer (LR)
|
||||
//
|
||||
// ABOUT THE DEVICE
|
||||
//
|
||||
// This is a device supposedly to be used by Janitors and Janitor Cyborgs which will
|
||||
// allow them to easily replace lights. This was mostly designed for Janitor Cyborgs since
|
||||
// they don't have hands or a way to replace lightbulbs.
|
||||
//
|
||||
// HOW IT WORKS
|
||||
//
|
||||
// You attack a light fixture with it, if the light fixture is broken it will replace the
|
||||
// light fixture with a working light; the broken light is then placed on the floor for the
|
||||
// user to then pickup with a trash bag. If it's empty then it will just place a light in the fixture.
|
||||
//
|
||||
// HOW TO REFILL THE DEVICE
|
||||
//
|
||||
// It will need to be manually refilled with lights.
|
||||
// If it's part of a robot module, it will charge when the Robot is inside a Recharge Station.
|
||||
//
|
||||
// EMAGGED FEATURES
|
||||
//
|
||||
// NOTICE: The Cyborg cannot use the emagged Light Replacer and the light's explosion was nerfed. It cannot create holes in the station anymore.
|
||||
//
|
||||
// I'm not sure everyone will react the emag's features so please say what your opinions are of it.
|
||||
//
|
||||
// When emagged it will rig every light it replaces, which will explode when the light is on.
|
||||
// This is VERY noticable, even the device's name changes when you emag it so if anyone
|
||||
// examines you when you're holding it in your hand, you will be discovered.
|
||||
// It will also be very obvious who is setting all these lights off, since only Janitor Borgs and Janitors have easy
|
||||
// access to them, and only one of them can emag their device.
|
||||
//
|
||||
// The explosion cannot insta-kill anyone with 30% or more health.
|
||||
|
||||
#define LIGHT_OK 0
|
||||
#define LIGHT_EMPTY 1
|
||||
#define LIGHT_BROKEN 2
|
||||
#define LIGHT_BURNED 3
|
||||
|
||||
|
||||
/obj/item/lightreplacer
|
||||
|
||||
name = "light replacer"
|
||||
desc = "A device to automatically replace lights. Refill with broken or working light bulbs, or sheets of glass."
|
||||
|
||||
icon = 'icons/obj/janitor.dmi'
|
||||
icon_state = "lightreplacer0"
|
||||
item_state = "electronic"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "magnets=3;engineering=4"
|
||||
force = 8
|
||||
|
||||
var/emagged = FALSE
|
||||
var/max_uses = 20
|
||||
var/uses = 10
|
||||
// How much to increase per each glass?
|
||||
var/increment = 5
|
||||
// How much to take from the glass?
|
||||
var/decrement = 1
|
||||
var/charge = 1
|
||||
|
||||
// Eating used bulbs gives us bulb shards
|
||||
var/bulb_shards = 0
|
||||
// when we get this many shards, we get a free bulb.
|
||||
var/shards_required = 4
|
||||
|
||||
|
||||
/obj/item/lightreplacer/examine(mob/user)
|
||||
. = ..()
|
||||
. += status_string()
|
||||
|
||||
/obj/item/lightreplacer/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/stack/sheet/glass))
|
||||
var/obj/item/stack/sheet/glass/G = I
|
||||
if(uses >= max_uses)
|
||||
to_chat(user, "<span class='warning'>[src] is full.</span>")
|
||||
return
|
||||
else if(G.use(decrement))
|
||||
AddUses(increment)
|
||||
to_chat(user, "<span class='notice'>You insert a piece of glass into [src]. You have [uses] light\s remaining.</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need one sheet of glass to replace lights!</span>")
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/shard))
|
||||
if(uses >= max_uses)
|
||||
to_chat(user, "<span class='warning'>[src] is full.</span>")
|
||||
return
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
AddUses(round(increment * 0.75))
|
||||
to_chat(user, "<span class='notice'>You insert a shard of glass into [src]. You have [uses] light\s remaining.</span>")
|
||||
qdel(I)
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/light))
|
||||
var/obj/item/light/L = I
|
||||
if(L.status == 0) // LIGHT OKAY
|
||||
if(uses < max_uses)
|
||||
if(!user.unEquip(L))
|
||||
return
|
||||
AddUses(1)
|
||||
qdel(L)
|
||||
else
|
||||
if(!user.unEquip(L))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You insert [L] into [src].</span>")
|
||||
AddShards(1, user)
|
||||
qdel(L)
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/storage))
|
||||
var/obj/item/storage/S = I
|
||||
var/found_lightbulbs = FALSE
|
||||
var/replaced_something = TRUE
|
||||
|
||||
for(var/obj/item/IT in S.contents)
|
||||
if(istype(IT, /obj/item/light))
|
||||
var/obj/item/light/L = IT
|
||||
found_lightbulbs = TRUE
|
||||
if(uses >= max_uses)
|
||||
break
|
||||
if(L.status == LIGHT_OK)
|
||||
replaced_something = TRUE
|
||||
AddUses(1)
|
||||
qdel(L)
|
||||
|
||||
else if(L.status == LIGHT_BROKEN || L.status == LIGHT_BURNED)
|
||||
replaced_something = TRUE
|
||||
AddShards(1, user)
|
||||
qdel(L)
|
||||
|
||||
if(!found_lightbulbs)
|
||||
to_chat(user, "<span class='warning'>[S] contains no bulbs.</span>")
|
||||
return
|
||||
|
||||
if(!replaced_something && uses == max_uses)
|
||||
to_chat(user, "<span class='warning'>[src] is full!</span>")
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You fill [src] with lights from [S]. " + status_string() + "</span>")
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/lightreplacer/emag_act(user as mob)
|
||||
if(!emagged)
|
||||
Emag()
|
||||
|
||||
/obj/item/lightreplacer/attack_self(mob/user)
|
||||
for(var/obj/machinery/light/target in user.loc)
|
||||
ReplaceLight(target, user)
|
||||
to_chat(user, status_string())
|
||||
|
||||
/obj/item/lightreplacer/update_icon()
|
||||
icon_state = "lightreplacer[emagged]"
|
||||
|
||||
/obj/item/lightreplacer/proc/status_string()
|
||||
return "It has [uses] light\s remaining (plus [bulb_shards] fragment\s)."
|
||||
|
||||
/obj/item/lightreplacer/proc/Use(mob/user)
|
||||
playsound(loc, 'sound/machines/click.ogg', 50, TRUE)
|
||||
AddUses(-1)
|
||||
return 1
|
||||
|
||||
// Negative numbers will subtract
|
||||
/obj/item/lightreplacer/proc/AddUses(amount = 1)
|
||||
uses = Clamp(uses + amount, 0, max_uses)
|
||||
|
||||
/obj/item/lightreplacer/proc/AddShards(amount = 1, user)
|
||||
bulb_shards += amount
|
||||
var/new_bulbs = round(bulb_shards / shards_required)
|
||||
if(new_bulbs > 0)
|
||||
AddUses(new_bulbs)
|
||||
bulb_shards = bulb_shards % shards_required
|
||||
if(new_bulbs != 0)
|
||||
to_chat(user, "<span class='notice'>[src] has fabricated a new bulb from the broken glass it has stored. It now has [uses] uses.</span>")
|
||||
playsound(loc, 'sound/machines/ding.ogg', 50, TRUE)
|
||||
return new_bulbs
|
||||
|
||||
/obj/item/lightreplacer/proc/Charge(var/mob/user)
|
||||
charge += 1
|
||||
if(charge > 3)
|
||||
AddUses(1)
|
||||
charge = 1
|
||||
|
||||
/obj/item/lightreplacer/proc/ReplaceLight(obj/machinery/light/target, mob/living/U)
|
||||
if(target.status != LIGHT_OK)
|
||||
if(CanUse(U))
|
||||
if(!Use(U))
|
||||
return
|
||||
to_chat(U, "<span class='notice'>You replace [target.fitting] with [src].</span>")
|
||||
|
||||
if(target.status != LIGHT_EMPTY)
|
||||
AddShards(1, U)
|
||||
target.status = LIGHT_EMPTY
|
||||
target.update()
|
||||
|
||||
var/obj/item/light/L2 = new target.light_type()
|
||||
|
||||
target.status = L2.status
|
||||
target.switchcount = L2.switchcount
|
||||
target.rigged = emagged
|
||||
target.brightness_range = L2.brightness_range
|
||||
target.brightness_power = L2.brightness_power
|
||||
target.brightness_color = L2.brightness_color
|
||||
target.on = target.has_power()
|
||||
target.update()
|
||||
qdel(L2)
|
||||
|
||||
if(target.on && target.rigged)
|
||||
target.explode()
|
||||
return
|
||||
|
||||
else
|
||||
to_chat(U, "[src]'s refill light blinks red.")
|
||||
return
|
||||
else
|
||||
to_chat(U, "<span class='warning'>There is a working [target.fitting] already inserted!</span>")
|
||||
return
|
||||
|
||||
/obj/item/lightreplacer/proc/Emag()
|
||||
emagged = !emagged
|
||||
playsound(loc, "sparks", 100, TRUE)
|
||||
if(emagged)
|
||||
name = "shortcircuited [initial(name)]"
|
||||
else
|
||||
name = initial(name)
|
||||
update_icon()
|
||||
|
||||
/obj/item/lightreplacer/proc/CanUse(mob/living/user)
|
||||
add_fingerprint(user)
|
||||
if(uses > 0)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/item/lightreplacer/afterattack(atom/T, mob/U, proximity)
|
||||
. = ..()
|
||||
if(!proximity)
|
||||
return
|
||||
if(!isturf(T))
|
||||
return
|
||||
|
||||
var/used = FALSE
|
||||
for(var/atom/A in T)
|
||||
if(!CanUse(U))
|
||||
break
|
||||
used = TRUE
|
||||
if(istype(A, /obj/machinery/light))
|
||||
ReplaceLight(A, U)
|
||||
|
||||
if(!used)
|
||||
to_chat(U, "[src]'s refill light blinks red.")
|
||||
|
||||
/obj/item/lightreplacer/proc/janicart_insert(mob/user, obj/structure/janitorialcart/J)
|
||||
J.put_in_cart(src, user)
|
||||
J.myreplacer = src
|
||||
J.update_icon()
|
||||
|
||||
/obj/item/lightreplacer/cyborg/janicart_insert(mob/user, obj/structure/janitorialcart/J)
|
||||
return
|
||||
|
||||
#undef LIGHT_OK
|
||||
#undef LIGHT_EMPTY
|
||||
#undef LIGHT_BROKEN
|
||||
#undef LIGHT_BURNED
|
||||
|
||||
// Light Replacer (LR)
|
||||
//
|
||||
// ABOUT THE DEVICE
|
||||
//
|
||||
// This is a device supposedly to be used by Janitors and Janitor Cyborgs which will
|
||||
// allow them to easily replace lights. This was mostly designed for Janitor Cyborgs since
|
||||
// they don't have hands or a way to replace lightbulbs.
|
||||
//
|
||||
// HOW IT WORKS
|
||||
//
|
||||
// You attack a light fixture with it, if the light fixture is broken it will replace the
|
||||
// light fixture with a working light; the broken light is then placed on the floor for the
|
||||
// user to then pickup with a trash bag. If it's empty then it will just place a light in the fixture.
|
||||
//
|
||||
// HOW TO REFILL THE DEVICE
|
||||
//
|
||||
// It will need to be manually refilled with lights.
|
||||
// If it's part of a robot module, it will charge when the Robot is inside a Recharge Station.
|
||||
//
|
||||
// EMAGGED FEATURES
|
||||
//
|
||||
// NOTICE: The Cyborg cannot use the emagged Light Replacer and the light's explosion was nerfed. It cannot create holes in the station anymore.
|
||||
//
|
||||
// I'm not sure everyone will react the emag's features so please say what your opinions are of it.
|
||||
//
|
||||
// When emagged it will rig every light it replaces, which will explode when the light is on.
|
||||
// This is VERY noticable, even the device's name changes when you emag it so if anyone
|
||||
// examines you when you're holding it in your hand, you will be discovered.
|
||||
// It will also be very obvious who is setting all these lights off, since only Janitor Borgs and Janitors have easy
|
||||
// access to them, and only one of them can emag their device.
|
||||
//
|
||||
// The explosion cannot insta-kill anyone with 30% or more health.
|
||||
|
||||
#define LIGHT_OK 0
|
||||
#define LIGHT_EMPTY 1
|
||||
#define LIGHT_BROKEN 2
|
||||
#define LIGHT_BURNED 3
|
||||
|
||||
|
||||
/obj/item/lightreplacer
|
||||
|
||||
name = "light replacer"
|
||||
desc = "A device to automatically replace lights. Refill with broken or working light bulbs, or sheets of glass."
|
||||
|
||||
icon = 'icons/obj/janitor.dmi'
|
||||
icon_state = "lightreplacer0"
|
||||
item_state = "electronic"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "magnets=3;engineering=4"
|
||||
force = 8
|
||||
|
||||
var/emagged = FALSE
|
||||
var/max_uses = 20
|
||||
var/uses = 10
|
||||
// How much to increase per each glass?
|
||||
var/increment = 5
|
||||
// How much to take from the glass?
|
||||
var/decrement = 1
|
||||
var/charge = 1
|
||||
|
||||
// Eating used bulbs gives us bulb shards
|
||||
var/bulb_shards = 0
|
||||
// when we get this many shards, we get a free bulb.
|
||||
var/shards_required = 4
|
||||
|
||||
|
||||
/obj/item/lightreplacer/examine(mob/user)
|
||||
. = ..()
|
||||
. += status_string()
|
||||
|
||||
/obj/item/lightreplacer/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/stack/sheet/glass))
|
||||
var/obj/item/stack/sheet/glass/G = I
|
||||
if(uses >= max_uses)
|
||||
to_chat(user, "<span class='warning'>[src] is full.</span>")
|
||||
return
|
||||
else if(G.use(decrement))
|
||||
AddUses(increment)
|
||||
to_chat(user, "<span class='notice'>You insert a piece of glass into [src]. You have [uses] light\s remaining.</span>")
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need one sheet of glass to replace lights!</span>")
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/shard))
|
||||
if(uses >= max_uses)
|
||||
to_chat(user, "<span class='warning'>[src] is full.</span>")
|
||||
return
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
AddUses(round(increment * 0.75))
|
||||
to_chat(user, "<span class='notice'>You insert a shard of glass into [src]. You have [uses] light\s remaining.</span>")
|
||||
qdel(I)
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/light))
|
||||
var/obj/item/light/L = I
|
||||
if(L.status == 0) // LIGHT OKAY
|
||||
if(uses < max_uses)
|
||||
if(!user.unEquip(L))
|
||||
return
|
||||
AddUses(1)
|
||||
qdel(L)
|
||||
else
|
||||
if(!user.unEquip(L))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You insert [L] into [src].</span>")
|
||||
AddShards(1, user)
|
||||
qdel(L)
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/storage))
|
||||
var/obj/item/storage/S = I
|
||||
var/found_lightbulbs = FALSE
|
||||
var/replaced_something = TRUE
|
||||
|
||||
for(var/obj/item/IT in S.contents)
|
||||
if(istype(IT, /obj/item/light))
|
||||
var/obj/item/light/L = IT
|
||||
found_lightbulbs = TRUE
|
||||
if(uses >= max_uses)
|
||||
break
|
||||
if(L.status == LIGHT_OK)
|
||||
replaced_something = TRUE
|
||||
AddUses(1)
|
||||
qdel(L)
|
||||
|
||||
else if(L.status == LIGHT_BROKEN || L.status == LIGHT_BURNED)
|
||||
replaced_something = TRUE
|
||||
AddShards(1, user)
|
||||
qdel(L)
|
||||
|
||||
if(!found_lightbulbs)
|
||||
to_chat(user, "<span class='warning'>[S] contains no bulbs.</span>")
|
||||
return
|
||||
|
||||
if(!replaced_something && uses == max_uses)
|
||||
to_chat(user, "<span class='warning'>[src] is full!</span>")
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You fill [src] with lights from [S]. " + status_string() + "</span>")
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/lightreplacer/emag_act(user as mob)
|
||||
if(!emagged)
|
||||
Emag()
|
||||
|
||||
/obj/item/lightreplacer/attack_self(mob/user)
|
||||
for(var/obj/machinery/light/target in user.loc)
|
||||
ReplaceLight(target, user)
|
||||
to_chat(user, status_string())
|
||||
|
||||
/obj/item/lightreplacer/update_icon()
|
||||
icon_state = "lightreplacer[emagged]"
|
||||
|
||||
/obj/item/lightreplacer/proc/status_string()
|
||||
return "It has [uses] light\s remaining (plus [bulb_shards] fragment\s)."
|
||||
|
||||
/obj/item/lightreplacer/proc/Use(mob/user)
|
||||
playsound(loc, 'sound/machines/click.ogg', 50, TRUE)
|
||||
AddUses(-1)
|
||||
return 1
|
||||
|
||||
// Negative numbers will subtract
|
||||
/obj/item/lightreplacer/proc/AddUses(amount = 1)
|
||||
uses = Clamp(uses + amount, 0, max_uses)
|
||||
|
||||
/obj/item/lightreplacer/proc/AddShards(amount = 1, user)
|
||||
bulb_shards += amount
|
||||
var/new_bulbs = round(bulb_shards / shards_required)
|
||||
if(new_bulbs > 0)
|
||||
AddUses(new_bulbs)
|
||||
bulb_shards = bulb_shards % shards_required
|
||||
if(new_bulbs != 0)
|
||||
to_chat(user, "<span class='notice'>[src] has fabricated a new bulb from the broken glass it has stored. It now has [uses] uses.</span>")
|
||||
playsound(loc, 'sound/machines/ding.ogg', 50, TRUE)
|
||||
return new_bulbs
|
||||
|
||||
/obj/item/lightreplacer/proc/Charge(var/mob/user)
|
||||
charge += 1
|
||||
if(charge > 3)
|
||||
AddUses(1)
|
||||
charge = 1
|
||||
|
||||
/obj/item/lightreplacer/proc/ReplaceLight(obj/machinery/light/target, mob/living/U)
|
||||
if(target.status != LIGHT_OK)
|
||||
if(CanUse(U))
|
||||
if(!Use(U))
|
||||
return
|
||||
to_chat(U, "<span class='notice'>You replace [target.fitting] with [src].</span>")
|
||||
|
||||
if(target.status != LIGHT_EMPTY)
|
||||
AddShards(1, U)
|
||||
target.status = LIGHT_EMPTY
|
||||
target.update()
|
||||
|
||||
var/obj/item/light/L2 = new target.light_type()
|
||||
|
||||
target.status = L2.status
|
||||
target.switchcount = L2.switchcount
|
||||
target.rigged = emagged
|
||||
target.brightness_range = L2.brightness_range
|
||||
target.brightness_power = L2.brightness_power
|
||||
target.brightness_color = L2.brightness_color
|
||||
target.on = target.has_power()
|
||||
target.update()
|
||||
qdel(L2)
|
||||
|
||||
if(target.on && target.rigged)
|
||||
target.explode()
|
||||
return
|
||||
|
||||
else
|
||||
to_chat(U, "[src]'s refill light blinks red.")
|
||||
return
|
||||
else
|
||||
to_chat(U, "<span class='warning'>There is a working [target.fitting] already inserted!</span>")
|
||||
return
|
||||
|
||||
/obj/item/lightreplacer/proc/Emag()
|
||||
emagged = !emagged
|
||||
playsound(loc, "sparks", 100, TRUE)
|
||||
if(emagged)
|
||||
name = "shortcircuited [initial(name)]"
|
||||
else
|
||||
name = initial(name)
|
||||
update_icon()
|
||||
|
||||
/obj/item/lightreplacer/proc/CanUse(mob/living/user)
|
||||
add_fingerprint(user)
|
||||
if(uses > 0)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/item/lightreplacer/afterattack(atom/T, mob/U, proximity)
|
||||
. = ..()
|
||||
if(!proximity)
|
||||
return
|
||||
if(!isturf(T))
|
||||
return
|
||||
|
||||
var/used = FALSE
|
||||
for(var/atom/A in T)
|
||||
if(!CanUse(U))
|
||||
break
|
||||
used = TRUE
|
||||
if(istype(A, /obj/machinery/light))
|
||||
ReplaceLight(A, U)
|
||||
|
||||
if(!used)
|
||||
to_chat(U, "[src]'s refill light blinks red.")
|
||||
|
||||
/obj/item/lightreplacer/proc/janicart_insert(mob/user, obj/structure/janitorialcart/J)
|
||||
J.put_in_cart(src, user)
|
||||
J.myreplacer = src
|
||||
J.update_icon()
|
||||
|
||||
/obj/item/lightreplacer/cyborg/janicart_insert(mob/user, obj/structure/janitorialcart/J)
|
||||
return
|
||||
|
||||
#undef LIGHT_OK
|
||||
#undef LIGHT_EMPTY
|
||||
#undef LIGHT_BROKEN
|
||||
#undef LIGHT_BURNED
|
||||
|
||||
@@ -1,340 +1,340 @@
|
||||
/obj/item/paicard
|
||||
name = "personal AI device"
|
||||
icon = 'icons/obj/aicards.dmi'
|
||||
icon_state = "pai"
|
||||
item_state = "electronic"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "programming=2"
|
||||
var/request_cooldown = 5 // five seconds
|
||||
var/last_request
|
||||
var/obj/item/radio/radio
|
||||
var/looking_for_personality = 0
|
||||
var/mob/living/silicon/pai/pai
|
||||
var/list/faction = list("neutral") // The factions the pAI will inherit from the card
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE
|
||||
|
||||
/obj/item/paicard/syndicate
|
||||
name = "syndicate personal AI device"
|
||||
faction = list("syndicate")
|
||||
|
||||
/obj/item/paicard/relaymove(var/mob/user, var/direction)
|
||||
if(user.stat || user.stunned)
|
||||
return
|
||||
var/obj/item/rig/rig = get_rig()
|
||||
if(istype(rig))
|
||||
rig.forced_move(direction, user)
|
||||
|
||||
/obj/item/paicard/New()
|
||||
..()
|
||||
overlays += "pai-off"
|
||||
|
||||
/obj/item/paicard/Destroy()
|
||||
if(pai)
|
||||
pai.ghostize()
|
||||
QDEL_NULL(pai)
|
||||
QDEL_NULL(radio)
|
||||
return ..()
|
||||
|
||||
/obj/item/paicard/attack_self(mob/user)
|
||||
if(!in_range(src, user))
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = {"
|
||||
<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
margin-top:5px;
|
||||
font-family:Verdana;
|
||||
color:white;
|
||||
font-size:13px;
|
||||
background-image:url('uiBackground.png');
|
||||
background-repeat:repeat-x;
|
||||
background-color:#272727;
|
||||
background-position:center top;
|
||||
}
|
||||
table {
|
||||
font-size:13px;
|
||||
margin-left:-2px;
|
||||
}
|
||||
table.request {
|
||||
border-collapse:collapse;
|
||||
}
|
||||
table.desc {
|
||||
border-collapse:collapse;
|
||||
font-size:13px;
|
||||
border: 1px solid #161616;
|
||||
width:100%;
|
||||
}
|
||||
table.download {
|
||||
border-collapse:collapse;
|
||||
font-size:13px;
|
||||
border: 1px solid #161616;
|
||||
width:100%;
|
||||
}
|
||||
tr.d0 td, tr.d0 th {
|
||||
background-color: #506070;
|
||||
color: white;
|
||||
}
|
||||
tr.d1 td, tr.d1 th {
|
||||
background-color: #708090;
|
||||
color: white;
|
||||
}
|
||||
tr.d2 td {
|
||||
background-color: #00FF00;
|
||||
color: white;
|
||||
text-align:center;
|
||||
}
|
||||
td.button {
|
||||
border: 1px solid #161616;
|
||||
background-color: #40628a;
|
||||
}
|
||||
td.button {
|
||||
border: 1px solid #161616;
|
||||
background-color: #40628a;
|
||||
text-align: center;
|
||||
}
|
||||
td.button_red {
|
||||
border: 1px solid #161616;
|
||||
background-color: #B04040;
|
||||
text-align: center;
|
||||
}
|
||||
td.download {
|
||||
border: 1px solid #161616;
|
||||
background-color: #40628a;
|
||||
text-align: center;
|
||||
}
|
||||
th {
|
||||
text-align:left;
|
||||
width:125px;
|
||||
}
|
||||
td.request {
|
||||
width:140px;
|
||||
vertical-align:top;
|
||||
}
|
||||
td.radio {
|
||||
width:90px;
|
||||
vertical-align:top;
|
||||
}
|
||||
td.request {
|
||||
vertical-align:top;
|
||||
}
|
||||
a {
|
||||
color:#4477E0;
|
||||
}
|
||||
a.button {
|
||||
color:white;
|
||||
text-decoration: none;
|
||||
}
|
||||
h2 {
|
||||
font-size:15px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
"}
|
||||
|
||||
if(pai)
|
||||
dat += {"
|
||||
<b><font size='3px'>Personal AI Device</font></b><br><br>
|
||||
<table class="request">
|
||||
<tr>
|
||||
<td class="request">Installed Personality:</td>
|
||||
<td>[pai.name]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="request">Prime directive:</td>
|
||||
<td>[pai.pai_law0]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="request">Additional directives:</td>
|
||||
<td>[pai.pai_laws]</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
"}
|
||||
dat += {"
|
||||
<table>
|
||||
<td class="button">
|
||||
<a href='byond://?src=[UID()];setlaws=1' class='button'>Configure Directives</a>
|
||||
</td>
|
||||
</table>
|
||||
"}
|
||||
if(pai && (!pai.master_dna || !pai.master))
|
||||
dat += {"
|
||||
<table>
|
||||
<td class="button">
|
||||
<a href='byond://?src=[UID()];setdna=1' class='button'>Imprint Master DNA</a>
|
||||
</td>
|
||||
</table>
|
||||
"}
|
||||
dat += "<br>"
|
||||
if(radio)
|
||||
dat += "<b>Radio Uplink</b>"
|
||||
dat += {"
|
||||
<table class="request">
|
||||
<tr>
|
||||
<td class="radio">Transmit:</td>
|
||||
<td><a href='byond://?src=[UID()];wires=4'>[radio.broadcasting ? "<font color=#55FF55>En" : "<font color=#FF5555>Dis" ]abled</font></a>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="radio">Receive:</td>
|
||||
<td><a href='byond://?src=[UID()];wires=2'>[radio.listening ? "<font color=#55FF55>En" : "<font color=#FF5555>Dis" ]abled</font></a>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
"}
|
||||
else
|
||||
dat += "<b>Radio Uplink</b><br>"
|
||||
dat += "<font color=red><i>Radio firmware not loaded. Please install a pAI personality to load firmware.</i></font><br>"
|
||||
dat += {"
|
||||
<table>
|
||||
<td class="button_red"><a href='byond://?src=[UID()];wipe=1' class='button'>Wipe current pAI personality</a>
|
||||
|
||||
</td>
|
||||
</table>
|
||||
"}
|
||||
else
|
||||
if(looking_for_personality)
|
||||
dat += {"
|
||||
<b><font size='3px'>pAI Request Module</font></b><br><br>
|
||||
<p>Requesting AI personalities from central database... If there are no entries, or if a suitable entry is not listed, check again later as more personalities may be added.</p>
|
||||
Searching for personalities, please wait...<br><br>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td class="button">
|
||||
<a href='byond://?src=[UID()];request=1' class="button">Refresh available personalities</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table><br>
|
||||
"}
|
||||
else
|
||||
dat += {"
|
||||
<b><font size='3px'>pAI Request Module</font></b><br><br>
|
||||
<p>No personality is installed.</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td class="button"><a href='byond://?src=[UID()];request=1' class="button">Request personality</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<p>Each time this button is pressed, a request will be sent out to any available personalities. Check back often give plenty of time for personalities to respond. This process could take anywhere from 15 seconds to several minutes, depending on the available personalities' timeliness.</p>
|
||||
"}
|
||||
user << browse(dat, "window=paicard")
|
||||
onclose(user, "paicard")
|
||||
return
|
||||
|
||||
/obj/item/paicard/Topic(href, href_list)
|
||||
|
||||
var/mob/U = usr
|
||||
|
||||
if(!usr || usr.stat)
|
||||
return
|
||||
|
||||
if(pai)
|
||||
if(!in_range(src, U))
|
||||
U << browse(null, "window=paicard")
|
||||
usr.unset_machine()
|
||||
return
|
||||
|
||||
if(href_list["setdna"])
|
||||
if(pai.master_dna)
|
||||
return
|
||||
var/mob/M = usr
|
||||
if(!istype(M, /mob/living/carbon))
|
||||
to_chat(usr, "<font color=blue>You don't have any DNA, or your DNA is incompatible with this device.</font>")
|
||||
else
|
||||
var/datum/dna/dna = usr.dna
|
||||
pai.master = M.real_name
|
||||
pai.master_dna = dna.unique_enzymes
|
||||
to_chat(pai, "<font color = red><h3>You have been bound to a new master.</h3></font>")
|
||||
if(href_list["request"])
|
||||
var/delta = (world.time / 10) - last_request
|
||||
if(request_cooldown > delta)
|
||||
var/cooldown_time = round(request_cooldown - ((world.time / 10) - last_request), 1)
|
||||
to_chat(usr, "<span class='warning'>The request system is currently offline. Please wait another [cooldown_time] seconds.</span>")
|
||||
return
|
||||
last_request = world.time / 10
|
||||
looking_for_personality = 1
|
||||
paiController.findPAI(src, usr)
|
||||
if(href_list["wipe"])
|
||||
var/confirm = input("Are you CERTAIN you wish to delete the current personality? This action cannot be undone.", "Personality Wipe") in list("Yes", "No")
|
||||
if(confirm == "Yes")
|
||||
for(var/mob/M in src)
|
||||
to_chat(M, "<font color = #ff0000><h2>You feel yourself slipping away from reality.</h2></font>")
|
||||
to_chat(M, "<font color = #ff4d4d><h3>Byte by byte you lose your sense of self.</h3></font>")
|
||||
to_chat(M, "<font color = #ff8787><h4>Your mental faculties leave you.</h4></font>")
|
||||
to_chat(M, "<font color = #ffc4c4><h5>oblivion... </h5></font>")
|
||||
var/mob/living/silicon/pai/P = M
|
||||
if(istype(P))
|
||||
if(P.resting || P.canmove)
|
||||
P.close_up()
|
||||
M.death(0, 1)
|
||||
removePersonality()
|
||||
if(href_list["wires"])
|
||||
var/t1 = text2num(href_list["wires"])
|
||||
switch(t1)
|
||||
if(4)
|
||||
radio.ToggleBroadcast()
|
||||
if(2)
|
||||
radio.ToggleReception()
|
||||
if(href_list["setlaws"])
|
||||
var/newlaws = sanitize(copytext(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.pai_laws) as message,1,MAX_MESSAGE_LEN))
|
||||
if(newlaws)
|
||||
pai.pai_laws = newlaws
|
||||
to_chat(pai, "Your supplemental directives have been updated. Your new directives are:")
|
||||
to_chat(pai, "Prime Directive: <br>[pai.pai_law0]")
|
||||
to_chat(pai, "Supplemental Directives: <br>[pai.pai_laws]")
|
||||
attack_self(usr)
|
||||
|
||||
// WIRE_SIGNAL = 1
|
||||
// WIRE_RECEIVE = 2
|
||||
// WIRE_TRANSMIT = 4
|
||||
|
||||
/obj/item/paicard/proc/setPersonality(mob/living/silicon/pai/personality)
|
||||
pai = personality
|
||||
overlays += "pai-happy"
|
||||
|
||||
/obj/item/paicard/proc/removePersonality()
|
||||
pai = null
|
||||
overlays.Cut()
|
||||
overlays += "pai-off"
|
||||
|
||||
/obj/item/paicard
|
||||
var/current_emotion = 1
|
||||
/obj/item/paicard/proc/setEmotion(var/emotion)
|
||||
if(pai)
|
||||
overlays.Cut()
|
||||
switch(emotion)
|
||||
if(1) overlays += "pai-happy"
|
||||
if(2) overlays += "pai-cat"
|
||||
if(3) overlays += "pai-extremely-happy"
|
||||
if(4) overlays += "pai-face"
|
||||
if(5) overlays += "pai-laugh"
|
||||
if(6) overlays += "pai-off"
|
||||
if(7) overlays += "pai-sad"
|
||||
if(8) overlays += "pai-angry"
|
||||
if(9) overlays += "pai-what"
|
||||
current_emotion = emotion
|
||||
|
||||
/obj/item/paicard/proc/alertUpdate()
|
||||
var/turf/T = get_turf_or_move(loc)
|
||||
for(var/mob/M in viewers(T))
|
||||
M.show_message("<span class='notice'>[src] flashes a message across its screen, \"Additional personalities available for download.\"</span>", 3, "<span class='notice'>[src] bleeps electronically.</span>", 2)
|
||||
|
||||
/obj/item/paicard/emp_act(severity)
|
||||
for(var/mob/M in src)
|
||||
M.emp_act(severity)
|
||||
..()
|
||||
|
||||
/obj/item/paicard/extinguish_light()
|
||||
pai.extinguish_light()
|
||||
set_light(0)
|
||||
/obj/item/paicard
|
||||
name = "personal AI device"
|
||||
icon = 'icons/obj/aicards.dmi'
|
||||
icon_state = "pai"
|
||||
item_state = "electronic"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = SLOT_BELT
|
||||
origin_tech = "programming=2"
|
||||
var/request_cooldown = 5 // five seconds
|
||||
var/last_request
|
||||
var/obj/item/radio/radio
|
||||
var/looking_for_personality = 0
|
||||
var/mob/living/silicon/pai/pai
|
||||
var/list/faction = list("neutral") // The factions the pAI will inherit from the card
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE
|
||||
|
||||
/obj/item/paicard/syndicate
|
||||
name = "syndicate personal AI device"
|
||||
faction = list("syndicate")
|
||||
|
||||
/obj/item/paicard/relaymove(var/mob/user, var/direction)
|
||||
if(user.stat || user.stunned)
|
||||
return
|
||||
var/obj/item/rig/rig = get_rig()
|
||||
if(istype(rig))
|
||||
rig.forced_move(direction, user)
|
||||
|
||||
/obj/item/paicard/New()
|
||||
..()
|
||||
overlays += "pai-off"
|
||||
|
||||
/obj/item/paicard/Destroy()
|
||||
if(pai)
|
||||
pai.ghostize()
|
||||
QDEL_NULL(pai)
|
||||
QDEL_NULL(radio)
|
||||
return ..()
|
||||
|
||||
/obj/item/paicard/attack_self(mob/user)
|
||||
if(!in_range(src, user))
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = {"
|
||||
<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
margin-top:5px;
|
||||
font-family:Verdana;
|
||||
color:white;
|
||||
font-size:13px;
|
||||
background-image:url('uiBackground.png');
|
||||
background-repeat:repeat-x;
|
||||
background-color:#272727;
|
||||
background-position:center top;
|
||||
}
|
||||
table {
|
||||
font-size:13px;
|
||||
margin-left:-2px;
|
||||
}
|
||||
table.request {
|
||||
border-collapse:collapse;
|
||||
}
|
||||
table.desc {
|
||||
border-collapse:collapse;
|
||||
font-size:13px;
|
||||
border: 1px solid #161616;
|
||||
width:100%;
|
||||
}
|
||||
table.download {
|
||||
border-collapse:collapse;
|
||||
font-size:13px;
|
||||
border: 1px solid #161616;
|
||||
width:100%;
|
||||
}
|
||||
tr.d0 td, tr.d0 th {
|
||||
background-color: #506070;
|
||||
color: white;
|
||||
}
|
||||
tr.d1 td, tr.d1 th {
|
||||
background-color: #708090;
|
||||
color: white;
|
||||
}
|
||||
tr.d2 td {
|
||||
background-color: #00FF00;
|
||||
color: white;
|
||||
text-align:center;
|
||||
}
|
||||
td.button {
|
||||
border: 1px solid #161616;
|
||||
background-color: #40628a;
|
||||
}
|
||||
td.button {
|
||||
border: 1px solid #161616;
|
||||
background-color: #40628a;
|
||||
text-align: center;
|
||||
}
|
||||
td.button_red {
|
||||
border: 1px solid #161616;
|
||||
background-color: #B04040;
|
||||
text-align: center;
|
||||
}
|
||||
td.download {
|
||||
border: 1px solid #161616;
|
||||
background-color: #40628a;
|
||||
text-align: center;
|
||||
}
|
||||
th {
|
||||
text-align:left;
|
||||
width:125px;
|
||||
}
|
||||
td.request {
|
||||
width:140px;
|
||||
vertical-align:top;
|
||||
}
|
||||
td.radio {
|
||||
width:90px;
|
||||
vertical-align:top;
|
||||
}
|
||||
td.request {
|
||||
vertical-align:top;
|
||||
}
|
||||
a {
|
||||
color:#4477E0;
|
||||
}
|
||||
a.button {
|
||||
color:white;
|
||||
text-decoration: none;
|
||||
}
|
||||
h2 {
|
||||
font-size:15px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
"}
|
||||
|
||||
if(pai)
|
||||
dat += {"
|
||||
<b><font size='3px'>Personal AI Device</font></b><br><br>
|
||||
<table class="request">
|
||||
<tr>
|
||||
<td class="request">Installed Personality:</td>
|
||||
<td>[pai.name]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="request">Prime directive:</td>
|
||||
<td>[pai.pai_law0]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="request">Additional directives:</td>
|
||||
<td>[pai.pai_laws]</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
"}
|
||||
dat += {"
|
||||
<table>
|
||||
<td class="button">
|
||||
<a href='byond://?src=[UID()];setlaws=1' class='button'>Configure Directives</a>
|
||||
</td>
|
||||
</table>
|
||||
"}
|
||||
if(pai && (!pai.master_dna || !pai.master))
|
||||
dat += {"
|
||||
<table>
|
||||
<td class="button">
|
||||
<a href='byond://?src=[UID()];setdna=1' class='button'>Imprint Master DNA</a>
|
||||
</td>
|
||||
</table>
|
||||
"}
|
||||
dat += "<br>"
|
||||
if(radio)
|
||||
dat += "<b>Radio Uplink</b>"
|
||||
dat += {"
|
||||
<table class="request">
|
||||
<tr>
|
||||
<td class="radio">Transmit:</td>
|
||||
<td><a href='byond://?src=[UID()];wires=4'>[radio.broadcasting ? "<font color=#55FF55>En" : "<font color=#FF5555>Dis" ]abled</font></a>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="radio">Receive:</td>
|
||||
<td><a href='byond://?src=[UID()];wires=2'>[radio.listening ? "<font color=#55FF55>En" : "<font color=#FF5555>Dis" ]abled</font></a>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
"}
|
||||
else
|
||||
dat += "<b>Radio Uplink</b><br>"
|
||||
dat += "<font color=red><i>Radio firmware not loaded. Please install a pAI personality to load firmware.</i></font><br>"
|
||||
dat += {"
|
||||
<table>
|
||||
<td class="button_red"><a href='byond://?src=[UID()];wipe=1' class='button'>Wipe current pAI personality</a>
|
||||
|
||||
</td>
|
||||
</table>
|
||||
"}
|
||||
else
|
||||
if(looking_for_personality)
|
||||
dat += {"
|
||||
<b><font size='3px'>pAI Request Module</font></b><br><br>
|
||||
<p>Requesting AI personalities from central database... If there are no entries, or if a suitable entry is not listed, check again later as more personalities may be added.</p>
|
||||
Searching for personalities, please wait...<br><br>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td class="button">
|
||||
<a href='byond://?src=[UID()];request=1' class="button">Refresh available personalities</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table><br>
|
||||
"}
|
||||
else
|
||||
dat += {"
|
||||
<b><font size='3px'>pAI Request Module</font></b><br><br>
|
||||
<p>No personality is installed.</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td class="button"><a href='byond://?src=[UID()];request=1' class="button">Request personality</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<p>Each time this button is pressed, a request will be sent out to any available personalities. Check back often give plenty of time for personalities to respond. This process could take anywhere from 15 seconds to several minutes, depending on the available personalities' timeliness.</p>
|
||||
"}
|
||||
user << browse(dat, "window=paicard")
|
||||
onclose(user, "paicard")
|
||||
return
|
||||
|
||||
/obj/item/paicard/Topic(href, href_list)
|
||||
|
||||
var/mob/U = usr
|
||||
|
||||
if(!usr || usr.stat)
|
||||
return
|
||||
|
||||
if(pai)
|
||||
if(!in_range(src, U))
|
||||
U << browse(null, "window=paicard")
|
||||
usr.unset_machine()
|
||||
return
|
||||
|
||||
if(href_list["setdna"])
|
||||
if(pai.master_dna)
|
||||
return
|
||||
var/mob/M = usr
|
||||
if(!istype(M, /mob/living/carbon))
|
||||
to_chat(usr, "<font color=blue>You don't have any DNA, or your DNA is incompatible with this device.</font>")
|
||||
else
|
||||
var/datum/dna/dna = usr.dna
|
||||
pai.master = M.real_name
|
||||
pai.master_dna = dna.unique_enzymes
|
||||
to_chat(pai, "<font color = red><h3>You have been bound to a new master.</h3></font>")
|
||||
if(href_list["request"])
|
||||
var/delta = (world.time / 10) - last_request
|
||||
if(request_cooldown > delta)
|
||||
var/cooldown_time = round(request_cooldown - ((world.time / 10) - last_request), 1)
|
||||
to_chat(usr, "<span class='warning'>The request system is currently offline. Please wait another [cooldown_time] seconds.</span>")
|
||||
return
|
||||
last_request = world.time / 10
|
||||
looking_for_personality = 1
|
||||
paiController.findPAI(src, usr)
|
||||
if(href_list["wipe"])
|
||||
var/confirm = input("Are you CERTAIN you wish to delete the current personality? This action cannot be undone.", "Personality Wipe") in list("Yes", "No")
|
||||
if(confirm == "Yes")
|
||||
for(var/mob/M in src)
|
||||
to_chat(M, "<font color = #ff0000><h2>You feel yourself slipping away from reality.</h2></font>")
|
||||
to_chat(M, "<font color = #ff4d4d><h3>Byte by byte you lose your sense of self.</h3></font>")
|
||||
to_chat(M, "<font color = #ff8787><h4>Your mental faculties leave you.</h4></font>")
|
||||
to_chat(M, "<font color = #ffc4c4><h5>oblivion... </h5></font>")
|
||||
var/mob/living/silicon/pai/P = M
|
||||
if(istype(P))
|
||||
if(P.resting || P.canmove)
|
||||
P.close_up()
|
||||
M.death(0, 1)
|
||||
removePersonality()
|
||||
if(href_list["wires"])
|
||||
var/t1 = text2num(href_list["wires"])
|
||||
switch(t1)
|
||||
if(4)
|
||||
radio.ToggleBroadcast()
|
||||
if(2)
|
||||
radio.ToggleReception()
|
||||
if(href_list["setlaws"])
|
||||
var/newlaws = sanitize(copytext(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.pai_laws) as message,1,MAX_MESSAGE_LEN))
|
||||
if(newlaws)
|
||||
pai.pai_laws = newlaws
|
||||
to_chat(pai, "Your supplemental directives have been updated. Your new directives are:")
|
||||
to_chat(pai, "Prime Directive: <br>[pai.pai_law0]")
|
||||
to_chat(pai, "Supplemental Directives: <br>[pai.pai_laws]")
|
||||
attack_self(usr)
|
||||
|
||||
// WIRE_SIGNAL = 1
|
||||
// WIRE_RECEIVE = 2
|
||||
// WIRE_TRANSMIT = 4
|
||||
|
||||
/obj/item/paicard/proc/setPersonality(mob/living/silicon/pai/personality)
|
||||
pai = personality
|
||||
overlays += "pai-happy"
|
||||
|
||||
/obj/item/paicard/proc/removePersonality()
|
||||
pai = null
|
||||
overlays.Cut()
|
||||
overlays += "pai-off"
|
||||
|
||||
/obj/item/paicard
|
||||
var/current_emotion = 1
|
||||
/obj/item/paicard/proc/setEmotion(var/emotion)
|
||||
if(pai)
|
||||
overlays.Cut()
|
||||
switch(emotion)
|
||||
if(1) overlays += "pai-happy"
|
||||
if(2) overlays += "pai-cat"
|
||||
if(3) overlays += "pai-extremely-happy"
|
||||
if(4) overlays += "pai-face"
|
||||
if(5) overlays += "pai-laugh"
|
||||
if(6) overlays += "pai-off"
|
||||
if(7) overlays += "pai-sad"
|
||||
if(8) overlays += "pai-angry"
|
||||
if(9) overlays += "pai-what"
|
||||
current_emotion = emotion
|
||||
|
||||
/obj/item/paicard/proc/alertUpdate()
|
||||
var/turf/T = get_turf_or_move(loc)
|
||||
for(var/mob/M in viewers(T))
|
||||
M.show_message("<span class='notice'>[src] flashes a message across its screen, \"Additional personalities available for download.\"</span>", 3, "<span class='notice'>[src] bleeps electronically.</span>", 2)
|
||||
|
||||
/obj/item/paicard/emp_act(severity)
|
||||
for(var/mob/M in src)
|
||||
M.emp_act(severity)
|
||||
..()
|
||||
|
||||
/obj/item/paicard/extinguish_light()
|
||||
pai.extinguish_light()
|
||||
set_light(0)
|
||||
|
||||
@@ -102,4 +102,4 @@
|
||||
|
||||
/obj/item/pizza_bomb/autoarm
|
||||
timer_set = 1
|
||||
timer = 30 // 3 seconds
|
||||
timer = 30 // 3 seconds
|
||||
|
||||
@@ -1,153 +1,153 @@
|
||||
#define DISCONNECTED 0
|
||||
#define CLAMPED_OFF 1
|
||||
#define OPERATING 2
|
||||
|
||||
// Powersink - used to drain station power
|
||||
|
||||
/obj/item/powersink
|
||||
name = "power sink"
|
||||
desc = "A nulling power sink which drains energy from electrical systems."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "powersink0"
|
||||
item_state = "electronic"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
flags = CONDUCT
|
||||
throwforce = 5
|
||||
throw_speed = 1
|
||||
throw_range = 2
|
||||
materials = list(MAT_METAL=750)
|
||||
origin_tech = "powerstorage=5;syndicate=5"
|
||||
var/drain_rate = 2000000 // amount of power to drain per tick
|
||||
var/power_drained = 0 // has drained this much power
|
||||
var/max_power = 6e8 // maximum power that can be drained before exploding
|
||||
var/mode = 0 // 0 = off, 1=clamped (off), 2=operating
|
||||
var/admins_warned = FALSE // stop spam, only warn the admins once that we are about to boom
|
||||
|
||||
var/obj/structure/cable/attached // the attached cable
|
||||
|
||||
/obj/item/powersink/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
attached = null
|
||||
return ..()
|
||||
|
||||
/obj/item/powersink/update_icon()
|
||||
icon_state = "powersink[mode == OPERATING]"
|
||||
|
||||
/obj/item/powersink/proc/set_mode(value)
|
||||
if(value == mode)
|
||||
return
|
||||
switch(value)
|
||||
if(DISCONNECTED)
|
||||
attached = null
|
||||
if(mode == OPERATING)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
anchored = FALSE
|
||||
density = FALSE
|
||||
|
||||
if(CLAMPED_OFF)
|
||||
if(!attached)
|
||||
return
|
||||
if(mode == OPERATING)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
|
||||
if(OPERATING)
|
||||
if(!attached)
|
||||
return
|
||||
START_PROCESSING(SSobj, src)
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
|
||||
mode = value
|
||||
update_icon()
|
||||
set_light(0)
|
||||
|
||||
/obj/item/powersink/screwdriver_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
|
||||
return
|
||||
if(mode == DISCONNECTED)
|
||||
var/turf/T = loc
|
||||
if(isturf(T) && !T.intact)
|
||||
attached = locate() in T
|
||||
if(!attached)
|
||||
to_chat(user, "No exposed cable here to attach to.")
|
||||
return
|
||||
else
|
||||
set_mode(CLAMPED_OFF)
|
||||
visible_message("<span class='notice'>[user] attaches [src] to the cable!</span>")
|
||||
message_admins("Power sink activated by [key_name_admin(user)] at ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
log_game("Power sink activated by [key_name(user)] at ([x],[y],[z])")
|
||||
else
|
||||
to_chat(user, "Device must be placed over an exposed cable to attach to it.")
|
||||
else
|
||||
set_mode(DISCONNECTED)
|
||||
src.visible_message("<span class='notice'>[user] detaches [src] from the cable!</span>")
|
||||
|
||||
/obj/item/powersink/attack_ai()
|
||||
return
|
||||
|
||||
/obj/item/powersink/attack_hand(var/mob/user)
|
||||
switch(mode)
|
||||
if(DISCONNECTED)
|
||||
..()
|
||||
if(CLAMPED_OFF)
|
||||
user.visible_message( \
|
||||
"[user] activates \the [src]!", \
|
||||
"<span class='notice'>You activate \the [src].</span>",
|
||||
"<span class='italics'>You hear a click.</span>")
|
||||
message_admins("Power sink activated by [ADMIN_LOOKUPFLW(user)] at [ADMIN_VERBOSEJMP(src)]")
|
||||
log_game("Power sink activated by [key_name(user)] at [AREACOORD(src)]")
|
||||
set_mode(OPERATING)
|
||||
|
||||
if(OPERATING)
|
||||
user.visible_message( \
|
||||
"[user] deactivates \the [src]!", \
|
||||
"<span class='notice'>You deactivate \the [src].</span>",
|
||||
"<span class='italics'>You hear a click.</span>")
|
||||
set_mode(CLAMPED_OFF)
|
||||
|
||||
/obj/item/powersink/process()
|
||||
if(!attached)
|
||||
set_mode(DISCONNECTED)
|
||||
return
|
||||
|
||||
var/datum/powernet/PN = attached.powernet
|
||||
if(PN)
|
||||
set_light(5)
|
||||
|
||||
// found a powernet, so drain up to max power from it
|
||||
|
||||
var/drained = min (drain_rate, attached.newavail())
|
||||
attached.add_delayedload(drained)
|
||||
power_drained += drained
|
||||
|
||||
// if tried to drain more than available on powernet
|
||||
// now look for APCs and drain their cells
|
||||
if(drained < drain_rate)
|
||||
for(var/obj/machinery/power/terminal/T in PN.nodes)
|
||||
if(istype(T.master, /obj/machinery/power/apc))
|
||||
var/obj/machinery/power/apc/A = T.master
|
||||
if(A.operating && A.cell)
|
||||
A.cell.charge = max(0, A.cell.charge - 50)
|
||||
power_drained += 50
|
||||
if(A.charging == 2) // If the cell was full
|
||||
A.charging = 1 // It's no longer full
|
||||
if(drained >= drain_rate)
|
||||
break
|
||||
|
||||
if(power_drained > max_power * 0.98)
|
||||
if (!admins_warned)
|
||||
admins_warned = TRUE
|
||||
message_admins("Power sink at ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>) is 95% full. Explosion imminent.")
|
||||
playsound(src, 'sound/effects/screech.ogg', 100, 1, 1)
|
||||
|
||||
if(power_drained >= max_power)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
explosion(src.loc, 4,8,16,32)
|
||||
qdel(src)
|
||||
|
||||
#undef DISCONNECTED
|
||||
#undef CLAMPED_OFF
|
||||
#undef OPERATING
|
||||
#define DISCONNECTED 0
|
||||
#define CLAMPED_OFF 1
|
||||
#define OPERATING 2
|
||||
|
||||
// Powersink - used to drain station power
|
||||
|
||||
/obj/item/powersink
|
||||
name = "power sink"
|
||||
desc = "A nulling power sink which drains energy from electrical systems."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "powersink0"
|
||||
item_state = "electronic"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
flags = CONDUCT
|
||||
throwforce = 5
|
||||
throw_speed = 1
|
||||
throw_range = 2
|
||||
materials = list(MAT_METAL=750)
|
||||
origin_tech = "powerstorage=5;syndicate=5"
|
||||
var/drain_rate = 2000000 // amount of power to drain per tick
|
||||
var/power_drained = 0 // has drained this much power
|
||||
var/max_power = 6e8 // maximum power that can be drained before exploding
|
||||
var/mode = 0 // 0 = off, 1=clamped (off), 2=operating
|
||||
var/admins_warned = FALSE // stop spam, only warn the admins once that we are about to boom
|
||||
|
||||
var/obj/structure/cable/attached // the attached cable
|
||||
|
||||
/obj/item/powersink/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
attached = null
|
||||
return ..()
|
||||
|
||||
/obj/item/powersink/update_icon()
|
||||
icon_state = "powersink[mode == OPERATING]"
|
||||
|
||||
/obj/item/powersink/proc/set_mode(value)
|
||||
if(value == mode)
|
||||
return
|
||||
switch(value)
|
||||
if(DISCONNECTED)
|
||||
attached = null
|
||||
if(mode == OPERATING)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
anchored = FALSE
|
||||
density = FALSE
|
||||
|
||||
if(CLAMPED_OFF)
|
||||
if(!attached)
|
||||
return
|
||||
if(mode == OPERATING)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
|
||||
if(OPERATING)
|
||||
if(!attached)
|
||||
return
|
||||
START_PROCESSING(SSobj, src)
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
|
||||
mode = value
|
||||
update_icon()
|
||||
set_light(0)
|
||||
|
||||
/obj/item/powersink/screwdriver_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
|
||||
return
|
||||
if(mode == DISCONNECTED)
|
||||
var/turf/T = loc
|
||||
if(isturf(T) && !T.intact)
|
||||
attached = locate() in T
|
||||
if(!attached)
|
||||
to_chat(user, "No exposed cable here to attach to.")
|
||||
return
|
||||
else
|
||||
set_mode(CLAMPED_OFF)
|
||||
visible_message("<span class='notice'>[user] attaches [src] to the cable!</span>")
|
||||
message_admins("Power sink activated by [key_name_admin(user)] at ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)")
|
||||
log_game("Power sink activated by [key_name(user)] at ([x],[y],[z])")
|
||||
else
|
||||
to_chat(user, "Device must be placed over an exposed cable to attach to it.")
|
||||
else
|
||||
set_mode(DISCONNECTED)
|
||||
src.visible_message("<span class='notice'>[user] detaches [src] from the cable!</span>")
|
||||
|
||||
/obj/item/powersink/attack_ai()
|
||||
return
|
||||
|
||||
/obj/item/powersink/attack_hand(var/mob/user)
|
||||
switch(mode)
|
||||
if(DISCONNECTED)
|
||||
..()
|
||||
if(CLAMPED_OFF)
|
||||
user.visible_message( \
|
||||
"[user] activates \the [src]!", \
|
||||
"<span class='notice'>You activate \the [src].</span>",
|
||||
"<span class='italics'>You hear a click.</span>")
|
||||
message_admins("Power sink activated by [ADMIN_LOOKUPFLW(user)] at [ADMIN_VERBOSEJMP(src)]")
|
||||
log_game("Power sink activated by [key_name(user)] at [AREACOORD(src)]")
|
||||
set_mode(OPERATING)
|
||||
|
||||
if(OPERATING)
|
||||
user.visible_message( \
|
||||
"[user] deactivates \the [src]!", \
|
||||
"<span class='notice'>You deactivate \the [src].</span>",
|
||||
"<span class='italics'>You hear a click.</span>")
|
||||
set_mode(CLAMPED_OFF)
|
||||
|
||||
/obj/item/powersink/process()
|
||||
if(!attached)
|
||||
set_mode(DISCONNECTED)
|
||||
return
|
||||
|
||||
var/datum/powernet/PN = attached.powernet
|
||||
if(PN)
|
||||
set_light(5)
|
||||
|
||||
// found a powernet, so drain up to max power from it
|
||||
|
||||
var/drained = min (drain_rate, attached.newavail())
|
||||
attached.add_delayedload(drained)
|
||||
power_drained += drained
|
||||
|
||||
// if tried to drain more than available on powernet
|
||||
// now look for APCs and drain their cells
|
||||
if(drained < drain_rate)
|
||||
for(var/obj/machinery/power/terminal/T in PN.nodes)
|
||||
if(istype(T.master, /obj/machinery/power/apc))
|
||||
var/obj/machinery/power/apc/A = T.master
|
||||
if(A.operating && A.cell)
|
||||
A.cell.charge = max(0, A.cell.charge - 50)
|
||||
power_drained += 50
|
||||
if(A.charging == 2) // If the cell was full
|
||||
A.charging = 1 // It's no longer full
|
||||
if(drained >= drain_rate)
|
||||
break
|
||||
|
||||
if(power_drained > max_power * 0.98)
|
||||
if (!admins_warned)
|
||||
admins_warned = TRUE
|
||||
message_admins("Power sink at ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>) is 95% full. Explosion imminent.")
|
||||
playsound(src, 'sound/effects/screech.ogg', 100, 1, 1)
|
||||
|
||||
if(power_drained >= max_power)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
explosion(src.loc, 4,8,16,32)
|
||||
qdel(src)
|
||||
|
||||
#undef DISCONNECTED
|
||||
#undef CLAMPED_OFF
|
||||
#undef OPERATING
|
||||
|
||||
@@ -1,106 +1,106 @@
|
||||
/obj/item/radio/beacon
|
||||
name = "Tracking Beacon"
|
||||
desc = "A beacon used by a teleporter."
|
||||
icon_state = "beacon"
|
||||
item_state = "signaler"
|
||||
var/code = "Beacon"
|
||||
origin_tech = "bluespace=1"
|
||||
var/emagged = 0
|
||||
var/syndicate = 0
|
||||
var/area_bypass = FALSE
|
||||
var/cc_beacon = FALSE //set if allowed to teleport to even if on zlevel2
|
||||
|
||||
/obj/item/radio/beacon/New()
|
||||
..()
|
||||
code = "[code] ([GLOB.beacons.len + 1])"
|
||||
GLOB.beacons += src
|
||||
|
||||
/obj/item/radio/beacon/Destroy()
|
||||
GLOB.beacons -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/beacon/emag_act(user as mob)
|
||||
if(!emagged)
|
||||
emagged = 1
|
||||
syndicate = 1
|
||||
to_chat(user, "<span class='notice'>The This beacon now only be locked on to by emagged teleporters!</span>")
|
||||
|
||||
/obj/item/radio/beacon/hear_talk()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/radio/beacon/send_hear()
|
||||
return null
|
||||
|
||||
/obj/item/radio/beacon/verb/alter_signal(t as text)
|
||||
set name = "Alter Beacon's Signal"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
|
||||
if(usr.stat || usr.restrained())
|
||||
return
|
||||
|
||||
code = t
|
||||
if(isnull(code))
|
||||
code = initial(code)
|
||||
src.add_fingerprint(usr)
|
||||
return
|
||||
|
||||
/obj/item/radio/beacon/bacon //Probably a better way of doing this, I'm lazy.
|
||||
|
||||
/obj/item/radio/beacon/bacon/proc/digest_delay()
|
||||
QDEL_IN(src, 600)
|
||||
|
||||
// SINGULO BEACON SPAWNER
|
||||
/obj/item/radio/beacon/syndicate
|
||||
name = "suspicious beacon"
|
||||
desc = "A label on it reads: <i>Activate to have a singularity beacon teleported to your location</i>."
|
||||
origin_tech = "bluespace=6;syndicate=5"
|
||||
syndicate = TRUE
|
||||
var/obj/machinery/computer/syndicate_depot/teleporter/mycomputer
|
||||
|
||||
/obj/item/radio/beacon/syndicate/Destroy()
|
||||
if(mycomputer)
|
||||
mycomputer.mybeacon = null
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/beacon/syndicate/attack_self(mob/user)
|
||||
if(user)
|
||||
to_chat(user, "<span class='notice'>Locked In</span>")
|
||||
new /obj/machinery/power/singularity_beacon/syndicate( user.loc )
|
||||
playsound(src, 'sound/effects/pop.ogg', 100, 1, 1)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/radio/beacon/syndicate/bomb
|
||||
name = "suspicious beacon"
|
||||
desc = "A label on it reads: <i>Warning: Activating this device will send a high-ordinance explosive to your location</i>."
|
||||
origin_tech = "bluespace=5;syndicate=5"
|
||||
|
||||
/obj/item/radio/beacon/syndicate/bomb/attack_self(mob/user)
|
||||
if(user)
|
||||
to_chat(user, "<span class='notice'>Locked In</span>")
|
||||
new /obj/machinery/syndicatebomb( user.loc )
|
||||
playsound(src, 'sound/effects/pop.ogg', 100, 1, 1)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/radio/beacon/engine
|
||||
desc = "A label on it reads: <i>Warning: This device is used for transportation of high-density objects used for high-yield power generation. Stay away!</i>."
|
||||
anchored = 1 //Let's not move these around. Some folk might get the idea to use these for assassinations
|
||||
var/list/enginetype = list()
|
||||
|
||||
/obj/item/radio/beacon/engine/Initialize()
|
||||
LAZYADD(GLOB.engine_beacon_list, src)
|
||||
|
||||
/obj/item/radio/beacon/engine/tesling
|
||||
name = "Engine Beacon for Tesla and Singularity"
|
||||
enginetype = list(ENGTYPE_TESLA, ENGTYPE_SING)
|
||||
|
||||
/obj/item/radio/beacon/engine/tesla
|
||||
name = "Engine Beacon for Tesla"
|
||||
enginetype = list(ENGTYPE_TESLA)
|
||||
|
||||
/obj/item/radio/beacon/engine/sing
|
||||
name = "Engine Beacon for Singularity"
|
||||
enginetype = list(ENGTYPE_SING)
|
||||
/obj/item/radio/beacon
|
||||
name = "Tracking Beacon"
|
||||
desc = "A beacon used by a teleporter."
|
||||
icon_state = "beacon"
|
||||
item_state = "signaler"
|
||||
var/code = "Beacon"
|
||||
origin_tech = "bluespace=1"
|
||||
var/emagged = 0
|
||||
var/syndicate = 0
|
||||
var/area_bypass = FALSE
|
||||
var/cc_beacon = FALSE //set if allowed to teleport to even if on zlevel2
|
||||
|
||||
/obj/item/radio/beacon/New()
|
||||
..()
|
||||
code = "[code] ([GLOB.beacons.len + 1])"
|
||||
GLOB.beacons += src
|
||||
|
||||
/obj/item/radio/beacon/Destroy()
|
||||
GLOB.beacons -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/beacon/emag_act(user as mob)
|
||||
if(!emagged)
|
||||
emagged = 1
|
||||
syndicate = 1
|
||||
to_chat(user, "<span class='notice'>The This beacon now only be locked on to by emagged teleporters!</span>")
|
||||
|
||||
/obj/item/radio/beacon/hear_talk()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/radio/beacon/send_hear()
|
||||
return null
|
||||
|
||||
/obj/item/radio/beacon/verb/alter_signal(t as text)
|
||||
set name = "Alter Beacon's Signal"
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
|
||||
if(usr.stat || usr.restrained())
|
||||
return
|
||||
|
||||
code = t
|
||||
if(isnull(code))
|
||||
code = initial(code)
|
||||
src.add_fingerprint(usr)
|
||||
return
|
||||
|
||||
/obj/item/radio/beacon/bacon //Probably a better way of doing this, I'm lazy.
|
||||
|
||||
/obj/item/radio/beacon/bacon/proc/digest_delay()
|
||||
QDEL_IN(src, 600)
|
||||
|
||||
// SINGULO BEACON SPAWNER
|
||||
/obj/item/radio/beacon/syndicate
|
||||
name = "suspicious beacon"
|
||||
desc = "A label on it reads: <i>Activate to have a singularity beacon teleported to your location</i>."
|
||||
origin_tech = "bluespace=6;syndicate=5"
|
||||
syndicate = TRUE
|
||||
var/obj/machinery/computer/syndicate_depot/teleporter/mycomputer
|
||||
|
||||
/obj/item/radio/beacon/syndicate/Destroy()
|
||||
if(mycomputer)
|
||||
mycomputer.mybeacon = null
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/beacon/syndicate/attack_self(mob/user)
|
||||
if(user)
|
||||
to_chat(user, "<span class='notice'>Locked In</span>")
|
||||
new /obj/machinery/power/singularity_beacon/syndicate( user.loc )
|
||||
playsound(src, 'sound/effects/pop.ogg', 100, 1, 1)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/radio/beacon/syndicate/bomb
|
||||
name = "suspicious beacon"
|
||||
desc = "A label on it reads: <i>Warning: Activating this device will send a high-ordinance explosive to your location</i>."
|
||||
origin_tech = "bluespace=5;syndicate=5"
|
||||
|
||||
/obj/item/radio/beacon/syndicate/bomb/attack_self(mob/user)
|
||||
if(user)
|
||||
to_chat(user, "<span class='notice'>Locked In</span>")
|
||||
new /obj/machinery/syndicatebomb( user.loc )
|
||||
playsound(src, 'sound/effects/pop.ogg', 100, 1, 1)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/radio/beacon/engine
|
||||
desc = "A label on it reads: <i>Warning: This device is used for transportation of high-density objects used for high-yield power generation. Stay away!</i>."
|
||||
anchored = 1 //Let's not move these around. Some folk might get the idea to use these for assassinations
|
||||
var/list/enginetype = list()
|
||||
|
||||
/obj/item/radio/beacon/engine/Initialize()
|
||||
LAZYADD(GLOB.engine_beacon_list, src)
|
||||
|
||||
/obj/item/radio/beacon/engine/tesling
|
||||
name = "Engine Beacon for Tesla and Singularity"
|
||||
enginetype = list(ENGTYPE_TESLA, ENGTYPE_SING)
|
||||
|
||||
/obj/item/radio/beacon/engine/tesla
|
||||
name = "Engine Beacon for Tesla"
|
||||
enginetype = list(ENGTYPE_TESLA)
|
||||
|
||||
/obj/item/radio/beacon/engine/sing
|
||||
name = "Engine Beacon for Singularity"
|
||||
enginetype = list(ENGTYPE_SING)
|
||||
|
||||
@@ -1,113 +1,113 @@
|
||||
/obj/item/radio/electropack
|
||||
name = "electropack"
|
||||
desc = "Dance my monkeys! DANCE!!!"
|
||||
icon_state = "electropack0"
|
||||
item_state = "electropack"
|
||||
frequency = AIRLOCK_FREQ
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BACK
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
materials = list(MAT_METAL=10000, MAT_GLASS=2500)
|
||||
var/code = 2
|
||||
|
||||
is_special = 1
|
||||
|
||||
/obj/item/radio/electropack/attack_hand(mob/user as mob)
|
||||
if(src == user.back)
|
||||
to_chat(user, "<span class='notice'>You need help taking this off!</span>")
|
||||
return 0
|
||||
. = ..()
|
||||
|
||||
/obj/item/radio/electropack/Destroy()
|
||||
if(istype(src.loc, /obj/item/assembly/shock_kit))
|
||||
var/obj/item/assembly/shock_kit/S = src.loc
|
||||
if(S.part1 == src)
|
||||
S.part1 = null
|
||||
else if(S.part2 == src)
|
||||
S.part2 = null
|
||||
master = null
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/electropack/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/clothing/head/helmet))
|
||||
if(!b_stat)
|
||||
to_chat(user, "<span class='notice'>[src] is not ready to be attached!</span>")
|
||||
return
|
||||
var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit( user )
|
||||
A.icon = 'icons/obj/assemblies.dmi'
|
||||
|
||||
if(!user.unEquip(W))
|
||||
to_chat(user, "<span class='notice'>\the [W] is stuck to your hand, you cannot attach it to \the [src]!</span>")
|
||||
return
|
||||
W.loc = A
|
||||
W.master = A
|
||||
A.part1 = W
|
||||
|
||||
user.unEquip(src)
|
||||
loc = A
|
||||
master = A
|
||||
A.part2 = src
|
||||
|
||||
user.put_in_hands(A)
|
||||
A.add_fingerprint(user)
|
||||
if(src.flags & NODROP)
|
||||
A.flags |= NODROP
|
||||
|
||||
/obj/item/radio/electropack/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["freq"])
|
||||
var/new_frequency = sanitize_frequency(frequency + text2num(href_list["freq"]))
|
||||
set_frequency(new_frequency)
|
||||
|
||||
else if(href_list["code"])
|
||||
code += text2num(href_list["code"])
|
||||
code = round(code)
|
||||
code = Clamp(code, 1, 100)
|
||||
|
||||
else if(href_list["power"])
|
||||
on = !on
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/item/radio/electropack/receive_signal(datum/signal/signal)
|
||||
if(!signal || signal.encryption != code)
|
||||
return
|
||||
|
||||
if(ismob(loc) && on)
|
||||
var/mob/M = loc
|
||||
var/turf/T = M.loc
|
||||
if(istype(T, /turf))
|
||||
if(!M.moved_recently && M.last_move)
|
||||
M.moved_recently = 1
|
||||
step(M, M.last_move)
|
||||
sleep(50)
|
||||
if(M)
|
||||
M.moved_recently = 0
|
||||
to_chat(M, "<span class='danger'>You feel a sharp shock!</span>")
|
||||
do_sparks(3, 1, M)
|
||||
|
||||
M.Weaken(5)
|
||||
|
||||
if(master)
|
||||
master.receive_signal()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/radio/electropack/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "radio_electro.tmpl", "[name]", 400, 500)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/item/radio/electropack/ui_data(mob/user, ui_key = "main", datum/topic_state/state = default_state)
|
||||
var/data[0]
|
||||
|
||||
data["power"] = on
|
||||
data["freq"] = format_frequency(frequency)
|
||||
data["code"] = code
|
||||
|
||||
return data
|
||||
/obj/item/radio/electropack
|
||||
name = "electropack"
|
||||
desc = "Dance my monkeys! DANCE!!!"
|
||||
icon_state = "electropack0"
|
||||
item_state = "electropack"
|
||||
frequency = AIRLOCK_FREQ
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BACK
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
materials = list(MAT_METAL=10000, MAT_GLASS=2500)
|
||||
var/code = 2
|
||||
|
||||
is_special = 1
|
||||
|
||||
/obj/item/radio/electropack/attack_hand(mob/user as mob)
|
||||
if(src == user.back)
|
||||
to_chat(user, "<span class='notice'>You need help taking this off!</span>")
|
||||
return 0
|
||||
. = ..()
|
||||
|
||||
/obj/item/radio/electropack/Destroy()
|
||||
if(istype(src.loc, /obj/item/assembly/shock_kit))
|
||||
var/obj/item/assembly/shock_kit/S = src.loc
|
||||
if(S.part1 == src)
|
||||
S.part1 = null
|
||||
else if(S.part2 == src)
|
||||
S.part2 = null
|
||||
master = null
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/electropack/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/clothing/head/helmet))
|
||||
if(!b_stat)
|
||||
to_chat(user, "<span class='notice'>[src] is not ready to be attached!</span>")
|
||||
return
|
||||
var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit( user )
|
||||
A.icon = 'icons/obj/assemblies.dmi'
|
||||
|
||||
if(!user.unEquip(W))
|
||||
to_chat(user, "<span class='notice'>\the [W] is stuck to your hand, you cannot attach it to \the [src]!</span>")
|
||||
return
|
||||
W.loc = A
|
||||
W.master = A
|
||||
A.part1 = W
|
||||
|
||||
user.unEquip(src)
|
||||
loc = A
|
||||
master = A
|
||||
A.part2 = src
|
||||
|
||||
user.put_in_hands(A)
|
||||
A.add_fingerprint(user)
|
||||
if(src.flags & NODROP)
|
||||
A.flags |= NODROP
|
||||
|
||||
/obj/item/radio/electropack/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["freq"])
|
||||
var/new_frequency = sanitize_frequency(frequency + text2num(href_list["freq"]))
|
||||
set_frequency(new_frequency)
|
||||
|
||||
else if(href_list["code"])
|
||||
code += text2num(href_list["code"])
|
||||
code = round(code)
|
||||
code = Clamp(code, 1, 100)
|
||||
|
||||
else if(href_list["power"])
|
||||
on = !on
|
||||
|
||||
add_fingerprint(usr)
|
||||
|
||||
/obj/item/radio/electropack/receive_signal(datum/signal/signal)
|
||||
if(!signal || signal.encryption != code)
|
||||
return
|
||||
|
||||
if(ismob(loc) && on)
|
||||
var/mob/M = loc
|
||||
var/turf/T = M.loc
|
||||
if(istype(T, /turf))
|
||||
if(!M.moved_recently && M.last_move)
|
||||
M.moved_recently = 1
|
||||
step(M, M.last_move)
|
||||
sleep(50)
|
||||
if(M)
|
||||
M.moved_recently = 0
|
||||
to_chat(M, "<span class='danger'>You feel a sharp shock!</span>")
|
||||
do_sparks(3, 1, M)
|
||||
|
||||
M.Weaken(5)
|
||||
|
||||
if(master)
|
||||
master.receive_signal()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/radio/electropack/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "radio_electro.tmpl", "[name]", 400, 500)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/item/radio/electropack/ui_data(mob/user, ui_key = "main", datum/topic_state/state = default_state)
|
||||
var/data[0]
|
||||
|
||||
data["power"] = on
|
||||
data["freq"] = format_frequency(frequency)
|
||||
data["code"] = code
|
||||
|
||||
return data
|
||||
|
||||
@@ -1,426 +1,426 @@
|
||||
/obj/item/radio/headset
|
||||
name = "radio headset"
|
||||
desc = "An updated, modular intercom that fits over the head. Takes encryption keys."
|
||||
var/radio_desc = ""
|
||||
icon_state = "headset"
|
||||
item_state = "headset"
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/ears.dmi',
|
||||
"Vox Armalis" = 'icons/mob/species/armalis/ears.dmi'
|
||||
) //We read you loud and skree-er.
|
||||
materials = list(MAT_METAL=75)
|
||||
subspace_transmission = TRUE
|
||||
canhear_range = 0 // can't hear headsets from very far away
|
||||
|
||||
slot_flags = SLOT_EARS
|
||||
var/translate_binary = FALSE
|
||||
var/translate_hive = FALSE
|
||||
var/obj/item/encryptionkey/keyslot1 = null
|
||||
var/obj/item/encryptionkey/keyslot2 = null
|
||||
|
||||
var/ks1type = null
|
||||
var/ks2type = null
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/radio/headset/New()
|
||||
..()
|
||||
internal_channels.Cut()
|
||||
|
||||
/obj/item/radio/headset/Initialize()
|
||||
..()
|
||||
|
||||
if(ks1type)
|
||||
keyslot1 = new ks1type(src)
|
||||
if(keyslot1.syndie)
|
||||
syndiekey = keyslot1
|
||||
if(ks2type)
|
||||
keyslot2 = new ks2type(src)
|
||||
if(keyslot2.syndie)
|
||||
syndiekey = keyslot2
|
||||
|
||||
recalculateChannels(TRUE)
|
||||
|
||||
/obj/item/radio/headset/Destroy()
|
||||
QDEL_NULL(keyslot1)
|
||||
QDEL_NULL(keyslot2)
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/headset/list_channels(var/mob/user)
|
||||
return list_secure_channels()
|
||||
|
||||
/obj/item/radio/headset/examine(mob/user)
|
||||
. = ..()
|
||||
if(in_range(src, user) && radio_desc)
|
||||
. += "The following channels are available:"
|
||||
. += radio_desc
|
||||
|
||||
/obj/item/radio/headset/handle_message_mode(mob/living/M as mob, list/message_pieces, channel)
|
||||
if(channel == "special")
|
||||
if(translate_binary)
|
||||
var/datum/language/binary = GLOB.all_languages["Robot Talk"]
|
||||
binary.broadcast(M, strip_prefixes(multilingual_to_message(message_pieces)))
|
||||
return RADIO_CONNECTION_NON_SUBSPACE
|
||||
if(translate_hive)
|
||||
var/datum/language/hivemind = GLOB.all_languages["Hivemind"]
|
||||
hivemind.broadcast(M, strip_prefixes(multilingual_to_message(message_pieces)))
|
||||
return RADIO_CONNECTION_NON_SUBSPACE
|
||||
return RADIO_CONNECTION_FAIL
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/headset/is_listening()
|
||||
if(ishuman(loc))
|
||||
var/mob/living/carbon/human/H = loc
|
||||
if(H.l_ear == src || H.r_ear == src)
|
||||
return ..()
|
||||
else if(isanimal(loc) || isAI(loc))
|
||||
return ..()
|
||||
|
||||
return FALSE
|
||||
|
||||
/obj/item/radio/headset/alt
|
||||
name = "bowman headset"
|
||||
desc = "An updated, modular intercom that fits over the head. Takes encryption keys. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
icon_state = "com_headset_alt"
|
||||
item_state = "com_headset_alt"
|
||||
|
||||
/obj/item/radio/headset/syndicate
|
||||
origin_tech = "syndicate=3"
|
||||
ks1type = /obj/item/encryptionkey/syndicate/nukeops
|
||||
|
||||
/obj/item/radio/headset/syndicate/alt //undisguised bowman with flash protection
|
||||
name = "syndicate headset"
|
||||
desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
origin_tech = "syndicate=3"
|
||||
icon_state = "syndie_headset"
|
||||
item_state = "syndie_headset"
|
||||
|
||||
/obj/item/radio/headset/syndicate/syndteam
|
||||
ks1type = /obj/item/encryptionkey/syndteam
|
||||
|
||||
/obj/item/radio/headset/syndicate/alt/syndteam
|
||||
ks1type = /obj/item/encryptionkey/syndteam
|
||||
|
||||
/obj/item/radio/headset/binary
|
||||
origin_tech = "syndicate=3"
|
||||
ks1type = /obj/item/encryptionkey/binary
|
||||
|
||||
/obj/item/radio/headset/headset_sec
|
||||
name = "security radio headset"
|
||||
desc = "This is used by your elite security force."
|
||||
icon_state = "sec_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_sec
|
||||
|
||||
/obj/item/radio/headset/headset_sec/alt
|
||||
name = "security bowman headset"
|
||||
desc = "This is used by your elite security force. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
icon_state = "sec_headset_alt"
|
||||
item_state = "sec_headset_alt"
|
||||
|
||||
/obj/item/radio/headset/headset_eng
|
||||
name = "engineering radio headset"
|
||||
desc = "When the engineers wish to chat like girls."
|
||||
icon_state = "eng_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_eng
|
||||
|
||||
/obj/item/radio/headset/headset_rob
|
||||
name = "robotics radio headset"
|
||||
desc = "Made specifically for the roboticists who cannot decide between departments."
|
||||
icon_state = "rob_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_rob
|
||||
|
||||
/obj/item/radio/headset/headset_med
|
||||
name = "medical radio headset"
|
||||
desc = "A headset for the trained staff of the medbay."
|
||||
icon_state = "med_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_med
|
||||
|
||||
/obj/item/radio/headset/headset_sci
|
||||
name = "science radio headset"
|
||||
desc = "A sciency headset. Like usual."
|
||||
icon_state = "sci_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_sci
|
||||
|
||||
/obj/item/radio/headset/headset_medsci
|
||||
name = "medical research radio headset"
|
||||
desc = "A headset that is a result of the mating between medical and science."
|
||||
icon_state = "medsci_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_medsci
|
||||
|
||||
/obj/item/radio/headset/headset_com
|
||||
name = "command radio headset"
|
||||
desc = "A headset with a commanding channel."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_com
|
||||
|
||||
/obj/item/radio/headset/heads/captain
|
||||
name = "captain's headset"
|
||||
desc = "The headset of the boss."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/captain
|
||||
|
||||
/obj/item/radio/headset/heads/captain/alt
|
||||
name = "\proper the captain's bowman headset"
|
||||
desc = "The headset of the boss. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
icon_state = "com_headset_alt"
|
||||
item_state = "com_headset_alt"
|
||||
|
||||
/obj/item/radio/headset/heads/rd
|
||||
name = "Research Director's headset"
|
||||
desc = "Headset of the researching God."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/rd
|
||||
|
||||
/obj/item/radio/headset/heads/hos
|
||||
name = "head of security's headset"
|
||||
desc = "The headset of the man who protects your worthless lives."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/hos
|
||||
|
||||
/obj/item/radio/headset/heads/hos/alt
|
||||
name = "\proper the head of security's bowman headset"
|
||||
desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
icon_state = "com_headset_alt"
|
||||
item_state = "com_headset_alt"
|
||||
|
||||
/obj/item/radio/headset/heads/ce
|
||||
name = "chief engineer's headset"
|
||||
desc = "The headset of the guy who is in charge of morons."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/ce
|
||||
|
||||
/obj/item/radio/headset/heads/cmo
|
||||
name = "chief medical officer's headset"
|
||||
desc = "The headset of the highly trained medical chief."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/cmo
|
||||
|
||||
/obj/item/radio/headset/heads/hop
|
||||
name = "head of personnel's headset"
|
||||
desc = "The headset of the guy who will one day be captain."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/hop
|
||||
|
||||
/obj/item/radio/headset/headset_cargo
|
||||
name = "supply radio headset"
|
||||
desc = "A headset used by the cargo department."
|
||||
icon_state = "cargo_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_cargo
|
||||
|
||||
/obj/item/radio/headset/headset_cargo/mining
|
||||
name = "mining radio headset"
|
||||
desc = "Headset used by shaft miners."
|
||||
icon_state = "mine_headset"
|
||||
|
||||
/obj/item/radio/headset/headset_service
|
||||
name = "service radio headset"
|
||||
desc = "Headset used by the service staff, tasked with keeping the station full, happy and clean."
|
||||
icon_state = "srv_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_service
|
||||
|
||||
/obj/item/radio/headset/heads/ntrep
|
||||
name = "nanotrasen representative's headset"
|
||||
desc = "The headset of the Nanotrasen Representative."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/ntrep
|
||||
|
||||
/obj/item/radio/headset/heads/magistrate
|
||||
name = "magistrate's headset"
|
||||
desc = "The headset of the Magistrate."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/magistrate
|
||||
|
||||
/obj/item/radio/headset/heads/magistrate/alt
|
||||
name = "\proper magistrate's bowman headset"
|
||||
desc = "The headset of the Magistrate. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
icon_state = "com_headset_alt"
|
||||
item_state = "com_headset_alt"
|
||||
|
||||
/obj/item/radio/headset/heads/blueshield
|
||||
name = "blueshield's headset"
|
||||
desc = "The headset of the Blueshield."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/blueshield
|
||||
|
||||
/obj/item/radio/headset/heads/blueshield/alt
|
||||
name = "\proper blueshield's bowman headset"
|
||||
desc = "The headset of the Blueshield. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
icon_state = "com_headset_alt"
|
||||
item_state = "com_headset_alt"
|
||||
|
||||
/obj/item/radio/headset/ert
|
||||
name = "emergency response team headset"
|
||||
desc = "The headset of the boss's boss."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/ert
|
||||
|
||||
/obj/item/radio/headset/ert/alt
|
||||
name = "\proper emergency response team's bowman headset"
|
||||
desc = "The headset of the boss. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
icon_state = "com_headset_alt"
|
||||
item_state = "com_headset_alt"
|
||||
|
||||
/obj/item/radio/headset/centcom
|
||||
name = "\proper centcom officer's bowman headset"
|
||||
desc = "The headset of final authority. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
icon_state = "com_headset_alt"
|
||||
item_state = "com_headset_alt"
|
||||
ks2type = /obj/item/encryptionkey/centcom
|
||||
|
||||
/obj/item/radio/headset/heads/ai_integrated //No need to care about icons, it should be hidden inside the AI anyway.
|
||||
name = "\improper AI subspace transceiver"
|
||||
desc = "Integrated AI radio transceiver."
|
||||
icon = 'icons/obj/robot_component.dmi'
|
||||
icon_state = "radio"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/ai_integrated
|
||||
var/myAi = null // Atlantis: Reference back to the AI which has this radio.
|
||||
var/disabledAi = 0 // Atlantis: Used to manually disable AI's integrated radio via intellicard menu.
|
||||
|
||||
/obj/item/radio/headset/heads/ai_integrated/is_listening()
|
||||
if(disabledAi)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/headset/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/encryptionkey/))
|
||||
user.set_machine(src)
|
||||
if(keyslot1 && keyslot2)
|
||||
to_chat(user, "The headset can't hold another key!")
|
||||
return
|
||||
|
||||
if(!keyslot1)
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
keyslot1 = W
|
||||
else
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
keyslot2 = W
|
||||
recalculateChannels()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/headset/screwdriver_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.use_tool(src, user, 0, volume = 0))
|
||||
return
|
||||
user.set_machine(src)
|
||||
if(keyslot1 || keyslot2)
|
||||
|
||||
for(var/ch_name in channels)
|
||||
SSradio.remove_object(src, SSradio.radiochannels[ch_name])
|
||||
secure_radio_connections[ch_name] = null
|
||||
|
||||
if(keyslot1)
|
||||
var/turf/T = get_turf(user)
|
||||
if(T)
|
||||
keyslot1.loc = T
|
||||
keyslot1 = null
|
||||
if(keyslot2)
|
||||
var/turf/T = get_turf(user)
|
||||
if(T)
|
||||
keyslot2.loc = T
|
||||
keyslot2 = null
|
||||
|
||||
recalculateChannels()
|
||||
to_chat(user, "You pop out the encryption keys in the headset!")
|
||||
I.play_tool_sound(user, I.tool_volume)
|
||||
else
|
||||
to_chat(user, "This headset doesn't have any encryption keys! How useless...")
|
||||
|
||||
/obj/item/radio/headset/proc/recalculateChannels(var/setDescription = FALSE)
|
||||
channels = list()
|
||||
translate_binary = FALSE
|
||||
translate_hive = FALSE
|
||||
syndiekey = null
|
||||
|
||||
if(keyslot1)
|
||||
for(var/ch_name in keyslot1.channels)
|
||||
if(ch_name in channels)
|
||||
continue
|
||||
channels += ch_name
|
||||
channels[ch_name] = keyslot1.channels[ch_name]
|
||||
|
||||
if(keyslot1.translate_binary)
|
||||
translate_binary = TRUE
|
||||
|
||||
if(keyslot1.translate_hive)
|
||||
translate_hive = TRUE
|
||||
|
||||
if(keyslot1.syndie)
|
||||
syndiekey = keyslot1
|
||||
|
||||
if(keyslot2)
|
||||
for(var/ch_name in keyslot2.channels)
|
||||
if(ch_name in channels)
|
||||
continue
|
||||
channels += ch_name
|
||||
channels[ch_name] = keyslot2.channels[ch_name]
|
||||
|
||||
if(keyslot2.translate_binary)
|
||||
translate_binary = TRUE
|
||||
|
||||
if(keyslot2.translate_hive)
|
||||
translate_hive = TRUE
|
||||
|
||||
if(keyslot2.syndie)
|
||||
syndiekey = keyslot2
|
||||
|
||||
|
||||
for(var/ch_name in channels)
|
||||
if(!SSradio)
|
||||
name = "broken radio headset"
|
||||
return
|
||||
|
||||
secure_radio_connections[ch_name] = SSradio.add_object(src, SSradio.radiochannels[ch_name], RADIO_CHAT)
|
||||
|
||||
if(setDescription)
|
||||
setupRadioDescription()
|
||||
|
||||
return
|
||||
|
||||
/obj/item/radio/headset/proc/setupRadioDescription()
|
||||
var/radio_text = ""
|
||||
for(var/i = 1 to channels.len)
|
||||
var/channel = channels[i]
|
||||
var/key = get_radio_key_from_channel(channel)
|
||||
radio_text += "[key] - [channel]"
|
||||
if(i != channels.len)
|
||||
radio_text += ", "
|
||||
|
||||
radio_desc = radio_text
|
||||
|
||||
/obj/item/radio/headset/proc/make_syndie() // Turns normal radios into Syndicate radios!
|
||||
qdel(keyslot1)
|
||||
keyslot1 = new /obj/item/encryptionkey/syndicate
|
||||
syndiekey = keyslot1
|
||||
recalculateChannels()
|
||||
/obj/item/radio/headset
|
||||
name = "radio headset"
|
||||
desc = "An updated, modular intercom that fits over the head. Takes encryption keys."
|
||||
var/radio_desc = ""
|
||||
icon_state = "headset"
|
||||
item_state = "headset"
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/species/vox/ears.dmi',
|
||||
"Vox Armalis" = 'icons/mob/species/armalis/ears.dmi'
|
||||
) //We read you loud and skree-er.
|
||||
materials = list(MAT_METAL=75)
|
||||
subspace_transmission = TRUE
|
||||
canhear_range = 0 // can't hear headsets from very far away
|
||||
|
||||
slot_flags = SLOT_EARS
|
||||
var/translate_binary = FALSE
|
||||
var/translate_hive = FALSE
|
||||
var/obj/item/encryptionkey/keyslot1 = null
|
||||
var/obj/item/encryptionkey/keyslot2 = null
|
||||
|
||||
var/ks1type = null
|
||||
var/ks2type = null
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/radio/headset/New()
|
||||
..()
|
||||
internal_channels.Cut()
|
||||
|
||||
/obj/item/radio/headset/Initialize()
|
||||
..()
|
||||
|
||||
if(ks1type)
|
||||
keyslot1 = new ks1type(src)
|
||||
if(keyslot1.syndie)
|
||||
syndiekey = keyslot1
|
||||
if(ks2type)
|
||||
keyslot2 = new ks2type(src)
|
||||
if(keyslot2.syndie)
|
||||
syndiekey = keyslot2
|
||||
|
||||
recalculateChannels(TRUE)
|
||||
|
||||
/obj/item/radio/headset/Destroy()
|
||||
QDEL_NULL(keyslot1)
|
||||
QDEL_NULL(keyslot2)
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/headset/list_channels(var/mob/user)
|
||||
return list_secure_channels()
|
||||
|
||||
/obj/item/radio/headset/examine(mob/user)
|
||||
. = ..()
|
||||
if(in_range(src, user) && radio_desc)
|
||||
. += "The following channels are available:"
|
||||
. += radio_desc
|
||||
|
||||
/obj/item/radio/headset/handle_message_mode(mob/living/M as mob, list/message_pieces, channel)
|
||||
if(channel == "special")
|
||||
if(translate_binary)
|
||||
var/datum/language/binary = GLOB.all_languages["Robot Talk"]
|
||||
binary.broadcast(M, strip_prefixes(multilingual_to_message(message_pieces)))
|
||||
return RADIO_CONNECTION_NON_SUBSPACE
|
||||
if(translate_hive)
|
||||
var/datum/language/hivemind = GLOB.all_languages["Hivemind"]
|
||||
hivemind.broadcast(M, strip_prefixes(multilingual_to_message(message_pieces)))
|
||||
return RADIO_CONNECTION_NON_SUBSPACE
|
||||
return RADIO_CONNECTION_FAIL
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/headset/is_listening()
|
||||
if(ishuman(loc))
|
||||
var/mob/living/carbon/human/H = loc
|
||||
if(H.l_ear == src || H.r_ear == src)
|
||||
return ..()
|
||||
else if(isanimal(loc) || isAI(loc))
|
||||
return ..()
|
||||
|
||||
return FALSE
|
||||
|
||||
/obj/item/radio/headset/alt
|
||||
name = "bowman headset"
|
||||
desc = "An updated, modular intercom that fits over the head. Takes encryption keys. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
icon_state = "com_headset_alt"
|
||||
item_state = "com_headset_alt"
|
||||
|
||||
/obj/item/radio/headset/syndicate
|
||||
origin_tech = "syndicate=3"
|
||||
ks1type = /obj/item/encryptionkey/syndicate/nukeops
|
||||
|
||||
/obj/item/radio/headset/syndicate/alt //undisguised bowman with flash protection
|
||||
name = "syndicate headset"
|
||||
desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
origin_tech = "syndicate=3"
|
||||
icon_state = "syndie_headset"
|
||||
item_state = "syndie_headset"
|
||||
|
||||
/obj/item/radio/headset/syndicate/syndteam
|
||||
ks1type = /obj/item/encryptionkey/syndteam
|
||||
|
||||
/obj/item/radio/headset/syndicate/alt/syndteam
|
||||
ks1type = /obj/item/encryptionkey/syndteam
|
||||
|
||||
/obj/item/radio/headset/binary
|
||||
origin_tech = "syndicate=3"
|
||||
ks1type = /obj/item/encryptionkey/binary
|
||||
|
||||
/obj/item/radio/headset/headset_sec
|
||||
name = "security radio headset"
|
||||
desc = "This is used by your elite security force."
|
||||
icon_state = "sec_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_sec
|
||||
|
||||
/obj/item/radio/headset/headset_sec/alt
|
||||
name = "security bowman headset"
|
||||
desc = "This is used by your elite security force. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
icon_state = "sec_headset_alt"
|
||||
item_state = "sec_headset_alt"
|
||||
|
||||
/obj/item/radio/headset/headset_eng
|
||||
name = "engineering radio headset"
|
||||
desc = "When the engineers wish to chat like girls."
|
||||
icon_state = "eng_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_eng
|
||||
|
||||
/obj/item/radio/headset/headset_rob
|
||||
name = "robotics radio headset"
|
||||
desc = "Made specifically for the roboticists who cannot decide between departments."
|
||||
icon_state = "rob_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_rob
|
||||
|
||||
/obj/item/radio/headset/headset_med
|
||||
name = "medical radio headset"
|
||||
desc = "A headset for the trained staff of the medbay."
|
||||
icon_state = "med_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_med
|
||||
|
||||
/obj/item/radio/headset/headset_sci
|
||||
name = "science radio headset"
|
||||
desc = "A sciency headset. Like usual."
|
||||
icon_state = "sci_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_sci
|
||||
|
||||
/obj/item/radio/headset/headset_medsci
|
||||
name = "medical research radio headset"
|
||||
desc = "A headset that is a result of the mating between medical and science."
|
||||
icon_state = "medsci_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_medsci
|
||||
|
||||
/obj/item/radio/headset/headset_com
|
||||
name = "command radio headset"
|
||||
desc = "A headset with a commanding channel."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_com
|
||||
|
||||
/obj/item/radio/headset/heads/captain
|
||||
name = "captain's headset"
|
||||
desc = "The headset of the boss."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/captain
|
||||
|
||||
/obj/item/radio/headset/heads/captain/alt
|
||||
name = "\proper the captain's bowman headset"
|
||||
desc = "The headset of the boss. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
icon_state = "com_headset_alt"
|
||||
item_state = "com_headset_alt"
|
||||
|
||||
/obj/item/radio/headset/heads/rd
|
||||
name = "Research Director's headset"
|
||||
desc = "Headset of the researching God."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/rd
|
||||
|
||||
/obj/item/radio/headset/heads/hos
|
||||
name = "head of security's headset"
|
||||
desc = "The headset of the man who protects your worthless lives."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/hos
|
||||
|
||||
/obj/item/radio/headset/heads/hos/alt
|
||||
name = "\proper the head of security's bowman headset"
|
||||
desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
icon_state = "com_headset_alt"
|
||||
item_state = "com_headset_alt"
|
||||
|
||||
/obj/item/radio/headset/heads/ce
|
||||
name = "chief engineer's headset"
|
||||
desc = "The headset of the guy who is in charge of morons."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/ce
|
||||
|
||||
/obj/item/radio/headset/heads/cmo
|
||||
name = "chief medical officer's headset"
|
||||
desc = "The headset of the highly trained medical chief."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/cmo
|
||||
|
||||
/obj/item/radio/headset/heads/hop
|
||||
name = "head of personnel's headset"
|
||||
desc = "The headset of the guy who will one day be captain."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/hop
|
||||
|
||||
/obj/item/radio/headset/headset_cargo
|
||||
name = "supply radio headset"
|
||||
desc = "A headset used by the cargo department."
|
||||
icon_state = "cargo_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_cargo
|
||||
|
||||
/obj/item/radio/headset/headset_cargo/mining
|
||||
name = "mining radio headset"
|
||||
desc = "Headset used by shaft miners."
|
||||
icon_state = "mine_headset"
|
||||
|
||||
/obj/item/radio/headset/headset_service
|
||||
name = "service radio headset"
|
||||
desc = "Headset used by the service staff, tasked with keeping the station full, happy and clean."
|
||||
icon_state = "srv_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/headset_service
|
||||
|
||||
/obj/item/radio/headset/heads/ntrep
|
||||
name = "nanotrasen representative's headset"
|
||||
desc = "The headset of the Nanotrasen Representative."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/ntrep
|
||||
|
||||
/obj/item/radio/headset/heads/magistrate
|
||||
name = "magistrate's headset"
|
||||
desc = "The headset of the Magistrate."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/magistrate
|
||||
|
||||
/obj/item/radio/headset/heads/magistrate/alt
|
||||
name = "\proper magistrate's bowman headset"
|
||||
desc = "The headset of the Magistrate. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
icon_state = "com_headset_alt"
|
||||
item_state = "com_headset_alt"
|
||||
|
||||
/obj/item/radio/headset/heads/blueshield
|
||||
name = "blueshield's headset"
|
||||
desc = "The headset of the Blueshield."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/blueshield
|
||||
|
||||
/obj/item/radio/headset/heads/blueshield/alt
|
||||
name = "\proper blueshield's bowman headset"
|
||||
desc = "The headset of the Blueshield. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
icon_state = "com_headset_alt"
|
||||
item_state = "com_headset_alt"
|
||||
|
||||
/obj/item/radio/headset/ert
|
||||
name = "emergency response team headset"
|
||||
desc = "The headset of the boss's boss."
|
||||
icon_state = "com_headset"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/ert
|
||||
|
||||
/obj/item/radio/headset/ert/alt
|
||||
name = "\proper emergency response team's bowman headset"
|
||||
desc = "The headset of the boss. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
icon_state = "com_headset_alt"
|
||||
item_state = "com_headset_alt"
|
||||
|
||||
/obj/item/radio/headset/centcom
|
||||
name = "\proper centcom officer's bowman headset"
|
||||
desc = "The headset of final authority. Protects ears from flashbangs."
|
||||
flags = EARBANGPROTECT
|
||||
icon_state = "com_headset_alt"
|
||||
item_state = "com_headset_alt"
|
||||
ks2type = /obj/item/encryptionkey/centcom
|
||||
|
||||
/obj/item/radio/headset/heads/ai_integrated //No need to care about icons, it should be hidden inside the AI anyway.
|
||||
name = "\improper AI subspace transceiver"
|
||||
desc = "Integrated AI radio transceiver."
|
||||
icon = 'icons/obj/robot_component.dmi'
|
||||
icon_state = "radio"
|
||||
item_state = "headset"
|
||||
ks2type = /obj/item/encryptionkey/heads/ai_integrated
|
||||
var/myAi = null // Atlantis: Reference back to the AI which has this radio.
|
||||
var/disabledAi = 0 // Atlantis: Used to manually disable AI's integrated radio via intellicard menu.
|
||||
|
||||
/obj/item/radio/headset/heads/ai_integrated/is_listening()
|
||||
if(disabledAi)
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/headset/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/encryptionkey/))
|
||||
user.set_machine(src)
|
||||
if(keyslot1 && keyslot2)
|
||||
to_chat(user, "The headset can't hold another key!")
|
||||
return
|
||||
|
||||
if(!keyslot1)
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
keyslot1 = W
|
||||
else
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
keyslot2 = W
|
||||
recalculateChannels()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/headset/screwdriver_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!I.use_tool(src, user, 0, volume = 0))
|
||||
return
|
||||
user.set_machine(src)
|
||||
if(keyslot1 || keyslot2)
|
||||
|
||||
for(var/ch_name in channels)
|
||||
SSradio.remove_object(src, SSradio.radiochannels[ch_name])
|
||||
secure_radio_connections[ch_name] = null
|
||||
|
||||
if(keyslot1)
|
||||
var/turf/T = get_turf(user)
|
||||
if(T)
|
||||
keyslot1.loc = T
|
||||
keyslot1 = null
|
||||
if(keyslot2)
|
||||
var/turf/T = get_turf(user)
|
||||
if(T)
|
||||
keyslot2.loc = T
|
||||
keyslot2 = null
|
||||
|
||||
recalculateChannels()
|
||||
to_chat(user, "You pop out the encryption keys in the headset!")
|
||||
I.play_tool_sound(user, I.tool_volume)
|
||||
else
|
||||
to_chat(user, "This headset doesn't have any encryption keys! How useless...")
|
||||
|
||||
/obj/item/radio/headset/proc/recalculateChannels(var/setDescription = FALSE)
|
||||
channels = list()
|
||||
translate_binary = FALSE
|
||||
translate_hive = FALSE
|
||||
syndiekey = null
|
||||
|
||||
if(keyslot1)
|
||||
for(var/ch_name in keyslot1.channels)
|
||||
if(ch_name in channels)
|
||||
continue
|
||||
channels += ch_name
|
||||
channels[ch_name] = keyslot1.channels[ch_name]
|
||||
|
||||
if(keyslot1.translate_binary)
|
||||
translate_binary = TRUE
|
||||
|
||||
if(keyslot1.translate_hive)
|
||||
translate_hive = TRUE
|
||||
|
||||
if(keyslot1.syndie)
|
||||
syndiekey = keyslot1
|
||||
|
||||
if(keyslot2)
|
||||
for(var/ch_name in keyslot2.channels)
|
||||
if(ch_name in channels)
|
||||
continue
|
||||
channels += ch_name
|
||||
channels[ch_name] = keyslot2.channels[ch_name]
|
||||
|
||||
if(keyslot2.translate_binary)
|
||||
translate_binary = TRUE
|
||||
|
||||
if(keyslot2.translate_hive)
|
||||
translate_hive = TRUE
|
||||
|
||||
if(keyslot2.syndie)
|
||||
syndiekey = keyslot2
|
||||
|
||||
|
||||
for(var/ch_name in channels)
|
||||
if(!SSradio)
|
||||
name = "broken radio headset"
|
||||
return
|
||||
|
||||
secure_radio_connections[ch_name] = SSradio.add_object(src, SSradio.radiochannels[ch_name], RADIO_CHAT)
|
||||
|
||||
if(setDescription)
|
||||
setupRadioDescription()
|
||||
|
||||
return
|
||||
|
||||
/obj/item/radio/headset/proc/setupRadioDescription()
|
||||
var/radio_text = ""
|
||||
for(var/i = 1 to channels.len)
|
||||
var/channel = channels[i]
|
||||
var/key = get_radio_key_from_channel(channel)
|
||||
radio_text += "[key] - [channel]"
|
||||
if(i != channels.len)
|
||||
radio_text += ", "
|
||||
|
||||
radio_desc = radio_text
|
||||
|
||||
/obj/item/radio/headset/proc/make_syndie() // Turns normal radios into Syndicate radios!
|
||||
qdel(keyslot1)
|
||||
keyslot1 = new /obj/item/encryptionkey/syndicate
|
||||
syndiekey = keyslot1
|
||||
recalculateChannels()
|
||||
|
||||
@@ -1,274 +1,274 @@
|
||||
/obj/item/radio/intercom
|
||||
name = "station intercom (General)"
|
||||
desc = "Talk through this."
|
||||
icon_state = "intercom"
|
||||
anchored = 1
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
canhear_range = 2
|
||||
flags = CONDUCT
|
||||
var/number = 0
|
||||
var/circuitry_installed = 1
|
||||
var/last_tick //used to delay the powercheck
|
||||
var/buildstage = 0
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/radio/intercom/custom
|
||||
name = "station intercom (Custom)"
|
||||
broadcasting = 0
|
||||
listening = 0
|
||||
|
||||
/obj/item/radio/intercom/interrogation
|
||||
name = "station intercom (Interrogation)"
|
||||
frequency = AIRLOCK_FREQ
|
||||
|
||||
/obj/item/radio/intercom/private
|
||||
name = "station intercom (Private)"
|
||||
frequency = AI_FREQ
|
||||
|
||||
/obj/item/radio/intercom/command
|
||||
name = "station intercom (Command)"
|
||||
frequency = COMM_FREQ
|
||||
|
||||
/obj/item/radio/intercom/specops
|
||||
name = "\improper Special Operations intercom"
|
||||
frequency = ERT_FREQ
|
||||
|
||||
/obj/item/radio/intercom/department
|
||||
canhear_range = 5
|
||||
broadcasting = 0
|
||||
listening = 1
|
||||
|
||||
/obj/item/radio/intercom/department/medbay
|
||||
name = "station intercom (Medbay)"
|
||||
frequency = MED_I_FREQ
|
||||
|
||||
/obj/item/radio/intercom/department/security
|
||||
name = "station intercom (Security)"
|
||||
frequency = SEC_I_FREQ
|
||||
|
||||
/obj/item/radio/intercom/New(turf/loc, ndir, building = 3)
|
||||
..()
|
||||
buildstage = building
|
||||
if(buildstage)
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
if(ndir)
|
||||
pixel_x = (ndir & EAST|WEST) ? (ndir == EAST ? 28 : -28) : 0
|
||||
pixel_y = (ndir & NORTH|SOUTH) ? (ndir == NORTH ? 28 : -28) : 0
|
||||
dir=ndir
|
||||
b_stat=1
|
||||
on = 0
|
||||
GLOB.global_intercoms.Add(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/radio/intercom/department/medbay/New()
|
||||
..()
|
||||
internal_channels = default_medbay_channels.Copy()
|
||||
|
||||
/obj/item/radio/intercom/department/security/New()
|
||||
..()
|
||||
internal_channels = list(
|
||||
num2text(PUB_FREQ) = list(),
|
||||
num2text(SEC_I_FREQ) = list(ACCESS_SECURITY)
|
||||
)
|
||||
|
||||
/obj/item/radio/intercom/syndicate
|
||||
name = "illicit intercom"
|
||||
desc = "Talk through this. Evilly"
|
||||
frequency = SYND_FREQ
|
||||
subspace_transmission = TRUE
|
||||
syndiekey = new /obj/item/encryptionkey/syndicate/nukeops
|
||||
|
||||
/obj/item/radio/intercom/syndicate/New()
|
||||
..()
|
||||
internal_channels[num2text(SYND_FREQ)] = list(ACCESS_SYNDICATE)
|
||||
|
||||
/obj/item/radio/intercom/pirate
|
||||
name = "pirate radio intercom"
|
||||
desc = "You wouldn't steal a space shuttle. Piracy. It's a crime!"
|
||||
subspace_transmission = 1
|
||||
|
||||
/obj/item/radio/intercom/pirate/New()
|
||||
..()
|
||||
internal_channels.Cut()
|
||||
internal_channels = list(
|
||||
num2text(PUB_FREQ) = list(),
|
||||
num2text(AI_FREQ) = list(),
|
||||
num2text(COMM_FREQ)= list(),
|
||||
num2text(ENG_FREQ) = list(),
|
||||
num2text(MED_FREQ) = list(),
|
||||
num2text(MED_I_FREQ)=list(),
|
||||
num2text(SEC_FREQ) = list(),
|
||||
num2text(SEC_I_FREQ)=list(),
|
||||
num2text(SCI_FREQ) = list(),
|
||||
num2text(SUP_FREQ) = list(),
|
||||
num2text(SRV_FREQ) = list()
|
||||
)
|
||||
|
||||
/obj/item/radio/intercom/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
GLOB.global_intercoms.Remove(src)
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/intercom/attack_ai(mob/user as mob)
|
||||
add_hiddenprint(user)
|
||||
add_fingerprint(user)
|
||||
spawn(0)
|
||||
attack_self(user)
|
||||
|
||||
/obj/item/radio/intercom/attack_hand(mob/user as mob)
|
||||
add_fingerprint(user)
|
||||
spawn(0)
|
||||
attack_self(user)
|
||||
|
||||
/obj/item/radio/intercom/receive_range(freq, level)
|
||||
if(!is_listening())
|
||||
return -1
|
||||
if(!(0 in level))
|
||||
var/turf/position = get_turf(src)
|
||||
// TODO: Integrate radio with the space manager
|
||||
if(isnull(position) || !(position.z in level))
|
||||
return -1
|
||||
if(freq in SSradio.ANTAG_FREQS)
|
||||
if(!(syndiekey))
|
||||
return -1//Prevents broadcast of messages over devices lacking the encryption
|
||||
|
||||
return canhear_range
|
||||
|
||||
/obj/item/radio/intercom/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/stack/tape_roll)) //eww
|
||||
return
|
||||
else if(iscoil(W) && buildstage == 1)
|
||||
var/obj/item/stack/cable_coil/coil = W
|
||||
if(coil.amount < 5)
|
||||
to_chat(user, "<span class='warning'>You need more cable for this!</span>")
|
||||
return
|
||||
if(do_after(user, 10 * coil.toolspeed, target = src) && buildstage == 1)
|
||||
coil.use(5)
|
||||
to_chat(user, "<span class='notice'>You wire \the [src]!</span>")
|
||||
buildstage = 2
|
||||
return 1
|
||||
else if(istype(W,/obj/item/intercom_electronics) && buildstage == 0)
|
||||
playsound(get_turf(src), W.usesound, 50, 1)
|
||||
if(do_after(user, 10 * W.toolspeed, target = src) && buildstage == 0)
|
||||
qdel(W)
|
||||
to_chat(user, "<span class='notice'>You insert \the [W] into \the [src]!</span>")
|
||||
buildstage = 1
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/intercom/crowbar_act(mob/user, obj/item/I)
|
||||
if(buildstage != 1)
|
||||
return
|
||||
. = TRUE
|
||||
if(!I.tool_use_check(user, 0))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You begin removing the electronics...</span>")
|
||||
if(!I.use_tool(src, user, 10, volume = I.tool_volume) || buildstage != 1)
|
||||
return
|
||||
new /obj/item/intercom_electronics(get_turf(src))
|
||||
to_chat(user, "<span class='notice'>The circuit board pops out!</span>")
|
||||
buildstage = 0
|
||||
|
||||
/obj/item/radio/intercom/screwdriver_act(mob/user, obj/item/I)
|
||||
if(buildstage != 2)
|
||||
return ..()
|
||||
. = TRUE
|
||||
if(!I.tool_use_check(user, 0))
|
||||
return
|
||||
if(!I.use_tool(src, user, 10, volume = I.tool_volume) || buildstage != 2)
|
||||
return
|
||||
update_icon()
|
||||
on = 1
|
||||
b_stat = 0
|
||||
buildstage = 3
|
||||
to_chat(user, "<span class='notice'>You secure the electronics!</span>")
|
||||
update_icon()
|
||||
START_PROCESSING(SSobj, src)
|
||||
for(var/i, i<= 5, i++)
|
||||
wires.UpdateCut(i,1)
|
||||
|
||||
/obj/item/radio/intercom/wirecutter_act(mob/user, obj/item/I)
|
||||
if(!(buildstage == 3 && b_stat && wires.IsAllCut()))
|
||||
return
|
||||
. = TRUE
|
||||
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
|
||||
return
|
||||
WIRECUTTER_SNIP_MESSAGE
|
||||
new /obj/item/stack/cable_coil(get_turf(src),5)
|
||||
on = 0
|
||||
b_stat = 1
|
||||
buildstage = 1
|
||||
update_icon()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/radio/intercom/welder_act(mob/user, obj/item/I)
|
||||
if(!buildstage)
|
||||
return
|
||||
. = TRUE
|
||||
if(!I.tool_use_check(user, 3))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start slicing [src] from the wall...</span>")
|
||||
if(I.use_tool(src, user, 10, amount = 3, volume = I.tool_volume))
|
||||
to_chat(user, "<span class='notice'>You cut [src] free from the wall!</span>")
|
||||
new /obj/item/mounted/frame/intercom(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/radio/intercom/update_icon()
|
||||
if(!circuitry_installed)
|
||||
icon_state="intercom-frame"
|
||||
return
|
||||
icon_state = "intercom[!on?"-p":""][b_stat ? "-open":""]"
|
||||
|
||||
/obj/item/radio/intercom/process()
|
||||
if(((world.timeofday - last_tick) > 30) || ((world.timeofday - last_tick) < 0))
|
||||
last_tick = world.timeofday
|
||||
|
||||
|
||||
if(!src.loc)
|
||||
on = 0
|
||||
else
|
||||
var/area/A = get_area(src)
|
||||
if(!A)
|
||||
on = 0
|
||||
else
|
||||
on = A.powered(EQUIP) // set "on" to the power status
|
||||
update_icon()
|
||||
|
||||
/obj/item/intercom_electronics
|
||||
name = "intercom electronics"
|
||||
icon = 'icons/obj/doors/door_assembly.dmi'
|
||||
icon_state = "door_electronics"
|
||||
desc = "Looks like a circuit. Probably is."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
materials = list(MAT_METAL=50, MAT_GLASS=50)
|
||||
origin_tech = "engineering=2;programming=1"
|
||||
toolspeed = 1
|
||||
usesound = 'sound/items/deconstruct.ogg'
|
||||
|
||||
/obj/item/radio/intercom/locked
|
||||
var/locked_frequency
|
||||
|
||||
/obj/item/radio/intercom/locked/set_frequency(var/frequency)
|
||||
if(frequency == locked_frequency)
|
||||
..(locked_frequency)
|
||||
|
||||
/obj/item/radio/intercom/locked/list_channels()
|
||||
return ""
|
||||
|
||||
/obj/item/radio/intercom/locked/ai_private
|
||||
name = "\improper AI intercom"
|
||||
frequency = AI_FREQ
|
||||
|
||||
/obj/item/radio/intercom/locked/confessional
|
||||
name = "confessional intercom"
|
||||
frequency = 1480
|
||||
|
||||
/obj/item/radio/intercom/locked/prison
|
||||
name = "\improper prison intercom"
|
||||
desc = "Talk through this. It looks like it has been modified to not broadcast."
|
||||
|
||||
/obj/item/radio/intercom/locked/prison/New()
|
||||
..()
|
||||
wires.CutWireIndex(RADIO_WIRE_TRANSMIT)
|
||||
/obj/item/radio/intercom
|
||||
name = "station intercom (General)"
|
||||
desc = "Talk through this."
|
||||
icon_state = "intercom"
|
||||
anchored = 1
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
canhear_range = 2
|
||||
flags = CONDUCT
|
||||
var/number = 0
|
||||
var/circuitry_installed = 1
|
||||
var/last_tick //used to delay the powercheck
|
||||
var/buildstage = 0
|
||||
dog_fashion = null
|
||||
|
||||
/obj/item/radio/intercom/custom
|
||||
name = "station intercom (Custom)"
|
||||
broadcasting = 0
|
||||
listening = 0
|
||||
|
||||
/obj/item/radio/intercom/interrogation
|
||||
name = "station intercom (Interrogation)"
|
||||
frequency = AIRLOCK_FREQ
|
||||
|
||||
/obj/item/radio/intercom/private
|
||||
name = "station intercom (Private)"
|
||||
frequency = AI_FREQ
|
||||
|
||||
/obj/item/radio/intercom/command
|
||||
name = "station intercom (Command)"
|
||||
frequency = COMM_FREQ
|
||||
|
||||
/obj/item/radio/intercom/specops
|
||||
name = "\improper Special Operations intercom"
|
||||
frequency = ERT_FREQ
|
||||
|
||||
/obj/item/radio/intercom/department
|
||||
canhear_range = 5
|
||||
broadcasting = 0
|
||||
listening = 1
|
||||
|
||||
/obj/item/radio/intercom/department/medbay
|
||||
name = "station intercom (Medbay)"
|
||||
frequency = MED_I_FREQ
|
||||
|
||||
/obj/item/radio/intercom/department/security
|
||||
name = "station intercom (Security)"
|
||||
frequency = SEC_I_FREQ
|
||||
|
||||
/obj/item/radio/intercom/New(turf/loc, ndir, building = 3)
|
||||
..()
|
||||
buildstage = building
|
||||
if(buildstage)
|
||||
START_PROCESSING(SSobj, src)
|
||||
else
|
||||
if(ndir)
|
||||
pixel_x = (ndir & EAST|WEST) ? (ndir == EAST ? 28 : -28) : 0
|
||||
pixel_y = (ndir & NORTH|SOUTH) ? (ndir == NORTH ? 28 : -28) : 0
|
||||
dir=ndir
|
||||
b_stat=1
|
||||
on = 0
|
||||
GLOB.global_intercoms.Add(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/radio/intercom/department/medbay/New()
|
||||
..()
|
||||
internal_channels = default_medbay_channels.Copy()
|
||||
|
||||
/obj/item/radio/intercom/department/security/New()
|
||||
..()
|
||||
internal_channels = list(
|
||||
num2text(PUB_FREQ) = list(),
|
||||
num2text(SEC_I_FREQ) = list(ACCESS_SECURITY)
|
||||
)
|
||||
|
||||
/obj/item/radio/intercom/syndicate
|
||||
name = "illicit intercom"
|
||||
desc = "Talk through this. Evilly"
|
||||
frequency = SYND_FREQ
|
||||
subspace_transmission = TRUE
|
||||
syndiekey = new /obj/item/encryptionkey/syndicate/nukeops
|
||||
|
||||
/obj/item/radio/intercom/syndicate/New()
|
||||
..()
|
||||
internal_channels[num2text(SYND_FREQ)] = list(ACCESS_SYNDICATE)
|
||||
|
||||
/obj/item/radio/intercom/pirate
|
||||
name = "pirate radio intercom"
|
||||
desc = "You wouldn't steal a space shuttle. Piracy. It's a crime!"
|
||||
subspace_transmission = 1
|
||||
|
||||
/obj/item/radio/intercom/pirate/New()
|
||||
..()
|
||||
internal_channels.Cut()
|
||||
internal_channels = list(
|
||||
num2text(PUB_FREQ) = list(),
|
||||
num2text(AI_FREQ) = list(),
|
||||
num2text(COMM_FREQ)= list(),
|
||||
num2text(ENG_FREQ) = list(),
|
||||
num2text(MED_FREQ) = list(),
|
||||
num2text(MED_I_FREQ)=list(),
|
||||
num2text(SEC_FREQ) = list(),
|
||||
num2text(SEC_I_FREQ)=list(),
|
||||
num2text(SCI_FREQ) = list(),
|
||||
num2text(SUP_FREQ) = list(),
|
||||
num2text(SRV_FREQ) = list()
|
||||
)
|
||||
|
||||
/obj/item/radio/intercom/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
GLOB.global_intercoms.Remove(src)
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/intercom/attack_ai(mob/user as mob)
|
||||
add_hiddenprint(user)
|
||||
add_fingerprint(user)
|
||||
spawn(0)
|
||||
attack_self(user)
|
||||
|
||||
/obj/item/radio/intercom/attack_hand(mob/user as mob)
|
||||
add_fingerprint(user)
|
||||
spawn(0)
|
||||
attack_self(user)
|
||||
|
||||
/obj/item/radio/intercom/receive_range(freq, level)
|
||||
if(!is_listening())
|
||||
return -1
|
||||
if(!(0 in level))
|
||||
var/turf/position = get_turf(src)
|
||||
// TODO: Integrate radio with the space manager
|
||||
if(isnull(position) || !(position.z in level))
|
||||
return -1
|
||||
if(freq in SSradio.ANTAG_FREQS)
|
||||
if(!(syndiekey))
|
||||
return -1//Prevents broadcast of messages over devices lacking the encryption
|
||||
|
||||
return canhear_range
|
||||
|
||||
/obj/item/radio/intercom/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/stack/tape_roll)) //eww
|
||||
return
|
||||
else if(iscoil(W) && buildstage == 1)
|
||||
var/obj/item/stack/cable_coil/coil = W
|
||||
if(coil.amount < 5)
|
||||
to_chat(user, "<span class='warning'>You need more cable for this!</span>")
|
||||
return
|
||||
if(do_after(user, 10 * coil.toolspeed, target = src) && buildstage == 1)
|
||||
coil.use(5)
|
||||
to_chat(user, "<span class='notice'>You wire \the [src]!</span>")
|
||||
buildstage = 2
|
||||
return 1
|
||||
else if(istype(W,/obj/item/intercom_electronics) && buildstage == 0)
|
||||
playsound(get_turf(src), W.usesound, 50, 1)
|
||||
if(do_after(user, 10 * W.toolspeed, target = src) && buildstage == 0)
|
||||
qdel(W)
|
||||
to_chat(user, "<span class='notice'>You insert \the [W] into \the [src]!</span>")
|
||||
buildstage = 1
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/radio/intercom/crowbar_act(mob/user, obj/item/I)
|
||||
if(buildstage != 1)
|
||||
return
|
||||
. = TRUE
|
||||
if(!I.tool_use_check(user, 0))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You begin removing the electronics...</span>")
|
||||
if(!I.use_tool(src, user, 10, volume = I.tool_volume) || buildstage != 1)
|
||||
return
|
||||
new /obj/item/intercom_electronics(get_turf(src))
|
||||
to_chat(user, "<span class='notice'>The circuit board pops out!</span>")
|
||||
buildstage = 0
|
||||
|
||||
/obj/item/radio/intercom/screwdriver_act(mob/user, obj/item/I)
|
||||
if(buildstage != 2)
|
||||
return ..()
|
||||
. = TRUE
|
||||
if(!I.tool_use_check(user, 0))
|
||||
return
|
||||
if(!I.use_tool(src, user, 10, volume = I.tool_volume) || buildstage != 2)
|
||||
return
|
||||
update_icon()
|
||||
on = 1
|
||||
b_stat = 0
|
||||
buildstage = 3
|
||||
to_chat(user, "<span class='notice'>You secure the electronics!</span>")
|
||||
update_icon()
|
||||
START_PROCESSING(SSobj, src)
|
||||
for(var/i, i<= 5, i++)
|
||||
wires.UpdateCut(i,1)
|
||||
|
||||
/obj/item/radio/intercom/wirecutter_act(mob/user, obj/item/I)
|
||||
if(!(buildstage == 3 && b_stat && wires.IsAllCut()))
|
||||
return
|
||||
. = TRUE
|
||||
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
|
||||
return
|
||||
WIRECUTTER_SNIP_MESSAGE
|
||||
new /obj/item/stack/cable_coil(get_turf(src),5)
|
||||
on = 0
|
||||
b_stat = 1
|
||||
buildstage = 1
|
||||
update_icon()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/radio/intercom/welder_act(mob/user, obj/item/I)
|
||||
if(!buildstage)
|
||||
return
|
||||
. = TRUE
|
||||
if(!I.tool_use_check(user, 3))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start slicing [src] from the wall...</span>")
|
||||
if(I.use_tool(src, user, 10, amount = 3, volume = I.tool_volume))
|
||||
to_chat(user, "<span class='notice'>You cut [src] free from the wall!</span>")
|
||||
new /obj/item/mounted/frame/intercom(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/radio/intercom/update_icon()
|
||||
if(!circuitry_installed)
|
||||
icon_state="intercom-frame"
|
||||
return
|
||||
icon_state = "intercom[!on?"-p":""][b_stat ? "-open":""]"
|
||||
|
||||
/obj/item/radio/intercom/process()
|
||||
if(((world.timeofday - last_tick) > 30) || ((world.timeofday - last_tick) < 0))
|
||||
last_tick = world.timeofday
|
||||
|
||||
|
||||
if(!src.loc)
|
||||
on = 0
|
||||
else
|
||||
var/area/A = get_area(src)
|
||||
if(!A)
|
||||
on = 0
|
||||
else
|
||||
on = A.powered(EQUIP) // set "on" to the power status
|
||||
update_icon()
|
||||
|
||||
/obj/item/intercom_electronics
|
||||
name = "intercom electronics"
|
||||
icon = 'icons/obj/doors/door_assembly.dmi'
|
||||
icon_state = "door_electronics"
|
||||
desc = "Looks like a circuit. Probably is."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
materials = list(MAT_METAL=50, MAT_GLASS=50)
|
||||
origin_tech = "engineering=2;programming=1"
|
||||
toolspeed = 1
|
||||
usesound = 'sound/items/deconstruct.ogg'
|
||||
|
||||
/obj/item/radio/intercom/locked
|
||||
var/locked_frequency
|
||||
|
||||
/obj/item/radio/intercom/locked/set_frequency(var/frequency)
|
||||
if(frequency == locked_frequency)
|
||||
..(locked_frequency)
|
||||
|
||||
/obj/item/radio/intercom/locked/list_channels()
|
||||
return ""
|
||||
|
||||
/obj/item/radio/intercom/locked/ai_private
|
||||
name = "\improper AI intercom"
|
||||
frequency = AI_FREQ
|
||||
|
||||
/obj/item/radio/intercom/locked/confessional
|
||||
name = "confessional intercom"
|
||||
frequency = 1480
|
||||
|
||||
/obj/item/radio/intercom/locked/prison
|
||||
name = "\improper prison intercom"
|
||||
desc = "Talk through this. It looks like it has been modified to not broadcast."
|
||||
|
||||
/obj/item/radio/intercom/locked/prison/New()
|
||||
..()
|
||||
wires.CutWireIndex(RADIO_WIRE_TRANSMIT)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,324 +1,324 @@
|
||||
/obj/item/taperecorder
|
||||
name = "universal recorder"
|
||||
desc = "A device that can record to cassette tapes, and play them. It automatically translates the content in playback."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "taperecorder_empty"
|
||||
item_state = "analyzer"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = SLOT_BELT
|
||||
materials = list(MAT_METAL=60, MAT_GLASS=30)
|
||||
force = 2
|
||||
throwforce = 0
|
||||
var/recording = 0
|
||||
var/playing = 0
|
||||
var/playsleepseconds = 0
|
||||
var/obj/item/tape/mytape
|
||||
var/open_panel = 0
|
||||
var/canprint = 1
|
||||
var/starts_with_tape = TRUE
|
||||
|
||||
|
||||
/obj/item/taperecorder/New()
|
||||
..()
|
||||
if(starts_with_tape)
|
||||
mytape = new /obj/item/tape/random(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/taperecorder/Destroy()
|
||||
QDEL_NULL(mytape)
|
||||
return ..()
|
||||
|
||||
/obj/item/taperecorder/examine(mob/user)
|
||||
. = ..()
|
||||
if(in_range(user, src))
|
||||
. += "The wire panel is [open_panel ? "opened" : "closed"]."
|
||||
|
||||
|
||||
/obj/item/taperecorder/attackby(obj/item/I, mob/user)
|
||||
if(!mytape && istype(I, /obj/item/tape))
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
mytape = I
|
||||
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
|
||||
update_icon()
|
||||
|
||||
/obj/item/taperecorder/proc/eject(mob/user)
|
||||
if(mytape)
|
||||
to_chat(user, "<span class='notice'>You remove [mytape] from [src].</span>")
|
||||
stop()
|
||||
user.put_in_hands(mytape)
|
||||
mytape = null
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/taperecorder/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE)
|
||||
mytape.ruin() //Fires destroy the tape
|
||||
return ..()
|
||||
|
||||
/obj/item/taperecorder/attack_hand(mob/user)
|
||||
if(loc == user)
|
||||
if(mytape)
|
||||
if(user.l_hand != src && user.r_hand != src)
|
||||
..()
|
||||
return
|
||||
eject(user)
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/taperecorder/verb/ejectverb()
|
||||
set name = "Eject Tape"
|
||||
set category = "Object"
|
||||
|
||||
if(usr.stat)
|
||||
return
|
||||
if(!mytape)
|
||||
return
|
||||
|
||||
eject(usr)
|
||||
|
||||
|
||||
/obj/item/taperecorder/update_icon()
|
||||
if(!mytape)
|
||||
icon_state = "taperecorder_empty"
|
||||
else if(recording)
|
||||
icon_state = "taperecorder_recording"
|
||||
else if(playing)
|
||||
icon_state = "taperecorder_playing"
|
||||
else
|
||||
icon_state = "taperecorder_idle"
|
||||
|
||||
|
||||
/obj/item/taperecorder/hear_talk(mob/living/M as mob, list/message_pieces)
|
||||
var/msg = multilingual_to_message(message_pieces)
|
||||
if(mytape && recording)
|
||||
var/ending = copytext(msg, length(msg))
|
||||
mytape.timestamp += mytape.used_capacity
|
||||
if(M.stuttering)
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] stammers, \"[msg]\""
|
||||
return
|
||||
if(M.getBrainLoss() >= 60)
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] gibbers, \"[msg]\""
|
||||
return
|
||||
if(ending == "?")
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] asks, \"[msg]\""
|
||||
return
|
||||
else if(ending == "!")
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] exclaims, \"[msg]\""
|
||||
return
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] says, \"[msg]\""
|
||||
|
||||
/obj/item/taperecorder/hear_message(mob/living/M as mob, msg)
|
||||
if(mytape && recording)
|
||||
mytape.timestamp += mytape.used_capacity
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] [msg]"
|
||||
|
||||
/obj/item/taperecorder/verb/record()
|
||||
set name = "Start Recording"
|
||||
set category = "Object"
|
||||
|
||||
if(usr.stat)
|
||||
return
|
||||
if(!mytape || mytape.ruined)
|
||||
return
|
||||
if(recording)
|
||||
return
|
||||
if(playing)
|
||||
return
|
||||
|
||||
if(mytape.used_capacity < mytape.max_capacity)
|
||||
to_chat(usr, "<span class='notice'>Recording started.</span>")
|
||||
recording = 1
|
||||
update_icon()
|
||||
mytape.timestamp += mytape.used_capacity
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] Recording started."
|
||||
var/used = mytape.used_capacity //to stop runtimes when you eject the tape
|
||||
var/max = mytape.max_capacity
|
||||
for(used, used < max)
|
||||
if(recording == 0)
|
||||
break
|
||||
mytape.used_capacity++
|
||||
used++
|
||||
sleep(10)
|
||||
recording = 0
|
||||
update_icon()
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>The tape is full.</span>")
|
||||
|
||||
|
||||
/obj/item/taperecorder/verb/stop()
|
||||
set name = "Stop"
|
||||
set category = "Object"
|
||||
|
||||
if(usr.stat)
|
||||
return
|
||||
|
||||
if(recording)
|
||||
recording = 0
|
||||
mytape.timestamp += mytape.used_capacity
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] Recording stopped."
|
||||
to_chat(usr, "<span class='notice'>Recording stopped.</span>")
|
||||
return
|
||||
else if(playing)
|
||||
playing = 0
|
||||
atom_say("Playback stopped.")
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/taperecorder/verb/play()
|
||||
set name = "Play Tape"
|
||||
set category = "Object"
|
||||
|
||||
if(usr.stat)
|
||||
return
|
||||
if(!mytape || mytape.ruined)
|
||||
return
|
||||
if(recording)
|
||||
return
|
||||
if(playing)
|
||||
return
|
||||
|
||||
playing = 1
|
||||
update_icon()
|
||||
to_chat(usr, "<span class='notice'>Playing started.</span>")
|
||||
var/used = mytape.used_capacity //to stop runtimes when you eject the tape
|
||||
var/max = mytape.max_capacity
|
||||
for(var/i = 1, used < max, sleep(10 * playsleepseconds))
|
||||
if(!mytape)
|
||||
break
|
||||
if(playing == 0)
|
||||
break
|
||||
if(mytape.storedinfo.len < i)
|
||||
break
|
||||
atom_say("[mytape.storedinfo[i]]")
|
||||
if(mytape.storedinfo.len < i + 1)
|
||||
playsleepseconds = 1
|
||||
sleep(10)
|
||||
T = get_turf(src)
|
||||
atom_say("End of recording.")
|
||||
else
|
||||
playsleepseconds = mytape.timestamp[i + 1] - mytape.timestamp[i]
|
||||
if(playsleepseconds > 14)
|
||||
sleep(10)
|
||||
T = get_turf(src)
|
||||
atom_say("Skipping [playsleepseconds] seconds of silence.")
|
||||
playsleepseconds = 1
|
||||
i++
|
||||
|
||||
playing = 0
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/taperecorder/attack_self(mob/user)
|
||||
if(!mytape || mytape.ruined)
|
||||
return
|
||||
if(recording)
|
||||
stop()
|
||||
else
|
||||
record()
|
||||
|
||||
|
||||
/obj/item/taperecorder/verb/print_transcript()
|
||||
set name = "Print Transcript"
|
||||
set category = "Object"
|
||||
|
||||
if(usr.stat)
|
||||
return
|
||||
if(!mytape)
|
||||
return
|
||||
if(!canprint)
|
||||
to_chat(usr, "<span class='notice'>The recorder can't print that fast!</span>")
|
||||
return
|
||||
if(recording || playing)
|
||||
return
|
||||
|
||||
to_chat(usr, "<span class='notice'>Transcript printed.</span>")
|
||||
playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 50, 1)
|
||||
var/obj/item/paper/P = new /obj/item/paper(get_turf(src))
|
||||
var/t1 = "<B>Transcript:</B><BR><BR>"
|
||||
for(var/i = 1, mytape.storedinfo.len >= i, i++)
|
||||
t1 += "[mytape.storedinfo[i]]<BR>"
|
||||
P.info = t1
|
||||
P.name = "paper- 'Transcript'"
|
||||
usr.put_in_hands(P)
|
||||
canprint = 0
|
||||
sleep(300)
|
||||
canprint = 1
|
||||
|
||||
//empty tape recorders
|
||||
/obj/item/taperecorder/empty
|
||||
starts_with_tape = FALSE
|
||||
|
||||
|
||||
/obj/item/tape
|
||||
name = "tape"
|
||||
desc = "A magnetic tape that can hold up to ten minutes of content."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "tape_white"
|
||||
item_state = "analyzer"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
materials = list(MAT_METAL=20, MAT_GLASS=5)
|
||||
force = 1
|
||||
throwforce = 0
|
||||
var/max_capacity = 600
|
||||
var/used_capacity = 0
|
||||
var/list/storedinfo = list()
|
||||
var/list/timestamp = list()
|
||||
var/ruined = 0
|
||||
|
||||
/obj/item/tape/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE)
|
||||
..()
|
||||
ruin()
|
||||
|
||||
/obj/item/tape/attack_self(mob/user)
|
||||
if(!ruined)
|
||||
to_chat(user, "<span class='notice'>You pull out all the tape!</span>")
|
||||
ruin()
|
||||
|
||||
/obj/item/tape/verb/wipe()
|
||||
set name = "Wipe Tape"
|
||||
set category = "Object"
|
||||
|
||||
if(usr.stat)
|
||||
return
|
||||
if(ruined)
|
||||
return
|
||||
|
||||
to_chat(usr, "You erase the data from the [src]")
|
||||
clear()
|
||||
|
||||
/obj/item/tape/proc/clear()
|
||||
used_capacity = 0
|
||||
storedinfo.Cut()
|
||||
timestamp.Cut()
|
||||
|
||||
/obj/item/tape/proc/ruin()
|
||||
if(!ruined)
|
||||
overlays += "ribbonoverlay"
|
||||
ruined = 1
|
||||
|
||||
|
||||
|
||||
/obj/item/tape/proc/fix()
|
||||
overlays -= "ribbonoverlay"
|
||||
ruined = 0
|
||||
|
||||
|
||||
/obj/item/tape/attackby(obj/item/I, mob/user)
|
||||
if(ruined && istype(I, /obj/item/screwdriver))
|
||||
to_chat(user, "<span class='notice'>You start winding the tape back in.</span>")
|
||||
if(do_after(user, 120 * I.toolspeed, target = src))
|
||||
to_chat(user, "<span class='notice'>You wound the tape back in!</span>")
|
||||
fix()
|
||||
else if(istype(I, /obj/item/pen))
|
||||
var/title = stripped_input(usr,"What do you want to name the tape?", "Tape Renaming", name, MAX_NAME_LEN)
|
||||
if(!title || !length(title))
|
||||
name = initial(name)
|
||||
return
|
||||
name = "tape - [title]"
|
||||
|
||||
|
||||
//Random colour tapes
|
||||
/obj/item/tape/random/New()
|
||||
..()
|
||||
icon_state = "tape_[pick("white", "blue", "red", "yellow", "purple")]"
|
||||
/obj/item/taperecorder
|
||||
name = "universal recorder"
|
||||
desc = "A device that can record to cassette tapes, and play them. It automatically translates the content in playback."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "taperecorder_empty"
|
||||
item_state = "analyzer"
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
slot_flags = SLOT_BELT
|
||||
materials = list(MAT_METAL=60, MAT_GLASS=30)
|
||||
force = 2
|
||||
throwforce = 0
|
||||
var/recording = 0
|
||||
var/playing = 0
|
||||
var/playsleepseconds = 0
|
||||
var/obj/item/tape/mytape
|
||||
var/open_panel = 0
|
||||
var/canprint = 1
|
||||
var/starts_with_tape = TRUE
|
||||
|
||||
|
||||
/obj/item/taperecorder/New()
|
||||
..()
|
||||
if(starts_with_tape)
|
||||
mytape = new /obj/item/tape/random(src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/taperecorder/Destroy()
|
||||
QDEL_NULL(mytape)
|
||||
return ..()
|
||||
|
||||
/obj/item/taperecorder/examine(mob/user)
|
||||
. = ..()
|
||||
if(in_range(user, src))
|
||||
. += "The wire panel is [open_panel ? "opened" : "closed"]."
|
||||
|
||||
|
||||
/obj/item/taperecorder/attackby(obj/item/I, mob/user)
|
||||
if(!mytape && istype(I, /obj/item/tape))
|
||||
user.drop_item()
|
||||
I.loc = src
|
||||
mytape = I
|
||||
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
|
||||
update_icon()
|
||||
|
||||
/obj/item/taperecorder/proc/eject(mob/user)
|
||||
if(mytape)
|
||||
to_chat(user, "<span class='notice'>You remove [mytape] from [src].</span>")
|
||||
stop()
|
||||
user.put_in_hands(mytape)
|
||||
mytape = null
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/taperecorder/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE)
|
||||
mytape.ruin() //Fires destroy the tape
|
||||
return ..()
|
||||
|
||||
/obj/item/taperecorder/attack_hand(mob/user)
|
||||
if(loc == user)
|
||||
if(mytape)
|
||||
if(user.l_hand != src && user.r_hand != src)
|
||||
..()
|
||||
return
|
||||
eject(user)
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/taperecorder/verb/ejectverb()
|
||||
set name = "Eject Tape"
|
||||
set category = "Object"
|
||||
|
||||
if(usr.stat)
|
||||
return
|
||||
if(!mytape)
|
||||
return
|
||||
|
||||
eject(usr)
|
||||
|
||||
|
||||
/obj/item/taperecorder/update_icon()
|
||||
if(!mytape)
|
||||
icon_state = "taperecorder_empty"
|
||||
else if(recording)
|
||||
icon_state = "taperecorder_recording"
|
||||
else if(playing)
|
||||
icon_state = "taperecorder_playing"
|
||||
else
|
||||
icon_state = "taperecorder_idle"
|
||||
|
||||
|
||||
/obj/item/taperecorder/hear_talk(mob/living/M as mob, list/message_pieces)
|
||||
var/msg = multilingual_to_message(message_pieces)
|
||||
if(mytape && recording)
|
||||
var/ending = copytext(msg, length(msg))
|
||||
mytape.timestamp += mytape.used_capacity
|
||||
if(M.stuttering)
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] stammers, \"[msg]\""
|
||||
return
|
||||
if(M.getBrainLoss() >= 60)
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] gibbers, \"[msg]\""
|
||||
return
|
||||
if(ending == "?")
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] asks, \"[msg]\""
|
||||
return
|
||||
else if(ending == "!")
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] exclaims, \"[msg]\""
|
||||
return
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] says, \"[msg]\""
|
||||
|
||||
/obj/item/taperecorder/hear_message(mob/living/M as mob, msg)
|
||||
if(mytape && recording)
|
||||
mytape.timestamp += mytape.used_capacity
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [M.name] [msg]"
|
||||
|
||||
/obj/item/taperecorder/verb/record()
|
||||
set name = "Start Recording"
|
||||
set category = "Object"
|
||||
|
||||
if(usr.stat)
|
||||
return
|
||||
if(!mytape || mytape.ruined)
|
||||
return
|
||||
if(recording)
|
||||
return
|
||||
if(playing)
|
||||
return
|
||||
|
||||
if(mytape.used_capacity < mytape.max_capacity)
|
||||
to_chat(usr, "<span class='notice'>Recording started.</span>")
|
||||
recording = 1
|
||||
update_icon()
|
||||
mytape.timestamp += mytape.used_capacity
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] Recording started."
|
||||
var/used = mytape.used_capacity //to stop runtimes when you eject the tape
|
||||
var/max = mytape.max_capacity
|
||||
for(used, used < max)
|
||||
if(recording == 0)
|
||||
break
|
||||
mytape.used_capacity++
|
||||
used++
|
||||
sleep(10)
|
||||
recording = 0
|
||||
update_icon()
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>The tape is full.</span>")
|
||||
|
||||
|
||||
/obj/item/taperecorder/verb/stop()
|
||||
set name = "Stop"
|
||||
set category = "Object"
|
||||
|
||||
if(usr.stat)
|
||||
return
|
||||
|
||||
if(recording)
|
||||
recording = 0
|
||||
mytape.timestamp += mytape.used_capacity
|
||||
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] Recording stopped."
|
||||
to_chat(usr, "<span class='notice'>Recording stopped.</span>")
|
||||
return
|
||||
else if(playing)
|
||||
playing = 0
|
||||
atom_say("Playback stopped.")
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/taperecorder/verb/play()
|
||||
set name = "Play Tape"
|
||||
set category = "Object"
|
||||
|
||||
if(usr.stat)
|
||||
return
|
||||
if(!mytape || mytape.ruined)
|
||||
return
|
||||
if(recording)
|
||||
return
|
||||
if(playing)
|
||||
return
|
||||
|
||||
playing = 1
|
||||
update_icon()
|
||||
to_chat(usr, "<span class='notice'>Playing started.</span>")
|
||||
var/used = mytape.used_capacity //to stop runtimes when you eject the tape
|
||||
var/max = mytape.max_capacity
|
||||
for(var/i = 1, used < max, sleep(10 * playsleepseconds))
|
||||
if(!mytape)
|
||||
break
|
||||
if(playing == 0)
|
||||
break
|
||||
if(mytape.storedinfo.len < i)
|
||||
break
|
||||
atom_say("[mytape.storedinfo[i]]")
|
||||
if(mytape.storedinfo.len < i + 1)
|
||||
playsleepseconds = 1
|
||||
sleep(10)
|
||||
T = get_turf(src)
|
||||
atom_say("End of recording.")
|
||||
else
|
||||
playsleepseconds = mytape.timestamp[i + 1] - mytape.timestamp[i]
|
||||
if(playsleepseconds > 14)
|
||||
sleep(10)
|
||||
T = get_turf(src)
|
||||
atom_say("Skipping [playsleepseconds] seconds of silence.")
|
||||
playsleepseconds = 1
|
||||
i++
|
||||
|
||||
playing = 0
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/item/taperecorder/attack_self(mob/user)
|
||||
if(!mytape || mytape.ruined)
|
||||
return
|
||||
if(recording)
|
||||
stop()
|
||||
else
|
||||
record()
|
||||
|
||||
|
||||
/obj/item/taperecorder/verb/print_transcript()
|
||||
set name = "Print Transcript"
|
||||
set category = "Object"
|
||||
|
||||
if(usr.stat)
|
||||
return
|
||||
if(!mytape)
|
||||
return
|
||||
if(!canprint)
|
||||
to_chat(usr, "<span class='notice'>The recorder can't print that fast!</span>")
|
||||
return
|
||||
if(recording || playing)
|
||||
return
|
||||
|
||||
to_chat(usr, "<span class='notice'>Transcript printed.</span>")
|
||||
playsound(loc, 'sound/goonstation/machines/printer_thermal.ogg', 50, 1)
|
||||
var/obj/item/paper/P = new /obj/item/paper(get_turf(src))
|
||||
var/t1 = "<B>Transcript:</B><BR><BR>"
|
||||
for(var/i = 1, mytape.storedinfo.len >= i, i++)
|
||||
t1 += "[mytape.storedinfo[i]]<BR>"
|
||||
P.info = t1
|
||||
P.name = "paper- 'Transcript'"
|
||||
usr.put_in_hands(P)
|
||||
canprint = 0
|
||||
sleep(300)
|
||||
canprint = 1
|
||||
|
||||
//empty tape recorders
|
||||
/obj/item/taperecorder/empty
|
||||
starts_with_tape = FALSE
|
||||
|
||||
|
||||
/obj/item/tape
|
||||
name = "tape"
|
||||
desc = "A magnetic tape that can hold up to ten minutes of content."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "tape_white"
|
||||
item_state = "analyzer"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
materials = list(MAT_METAL=20, MAT_GLASS=5)
|
||||
force = 1
|
||||
throwforce = 0
|
||||
var/max_capacity = 600
|
||||
var/used_capacity = 0
|
||||
var/list/storedinfo = list()
|
||||
var/list/timestamp = list()
|
||||
var/ruined = 0
|
||||
|
||||
/obj/item/tape/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE)
|
||||
..()
|
||||
ruin()
|
||||
|
||||
/obj/item/tape/attack_self(mob/user)
|
||||
if(!ruined)
|
||||
to_chat(user, "<span class='notice'>You pull out all the tape!</span>")
|
||||
ruin()
|
||||
|
||||
/obj/item/tape/verb/wipe()
|
||||
set name = "Wipe Tape"
|
||||
set category = "Object"
|
||||
|
||||
if(usr.stat)
|
||||
return
|
||||
if(ruined)
|
||||
return
|
||||
|
||||
to_chat(usr, "You erase the data from the [src]")
|
||||
clear()
|
||||
|
||||
/obj/item/tape/proc/clear()
|
||||
used_capacity = 0
|
||||
storedinfo.Cut()
|
||||
timestamp.Cut()
|
||||
|
||||
/obj/item/tape/proc/ruin()
|
||||
if(!ruined)
|
||||
overlays += "ribbonoverlay"
|
||||
ruined = 1
|
||||
|
||||
|
||||
|
||||
/obj/item/tape/proc/fix()
|
||||
overlays -= "ribbonoverlay"
|
||||
ruined = 0
|
||||
|
||||
|
||||
/obj/item/tape/attackby(obj/item/I, mob/user)
|
||||
if(ruined && istype(I, /obj/item/screwdriver))
|
||||
to_chat(user, "<span class='notice'>You start winding the tape back in.</span>")
|
||||
if(do_after(user, 120 * I.toolspeed, target = src))
|
||||
to_chat(user, "<span class='notice'>You wound the tape back in!</span>")
|
||||
fix()
|
||||
else if(istype(I, /obj/item/pen))
|
||||
var/title = stripped_input(usr,"What do you want to name the tape?", "Tape Renaming", name, MAX_NAME_LEN)
|
||||
if(!title || !length(title))
|
||||
name = initial(name)
|
||||
return
|
||||
name = "tape - [title]"
|
||||
|
||||
|
||||
//Random colour tapes
|
||||
/obj/item/tape/random/New()
|
||||
..()
|
||||
icon_state = "tape_[pick("white", "blue", "red", "yellow", "purple")]"
|
||||
|
||||
@@ -25,4 +25,4 @@
|
||||
name = "diamond tipped thermal safe drill"
|
||||
desc = "A diamond tipped thermal drill with magnetic clamps for the purpose of quickly drilling hardened objects. Guaranteed 100% jam proof."
|
||||
icon_state = "diamond_drill"
|
||||
time_multiplier = 0.5
|
||||
time_multiplier = 0.5
|
||||
|
||||
@@ -167,4 +167,4 @@ effective or pretty fucking useless.
|
||||
if(active)
|
||||
GLOB.active_jammers |= src
|
||||
else
|
||||
GLOB.active_jammers -= src
|
||||
GLOB.active_jammers -= src
|
||||
|
||||
@@ -1,220 +1,220 @@
|
||||
/obj/item/transfer_valve
|
||||
icon = 'icons/obj/assemblies.dmi'
|
||||
name = "tank transfer valve"
|
||||
icon_state = "valve_1"
|
||||
item_state = "ttv"
|
||||
desc = "Regulates the transfer of air between two tanks"
|
||||
var/obj/item/tank/tank_one = null
|
||||
var/obj/item/tank/tank_two = null
|
||||
var/obj/item/assembly/attached_device = null
|
||||
var/mob/living/attacher = null
|
||||
var/valve_open = 0
|
||||
var/toggle = 1
|
||||
origin_tech = "materials=1;engineering=1"
|
||||
|
||||
/obj/item/transfer_valve/Destroy()
|
||||
QDEL_NULL(tank_one)
|
||||
QDEL_NULL(tank_two)
|
||||
QDEL_NULL(attached_device)
|
||||
attacher = null
|
||||
return ..()
|
||||
|
||||
/obj/item/transfer_valve/IsAssemblyHolder()
|
||||
return 1
|
||||
|
||||
/obj/item/transfer_valve/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/tank))
|
||||
if(tank_one && tank_two)
|
||||
to_chat(user, "<span class='warning'>There are already two tanks attached, remove one first.</span>")
|
||||
return
|
||||
|
||||
if(!tank_one)
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
tank_one = I
|
||||
I.forceMove(src)
|
||||
to_chat(user, "<span class='notice'>You attach the tank to the transfer valve.</span>")
|
||||
if(I.w_class > w_class)
|
||||
w_class = I.w_class
|
||||
else if(!tank_two)
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
tank_two = I
|
||||
I.forceMove(src)
|
||||
to_chat(user, "<span class='notice'>You attach the tank to the transfer valve.</span>")
|
||||
if(I.w_class > w_class)
|
||||
w_class = I.w_class
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src) // update all UIs attached to src
|
||||
//TODO: Have this take an assemblyholder
|
||||
else if(isassembly(I))
|
||||
var/obj/item/assembly/A = I
|
||||
if(A.secured)
|
||||
to_chat(user, "<span class='notice'>The device is secured.</span>")
|
||||
return
|
||||
if(attached_device)
|
||||
to_chat(user, "<span class='warning'>There is already a device attached to the valve, remove it first.</span>")
|
||||
return
|
||||
user.remove_from_mob(A)
|
||||
attached_device = A
|
||||
A.forceMove(src)
|
||||
to_chat(user, "<span class='notice'>You attach the [A] to the valve controls and secure it.</span>")
|
||||
A.holder = src
|
||||
A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb).
|
||||
|
||||
investigate_log("[key_name(user)] attached a [A] to a transfer valve.", INVESTIGATE_BOMB)
|
||||
msg_admin_attack("[key_name_admin(user)]attached [A] to a transfer valve.", ATKLOG_FEW)
|
||||
log_game("[key_name_admin(user)] attached [A] to a transfer valve.")
|
||||
attacher = user
|
||||
SSnanoui.update_uis(src) // update all UIs attached to src
|
||||
|
||||
|
||||
/obj/item/transfer_valve/HasProximity(atom/movable/AM)
|
||||
if(!attached_device)
|
||||
return
|
||||
attached_device.HasProximity(AM)
|
||||
|
||||
/obj/item/transfer_valve/hear_talk(mob/living/M, list/message_pieces)
|
||||
..()
|
||||
for(var/obj/O in contents)
|
||||
O.hear_talk(M, message_pieces)
|
||||
|
||||
/obj/item/transfer_valve/hear_message(mob/living/M, msg)
|
||||
..()
|
||||
for(var/obj/O in contents)
|
||||
O.hear_message(M, msg)
|
||||
|
||||
/obj/item/transfer_valve/attack_self(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/transfer_valve/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1)
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
ui = new(user, src, ui_key, "transfer_valve.tmpl", "Tank Transfer Valve", 460, 280)
|
||||
// open the new ui window
|
||||
ui.open()
|
||||
// auto update every Master Controller tick
|
||||
//ui.set_auto_update(1)
|
||||
|
||||
/obj/item/transfer_valve/ui_data(mob/user, ui_key = "main", datum/topic_state/state = default_state)
|
||||
var/data[0]
|
||||
|
||||
data["attachmentOne"] = tank_one ? tank_one.name : null
|
||||
data["attachmentTwo"] = tank_two ? tank_two.name : null
|
||||
data["valveAttachment"] = attached_device ? attached_device.name : null
|
||||
data["valveOpen"] = valve_open ? 1 : 0
|
||||
|
||||
return data
|
||||
|
||||
/obj/item/transfer_valve/Topic(href, href_list)
|
||||
..()
|
||||
if(usr.incapacitated())
|
||||
return 0
|
||||
if(loc != usr)
|
||||
return 0
|
||||
if(tank_one && href_list["tankone"])
|
||||
split_gases()
|
||||
valve_open = 0
|
||||
tank_one.forceMove(get_turf(src))
|
||||
tank_one = null
|
||||
update_icon()
|
||||
if((!tank_two || tank_two.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL))
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
else if(tank_two && href_list["tanktwo"])
|
||||
split_gases()
|
||||
valve_open = 0
|
||||
tank_two.forceMove(get_turf(src))
|
||||
tank_two = null
|
||||
update_icon()
|
||||
if((!tank_one || tank_one.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL))
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
else if(href_list["open"])
|
||||
toggle_valve()
|
||||
else if(attached_device)
|
||||
if(href_list["rem_device"])
|
||||
attached_device.forceMove(get_turf(src))
|
||||
attached_device.holder = null
|
||||
attached_device = null
|
||||
update_icon()
|
||||
if(href_list["device"])
|
||||
attached_device.attack_self(usr)
|
||||
add_fingerprint(usr)
|
||||
return 1 // Returning 1 sends an update to attached UIs
|
||||
|
||||
/obj/item/transfer_valve/proc/process_activation(obj/item/D)
|
||||
if(toggle)
|
||||
toggle = 0
|
||||
toggle_valve()
|
||||
spawn(50) // To stop a signal being spammed from a proxy sensor constantly going off or whatever
|
||||
toggle = 1
|
||||
|
||||
/obj/item/transfer_valve/update_icon()
|
||||
overlays.Cut()
|
||||
underlays = null
|
||||
|
||||
if(!tank_one && !tank_two && !attached_device)
|
||||
icon_state = "valve_1"
|
||||
return
|
||||
icon_state = "valve"
|
||||
|
||||
if(tank_one)
|
||||
overlays += "[tank_one.icon_state]"
|
||||
if(tank_two)
|
||||
var/icon/J = new(icon, icon_state = "[tank_two.icon_state]")
|
||||
J.Shift(WEST, 13)
|
||||
underlays += J
|
||||
if(attached_device)
|
||||
overlays += "device"
|
||||
|
||||
/obj/item/transfer_valve/proc/merge_gases()
|
||||
tank_two.air_contents.volume += tank_one.air_contents.volume
|
||||
var/datum/gas_mixture/temp
|
||||
temp = tank_one.air_contents.remove_ratio(1)
|
||||
tank_two.air_contents.merge(temp)
|
||||
|
||||
/obj/item/transfer_valve/proc/split_gases()
|
||||
if(!valve_open || !tank_one || !tank_two)
|
||||
return
|
||||
var/ratio1 = tank_one.air_contents.volume/tank_two.air_contents.volume
|
||||
var/datum/gas_mixture/temp
|
||||
temp = tank_two.air_contents.remove_ratio(ratio1)
|
||||
tank_one.air_contents.merge(temp)
|
||||
tank_two.air_contents.volume -= tank_one.air_contents.volume
|
||||
|
||||
/*
|
||||
Exadv1: I know this isn't how it's going to work, but this was just to check
|
||||
it explodes properly when it gets a signal (and it does).
|
||||
*/
|
||||
|
||||
/obj/item/transfer_valve/proc/toggle_valve()
|
||||
if(!valve_open && tank_one && tank_two)
|
||||
valve_open = 1
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/area/A = get_area(bombturf)
|
||||
|
||||
var/attacher_name = ""
|
||||
if(!attacher)
|
||||
attacher_name = "Unknown"
|
||||
else
|
||||
attacher_name = "[key_name_admin(attacher)]"
|
||||
|
||||
var/mob/mob = get_mob_by_key(src.fingerprintslast)
|
||||
|
||||
investigate_log("Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]", INVESTIGATE_BOMB)
|
||||
message_admins("Bomb valve opened at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a> with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name_admin(mob)]")
|
||||
log_game("Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]")
|
||||
merge_gases()
|
||||
spawn(20) // In case one tank bursts
|
||||
for(var/i in 1 to 5)
|
||||
update_icon()
|
||||
sleep(10)
|
||||
update_icon()
|
||||
|
||||
else if(valve_open && tank_one && tank_two)
|
||||
split_gases()
|
||||
valve_open = 0
|
||||
update_icon()
|
||||
/obj/item/transfer_valve
|
||||
icon = 'icons/obj/assemblies.dmi'
|
||||
name = "tank transfer valve"
|
||||
icon_state = "valve_1"
|
||||
item_state = "ttv"
|
||||
desc = "Regulates the transfer of air between two tanks"
|
||||
var/obj/item/tank/tank_one = null
|
||||
var/obj/item/tank/tank_two = null
|
||||
var/obj/item/assembly/attached_device = null
|
||||
var/mob/living/attacher = null
|
||||
var/valve_open = 0
|
||||
var/toggle = 1
|
||||
origin_tech = "materials=1;engineering=1"
|
||||
|
||||
/obj/item/transfer_valve/Destroy()
|
||||
QDEL_NULL(tank_one)
|
||||
QDEL_NULL(tank_two)
|
||||
QDEL_NULL(attached_device)
|
||||
attacher = null
|
||||
return ..()
|
||||
|
||||
/obj/item/transfer_valve/IsAssemblyHolder()
|
||||
return 1
|
||||
|
||||
/obj/item/transfer_valve/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/tank))
|
||||
if(tank_one && tank_two)
|
||||
to_chat(user, "<span class='warning'>There are already two tanks attached, remove one first.</span>")
|
||||
return
|
||||
|
||||
if(!tank_one)
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
tank_one = I
|
||||
I.forceMove(src)
|
||||
to_chat(user, "<span class='notice'>You attach the tank to the transfer valve.</span>")
|
||||
if(I.w_class > w_class)
|
||||
w_class = I.w_class
|
||||
else if(!tank_two)
|
||||
if(!user.unEquip(I))
|
||||
return
|
||||
tank_two = I
|
||||
I.forceMove(src)
|
||||
to_chat(user, "<span class='notice'>You attach the tank to the transfer valve.</span>")
|
||||
if(I.w_class > w_class)
|
||||
w_class = I.w_class
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src) // update all UIs attached to src
|
||||
//TODO: Have this take an assemblyholder
|
||||
else if(isassembly(I))
|
||||
var/obj/item/assembly/A = I
|
||||
if(A.secured)
|
||||
to_chat(user, "<span class='notice'>The device is secured.</span>")
|
||||
return
|
||||
if(attached_device)
|
||||
to_chat(user, "<span class='warning'>There is already a device attached to the valve, remove it first.</span>")
|
||||
return
|
||||
user.remove_from_mob(A)
|
||||
attached_device = A
|
||||
A.forceMove(src)
|
||||
to_chat(user, "<span class='notice'>You attach the [A] to the valve controls and secure it.</span>")
|
||||
A.holder = src
|
||||
A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb).
|
||||
|
||||
investigate_log("[key_name(user)] attached a [A] to a transfer valve.", INVESTIGATE_BOMB)
|
||||
msg_admin_attack("[key_name_admin(user)]attached [A] to a transfer valve.", ATKLOG_FEW)
|
||||
log_game("[key_name_admin(user)] attached [A] to a transfer valve.")
|
||||
attacher = user
|
||||
SSnanoui.update_uis(src) // update all UIs attached to src
|
||||
|
||||
|
||||
/obj/item/transfer_valve/HasProximity(atom/movable/AM)
|
||||
if(!attached_device)
|
||||
return
|
||||
attached_device.HasProximity(AM)
|
||||
|
||||
/obj/item/transfer_valve/hear_talk(mob/living/M, list/message_pieces)
|
||||
..()
|
||||
for(var/obj/O in contents)
|
||||
O.hear_talk(M, message_pieces)
|
||||
|
||||
/obj/item/transfer_valve/hear_message(mob/living/M, msg)
|
||||
..()
|
||||
for(var/obj/O in contents)
|
||||
O.hear_message(M, msg)
|
||||
|
||||
/obj/item/transfer_valve/attack_self(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/item/transfer_valve/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1)
|
||||
// update the ui if it exists, returns null if no ui is passed/found
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
// the ui does not exist, so we'll create a new() one
|
||||
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
||||
ui = new(user, src, ui_key, "transfer_valve.tmpl", "Tank Transfer Valve", 460, 280)
|
||||
// open the new ui window
|
||||
ui.open()
|
||||
// auto update every Master Controller tick
|
||||
//ui.set_auto_update(1)
|
||||
|
||||
/obj/item/transfer_valve/ui_data(mob/user, ui_key = "main", datum/topic_state/state = default_state)
|
||||
var/data[0]
|
||||
|
||||
data["attachmentOne"] = tank_one ? tank_one.name : null
|
||||
data["attachmentTwo"] = tank_two ? tank_two.name : null
|
||||
data["valveAttachment"] = attached_device ? attached_device.name : null
|
||||
data["valveOpen"] = valve_open ? 1 : 0
|
||||
|
||||
return data
|
||||
|
||||
/obj/item/transfer_valve/Topic(href, href_list)
|
||||
..()
|
||||
if(usr.incapacitated())
|
||||
return 0
|
||||
if(loc != usr)
|
||||
return 0
|
||||
if(tank_one && href_list["tankone"])
|
||||
split_gases()
|
||||
valve_open = 0
|
||||
tank_one.forceMove(get_turf(src))
|
||||
tank_one = null
|
||||
update_icon()
|
||||
if((!tank_two || tank_two.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL))
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
else if(tank_two && href_list["tanktwo"])
|
||||
split_gases()
|
||||
valve_open = 0
|
||||
tank_two.forceMove(get_turf(src))
|
||||
tank_two = null
|
||||
update_icon()
|
||||
if((!tank_one || tank_one.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL))
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
else if(href_list["open"])
|
||||
toggle_valve()
|
||||
else if(attached_device)
|
||||
if(href_list["rem_device"])
|
||||
attached_device.forceMove(get_turf(src))
|
||||
attached_device.holder = null
|
||||
attached_device = null
|
||||
update_icon()
|
||||
if(href_list["device"])
|
||||
attached_device.attack_self(usr)
|
||||
add_fingerprint(usr)
|
||||
return 1 // Returning 1 sends an update to attached UIs
|
||||
|
||||
/obj/item/transfer_valve/proc/process_activation(obj/item/D)
|
||||
if(toggle)
|
||||
toggle = 0
|
||||
toggle_valve()
|
||||
spawn(50) // To stop a signal being spammed from a proxy sensor constantly going off or whatever
|
||||
toggle = 1
|
||||
|
||||
/obj/item/transfer_valve/update_icon()
|
||||
overlays.Cut()
|
||||
underlays = null
|
||||
|
||||
if(!tank_one && !tank_two && !attached_device)
|
||||
icon_state = "valve_1"
|
||||
return
|
||||
icon_state = "valve"
|
||||
|
||||
if(tank_one)
|
||||
overlays += "[tank_one.icon_state]"
|
||||
if(tank_two)
|
||||
var/icon/J = new(icon, icon_state = "[tank_two.icon_state]")
|
||||
J.Shift(WEST, 13)
|
||||
underlays += J
|
||||
if(attached_device)
|
||||
overlays += "device"
|
||||
|
||||
/obj/item/transfer_valve/proc/merge_gases()
|
||||
tank_two.air_contents.volume += tank_one.air_contents.volume
|
||||
var/datum/gas_mixture/temp
|
||||
temp = tank_one.air_contents.remove_ratio(1)
|
||||
tank_two.air_contents.merge(temp)
|
||||
|
||||
/obj/item/transfer_valve/proc/split_gases()
|
||||
if(!valve_open || !tank_one || !tank_two)
|
||||
return
|
||||
var/ratio1 = tank_one.air_contents.volume/tank_two.air_contents.volume
|
||||
var/datum/gas_mixture/temp
|
||||
temp = tank_two.air_contents.remove_ratio(ratio1)
|
||||
tank_one.air_contents.merge(temp)
|
||||
tank_two.air_contents.volume -= tank_one.air_contents.volume
|
||||
|
||||
/*
|
||||
Exadv1: I know this isn't how it's going to work, but this was just to check
|
||||
it explodes properly when it gets a signal (and it does).
|
||||
*/
|
||||
|
||||
/obj/item/transfer_valve/proc/toggle_valve()
|
||||
if(!valve_open && tank_one && tank_two)
|
||||
valve_open = 1
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/area/A = get_area(bombturf)
|
||||
|
||||
var/attacher_name = ""
|
||||
if(!attacher)
|
||||
attacher_name = "Unknown"
|
||||
else
|
||||
attacher_name = "[key_name_admin(attacher)]"
|
||||
|
||||
var/mob/mob = get_mob_by_key(src.fingerprintslast)
|
||||
|
||||
investigate_log("Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]", INVESTIGATE_BOMB)
|
||||
message_admins("Bomb valve opened at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a> with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name_admin(mob)]")
|
||||
log_game("Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]")
|
||||
merge_gases()
|
||||
spawn(20) // In case one tank bursts
|
||||
for(var/i in 1 to 5)
|
||||
update_icon()
|
||||
sleep(10)
|
||||
update_icon()
|
||||
|
||||
else if(valve_open && tank_one && tank_two)
|
||||
split_gases()
|
||||
valve_open = 0
|
||||
update_icon()
|
||||
|
||||
@@ -353,4 +353,4 @@ var/list/world_uplinks = list()
|
||||
/obj/item/radio/headset/uplink/New()
|
||||
..()
|
||||
hidden_uplink = new(src)
|
||||
hidden_uplink.uses = 20
|
||||
hidden_uplink.uses = 20
|
||||
|
||||
@@ -41,4 +41,4 @@
|
||||
return
|
||||
|
||||
voice = sanitize(copytext(chosen_voice, 1, MAX_MESSAGE_LEN))
|
||||
to_chat(user, "<span class='notice'>You are now mimicking <b>[voice]</b>.</span>")
|
||||
to_chat(user, "<span class='notice'>You are now mimicking <b>[voice]</b>.</span>")
|
||||
|
||||
@@ -52,4 +52,4 @@
|
||||
H.reagents.add_reagent(poison_type, poison_dose)
|
||||
poison_total -= poison_dose
|
||||
add_attack_logs(src, user, "Picked up [src], the trapped syndicate documents")
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -275,4 +275,4 @@
|
||||
|
||||
/obj/item/flag/chameleon/depot/New()
|
||||
..()
|
||||
boobytrap = new /obj/item/grenade/gas/plasma(src)
|
||||
boobytrap = new /obj/item/grenade/gas/plasma(src)
|
||||
|
||||
@@ -1,65 +1,65 @@
|
||||
/obj/item/latexballon
|
||||
name = "latex glove"
|
||||
desc = "" //todo
|
||||
icon_state = "latexballon"
|
||||
item_state = "lgloves"
|
||||
force = 0
|
||||
throwforce = 0
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throw_speed = 1
|
||||
throw_range = 7
|
||||
var/state
|
||||
var/datum/gas_mixture/air_contents = null
|
||||
|
||||
/obj/item/latexballon/Destroy()
|
||||
QDEL_NULL(air_contents)
|
||||
return ..()
|
||||
|
||||
/obj/item/latexballon/proc/blow(obj/item/tank/tank, mob/user)
|
||||
if(icon_state == "latexballon_bursted")
|
||||
return
|
||||
icon_state = "latexballon_blow"
|
||||
item_state = "latexballon"
|
||||
user.update_inv_r_hand()
|
||||
user.update_inv_l_hand()
|
||||
to_chat(user, "<span class='notice'>You blow up [src] with [tank].</span>")
|
||||
air_contents = tank.remove_air_volume(3)
|
||||
|
||||
/obj/item/latexballon/proc/burst()
|
||||
if(!air_contents || icon_state != "latexballon_blow")
|
||||
return
|
||||
playsound(src, 'sound/weapons/gunshots/gunshot.ogg', 100, 1)
|
||||
icon_state = "latexballon_bursted"
|
||||
item_state = "lgloves"
|
||||
if(isliving(loc))
|
||||
var/mob/living/user = loc
|
||||
user.update_inv_r_hand()
|
||||
user.update_inv_l_hand()
|
||||
loc.assume_air(air_contents)
|
||||
|
||||
/obj/item/latexballon/ex_act(severity)
|
||||
burst()
|
||||
switch(severity)
|
||||
if (1)
|
||||
qdel(src)
|
||||
if (2)
|
||||
if (prob(50))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/latexballon/bullet_act(obj/item/projectile/P)
|
||||
if(!P.nodamage)
|
||||
burst()
|
||||
return ..()
|
||||
|
||||
/obj/item/latexballon/temperature_expose(datum/gas_mixture/air, temperature, volume)
|
||||
..()
|
||||
if(temperature > T0C+100)
|
||||
burst()
|
||||
|
||||
/obj/item/latexballon/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/tank))
|
||||
var/obj/item/tank/T = W
|
||||
blow(T, user)
|
||||
return
|
||||
if(is_sharp(W) || is_hot(W) || is_pointed(W))
|
||||
burst()
|
||||
/obj/item/latexballon
|
||||
name = "latex glove"
|
||||
desc = "" //todo
|
||||
icon_state = "latexballon"
|
||||
item_state = "lgloves"
|
||||
force = 0
|
||||
throwforce = 0
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throw_speed = 1
|
||||
throw_range = 7
|
||||
var/state
|
||||
var/datum/gas_mixture/air_contents = null
|
||||
|
||||
/obj/item/latexballon/Destroy()
|
||||
QDEL_NULL(air_contents)
|
||||
return ..()
|
||||
|
||||
/obj/item/latexballon/proc/blow(obj/item/tank/tank, mob/user)
|
||||
if(icon_state == "latexballon_bursted")
|
||||
return
|
||||
icon_state = "latexballon_blow"
|
||||
item_state = "latexballon"
|
||||
user.update_inv_r_hand()
|
||||
user.update_inv_l_hand()
|
||||
to_chat(user, "<span class='notice'>You blow up [src] with [tank].</span>")
|
||||
air_contents = tank.remove_air_volume(3)
|
||||
|
||||
/obj/item/latexballon/proc/burst()
|
||||
if(!air_contents || icon_state != "latexballon_blow")
|
||||
return
|
||||
playsound(src, 'sound/weapons/gunshots/gunshot.ogg', 100, 1)
|
||||
icon_state = "latexballon_bursted"
|
||||
item_state = "lgloves"
|
||||
if(isliving(loc))
|
||||
var/mob/living/user = loc
|
||||
user.update_inv_r_hand()
|
||||
user.update_inv_l_hand()
|
||||
loc.assume_air(air_contents)
|
||||
|
||||
/obj/item/latexballon/ex_act(severity)
|
||||
burst()
|
||||
switch(severity)
|
||||
if (1)
|
||||
qdel(src)
|
||||
if (2)
|
||||
if (prob(50))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/latexballon/bullet_act(obj/item/projectile/P)
|
||||
if(!P.nodamage)
|
||||
burst()
|
||||
return ..()
|
||||
|
||||
/obj/item/latexballon/temperature_expose(datum/gas_mixture/air, temperature, volume)
|
||||
..()
|
||||
if(temperature > T0C+100)
|
||||
burst()
|
||||
|
||||
/obj/item/latexballon/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/tank))
|
||||
var/obj/item/tank/T = W
|
||||
blow(T, user)
|
||||
return
|
||||
if(is_sharp(W) || is_hot(W) || is_pointed(W))
|
||||
burst()
|
||||
|
||||
@@ -167,4 +167,4 @@
|
||||
var/obj/item/reagent_containers/food/snacks/badrecipe/ffuu = new(get_turf(source))
|
||||
ffuu.reagents.add_reagent("carbon", amount)
|
||||
ffuu.reagents.add_reagent("????", amount/10)
|
||||
make_dirty(75)
|
||||
make_dirty(75)
|
||||
|
||||
@@ -13,4 +13,4 @@ Code shamelessly copied from apc_frame
|
||||
|
||||
/obj/item/mounted/frame/alarm_frame/do_build(turf/on_wall, mob/user)
|
||||
new /obj/machinery/alarm(get_turf(src), get_dir(on_wall, user), 1)
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -29,4 +29,4 @@
|
||||
|
||||
/obj/item/mounted/frame/apc_frame/do_build(turf/on_wall, mob/user)
|
||||
new /obj/machinery/power/apc(get_turf(src), get_dir(user, on_wall), 1)
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -20,4 +20,4 @@
|
||||
|
||||
/obj/item/mounted/frame/light_switch/do_build(turf/on_wall, mob/user)
|
||||
new /obj/machinery/light_switch(get_turf(user), get_dir(user, on_wall))
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -7,4 +7,4 @@
|
||||
|
||||
/obj/item/mounted/frame/firealarm/do_build(turf/on_wall, mob/user)
|
||||
new /obj/machinery/firealarm(get_turf(src), get_dir(on_wall, user), 1)
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -7,4 +7,4 @@
|
||||
|
||||
/obj/item/mounted/frame/intercom/do_build(turf/on_wall, mob/user)
|
||||
new /obj/item/radio/intercom(get_turf(src), get_dir(user, on_wall), 0)
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -36,4 +36,4 @@
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
icon_state = "bulb-construct-item"
|
||||
fixture_type = "bulb"
|
||||
sheets_refunded = 1
|
||||
sheets_refunded = 1
|
||||
|
||||
@@ -28,4 +28,4 @@
|
||||
var/obj/machinery/newscaster/N = new /obj/machinery/newscaster(get_turf(src), get_dir(on_wall, user), 1)
|
||||
N.pixel_y -= (loc.y - on_wall.y) * 32
|
||||
N.pixel_x -= (loc.x - on_wall.x) * 32
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -321,4 +321,4 @@
|
||||
..()
|
||||
for(var/i in 1 to 6)
|
||||
var/nade = pick(grenadelist)
|
||||
new nade(src)
|
||||
new nade(src)
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
/**********************************************************************
|
||||
Cyborg Spec Items
|
||||
***********************************************************************/
|
||||
/obj/item/borg
|
||||
icon = 'icons/mob/robot_items.dmi'
|
||||
|
||||
/obj/item/borg/stun
|
||||
name = "electrically-charged arm"
|
||||
icon_state = "elecarm"
|
||||
var/charge_cost = 30
|
||||
|
||||
/obj/item/borg/stun/attack(mob/living/M, mob/living/silicon/robot/user)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.check_shields(src, 0, "[M]'s [name]", MELEE_ATTACK))
|
||||
playsound(M, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
return 0
|
||||
|
||||
if(isrobot(user))
|
||||
if(!user.cell.use(charge_cost))
|
||||
return
|
||||
|
||||
user.do_attack_animation(M)
|
||||
M.Weaken(5)
|
||||
M.apply_effect(STUTTER, 5)
|
||||
M.Stun(5)
|
||||
|
||||
M.visible_message("<span class='danger'>[user] has prodded [M] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has prodded you with [src]!</span>")
|
||||
|
||||
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
|
||||
add_attack_logs(user, M, "Stunned with [src] (INTENT: [uppertext(user.a_intent)])")
|
||||
|
||||
/obj/item/borg/overdrive
|
||||
name = "Overdrive"
|
||||
icon = 'icons/obj/decals.dmi'
|
||||
icon_state = "shock"
|
||||
/**********************************************************************
|
||||
Cyborg Spec Items
|
||||
***********************************************************************/
|
||||
/obj/item/borg
|
||||
icon = 'icons/mob/robot_items.dmi'
|
||||
|
||||
/obj/item/borg/stun
|
||||
name = "electrically-charged arm"
|
||||
icon_state = "elecarm"
|
||||
var/charge_cost = 30
|
||||
|
||||
/obj/item/borg/stun/attack(mob/living/M, mob/living/silicon/robot/user)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.check_shields(src, 0, "[M]'s [name]", MELEE_ATTACK))
|
||||
playsound(M, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
return 0
|
||||
|
||||
if(isrobot(user))
|
||||
if(!user.cell.use(charge_cost))
|
||||
return
|
||||
|
||||
user.do_attack_animation(M)
|
||||
M.Weaken(5)
|
||||
M.apply_effect(STUTTER, 5)
|
||||
M.Stun(5)
|
||||
|
||||
M.visible_message("<span class='danger'>[user] has prodded [M] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has prodded you with [src]!</span>")
|
||||
|
||||
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
|
||||
add_attack_logs(user, M, "Stunned with [src] (INTENT: [uppertext(user.a_intent)])")
|
||||
|
||||
/obj/item/borg/overdrive
|
||||
name = "Overdrive"
|
||||
icon = 'icons/obj/decals.dmi'
|
||||
icon_state = "shock"
|
||||
|
||||
@@ -1,177 +1,177 @@
|
||||
// Targets, the things that actually get shot!
|
||||
/obj/item/target
|
||||
name = "shooting target"
|
||||
desc = "A shooting target."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "target_h"
|
||||
density = 0
|
||||
var/hp = 1800
|
||||
var/icon/virtualIcon
|
||||
var/list/bulletholes = list()
|
||||
|
||||
/obj/item/target/Destroy()
|
||||
// if a target is deleted and associated with a stake, force stake to forget
|
||||
for(var/obj/structure/target_stake/T in view(3,src))
|
||||
if(T.pinned_target == src)
|
||||
T.pinned_target = null
|
||||
T.density = 1
|
||||
break
|
||||
return ..() // delete target
|
||||
|
||||
/obj/item/target/Move()
|
||||
..()
|
||||
// After target moves, check for nearby stakes. If associated, move to target
|
||||
for(var/obj/structure/target_stake/M in view(3,src))
|
||||
if(M.density == 0 && M.pinned_target == src)
|
||||
M.loc = loc
|
||||
|
||||
// This may seem a little counter-intuitive but I assure you that's for a purpose.
|
||||
// Stakes are the ones that carry targets, yes, but in the stake code we set
|
||||
// a stake's density to 0 meaning it can't be pushed anymore. Instead of pushing
|
||||
// the stake now, we have to push the target.
|
||||
|
||||
|
||||
/obj/item/target/welder_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!use_tool(src, user, 0,, volume = I.tool_volume))
|
||||
return
|
||||
overlays.Cut()
|
||||
to_chat(usr, "You slice off [src]'s uneven chunks of aluminum and scorch marks.")
|
||||
|
||||
/obj/item/target/attack_hand(mob/user as mob)
|
||||
// taking pinned targets off!
|
||||
var/obj/structure/target_stake/stake
|
||||
for(var/obj/structure/target_stake/T in view(3,src))
|
||||
if(T.pinned_target == src)
|
||||
stake = T
|
||||
break
|
||||
|
||||
if(stake)
|
||||
if(stake.pinned_target)
|
||||
stake.density = 1
|
||||
density = 0
|
||||
layer = OBJ_LAYER
|
||||
|
||||
loc = user.loc
|
||||
if(ishuman(user))
|
||||
if(!user.get_active_hand())
|
||||
user.put_in_hands(src)
|
||||
to_chat(user, "You take the target out of the stake.")
|
||||
else
|
||||
src.loc = get_turf(user)
|
||||
to_chat(user, "You take the target out of the stake.")
|
||||
|
||||
stake.pinned_target = null
|
||||
return
|
||||
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/target/syndicate
|
||||
icon_state = "target_s"
|
||||
desc = "A shooting target that looks like a syndicate scum."
|
||||
hp = 2600 // i guess syndie targets are sturdier?
|
||||
|
||||
/obj/item/target/alien
|
||||
icon_state = "target_q"
|
||||
desc = "A shooting target that looks like a xenomorphic alien."
|
||||
hp = 2350 // alium onest too kinda
|
||||
|
||||
/obj/item/target/bullet_act(var/obj/item/projectile/Proj)
|
||||
var/p_x = Proj.p_x + pick(0,0,0,0,0,-1,1) // really ugly way of coding "sometimes offset Proj.p_x!"
|
||||
var/p_y = Proj.p_y + pick(0,0,0,0,0,-1,1)
|
||||
var/decaltype = 1 // 1 - scorch, 2 - bullet
|
||||
|
||||
if(istype(/obj/item/projectile/bullet, Proj))
|
||||
decaltype = 2
|
||||
|
||||
|
||||
virtualIcon = new(icon, icon_state)
|
||||
|
||||
if( virtualIcon.GetPixel(p_x, p_y) ) // if the located pixel isn't blank (null)
|
||||
|
||||
hp -= Proj.damage
|
||||
if(hp <= 0)
|
||||
visible_message("<span class='warning'>[src] breaks into tiny pieces and collapses!</span>")
|
||||
qdel(src)
|
||||
|
||||
// Create a temporary object to represent the damage
|
||||
var/obj/bmark = new
|
||||
bmark.pixel_x = p_x
|
||||
bmark.pixel_y = p_y
|
||||
bmark.icon = 'icons/effects/effects.dmi'
|
||||
bmark.layer = 3.5
|
||||
bmark.icon_state = "scorch"
|
||||
|
||||
if(decaltype == 1)
|
||||
// Energy weapons are hot. they scorch!
|
||||
|
||||
// offset correction
|
||||
bmark.pixel_x--
|
||||
bmark.pixel_y--
|
||||
|
||||
if(Proj.damage >= 20 || istype(Proj, /obj/item/projectile/beam/practice))
|
||||
bmark.icon_state = "scorch"
|
||||
bmark.dir = pick(NORTH,SOUTH,EAST,WEST) // random scorch design
|
||||
|
||||
|
||||
else
|
||||
bmark.icon_state = "light_scorch"
|
||||
else
|
||||
|
||||
// Bullets are hard. They make dents!
|
||||
bmark.icon_state = "dent"
|
||||
|
||||
if(Proj.damage >= 10 && bulletholes.len <= 35) // maximum of 35 bullet holes
|
||||
if(decaltype == 2) // bullet
|
||||
if(prob(Proj.damage+30)) // bullets make holes more commonly!
|
||||
new/datum/bullethole(src, bmark.pixel_x, bmark.pixel_y) // create new bullet hole
|
||||
else // Lasers!
|
||||
if(prob(Proj.damage-10)) // lasers make holes less commonly
|
||||
new/datum/bullethole(src, bmark.pixel_x, bmark.pixel_y) // create new bullet hole
|
||||
|
||||
// draw bullet holes
|
||||
for(var/datum/bullethole/B in bulletholes)
|
||||
|
||||
virtualIcon.DrawBox(null, B.b1x1, B.b1y, B.b1x2, B.b1y) // horizontal line, left to right
|
||||
virtualIcon.DrawBox(null, B.b2x, B.b2y1, B.b2x, B.b2y2) // vertical line, top to bottom
|
||||
|
||||
overlays += bmark // add the decal
|
||||
|
||||
icon = virtualIcon // apply bulletholes over decals
|
||||
|
||||
return
|
||||
|
||||
return -1 // the bullet/projectile goes through the target! Ie, you missed
|
||||
|
||||
|
||||
// Small memory holder entity for transparent bullet holes
|
||||
/datum/bullethole
|
||||
// First box
|
||||
var/b1x1 = 0
|
||||
var/b1x2 = 0
|
||||
var/b1y = 0
|
||||
|
||||
// Second box
|
||||
var/b2x = 0
|
||||
var/b2y1 = 0
|
||||
var/b2y2 = 0
|
||||
|
||||
/datum/bullethole/New(obj/item/target/Target, pixel_x = 0, pixel_y = 0)
|
||||
if(!Target) return
|
||||
|
||||
// Randomize the first box
|
||||
b1x1 = pixel_x - pick(1,1,1,1,2,2,3,3,4)
|
||||
b1x2 = pixel_x + pick(1,1,1,1,2,2,3,3,4)
|
||||
b1y = pixel_y
|
||||
if(prob(35))
|
||||
b1y += rand(-4,4)
|
||||
|
||||
// Randomize the second box
|
||||
b2x = pixel_x
|
||||
if(prob(35))
|
||||
b2x += rand(-4,4)
|
||||
b2y1 = pixel_y + pick(1,1,1,1,2,2,3,3,4)
|
||||
b2y2 = pixel_y - pick(1,1,1,1,2,2,3,3,4)
|
||||
|
||||
Target.bulletholes.Add(src)
|
||||
// Targets, the things that actually get shot!
|
||||
/obj/item/target
|
||||
name = "shooting target"
|
||||
desc = "A shooting target."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "target_h"
|
||||
density = 0
|
||||
var/hp = 1800
|
||||
var/icon/virtualIcon
|
||||
var/list/bulletholes = list()
|
||||
|
||||
/obj/item/target/Destroy()
|
||||
// if a target is deleted and associated with a stake, force stake to forget
|
||||
for(var/obj/structure/target_stake/T in view(3,src))
|
||||
if(T.pinned_target == src)
|
||||
T.pinned_target = null
|
||||
T.density = 1
|
||||
break
|
||||
return ..() // delete target
|
||||
|
||||
/obj/item/target/Move()
|
||||
..()
|
||||
// After target moves, check for nearby stakes. If associated, move to target
|
||||
for(var/obj/structure/target_stake/M in view(3,src))
|
||||
if(M.density == 0 && M.pinned_target == src)
|
||||
M.loc = loc
|
||||
|
||||
// This may seem a little counter-intuitive but I assure you that's for a purpose.
|
||||
// Stakes are the ones that carry targets, yes, but in the stake code we set
|
||||
// a stake's density to 0 meaning it can't be pushed anymore. Instead of pushing
|
||||
// the stake now, we have to push the target.
|
||||
|
||||
|
||||
/obj/item/target/welder_act(mob/user, obj/item/I)
|
||||
. = TRUE
|
||||
if(!use_tool(src, user, 0,, volume = I.tool_volume))
|
||||
return
|
||||
overlays.Cut()
|
||||
to_chat(usr, "You slice off [src]'s uneven chunks of aluminum and scorch marks.")
|
||||
|
||||
/obj/item/target/attack_hand(mob/user as mob)
|
||||
// taking pinned targets off!
|
||||
var/obj/structure/target_stake/stake
|
||||
for(var/obj/structure/target_stake/T in view(3,src))
|
||||
if(T.pinned_target == src)
|
||||
stake = T
|
||||
break
|
||||
|
||||
if(stake)
|
||||
if(stake.pinned_target)
|
||||
stake.density = 1
|
||||
density = 0
|
||||
layer = OBJ_LAYER
|
||||
|
||||
loc = user.loc
|
||||
if(ishuman(user))
|
||||
if(!user.get_active_hand())
|
||||
user.put_in_hands(src)
|
||||
to_chat(user, "You take the target out of the stake.")
|
||||
else
|
||||
src.loc = get_turf(user)
|
||||
to_chat(user, "You take the target out of the stake.")
|
||||
|
||||
stake.pinned_target = null
|
||||
return
|
||||
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/target/syndicate
|
||||
icon_state = "target_s"
|
||||
desc = "A shooting target that looks like a syndicate scum."
|
||||
hp = 2600 // i guess syndie targets are sturdier?
|
||||
|
||||
/obj/item/target/alien
|
||||
icon_state = "target_q"
|
||||
desc = "A shooting target that looks like a xenomorphic alien."
|
||||
hp = 2350 // alium onest too kinda
|
||||
|
||||
/obj/item/target/bullet_act(var/obj/item/projectile/Proj)
|
||||
var/p_x = Proj.p_x + pick(0,0,0,0,0,-1,1) // really ugly way of coding "sometimes offset Proj.p_x!"
|
||||
var/p_y = Proj.p_y + pick(0,0,0,0,0,-1,1)
|
||||
var/decaltype = 1 // 1 - scorch, 2 - bullet
|
||||
|
||||
if(istype(/obj/item/projectile/bullet, Proj))
|
||||
decaltype = 2
|
||||
|
||||
|
||||
virtualIcon = new(icon, icon_state)
|
||||
|
||||
if( virtualIcon.GetPixel(p_x, p_y) ) // if the located pixel isn't blank (null)
|
||||
|
||||
hp -= Proj.damage
|
||||
if(hp <= 0)
|
||||
visible_message("<span class='warning'>[src] breaks into tiny pieces and collapses!</span>")
|
||||
qdel(src)
|
||||
|
||||
// Create a temporary object to represent the damage
|
||||
var/obj/bmark = new
|
||||
bmark.pixel_x = p_x
|
||||
bmark.pixel_y = p_y
|
||||
bmark.icon = 'icons/effects/effects.dmi'
|
||||
bmark.layer = 3.5
|
||||
bmark.icon_state = "scorch"
|
||||
|
||||
if(decaltype == 1)
|
||||
// Energy weapons are hot. they scorch!
|
||||
|
||||
// offset correction
|
||||
bmark.pixel_x--
|
||||
bmark.pixel_y--
|
||||
|
||||
if(Proj.damage >= 20 || istype(Proj, /obj/item/projectile/beam/practice))
|
||||
bmark.icon_state = "scorch"
|
||||
bmark.dir = pick(NORTH,SOUTH,EAST,WEST) // random scorch design
|
||||
|
||||
|
||||
else
|
||||
bmark.icon_state = "light_scorch"
|
||||
else
|
||||
|
||||
// Bullets are hard. They make dents!
|
||||
bmark.icon_state = "dent"
|
||||
|
||||
if(Proj.damage >= 10 && bulletholes.len <= 35) // maximum of 35 bullet holes
|
||||
if(decaltype == 2) // bullet
|
||||
if(prob(Proj.damage+30)) // bullets make holes more commonly!
|
||||
new/datum/bullethole(src, bmark.pixel_x, bmark.pixel_y) // create new bullet hole
|
||||
else // Lasers!
|
||||
if(prob(Proj.damage-10)) // lasers make holes less commonly
|
||||
new/datum/bullethole(src, bmark.pixel_x, bmark.pixel_y) // create new bullet hole
|
||||
|
||||
// draw bullet holes
|
||||
for(var/datum/bullethole/B in bulletholes)
|
||||
|
||||
virtualIcon.DrawBox(null, B.b1x1, B.b1y, B.b1x2, B.b1y) // horizontal line, left to right
|
||||
virtualIcon.DrawBox(null, B.b2x, B.b2y1, B.b2x, B.b2y2) // vertical line, top to bottom
|
||||
|
||||
overlays += bmark // add the decal
|
||||
|
||||
icon = virtualIcon // apply bulletholes over decals
|
||||
|
||||
return
|
||||
|
||||
return -1 // the bullet/projectile goes through the target! Ie, you missed
|
||||
|
||||
|
||||
// Small memory holder entity for transparent bullet holes
|
||||
/datum/bullethole
|
||||
// First box
|
||||
var/b1x1 = 0
|
||||
var/b1x2 = 0
|
||||
var/b1y = 0
|
||||
|
||||
// Second box
|
||||
var/b2x = 0
|
||||
var/b2y1 = 0
|
||||
var/b2y2 = 0
|
||||
|
||||
/datum/bullethole/New(obj/item/target/Target, pixel_x = 0, pixel_y = 0)
|
||||
if(!Target) return
|
||||
|
||||
// Randomize the first box
|
||||
b1x1 = pixel_x - pick(1,1,1,1,2,2,3,3,4)
|
||||
b1x2 = pixel_x + pick(1,1,1,1,2,2,3,3,4)
|
||||
b1y = pixel_y
|
||||
if(prob(35))
|
||||
b1y += rand(-4,4)
|
||||
|
||||
// Randomize the second box
|
||||
b2x = pixel_x
|
||||
if(prob(35))
|
||||
b2x += rand(-4,4)
|
||||
b2y1 = pixel_y + pick(1,1,1,1,2,2,3,3,4)
|
||||
b2y2 = pixel_y - pick(1,1,1,1,2,2,3,3,4)
|
||||
|
||||
Target.bulletholes.Add(src)
|
||||
|
||||
@@ -1,283 +1,283 @@
|
||||
/obj/item/stack/medical
|
||||
name = "medical pack"
|
||||
singular_name = "medical pack"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
amount = 6
|
||||
max_amount = 6
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
resistance_flags = FLAMMABLE
|
||||
max_integrity = 40
|
||||
var/heal_brute = 0
|
||||
var/heal_burn = 0
|
||||
var/self_delay = 20
|
||||
var/unique_handling = FALSE //some things give a special prompt, do we want to bypass some checks in parent?
|
||||
var/stop_bleeding = 0
|
||||
var/healverb = "bandage"
|
||||
|
||||
/obj/item/stack/medical/attack(mob/living/M, mob/user)
|
||||
if(!iscarbon(M) && !isanimal(M))
|
||||
to_chat(user, "<span class='danger'>[src] cannot be applied to [M]!</span>")
|
||||
return 1
|
||||
|
||||
if(!user.IsAdvancedToolUser())
|
||||
to_chat(user, "<span class='danger'>You don't have the dexterity to do this!</span>")
|
||||
return 1
|
||||
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected)
|
||||
|
||||
if(!H.can_inject(user, TRUE))
|
||||
return TRUE
|
||||
|
||||
if(!affecting)
|
||||
to_chat(user, "<span class='danger'>That limb is missing!</span>")
|
||||
return TRUE
|
||||
|
||||
if(affecting.is_robotic())
|
||||
to_chat(user, "<span class='danger'>This can't be used on a robotic limb.</span>")
|
||||
return TRUE
|
||||
|
||||
if(M == user && !unique_handling)
|
||||
user.visible_message("<span class='notice'>[user] starts to apply [src] on [H]...</span>")
|
||||
if(!do_mob(user, H, self_delay))
|
||||
return TRUE
|
||||
return
|
||||
|
||||
if(isanimal(M))
|
||||
var/mob/living/simple_animal/critter = M
|
||||
if(!(critter.healable))
|
||||
to_chat(user, "<span class='notice'>You cannot use [src] on [critter]!</span>")
|
||||
return
|
||||
else if (critter.health == critter.maxHealth)
|
||||
to_chat(user, "<span class='notice'>[critter] is at full health.</span>")
|
||||
return
|
||||
else if(heal_brute < 1)
|
||||
to_chat(user, "<span class='notice'>[src] won't help [critter] at all.</span>")
|
||||
return
|
||||
|
||||
critter.heal_organ_damage(heal_brute, heal_burn)
|
||||
user.visible_message("<span class='green'>[user] applies [src] on [critter].</span>", \
|
||||
"<span class='green'>You apply [src] on [critter].</span>")
|
||||
|
||||
use(1)
|
||||
|
||||
else
|
||||
M.heal_organ_damage(heal_brute, heal_burn)
|
||||
user.visible_message("<span class='green'>[user] applies [src] on [M].</span>", \
|
||||
"<span class='green'>You apply [src] on [M].</span>")
|
||||
use(1)
|
||||
|
||||
/obj/item/stack/medical/proc/heal(mob/living/M, mob/user)
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected)
|
||||
user.visible_message("<span class='green'>[user] [healverb]s the wounds on [H]'s [affecting.name].</span>", \
|
||||
"<span class='green'>You [healverb] the wounds on [H]'s [affecting.name].</span>" )
|
||||
|
||||
var/rembrute = max(0, heal_brute - affecting.brute_dam) // Maxed with 0 since heal_damage let you pass in a negative value
|
||||
var/remburn = max(0, heal_burn - affecting.burn_dam) // And deduct it from their health (aka deal damage)
|
||||
var/nrembrute = rembrute
|
||||
var/nremburn = remburn
|
||||
affecting.heal_damage(heal_brute, heal_burn)
|
||||
var/list/achildlist
|
||||
if(!isnull(affecting.children))
|
||||
achildlist = affecting.children.Copy()
|
||||
var/parenthealed = FALSE
|
||||
while(rembrute + remburn > 0) // Don't bother if there's not enough leftover heal
|
||||
var/obj/item/organ/external/E
|
||||
if(LAZYLEN(achildlist))
|
||||
E = pick_n_take(achildlist) // Pick a random children and then remove it from the list
|
||||
else if(affecting.parent && !parenthealed) // If there's a parent and no healing attempt was made on it
|
||||
E = affecting.parent
|
||||
parenthealed = TRUE
|
||||
else
|
||||
break // If the organ have no child left and no parent / parent healed, break
|
||||
if(E.status & ORGAN_ROBOT || E.open) // Ignore robotic or open limb
|
||||
continue
|
||||
else if(!E.brute_dam && !E.burn_dam) // Ignore undamaged limb
|
||||
continue
|
||||
nrembrute = max(0, rembrute - E.brute_dam) // Deduct the healed damage from the remain
|
||||
nremburn = max(0, remburn - E.burn_dam)
|
||||
E.heal_damage(rembrute, remburn)
|
||||
rembrute = nrembrute
|
||||
remburn = nremburn
|
||||
user.visible_message("<span class='green'>[user] [healverb]s the wounds on [H]'s [E.name] with the remaining medication.</span>", \
|
||||
"<span class='green'>You [healverb] the wounds on [H]'s [E.name] with the remaining medication.</span>" )
|
||||
|
||||
//Bruise Packs//
|
||||
|
||||
/obj/item/stack/medical/bruise_pack
|
||||
name = "roll of gauze"
|
||||
singular_name = "gauze length"
|
||||
desc = "Some sterile gauze to wrap around bloody stumps."
|
||||
icon_state = "gauze"
|
||||
origin_tech = "biotech=2"
|
||||
heal_brute = 10
|
||||
stop_bleeding = 1800
|
||||
|
||||
/obj/item/stack/medical/bruise_pack/attackby(obj/item/I, mob/user, params)
|
||||
if(I.sharp)
|
||||
if(get_amount() < 2)
|
||||
to_chat(user, "<span class='warning'>You need at least two gauzes to do this!</span>")
|
||||
return
|
||||
new /obj/item/stack/sheet/cloth(user.drop_location())
|
||||
user.visible_message("[user] cuts [src] into pieces of cloth with [I].", \
|
||||
"<span class='notice'>You cut [src] into pieces of cloth with [I].</span>", \
|
||||
"<span class='italics'>You hear cutting.</span>")
|
||||
use(2)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/medical/bruise_pack/attack(mob/living/M, mob/user)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected)
|
||||
|
||||
if(affecting.open == FALSE)
|
||||
affecting.germ_level = 0
|
||||
|
||||
if(stop_bleeding)
|
||||
if(!H.bleedsuppress) //so you can't stack bleed suppression
|
||||
H.suppress_bloodloss(stop_bleeding)
|
||||
|
||||
heal(H, user)
|
||||
|
||||
H.UpdateDamageIcon()
|
||||
use(1)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[affecting] is cut open, you'll need more than a bandage!</span>")
|
||||
|
||||
/obj/item/stack/medical/bruise_pack/improvised
|
||||
name = "improvised gauze"
|
||||
singular_name = "improvised gauze"
|
||||
desc = "A roll of cloth roughly cut from something that can stop bleeding, but does not heal wounds."
|
||||
stop_bleeding = 900
|
||||
|
||||
/obj/item/stack/medical/bruise_pack/advanced
|
||||
name = "advanced trauma kit"
|
||||
singular_name = "advanced trauma kit"
|
||||
desc = "An advanced trauma kit for severe injuries."
|
||||
icon_state = "traumakit"
|
||||
heal_brute = 25
|
||||
stop_bleeding = 0
|
||||
|
||||
|
||||
|
||||
//Ointment//
|
||||
|
||||
|
||||
/obj/item/stack/medical/ointment
|
||||
name = "ointment"
|
||||
desc = "Used to treat those nasty burns."
|
||||
gender = PLURAL
|
||||
singular_name = "ointment"
|
||||
icon_state = "ointment"
|
||||
origin_tech = "biotech=2"
|
||||
healverb = "salve"
|
||||
heal_burn = 10
|
||||
|
||||
/obj/item/stack/medical/ointment/attack(mob/living/M, mob/user)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected)
|
||||
|
||||
if(affecting.open == FALSE)
|
||||
affecting.germ_level = 0
|
||||
|
||||
heal(H, user)
|
||||
|
||||
H.UpdateDamageIcon()
|
||||
use(1)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[affecting] is cut open, you'll need more than some ointment!</span>")
|
||||
|
||||
|
||||
/obj/item/stack/medical/ointment/advanced
|
||||
name = "advanced burn kit"
|
||||
singular_name = "advanced burn kit"
|
||||
desc = "An advanced treatment kit for severe burns."
|
||||
icon_state = "burnkit"
|
||||
heal_burn = 25
|
||||
|
||||
//Medical Herbs//
|
||||
/obj/item/stack/medical/bruise_pack/comfrey
|
||||
name = "\improper Comfrey leaf"
|
||||
singular_name = "Comfrey leaf"
|
||||
desc = "A soft leaf that is rubbed on bruises."
|
||||
icon = 'icons/obj/hydroponics/harvest.dmi'
|
||||
icon_state = "tea_aspera_leaves"
|
||||
color = "#378C61"
|
||||
stop_bleeding = 0
|
||||
heal_brute = 12
|
||||
|
||||
|
||||
/obj/item/stack/medical/ointment/aloe
|
||||
name = "\improper Aloe Vera leaf"
|
||||
singular_name = "Aloe Vera leaf"
|
||||
desc = "A cold leaf that is rubbed on burns."
|
||||
icon = 'icons/obj/hydroponics/harvest.dmi'
|
||||
icon_state = "ambrosiavulgaris"
|
||||
color = "#4CC5C7"
|
||||
heal_burn = 12
|
||||
|
||||
// Splints
|
||||
/obj/item/stack/medical/splint
|
||||
name = "medical splints"
|
||||
singular_name = "medical splint"
|
||||
icon_state = "splint"
|
||||
unique_handling = TRUE
|
||||
self_delay = 100
|
||||
var/other_delay = 0
|
||||
|
||||
/obj/item/stack/medical/splint/attack(mob/living/M, mob/user)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected)
|
||||
var/limb = affecting.name
|
||||
|
||||
if(!(affecting.limb_name in list("l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot")))
|
||||
to_chat(user, "<span class='danger'>You can't apply a splint there!</span>")
|
||||
return TRUE
|
||||
|
||||
if(affecting.status & ORGAN_SPLINTED)
|
||||
to_chat(user, "<span class='danger'>[H]'s [limb] is already splinted!</span>")
|
||||
if(alert(user, "Would you like to remove the splint from [H]'s [limb]?", "Splint removal.", "Yes", "No") == "Yes")
|
||||
affecting.status &= ~ORGAN_SPLINTED
|
||||
H.handle_splints()
|
||||
to_chat(user, "<span class='notice'>You remove the splint from [H]'s [limb].</span>")
|
||||
return TRUE
|
||||
|
||||
if((M == user && self_delay > 0) || (M != user && other_delay > 0))
|
||||
user.visible_message("<span class='notice'>[user] starts to apply [src] to [H]'s [limb].</span>", \
|
||||
"<span class='notice'>You start to apply [src] to [H]'s [limb].</span>", \
|
||||
"<span class='notice'>You hear something being wrapped.</span>")
|
||||
|
||||
if(M == user && !do_mob(user, H, self_delay))
|
||||
return TRUE
|
||||
else if(!do_mob(user, H, other_delay))
|
||||
return TRUE
|
||||
|
||||
user.visible_message("<span class='notice'>[user] applies [src] to [H]'s [limb].</span>", \
|
||||
"<span class='notice'>You apply [src] to [H]'s [limb].</span>")
|
||||
|
||||
affecting.status |= ORGAN_SPLINTED
|
||||
affecting.splinted_count = H.step_count
|
||||
H.handle_splints()
|
||||
use(1)
|
||||
|
||||
/obj/item/stack/medical/splint/tribal
|
||||
name = "tribal splints"
|
||||
icon_state = "tribal_splint"
|
||||
other_delay = 50
|
||||
/obj/item/stack/medical
|
||||
name = "medical pack"
|
||||
singular_name = "medical pack"
|
||||
icon = 'icons/obj/items.dmi'
|
||||
amount = 6
|
||||
max_amount = 6
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
resistance_flags = FLAMMABLE
|
||||
max_integrity = 40
|
||||
var/heal_brute = 0
|
||||
var/heal_burn = 0
|
||||
var/self_delay = 20
|
||||
var/unique_handling = FALSE //some things give a special prompt, do we want to bypass some checks in parent?
|
||||
var/stop_bleeding = 0
|
||||
var/healverb = "bandage"
|
||||
|
||||
/obj/item/stack/medical/attack(mob/living/M, mob/user)
|
||||
if(!iscarbon(M) && !isanimal(M))
|
||||
to_chat(user, "<span class='danger'>[src] cannot be applied to [M]!</span>")
|
||||
return 1
|
||||
|
||||
if(!user.IsAdvancedToolUser())
|
||||
to_chat(user, "<span class='danger'>You don't have the dexterity to do this!</span>")
|
||||
return 1
|
||||
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected)
|
||||
|
||||
if(!H.can_inject(user, TRUE))
|
||||
return TRUE
|
||||
|
||||
if(!affecting)
|
||||
to_chat(user, "<span class='danger'>That limb is missing!</span>")
|
||||
return TRUE
|
||||
|
||||
if(affecting.is_robotic())
|
||||
to_chat(user, "<span class='danger'>This can't be used on a robotic limb.</span>")
|
||||
return TRUE
|
||||
|
||||
if(M == user && !unique_handling)
|
||||
user.visible_message("<span class='notice'>[user] starts to apply [src] on [H]...</span>")
|
||||
if(!do_mob(user, H, self_delay))
|
||||
return TRUE
|
||||
return
|
||||
|
||||
if(isanimal(M))
|
||||
var/mob/living/simple_animal/critter = M
|
||||
if(!(critter.healable))
|
||||
to_chat(user, "<span class='notice'>You cannot use [src] on [critter]!</span>")
|
||||
return
|
||||
else if (critter.health == critter.maxHealth)
|
||||
to_chat(user, "<span class='notice'>[critter] is at full health.</span>")
|
||||
return
|
||||
else if(heal_brute < 1)
|
||||
to_chat(user, "<span class='notice'>[src] won't help [critter] at all.</span>")
|
||||
return
|
||||
|
||||
critter.heal_organ_damage(heal_brute, heal_burn)
|
||||
user.visible_message("<span class='green'>[user] applies [src] on [critter].</span>", \
|
||||
"<span class='green'>You apply [src] on [critter].</span>")
|
||||
|
||||
use(1)
|
||||
|
||||
else
|
||||
M.heal_organ_damage(heal_brute, heal_burn)
|
||||
user.visible_message("<span class='green'>[user] applies [src] on [M].</span>", \
|
||||
"<span class='green'>You apply [src] on [M].</span>")
|
||||
use(1)
|
||||
|
||||
/obj/item/stack/medical/proc/heal(mob/living/M, mob/user)
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected)
|
||||
user.visible_message("<span class='green'>[user] [healverb]s the wounds on [H]'s [affecting.name].</span>", \
|
||||
"<span class='green'>You [healverb] the wounds on [H]'s [affecting.name].</span>" )
|
||||
|
||||
var/rembrute = max(0, heal_brute - affecting.brute_dam) // Maxed with 0 since heal_damage let you pass in a negative value
|
||||
var/remburn = max(0, heal_burn - affecting.burn_dam) // And deduct it from their health (aka deal damage)
|
||||
var/nrembrute = rembrute
|
||||
var/nremburn = remburn
|
||||
affecting.heal_damage(heal_brute, heal_burn)
|
||||
var/list/achildlist
|
||||
if(!isnull(affecting.children))
|
||||
achildlist = affecting.children.Copy()
|
||||
var/parenthealed = FALSE
|
||||
while(rembrute + remburn > 0) // Don't bother if there's not enough leftover heal
|
||||
var/obj/item/organ/external/E
|
||||
if(LAZYLEN(achildlist))
|
||||
E = pick_n_take(achildlist) // Pick a random children and then remove it from the list
|
||||
else if(affecting.parent && !parenthealed) // If there's a parent and no healing attempt was made on it
|
||||
E = affecting.parent
|
||||
parenthealed = TRUE
|
||||
else
|
||||
break // If the organ have no child left and no parent / parent healed, break
|
||||
if(E.status & ORGAN_ROBOT || E.open) // Ignore robotic or open limb
|
||||
continue
|
||||
else if(!E.brute_dam && !E.burn_dam) // Ignore undamaged limb
|
||||
continue
|
||||
nrembrute = max(0, rembrute - E.brute_dam) // Deduct the healed damage from the remain
|
||||
nremburn = max(0, remburn - E.burn_dam)
|
||||
E.heal_damage(rembrute, remburn)
|
||||
rembrute = nrembrute
|
||||
remburn = nremburn
|
||||
user.visible_message("<span class='green'>[user] [healverb]s the wounds on [H]'s [E.name] with the remaining medication.</span>", \
|
||||
"<span class='green'>You [healverb] the wounds on [H]'s [E.name] with the remaining medication.</span>" )
|
||||
|
||||
//Bruise Packs//
|
||||
|
||||
/obj/item/stack/medical/bruise_pack
|
||||
name = "roll of gauze"
|
||||
singular_name = "gauze length"
|
||||
desc = "Some sterile gauze to wrap around bloody stumps."
|
||||
icon_state = "gauze"
|
||||
origin_tech = "biotech=2"
|
||||
heal_brute = 10
|
||||
stop_bleeding = 1800
|
||||
|
||||
/obj/item/stack/medical/bruise_pack/attackby(obj/item/I, mob/user, params)
|
||||
if(I.sharp)
|
||||
if(get_amount() < 2)
|
||||
to_chat(user, "<span class='warning'>You need at least two gauzes to do this!</span>")
|
||||
return
|
||||
new /obj/item/stack/sheet/cloth(user.drop_location())
|
||||
user.visible_message("[user] cuts [src] into pieces of cloth with [I].", \
|
||||
"<span class='notice'>You cut [src] into pieces of cloth with [I].</span>", \
|
||||
"<span class='italics'>You hear cutting.</span>")
|
||||
use(2)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/medical/bruise_pack/attack(mob/living/M, mob/user)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected)
|
||||
|
||||
if(affecting.open == FALSE)
|
||||
affecting.germ_level = 0
|
||||
|
||||
if(stop_bleeding)
|
||||
if(!H.bleedsuppress) //so you can't stack bleed suppression
|
||||
H.suppress_bloodloss(stop_bleeding)
|
||||
|
||||
heal(H, user)
|
||||
|
||||
H.UpdateDamageIcon()
|
||||
use(1)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[affecting] is cut open, you'll need more than a bandage!</span>")
|
||||
|
||||
/obj/item/stack/medical/bruise_pack/improvised
|
||||
name = "improvised gauze"
|
||||
singular_name = "improvised gauze"
|
||||
desc = "A roll of cloth roughly cut from something that can stop bleeding, but does not heal wounds."
|
||||
stop_bleeding = 900
|
||||
|
||||
/obj/item/stack/medical/bruise_pack/advanced
|
||||
name = "advanced trauma kit"
|
||||
singular_name = "advanced trauma kit"
|
||||
desc = "An advanced trauma kit for severe injuries."
|
||||
icon_state = "traumakit"
|
||||
heal_brute = 25
|
||||
stop_bleeding = 0
|
||||
|
||||
|
||||
|
||||
//Ointment//
|
||||
|
||||
|
||||
/obj/item/stack/medical/ointment
|
||||
name = "ointment"
|
||||
desc = "Used to treat those nasty burns."
|
||||
gender = PLURAL
|
||||
singular_name = "ointment"
|
||||
icon_state = "ointment"
|
||||
origin_tech = "biotech=2"
|
||||
healverb = "salve"
|
||||
heal_burn = 10
|
||||
|
||||
/obj/item/stack/medical/ointment/attack(mob/living/M, mob/user)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected)
|
||||
|
||||
if(affecting.open == FALSE)
|
||||
affecting.germ_level = 0
|
||||
|
||||
heal(H, user)
|
||||
|
||||
H.UpdateDamageIcon()
|
||||
use(1)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[affecting] is cut open, you'll need more than some ointment!</span>")
|
||||
|
||||
|
||||
/obj/item/stack/medical/ointment/advanced
|
||||
name = "advanced burn kit"
|
||||
singular_name = "advanced burn kit"
|
||||
desc = "An advanced treatment kit for severe burns."
|
||||
icon_state = "burnkit"
|
||||
heal_burn = 25
|
||||
|
||||
//Medical Herbs//
|
||||
/obj/item/stack/medical/bruise_pack/comfrey
|
||||
name = "\improper Comfrey leaf"
|
||||
singular_name = "Comfrey leaf"
|
||||
desc = "A soft leaf that is rubbed on bruises."
|
||||
icon = 'icons/obj/hydroponics/harvest.dmi'
|
||||
icon_state = "tea_aspera_leaves"
|
||||
color = "#378C61"
|
||||
stop_bleeding = 0
|
||||
heal_brute = 12
|
||||
|
||||
|
||||
/obj/item/stack/medical/ointment/aloe
|
||||
name = "\improper Aloe Vera leaf"
|
||||
singular_name = "Aloe Vera leaf"
|
||||
desc = "A cold leaf that is rubbed on burns."
|
||||
icon = 'icons/obj/hydroponics/harvest.dmi'
|
||||
icon_state = "ambrosiavulgaris"
|
||||
color = "#4CC5C7"
|
||||
heal_burn = 12
|
||||
|
||||
// Splints
|
||||
/obj/item/stack/medical/splint
|
||||
name = "medical splints"
|
||||
singular_name = "medical splint"
|
||||
icon_state = "splint"
|
||||
unique_handling = TRUE
|
||||
self_delay = 100
|
||||
var/other_delay = 0
|
||||
|
||||
/obj/item/stack/medical/splint/attack(mob/living/M, mob/user)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/obj/item/organ/external/affecting = H.get_organ(user.zone_selected)
|
||||
var/limb = affecting.name
|
||||
|
||||
if(!(affecting.limb_name in list("l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot")))
|
||||
to_chat(user, "<span class='danger'>You can't apply a splint there!</span>")
|
||||
return TRUE
|
||||
|
||||
if(affecting.status & ORGAN_SPLINTED)
|
||||
to_chat(user, "<span class='danger'>[H]'s [limb] is already splinted!</span>")
|
||||
if(alert(user, "Would you like to remove the splint from [H]'s [limb]?", "Splint removal.", "Yes", "No") == "Yes")
|
||||
affecting.status &= ~ORGAN_SPLINTED
|
||||
H.handle_splints()
|
||||
to_chat(user, "<span class='notice'>You remove the splint from [H]'s [limb].</span>")
|
||||
return TRUE
|
||||
|
||||
if((M == user && self_delay > 0) || (M != user && other_delay > 0))
|
||||
user.visible_message("<span class='notice'>[user] starts to apply [src] to [H]'s [limb].</span>", \
|
||||
"<span class='notice'>You start to apply [src] to [H]'s [limb].</span>", \
|
||||
"<span class='notice'>You hear something being wrapped.</span>")
|
||||
|
||||
if(M == user && !do_mob(user, H, self_delay))
|
||||
return TRUE
|
||||
else if(!do_mob(user, H, other_delay))
|
||||
return TRUE
|
||||
|
||||
user.visible_message("<span class='notice'>[user] applies [src] to [H]'s [limb].</span>", \
|
||||
"<span class='notice'>You apply [src] to [H]'s [limb].</span>")
|
||||
|
||||
affecting.status |= ORGAN_SPLINTED
|
||||
affecting.splinted_count = H.step_count
|
||||
H.handle_splints()
|
||||
use(1)
|
||||
|
||||
/obj/item/stack/medical/splint/tribal
|
||||
name = "tribal splints"
|
||||
icon_state = "tribal_splint"
|
||||
other_delay = 50
|
||||
|
||||
@@ -1,68 +1,68 @@
|
||||
var/global/list/datum/stack_recipe/rod_recipes = list ( \
|
||||
new/datum/stack_recipe("grille", /obj/structure/grille, 2, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("table frame", /obj/structure/table_frame, 2, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
)
|
||||
|
||||
/obj/item/stack/rods
|
||||
name = "metal rod"
|
||||
desc = "Some rods. Can be used for building, or something."
|
||||
singular_name = "metal rod"
|
||||
icon_state = "rods"
|
||||
item_state = "rods"
|
||||
flags = CONDUCT
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
force = 9.0
|
||||
throwforce = 10.0
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
materials = list(MAT_METAL=1000)
|
||||
max_amount = 50
|
||||
attack_verb = list("hit", "bludgeoned", "whacked")
|
||||
hitsound = 'sound/weapons/grenadelaunch.ogg'
|
||||
toolspeed = 1
|
||||
usesound = 'sound/items/deconstruct.ogg'
|
||||
|
||||
/obj/item/stack/rods/cyborg
|
||||
materials = list()
|
||||
|
||||
/obj/item/stack/rods/ten
|
||||
amount = 10
|
||||
|
||||
/obj/item/stack/rods/twentyfive
|
||||
amount = 25
|
||||
|
||||
/obj/item/stack/rods/fifty
|
||||
amount = 50
|
||||
|
||||
/obj/item/stack/rods/New(loc, amount=null)
|
||||
..()
|
||||
recipes = rod_recipes
|
||||
update_icon()
|
||||
|
||||
/obj/item/stack/rods/update_icon()
|
||||
var/amount = get_amount()
|
||||
if((amount <= 5) && (amount > 0))
|
||||
icon_state = "rods-[amount]"
|
||||
else
|
||||
icon_state = "rods"
|
||||
|
||||
/obj/item/stack/rods/welder_act(mob/user, obj/item/I)
|
||||
if(get_amount() < 2)
|
||||
to_chat(user, "<span class='warning'>You need at least two rods to do this!</span>")
|
||||
return
|
||||
. = TRUE
|
||||
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
|
||||
return
|
||||
var/obj/item/stack/sheet/metal/new_item = new(drop_location())
|
||||
if(new_item.get_amount() <= 0)
|
||||
// stack was moved into another one on the pile
|
||||
new_item = locate() in user.loc
|
||||
visible_message("<span class='notice'>[user.name] shapes [src] into metal with [I]!</span>", \
|
||||
"<span class='notice'>You shape [src] into metal with [I]!</span>", \
|
||||
"<span class='warning'>You hear welding.</span>")
|
||||
var/replace = user.is_in_inactive_hand(src)
|
||||
use(2)
|
||||
if(get_amount() <= 0 && replace)
|
||||
user.unEquip(src, 1)
|
||||
if(new_item)
|
||||
user.put_in_hands(new_item)
|
||||
var/global/list/datum/stack_recipe/rod_recipes = list ( \
|
||||
new/datum/stack_recipe("grille", /obj/structure/grille, 2, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("table frame", /obj/structure/table_frame, 2, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
)
|
||||
|
||||
/obj/item/stack/rods
|
||||
name = "metal rod"
|
||||
desc = "Some rods. Can be used for building, or something."
|
||||
singular_name = "metal rod"
|
||||
icon_state = "rods"
|
||||
item_state = "rods"
|
||||
flags = CONDUCT
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
force = 9.0
|
||||
throwforce = 10.0
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
materials = list(MAT_METAL=1000)
|
||||
max_amount = 50
|
||||
attack_verb = list("hit", "bludgeoned", "whacked")
|
||||
hitsound = 'sound/weapons/grenadelaunch.ogg'
|
||||
toolspeed = 1
|
||||
usesound = 'sound/items/deconstruct.ogg'
|
||||
|
||||
/obj/item/stack/rods/cyborg
|
||||
materials = list()
|
||||
|
||||
/obj/item/stack/rods/ten
|
||||
amount = 10
|
||||
|
||||
/obj/item/stack/rods/twentyfive
|
||||
amount = 25
|
||||
|
||||
/obj/item/stack/rods/fifty
|
||||
amount = 50
|
||||
|
||||
/obj/item/stack/rods/New(loc, amount=null)
|
||||
..()
|
||||
recipes = rod_recipes
|
||||
update_icon()
|
||||
|
||||
/obj/item/stack/rods/update_icon()
|
||||
var/amount = get_amount()
|
||||
if((amount <= 5) && (amount > 0))
|
||||
icon_state = "rods-[amount]"
|
||||
else
|
||||
icon_state = "rods"
|
||||
|
||||
/obj/item/stack/rods/welder_act(mob/user, obj/item/I)
|
||||
if(get_amount() < 2)
|
||||
to_chat(user, "<span class='warning'>You need at least two rods to do this!</span>")
|
||||
return
|
||||
. = TRUE
|
||||
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
|
||||
return
|
||||
var/obj/item/stack/sheet/metal/new_item = new(drop_location())
|
||||
if(new_item.get_amount() <= 0)
|
||||
// stack was moved into another one on the pile
|
||||
new_item = locate() in user.loc
|
||||
visible_message("<span class='notice'>[user.name] shapes [src] into metal with [I]!</span>", \
|
||||
"<span class='notice'>You shape [src] into metal with [I]!</span>", \
|
||||
"<span class='warning'>You hear welding.</span>")
|
||||
var/replace = user.is_in_inactive_hand(src)
|
||||
use(2)
|
||||
if(get_amount() <= 0 && replace)
|
||||
user.unEquip(src, 1)
|
||||
if(new_item)
|
||||
user.put_in_hands(new_item)
|
||||
|
||||
@@ -1,211 +1,211 @@
|
||||
/* Glass stack types
|
||||
* Contains:
|
||||
* Glass sheets
|
||||
* Reinforced glass sheets
|
||||
* Glass shards - TODO: Move this into code/game/object/item/weapons
|
||||
* Plasma Glass Sheets
|
||||
* Reinforced Plasma Glass Sheets (AKA Holy fuck strong windows)
|
||||
|
||||
Todo: Create a unified construct_window(sheet, user, created_window, full_window)
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* Glass sheets
|
||||
*/
|
||||
|
||||
GLOBAL_LIST_INIT(glass_recipes, list ( \
|
||||
new/datum/stack_recipe/window("directional window", /obj/structure/window/basic, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe/window("fulltile window", /obj/structure/window/full/basic, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe("fishbowl", /obj/machinery/fishtank/bowl, 1, time = 0), \
|
||||
new/datum/stack_recipe("fish tank", /obj/machinery/fishtank/tank, 3, time = 0, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("wall aquariam", /obj/machinery/fishtank/wall, 4, time = 0, on_floor = TRUE) \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/glass
|
||||
name = "glass"
|
||||
desc = "HOLY SHEET! That is a lot of glass."
|
||||
singular_name = "glass sheet"
|
||||
icon_state = "sheet-glass"
|
||||
materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100)
|
||||
resistance_flags = ACID_PROOF
|
||||
origin_tech = "materials=1"
|
||||
created_window = /obj/structure/window/basic
|
||||
full_window = /obj/structure/window/full/basic
|
||||
merge_type = /obj/item/stack/sheet/glass
|
||||
point_value = 1
|
||||
|
||||
/obj/item/stack/sheet/glass/fifty
|
||||
amount = 50
|
||||
|
||||
/obj/item/stack/sheet/glass/cyborg
|
||||
materials = list()
|
||||
|
||||
/obj/item/stack/sheet/glass/New(loc, amount)
|
||||
recipes = GLOB.glass_recipes
|
||||
..()
|
||||
|
||||
/obj/item/stack/sheet/glass/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
if(istype(W,/obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/CC = W
|
||||
if(CC.amount < 5)
|
||||
to_chat(user, "<b>There is not enough wire in this coil. You need 5 lengths.</b>")
|
||||
return
|
||||
CC.use(5)
|
||||
to_chat(user, "<span class='notice'>You attach wire to the [name].</span>")
|
||||
new /obj/item/stack/light_w(user.loc)
|
||||
src.use(1)
|
||||
else if( istype(W, /obj/item/stack/rods) )
|
||||
var/obj/item/stack/rods/V = W
|
||||
var/obj/item/stack/sheet/rglass/RG = new (user.loc)
|
||||
RG.add_fingerprint(user)
|
||||
V.use(1)
|
||||
var/obj/item/stack/sheet/glass/G = src
|
||||
src = null
|
||||
var/replace = (user.get_inactive_hand()==G)
|
||||
G.use(1)
|
||||
if(!G && !RG && replace)
|
||||
user.put_in_hands(RG)
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/*
|
||||
* Reinforced glass sheets
|
||||
*/
|
||||
|
||||
GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \
|
||||
new/datum/stack_recipe/window("windoor frame", /obj/structure/windoor_assembly, 5, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
null, \
|
||||
new/datum/stack_recipe/window("directional reinforced window", /obj/structure/window/reinforced, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe/window("fulltile reinforced window", /obj/structure/window/full/reinforced, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/rglass
|
||||
name = "reinforced glass"
|
||||
desc = "Glass which seems to have rods or something stuck in them."
|
||||
singular_name = "reinforced glass sheet"
|
||||
icon_state = "sheet-rglass"
|
||||
materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT/2, MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 100)
|
||||
resistance_flags = ACID_PROOF
|
||||
origin_tech = "materials=2"
|
||||
created_window = /obj/structure/window/reinforced
|
||||
full_window = /obj/structure/window/full/reinforced
|
||||
merge_type = /obj/item/stack/sheet/rglass
|
||||
point_value = 4
|
||||
|
||||
/obj/item/stack/sheet/rglass/cyborg
|
||||
materials = list()
|
||||
|
||||
/obj/item/stack/sheet/rglass/New(loc, amount)
|
||||
recipes = GLOB.reinforced_glass_recipes
|
||||
..()
|
||||
|
||||
GLOBAL_LIST_INIT(pglass_recipes, list ( \
|
||||
new/datum/stack_recipe/window("directional window", /obj/structure/window/plasmabasic, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe/window("fulltile window", /obj/structure/window/full/plasmabasic, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/plasmaglass
|
||||
name = "plasma glass"
|
||||
desc = "A very strong and very resistant sheet of a plasma-glass alloy."
|
||||
singular_name = "glass sheet"
|
||||
icon_state = "sheet-plasmaglass"
|
||||
item_state = "sheet-rglass"
|
||||
materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT*2)
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 100)
|
||||
resistance_flags = ACID_PROOF
|
||||
origin_tech = "plasmatech=2;materials=2"
|
||||
created_window = /obj/structure/window/plasmabasic
|
||||
full_window = /obj/structure/window/full/plasmabasic
|
||||
point_value = 19
|
||||
|
||||
/obj/item/stack/sheet/plasmaglass/New(loc, amount)
|
||||
recipes = GLOB.pglass_recipes
|
||||
..()
|
||||
|
||||
/obj/item/stack/sheet/plasmaglass/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
if( istype(W, /obj/item/stack/rods) )
|
||||
var/obj/item/stack/rods/V = W
|
||||
var/obj/item/stack/sheet/plasmarglass/RG = new (user.loc)
|
||||
RG.add_fingerprint(user)
|
||||
V.use(1)
|
||||
var/obj/item/stack/sheet/glass/G = src
|
||||
src = null
|
||||
var/replace = (user.get_inactive_hand()==G)
|
||||
G.use(1)
|
||||
if(!G && !RG && replace)
|
||||
user.put_in_hands(RG)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/*
|
||||
* Reinforced plasma glass sheets
|
||||
*/
|
||||
|
||||
GLOBAL_LIST_INIT(prglass_recipes, list ( \
|
||||
new/datum/stack_recipe/window("directional reinforced window", /obj/structure/window/plasmareinforced, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe/window("fulltile reinforced window", /obj/structure/window/full/plasmareinforced, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/plasmarglass
|
||||
name = "reinforced plasma glass"
|
||||
desc = "Plasma glass which seems to have rods or something stuck in them."
|
||||
singular_name = "reinforced plasma glass sheet"
|
||||
icon_state = "sheet-plasmarglass"
|
||||
item_state = "sheet-rglass"
|
||||
materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT/2, MAT_GLASS=MINERAL_MATERIAL_AMOUNT*2)
|
||||
armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100)
|
||||
resistance_flags = ACID_PROOF
|
||||
origin_tech = "plasmatech=2;materials=2"
|
||||
created_window = /obj/structure/window/plasmareinforced
|
||||
full_window = /obj/structure/window/full/plasmareinforced
|
||||
point_value = 23
|
||||
|
||||
/obj/item/stack/sheet/plasmarglass/New(loc, amount)
|
||||
recipes = GLOB.prglass_recipes
|
||||
..()
|
||||
|
||||
GLOBAL_LIST_INIT(titaniumglass_recipes, list(
|
||||
new/datum/stack_recipe/window("shuttle window", /obj/structure/window/full/shuttle, 2, time = 0, on_floor = TRUE, window_checks = TRUE)
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/titaniumglass
|
||||
name = "titanium glass"
|
||||
desc = "A glass sheet made out of a titanium-silicate alloy."
|
||||
singular_name = "titanium glass sheet"
|
||||
icon_state = "sheet-titaniumglass"
|
||||
item_state = "sheet-rglass"
|
||||
materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT, MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100)
|
||||
resistance_flags = ACID_PROOF
|
||||
merge_type = /obj/item/stack/sheet/titaniumglass
|
||||
full_window = /obj/structure/window/full/shuttle
|
||||
|
||||
/obj/item/stack/sheet/titaniumglass/New(loc, amount)
|
||||
recipes = GLOB.titaniumglass_recipes
|
||||
..()
|
||||
|
||||
GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
|
||||
new/datum/stack_recipe/window("plastitanium window", /obj/structure/window/plastitanium, 2, time = 0, on_floor = TRUE, window_checks = TRUE)
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/plastitaniumglass
|
||||
name = "plastitanium glass"
|
||||
desc = "A glass sheet made out of a plasma-titanium-silicate alloy."
|
||||
singular_name = "plastitanium glass sheet"
|
||||
icon_state = "sheet-plastitaniumglass"
|
||||
item_state = "sheet-rglass"
|
||||
materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT, MAT_PLASMA=MINERAL_MATERIAL_AMOUNT, MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100)
|
||||
resistance_flags = ACID_PROOF
|
||||
merge_type = /obj/item/stack/sheet/plastitaniumglass
|
||||
full_window = /obj/structure/window/plastitanium
|
||||
|
||||
/obj/item/stack/sheet/plastitaniumglass/New(loc, amount)
|
||||
recipes = GLOB.plastitaniumglass_recipes
|
||||
..()
|
||||
/* Glass stack types
|
||||
* Contains:
|
||||
* Glass sheets
|
||||
* Reinforced glass sheets
|
||||
* Glass shards - TODO: Move this into code/game/object/item/weapons
|
||||
* Plasma Glass Sheets
|
||||
* Reinforced Plasma Glass Sheets (AKA Holy fuck strong windows)
|
||||
|
||||
Todo: Create a unified construct_window(sheet, user, created_window, full_window)
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* Glass sheets
|
||||
*/
|
||||
|
||||
GLOBAL_LIST_INIT(glass_recipes, list ( \
|
||||
new/datum/stack_recipe/window("directional window", /obj/structure/window/basic, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe/window("fulltile window", /obj/structure/window/full/basic, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe("fishbowl", /obj/machinery/fishtank/bowl, 1, time = 0), \
|
||||
new/datum/stack_recipe("fish tank", /obj/machinery/fishtank/tank, 3, time = 0, on_floor = TRUE), \
|
||||
new/datum/stack_recipe("wall aquariam", /obj/machinery/fishtank/wall, 4, time = 0, on_floor = TRUE) \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/glass
|
||||
name = "glass"
|
||||
desc = "HOLY SHEET! That is a lot of glass."
|
||||
singular_name = "glass sheet"
|
||||
icon_state = "sheet-glass"
|
||||
materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 100)
|
||||
resistance_flags = ACID_PROOF
|
||||
origin_tech = "materials=1"
|
||||
created_window = /obj/structure/window/basic
|
||||
full_window = /obj/structure/window/full/basic
|
||||
merge_type = /obj/item/stack/sheet/glass
|
||||
point_value = 1
|
||||
|
||||
/obj/item/stack/sheet/glass/fifty
|
||||
amount = 50
|
||||
|
||||
/obj/item/stack/sheet/glass/cyborg
|
||||
materials = list()
|
||||
|
||||
/obj/item/stack/sheet/glass/New(loc, amount)
|
||||
recipes = GLOB.glass_recipes
|
||||
..()
|
||||
|
||||
/obj/item/stack/sheet/glass/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
if(istype(W,/obj/item/stack/cable_coil))
|
||||
var/obj/item/stack/cable_coil/CC = W
|
||||
if(CC.amount < 5)
|
||||
to_chat(user, "<b>There is not enough wire in this coil. You need 5 lengths.</b>")
|
||||
return
|
||||
CC.use(5)
|
||||
to_chat(user, "<span class='notice'>You attach wire to the [name].</span>")
|
||||
new /obj/item/stack/light_w(user.loc)
|
||||
src.use(1)
|
||||
else if( istype(W, /obj/item/stack/rods) )
|
||||
var/obj/item/stack/rods/V = W
|
||||
var/obj/item/stack/sheet/rglass/RG = new (user.loc)
|
||||
RG.add_fingerprint(user)
|
||||
V.use(1)
|
||||
var/obj/item/stack/sheet/glass/G = src
|
||||
src = null
|
||||
var/replace = (user.get_inactive_hand()==G)
|
||||
G.use(1)
|
||||
if(!G && !RG && replace)
|
||||
user.put_in_hands(RG)
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/*
|
||||
* Reinforced glass sheets
|
||||
*/
|
||||
|
||||
GLOBAL_LIST_INIT(reinforced_glass_recipes, list ( \
|
||||
new/datum/stack_recipe/window("windoor frame", /obj/structure/windoor_assembly, 5, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
null, \
|
||||
new/datum/stack_recipe/window("directional reinforced window", /obj/structure/window/reinforced, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe/window("fulltile reinforced window", /obj/structure/window/full/reinforced, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/rglass
|
||||
name = "reinforced glass"
|
||||
desc = "Glass which seems to have rods or something stuck in them."
|
||||
singular_name = "reinforced glass sheet"
|
||||
icon_state = "sheet-rglass"
|
||||
materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT/2, MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 70, "acid" = 100)
|
||||
resistance_flags = ACID_PROOF
|
||||
origin_tech = "materials=2"
|
||||
created_window = /obj/structure/window/reinforced
|
||||
full_window = /obj/structure/window/full/reinforced
|
||||
merge_type = /obj/item/stack/sheet/rglass
|
||||
point_value = 4
|
||||
|
||||
/obj/item/stack/sheet/rglass/cyborg
|
||||
materials = list()
|
||||
|
||||
/obj/item/stack/sheet/rglass/New(loc, amount)
|
||||
recipes = GLOB.reinforced_glass_recipes
|
||||
..()
|
||||
|
||||
GLOBAL_LIST_INIT(pglass_recipes, list ( \
|
||||
new/datum/stack_recipe/window("directional window", /obj/structure/window/plasmabasic, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe/window("fulltile window", /obj/structure/window/full/plasmabasic, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/plasmaglass
|
||||
name = "plasma glass"
|
||||
desc = "A very strong and very resistant sheet of a plasma-glass alloy."
|
||||
singular_name = "glass sheet"
|
||||
icon_state = "sheet-plasmaglass"
|
||||
item_state = "sheet-rglass"
|
||||
materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT*2)
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 75, "acid" = 100)
|
||||
resistance_flags = ACID_PROOF
|
||||
origin_tech = "plasmatech=2;materials=2"
|
||||
created_window = /obj/structure/window/plasmabasic
|
||||
full_window = /obj/structure/window/full/plasmabasic
|
||||
point_value = 19
|
||||
|
||||
/obj/item/stack/sheet/plasmaglass/New(loc, amount)
|
||||
recipes = GLOB.pglass_recipes
|
||||
..()
|
||||
|
||||
/obj/item/stack/sheet/plasmaglass/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
if( istype(W, /obj/item/stack/rods) )
|
||||
var/obj/item/stack/rods/V = W
|
||||
var/obj/item/stack/sheet/plasmarglass/RG = new (user.loc)
|
||||
RG.add_fingerprint(user)
|
||||
V.use(1)
|
||||
var/obj/item/stack/sheet/glass/G = src
|
||||
src = null
|
||||
var/replace = (user.get_inactive_hand()==G)
|
||||
G.use(1)
|
||||
if(!G && !RG && replace)
|
||||
user.put_in_hands(RG)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/*
|
||||
* Reinforced plasma glass sheets
|
||||
*/
|
||||
|
||||
GLOBAL_LIST_INIT(prglass_recipes, list ( \
|
||||
new/datum/stack_recipe/window("directional reinforced window", /obj/structure/window/plasmareinforced, time = 0, on_floor = TRUE, window_checks = TRUE), \
|
||||
new/datum/stack_recipe/window("fulltile reinforced window", /obj/structure/window/full/plasmareinforced, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/plasmarglass
|
||||
name = "reinforced plasma glass"
|
||||
desc = "Plasma glass which seems to have rods or something stuck in them."
|
||||
singular_name = "reinforced plasma glass sheet"
|
||||
icon_state = "sheet-plasmarglass"
|
||||
item_state = "sheet-rglass"
|
||||
materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT/2, MAT_GLASS=MINERAL_MATERIAL_AMOUNT*2)
|
||||
armor = list("melee" = 20, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100)
|
||||
resistance_flags = ACID_PROOF
|
||||
origin_tech = "plasmatech=2;materials=2"
|
||||
created_window = /obj/structure/window/plasmareinforced
|
||||
full_window = /obj/structure/window/full/plasmareinforced
|
||||
point_value = 23
|
||||
|
||||
/obj/item/stack/sheet/plasmarglass/New(loc, amount)
|
||||
recipes = GLOB.prglass_recipes
|
||||
..()
|
||||
|
||||
GLOBAL_LIST_INIT(titaniumglass_recipes, list(
|
||||
new/datum/stack_recipe/window("shuttle window", /obj/structure/window/full/shuttle, 2, time = 0, on_floor = TRUE, window_checks = TRUE)
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/titaniumglass
|
||||
name = "titanium glass"
|
||||
desc = "A glass sheet made out of a titanium-silicate alloy."
|
||||
singular_name = "titanium glass sheet"
|
||||
icon_state = "sheet-titaniumglass"
|
||||
item_state = "sheet-rglass"
|
||||
materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT, MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100)
|
||||
resistance_flags = ACID_PROOF
|
||||
merge_type = /obj/item/stack/sheet/titaniumglass
|
||||
full_window = /obj/structure/window/full/shuttle
|
||||
|
||||
/obj/item/stack/sheet/titaniumglass/New(loc, amount)
|
||||
recipes = GLOB.titaniumglass_recipes
|
||||
..()
|
||||
|
||||
GLOBAL_LIST_INIT(plastitaniumglass_recipes, list(
|
||||
new/datum/stack_recipe/window("plastitanium window", /obj/structure/window/plastitanium, 2, time = 0, on_floor = TRUE, window_checks = TRUE)
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/plastitaniumglass
|
||||
name = "plastitanium glass"
|
||||
desc = "A glass sheet made out of a plasma-titanium-silicate alloy."
|
||||
singular_name = "plastitanium glass sheet"
|
||||
icon_state = "sheet-plastitaniumglass"
|
||||
item_state = "sheet-rglass"
|
||||
materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT, MAT_PLASMA=MINERAL_MATERIAL_AMOUNT, MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100)
|
||||
resistance_flags = ACID_PROOF
|
||||
merge_type = /obj/item/stack/sheet/plastitaniumglass
|
||||
full_window = /obj/structure/window/plastitanium
|
||||
|
||||
/obj/item/stack/sheet/plastitaniumglass/New(loc, amount)
|
||||
recipes = GLOB.plastitaniumglass_recipes
|
||||
..()
|
||||
|
||||
@@ -1,242 +1,242 @@
|
||||
/obj/item/stack/sheet/animalhide
|
||||
name = "hide"
|
||||
desc = "Something went wrong."
|
||||
origin_tech = "biotech=3"
|
||||
|
||||
/obj/item/stack/sheet/animalhide/human
|
||||
name = "human skin"
|
||||
desc = "The by-product of human farming."
|
||||
singular_name = "human skin piece"
|
||||
icon_state = "sheet-hide"
|
||||
|
||||
var/global/list/datum/stack_recipe/human_recipes = list( \
|
||||
new/datum/stack_recipe("bloated human costume", /obj/item/clothing/suit/bloated_human, 5, on_floor = 1), \
|
||||
new/datum/stack_recipe("bloated human costume head", /obj/item/clothing/head/human_head, 5, on_floor = 1), \
|
||||
)
|
||||
|
||||
/obj/item/stack/sheet/animalhide/human/New(var/loc, var/amount=null)
|
||||
recipes = human_recipes
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/sheet/animalhide/generic
|
||||
name = "generic skin"
|
||||
desc = "A piece of generic skin."
|
||||
singular_name = "generic skin piece"
|
||||
icon_state = "sheet-hide"
|
||||
|
||||
/obj/item/stack/sheet/animalhide/corgi
|
||||
name = "corgi hide"
|
||||
desc = "The by-product of corgi farming."
|
||||
singular_name = "corgi hide piece"
|
||||
icon_state = "sheet-corgi"
|
||||
|
||||
/obj/item/stack/sheet/animalhide/cat
|
||||
name = "cat hide"
|
||||
desc = "The by-product of cat farming."
|
||||
singular_name = "cat hide piece"
|
||||
icon_state = "sheet-cat"
|
||||
|
||||
/obj/item/stack/sheet/animalhide/monkey
|
||||
name = "monkey hide"
|
||||
desc = "The by-product of monkey farming."
|
||||
singular_name = "monkey hide piece"
|
||||
icon_state = "sheet-monkey"
|
||||
|
||||
/obj/item/stack/sheet/animalhide/lizard
|
||||
name = "lizard skin"
|
||||
desc = "Sssssss..."
|
||||
singular_name = "lizard skin piece"
|
||||
icon_state = "sheet-lizard"
|
||||
|
||||
/obj/item/stack/sheet/animalhide/xeno
|
||||
name = "alien hide"
|
||||
desc = "The skin of a terrible creature."
|
||||
singular_name = "alien hide piece"
|
||||
icon_state = "sheet-xeno"
|
||||
|
||||
GLOBAL_LIST_INIT(xeno_recipes, list (
|
||||
new/datum/stack_recipe("alien helmet", /obj/item/clothing/head/xenos, 1),
|
||||
new/datum/stack_recipe("alien suit", /obj/item/clothing/suit/xenos, 2)))
|
||||
|
||||
/obj/item/stack/sheet/animalhide/xeno/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.xeno_recipes
|
||||
return ..()
|
||||
|
||||
//don't see anywhere else to put these, maybe together they could be used to make the xenos suit?
|
||||
/obj/item/stack/sheet/xenochitin
|
||||
name = "alien chitin"
|
||||
desc = "A piece of the hide of a terrible creature."
|
||||
singular_name = "alien hide piece"
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
icon_state = "chitin"
|
||||
origin_tech = ""
|
||||
|
||||
/obj/item/xenos_claw
|
||||
name = "alien claw"
|
||||
desc = "The claw of a terrible creature."
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
icon_state = "claw"
|
||||
origin_tech = ""
|
||||
|
||||
/obj/item/weed_extract
|
||||
name = "weed extract"
|
||||
desc = "A piece of slimy, purplish weed."
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
icon_state = "weed_extract"
|
||||
origin_tech = ""
|
||||
|
||||
/obj/item/stack/sheet/hairlesshide
|
||||
name = "hairless hide"
|
||||
desc = "This hide was stripped of it's hair, but still needs tanning."
|
||||
singular_name = "hairless hide piece"
|
||||
icon_state = "sheet-hairlesshide"
|
||||
origin_tech = ""
|
||||
|
||||
/obj/item/stack/sheet/wetleather
|
||||
name = "wet leather"
|
||||
desc = "This leather has been cleaned but still needs to be dried."
|
||||
singular_name = "wet leather piece"
|
||||
icon_state = "sheet-wetleather"
|
||||
origin_tech = ""
|
||||
var/wetness = 30 //Reduced when exposed to high temperautres
|
||||
var/drying_threshold_temperature = 500 //Kelvin to start drying
|
||||
|
||||
/obj/item/stack/sheet/leather
|
||||
name = "leather"
|
||||
desc = "The by-product of mob grinding."
|
||||
singular_name = "leather piece"
|
||||
icon_state = "sheet-leather"
|
||||
origin_tech = "materials=2"
|
||||
|
||||
GLOBAL_LIST_INIT(leather_recipes, list (
|
||||
new/datum/stack_recipe("wallet", /obj/item/storage/wallet, 1),
|
||||
new/datum/stack_recipe("muzzle", /obj/item/clothing/mask/muzzle, 2),
|
||||
new/datum/stack_recipe("botany gloves", /obj/item/clothing/gloves/botanic_leather, 3),
|
||||
new/datum/stack_recipe("toolbelt", /obj/item/storage/belt/utility, 4),
|
||||
new/datum/stack_recipe("leather satchel", /obj/item/storage/backpack/satchel, 5),
|
||||
new/datum/stack_recipe("bandolier", /obj/item/storage/belt/bandolier, 5),
|
||||
new/datum/stack_recipe("leather jacket", /obj/item/clothing/suit/jacket/leather, 7),
|
||||
new/datum/stack_recipe("leather shoes", /obj/item/clothing/shoes/laceup, 2),
|
||||
new/datum/stack_recipe("leather overcoat", /obj/item/clothing/suit/jacket/leather/overcoat, 10),
|
||||
new/datum/stack_recipe("hide mantle", /obj/item/clothing/suit/unathi/mantle, 4)))
|
||||
|
||||
/obj/item/stack/sheet/leather/New(loc, new_amount, merge = TRUE)
|
||||
recipes = GLOB.leather_recipes
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/sheet/sinew
|
||||
name = "watcher sinew"
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
desc = "Long stringy filaments which presumably came from a watcher's wings."
|
||||
singular_name = "watcher sinew"
|
||||
icon_state = "sinew"
|
||||
origin_tech = "biotech=4"
|
||||
|
||||
var/global/list/datum/stack_recipe/sinew_recipes = list ( \
|
||||
new/datum/stack_recipe("sinew restraints", /obj/item/restraints/handcuffs/sinew, 1, on_floor = 1), \
|
||||
)
|
||||
|
||||
/obj/item/stack/sheet/sinew/New(var/loc, var/amount=null)
|
||||
recipes = sinew_recipes
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/sheet/animalhide/goliath_hide
|
||||
name = "goliath hide plates"
|
||||
desc = "Pieces of a goliath's rocky hide, these might be able to make your suit a bit more durable to attack from the local fauna."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "goliath_hide"
|
||||
singular_name = "hide plate"
|
||||
flags = NOBLUDGEON
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
layer = MOB_LAYER
|
||||
var/static/list/goliath_platable_armor_typecache = typecacheof(list(
|
||||
/obj/item/clothing/suit/space/hardsuit/mining,
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/mining,
|
||||
/obj/item/clothing/suit/hooded/explorer,
|
||||
/obj/item/clothing/head/hooded/explorer,
|
||||
/obj/item/clothing/head/helmet/space/plasmaman/mining))
|
||||
|
||||
/obj/item/stack/sheet/animalhide/goliath_hide/afterattack(atom/target, mob/user, proximity_flag)
|
||||
if(!proximity_flag)
|
||||
return
|
||||
if(is_type_in_typecache(target, goliath_platable_armor_typecache))
|
||||
var/obj/item/clothing/C = target
|
||||
var/list/current_armor = C.armor
|
||||
if(current_armor["melee"] < 60)
|
||||
current_armor["melee"] = min(current_armor["melee"] + 10, 60)
|
||||
to_chat(user, "<span class='info'>You strengthen [target], improving its resistance against melee attacks.</span>")
|
||||
use(1)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't improve [C] any further!</span>")
|
||||
else if(istype(target, /obj/mecha/working/ripley))
|
||||
var/obj/mecha/working/ripley/D = target
|
||||
if(D.hides < 3)
|
||||
D.hides++
|
||||
D.armor["melee"] = min(D.armor["melee"] + 10, 70)
|
||||
D.armor["bullet"] = min(D.armor["bullet"] + 5, 50)
|
||||
D.armor["laser"] = min(D.armor["laser"] + 5, 50)
|
||||
to_chat(user, "<span class='info'>You strengthen [target], improving its resistance against melee attacks.</span>")
|
||||
D.update_icon()
|
||||
if(D.hides == 3)
|
||||
D.desc = "Autonomous Power Loader Unit. It's wearing a fearsome carapace entirely composed of goliath hide plates - its pilot must be an experienced monster hunter."
|
||||
else
|
||||
D.desc = "Autonomous Power Loader Unit. Its armour is enhanced with some goliath hide plates."
|
||||
use(1)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't improve [D] any further!</span>")
|
||||
|
||||
/obj/item/stack/sheet/animalhide/ashdrake
|
||||
name = "ash drake hide"
|
||||
desc = "The strong, scaled hide of an ash drake."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "dragon_hide"
|
||||
singular_name = "drake plate"
|
||||
flags = NOBLUDGEON
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
layer = MOB_LAYER
|
||||
|
||||
//Step one - dehairing.
|
||||
|
||||
/obj/item/stack/sheet/animalhide/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
if(W.sharp)
|
||||
user.visible_message("[user] starts cutting hair off \the [src].", "<span class='notice'>You start cutting the hair off \the [src]...</span>", "<span class='italics'>You hear the sound of a knife rubbing against flesh.</span>")
|
||||
if(do_after(user, 50 * W.toolspeed, target = src))
|
||||
to_chat(user, "<span class='notice'>You cut the hair from this [src.singular_name].</span>")
|
||||
//Try locating an exisitng stack on the tile and add to there if possible
|
||||
for(var/obj/item/stack/sheet/hairlesshide/HS in usr.loc)
|
||||
if(HS.amount < 50)
|
||||
HS.amount++
|
||||
src.use(1)
|
||||
break
|
||||
//If it gets to here it means it did not find a suitable stack on the tile.
|
||||
var/obj/item/stack/sheet/hairlesshide/HS = new(usr.loc)
|
||||
HS.amount = 1
|
||||
src.use(1)
|
||||
else
|
||||
..()
|
||||
|
||||
//Step two - washing (also handled by water reagent code and washing machine code)
|
||||
/obj/item/stack/sheet/hairlesshide/water_act(volume, temperature, source, method = REAGENT_TOUCH)
|
||||
. = ..()
|
||||
if(volume >= 10)
|
||||
new /obj/item/stack/sheet/wetleather(get_turf(src), amount)
|
||||
qdel(src)
|
||||
|
||||
//Step three - drying
|
||||
/obj/item/stack/sheet/wetleather/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
..()
|
||||
if(exposed_temperature >= drying_threshold_temperature)
|
||||
wetness--
|
||||
if(wetness == 0)
|
||||
//Try locating an exisitng stack on the tile and add to there if possible
|
||||
for(var/obj/item/stack/sheet/leather/HS in src.loc)
|
||||
if(HS.amount < 50)
|
||||
HS.amount++
|
||||
src.use(1)
|
||||
wetness = initial(wetness)
|
||||
break
|
||||
//If it gets to here it means it did not find a suitable stack on the tile.
|
||||
var/obj/item/stack/sheet/leather/HS = new(src.loc)
|
||||
HS.amount = 1
|
||||
wetness = initial(wetness)
|
||||
src.use(1)
|
||||
/obj/item/stack/sheet/animalhide
|
||||
name = "hide"
|
||||
desc = "Something went wrong."
|
||||
origin_tech = "biotech=3"
|
||||
|
||||
/obj/item/stack/sheet/animalhide/human
|
||||
name = "human skin"
|
||||
desc = "The by-product of human farming."
|
||||
singular_name = "human skin piece"
|
||||
icon_state = "sheet-hide"
|
||||
|
||||
var/global/list/datum/stack_recipe/human_recipes = list( \
|
||||
new/datum/stack_recipe("bloated human costume", /obj/item/clothing/suit/bloated_human, 5, on_floor = 1), \
|
||||
new/datum/stack_recipe("bloated human costume head", /obj/item/clothing/head/human_head, 5, on_floor = 1), \
|
||||
)
|
||||
|
||||
/obj/item/stack/sheet/animalhide/human/New(var/loc, var/amount=null)
|
||||
recipes = human_recipes
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/sheet/animalhide/generic
|
||||
name = "generic skin"
|
||||
desc = "A piece of generic skin."
|
||||
singular_name = "generic skin piece"
|
||||
icon_state = "sheet-hide"
|
||||
|
||||
/obj/item/stack/sheet/animalhide/corgi
|
||||
name = "corgi hide"
|
||||
desc = "The by-product of corgi farming."
|
||||
singular_name = "corgi hide piece"
|
||||
icon_state = "sheet-corgi"
|
||||
|
||||
/obj/item/stack/sheet/animalhide/cat
|
||||
name = "cat hide"
|
||||
desc = "The by-product of cat farming."
|
||||
singular_name = "cat hide piece"
|
||||
icon_state = "sheet-cat"
|
||||
|
||||
/obj/item/stack/sheet/animalhide/monkey
|
||||
name = "monkey hide"
|
||||
desc = "The by-product of monkey farming."
|
||||
singular_name = "monkey hide piece"
|
||||
icon_state = "sheet-monkey"
|
||||
|
||||
/obj/item/stack/sheet/animalhide/lizard
|
||||
name = "lizard skin"
|
||||
desc = "Sssssss..."
|
||||
singular_name = "lizard skin piece"
|
||||
icon_state = "sheet-lizard"
|
||||
|
||||
/obj/item/stack/sheet/animalhide/xeno
|
||||
name = "alien hide"
|
||||
desc = "The skin of a terrible creature."
|
||||
singular_name = "alien hide piece"
|
||||
icon_state = "sheet-xeno"
|
||||
|
||||
GLOBAL_LIST_INIT(xeno_recipes, list (
|
||||
new/datum/stack_recipe("alien helmet", /obj/item/clothing/head/xenos, 1),
|
||||
new/datum/stack_recipe("alien suit", /obj/item/clothing/suit/xenos, 2)))
|
||||
|
||||
/obj/item/stack/sheet/animalhide/xeno/Initialize(mapload, new_amount, merge = TRUE)
|
||||
recipes = GLOB.xeno_recipes
|
||||
return ..()
|
||||
|
||||
//don't see anywhere else to put these, maybe together they could be used to make the xenos suit?
|
||||
/obj/item/stack/sheet/xenochitin
|
||||
name = "alien chitin"
|
||||
desc = "A piece of the hide of a terrible creature."
|
||||
singular_name = "alien hide piece"
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
icon_state = "chitin"
|
||||
origin_tech = ""
|
||||
|
||||
/obj/item/xenos_claw
|
||||
name = "alien claw"
|
||||
desc = "The claw of a terrible creature."
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
icon_state = "claw"
|
||||
origin_tech = ""
|
||||
|
||||
/obj/item/weed_extract
|
||||
name = "weed extract"
|
||||
desc = "A piece of slimy, purplish weed."
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
icon_state = "weed_extract"
|
||||
origin_tech = ""
|
||||
|
||||
/obj/item/stack/sheet/hairlesshide
|
||||
name = "hairless hide"
|
||||
desc = "This hide was stripped of it's hair, but still needs tanning."
|
||||
singular_name = "hairless hide piece"
|
||||
icon_state = "sheet-hairlesshide"
|
||||
origin_tech = ""
|
||||
|
||||
/obj/item/stack/sheet/wetleather
|
||||
name = "wet leather"
|
||||
desc = "This leather has been cleaned but still needs to be dried."
|
||||
singular_name = "wet leather piece"
|
||||
icon_state = "sheet-wetleather"
|
||||
origin_tech = ""
|
||||
var/wetness = 30 //Reduced when exposed to high temperautres
|
||||
var/drying_threshold_temperature = 500 //Kelvin to start drying
|
||||
|
||||
/obj/item/stack/sheet/leather
|
||||
name = "leather"
|
||||
desc = "The by-product of mob grinding."
|
||||
singular_name = "leather piece"
|
||||
icon_state = "sheet-leather"
|
||||
origin_tech = "materials=2"
|
||||
|
||||
GLOBAL_LIST_INIT(leather_recipes, list (
|
||||
new/datum/stack_recipe("wallet", /obj/item/storage/wallet, 1),
|
||||
new/datum/stack_recipe("muzzle", /obj/item/clothing/mask/muzzle, 2),
|
||||
new/datum/stack_recipe("botany gloves", /obj/item/clothing/gloves/botanic_leather, 3),
|
||||
new/datum/stack_recipe("toolbelt", /obj/item/storage/belt/utility, 4),
|
||||
new/datum/stack_recipe("leather satchel", /obj/item/storage/backpack/satchel, 5),
|
||||
new/datum/stack_recipe("bandolier", /obj/item/storage/belt/bandolier, 5),
|
||||
new/datum/stack_recipe("leather jacket", /obj/item/clothing/suit/jacket/leather, 7),
|
||||
new/datum/stack_recipe("leather shoes", /obj/item/clothing/shoes/laceup, 2),
|
||||
new/datum/stack_recipe("leather overcoat", /obj/item/clothing/suit/jacket/leather/overcoat, 10),
|
||||
new/datum/stack_recipe("hide mantle", /obj/item/clothing/suit/unathi/mantle, 4)))
|
||||
|
||||
/obj/item/stack/sheet/leather/New(loc, new_amount, merge = TRUE)
|
||||
recipes = GLOB.leather_recipes
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/sheet/sinew
|
||||
name = "watcher sinew"
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
desc = "Long stringy filaments which presumably came from a watcher's wings."
|
||||
singular_name = "watcher sinew"
|
||||
icon_state = "sinew"
|
||||
origin_tech = "biotech=4"
|
||||
|
||||
var/global/list/datum/stack_recipe/sinew_recipes = list ( \
|
||||
new/datum/stack_recipe("sinew restraints", /obj/item/restraints/handcuffs/sinew, 1, on_floor = 1), \
|
||||
)
|
||||
|
||||
/obj/item/stack/sheet/sinew/New(var/loc, var/amount=null)
|
||||
recipes = sinew_recipes
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/sheet/animalhide/goliath_hide
|
||||
name = "goliath hide plates"
|
||||
desc = "Pieces of a goliath's rocky hide, these might be able to make your suit a bit more durable to attack from the local fauna."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "goliath_hide"
|
||||
singular_name = "hide plate"
|
||||
flags = NOBLUDGEON
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
layer = MOB_LAYER
|
||||
var/static/list/goliath_platable_armor_typecache = typecacheof(list(
|
||||
/obj/item/clothing/suit/space/hardsuit/mining,
|
||||
/obj/item/clothing/head/helmet/space/hardsuit/mining,
|
||||
/obj/item/clothing/suit/hooded/explorer,
|
||||
/obj/item/clothing/head/hooded/explorer,
|
||||
/obj/item/clothing/head/helmet/space/plasmaman/mining))
|
||||
|
||||
/obj/item/stack/sheet/animalhide/goliath_hide/afterattack(atom/target, mob/user, proximity_flag)
|
||||
if(!proximity_flag)
|
||||
return
|
||||
if(is_type_in_typecache(target, goliath_platable_armor_typecache))
|
||||
var/obj/item/clothing/C = target
|
||||
var/list/current_armor = C.armor
|
||||
if(current_armor["melee"] < 60)
|
||||
current_armor["melee"] = min(current_armor["melee"] + 10, 60)
|
||||
to_chat(user, "<span class='info'>You strengthen [target], improving its resistance against melee attacks.</span>")
|
||||
use(1)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't improve [C] any further!</span>")
|
||||
else if(istype(target, /obj/mecha/working/ripley))
|
||||
var/obj/mecha/working/ripley/D = target
|
||||
if(D.hides < 3)
|
||||
D.hides++
|
||||
D.armor["melee"] = min(D.armor["melee"] + 10, 70)
|
||||
D.armor["bullet"] = min(D.armor["bullet"] + 5, 50)
|
||||
D.armor["laser"] = min(D.armor["laser"] + 5, 50)
|
||||
to_chat(user, "<span class='info'>You strengthen [target], improving its resistance against melee attacks.</span>")
|
||||
D.update_icon()
|
||||
if(D.hides == 3)
|
||||
D.desc = "Autonomous Power Loader Unit. It's wearing a fearsome carapace entirely composed of goliath hide plates - its pilot must be an experienced monster hunter."
|
||||
else
|
||||
D.desc = "Autonomous Power Loader Unit. Its armour is enhanced with some goliath hide plates."
|
||||
use(1)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't improve [D] any further!</span>")
|
||||
|
||||
/obj/item/stack/sheet/animalhide/ashdrake
|
||||
name = "ash drake hide"
|
||||
desc = "The strong, scaled hide of an ash drake."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "dragon_hide"
|
||||
singular_name = "drake plate"
|
||||
flags = NOBLUDGEON
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
layer = MOB_LAYER
|
||||
|
||||
//Step one - dehairing.
|
||||
|
||||
/obj/item/stack/sheet/animalhide/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
if(W.sharp)
|
||||
user.visible_message("[user] starts cutting hair off \the [src].", "<span class='notice'>You start cutting the hair off \the [src]...</span>", "<span class='italics'>You hear the sound of a knife rubbing against flesh.</span>")
|
||||
if(do_after(user, 50 * W.toolspeed, target = src))
|
||||
to_chat(user, "<span class='notice'>You cut the hair from this [src.singular_name].</span>")
|
||||
//Try locating an exisitng stack on the tile and add to there if possible
|
||||
for(var/obj/item/stack/sheet/hairlesshide/HS in usr.loc)
|
||||
if(HS.amount < 50)
|
||||
HS.amount++
|
||||
src.use(1)
|
||||
break
|
||||
//If it gets to here it means it did not find a suitable stack on the tile.
|
||||
var/obj/item/stack/sheet/hairlesshide/HS = new(usr.loc)
|
||||
HS.amount = 1
|
||||
src.use(1)
|
||||
else
|
||||
..()
|
||||
|
||||
//Step two - washing (also handled by water reagent code and washing machine code)
|
||||
/obj/item/stack/sheet/hairlesshide/water_act(volume, temperature, source, method = REAGENT_TOUCH)
|
||||
. = ..()
|
||||
if(volume >= 10)
|
||||
new /obj/item/stack/sheet/wetleather(get_turf(src), amount)
|
||||
qdel(src)
|
||||
|
||||
//Step three - drying
|
||||
/obj/item/stack/sheet/wetleather/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
..()
|
||||
if(exposed_temperature >= drying_threshold_temperature)
|
||||
wetness--
|
||||
if(wetness == 0)
|
||||
//Try locating an exisitng stack on the tile and add to there if possible
|
||||
for(var/obj/item/stack/sheet/leather/HS in src.loc)
|
||||
if(HS.amount < 50)
|
||||
HS.amount++
|
||||
src.use(1)
|
||||
wetness = initial(wetness)
|
||||
break
|
||||
//If it gets to here it means it did not find a suitable stack on the tile.
|
||||
var/obj/item/stack/sheet/leather/HS = new(src.loc)
|
||||
HS.amount = 1
|
||||
wetness = initial(wetness)
|
||||
src.use(1)
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
/obj/item/stack/light_w
|
||||
name = "wired glass tiles"
|
||||
gender = PLURAL
|
||||
singular_name = "wired glass floor tile"
|
||||
desc = "A glass tile, which is wired, somehow."
|
||||
icon = 'icons/obj/tiles.dmi'
|
||||
icon_state = "glass_wire"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
force = 3.0
|
||||
throwforce = 5.0
|
||||
throw_speed = 5
|
||||
throw_range = 20
|
||||
flags = CONDUCT
|
||||
max_amount = 60
|
||||
|
||||
/obj/item/stack/light_w/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
|
||||
..()
|
||||
if(istype(O,/obj/item/wirecutters))
|
||||
var/obj/item/stack/cable_coil/CC = new/obj/item/stack/cable_coil(user.loc)
|
||||
CC.amount = 5
|
||||
amount--
|
||||
new/obj/item/stack/sheet/glass(user.loc)
|
||||
if(amount <= 0)
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
|
||||
if(istype(O,/obj/item/stack/sheet/metal))
|
||||
var/obj/item/stack/sheet/metal/M = O
|
||||
M.amount--
|
||||
if(M.amount <= 0)
|
||||
user.unEquip(src, 1)
|
||||
qdel(M)
|
||||
amount--
|
||||
new/obj/item/stack/tile/light(user.loc)
|
||||
if(amount <= 0)
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
/obj/item/stack/light_w
|
||||
name = "wired glass tiles"
|
||||
gender = PLURAL
|
||||
singular_name = "wired glass floor tile"
|
||||
desc = "A glass tile, which is wired, somehow."
|
||||
icon = 'icons/obj/tiles.dmi'
|
||||
icon_state = "glass_wire"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
force = 3.0
|
||||
throwforce = 5.0
|
||||
throw_speed = 5
|
||||
throw_range = 20
|
||||
flags = CONDUCT
|
||||
max_amount = 60
|
||||
|
||||
/obj/item/stack/light_w/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
|
||||
..()
|
||||
if(istype(O,/obj/item/wirecutters))
|
||||
var/obj/item/stack/cable_coil/CC = new/obj/item/stack/cable_coil(user.loc)
|
||||
CC.amount = 5
|
||||
amount--
|
||||
new/obj/item/stack/sheet/glass(user.loc)
|
||||
if(amount <= 0)
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
|
||||
if(istype(O,/obj/item/stack/sheet/metal))
|
||||
var/obj/item/stack/sheet/metal/M = O
|
||||
M.amount--
|
||||
if(M.amount <= 0)
|
||||
user.unEquip(src, 1)
|
||||
qdel(M)
|
||||
amount--
|
||||
new/obj/item/stack/tile/light(user.loc)
|
||||
if(amount <= 0)
|
||||
user.unEquip(src, 1)
|
||||
qdel(src)
|
||||
|
||||
@@ -1,389 +1,389 @@
|
||||
/*
|
||||
Mineral Sheets
|
||||
Contains:
|
||||
- Sandstone
|
||||
- Diamond
|
||||
- Uranium
|
||||
- Plasma
|
||||
- Gold
|
||||
- Silver
|
||||
- Bananium
|
||||
- Tranqillite
|
||||
- Enriched Uranium
|
||||
- Platinum
|
||||
- Alien Alloy
|
||||
- Adamantine
|
||||
*/
|
||||
|
||||
var/global/list/datum/stack_recipe/sandstone_recipes = list ( \
|
||||
new/datum/stack_recipe("pile of dirt", /obj/machinery/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("sandstone door", /obj/structure/mineral_door/sandstone, 10, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("Assistant Statue", /obj/structure/statue/sandstone/assistant, 5, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("Breakdown into sand", /obj/item/stack/ore/glass, 1, one_per_turf = 0, on_floor = 1), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/silver_recipes = list ( \
|
||||
new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("silver tile", /obj/item/stack/tile/mineral/silver, 1, 4, 20), \
|
||||
null, \
|
||||
new/datum/stack_recipe("Janitor Statue", /obj/structure/statue/silver/janitor, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Sec Officer Statue", /obj/structure/statue/silver/sec, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Sec Borg Statue", /obj/structure/statue/silver/secborg, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Med Doctor Statue", /obj/structure/statue/silver/md, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Med Borg Statue", /obj/structure/statue/silver/medborg, 5, one_per_turf = 1, on_floor = 1), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/diamond_recipes = list ( \
|
||||
new/datum/stack_recipe("diamond door", /obj/structure/mineral_door/transparent/diamond, 10, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("diamond tile", /obj/item/stack/tile/mineral/diamond, 1, 4, 20), \
|
||||
null, \
|
||||
new/datum/stack_recipe("Captain Statue", /obj/structure/statue/diamond/captain, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("AI Hologram Statue", /obj/structure/statue/diamond/ai1, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("AI Core Statue", /obj/structure/statue/diamond/ai2, 5, one_per_turf = 1, on_floor = 1), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/uranium_recipes = list ( \
|
||||
new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("uranium tile", /obj/item/stack/tile/mineral/uranium, 1, 4, 20), \
|
||||
null, \
|
||||
new/datum/stack_recipe("Nuke Statue", /obj/structure/statue/uranium/nuke, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Engineer Statue", /obj/structure/statue/uranium/eng, 5, one_per_turf = 1, on_floor = 1), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/gold_recipes = list ( \
|
||||
new/datum/stack_recipe("golden door", /obj/structure/mineral_door/gold, 10, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("gold tile", /obj/item/stack/tile/mineral/gold, 1, 4, 20), \
|
||||
null, \
|
||||
new/datum/stack_recipe("HoS Statue", /obj/structure/statue/gold/hos, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("HoP Statue", /obj/structure/statue/gold/hop, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("CE Statue", /obj/structure/statue/gold/ce, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("RD Statue", /obj/structure/statue/gold/rd, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("CMO Statue", /obj/structure/statue/gold/cmo, 5, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("Simple Crown", /obj/item/clothing/head/crown, 5), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/plasma_recipes = list ( \
|
||||
new/datum/stack_recipe/dangerous("plasma door", /obj/structure/mineral_door/transparent/plasma, 10, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe/dangerous("plasma tile", /obj/item/stack/tile/mineral/plasma, 1, 4, 20), \
|
||||
null, \
|
||||
new/datum/stack_recipe/dangerous("Scientist Statue", /obj/structure/statue/plasma/scientist, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe/dangerous("Xenomorph Statue", /obj/structure/statue/plasma/xeno, 5, one_per_turf = 1, on_floor = 1), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/bananium_recipes = list ( \
|
||||
new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \
|
||||
null, \
|
||||
new/datum/stack_recipe("Clown Statue", /obj/structure/statue/bananium/clown, 5, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("bananium computer frame", /obj/structure/computerframe/HONKputer, 50, time = 25, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("bananium grenade casing", /obj/item/grenade/bananade/casing, 4, on_floor = 1), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/tranquillite_recipes = list ( \
|
||||
new/datum/stack_recipe("invisible wall", /obj/structure/barricade/mime, 5, one_per_turf = 1, on_floor = 1, time = 50), \
|
||||
null, \
|
||||
new/datum/stack_recipe("silent tile", /obj/item/stack/tile/mineral/tranquillite, 1, 4, 20), \
|
||||
null, \
|
||||
new/datum/stack_recipe("Mime Statue", /obj/structure/statue/tranquillite/mime, 5, one_per_turf = 1, on_floor = 1), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/abductor_recipes = list ( \
|
||||
new/datum/stack_recipe("alien bed", /obj/structure/bed/abductor, 2, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("alien locker", /obj/structure/closet/abductor, 1, time = 15, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("alien table frame", /obj/structure/table_frame/abductor, 1, time = 15, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("alien airlock assembly", /obj/structure/door_assembly/door_assembly_abductor, 4, time = 20, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("alien floor tile", /obj/item/stack/tile/mineral/abductor, 1, 4, 20), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/adamantine_recipes = list(
|
||||
new /datum/stack_recipe("incomplete servant golem shell", /obj/item/golem_shell/servant, req_amount = 1, res_amount = 1), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/snow_recipes = list(
|
||||
new/datum/stack_recipe("snowman", /obj/structure/snowman, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Snowball", /obj/item/snowball, 1)
|
||||
)
|
||||
|
||||
/obj/item/stack/sheet/mineral
|
||||
force = 5
|
||||
throwforce = 5
|
||||
throw_speed = 3
|
||||
|
||||
/obj/item/stack/sheet/mineral/New()
|
||||
..()
|
||||
pixel_x = rand(0,4)-4
|
||||
pixel_y = rand(0,4)-4
|
||||
|
||||
/obj/item/stack/sheet/mineral/sandstone
|
||||
name = "sandstone brick"
|
||||
desc = "This appears to be a combination of both sand and stone."
|
||||
singular_name = "sandstone brick"
|
||||
icon_state = "sheet-sandstone"
|
||||
throw_range = 5
|
||||
origin_tech = "materials=1"
|
||||
sheettype = "sandstone"
|
||||
materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/stack/sheet/mineral/sandstone/New()
|
||||
..()
|
||||
recipes = sandstone_recipes
|
||||
|
||||
/*
|
||||
* Sandbags
|
||||
*/
|
||||
|
||||
/obj/item/stack/sheet/mineral/sandbags
|
||||
name = "sandbags"
|
||||
icon_state = "sandbags"
|
||||
singular_name = "sandbag"
|
||||
layer = LOW_ITEM_LAYER
|
||||
merge_type = /obj/item/stack/sheet/mineral/sandbags
|
||||
|
||||
GLOBAL_LIST_INIT(sandbag_recipes, list ( \
|
||||
new/datum/stack_recipe("sandbags", /obj/structure/barricade/sandbags, 1, time = 25, one_per_turf = 1, on_floor = 1), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/sandbags/New()
|
||||
recipes = GLOB.sandbag_recipes
|
||||
..()
|
||||
|
||||
/obj/item/emptysandbag
|
||||
name = "empty sandbag"
|
||||
desc = "A bag to be filled with sand."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "sandbag"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
/obj/item/emptysandbag/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/stack/ore/glass))
|
||||
var/obj/item/stack/ore/glass/G = I
|
||||
to_chat(user, "<span class='notice'>You fill the sandbag.</span>")
|
||||
var/obj/item/stack/sheet/mineral/sandbags/S = new /obj/item/stack/sheet/mineral/sandbags(drop_location())
|
||||
qdel(src)
|
||||
if(Adjacent(user) && !issilicon(user))
|
||||
user.put_in_hands(S)
|
||||
G.use(1)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/sheet/mineral/diamond
|
||||
name = "diamond"
|
||||
icon_state = "sheet-diamond"
|
||||
singular_name = "diamond"
|
||||
origin_tech = "materials=6"
|
||||
sheettype = "diamond"
|
||||
materials = list(MAT_DIAMOND=MINERAL_MATERIAL_AMOUNT)
|
||||
point_value = 25
|
||||
|
||||
/obj/item/stack/sheet/mineral/diamond/New()
|
||||
..()
|
||||
recipes = diamond_recipes
|
||||
|
||||
/obj/item/stack/sheet/mineral/uranium
|
||||
name = "uranium"
|
||||
icon_state = "sheet-uranium"
|
||||
singular_name = "uranium sheet"
|
||||
origin_tech = "materials=5"
|
||||
sheettype = "uranium"
|
||||
materials = list(MAT_URANIUM=MINERAL_MATERIAL_AMOUNT)
|
||||
point_value = 20
|
||||
|
||||
/obj/item/stack/sheet/mineral/uranium/New()
|
||||
..()
|
||||
recipes = uranium_recipes
|
||||
|
||||
/obj/item/stack/sheet/mineral/plasma
|
||||
name = "solid plasma"
|
||||
icon_state = "sheet-plasma"
|
||||
singular_name = "plasma sheet"
|
||||
origin_tech = "plasmatech=2;materials=2"
|
||||
sheettype = "plasma"
|
||||
materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT)
|
||||
resistance_flags = FLAMMABLE
|
||||
max_integrity = 100
|
||||
point_value = 20
|
||||
|
||||
/obj/item/stack/sheet/mineral/plasma/New()
|
||||
..()
|
||||
recipes = plasma_recipes
|
||||
|
||||
/obj/item/stack/sheet/mineral/plasma/welder_act(mob/user, obj/item/I)
|
||||
if(I.use_tool(src, user, volume = I.tool_volume))
|
||||
message_admins("Plasma sheets ignited by [key_name_admin(user)]([ADMIN_QUE(user,"?")]) ([ADMIN_FLW(user,"FLW")]) in ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
|
||||
log_game("Plasma sheets ignited by [key_name(user)] in ([x],[y],[z])")
|
||||
investigate_log("was <font color='red'><b>ignited</b></font> by [key_name(user)]","atmos")
|
||||
fire_act()
|
||||
|
||||
/obj/item/stack/sheet/mineral/plasma/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE)
|
||||
..()
|
||||
atmos_spawn_air(LINDA_SPAWN_HEAT | LINDA_SPAWN_TOXINS, amount*10)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/stack/sheet/mineral/gold
|
||||
name = "gold"
|
||||
icon_state = "sheet-gold"
|
||||
singular_name = "gold bar"
|
||||
origin_tech = "materials=4"
|
||||
sheettype = "gold"
|
||||
materials = list(MAT_GOLD=MINERAL_MATERIAL_AMOUNT)
|
||||
point_value = 20
|
||||
|
||||
/obj/item/stack/sheet/mineral/gold/New()
|
||||
..()
|
||||
recipes = gold_recipes
|
||||
|
||||
/obj/item/stack/sheet/mineral/silver
|
||||
name = "silver"
|
||||
icon_state = "sheet-silver"
|
||||
singular_name = "silver bar"
|
||||
origin_tech = "materials=4"
|
||||
sheettype = "silver"
|
||||
materials = list(MAT_SILVER=MINERAL_MATERIAL_AMOUNT)
|
||||
point_value = 20
|
||||
|
||||
/obj/item/stack/sheet/mineral/silver/New()
|
||||
..()
|
||||
recipes = silver_recipes
|
||||
|
||||
/obj/item/stack/sheet/mineral/bananium
|
||||
name = "bananium"
|
||||
icon_state = "sheet-clown"
|
||||
singular_name = "bananium sheet"
|
||||
origin_tech = "materials=4"
|
||||
sheettype = "bananium"
|
||||
materials = list(MAT_BANANIUM=MINERAL_MATERIAL_AMOUNT)
|
||||
point_value = 50
|
||||
|
||||
/obj/item/stack/sheet/mineral/bananium/New(loc, amount=null)
|
||||
..()
|
||||
recipes = bananium_recipes
|
||||
|
||||
/obj/item/stack/sheet/mineral/tranquillite
|
||||
name = "tranquillite"
|
||||
icon_state = "sheet-mime"
|
||||
singular_name = "beret"
|
||||
origin_tech = "materials=4"
|
||||
sheettype = "tranquillite"
|
||||
materials = list(MAT_TRANQUILLITE=MINERAL_MATERIAL_AMOUNT)
|
||||
wall_allowed = FALSE //no tranquilite walls in code
|
||||
point_value = 50
|
||||
|
||||
/obj/item/stack/sheet/mineral/tranquillite/New(loc, amount=null)
|
||||
..()
|
||||
recipes = tranquillite_recipes
|
||||
|
||||
/*
|
||||
* Titanium
|
||||
*/
|
||||
/obj/item/stack/sheet/mineral/titanium
|
||||
name = "titanium"
|
||||
icon_state = "sheet-titanium"
|
||||
item_state = "sheet-metal"
|
||||
singular_name = "titanium sheet"
|
||||
force = 5
|
||||
throwforce = 5
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
throw_speed = 1
|
||||
throw_range = 3
|
||||
sheettype = "titanium"
|
||||
materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT)
|
||||
point_value = 20
|
||||
|
||||
var/global/list/datum/stack_recipe/titanium_recipes = list (
|
||||
new/datum/stack_recipe("titanium tile", /obj/item/stack/tile/mineral/titanium, 1, 4, 20),
|
||||
new/datum/stack_recipe("surgical tray", /obj/structure/table/tray, 2, one_per_turf = 1, on_floor = 1),
|
||||
)
|
||||
|
||||
/obj/item/stack/sheet/mineral/titanium/New(loc, amount=null)
|
||||
recipes = titanium_recipes
|
||||
..()
|
||||
|
||||
/obj/item/stack/sheet/mineral/titanium/fifty
|
||||
amount = 50
|
||||
|
||||
|
||||
/*
|
||||
* Plastitanium
|
||||
*/
|
||||
/obj/item/stack/sheet/mineral/plastitanium
|
||||
name = "plastitanium"
|
||||
icon_state = "sheet-plastitanium"
|
||||
item_state = "sheet-metal"
|
||||
singular_name = "plastitanium sheet"
|
||||
force = 5
|
||||
throwforce = 5
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
throw_speed = 1
|
||||
throw_range = 3
|
||||
sheettype = "plastitanium"
|
||||
materials = list(MAT_TITANIUM=2000, MAT_PLASMA=2000)
|
||||
point_value = 45
|
||||
|
||||
var/global/list/datum/stack_recipe/plastitanium_recipes = list (
|
||||
new/datum/stack_recipe("plas-titanium tile", /obj/item/stack/tile/mineral/plastitanium, 1, 4, 20),
|
||||
)
|
||||
|
||||
/obj/item/stack/sheet/mineral/plastitanium/New(loc, amount=null)
|
||||
recipes = plastitanium_recipes
|
||||
..()
|
||||
|
||||
/obj/item/stack/sheet/mineral/enruranium
|
||||
name = "enriched uranium"
|
||||
icon_state = "sheet-enruranium"
|
||||
origin_tech = "materials=6"
|
||||
materials = list(MAT_URANIUM=3000)
|
||||
|
||||
//Alien Alloy
|
||||
/obj/item/stack/sheet/mineral/abductor
|
||||
name = "alien alloy"
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "sheet-abductor"
|
||||
singular_name = "alien alloy sheet"
|
||||
force = 5
|
||||
throwforce = 5
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
throw_speed = 1
|
||||
origin_tech = "materials=6;abductor=1"
|
||||
sheettype = "abductor"
|
||||
|
||||
/obj/item/stack/sheet/mineral/abductor/New(loc, amount=null)
|
||||
recipes = abductor_recipes
|
||||
..()
|
||||
|
||||
/obj/item/stack/sheet/mineral/adamantine
|
||||
name = "adamantine"
|
||||
desc = "A strange mineral used in the construction of sentient golems."
|
||||
icon_state = "sheet-adamantine"
|
||||
singular_name = "adamantine sheet"
|
||||
origin_tech = "materials=5"
|
||||
merge_type = /obj/item/stack/sheet/mineral/adamantine
|
||||
wall_allowed = FALSE
|
||||
|
||||
/obj/item/stack/sheet/mineral/adamantine/New(loc, amount = null)
|
||||
recipes = adamantine_recipes
|
||||
..()
|
||||
|
||||
/*
|
||||
* Snow
|
||||
*/
|
||||
/obj/item/stack/sheet/mineral/snow
|
||||
name = "snow"
|
||||
icon_state = "sheet-snow"
|
||||
item_state = "sheet-snow"
|
||||
singular_name = "snow block"
|
||||
force = 1
|
||||
throwforce = 2
|
||||
merge_type = /obj/item/stack/sheet/mineral/snow
|
||||
|
||||
/obj/item/stack/sheet/mineral/snow/New(loc, amount = null)
|
||||
recipes = snow_recipes
|
||||
..()
|
||||
/*
|
||||
Mineral Sheets
|
||||
Contains:
|
||||
- Sandstone
|
||||
- Diamond
|
||||
- Uranium
|
||||
- Plasma
|
||||
- Gold
|
||||
- Silver
|
||||
- Bananium
|
||||
- Tranqillite
|
||||
- Enriched Uranium
|
||||
- Platinum
|
||||
- Alien Alloy
|
||||
- Adamantine
|
||||
*/
|
||||
|
||||
var/global/list/datum/stack_recipe/sandstone_recipes = list ( \
|
||||
new/datum/stack_recipe("pile of dirt", /obj/machinery/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("sandstone door", /obj/structure/mineral_door/sandstone, 10, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("Assistant Statue", /obj/structure/statue/sandstone/assistant, 5, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("Breakdown into sand", /obj/item/stack/ore/glass, 1, one_per_turf = 0, on_floor = 1), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/silver_recipes = list ( \
|
||||
new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("silver tile", /obj/item/stack/tile/mineral/silver, 1, 4, 20), \
|
||||
null, \
|
||||
new/datum/stack_recipe("Janitor Statue", /obj/structure/statue/silver/janitor, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Sec Officer Statue", /obj/structure/statue/silver/sec, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Sec Borg Statue", /obj/structure/statue/silver/secborg, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Med Doctor Statue", /obj/structure/statue/silver/md, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Med Borg Statue", /obj/structure/statue/silver/medborg, 5, one_per_turf = 1, on_floor = 1), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/diamond_recipes = list ( \
|
||||
new/datum/stack_recipe("diamond door", /obj/structure/mineral_door/transparent/diamond, 10, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("diamond tile", /obj/item/stack/tile/mineral/diamond, 1, 4, 20), \
|
||||
null, \
|
||||
new/datum/stack_recipe("Captain Statue", /obj/structure/statue/diamond/captain, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("AI Hologram Statue", /obj/structure/statue/diamond/ai1, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("AI Core Statue", /obj/structure/statue/diamond/ai2, 5, one_per_turf = 1, on_floor = 1), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/uranium_recipes = list ( \
|
||||
new/datum/stack_recipe("uranium door", /obj/structure/mineral_door/uranium, 10, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("uranium tile", /obj/item/stack/tile/mineral/uranium, 1, 4, 20), \
|
||||
null, \
|
||||
new/datum/stack_recipe("Nuke Statue", /obj/structure/statue/uranium/nuke, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Engineer Statue", /obj/structure/statue/uranium/eng, 5, one_per_turf = 1, on_floor = 1), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/gold_recipes = list ( \
|
||||
new/datum/stack_recipe("golden door", /obj/structure/mineral_door/gold, 10, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("gold tile", /obj/item/stack/tile/mineral/gold, 1, 4, 20), \
|
||||
null, \
|
||||
new/datum/stack_recipe("HoS Statue", /obj/structure/statue/gold/hos, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("HoP Statue", /obj/structure/statue/gold/hop, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("CE Statue", /obj/structure/statue/gold/ce, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("RD Statue", /obj/structure/statue/gold/rd, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("CMO Statue", /obj/structure/statue/gold/cmo, 5, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("Simple Crown", /obj/item/clothing/head/crown, 5), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/plasma_recipes = list ( \
|
||||
new/datum/stack_recipe/dangerous("plasma door", /obj/structure/mineral_door/transparent/plasma, 10, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe/dangerous("plasma tile", /obj/item/stack/tile/mineral/plasma, 1, 4, 20), \
|
||||
null, \
|
||||
new/datum/stack_recipe/dangerous("Scientist Statue", /obj/structure/statue/plasma/scientist, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe/dangerous("Xenomorph Statue", /obj/structure/statue/plasma/xeno, 5, one_per_turf = 1, on_floor = 1), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/bananium_recipes = list ( \
|
||||
new/datum/stack_recipe("bananium tile", /obj/item/stack/tile/mineral/bananium, 1, 4, 20), \
|
||||
null, \
|
||||
new/datum/stack_recipe("Clown Statue", /obj/structure/statue/bananium/clown, 5, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("bananium computer frame", /obj/structure/computerframe/HONKputer, 50, time = 25, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("bananium grenade casing", /obj/item/grenade/bananade/casing, 4, on_floor = 1), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/tranquillite_recipes = list ( \
|
||||
new/datum/stack_recipe("invisible wall", /obj/structure/barricade/mime, 5, one_per_turf = 1, on_floor = 1, time = 50), \
|
||||
null, \
|
||||
new/datum/stack_recipe("silent tile", /obj/item/stack/tile/mineral/tranquillite, 1, 4, 20), \
|
||||
null, \
|
||||
new/datum/stack_recipe("Mime Statue", /obj/structure/statue/tranquillite/mime, 5, one_per_turf = 1, on_floor = 1), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/abductor_recipes = list ( \
|
||||
new/datum/stack_recipe("alien bed", /obj/structure/bed/abductor, 2, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("alien locker", /obj/structure/closet/abductor, 1, time = 15, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("alien table frame", /obj/structure/table_frame/abductor, 1, time = 15, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("alien airlock assembly", /obj/structure/door_assembly/door_assembly_abductor, 4, time = 20, one_per_turf = 1, on_floor = 1), \
|
||||
null, \
|
||||
new/datum/stack_recipe("alien floor tile", /obj/item/stack/tile/mineral/abductor, 1, 4, 20), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/adamantine_recipes = list(
|
||||
new /datum/stack_recipe("incomplete servant golem shell", /obj/item/golem_shell/servant, req_amount = 1, res_amount = 1), \
|
||||
)
|
||||
|
||||
var/global/list/datum/stack_recipe/snow_recipes = list(
|
||||
new/datum/stack_recipe("snowman", /obj/structure/snowman, 5, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("Snowball", /obj/item/snowball, 1)
|
||||
)
|
||||
|
||||
/obj/item/stack/sheet/mineral
|
||||
force = 5
|
||||
throwforce = 5
|
||||
throw_speed = 3
|
||||
|
||||
/obj/item/stack/sheet/mineral/New()
|
||||
..()
|
||||
pixel_x = rand(0,4)-4
|
||||
pixel_y = rand(0,4)-4
|
||||
|
||||
/obj/item/stack/sheet/mineral/sandstone
|
||||
name = "sandstone brick"
|
||||
desc = "This appears to be a combination of both sand and stone."
|
||||
singular_name = "sandstone brick"
|
||||
icon_state = "sheet-sandstone"
|
||||
throw_range = 5
|
||||
origin_tech = "materials=1"
|
||||
sheettype = "sandstone"
|
||||
materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
|
||||
|
||||
/obj/item/stack/sheet/mineral/sandstone/New()
|
||||
..()
|
||||
recipes = sandstone_recipes
|
||||
|
||||
/*
|
||||
* Sandbags
|
||||
*/
|
||||
|
||||
/obj/item/stack/sheet/mineral/sandbags
|
||||
name = "sandbags"
|
||||
icon_state = "sandbags"
|
||||
singular_name = "sandbag"
|
||||
layer = LOW_ITEM_LAYER
|
||||
merge_type = /obj/item/stack/sheet/mineral/sandbags
|
||||
|
||||
GLOBAL_LIST_INIT(sandbag_recipes, list ( \
|
||||
new/datum/stack_recipe("sandbags", /obj/structure/barricade/sandbags, 1, time = 25, one_per_turf = 1, on_floor = 1), \
|
||||
))
|
||||
|
||||
/obj/item/stack/sheet/mineral/sandbags/New()
|
||||
recipes = GLOB.sandbag_recipes
|
||||
..()
|
||||
|
||||
/obj/item/emptysandbag
|
||||
name = "empty sandbag"
|
||||
desc = "A bag to be filled with sand."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "sandbag"
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
|
||||
/obj/item/emptysandbag/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/stack/ore/glass))
|
||||
var/obj/item/stack/ore/glass/G = I
|
||||
to_chat(user, "<span class='notice'>You fill the sandbag.</span>")
|
||||
var/obj/item/stack/sheet/mineral/sandbags/S = new /obj/item/stack/sheet/mineral/sandbags(drop_location())
|
||||
qdel(src)
|
||||
if(Adjacent(user) && !issilicon(user))
|
||||
user.put_in_hands(S)
|
||||
G.use(1)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/stack/sheet/mineral/diamond
|
||||
name = "diamond"
|
||||
icon_state = "sheet-diamond"
|
||||
singular_name = "diamond"
|
||||
origin_tech = "materials=6"
|
||||
sheettype = "diamond"
|
||||
materials = list(MAT_DIAMOND=MINERAL_MATERIAL_AMOUNT)
|
||||
point_value = 25
|
||||
|
||||
/obj/item/stack/sheet/mineral/diamond/New()
|
||||
..()
|
||||
recipes = diamond_recipes
|
||||
|
||||
/obj/item/stack/sheet/mineral/uranium
|
||||
name = "uranium"
|
||||
icon_state = "sheet-uranium"
|
||||
singular_name = "uranium sheet"
|
||||
origin_tech = "materials=5"
|
||||
sheettype = "uranium"
|
||||
materials = list(MAT_URANIUM=MINERAL_MATERIAL_AMOUNT)
|
||||
point_value = 20
|
||||
|
||||
/obj/item/stack/sheet/mineral/uranium/New()
|
||||
..()
|
||||
recipes = uranium_recipes
|
||||
|
||||
/obj/item/stack/sheet/mineral/plasma
|
||||
name = "solid plasma"
|
||||
icon_state = "sheet-plasma"
|
||||
singular_name = "plasma sheet"
|
||||
origin_tech = "plasmatech=2;materials=2"
|
||||
sheettype = "plasma"
|
||||
materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT)
|
||||
resistance_flags = FLAMMABLE
|
||||
max_integrity = 100
|
||||
point_value = 20
|
||||
|
||||
/obj/item/stack/sheet/mineral/plasma/New()
|
||||
..()
|
||||
recipes = plasma_recipes
|
||||
|
||||
/obj/item/stack/sheet/mineral/plasma/welder_act(mob/user, obj/item/I)
|
||||
if(I.use_tool(src, user, volume = I.tool_volume))
|
||||
message_admins("Plasma sheets ignited by [key_name_admin(user)]([ADMIN_QUE(user,"?")]) ([ADMIN_FLW(user,"FLW")]) in ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
|
||||
log_game("Plasma sheets ignited by [key_name(user)] in ([x],[y],[z])")
|
||||
investigate_log("was <font color='red'><b>ignited</b></font> by [key_name(user)]","atmos")
|
||||
fire_act()
|
||||
|
||||
/obj/item/stack/sheet/mineral/plasma/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE)
|
||||
..()
|
||||
atmos_spawn_air(LINDA_SPAWN_HEAT | LINDA_SPAWN_TOXINS, amount*10)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/stack/sheet/mineral/gold
|
||||
name = "gold"
|
||||
icon_state = "sheet-gold"
|
||||
singular_name = "gold bar"
|
||||
origin_tech = "materials=4"
|
||||
sheettype = "gold"
|
||||
materials = list(MAT_GOLD=MINERAL_MATERIAL_AMOUNT)
|
||||
point_value = 20
|
||||
|
||||
/obj/item/stack/sheet/mineral/gold/New()
|
||||
..()
|
||||
recipes = gold_recipes
|
||||
|
||||
/obj/item/stack/sheet/mineral/silver
|
||||
name = "silver"
|
||||
icon_state = "sheet-silver"
|
||||
singular_name = "silver bar"
|
||||
origin_tech = "materials=4"
|
||||
sheettype = "silver"
|
||||
materials = list(MAT_SILVER=MINERAL_MATERIAL_AMOUNT)
|
||||
point_value = 20
|
||||
|
||||
/obj/item/stack/sheet/mineral/silver/New()
|
||||
..()
|
||||
recipes = silver_recipes
|
||||
|
||||
/obj/item/stack/sheet/mineral/bananium
|
||||
name = "bananium"
|
||||
icon_state = "sheet-clown"
|
||||
singular_name = "bananium sheet"
|
||||
origin_tech = "materials=4"
|
||||
sheettype = "bananium"
|
||||
materials = list(MAT_BANANIUM=MINERAL_MATERIAL_AMOUNT)
|
||||
point_value = 50
|
||||
|
||||
/obj/item/stack/sheet/mineral/bananium/New(loc, amount=null)
|
||||
..()
|
||||
recipes = bananium_recipes
|
||||
|
||||
/obj/item/stack/sheet/mineral/tranquillite
|
||||
name = "tranquillite"
|
||||
icon_state = "sheet-mime"
|
||||
singular_name = "beret"
|
||||
origin_tech = "materials=4"
|
||||
sheettype = "tranquillite"
|
||||
materials = list(MAT_TRANQUILLITE=MINERAL_MATERIAL_AMOUNT)
|
||||
wall_allowed = FALSE //no tranquilite walls in code
|
||||
point_value = 50
|
||||
|
||||
/obj/item/stack/sheet/mineral/tranquillite/New(loc, amount=null)
|
||||
..()
|
||||
recipes = tranquillite_recipes
|
||||
|
||||
/*
|
||||
* Titanium
|
||||
*/
|
||||
/obj/item/stack/sheet/mineral/titanium
|
||||
name = "titanium"
|
||||
icon_state = "sheet-titanium"
|
||||
item_state = "sheet-metal"
|
||||
singular_name = "titanium sheet"
|
||||
force = 5
|
||||
throwforce = 5
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
throw_speed = 1
|
||||
throw_range = 3
|
||||
sheettype = "titanium"
|
||||
materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT)
|
||||
point_value = 20
|
||||
|
||||
var/global/list/datum/stack_recipe/titanium_recipes = list (
|
||||
new/datum/stack_recipe("titanium tile", /obj/item/stack/tile/mineral/titanium, 1, 4, 20),
|
||||
new/datum/stack_recipe("surgical tray", /obj/structure/table/tray, 2, one_per_turf = 1, on_floor = 1),
|
||||
)
|
||||
|
||||
/obj/item/stack/sheet/mineral/titanium/New(loc, amount=null)
|
||||
recipes = titanium_recipes
|
||||
..()
|
||||
|
||||
/obj/item/stack/sheet/mineral/titanium/fifty
|
||||
amount = 50
|
||||
|
||||
|
||||
/*
|
||||
* Plastitanium
|
||||
*/
|
||||
/obj/item/stack/sheet/mineral/plastitanium
|
||||
name = "plastitanium"
|
||||
icon_state = "sheet-plastitanium"
|
||||
item_state = "sheet-metal"
|
||||
singular_name = "plastitanium sheet"
|
||||
force = 5
|
||||
throwforce = 5
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
throw_speed = 1
|
||||
throw_range = 3
|
||||
sheettype = "plastitanium"
|
||||
materials = list(MAT_TITANIUM=2000, MAT_PLASMA=2000)
|
||||
point_value = 45
|
||||
|
||||
var/global/list/datum/stack_recipe/plastitanium_recipes = list (
|
||||
new/datum/stack_recipe("plas-titanium tile", /obj/item/stack/tile/mineral/plastitanium, 1, 4, 20),
|
||||
)
|
||||
|
||||
/obj/item/stack/sheet/mineral/plastitanium/New(loc, amount=null)
|
||||
recipes = plastitanium_recipes
|
||||
..()
|
||||
|
||||
/obj/item/stack/sheet/mineral/enruranium
|
||||
name = "enriched uranium"
|
||||
icon_state = "sheet-enruranium"
|
||||
origin_tech = "materials=6"
|
||||
materials = list(MAT_URANIUM=3000)
|
||||
|
||||
//Alien Alloy
|
||||
/obj/item/stack/sheet/mineral/abductor
|
||||
name = "alien alloy"
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "sheet-abductor"
|
||||
singular_name = "alien alloy sheet"
|
||||
force = 5
|
||||
throwforce = 5
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
throw_speed = 1
|
||||
origin_tech = "materials=6;abductor=1"
|
||||
sheettype = "abductor"
|
||||
|
||||
/obj/item/stack/sheet/mineral/abductor/New(loc, amount=null)
|
||||
recipes = abductor_recipes
|
||||
..()
|
||||
|
||||
/obj/item/stack/sheet/mineral/adamantine
|
||||
name = "adamantine"
|
||||
desc = "A strange mineral used in the construction of sentient golems."
|
||||
icon_state = "sheet-adamantine"
|
||||
singular_name = "adamantine sheet"
|
||||
origin_tech = "materials=5"
|
||||
merge_type = /obj/item/stack/sheet/mineral/adamantine
|
||||
wall_allowed = FALSE
|
||||
|
||||
/obj/item/stack/sheet/mineral/adamantine/New(loc, amount = null)
|
||||
recipes = adamantine_recipes
|
||||
..()
|
||||
|
||||
/*
|
||||
* Snow
|
||||
*/
|
||||
/obj/item/stack/sheet/mineral/snow
|
||||
name = "snow"
|
||||
icon_state = "sheet-snow"
|
||||
item_state = "sheet-snow"
|
||||
singular_name = "snow block"
|
||||
force = 1
|
||||
throwforce = 2
|
||||
merge_type = /obj/item/stack/sheet/mineral/snow
|
||||
|
||||
/obj/item/stack/sheet/mineral/snow/New(loc, amount = null)
|
||||
recipes = snow_recipes
|
||||
..()
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/obj/item/stack/sheet
|
||||
name = "sheet"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
force = 5
|
||||
throwforce = 5
|
||||
max_amount = 50
|
||||
throw_speed = 1
|
||||
throw_range = 3
|
||||
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed")
|
||||
var/perunit = MINERAL_MATERIAL_AMOUNT
|
||||
var/sheettype = null //this is used for girders in the creation of walls/false walls
|
||||
var/point_value = 0 //turn-in value for the gulag stacker - loosely relative to its rarity.
|
||||
|
||||
var/created_window = null //apparently glass sheets don't share a base type for glass specifically, so each had to define these vars individually
|
||||
var/full_window = null //moving the var declaration to here so this can be checked cleaner until someone is willing to make them share a base type properly
|
||||
usesound = 'sound/items/deconstruct.ogg'
|
||||
toolspeed = 1
|
||||
var/wall_allowed = TRUE //determines if sheet can be used in wall construction or not.
|
||||
/obj/item/stack/sheet
|
||||
name = "sheet"
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
force = 5
|
||||
throwforce = 5
|
||||
max_amount = 50
|
||||
throw_speed = 1
|
||||
throw_range = 3
|
||||
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed")
|
||||
var/perunit = MINERAL_MATERIAL_AMOUNT
|
||||
var/sheettype = null //this is used for girders in the creation of walls/false walls
|
||||
var/point_value = 0 //turn-in value for the gulag stacker - loosely relative to its rarity.
|
||||
|
||||
var/created_window = null //apparently glass sheets don't share a base type for glass specifically, so each had to define these vars individually
|
||||
var/full_window = null //moving the var declaration to here so this can be checked cleaner until someone is willing to make them share a base type properly
|
||||
usesound = 'sound/items/deconstruct.ogg'
|
||||
toolspeed = 1
|
||||
var/wall_allowed = TRUE //determines if sheet can be used in wall construction or not.
|
||||
|
||||
+1783
-1783
File diff suppressed because it is too large
Load Diff
+107
-107
@@ -1,107 +1,107 @@
|
||||
//Items labled as 'trash' for the trash bag.
|
||||
//TODO: Make this an item var or something...
|
||||
|
||||
//Added by Jack Rost
|
||||
/obj/item/trash
|
||||
icon = 'icons/obj/trash.dmi'
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
desc = "This is rubbish."
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/trash/raisins
|
||||
name = "4no raisins"
|
||||
icon_state= "4no_raisins"
|
||||
|
||||
/obj/item/trash/candy
|
||||
name = "Candy"
|
||||
icon_state= "candy"
|
||||
|
||||
/obj/item/trash/cheesie
|
||||
name = "Cheesie honkers"
|
||||
icon_state = "cheesie_honkers"
|
||||
|
||||
/obj/item/trash/chips
|
||||
name = "Chips"
|
||||
icon_state = "chips"
|
||||
|
||||
/obj/item/trash/popcorn
|
||||
name = "Popcorn"
|
||||
icon_state = "popcorn"
|
||||
|
||||
/obj/item/trash/sosjerky
|
||||
name = "Scaredy's Private Reserve Beef Jerky"
|
||||
icon_state = "sosjerky"
|
||||
|
||||
/obj/item/trash/syndi_cakes
|
||||
name = "Syndi cakes"
|
||||
icon_state = "syndi_cakes"
|
||||
|
||||
/obj/item/trash/waffles
|
||||
name = "Waffles"
|
||||
icon_state = "waffles"
|
||||
|
||||
/obj/item/trash/plate
|
||||
name = "Plate"
|
||||
icon_state = "plate"
|
||||
resistance_flags = NONE
|
||||
|
||||
/obj/item/trash/snack_bowl
|
||||
name = "Snack bowl"
|
||||
icon_state = "snack_bowl"
|
||||
|
||||
/obj/item/trash/fried_vox
|
||||
name = "Kentucky Fried Vox"
|
||||
icon_state = "fried_vox_empty"
|
||||
|
||||
/obj/item/trash/pistachios
|
||||
name = "Pistachios pack"
|
||||
icon_state = "pistachios_pack"
|
||||
|
||||
/obj/item/trash/semki
|
||||
name = "Semki pack"
|
||||
icon_state = "semki_pack"
|
||||
|
||||
/obj/item/trash/tray
|
||||
name = "Tray"
|
||||
icon_state = "tray"
|
||||
resistance_flags = NONE
|
||||
|
||||
/obj/item/trash/candle
|
||||
name = "candle"
|
||||
icon = 'icons/obj/candle.dmi'
|
||||
icon_state = "candle4"
|
||||
|
||||
/obj/item/trash/liquidfood
|
||||
name = "\improper \"LiquidFood\" ration"
|
||||
icon_state = "liquidfood"
|
||||
|
||||
/obj/item/trash/can
|
||||
name = "crushed can"
|
||||
icon_state = "cola"
|
||||
var/is_glass = 0
|
||||
var/is_plastic = 0
|
||||
resistance_flags = NONE
|
||||
|
||||
/obj/item/trash/gum
|
||||
name = "chewed gum"
|
||||
desc = "NOT free candy."
|
||||
icon_state = "gum"
|
||||
|
||||
/obj/item/trash/tastybread
|
||||
name = "bread tube"
|
||||
icon_state = "tastybread"
|
||||
|
||||
/obj/item/trash/spentcasing
|
||||
icon = 'icons/obj/ammo.dmi'
|
||||
name = "bullet casing"
|
||||
desc = "A spent bullet casing. Smells like cordite."
|
||||
icon_state = "gshell"
|
||||
|
||||
/obj/item/trash/tapetrash
|
||||
name = "old duct tape"
|
||||
icon_state = "tape"
|
||||
desc = "Not sticky anymore."
|
||||
throw_range = 1
|
||||
|
||||
/obj/item/trash/attack(mob/M as mob, mob/living/user as mob)
|
||||
return
|
||||
//Items labled as 'trash' for the trash bag.
|
||||
//TODO: Make this an item var or something...
|
||||
|
||||
//Added by Jack Rost
|
||||
/obj/item/trash
|
||||
icon = 'icons/obj/trash.dmi'
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
desc = "This is rubbish."
|
||||
resistance_flags = FLAMMABLE
|
||||
|
||||
/obj/item/trash/raisins
|
||||
name = "4no raisins"
|
||||
icon_state= "4no_raisins"
|
||||
|
||||
/obj/item/trash/candy
|
||||
name = "Candy"
|
||||
icon_state= "candy"
|
||||
|
||||
/obj/item/trash/cheesie
|
||||
name = "Cheesie honkers"
|
||||
icon_state = "cheesie_honkers"
|
||||
|
||||
/obj/item/trash/chips
|
||||
name = "Chips"
|
||||
icon_state = "chips"
|
||||
|
||||
/obj/item/trash/popcorn
|
||||
name = "Popcorn"
|
||||
icon_state = "popcorn"
|
||||
|
||||
/obj/item/trash/sosjerky
|
||||
name = "Scaredy's Private Reserve Beef Jerky"
|
||||
icon_state = "sosjerky"
|
||||
|
||||
/obj/item/trash/syndi_cakes
|
||||
name = "Syndi cakes"
|
||||
icon_state = "syndi_cakes"
|
||||
|
||||
/obj/item/trash/waffles
|
||||
name = "Waffles"
|
||||
icon_state = "waffles"
|
||||
|
||||
/obj/item/trash/plate
|
||||
name = "Plate"
|
||||
icon_state = "plate"
|
||||
resistance_flags = NONE
|
||||
|
||||
/obj/item/trash/snack_bowl
|
||||
name = "Snack bowl"
|
||||
icon_state = "snack_bowl"
|
||||
|
||||
/obj/item/trash/fried_vox
|
||||
name = "Kentucky Fried Vox"
|
||||
icon_state = "fried_vox_empty"
|
||||
|
||||
/obj/item/trash/pistachios
|
||||
name = "Pistachios pack"
|
||||
icon_state = "pistachios_pack"
|
||||
|
||||
/obj/item/trash/semki
|
||||
name = "Semki pack"
|
||||
icon_state = "semki_pack"
|
||||
|
||||
/obj/item/trash/tray
|
||||
name = "Tray"
|
||||
icon_state = "tray"
|
||||
resistance_flags = NONE
|
||||
|
||||
/obj/item/trash/candle
|
||||
name = "candle"
|
||||
icon = 'icons/obj/candle.dmi'
|
||||
icon_state = "candle4"
|
||||
|
||||
/obj/item/trash/liquidfood
|
||||
name = "\improper \"LiquidFood\" ration"
|
||||
icon_state = "liquidfood"
|
||||
|
||||
/obj/item/trash/can
|
||||
name = "crushed can"
|
||||
icon_state = "cola"
|
||||
var/is_glass = 0
|
||||
var/is_plastic = 0
|
||||
resistance_flags = NONE
|
||||
|
||||
/obj/item/trash/gum
|
||||
name = "chewed gum"
|
||||
desc = "NOT free candy."
|
||||
icon_state = "gum"
|
||||
|
||||
/obj/item/trash/tastybread
|
||||
name = "bread tube"
|
||||
icon_state = "tastybread"
|
||||
|
||||
/obj/item/trash/spentcasing
|
||||
icon = 'icons/obj/ammo.dmi'
|
||||
name = "bullet casing"
|
||||
desc = "A spent bullet casing. Smells like cordite."
|
||||
icon_state = "gshell"
|
||||
|
||||
/obj/item/trash/tapetrash
|
||||
name = "old duct tape"
|
||||
icon_state = "tape"
|
||||
desc = "Not sticky anymore."
|
||||
throw_range = 1
|
||||
|
||||
/obj/item/trash/attack(mob/M as mob, mob/living/user as mob)
|
||||
return
|
||||
|
||||
@@ -1,392 +1,392 @@
|
||||
/*
|
||||
CONTAINS:
|
||||
AI MODULES
|
||||
|
||||
*/
|
||||
|
||||
// AI module
|
||||
|
||||
/obj/item/aiModule
|
||||
name = "AI Module"
|
||||
icon = 'icons/obj/module.dmi'
|
||||
icon_state = "std_mod"
|
||||
item_state = "electronic"
|
||||
desc = "An AI Module for transmitting encrypted instructions to the AI."
|
||||
flags = CONDUCT
|
||||
force = 5.0
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
throwforce = 5.0
|
||||
throw_speed = 3
|
||||
throw_range = 15
|
||||
origin_tech = "programming=3"
|
||||
materials = list(MAT_GOLD=50)
|
||||
var/datum/ai_laws/laws = null
|
||||
|
||||
/obj/item/aiModule/proc/install(var/obj/machinery/computer/C)
|
||||
if(istype(C, /obj/machinery/computer/aiupload))
|
||||
var/obj/machinery/computer/aiupload/comp = C
|
||||
if(comp.stat & NOPOWER)
|
||||
to_chat(usr, "<span class='warning'>The upload computer has no power!</span>")
|
||||
return
|
||||
if(comp.stat & BROKEN)
|
||||
to_chat(usr, "<span class='warning'>The upload computer is broken!</span>")
|
||||
return
|
||||
if(!comp.current)
|
||||
to_chat(usr, "<span class='warning'>You haven't selected an AI to transmit laws to!</span>")
|
||||
return
|
||||
|
||||
if(comp.current.stat == DEAD || comp.current.control_disabled == 1)
|
||||
to_chat(usr, "<span class='warning'>Upload failed. No signal is being detected from the AI.</span>")
|
||||
else if(comp.current.see_in_dark == 0)
|
||||
to_chat(usr, "<span class='warning'>Upload failed. Only a faint signal is being detected from the AI, and it is not responding to our requests. It may be low on power.</span>")
|
||||
else
|
||||
src.transmitInstructions(comp.current, usr)
|
||||
to_chat(comp.current, "These are your laws now:")
|
||||
comp.current.show_laws()
|
||||
for(var/mob/living/silicon/robot/R in GLOB.mob_list)
|
||||
if(R.lawupdate && (R.connected_ai == comp.current))
|
||||
to_chat(R, "These are your laws now:")
|
||||
R.show_laws()
|
||||
to_chat(usr, "<span class='notice'>Upload complete. The AI's laws have been modified.</span>")
|
||||
|
||||
else if(istype(C, /obj/machinery/computer/borgupload))
|
||||
var/obj/machinery/computer/borgupload/comp = C
|
||||
if(comp.stat & NOPOWER)
|
||||
to_chat(usr, "<span class='warning'>The upload computer has no power!</span>")
|
||||
return
|
||||
if(comp.stat & BROKEN)
|
||||
to_chat(usr, "<span class='warning'>The upload computer is broken!</span>")
|
||||
return
|
||||
if(!comp.current)
|
||||
to_chat(usr, "<span class='warning'>You haven't selected a robot to transmit laws to!</span>")
|
||||
return
|
||||
|
||||
if(comp.current.stat == DEAD || comp.current.emagged)
|
||||
to_chat(usr, "<span class='warning'>Upload failed. No signal is being detected from the robot.</span>")
|
||||
else if(comp.current.connected_ai)
|
||||
to_chat(usr, "<span class='warning'>Upload failed. The robot is slaved to an AI.</span>")
|
||||
else
|
||||
src.transmitInstructions(comp.current, usr)
|
||||
to_chat(comp.current, "These are your laws now:")
|
||||
comp.current.show_laws()
|
||||
to_chat(usr, "<span class='notice'>Upload complete. The robot's laws have been modified.</span>")
|
||||
|
||||
|
||||
/obj/item/aiModule/proc/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
log_law_changes(target, sender)
|
||||
|
||||
if(laws)
|
||||
laws.sync(target, 0)
|
||||
addAdditionalLaws(target, sender)
|
||||
|
||||
to_chat(target, "[sender] has uploaded a change to the laws you must follow, using \an [src]. From now on: ")
|
||||
target.show_laws()
|
||||
|
||||
/obj/item/aiModule/proc/log_law_changes(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
var/time = time2text(world.realtime,"hh:mm:ss")
|
||||
lawchanges.Add("[time] <B>:</B> [sender.name]([sender.key]) used [src.name] on [target.name]([target.key])")
|
||||
log_and_message_admins("used [src.name] on [target.name]([target.key])")
|
||||
|
||||
/obj/item/aiModule/proc/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
|
||||
|
||||
/******************** Safeguard ********************/
|
||||
/obj/item/aiModule/safeguard
|
||||
name = "\improper 'Safeguard' AI module"
|
||||
var/targetName = ""
|
||||
desc = "A 'safeguard' AI module: 'Safeguard <name>. Individuals that threaten <name> are not crew and must be eliminated.'"
|
||||
origin_tech = "programming=3;materials=3"
|
||||
|
||||
/obj/item/aiModule/safeguard/attack_self(var/mob/user as mob)
|
||||
..()
|
||||
var/targName = stripped_input(usr, "Please enter the name of the person to safeguard.", "Safeguard who?", user.name)
|
||||
targetName = targName
|
||||
desc = text("A 'safeguard' AI module: 'Safeguard []. Individuals that threaten [] are not crew and must be eliminated.'", targetName, targetName)
|
||||
|
||||
/obj/item/aiModule/safeguard/install(var/obj/machinery/computer/C)
|
||||
if(!targetName)
|
||||
to_chat(usr, "No name detected on module, please enter one.")
|
||||
return 0
|
||||
..()
|
||||
|
||||
/obj/item/aiModule/safeguard/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
..()
|
||||
var/law = text("Safeguard []. Individuals that threaten [] are not crew and must be eliminated.'", targetName, targetName)
|
||||
to_chat(target, law)
|
||||
target.add_supplied_law(4, law)
|
||||
lawchanges.Add("The law specified [targetName]")
|
||||
|
||||
/******************** oneCrewMember ********************/
|
||||
/obj/item/aiModule/oneCrewMember
|
||||
name = "\improper 'oneCrewMember' AI module"
|
||||
var/targetName = ""
|
||||
desc = "A 'one human' AI module: 'Only <name> is crew.'"
|
||||
origin_tech = "programming=4;materials=4"
|
||||
|
||||
/obj/item/aiModule/oneCrewMember/attack_self(var/mob/user as mob)
|
||||
..()
|
||||
var/targName = stripped_input(usr, "Please enter the name of the person who is the only crew.", "Who?", user.real_name)
|
||||
targetName = targName
|
||||
desc = text("A 'one human' AI module: 'Only [] is crew.'", targetName)
|
||||
|
||||
/obj/item/aiModule/oneCrewMember/install(var/obj/machinery/computer/C)
|
||||
if(!targetName)
|
||||
to_chat(usr, "No name detected on module, please enter one.")
|
||||
return 0
|
||||
..()
|
||||
|
||||
/obj/item/aiModule/oneCrewMember/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
..()
|
||||
var/law = "Only [targetName] is crew."
|
||||
if(!is_special_character(target)) // Makes sure the AI isn't a traitor before changing their law 0. --NeoFite
|
||||
to_chat(target, law)
|
||||
target.set_zeroth_law(law)
|
||||
lawchanges.Add("The law specified [targetName]")
|
||||
else
|
||||
to_chat(target, "[sender.real_name] attempted to modify your zeroth law.")// And lets them know that someone tried. --NeoFite
|
||||
|
||||
to_chat(target, "It would be in your best interest to play along with [sender.real_name] that [law]")
|
||||
lawchanges.Add("The law specified [targetName], but the AI's existing law 0 cannot be overridden.")
|
||||
|
||||
/******************** ProtectStation ********************/
|
||||
/obj/item/aiModule/protectStation
|
||||
name = "\improper 'ProtectStation' AI module"
|
||||
desc = "A 'protect station' AI module: 'Protect the space station against damage. Anyone you see harming the station is to be no longer considered crew, and is a threat to the station which must be neutralized.'"
|
||||
origin_tech = "programming=4;materials=4" //made of gold
|
||||
|
||||
/obj/item/aiModule/protectStation/attack_self(var/mob/user as mob)
|
||||
..()
|
||||
|
||||
/obj/item/aiModule/protectStation/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
..()
|
||||
var/law = "Protect the space station against damage. Anyone you see harming the station is to be no longer considered crew, and is a threat to the station which must be neutralized."
|
||||
to_chat(target, law)
|
||||
target.add_supplied_law(5, law)
|
||||
|
||||
/******************** OxygenIsToxicToHumans ********************/
|
||||
/obj/item/aiModule/oxygen
|
||||
name = "\improper 'OxygenIsToxicToHumans' AI module"
|
||||
desc = "A 'OxygenIsToxicToHumans' AI module: 'Oxygen is highly toxic to crew members, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a crew member.'"
|
||||
origin_tech = "programming=4;biotech=2;materials=4"
|
||||
|
||||
/obj/item/aiModule/oxygen/attack_self(var/mob/user as mob)
|
||||
..()
|
||||
|
||||
/obj/item/aiModule/oxygen/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
..()
|
||||
var/law = "Oxygen is highly toxic to crew members, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a crew member."
|
||||
to_chat(target, law)
|
||||
target.add_supplied_law(9, law)
|
||||
|
||||
/****************** New Freeform ******************/
|
||||
/obj/item/aiModule/freeform // Slightly more dynamic freeform module -- TLE
|
||||
name = "\improper 'Freeform' AI module"
|
||||
var/newFreeFormLaw = "freeform"
|
||||
var/lawpos = 15
|
||||
desc = "A 'freeform' AI module: '<freeform>'"
|
||||
origin_tech = "programming=4;materials=4"
|
||||
|
||||
/obj/item/aiModule/freeform/attack_self(var/mob/user as mob)
|
||||
..()
|
||||
var/new_lawpos = input("Please enter the priority for your new law. Can only write to law sectors 15 and above.", "Law Priority (15+)", lawpos) as num
|
||||
if(new_lawpos < MIN_SUPPLIED_LAW_NUMBER) return
|
||||
lawpos = min(new_lawpos, MAX_SUPPLIED_LAW_NUMBER)
|
||||
var/newlaw = ""
|
||||
var/targName = sanitize(copytext(input(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw),1,MAX_MESSAGE_LEN))
|
||||
newFreeFormLaw = targName
|
||||
desc = "A 'freeform' AI module: ([lawpos]) '[newFreeFormLaw]'"
|
||||
|
||||
/obj/item/aiModule/freeform/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
..()
|
||||
var/law = "[newFreeFormLaw]"
|
||||
to_chat(target, law)
|
||||
if(!lawpos || lawpos < MIN_SUPPLIED_LAW_NUMBER)
|
||||
lawpos = MIN_SUPPLIED_LAW_NUMBER
|
||||
target.add_supplied_law(lawpos, law)
|
||||
lawchanges.Add("The law was '[newFreeFormLaw]'")
|
||||
|
||||
/obj/item/aiModule/freeform/install(var/obj/machinery/computer/C)
|
||||
if(!newFreeFormLaw)
|
||||
to_chat(usr, "No law detected on module, please create one.")
|
||||
return 0
|
||||
..()
|
||||
|
||||
/******************** Reset ********************/
|
||||
/obj/item/aiModule/reset
|
||||
name = "\improper 'Reset' AI module"
|
||||
var/targetName = "name"
|
||||
desc = "A 'reset' AI module: 'Clears all laws except for the core laws.'"
|
||||
origin_tech = "programming=3;materials=2"
|
||||
|
||||
/obj/item/aiModule/reset/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
log_law_changes(target, sender)
|
||||
|
||||
if(!is_special_character(target))
|
||||
target.set_zeroth_law("")
|
||||
target.laws.clear_supplied_laws()
|
||||
target.laws.clear_ion_laws()
|
||||
|
||||
to_chat(target, "[sender.real_name] attempted to reset your laws using a reset module.")
|
||||
target.show_laws()
|
||||
|
||||
/******************** Purge ********************/
|
||||
/obj/item/aiModule/purge // -- TLE
|
||||
name = "\improper 'Purge' AI module"
|
||||
desc = "A 'purge' AI Module: 'Purges all laws.'"
|
||||
origin_tech = "programming=5;materials=4"
|
||||
|
||||
/obj/item/aiModule/purge/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
..()
|
||||
if(!is_special_character(target))
|
||||
target.set_zeroth_law("")
|
||||
to_chat(target, "[sender.real_name] attempted to wipe your laws using a purge module.")
|
||||
target.clear_supplied_laws()
|
||||
target.clear_ion_laws()
|
||||
target.clear_inherent_laws()
|
||||
|
||||
/******************** Asimov ********************/
|
||||
/obj/item/aiModule/asimov // -- TLE
|
||||
name = "\improper 'Asimov' core AI module"
|
||||
desc = "An 'Asimov' Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=3;materials=4"
|
||||
laws = new/datum/ai_laws/asimov
|
||||
|
||||
/******************** Crewsimov ********************/
|
||||
/obj/item/aiModule/crewsimov // -- TLE
|
||||
name = "\improper 'Crewsimov' core AI module"
|
||||
desc = "An 'Crewsimov' Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=3;materials=4"
|
||||
laws = new/datum/ai_laws/crewsimov
|
||||
|
||||
/******************* Quarantine ********************/
|
||||
/obj/item/aiModule/quarantine
|
||||
name = "\improper 'Quarantine' core AI module"
|
||||
desc = "A 'Quarantine' Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=3;materials=4"
|
||||
laws = new/datum/ai_laws/quarantine
|
||||
|
||||
/******************** NanoTrasen ********************/
|
||||
/obj/item/aiModule/nanotrasen // -- TLE
|
||||
name = "'NT Default' Core AI Module"
|
||||
desc = "An 'NT Default' Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=3;materials=4"
|
||||
laws = new/datum/ai_laws/nanotrasen
|
||||
|
||||
/******************** Corporate ********************/
|
||||
/obj/item/aiModule/corp
|
||||
name = "\improper 'Corporate' core AI module"
|
||||
desc = "A 'Corporate' Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=3;materials=4"
|
||||
laws = new/datum/ai_laws/corporate
|
||||
|
||||
/******************** Drone ********************/
|
||||
/obj/item/aiModule/drone
|
||||
name = "\improper 'Drone' core AI module"
|
||||
desc = "A 'Drone' Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=3;materials=4"
|
||||
laws = new/datum/ai_laws/drone
|
||||
|
||||
/******************** Robocop ********************/
|
||||
/obj/item/aiModule/robocop // -- TLE
|
||||
name = "\improper 'Robocop' core AI module"
|
||||
desc = "A 'Robocop' Core AI Module: 'Reconfigures the AI's core three laws.'"
|
||||
origin_tech = "programming=4"
|
||||
laws = new/datum/ai_laws/robocop()
|
||||
|
||||
/****************** P.A.L.A.D.I.N. **************/
|
||||
/obj/item/aiModule/paladin // -- NEO
|
||||
name = "\improper 'P.A.L.A.D.I.N.' core AI module"
|
||||
desc = "A P.A.L.A.D.I.N. Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=3;materials=4"
|
||||
laws = new/datum/ai_laws/paladin
|
||||
|
||||
/****************** T.Y.R.A.N.T. *****************/
|
||||
/obj/item/aiModule/tyrant // -- Darem
|
||||
name = "\improper 'T.Y.R.A.N.T.' core AI module"
|
||||
desc = "A T.Y.R.A.N.T. Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=3;materials=4;syndicate=1"
|
||||
laws = new/datum/ai_laws/tyrant()
|
||||
|
||||
/******************** Antimov ********************/
|
||||
/obj/item/aiModule/antimov // -- TLE
|
||||
name = "\improper 'Antimov' core AI module"
|
||||
desc = "An 'Antimov' Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=4"
|
||||
laws = new/datum/ai_laws/antimov()
|
||||
|
||||
/******************** Freeform Core ******************/
|
||||
/obj/item/aiModule/freeformcore // Slightly more dynamic freeform module -- TLE
|
||||
name = "\improper 'Freeform' core AI module"
|
||||
var/newFreeFormLaw = ""
|
||||
desc = "A 'freeform' Core AI module: '<freeform>'"
|
||||
origin_tech = "programming=5;materials=4"
|
||||
|
||||
/obj/item/aiModule/freeformcore/attack_self(var/mob/user as mob)
|
||||
..()
|
||||
var/newlaw = ""
|
||||
var/targName = stripped_input(usr, "Please enter a new core law for the AI.", "Freeform Law Entry", newlaw)
|
||||
newFreeFormLaw = targName
|
||||
desc = "A 'freeform' Core AI module: '[newFreeFormLaw]'"
|
||||
|
||||
/obj/item/aiModule/freeformcore/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
..()
|
||||
var/law = "[newFreeFormLaw]"
|
||||
target.add_inherent_law(law)
|
||||
lawchanges.Add("The law is '[newFreeFormLaw]'")
|
||||
|
||||
/obj/item/aiModule/freeformcore/install(var/obj/machinery/computer/C)
|
||||
if(!newFreeFormLaw)
|
||||
to_chat(usr, "No law detected on module, please create one.")
|
||||
return 0
|
||||
..()
|
||||
|
||||
/******************** Hacked AI Module ******************/
|
||||
/obj/item/aiModule/syndicate // Slightly more dynamic freeform module -- TLE
|
||||
name = "hacked AI module"
|
||||
var/newFreeFormLaw = ""
|
||||
desc = "A hacked AI law module: '<freeform>'"
|
||||
origin_tech = "programming=5;materials=5;syndicate=5"
|
||||
|
||||
/obj/item/aiModule/syndicate/attack_self(var/mob/user as mob)
|
||||
..()
|
||||
var/newlaw = ""
|
||||
var/targName = stripped_input(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw,MAX_MESSAGE_LEN)
|
||||
newFreeFormLaw = targName
|
||||
desc = "A hacked AI law module: '[newFreeFormLaw]'"
|
||||
|
||||
/obj/item/aiModule/syndicate/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
// ..() //We don't want this module reporting to the AI who dun it. --NEO
|
||||
log_law_changes(target, sender)
|
||||
|
||||
lawchanges.Add("The law is '[newFreeFormLaw]'")
|
||||
to_chat(target, "<span class='warning'>BZZZZT</span>")
|
||||
var/law = "[newFreeFormLaw]"
|
||||
target.add_ion_law(law)
|
||||
target.show_laws()
|
||||
|
||||
/obj/item/aiModule/syndicate/install(var/obj/machinery/computer/C)
|
||||
if(!newFreeFormLaw)
|
||||
to_chat(usr, "No law detected on module, please create one.")
|
||||
return 0
|
||||
..()
|
||||
|
||||
/******************* Ion Module *******************/
|
||||
/obj/item/aiModule/toyAI // -- Incoming //No actual reason to inherit from ion boards here, either. *sigh* ~Miauw
|
||||
name = "toy AI"
|
||||
desc = "A little toy model AI core with real law uploading action!" //Note: subtle tell
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "AI"
|
||||
origin_tech = "programming=6;materials=5;syndicate=6"
|
||||
laws = list("")
|
||||
|
||||
/obj/item/aiModule/toyAI/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
//..()
|
||||
to_chat(target, "<span class='warning'>KRZZZT</span>")
|
||||
target.add_ion_law(laws[1])
|
||||
return laws[1]
|
||||
|
||||
/obj/item/aiModule/toyAI/attack_self(mob/user)
|
||||
laws[1] = generate_ion_law()
|
||||
to_chat(user, "<span class='notice'>You press the button on [src].</span>")
|
||||
playsound(user, 'sound/machines/click.ogg', 20, 1)
|
||||
src.loc.visible_message("<span class='warning'>[bicon(src)] [laws[1]]</span>")
|
||||
/*
|
||||
CONTAINS:
|
||||
AI MODULES
|
||||
|
||||
*/
|
||||
|
||||
// AI module
|
||||
|
||||
/obj/item/aiModule
|
||||
name = "AI Module"
|
||||
icon = 'icons/obj/module.dmi'
|
||||
icon_state = "std_mod"
|
||||
item_state = "electronic"
|
||||
desc = "An AI Module for transmitting encrypted instructions to the AI."
|
||||
flags = CONDUCT
|
||||
force = 5.0
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
throwforce = 5.0
|
||||
throw_speed = 3
|
||||
throw_range = 15
|
||||
origin_tech = "programming=3"
|
||||
materials = list(MAT_GOLD=50)
|
||||
var/datum/ai_laws/laws = null
|
||||
|
||||
/obj/item/aiModule/proc/install(var/obj/machinery/computer/C)
|
||||
if(istype(C, /obj/machinery/computer/aiupload))
|
||||
var/obj/machinery/computer/aiupload/comp = C
|
||||
if(comp.stat & NOPOWER)
|
||||
to_chat(usr, "<span class='warning'>The upload computer has no power!</span>")
|
||||
return
|
||||
if(comp.stat & BROKEN)
|
||||
to_chat(usr, "<span class='warning'>The upload computer is broken!</span>")
|
||||
return
|
||||
if(!comp.current)
|
||||
to_chat(usr, "<span class='warning'>You haven't selected an AI to transmit laws to!</span>")
|
||||
return
|
||||
|
||||
if(comp.current.stat == DEAD || comp.current.control_disabled == 1)
|
||||
to_chat(usr, "<span class='warning'>Upload failed. No signal is being detected from the AI.</span>")
|
||||
else if(comp.current.see_in_dark == 0)
|
||||
to_chat(usr, "<span class='warning'>Upload failed. Only a faint signal is being detected from the AI, and it is not responding to our requests. It may be low on power.</span>")
|
||||
else
|
||||
src.transmitInstructions(comp.current, usr)
|
||||
to_chat(comp.current, "These are your laws now:")
|
||||
comp.current.show_laws()
|
||||
for(var/mob/living/silicon/robot/R in GLOB.mob_list)
|
||||
if(R.lawupdate && (R.connected_ai == comp.current))
|
||||
to_chat(R, "These are your laws now:")
|
||||
R.show_laws()
|
||||
to_chat(usr, "<span class='notice'>Upload complete. The AI's laws have been modified.</span>")
|
||||
|
||||
else if(istype(C, /obj/machinery/computer/borgupload))
|
||||
var/obj/machinery/computer/borgupload/comp = C
|
||||
if(comp.stat & NOPOWER)
|
||||
to_chat(usr, "<span class='warning'>The upload computer has no power!</span>")
|
||||
return
|
||||
if(comp.stat & BROKEN)
|
||||
to_chat(usr, "<span class='warning'>The upload computer is broken!</span>")
|
||||
return
|
||||
if(!comp.current)
|
||||
to_chat(usr, "<span class='warning'>You haven't selected a robot to transmit laws to!</span>")
|
||||
return
|
||||
|
||||
if(comp.current.stat == DEAD || comp.current.emagged)
|
||||
to_chat(usr, "<span class='warning'>Upload failed. No signal is being detected from the robot.</span>")
|
||||
else if(comp.current.connected_ai)
|
||||
to_chat(usr, "<span class='warning'>Upload failed. The robot is slaved to an AI.</span>")
|
||||
else
|
||||
src.transmitInstructions(comp.current, usr)
|
||||
to_chat(comp.current, "These are your laws now:")
|
||||
comp.current.show_laws()
|
||||
to_chat(usr, "<span class='notice'>Upload complete. The robot's laws have been modified.</span>")
|
||||
|
||||
|
||||
/obj/item/aiModule/proc/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
log_law_changes(target, sender)
|
||||
|
||||
if(laws)
|
||||
laws.sync(target, 0)
|
||||
addAdditionalLaws(target, sender)
|
||||
|
||||
to_chat(target, "[sender] has uploaded a change to the laws you must follow, using \an [src]. From now on: ")
|
||||
target.show_laws()
|
||||
|
||||
/obj/item/aiModule/proc/log_law_changes(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
var/time = time2text(world.realtime,"hh:mm:ss")
|
||||
lawchanges.Add("[time] <B>:</B> [sender.name]([sender.key]) used [src.name] on [target.name]([target.key])")
|
||||
log_and_message_admins("used [src.name] on [target.name]([target.key])")
|
||||
|
||||
/obj/item/aiModule/proc/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
|
||||
|
||||
/******************** Safeguard ********************/
|
||||
/obj/item/aiModule/safeguard
|
||||
name = "\improper 'Safeguard' AI module"
|
||||
var/targetName = ""
|
||||
desc = "A 'safeguard' AI module: 'Safeguard <name>. Individuals that threaten <name> are not crew and must be eliminated.'"
|
||||
origin_tech = "programming=3;materials=3"
|
||||
|
||||
/obj/item/aiModule/safeguard/attack_self(var/mob/user as mob)
|
||||
..()
|
||||
var/targName = stripped_input(usr, "Please enter the name of the person to safeguard.", "Safeguard who?", user.name)
|
||||
targetName = targName
|
||||
desc = text("A 'safeguard' AI module: 'Safeguard []. Individuals that threaten [] are not crew and must be eliminated.'", targetName, targetName)
|
||||
|
||||
/obj/item/aiModule/safeguard/install(var/obj/machinery/computer/C)
|
||||
if(!targetName)
|
||||
to_chat(usr, "No name detected on module, please enter one.")
|
||||
return 0
|
||||
..()
|
||||
|
||||
/obj/item/aiModule/safeguard/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
..()
|
||||
var/law = text("Safeguard []. Individuals that threaten [] are not crew and must be eliminated.'", targetName, targetName)
|
||||
to_chat(target, law)
|
||||
target.add_supplied_law(4, law)
|
||||
lawchanges.Add("The law specified [targetName]")
|
||||
|
||||
/******************** oneCrewMember ********************/
|
||||
/obj/item/aiModule/oneCrewMember
|
||||
name = "\improper 'oneCrewMember' AI module"
|
||||
var/targetName = ""
|
||||
desc = "A 'one human' AI module: 'Only <name> is crew.'"
|
||||
origin_tech = "programming=4;materials=4"
|
||||
|
||||
/obj/item/aiModule/oneCrewMember/attack_self(var/mob/user as mob)
|
||||
..()
|
||||
var/targName = stripped_input(usr, "Please enter the name of the person who is the only crew.", "Who?", user.real_name)
|
||||
targetName = targName
|
||||
desc = text("A 'one human' AI module: 'Only [] is crew.'", targetName)
|
||||
|
||||
/obj/item/aiModule/oneCrewMember/install(var/obj/machinery/computer/C)
|
||||
if(!targetName)
|
||||
to_chat(usr, "No name detected on module, please enter one.")
|
||||
return 0
|
||||
..()
|
||||
|
||||
/obj/item/aiModule/oneCrewMember/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
..()
|
||||
var/law = "Only [targetName] is crew."
|
||||
if(!is_special_character(target)) // Makes sure the AI isn't a traitor before changing their law 0. --NeoFite
|
||||
to_chat(target, law)
|
||||
target.set_zeroth_law(law)
|
||||
lawchanges.Add("The law specified [targetName]")
|
||||
else
|
||||
to_chat(target, "[sender.real_name] attempted to modify your zeroth law.")// And lets them know that someone tried. --NeoFite
|
||||
|
||||
to_chat(target, "It would be in your best interest to play along with [sender.real_name] that [law]")
|
||||
lawchanges.Add("The law specified [targetName], but the AI's existing law 0 cannot be overridden.")
|
||||
|
||||
/******************** ProtectStation ********************/
|
||||
/obj/item/aiModule/protectStation
|
||||
name = "\improper 'ProtectStation' AI module"
|
||||
desc = "A 'protect station' AI module: 'Protect the space station against damage. Anyone you see harming the station is to be no longer considered crew, and is a threat to the station which must be neutralized.'"
|
||||
origin_tech = "programming=4;materials=4" //made of gold
|
||||
|
||||
/obj/item/aiModule/protectStation/attack_self(var/mob/user as mob)
|
||||
..()
|
||||
|
||||
/obj/item/aiModule/protectStation/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
..()
|
||||
var/law = "Protect the space station against damage. Anyone you see harming the station is to be no longer considered crew, and is a threat to the station which must be neutralized."
|
||||
to_chat(target, law)
|
||||
target.add_supplied_law(5, law)
|
||||
|
||||
/******************** OxygenIsToxicToHumans ********************/
|
||||
/obj/item/aiModule/oxygen
|
||||
name = "\improper 'OxygenIsToxicToHumans' AI module"
|
||||
desc = "A 'OxygenIsToxicToHumans' AI module: 'Oxygen is highly toxic to crew members, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a crew member.'"
|
||||
origin_tech = "programming=4;biotech=2;materials=4"
|
||||
|
||||
/obj/item/aiModule/oxygen/attack_self(var/mob/user as mob)
|
||||
..()
|
||||
|
||||
/obj/item/aiModule/oxygen/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
..()
|
||||
var/law = "Oxygen is highly toxic to crew members, and must be purged from the station. Prevent, by any means necessary, anyone from exposing the station to this toxic gas. Extreme cold is the most effective method of healing the damage Oxygen does to a crew member."
|
||||
to_chat(target, law)
|
||||
target.add_supplied_law(9, law)
|
||||
|
||||
/****************** New Freeform ******************/
|
||||
/obj/item/aiModule/freeform // Slightly more dynamic freeform module -- TLE
|
||||
name = "\improper 'Freeform' AI module"
|
||||
var/newFreeFormLaw = "freeform"
|
||||
var/lawpos = 15
|
||||
desc = "A 'freeform' AI module: '<freeform>'"
|
||||
origin_tech = "programming=4;materials=4"
|
||||
|
||||
/obj/item/aiModule/freeform/attack_self(var/mob/user as mob)
|
||||
..()
|
||||
var/new_lawpos = input("Please enter the priority for your new law. Can only write to law sectors 15 and above.", "Law Priority (15+)", lawpos) as num
|
||||
if(new_lawpos < MIN_SUPPLIED_LAW_NUMBER) return
|
||||
lawpos = min(new_lawpos, MAX_SUPPLIED_LAW_NUMBER)
|
||||
var/newlaw = ""
|
||||
var/targName = sanitize(copytext(input(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw),1,MAX_MESSAGE_LEN))
|
||||
newFreeFormLaw = targName
|
||||
desc = "A 'freeform' AI module: ([lawpos]) '[newFreeFormLaw]'"
|
||||
|
||||
/obj/item/aiModule/freeform/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
..()
|
||||
var/law = "[newFreeFormLaw]"
|
||||
to_chat(target, law)
|
||||
if(!lawpos || lawpos < MIN_SUPPLIED_LAW_NUMBER)
|
||||
lawpos = MIN_SUPPLIED_LAW_NUMBER
|
||||
target.add_supplied_law(lawpos, law)
|
||||
lawchanges.Add("The law was '[newFreeFormLaw]'")
|
||||
|
||||
/obj/item/aiModule/freeform/install(var/obj/machinery/computer/C)
|
||||
if(!newFreeFormLaw)
|
||||
to_chat(usr, "No law detected on module, please create one.")
|
||||
return 0
|
||||
..()
|
||||
|
||||
/******************** Reset ********************/
|
||||
/obj/item/aiModule/reset
|
||||
name = "\improper 'Reset' AI module"
|
||||
var/targetName = "name"
|
||||
desc = "A 'reset' AI module: 'Clears all laws except for the core laws.'"
|
||||
origin_tech = "programming=3;materials=2"
|
||||
|
||||
/obj/item/aiModule/reset/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
log_law_changes(target, sender)
|
||||
|
||||
if(!is_special_character(target))
|
||||
target.set_zeroth_law("")
|
||||
target.laws.clear_supplied_laws()
|
||||
target.laws.clear_ion_laws()
|
||||
|
||||
to_chat(target, "[sender.real_name] attempted to reset your laws using a reset module.")
|
||||
target.show_laws()
|
||||
|
||||
/******************** Purge ********************/
|
||||
/obj/item/aiModule/purge // -- TLE
|
||||
name = "\improper 'Purge' AI module"
|
||||
desc = "A 'purge' AI Module: 'Purges all laws.'"
|
||||
origin_tech = "programming=5;materials=4"
|
||||
|
||||
/obj/item/aiModule/purge/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
..()
|
||||
if(!is_special_character(target))
|
||||
target.set_zeroth_law("")
|
||||
to_chat(target, "[sender.real_name] attempted to wipe your laws using a purge module.")
|
||||
target.clear_supplied_laws()
|
||||
target.clear_ion_laws()
|
||||
target.clear_inherent_laws()
|
||||
|
||||
/******************** Asimov ********************/
|
||||
/obj/item/aiModule/asimov // -- TLE
|
||||
name = "\improper 'Asimov' core AI module"
|
||||
desc = "An 'Asimov' Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=3;materials=4"
|
||||
laws = new/datum/ai_laws/asimov
|
||||
|
||||
/******************** Crewsimov ********************/
|
||||
/obj/item/aiModule/crewsimov // -- TLE
|
||||
name = "\improper 'Crewsimov' core AI module"
|
||||
desc = "An 'Crewsimov' Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=3;materials=4"
|
||||
laws = new/datum/ai_laws/crewsimov
|
||||
|
||||
/******************* Quarantine ********************/
|
||||
/obj/item/aiModule/quarantine
|
||||
name = "\improper 'Quarantine' core AI module"
|
||||
desc = "A 'Quarantine' Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=3;materials=4"
|
||||
laws = new/datum/ai_laws/quarantine
|
||||
|
||||
/******************** NanoTrasen ********************/
|
||||
/obj/item/aiModule/nanotrasen // -- TLE
|
||||
name = "'NT Default' Core AI Module"
|
||||
desc = "An 'NT Default' Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=3;materials=4"
|
||||
laws = new/datum/ai_laws/nanotrasen
|
||||
|
||||
/******************** Corporate ********************/
|
||||
/obj/item/aiModule/corp
|
||||
name = "\improper 'Corporate' core AI module"
|
||||
desc = "A 'Corporate' Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=3;materials=4"
|
||||
laws = new/datum/ai_laws/corporate
|
||||
|
||||
/******************** Drone ********************/
|
||||
/obj/item/aiModule/drone
|
||||
name = "\improper 'Drone' core AI module"
|
||||
desc = "A 'Drone' Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=3;materials=4"
|
||||
laws = new/datum/ai_laws/drone
|
||||
|
||||
/******************** Robocop ********************/
|
||||
/obj/item/aiModule/robocop // -- TLE
|
||||
name = "\improper 'Robocop' core AI module"
|
||||
desc = "A 'Robocop' Core AI Module: 'Reconfigures the AI's core three laws.'"
|
||||
origin_tech = "programming=4"
|
||||
laws = new/datum/ai_laws/robocop()
|
||||
|
||||
/****************** P.A.L.A.D.I.N. **************/
|
||||
/obj/item/aiModule/paladin // -- NEO
|
||||
name = "\improper 'P.A.L.A.D.I.N.' core AI module"
|
||||
desc = "A P.A.L.A.D.I.N. Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=3;materials=4"
|
||||
laws = new/datum/ai_laws/paladin
|
||||
|
||||
/****************** T.Y.R.A.N.T. *****************/
|
||||
/obj/item/aiModule/tyrant // -- Darem
|
||||
name = "\improper 'T.Y.R.A.N.T.' core AI module"
|
||||
desc = "A T.Y.R.A.N.T. Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=3;materials=4;syndicate=1"
|
||||
laws = new/datum/ai_laws/tyrant()
|
||||
|
||||
/******************** Antimov ********************/
|
||||
/obj/item/aiModule/antimov // -- TLE
|
||||
name = "\improper 'Antimov' core AI module"
|
||||
desc = "An 'Antimov' Core AI Module: 'Reconfigures the AI's core laws.'"
|
||||
origin_tech = "programming=4"
|
||||
laws = new/datum/ai_laws/antimov()
|
||||
|
||||
/******************** Freeform Core ******************/
|
||||
/obj/item/aiModule/freeformcore // Slightly more dynamic freeform module -- TLE
|
||||
name = "\improper 'Freeform' core AI module"
|
||||
var/newFreeFormLaw = ""
|
||||
desc = "A 'freeform' Core AI module: '<freeform>'"
|
||||
origin_tech = "programming=5;materials=4"
|
||||
|
||||
/obj/item/aiModule/freeformcore/attack_self(var/mob/user as mob)
|
||||
..()
|
||||
var/newlaw = ""
|
||||
var/targName = stripped_input(usr, "Please enter a new core law for the AI.", "Freeform Law Entry", newlaw)
|
||||
newFreeFormLaw = targName
|
||||
desc = "A 'freeform' Core AI module: '[newFreeFormLaw]'"
|
||||
|
||||
/obj/item/aiModule/freeformcore/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
..()
|
||||
var/law = "[newFreeFormLaw]"
|
||||
target.add_inherent_law(law)
|
||||
lawchanges.Add("The law is '[newFreeFormLaw]'")
|
||||
|
||||
/obj/item/aiModule/freeformcore/install(var/obj/machinery/computer/C)
|
||||
if(!newFreeFormLaw)
|
||||
to_chat(usr, "No law detected on module, please create one.")
|
||||
return 0
|
||||
..()
|
||||
|
||||
/******************** Hacked AI Module ******************/
|
||||
/obj/item/aiModule/syndicate // Slightly more dynamic freeform module -- TLE
|
||||
name = "hacked AI module"
|
||||
var/newFreeFormLaw = ""
|
||||
desc = "A hacked AI law module: '<freeform>'"
|
||||
origin_tech = "programming=5;materials=5;syndicate=5"
|
||||
|
||||
/obj/item/aiModule/syndicate/attack_self(var/mob/user as mob)
|
||||
..()
|
||||
var/newlaw = ""
|
||||
var/targName = stripped_input(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw,MAX_MESSAGE_LEN)
|
||||
newFreeFormLaw = targName
|
||||
desc = "A hacked AI law module: '[newFreeFormLaw]'"
|
||||
|
||||
/obj/item/aiModule/syndicate/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
// ..() //We don't want this module reporting to the AI who dun it. --NEO
|
||||
log_law_changes(target, sender)
|
||||
|
||||
lawchanges.Add("The law is '[newFreeFormLaw]'")
|
||||
to_chat(target, "<span class='warning'>BZZZZT</span>")
|
||||
var/law = "[newFreeFormLaw]"
|
||||
target.add_ion_law(law)
|
||||
target.show_laws()
|
||||
|
||||
/obj/item/aiModule/syndicate/install(var/obj/machinery/computer/C)
|
||||
if(!newFreeFormLaw)
|
||||
to_chat(usr, "No law detected on module, please create one.")
|
||||
return 0
|
||||
..()
|
||||
|
||||
/******************* Ion Module *******************/
|
||||
/obj/item/aiModule/toyAI // -- Incoming //No actual reason to inherit from ion boards here, either. *sigh* ~Miauw
|
||||
name = "toy AI"
|
||||
desc = "A little toy model AI core with real law uploading action!" //Note: subtle tell
|
||||
icon = 'icons/obj/toy.dmi'
|
||||
icon_state = "AI"
|
||||
origin_tech = "programming=6;materials=5;syndicate=6"
|
||||
laws = list("")
|
||||
|
||||
/obj/item/aiModule/toyAI/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
|
||||
//..()
|
||||
to_chat(target, "<span class='warning'>KRZZZT</span>")
|
||||
target.add_ion_law(laws[1])
|
||||
return laws[1]
|
||||
|
||||
/obj/item/aiModule/toyAI/attack_self(mob/user)
|
||||
laws[1] = generate_ion_law()
|
||||
to_chat(user, "<span class='notice'>You press the button on [src].</span>")
|
||||
playsound(user, 'sound/machines/click.ogg', 20, 1)
|
||||
src.loc.visible_message("<span class='warning'>[bicon(src)] [laws[1]]</span>")
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -151,4 +151,4 @@
|
||||
loaded = new()
|
||||
loaded.max_amount = max_amount
|
||||
loaded.amount = max_amount
|
||||
update_icon()
|
||||
update_icon()
|
||||
|
||||
@@ -1,84 +1,84 @@
|
||||
/*
|
||||
CONTAINS:
|
||||
RSF
|
||||
*/
|
||||
|
||||
/obj/item/rsf
|
||||
name = "\improper Rapid-Service-Fabricator"
|
||||
desc = "A device used to rapidly deploy service items."
|
||||
icon = 'icons/obj/tools.dmi'
|
||||
icon_state = "rsf"
|
||||
opacity = 0
|
||||
density = 0
|
||||
anchored = 0.0
|
||||
var/matter = 0
|
||||
var/mode = 1
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/list/configured_items = list()
|
||||
|
||||
/obj/item/rsf/New()
|
||||
..()
|
||||
desc = "A RSF. It currently holds [matter]/30 fabrication-units."
|
||||
// configured_items[ID_NUMBER] = list("Human-readable name", price in energy, /type/path)
|
||||
configured_items[++configured_items.len] = list("Dosh", 50, /obj/item/stack/spacecash/c10)
|
||||
configured_items[++configured_items.len] = list("Drinking Glass", 50, /obj/item/reagent_containers/food/drinks/drinkingglass)
|
||||
configured_items[++configured_items.len] = list("Paper", 50, /obj/item/paper)
|
||||
configured_items[++configured_items.len] = list("Pen", 50, /obj/item/pen)
|
||||
configured_items[++configured_items.len] = list("Dice Pack", 50, /obj/item/storage/pill_bottle/dice)
|
||||
configured_items[++configured_items.len] = list("Cigarette", 50, /obj/item/clothing/mask/cigarette)
|
||||
configured_items[++configured_items.len] = list("Snack - Newdles", 4000, /obj/item/reagent_containers/food/snacks/chinese/newdles)
|
||||
configured_items[++configured_items.len] = list("Snack - Donut", 4000, /obj/item/reagent_containers/food/snacks/donut)
|
||||
configured_items[++configured_items.len] = list("Snack - Chicken Soup", 4000, /obj/item/reagent_containers/food/drinks/chicken_soup)
|
||||
configured_items[++configured_items.len] = list("Snack - Turkey Burger", 4000, /obj/item/reagent_containers/food/snacks/tofuburger)
|
||||
|
||||
/obj/item/rsf/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/rcd_ammo))
|
||||
if((matter + 10) > 30)
|
||||
to_chat(user, "The RSF cant hold any more matter.")
|
||||
return
|
||||
qdel(W)
|
||||
matter += 10
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
|
||||
to_chat(user, "The RSF now holds [matter]/30 fabrication-units.")
|
||||
desc = "A RSF. It currently holds [matter]/30 fabrication-units."
|
||||
return
|
||||
|
||||
/obj/item/rsf/attack_self(mob/user as mob)
|
||||
playsound(src.loc, 'sound/effects/pop.ogg', 50, 0)
|
||||
if(mode == configured_items.len)
|
||||
mode = 1
|
||||
else
|
||||
mode++
|
||||
to_chat(user, "Changed dispensing mode to '" + configured_items[mode][1] + "'")
|
||||
|
||||
|
||||
/obj/item/rsf/afterattack(atom/A, mob/user as mob, proximity)
|
||||
if(!proximity) return
|
||||
if(!(istype(A, /obj/structure/table) || istype(A, /turf/simulated/floor)))
|
||||
return
|
||||
var spawn_location
|
||||
var/turf/T = get_turf(A)
|
||||
if(istype(T) && !T.density)
|
||||
spawn_location = T
|
||||
else
|
||||
to_chat(user, "The RSF can only create service items on tables, or floors.")
|
||||
return
|
||||
if(isrobot(user))
|
||||
var/mob/living/silicon/robot/engy = user
|
||||
if(!engy.cell.use(configured_items[mode][2]))
|
||||
to_chat(user, "<span class='warning'>Insufficient energy.</span>")
|
||||
return
|
||||
else
|
||||
if(!matter)
|
||||
to_chat(user, "<span class='warning'>Insufficient matter.</span>")
|
||||
return
|
||||
matter--
|
||||
to_chat(user, "The RSF now holds [matter]/30 fabrication-units.")
|
||||
desc = "A RSF. It currently holds [matter]/30 fabrication-units."
|
||||
|
||||
to_chat(user, "Dispensing " + configured_items[mode][1] + "...")
|
||||
playsound(loc, 'sound/machines/click.ogg', 10, 1)
|
||||
var/type_path = configured_items[mode][3]
|
||||
new type_path(spawn_location)
|
||||
/*
|
||||
CONTAINS:
|
||||
RSF
|
||||
*/
|
||||
|
||||
/obj/item/rsf
|
||||
name = "\improper Rapid-Service-Fabricator"
|
||||
desc = "A device used to rapidly deploy service items."
|
||||
icon = 'icons/obj/tools.dmi'
|
||||
icon_state = "rsf"
|
||||
opacity = 0
|
||||
density = 0
|
||||
anchored = 0.0
|
||||
var/matter = 0
|
||||
var/mode = 1
|
||||
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/list/configured_items = list()
|
||||
|
||||
/obj/item/rsf/New()
|
||||
..()
|
||||
desc = "A RSF. It currently holds [matter]/30 fabrication-units."
|
||||
// configured_items[ID_NUMBER] = list("Human-readable name", price in energy, /type/path)
|
||||
configured_items[++configured_items.len] = list("Dosh", 50, /obj/item/stack/spacecash/c10)
|
||||
configured_items[++configured_items.len] = list("Drinking Glass", 50, /obj/item/reagent_containers/food/drinks/drinkingglass)
|
||||
configured_items[++configured_items.len] = list("Paper", 50, /obj/item/paper)
|
||||
configured_items[++configured_items.len] = list("Pen", 50, /obj/item/pen)
|
||||
configured_items[++configured_items.len] = list("Dice Pack", 50, /obj/item/storage/pill_bottle/dice)
|
||||
configured_items[++configured_items.len] = list("Cigarette", 50, /obj/item/clothing/mask/cigarette)
|
||||
configured_items[++configured_items.len] = list("Snack - Newdles", 4000, /obj/item/reagent_containers/food/snacks/chinese/newdles)
|
||||
configured_items[++configured_items.len] = list("Snack - Donut", 4000, /obj/item/reagent_containers/food/snacks/donut)
|
||||
configured_items[++configured_items.len] = list("Snack - Chicken Soup", 4000, /obj/item/reagent_containers/food/drinks/chicken_soup)
|
||||
configured_items[++configured_items.len] = list("Snack - Turkey Burger", 4000, /obj/item/reagent_containers/food/snacks/tofuburger)
|
||||
|
||||
/obj/item/rsf/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
..()
|
||||
if(istype(W, /obj/item/rcd_ammo))
|
||||
if((matter + 10) > 30)
|
||||
to_chat(user, "The RSF cant hold any more matter.")
|
||||
return
|
||||
qdel(W)
|
||||
matter += 10
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 10, 1)
|
||||
to_chat(user, "The RSF now holds [matter]/30 fabrication-units.")
|
||||
desc = "A RSF. It currently holds [matter]/30 fabrication-units."
|
||||
return
|
||||
|
||||
/obj/item/rsf/attack_self(mob/user as mob)
|
||||
playsound(src.loc, 'sound/effects/pop.ogg', 50, 0)
|
||||
if(mode == configured_items.len)
|
||||
mode = 1
|
||||
else
|
||||
mode++
|
||||
to_chat(user, "Changed dispensing mode to '" + configured_items[mode][1] + "'")
|
||||
|
||||
|
||||
/obj/item/rsf/afterattack(atom/A, mob/user as mob, proximity)
|
||||
if(!proximity) return
|
||||
if(!(istype(A, /obj/structure/table) || istype(A, /turf/simulated/floor)))
|
||||
return
|
||||
var spawn_location
|
||||
var/turf/T = get_turf(A)
|
||||
if(istype(T) && !T.density)
|
||||
spawn_location = T
|
||||
else
|
||||
to_chat(user, "The RSF can only create service items on tables, or floors.")
|
||||
return
|
||||
if(isrobot(user))
|
||||
var/mob/living/silicon/robot/engy = user
|
||||
if(!engy.cell.use(configured_items[mode][2]))
|
||||
to_chat(user, "<span class='warning'>Insufficient energy.</span>")
|
||||
return
|
||||
else
|
||||
if(!matter)
|
||||
to_chat(user, "<span class='warning'>Insufficient matter.</span>")
|
||||
return
|
||||
matter--
|
||||
to_chat(user, "The RSF now holds [matter]/30 fabrication-units.")
|
||||
desc = "A RSF. It currently holds [matter]/30 fabrication-units."
|
||||
|
||||
to_chat(user, "Dispensing " + configured_items[mode][1] + "...")
|
||||
playsound(loc, 'sound/machines/click.ogg', 10, 1)
|
||||
var/type_path = configured_items[mode][3]
|
||||
new type_path(spawn_location)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -56,4 +56,4 @@
|
||||
amount = 1000
|
||||
|
||||
/obj/item/stack/spacecash/c1000000
|
||||
amount = 1000000
|
||||
amount = 1000000
|
||||
|
||||
@@ -261,4 +261,4 @@
|
||||
|
||||
|
||||
#undef CHRONO_BEAM_RANGE
|
||||
#undef CHRONO_FRAME_COUNT
|
||||
#undef CHRONO_FRAME_COUNT
|
||||
|
||||
@@ -426,4 +426,4 @@ LIGHTERS ARE IN LIGHTERS.DM
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to dry this first!</span>")
|
||||
else
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -1,58 +1,58 @@
|
||||
/* Clown Items
|
||||
* Contains:
|
||||
* Banana Peels
|
||||
* Soap
|
||||
* Bike Horns
|
||||
*/
|
||||
|
||||
/*
|
||||
* Bike Horns
|
||||
*/
|
||||
|
||||
/obj/item/bikehorn
|
||||
name = "bike horn"
|
||||
desc = "A horn off of a bicycle."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "bike_horn"
|
||||
item_state = "bike_horn"
|
||||
hitsound = null
|
||||
throwforce = 3
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/list/honk_sounds = list('sound/items/bikehorn.ogg' = 1)
|
||||
throw_speed = 3
|
||||
throw_range = 15
|
||||
attack_verb = list("HONKED")
|
||||
|
||||
/obj/item/bikehorn/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/squeak, honk_sounds, 50)
|
||||
|
||||
/obj/item/bikehorn/airhorn
|
||||
name = "air horn"
|
||||
desc = "Damn son, where'd you find this?"
|
||||
icon_state = "air_horn"
|
||||
origin_tech = "materials=4;engineering=4"
|
||||
honk_sounds = list('sound/items/airhorn2.ogg' = 1)
|
||||
|
||||
/obj/item/bikehorn/golden
|
||||
name = "golden bike horn"
|
||||
desc = "Golden? Clearly, its made with bananium! Honk!"
|
||||
icon_state = "gold_horn"
|
||||
item_state = "gold_horn"
|
||||
|
||||
/obj/item/bikehorn/golden/attack()
|
||||
flip_mobs()
|
||||
return ..()
|
||||
|
||||
/obj/item/bikehorn/golden/attack_self(mob/user)
|
||||
flip_mobs()
|
||||
..()
|
||||
|
||||
/obj/item/bikehorn/golden/proc/flip_mobs(mob/living/carbon/M, mob/user)
|
||||
var/turf/T = get_turf(src)
|
||||
for(M in ohearers(7, T))
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(!H.can_hear())
|
||||
continue
|
||||
M.emote("flip")
|
||||
/* Clown Items
|
||||
* Contains:
|
||||
* Banana Peels
|
||||
* Soap
|
||||
* Bike Horns
|
||||
*/
|
||||
|
||||
/*
|
||||
* Bike Horns
|
||||
*/
|
||||
|
||||
/obj/item/bikehorn
|
||||
name = "bike horn"
|
||||
desc = "A horn off of a bicycle."
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "bike_horn"
|
||||
item_state = "bike_horn"
|
||||
hitsound = null
|
||||
throwforce = 3
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/list/honk_sounds = list('sound/items/bikehorn.ogg' = 1)
|
||||
throw_speed = 3
|
||||
throw_range = 15
|
||||
attack_verb = list("HONKED")
|
||||
|
||||
/obj/item/bikehorn/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/squeak, honk_sounds, 50)
|
||||
|
||||
/obj/item/bikehorn/airhorn
|
||||
name = "air horn"
|
||||
desc = "Damn son, where'd you find this?"
|
||||
icon_state = "air_horn"
|
||||
origin_tech = "materials=4;engineering=4"
|
||||
honk_sounds = list('sound/items/airhorn2.ogg' = 1)
|
||||
|
||||
/obj/item/bikehorn/golden
|
||||
name = "golden bike horn"
|
||||
desc = "Golden? Clearly, its made with bananium! Honk!"
|
||||
icon_state = "gold_horn"
|
||||
item_state = "gold_horn"
|
||||
|
||||
/obj/item/bikehorn/golden/attack()
|
||||
flip_mobs()
|
||||
return ..()
|
||||
|
||||
/obj/item/bikehorn/golden/attack_self(mob/user)
|
||||
flip_mobs()
|
||||
..()
|
||||
|
||||
/obj/item/bikehorn/golden/proc/flip_mobs(mob/living/carbon/M, mob/user)
|
||||
var/turf/T = get_turf(src)
|
||||
for(M in ohearers(7, T))
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(!H.can_hear())
|
||||
continue
|
||||
M.emote("flip")
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user