Merge branch 'ParadiseSS13/master' into runtime-fix-2

This commit is contained in:
joep van der velden
2020-03-18 16:59:49 +01:00
1748 changed files with 191532 additions and 184661 deletions
+1 -1
View File
@@ -91,4 +91,4 @@
max_butts = 12
max_integrity = 12
materials = list(MAT_GLASS=60)
throwforce = 6
throwforce = 6
+77 -77
View File
@@ -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>")
+86 -99
View File
@@ -1,99 +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(istype(W, /obj/item/weldingtool))
var/obj/item/weldingtool/WT = W
if(WT.isOn()) //Badasses dont get blinded by lighting their candle with a welding tool
light("<span class='notice'>[user] casually lights [src] with [WT], what a badass.")
return
if(istype(W, /obj/item/lighter))
var/obj/item/lighter/L = W
if(L.lit)
light("<span class='notice'>After some fiddling, [user] manages to light [src] with [L].</span>")
return
if(istype(W, /obj/item/match))
var/obj/item/match/M = W
if(M.lit)
light("<span class='notice'>[user] lights [src] with [M]</span>")
return
if(istype(W, /obj/item/candle))
var/obj/item/candle/C = W
if(C.lit)
light("<span class='notice'>[user] tilts [C] and lights [src] with it.</span>")
return
return ..()
/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
+1 -1
View File
@@ -111,7 +111,7 @@
name = "civillian door remote"
icon_state = "gangtool-white"
region_access = list(REGION_GENERAL, REGION_SUPPLY)
additional_access = list(access_hop)
additional_access = list(ACCESS_HOP)
/obj/item/door_remote/centcomm
name = "centcomm door remote"
+287 -287
View File
@@ -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];'>&nbsp;&nbsp;&nbsp;</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];'>&nbsp;&nbsp;&nbsp;</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];'>&nbsp;&nbsp;&nbsp;</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];'>&nbsp;&nbsp;&nbsp;</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
+2 -2
View File
@@ -22,7 +22,7 @@
owned = 0
return ..()
/obj/item/toy/carpplushie/dehy_carp/water_act(volume, temperature, source, method = TOUCH)
/obj/item/toy/carpplushie/dehy_carp/water_act(volume, temperature, source, method = REAGENT_TOUCH)
. = ..()
if(volume >= 1)
Swell()
@@ -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)
+107 -107
View File
@@ -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
+258 -258
View File
@@ -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()
+398 -397
View File
@@ -1,397 +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
@@ -14,12 +14,12 @@
flags = CONDUCT
slot_flags = SLOT_BELT
var/static/list/allowed_states = list("arrival", "arrivalcorner", "bar", "barber", "blackcorner", "blue", "bluecorner",
var/static/list/allowed_states = list("arrival", "arrivalcorner", "bar", "barber", "bcircuit", "blackcorner", "blue", "bluecorner",
"bluefull", "bluered", "blueyellow", "blueyellowfull", "bot", "brown", "browncorner", "browncornerold", "brownold",
"cafeteria", "caution", "cautioncorner", "chapel", "cmo", "dark", "delivery", "escape", "escapecorner", "floor",
"freezerfloor", "green", "greenblue", "greenbluefull", "greencorner", "greenfull", "greenyellow",
"freezerfloor", "gcircuit", "green", "greenblue", "greenbluefull", "greencorner", "greenfull", "greenyellow",
"greenyellowfull", "grimy", "loadingarea", "neutral", "neutralcorner", "neutralfull", "orange", "orangecorner",
"orangefull", "purple", "purplecorner", "purplefull", "rampbottom", "ramptop", "red", "redblue", "redbluefull",
"orangefull", "purple", "purplecorner", "purplefull", "rcircuit", "rampbottom", "ramptop", "red", "redblue", "redbluefull",
"redcorner", "redfull", "redgreen", "redgreenfull", "redyellow", "redyellowfull", "warning", "warningcorner", "warnwhite",
"warnwhitecorner", "white", "whiteblue", "whitebluecorner", "whitebluefull", "whitebot", "whitecorner", "whitedelivery",
"whitegreen", "whitegreencorner", "whitegreenfull", "whitehall", "whitepurple", "whitepurplecorner", "whitepurplefull",
@@ -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)
@@ -167,7 +167,7 @@
reqs = list(/obj/item/stack/sheet/wood = 5,
/obj/item/stack/cable_coil = 6,
/obj/item/stack/tape_roll = 5)
tools = list(/obj/item/screwdriver, /obj/item/wirecutters)
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
time = 80
category = CAT_MISC
@@ -177,7 +177,7 @@
reqs = list(/obj/item/stack/sheet/wood = 5,
/obj/item/stack/cable_coil = 6,
/obj/item/stack/tape_roll = 5)
tools = list(/obj/item/screwdriver, /obj/item/wirecutters)
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
time = 80
category = CAT_MISC
@@ -187,6 +187,6 @@
reqs = list(/obj/item/stack/sheet/metal = 5,
/obj/item/stack/cable_coil = 6,
/obj/item/stack/tape_roll = 5)
tools = list(/obj/item/screwdriver, /obj/item/wirecutters)
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
time = 80
category = CAT_MISC
category = CAT_MISC
+269 -269
View File
@@ -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
+340 -340
View File
@@ -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
+153 -153
View File
@@ -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/attackby(obj/item/I, mob/user)
if(isscrewdriver(I))
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>")
else
return ..()
/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
+106 -106
View File
@@ -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
+426 -425
View File
@@ -1,425 +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)
user.set_machine(src)
if(!( istype(W, /obj/item/screwdriver) || (istype(W, /obj/item/encryptionkey/ ))))
return ..()
if(istype(W, /obj/item/screwdriver))
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!")
else
to_chat(user, "This headset doesn't have any encryption keys! How useless...")
if(istype(W, /obj/item/encryptionkey/))
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()
return
/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()
+274 -268
View File
@@ -1,268 +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
switch(buildstage)
if(3)
if(iswirecutter(W) && b_stat && wires.IsAllCut())
to_chat(user, "<span class='notice'>You cut out the intercoms wiring and disconnect its electronics.</span>")
playsound(get_turf(src), W.usesound, 50, 1)
if(do_after(user, 10 * W.toolspeed, target = src))
if(buildstage != 3)
return
new /obj/item/stack/cable_coil(get_turf(src),5)
on = 0
b_stat = 1
buildstage = 1
update_icon()
STOP_PROCESSING(SSobj, src)
return 1
else return ..()
if(2)
if(isscrewdriver(W))
playsound(get_turf(src), W.usesound, 50, 1)
if(do_after(user, 10 * W.toolspeed, target = src))
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)
return 1
if(1)
if(iscoil(W))
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))
coil.use(5)
to_chat(user, "<span class='notice'>You wire \the [src]!</span>")
buildstage = 2
return 1
if(iscrowbar(W))
to_chat(user, "<span class='notice'>You begin removing the electronics...</span>")
playsound(get_turf(src), W.usesound, 50, 1)
if(do_after(user, 10 * W.toolspeed, target = src))
if(buildstage != 1)
return
new /obj/item/intercom_electronics(get_turf(src))
to_chat(user, "<span class='notice'>The circuitboard pops out!</span>")
buildstage = 0
return 1
if(0)
if(istype(W,/obj/item/intercom_electronics))
playsound(get_turf(src), W.usesound, 50, 1)
if(do_after(user, 10 * W.toolspeed, target = src))
qdel(W)
to_chat(user, "<span class='notice'>You insert \the [W] into \the [src]!</span>")
buildstage = 1
return 1
if(iswelder(W))
var/obj/item/weldingtool/WT=W
playsound(get_turf(src), WT.usesound, 50, 1)
if(!WT.remove_fuel(3, user))
to_chat(user, "<span class='warning'>You're out of welding fuel.</span>")
return 1
if(do_after(user, 10 * WT.toolspeed, target = src))
to_chat(user, "<span class='notice'>You cut the intercom frame from the wall!</span>")
new /obj/item/mounted/frame/intercom(get_turf(src))
qdel(src)
return 1
/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(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
@@ -9,6 +9,7 @@
var/datum/nano_module/crew_monitor/crew_monitor
/obj/item/sensor_device/New()
..()
crew_monitor = new(src)
/obj/item/sensor_device/Destroy()
+324 -320
View File
@@ -1,320 +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
/obj/item/taperecorder/New()
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/New()
return
/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")]"
@@ -10,6 +10,7 @@
var/datum/effect_system/spark_spread/spark_system
/obj/item/thermal_drill/New()
..()
soundloop = new(list(src), FALSE)
spark_system = new /datum/effect_system/spark_spread()
spark_system.set_up(1, 0, src)
@@ -24,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
+220 -220
View File
@@ -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()
+3 -1
View File
@@ -316,6 +316,7 @@ var/list/world_uplinks = list()
// implant uplink (not the implant tool) and a preset headset uplink.
/obj/item/radio/uplink/New()
..()
hidden_uplink = new(src)
icon_state = "radio"
@@ -339,6 +340,7 @@ var/list/world_uplinks = list()
hidden_uplink.uplink_type = "sst"
/obj/item/multitool/uplink/New()
..()
hidden_uplink = new(src)
/obj/item/multitool/uplink/attack_self(mob/user as mob)
@@ -351,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
+1 -1
View File
@@ -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>")
+1 -1
View File
@@ -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 ..()
+16 -13
View File
@@ -197,7 +197,7 @@
name = "Chameleon flag"
desc = "A poor recreation of the official NT flag. It seems to shimmer a little."
icon_state = "ntflag"
origin_tech = "syndicate=4;magnets=4"
origin_tech = "syndicate=1;magnets=4"
var/updated_icon_state = null
var/used = FALSE
var/obj/item/grenade/boobytrap = null
@@ -245,22 +245,25 @@
message_admins("[key_name_admin(user)] has hidden [I] in the [src] ready for detonation at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a>.")
log_game("[key_name(user)] has hidden [I] in the [src] ready for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).")
investigate_log("[key_name(user)] has hidden [I] in the [src] ready for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).", INVESTIGATE_BOMB)
else if(isscrewdriver(I) && boobytrap && user == trapper)
to_chat(user, "<span class='notice'>You remove [boobytrap] from the [src].</span>")
boobytrap.forceMove(get_turf(src))
boobytrap = null
trapper = null
else
return ..()
/obj/item/flag/chameleon/attackby(obj/item/W, mob/user, params)
if(is_hot(W) && !(resistance_flags & ON_FIRE) && boobytrap && trapper)
else if(is_hot(I) && !(resistance_flags & ON_FIRE) && boobytrap && trapper)
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
message_admins("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a>.")
log_game("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).")
investigate_log("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).", INVESTIGATE_BOMB)
return ..()
else
return ..()
/obj/item/flag/chameleon/screwdriver_act(mob/user, obj/item/I)
if(!boobytrap || user != trapper)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
to_chat(user, "<span class='notice'>You remove [boobytrap] from [src].</span>")
boobytrap.forceMove(get_turf(src))
boobytrap = null
trapper = null
/obj/item/flag/chameleon/burn()
if(boobytrap)
@@ -272,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)
+65 -65
View File
@@ -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()
+1 -1
View File
@@ -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)
+4 -4
View File
@@ -160,7 +160,7 @@
/obj/structure/closet/crate/secure/unknownchemicals
name = "grey-market chemicals grab pack"
desc = "Crate full of chemicals of unknown type and value from a 'trusted' source."
req_one_access = list(access_chemistry,access_research,access_qm) // the qm knows a guy, you see.
req_one_access = list(ACCESS_CHEMISTRY,ACCESS_RESEARCH,ACCESS_QM) // the qm knows a guy, you see.
/obj/structure/closet/crate/secure/unknownchemicals/New()
..()
@@ -178,7 +178,7 @@
/obj/structure/closet/crate/secure/chemicals
name = "chemical supply kit"
desc = "Full of basic chemistry supplies."
req_one_access = list(access_chemistry,access_research)
req_one_access = list(ACCESS_CHEMISTRY,ACCESS_RESEARCH)
/obj/structure/closet/crate/secure/chemicals/New()
..()
@@ -233,7 +233,7 @@
/obj/structure/closet/secure_closet/random_drinks
name = "unlabelled booze closet"
req_access = list(access_bar)
req_access = list(ACCESS_BAR)
icon_state = "cabinetdetective_locked"
icon_closed = "cabinetdetective"
icon_locked = "cabinetdetective_locked"
@@ -321,4 +321,4 @@
..()
for(var/i in 1 to 6)
var/nade = pick(grenadelist)
new nade(src)
new nade(src)
+37 -37
View File
@@ -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"
+177 -180
View File
@@ -1,180 +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/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/weldingtool))
var/obj/item/weldingtool/WT = W
if(WT.remove_fuel(0, user))
overlays.Cut()
to_chat(usr, "You slice off [src]'s uneven chunks of aluminum and scorch marks.")
return
/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)
+283 -283
View File
@@ -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
+68 -74
View File
@@ -1,74 +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/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/weldingtool))
var/obj/item/weldingtool/WT = W
if(get_amount() < 2)
to_chat(user, "<span class='warning'>You need at least two rods to do this!</span>")
return
if(WT.remove_fuel(0,user))
var/obj/item/stack/sheet/metal/new_item = new(user.loc)
if(new_item.get_amount() <= 0)
// stack was moved into another one on the pile
new_item = locate() in user.loc
user.visible_message("[user.name] shape [src] into metal with the welding tool.", \
"<span class='notice'>You shape [src] into metal with the welding tool.</span>", \
"<span class='italics'>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)
return
..()
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)
+211 -211
View File
@@ -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
..()
+242 -242
View File
@@ -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 = 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)
+37 -37
View File
@@ -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)
+389 -391
View File
@@ -1,391 +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/attackby(obj/item/W, mob/user, params)
if(is_hot(W) > 300)//If the temperature of the object is over 300, then ignite
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()
else
return ..()
/obj/item/stack/sheet/mineral/plasma/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE)
..()
atmos_spawn_air(SPAWN_HEAT | 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
..()
+18 -18
View File
@@ -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.
+8 -2
View File
@@ -222,7 +222,7 @@
interact(usr)
return
/obj/item/stack/proc/use(used, check = TRUE)
/obj/item/stack/use(used, check = TRUE)
if(check && zero_amount())
return FALSE
if(amount < used)
@@ -296,6 +296,8 @@
else
return ..()
// Returns TRUE if the stack amount is zero.
// Also qdels the stack gracefully if it is.
/obj/item/stack/proc/zero_amount()
if(amount < 1)
if(isrobot(loc))
@@ -305,7 +307,11 @@
if(ismob(loc))
var/mob/living/L = loc // At this stage, stack code is so horrible and atrocious, I wouldn't be all surprised ghosts can somehow have stacks. If this happens, then the world deserves to burn.
L.unEquip(src, TRUE)
qdel(src)
if(amount < 1)
// If you stand on top of a stack, and drop a - different - 0-amount stack on the floor,
// the two get merged, so the amount of items in the stack can increase from the 0 that it had before.
// Check the amount again, to be sure we're not qdeling healthy stacks.
qdel(src)
return TRUE
return FALSE
@@ -8,6 +8,16 @@
mineralType = "plasma"
materials = list(MAT_PLASMA=500)
/obj/item/stack/tile/mineral/plasma/welder_act(mob/user, obj/item/I)
if(I.use_tool(src, user, volume = I.tool_volume))
atmos_spawn_air(LINDA_SPAWN_HEAT | LINDA_SPAWN_TOXINS, 5)
user.visible_message("<span class='warning'>[user.name] sets the plasma tiles on fire!</span>", \
"<span class='warning'>You set the plasma tiles on fire!</span>")
message_admins("Plasma tiles ignited by [key_name_admin(user)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) in ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
log_game("Plasma tiles ignited by [key_name(user)] in ([x],[y],[z])")
investigate_log("was <font color='red'><b>ignited</b></font> by [key_name(user)]","atmos")
qdel(src)
/obj/item/stack/tile/mineral/uranium
name = "uranium tile"
singular_name = "uranium floor tile"
@@ -133,4 +143,4 @@ var/global/list/datum/stack_recipe/silverfancy_tile_recipes = list ( \
icon_state = "tile_darkshuttle"
turf_type = /turf/simulated/floor/mineral/plastitanium
mineralType = "plastitanium"
materials = list(MAT_TITANIUM=250, MAT_PLASMA=250)
materials = list(MAT_TITANIUM=250, MAT_PLASMA=250)
+168 -199
View File
@@ -1,199 +1,168 @@
/obj/item/stack/tile
name = "broken tile"
singular_name = "broken tile"
desc = "A broken tile. This should not exist."
icon = 'icons/obj/tiles.dmi'
icon_state = "tile"
item_state = "tile"
w_class = WEIGHT_CLASS_NORMAL
force = 1
throwforce = 1
throw_speed = 5
throw_range = 20
max_amount = 60
flags = CONDUCT
origin_tech = "materials=1"
var/turf_type = null
var/mineralType = null
/obj/item/stack/tile/New(loc, amount)
..()
pixel_x = rand(-3, 3)
pixel_y = rand(-3, 3) //randomize a little
/obj/item/stack/tile/attackby(obj/item/W, mob/user, params)
if(iswelder(W))
var/obj/item/weldingtool/WT = W
if(is_hot(W) && !mineralType)
to_chat(user, "<span class='warning'>You can not reform this!</span>")
return
if(get_amount() < 4)
to_chat(user, "<span class='warning'>You need at least four tiles to do this!</span>")
return
if(WT.remove_fuel(0,user))
if(mineralType == "plasma")
atmos_spawn_air(SPAWN_HEAT | SPAWN_TOXINS, 5)
user.visible_message("<span class='warning'>[user.name] sets the plasma tiles on fire!</span>", \
"<span class='warning'>You set the plasma tiles on fire!</span>")
message_admins("Plasma tiles ignited by [key_name_admin(user)](<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[user]'>FLW</A>) in ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
log_game("Plasma tiles ignited by [key_name(user)] in ([x],[y],[z])")
investigate_log("was <font color='red'><b>ignited</b></font> by [key_name(user)]","atmos")
qdel(src)
return
if (mineralType == "metal")
var/obj/item/stack/sheet/metal/new_item = new(user.loc)
user.visible_message("[user.name] shaped [src] into metal with the welding tool.", \
"<span class='notice'>You shaped [src] into metal with the welding tool.</span>", \
"<span class='italics'>You hear welding.</span>")
var/obj/item/stack/rods/R = src
src = null
var/replace = (user.get_inactive_hand()==R)
R.use(4)
if(!R && replace)
user.put_in_hands(new_item)
else
var/sheet_type = text2path("/obj/item/stack/sheet/mineral/[mineralType]")
var/obj/item/stack/sheet/mineral/new_item = new sheet_type(user.loc)
user.visible_message("[user.name] shaped [src] into a sheet with the welding tool.", \
"<span class='notice'>You shaped [src] into a sheet with the welding tool.</span>", \
"<span class='italics'>You hear welding.</span>")
var/obj/item/stack/rods/R = src
src = null
var/replace = (user.get_inactive_hand()==R)
R.use(4)
if (!R && replace)
user.put_in_hands(new_item)
else
return ..()
//Grass
/obj/item/stack/tile/grass
name = "grass tiles"
gender = PLURAL
singular_name = "grass floor tile"
desc = "A patch of grass like they often use on golf courses"
icon_state = "tile_grass"
origin_tech = "biotech=1"
turf_type = /turf/simulated/floor/grass
resistance_flags = FLAMMABLE
//Wood
/obj/item/stack/tile/wood
name = "wood floor tiles"
gender = PLURAL
singular_name = "wood floor tile"
desc = "an easy to fit wood floor tile"
icon_state = "tile-wood"
origin_tech = "biotech=1"
turf_type = /turf/simulated/floor/wood
resistance_flags = FLAMMABLE
//Carpets
/obj/item/stack/tile/carpet
name = "carpet"
singular_name = "carpet"
desc = "A piece of carpet. It is the same size as a floor tile"
icon_state = "tile-carpet"
turf_type = /turf/simulated/floor/carpet
resistance_flags = FLAMMABLE
/obj/item/stack/tile/carpet/black
name = "black carpet"
icon_state = "tile-carpet-black"
turf_type = /turf/simulated/floor/carpet/black
//Plasteel
/obj/item/stack/tile/plasteel
name = "floor tiles"
gender = PLURAL
singular_name = "floor tile"
desc = "Those could work as a pretty decent throwing weapon."
icon_state = "tile"
force = 6
materials = list(MAT_METAL=500)
throwforce = 10
throw_speed = 3
throw_range = 7
flags = CONDUCT
turf_type = /turf/simulated/floor/plasteel
mineralType = "metal"
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70)
resistance_flags = FIRE_PROOF
//Light
/obj/item/stack/tile/light
name = "light tiles"
gender = PLURAL
singular_name = "light floor tile"
desc = "A floor tile, made out off glass. Use a multitool on it to change its color."
icon_state = "tile_light blue"
force = 3
throwforce = 5
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed")
turf_type = /turf/simulated/floor/light
//Fakespace
/obj/item/stack/tile/fakespace
name = "astral carpet"
singular_name = "astral carpet"
desc = "A piece of carpet with a convincing star pattern."
icon_state = "tile_space"
turf_type = /turf/simulated/floor/fakespace
resistance_flags = FLAMMABLE
merge_type = /obj/item/stack/tile/fakespace
/obj/item/stack/tile/fakespace/loaded
amount = 30
//High-traction
/obj/item/stack/tile/noslip
name = "high-traction floor tile"
singular_name = "high-traction floor tile"
desc = "A high-traction floor tile. It feels rubbery in your hand."
icon_state = "tile_noslip"
turf_type = /turf/simulated/floor/noslip
origin_tech = "materials=3"
merge_type = /obj/item/stack/tile/noslip
/obj/item/stack/tile/noslip/loaded
amount = 20
//Pod floor
/obj/item/stack/tile/pod
name = "pod floor tile"
singular_name = "pod floor tile"
desc = "A grooved floor tile."
icon_state = "tile_pod"
turf_type = /turf/simulated/floor/pod
/obj/item/stack/tile/pod/light
name = "light pod floor tile"
singular_name = "light pod floor tile"
desc = "A lightly colored grooved floor tile."
icon_state = "tile_podlight"
turf_type = /turf/simulated/floor/pod
/obj/item/stack/tile/pod/dark
name = "dark pod floor tile"
singular_name = "dark pod floor tile"
desc = "A darkly colored grooved floor tile."
icon_state = "tile_poddark"
turf_type = /turf/simulated/floor/pod/dark
/obj/item/stack/tile/arcade_carpet
name = "arcade carpet"
singular_name = "arcade carpet"
desc= "A piece of carpet with a retro spaceship pattern."
icon_state = "tile_space"
turf_type = /turf/simulated/floor/carpet/arcade
merge_type = /obj/item/stack/tile/arcade_carpet
resistance_flags = FLAMMABLE
/obj/item/stack/tile/arcade_carpet/loaded
amount = 20
/obj/item/stack/tile
name = "broken tile"
singular_name = "broken tile"
desc = "A broken tile. This should not exist."
icon = 'icons/obj/tiles.dmi'
icon_state = "tile"
item_state = "tile"
w_class = WEIGHT_CLASS_NORMAL
force = 1
throwforce = 1
throw_speed = 5
throw_range = 20
max_amount = 60
flags = CONDUCT
origin_tech = "materials=1"
var/turf_type = null
var/mineralType = null
/obj/item/stack/tile/New(loc, amount)
..()
pixel_x = rand(-3, 3)
pixel_y = rand(-3, 3) //randomize a little
/obj/item/stack/tile/welder_act(mob/user, obj/item/I)
if(get_amount() < 4)
to_chat(user, "<span class='warning'>You need at least four tiles to do this!</span>")
return
. = TRUE
if(!I.use_tool(src, user, volume = I.tool_volume))
to_chat(user, "<span class='warning'>You can not reform this!</span>")
return
if (mineralType == "metal")
var/obj/item/stack/sheet/metal/new_item = new(user.loc)
user.visible_message("[user.name] shaped [src] into metal with the welding tool.", \
"<span class='notice'>You shaped [src] into metal with the welding tool.</span>", \
"<span class='italics'>You hear welding.</span>")
var/obj/item/stack/rods/R = src
src = null
var/replace = (user.get_inactive_hand()==R)
R.use(4)
if(!R && replace)
user.put_in_hands(new_item)
//Grass
/obj/item/stack/tile/grass
name = "grass tiles"
gender = PLURAL
singular_name = "grass floor tile"
desc = "A patch of grass like they often use on golf courses"
icon_state = "tile_grass"
origin_tech = "biotech=1"
turf_type = /turf/simulated/floor/grass
resistance_flags = FLAMMABLE
//Wood
/obj/item/stack/tile/wood
name = "wood floor tiles"
gender = PLURAL
singular_name = "wood floor tile"
desc = "an easy to fit wood floor tile"
icon_state = "tile-wood"
origin_tech = "biotech=1"
turf_type = /turf/simulated/floor/wood
resistance_flags = FLAMMABLE
//Carpets
/obj/item/stack/tile/carpet
name = "carpet"
singular_name = "carpet"
desc = "A piece of carpet. It is the same size as a floor tile"
icon_state = "tile-carpet"
turf_type = /turf/simulated/floor/carpet
resistance_flags = FLAMMABLE
/obj/item/stack/tile/carpet/black
name = "black carpet"
icon_state = "tile-carpet-black"
turf_type = /turf/simulated/floor/carpet/black
//Plasteel
/obj/item/stack/tile/plasteel
name = "floor tiles"
gender = PLURAL
singular_name = "floor tile"
desc = "Those could work as a pretty decent throwing weapon."
icon_state = "tile"
force = 6
materials = list(MAT_METAL=500)
throwforce = 10
throw_speed = 3
throw_range = 7
flags = CONDUCT
turf_type = /turf/simulated/floor/plasteel
mineralType = "metal"
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70)
resistance_flags = FIRE_PROOF
//Light
/obj/item/stack/tile/light
name = "light tiles"
gender = PLURAL
singular_name = "light floor tile"
desc = "A floor tile, made out off glass. Use a multitool on it to change its color."
icon_state = "tile_light blue"
force = 3
throwforce = 5
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "smashed")
turf_type = /turf/simulated/floor/light
//Fakespace
/obj/item/stack/tile/fakespace
name = "astral carpet"
singular_name = "astral carpet"
desc = "A piece of carpet with a convincing star pattern."
icon_state = "tile_space"
turf_type = /turf/simulated/floor/fakespace
resistance_flags = FLAMMABLE
merge_type = /obj/item/stack/tile/fakespace
/obj/item/stack/tile/fakespace/loaded
amount = 30
//High-traction
/obj/item/stack/tile/noslip
name = "high-traction floor tile"
singular_name = "high-traction floor tile"
desc = "A high-traction floor tile. It feels rubbery in your hand."
icon_state = "tile_noslip"
turf_type = /turf/simulated/floor/noslip
origin_tech = "materials=3"
merge_type = /obj/item/stack/tile/noslip
/obj/item/stack/tile/noslip/loaded
amount = 20
//Pod floor
/obj/item/stack/tile/pod
name = "pod floor tile"
singular_name = "pod floor tile"
desc = "A grooved floor tile."
icon_state = "tile_pod"
turf_type = /turf/simulated/floor/pod
/obj/item/stack/tile/pod/light
name = "light pod floor tile"
singular_name = "light pod floor tile"
desc = "A lightly colored grooved floor tile."
icon_state = "tile_podlight"
turf_type = /turf/simulated/floor/pod
/obj/item/stack/tile/pod/dark
name = "dark pod floor tile"
singular_name = "dark pod floor tile"
desc = "A darkly colored grooved floor tile."
icon_state = "tile_poddark"
turf_type = /turf/simulated/floor/pod/dark
/obj/item/stack/tile/arcade_carpet
name = "arcade carpet"
singular_name = "arcade carpet"
desc= "A piece of carpet with a retro spaceship pattern."
icon_state = "tile_space"
turf_type = /turf/simulated/floor/carpet/arcade
merge_type = /obj/item/stack/tile/arcade_carpet
resistance_flags = FLAMMABLE
/obj/item/stack/tile/arcade_carpet/loaded
amount = 20
+85
View File
@@ -0,0 +1,85 @@
/obj/item/crowbar
name = "pocket crowbar"
desc = "A small crowbar. This handy tool is useful for lots of things, such as prying floor tiles or opening unpowered doors."
icon = 'icons/obj/tools.dmi'
icon_state = "crowbar"
item_state = "crowbar"
usesound = 'sound/items/crowbar.ogg'
flags = CONDUCT
slot_flags = SLOT_BELT
force = 5
throwforce = 7
item_state = "crowbar"
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=50)
origin_tech = "engineering=1;combat=1"
attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked")
toolspeed = 1
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30)
tool_behaviour = TOOL_CROWBAR
/obj/item/crowbar/red
icon_state = "crowbar_red"
item_state = "crowbar_red"
force = 8
/obj/item/crowbar/brass
name = "brass crowbar"
desc = "A brass crowbar. It feels faintly warm to the touch."
icon_state = "crowbar_brass"
item_state = "crowbar_brass"
toolspeed = 0.5
resistance_flags = FIRE_PROOF | ACID_PROOF
/obj/item/crowbar/abductor
name = "alien crowbar"
desc = "A hard-light crowbar. It appears to pry by itself, without any effort required."
icon = 'icons/obj/abductor.dmi'
usesound = 'sound/weapons/sonic_jackhammer.ogg'
icon_state = "crowbar"
toolspeed = 0.1
origin_tech = "combat=4;engineering=4;abductor=3"
/obj/item/crowbar/large
name = "crowbar"
desc = "It's a big crowbar. It doesn't fit in your pockets, because its too big."
force = 12
w_class = WEIGHT_CLASS_NORMAL
throw_speed = 3
throw_range = 3
materials = list(MAT_METAL=70)
icon_state = "crowbar_large"
item_state = "crowbar_large"
toolspeed = 0.5
/obj/item/crowbar/cyborg
name = "hydraulic crowbar"
desc = "A hydraulic prying tool, compact but powerful. Designed to replace crowbar in construction cyborgs."
usesound = 'sound/items/jaws_pry.ogg'
force = 10
toolspeed = 0.5
/obj/item/crowbar/power
name = "jaws of life"
desc = "A set of jaws of life, the magic of science has managed to fit it down into a device small enough to fit in a tool belt. It's fitted with a prying head."
icon_state = "jaws_pry"
item_state = "jawsoflife"
materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25)
origin_tech = "materials=2;engineering=2"
usesound = 'sound/items/jaws_pry.ogg'
force = 15
toolspeed = 0.25
var/airlock_open_time = 100 // Time required to open powered airlocks
/obj/item/crowbar/power/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is putting [user.p_their()] head in [src]. It looks like [user.p_theyre()] trying to commit suicide!</span>")
playsound(loc, 'sound/items/jaws_pry.ogg', 50, 1, -1)
return BRUTELOSS
/obj/item/crowbar/power/attack_self(mob/user)
playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1)
var/obj/item/wirecutters/power/cutjaws = new /obj/item/wirecutters/power
to_chat(user, "<span class='notice'>You attach the cutting jaws to [src].</span>")
qdel(src)
user.put_in_active_hand(cutjaws)
@@ -1,111 +1,121 @@
#define PROXIMITY_NONE ""
#define PROXIMITY_ON_SCREEN "_red"
#define PROXIMITY_NEAR "_yellow"
/**
* Multitool -- A multitool is used for hacking electronic devices.
* TO-DO -- Using it as a power measurement tool for cables etc. Nannek.
*
*/
/obj/item/multitool
name = "multitool"
desc = "Used for pulsing wires to test which to cut. Not recommended by doctors."
icon = 'icons/obj/device.dmi'
icon_state = "multitool"
flags = CONDUCT
force = 5.0
w_class = WEIGHT_CLASS_SMALL
throwforce = 0
throw_range = 7
throw_speed = 3
materials = list(MAT_METAL=50, MAT_GLASS=20)
origin_tech = "magnets=1;engineering=2"
toolspeed = 1
hitsound = 'sound/weapons/tap.ogg'
var/shows_wire_information = FALSE // shows what a wire does if set to TRUE
var/obj/machinery/buffer // simple machine buffer for device linkage
/obj/item/multitool/proc/IsBufferA(var/typepath)
if(!buffer)
return 0
return istype(buffer,typepath)
// Syndicate device disguised as a multitool; it will turn red when an AI camera is nearby.
/obj/item/multitool/Destroy()
buffer = null
return ..()
/obj/item/multitool/ai_detect
var/track_cooldown = 0
var/track_delay = 10 //How often it checks for proximity
var/detect_state = PROXIMITY_NONE
var/rangealert = 8 //Glows red when inside
var/rangewarning = 20 //Glows yellow when inside
origin_tech = "magnets=1;engineering=2;syndicate=1"
/obj/item/multitool/ai_detect/New()
..()
START_PROCESSING(SSobj, src)
/obj/item/multitool/ai_detect/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/multitool/ai_detect/process()
if(track_cooldown > world.time)
return
detect_state = PROXIMITY_NONE
multitool_detect()
icon_state = "[initial(icon_state)][detect_state]"
track_cooldown = world.time + track_delay
/obj/item/multitool/ai_detect/proc/multitool_detect()
var/turf/our_turf = get_turf(src)
for(var/mob/living/silicon/ai/AI in ai_list)
if(AI.cameraFollow == src)
detect_state = PROXIMITY_ON_SCREEN
break
if(!detect_state && cameranet.chunkGenerated(our_turf.x, our_turf.y, our_turf.z))
var/datum/camerachunk/chunk = cameranet.getCameraChunk(our_turf.x, our_turf.y, our_turf.z)
if(chunk)
if(chunk.seenby.len)
for(var/mob/camera/aiEye/A in chunk.seenby)
var/turf/detect_turf = get_turf(A)
if(get_dist(our_turf, detect_turf) < rangealert)
detect_state = PROXIMITY_ON_SCREEN
break
if(get_dist(our_turf, detect_turf) < rangewarning)
detect_state = PROXIMITY_NEAR
break
/obj/item/multitool/ai_detect/admin
desc = "Used for pulsing wires to test which to cut. Not recommended by doctors. Has a strange tag that says 'Grief in Safety'" //What else should I say for a meme item?
track_delay = 5
shows_wire_information = TRUE
/obj/item/multitool/ai_detect/admin/multitool_detect()
var/turf/our_turf = get_turf(src)
for(var/mob/J in urange(rangewarning,our_turf))
if(check_rights(R_ADMIN, 0, J))
detect_state = PROXIMITY_NEAR
var/turf/detect_turf = get_turf(J)
if(get_dist(our_turf, detect_turf) < rangealert)
detect_state = PROXIMITY_ON_SCREEN
break
/obj/item/multitool/cyborg
name = "multitool"
desc = "Optimised and stripped-down version of a regular multitool."
toolspeed = 0.5
/obj/item/multitool/abductor
name = "alien multitool"
desc = "An omni-technological interface."
icon = 'icons/obj/abductor.dmi'
icon_state = "multitool"
toolspeed = 0.1
origin_tech = "magnets=5;engineering=5;abductor=3"
shows_wire_information = TRUE
#define PROXIMITY_NONE ""
#define PROXIMITY_ON_SCREEN "_red"
#define PROXIMITY_NEAR "_yellow"
/**
* Multitool -- A multitool is used for hacking electronic devices.
*/
/obj/item/multitool
name = "multitool"
desc = "Used for pulsing wires to test which to cut. Not recommended by doctors."
icon = 'icons/obj/device.dmi'
icon_state = "multitool"
flags = CONDUCT
force = 5.0
w_class = WEIGHT_CLASS_SMALL
throwforce = 0
throw_range = 7
throw_speed = 3
materials = list(MAT_METAL=50, MAT_GLASS=20)
origin_tech = "magnets=1;engineering=2"
toolspeed = 1
tool_behaviour = TOOL_MULTITOOL
hitsound = 'sound/weapons/tap.ogg'
var/shows_wire_information = FALSE // shows what a wire does if set to TRUE
var/obj/machinery/buffer // simple machine buffer for device linkage
/obj/item/multitool/proc/IsBufferA(var/typepath)
if(!buffer)
return 0
return istype(buffer,typepath)
/obj/item/multitool/multitool_check_buffer(user, silent = FALSE)
return TRUE
/obj/item/multitool/proc/set_multitool_buffer(mob/user, obj/machinery/M) //Loads a machine into memory, returns TRUE if it does
if(!ismachinery(M))
to_chat(user, "<span class='warning'>That's not a machine!</span>")
return
buffer = M
to_chat(user, "<span class='notice'>You load [M] into [src]'s internal buffer.</span>")
return TRUE
// Syndicate device disguised as a multitool; it will turn red when an AI camera is nearby.
/obj/item/multitool/Destroy()
buffer = null
return ..()
/obj/item/multitool/ai_detect
var/track_cooldown = 0
var/track_delay = 10 //How often it checks for proximity
var/detect_state = PROXIMITY_NONE
var/rangealert = 8 //Glows red when inside
var/rangewarning = 20 //Glows yellow when inside
origin_tech = "magnets=1;engineering=2;syndicate=1"
/obj/item/multitool/ai_detect/New()
..()
START_PROCESSING(SSobj, src)
/obj/item/multitool/ai_detect/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/multitool/ai_detect/process()
if(track_cooldown > world.time)
return
detect_state = PROXIMITY_NONE
multitool_detect()
icon_state = "[initial(icon_state)][detect_state]"
track_cooldown = world.time + track_delay
/obj/item/multitool/ai_detect/proc/multitool_detect()
var/turf/our_turf = get_turf(src)
for(var/mob/living/silicon/ai/AI in ai_list)
if(AI.cameraFollow == src)
detect_state = PROXIMITY_ON_SCREEN
break
if(!detect_state && cameranet.chunkGenerated(our_turf.x, our_turf.y, our_turf.z))
var/datum/camerachunk/chunk = cameranet.getCameraChunk(our_turf.x, our_turf.y, our_turf.z)
if(chunk)
if(chunk.seenby.len)
for(var/mob/camera/aiEye/A in chunk.seenby)
var/turf/detect_turf = get_turf(A)
if(get_dist(our_turf, detect_turf) < rangealert)
detect_state = PROXIMITY_ON_SCREEN
break
if(get_dist(our_turf, detect_turf) < rangewarning)
detect_state = PROXIMITY_NEAR
break
/obj/item/multitool/ai_detect/admin
desc = "Used for pulsing wires to test which to cut. Not recommended by doctors. Has a strange tag that says 'Grief in Safety'" //What else should I say for a meme item?
track_delay = 5
shows_wire_information = TRUE
/obj/item/multitool/ai_detect/admin/multitool_detect()
var/turf/our_turf = get_turf(src)
for(var/mob/J in urange(rangewarning,our_turf))
if(check_rights(R_ADMIN, 0, J))
detect_state = PROXIMITY_NEAR
var/turf/detect_turf = get_turf(J)
if(get_dist(our_turf, detect_turf) < rangealert)
detect_state = PROXIMITY_ON_SCREEN
break
/obj/item/multitool/cyborg
name = "multitool"
desc = "Optimised and stripped-down version of a regular multitool."
toolspeed = 0.5
/obj/item/multitool/abductor
name = "alien multitool"
desc = "An omni-technological interface."
icon = 'icons/obj/abductor.dmi'
icon_state = "multitool"
toolspeed = 0.1
origin_tech = "magnets=5;engineering=5;abductor=3"
shows_wire_information = TRUE
@@ -0,0 +1,101 @@
//Screwdriver
/obj/item/screwdriver
name = "screwdriver"
desc = "You can be totally screwy with this."
icon = 'icons/obj/tools.dmi'
icon_state = "screwdriver_map"
flags = CONDUCT
slot_flags = SLOT_BELT
force = 5
w_class = WEIGHT_CLASS_TINY
throwforce = 5
throw_speed = 3
throw_range = 5
materials = list(MAT_METAL=75)
attack_verb = list("stabbed")
hitsound = 'sound/weapons/bladeslice.ogg'
usesound = 'sound/items/screwdriver.ogg'
toolspeed = 1
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30)
tool_behaviour = TOOL_SCREWDRIVER
var/random_color = TRUE //if the screwdriver uses random coloring
/obj/item/screwdriver/nuke
name = "screwdriver"
desc = "A screwdriver with an ultra thin tip."
icon_state = "screwdriver_nuke"
toolspeed = 0.5
/obj/item/screwdriver/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is stabbing [src] into [user.p_their()] [pick("temple", "heart")]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return BRUTELOSS
/obj/item/screwdriver/New(loc, var/param_color = null)
..()
if(random_color)
if(!param_color)
param_color = pick("red","blue","pink","brown","green","cyan","yellow")
icon_state = "screwdriver_[param_color]"
if (prob(75))
src.pixel_y = rand(0, 16)
/obj/item/screwdriver/attack(mob/living/carbon/M, mob/living/carbon/user)
if(!istype(M) || user.a_intent == INTENT_HELP)
return ..()
if(user.zone_selected != "eyes" && user.zone_selected != "head")
return ..()
if((CLUMSY in user.mutations) && prob(50))
M = user
return eyestab(M,user)
/obj/item/screwdriver/brass
name = "brass screwdriver"
desc = "A screwdriver made of brass. The handle feels freezing cold."
icon_state = "screwdriver_brass"
toolspeed = 0.5
random_color = FALSE
resistance_flags = FIRE_PROOF | ACID_PROOF
/obj/item/screwdriver/abductor
name = "alien screwdriver"
desc = "An ultrasonic screwdriver."
icon = 'icons/obj/abductor.dmi'
icon_state = "screwdriver"
usesound = 'sound/items/pshoom.ogg'
toolspeed = 0.1
random_color = FALSE
/obj/item/screwdriver/power
name = "hand drill"
desc = "A simple hand drill with a screwdriver bit attached."
icon_state = "drill_screw"
item_state = "drill"
materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25)
origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get
force = 8 //might or might not be too high, subject to change
throwforce = 8
throw_speed = 2
throw_range = 3//it's heavier than a screw driver/wrench, so it does more damage, but can't be thrown as far
attack_verb = list("drilled", "screwed", "jabbed","whacked")
hitsound = 'sound/items/drill_hit.ogg'
usesound = 'sound/items/drill_use.ogg'
toolspeed = 0.25
random_color = FALSE
/obj/item/screwdriver/power/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is putting [src] to [user.p_their()] temple. It looks like [user.p_theyre()] trying to commit suicide!</span>")
return BRUTELOSS
/obj/item/screwdriver/power/attack_self(mob/user)
playsound(get_turf(user), 'sound/items/change_drill.ogg', 50, 1)
var/obj/item/wrench/power/b_drill = new /obj/item/wrench/power
to_chat(user, "<span class='notice'>You attach the bolt driver bit to [src].</span>")
qdel(src)
user.put_in_active_hand(b_drill)
/obj/item/screwdriver/cyborg
name = "powered screwdriver"
desc = "An electrical screwdriver, designed to be both precise and quick."
usesound = 'sound/items/drill_use.ogg'
toolspeed = 0.5
@@ -0,0 +1,60 @@
// Called when a mob tries to use the item as a tool.
// Handles most checks.
/obj/item/proc/use_tool(atom/target, mob/living/user, delay, amount=0, volume=0, datum/callback/extra_checks)
// No delay means there is no start message, and no reason to call tool_start_check before use_tool.
// Run the start check here so we wouldn't have to call it manually.
target.add_fingerprint(user)
if(!tool_start_check(user, amount) && !delay)
return
delay *= toolspeed
// Play tool sound at the beginning of tool usage.
play_tool_sound(target, volume)
if(delay)
// Create a callback with checks that would be called every tick by do_after.
var/datum/callback/tool_check = CALLBACK(src, .proc/tool_check_callback, user, target, amount, extra_checks)
if(ismob(target))
if(!do_mob(user, target, delay, extra_checks=tool_check))
return
else
if(!do_after(user, delay, target=target, extra_checks=tool_check))
return
else
// Invoke the extra checks once, just in case.
if(extra_checks && !extra_checks.Invoke())
return
// Use tool's fuel, stack sheets or charges if amount is set.
if(amount && !use(amount))
return
// Play tool sound at the end of tool usage,
// but only if the delay between the beginning and the end is not too small
if(delay >= MIN_TOOL_SOUND_DELAY)
play_tool_sound(target, volume)
return TRUE
// Called before use_tool if there is a delay, or by use_tool if there isn't.
// Only ever used by welding tools and stacks, so it's not added on any other use_tool checks.
/obj/item/proc/tool_start_check(mob/living/user, amount=0)
return tool_use_check(user, amount)
// A check called by tool_start_check once, and by use_tool on every tick of delay.
/obj/item/proc/tool_use_check(mob/living/user, amount)
return !amount
/obj/item/proc/play_tool_sound(atom/target, volume = tool_volume)
if(target && usesound && volume)
var/played_sound = usesound
if(islist(usesound))
played_sound = pick(usesound)
playsound(target, played_sound, volume, 1)
// Used in a callback that is passed by use_tool into do_after call. Do not override, do not call manually.
/obj/item/proc/tool_check_callback(mob/living/user, atom/target, amount, datum/callback/extra_checks)
return tool_use_check(user, amount) && (!extra_checks || extra_checks.Invoke())
+232
View File
@@ -0,0 +1,232 @@
#define GET_FUEL reagents.get_reagent_amount("fuel")
/obj/item/weldingtool
name = "welding tool"
desc = "A standard edition welder provided by Nanotrasen."
icon = 'icons/obj/tools.dmi'
icon_state = "welder"
item_state = "welder"
flags = CONDUCT
slot_flags = SLOT_BELT
force = 3
throwforce = 5
throw_speed = 3
throw_range = 5
hitsound = "swing_hit"
w_class = WEIGHT_CLASS_SMALL
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 30)
resistance_flags = FIRE_PROOF
materials = list(MAT_METAL=70, MAT_GLASS=30)
origin_tech = "engineering=1;plasmatech=1"
tool_behaviour = TOOL_WELDER
toolspeed = 1
tool_enabled = FALSE
usesound = 'sound/items/welder.ogg'
var/maximum_fuel = 20
var/requires_fuel = TRUE //Set to FALSE if it doesn't need fuel, but serves equally well as a cost modifier
var/refills_over_time = FALSE //Do we regenerate fuel?
var/activation_sound = 'sound/items/welderactivate.ogg'
var/deactivation_sound = 'sound/items/welderdeactivate.ogg'
var/light_intensity = 2
var/low_fuel_changes_icon = TRUE//More than one icon_state due to low fuel?
var/progress_flash_divisor = 10 //Length of time between each "eye flash"
/obj/item/weldingtool/Initialize(mapload)
..()
create_reagents(maximum_fuel)
reagents.add_reagent("fuel", maximum_fuel)
if(refills_over_time)
reagents.reagents_generated_per_cycle += list("fuel" = 1)
update_icon()
/obj/item/weldingtool/examine(mob/user)
. = ..()
if(get_dist(user, src) <= 0)
. += "It contains [GET_FUEL] unit\s of fuel out of [maximum_fuel]."
/obj/item/weldingtool/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return FIRELOSS
/obj/item/weldingtool/process()
var/turf/T = get_turf(src)
T.hotspot_expose(2500, 5)
if(prob(5))
remove_fuel(1)
..()
/obj/item/weldingtool/attack_self(mob/user)
if(tool_enabled) //Turn off the welder if it's on
to_chat(user, "<span class='notice'>You switch off [src].</span>")
toggle_welder()
return
else if(GET_FUEL) //The welder is off, but we need to check if there is fuel in the tank
to_chat(user, "<span class='notice'>You switch on [src].</span>")
toggle_welder()
else //The welder is off and unfuelled
to_chat(user, "<span class='notice'>[src] is out of fuel!</span>")
/obj/item/weldingtool/proc/toggle_welder(turn_off = FALSE) //Turn it on or off, forces it to deactivate
tool_enabled = turn_off ? FALSE : !tool_enabled
if(tool_enabled)
START_PROCESSING(SSobj, src)
damtype = BURN
force = 15
hitsound = 'sound/items/welder.ogg'
playsound(loc, activation_sound, 50, 1)
set_light(light_intensity)
else
STOP_PROCESSING(SSobj, src)
damtype = BRUTE
force = 3
hitsound = "swing_hit"
playsound(loc, deactivation_sound, 50, 1)
set_light(0)
update_icon()
if(ismob(loc))
var/mob/M = loc
M.update_inv_r_hand()
M.update_inv_l_hand()
// If welding tool ran out of fuel during a construction task, construction fails.
/obj/item/weldingtool/tool_use_check(mob/living/user, amount)
if(!tool_enabled)
to_chat(user, "<span class='notice'>[src] has to be on to complete this task!</span>")
return FALSE
if(GET_FUEL >= amount * requires_fuel)
return TRUE
else
to_chat(user, "<span class='warning'>You need more welding fuel to complete this task!</span>")
return FALSE
// When welding is about to start, run a normal tool_use_check, then flash a mob if it succeeds.
/obj/item/weldingtool/tool_start_check(mob/living/user, amount=0)
. = tool_use_check(user, amount)
if(. && user)
user.flash_eyes(light_intensity)
/obj/item/weldingtool/use(amount)
if(GET_FUEL < amount * requires_fuel)
return
remove_fuel(amount)
return TRUE
/obj/item/weldingtool/use_tool(target, user, delay, amount, volume, datum/callback/extra_checks)
var/did_thing = ..()
if(did_thing)
remove_fuel(1) //Consume some fuel after we do a welding action
if(delay)
progress_flash_divisor = initial(progress_flash_divisor)
return did_thing
/obj/item/weldingtool/tool_check_callback(mob/living/user, amount, datum/callback/extra_checks)
. = ..()
if(. && user)
if(progress_flash_divisor == 0)
user.flash_eyes(min(light_intensity, 1))
progress_flash_divisor = initial(progress_flash_divisor)
else
progress_flash_divisor--
/obj/item/weldingtool/proc/remove_fuel(amount) //NB: doesn't check if we have enough fuel, it just removes however much is left if there's not enough
reagents.remove_reagent("fuel", amount * requires_fuel)
if(!GET_FUEL)
toggle_welder(TRUE)
/obj/item/weldingtool/refill(mob/user, atom/A, amount)
if(!A.reagents)
return
if(GET_FUEL >= maximum_fuel)
to_chat(user, "<span class='notice'>[src] is already full!</span>")
return
var/amount_transferred = A.reagents.trans_id_to(src, "fuel", amount)
if(amount_transferred)
to_chat(user, "<span class='notice'>You refuel [src] by [amount_transferred] unit\s.</span>")
playsound(src, 'sound/effects/refill.ogg', 50, 1)
update_icon()
return amount_transferred
else
to_chat(user, "<span class='warning'>There's not enough fuel in [A] to refuel [src]!</span>")
/obj/item/weldingtool/proc/update_torch()
overlays.Cut()
if(tool_enabled)
overlays += "[initial(icon_state)]-on"
item_state = "[initial(item_state)]1"
else
item_state = "[initial(item_state)]"
/obj/item/weldingtool/update_icon()
if(low_fuel_changes_icon)
var/ratio = GET_FUEL / maximum_fuel
ratio = Ceiling(ratio*4) * 25
if(ratio == 100)
icon_state = initial(icon_state)
else
icon_state = "[initial(icon_state)][ratio]"
update_torch()
..()
/obj/item/weldingtool/largetank
name = "industrial welding tool"
desc = "A slightly larger welder with a larger tank."
icon_state = "indwelder"
maximum_fuel = 40
materials = list(MAT_METAL=70, MAT_GLASS=60)
origin_tech = "engineering=2;plasmatech=2"
/obj/item/weldingtool/largetank/cyborg
name = "integrated welding tool"
desc = "An advanced welder designed to be used in robotic systems."
toolspeed = 0.5
/obj/item/weldingtool/mini
name = "emergency welding tool"
desc = "A miniature welder used during emergencies."
icon_state = "miniwelder"
maximum_fuel = 10
w_class = WEIGHT_CLASS_TINY
materials = list(MAT_METAL=30, MAT_GLASS=10)
low_fuel_changes_icon = FALSE
/obj/item/weldingtool/abductor
name = "alien welding tool"
desc = "An alien welding tool. Whatever fuel it uses, it never runs out."
icon = 'icons/obj/abductor.dmi'
icon_state = "welder"
toolspeed = 0.1
light_intensity = 0
origin_tech = "plasmatech=5;engineering=5;abductor=3"
requires_fuel = FALSE
refills_over_time = TRUE
low_fuel_changes_icon = FALSE
/obj/item/weldingtool/hugetank
name = "upgraded welding tool"
desc = "An upgraded welder based off the industrial welder."
icon_state = "upindwelder"
item_state = "upindwelder"
maximum_fuel = 80
materials = list(MAT_METAL=70, MAT_GLASS=120)
origin_tech = "engineering=3;plasmatech=2"
/obj/item/weldingtool/experimental
name = "experimental welding tool"
desc = "An experimental welder capable of self-fuel generation and less harmful to the eyes."
icon_state = "exwelder"
item_state = "exwelder"
maximum_fuel = 40
materials = list(MAT_METAL=70, MAT_GLASS=120)
origin_tech = "materials=4;engineering=4;bluespace=3;plasmatech=4"
light_intensity = 1
toolspeed = 0.5
refills_over_time = TRUE
low_fuel_changes_icon = FALSE
/obj/item/weldingtool/experimental/brass
name = "brass welding tool"
desc = "A brass welder that seems to constantly refuel itself. It is faintly warm to the touch."
icon_state = "brasswelder"
item_state = "brasswelder"
resistance_flags = FIRE_PROOF | ACID_PROOF
@@ -0,0 +1,95 @@
/obj/item/wirecutters
name = "wirecutters"
desc = "This cuts wires."
icon = 'icons/obj/tools.dmi'
icon_state = "cutters"
flags = CONDUCT
slot_flags = SLOT_BELT
force = 6
throw_speed = 3
throw_range = 7
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=80)
origin_tech = "materials=1;engineering=1"
attack_verb = list("pinched", "nipped")
hitsound = 'sound/items/wirecutter.ogg'
usesound = 'sound/items/wirecutter.ogg'
sharp = 1
toolspeed = 1
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30)
tool_behaviour = TOOL_WIRECUTTER
var/random_color = TRUE
/obj/item/wirecutters/New(loc, param_color = null)
..()
if(random_color)
if(!param_color)
param_color = pick("yellow", "red")
icon_state = "cutters_[param_color]"
/obj/item/wirecutters/attack(mob/living/carbon/C, mob/user)
if(istype(C) && C.handcuffed && istype(C.handcuffed, /obj/item/restraints/handcuffs/cable))
user.visible_message("<span class='notice'>[user] cuts [C]'s restraints with [src]!</span>")
QDEL_NULL(C.handcuffed)
if(C.buckled && C.buckled.buckle_requires_restraints)
C.buckled.unbuckle_mob(C)
C.update_handcuffed()
return
else
..()
/obj/item/wirecutters/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is cutting at [user.p_their()] arteries with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
playsound(loc, usesound, 50, 1, -1)
return BRUTELOSS
/obj/item/wirecutters/brass
name = "brass wirecutters"
desc = "A pair of wirecutters made of brass. The handle feels freezing cold to the touch."
icon_state = "cutters_brass"
toolspeed = 0.5
random_color = FALSE
resistance_flags = FIRE_PROOF | ACID_PROOF
/obj/item/wirecutters/abductor
name = "alien wirecutters"
desc = "Extremely sharp wirecutters, made out of a silvery-green metal."
icon = 'icons/obj/abductor.dmi'
icon_state = "cutters"
toolspeed = 0.1
origin_tech = "materials=5;engineering=4;abductor=3"
random_color = FALSE
/obj/item/wirecutters/cyborg
name = "wirecutters"
desc = "This cuts wires."
toolspeed = 0.5
/obj/item/wirecutters/power
name = "jaws of life"
desc = "A set of jaws of life, the magic of science has managed to fit it down into a device small enough to fit in a tool belt. It's fitted with a cutting head."
icon_state = "jaws_cutter"
item_state = "jawsoflife"
origin_tech = "materials=2;engineering=2"
materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25)
usesound = 'sound/items/jaws_cut.ogg'
toolspeed = 0.25
random_color = FALSE
/obj/item/wirecutters/power/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is wrapping \the [src] around [user.p_their()] neck. It looks like [user.p_theyre()] trying to rip [user.p_their()] head off!</span>")
playsound(loc, 'sound/items/jaws_cut.ogg', 50, 1, -1)
if(ishuman(user))
var/mob/living/carbon/human/H = user
var/obj/item/organ/external/head/head = H.bodyparts_by_name["head"]
if(head)
head.droplimb(0, DROPLIMB_BLUNT, FALSE, TRUE)
playsound(loc,pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg') ,50, 1, -1)
return BRUTELOSS
/obj/item/wirecutters/power/attack_self(mob/user)
playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1)
var/obj/item/crowbar/power/pryjaws = new /obj/item/crowbar/power
to_chat(user, "<span class='notice'>You attach the pry jaws to [src].</span>")
qdel(src)
user.put_in_active_hand(pryjaws)
+105
View File
@@ -0,0 +1,105 @@
//Wrench
/obj/item/wrench
name = "wrench"
desc = "A wrench with common uses. Can be found in your hand."
icon = 'icons/obj/tools.dmi'
icon_state = "wrench"
flags = CONDUCT
slot_flags = SLOT_BELT
force = 5
throwforce = 7
usesound = 'sound/items/ratchet.ogg'
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=150)
origin_tech = "materials=1;engineering=1"
attack_verb = list("bashed", "battered", "bludgeoned", "whacked")
toolspeed = 1
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30)
tool_behaviour = TOOL_WRENCH
/obj/item/wrench/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1)
return BRUTELOSS
/obj/item/wrench/cyborg
name = "automatic wrench"
desc = "An advanced robotic wrench. Can be found in construction cyborgs."
toolspeed = 0.5
/obj/item/wrench/brass
name = "brass wrench"
desc = "A brass wrench. It's faintly warm to the touch."
icon_state = "wrench_brass"
toolspeed = 0.5
resistance_flags = FIRE_PROOF | ACID_PROOF
/obj/item/wrench/abductor
name = "alien wrench"
desc = "A polarized wrench. It causes anything placed between the jaws to turn."
icon = 'icons/obj/abductor.dmi'
icon_state = "wrench"
usesound = 'sound/effects/empulse.ogg'
toolspeed = 0.1
origin_tech = "materials=5;engineering=5;abductor=3"
/obj/item/wrench/power
name = "hand drill"
desc = "A simple powered drill with a bolt bit."
icon_state = "drill_bolt"
item_state = "drill"
usesound = 'sound/items/drill_use.ogg'
materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25)
origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get
force = 8 //might or might not be too high, subject to change
throwforce = 8
attack_verb = list("drilled", "screwed", "jabbed")
toolspeed = 0.25
/obj/item/wrench/power/attack_self(mob/user)
playsound(get_turf(user),'sound/items/change_drill.ogg', 50, 1)
var/obj/item/wirecutters/power/s_drill = new /obj/item/screwdriver/power
to_chat(user, "<span class='notice'>You attach the screwdriver bit to [src].</span>")
qdel(src)
user.put_in_active_hand(s_drill)
/obj/item/wrench/power/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is pressing [src] against [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!")
return BRUTELOSS
/obj/item/wrench/medical
name = "medical wrench"
desc = "A medical wrench with common (medical?) uses. Can be found in your hand."
icon_state = "wrench_medical"
force = 2 //MEDICAL
throwforce = 4
origin_tech = "materials=1;engineering=1;biotech=3"
attack_verb = list("wrenched", "medicaled", "tapped", "jabbed", "whacked")
/obj/item/wrench/medical/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is praying to the medical wrench to take [user.p_their()] soul. It looks like [user.p_theyre()] trying to commit suicide!</span>")
// TODO Make them glow with the power of the M E D I C A L W R E N C H
// during their ascension
// Stun stops them from wandering off
user.Stun(5)
playsound(loc, 'sound/effects/pray.ogg', 50, 1, -1)
// Let the sound effect finish playing
sleep(20)
if(!user)
return
for(var/obj/item/W in user)
user.unEquip(W)
var/obj/item/wrench/medical/W = new /obj/item/wrench/medical(loc)
W.add_fingerprint(user)
W.desc += " For some reason, it reminds you of [user.name]."
if(!user)
return
user.dust()
return OBLITERATION
File diff suppressed because it is too large Load Diff
+107 -103
View File
@@ -1,103 +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/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
+392 -392
View File
@@ -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
+22 -18
View File
@@ -36,26 +36,30 @@
return
update_icon()
to_chat(user, "<span class='notice'>You add the cables to the [src]. It now contains [loaded.amount].</span>")
else if(isscrewdriver(W))
if(!loaded)
return
to_chat(user, "<span class='notice'>You loosen the securing screws on the side, allowing you to lower the guiding edge and retrieve the wires.</span>")
while(loaded.amount > 30) //There are only two kinds of situations: "nodiff" (60,90), or "diff" (31-59, 61-89)
var/diff = loaded.amount % 30
if(diff)
loaded.use(diff)
new /obj/item/stack/cable_coil(user.loc, diff)
else
loaded.use(30)
new /obj/item/stack/cable_coil(user.loc, 30)
loaded.max_amount = initial(loaded.max_amount)
loaded.forceMove(user.loc)
user.put_in_hands(loaded)
loaded = null
update_icon()
else
..()
/obj/item/twohanded/rcl/screwdriver_act(mob/user, obj/item/I)
if(!loaded)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
to_chat(user, "<span class='notice'>You loosen the securing screws on the side, allowing you to lower the guiding edge and retrieve the wires.</span>")
while(loaded.amount > 30) //There are only two kinds of situations: "nodiff" (60,90), or "diff" (31-59, 61-89)
var/diff = loaded.amount % 30
if(diff)
loaded.use(diff)
new /obj/item/stack/cable_coil(user.loc, diff)
else
loaded.use(30)
new /obj/item/stack/cable_coil(user.loc, 30)
loaded.max_amount = initial(loaded.max_amount)
loaded.forceMove(user.loc)
user.put_in_hands(loaded)
loaded = null
update_icon()
/obj/item/twohanded/rcl/examine(mob/user)
. = ..()
if(loaded)
@@ -147,4 +151,4 @@
loaded = new()
loaded.max_amount = max_amount
loaded.amount = max_amount
update_icon()
update_icon()
+84 -84
View File
@@ -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)
return
/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
+1 -1
View File
@@ -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
+81 -75
View File
@@ -1,5 +1,3 @@
//cleansed 9/15/2012 17:48
/*
CONTAINS:
CIGARETTES
@@ -13,6 +11,7 @@ LIGHTERS ARE IN LIGHTERS.DM
//////////////////
//FINE SMOKABLES//
//////////////////
/obj/item/clothing/mask/cigarette
name = "cigarette"
desc = "A roll of tobacco and nicotine."
@@ -29,21 +28,23 @@ LIGHTERS ARE IN LIGHTERS.DM
var/icon_off = "cigoff"
var/type_butt = /obj/item/cigbutt
var/lastHolder = null
var/smoketime = 300
var/chem_volume = 30
var/smoketime = 150
var/chem_volume = 60
var/list/list_reagents = list("nicotine" = 40)
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/mask.dmi',
"Unathi" = 'icons/mob/species/unathi/mask.dmi',
"Tajaran" = 'icons/mob/species/tajaran/mask.dmi',
"Vulpkanin" = 'icons/mob/species/vulpkanin/mask.dmi',
"Grey" = 'icons/mob/species/grey/mask.dmi'
)
"Grey" = 'icons/mob/species/grey/mask.dmi')
/obj/item/clothing/mask/cigarette/New()
..()
create_reagents(chem_volume) // making the cigarrete a chemical holder with a maximum volume of 30
reagents.set_reacting(FALSE) // so it doesn't react until you light it
if(list_reagents)
reagents.add_reagent_list(list_reagents)
/obj/item/clothing/mask/cigarette/Destroy()
QDEL_NULL(reagents)
@@ -55,7 +56,7 @@ LIGHTERS ARE IN LIGHTERS.DM
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(M)
light("<span class='notice'>[user] coldly lights the [name] with the burning body of [M]. Clearly, [user.p_they()] offer[user.p_s()] the warmest of regards...</span>")
return 1
return TRUE
else
return ..()
@@ -64,57 +65,56 @@ LIGHTERS ARE IN LIGHTERS.DM
..()
light()
/obj/item/clothing/mask/cigarette/attackby(obj/item/W as obj, mob/user as mob, params)
/obj/item/clothing/mask/cigarette/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/clothing/mask/cigarette/attackby(obj/item/I, mob/user, params)
..()
if(istype(W, /obj/item/weldingtool))
var/obj/item/weldingtool/WT = W
if(WT.isOn())//Badasses dont get blinded while lighting their cig with a welding tool
light("<span class='notice'>[user] casually lights the [name] with [W], what a badass.</span>")
else if(istype(W, /obj/item/lighter/zippo))
var/obj/item/lighter/zippo/Z = W
if(istype(I, /obj/item/lighter/zippo))
var/obj/item/lighter/zippo/Z = I
if(Z.lit)
light("<span class='rose'>With a single flick of [user.p_their()] wrist, [user] smoothly lights [user.p_their()] [name] with [user.p_their()] [W]. Damn [user.p_theyre()] cool.</span>")
light("<span class='rose'>With a single flick of [user.p_their()] wrist, [user] smoothly lights [user.p_their()] [name] with [user.p_their()] [Z]. Damn [user.p_theyre()] cool.</span>")
else if(istype(W, /obj/item/lighter))
var/obj/item/lighter/L = W
else if(istype(I, /obj/item/lighter))
var/obj/item/lighter/L = I
if(L.lit)
light("<span class='notice'>After some fiddling, [user] manages to light [user.p_their()] [name] with [W].</span>")
light("<span class='notice'>After some fiddling, [user] manages to light [user.p_their()] [name] with [L].</span>")
else if(istype(W, /obj/item/match))
var/obj/item/match/M = W
if(M.lit == 1)
light("<span class='notice'>[user] lights [user.p_their()] [name] with [user.p_their()] [W].</span>")
else if(istype(I, /obj/item/match))
var/obj/item/match/M = I
if(M.lit)
light("<span class='notice'>[user] lights [user.p_their()] [name] with [user.p_their()] [M].</span>")
else if(istype(W, /obj/item/melee/energy/sword/saber))
var/obj/item/melee/energy/sword/saber/S = W
else if(istype(I, /obj/item/melee/energy/sword/saber))
var/obj/item/melee/energy/sword/saber/S = I
if(S.active)
light("<span class='warning'>[user] makes a violent slashing motion, barely missing [user.p_their()] nose as light flashes. [user.p_they(TRUE)] light[user.p_s()] [user.p_their()] [name] with [W] in the process.</span>")
light("<span class='warning'>[user] makes a violent slashing motion, barely missing [user.p_their()] nose as light flashes. [user.p_they(TRUE)] light[user.p_s()] [user.p_their()] [name] with [S] in the process.</span>")
else if(istype(W, /obj/item/assembly/igniter))
light("<span class='notice'>[user] fiddles with [W], and manages to light [user.p_their()] [name].</span>")
else if(istype(I, /obj/item/assembly/igniter))
light("<span class='notice'>[user] fiddles with [I], and manages to light [user.p_their()] [name].</span>")
else if(istype(W, /obj/item/gun/magic/wand/fireball))
var/obj/item/gun/magic/wand/fireball/F = W
else if(istype(I, /obj/item/gun/magic/wand/fireball))
var/obj/item/gun/magic/wand/fireball/F = I
if(F.charges)
if(prob(50) || user.mind.assigned_role == "Wizard")
light("<span class='notice'>Holy shit, did [user] just manage to light [user.p_their()] [name] with [W], with only moderate eyebrow singing?</span>")
light("<span class='notice'>Holy shit, did [user] just manage to light [user.p_their()] [name] with [F], with only moderate eyebrow singing?</span>")
else
to_chat(user, "<span class='warning'>Unsure which end of the wand is which, [user] fails to light [name] with [W].</span>")
to_chat(user, "<span class='warning'>Unsure which end of the wand is which, [user] fails to light [name] with [F].</span>")
explosion(user.loc, -1, 0, 2, 3, 0, flame_range = 2)
F.charges--
//can't think of any other way to update the overlays :<
user.update_inv_wear_mask()
user.update_inv_l_hand()
user.update_inv_r_hand()
return
/obj/item/clothing/mask/cigarette/afterattack(obj/item/reagent_containers/glass/glass, mob/user as mob, proximity)
/obj/item/clothing/mask/cigarette/afterattack(obj/item/reagent_containers/glass/glass, mob/user, proximity)
..()
if(!proximity) return
if(!proximity)
return
if(istype(glass)) //you can dip cigarettes into beakers
var/transfered = glass.reagents.trans_to(src, chem_volume)
if(transfered) //if reagents were transfered, show the message
@@ -127,8 +127,8 @@ LIGHTERS ARE IN LIGHTERS.DM
/obj/item/clothing/mask/cigarette/proc/light(flavor_text = null)
if(!src.lit)
src.lit = 1
if(!lit)
lit = TRUE
name = "lit [name]"
attack_verb = list("burnt", "singed")
hitsound = 'sound/items/welder.ogg'
@@ -168,14 +168,13 @@ LIGHTERS ARE IN LIGHTERS.DM
if(isliving(loc))
M.IgniteMob()
smoketime--
if(smoketime < 1)
if(reagents.total_volume <= 0 || smoketime < 1)
die()
return
smoke()
return
/obj/item/clothing/mask/cigarette/attack_self(mob/user as mob)
/obj/item/clothing/mask/cigarette/attack_self(mob/user)
if(lit)
user.visible_message("<span class='notice'>[user] calmly drops and treads on the lit [src], putting it out instantly.</span>")
die()
@@ -183,13 +182,13 @@ LIGHTERS ARE IN LIGHTERS.DM
/obj/item/clothing/mask/cigarette/proc/smoke()
var/turf/location = get_turf(src)
var/is_being_smoked = 0
var/is_being_smoked = FALSE
// Check whether this is actually in a mouth, being smoked
if(iscarbon(loc))
var/mob/living/carbon/C = loc
if(src == C.wear_mask)
// There used to be a species check here, but synthetics can smoke now
is_being_smoked = 1
is_being_smoked = TRUE
if(location)
location.hotspot_expose(700, 5)
if(reagents && reagents.total_volume) // check if it has any reagents at all
@@ -201,7 +200,6 @@ LIGHTERS ARE IN LIGHTERS.DM
to_chat(C, "<span class='notice'>Your [name] loses its flavor.</span>")
else // else just remove some of the reagents
reagents.remove_any(REAGENTS_METABOLISM)
return
/obj/item/clothing/mask/cigarette/proc/die()
var/turf/T = get_turf(src)
@@ -216,12 +214,26 @@ LIGHTERS ARE IN LIGHTERS.DM
qdel(src)
/obj/item/clothing/mask/cigarette/menthol
list_reagents = list("nicotine" = 40, "menthol" = 20)
/obj/item/clothing/mask/cigarette/random
/obj/item/clothing/mask/cigarette/random/New()
list_reagents = list("nicotine" = 40, pick("fuel","saltpetre","synaptizine","green_vomit","potass_iodide","msg","lexorin","mannitol","spaceacillin","cryoxadone","holywater","tea","egg","haloperidol","mutagen","omnizine","carpet","aranesp","cryostylane","chocolate","bilk","cheese","rum","blood","charcoal","coffee","ectoplasm","space_drugs","milk","mutadone","antihol","teporone","insulin","salbutamol","toxin") = 20)
..()
var/random_reagent = pick("fuel","saltpetre","synaptizine","green_vomit","potass_iodide","msg","lexorin","mannitol","spaceacillin","cryoxadone","holywater","tea","egg","haloperidol","mutagen","omnizine","carpet","aranesp","cryostylane","chocolate","bilk","cheese","rum","blood","charcoal","coffee","ectoplasm","space_drugs","milk","mutadone","antihol","teporone","insulin","salbutamol","toxin")
reagents.add_reagent(random_reagent, 10)
/obj/item/clothing/mask/cigarette/syndicate
list_reagents = list("nicotine" = 40, "omnizine" = 20)
/obj/item/clothing/mask/cigarette/medical_marijuana
list_reagents = list("thc" = 40, "cbd" = 20)
/obj/item/clothing/mask/cigarette/robustgold
list_reagents = list("nicotine" = 40, "gold" = 1)
/obj/item/clothing/mask/cigarette/shadyjims
list_reagents = list("nicotine" = 40, "lipolicide" = 7.5, "ammonia" = 2, "atrazine" = 1, "toxin" = 1.5)
/obj/item/clothing/mask/cigarette/rollie
name = "rollie"
@@ -232,8 +244,6 @@ LIGHTERS ARE IN LIGHTERS.DM
type_butt = /obj/item/cigbutt/roach
throw_speed = 0.5
item_state = "spliffoff"
smoketime = 250
chem_volume = 100
/obj/item/clothing/mask/cigarette/rollie/New()
..()
@@ -254,6 +264,7 @@ LIGHTERS ARE IN LIGHTERS.DM
////////////
// CIGARS //
////////////
/obj/item/clothing/mask/cigarette/cigar
name = "Premium Cigar"
desc = "A brown roll of tobacco and... well, you're not quite sure. This thing's huge!"
@@ -263,12 +274,9 @@ LIGHTERS ARE IN LIGHTERS.DM
type_butt = /obj/item/cigbutt/cigarbutt
throw_speed = 0.5
item_state = "cigaroff"
smoketime = 1500
chem_volume = 40
/obj/item/clothing/mask/cigarette/cigar/New()
..()
reagents.add_reagent("nicotine", chem_volume/2)
smoketime = 300
chem_volume = 120
list_reagents = list("nicotine" = 120)
/obj/item/clothing/mask/cigarette/cigar/cohiba
name = "Cohiba Robusto Cigar"
@@ -283,8 +291,9 @@ LIGHTERS ARE IN LIGHTERS.DM
icon_state = "cigar2off"
icon_on = "cigar2on"
icon_off = "cigar2off"
smoketime = 7200
chem_volume = 60
smoketime = 450
chem_volume = 180
list_reagents = list("nicotine" = 180)
/obj/item/cigbutt
name = "cigarette butt"
@@ -306,17 +315,18 @@ LIGHTERS ARE IN LIGHTERS.DM
icon_state = "cigarbutt"
/obj/item/clothing/mask/cigarette/cigar/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/reagent_containers))
/obj/item/clothing/mask/cigarette/cigar/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/reagent_containers))
return
if(istype(W, /obj/item/match))
if(istype(I, /obj/item/match))
..()
else
to_chat(user, "<span class='notice'>\The [src] straight out REFUSES to be lit by such uncivilized means.</span>")
to_chat(user, "<span class='notice'>[src] straight out REFUSES to be lit by such uncivilized means.</span>")
/////////////////
//SMOKING PIPES//
/////////////////
/obj/item/clothing/mask/cigarette/pipe
name = "smoking pipe"
desc = "A pipe, for smoking. Probably made of meershaum or something."
@@ -326,14 +336,11 @@ LIGHTERS ARE IN LIGHTERS.DM
icon_off = "pipeoff"
smoketime = 500
chem_volume = 200
/obj/item/clothing/mask/cigarette/pipe/New()
..()
reagents.add_reagent("nicotine", chem_volume)
list_reagents = list("nicotine" = 200)
/obj/item/clothing/mask/cigarette/pipe/light(flavor_text = null)
if(!src.lit)
src.lit = 1
if(!lit)
lit = TRUE
damtype = "fire"
icon_state = icon_on
item_state = icon_on
@@ -350,19 +357,18 @@ LIGHTERS ARE IN LIGHTERS.DM
if(ismob(loc))
var/mob/living/M = loc
to_chat(M, "<span class='notice'>Your [name] goes out, and you empty the ash.</span>")
lit = 0
lit = FALSE
icon_state = icon_off
item_state = icon_off
M.update_inv_wear_mask(0)
STOP_PROCESSING(SSobj, src)
return
smoke()
return
/obj/item/clothing/mask/cigarette/pipe/attack_self(mob/user as mob) //Refills the pipe. Can be changed to an attackby later, if loose tobacco is added to vendors or something.
/obj/item/clothing/mask/cigarette/pipe/attack_self(mob/user) //Refills the pipe. Can be changed to an attackby later, if loose tobacco is added to vendors or something.
if(lit)
user.visible_message("<span class='notice'>[user] puts out [src].</span>")
lit = 0
lit = FALSE
icon_state = icon_off
item_state = icon_off
STOP_PROCESSING(SSobj, src)
@@ -371,15 +377,14 @@ LIGHTERS ARE IN LIGHTERS.DM
to_chat(user, "<span class='notice'>You refill the pipe with tobacco.</span>")
reagents.add_reagent("nicotine", chem_volume)
smoketime = initial(smoketime)
return
/obj/item/clothing/mask/cigarette/pipe/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/reagent_containers))
/obj/item/clothing/mask/cigarette/pipe/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/reagent_containers))
return
if(istype(W, /obj/item/match))
if(istype(I, /obj/item/match))
..()
else
to_chat(user, "<span class='notice'>\The [src] straight out REFUSES to be lit by such means.</span>")
to_chat(user, "<span class='notice'>[src] straight out REFUSES to be lit by such means.</span>")
/obj/item/clothing/mask/cigarette/pipe/cobpipe
name = "corn cob pipe"
@@ -394,6 +399,7 @@ LIGHTERS ARE IN LIGHTERS.DM
///////////
//ROLLING//
///////////
/obj/item/rollingpaper
name = "rolling paper"
desc = "A thin piece of paper used to make fine smokeables."
+58 -58
View File
@@ -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")
@@ -0,0 +1,21 @@
// Conversion kit
/obj/item/conversion_kit
name = "\improper Revolver Conversion Kit"
desc = "A professional conversion kit used to convert any knock off revolver into the real deal capable of shooting lethal .357 rounds without the possibility of catastrophic failure."
icon_state = "kit"
flags = CONDUCT
w_class = WEIGHT_CLASS_SMALL
origin_tech = "combat=2"
var/open = 0
/obj/item/conversion_kit/New()
..()
update_icon()
/obj/item/conversion_kit/update_icon()
icon_state = "[initial(icon_state)]_[open]"
/obj/item/conversion_kit/attack_self(mob/user)
open = !open
to_chat(user, "<span class='notice'>You [open ? "open" : "close"] the conversion kit.</span>")
update_icon()
+180 -179
View File
@@ -1,179 +1,180 @@
/obj/item/lipstick
name = "red lipstick"
desc = "A generic brand of lipstick."
icon = 'icons/obj/items.dmi'
icon_state = "lipstick"
w_class = WEIGHT_CLASS_TINY
var/colour = "red"
var/open = 0
var/list/lipstick_colors = list(
"purple" = "purple",
"jade" = "#216F43",
"lime" = "lime",
"black" = "black",
"green" = "green",
"blue" = "blue",
"white" = "white")
/obj/item/lipstick/purple
name = "purple lipstick"
colour = "purple"
/obj/item/lipstick/jade
name = "jade lipstick"
colour = "#216F43"
/obj/item/lipstick/lime
name = "lime lipstick"
colour = "lime"
/obj/item/lipstick/black
name = "black lipstick"
colour = "black"
/obj/item/lipstick/green
name = "green lipstick"
colour = "green"
/obj/item/lipstick/blue
name = "blue lipstick"
colour = "blue"
/obj/item/lipstick/white
name = "white lipstick"
colour = "white"
/obj/item/lipstick/random
name = "lipstick"
/obj/item/lipstick/random/New()
var/lscolor = pick(lipstick_colors)//A random color is picked from the var defined initially in a new var.
colour = lipstick_colors[lscolor]//The color of the lipstick is pulled from the new variable (right hand side, HTML & Hex RGB)
name = "[lscolor] lipstick"//The new variable is also used to match the name to the color of the lipstick. Kudos to Desolate & Lemon
/obj/item/lipstick/attack_self(mob/user as mob)
overlays.Cut()
to_chat(user, "<span class='notice'>You twist \the [src] [open ? "closed" : "open"].</span>")
open = !open
if(open)
var/image/colored = image("icon"='icons/obj/items.dmi', "icon_state"="lipstick_uncap_color")
colored.color = colour
icon_state = "lipstick_uncap"
overlays += colored
else
icon_state = "lipstick"
/obj/item/lipstick/attack(mob/M as mob, mob/user as mob)
if(!open) return
if(!istype(M, /mob)) return
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.lip_style) //if they already have lipstick on
to_chat(user, "<span class='notice'>You need to wipe off the old lipstick first!</span>")
return
if(H == user)
user.visible_message("<span class='notice'>[user] does [user.p_their()] lips with [src].</span>", \
"<span class='notice'>You take a moment to apply [src]. Perfect!</span>")
H.lip_style = "lipstick"
H.lip_color = colour
H.update_body()
else
user.visible_message("<span class='warning'>[user] begins to do [H]'s lips with \the [src].</span>", \
"<span class='notice'>You begin to apply \the [src].</span>")
if(do_after(user, 20, target = H))
user.visible_message("<span class='notice'>[user] does [H]'s lips with \the [src].</span>", \
"<span class='notice'>You apply \the [src].</span>")
H.lip_style = "lipstick"
H.lip_color = colour
H.update_body()
else
to_chat(user, "<span class='notice'>Where are the lips on that?</span>")
/obj/item/razor
name = "electric razor"
desc = "The latest and greatest power razor born from the science of shaving."
icon = 'icons/obj/items.dmi'
icon_state = "razor"
flags = CONDUCT
w_class = WEIGHT_CLASS_TINY
usesound = 'sound/items/welder2.ogg'
toolspeed = 1
/obj/item/razor/attack(mob/living/carbon/M as mob, mob/user as mob)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/head/C = H.get_organ("head")
var/datum/robolimb/robohead = all_robolimbs[C.model]
if(user.zone_selected == "mouth")
if(!get_location_accessible(H, "mouth"))
to_chat(user, "<span class='warning'>The mask is in the way.</span>")
return
if((C.dna.species.bodyflags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'...
to_chat(user, "<span class='warning'>You find yourself disappointed at the appalling lack of facial hair.</span>")
return
if(C.f_style == "Shaved")
to_chat(user, "<span class='notice'>Already clean-shaven.</span>")
return
if(H == user) //shaving yourself
user.visible_message("<span class='notice'>[user] starts to shave [user.p_their()] facial hair with [src].</span>", \
"<span class='notice'>You take a moment shave your facial hair with \the [src].</span>")
if(do_after(user, 50 * toolspeed, target = H))
user.visible_message("<span class='notice'>[user] shaves [user.p_their()] facial hair clean with [src].</span>", \
"<span class='notice'>You finish shaving with [src]. Fast and clean!</span>")
C.f_style = "Shaved"
H.update_fhair()
playsound(src.loc, usesound, 20, 1)
else
var/turf/user_loc = user.loc
var/turf/H_loc = H.loc
user.visible_message("<span class='danger'>[user] tries to shave [H]'s facial hair with \the [src].</span>", \
"<span class='warning'>You start shaving [H]'s facial hair.</span>")
if(do_after(user, 50 * toolspeed, target = H))
if(user_loc == user.loc && H_loc == H.loc)
user.visible_message("<span class='danger'>[user] shaves off [H]'s facial hair with \the [src].</span>", \
"<span class='notice'>You shave [H]'s facial hair clean off.</span>")
C.f_style = "Shaved"
H.update_fhair()
playsound(src.loc, usesound, 20, 1)
if(user.zone_selected == "head")
if(!get_location_accessible(H, "head"))
to_chat(user, "<span class='warning'>The headgear is in the way.</span>")
return
if((C.dna.species.bodyflags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'...
to_chat(user, "<span class='warning'>You find yourself disappointed at the appalling lack of hair.</span>")
return
if(C.h_style == "Bald" || C.h_style == "Balding Hair" || C.h_style == "Skinhead")
to_chat(user, "<span class='notice'>There is not enough hair left to shave...</span>")
return
if(isskrell(M))
to_chat(user, "<span class='warning'>Your razor isn't going to cut through tentacles.</span>")
return
if(H == user) //shaving yourself
user.visible_message("<span class='warning'>[user] starts to shave [user.p_their()] head with [src].</span>", \
"<span class='warning'>You start to shave your head with \the [src].</span>")
if(do_after(user, 50 * toolspeed, target = H))
user.visible_message("<span class='notice'>[user] shaves [user.p_their()] head with [src].</span>", \
"<span class='notice'>You finish shaving with \the [src].</span>")
C.h_style = "Skinhead"
H.update_hair()
playsound(src.loc, usesound, 40, 1)
else
var/turf/user_loc = user.loc
var/turf/H_loc = H.loc
user.visible_message("<span class='danger'>[user] tries to shave [H]'s head with \the [src]!</span>", \
"<span class='warning'>You start shaving [H]'s head.</span>")
if(do_after(user, 50 * toolspeed, target = H))
if(user_loc == user.loc && H_loc == H.loc)
user.visible_message("<span class='danger'>[user] shaves [H]'s head bald with \the [src]!</span>", \
"<span class='warning'>You shave [H]'s head bald.</span>")
C.h_style = "Skinhead"
H.update_hair()
playsound(src.loc, usesound, 40, 1)
else
..()
else
..()
/obj/item/lipstick
name = "red lipstick"
desc = "A generic brand of lipstick."
icon = 'icons/obj/items.dmi'
icon_state = "lipstick"
w_class = WEIGHT_CLASS_TINY
var/colour = "red"
var/open = 0
var/list/lipstick_colors = list(
"purple" = "purple",
"jade" = "#216F43",
"lime" = "lime",
"black" = "black",
"green" = "green",
"blue" = "blue",
"white" = "white")
/obj/item/lipstick/purple
name = "purple lipstick"
colour = "purple"
/obj/item/lipstick/jade
name = "jade lipstick"
colour = "#216F43"
/obj/item/lipstick/lime
name = "lime lipstick"
colour = "lime"
/obj/item/lipstick/black
name = "black lipstick"
colour = "black"
/obj/item/lipstick/green
name = "green lipstick"
colour = "green"
/obj/item/lipstick/blue
name = "blue lipstick"
colour = "blue"
/obj/item/lipstick/white
name = "white lipstick"
colour = "white"
/obj/item/lipstick/random
name = "lipstick"
/obj/item/lipstick/random/New()
..()
var/lscolor = pick(lipstick_colors)//A random color is picked from the var defined initially in a new var.
colour = lipstick_colors[lscolor]//The color of the lipstick is pulled from the new variable (right hand side, HTML & Hex RGB)
name = "[lscolor] lipstick"//The new variable is also used to match the name to the color of the lipstick. Kudos to Desolate & Lemon
/obj/item/lipstick/attack_self(mob/user as mob)
overlays.Cut()
to_chat(user, "<span class='notice'>You twist \the [src] [open ? "closed" : "open"].</span>")
open = !open
if(open)
var/image/colored = image("icon"='icons/obj/items.dmi', "icon_state"="lipstick_uncap_color")
colored.color = colour
icon_state = "lipstick_uncap"
overlays += colored
else
icon_state = "lipstick"
/obj/item/lipstick/attack(mob/M as mob, mob/user as mob)
if(!open) return
if(!istype(M, /mob)) return
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.lip_style) //if they already have lipstick on
to_chat(user, "<span class='notice'>You need to wipe off the old lipstick first!</span>")
return
if(H == user)
user.visible_message("<span class='notice'>[user] does [user.p_their()] lips with [src].</span>", \
"<span class='notice'>You take a moment to apply [src]. Perfect!</span>")
H.lip_style = "lipstick"
H.lip_color = colour
H.update_body()
else
user.visible_message("<span class='warning'>[user] begins to do [H]'s lips with \the [src].</span>", \
"<span class='notice'>You begin to apply \the [src].</span>")
if(do_after(user, 20, target = H))
user.visible_message("<span class='notice'>[user] does [H]'s lips with \the [src].</span>", \
"<span class='notice'>You apply \the [src].</span>")
H.lip_style = "lipstick"
H.lip_color = colour
H.update_body()
else
to_chat(user, "<span class='notice'>Where are the lips on that?</span>")
/obj/item/razor
name = "electric razor"
desc = "The latest and greatest power razor born from the science of shaving."
icon = 'icons/obj/items.dmi'
icon_state = "razor"
flags = CONDUCT
w_class = WEIGHT_CLASS_TINY
usesound = 'sound/items/welder2.ogg'
toolspeed = 1
/obj/item/razor/attack(mob/living/carbon/M as mob, mob/user as mob)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/head/C = H.get_organ("head")
var/datum/robolimb/robohead = all_robolimbs[C.model]
if(user.zone_selected == "mouth")
if(!get_location_accessible(H, "mouth"))
to_chat(user, "<span class='warning'>The mask is in the way.</span>")
return
if((C.dna.species.bodyflags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'...
to_chat(user, "<span class='warning'>You find yourself disappointed at the appalling lack of facial hair.</span>")
return
if(C.f_style == "Shaved")
to_chat(user, "<span class='notice'>Already clean-shaven.</span>")
return
if(H == user) //shaving yourself
user.visible_message("<span class='notice'>[user] starts to shave [user.p_their()] facial hair with [src].</span>", \
"<span class='notice'>You take a moment shave your facial hair with \the [src].</span>")
if(do_after(user, 50 * toolspeed, target = H))
user.visible_message("<span class='notice'>[user] shaves [user.p_their()] facial hair clean with [src].</span>", \
"<span class='notice'>You finish shaving with [src]. Fast and clean!</span>")
C.f_style = "Shaved"
H.update_fhair()
playsound(src.loc, usesound, 20, 1)
else
var/turf/user_loc = user.loc
var/turf/H_loc = H.loc
user.visible_message("<span class='danger'>[user] tries to shave [H]'s facial hair with \the [src].</span>", \
"<span class='warning'>You start shaving [H]'s facial hair.</span>")
if(do_after(user, 50 * toolspeed, target = H))
if(user_loc == user.loc && H_loc == H.loc)
user.visible_message("<span class='danger'>[user] shaves off [H]'s facial hair with \the [src].</span>", \
"<span class='notice'>You shave [H]'s facial hair clean off.</span>")
C.f_style = "Shaved"
H.update_fhair()
playsound(src.loc, usesound, 20, 1)
if(user.zone_selected == "head")
if(!get_location_accessible(H, "head"))
to_chat(user, "<span class='warning'>The headgear is in the way.</span>")
return
if((C.dna.species.bodyflags & ALL_RPARTS) && robohead.is_monitor) //If the target is of a species that can have prosthetic heads, but the head doesn't support human hair 'wigs'...
to_chat(user, "<span class='warning'>You find yourself disappointed at the appalling lack of hair.</span>")
return
if(C.h_style == "Bald" || C.h_style == "Balding Hair" || C.h_style == "Skinhead")
to_chat(user, "<span class='notice'>There is not enough hair left to shave...</span>")
return
if(isskrell(M))
to_chat(user, "<span class='warning'>Your razor isn't going to cut through tentacles.</span>")
return
if(H == user) //shaving yourself
user.visible_message("<span class='warning'>[user] starts to shave [user.p_their()] head with [src].</span>", \
"<span class='warning'>You start to shave your head with \the [src].</span>")
if(do_after(user, 50 * toolspeed, target = H))
user.visible_message("<span class='notice'>[user] shaves [user.p_their()] head with [src].</span>", \
"<span class='notice'>You finish shaving with \the [src].</span>")
C.h_style = "Skinhead"
H.update_hair()
playsound(src.loc, usesound, 40, 1)
else
var/turf/user_loc = user.loc
var/turf/H_loc = H.loc
user.visible_message("<span class='danger'>[user] tries to shave [H]'s head with \the [src]!</span>", \
"<span class='warning'>You start shaving [H]'s head.</span>")
if(do_after(user, 50 * toolspeed, target = H))
if(user_loc == user.loc && H_loc == H.loc)
user.visible_message("<span class='danger'>[user] shaves [H]'s head bald with \the [src]!</span>", \
"<span class='warning'>You shave [H]'s head bald.</span>")
C.h_style = "Skinhead"
H.update_hair()
playsound(src.loc, usesound, 40, 1)
else
..()
else
..()
+213 -213
View File
@@ -1,213 +1,213 @@
/obj/item/storage/pill_bottle/dice
name = "bag of dice"
desc = "Contains all the luck you'll ever need."
icon = 'icons/obj/dice.dmi'
icon_state = "dicebag"
can_hold = list(/obj/item/dice)
allow_wrap = FALSE
/obj/item/storage/pill_bottle/dice/New()
..()
var/special_die = pick("1","2","fudge","00","100")
if(special_die == "1")
new /obj/item/dice/d1(src)
if(special_die == "2")
new /obj/item/dice/d2(src)
new /obj/item/dice/d4(src)
new /obj/item/dice/d6(src)
if(special_die == "fudge")
new /obj/item/dice/fudge(src)
new /obj/item/dice/d8(src)
new /obj/item/dice/d10(src)
if(special_die == "00")
new /obj/item/dice/d00(src)
new /obj/item/dice/d12(src)
new /obj/item/dice/d20(src)
if(special_die == "100")
new /obj/item/dice/d100(src)
/obj/item/storage/pill_bottle/dice/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is gambling with death! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (OXYLOSS)
/obj/item/dice //depreciated d6, use /obj/item/dice/d6 if you actually want a d6
name = "die"
desc = "A die with six sides. Basic and servicable."
icon = 'icons/obj/dice.dmi'
icon_state = "d6"
w_class = WEIGHT_CLASS_TINY
var/sides = 6
var/result = null
var/list/special_faces = list() //entries should match up to sides var if used
var/rigged = DICE_NOT_RIGGED
var/rigged_value
/obj/item/dice/Initialize(mapload)
. = ..()
if(!result)
result = roll(sides)
update_icon()
/obj/item/dice/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is gambling with death! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (OXYLOSS)
/obj/item/dice/d1
name = "d1"
desc = "A die with one side. Deterministic!"
icon_state = "d1"
sides = 1
/obj/item/dice/d2
name = "d2"
desc = "A die with two sides. Coins are undignified!"
icon_state = "d2"
sides = 2
/obj/item/dice/d4
name = "d4"
desc = "A die with four sides. The nerd's caltrop."
icon_state = "d4"
sides = 4
/obj/item/dice/d4/Initialize(mapload)
. = ..()
AddComponent(/datum/component/caltrop, 1, 4) //1d4 damage
/obj/item/dice/d6
name = "d6"
/obj/item/dice/fudge
name = "fudge die"
desc = "A die with six sides but only three results. Is this a plus or a minus? Your mind is drawing a blank..."
sides = 3 //shhh
icon_state = "fudge"
special_faces = list("minus","blank","plus")
/obj/item/dice/d8
name = "d8"
desc = "A die with eight sides. It feels... lucky."
icon_state = "d8"
sides = 8
/obj/item/dice/d10
name = "d10"
desc = "A die with ten sides. Useful for percentages."
icon_state = "d10"
sides = 10
/obj/item/dice/d00
name = "d00"
desc = "A die with ten sides. Works better for d100 rolls than a golfball."
icon_state = "d00"
sides = 10
/obj/item/dice/d12
name = "d12"
desc = "A die with twelve sides. There's an air of neglect about it."
icon_state = "d12"
sides = 12
/obj/item/dice/d20
name = "d20"
desc = "A die with twenty sides. The prefered die to throw at the GM."
icon_state = "d20"
sides = 20
/obj/item/dice/d100
name = "d100"
desc = "A die with one hundred sides! Probably not fairly weighted..."
icon_state = "d100"
sides = 100
/obj/item/dice/d100/update_icon()
return
/obj/item/dice/d20/e20
var/triggered = 0
/obj/item/dice/attack_self(mob/user as mob)
diceroll(user)
/obj/item/dice/throw_impact(atom/target)
diceroll(thrownby)
. = ..()
/obj/item/dice/proc/diceroll(mob/user)
result = roll(sides)
if(rigged != DICE_NOT_RIGGED && result != rigged_value)
if(rigged == DICE_BASICALLY_RIGGED && prob(Clamp(1/(sides - 1) * 100, 25, 80)))
result = rigged_value
else if(rigged == DICE_TOTALLY_RIGGED)
result = rigged_value
. = result
var/fake_result = roll(sides)//Daredevil isn't as good as he used to be
var/comment = ""
if(sides == 20 && result == 20)
comment = "NAT 20!"
else if(sides == 20 && result == 1)
comment = "Ouch, bad luck."
update_icon()
if(initial(icon_state) == "d00")
result = (result - 1)*10
if(special_faces.len == sides)
result = special_faces[result]
if(user != null) //Dice was rolled in someone's hand
user.visible_message("[user] has thrown [src]. It lands on [result]. [comment]", \
"<span class='notice'>You throw [src]. It lands on [result]. [comment]</span>", \
"<span class='italics'>You hear [src] rolling, it sounds like a [fake_result].</span>")
else if(!src.throwing) //Dice was thrown and is coming to rest
visible_message("<span class='notice'>[src] rolls to a stop, landing on [result]. [comment]</span>")
/obj/item/dice/d20/e20/diceroll(mob/user as mob, thrown)
if(triggered)
return
. = ..()
if(result == 1)
to_chat(user, "<span class='danger'>Rocks fall, you die.</span>")
user.gib()
else
triggered = 1
visible_message("<span class='notice'>You hear a quiet click.</span>")
spawn(40)
var/cap = 0
if(result > MAX_EX_LIGHT_RANGE && result != 20)
cap = 1
result = min(result, MAX_EX_LIGHT_RANGE) //Apply the bombcap
else if(result == 20) //Roll a nat 20, screw the bombcap
result = 24
var/turf/epicenter = get_turf(src)
explosion(epicenter, round(result*0.25), round(result*0.5), round(result), round(result*1.5), 1, cap)
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
investigate_log("E20 detonated at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with a roll of [result]. Triggered by: [key_name(user)]", INVESTIGATE_BOMB)
message_admins("E20 detonated at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a> with a roll of [result]. Triggered by: [key_name_admin(user)]")
log_game("E20 detonated at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with a roll of [result]. Triggered by: [key_name(user)]")
/obj/item/dice/update_icon()
overlays.Cut()
overlays += "[icon_state][result]"
/obj/item/storage/box/dice
name = "Box of dice"
desc = "ANOTHER ONE!? FUCK!"
icon_state = "box"
/obj/item/storage/box/dice/New()
..()
new /obj/item/dice/d2(src)
new /obj/item/dice/d4(src)
new /obj/item/dice/d8(src)
new /obj/item/dice/d10(src)
new /obj/item/dice/d00(src)
new /obj/item/dice/d12(src)
new /obj/item/dice/d20(src)
/obj/item/storage/pill_bottle/dice
name = "bag of dice"
desc = "Contains all the luck you'll ever need."
icon = 'icons/obj/dice.dmi'
icon_state = "dicebag"
can_hold = list(/obj/item/dice)
allow_wrap = FALSE
/obj/item/storage/pill_bottle/dice/New()
..()
var/special_die = pick("1","2","fudge","00","100")
if(special_die == "1")
new /obj/item/dice/d1(src)
if(special_die == "2")
new /obj/item/dice/d2(src)
new /obj/item/dice/d4(src)
new /obj/item/dice/d6(src)
if(special_die == "fudge")
new /obj/item/dice/fudge(src)
new /obj/item/dice/d8(src)
new /obj/item/dice/d10(src)
if(special_die == "00")
new /obj/item/dice/d00(src)
new /obj/item/dice/d12(src)
new /obj/item/dice/d20(src)
if(special_die == "100")
new /obj/item/dice/d100(src)
/obj/item/storage/pill_bottle/dice/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is gambling with death! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (OXYLOSS)
/obj/item/dice //depreciated d6, use /obj/item/dice/d6 if you actually want a d6
name = "die"
desc = "A die with six sides. Basic and servicable."
icon = 'icons/obj/dice.dmi'
icon_state = "d6"
w_class = WEIGHT_CLASS_TINY
var/sides = 6
var/result = null
var/list/special_faces = list() //entries should match up to sides var if used
var/rigged = DICE_NOT_RIGGED
var/rigged_value
/obj/item/dice/Initialize(mapload)
. = ..()
if(!result)
result = roll(sides)
update_icon()
/obj/item/dice/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is gambling with death! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (OXYLOSS)
/obj/item/dice/d1
name = "d1"
desc = "A die with one side. Deterministic!"
icon_state = "d1"
sides = 1
/obj/item/dice/d2
name = "d2"
desc = "A die with two sides. Coins are undignified!"
icon_state = "d2"
sides = 2
/obj/item/dice/d4
name = "d4"
desc = "A die with four sides. The nerd's caltrop."
icon_state = "d4"
sides = 4
/obj/item/dice/d4/Initialize(mapload)
. = ..()
AddComponent(/datum/component/caltrop, 1, 4) //1d4 damage
/obj/item/dice/d6
name = "d6"
/obj/item/dice/fudge
name = "fudge die"
desc = "A die with six sides but only three results. Is this a plus or a minus? Your mind is drawing a blank..."
sides = 3 //shhh
icon_state = "fudge"
special_faces = list("minus","blank","plus")
/obj/item/dice/d8
name = "d8"
desc = "A die with eight sides. It feels... lucky."
icon_state = "d8"
sides = 8
/obj/item/dice/d10
name = "d10"
desc = "A die with ten sides. Useful for percentages."
icon_state = "d10"
sides = 10
/obj/item/dice/d00
name = "d00"
desc = "A die with ten sides. Works better for d100 rolls than a golfball."
icon_state = "d00"
sides = 10
/obj/item/dice/d12
name = "d12"
desc = "A die with twelve sides. There's an air of neglect about it."
icon_state = "d12"
sides = 12
/obj/item/dice/d20
name = "d20"
desc = "A die with twenty sides. The prefered die to throw at the GM."
icon_state = "d20"
sides = 20
/obj/item/dice/d100
name = "d100"
desc = "A die with one hundred sides! Probably not fairly weighted..."
icon_state = "d100"
sides = 100
/obj/item/dice/d100/update_icon()
return
/obj/item/dice/d20/e20
var/triggered = 0
/obj/item/dice/attack_self(mob/user as mob)
diceroll(user)
/obj/item/dice/throw_impact(atom/target)
diceroll(thrownby)
. = ..()
/obj/item/dice/proc/diceroll(mob/user)
result = roll(sides)
if(rigged != DICE_NOT_RIGGED && result != rigged_value)
if(rigged == DICE_BASICALLY_RIGGED && prob(Clamp(1/(sides - 1) * 100, 25, 80)))
result = rigged_value
else if(rigged == DICE_TOTALLY_RIGGED)
result = rigged_value
. = result
var/fake_result = roll(sides)//Daredevil isn't as good as he used to be
var/comment = ""
if(sides == 20 && result == 20)
comment = "NAT 20!"
else if(sides == 20 && result == 1)
comment = "Ouch, bad luck."
update_icon()
if(initial(icon_state) == "d00")
result = (result - 1)*10
if(special_faces.len == sides)
result = special_faces[result]
if(user != null) //Dice was rolled in someone's hand
user.visible_message("[user] has thrown [src]. It lands on [result]. [comment]", \
"<span class='notice'>You throw [src]. It lands on [result]. [comment]</span>", \
"<span class='italics'>You hear [src] rolling, it sounds like a [fake_result].</span>")
else if(!src.throwing) //Dice was thrown and is coming to rest
visible_message("<span class='notice'>[src] rolls to a stop, landing on [result]. [comment]</span>")
/obj/item/dice/d20/e20/diceroll(mob/user as mob, thrown)
if(triggered)
return
. = ..()
if(result == 1)
to_chat(user, "<span class='danger'>Rocks fall, you die.</span>")
user.gib()
else
triggered = 1
visible_message("<span class='notice'>You hear a quiet click.</span>")
spawn(40)
var/cap = 0
if(result > MAX_EX_LIGHT_RANGE && result != 20)
cap = 1
result = min(result, MAX_EX_LIGHT_RANGE) //Apply the bombcap
else if(result == 20) //Roll a nat 20, screw the bombcap
result = 24
var/turf/epicenter = get_turf(src)
explosion(epicenter, round(result*0.25), round(result*0.5), round(result), round(result*1.5), 1, cap)
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
investigate_log("E20 detonated at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with a roll of [result]. Triggered by: [key_name(user)]", INVESTIGATE_BOMB)
message_admins("E20 detonated at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a> with a roll of [result]. Triggered by: [key_name_admin(user)]")
log_game("E20 detonated at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with a roll of [result]. Triggered by: [key_name(user)]")
/obj/item/dice/update_icon()
overlays.Cut()
overlays += "[icon_state][result]"
/obj/item/storage/box/dice
name = "Box of dice"
desc = "ANOTHER ONE!? FUCK!"
icon_state = "box"
/obj/item/storage/box/dice/New()
..()
new /obj/item/dice/d2(src)
new /obj/item/dice/d4(src)
new /obj/item/dice/d8(src)
new /obj/item/dice/d10(src)
new /obj/item/dice/d00(src)
new /obj/item/dice/d12(src)
new /obj/item/dice/d20(src)
File diff suppressed because it is too large Load Diff
+277 -277
View File
@@ -1,277 +1,277 @@
/obj/item/grenade/plastic
name = "plastic explosive"
desc = "Used to put holes in specific areas without too much extra hole."
icon_state = "plastic-explosive0"
item_state = "plastic-explosive"
flags = NOBLUDGEON
det_time = 10
display_timer = 0
origin_tech = "syndicate=1"
toolspeed = 1
var/atom/target = null
var/image_overlay = null
var/obj/item/assembly_holder/nadeassembly = null
var/assemblyattacher
/obj/item/grenade/plastic/New()
image_overlay = image('icons/obj/grenade.dmi', "[item_state]2")
..()
/obj/item/grenade/plastic/Destroy()
QDEL_NULL(nadeassembly)
target = null
return ..()
/obj/item/grenade/plastic/attackby(obj/item/I, mob/user, params)
if(!nadeassembly && istype(I, /obj/item/assembly_holder))
var/obj/item/assembly_holder/A = I
if(!user.unEquip(I))
return ..()
nadeassembly = A
A.master = src
A.loc = src
assemblyattacher = user.ckey
to_chat(user, "<span class='notice'>You add [A] to the [name].</span>")
playsound(src, 'sound/weapons/tap.ogg', 20, 1)
update_icon()
return
if(nadeassembly && istype(I, /obj/item/wirecutters))
playsound(src, I.usesound, 20, 1)
nadeassembly.loc = get_turf(src)
nadeassembly.master = null
nadeassembly = null
update_icon()
return
..()
//assembly stuff
/obj/item/grenade/plastic/receive_signal()
prime()
/obj/item/grenade/plastic/Crossed(atom/movable/AM, oldloc)
if(nadeassembly)
nadeassembly.Crossed(AM, oldloc)
/obj/item/grenade/plastic/on_found(mob/finder)
if(nadeassembly)
nadeassembly.on_found(finder)
/obj/item/grenade/plastic/attack_self(mob/user)
if(nadeassembly)
nadeassembly.attack_self(user)
return
var/newtime = input(usr, "Please set the timer.", "Timer", det_time) as num
if(user.is_in_active_hand(src))
newtime = Clamp(newtime, 10, 60000)
det_time = newtime
to_chat(user, "Timer set for [det_time] seconds.")
/obj/item/grenade/plastic/afterattack(atom/movable/AM, mob/user, flag)
if (!flag)
return
if (istype(AM, /mob/living/carbon))
return
to_chat(user, "<span class='notice'>You start planting the [src]. The timer is set to [det_time]...</span>")
if(do_after(user, 50 * toolspeed, target = AM))
if(!user.unEquip(src))
return
src.target = AM
loc = null
message_admins("[key_name_admin(user)]([ADMIN_QUE(user,"?")]) ([ADMIN_FLW(user,"FLW")]) planted [src.name] on [target.name] at ([target.x],[target.y],[target.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[target.x];Y=[target.y];Z=[target.z]'>JMP</a>) with [det_time] second fuse",0,1)
log_game("[key_name(user)] planted [name] on [target.name] at ([target.x],[target.y],[target.z]) with [det_time] second fuse")
target.overlays += image_overlay
if(!nadeassembly)
to_chat(user, "<span class='notice'>You plant the bomb. Timer counting down from [det_time].</span>")
addtimer(CALLBACK(src, .proc/prime), det_time*10)
/obj/item/grenade/plastic/suicide_act(mob/user)
message_admins("[key_name_admin(user)]([ADMIN_QUE(user,"?")]) ([ADMIN_FLW(user,"FLW")]) suicided with [src.name] at ([user.x],[user.y],[user.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)",0,1)
log_game("[key_name(user)] suicided with [name] at ([user.x],[user.y],[user.z])")
user.visible_message("<span class='suicide'>[user] activates the [name] and holds it above [user.p_their()] head! It looks like [user.p_theyre()] going out with a bang!</span>")
var/message_say = "FOR NO RAISIN!"
if(user.mind)
if(user.mind.special_role)
var/role = lowertext(user.mind.special_role)
if(role == ROLE_TRAITOR || role == "syndicate" || role == "syndicate commando")
message_say = "FOR THE SYNDICATE!"
else if(role == ROLE_CHANGELING)
message_say = "FOR THE HIVE!"
else if(role == ROLE_CULTIST)
message_say = "FOR NARSIE!"
else if(role == ROLE_NINJA)
message_say = "FOR THE CLAN!"
else if(role == ROLE_WIZARD)
message_say = "FOR THE FEDERATION!"
else if(role == ROLE_REV || role == "head revolutionary")
message_say = "FOR THE REVOLOUTION!"
else if(role == "death commando" || role == ROLE_ERT)
message_say = "FOR NANOTRASEN!"
else if(role == ROLE_DEVIL)
message_say = "FOR INFERNO!"
user.say(message_say)
target = user
sleep(10)
prime()
user.gib()
return OBLITERATION
/obj/item/grenade/plastic/update_icon()
if(nadeassembly)
icon_state = "[item_state]1"
else
icon_state = "[item_state]0"
//////////////////////////
///// The Explosives /////
//////////////////////////
/obj/item/grenade/plastic/c4
name = "C4"
desc = "Used to put holes in specific areas without too much extra hole. A saboteurs favourite."
/obj/item/grenade/plastic/c4/prime()
var/turf/location
if(target)
if(!QDELETED(target))
if(istype(target, /turf/))
location = get_turf(target) // Set the explosion location to turf if planted directly on a wall or floor
else
location = get_atom_on_turf(target) // Otherwise, make sure we're blowing up what's on top of the turf
target.overlays -= image_overlay
else
location = get_atom_on_turf(src)
if(location)
explosion(location,0,0,3)
location.ex_act(2, target)
if(istype(target, /mob))
var/mob/M = target
M.gib()
qdel(src)
// X4 is an upgraded directional variant of c4 which is relatively safe to be standing next to. And much less safe to be standing on the other side of.
// C4 is intended to be used for infiltration, and destroying tech. X4 is intended to be used for heavy breaching and tight spaces.
// Intended to replace C4 for nukeops, and to be a randomdrop in surplus/random traitor purchases.
/obj/item/grenade/plastic/x4
name = "X4"
desc = "A specialized shaped high explosive breaching charge. Designed to be safer for the user, and less so, for the wall."
var/aim_dir = NORTH
icon_state = "plasticx40"
item_state = "plasticx4"
/obj/item/grenade/plastic/x4/prime()
var/turf/location
if(target)
if(!QDELETED(target))
if(istype(target, /turf/))
location = get_turf(target)
else
location = get_atom_on_turf(target)
target.overlays -= image_overlay
else
location = get_atom_on_turf(src)
if(location)
if(target && target.density)
var/turf/T = get_step(location, aim_dir)
explosion(get_step(T, aim_dir),0,0,3)
explosion(T,0,2,0)
location.ex_act(2, target)
else
explosion(location, 0, 2, 3)
location.ex_act(2, target)
if(istype(target, /mob))
var/mob/M = target
M.gib()
qdel(src)
/obj/item/grenade/plastic/x4/afterattack(atom/movable/AM, mob/user, flag)
aim_dir = get_dir(user,AM)
..()
// Shaped charge
// Same blasting power as C4, but with the same idea as the X4 -- Everyone on one side of the wall is safe.
/obj/item/grenade/plastic/c4_shaped
name = "C4 (shaped)"
desc = "A brick of C4 shaped to allow more precise breaching."
var/aim_dir = NORTH
/obj/item/grenade/plastic/c4_shaped/prime()
var/turf/location
if(target)
if(!QDELETED(target))
location = get_turf(target)
target.overlays -= image_overlay
else
location = get_turf(src)
if(location)
if(target && target.density)
var/turf/T = get_step(location, aim_dir)
explosion(get_step(T, aim_dir),0,0,3)
location.ex_act(2, target)
else
explosion(location, 0, 0, 3)
location.ex_act(2, target)
if(istype(target, /mob))
var/mob/M = target
M.gib()
qdel(src)
/obj/item/grenade/plastic/c4_shaped/afterattack(atom/movable/AM, mob/user, flag)
aim_dir = get_dir(user,AM)
..()
/obj/item/grenade/plastic/c4_shaped/flash
name = "C4 (flash)"
desc = "A C4 charge with an altered chemical composition, designed to blind and deafen the occupants of a room before breaching."
/obj/item/grenade/plastic/c4_shaped/flash/prime()
if(target && target.density)
T = get_step(get_turf(target), aim_dir)
else if(target)
T = get_turf(target)
else
T = get_turf(src)
var/obj/item/grenade/flashbang/CB = new/obj/item/grenade/flashbang(T)
CB.prime()
..()
/obj/item/grenade/plastic/x4/thermite
name = "T4"
desc = "A wall breaching charge, containing fuel, metal oxide and metal powder mixed in just the right way. One hell of a combination. Effective against walls, ineffective against airlocks..."
det_time = 2
icon_state = "t4breach0"
item_state = "t4breach"
/obj/item/grenade/plastic/x4/thermite/prime()
var/turf/location
if(target)
if(!QDELETED(target))
location = get_turf(target)
target.overlays -= image_overlay
else
location = get_turf(src)
if(location)
var/datum/effect_system/smoke_spread/smoke = new
smoke.set_up(8,0, location, aim_dir)
if(target && target.density)
var/turf/T = get_step(location, aim_dir)
for(var/turf/simulated/wall/W in range(1, location))
W.thermitemelt(speed = 30)
addtimer(CALLBACK(null, .proc/explosion, T, 0, 0, 2), 3)
addtimer(CALLBACK(smoke, /datum/effect_system/smoke_spread/.proc/start), 3)
else
addtimer(CALLBACK(null, .proc/explosion, T, 0, 0, 2), 3)
addtimer(CALLBACK(smoke, /datum/effect_system/smoke_spread/.proc/start), 3)
if(isliving(target))
var/mob/living/M = target
M.adjust_fire_stacks(2)
M.IgniteMob()
qdel(src)
/obj/item/grenade/plastic
name = "plastic explosive"
desc = "Used to put holes in specific areas without too much extra hole."
icon_state = "plastic-explosive0"
item_state = "plastic-explosive"
flags = NOBLUDGEON
det_time = 10
display_timer = 0
origin_tech = "syndicate=1"
toolspeed = 1
var/atom/target = null
var/image_overlay = null
var/obj/item/assembly_holder/nadeassembly = null
var/assemblyattacher
/obj/item/grenade/plastic/New()
image_overlay = image('icons/obj/grenade.dmi', "[item_state]2")
..()
/obj/item/grenade/plastic/Destroy()
QDEL_NULL(nadeassembly)
target = null
return ..()
/obj/item/grenade/plastic/attackby(obj/item/I, mob/user, params)
if(!nadeassembly && istype(I, /obj/item/assembly_holder))
var/obj/item/assembly_holder/A = I
if(!user.unEquip(I))
return ..()
nadeassembly = A
A.master = src
A.loc = src
assemblyattacher = user.ckey
to_chat(user, "<span class='notice'>You add [A] to the [name].</span>")
playsound(src, 'sound/weapons/tap.ogg', 20, 1)
update_icon()
return
if(nadeassembly && istype(I, /obj/item/wirecutters))
playsound(src, I.usesound, 20, 1)
nadeassembly.loc = get_turf(src)
nadeassembly.master = null
nadeassembly = null
update_icon()
return
..()
//assembly stuff
/obj/item/grenade/plastic/receive_signal()
prime()
/obj/item/grenade/plastic/Crossed(atom/movable/AM, oldloc)
if(nadeassembly)
nadeassembly.Crossed(AM, oldloc)
/obj/item/grenade/plastic/on_found(mob/finder)
if(nadeassembly)
nadeassembly.on_found(finder)
/obj/item/grenade/plastic/attack_self(mob/user)
if(nadeassembly)
nadeassembly.attack_self(user)
return
var/newtime = input(usr, "Please set the timer.", "Timer", det_time) as num
if(user.is_in_active_hand(src))
newtime = Clamp(newtime, 10, 60000)
det_time = newtime
to_chat(user, "Timer set for [det_time] seconds.")
/obj/item/grenade/plastic/afterattack(atom/movable/AM, mob/user, flag)
if (!flag)
return
if (istype(AM, /mob/living/carbon))
return
to_chat(user, "<span class='notice'>You start planting the [src]. The timer is set to [det_time]...</span>")
if(do_after(user, 50 * toolspeed, target = AM))
if(!user.unEquip(src))
return
src.target = AM
loc = null
message_admins("[key_name_admin(user)]([ADMIN_QUE(user,"?")]) ([ADMIN_FLW(user,"FLW")]) planted [src.name] on [target.name] at ([target.x],[target.y],[target.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[target.x];Y=[target.y];Z=[target.z]'>JMP</a>) with [det_time] second fuse",0,1)
log_game("[key_name(user)] planted [name] on [target.name] at ([target.x],[target.y],[target.z]) with [det_time] second fuse")
target.overlays += image_overlay
if(!nadeassembly)
to_chat(user, "<span class='notice'>You plant the bomb. Timer counting down from [det_time].</span>")
addtimer(CALLBACK(src, .proc/prime), det_time*10)
/obj/item/grenade/plastic/suicide_act(mob/user)
message_admins("[key_name_admin(user)]([ADMIN_QUE(user,"?")]) ([ADMIN_FLW(user,"FLW")]) suicided with [src.name] at ([user.x],[user.y],[user.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)",0,1)
log_game("[key_name(user)] suicided with [name] at ([user.x],[user.y],[user.z])")
user.visible_message("<span class='suicide'>[user] activates the [name] and holds it above [user.p_their()] head! It looks like [user.p_theyre()] going out with a bang!</span>")
var/message_say = "FOR NO RAISIN!"
if(user.mind)
if(user.mind.special_role)
var/role = lowertext(user.mind.special_role)
if(role == ROLE_TRAITOR || role == "syndicate" || role == "syndicate commando")
message_say = "FOR THE SYNDICATE!"
else if(role == ROLE_CHANGELING)
message_say = "FOR THE HIVE!"
else if(role == ROLE_CULTIST)
message_say = "FOR NARSIE!"
else if(role == ROLE_NINJA)
message_say = "FOR THE CLAN!"
else if(role == ROLE_WIZARD)
message_say = "FOR THE FEDERATION!"
else if(role == ROLE_REV || role == "head revolutionary")
message_say = "FOR THE REVOLOUTION!"
else if(role == "death commando" || role == ROLE_ERT)
message_say = "FOR NANOTRASEN!"
else if(role == ROLE_DEVIL)
message_say = "FOR INFERNO!"
user.say(message_say)
target = user
sleep(10)
prime()
user.gib()
return OBLITERATION
/obj/item/grenade/plastic/update_icon()
if(nadeassembly)
icon_state = "[item_state]1"
else
icon_state = "[item_state]0"
//////////////////////////
///// The Explosives /////
//////////////////////////
/obj/item/grenade/plastic/c4
name = "C4"
desc = "Used to put holes in specific areas without too much extra hole. A saboteurs favourite."
/obj/item/grenade/plastic/c4/prime()
var/turf/location
if(target)
if(!QDELETED(target))
if(istype(target, /turf/))
location = get_turf(target) // Set the explosion location to turf if planted directly on a wall or floor
else
location = get_atom_on_turf(target) // Otherwise, make sure we're blowing up what's on top of the turf
target.overlays -= image_overlay
else
location = get_atom_on_turf(src)
if(location)
explosion(location,0,0,3)
location.ex_act(2, target)
if(istype(target, /mob))
var/mob/M = target
M.gib()
qdel(src)
// X4 is an upgraded directional variant of c4 which is relatively safe to be standing next to. And much less safe to be standing on the other side of.
// C4 is intended to be used for infiltration, and destroying tech. X4 is intended to be used for heavy breaching and tight spaces.
// Intended to replace C4 for nukeops, and to be a randomdrop in surplus/random traitor purchases.
/obj/item/grenade/plastic/x4
name = "X4"
desc = "A specialized shaped high explosive breaching charge. Designed to be safer for the user, and less so, for the wall."
var/aim_dir = NORTH
icon_state = "plasticx40"
item_state = "plasticx4"
/obj/item/grenade/plastic/x4/prime()
var/turf/location
if(target)
if(!QDELETED(target))
if(istype(target, /turf/))
location = get_turf(target)
else
location = get_atom_on_turf(target)
target.overlays -= image_overlay
else
location = get_atom_on_turf(src)
if(location)
if(target && target.density)
var/turf/T = get_step(location, aim_dir)
explosion(get_step(T, aim_dir),0,0,3)
explosion(T,0,2,0)
location.ex_act(2, target)
else
explosion(location, 0, 2, 3)
location.ex_act(2, target)
if(istype(target, /mob))
var/mob/M = target
M.gib()
qdel(src)
/obj/item/grenade/plastic/x4/afterattack(atom/movable/AM, mob/user, flag)
aim_dir = get_dir(user,AM)
..()
// Shaped charge
// Same blasting power as C4, but with the same idea as the X4 -- Everyone on one side of the wall is safe.
/obj/item/grenade/plastic/c4_shaped
name = "C4 (shaped)"
desc = "A brick of C4 shaped to allow more precise breaching."
var/aim_dir = NORTH
/obj/item/grenade/plastic/c4_shaped/prime()
var/turf/location
if(target)
if(!QDELETED(target))
location = get_turf(target)
target.overlays -= image_overlay
else
location = get_turf(src)
if(location)
if(target && target.density)
var/turf/T = get_step(location, aim_dir)
explosion(get_step(T, aim_dir),0,0,3)
location.ex_act(2, target)
else
explosion(location, 0, 0, 3)
location.ex_act(2, target)
if(istype(target, /mob))
var/mob/M = target
M.gib()
qdel(src)
/obj/item/grenade/plastic/c4_shaped/afterattack(atom/movable/AM, mob/user, flag)
aim_dir = get_dir(user,AM)
..()
/obj/item/grenade/plastic/c4_shaped/flash
name = "C4 (flash)"
desc = "A C4 charge with an altered chemical composition, designed to blind and deafen the occupants of a room before breaching."
/obj/item/grenade/plastic/c4_shaped/flash/prime()
if(target && target.density)
T = get_step(get_turf(target), aim_dir)
else if(target)
T = get_turf(target)
else
T = get_turf(src)
var/obj/item/grenade/flashbang/CB = new/obj/item/grenade/flashbang(T)
CB.prime()
..()
/obj/item/grenade/plastic/x4/thermite
name = "T4"
desc = "A wall breaching charge, containing fuel, metal oxide and metal powder mixed in just the right way. One hell of a combination. Effective against walls, ineffective against airlocks..."
det_time = 2
icon_state = "t4breach0"
item_state = "t4breach"
/obj/item/grenade/plastic/x4/thermite/prime()
var/turf/location
if(target)
if(!QDELETED(target))
location = get_turf(target)
target.overlays -= image_overlay
else
location = get_turf(src)
if(location)
var/datum/effect_system/smoke_spread/smoke = new
smoke.set_up(8,0, location, aim_dir)
if(target && target.density)
var/turf/T = get_step(location, aim_dir)
for(var/turf/simulated/wall/W in range(1, location))
W.thermitemelt(speed = 30)
addtimer(CALLBACK(null, .proc/explosion, T, 0, 0, 2), 3)
addtimer(CALLBACK(smoke, /datum/effect_system/smoke_spread/.proc/start), 3)
else
addtimer(CALLBACK(null, .proc/explosion, T, 0, 0, 2), 3)
addtimer(CALLBACK(smoke, /datum/effect_system/smoke_spread/.proc/start), 3)
if(isliving(target))
var/mob/living/M = target
M.adjust_fire_stacks(2)
M.IgniteMob()
qdel(src)
+180 -179
View File
@@ -1,179 +1,180 @@
/obj/item/extinguisher
name = "fire extinguisher"
desc = "A traditional red fire extinguisher."
icon = 'icons/obj/items.dmi'
icon_state = "fire_extinguisher0"
item_state = "fire_extinguisher"
hitsound = 'sound/weapons/smash.ogg'
flags = CONDUCT
throwforce = 10
w_class = WEIGHT_CLASS_NORMAL
throw_speed = 2
throw_range = 7
force = 10
container_type = AMOUNT_VISIBLE
materials = list(MAT_METAL=90)
attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed")
dog_fashion = /datum/dog_fashion/back
resistance_flags = FIRE_PROOF
var/max_water = 50
var/last_use = 1.0
var/safety = 1
var/refilling = FALSE
var/sprite_name = "fire_extinguisher"
var/power = 5 //Maximum distance launched water will travel
var/precision = 0 //By default, turfs picked from a spray are random, set to 1 to make it always have at least one water effect per row
var/cooling_power = 2 //Sets the cooling_temperature of the water reagent datum inside of the extinguisher when it is refilled
/obj/item/extinguisher/mini
name = "pocket fire extinguisher"
desc = "A light and compact fibreglass-framed model fire extinguisher."
icon_state = "miniFE0"
item_state = "miniFE"
hitsound = null //it is much lighter, after all.
flags = null //doesn't CONDUCT
throwforce = 2
w_class = WEIGHT_CLASS_SMALL
force = 3.0
materials = list()
max_water = 30
sprite_name = "miniFE"
dog_fashion = null
/obj/item/extinguisher/examine(mob/user)
. = ..()
. += "<span class='notice'>The safety is [safety ? "on" : "off"].</span>"
/obj/item/extinguisher/New()
create_reagents(max_water)
reagents.add_reagent("water", max_water)
/obj/item/extinguisher/attack_self(mob/user as mob)
safety = !safety
src.icon_state = "[sprite_name][!safety]"
src.desc = "The safety is [safety ? "on" : "off"]."
to_chat(user, "The safety is [safety ? "on" : "off"].")
return
/obj/item/extinguisher/attack_obj(obj/O, mob/living/user)
if(AttemptRefill(O, user))
refilling = TRUE
return FALSE
else
return ..()
/obj/item/extinguisher/proc/AttemptRefill(atom/target, mob/user)
if(istype(target, /obj/structure/reagent_dispensers/watertank) && target.Adjacent(user))
var/safety_save = safety
safety = 1
if(reagents.total_volume == reagents.maximum_volume)
to_chat(user, "<span class='notice'>\The [src] is already full!</span>")
safety = safety_save
return 1
var/obj/structure/reagent_dispensers/watertank/W = target
var/transferred = W.reagents.trans_to(src, max_water)
if(transferred > 0)
to_chat(user, "<span class='notice'>\The [src] has been refilled by [transferred] units</span>")
playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6)
for(var/datum/reagent/water/R in reagents.reagent_list)
R.cooling_temperature = cooling_power
else
to_chat(user, "<span class='notice'>\The [W] is empty!</span>")
safety = safety_save
return 1
else
return 0
/obj/item/extinguisher/afterattack(atom/target, mob/user , flag)
. = ..()
//TODO; Add support for reagents in water.
if(target.loc == user)//No more spraying yourself when putting your extinguisher away
return
if(refilling)
refilling = FALSE
return
if(!safety)
if(src.reagents.total_volume < 1)
to_chat(usr, "<span class='danger'>\The [src] is empty.</span>")
return
if(world.time < src.last_use + 20)
return
src.last_use = world.time
playsound(src.loc, 'sound/effects/extinguish.ogg', 75, 1, -3)
var/direction = get_dir(src,target)
if(usr.buckled && isobj(usr.buckled) && !usr.buckled.anchored )
spawn(0)
var/obj/structure/chair/C = null
if(istype(usr.buckled, /obj/structure/chair))
C = usr.buckled
var/obj/B = usr.buckled
var/movementdirection = turn(direction,180)
if(C) C.propelled = 4
step(B, movementdirection)
sleep(1)
step(B, movementdirection)
if(C) C.propelled = 3
sleep(1)
step(B, movementdirection)
sleep(1)
step(B, movementdirection)
if(C) C.propelled = 2
sleep(2)
step(B, movementdirection)
if(C) C.propelled = 1
sleep(2)
step(B, movementdirection)
if(C) C.propelled = 0
sleep(3)
step(B, movementdirection)
sleep(3)
step(B, movementdirection)
sleep(3)
step(B, movementdirection)
else user.newtonian_move(turn(direction, 180))
var/turf/T = get_turf(target)
var/turf/T1 = get_step(T,turn(direction, 90))
var/turf/T2 = get_step(T,turn(direction, -90))
var/list/the_targets = list(T,T1,T2)
if(precision)
var/turf/T3 = get_step(T1, turn(direction, 90))
var/turf/T4 = get_step(T2,turn(direction, -90))
the_targets = list(T,T1,T2,T3,T4)
for(var/a=0, a<5, a++)
spawn(0)
var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water( get_turf(src) )
var/turf/my_target = pick(the_targets)
if(precision)
the_targets -= my_target
var/datum/reagents/R = new/datum/reagents(5)
if(!W) return
W.reagents = R
R.my_atom = W
if(!W || !src) return
src.reagents.trans_to(W,1)
for(var/b=0, b<5, b++)
step_towards(W,my_target)
if(!W || !W.reagents) return
W.reagents.reaction(get_turf(W))
for(var/atom/atm in get_turf(W))
if(!W) return
W.reagents.reaction(atm)
if(isliving(atm)) //For extinguishing mobs on fire
var/mob/living/M = atm
M.ExtinguishMob()
if(W.loc == my_target) break
sleep(2)
else
return ..()
/obj/item/extinguisher
name = "fire extinguisher"
desc = "A traditional red fire extinguisher."
icon = 'icons/obj/items.dmi'
icon_state = "fire_extinguisher0"
item_state = "fire_extinguisher"
hitsound = 'sound/weapons/smash.ogg'
flags = CONDUCT
throwforce = 10
w_class = WEIGHT_CLASS_NORMAL
throw_speed = 2
throw_range = 7
force = 10
container_type = AMOUNT_VISIBLE
materials = list(MAT_METAL=90)
attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed")
dog_fashion = /datum/dog_fashion/back
resistance_flags = FIRE_PROOF
var/max_water = 50
var/last_use = 1.0
var/safety = 1
var/refilling = FALSE
var/sprite_name = "fire_extinguisher"
var/power = 5 //Maximum distance launched water will travel
var/precision = 0 //By default, turfs picked from a spray are random, set to 1 to make it always have at least one water effect per row
var/cooling_power = 2 //Sets the cooling_temperature of the water reagent datum inside of the extinguisher when it is refilled
/obj/item/extinguisher/mini
name = "pocket fire extinguisher"
desc = "A light and compact fibreglass-framed model fire extinguisher."
icon_state = "miniFE0"
item_state = "miniFE"
hitsound = null //it is much lighter, after all.
flags = null //doesn't CONDUCT
throwforce = 2
w_class = WEIGHT_CLASS_SMALL
force = 3.0
materials = list()
max_water = 30
sprite_name = "miniFE"
dog_fashion = null
/obj/item/extinguisher/examine(mob/user)
. = ..()
. += "<span class='notice'>The safety is [safety ? "on" : "off"].</span>"
/obj/item/extinguisher/New()
..()
create_reagents(max_water)
reagents.add_reagent("water", max_water)
/obj/item/extinguisher/attack_self(mob/user as mob)
safety = !safety
src.icon_state = "[sprite_name][!safety]"
src.desc = "The safety is [safety ? "on" : "off"]."
to_chat(user, "The safety is [safety ? "on" : "off"].")
return
/obj/item/extinguisher/attack_obj(obj/O, mob/living/user)
if(AttemptRefill(O, user))
refilling = TRUE
return FALSE
else
return ..()
/obj/item/extinguisher/proc/AttemptRefill(atom/target, mob/user)
if(istype(target, /obj/structure/reagent_dispensers/watertank) && target.Adjacent(user))
var/safety_save = safety
safety = 1
if(reagents.total_volume == reagents.maximum_volume)
to_chat(user, "<span class='notice'>\The [src] is already full!</span>")
safety = safety_save
return 1
var/obj/structure/reagent_dispensers/watertank/W = target
var/transferred = W.reagents.trans_to(src, max_water)
if(transferred > 0)
to_chat(user, "<span class='notice'>\The [src] has been refilled by [transferred] units</span>")
playsound(src.loc, 'sound/effects/refill.ogg', 50, 1, -6)
for(var/datum/reagent/water/R in reagents.reagent_list)
R.cooling_temperature = cooling_power
else
to_chat(user, "<span class='notice'>\The [W] is empty!</span>")
safety = safety_save
return 1
else
return 0
/obj/item/extinguisher/afterattack(atom/target, mob/user , flag)
. = ..()
//TODO; Add support for reagents in water.
if(target.loc == user)//No more spraying yourself when putting your extinguisher away
return
if(refilling)
refilling = FALSE
return
if(!safety)
if(src.reagents.total_volume < 1)
to_chat(usr, "<span class='danger'>\The [src] is empty.</span>")
return
if(world.time < src.last_use + 20)
return
src.last_use = world.time
playsound(src.loc, 'sound/effects/extinguish.ogg', 75, 1, -3)
var/direction = get_dir(src,target)
if(usr.buckled && isobj(usr.buckled) && !usr.buckled.anchored )
spawn(0)
var/obj/structure/chair/C = null
if(istype(usr.buckled, /obj/structure/chair))
C = usr.buckled
var/obj/B = usr.buckled
var/movementdirection = turn(direction,180)
if(C) C.propelled = 4
step(B, movementdirection)
sleep(1)
step(B, movementdirection)
if(C) C.propelled = 3
sleep(1)
step(B, movementdirection)
sleep(1)
step(B, movementdirection)
if(C) C.propelled = 2
sleep(2)
step(B, movementdirection)
if(C) C.propelled = 1
sleep(2)
step(B, movementdirection)
if(C) C.propelled = 0
sleep(3)
step(B, movementdirection)
sleep(3)
step(B, movementdirection)
sleep(3)
step(B, movementdirection)
else user.newtonian_move(turn(direction, 180))
var/turf/T = get_turf(target)
var/turf/T1 = get_step(T,turn(direction, 90))
var/turf/T2 = get_step(T,turn(direction, -90))
var/list/the_targets = list(T,T1,T2)
if(precision)
var/turf/T3 = get_step(T1, turn(direction, 90))
var/turf/T4 = get_step(T2,turn(direction, -90))
the_targets = list(T,T1,T2,T3,T4)
for(var/a=0, a<5, a++)
spawn(0)
var/obj/effect/particle_effect/water/W = new /obj/effect/particle_effect/water( get_turf(src) )
var/turf/my_target = pick(the_targets)
if(precision)
the_targets -= my_target
var/datum/reagents/R = new/datum/reagents(5)
if(!W) return
W.reagents = R
R.my_atom = W
if(!W || !src) return
src.reagents.trans_to(W,1)
for(var/b=0, b<5, b++)
step_towards(W,my_target)
if(!W || !W.reagents) return
W.reagents.reaction(get_turf(W))
for(var/atom/atm in get_turf(W))
if(!W) return
W.reagents.reaction(atm)
if(isliving(atm)) //For extinguishing mobs on fire
var/mob/living/M = atm
M.ExtinguishMob()
if(W.loc == my_target) break
sleep(2)
else
return ..()
+3 -3
View File
@@ -7,7 +7,7 @@ obj/item/firework
obj/item/firework/attackby(obj/item/W,mob/user, params)
if(litzor)
return
if(istype(W, /obj/item/weldingtool) && W:welding || istype(W,/obj/item/lighter) && W:lit)
if(is_hot(W))
for(var/mob/M in viewers(user))
to_chat(M, "[user] lits \the [src]")
litzor = 1
@@ -29,7 +29,7 @@ obj/item/sparkler
obj/item/sparkler/attackby(obj/item/W,mob/user, params)
if(litzor)
return
if(istype(W, /obj/item/weldingtool) && W:welding || istype(W,/obj/item/lighter) && W:lit)
if(is_hot(W))
for(var/mob/M in viewers(user))
to_chat(M, "[user] lits \the [src]")
litzor = 1
@@ -59,4 +59,4 @@ obj/item/sparkler/attackby(obj/item/W,mob/user, params)
new /obj/item/firework(src)
new /obj/item/firework(src)
new /obj/item/firework(src)
new /obj/item/firework(src)
new /obj/item/firework(src)
+30 -25
View File
@@ -76,28 +76,7 @@
flame_turf(turflist)
/obj/item/flamethrower/attackby(obj/item/I, mob/user, params)
if(iswrench(I) && !status)//Taking this apart
var/turf/T = get_turf(src)
if(weldtool)
weldtool.forceMove(T)
weldtool = null
if(igniter)
igniter.forceMove(T)
igniter = null
if(ptank)
ptank.forceMove(T)
ptank = null
new /obj/item/stack/rods(T)
qdel(src)
return
else if(isscrewdriver(I) && igniter && !lit)
status = !status
to_chat(user, "<span class='notice'>[igniter] is now [status ? "secured" : "unsecured"]!</span>")
update_icon()
return
else if(isigniter(I))
if(isigniter(I))
var/obj/item/assembly/igniter/IG = I
if(IG.secured)
return
@@ -130,6 +109,34 @@
else
return ..()
/obj/item/flamethrower/wrench_act(mob/user, obj/item/I)
if(status)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
var/turf/T = get_turf(src)
if(weldtool)
weldtool.forceMove(T)
weldtool = null
if(igniter)
igniter.forceMove(T)
igniter = null
if(ptank)
ptank.forceMove(T)
ptank = null
new /obj/item/stack/rods(T)
qdel(src)
/obj/item/flamethrower/screwdriver_act(mob/user, obj/item/I)
if(!igniter || lit)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
status = !status
to_chat(user, "<span class='notice'>[igniter] is now [status ? "secured" : "unsecured"]!</span>")
update_icon()
/obj/item/flamethrower/attack_self(mob/user)
toggle_igniter(user)
@@ -168,7 +175,6 @@
..()
weldtool = locate(/obj/item/weldingtool) in contents
igniter = locate(/obj/item/assembly/igniter) in contents
weldtool.status = FALSE
igniter.secured = FALSE
status = TRUE
update_icon()
@@ -216,7 +222,6 @@
if(create_full)
if(!weldtool)
weldtool = new /obj/item/weldingtool(src)
weldtool.status = FALSE
if(!igniter)
igniter = new igniter_type(src)
igniter.secured = FALSE
@@ -245,4 +250,4 @@
location.hotspot_expose(700, 2)
/obj/item/assembly/igniter/proc/ignite_turf(obj/item/flamethrower/F, turf/simulated/location, release_amount = 0.05)
F.default_ignite(location, release_amount)
F.default_ignite(location, release_amount)
@@ -5,7 +5,7 @@
icon = 'icons/obj/grenade.dmi'
icon_state = "syndicate"
item_state = "flashbang"
var/spawn_contents = SPAWN_HEAT | SPAWN_TOXINS
var/spawn_contents = LINDA_SPAWN_HEAT | LINDA_SPAWN_TOXINS
var/spawn_amount = 100
/obj/item/grenade/gas/prime()
@@ -21,13 +21,13 @@
/obj/item/grenade/gas/knockout
name = "knockout grenade"
desc = "A grenade that releases pure N2O gas."
spawn_contents = SPAWN_20C | SPAWN_N2O
spawn_contents = LINDA_SPAWN_20C | LINDA_SPAWN_N2O
/obj/item/grenade/gas/oxygen
name = "oxygen grenade"
desc = "A grenade that releases pure O2 gas."
icon_state = "oxygen"
spawn_contents = SPAWN_20C | SPAWN_OXYGEN
spawn_contents = LINDA_SPAWN_20C | LINDA_SPAWN_OXYGEN
spawn_amount = 500
/obj/item/grenade/gluon
@@ -51,4 +51,4 @@
L.adjustStaminaLoss(stamina_damage)
L.apply_effect(rad_damage, IRRADIATE)
L.adjust_bodytemperature(-230)
qdel(src)
qdel(src)
File diff suppressed because it is too large Load Diff
@@ -1,11 +1,11 @@
/obj/item/grenade/empgrenade
name = "classic EMP grenade"
desc = "It is designed to wreak havoc on electronic systems."
icon_state = "emp"
item_state = "emp"
origin_tech = "magnets=3;combat=2"
/obj/item/grenade/empgrenade/prime()
update_mob()
empulse(src, 4, 10, 1)
qdel(src)
/obj/item/grenade/empgrenade
name = "classic EMP grenade"
desc = "It is designed to wreak havoc on electronic systems."
icon_state = "emp"
item_state = "emp"
origin_tech = "magnets=3;combat=2"
/obj/item/grenade/empgrenade/prime()
update_mob()
empulse(src, 4, 10, 1)
qdel(src)
@@ -1,79 +1,79 @@
/obj/item/grenade/flashbang
name = "flashbang"
icon_state = "flashbang"
item_state = "flashbang"
origin_tech = "materials=2;combat=3"
light_power = 10
light_color = LIGHT_COLOR_WHITE
var/light_time = 2
var/range = 7
/obj/item/grenade/flashbang/prime()
update_mob()
var/flashbang_turf = get_turf(src)
if(!flashbang_turf)
return
set_light(7)
do_sparks(rand(5, 9), FALSE, src)
playsound(flashbang_turf, 'sound/effects/bang.ogg', 25, 1)
bang(flashbang_turf, src, range)
for(var/obj/structure/blob/B in hear(8, flashbang_turf)) //Blob damage here
var/damage = round(30 / (get_dist(B, get_turf(src)) + 1))
B.take_damage(damage, BURN, "melee", 0)
spawn(light_time)
qdel(src)
/proc/bang(turf/T, atom/A, range = 7, flash = TRUE, bang = TRUE)
for(var/mob/living/M in hearers(range, T))
if(M.stat == DEAD)
continue
M.show_message("<span class='warning'>BANG</span>", 2)
//Checking for protections
var/ear_safety = M.check_ear_prot()
var/distance = max(1, get_dist(get_turf(A), get_turf(M)))
//Flash
if(flash)
if(M.weakeyes)
M.visible_message("<span class='disarm'><b>[M]</b> screams and collapses!</span>")
to_chat(M, "<span class='userdanger'><font size=3>AAAAGH!</font></span>")
M.Weaken(15) //hella stunned
M.Stun(15)
if(ishuman(M))
M.emote("scream")
var/mob/living/carbon/human/H = M
var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes)
if(E)
E.receive_damage(8, 1)
if(M.flash_eyes(affect_silicon = TRUE))
M.Stun(max(10 / distance, 3))
M.Weaken(max(10 / distance, 3))
//Bang
if(bang)
if(!distance || A.loc == M || A.loc == M.loc) //Holding on person or being exactly where lies is significantly more dangerous and voids protection
M.Stun(10)
M.Weaken(10)
if(!ear_safety)
M.Stun(max(10 / distance, 3))
M.Weaken(max(10 / distance, 3))
M.AdjustEarDamage(rand(0, 5), 15)
if(iscarbon(M))
var/mob/living/carbon/C = M
var/obj/item/organ/internal/ears/ears = C.get_int_organ(/obj/item/organ/internal/ears)
if(istype(ears))
if(ears.ear_damage >= 15)
to_chat(M, "<span class='warning'>Your ears start to ring badly!</span>")
if(prob(ears.ear_damage - 5))
to_chat(M, "<span class='warning'>You can't hear anything!</span>")
M.BecomeDeaf()
else
if(ears.ear_damage >= 5)
to_chat(M, "<span class='warning'>Your ears start to ring!</span>")
/obj/item/grenade/flashbang
name = "flashbang"
icon_state = "flashbang"
item_state = "flashbang"
origin_tech = "materials=2;combat=3"
light_power = 10
light_color = LIGHT_COLOR_WHITE
var/light_time = 2
var/range = 7
/obj/item/grenade/flashbang/prime()
update_mob()
var/flashbang_turf = get_turf(src)
if(!flashbang_turf)
return
set_light(7)
do_sparks(rand(5, 9), FALSE, src)
playsound(flashbang_turf, 'sound/effects/bang.ogg', 25, 1)
bang(flashbang_turf, src, range)
for(var/obj/structure/blob/B in hear(8, flashbang_turf)) //Blob damage here
var/damage = round(30 / (get_dist(B, get_turf(src)) + 1))
B.take_damage(damage, BURN, "melee", 0)
spawn(light_time)
qdel(src)
/proc/bang(turf/T, atom/A, range = 7, flash = TRUE, bang = TRUE)
for(var/mob/living/M in hearers(range, T))
if(M.stat == DEAD)
continue
M.show_message("<span class='warning'>BANG</span>", 2)
//Checking for protections
var/ear_safety = M.check_ear_prot()
var/distance = max(1, get_dist(get_turf(A), get_turf(M)))
//Flash
if(flash)
if(M.weakeyes)
M.visible_message("<span class='disarm'><b>[M]</b> screams and collapses!</span>")
to_chat(M, "<span class='userdanger'><font size=3>AAAAGH!</font></span>")
M.Weaken(15) //hella stunned
M.Stun(15)
if(ishuman(M))
M.emote("scream")
var/mob/living/carbon/human/H = M
var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes)
if(E)
E.receive_damage(8, 1)
if(M.flash_eyes(affect_silicon = TRUE))
M.Stun(max(10 / distance, 3))
M.Weaken(max(10 / distance, 3))
//Bang
if(bang)
if(!distance || A.loc == M || A.loc == M.loc) //Holding on person or being exactly where lies is significantly more dangerous and voids protection
M.Stun(10)
M.Weaken(10)
if(!ear_safety)
M.Stun(max(10 / distance, 3))
M.Weaken(max(10 / distance, 3))
M.AdjustEarDamage(rand(0, 5), 15)
if(iscarbon(M))
var/mob/living/carbon/C = M
var/obj/item/organ/internal/ears/ears = C.get_int_organ(/obj/item/organ/internal/ears)
if(istype(ears))
if(ears.ear_damage >= 15)
to_chat(M, "<span class='warning'>Your ears start to ring badly!</span>")
if(prob(ears.ear_damage - 5))
to_chat(M, "<span class='warning'>You can't hear anything!</span>")
M.BecomeDeaf()
else
if(ears.ear_damage >= 5)
to_chat(M, "<span class='warning'>Your ears start to ring!</span>")
@@ -47,4 +47,5 @@
hitsound = 'sound/weapons/pierce.ogg'
/obj/item/embedded/shrapnel/New()
..()
icon_state = pick("shrapnel1", "shrapnel2", "shrapnel3")
@@ -1,111 +1,111 @@
/obj/item/grenade
name = "grenade"
desc = "A hand held grenade, with an adjustable timer."
w_class = WEIGHT_CLASS_SMALL
icon = 'icons/obj/grenade.dmi'
icon_state = "grenade"
item_state = "flashbang"
throw_speed = 4
throw_range = 20
flags = CONDUCT
slot_flags = SLOT_BELT
resistance_flags = FLAMMABLE
max_integrity = 40
var/active = 0
var/det_time = 50
var/display_timer = 1
/obj/item/grenade/deconstruct(disassembled = TRUE)
if(!disassembled)
prime()
if(!QDELETED(src))
qdel(src)
/obj/item/grenade/proc/clown_check(var/mob/living/user)
if((CLUMSY in user.mutations) && prob(50))
to_chat(user, "<span class='warning'>Huh? How does this thing work?</span>")
active = 1
icon_state = initial(icon_state) + "_active"
playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1, -3)
spawn(5)
if(user)
user.drop_item()
prime()
return 0
return 1
/*/obj/item/grenade/afterattack(atom/target as mob|obj|turf|area, mob/user as mob)
if(istype(target, /obj/item/storage)) return ..() // Trying to put it in a full container
if(istype(target, /obj/item/gun/grenadelauncher)) return ..()
if((user.is_in_active_hand(src)) && (!active) && (clown_check(user)) && target.loc != src.loc)
to_chat(user, "<span class='warning'>You prime the [name]! [det_time/10] seconds!</span>")
active = 1
icon_state = initial(icon_state) + "_active"
playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1, -3)
spawn(det_time)
prime()
return
user.dir = get_dir(user, target)
user.drop_item()
var/t = (isturf(target) ? target : target.loc)
walk_towards(src, t, 3)
return*/
/obj/item/grenade/examine(mob/user)
. = ..()
if(display_timer)
if(det_time > 1)
. += "The timer is set to [det_time/10] second\s."
else
. += "\The [src] is set for instant detonation."
/obj/item/grenade/attack_self(mob/user as mob)
if(!active)
if(clown_check(user))
to_chat(user, "<span class='warning'>You prime the [name]! [det_time/10] seconds!</span>")
active = 1
icon_state = initial(icon_state) + "_active"
add_fingerprint(user)
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
message_admins("[key_name_admin(usr)] has primed a [name] for detonation at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a>")
log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])")
investigate_log("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])", INVESTIGATE_BOMB)
if(iscarbon(user))
var/mob/living/carbon/C = user
C.throw_mode_on()
spawn(det_time)
prime()
/obj/item/grenade/proc/prime()
/obj/item/grenade/proc/update_mob()
if(ismob(loc))
var/mob/M = loc
M.unEquip(src)
/obj/item/grenade/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/screwdriver))
switch(det_time)
if("1")
det_time = 10
to_chat(user, "<span class='notice'>You set the [name] for 1 second detonation time.</span>")
if("10")
det_time = 30
to_chat(user, "<span class='notice'>You set the [name] for 3 second detonation time.</span>")
if("30")
det_time = 50
to_chat(user, "<span class='notice'>You set the [name] for 5 second detonation time.</span>")
if("50")
det_time = 1
to_chat(user, "<span class='notice'>You set the [name] for instant detonation.</span>")
add_fingerprint(user)
..()
/obj/item/grenade/attack_hand()
walk(src, null, null)
..()
/obj/item/grenade
name = "grenade"
desc = "A hand held grenade, with an adjustable timer."
w_class = WEIGHT_CLASS_SMALL
icon = 'icons/obj/grenade.dmi'
icon_state = "grenade"
item_state = "flashbang"
throw_speed = 4
throw_range = 20
flags = CONDUCT
slot_flags = SLOT_BELT
resistance_flags = FLAMMABLE
max_integrity = 40
var/active = 0
var/det_time = 50
var/display_timer = 1
/obj/item/grenade/deconstruct(disassembled = TRUE)
if(!disassembled)
prime()
if(!QDELETED(src))
qdel(src)
/obj/item/grenade/proc/clown_check(var/mob/living/user)
if((CLUMSY in user.mutations) && prob(50))
to_chat(user, "<span class='warning'>Huh? How does this thing work?</span>")
active = 1
icon_state = initial(icon_state) + "_active"
playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1, -3)
spawn(5)
if(user)
user.drop_item()
prime()
return 0
return 1
/*/obj/item/grenade/afterattack(atom/target as mob|obj|turf|area, mob/user as mob)
if(istype(target, /obj/item/storage)) return ..() // Trying to put it in a full container
if(istype(target, /obj/item/gun/grenadelauncher)) return ..()
if((user.is_in_active_hand(src)) && (!active) && (clown_check(user)) && target.loc != src.loc)
to_chat(user, "<span class='warning'>You prime the [name]! [det_time/10] seconds!</span>")
active = 1
icon_state = initial(icon_state) + "_active"
playsound(loc, 'sound/weapons/armbomb.ogg', 75, 1, -3)
spawn(det_time)
prime()
return
user.dir = get_dir(user, target)
user.drop_item()
var/t = (isturf(target) ? target : target.loc)
walk_towards(src, t, 3)
return*/
/obj/item/grenade/examine(mob/user)
. = ..()
if(display_timer)
if(det_time > 1)
. += "The timer is set to [det_time/10] second\s."
else
. += "\The [src] is set for instant detonation."
/obj/item/grenade/attack_self(mob/user as mob)
if(!active)
if(clown_check(user))
to_chat(user, "<span class='warning'>You prime the [name]! [det_time/10] seconds!</span>")
active = 1
icon_state = initial(icon_state) + "_active"
add_fingerprint(user)
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
message_admins("[key_name_admin(usr)] has primed a [name] for detonation at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a>")
log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])")
investigate_log("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])", INVESTIGATE_BOMB)
if(iscarbon(user))
var/mob/living/carbon/C = user
C.throw_mode_on()
spawn(det_time)
prime()
/obj/item/grenade/proc/prime()
/obj/item/grenade/proc/update_mob()
if(ismob(loc))
var/mob/M = loc
M.unEquip(src)
/obj/item/grenade/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/screwdriver))
switch(det_time)
if("1")
det_time = 10
to_chat(user, "<span class='notice'>You set the [name] for 1 second detonation time.</span>")
if("10")
det_time = 30
to_chat(user, "<span class='notice'>You set the [name] for 3 second detonation time.</span>")
if("30")
det_time = 50
to_chat(user, "<span class='notice'>You set the [name] for 5 second detonation time.</span>")
if("50")
det_time = 1
to_chat(user, "<span class='notice'>You set the [name] for instant detonation.</span>")
add_fingerprint(user)
..()
/obj/item/grenade/attack_hand()
walk(src, null, null)
..()
@@ -1,37 +1,37 @@
/obj/item/grenade/smokebomb
desc = "It is set to detonate in 2 seconds."
name = "smoke bomb"
icon = 'icons/obj/grenade.dmi'
icon_state = "flashbang"
det_time = 20
item_state = "flashbang"
slot_flags = SLOT_BELT
var/datum/effect_system/smoke_spread/bad/smoke
/obj/item/grenade/smokebomb/New()
..()
src.smoke = new /datum/effect_system/smoke_spread/bad
src.smoke.attach(src)
/obj/item/grenade/smokebomb/Destroy()
QDEL_NULL(smoke)
return ..()
/obj/item/grenade/smokebomb/prime()
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
src.smoke.set_up(10, 0, usr.loc)
spawn(0)
src.smoke.start()
sleep(10)
src.smoke.start()
sleep(10)
src.smoke.start()
sleep(10)
src.smoke.start()
for(var/obj/structure/blob/B in view(8,src))
var/damage = round(30/(get_dist(B,src)+1))
B.take_damage(damage, BURN, "melee", 0)
sleep(80)
qdel(src)
return
/obj/item/grenade/smokebomb
desc = "It is set to detonate in 2 seconds."
name = "smoke bomb"
icon = 'icons/obj/grenade.dmi'
icon_state = "flashbang"
det_time = 20
item_state = "flashbang"
slot_flags = SLOT_BELT
var/datum/effect_system/smoke_spread/bad/smoke
/obj/item/grenade/smokebomb/New()
..()
src.smoke = new /datum/effect_system/smoke_spread/bad
src.smoke.attach(src)
/obj/item/grenade/smokebomb/Destroy()
QDEL_NULL(smoke)
return ..()
/obj/item/grenade/smokebomb/prime()
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
src.smoke.set_up(10, 0, usr.loc)
spawn(0)
src.smoke.start()
sleep(10)
src.smoke.start()
sleep(10)
src.smoke.start()
sleep(10)
src.smoke.start()
for(var/obj/structure/blob/B in view(8,src))
var/damage = round(30/(get_dist(B,src)+1))
B.take_damage(damage, BURN, "melee", 0)
sleep(80)
qdel(src)
return
@@ -1,68 +1,68 @@
/obj/item/grenade/spawnergrenade
desc = "It is set to detonate in 5 seconds. It will unleash unleash an unspecified anomaly into the vicinity."
name = "delivery grenade"
icon = 'icons/obj/grenade.dmi'
icon_state = "delivery"
item_state = "flashbang"
origin_tech = "materials=3;magnets=4"
var/spawner_type = null // must be an object path
var/deliveryamt = 1 // amount of type to deliver
spawner_type = /mob/living/simple_animal/hostile/viscerator
prime() // Prime now just handles the two loops that query for people in lockers and people who can see it.
if(spawner_type && deliveryamt)
// Make a quick flash
var/turf/T = get_turf(src)
playsound(T, 'sound/effects/phasein.ogg', 100, 1)
for(var/mob/living/carbon/C in viewers(T, null))
C.flash_eyes()
for(var/i=1, i<=deliveryamt, i++)
var/atom/movable/x = new spawner_type
x.admin_spawned = admin_spawned
x.loc = T
if(prob(50))
for(var/j = 1, j <= rand(1, 3), j++)
step(x, pick(NORTH,SOUTH,EAST,WEST))
// Spawn some hostile syndicate critters
qdel(src)
return
/obj/item/grenade/spawnergrenade/manhacks
name = "manhack delivery grenade"
spawner_type = /mob/living/simple_animal/hostile/viscerator
deliveryamt = 5
origin_tech = "materials=3;magnets=4;syndicate=3"
/obj/item/grenade/spawnergrenade/spesscarp
name = "carp delivery grenade"
spawner_type = /mob/living/simple_animal/hostile/carp
deliveryamt = 5
origin_tech = "materials=3;magnets=4;syndicate=3"
/obj/item/grenade/spawnergrenade/feral_cats
name = "feral cat delivery grenade"
desc = "This grenade contains 5 dehydrated feral cats in a similar manner to dehydrated monkeys, which, upon detonation, will be rehydrated by a small reservoir of water contained within the grenade. These cats will then attack anything in sight."
spawner_type = /mob/living/simple_animal/hostile/feral_cat
deliveryamt = 5
origin_tech = "materials=3;magnets=4;syndicate=3"
/obj/item/grenade/spawnergrenade/feral_cats/prime() //Own proc for this because the regular one would flash people which was dumb.
update_mob()
if(spawner_type && deliveryamt)
var/turf/T = get_turf(src)
playsound(T, 'sound/effects/phasein.ogg', 100, 1)
for(var/i=1, i<=deliveryamt, i++)
var/atom/movable/x = new spawner_type
x.loc = T
if(prob(50))
for(var/j = 1, j <= rand(1, 3), j++)
step(x, pick(NORTH,SOUTH,EAST,WEST))
qdel(src)
return
/obj/item/grenade/spawnergrenade
desc = "It is set to detonate in 5 seconds. It will unleash unleash an unspecified anomaly into the vicinity."
name = "delivery grenade"
icon = 'icons/obj/grenade.dmi'
icon_state = "delivery"
item_state = "flashbang"
origin_tech = "materials=3;magnets=4"
var/spawner_type = null // must be an object path
var/deliveryamt = 1 // amount of type to deliver
spawner_type = /mob/living/simple_animal/hostile/viscerator
prime() // Prime now just handles the two loops that query for people in lockers and people who can see it.
if(spawner_type && deliveryamt)
// Make a quick flash
var/turf/T = get_turf(src)
playsound(T, 'sound/effects/phasein.ogg', 100, 1)
for(var/mob/living/carbon/C in viewers(T, null))
C.flash_eyes()
for(var/i=1, i<=deliveryamt, i++)
var/atom/movable/x = new spawner_type
x.admin_spawned = admin_spawned
x.loc = T
if(prob(50))
for(var/j = 1, j <= rand(1, 3), j++)
step(x, pick(NORTH,SOUTH,EAST,WEST))
// Spawn some hostile syndicate critters
qdel(src)
return
/obj/item/grenade/spawnergrenade/manhacks
name = "manhack delivery grenade"
spawner_type = /mob/living/simple_animal/hostile/viscerator
deliveryamt = 5
origin_tech = "materials=3;magnets=4;syndicate=3"
/obj/item/grenade/spawnergrenade/spesscarp
name = "carp delivery grenade"
spawner_type = /mob/living/simple_animal/hostile/carp
deliveryamt = 5
origin_tech = "materials=3;magnets=4;syndicate=3"
/obj/item/grenade/spawnergrenade/feral_cats
name = "feral cat delivery grenade"
desc = "This grenade contains 5 dehydrated feral cats in a similar manner to dehydrated monkeys, which, upon detonation, will be rehydrated by a small reservoir of water contained within the grenade. These cats will then attack anything in sight."
spawner_type = /mob/living/simple_animal/hostile/feral_cat
deliveryamt = 5
origin_tech = "materials=3;magnets=4;syndicate=3"
/obj/item/grenade/spawnergrenade/feral_cats/prime() //Own proc for this because the regular one would flash people which was dumb.
update_mob()
if(spawner_type && deliveryamt)
var/turf/T = get_turf(src)
playsound(T, 'sound/effects/phasein.ogg', 100, 1)
for(var/i=1, i<=deliveryamt, i++)
var/atom/movable/x = new spawner_type
x.loc = T
if(prob(50))
for(var/j = 1, j <= rand(1, 3), j++)
step(x, pick(NORTH,SOUTH,EAST,WEST))
qdel(src)
return
@@ -9,4 +9,4 @@
/obj/item/grenade/syndieminibomb/prime()
update_mob()
explosion(loc, 1, 2, 4, flame_range = 2)
qdel(src)
qdel(src)
+194 -194
View File
@@ -1,194 +1,194 @@
/obj/item/restraints/handcuffs
name = "handcuffs"
desc = "Use this to keep prisoners in line."
gender = PLURAL
icon = 'icons/obj/items.dmi'
icon_state = "handcuff"
flags = CONDUCT
slot_flags = SLOT_BELT
throwforce = 5
w_class = WEIGHT_CLASS_SMALL
throw_speed = 2
throw_range = 5
materials = list(MAT_METAL=500)
origin_tech = "engineering=3;combat=3"
breakouttime = 600 //Deciseconds = 60s = 1 minutes
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
var/cuffsound = 'sound/weapons/handcuffs.ogg'
var/trashtype = null //For disposable cuffs
var/ignoresClumsy = FALSE
/obj/item/restraints/handcuffs/attack(mob/living/carbon/C, mob/user)
if(!user.IsAdvancedToolUser())
return
if(!istype(C))
return
if(flags & NODROP)
to_chat(user, "<span class='warning'>[src] is stuck to your hand!</span>")
return
if((CLUMSY in user.mutations) && prob(50) && (!ignoresClumsy))
to_chat(user, "<span class='warning'>Uh... how do those things work?!</span>")
apply_cuffs(user, user)
return
cuff(C, user)
/obj/item/restraints/handcuffs/proc/cuff(mob/living/carbon/C, mob/user, remove_src = TRUE)
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(!(H.has_left_hand() || H.has_right_hand()))
to_chat(user, "<span class='warning'>How do you suggest handcuffing someone with no hands?</span>")
return
if(!C.handcuffed)
C.visible_message("<span class='danger'>[user] is trying to put [src.name] on [C]!</span>", \
"<span class='userdanger'>[user] is trying to put [src.name] on [C]!</span>")
playsound(loc, cuffsound, 30, 1, -2)
if(do_mob(user, C, 30))
apply_cuffs(C, user, remove_src)
to_chat(user, "<span class='notice'>You handcuff [C].</span>")
if(istype(src, /obj/item/restraints/handcuffs/cable))
feedback_add_details("handcuffs", "C")
else
feedback_add_details("handcuffs", "H")
add_attack_logs(user, C, "Handcuffed ([src])")
else
to_chat(user, "<span class='warning'>You fail to handcuff [C].</span>")
/obj/item/restraints/handcuffs/proc/apply_cuffs(mob/living/carbon/target, mob/user, remove_src = TRUE)
if(!target.handcuffed)
if(remove_src)
user.drop_item()
if(trashtype)
target.handcuffed = new trashtype(target)
if(remove_src)
qdel(src)
else
if(remove_src)
loc = target
target.handcuffed = src
else
target.handcuffed = new type(loc)
target.update_handcuffed()
return
/obj/item/restraints/handcuffs/sinew
name = "sinew restraints"
desc = "A pair of restraints fashioned from long strands of flesh."
icon = 'icons/obj/mining.dmi'
icon_state = "sinewcuff"
item_state = "sinewcuff"
breakouttime = 300 //Deciseconds = 30s
cuffsound = 'sound/weapons/cablecuff.ogg'
/obj/item/restraints/handcuffs/cable
name = "cable restraints"
desc = "Looks like some cables tied together. Could be used to tie something up."
icon_state = "cuff_white"
origin_tech = "engineering=2"
materials = list(MAT_METAL=150, MAT_GLASS=75)
breakouttime = 300 //Deciseconds = 30s
cuffsound = 'sound/weapons/cablecuff.ogg'
/obj/item/restraints/handcuffs/cable/red
color = COLOR_RED
/obj/item/restraints/handcuffs/cable/yellow
color = COLOR_YELLOW
/obj/item/restraints/handcuffs/cable/blue
color = COLOR_BLUE
/obj/item/restraints/handcuffs/cable/green
color = COLOR_GREEN
/obj/item/restraints/handcuffs/cable/pink
color = COLOR_PINK
/obj/item/restraints/handcuffs/cable/orange
color = COLOR_ORANGE
/obj/item/restraints/handcuffs/cable/cyan
color = COLOR_CYAN
/obj/item/restraints/handcuffs/cable/white
color = COLOR_WHITE
/obj/item/restraints/handcuffs/cable/random/New()
color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
..()
/obj/item/restraints/handcuffs/cable/proc/cable_color(var/colorC)
if(colorC)
if(colorC == "rainbow")
colorC = color_rainbow()
color = colorC
else
color = COLOR_RED
/obj/item/restraints/handcuffs/cable/proc/color_rainbow()
color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
return color
/obj/item/restraints/handcuffs/alien
icon_state = "handcuffAlien"
/obj/item/restraints/handcuffs/pinkcuffs
name = "fluffy pink handcuffs"
desc = "Use this to keep prisoners in line. Or you know, your significant other."
icon_state = "pinkcuffs"
/obj/item/restraints/handcuffs/cable/attackby(var/obj/item/I, mob/user as mob, params)
..()
if(istype(I, /obj/item/stack/rods))
var/obj/item/stack/rods/R = I
if(R.use(1))
var/obj/item/wirerod/W = new /obj/item/wirerod
if(!remove_item_from_storage(user))
user.unEquip(src)
user.put_in_hands(W)
to_chat(user, "<span class='notice'>You wrap the cable restraint around the top of the rod.</span>")
qdel(src)
else
to_chat(user, "<span class='warning'>You need one rod to make a wired rod!</span>")
else if(istype(I, /obj/item/stack/sheet/metal))
var/obj/item/stack/sheet/metal/M = I
if(M.amount < 6)
to_chat(user, "<span class='warning'>You need at least six metal sheets to make good enough weights!</span>")
return
to_chat(user, "<span class='notice'>You begin to apply [I] to [src]...</span>")
if(do_after(user, 35 * M.toolspeed, target = src))
var/obj/item/restraints/legcuffs/bola/S = new /obj/item/restraints/legcuffs/bola
M.use(6)
user.put_in_hands(S)
to_chat(user, "<span class='notice'>You make some weights out of [I] and tie them to [src].</span>")
if(!remove_item_from_storage(user))
user.unEquip(src)
qdel(src)
else if(istype(I, /obj/item/toy/crayon))
var/obj/item/toy/crayon/C = I
cable_color(C.colourName)
/obj/item/restraints/handcuffs/cable/zipties
name = "zipties"
desc = "Plastic, disposable zipties that can be used to restrain temporarily but are destroyed after use."
icon_state = "cuff_white"
breakouttime = 450 //Deciseconds = 45s
materials = list()
trashtype = /obj/item/restraints/handcuffs/cable/zipties/used
/obj/item/restraints/handcuffs/cable/zipties/cyborg/attack(mob/living/carbon/C, mob/user)
if(isrobot(user))
cuff(C, user, FALSE)
/obj/item/restraints/handcuffs/cable/zipties/used
desc = "A pair of broken zipties."
icon_state = "cuff_white_used"
/obj/item/restraints/handcuffs/cable/zipties/used/attack()
return
/obj/item/restraints/handcuffs
name = "handcuffs"
desc = "Use this to keep prisoners in line."
gender = PLURAL
icon = 'icons/obj/items.dmi'
icon_state = "handcuff"
flags = CONDUCT
slot_flags = SLOT_BELT
throwforce = 5
w_class = WEIGHT_CLASS_SMALL
throw_speed = 2
throw_range = 5
materials = list(MAT_METAL=500)
origin_tech = "engineering=3;combat=3"
breakouttime = 600 //Deciseconds = 60s = 1 minutes
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50)
var/cuffsound = 'sound/weapons/handcuffs.ogg'
var/trashtype = null //For disposable cuffs
var/ignoresClumsy = FALSE
/obj/item/restraints/handcuffs/attack(mob/living/carbon/C, mob/user)
if(!user.IsAdvancedToolUser())
return
if(!istype(C))
return
if(flags & NODROP)
to_chat(user, "<span class='warning'>[src] is stuck to your hand!</span>")
return
if((CLUMSY in user.mutations) && prob(50) && (!ignoresClumsy))
to_chat(user, "<span class='warning'>Uh... how do those things work?!</span>")
apply_cuffs(user, user)
return
cuff(C, user)
/obj/item/restraints/handcuffs/proc/cuff(mob/living/carbon/C, mob/user, remove_src = TRUE)
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(!(H.has_left_hand() || H.has_right_hand()))
to_chat(user, "<span class='warning'>How do you suggest handcuffing someone with no hands?</span>")
return
if(!C.handcuffed)
C.visible_message("<span class='danger'>[user] is trying to put [src.name] on [C]!</span>", \
"<span class='userdanger'>[user] is trying to put [src.name] on [C]!</span>")
playsound(loc, cuffsound, 30, 1, -2)
if(do_mob(user, C, 30))
apply_cuffs(C, user, remove_src)
to_chat(user, "<span class='notice'>You handcuff [C].</span>")
if(istype(src, /obj/item/restraints/handcuffs/cable))
feedback_add_details("handcuffs", "C")
else
feedback_add_details("handcuffs", "H")
add_attack_logs(user, C, "Handcuffed ([src])")
else
to_chat(user, "<span class='warning'>You fail to handcuff [C].</span>")
/obj/item/restraints/handcuffs/proc/apply_cuffs(mob/living/carbon/target, mob/user, remove_src = TRUE)
if(!target.handcuffed)
if(remove_src)
user.drop_item()
if(trashtype)
target.handcuffed = new trashtype(target)
if(remove_src)
qdel(src)
else
if(remove_src)
loc = target
target.handcuffed = src
else
target.handcuffed = new type(loc)
target.update_handcuffed()
return
/obj/item/restraints/handcuffs/sinew
name = "sinew restraints"
desc = "A pair of restraints fashioned from long strands of flesh."
icon = 'icons/obj/mining.dmi'
icon_state = "sinewcuff"
item_state = "sinewcuff"
breakouttime = 300 //Deciseconds = 30s
cuffsound = 'sound/weapons/cablecuff.ogg'
/obj/item/restraints/handcuffs/cable
name = "cable restraints"
desc = "Looks like some cables tied together. Could be used to tie something up."
icon_state = "cuff_white"
origin_tech = "engineering=2"
materials = list(MAT_METAL=150, MAT_GLASS=75)
breakouttime = 300 //Deciseconds = 30s
cuffsound = 'sound/weapons/cablecuff.ogg'
/obj/item/restraints/handcuffs/cable/red
color = COLOR_RED
/obj/item/restraints/handcuffs/cable/yellow
color = COLOR_YELLOW
/obj/item/restraints/handcuffs/cable/blue
color = COLOR_BLUE
/obj/item/restraints/handcuffs/cable/green
color = COLOR_GREEN
/obj/item/restraints/handcuffs/cable/pink
color = COLOR_PINK
/obj/item/restraints/handcuffs/cable/orange
color = COLOR_ORANGE
/obj/item/restraints/handcuffs/cable/cyan
color = COLOR_CYAN
/obj/item/restraints/handcuffs/cable/white
color = COLOR_WHITE
/obj/item/restraints/handcuffs/cable/random/New()
color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
..()
/obj/item/restraints/handcuffs/cable/proc/cable_color(var/colorC)
if(colorC)
if(colorC == "rainbow")
colorC = color_rainbow()
color = colorC
else
color = COLOR_RED
/obj/item/restraints/handcuffs/cable/proc/color_rainbow()
color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
return color
/obj/item/restraints/handcuffs/alien
icon_state = "handcuffAlien"
/obj/item/restraints/handcuffs/pinkcuffs
name = "fluffy pink handcuffs"
desc = "Use this to keep prisoners in line. Or you know, your significant other."
icon_state = "pinkcuffs"
/obj/item/restraints/handcuffs/cable/attackby(var/obj/item/I, mob/user as mob, params)
..()
if(istype(I, /obj/item/stack/rods))
var/obj/item/stack/rods/R = I
if(R.use(1))
var/obj/item/wirerod/W = new /obj/item/wirerod
if(!remove_item_from_storage(user))
user.unEquip(src)
user.put_in_hands(W)
to_chat(user, "<span class='notice'>You wrap the cable restraint around the top of the rod.</span>")
qdel(src)
else
to_chat(user, "<span class='warning'>You need one rod to make a wired rod!</span>")
else if(istype(I, /obj/item/stack/sheet/metal))
var/obj/item/stack/sheet/metal/M = I
if(M.amount < 6)
to_chat(user, "<span class='warning'>You need at least six metal sheets to make good enough weights!</span>")
return
to_chat(user, "<span class='notice'>You begin to apply [I] to [src]...</span>")
if(do_after(user, 35 * M.toolspeed, target = src))
var/obj/item/restraints/legcuffs/bola/S = new /obj/item/restraints/legcuffs/bola
M.use(6)
user.put_in_hands(S)
to_chat(user, "<span class='notice'>You make some weights out of [I] and tie them to [src].</span>")
if(!remove_item_from_storage(user))
user.unEquip(src)
qdel(src)
else if(istype(I, /obj/item/toy/crayon))
var/obj/item/toy/crayon/C = I
cable_color(C.colourName)
/obj/item/restraints/handcuffs/cable/zipties
name = "zipties"
desc = "Plastic, disposable zipties that can be used to restrain temporarily but are destroyed after use."
icon_state = "cuff_white"
breakouttime = 450 //Deciseconds = 45s
materials = list()
trashtype = /obj/item/restraints/handcuffs/cable/zipties/used
/obj/item/restraints/handcuffs/cable/zipties/cyborg/attack(mob/living/carbon/C, mob/user)
if(isrobot(user))
cuff(C, user, FALSE)
/obj/item/restraints/handcuffs/cable/zipties/used
desc = "A pair of broken zipties."
icon_state = "cuff_white_used"
/obj/item/restraints/handcuffs/cable/zipties/used/attack()
return
+1 -1
View File
@@ -120,4 +120,4 @@
if(signs.len)
for(var/H in signs)
qdel(H)
to_chat(user, "<span class='notice'>You clear all active holograms.</span>")
to_chat(user, "<span class='notice'>You clear all active holograms.</span>")
@@ -556,6 +556,7 @@
var/faith = 99 //a conversion requires 100 faith to attempt. faith recharges over time while you are wearing missionary robes that have been linked to the staff.
/obj/item/nullrod/missionary_staff/New()
..()
team_color = pick("red", "blue")
icon_state = "godstaff-[team_color]"
item_state = "godstaff-[team_color]"
@@ -8,4 +8,4 @@
return "ERROR"
else
healthstring = "[round(imp_in.getOxyLoss())] - [round(imp_in.getFireLoss())] - [round(imp_in.getToxLoss())] - [round(imp_in.getBruteLoss())]"
return healthstring
return healthstring
@@ -1,87 +1,87 @@
/obj/item/implant
name = "implant"
icon = 'icons/obj/implants.dmi'
icon_state = "generic" //Shows up as the action button icon
origin_tech = "materials=2;biotech=3;programming=2"
actions_types = list(/datum/action/item_action/hands_free/activate)
var/activated = 1 //1 for implant types that can be activated, 0 for ones that are "always on" like mindshield implants
var/implanted = null
var/mob/living/imp_in = null
item_color = "b"
var/allow_multiple = 0
var/uses = -1
flags = DROPDEL
/obj/item/implant/proc/trigger(emote, mob/source, force)
return
/obj/item/implant/proc/activate()
return
/obj/item/implant/ui_action_click()
activate("action_button")
//What does the implant do upon injection?
//return 1 if the implant injects
//return -1 if the implant fails to inject
//return 0 if there is no room for implant
/obj/item/implant/proc/implant(var/mob/source, var/mob/user)
var/obj/item/implant/imp_e = locate(src.type) in source
if(!allow_multiple && imp_e && imp_e != src)
if(imp_e.uses < initial(imp_e.uses)*2)
if(uses == -1)
imp_e.uses = -1
else
imp_e.uses = min(imp_e.uses + uses, initial(imp_e.uses)*2)
qdel(src)
return 1
else
return 0
src.loc = source
imp_in = source
implanted = 1
if(activated)
for(var/X in actions)
var/datum/action/A = X
A.Grant(source)
if(ishuman(source))
var/mob/living/carbon/human/H = source
H.sec_hud_set_implants()
if(user)
add_attack_logs(user, source, "Implanted with [src]")
return 1
/obj/item/implant/proc/removed(var/mob/source)
src.loc = null
imp_in = null
implanted = 0
for(var/X in actions)
var/datum/action/A = X
A.Grant(source)
if(ishuman(source))
var/mob/living/carbon/human/H = source
H.sec_hud_set_implants()
return 1
/obj/item/implant/Destroy()
if(imp_in)
removed(imp_in)
return ..()
/obj/item/implant/proc/get_data()
return "No information available"
/obj/item/implant/dropped(mob/user)
. = 1
..()
/obj/item/implant
name = "implant"
icon = 'icons/obj/implants.dmi'
icon_state = "generic" //Shows up as the action button icon
origin_tech = "materials=2;biotech=3;programming=2"
actions_types = list(/datum/action/item_action/hands_free/activate)
var/activated = 1 //1 for implant types that can be activated, 0 for ones that are "always on" like mindshield implants
var/implanted = null
var/mob/living/imp_in = null
item_color = "b"
var/allow_multiple = 0
var/uses = -1
flags = DROPDEL
/obj/item/implant/proc/trigger(emote, mob/source, force)
return
/obj/item/implant/proc/activate()
return
/obj/item/implant/ui_action_click()
activate("action_button")
//What does the implant do upon injection?
//return 1 if the implant injects
//return -1 if the implant fails to inject
//return 0 if there is no room for implant
/obj/item/implant/proc/implant(var/mob/source, var/mob/user)
var/obj/item/implant/imp_e = locate(src.type) in source
if(!allow_multiple && imp_e && imp_e != src)
if(imp_e.uses < initial(imp_e.uses)*2)
if(uses == -1)
imp_e.uses = -1
else
imp_e.uses = min(imp_e.uses + uses, initial(imp_e.uses)*2)
qdel(src)
return 1
else
return 0
src.loc = source
imp_in = source
implanted = 1
if(activated)
for(var/X in actions)
var/datum/action/A = X
A.Grant(source)
if(ishuman(source))
var/mob/living/carbon/human/H = source
H.sec_hud_set_implants()
if(user)
add_attack_logs(user, source, "Implanted with [src]")
return 1
/obj/item/implant/proc/removed(var/mob/source)
src.loc = null
imp_in = null
implanted = 0
for(var/X in actions)
var/datum/action/A = X
A.Grant(source)
if(ishuman(source))
var/mob/living/carbon/human/H = source
H.sec_hud_set_implants()
return 1
/obj/item/implant/Destroy()
if(imp_in)
removed(imp_in)
return ..()
/obj/item/implant/proc/get_data()
return "No information available"
/obj/item/implant/dropped(mob/user)
. = 1
..()
@@ -44,4 +44,4 @@
if(c.team == team)
console = c
break
return console
return console
@@ -174,4 +174,4 @@
/obj/item/implanter/dust/New()
imp = new /obj/item/implant/dust(src)
..()
..()
@@ -37,4 +37,4 @@
/obj/item/implantcase/krav_maga/New()
imp = new /obj/item/implant/krav_maga(src)
..()
..()
@@ -56,4 +56,4 @@
/obj/item/implantcase/mindshield/New()
imp = new /obj/item/implant/mindshield(src)
..()
..()
@@ -37,4 +37,4 @@
/obj/item/implantcase/track/New()
imp = new /obj/item/implant/tracking(src)
..()
..()
@@ -48,7 +48,7 @@
return -1
mindslave_target.implanting = 1
to_chat(mindslave_target, "<span class='notice'>You feel completely loyal to [user.name].</span>")
to_chat(mindslave_target, "<span class='danger'>You feel completely loyal to [user.name].</span>")
if(!(user.mind in SSticker.mode.implanter))
SSticker.mode.implanter[user.mind] = list()
implanters = SSticker.mode.implanter[user.mind]
@@ -57,7 +57,7 @@
SSticker.mode.implanted[mindslave_target.mind] = user.mind
SSticker.mode.implanter[user.mind] = implanters
to_chat(mindslave_target, "<span class='warning'><B>You're now completely loyal to [user.name]!</B> You now must lay down your life to protect [user.p_them()] and assist in [user.p_their()] goals at any cost.</span>")
to_chat(mindslave_target, "<span class='danger'><B>You're now completely loyal to [user.name]!</B> You now must lay down your life to protect [user.p_them()] and assist in [user.p_their()] goals at any cost.</span>")
var/datum/objective/protect/mindslave/MS = new
MS.owner = mindslave_target.mind

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