Whitespace Standardization [MDB IGNORE] (#15748)

* Update settings

* Whitespace changes

* Comment out merger hooks in gitattributes

Corrupt maps would have to be resolved in repo before hooks could be updated

* Revert "Whitespace changes"

This reverts commit afbdd1d844.

* Whitespace again minus example

* Gitignore example changelog

* Restore changelog merge setting

* Keep older dmi hook attribute until hooks can be updated

* update vscode settings too

* Renormalize remaining

* Revert "Gitignore example changelog"

This reverts commit de22ad375d.

* Attempt to normalize example.yml (and another file I guess)

* Try again
This commit is contained in:
Drathek
2024-02-20 02:28:51 -08:00
committed by GitHub
parent 3b61f677b3
commit 7c8bb85de3
1175 changed files with 818171 additions and 818145 deletions
+208 -208
View File
@@ -1,208 +1,208 @@
/atom/movable
var/can_buckle = FALSE
var/buckle_movable = 0
var/buckle_dir = 0
var/buckle_lying = -1 //bed-like behavior, forces mob.lying = buckle_lying if != -1
var/buckle_require_restraints = 0 //require people to be handcuffed before being able to buckle. eg: pipes
// var/mob/living/buckled_mob = null
var/list/mob/living/buckled_mobs = null //list()
var/max_buckled_mobs = 1
/atom/movable/attack_hand(mob/living/user)
. = ..()
// if(can_buckle && buckled_mob)
// user_unbuckle_mob(user)
if(can_buckle && has_buckled_mobs())
if(buckled_mobs.len > 1)
var/unbuckled = tgui_input_list(user, "Who do you wish to unbuckle?","Unbuckle Who?", buckled_mobs)
if(user_unbuckle_mob(unbuckled, user))
return TRUE
else
if(user_unbuckle_mob(buckled_mobs[1], user))
return TRUE
/obj/proc/attack_alien(mob/user as mob) //For calling in the event of Xenomorph or other alien checks.
return
/obj/attack_robot(mob/living/user)
if(Adjacent(user) && has_buckled_mobs()) //Checks if what we're touching is adjacent to us and has someone buckled to it. This should prevent interacting with anti-robot manual valves among other things.
return attack_hand(user) //Process as if we're a normal person touching the object.
return ..() //Otherwise, treat this as an AI click like usual.
/atom/movable/MouseDrop_T(mob/living/M, mob/living/user)
. = ..()
if(can_buckle && istype(M))
if(user_buckle_mob(M, user))
return TRUE
/atom/movable/proc/has_buckled_mobs()
return LAZYLEN(buckled_mobs)
/atom/movable/Destroy()
unbuckle_all_mobs()
return ..()
/atom/movable/proc/buckle_mob(mob/living/M, forced = FALSE, check_loc = TRUE)
if(check_loc && M.loc != loc)
return FALSE
if(!can_buckle_check(M, forced))
return FALSE
if(M == src)
stack_trace("Recursive buckle warning: [M] being buckled to self.")
return
M.buckled = src
M.facing_dir = null
M.set_dir(buckle_dir ? buckle_dir : dir)
M.update_canmove()
M.update_floating( M.Check_Dense_Object() )
// buckled_mob = M
buckled_mobs |= M
//VOREStation Add
if(riding_datum)
riding_datum.ridden = src
riding_datum.handle_vehicle_offsets()
M.update_water()
//VOREStation Add End
post_buckle_mob(M)
M.throw_alert("buckled", /obj/screen/alert/restrained/buckled, new_master = src)
return TRUE
/atom/movable/proc/unbuckle_mob(mob/living/buckled_mob, force = FALSE)
if(!buckled_mob) // If we didn't get told which mob needs to get unbuckled, just assume its the first one on the list.
if(has_buckled_mobs())
buckled_mob = buckled_mobs[1]
else
return
if(buckled_mob && buckled_mob.buckled == src)
. = buckled_mob
buckled_mob.buckled = null
buckled_mob.anchored = initial(buckled_mob.anchored)
buckled_mob.update_canmove()
buckled_mob.update_floating( buckled_mob.Check_Dense_Object() )
buckled_mob.clear_alert("buckled")
// buckled_mob = null
buckled_mobs -= buckled_mob
//VOREStation Add
buckled_mob.update_water()
if(riding_datum)
riding_datum.restore_position(buckled_mob)
riding_datum.handle_vehicle_offsets() // So the person in back goes to the front.
//VOREStation Add End
post_buckle_mob(.)
/atom/movable/proc/unbuckle_all_mobs(force = FALSE)
if(!has_buckled_mobs())
return
for(var/m in buckled_mobs)
unbuckle_mob(m, force)
//Handle any extras after buckling/unbuckling
//Called on buckle_mob() and unbuckle_mob()
/atom/movable/proc/post_buckle_mob(mob/living/M)
return
//Wrapper procs that handle sanity and user feedback
/atom/movable/proc/user_buckle_mob(mob/living/M, mob/user, var/forced = FALSE, var/silent = FALSE)
if(!ticker)
to_chat(user, "<span class='warning'>You can't buckle anyone in before the game starts.</span>")
return FALSE // Is this really needed?
if(!user.Adjacent(M) || user.restrained() || user.stat || istype(user, /mob/living/silicon/pai))
return FALSE
if(M in buckled_mobs)
to_chat(user, "<span class='warning'>\The [M] is already buckled to \the [src].</span>")
return FALSE
if(!can_buckle_check(M, forced))
return FALSE
add_fingerprint(user)
// unbuckle_mob()
//can't buckle unless you share locs so try to move M to the obj.
if(M.loc != src.loc)
if(M.Adjacent(src) && user.Adjacent(src))
M.forceMove(get_turf(src))
// step_towards(M, src)
. = buckle_mob(M, forced)
playsound(src, 'sound/effects/seatbelt.ogg', 50, 1)
if(.)
var/reveal_message = list("buckled_mob" = null, "buckled_to" = null) //VORE EDIT: This being a list and messages existing for the buckle target atom.
if(!silent)
if(M == user)
reveal_message["buckled_mob"] = "<span class='notice'>You come out of hiding and buckle yourself to [src].</span>" //VORE EDIT
reveal_message["buckled_to"] = "<span class='notice'>You come out of hiding as [M.name] buckles themselves to you.</span>" //VORE EDIT
M.visible_message(\
"<span class='notice'>[M.name] buckles themselves to [src].</span>",\
"<span class='notice'>You buckle yourself to [src].</span>",\
"<span class='notice'>You hear metal clanking.</span>")
else
reveal_message["buckled_mob"] = "<span class='notice'>You are revealed as you are buckled to [src].</span>" //VORE EDIT
reveal_message["buckled_to"] = "<span class='notice'>You are revealed as [M.name] is buckled to you.</span>" //VORE EDIT
M.visible_message(\
"<span class='danger'>[M.name] is buckled to [src] by [user.name]!</span>",\
"<span class='danger'>You are buckled to [src] by [user.name]!</span>",\
"<span class='notice'>You hear metal clanking.</span>")
M.reveal(silent, reveal_message["buckled_mob"]) //Reveal people so they aren't buckled to chairs from behind. //VORE EDIT, list arg instead of simple message var for buckled mob
//Vore edit start
var/mob/living/L = src
if(istype(L))
L.reveal(silent, reveal_message["buckled_to"])
//Vore edit end
/atom/movable/proc/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
var/mob/living/M = unbuckle_mob(buckled_mob)
playsound(src, 'sound/effects/seatbelt.ogg', 50, 1)
if(M)
if(M != user)
M.visible_message(\
"<span class='notice'>[M.name] was unbuckled by [user.name]!</span>",\
"<span class='notice'>You were unbuckled from [src] by [user.name].</span>",\
"<span class='notice'>You hear metal clanking.</span>")
else
M.visible_message(\
"<span class='notice'>[M.name] unbuckled themselves!</span>",\
"<span class='notice'>You unbuckle yourself from [src].</span>",\
"<span class='notice'>You hear metal clanking.</span>")
add_fingerprint(user)
return M
/atom/movable/proc/handle_buckled_mob_movement(atom/old_loc, direct, movetime)
for(var/mob/living/L as anything in buckled_mobs)
if(!L.Move(loc, direct, movetime))
L.forceMove(loc, direct, movetime)
L.last_move = last_move
L.inertia_dir = last_move
if(!buckle_dir)
L.set_dir(dir)
else
L.set_dir(buckle_dir)
/atom/movable/proc/can_buckle_check(mob/living/M, forced = FALSE)
if(!buckled_mobs)
buckled_mobs = list()
if(!istype(M))
return FALSE
if((!can_buckle && !forced) || M.buckled || M.pinned.len || (buckled_mobs.len >= max_buckled_mobs) || (buckle_require_restraints && !M.restrained()))
return FALSE
if(has_buckled_mobs() && buckled_mobs.len >= max_buckled_mobs) //Handles trying to buckle yourself to the chair when someone is on it
to_chat(M, "<span class='notice'>\The [src] can't buckle anymore people.</span>")
return FALSE
return TRUE
/atom/movable
var/can_buckle = FALSE
var/buckle_movable = 0
var/buckle_dir = 0
var/buckle_lying = -1 //bed-like behavior, forces mob.lying = buckle_lying if != -1
var/buckle_require_restraints = 0 //require people to be handcuffed before being able to buckle. eg: pipes
// var/mob/living/buckled_mob = null
var/list/mob/living/buckled_mobs = null //list()
var/max_buckled_mobs = 1
/atom/movable/attack_hand(mob/living/user)
. = ..()
// if(can_buckle && buckled_mob)
// user_unbuckle_mob(user)
if(can_buckle && has_buckled_mobs())
if(buckled_mobs.len > 1)
var/unbuckled = tgui_input_list(user, "Who do you wish to unbuckle?","Unbuckle Who?", buckled_mobs)
if(user_unbuckle_mob(unbuckled, user))
return TRUE
else
if(user_unbuckle_mob(buckled_mobs[1], user))
return TRUE
/obj/proc/attack_alien(mob/user as mob) //For calling in the event of Xenomorph or other alien checks.
return
/obj/attack_robot(mob/living/user)
if(Adjacent(user) && has_buckled_mobs()) //Checks if what we're touching is adjacent to us and has someone buckled to it. This should prevent interacting with anti-robot manual valves among other things.
return attack_hand(user) //Process as if we're a normal person touching the object.
return ..() //Otherwise, treat this as an AI click like usual.
/atom/movable/MouseDrop_T(mob/living/M, mob/living/user)
. = ..()
if(can_buckle && istype(M))
if(user_buckle_mob(M, user))
return TRUE
/atom/movable/proc/has_buckled_mobs()
return LAZYLEN(buckled_mobs)
/atom/movable/Destroy()
unbuckle_all_mobs()
return ..()
/atom/movable/proc/buckle_mob(mob/living/M, forced = FALSE, check_loc = TRUE)
if(check_loc && M.loc != loc)
return FALSE
if(!can_buckle_check(M, forced))
return FALSE
if(M == src)
stack_trace("Recursive buckle warning: [M] being buckled to self.")
return
M.buckled = src
M.facing_dir = null
M.set_dir(buckle_dir ? buckle_dir : dir)
M.update_canmove()
M.update_floating( M.Check_Dense_Object() )
// buckled_mob = M
buckled_mobs |= M
//VOREStation Add
if(riding_datum)
riding_datum.ridden = src
riding_datum.handle_vehicle_offsets()
M.update_water()
//VOREStation Add End
post_buckle_mob(M)
M.throw_alert("buckled", /obj/screen/alert/restrained/buckled, new_master = src)
return TRUE
/atom/movable/proc/unbuckle_mob(mob/living/buckled_mob, force = FALSE)
if(!buckled_mob) // If we didn't get told which mob needs to get unbuckled, just assume its the first one on the list.
if(has_buckled_mobs())
buckled_mob = buckled_mobs[1]
else
return
if(buckled_mob && buckled_mob.buckled == src)
. = buckled_mob
buckled_mob.buckled = null
buckled_mob.anchored = initial(buckled_mob.anchored)
buckled_mob.update_canmove()
buckled_mob.update_floating( buckled_mob.Check_Dense_Object() )
buckled_mob.clear_alert("buckled")
// buckled_mob = null
buckled_mobs -= buckled_mob
//VOREStation Add
buckled_mob.update_water()
if(riding_datum)
riding_datum.restore_position(buckled_mob)
riding_datum.handle_vehicle_offsets() // So the person in back goes to the front.
//VOREStation Add End
post_buckle_mob(.)
/atom/movable/proc/unbuckle_all_mobs(force = FALSE)
if(!has_buckled_mobs())
return
for(var/m in buckled_mobs)
unbuckle_mob(m, force)
//Handle any extras after buckling/unbuckling
//Called on buckle_mob() and unbuckle_mob()
/atom/movable/proc/post_buckle_mob(mob/living/M)
return
//Wrapper procs that handle sanity and user feedback
/atom/movable/proc/user_buckle_mob(mob/living/M, mob/user, var/forced = FALSE, var/silent = FALSE)
if(!ticker)
to_chat(user, "<span class='warning'>You can't buckle anyone in before the game starts.</span>")
return FALSE // Is this really needed?
if(!user.Adjacent(M) || user.restrained() || user.stat || istype(user, /mob/living/silicon/pai))
return FALSE
if(M in buckled_mobs)
to_chat(user, "<span class='warning'>\The [M] is already buckled to \the [src].</span>")
return FALSE
if(!can_buckle_check(M, forced))
return FALSE
add_fingerprint(user)
// unbuckle_mob()
//can't buckle unless you share locs so try to move M to the obj.
if(M.loc != src.loc)
if(M.Adjacent(src) && user.Adjacent(src))
M.forceMove(get_turf(src))
// step_towards(M, src)
. = buckle_mob(M, forced)
playsound(src, 'sound/effects/seatbelt.ogg', 50, 1)
if(.)
var/reveal_message = list("buckled_mob" = null, "buckled_to" = null) //VORE EDIT: This being a list and messages existing for the buckle target atom.
if(!silent)
if(M == user)
reveal_message["buckled_mob"] = "<span class='notice'>You come out of hiding and buckle yourself to [src].</span>" //VORE EDIT
reveal_message["buckled_to"] = "<span class='notice'>You come out of hiding as [M.name] buckles themselves to you.</span>" //VORE EDIT
M.visible_message(\
"<span class='notice'>[M.name] buckles themselves to [src].</span>",\
"<span class='notice'>You buckle yourself to [src].</span>",\
"<span class='notice'>You hear metal clanking.</span>")
else
reveal_message["buckled_mob"] = "<span class='notice'>You are revealed as you are buckled to [src].</span>" //VORE EDIT
reveal_message["buckled_to"] = "<span class='notice'>You are revealed as [M.name] is buckled to you.</span>" //VORE EDIT
M.visible_message(\
"<span class='danger'>[M.name] is buckled to [src] by [user.name]!</span>",\
"<span class='danger'>You are buckled to [src] by [user.name]!</span>",\
"<span class='notice'>You hear metal clanking.</span>")
M.reveal(silent, reveal_message["buckled_mob"]) //Reveal people so they aren't buckled to chairs from behind. //VORE EDIT, list arg instead of simple message var for buckled mob
//Vore edit start
var/mob/living/L = src
if(istype(L))
L.reveal(silent, reveal_message["buckled_to"])
//Vore edit end
/atom/movable/proc/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
var/mob/living/M = unbuckle_mob(buckled_mob)
playsound(src, 'sound/effects/seatbelt.ogg', 50, 1)
if(M)
if(M != user)
M.visible_message(\
"<span class='notice'>[M.name] was unbuckled by [user.name]!</span>",\
"<span class='notice'>You were unbuckled from [src] by [user.name].</span>",\
"<span class='notice'>You hear metal clanking.</span>")
else
M.visible_message(\
"<span class='notice'>[M.name] unbuckled themselves!</span>",\
"<span class='notice'>You unbuckle yourself from [src].</span>",\
"<span class='notice'>You hear metal clanking.</span>")
add_fingerprint(user)
return M
/atom/movable/proc/handle_buckled_mob_movement(atom/old_loc, direct, movetime)
for(var/mob/living/L as anything in buckled_mobs)
if(!L.Move(loc, direct, movetime))
L.forceMove(loc, direct, movetime)
L.last_move = last_move
L.inertia_dir = last_move
if(!buckle_dir)
L.set_dir(dir)
else
L.set_dir(buckle_dir)
/atom/movable/proc/can_buckle_check(mob/living/M, forced = FALSE)
if(!buckled_mobs)
buckled_mobs = list()
if(!istype(M))
return FALSE
if((!can_buckle && !forced) || M.buckled || M.pinned.len || (buckled_mobs.len >= max_buckled_mobs) || (buckle_require_restraints && !M.restrained()))
return FALSE
if(has_buckled_mobs() && buckled_mobs.len >= max_buckled_mobs) //Handles trying to buckle yourself to the chair when someone is on it
to_chat(M, "<span class='notice'>\The [src] can't buckle anymore people.</span>")
return FALSE
return TRUE
+34 -34
View File
@@ -1,34 +1,34 @@
var/list/obj/effect/bump_teleporter/BUMP_TELEPORTERS = list()
/obj/effect/bump_teleporter
name = "bump-teleporter"
icon = 'icons/mob/screen1.dmi'
icon_state = "x2"
var/id = null //id of this bump_teleporter.
var/id_target = null //id of bump_teleporter which this moves you to.
invisibility = 101 //nope, can't see this
anchored = TRUE
density = TRUE
opacity = 0
/obj/effect/bump_teleporter/New()
..()
BUMP_TELEPORTERS += src
/obj/effect/bump_teleporter/Destroy()
BUMP_TELEPORTERS -= src
return ..()
/obj/effect/bump_teleporter/Bumped(atom/user)
if(!ismob(user))
//user.loc = src.loc //Stop at teleporter location
return
var/mob/M = user //VOREStation edit
if(!id_target)
//user.loc = src.loc //Stop at teleporter location, there is nowhere to teleport to.
return
for(var/obj/effect/bump_teleporter/BT in BUMP_TELEPORTERS)
if(BT.id == src.id_target)
M.forceMove(BT.loc) //Teleport to location with correct id. //VOREStation Edit
return
var/list/obj/effect/bump_teleporter/BUMP_TELEPORTERS = list()
/obj/effect/bump_teleporter
name = "bump-teleporter"
icon = 'icons/mob/screen1.dmi'
icon_state = "x2"
var/id = null //id of this bump_teleporter.
var/id_target = null //id of bump_teleporter which this moves you to.
invisibility = 101 //nope, can't see this
anchored = TRUE
density = TRUE
opacity = 0
/obj/effect/bump_teleporter/New()
..()
BUMP_TELEPORTERS += src
/obj/effect/bump_teleporter/Destroy()
BUMP_TELEPORTERS -= src
return ..()
/obj/effect/bump_teleporter/Bumped(atom/user)
if(!ismob(user))
//user.loc = src.loc //Stop at teleporter location
return
var/mob/M = user //VOREStation edit
if(!id_target)
//user.loc = src.loc //Stop at teleporter location, there is nowhere to teleport to.
return
for(var/obj/effect/bump_teleporter/BT in BUMP_TELEPORTERS)
if(BT.id == src.id_target)
M.forceMove(BT.loc) //Teleport to location with correct id. //VOREStation Edit
return
@@ -1,33 +1,33 @@
/obj/effect/decal/cleanable/blood/xeno
name = "xeno blood"
desc = "It's green and acidic. It looks like... <i>blood?</i>"
icon = 'icons/effects/blood.dmi'
basecolor = "#05EE05"
/obj/effect/decal/cleanable/blood/gibs/xeno
name = "xeno gibs"
desc = "Gnarly..."
icon_state = "xgib1"
random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6")
basecolor = "#05EE05"
/obj/effect/decal/cleanable/blood/gibs/xeno/update_icon()
color = "#FFFFFF"
/obj/effect/decal/cleanable/blood/gibs/xeno/up
random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6","xgibup1","xgibup1","xgibup1")
/obj/effect/decal/cleanable/blood/gibs/xeno/down
random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6","xgibdown1","xgibdown1","xgibdown1")
/obj/effect/decal/cleanable/blood/gibs/xeno/body
random_icon_states = list("xgibhead", "xgibtorso")
/obj/effect/decal/cleanable/blood/gibs/xeno/limb
random_icon_states = list("xgibleg", "xgibarm")
/obj/effect/decal/cleanable/blood/gibs/xeno/core
random_icon_states = list("xgibmid1", "xgibmid2", "xgibmid3")
/obj/effect/decal/cleanable/blood/xtracks
/obj/effect/decal/cleanable/blood/xeno
name = "xeno blood"
desc = "It's green and acidic. It looks like... <i>blood?</i>"
icon = 'icons/effects/blood.dmi'
basecolor = "#05EE05"
/obj/effect/decal/cleanable/blood/gibs/xeno
name = "xeno gibs"
desc = "Gnarly..."
icon_state = "xgib1"
random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6")
basecolor = "#05EE05"
/obj/effect/decal/cleanable/blood/gibs/xeno/update_icon()
color = "#FFFFFF"
/obj/effect/decal/cleanable/blood/gibs/xeno/up
random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6","xgibup1","xgibup1","xgibup1")
/obj/effect/decal/cleanable/blood/gibs/xeno/down
random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6","xgibdown1","xgibdown1","xgibdown1")
/obj/effect/decal/cleanable/blood/gibs/xeno/body
random_icon_states = list("xgibhead", "xgibtorso")
/obj/effect/decal/cleanable/blood/gibs/xeno/limb
random_icon_states = list("xgibleg", "xgibarm")
/obj/effect/decal/cleanable/blood/gibs/xeno/core
random_icon_states = list("xgibmid1", "xgibmid2", "xgibmid3")
/obj/effect/decal/cleanable/blood/xtracks
basecolor = "#05EE05"
@@ -1,253 +1,253 @@
#define DRYING_TIME 5 * 60*10 //for 1 unit of depth in puddle (amount var)
var/global/list/image/splatter_cache=list()
/obj/effect/decal/cleanable/blood
name = "blood"
var/dryname = "dried blood"
desc = "It's thick and gooey. Perhaps it's the chef's cooking?"
var/drydesc = "It's dry and crusty. Someone is not doing their job."
gender = PLURAL
density = FALSE
anchored = TRUE
plane = BLOOD_PLANE
layer = BLOOD_DECAL_LAYER
icon = 'icons/effects/blood.dmi'
icon_state = "mfloor1"
random_icon_states = list("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7")
var/base_icon = 'icons/effects/blood.dmi'
blood_DNA = list()
var/basecolor="#A10808" // Color when wet.
var/synthblood = 0
var/list/datum/disease2/disease/virus2 = list()
var/amount = 5
generic_filth = TRUE
persistent = FALSE
/obj/effect/decal/cleanable/blood/reveal_blood()
if(!fluorescent)
fluorescent = 1
basecolor = COLOR_LUMINOL
update_icon()
/obj/effect/decal/cleanable/blood/clean_blood()
fluorescent = 0
if(invisibility != 100)
invisibility = 100
amount = 0
..(ignore=1)
/obj/effect/decal/cleanable/blood/New()
..()
update_icon()
if(istype(src, /obj/effect/decal/cleanable/blood/gibs))
return
if(src.type == /obj/effect/decal/cleanable/blood)
if(src.loc && isturf(src.loc))
for(var/obj/effect/decal/cleanable/blood/B in src.loc)
if(B != src)
if (B.blood_DNA)
blood_DNA |= B.blood_DNA.Copy()
qdel(B)
addtimer(CALLBACK(src, PROC_REF(dry)), DRYING_TIME * (amount+1))
/obj/effect/decal/cleanable/blood/update_icon()
if(basecolor == "rainbow") basecolor = get_random_colour(1)
color = basecolor
if(basecolor == SYNTH_BLOOD_COLOUR)
name = "oil"
desc = "It's quite oily."
else if(synthblood)
name = "synthetic blood"
desc = "It's quite greasy."
else
name = initial(name)
desc = initial(desc)
/obj/effect/decal/cleanable/blood/Crossed(mob/living/carbon/human/perp)
if(perp.is_incorporeal())
return
if (!istype(perp))
return
if(amount < 1)
return
var/obj/item/organ/external/l_foot = perp.get_organ("l_foot")
var/obj/item/organ/external/r_foot = perp.get_organ("r_foot")
var/hasfeet = 1
if((!l_foot || l_foot.is_stump()) && (!r_foot || r_foot.is_stump()))
hasfeet = 0
if(perp.shoes && !perp.buckled)//Adding blood to shoes
var/obj/item/clothing/shoes/S = perp.shoes
if(istype(S))
S.blood_color = basecolor
S.track_blood = max(amount,S.track_blood)
if(!S.blood_overlay)
S.generate_blood_overlay()
if(!S.blood_DNA)
S.blood_DNA = list()
S.blood_overlay.color = basecolor
S.add_overlay(S.blood_overlay)
if(S.blood_overlay && S.blood_overlay.color != basecolor)
S.blood_overlay.color = basecolor
S.add_overlay(S.blood_overlay)
S.blood_DNA |= blood_DNA.Copy()
perp.update_inv_shoes()
else if (hasfeet)//Or feet
perp.feet_blood_color = basecolor
perp.track_blood = max(amount,perp.track_blood)
LAZYINITLIST(perp.feet_blood_DNA)
perp.feet_blood_DNA |= blood_DNA.Copy()
perp.update_bloodied()
else if (perp.buckled && istype(perp.buckled, /obj/structure/bed/chair/wheelchair))
var/obj/structure/bed/chair/wheelchair/W = perp.buckled
W.bloodiness = 4
amount--
/obj/effect/decal/cleanable/blood/proc/dry()
name = dryname
desc = drydesc
color = adjust_brightness(color, -50)
amount = 0
/obj/effect/decal/cleanable/blood/attack_hand(mob/living/carbon/human/user)
..()
if (amount && istype(user))
add_fingerprint(user)
if (user.gloves)
return
var/taken = rand(1,amount)
amount -= taken
to_chat(user, "<span class='notice'>You get some of \the [src] on your hands.</span>")
if (!user.blood_DNA)
user.blood_DNA = list()
user.blood_DNA |= blood_DNA.Copy()
user.bloody_hands += taken
user.hand_blood_color = basecolor
user.update_inv_gloves(1)
user.verbs += /mob/living/carbon/human/proc/bloody_doodle
/obj/effect/decal/cleanable/blood/splatter
random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5")
amount = 2
/obj/effect/decal/cleanable/blood/drip
name = "drips of blood"
desc = "It's red."
gender = PLURAL
icon = 'icons/effects/drip.dmi'
icon_state = "1"
random_icon_states = list("1","2","3","4","5")
amount = 0
var/list/drips = list()
/obj/effect/decal/cleanable/blood/drip/New()
..()
drips |= icon_state
/obj/effect/decal/cleanable/blood/writing
icon_state = "tracks"
desc = "It looks like a writing in blood."
gender = NEUTER
random_icon_states = list("writing1","writing2","writing3","writing4","writing5")
amount = 0
var/message
/obj/effect/decal/cleanable/blood/writing/New()
..()
if(random_icon_states.len)
for(var/obj/effect/decal/cleanable/blood/writing/W in loc)
random_icon_states.Remove(W.icon_state)
icon_state = pick(random_icon_states)
else
icon_state = "writing1"
/obj/effect/decal/cleanable/blood/writing/examine(mob/user)
. = ..()
. += "It reads: <font color='[basecolor]'>\"[message]\"</font>"
/obj/effect/decal/cleanable/blood/gibs
name = "gibs"
desc = "They look bloody and gruesome."
gender = PLURAL
density = FALSE
anchored = TRUE
icon = 'icons/effects/blood.dmi'
icon_state = "gibbl5"
random_icon_states = list("gib1", "gib2", "gib3", "gib5", "gib6")
var/fleshcolor = "#FFFFFF"
/obj/effect/decal/cleanable/blood/gibs/update_icon()
var/image/giblets = new(base_icon, "[icon_state]_flesh", dir)
if(!fleshcolor || fleshcolor == "rainbow")
fleshcolor = get_random_colour(1)
giblets.color = fleshcolor
var/icon/blood = new(base_icon,"[icon_state]",dir)
if(basecolor == "rainbow") basecolor = get_random_colour(1)
blood.Blend(basecolor,ICON_MULTIPLY)
icon = blood
cut_overlays()
add_overlay(giblets)
/obj/effect/decal/cleanable/blood/gibs/up
random_icon_states = list("gib1", "gib2", "gib3", "gib5", "gib6","gibup1","gibup1","gibup1")
/obj/effect/decal/cleanable/blood/gibs/down
random_icon_states = list("gib1", "gib2", "gib3", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
/obj/effect/decal/cleanable/blood/gibs/body
random_icon_states = list("gibhead", "gibtorso")
/obj/effect/decal/cleanable/blood/gibs/limb
random_icon_states = list("gibleg", "gibarm")
/obj/effect/decal/cleanable/blood/gibs/core
random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
/obj/effect/decal/cleanable/blood/gibs/proc/streak(var/list/directions)
spawn (0)
var/direction = pick(directions)
for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++)
sleep(3)
if (i > 0)
var/obj/effect/decal/cleanable/blood/b = new /obj/effect/decal/cleanable/blood/splatter(src.loc)
b.basecolor = src.basecolor
b.update_icon()
if (step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/mucus
name = "mucus"
desc = "Disgusting mucus."
gender = PLURAL
density = FALSE
anchored = TRUE
icon = 'icons/effects/blood.dmi'
icon_state = "mucus"
random_icon_states = list("mucus")
var/list/datum/disease2/disease/virus2 = list()
var/dry = 0 // Keeps the lag down
/obj/effect/decal/cleanable/mucus/Initialize()
. = ..()
VARSET_IN(src, dry, TRUE, DRYING_TIME * 2)
//This version should be used for admin spawns and pre-mapped virus vectors (e.g. in PoIs), this version does not dry
/obj/effect/decal/cleanable/mucus/mapped/Initialize()
. = ..()
virus2 |= new /datum/disease2/disease
virus2[1].makerandom()
/obj/effect/decal/cleanable/mucus/mapped/Destroy()
virus2.Cut()
return ..()
#define DRYING_TIME 5 * 60*10 //for 1 unit of depth in puddle (amount var)
var/global/list/image/splatter_cache=list()
/obj/effect/decal/cleanable/blood
name = "blood"
var/dryname = "dried blood"
desc = "It's thick and gooey. Perhaps it's the chef's cooking?"
var/drydesc = "It's dry and crusty. Someone is not doing their job."
gender = PLURAL
density = FALSE
anchored = TRUE
plane = BLOOD_PLANE
layer = BLOOD_DECAL_LAYER
icon = 'icons/effects/blood.dmi'
icon_state = "mfloor1"
random_icon_states = list("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7")
var/base_icon = 'icons/effects/blood.dmi'
blood_DNA = list()
var/basecolor="#A10808" // Color when wet.
var/synthblood = 0
var/list/datum/disease2/disease/virus2 = list()
var/amount = 5
generic_filth = TRUE
persistent = FALSE
/obj/effect/decal/cleanable/blood/reveal_blood()
if(!fluorescent)
fluorescent = 1
basecolor = COLOR_LUMINOL
update_icon()
/obj/effect/decal/cleanable/blood/clean_blood()
fluorescent = 0
if(invisibility != 100)
invisibility = 100
amount = 0
..(ignore=1)
/obj/effect/decal/cleanable/blood/New()
..()
update_icon()
if(istype(src, /obj/effect/decal/cleanable/blood/gibs))
return
if(src.type == /obj/effect/decal/cleanable/blood)
if(src.loc && isturf(src.loc))
for(var/obj/effect/decal/cleanable/blood/B in src.loc)
if(B != src)
if (B.blood_DNA)
blood_DNA |= B.blood_DNA.Copy()
qdel(B)
addtimer(CALLBACK(src, PROC_REF(dry)), DRYING_TIME * (amount+1))
/obj/effect/decal/cleanable/blood/update_icon()
if(basecolor == "rainbow") basecolor = get_random_colour(1)
color = basecolor
if(basecolor == SYNTH_BLOOD_COLOUR)
name = "oil"
desc = "It's quite oily."
else if(synthblood)
name = "synthetic blood"
desc = "It's quite greasy."
else
name = initial(name)
desc = initial(desc)
/obj/effect/decal/cleanable/blood/Crossed(mob/living/carbon/human/perp)
if(perp.is_incorporeal())
return
if (!istype(perp))
return
if(amount < 1)
return
var/obj/item/organ/external/l_foot = perp.get_organ("l_foot")
var/obj/item/organ/external/r_foot = perp.get_organ("r_foot")
var/hasfeet = 1
if((!l_foot || l_foot.is_stump()) && (!r_foot || r_foot.is_stump()))
hasfeet = 0
if(perp.shoes && !perp.buckled)//Adding blood to shoes
var/obj/item/clothing/shoes/S = perp.shoes
if(istype(S))
S.blood_color = basecolor
S.track_blood = max(amount,S.track_blood)
if(!S.blood_overlay)
S.generate_blood_overlay()
if(!S.blood_DNA)
S.blood_DNA = list()
S.blood_overlay.color = basecolor
S.add_overlay(S.blood_overlay)
if(S.blood_overlay && S.blood_overlay.color != basecolor)
S.blood_overlay.color = basecolor
S.add_overlay(S.blood_overlay)
S.blood_DNA |= blood_DNA.Copy()
perp.update_inv_shoes()
else if (hasfeet)//Or feet
perp.feet_blood_color = basecolor
perp.track_blood = max(amount,perp.track_blood)
LAZYINITLIST(perp.feet_blood_DNA)
perp.feet_blood_DNA |= blood_DNA.Copy()
perp.update_bloodied()
else if (perp.buckled && istype(perp.buckled, /obj/structure/bed/chair/wheelchair))
var/obj/structure/bed/chair/wheelchair/W = perp.buckled
W.bloodiness = 4
amount--
/obj/effect/decal/cleanable/blood/proc/dry()
name = dryname
desc = drydesc
color = adjust_brightness(color, -50)
amount = 0
/obj/effect/decal/cleanable/blood/attack_hand(mob/living/carbon/human/user)
..()
if (amount && istype(user))
add_fingerprint(user)
if (user.gloves)
return
var/taken = rand(1,amount)
amount -= taken
to_chat(user, "<span class='notice'>You get some of \the [src] on your hands.</span>")
if (!user.blood_DNA)
user.blood_DNA = list()
user.blood_DNA |= blood_DNA.Copy()
user.bloody_hands += taken
user.hand_blood_color = basecolor
user.update_inv_gloves(1)
user.verbs += /mob/living/carbon/human/proc/bloody_doodle
/obj/effect/decal/cleanable/blood/splatter
random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5")
amount = 2
/obj/effect/decal/cleanable/blood/drip
name = "drips of blood"
desc = "It's red."
gender = PLURAL
icon = 'icons/effects/drip.dmi'
icon_state = "1"
random_icon_states = list("1","2","3","4","5")
amount = 0
var/list/drips = list()
/obj/effect/decal/cleanable/blood/drip/New()
..()
drips |= icon_state
/obj/effect/decal/cleanable/blood/writing
icon_state = "tracks"
desc = "It looks like a writing in blood."
gender = NEUTER
random_icon_states = list("writing1","writing2","writing3","writing4","writing5")
amount = 0
var/message
/obj/effect/decal/cleanable/blood/writing/New()
..()
if(random_icon_states.len)
for(var/obj/effect/decal/cleanable/blood/writing/W in loc)
random_icon_states.Remove(W.icon_state)
icon_state = pick(random_icon_states)
else
icon_state = "writing1"
/obj/effect/decal/cleanable/blood/writing/examine(mob/user)
. = ..()
. += "It reads: <font color='[basecolor]'>\"[message]\"</font>"
/obj/effect/decal/cleanable/blood/gibs
name = "gibs"
desc = "They look bloody and gruesome."
gender = PLURAL
density = FALSE
anchored = TRUE
icon = 'icons/effects/blood.dmi'
icon_state = "gibbl5"
random_icon_states = list("gib1", "gib2", "gib3", "gib5", "gib6")
var/fleshcolor = "#FFFFFF"
/obj/effect/decal/cleanable/blood/gibs/update_icon()
var/image/giblets = new(base_icon, "[icon_state]_flesh", dir)
if(!fleshcolor || fleshcolor == "rainbow")
fleshcolor = get_random_colour(1)
giblets.color = fleshcolor
var/icon/blood = new(base_icon,"[icon_state]",dir)
if(basecolor == "rainbow") basecolor = get_random_colour(1)
blood.Blend(basecolor,ICON_MULTIPLY)
icon = blood
cut_overlays()
add_overlay(giblets)
/obj/effect/decal/cleanable/blood/gibs/up
random_icon_states = list("gib1", "gib2", "gib3", "gib5", "gib6","gibup1","gibup1","gibup1")
/obj/effect/decal/cleanable/blood/gibs/down
random_icon_states = list("gib1", "gib2", "gib3", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
/obj/effect/decal/cleanable/blood/gibs/body
random_icon_states = list("gibhead", "gibtorso")
/obj/effect/decal/cleanable/blood/gibs/limb
random_icon_states = list("gibleg", "gibarm")
/obj/effect/decal/cleanable/blood/gibs/core
random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
/obj/effect/decal/cleanable/blood/gibs/proc/streak(var/list/directions)
spawn (0)
var/direction = pick(directions)
for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++)
sleep(3)
if (i > 0)
var/obj/effect/decal/cleanable/blood/b = new /obj/effect/decal/cleanable/blood/splatter(src.loc)
b.basecolor = src.basecolor
b.update_icon()
if (step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/mucus
name = "mucus"
desc = "Disgusting mucus."
gender = PLURAL
density = FALSE
anchored = TRUE
icon = 'icons/effects/blood.dmi'
icon_state = "mucus"
random_icon_states = list("mucus")
var/list/datum/disease2/disease/virus2 = list()
var/dry = 0 // Keeps the lag down
/obj/effect/decal/cleanable/mucus/Initialize()
. = ..()
VARSET_IN(src, dry, TRUE, DRYING_TIME * 2)
//This version should be used for admin spawns and pre-mapped virus vectors (e.g. in PoIs), this version does not dry
/obj/effect/decal/cleanable/mucus/mapped/Initialize()
. = ..()
virus2 |= new /datum/disease2/disease
virus2[1].makerandom()
/obj/effect/decal/cleanable/mucus/mapped/Destroy()
virus2.Cut()
return ..()
+163 -163
View File
@@ -1,163 +1,163 @@
/obj/effect/decal/cleanable/generic
name = "clutter"
desc = "Someone should clean that up."
gender = PLURAL
density = FALSE
anchored = TRUE
icon = 'icons/obj/objects.dmi'
icon_state = "shards"
/obj/effect/decal/cleanable/ash
name = "ashes"
desc = "Ashes to ashes, dust to dust, and into space."
gender = PLURAL
icon = 'icons/obj/objects.dmi'
icon_state = "ash"
anchored = TRUE
/obj/effect/decal/cleanable/ash/attack_hand(mob/user as mob)
to_chat(user, "<span class='notice'>[src] sifts through your fingers.</span>")
var/turf/simulated/floor/F = get_turf(src)
if (istype(F))
F.dirt += 4
qdel(src)
/obj/effect/decal/cleanable/greenglow
/obj/effect/decal/cleanable/greenglow/New()
..()
QDEL_IN(src, 2 MINUTES)
/obj/effect/decal/cleanable/dirt
name = "dirt"
desc = "Someone should clean that up."
gender = PLURAL
density = FALSE
anchored = TRUE
icon = 'icons/effects/effects.dmi'
icon_state = "dirt"
mouse_opacity = 0
/obj/effect/decal/cleanable/dirt/Initialize(var/mapload, var/_age, var/dirt)
.=..()
var/turf/simulated/our_turf = src.loc
if(our_turf && istype(our_turf) && our_turf.can_dirty)
our_turf.dirt = clamp(max(age ? (dirt ? dirt : 101) : our_turf.dirt, our_turf.dirt), 0, 101)
var/calcalpha = our_turf.dirt > 50 ? min((our_turf.dirt - 50) * 5, 255) : 0
var/alreadyfound = FALSE
for (var/obj/effect/decal/cleanable/dirt/alreadythere in our_turf) //in case of multiple
if (alreadythere == src)
continue
else if (alreadyfound)
qdel(alreadythere)
continue
alreadyfound = TRUE
alreadythere.alpha = calcalpha //don't need to constantly recalc for all of them in it because it'll just max if a non-persistent dirt overlay gets added, and then the new dirt overlay will be deleted
if (alreadyfound)
return INITIALIZE_HINT_QDEL
alpha = calcalpha
/obj/effect/decal/cleanable/flour
name = "flour"
desc = "It's still good. Four second rule!"
gender = PLURAL
density = FALSE
anchored = TRUE
icon = 'icons/effects/effects.dmi'
icon_state = "flour"
/obj/effect/decal/cleanable/greenglow
name = "glowing goo"
desc = "Jeez. I hope that's not for lunch."
gender = PLURAL
density = FALSE
anchored = TRUE
light_range = 1
icon = 'icons/effects/effects.dmi'
icon_state = "greenglow"
/obj/effect/decal/cleanable/cobweb
name = "cobweb"
desc = "Somebody should remove that."
density = FALSE
anchored = TRUE
plane = OBJ_PLANE
icon = 'icons/effects/effects.dmi'
icon_state = "cobweb1"
/obj/effect/decal/cleanable/molten_item
name = "gooey grey mass"
desc = "It looks like a melted... something."
density = FALSE
anchored = TRUE
plane = OBJ_PLANE
icon = 'icons/obj/chemical.dmi'
icon_state = "molten"
/obj/effect/decal/cleanable/cobweb2
name = "cobweb"
desc = "Somebody should remove that."
density = FALSE
anchored = TRUE
plane = OBJ_PLANE
icon = 'icons/effects/effects.dmi'
icon_state = "cobweb2"
//Vomit (sorry)
/obj/effect/decal/cleanable/vomit
name = "vomit"
desc = "Gosh, how unpleasant."
gender = PLURAL
density = FALSE
anchored = TRUE
icon = 'icons/effects/blood.dmi'
icon_state = "vomit_1"
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
var/list/datum/disease2/disease/virus2 = list()
/obj/effect/decal/cleanable/tomato_smudge
name = "tomato smudge"
desc = "It's red."
density = FALSE
anchored = TRUE
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("tomato_floor1", "tomato_floor2", "tomato_floor3")
/obj/effect/decal/cleanable/egg_smudge
name = "smashed egg"
desc = "Seems like this one won't hatch."
density = FALSE
anchored = TRUE
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_egg1", "smashed_egg2", "smashed_egg3")
/obj/effect/decal/cleanable/pie_smudge //honk
name = "smashed pie"
desc = "It's pie cream from a cream pie."
density = FALSE
anchored = TRUE
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_pie")
/obj/effect/decal/cleanable/fruit_smudge
name = "smudge"
desc = "Some kind of fruit smear."
density = FALSE
anchored = TRUE
icon = 'icons/effects/blood.dmi'
icon_state = "mfloor1"
random_icon_states = list("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7")
/obj/effect/decal/cleanable/confetti
name = "confetti"
desc = "Tiny bits of colored paper thrown about for the janitor to enjoy!"
gender = PLURAL
density = FALSE
anchored = TRUE
icon = 'icons/effects/effects.dmi'
icon_state = "confetti"
/obj/effect/decal/cleanable/confetti/attack_hand(mob/user)
to_chat(user, "<span class='notice'>You start to meticulously pick up the confetti.</span>")
if(do_after(user, 60))
qdel(src)
/obj/effect/decal/cleanable/generic
name = "clutter"
desc = "Someone should clean that up."
gender = PLURAL
density = FALSE
anchored = TRUE
icon = 'icons/obj/objects.dmi'
icon_state = "shards"
/obj/effect/decal/cleanable/ash
name = "ashes"
desc = "Ashes to ashes, dust to dust, and into space."
gender = PLURAL
icon = 'icons/obj/objects.dmi'
icon_state = "ash"
anchored = TRUE
/obj/effect/decal/cleanable/ash/attack_hand(mob/user as mob)
to_chat(user, "<span class='notice'>[src] sifts through your fingers.</span>")
var/turf/simulated/floor/F = get_turf(src)
if (istype(F))
F.dirt += 4
qdel(src)
/obj/effect/decal/cleanable/greenglow
/obj/effect/decal/cleanable/greenglow/New()
..()
QDEL_IN(src, 2 MINUTES)
/obj/effect/decal/cleanable/dirt
name = "dirt"
desc = "Someone should clean that up."
gender = PLURAL
density = FALSE
anchored = TRUE
icon = 'icons/effects/effects.dmi'
icon_state = "dirt"
mouse_opacity = 0
/obj/effect/decal/cleanable/dirt/Initialize(var/mapload, var/_age, var/dirt)
.=..()
var/turf/simulated/our_turf = src.loc
if(our_turf && istype(our_turf) && our_turf.can_dirty)
our_turf.dirt = clamp(max(age ? (dirt ? dirt : 101) : our_turf.dirt, our_turf.dirt), 0, 101)
var/calcalpha = our_turf.dirt > 50 ? min((our_turf.dirt - 50) * 5, 255) : 0
var/alreadyfound = FALSE
for (var/obj/effect/decal/cleanable/dirt/alreadythere in our_turf) //in case of multiple
if (alreadythere == src)
continue
else if (alreadyfound)
qdel(alreadythere)
continue
alreadyfound = TRUE
alreadythere.alpha = calcalpha //don't need to constantly recalc for all of them in it because it'll just max if a non-persistent dirt overlay gets added, and then the new dirt overlay will be deleted
if (alreadyfound)
return INITIALIZE_HINT_QDEL
alpha = calcalpha
/obj/effect/decal/cleanable/flour
name = "flour"
desc = "It's still good. Four second rule!"
gender = PLURAL
density = FALSE
anchored = TRUE
icon = 'icons/effects/effects.dmi'
icon_state = "flour"
/obj/effect/decal/cleanable/greenglow
name = "glowing goo"
desc = "Jeez. I hope that's not for lunch."
gender = PLURAL
density = FALSE
anchored = TRUE
light_range = 1
icon = 'icons/effects/effects.dmi'
icon_state = "greenglow"
/obj/effect/decal/cleanable/cobweb
name = "cobweb"
desc = "Somebody should remove that."
density = FALSE
anchored = TRUE
plane = OBJ_PLANE
icon = 'icons/effects/effects.dmi'
icon_state = "cobweb1"
/obj/effect/decal/cleanable/molten_item
name = "gooey grey mass"
desc = "It looks like a melted... something."
density = FALSE
anchored = TRUE
plane = OBJ_PLANE
icon = 'icons/obj/chemical.dmi'
icon_state = "molten"
/obj/effect/decal/cleanable/cobweb2
name = "cobweb"
desc = "Somebody should remove that."
density = FALSE
anchored = TRUE
plane = OBJ_PLANE
icon = 'icons/effects/effects.dmi'
icon_state = "cobweb2"
//Vomit (sorry)
/obj/effect/decal/cleanable/vomit
name = "vomit"
desc = "Gosh, how unpleasant."
gender = PLURAL
density = FALSE
anchored = TRUE
icon = 'icons/effects/blood.dmi'
icon_state = "vomit_1"
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
var/list/datum/disease2/disease/virus2 = list()
/obj/effect/decal/cleanable/tomato_smudge
name = "tomato smudge"
desc = "It's red."
density = FALSE
anchored = TRUE
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("tomato_floor1", "tomato_floor2", "tomato_floor3")
/obj/effect/decal/cleanable/egg_smudge
name = "smashed egg"
desc = "Seems like this one won't hatch."
density = FALSE
anchored = TRUE
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_egg1", "smashed_egg2", "smashed_egg3")
/obj/effect/decal/cleanable/pie_smudge //honk
name = "smashed pie"
desc = "It's pie cream from a cream pie."
density = FALSE
anchored = TRUE
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_pie")
/obj/effect/decal/cleanable/fruit_smudge
name = "smudge"
desc = "Some kind of fruit smear."
density = FALSE
anchored = TRUE
icon = 'icons/effects/blood.dmi'
icon_state = "mfloor1"
random_icon_states = list("mfloor1", "mfloor2", "mfloor3", "mfloor4", "mfloor5", "mfloor6", "mfloor7")
/obj/effect/decal/cleanable/confetti
name = "confetti"
desc = "Tiny bits of colored paper thrown about for the janitor to enjoy!"
gender = PLURAL
density = FALSE
anchored = TRUE
icon = 'icons/effects/effects.dmi'
icon_state = "confetti"
/obj/effect/decal/cleanable/confetti/attack_hand(mob/user)
to_chat(user, "<span class='notice'>You start to meticulously pick up the confetti.</span>")
if(do_after(user, 60))
qdel(src)
@@ -1,52 +1,52 @@
/obj/effect/decal/cleanable/blood/gibs/robot
name = "robot debris"
desc = "It's a useless heap of junk... <i>or is it?</i>"
icon = 'icons/mob/robots.dmi'
icon_state = "gib1"
basecolor = SYNTH_BLOOD_COLOUR
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7")
generic_filth = FALSE
persistent = FALSE
/obj/effect/decal/cleanable/blood/gibs/robot/update_icon()
color = "#FFFFFF"
/obj/effect/decal/cleanable/blood/gibs/robot/dry() //pieces of robots do not dry up like
return
/obj/effect/decal/cleanable/blood/gibs/robot/streak(var/list/directions)
spawn (0)
var/direction = pick(directions)
for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++)
sleep(3)
if (i > 0)
if (prob(40))
var/obj/effect/decal/cleanable/blood/oil/streak = new(src.loc)
streak.update_icon()
else if (prob(10))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
if (step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/blood/gibs/robot/limb
random_icon_states = list("gibarm", "gibleg")
/obj/effect/decal/cleanable/blood/gibs/robot/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7","gibup1","gibup1") //2:7 is close enough to 1:4
/obj/effect/decal/cleanable/blood/gibs/robot/down
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7","gibdown1","gibdown1") //2:7 is close enough to 1:4
/obj/effect/decal/cleanable/blood/oil
basecolor = SYNTH_BLOOD_COLOUR
generic_filth = FALSE
persistent = FALSE
/obj/effect/decal/cleanable/blood/oil/dry()
return
/obj/effect/decal/cleanable/blood/oil/streak
random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5")
/obj/effect/decal/cleanable/blood/gibs/robot
name = "robot debris"
desc = "It's a useless heap of junk... <i>or is it?</i>"
icon = 'icons/mob/robots.dmi'
icon_state = "gib1"
basecolor = SYNTH_BLOOD_COLOUR
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7")
generic_filth = FALSE
persistent = FALSE
/obj/effect/decal/cleanable/blood/gibs/robot/update_icon()
color = "#FFFFFF"
/obj/effect/decal/cleanable/blood/gibs/robot/dry() //pieces of robots do not dry up like
return
/obj/effect/decal/cleanable/blood/gibs/robot/streak(var/list/directions)
spawn (0)
var/direction = pick(directions)
for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++)
sleep(3)
if (i > 0)
if (prob(40))
var/obj/effect/decal/cleanable/blood/oil/streak = new(src.loc)
streak.update_icon()
else if (prob(10))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, src)
s.start()
if (step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/blood/gibs/robot/limb
random_icon_states = list("gibarm", "gibleg")
/obj/effect/decal/cleanable/blood/gibs/robot/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7","gibup1","gibup1") //2:7 is close enough to 1:4
/obj/effect/decal/cleanable/blood/gibs/robot/down
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7","gibdown1","gibdown1") //2:7 is close enough to 1:4
/obj/effect/decal/cleanable/blood/oil
basecolor = SYNTH_BLOOD_COLOUR
generic_filth = FALSE
persistent = FALSE
/obj/effect/decal/cleanable/blood/oil/dry()
return
/obj/effect/decal/cleanable/blood/oil/streak
random_icon_states = list("mgibbl1", "mgibbl2", "mgibbl3", "mgibbl4", "mgibbl5")
amount = 2
+38 -38
View File
@@ -1,38 +1,38 @@
/*
USAGE NOTE
For decals, the var Persistent = 'has already been saved', and is primarily used to prevent duplicate savings of generic filth (filth.dm).
This also means 'TRUE' can be used to define a decal as "Do not save at all, even as a generic replacement." if a dirt decal is considered 'too common' to save.
generic_filth = TRUE means when the decal is saved, it will be switched out for a generic green 'filth' decal.
*/
/obj/effect/decal/cleanable
plane = DIRTY_PLANE
layer = DIRTY_LAYER
var/persistent = FALSE
var/generic_filth = FALSE
var/age = 0
var/list/random_icon_states = list()
/obj/effect/decal/cleanable/Initialize(var/mapload, var/_age)
if(!isnull(_age))
age = _age
if(random_icon_states && length(src.random_icon_states) > 0)
src.icon_state = pick(src.random_icon_states)
if(!mapload || !config.persistence_ignore_mapload)
SSpersistence.track_value(src, /datum/persistent/filth)
. = ..()
/obj/effect/decal/cleanable/Destroy()
SSpersistence.forget_value(src, /datum/persistent/filth)
. = ..()
/obj/effect/decal/cleanable/clean_blood(var/ignore = 0)
if(!ignore)
qdel(src)
return
..()
/obj/effect/decal/cleanable/New()
if (random_icon_states && length(src.random_icon_states) > 0)
src.icon_state = pick(src.random_icon_states)
..()
/*
USAGE NOTE
For decals, the var Persistent = 'has already been saved', and is primarily used to prevent duplicate savings of generic filth (filth.dm).
This also means 'TRUE' can be used to define a decal as "Do not save at all, even as a generic replacement." if a dirt decal is considered 'too common' to save.
generic_filth = TRUE means when the decal is saved, it will be switched out for a generic green 'filth' decal.
*/
/obj/effect/decal/cleanable
plane = DIRTY_PLANE
layer = DIRTY_LAYER
var/persistent = FALSE
var/generic_filth = FALSE
var/age = 0
var/list/random_icon_states = list()
/obj/effect/decal/cleanable/Initialize(var/mapload, var/_age)
if(!isnull(_age))
age = _age
if(random_icon_states && length(src.random_icon_states) > 0)
src.icon_state = pick(src.random_icon_states)
if(!mapload || !config.persistence_ignore_mapload)
SSpersistence.track_value(src, /datum/persistent/filth)
. = ..()
/obj/effect/decal/cleanable/Destroy()
SSpersistence.forget_value(src, /datum/persistent/filth)
. = ..()
/obj/effect/decal/cleanable/clean_blood(var/ignore = 0)
if(!ignore)
qdel(src)
return
..()
/obj/effect/decal/cleanable/New()
if (random_icon_states && length(src.random_icon_states) > 0)
src.icon_state = pick(src.random_icon_states)
..()
+31 -31
View File
@@ -1,31 +1,31 @@
/obj/effect/decal/cleanable/crayon
name = "rune"
desc = "A rune drawn in crayon."
icon = 'icons/obj/rune.dmi'
plane = DIRTY_PLANE
layer = DIRTY_LAYER
anchored = TRUE
/obj/effect/decal/cleanable/crayon/New(location,main = "#FFFFFF",shade = "#000000",var/type = "rune")
..()
loc = location
name = type
desc = "A [type] drawn in crayon."
switch(type)
if("rune")
type = "rune[rand(1,6)]"
if("graffiti")
type = pick("amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa")
var/icon/mainOverlay = new/icon('icons/effects/crayondecal.dmi',"[type]",2.1)
var/icon/shadeOverlay = new/icon('icons/effects/crayondecal.dmi',"[type]s",2.1)
mainOverlay.Blend(main,ICON_ADD)
shadeOverlay.Blend(shade,ICON_ADD)
add_overlay(mainOverlay)
add_overlay(shadeOverlay)
add_hiddenprint(usr)
/obj/effect/decal/cleanable/crayon
name = "rune"
desc = "A rune drawn in crayon."
icon = 'icons/obj/rune.dmi'
plane = DIRTY_PLANE
layer = DIRTY_LAYER
anchored = TRUE
/obj/effect/decal/cleanable/crayon/New(location,main = "#FFFFFF",shade = "#000000",var/type = "rune")
..()
loc = location
name = type
desc = "A [type] drawn in crayon."
switch(type)
if("rune")
type = "rune[rand(1,6)]"
if("graffiti")
type = pick("amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa")
var/icon/mainOverlay = new/icon('icons/effects/crayondecal.dmi',"[type]",2.1)
var/icon/shadeOverlay = new/icon('icons/effects/crayondecal.dmi',"[type]s",2.1)
mainOverlay.Blend(main,ICON_ADD)
shadeOverlay.Blend(shade,ICON_ADD)
add_overlay(mainOverlay)
add_overlay(shadeOverlay)
add_hiddenprint(usr)
+13 -13
View File
@@ -1,14 +1,14 @@
/obj/effect/decal/point
name = "arrow"
desc = "It's an arrow hanging in mid-air. There may be a wizard about."
icon = 'icons/mob/screen1.dmi'
icon_state = "arrow"
plane = ABOVE_PLANE
anchored = TRUE
mouse_opacity = 0
// Used for spray that you spray at walls, tables, hydrovats etc
/obj/effect/decal/spraystill
density = FALSE
anchored = TRUE
/obj/effect/decal/point
name = "arrow"
desc = "It's an arrow hanging in mid-air. There may be a wizard about."
icon = 'icons/mob/screen1.dmi'
icon_state = "arrow"
plane = ABOVE_PLANE
anchored = TRUE
mouse_opacity = 0
// Used for spray that you spray at walls, tables, hydrovats etc
/obj/effect/decal/spraystill
density = FALSE
anchored = TRUE
plane = ABOVE_PLANE
+70 -70
View File
@@ -1,70 +1,70 @@
/obj/effect/decal/remains
name = "remains"
gender = PLURAL
icon = 'icons/effects/blood.dmi'
icon_state = "remains"
anchored = FALSE
/obj/effect/decal/remains/human
desc = "They look like human remains. They have a strange aura about them."
/obj/effect/decal/remains/xeno
desc = "They look like the remains of something... alien. They have a strange aura about them."
icon_state = "remainsxeno"
/obj/effect/decal/remains/robot
desc = "They look like the remains of something mechanical. They have a strange aura about them."
icon = 'icons/mob/robots.dmi'
icon_state = "remainsrobot"
/obj/effect/decal/remains/mouse
desc = "They look like the remains of a small rodent."
icon_state = "mouse"
/obj/effect/decal/remains/lizard
desc = "They look like the remains of a small lizard."
icon_state = "lizard"
/obj/effect/decal/remains/unathi
desc = "They look like Unathi remains. Pointy."
icon_state = "remainsunathi"
/obj/effect/decal/remains/tajaran
desc = "They look like Tajaran remains. They're surprisingly small."
icon_state = "remainstajaran"
/obj/effect/decal/remains/ribcage
desc = "They look like animal remains of some sort... You hope."
icon_state = "remainsribcage"
/obj/effect/decal/remains/deer
desc = "They look like the remains of a large herbivore, picked clean."
icon_state = "remainsdeer"
/obj/effect/decal/remains/posi
desc = "This looks like part of an old FBP. Hopefully it was empty."
icon_state = "remainsposi"
/obj/effect/decal/remains/mummy1
name = "mummified remains"
desc = "They look like human remains. They've been here a long time."
icon_state = "mummified1"
/obj/effect/decal/remains/mummy2
name = "mummified remains"
desc = "They look like human remains. They've been here a long time."
icon_state = "mummified2"
/obj/effect/decal/remains/attack_hand(mob/user as mob)
to_chat(user, "<span class='notice'>[src] sinks together into a pile of ash.</span>")
var/turf/simulated/floor/F = get_turf(src)
if(istype(F))
new /obj/effect/decal/cleanable/ash(F)
qdel(src)
/obj/effect/decal/remains/robot/attack_hand(mob/user as mob)
to_chat(user, "<span class='notice'>[src] crumbles down into a pile of debris.</span>")
var/turf/simulated/floor/F = get_turf(src)
if(istype(F))
new /obj/effect/decal/cleanable/blood/gibs/robot(F)
qdel(src)
/obj/effect/decal/remains
name = "remains"
gender = PLURAL
icon = 'icons/effects/blood.dmi'
icon_state = "remains"
anchored = FALSE
/obj/effect/decal/remains/human
desc = "They look like human remains. They have a strange aura about them."
/obj/effect/decal/remains/xeno
desc = "They look like the remains of something... alien. They have a strange aura about them."
icon_state = "remainsxeno"
/obj/effect/decal/remains/robot
desc = "They look like the remains of something mechanical. They have a strange aura about them."
icon = 'icons/mob/robots.dmi'
icon_state = "remainsrobot"
/obj/effect/decal/remains/mouse
desc = "They look like the remains of a small rodent."
icon_state = "mouse"
/obj/effect/decal/remains/lizard
desc = "They look like the remains of a small lizard."
icon_state = "lizard"
/obj/effect/decal/remains/unathi
desc = "They look like Unathi remains. Pointy."
icon_state = "remainsunathi"
/obj/effect/decal/remains/tajaran
desc = "They look like Tajaran remains. They're surprisingly small."
icon_state = "remainstajaran"
/obj/effect/decal/remains/ribcage
desc = "They look like animal remains of some sort... You hope."
icon_state = "remainsribcage"
/obj/effect/decal/remains/deer
desc = "They look like the remains of a large herbivore, picked clean."
icon_state = "remainsdeer"
/obj/effect/decal/remains/posi
desc = "This looks like part of an old FBP. Hopefully it was empty."
icon_state = "remainsposi"
/obj/effect/decal/remains/mummy1
name = "mummified remains"
desc = "They look like human remains. They've been here a long time."
icon_state = "mummified1"
/obj/effect/decal/remains/mummy2
name = "mummified remains"
desc = "They look like human remains. They've been here a long time."
icon_state = "mummified2"
/obj/effect/decal/remains/attack_hand(mob/user as mob)
to_chat(user, "<span class='notice'>[src] sinks together into a pile of ash.</span>")
var/turf/simulated/floor/F = get_turf(src)
if(istype(F))
new /obj/effect/decal/cleanable/ash(F)
qdel(src)
/obj/effect/decal/remains/robot/attack_hand(mob/user as mob)
to_chat(user, "<span class='notice'>[src] crumbles down into a pile of debris.</span>")
var/turf/simulated/floor/F = get_turf(src)
if(istype(F))
new /obj/effect/decal/cleanable/blood/gibs/robot(F)
qdel(src)
@@ -1,10 +1,10 @@
/obj/effect/decal/warning_stripes
icon = 'icons/effects/warning_stripes.dmi'
/obj/effect/decal/warning_stripes/Initialize()
. = ..()
var/turf/T=get_turf(src)
var/image/I=image(icon, icon_state = icon_state, dir = dir)
I.color=color
T.add_overlay(I)
return INITIALIZE_HINT_QDEL
/obj/effect/decal/warning_stripes
icon = 'icons/effects/warning_stripes.dmi'
/obj/effect/decal/warning_stripes/Initialize()
. = ..()
var/turf/T=get_turf(src)
var/image/I=image(icon, icon_state = icon_state, dir = dir)
I.color=color
T.add_overlay(I)
return INITIALIZE_HINT_QDEL
File diff suppressed because it is too large Load Diff
@@ -1,72 +1,72 @@
/obj/effect/expl_particles
name = "explosive particles"
icon = 'icons/effects/effects.dmi'
icon_state = "explosion_particle"
opacity = 1
anchored = TRUE
mouse_opacity = 0
/obj/effect/expl_particles/New()
..()
spawn (15)
qdel(src)
return
/datum/effect/system/expl_particles
var/number = 10
var/turf/location
var/total_particles = 0
/datum/effect/system/expl_particles/proc/set_up(n = 10, loca)
number = n
if(istype(loca, /turf/)) location = loca
else location = get_turf(loca)
/datum/effect/system/expl_particles/proc/start()
var/i = 0
for(i=0, i<src.number, i++)
spawn(0)
var/obj/effect/expl_particles/expl = new /obj/effect/expl_particles(src.location)
var/direct = pick(alldirs)
for(i=0, i<pick(1;25,2;50,3,4;200), i++)
sleep(1)
step(expl,direct)
/obj/effect/explosion
name = "explosive particles"
icon = 'icons/effects/96x96.dmi'
icon_state = "explosion"
opacity = 1
anchored = TRUE
mouse_opacity = 0
pixel_x = -32
pixel_y = -32
/obj/effect/explosion/New()
..()
spawn (10)
qdel(src)
return
/datum/effect/system/explosion
var/turf/location
/datum/effect/system/explosion/proc/set_up(loca)
if(istype(loca, /turf/)) location = loca
else location = get_turf(loca)
/datum/effect/system/explosion/proc/start()
new/obj/effect/explosion( location )
var/datum/effect/system/expl_particles/P = new/datum/effect/system/expl_particles()
P.set_up(10,location)
P.start()
spawn(5)
var/datum/effect/effect/system/smoke_spread/S = new/datum/effect/effect/system/smoke_spread()
S.set_up(5,0,location,null)
S.start()
/datum/effect/system/explosion/smokeless/start()
new/obj/effect/explosion(location)
var/datum/effect/system/expl_particles/P = new/datum/effect/system/expl_particles()
P.set_up(10,location)
/obj/effect/expl_particles
name = "explosive particles"
icon = 'icons/effects/effects.dmi'
icon_state = "explosion_particle"
opacity = 1
anchored = TRUE
mouse_opacity = 0
/obj/effect/expl_particles/New()
..()
spawn (15)
qdel(src)
return
/datum/effect/system/expl_particles
var/number = 10
var/turf/location
var/total_particles = 0
/datum/effect/system/expl_particles/proc/set_up(n = 10, loca)
number = n
if(istype(loca, /turf/)) location = loca
else location = get_turf(loca)
/datum/effect/system/expl_particles/proc/start()
var/i = 0
for(i=0, i<src.number, i++)
spawn(0)
var/obj/effect/expl_particles/expl = new /obj/effect/expl_particles(src.location)
var/direct = pick(alldirs)
for(i=0, i<pick(1;25,2;50,3,4;200), i++)
sleep(1)
step(expl,direct)
/obj/effect/explosion
name = "explosive particles"
icon = 'icons/effects/96x96.dmi'
icon_state = "explosion"
opacity = 1
anchored = TRUE
mouse_opacity = 0
pixel_x = -32
pixel_y = -32
/obj/effect/explosion/New()
..()
spawn (10)
qdel(src)
return
/datum/effect/system/explosion
var/turf/location
/datum/effect/system/explosion/proc/set_up(loca)
if(istype(loca, /turf/)) location = loca
else location = get_turf(loca)
/datum/effect/system/explosion/proc/start()
new/obj/effect/explosion( location )
var/datum/effect/system/expl_particles/P = new/datum/effect/system/expl_particles()
P.set_up(10,location)
P.start()
spawn(5)
var/datum/effect/effect/system/smoke_spread/S = new/datum/effect/effect/system/smoke_spread()
S.set_up(5,0,location,null)
S.start()
/datum/effect/system/explosion/smokeless/start()
new/obj/effect/explosion(location)
var/datum/effect/system/expl_particles/P = new/datum/effect/system/expl_particles()
P.set_up(10,location)
P.start()
+55 -55
View File
@@ -1,55 +1,55 @@
/proc/gibs(atom/location, var/datum/dna/MobDNA, gibber_type = /obj/effect/gibspawner/generic, var/fleshcolor, var/bloodcolor)
new gibber_type(location,MobDNA,fleshcolor,bloodcolor)
/obj/effect/gibspawner
var/sparks = 0 //whether sparks spread on Gib()
var/list/gibtypes = list()
var/list/gibamounts = list()
var/list/gibdirections = list() //of lists
var/fleshcolor //Used for gibbed humans.
var/bloodcolor //Used for gibbed humans.
/obj/effect/gibspawner/New(location, var/datum/dna/MobDNA, var/fleshcolor, var/bloodcolor)
..()
if(fleshcolor) src.fleshcolor = fleshcolor
if(bloodcolor) src.bloodcolor = bloodcolor
Gib(loc,MobDNA)
/obj/effect/gibspawner/proc/Gib(atom/location, var/datum/dna/MobDNA = null)
if(gibtypes.len != gibamounts.len || gibamounts.len != gibdirections.len)
to_world("<span class='warning'>Gib list length mismatch!</span>")
return
var/obj/effect/decal/cleanable/blood/gibs/gib = null
if(sparks)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
s.set_up(2, 1, get_turf(location)) // Not sure if it's safe to pass an arbitrary object to set_up, todo
s.start()
for(var/i = 1, i<= gibtypes.len, i++)
if(gibamounts[i])
for(var/j = 1, j<= gibamounts[i], j++)
var/gibType = gibtypes[i]
gib = new gibType(location)
// Apply human species colouration to masks.
if(fleshcolor)
gib.fleshcolor = fleshcolor
if(bloodcolor)
gib.basecolor = bloodcolor
gib.update_icon()
gib.blood_DNA = list()
if(MobDNA)
gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.b_type
else if(istype(src, /obj/effect/gibspawner/human)) // Probably a monkey
gib.blood_DNA["Non-human DNA"] = "A+"
if(istype(location,/turf/))
var/list/directions = gibdirections[i]
if(directions.len)
gib.streak(directions)
qdel(src)
/proc/gibs(atom/location, var/datum/dna/MobDNA, gibber_type = /obj/effect/gibspawner/generic, var/fleshcolor, var/bloodcolor)
new gibber_type(location,MobDNA,fleshcolor,bloodcolor)
/obj/effect/gibspawner
var/sparks = 0 //whether sparks spread on Gib()
var/list/gibtypes = list()
var/list/gibamounts = list()
var/list/gibdirections = list() //of lists
var/fleshcolor //Used for gibbed humans.
var/bloodcolor //Used for gibbed humans.
/obj/effect/gibspawner/New(location, var/datum/dna/MobDNA, var/fleshcolor, var/bloodcolor)
..()
if(fleshcolor) src.fleshcolor = fleshcolor
if(bloodcolor) src.bloodcolor = bloodcolor
Gib(loc,MobDNA)
/obj/effect/gibspawner/proc/Gib(atom/location, var/datum/dna/MobDNA = null)
if(gibtypes.len != gibamounts.len || gibamounts.len != gibdirections.len)
to_world("<span class='warning'>Gib list length mismatch!</span>")
return
var/obj/effect/decal/cleanable/blood/gibs/gib = null
if(sparks)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
s.set_up(2, 1, get_turf(location)) // Not sure if it's safe to pass an arbitrary object to set_up, todo
s.start()
for(var/i = 1, i<= gibtypes.len, i++)
if(gibamounts[i])
for(var/j = 1, j<= gibamounts[i], j++)
var/gibType = gibtypes[i]
gib = new gibType(location)
// Apply human species colouration to masks.
if(fleshcolor)
gib.fleshcolor = fleshcolor
if(bloodcolor)
gib.basecolor = bloodcolor
gib.update_icon()
gib.blood_DNA = list()
if(MobDNA)
gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.b_type
else if(istype(src, /obj/effect/gibspawner/human)) // Probably a monkey
gib.blood_DNA["Non-human DNA"] = "A+"
if(istype(location,/turf/))
var/list/directions = gibdirections[i]
if(directions.len)
gib.streak(directions)
qdel(src)
+291 -291
View File
@@ -1,291 +1,291 @@
/obj/effect/landmark
name = "landmark"
icon = 'icons/mob/screen1.dmi'
icon_state = "x2"
anchored = TRUE
unacidable = TRUE
simulated = FALSE
invisibility = 100
var/delete_me = 0
/obj/effect/landmark/New()
..()
tag = text("landmark*[]", name)
invisibility = 101
switch(name) //some of these are probably obsolete
if("monkey")
monkeystart += loc
delete_me = 1
return
if("start")
newplayer_start += loc
delete_me = 1
return
if("JoinLate") // Bit difference, since we need the spawn point to move.
latejoin += src
simulated = TRUE
// delete_me = 1
return
if("JoinLateGateway")
latejoin_gateway += loc
latejoin += src //VOREStation Addition
delete_me = 1
return
if("JoinLateElevator")
latejoin_elevator += loc
delete_me = 1
return
if("JoinLateCryo")
latejoin_cryo += loc
delete_me = 1
return
if("JoinLateCyborg")
latejoin_cyborg += loc
delete_me = 1
return
if("prisonwarp")
prisonwarp += loc
delete_me = 1
return
if("Holding Facility")
holdingfacility += loc
if("tdome1")
tdome1 += loc
if("tdome2")
tdome2 += loc
if("tdomeadmin")
tdomeadmin += loc
if("tdomeobserve")
tdomeobserve += loc
if("prisonsecuritywarp")
prisonsecuritywarp += loc
delete_me = 1
return
if("blobstart")
blobstart += loc
delete_me = 1
return
if("xeno_spawn")
xeno_spawn += loc
delete_me = 1
return
if("endgame_exit")
endgame_safespawns += loc
delete_me = 1
return
if("bluespacerift")
endgame_exits += loc
delete_me = 1
return
//VOREStation Add Start
if("vinestart")
vinestart += loc
delete_me = 1
return
//VORE Station Add End
landmarks_list += src
return 1
/obj/effect/landmark/proc/delete()
delete_me = 1
/obj/effect/landmark/Initialize()
. = ..()
if(delete_me)
return INITIALIZE_HINT_QDEL
/obj/effect/landmark/Destroy(var/force = FALSE)
if(delete_me || force)
landmarks_list -= src
return ..()
return QDEL_HINT_LETMELIVE
/obj/effect/landmark/start
name = "start"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
anchored = TRUE
/obj/effect/landmark/start/New()
..()
tag = "start*[name]"
invisibility = 101
return 1
/obj/effect/landmark/forbidden_level
delete_me = 1
/obj/effect/landmark/forbidden_level/Initialize()
. = ..()
if(using_map)
using_map.secret_levels |= z
else
log_error("[type] mapped in but no using_map")
/obj/effect/landmark/hidden_level
delete_me = 1
/obj/effect/landmark/hidden_level/Initialize()
. = ..()
if(using_map)
using_map.hidden_levels |= z
else
log_error("[type] mapped in but no using_map")
/obj/effect/landmark/virtual_reality
name = "virtual_reality"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
anchored = TRUE
/obj/effect/landmark/virtual_reality/New()
..()
tag = "virtual_reality*[name]"
invisibility = 101
return 1
//Costume spawner landmarks
/obj/effect/landmark/costume/New() //costume spawner, selects a random subclass and disappears
var/list/options = typesof(/obj/effect/landmark/costume)
var/PICK= options[rand(1,options.len)]
new PICK(src.loc)
delete_me = 1
//SUBCLASSES. Spawn a bunch of items and disappear likewise
/obj/effect/landmark/costume/chicken/New()
new /obj/item/clothing/suit/chickensuit(src.loc)
new /obj/item/clothing/head/chicken(src.loc)
new /obj/item/weapon/reagent_containers/food/snacks/egg(src.loc)
delete_me = 1
/obj/effect/landmark/costume/gladiator/New()
new /obj/item/clothing/under/gladiator(src.loc)
new /obj/item/clothing/head/helmet/gladiator(src.loc)
qdel(src)
/obj/effect/landmark/costume/madscientist/New()
new /obj/item/clothing/under/suit_jacket/green(src.loc)
new /obj/item/clothing/head/flatcap(src.loc)
new /obj/item/clothing/suit/storage/toggle/labcoat/mad(src.loc)
new /obj/item/clothing/glasses/gglasses(src.loc)
delete_me = 1
/obj/effect/landmark/costume/elpresidente/New()
new /obj/item/clothing/under/suit_jacket/green(src.loc)
new /obj/item/clothing/head/flatcap(src.loc)
new /obj/item/clothing/mask/smokable/cigarette/cigar/havana(src.loc)
new /obj/item/clothing/shoes/boots/jackboots(src.loc)
delete_me = 1
/obj/effect/landmark/costume/nyangirl/New()
new /obj/item/clothing/under/schoolgirl(src.loc)
new /obj/item/clothing/head/kitty(src.loc)
delete_me = 1
/obj/effect/landmark/costume/maid/New()
new /obj/item/clothing/under/skirt(src.loc)
var/CHOICE = pick( /obj/item/clothing/head/beret , /obj/item/clothing/head/rabbitears )
new CHOICE(src.loc)
new /obj/item/clothing/glasses/sunglasses/blindfold(src.loc)
delete_me = 1
/obj/effect/landmark/costume/butler/New()
new /obj/item/clothing/accessory/wcoat(src.loc)
new /obj/item/clothing/under/suit_jacket(src.loc)
new /obj/item/clothing/head/that(src.loc)
delete_me = 1
/obj/effect/landmark/costume/scratch/New()
new /obj/item/clothing/gloves/white(src.loc)
new /obj/item/clothing/shoes/white(src.loc)
new /obj/item/clothing/under/scratch(src.loc)
if (prob(30))
new /obj/item/clothing/head/cueball(src.loc)
delete_me = 1
/obj/effect/landmark/costume/highlander/New()
new /obj/item/clothing/under/kilt(src.loc)
new /obj/item/clothing/head/beret(src.loc)
delete_me = 1
/obj/effect/landmark/costume/prig/New()
new /obj/item/clothing/accessory/wcoat(src.loc)
new /obj/item/clothing/glasses/monocle(src.loc)
var/CHOICE= pick( /obj/item/clothing/head/bowler, /obj/item/clothing/head/that)
new CHOICE(src.loc)
new /obj/item/clothing/shoes/black(src.loc)
new /obj/item/weapon/cane(src.loc)
new /obj/item/clothing/under/sl_suit(src.loc)
new /obj/item/clothing/mask/fakemoustache(src.loc)
delete_me = 1
/obj/effect/landmark/costume/plaguedoctor/New()
new /obj/item/clothing/suit/bio_suit/plaguedoctorsuit(src.loc)
new /obj/item/clothing/head/plaguedoctorhat(src.loc)
delete_me = 1
/obj/effect/landmark/costume/nightowl/New()
new /obj/item/clothing/under/owl(src.loc)
new /obj/item/clothing/mask/gas/owl_mask(src.loc)
delete_me = 1
/obj/effect/landmark/costume/waiter/New()
new /obj/item/clothing/under/waiter(src.loc)
var/CHOICE= pick( /obj/item/clothing/head/kitty, /obj/item/clothing/head/rabbitears)
new CHOICE(src.loc)
new /obj/item/clothing/suit/storage/apron(src.loc)
delete_me = 1
/obj/effect/landmark/costume/pirate/New()
new /obj/item/clothing/under/pirate(src.loc)
new /obj/item/clothing/suit/pirate(src.loc)
var/CHOICE = pick( /obj/item/clothing/head/pirate , /obj/item/clothing/head/bandana )
new CHOICE(src.loc)
new /obj/item/clothing/glasses/eyepatch(src.loc)
delete_me = 1
/obj/effect/landmark/costume/commie/New()
new /obj/item/clothing/under/soviet(src.loc)
new /obj/item/clothing/head/ushanka(src.loc)
delete_me = 1
/obj/effect/landmark/costume/imperium_monk/New()
new /obj/item/clothing/suit/imperium_monk(src.loc)
if (prob(25))
new /obj/item/clothing/mask/gas/cyborg(src.loc)
delete_me = 1
/obj/effect/landmark/costume/holiday_priest/New()
new /obj/item/clothing/suit/holidaypriest(src.loc)
qdel(src)
/obj/effect/landmark/costume/marisawizard/fake/New()
new /obj/item/clothing/head/wizard/marisa/fake(src.loc)
new/obj/item/clothing/suit/wizrobe/marisa/fake(src.loc)
delete_me = 1
/obj/effect/landmark/costume/cutewitch/New()
new /obj/item/clothing/under/sundress(src.loc)
new /obj/item/clothing/head/witchwig(src.loc)
new /obj/item/weapon/staff/broom(src.loc)
delete_me = 1
/obj/effect/landmark/costume/fakewizard/New()
new /obj/item/clothing/suit/wizrobe/fake(src.loc)
new /obj/item/clothing/head/wizard/fake(src.loc)
new /obj/item/weapon/staff/(src.loc)
delete_me = 1
/obj/effect/landmark/costume/sexyclown/New()
new /obj/item/clothing/mask/gas/sexyclown(src.loc)
new /obj/item/clothing/under/sexyclown(src.loc)
delete_me = 1
/obj/effect/landmark/costume/sexymime/New()
new /obj/item/clothing/mask/gas/sexymime(src.loc)
new /obj/item/clothing/under/sexymime(src.loc)
delete_me = 1
/obj/effect/landmark
name = "landmark"
icon = 'icons/mob/screen1.dmi'
icon_state = "x2"
anchored = TRUE
unacidable = TRUE
simulated = FALSE
invisibility = 100
var/delete_me = 0
/obj/effect/landmark/New()
..()
tag = text("landmark*[]", name)
invisibility = 101
switch(name) //some of these are probably obsolete
if("monkey")
monkeystart += loc
delete_me = 1
return
if("start")
newplayer_start += loc
delete_me = 1
return
if("JoinLate") // Bit difference, since we need the spawn point to move.
latejoin += src
simulated = TRUE
// delete_me = 1
return
if("JoinLateGateway")
latejoin_gateway += loc
latejoin += src //VOREStation Addition
delete_me = 1
return
if("JoinLateElevator")
latejoin_elevator += loc
delete_me = 1
return
if("JoinLateCryo")
latejoin_cryo += loc
delete_me = 1
return
if("JoinLateCyborg")
latejoin_cyborg += loc
delete_me = 1
return
if("prisonwarp")
prisonwarp += loc
delete_me = 1
return
if("Holding Facility")
holdingfacility += loc
if("tdome1")
tdome1 += loc
if("tdome2")
tdome2 += loc
if("tdomeadmin")
tdomeadmin += loc
if("tdomeobserve")
tdomeobserve += loc
if("prisonsecuritywarp")
prisonsecuritywarp += loc
delete_me = 1
return
if("blobstart")
blobstart += loc
delete_me = 1
return
if("xeno_spawn")
xeno_spawn += loc
delete_me = 1
return
if("endgame_exit")
endgame_safespawns += loc
delete_me = 1
return
if("bluespacerift")
endgame_exits += loc
delete_me = 1
return
//VOREStation Add Start
if("vinestart")
vinestart += loc
delete_me = 1
return
//VORE Station Add End
landmarks_list += src
return 1
/obj/effect/landmark/proc/delete()
delete_me = 1
/obj/effect/landmark/Initialize()
. = ..()
if(delete_me)
return INITIALIZE_HINT_QDEL
/obj/effect/landmark/Destroy(var/force = FALSE)
if(delete_me || force)
landmarks_list -= src
return ..()
return QDEL_HINT_LETMELIVE
/obj/effect/landmark/start
name = "start"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
anchored = TRUE
/obj/effect/landmark/start/New()
..()
tag = "start*[name]"
invisibility = 101
return 1
/obj/effect/landmark/forbidden_level
delete_me = 1
/obj/effect/landmark/forbidden_level/Initialize()
. = ..()
if(using_map)
using_map.secret_levels |= z
else
log_error("[type] mapped in but no using_map")
/obj/effect/landmark/hidden_level
delete_me = 1
/obj/effect/landmark/hidden_level/Initialize()
. = ..()
if(using_map)
using_map.hidden_levels |= z
else
log_error("[type] mapped in but no using_map")
/obj/effect/landmark/virtual_reality
name = "virtual_reality"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
anchored = TRUE
/obj/effect/landmark/virtual_reality/New()
..()
tag = "virtual_reality*[name]"
invisibility = 101
return 1
//Costume spawner landmarks
/obj/effect/landmark/costume/New() //costume spawner, selects a random subclass and disappears
var/list/options = typesof(/obj/effect/landmark/costume)
var/PICK= options[rand(1,options.len)]
new PICK(src.loc)
delete_me = 1
//SUBCLASSES. Spawn a bunch of items and disappear likewise
/obj/effect/landmark/costume/chicken/New()
new /obj/item/clothing/suit/chickensuit(src.loc)
new /obj/item/clothing/head/chicken(src.loc)
new /obj/item/weapon/reagent_containers/food/snacks/egg(src.loc)
delete_me = 1
/obj/effect/landmark/costume/gladiator/New()
new /obj/item/clothing/under/gladiator(src.loc)
new /obj/item/clothing/head/helmet/gladiator(src.loc)
qdel(src)
/obj/effect/landmark/costume/madscientist/New()
new /obj/item/clothing/under/suit_jacket/green(src.loc)
new /obj/item/clothing/head/flatcap(src.loc)
new /obj/item/clothing/suit/storage/toggle/labcoat/mad(src.loc)
new /obj/item/clothing/glasses/gglasses(src.loc)
delete_me = 1
/obj/effect/landmark/costume/elpresidente/New()
new /obj/item/clothing/under/suit_jacket/green(src.loc)
new /obj/item/clothing/head/flatcap(src.loc)
new /obj/item/clothing/mask/smokable/cigarette/cigar/havana(src.loc)
new /obj/item/clothing/shoes/boots/jackboots(src.loc)
delete_me = 1
/obj/effect/landmark/costume/nyangirl/New()
new /obj/item/clothing/under/schoolgirl(src.loc)
new /obj/item/clothing/head/kitty(src.loc)
delete_me = 1
/obj/effect/landmark/costume/maid/New()
new /obj/item/clothing/under/skirt(src.loc)
var/CHOICE = pick( /obj/item/clothing/head/beret , /obj/item/clothing/head/rabbitears )
new CHOICE(src.loc)
new /obj/item/clothing/glasses/sunglasses/blindfold(src.loc)
delete_me = 1
/obj/effect/landmark/costume/butler/New()
new /obj/item/clothing/accessory/wcoat(src.loc)
new /obj/item/clothing/under/suit_jacket(src.loc)
new /obj/item/clothing/head/that(src.loc)
delete_me = 1
/obj/effect/landmark/costume/scratch/New()
new /obj/item/clothing/gloves/white(src.loc)
new /obj/item/clothing/shoes/white(src.loc)
new /obj/item/clothing/under/scratch(src.loc)
if (prob(30))
new /obj/item/clothing/head/cueball(src.loc)
delete_me = 1
/obj/effect/landmark/costume/highlander/New()
new /obj/item/clothing/under/kilt(src.loc)
new /obj/item/clothing/head/beret(src.loc)
delete_me = 1
/obj/effect/landmark/costume/prig/New()
new /obj/item/clothing/accessory/wcoat(src.loc)
new /obj/item/clothing/glasses/monocle(src.loc)
var/CHOICE= pick( /obj/item/clothing/head/bowler, /obj/item/clothing/head/that)
new CHOICE(src.loc)
new /obj/item/clothing/shoes/black(src.loc)
new /obj/item/weapon/cane(src.loc)
new /obj/item/clothing/under/sl_suit(src.loc)
new /obj/item/clothing/mask/fakemoustache(src.loc)
delete_me = 1
/obj/effect/landmark/costume/plaguedoctor/New()
new /obj/item/clothing/suit/bio_suit/plaguedoctorsuit(src.loc)
new /obj/item/clothing/head/plaguedoctorhat(src.loc)
delete_me = 1
/obj/effect/landmark/costume/nightowl/New()
new /obj/item/clothing/under/owl(src.loc)
new /obj/item/clothing/mask/gas/owl_mask(src.loc)
delete_me = 1
/obj/effect/landmark/costume/waiter/New()
new /obj/item/clothing/under/waiter(src.loc)
var/CHOICE= pick( /obj/item/clothing/head/kitty, /obj/item/clothing/head/rabbitears)
new CHOICE(src.loc)
new /obj/item/clothing/suit/storage/apron(src.loc)
delete_me = 1
/obj/effect/landmark/costume/pirate/New()
new /obj/item/clothing/under/pirate(src.loc)
new /obj/item/clothing/suit/pirate(src.loc)
var/CHOICE = pick( /obj/item/clothing/head/pirate , /obj/item/clothing/head/bandana )
new CHOICE(src.loc)
new /obj/item/clothing/glasses/eyepatch(src.loc)
delete_me = 1
/obj/effect/landmark/costume/commie/New()
new /obj/item/clothing/under/soviet(src.loc)
new /obj/item/clothing/head/ushanka(src.loc)
delete_me = 1
/obj/effect/landmark/costume/imperium_monk/New()
new /obj/item/clothing/suit/imperium_monk(src.loc)
if (prob(25))
new /obj/item/clothing/mask/gas/cyborg(src.loc)
delete_me = 1
/obj/effect/landmark/costume/holiday_priest/New()
new /obj/item/clothing/suit/holidaypriest(src.loc)
qdel(src)
/obj/effect/landmark/costume/marisawizard/fake/New()
new /obj/item/clothing/head/wizard/marisa/fake(src.loc)
new/obj/item/clothing/suit/wizrobe/marisa/fake(src.loc)
delete_me = 1
/obj/effect/landmark/costume/cutewitch/New()
new /obj/item/clothing/under/sundress(src.loc)
new /obj/item/clothing/head/witchwig(src.loc)
new /obj/item/weapon/staff/broom(src.loc)
delete_me = 1
/obj/effect/landmark/costume/fakewizard/New()
new /obj/item/clothing/suit/wizrobe/fake(src.loc)
new /obj/item/clothing/head/wizard/fake(src.loc)
new /obj/item/weapon/staff/(src.loc)
delete_me = 1
/obj/effect/landmark/costume/sexyclown/New()
new /obj/item/clothing/mask/gas/sexyclown(src.loc)
new /obj/item/clothing/under/sexyclown(src.loc)
delete_me = 1
/obj/effect/landmark/costume/sexymime/New()
new /obj/item/clothing/mask/gas/sexymime(src.loc)
new /obj/item/clothing/under/sexymime(src.loc)
delete_me = 1
+20 -20
View File
@@ -1,21 +1,21 @@
/obj/effect/manifest
name = "manifest"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
unacidable = TRUE//Just to be sure.
/obj/effect/manifest/New()
src.invisibility = 101
return
/obj/effect/manifest/proc/manifest()
var/dat = "<B>Crew Manifest</B>:<BR>"
for(var/mob/living/carbon/human/M in mob_list)
dat += text(" <B>[]</B> - []<BR>", M.name, M.get_assignment())
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( src.loc )
P.info = dat
P.name = "paper- 'Crew Manifest'"
//SN src = null
qdel(src)
/obj/effect/manifest
name = "manifest"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
unacidable = TRUE//Just to be sure.
/obj/effect/manifest/New()
src.invisibility = 101
return
/obj/effect/manifest/proc/manifest()
var/dat = "<B>Crew Manifest</B>:<BR>"
for(var/mob/living/carbon/human/M in mob_list)
dat += text(" <B>[]</B> - []<BR>", M.name, M.get_assignment())
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( src.loc )
P.info = dat
P.name = "paper- 'Crew Manifest'"
//SN src = null
qdel(src)
return
@@ -1,191 +1,191 @@
GLOBAL_LIST_EMPTY(all_beam_points)
// Creates and manages a beam attached to itself and another beam_point.
// You can do cool things with these such as moving the beam_point to move the beam, turning them on and off on a timer, triggered by external input, and more.
/obj/effect/map_effect/beam_point
name = "beam point"
icon_state = "beam_point"
// General variables.
var/list/my_beams = list() // Instances of beams. Deleting one will kill the beam.
var/id = "A" // Two beam_points must share the same ID to be connected to each other.
var/max_beams = 10 // How many concurrent beams to seperate beam_points to have at once. Set to zero to only act as targets for other beam_points.
var/seek_range = 7 // How far to look for an end beam_point when not having a beam. Defaults to screen height/width. Make sure this is below beam_max_distance.
// Controls how and when the beam is created.
var/make_beams_on_init = FALSE
var/use_timer = FALSE // Sadly not the /tg/ timers.
var/list/on_duration = list(2 SECONDS, 2 SECONDS, 2 SECONDS) // How long the beam should stay on for, if use_timer is true. Alternates between each duration in the list.
var/list/off_duration = list(3 SECONDS, 0.5 SECOND, 0.5 SECOND) // How long it should stay off for. List length is not needed to be the same as on_duration.
var/timer_on_index = 1 // Index to use for on_duration list.
var/timer_off_index = 1// Ditto, for off_duration list.
var/initial_delay = 0 // How long to wait before first turning on the beam, to sync beam times or create a specific pattern.
var/beam_creation_sound = null // Optional sound played when one or more beams are created.
var/beam_destruction_sound = null // Optional sound played when a beam is destroyed.
// Beam datum arguments.
var/beam_icon = 'icons/effects/beam.dmi' // Icon file to use for beam visuals.
var/beam_icon_state = "b_beam" // Icon state to use for visuals.
var/beam_time = INFINITY // How long the beam lasts. By default it will last forever until destroyed.
var/beam_max_distance = 10 // If the beam is farther than this, it will be destroyed. Make sure it's higher than seek_range.
var/beam_type = /obj/effect/ebeam // The type of beam. Default has no special properties. Some others may do things like hurt things touching it.
var/beam_sleep_time = 3 // How often the beam updates visually. Suggested to leave this alone, 3 is already fast.
/obj/effect/map_effect/beam_point/Initialize()
GLOB.all_beam_points += src
if(make_beams_on_init)
create_beams()
if(use_timer)
addtimer(CALLBACK(src, PROC_REF(handle_beam_timer)), initial_delay)
return ..()
/obj/effect/map_effect/beam_point/Destroy()
destroy_all_beams()
use_timer = FALSE
GLOB.all_beam_points -= src
return ..()
// This is the top level proc to make the magic happen.
/obj/effect/map_effect/beam_point/proc/create_beams()
if(my_beams.len >= max_beams)
return
var/beams_to_fill = max_beams - my_beams.len
for(var/i = 1 to beams_to_fill)
var/obj/effect/map_effect/beam_point/point = seek_beam_point()
if(!point)
break // No more points could be found, no point checking repeatively.
build_beam(point)
// Finds a suitable beam point.
/obj/effect/map_effect/beam_point/proc/seek_beam_point()
for(var/obj/effect/map_effect/beam_point/point in GLOB.all_beam_points)
if(id != point.id)
continue // Not linked together by ID.
if(has_active_beam(point))
continue // Already got one.
if(point.z != src.z)
continue // Not on same z-level. get_dist() ignores z-levels by design according to docs.
if(get_dist(src, point) > seek_range)
continue // Too far.
return point
// Checks if the two points have an active beam between them.
// Used to make sure two points don't have more than one beam.
/obj/effect/map_effect/beam_point/proc/has_active_beam(var/obj/effect/map_effect/beam_point/them)
// First, check our beams.
for(var/datum/beam/B in my_beams)
if(B.target == them)
return TRUE
if(B.origin == them) // This shouldn't be needed unless the beam gets built backwards but why not.
return TRUE
// Now check theirs, to see if they have a beam on us.
for(var/datum/beam/B in them.my_beams)
if(B.target == src)
return TRUE
if(B.origin == src) // Same story as above.
return TRUE
return FALSE
/obj/effect/map_effect/beam_point/proc/build_beam(var/atom/beam_target)
if(!beam_target)
log_debug("[src] ([src.type] \[[x],[y],[z]\]) failed to build its beam due to not having a target.")
return FALSE
var/datum/beam/new_beam = Beam(beam_target, beam_icon_state, beam_icon, beam_time, beam_max_distance, beam_type, beam_sleep_time)
my_beams += new_beam
if(beam_creation_sound)
playsound(src, beam_creation_sound, 70, 1)
return TRUE
/obj/effect/map_effect/beam_point/proc/destroy_beam(var/datum/beam/B)
if(!B)
log_debug("[src] ([src.type] \[[x],[y],[z]\]) was asked to destroy a beam that does not exist.")
return FALSE
if(!(B in my_beams))
log_debug("[src] ([src.type] \[[x],[y],[z]\]) was asked to destroy a beam it did not own.")
return FALSE
my_beams -= B
qdel(B)
if(beam_destruction_sound)
playsound(src, beam_destruction_sound, 70, 1)
return TRUE
/obj/effect/map_effect/beam_point/proc/destroy_all_beams()
for(var/datum/beam/B in my_beams)
destroy_beam(B)
return TRUE
// This code makes me sad.
/obj/effect/map_effect/beam_point/proc/handle_beam_timer()
if(!use_timer || QDELETED(src))
return
if(my_beams.len) // Currently on.
destroy_all_beams()
color = "#FF0000"
timer_off_index++
if(timer_off_index > off_duration.len)
timer_off_index = 1
spawn(off_duration[timer_off_index])
.()
else // Currently off.
// If nobody's around, keep the beams off to avoid wasteful beam process(), if they have one.
if(!always_run && !check_for_player_proximity(src, proximity_needed, ignore_ghosts, ignore_afk))
spawn(retry_delay)
.()
return
create_beams()
color = "#00FF00"
timer_on_index++
if(timer_on_index > on_duration.len)
timer_on_index = 1
spawn(on_duration[timer_on_index])
.()
// Subtypes to use in maps and adminbuse.
// Remember, beam_points ONLY connect to other beam_points with the same id variable.
// Creates the beam when instantiated and stays on until told otherwise.
/obj/effect/map_effect/beam_point/instant
make_beams_on_init = TRUE
/obj/effect/map_effect/beam_point/instant/electric
beam_icon_state = "nzcrentrs_power"
beam_type = /obj/effect/ebeam/reactive/electric
beam_creation_sound = 'sound/effects/lightningshock.ogg'
beam_destruction_sound = "sparks"
// Turns on and off on a timer.
/obj/effect/map_effect/beam_point/timer
use_timer = TRUE
// Shocks people who touch the beam while it's on. Flicks on and off on a specific pattern.
/obj/effect/map_effect/beam_point/timer/electric
beam_icon_state = "nzcrentrs_power"
beam_type = /obj/effect/ebeam/reactive/electric
beam_creation_sound = 'sound/effects/lightningshock.ogg'
beam_destruction_sound = "sparks"
seek_range = 3
// Is only a target for other beams to connect to.
/obj/effect/map_effect/beam_point/end
max_beams = 0
// Can only have one beam.
/obj/effect/map_effect/beam_point/mono
make_beams_on_init = TRUE
max_beams = 1
GLOBAL_LIST_EMPTY(all_beam_points)
// Creates and manages a beam attached to itself and another beam_point.
// You can do cool things with these such as moving the beam_point to move the beam, turning them on and off on a timer, triggered by external input, and more.
/obj/effect/map_effect/beam_point
name = "beam point"
icon_state = "beam_point"
// General variables.
var/list/my_beams = list() // Instances of beams. Deleting one will kill the beam.
var/id = "A" // Two beam_points must share the same ID to be connected to each other.
var/max_beams = 10 // How many concurrent beams to seperate beam_points to have at once. Set to zero to only act as targets for other beam_points.
var/seek_range = 7 // How far to look for an end beam_point when not having a beam. Defaults to screen height/width. Make sure this is below beam_max_distance.
// Controls how and when the beam is created.
var/make_beams_on_init = FALSE
var/use_timer = FALSE // Sadly not the /tg/ timers.
var/list/on_duration = list(2 SECONDS, 2 SECONDS, 2 SECONDS) // How long the beam should stay on for, if use_timer is true. Alternates between each duration in the list.
var/list/off_duration = list(3 SECONDS, 0.5 SECOND, 0.5 SECOND) // How long it should stay off for. List length is not needed to be the same as on_duration.
var/timer_on_index = 1 // Index to use for on_duration list.
var/timer_off_index = 1// Ditto, for off_duration list.
var/initial_delay = 0 // How long to wait before first turning on the beam, to sync beam times or create a specific pattern.
var/beam_creation_sound = null // Optional sound played when one or more beams are created.
var/beam_destruction_sound = null // Optional sound played when a beam is destroyed.
// Beam datum arguments.
var/beam_icon = 'icons/effects/beam.dmi' // Icon file to use for beam visuals.
var/beam_icon_state = "b_beam" // Icon state to use for visuals.
var/beam_time = INFINITY // How long the beam lasts. By default it will last forever until destroyed.
var/beam_max_distance = 10 // If the beam is farther than this, it will be destroyed. Make sure it's higher than seek_range.
var/beam_type = /obj/effect/ebeam // The type of beam. Default has no special properties. Some others may do things like hurt things touching it.
var/beam_sleep_time = 3 // How often the beam updates visually. Suggested to leave this alone, 3 is already fast.
/obj/effect/map_effect/beam_point/Initialize()
GLOB.all_beam_points += src
if(make_beams_on_init)
create_beams()
if(use_timer)
addtimer(CALLBACK(src, PROC_REF(handle_beam_timer)), initial_delay)
return ..()
/obj/effect/map_effect/beam_point/Destroy()
destroy_all_beams()
use_timer = FALSE
GLOB.all_beam_points -= src
return ..()
// This is the top level proc to make the magic happen.
/obj/effect/map_effect/beam_point/proc/create_beams()
if(my_beams.len >= max_beams)
return
var/beams_to_fill = max_beams - my_beams.len
for(var/i = 1 to beams_to_fill)
var/obj/effect/map_effect/beam_point/point = seek_beam_point()
if(!point)
break // No more points could be found, no point checking repeatively.
build_beam(point)
// Finds a suitable beam point.
/obj/effect/map_effect/beam_point/proc/seek_beam_point()
for(var/obj/effect/map_effect/beam_point/point in GLOB.all_beam_points)
if(id != point.id)
continue // Not linked together by ID.
if(has_active_beam(point))
continue // Already got one.
if(point.z != src.z)
continue // Not on same z-level. get_dist() ignores z-levels by design according to docs.
if(get_dist(src, point) > seek_range)
continue // Too far.
return point
// Checks if the two points have an active beam between them.
// Used to make sure two points don't have more than one beam.
/obj/effect/map_effect/beam_point/proc/has_active_beam(var/obj/effect/map_effect/beam_point/them)
// First, check our beams.
for(var/datum/beam/B in my_beams)
if(B.target == them)
return TRUE
if(B.origin == them) // This shouldn't be needed unless the beam gets built backwards but why not.
return TRUE
// Now check theirs, to see if they have a beam on us.
for(var/datum/beam/B in them.my_beams)
if(B.target == src)
return TRUE
if(B.origin == src) // Same story as above.
return TRUE
return FALSE
/obj/effect/map_effect/beam_point/proc/build_beam(var/atom/beam_target)
if(!beam_target)
log_debug("[src] ([src.type] \[[x],[y],[z]\]) failed to build its beam due to not having a target.")
return FALSE
var/datum/beam/new_beam = Beam(beam_target, beam_icon_state, beam_icon, beam_time, beam_max_distance, beam_type, beam_sleep_time)
my_beams += new_beam
if(beam_creation_sound)
playsound(src, beam_creation_sound, 70, 1)
return TRUE
/obj/effect/map_effect/beam_point/proc/destroy_beam(var/datum/beam/B)
if(!B)
log_debug("[src] ([src.type] \[[x],[y],[z]\]) was asked to destroy a beam that does not exist.")
return FALSE
if(!(B in my_beams))
log_debug("[src] ([src.type] \[[x],[y],[z]\]) was asked to destroy a beam it did not own.")
return FALSE
my_beams -= B
qdel(B)
if(beam_destruction_sound)
playsound(src, beam_destruction_sound, 70, 1)
return TRUE
/obj/effect/map_effect/beam_point/proc/destroy_all_beams()
for(var/datum/beam/B in my_beams)
destroy_beam(B)
return TRUE
// This code makes me sad.
/obj/effect/map_effect/beam_point/proc/handle_beam_timer()
if(!use_timer || QDELETED(src))
return
if(my_beams.len) // Currently on.
destroy_all_beams()
color = "#FF0000"
timer_off_index++
if(timer_off_index > off_duration.len)
timer_off_index = 1
spawn(off_duration[timer_off_index])
.()
else // Currently off.
// If nobody's around, keep the beams off to avoid wasteful beam process(), if they have one.
if(!always_run && !check_for_player_proximity(src, proximity_needed, ignore_ghosts, ignore_afk))
spawn(retry_delay)
.()
return
create_beams()
color = "#00FF00"
timer_on_index++
if(timer_on_index > on_duration.len)
timer_on_index = 1
spawn(on_duration[timer_on_index])
.()
// Subtypes to use in maps and adminbuse.
// Remember, beam_points ONLY connect to other beam_points with the same id variable.
// Creates the beam when instantiated and stays on until told otherwise.
/obj/effect/map_effect/beam_point/instant
make_beams_on_init = TRUE
/obj/effect/map_effect/beam_point/instant/electric
beam_icon_state = "nzcrentrs_power"
beam_type = /obj/effect/ebeam/reactive/electric
beam_creation_sound = 'sound/effects/lightningshock.ogg'
beam_destruction_sound = "sparks"
// Turns on and off on a timer.
/obj/effect/map_effect/beam_point/timer
use_timer = TRUE
// Shocks people who touch the beam while it's on. Flicks on and off on a specific pattern.
/obj/effect/map_effect/beam_point/timer/electric
beam_icon_state = "nzcrentrs_power"
beam_type = /obj/effect/ebeam/reactive/electric
beam_creation_sound = 'sound/effects/lightningshock.ogg'
beam_destruction_sound = "sparks"
seek_range = 3
// Is only a target for other beams to connect to.
/obj/effect/map_effect/beam_point/end
max_beams = 0
// Can only have one beam.
/obj/effect/map_effect/beam_point/mono
make_beams_on_init = TRUE
max_beams = 1
@@ -1,69 +1,69 @@
// These are objects you can use inside special maps (like PoIs), or for adminbuse.
// Players cannot see or interact with these.
/obj/effect/map_effect
anchored = TRUE
invisibility = 99 // So a badmin can go view these by changing their see_invisible.
icon = 'icons/effects/map_effects.dmi'
// Below vars concern check_for_player_proximity() and is used to not waste effort if nobody is around to appreciate the effects.
var/always_run = FALSE // If true, the game will not try to suppress this from firing if nobody is around to see it.
var/proximity_needed = 12 // How many tiles a mob with a client must be for this to run.
var/ignore_ghosts = FALSE // If true, ghosts won't satisfy the above requirement.
var/ignore_afk = TRUE // If true, AFK people (5 minutes) won't satisfy it as well.
var/retry_delay = 5 SECONDS // How long until we check for players again.
var/next_attempt = 0 // Next time we're going to do ACTUAL WORK
/obj/effect/map_effect/ex_act()
return
/obj/effect/map_effect/singularity_pull()
return
/obj/effect/map_effect/singularity_act()
return
// Base type for effects that run on variable intervals.
/obj/effect/map_effect/interval
var/interval_lower_bound = 5 SECONDS // Lower number for how often the map_effect will trigger.
var/interval_upper_bound = 5 SECONDS // Higher number for above.
/obj/effect/map_effect/interval/Initialize()
. = ..()
START_PROCESSING(SSobj, src)
/obj/effect/map_effect/interval/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
// Override this for the specific thing to do.
/obj/effect/map_effect/interval/proc/trigger()
return
// Handles the delay and making sure it doesn't run when it would be bad.
/obj/effect/map_effect/interval/process()
//Not yet!
if(world.time < next_attempt)
return
// Check to see if we're useful first.
if(!always_run && !check_for_player_proximity(src, proximity_needed, ignore_ghosts, ignore_afk))
next_attempt = world.time + retry_delay
// Hey there's someone nearby.
else
next_attempt = world.time + rand(interval_lower_bound, interval_upper_bound)
trigger()
// Helper proc to optimize the use of effects by making sure they do not run if nobody is around to perceive it.
/proc/check_for_player_proximity(var/atom/proximity_to, var/radius = 12, var/ignore_ghosts = FALSE, var/ignore_afk = TRUE)
if(!proximity_to)
return FALSE
for(var/thing in player_list)
var/mob/M = thing // Avoiding typechecks for more speed, player_list will only contain mobs anyways.
if(ignore_ghosts && isobserver(M))
continue
if(ignore_afk && M.client && M.client.is_afk(5 MINUTES))
continue
if(M.z == proximity_to.z && get_dist(M, proximity_to) <= radius)
return TRUE
return FALSE
// These are objects you can use inside special maps (like PoIs), or for adminbuse.
// Players cannot see or interact with these.
/obj/effect/map_effect
anchored = TRUE
invisibility = 99 // So a badmin can go view these by changing their see_invisible.
icon = 'icons/effects/map_effects.dmi'
// Below vars concern check_for_player_proximity() and is used to not waste effort if nobody is around to appreciate the effects.
var/always_run = FALSE // If true, the game will not try to suppress this from firing if nobody is around to see it.
var/proximity_needed = 12 // How many tiles a mob with a client must be for this to run.
var/ignore_ghosts = FALSE // If true, ghosts won't satisfy the above requirement.
var/ignore_afk = TRUE // If true, AFK people (5 minutes) won't satisfy it as well.
var/retry_delay = 5 SECONDS // How long until we check for players again.
var/next_attempt = 0 // Next time we're going to do ACTUAL WORK
/obj/effect/map_effect/ex_act()
return
/obj/effect/map_effect/singularity_pull()
return
/obj/effect/map_effect/singularity_act()
return
// Base type for effects that run on variable intervals.
/obj/effect/map_effect/interval
var/interval_lower_bound = 5 SECONDS // Lower number for how often the map_effect will trigger.
var/interval_upper_bound = 5 SECONDS // Higher number for above.
/obj/effect/map_effect/interval/Initialize()
. = ..()
START_PROCESSING(SSobj, src)
/obj/effect/map_effect/interval/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
// Override this for the specific thing to do.
/obj/effect/map_effect/interval/proc/trigger()
return
// Handles the delay and making sure it doesn't run when it would be bad.
/obj/effect/map_effect/interval/process()
//Not yet!
if(world.time < next_attempt)
return
// Check to see if we're useful first.
if(!always_run && !check_for_player_proximity(src, proximity_needed, ignore_ghosts, ignore_afk))
next_attempt = world.time + retry_delay
// Hey there's someone nearby.
else
next_attempt = world.time + rand(interval_lower_bound, interval_upper_bound)
trigger()
// Helper proc to optimize the use of effects by making sure they do not run if nobody is around to perceive it.
/proc/check_for_player_proximity(var/atom/proximity_to, var/radius = 12, var/ignore_ghosts = FALSE, var/ignore_afk = TRUE)
if(!proximity_to)
return FALSE
for(var/thing in player_list)
var/mob/M = thing // Avoiding typechecks for more speed, player_list will only contain mobs anyways.
if(ignore_ghosts && isobserver(M))
continue
if(ignore_afk && M.client && M.client.is_afk(5 MINUTES))
continue
if(M.z == proximity_to.z && get_dist(M, proximity_to) <= radius)
return TRUE
return FALSE
@@ -1,39 +1,39 @@
// Emits light forever with magic. Useful for mood lighting in Points of Interest.
// Be sure to check how it looks ingame, and fiddle with the settings until it looks right.
/obj/effect/map_effect/perma_light
name = "permanent light"
icon_state = "permalight"
light_range = 3
light_power = 1
light_color = "#FFFFFF"
light_on = TRUE
/obj/effect/map_effect/perma_light/brighter
name = "permanent light (bright)"
icon_state = "permalight"
light_range = 5
light_power = 3
light_color = "#FFFFFF"
/obj/effect/map_effect/perma_light/concentrated
name = "permanent light (concentrated)"
light_range = 2
light_power = 5
/obj/effect/map_effect/perma_light/concentrated/incandescent
name = "permanent light (concentrated incandescent)"
light_color = LIGHT_COLOR_INCANDESCENT_TUBE
// VOREStation Addition Start
/obj/effect/map_effect/perma_light/gateway
name = "permanent light (gateway)"
icon_state = "permalight"
light_range = 10
light_power = 5
light_color = "#b6cdff"
// Emits light forever with magic. Useful for mood lighting in Points of Interest.
// Be sure to check how it looks ingame, and fiddle with the settings until it looks right.
/obj/effect/map_effect/perma_light
name = "permanent light"
icon_state = "permalight"
light_range = 3
light_power = 1
light_color = "#FFFFFF"
light_on = TRUE
/obj/effect/map_effect/perma_light/brighter
name = "permanent light (bright)"
icon_state = "permalight"
light_range = 5
light_power = 3
light_color = "#FFFFFF"
/obj/effect/map_effect/perma_light/concentrated
name = "permanent light (concentrated)"
light_range = 2
light_power = 5
/obj/effect/map_effect/perma_light/concentrated/incandescent
name = "permanent light (concentrated incandescent)"
light_color = LIGHT_COLOR_INCANDESCENT_TUBE
// VOREStation Addition Start
/obj/effect/map_effect/perma_light/gateway
name = "permanent light (gateway)"
icon_state = "permalight"
light_range = 10
light_power = 5
light_color = "#b6cdff"
// VOREStation Addition End
@@ -1,19 +1,19 @@
// Constantly emites radiation from the tile it's placed on.
/obj/effect/map_effect/radiation_emitter
name = "radiation emitter"
icon_state = "radiation_emitter"
var/radiation_power = 30 // Bigger numbers means more radiation.
/obj/effect/map_effect/radiation_emitter/Initialize()
START_PROCESSING(SSobj, src)
return ..()
/obj/effect/map_effect/radiation_emitter/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/effect/map_effect/radiation_emitter/process()
SSradiation.radiate(src, radiation_power)
// Constantly emites radiation from the tile it's placed on.
/obj/effect/map_effect/radiation_emitter
name = "radiation emitter"
icon_state = "radiation_emitter"
var/radiation_power = 30 // Bigger numbers means more radiation.
/obj/effect/map_effect/radiation_emitter/Initialize()
START_PROCESSING(SSobj, src)
return ..()
/obj/effect/map_effect/radiation_emitter/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/effect/map_effect/radiation_emitter/process()
SSradiation.radiate(src, radiation_power)
/obj/effect/map_effect/radiation_emitter/strong
radiation_power = 100
@@ -1,17 +1,17 @@
// Makes the screen shake for nearby players every so often.
/obj/effect/map_effect/interval/screen_shaker
name = "screen shaker"
icon_state = "screen_shaker"
interval_lower_bound = 1 SECOND
interval_upper_bound = 2 SECONDS
var/shake_radius = 7 // How far the shaking effect extends to. By default it is one screen length.
var/shake_duration = 2 // How long the shaking lasts.
var/shake_strength = 1 // How much it shakes.
/obj/effect/map_effect/interval/screen_shaker/trigger()
for(var/mob/M as anything in player_list)
if(M.z == src.z && get_dist(src, M) <= shake_radius)
shake_camera(M, shake_duration, shake_strength)
// Makes the screen shake for nearby players every so often.
/obj/effect/map_effect/interval/screen_shaker
name = "screen shaker"
icon_state = "screen_shaker"
interval_lower_bound = 1 SECOND
interval_upper_bound = 2 SECONDS
var/shake_radius = 7 // How far the shaking effect extends to. By default it is one screen length.
var/shake_duration = 2 // How long the shaking lasts.
var/shake_strength = 1 // How much it shakes.
/obj/effect/map_effect/interval/screen_shaker/trigger()
for(var/mob/M as anything in player_list)
if(M.z == src.z && get_dist(src, M) <= shake_radius)
shake_camera(M, shake_duration, shake_strength)
..()
+404 -404
View File
@@ -1,404 +1,404 @@
/obj/effect/mine
name = "land mine" //The name and description are deliberately NOT modified, so you can't game the mines you find.
desc = "A small explosive land mine."
density = FALSE
anchored = TRUE
icon = 'icons/obj/weapons.dmi'
icon_state = "landmine"
var/triggered = 0
var/smoke_strength = 3
var/obj/item/weapon/mine/mineitemtype = /obj/item/weapon/mine
var/panel_open = FALSE
var/datum/wires/mines/wires = null
var/camo_net = FALSE // Will the mine 'cloak' on deployment?
// The trap item will be triggered in some manner when detonating. Default only checks for grenades.
var/obj/item/trap = null
/obj/effect/mine/Initialize()
icon_state = "landmine_armed"
wires = new(src)
. = ..()
if(ispath(trap))
trap = new trap(src)
register_dangerous_to_step()
if(camo_net)
alpha = 50
/obj/effect/mine/Destroy()
unregister_dangerous_to_step()
if(trap)
QDEL_NULL(trap)
qdel_null(wires)
return ..()
/obj/effect/mine/Moved(atom/oldloc)
. = ..()
if(.)
var/turf/old_turf = get_turf(oldloc)
var/turf/new_turf = get_turf(src)
if(old_turf != new_turf)
old_turf.unregister_dangerous_object(src)
new_turf.register_dangerous_object(src)
/obj/effect/mine/proc/explode(var/mob/living/M)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
triggered = 1
s.set_up(3, 1, src)
s.start()
if(trap)
trigger_trap(M)
visible_message("\The [src.name] flashes as it is triggered!")
else
explosion(loc, 0, 2, 3, 4) //land mines are dangerous, folks.
visible_message("\The [src.name] detonates!")
qdel(s)
qdel(src)
/obj/effect/mine/proc/trigger_trap(var/mob/living/victim)
if(istype(trap, /obj/item/weapon/grenade))
var/obj/item/weapon/grenade/G = trap
trap = null
G.forceMove(get_turf(src))
if(victim.ckey)
msg_admin_attack("[key_name_admin(victim)] stepped on \a [src.name], triggering [trap]")
G.activate()
if(istype(trap, /obj/item/device/transfer_valve))
var/obj/item/device/transfer_valve/TV = trap
trap = null
TV.forceMove(get_turf(src))
TV.toggle_valve()
/obj/effect/mine/bullet_act()
if(prob(50))
explode()
/obj/effect/mine/ex_act(severity)
if(severity <= 2 || prob(50))
explode()
..()
/obj/effect/mine/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
Bumped(AM)
/obj/effect/mine/Bumped(mob/M as mob|obj)
if(triggered)
return
if(istype(M, /obj/mecha))
explode(M)
if(istype(M, /mob/living/))
var/mob/living/mob = M
if(!mob.hovering || !mob.flying)
explode(M)
/obj/effect/mine/attackby(obj/item/W as obj, mob/living/user as mob)
if(W.has_tool_quality(TOOL_SCREWDRIVER))
panel_open = !panel_open
user.visible_message("<span class='warning'>[user] very carefully screws the mine's panel [panel_open ? "open" : "closed"].</span>",
"<span class='notice'>You very carefully screw the mine's panel [panel_open ? "open" : "closed"].</span>")
playsound(src, W.usesound, 50, 1)
// Panel open, stay uncloaked, or uncloak if already cloaked. If you don't cloak on place, ignore it and just be normal alpha.
alpha = camo_net ? (panel_open ? 255 : 50) : 255
else if((W.has_tool_quality(TOOL_WIRECUTTER) || istype(W, /obj/item/device/multitool)) && panel_open)
interact(user)
else
..()
/obj/effect/mine/interact(mob/living/user as mob)
if(!panel_open || istype(user, /mob/living/silicon/ai))
return
user.set_machine(src)
wires.Interact(user)
/obj/effect/mine/camo
camo_net = TRUE
/obj/effect/mine/dnascramble
mineitemtype = /obj/item/weapon/mine/dnascramble
/obj/effect/mine/dnascramble/explode(var/mob/living/M)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
triggered = 1
s.set_up(3, 1, src)
s.start()
if(istype(M))
M.radiation += 50
randmutb(M)
domutcheck(M,null)
visible_message("\The [src.name] flashes violently before disintegrating!")
spawn(0)
qdel(s)
qdel(src)
/obj/effect/mine/stun
mineitemtype = /obj/item/weapon/mine/stun
/obj/effect/mine/stun/explode(var/mob/living/M)
triggered = 1
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
s.set_up(3, 1, src)
s.start()
if(istype(M))
M.Stun(30)
visible_message("\The [src.name] flashes violently before disintegrating!")
spawn(0)
qdel(s)
qdel(src)
/obj/effect/mine/n2o
mineitemtype = /obj/item/weapon/mine/n2o
/obj/effect/mine/n2o/explode(var/mob/living/M)
triggered = 1
for (var/turf/simulated/floor/target in range(1,src))
if(!target.blocks_air)
target.assume_gas("nitrous_oxide", 30)
visible_message("\The [src.name] detonates!")
spawn(0)
qdel(src)
/obj/effect/mine/phoron
mineitemtype = /obj/item/weapon/mine/phoron
/obj/effect/mine/phoron/explode(var/mob/living/M)
triggered = 1
for (var/turf/simulated/floor/target in range(1,src))
if(!target.blocks_air)
target.assume_gas("phoron", 30)
target.hotspot_expose(1000, CELL_VOLUME)
visible_message("\The [src.name] detonates!")
spawn(0)
qdel(src)
/obj/effect/mine/kick
mineitemtype = /obj/item/weapon/mine/kick
/obj/effect/mine/kick/explode(var/mob/living/M)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
triggered = 1
s.set_up(3, 1, src)
s.start()
if(istype(M, /obj/mecha))
var/obj/mecha/E = M
M = E.occupant
if(istype(M))
qdel(M.client)
spawn(0)
qdel(s)
qdel(src)
/obj/effect/mine/frag
mineitemtype = /obj/item/weapon/mine/frag
var/fragment_types = list(/obj/item/projectile/bullet/pellet/fragment)
var/num_fragments = 20 //total number of fragments produced by the grenade
//The radius of the circle used to launch projectiles. Lower values mean less projectiles are used but if set too low gaps may appear in the spread pattern
var/spread_range = 7
/obj/effect/mine/frag/explode(var/mob/living/M)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
triggered = 1
s.set_up(3, 1, src)
s.start()
var/turf/O = get_turf(src)
if(!O)
return
src.fragmentate(O, 20, 7, list(/obj/item/projectile/bullet/pellet/fragment)) //only 20 weak fragments because you're stepping directly on it
visible_message("\The [src.name] detonates!")
spawn(0)
qdel(s)
qdel(src)
/obj/effect/mine/training //Name and Desc commented out so it's possible to trick people with the training mines
// name = "training mine"
// desc = "A mine with its payload removed, for EOD training and demonstrations."
mineitemtype = /obj/item/weapon/mine/training
/obj/effect/mine/training/explode(var/mob/living/M)
triggered = 1
visible_message("\The [src.name]'s light flashes rapidly as it 'explodes'.")
new src.mineitemtype(get_turf(src))
spawn(0)
qdel(src)
/obj/effect/mine/emp
mineitemtype = /obj/item/weapon/mine/emp
/obj/effect/mine/emp/explode(var/mob/living/M)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
s.set_up(3, 1, src)
s.start()
visible_message("\The [src.name] flashes violently before disintegrating!")
empulse(loc, 2, 4, 7, 10, 1) // As strong as an EMP grenade
spawn(0)
qdel(src)
/obj/effect/mine/emp/camo
camo_net = TRUE
/obj/effect/mine/incendiary
mineitemtype = /obj/item/weapon/mine/incendiary
/obj/effect/mine/incendiary/explode(var/mob/living/M)
triggered = 1
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
s.set_up(3, 1, src)
s.start()
if(istype(M))
M.adjust_fire_stacks(5)
M.fire_act()
visible_message("\The [src.name] bursts into flames!")
spawn(0)
qdel(src)
/obj/effect/mine/gadget
mineitemtype = /obj/item/weapon/mine/gadget
/obj/effect/mine/gadget/explode(var/mob/living/M)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
triggered = 1
s.set_up(3, 1, src)
s.start()
if(trap)
trigger_trap(M)
visible_message("\The [src.name] flashes as it is triggered!")
else
explosion(loc, 0, 0, 2, 2)
visible_message("\The [src.name] detonates!")
qdel(s)
qdel(src)
/////////////////////////////////////////////
// The held item version of the above mines
/////////////////////////////////////////////
/obj/item/weapon/mine
name = "mine"
desc = "A small explosive mine with 'HE' and a grenade symbol on the side."
icon = 'icons/obj/weapons.dmi'
icon_state = "uglymine"
var/countdown = 10
var/minetype = /obj/effect/mine //This MUST be an /obj/effect/mine type, or it'll runtime.
var/obj/item/trap = null
var/list/allowed_gadgets = null
/obj/item/weapon/mine/attack_self(mob/user as mob) // You do not want to move or throw a land mine while priming it... Explosives + Sudden Movement = Bad Times
add_fingerprint(user)
msg_admin_attack("[key_name_admin(user)] primed \a [src]")
user.visible_message("[user] starts priming \the [src.name].", "You start priming \the [src.name]. Hold still!")
if(do_after(user, 10 SECONDS))
playsound(src, 'sound/weapons/armbomb.ogg', 75, 1, -3)
prime(user)
else
visible_message("[user] triggers \the [src.name]!", "You accidentally trigger \the [src.name]!")
prime(user, TRUE)
return
/obj/item/weapon/mine/attackby(obj/item/W as obj, mob/living/user as mob)
if(W.has_tool_quality(TOOL_SCREWDRIVER) && trap)
to_chat(user, "<span class='notice'>You begin removing \the [trap].</span>")
if(do_after(user, 10 SECONDS))
to_chat(user, "<span class='notice'>You finish disconnecting the mine's trigger.</span>")
trap.forceMove(get_turf(src))
trap = null
return
if(LAZYLEN(allowed_gadgets) && !trap)
var/allowed = FALSE
for(var/path in allowed_gadgets)
if(istype(W, path))
allowed = TRUE
break
if(allowed)
user.drop_from_inventory(W)
W.forceMove(src)
trap = W
..()
/obj/item/weapon/mine/proc/prime(mob/user as mob, var/explode_now = FALSE)
visible_message("\The [src.name] beeps as the priming sequence completes.")
var/obj/effect/mine/R = new minetype(get_turf(src))
src.transfer_fingerprints_to(R)
R.add_fingerprint(user)
if(trap)
R.trap = trap
trap = null
R.trap.forceMove(R)
if(explode_now)
R.explode(user)
spawn(0)
qdel(src)
/obj/item/weapon/mine/dnascramble
name = "radiation mine"
desc = "A small explosive mine with a radiation symbol on the side."
minetype = /obj/effect/mine/dnascramble
/obj/item/weapon/mine/phoron
name = "incendiary mine"
desc = "A small explosive mine with a fire symbol on the side."
minetype = /obj/effect/mine/phoron
/obj/item/weapon/mine/kick
name = "kick mine"
desc = "Concentrated war crimes. Handle with care."
minetype = /obj/effect/mine/kick
/obj/item/weapon/mine/n2o
name = "nitrous oxide mine"
desc = "A small explosive mine with three Z's on the side."
minetype = /obj/effect/mine/n2o
/obj/item/weapon/mine/stun
name = "stun mine"
desc = "A small explosive mine with a lightning bolt symbol on the side."
minetype = /obj/effect/mine/stun
/obj/item/weapon/mine/frag
name = "fragmentation mine"
desc = "A small explosive mine with 'FRAG' and a grenade symbol on the side."
minetype = /obj/effect/mine/frag
/obj/item/weapon/mine/training
name = "training mine"
desc = "A mine with its payload removed, for EOD training and demonstrations."
minetype = /obj/effect/mine/training
/obj/item/weapon/mine/emp
name = "emp mine"
desc = "A small explosive mine with a lightning bolt symbol on the side."
minetype = /obj/effect/mine/emp
/obj/item/weapon/mine/incendiary
name = "incendiary mine"
desc = "A small explosive mine with a fire symbol on the side."
minetype = /obj/effect/mine/incendiary
/obj/item/weapon/mine/gadget
name = "gadget mine"
desc = "A small pressure-triggered device. If no component is added, the internal release bolts will detonate in unison when triggered."
allowed_gadgets = list(/obj/item/weapon/grenade, /obj/item/device/transfer_valve)
// This tells AI mobs to not be dumb and step on mines willingly.
/obj/item/weapon/mine/is_safe_to_step(mob/living/L)
if(!L.hovering || !L.flying)
return FALSE
return ..()
/obj/effect/mine
name = "land mine" //The name and description are deliberately NOT modified, so you can't game the mines you find.
desc = "A small explosive land mine."
density = FALSE
anchored = TRUE
icon = 'icons/obj/weapons.dmi'
icon_state = "landmine"
var/triggered = 0
var/smoke_strength = 3
var/obj/item/weapon/mine/mineitemtype = /obj/item/weapon/mine
var/panel_open = FALSE
var/datum/wires/mines/wires = null
var/camo_net = FALSE // Will the mine 'cloak' on deployment?
// The trap item will be triggered in some manner when detonating. Default only checks for grenades.
var/obj/item/trap = null
/obj/effect/mine/Initialize()
icon_state = "landmine_armed"
wires = new(src)
. = ..()
if(ispath(trap))
trap = new trap(src)
register_dangerous_to_step()
if(camo_net)
alpha = 50
/obj/effect/mine/Destroy()
unregister_dangerous_to_step()
if(trap)
QDEL_NULL(trap)
qdel_null(wires)
return ..()
/obj/effect/mine/Moved(atom/oldloc)
. = ..()
if(.)
var/turf/old_turf = get_turf(oldloc)
var/turf/new_turf = get_turf(src)
if(old_turf != new_turf)
old_turf.unregister_dangerous_object(src)
new_turf.register_dangerous_object(src)
/obj/effect/mine/proc/explode(var/mob/living/M)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
triggered = 1
s.set_up(3, 1, src)
s.start()
if(trap)
trigger_trap(M)
visible_message("\The [src.name] flashes as it is triggered!")
else
explosion(loc, 0, 2, 3, 4) //land mines are dangerous, folks.
visible_message("\The [src.name] detonates!")
qdel(s)
qdel(src)
/obj/effect/mine/proc/trigger_trap(var/mob/living/victim)
if(istype(trap, /obj/item/weapon/grenade))
var/obj/item/weapon/grenade/G = trap
trap = null
G.forceMove(get_turf(src))
if(victim.ckey)
msg_admin_attack("[key_name_admin(victim)] stepped on \a [src.name], triggering [trap]")
G.activate()
if(istype(trap, /obj/item/device/transfer_valve))
var/obj/item/device/transfer_valve/TV = trap
trap = null
TV.forceMove(get_turf(src))
TV.toggle_valve()
/obj/effect/mine/bullet_act()
if(prob(50))
explode()
/obj/effect/mine/ex_act(severity)
if(severity <= 2 || prob(50))
explode()
..()
/obj/effect/mine/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
Bumped(AM)
/obj/effect/mine/Bumped(mob/M as mob|obj)
if(triggered)
return
if(istype(M, /obj/mecha))
explode(M)
if(istype(M, /mob/living/))
var/mob/living/mob = M
if(!mob.hovering || !mob.flying)
explode(M)
/obj/effect/mine/attackby(obj/item/W as obj, mob/living/user as mob)
if(W.has_tool_quality(TOOL_SCREWDRIVER))
panel_open = !panel_open
user.visible_message("<span class='warning'>[user] very carefully screws the mine's panel [panel_open ? "open" : "closed"].</span>",
"<span class='notice'>You very carefully screw the mine's panel [panel_open ? "open" : "closed"].</span>")
playsound(src, W.usesound, 50, 1)
// Panel open, stay uncloaked, or uncloak if already cloaked. If you don't cloak on place, ignore it and just be normal alpha.
alpha = camo_net ? (panel_open ? 255 : 50) : 255
else if((W.has_tool_quality(TOOL_WIRECUTTER) || istype(W, /obj/item/device/multitool)) && panel_open)
interact(user)
else
..()
/obj/effect/mine/interact(mob/living/user as mob)
if(!panel_open || istype(user, /mob/living/silicon/ai))
return
user.set_machine(src)
wires.Interact(user)
/obj/effect/mine/camo
camo_net = TRUE
/obj/effect/mine/dnascramble
mineitemtype = /obj/item/weapon/mine/dnascramble
/obj/effect/mine/dnascramble/explode(var/mob/living/M)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
triggered = 1
s.set_up(3, 1, src)
s.start()
if(istype(M))
M.radiation += 50
randmutb(M)
domutcheck(M,null)
visible_message("\The [src.name] flashes violently before disintegrating!")
spawn(0)
qdel(s)
qdel(src)
/obj/effect/mine/stun
mineitemtype = /obj/item/weapon/mine/stun
/obj/effect/mine/stun/explode(var/mob/living/M)
triggered = 1
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
s.set_up(3, 1, src)
s.start()
if(istype(M))
M.Stun(30)
visible_message("\The [src.name] flashes violently before disintegrating!")
spawn(0)
qdel(s)
qdel(src)
/obj/effect/mine/n2o
mineitemtype = /obj/item/weapon/mine/n2o
/obj/effect/mine/n2o/explode(var/mob/living/M)
triggered = 1
for (var/turf/simulated/floor/target in range(1,src))
if(!target.blocks_air)
target.assume_gas("nitrous_oxide", 30)
visible_message("\The [src.name] detonates!")
spawn(0)
qdel(src)
/obj/effect/mine/phoron
mineitemtype = /obj/item/weapon/mine/phoron
/obj/effect/mine/phoron/explode(var/mob/living/M)
triggered = 1
for (var/turf/simulated/floor/target in range(1,src))
if(!target.blocks_air)
target.assume_gas("phoron", 30)
target.hotspot_expose(1000, CELL_VOLUME)
visible_message("\The [src.name] detonates!")
spawn(0)
qdel(src)
/obj/effect/mine/kick
mineitemtype = /obj/item/weapon/mine/kick
/obj/effect/mine/kick/explode(var/mob/living/M)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
triggered = 1
s.set_up(3, 1, src)
s.start()
if(istype(M, /obj/mecha))
var/obj/mecha/E = M
M = E.occupant
if(istype(M))
qdel(M.client)
spawn(0)
qdel(s)
qdel(src)
/obj/effect/mine/frag
mineitemtype = /obj/item/weapon/mine/frag
var/fragment_types = list(/obj/item/projectile/bullet/pellet/fragment)
var/num_fragments = 20 //total number of fragments produced by the grenade
//The radius of the circle used to launch projectiles. Lower values mean less projectiles are used but if set too low gaps may appear in the spread pattern
var/spread_range = 7
/obj/effect/mine/frag/explode(var/mob/living/M)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
triggered = 1
s.set_up(3, 1, src)
s.start()
var/turf/O = get_turf(src)
if(!O)
return
src.fragmentate(O, 20, 7, list(/obj/item/projectile/bullet/pellet/fragment)) //only 20 weak fragments because you're stepping directly on it
visible_message("\The [src.name] detonates!")
spawn(0)
qdel(s)
qdel(src)
/obj/effect/mine/training //Name and Desc commented out so it's possible to trick people with the training mines
// name = "training mine"
// desc = "A mine with its payload removed, for EOD training and demonstrations."
mineitemtype = /obj/item/weapon/mine/training
/obj/effect/mine/training/explode(var/mob/living/M)
triggered = 1
visible_message("\The [src.name]'s light flashes rapidly as it 'explodes'.")
new src.mineitemtype(get_turf(src))
spawn(0)
qdel(src)
/obj/effect/mine/emp
mineitemtype = /obj/item/weapon/mine/emp
/obj/effect/mine/emp/explode(var/mob/living/M)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
s.set_up(3, 1, src)
s.start()
visible_message("\The [src.name] flashes violently before disintegrating!")
empulse(loc, 2, 4, 7, 10, 1) // As strong as an EMP grenade
spawn(0)
qdel(src)
/obj/effect/mine/emp/camo
camo_net = TRUE
/obj/effect/mine/incendiary
mineitemtype = /obj/item/weapon/mine/incendiary
/obj/effect/mine/incendiary/explode(var/mob/living/M)
triggered = 1
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
s.set_up(3, 1, src)
s.start()
if(istype(M))
M.adjust_fire_stacks(5)
M.fire_act()
visible_message("\The [src.name] bursts into flames!")
spawn(0)
qdel(src)
/obj/effect/mine/gadget
mineitemtype = /obj/item/weapon/mine/gadget
/obj/effect/mine/gadget/explode(var/mob/living/M)
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread()
triggered = 1
s.set_up(3, 1, src)
s.start()
if(trap)
trigger_trap(M)
visible_message("\The [src.name] flashes as it is triggered!")
else
explosion(loc, 0, 0, 2, 2)
visible_message("\The [src.name] detonates!")
qdel(s)
qdel(src)
/////////////////////////////////////////////
// The held item version of the above mines
/////////////////////////////////////////////
/obj/item/weapon/mine
name = "mine"
desc = "A small explosive mine with 'HE' and a grenade symbol on the side."
icon = 'icons/obj/weapons.dmi'
icon_state = "uglymine"
var/countdown = 10
var/minetype = /obj/effect/mine //This MUST be an /obj/effect/mine type, or it'll runtime.
var/obj/item/trap = null
var/list/allowed_gadgets = null
/obj/item/weapon/mine/attack_self(mob/user as mob) // You do not want to move or throw a land mine while priming it... Explosives + Sudden Movement = Bad Times
add_fingerprint(user)
msg_admin_attack("[key_name_admin(user)] primed \a [src]")
user.visible_message("[user] starts priming \the [src.name].", "You start priming \the [src.name]. Hold still!")
if(do_after(user, 10 SECONDS))
playsound(src, 'sound/weapons/armbomb.ogg', 75, 1, -3)
prime(user)
else
visible_message("[user] triggers \the [src.name]!", "You accidentally trigger \the [src.name]!")
prime(user, TRUE)
return
/obj/item/weapon/mine/attackby(obj/item/W as obj, mob/living/user as mob)
if(W.has_tool_quality(TOOL_SCREWDRIVER) && trap)
to_chat(user, "<span class='notice'>You begin removing \the [trap].</span>")
if(do_after(user, 10 SECONDS))
to_chat(user, "<span class='notice'>You finish disconnecting the mine's trigger.</span>")
trap.forceMove(get_turf(src))
trap = null
return
if(LAZYLEN(allowed_gadgets) && !trap)
var/allowed = FALSE
for(var/path in allowed_gadgets)
if(istype(W, path))
allowed = TRUE
break
if(allowed)
user.drop_from_inventory(W)
W.forceMove(src)
trap = W
..()
/obj/item/weapon/mine/proc/prime(mob/user as mob, var/explode_now = FALSE)
visible_message("\The [src.name] beeps as the priming sequence completes.")
var/obj/effect/mine/R = new minetype(get_turf(src))
src.transfer_fingerprints_to(R)
R.add_fingerprint(user)
if(trap)
R.trap = trap
trap = null
R.trap.forceMove(R)
if(explode_now)
R.explode(user)
spawn(0)
qdel(src)
/obj/item/weapon/mine/dnascramble
name = "radiation mine"
desc = "A small explosive mine with a radiation symbol on the side."
minetype = /obj/effect/mine/dnascramble
/obj/item/weapon/mine/phoron
name = "incendiary mine"
desc = "A small explosive mine with a fire symbol on the side."
minetype = /obj/effect/mine/phoron
/obj/item/weapon/mine/kick
name = "kick mine"
desc = "Concentrated war crimes. Handle with care."
minetype = /obj/effect/mine/kick
/obj/item/weapon/mine/n2o
name = "nitrous oxide mine"
desc = "A small explosive mine with three Z's on the side."
minetype = /obj/effect/mine/n2o
/obj/item/weapon/mine/stun
name = "stun mine"
desc = "A small explosive mine with a lightning bolt symbol on the side."
minetype = /obj/effect/mine/stun
/obj/item/weapon/mine/frag
name = "fragmentation mine"
desc = "A small explosive mine with 'FRAG' and a grenade symbol on the side."
minetype = /obj/effect/mine/frag
/obj/item/weapon/mine/training
name = "training mine"
desc = "A mine with its payload removed, for EOD training and demonstrations."
minetype = /obj/effect/mine/training
/obj/item/weapon/mine/emp
name = "emp mine"
desc = "A small explosive mine with a lightning bolt symbol on the side."
minetype = /obj/effect/mine/emp
/obj/item/weapon/mine/incendiary
name = "incendiary mine"
desc = "A small explosive mine with a fire symbol on the side."
minetype = /obj/effect/mine/incendiary
/obj/item/weapon/mine/gadget
name = "gadget mine"
desc = "A small pressure-triggered device. If no component is added, the internal release bolts will detonate in unison when triggered."
allowed_gadgets = list(/obj/item/weapon/grenade, /obj/item/device/transfer_valve)
// This tells AI mobs to not be dumb and step on mines willingly.
/obj/item/weapon/mine/is_safe_to_step(mob/living/L)
if(!L.hovering || !L.flying)
return FALSE
return ..()
+152 -152
View File
@@ -1,152 +1,152 @@
//The effect when you wrap a dead body in gift wrap
/obj/effect/spresent
name = "strange present"
desc = "It's a ... present?"
icon = 'icons/obj/items.dmi'
icon_state = "strangepresent"
density = TRUE
anchored = FALSE
/obj/effect/temporary_effect
name = "self deleting effect"
desc = "How are you examining what which cannot be seen?"
icon = 'icons/effects/effects.dmi'
invisibility = 0
var/time_to_die = 10 SECONDS // Afer which, it will delete itself.
/obj/effect/temporary_effect/Initialize()
. = ..()
if(time_to_die)
QDEL_IN(src, time_to_die)
// Shown really briefly when attacking with axes.
/obj/effect/temporary_effect/cleave_attack
name = "cleaving attack"
desc = "Something swinging really wide."
icon = 'icons/effects/96x96.dmi'
icon_state = "cleave"
plane = ABOVE_MOB_PLANE
layer = ABOVE_MOB_LAYER
time_to_die = 6
alpha = 140
mouse_opacity = 0
pixel_x = -32
pixel_y = -32
/obj/effect/temporary_effect/cleave_attack/Initialize() // Makes the slash fade smoothly. When completely transparent it should qdel itself.
. = ..()
animate(src, alpha = 0, time = time_to_die - 1)
/obj/effect/temporary_effect/shuttle_landing
name = "shuttle landing"
desc = "You better move if you don't want to go splat!"
//VOREStation Edit Start
icon = 'icons/goonstation/featherzone.dmi'
icon_state = "hazard-corners"
time_to_die = 5 SECONDS
plane = PLANE_LIGHTING_ABOVE
//VOREStation Edit End
// The manifestation of Zeus's might. Or just a really unlucky day.
// This is purely a visual effect, this isn't the part of the code that hurts things.
/obj/effect/temporary_effect/lightning_strike
name = "lightning"
desc = "How <i>shocked</i> you must be, to see this text. You must have <i>lightning</i> reflexes. \
The humor in this description is just so <i>electrifying</i>."
icon = 'icons/effects/96x256.dmi'
icon_state = "lightning_strike"
plane = PLANE_LIGHTING_ABOVE
time_to_die = 1 SECOND
pixel_x = -32
/obj/effect/temporary_effect/lightning_strike/Initialize()
icon_state += "[rand(1,2)]" // To have two variants of lightning sprites.
animate(src, alpha = 0, time = time_to_die - 1)
. = ..()
/obj/effect/dummy/lighting_obj
name = "lighting fx obj"
desc = "Tell a coder if you're seeing this."
icon_state = "nothing"
light_system = MOVABLE_LIGHT
light_range = MINIMUM_USEFUL_LIGHT_RANGE
light_color = COLOR_WHITE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
light_on = TRUE
blocks_emissive = FALSE
/obj/effect/dummy/lighting_obj/Initialize(mapload, _range, _power, _color, _duration)
. = ..()
if(!isnull(_range))
set_light_range(_range)
if(!isnull(_power))
set_light_power(_power)
if(!isnull(_color))
set_light_color(_color)
if(_duration)
QDEL_IN(src, _duration)
/obj/effect/dummy/lighting_obj/moblight
name = "mob lighting fx"
/obj/effect/dummy/lighting_obj/moblight/Initialize(mapload, _color, _range, _power, _duration)
. = ..()
if(!ismob(loc))
return INITIALIZE_HINT_QDEL
/obj/effect/dummy/lighting_obj/moblight/fire
name = "fire"
light_color = LIGHT_COLOR_FIRE
light_range = LIGHT_RANGE_FIRE
/obj/effect/abstract
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
plane = ABOVE_MOB_PLANE
/obj/effect/abstract/light_spot
icon = 'icons/effects/eris_flashlight.dmi'
icon_state = "medium"
pixel_x = -16
pixel_y = -16
/obj/effect/abstract/directional_lighting
var/obj/effect/abstract/light_spot/light_spot = new
var/trans_angle
var/icon_dist
/obj/effect/abstract/directional_lighting/Initialize()
. = ..()
vis_contents += light_spot
/obj/effect/abstract/directional_lighting/proc/face_light(atom/movable/source, angle, distance)
if(!loc) // We're in nullspace
return
// Save ourselves some matrix math
if(angle != trans_angle)
trans_angle = angle
// Doing this in one operation (tn = turn(initial(tn), angle)) has strange results...
light_spot.transform = initial(light_spot.transform)
light_spot.transform = turn(light_spot.transform, angle)
if(icon_dist != distance)
icon_dist = distance
switch(distance)
if(0)
light_spot.icon_state = "vclose"
if(1)
light_spot.icon_state = "close"
if(2)
light_spot.icon_state = "medium"
if(3 to INFINITY)
light_spot.icon_state = "far"
/obj/effect/abstract/directional_lighting/Destroy(force)
if(!force)
stack_trace("Directional light atom deleted, but not by our component")
return QDEL_HINT_LETMELIVE
vis_contents.Cut()
qdel_null(light_spot)
return ..()
//The effect when you wrap a dead body in gift wrap
/obj/effect/spresent
name = "strange present"
desc = "It's a ... present?"
icon = 'icons/obj/items.dmi'
icon_state = "strangepresent"
density = TRUE
anchored = FALSE
/obj/effect/temporary_effect
name = "self deleting effect"
desc = "How are you examining what which cannot be seen?"
icon = 'icons/effects/effects.dmi'
invisibility = 0
var/time_to_die = 10 SECONDS // Afer which, it will delete itself.
/obj/effect/temporary_effect/Initialize()
. = ..()
if(time_to_die)
QDEL_IN(src, time_to_die)
// Shown really briefly when attacking with axes.
/obj/effect/temporary_effect/cleave_attack
name = "cleaving attack"
desc = "Something swinging really wide."
icon = 'icons/effects/96x96.dmi'
icon_state = "cleave"
plane = ABOVE_MOB_PLANE
layer = ABOVE_MOB_LAYER
time_to_die = 6
alpha = 140
mouse_opacity = 0
pixel_x = -32
pixel_y = -32
/obj/effect/temporary_effect/cleave_attack/Initialize() // Makes the slash fade smoothly. When completely transparent it should qdel itself.
. = ..()
animate(src, alpha = 0, time = time_to_die - 1)
/obj/effect/temporary_effect/shuttle_landing
name = "shuttle landing"
desc = "You better move if you don't want to go splat!"
//VOREStation Edit Start
icon = 'icons/goonstation/featherzone.dmi'
icon_state = "hazard-corners"
time_to_die = 5 SECONDS
plane = PLANE_LIGHTING_ABOVE
//VOREStation Edit End
// The manifestation of Zeus's might. Or just a really unlucky day.
// This is purely a visual effect, this isn't the part of the code that hurts things.
/obj/effect/temporary_effect/lightning_strike
name = "lightning"
desc = "How <i>shocked</i> you must be, to see this text. You must have <i>lightning</i> reflexes. \
The humor in this description is just so <i>electrifying</i>."
icon = 'icons/effects/96x256.dmi'
icon_state = "lightning_strike"
plane = PLANE_LIGHTING_ABOVE
time_to_die = 1 SECOND
pixel_x = -32
/obj/effect/temporary_effect/lightning_strike/Initialize()
icon_state += "[rand(1,2)]" // To have two variants of lightning sprites.
animate(src, alpha = 0, time = time_to_die - 1)
. = ..()
/obj/effect/dummy/lighting_obj
name = "lighting fx obj"
desc = "Tell a coder if you're seeing this."
icon_state = "nothing"
light_system = MOVABLE_LIGHT
light_range = MINIMUM_USEFUL_LIGHT_RANGE
light_color = COLOR_WHITE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
light_on = TRUE
blocks_emissive = FALSE
/obj/effect/dummy/lighting_obj/Initialize(mapload, _range, _power, _color, _duration)
. = ..()
if(!isnull(_range))
set_light_range(_range)
if(!isnull(_power))
set_light_power(_power)
if(!isnull(_color))
set_light_color(_color)
if(_duration)
QDEL_IN(src, _duration)
/obj/effect/dummy/lighting_obj/moblight
name = "mob lighting fx"
/obj/effect/dummy/lighting_obj/moblight/Initialize(mapload, _color, _range, _power, _duration)
. = ..()
if(!ismob(loc))
return INITIALIZE_HINT_QDEL
/obj/effect/dummy/lighting_obj/moblight/fire
name = "fire"
light_color = LIGHT_COLOR_FIRE
light_range = LIGHT_RANGE_FIRE
/obj/effect/abstract
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
plane = ABOVE_MOB_PLANE
/obj/effect/abstract/light_spot
icon = 'icons/effects/eris_flashlight.dmi'
icon_state = "medium"
pixel_x = -16
pixel_y = -16
/obj/effect/abstract/directional_lighting
var/obj/effect/abstract/light_spot/light_spot = new
var/trans_angle
var/icon_dist
/obj/effect/abstract/directional_lighting/Initialize()
. = ..()
vis_contents += light_spot
/obj/effect/abstract/directional_lighting/proc/face_light(atom/movable/source, angle, distance)
if(!loc) // We're in nullspace
return
// Save ourselves some matrix math
if(angle != trans_angle)
trans_angle = angle
// Doing this in one operation (tn = turn(initial(tn), angle)) has strange results...
light_spot.transform = initial(light_spot.transform)
light_spot.transform = turn(light_spot.transform, angle)
if(icon_dist != distance)
icon_dist = distance
switch(distance)
if(0)
light_spot.icon_state = "vclose"
if(1)
light_spot.icon_state = "close"
if(2)
light_spot.icon_state = "medium"
if(3 to INFINITY)
light_spot.icon_state = "far"
/obj/effect/abstract/directional_lighting/Destroy(force)
if(!force)
stack_trace("Directional light atom deleted, but not by our component")
return QDEL_HINT_LETMELIVE
vis_contents.Cut()
qdel_null(light_spot)
return ..()
+191 -191
View File
@@ -1,191 +1,191 @@
/obj/effect/overlay
name = "overlay"
unacidable = TRUE
var/i_attached//Added for possible image attachments to objects. For hallucinations and the like.
/obj/effect/overlay/beam//Not actually a projectile, just an effect.
name="beam"
icon='icons/effects/beam.dmi'
icon_state="b_beam"
plane = ABOVE_OBJ_PLANE
var/tmp/atom/BeamSource
/obj/effect/overlay/beam/New()
..()
spawn(10) qdel(src)
/obj/effect/overlay/palmtree_r
name = "Palm tree"
icon = 'icons/misc/beach2.dmi'
icon_state = "palm1"
density = TRUE
plane = MOB_PLANE
layer = ABOVE_MOB_LAYER
anchored = TRUE
/obj/effect/overlay/palmtree_l
name = "Palm tree"
icon = 'icons/misc/beach2.dmi'
icon_state = "palm2"
density = TRUE
plane = MOB_PLANE
layer = ABOVE_MOB_LAYER
anchored = TRUE
/obj/effect/overlay/coconut
name = "Coconuts"
icon = 'icons/misc/beach.dmi'
icon_state = "coconuts"
/obj/effect/overlay/bluespacify
name = "Bluespace"
icon = 'icons/turf/space_vr.dmi' //VOREStation Edit
icon_state = "bluespacify"
plane = ABOVE_PLANE
/obj/effect/overlay/wallrot
name = "wallrot"
desc = "Ick..."
icon = 'icons/effects/wallrot.dmi'
anchored = TRUE
density = TRUE
plane = MOB_PLANE
layer = ABOVE_MOB_LAYER
mouse_opacity = 0
/obj/effect/overlay/wallrot/New()
..()
pixel_x += rand(-10, 10)
pixel_y += rand(-10, 10)
/obj/effect/overlay/snow
name = "snow"
icon = 'icons/turf/overlays.dmi'
icon_state = "snow"
anchored = TRUE
plane = TURF_PLANE
// Todo: Add a version that gradually reaccumulates over time by means of alpha transparency. -Spades
/obj/effect/overlay/snow/attackby(obj/item/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/shovel))
user.visible_message("<span class='notice'>[user] begins to shovel away \the [src].</span>")
if(do_after(user, 40))
to_chat(user, "<span class='notice'>You have finished shoveling!</span>")
qdel(src)
return
/obj/effect/overlay/snow/floor
icon_state = "snowfloor"
plane = TURF_PLANE
layer = ABOVE_TURF_LAYER
mouse_opacity = 0 //Don't block underlying tile interactions
/obj/effect/overlay/snow/floor/edges
icon_state = "snow_edges"
/obj/effect/overlay/snow/floor/surround
icon_state = "snow_surround"
/obj/effect/overlay/snow/airlock
icon_state = "snowairlock"
layer = DOOR_CLOSED_LAYER+0.01
/obj/effect/overlay/snow/floor/pointy
icon_state = "snowfloorpointy"
/obj/effect/overlay/snow/wall
icon_state = "snowwall"
plane = MOB_PLANE
layer = ABOVE_MOB_LAYER
/obj/effect/overlay/holographic
mouse_opacity = FALSE
anchored = TRUE
plane = ABOVE_PLANE
// Similar to the tesla ball but doesn't actually do anything and is purely visual.
/obj/effect/overlay/energy_ball
name = "energy ball"
desc = "An energy ball."
icon = 'icons/obj/tesla_engine/energy_ball.dmi'
icon_state = "energy_ball"
plane = PLANE_LIGHTING_ABOVE
pixel_x = -32
pixel_y = -32
/obj/effect/overlay/vis
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
anchored = TRUE
vis_flags = VIS_INHERIT_DIR
///When detected to be unused it gets set to world.time, after a while it gets removed
var/unused = 0
///overlays which go unused for this amount of time get cleaned up
var/cache_expiration = 2 MINUTES
/*
/obj/effect/overlay/atmos_excited
name = "excited group"
icon = null
icon_state = null
anchored = TRUE // should only appear in vis_contents, but to be safe
appearance_flags = RESET_TRANSFORM | TILE_BOUND
invisibility = INVISIBILITY_ABSTRACT
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
plane = ATMOS_GROUP_PLANE
*/
/obj/effect/overlay/light_visible
name = ""
icon = 'icons/effects/light_overlays/light_32.dmi'
icon_state = "light"
plane = PLANE_O_LIGHTING_VISUAL
appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
alpha = 0
vis_flags = NONE
blocks_emissive = FALSE
/obj/effect/overlay/light_visible/Destroy(force)
if(!force)
stack_trace("Movable light visible mask deleted, but not by our component")
return QDEL_HINT_LETMELIVE
return ..()
/obj/effect/overlay/light_cone
name = ""
icon = 'icons/effects/light_overlays/light_cone.dmi'
icon_state = "light"
plane = PLANE_O_LIGHTING_VISUAL
appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
vis_flags = NONE
alpha = 110
blocks_emissive = FALSE
var/static/matrix/normal_transform
/obj/effect/overlay/light_cone/Initialize()
. = ..()
apply_standard_transform()
/obj/effect/overlay/light_cone/proc/reset_transform(apply_standard)
transform = initial(transform)
if(apply_standard)
apply_standard_transform()
/obj/effect/overlay/light_cone/proc/apply_standard_transform()
transform = transform.Translate(-32, -32)
/obj/effect/overlay/light_cone/Destroy(force)
if(!force)
stack_trace("Directional light cone deleted, but not by our component")
return QDEL_HINT_LETMELIVE
return ..()
/obj/effect/overlay/closet_door
anchored = TRUE
plane = FLOAT_PLANE
layer = FLOAT_LAYER
vis_flags = VIS_INHERIT_ID
appearance_flags = KEEP_TOGETHER | LONG_GLIDE | PIXEL_SCALE
/obj/effect/overlay
name = "overlay"
unacidable = TRUE
var/i_attached//Added for possible image attachments to objects. For hallucinations and the like.
/obj/effect/overlay/beam//Not actually a projectile, just an effect.
name="beam"
icon='icons/effects/beam.dmi'
icon_state="b_beam"
plane = ABOVE_OBJ_PLANE
var/tmp/atom/BeamSource
/obj/effect/overlay/beam/New()
..()
spawn(10) qdel(src)
/obj/effect/overlay/palmtree_r
name = "Palm tree"
icon = 'icons/misc/beach2.dmi'
icon_state = "palm1"
density = TRUE
plane = MOB_PLANE
layer = ABOVE_MOB_LAYER
anchored = TRUE
/obj/effect/overlay/palmtree_l
name = "Palm tree"
icon = 'icons/misc/beach2.dmi'
icon_state = "palm2"
density = TRUE
plane = MOB_PLANE
layer = ABOVE_MOB_LAYER
anchored = TRUE
/obj/effect/overlay/coconut
name = "Coconuts"
icon = 'icons/misc/beach.dmi'
icon_state = "coconuts"
/obj/effect/overlay/bluespacify
name = "Bluespace"
icon = 'icons/turf/space_vr.dmi' //VOREStation Edit
icon_state = "bluespacify"
plane = ABOVE_PLANE
/obj/effect/overlay/wallrot
name = "wallrot"
desc = "Ick..."
icon = 'icons/effects/wallrot.dmi'
anchored = TRUE
density = TRUE
plane = MOB_PLANE
layer = ABOVE_MOB_LAYER
mouse_opacity = 0
/obj/effect/overlay/wallrot/New()
..()
pixel_x += rand(-10, 10)
pixel_y += rand(-10, 10)
/obj/effect/overlay/snow
name = "snow"
icon = 'icons/turf/overlays.dmi'
icon_state = "snow"
anchored = TRUE
plane = TURF_PLANE
// Todo: Add a version that gradually reaccumulates over time by means of alpha transparency. -Spades
/obj/effect/overlay/snow/attackby(obj/item/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/shovel))
user.visible_message("<span class='notice'>[user] begins to shovel away \the [src].</span>")
if(do_after(user, 40))
to_chat(user, "<span class='notice'>You have finished shoveling!</span>")
qdel(src)
return
/obj/effect/overlay/snow/floor
icon_state = "snowfloor"
plane = TURF_PLANE
layer = ABOVE_TURF_LAYER
mouse_opacity = 0 //Don't block underlying tile interactions
/obj/effect/overlay/snow/floor/edges
icon_state = "snow_edges"
/obj/effect/overlay/snow/floor/surround
icon_state = "snow_surround"
/obj/effect/overlay/snow/airlock
icon_state = "snowairlock"
layer = DOOR_CLOSED_LAYER+0.01
/obj/effect/overlay/snow/floor/pointy
icon_state = "snowfloorpointy"
/obj/effect/overlay/snow/wall
icon_state = "snowwall"
plane = MOB_PLANE
layer = ABOVE_MOB_LAYER
/obj/effect/overlay/holographic
mouse_opacity = FALSE
anchored = TRUE
plane = ABOVE_PLANE
// Similar to the tesla ball but doesn't actually do anything and is purely visual.
/obj/effect/overlay/energy_ball
name = "energy ball"
desc = "An energy ball."
icon = 'icons/obj/tesla_engine/energy_ball.dmi'
icon_state = "energy_ball"
plane = PLANE_LIGHTING_ABOVE
pixel_x = -32
pixel_y = -32
/obj/effect/overlay/vis
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
anchored = TRUE
vis_flags = VIS_INHERIT_DIR
///When detected to be unused it gets set to world.time, after a while it gets removed
var/unused = 0
///overlays which go unused for this amount of time get cleaned up
var/cache_expiration = 2 MINUTES
/*
/obj/effect/overlay/atmos_excited
name = "excited group"
icon = null
icon_state = null
anchored = TRUE // should only appear in vis_contents, but to be safe
appearance_flags = RESET_TRANSFORM | TILE_BOUND
invisibility = INVISIBILITY_ABSTRACT
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
plane = ATMOS_GROUP_PLANE
*/
/obj/effect/overlay/light_visible
name = ""
icon = 'icons/effects/light_overlays/light_32.dmi'
icon_state = "light"
plane = PLANE_O_LIGHTING_VISUAL
appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
alpha = 0
vis_flags = NONE
blocks_emissive = FALSE
/obj/effect/overlay/light_visible/Destroy(force)
if(!force)
stack_trace("Movable light visible mask deleted, but not by our component")
return QDEL_HINT_LETMELIVE
return ..()
/obj/effect/overlay/light_cone
name = ""
icon = 'icons/effects/light_overlays/light_cone.dmi'
icon_state = "light"
plane = PLANE_O_LIGHTING_VISUAL
appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
vis_flags = NONE
alpha = 110
blocks_emissive = FALSE
var/static/matrix/normal_transform
/obj/effect/overlay/light_cone/Initialize()
. = ..()
apply_standard_transform()
/obj/effect/overlay/light_cone/proc/reset_transform(apply_standard)
transform = initial(transform)
if(apply_standard)
apply_standard_transform()
/obj/effect/overlay/light_cone/proc/apply_standard_transform()
transform = transform.Translate(-32, -32)
/obj/effect/overlay/light_cone/Destroy(force)
if(!force)
stack_trace("Directional light cone deleted, but not by our component")
return QDEL_HINT_LETMELIVE
return ..()
/obj/effect/overlay/closet_door
anchored = TRUE
plane = FLOAT_PLANE
layer = FLOAT_LAYER
vis_flags = VIS_INHERIT_ID
appearance_flags = KEEP_TOGETHER | LONG_GLIDE | PIXEL_SCALE
+69 -69
View File
@@ -1,69 +1,69 @@
GLOBAL_LIST_BOILERPLATE(all_portals, /obj/effect/portal)
/obj/effect/portal
name = "portal"
desc = "Looks unstable. Best to test it with the clown."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "portal"
density = TRUE
unacidable = TRUE//Can't destroy energy portals.
var/failchance = 5
var/obj/item/target = null
var/creator = null
anchored = TRUE
/obj/effect/portal/Bumped(mob/M as mob|obj)
if(istype(M,/mob) && !(istype(M,/mob/living)))
return //do not send ghosts, zshadows, ai eyes, etc
spawn(0)
src.teleport(M)
return
return
/obj/effect/portal/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(istype(AM,/mob) && !(istype(AM,/mob/living)))
return //do not send ghosts, zshadows, ai eyes, etc
spawn(0)
src.teleport(AM)
return
return
/obj/effect/portal/attack_hand(mob/user as mob)
if(istype(user) && !(istype(user,/mob/living)))
return //do not send ghosts, zshadows, ai eyes, etc
spawn(0)
src.teleport(user)
return
return
/obj/effect/portal/Initialize()
. = ..()
QDEL_IN(src, 30 SECONDS)
/obj/effect/portal/proc/teleport(atom/movable/M as mob|obj)
if(istype(M, /obj/effect)) //sparks don't teleport
return
if (M.anchored&&istype(M, /obj/mecha))
return
if (icon_state == "portal1")
return
if (!( target ))
qdel(src)
return
if (istype(M, /atom/movable))
//VOREStation Addition Start: Prevent taurriding abuse
if(istype(M, /mob/living))
var/mob/living/L = M
if(LAZYLEN(L.buckled_mobs))
var/datum/riding/R = L.riding_datum
for(var/rider in L.buckled_mobs)
R.force_dismount(rider)
//VOREStation Addition End: Prevent taurriding abuse
if(prob(failchance)) //oh dear a problem, put em in deep space
src.icon_state = "portal1"
do_teleport(M, locate(rand(5, world.maxx - 5), rand(5, world.maxy -5), 3), 0)
else
do_teleport(M, target, 1) ///You will appear adjacent to the beacon
GLOBAL_LIST_BOILERPLATE(all_portals, /obj/effect/portal)
/obj/effect/portal
name = "portal"
desc = "Looks unstable. Best to test it with the clown."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "portal"
density = TRUE
unacidable = TRUE//Can't destroy energy portals.
var/failchance = 5
var/obj/item/target = null
var/creator = null
anchored = TRUE
/obj/effect/portal/Bumped(mob/M as mob|obj)
if(istype(M,/mob) && !(istype(M,/mob/living)))
return //do not send ghosts, zshadows, ai eyes, etc
spawn(0)
src.teleport(M)
return
return
/obj/effect/portal/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(istype(AM,/mob) && !(istype(AM,/mob/living)))
return //do not send ghosts, zshadows, ai eyes, etc
spawn(0)
src.teleport(AM)
return
return
/obj/effect/portal/attack_hand(mob/user as mob)
if(istype(user) && !(istype(user,/mob/living)))
return //do not send ghosts, zshadows, ai eyes, etc
spawn(0)
src.teleport(user)
return
return
/obj/effect/portal/Initialize()
. = ..()
QDEL_IN(src, 30 SECONDS)
/obj/effect/portal/proc/teleport(atom/movable/M as mob|obj)
if(istype(M, /obj/effect)) //sparks don't teleport
return
if (M.anchored&&istype(M, /obj/mecha))
return
if (icon_state == "portal1")
return
if (!( target ))
qdel(src)
return
if (istype(M, /atom/movable))
//VOREStation Addition Start: Prevent taurriding abuse
if(istype(M, /mob/living))
var/mob/living/L = M
if(LAZYLEN(L.buckled_mobs))
var/datum/riding/R = L.riding_datum
for(var/rider in L.buckled_mobs)
R.force_dismount(rider)
//VOREStation Addition End: Prevent taurriding abuse
if(prob(failchance)) //oh dear a problem, put em in deep space
src.icon_state = "portal1"
do_teleport(M, locate(rand(5, world.maxx - 5), rand(5, world.maxy -5), 3), 0)
else
do_teleport(M, target, 1) ///You will appear adjacent to the beacon
File diff suppressed because it is too large Load Diff
+143 -143
View File
@@ -1,143 +1,143 @@
/client/proc/spawn_tanktransferbomb()
set category = "Debug"
set desc = "Spawn a tank transfer valve bomb"
set name = "Instant TTV"
if(!check_rights(R_SPAWN)) return
var/obj/effect/spawner/newbomb/proto = /obj/effect/spawner/newbomb/radio/custom
var/p = tgui_input_number(usr, "Enter phoron amount (mol):","Phoron", initial(proto.phoron_amt))
if(p == null) return
var/o = tgui_input_number(usr, "Enter oxygen amount (mol):","Oxygen", initial(proto.oxygen_amt))
if(o == null) return
var/c = tgui_input_number(usr, "Enter carbon dioxide amount (mol):","Carbon Dioxide", initial(proto.carbon_amt))
if(c == null) return
new /obj/effect/spawner/newbomb/radio/custom(get_turf(mob), p, o, c)
/obj/effect/spawner/newbomb
name = "TTV bomb"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
var/assembly_type = /obj/item/device/assembly/signaler
//Note that the maximum amount of gas you can put in a 70L air tank at 1013.25 kPa and 519K is 16.44 mol.
var/phoron_amt = 12
var/oxygen_amt = 18
var/carbon_amt = 0
/obj/effect/spawner/newbomb/timer
name = "TTV bomb - timer"
assembly_type = /obj/item/device/assembly/timer
/obj/effect/spawner/newbomb/timer/syndicate
name = "TTV bomb - merc"
//High yield bombs. Yes, it is possible to make these with toxins
phoron_amt = 18.5
oxygen_amt = 28.5
/obj/effect/spawner/newbomb/proximity
name = "TTV bomb - proximity"
assembly_type = /obj/item/device/assembly/prox_sensor
/obj/effect/spawner/newbomb/radio/custom/New(var/newloc, ph, ox, co)
if(ph != null) phoron_amt = ph
if(ox != null) oxygen_amt = ox
if(co != null) carbon_amt = co
..()
/obj/effect/spawner/newbomb/Initialize(newloc)
..(newloc)
var/obj/item/device/transfer_valve/V = new(src.loc)
var/obj/item/weapon/tank/phoron/PT = new(V)
var/obj/item/weapon/tank/oxygen/OT = new(V)
V.tank_one = PT
V.tank_two = OT
PT.master = V
OT.master = V
PT.valve_welded = 1
PT.air_contents.gas["phoron"] = phoron_amt
PT.air_contents.gas["carbon_dioxide"] = carbon_amt
PT.air_contents.total_moles = phoron_amt + carbon_amt
PT.air_contents.temperature = PHORON_MINIMUM_BURN_TEMPERATURE+1
PT.air_contents.update_values()
OT.valve_welded = 1
OT.air_contents.gas["oxygen"] = oxygen_amt
OT.air_contents.total_moles = oxygen_amt
OT.air_contents.temperature = PHORON_MINIMUM_BURN_TEMPERATURE+1
OT.air_contents.update_values()
var/obj/item/device/assembly/S = new assembly_type(V)
V.attached_device = S
S.holder = V
S.toggle_secure()
V.update_icon()
return INITIALIZE_HINT_QDEL
///////////////////////
//One Tank Bombs, WOOOOOOO! -Luke
///////////////////////
/obj/effect/spawner/onetankbomb
name = "Single-tank bomb"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
// var/assembly_type = /obj/item/device/assembly/signaler
//Note that the maximum amount of gas you can put in a 70L air tank at 1013.25 kPa and 519K is 16.44 mol.
var/phoron_amt = 0
var/oxygen_amt = 0
/obj/effect/spawner/onetankbomb/New(newloc) //just needs an assembly.
..(newloc)
var/type = pick(/obj/item/weapon/tank/phoron/onetankbomb, /obj/item/weapon/tank/oxygen/onetankbomb)
new type(src.loc)
qdel(src)
/obj/effect/spawner/onetankbomb/full
name = "Single-tank bomb"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
// var/assembly_type = /obj/item/device/assembly/signaler
//Note that the maximum amount of gas you can put in a 70L air tank at 1013.25 kPa and 519K is 16.44 mol.
/obj/effect/spawner/onetankbomb/full/New(newloc) //just needs an assembly.
..(newloc)
var/type = pick(/obj/item/weapon/tank/phoron/onetankbomb/full, /obj/item/weapon/tank/oxygen/onetankbomb/full)
new type(src.loc)
qdel(src)
/obj/effect/spawner/onetankbomb/frag
name = "Single-tank bomb"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
// var/assembly_type = /obj/item/device/assembly/signaler
//Note that the maximum amount of gas you can put in a 70L air tank at 1013.25 kPa and 519K is 16.44 mol.
/obj/effect/spawner/onetankbomb/full/New(newloc) //just needs an assembly.
..(newloc)
var/type = pick(/obj/item/weapon/tank/phoron/onetankbomb/full, /obj/item/weapon/tank/oxygen/onetankbomb/full)
new type(src.loc)
qdel(src)
/client/proc/spawn_tanktransferbomb()
set category = "Debug"
set desc = "Spawn a tank transfer valve bomb"
set name = "Instant TTV"
if(!check_rights(R_SPAWN)) return
var/obj/effect/spawner/newbomb/proto = /obj/effect/spawner/newbomb/radio/custom
var/p = tgui_input_number(usr, "Enter phoron amount (mol):","Phoron", initial(proto.phoron_amt))
if(p == null) return
var/o = tgui_input_number(usr, "Enter oxygen amount (mol):","Oxygen", initial(proto.oxygen_amt))
if(o == null) return
var/c = tgui_input_number(usr, "Enter carbon dioxide amount (mol):","Carbon Dioxide", initial(proto.carbon_amt))
if(c == null) return
new /obj/effect/spawner/newbomb/radio/custom(get_turf(mob), p, o, c)
/obj/effect/spawner/newbomb
name = "TTV bomb"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
var/assembly_type = /obj/item/device/assembly/signaler
//Note that the maximum amount of gas you can put in a 70L air tank at 1013.25 kPa and 519K is 16.44 mol.
var/phoron_amt = 12
var/oxygen_amt = 18
var/carbon_amt = 0
/obj/effect/spawner/newbomb/timer
name = "TTV bomb - timer"
assembly_type = /obj/item/device/assembly/timer
/obj/effect/spawner/newbomb/timer/syndicate
name = "TTV bomb - merc"
//High yield bombs. Yes, it is possible to make these with toxins
phoron_amt = 18.5
oxygen_amt = 28.5
/obj/effect/spawner/newbomb/proximity
name = "TTV bomb - proximity"
assembly_type = /obj/item/device/assembly/prox_sensor
/obj/effect/spawner/newbomb/radio/custom/New(var/newloc, ph, ox, co)
if(ph != null) phoron_amt = ph
if(ox != null) oxygen_amt = ox
if(co != null) carbon_amt = co
..()
/obj/effect/spawner/newbomb/Initialize(newloc)
..(newloc)
var/obj/item/device/transfer_valve/V = new(src.loc)
var/obj/item/weapon/tank/phoron/PT = new(V)
var/obj/item/weapon/tank/oxygen/OT = new(V)
V.tank_one = PT
V.tank_two = OT
PT.master = V
OT.master = V
PT.valve_welded = 1
PT.air_contents.gas["phoron"] = phoron_amt
PT.air_contents.gas["carbon_dioxide"] = carbon_amt
PT.air_contents.total_moles = phoron_amt + carbon_amt
PT.air_contents.temperature = PHORON_MINIMUM_BURN_TEMPERATURE+1
PT.air_contents.update_values()
OT.valve_welded = 1
OT.air_contents.gas["oxygen"] = oxygen_amt
OT.air_contents.total_moles = oxygen_amt
OT.air_contents.temperature = PHORON_MINIMUM_BURN_TEMPERATURE+1
OT.air_contents.update_values()
var/obj/item/device/assembly/S = new assembly_type(V)
V.attached_device = S
S.holder = V
S.toggle_secure()
V.update_icon()
return INITIALIZE_HINT_QDEL
///////////////////////
//One Tank Bombs, WOOOOOOO! -Luke
///////////////////////
/obj/effect/spawner/onetankbomb
name = "Single-tank bomb"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
// var/assembly_type = /obj/item/device/assembly/signaler
//Note that the maximum amount of gas you can put in a 70L air tank at 1013.25 kPa and 519K is 16.44 mol.
var/phoron_amt = 0
var/oxygen_amt = 0
/obj/effect/spawner/onetankbomb/New(newloc) //just needs an assembly.
..(newloc)
var/type = pick(/obj/item/weapon/tank/phoron/onetankbomb, /obj/item/weapon/tank/oxygen/onetankbomb)
new type(src.loc)
qdel(src)
/obj/effect/spawner/onetankbomb/full
name = "Single-tank bomb"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
// var/assembly_type = /obj/item/device/assembly/signaler
//Note that the maximum amount of gas you can put in a 70L air tank at 1013.25 kPa and 519K is 16.44 mol.
/obj/effect/spawner/onetankbomb/full/New(newloc) //just needs an assembly.
..(newloc)
var/type = pick(/obj/item/weapon/tank/phoron/onetankbomb/full, /obj/item/weapon/tank/oxygen/onetankbomb/full)
new type(src.loc)
qdel(src)
/obj/effect/spawner/onetankbomb/frag
name = "Single-tank bomb"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
// var/assembly_type = /obj/item/device/assembly/signaler
//Note that the maximum amount of gas you can put in a 70L air tank at 1013.25 kPa and 519K is 16.44 mol.
/obj/effect/spawner/onetankbomb/full/New(newloc) //just needs an assembly.
..(newloc)
var/type = pick(/obj/item/weapon/tank/phoron/onetankbomb/full, /obj/item/weapon/tank/oxygen/onetankbomb/full)
new type(src.loc)
qdel(src)
@@ -1,26 +1,26 @@
/obj/effect/gibspawner/generic
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/core)
gibamounts = list(2,2,1)
/obj/effect/gibspawner/generic/New()
gibdirections = list(list(WEST, NORTHWEST, SOUTHWEST, NORTH),list(EAST, NORTHEAST, SOUTHEAST, SOUTH), list())
..()
/obj/effect/gibspawner/human
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/down,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/core)
gibamounts = list(1,1,1,1,1,1,1)
/obj/effect/gibspawner/human/New()
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), alldirs, alldirs, list())
gibamounts[6] = pick(0,1,2)
..()
/obj/effect/gibspawner/robot
sparks = 1
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/robot/up,/obj/effect/decal/cleanable/blood/gibs/robot/down,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot/limb)
gibamounts = list(1,1,1,1,1,1)
/obj/effect/gibspawner/robot/New()
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), alldirs, alldirs)
gibamounts[6] = pick(0,1,2)
/obj/effect/gibspawner/generic
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/core)
gibamounts = list(2,2,1)
/obj/effect/gibspawner/generic/New()
gibdirections = list(list(WEST, NORTHWEST, SOUTHWEST, NORTH),list(EAST, NORTHEAST, SOUTHEAST, SOUTH), list())
..()
/obj/effect/gibspawner/human
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/down,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/core)
gibamounts = list(1,1,1,1,1,1,1)
/obj/effect/gibspawner/human/New()
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), alldirs, alldirs, list())
gibamounts[6] = pick(0,1,2)
..()
/obj/effect/gibspawner/robot
sparks = 1
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/robot/up,/obj/effect/decal/cleanable/blood/gibs/robot/down,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot/limb)
gibamounts = list(1,1,1,1,1,1)
/obj/effect/gibspawner/robot/New()
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), alldirs, alldirs)
gibamounts[6] = pick(0,1,2)
..()
+324 -324
View File
@@ -1,324 +1,324 @@
//generic procs copied from obj/effect/alien
/obj/effect/spider
name = "web"
desc = "it's stringy and sticky"
icon = 'icons/effects/effects.dmi'
anchored = TRUE
density = FALSE
var/health = 15
//similar to weeds, but only barfed out by nurses manually
/obj/effect/spider/ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
if(2.0)
if (prob(50))
qdel(src)
if(3.0)
if (prob(5))
qdel(src)
return
/obj/effect/spider/attackby(var/obj/item/weapon/W, var/mob/user)
user.setClickCooldown(user.get_attack_speed(W))
if(LAZYLEN(W.attack_verb))
visible_message("<span class='warning'>\The [src] has been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]</span>")
else
visible_message("<span class='warning'>\The [src] has been attacked with \the [W][(user ? " by [user]." : ".")]</span>")
var/damage = W.force / 4.0
if(W.has_tool_quality(TOOL_WELDER))
var/obj/item/weapon/weldingtool/WT = W.get_welder()
if(WT.remove_fuel(0, user))
damage = 15
playsound(src, W.usesound, 100, 1)
health -= damage
healthcheck()
/obj/effect/spider/spiderling/attack_hand(mob/living/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
user.do_attack_animation(src)
if(prob(20))
visible_message("<span class='warning'>\The [user] tries to stomp on \the [src], but misses!</span>")
var/list/nearby = oview(2, src)
if(length(nearby))
walk_to(src, pick(nearby), 2)
return
visible_message("<span class='warning'>\The [user] stomps \the [src] dead!</span>")
die()
/obj/effect/spider/bullet_act(var/obj/item/projectile/Proj)
..()
health -= Proj.get_structure_damage()
healthcheck()
/obj/effect/spider/proc/die()
qdel(src)
/obj/effect/spider/proc/healthcheck()
if(health <= 0)
die()
/obj/effect/spider/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300 + T0C)
health -= 5
healthcheck()
/obj/effect/spider/stickyweb
icon_state = "stickyweb1"
/obj/effect/spider/stickyweb/Initialize()
if(prob(50))
icon_state = "stickyweb2"
return ..()
/obj/effect/spider/stickyweb/CanPass(atom/movable/mover, turf/target)
if(istype(mover, /mob/living/simple_mob/animal/giant_spider))
return TRUE
else if(istype(mover, /mob/living))
if(prob(50))
to_chat(mover, span("warning", "You get stuck in \the [src] for a moment."))
return FALSE
else if(istype(mover, /obj/item/projectile))
return prob(30)
return TRUE
/obj/effect/spider/eggcluster
name = "egg cluster"
desc = "They seem to pulse slightly with an inner life"
icon_state = "eggs"
var/amount_grown = 0
var/spiders_min = 6
var/spiders_max = 24
var/spider_type = /obj/effect/spider/spiderling
var/faction = "spiders"
/obj/effect/spider/eggcluster/Initialize()
pixel_x = rand(3,-3)
pixel_y = rand(3,-3)
START_PROCESSING(SSobj, src)
return ..()
/obj/effect/spider/eggcluster/New(var/location, var/atom/parent)
get_light_and_color(parent)
..()
/obj/effect/spider/eggcluster/Destroy()
STOP_PROCESSING(SSobj, src)
if(istype(loc, /obj/item/organ/external))
var/obj/item/organ/external/O = loc
O.implants -= src
return ..()
/obj/effect/spider/eggcluster/process()
amount_grown += rand(0,2)
if(amount_grown >= 100)
var/num = rand(spiders_min, spiders_max)
var/obj/item/organ/external/O = null
if(istype(loc, /obj/item/organ/external))
O = loc
for(var/i=0, i<num, i++)
var/obj/effect/spider/spiderling/spiderling = new spider_type(src.loc, src)
if(O)
O.implants += spiderling
spiderling.faction = faction
qdel(src)
/obj/effect/spider/eggcluster/small
spiders_min = 1
spiders_max = 3
/obj/effect/spider/eggcluster/small/frost
spider_type = /obj/effect/spider/spiderling/frost
/obj/effect/spider/eggcluster/royal
spiders_min = 2
spiders_max = 5
spider_type = /obj/effect/spider/spiderling/varied
/obj/effect/spider/spiderling
name = "spiderling"
desc = "It never stays still for long."
icon_state = "spiderling"
anchored = FALSE
layer = HIDING_LAYER
health = 3
var/last_itch = 0
var/amount_grown = 0
var/obj/machinery/atmospherics/unary/vent_pump/entry_vent
var/travelling_in_vent = 0
var/list/grow_as = list(/mob/living/simple_mob/animal/giant_spider, /mob/living/simple_mob/animal/giant_spider/hunter)
var/faction = "spiders"
var/stunted = FALSE
/obj/effect/spider/spiderling/frost
grow_as = list(/mob/living/simple_mob/animal/giant_spider/frost)
/obj/effect/spider/spiderling/varied
grow_as = list(/mob/living/simple_mob/animal/giant_spider, /mob/living/simple_mob/animal/giant_spider/nurse, /mob/living/simple_mob/animal/giant_spider/hunter,
/mob/living/simple_mob/animal/giant_spider/frost, /mob/living/simple_mob/animal/giant_spider/electric, /mob/living/simple_mob/animal/giant_spider/lurker,
/mob/living/simple_mob/animal/giant_spider/pepper, /mob/living/simple_mob/animal/giant_spider/thermic, /mob/living/simple_mob/animal/giant_spider/tunneler,
/mob/living/simple_mob/animal/giant_spider/webslinger, /mob/living/simple_mob/animal/giant_spider/phorogenic, /mob/living/simple_mob/animal/giant_spider/carrier,
/mob/living/simple_mob/animal/giant_spider/ion)
/obj/effect/spider/spiderling/New(var/location, var/atom/parent)
pixel_x = rand(6,-6)
pixel_y = rand(6,-6)
START_PROCESSING(SSobj, src)
//50% chance to grow up
if(amount_grown != -1 && prob(50))
amount_grown = 1
get_light_and_color(parent)
..()
/obj/effect/spider/spiderling/Destroy()
STOP_PROCESSING(SSobj, src)
walk(src, 0) // Because we might have called walk_to, we must stop the walk loop or BYOND keeps an internal reference to us forever.
return ..()
/obj/effect/spider/spiderling/Bump(atom/user)
if(istype(user, /obj/structure/table))
src.loc = user.loc
else
..()
/obj/effect/spider/spiderling/die()
visible_message("<span class='alert'>[src] dies!</span>")
new /obj/effect/decal/cleanable/spiderling_remains(src.loc)
..()
/obj/effect/spider/spiderling/healthcheck()
if(health <= 0)
die()
/obj/effect/spider/spiderling/process()
healthcheck()
if(travelling_in_vent)
if(istype(src.loc, /turf))
travelling_in_vent = 0
entry_vent = null
else if(entry_vent)
if(get_dist(src, entry_vent) <= 1)
//VOREStation Edit Start
var/obj/machinery/atmospherics/unary/vent_pump/exit_vent = get_safe_ventcrawl_target(entry_vent)
if(!exit_vent)
return
spawn(rand(20,60))
loc = exit_vent
var/travel_time = round(get_dist(loc, exit_vent.loc) / 2)
spawn(travel_time)
if(!exit_vent || exit_vent.welded)
loc = entry_vent
entry_vent = null
return
if(prob(50))
src.visible_message("<span class='notice'>You hear something squeezing through the ventilation ducts.</span>",2)
sleep(travel_time)
if(!exit_vent || exit_vent.welded)
loc = entry_vent
entry_vent = null
return
loc = exit_vent.loc
entry_vent = null
var/area/new_area = get_area(loc)
if(new_area)
new_area.Entered(src)
//VOREStation Edit End
//=================
if(isturf(loc))
skitter()
else if(isorgan(loc))
if(amount_grown < 0) amount_grown = 1
var/obj/item/organ/external/O = loc
if(!O.owner || O.owner.stat == DEAD || amount_grown > 80)
O.implants -= src
src.loc = O.owner ? O.owner.loc : O.loc
src.visible_message("<span class='warning'>\A [src] makes its way out of [O.owner ? "[O.owner]'s [O.name]" : "\the [O]"]!</span>")
if(O.owner)
O.owner.apply_damage(1, BRUTE, O.organ_tag)
else if(prob(1))
O.owner.apply_damage(1, TOX, O.organ_tag)
if(world.time > last_itch + 30 SECONDS)
last_itch = world.time
to_chat(O.owner, "<span class='notice'>Your [O.name] itches...</span>")
else if(prob(1))
src.visible_message("<b>\The [src]</b> skitters.")
if(amount_grown >= 0)
amount_grown += rand(0,2)
/obj/effect/spider/spiderling/proc/skitter()
if(isturf(loc))
if(prob(25))
var/list/nearby = trange(5, src) - loc
if(nearby.len)
var/target_atom = pick(nearby)
walk_to(src, target_atom, 5)
if(prob(25))
src.visible_message("<span class='notice'>\The [src] skitters[pick(" away"," around","")].</span>")
else if(amount_grown < 75 && prob(5))
//vent crawl!
for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(7,src))
if(!v.welded)
entry_vent = v
walk_to(src, entry_vent, 5)
break
if(amount_grown >= 100)
var/spawn_type = pick(grow_as)
var/mob/living/simple_mob/animal/giant_spider/GS = new spawn_type(src.loc, src)
GS.faction = faction
if(stunted)
spawn(2)
GS.make_spiderling()
qdel(src)
/obj/effect/spider/spiderling/stunted
stunted = TRUE
grow_as = list(/mob/living/simple_mob/animal/giant_spider, /mob/living/simple_mob/animal/giant_spider/hunter)
/obj/effect/spider/spiderling/non_growing
amount_grown = -1
/obj/effect/spider/spiderling/princess
name = "royal spiderling"
desc = "There's a special aura about this one."
grow_as = list(/mob/living/simple_mob/animal/giant_spider/nurse/queen)
/obj/effect/spider/spiderling/princess/New(var/location, var/atom/parent)
..()
amount_grown = 50
/obj/effect/decal/cleanable/spiderling_remains
name = "spiderling remains"
desc = "Green squishy mess."
icon = 'icons/effects/effects.dmi'
icon_state = "greenshatter"
/obj/effect/spider/cocoon
name = "cocoon"
desc = "Something wrapped in silky spider web"
icon_state = "cocoon1"
health = 60
/obj/effect/spider/cocoon/New()
icon_state = pick("cocoon1","cocoon2","cocoon3")
/obj/effect/spider/cocoon/Destroy()
src.visible_message("<span class='warning'>\The [src] splits open.</span>")
for(var/atom/movable/A in contents)
A.loc = src.loc
return ..()
//generic procs copied from obj/effect/alien
/obj/effect/spider
name = "web"
desc = "it's stringy and sticky"
icon = 'icons/effects/effects.dmi'
anchored = TRUE
density = FALSE
var/health = 15
//similar to weeds, but only barfed out by nurses manually
/obj/effect/spider/ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
if(2.0)
if (prob(50))
qdel(src)
if(3.0)
if (prob(5))
qdel(src)
return
/obj/effect/spider/attackby(var/obj/item/weapon/W, var/mob/user)
user.setClickCooldown(user.get_attack_speed(W))
if(LAZYLEN(W.attack_verb))
visible_message("<span class='warning'>\The [src] has been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]</span>")
else
visible_message("<span class='warning'>\The [src] has been attacked with \the [W][(user ? " by [user]." : ".")]</span>")
var/damage = W.force / 4.0
if(W.has_tool_quality(TOOL_WELDER))
var/obj/item/weapon/weldingtool/WT = W.get_welder()
if(WT.remove_fuel(0, user))
damage = 15
playsound(src, W.usesound, 100, 1)
health -= damage
healthcheck()
/obj/effect/spider/spiderling/attack_hand(mob/living/user)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
user.do_attack_animation(src)
if(prob(20))
visible_message("<span class='warning'>\The [user] tries to stomp on \the [src], but misses!</span>")
var/list/nearby = oview(2, src)
if(length(nearby))
walk_to(src, pick(nearby), 2)
return
visible_message("<span class='warning'>\The [user] stomps \the [src] dead!</span>")
die()
/obj/effect/spider/bullet_act(var/obj/item/projectile/Proj)
..()
health -= Proj.get_structure_damage()
healthcheck()
/obj/effect/spider/proc/die()
qdel(src)
/obj/effect/spider/proc/healthcheck()
if(health <= 0)
die()
/obj/effect/spider/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300 + T0C)
health -= 5
healthcheck()
/obj/effect/spider/stickyweb
icon_state = "stickyweb1"
/obj/effect/spider/stickyweb/Initialize()
if(prob(50))
icon_state = "stickyweb2"
return ..()
/obj/effect/spider/stickyweb/CanPass(atom/movable/mover, turf/target)
if(istype(mover, /mob/living/simple_mob/animal/giant_spider))
return TRUE
else if(istype(mover, /mob/living))
if(prob(50))
to_chat(mover, span("warning", "You get stuck in \the [src] for a moment."))
return FALSE
else if(istype(mover, /obj/item/projectile))
return prob(30)
return TRUE
/obj/effect/spider/eggcluster
name = "egg cluster"
desc = "They seem to pulse slightly with an inner life"
icon_state = "eggs"
var/amount_grown = 0
var/spiders_min = 6
var/spiders_max = 24
var/spider_type = /obj/effect/spider/spiderling
var/faction = "spiders"
/obj/effect/spider/eggcluster/Initialize()
pixel_x = rand(3,-3)
pixel_y = rand(3,-3)
START_PROCESSING(SSobj, src)
return ..()
/obj/effect/spider/eggcluster/New(var/location, var/atom/parent)
get_light_and_color(parent)
..()
/obj/effect/spider/eggcluster/Destroy()
STOP_PROCESSING(SSobj, src)
if(istype(loc, /obj/item/organ/external))
var/obj/item/organ/external/O = loc
O.implants -= src
return ..()
/obj/effect/spider/eggcluster/process()
amount_grown += rand(0,2)
if(amount_grown >= 100)
var/num = rand(spiders_min, spiders_max)
var/obj/item/organ/external/O = null
if(istype(loc, /obj/item/organ/external))
O = loc
for(var/i=0, i<num, i++)
var/obj/effect/spider/spiderling/spiderling = new spider_type(src.loc, src)
if(O)
O.implants += spiderling
spiderling.faction = faction
qdel(src)
/obj/effect/spider/eggcluster/small
spiders_min = 1
spiders_max = 3
/obj/effect/spider/eggcluster/small/frost
spider_type = /obj/effect/spider/spiderling/frost
/obj/effect/spider/eggcluster/royal
spiders_min = 2
spiders_max = 5
spider_type = /obj/effect/spider/spiderling/varied
/obj/effect/spider/spiderling
name = "spiderling"
desc = "It never stays still for long."
icon_state = "spiderling"
anchored = FALSE
layer = HIDING_LAYER
health = 3
var/last_itch = 0
var/amount_grown = 0
var/obj/machinery/atmospherics/unary/vent_pump/entry_vent
var/travelling_in_vent = 0
var/list/grow_as = list(/mob/living/simple_mob/animal/giant_spider, /mob/living/simple_mob/animal/giant_spider/hunter)
var/faction = "spiders"
var/stunted = FALSE
/obj/effect/spider/spiderling/frost
grow_as = list(/mob/living/simple_mob/animal/giant_spider/frost)
/obj/effect/spider/spiderling/varied
grow_as = list(/mob/living/simple_mob/animal/giant_spider, /mob/living/simple_mob/animal/giant_spider/nurse, /mob/living/simple_mob/animal/giant_spider/hunter,
/mob/living/simple_mob/animal/giant_spider/frost, /mob/living/simple_mob/animal/giant_spider/electric, /mob/living/simple_mob/animal/giant_spider/lurker,
/mob/living/simple_mob/animal/giant_spider/pepper, /mob/living/simple_mob/animal/giant_spider/thermic, /mob/living/simple_mob/animal/giant_spider/tunneler,
/mob/living/simple_mob/animal/giant_spider/webslinger, /mob/living/simple_mob/animal/giant_spider/phorogenic, /mob/living/simple_mob/animal/giant_spider/carrier,
/mob/living/simple_mob/animal/giant_spider/ion)
/obj/effect/spider/spiderling/New(var/location, var/atom/parent)
pixel_x = rand(6,-6)
pixel_y = rand(6,-6)
START_PROCESSING(SSobj, src)
//50% chance to grow up
if(amount_grown != -1 && prob(50))
amount_grown = 1
get_light_and_color(parent)
..()
/obj/effect/spider/spiderling/Destroy()
STOP_PROCESSING(SSobj, src)
walk(src, 0) // Because we might have called walk_to, we must stop the walk loop or BYOND keeps an internal reference to us forever.
return ..()
/obj/effect/spider/spiderling/Bump(atom/user)
if(istype(user, /obj/structure/table))
src.loc = user.loc
else
..()
/obj/effect/spider/spiderling/die()
visible_message("<span class='alert'>[src] dies!</span>")
new /obj/effect/decal/cleanable/spiderling_remains(src.loc)
..()
/obj/effect/spider/spiderling/healthcheck()
if(health <= 0)
die()
/obj/effect/spider/spiderling/process()
healthcheck()
if(travelling_in_vent)
if(istype(src.loc, /turf))
travelling_in_vent = 0
entry_vent = null
else if(entry_vent)
if(get_dist(src, entry_vent) <= 1)
//VOREStation Edit Start
var/obj/machinery/atmospherics/unary/vent_pump/exit_vent = get_safe_ventcrawl_target(entry_vent)
if(!exit_vent)
return
spawn(rand(20,60))
loc = exit_vent
var/travel_time = round(get_dist(loc, exit_vent.loc) / 2)
spawn(travel_time)
if(!exit_vent || exit_vent.welded)
loc = entry_vent
entry_vent = null
return
if(prob(50))
src.visible_message("<span class='notice'>You hear something squeezing through the ventilation ducts.</span>",2)
sleep(travel_time)
if(!exit_vent || exit_vent.welded)
loc = entry_vent
entry_vent = null
return
loc = exit_vent.loc
entry_vent = null
var/area/new_area = get_area(loc)
if(new_area)
new_area.Entered(src)
//VOREStation Edit End
//=================
if(isturf(loc))
skitter()
else if(isorgan(loc))
if(amount_grown < 0) amount_grown = 1
var/obj/item/organ/external/O = loc
if(!O.owner || O.owner.stat == DEAD || amount_grown > 80)
O.implants -= src
src.loc = O.owner ? O.owner.loc : O.loc
src.visible_message("<span class='warning'>\A [src] makes its way out of [O.owner ? "[O.owner]'s [O.name]" : "\the [O]"]!</span>")
if(O.owner)
O.owner.apply_damage(1, BRUTE, O.organ_tag)
else if(prob(1))
O.owner.apply_damage(1, TOX, O.organ_tag)
if(world.time > last_itch + 30 SECONDS)
last_itch = world.time
to_chat(O.owner, "<span class='notice'>Your [O.name] itches...</span>")
else if(prob(1))
src.visible_message("<b>\The [src]</b> skitters.")
if(amount_grown >= 0)
amount_grown += rand(0,2)
/obj/effect/spider/spiderling/proc/skitter()
if(isturf(loc))
if(prob(25))
var/list/nearby = trange(5, src) - loc
if(nearby.len)
var/target_atom = pick(nearby)
walk_to(src, target_atom, 5)
if(prob(25))
src.visible_message("<span class='notice'>\The [src] skitters[pick(" away"," around","")].</span>")
else if(amount_grown < 75 && prob(5))
//vent crawl!
for(var/obj/machinery/atmospherics/unary/vent_pump/v in view(7,src))
if(!v.welded)
entry_vent = v
walk_to(src, entry_vent, 5)
break
if(amount_grown >= 100)
var/spawn_type = pick(grow_as)
var/mob/living/simple_mob/animal/giant_spider/GS = new spawn_type(src.loc, src)
GS.faction = faction
if(stunted)
spawn(2)
GS.make_spiderling()
qdel(src)
/obj/effect/spider/spiderling/stunted
stunted = TRUE
grow_as = list(/mob/living/simple_mob/animal/giant_spider, /mob/living/simple_mob/animal/giant_spider/hunter)
/obj/effect/spider/spiderling/non_growing
amount_grown = -1
/obj/effect/spider/spiderling/princess
name = "royal spiderling"
desc = "There's a special aura about this one."
grow_as = list(/mob/living/simple_mob/animal/giant_spider/nurse/queen)
/obj/effect/spider/spiderling/princess/New(var/location, var/atom/parent)
..()
amount_grown = 50
/obj/effect/decal/cleanable/spiderling_remains
name = "spiderling remains"
desc = "Green squishy mess."
icon = 'icons/effects/effects.dmi'
icon_state = "greenshatter"
/obj/effect/spider/cocoon
name = "cocoon"
desc = "Something wrapped in silky spider web"
icon_state = "cocoon1"
health = 60
/obj/effect/spider/cocoon/New()
icon_state = pick("cocoon1","cocoon2","cocoon3")
/obj/effect/spider/cocoon/Destroy()
src.visible_message("<span class='warning'>\The [src] splits open.</span>")
for(var/atom/movable/A in contents)
A.loc = src.loc
return ..()
+73 -73
View File
@@ -1,74 +1,74 @@
// Uncomment this define to check for possible lengthy processing of emp_act()s.
// If emp_act() takes more than defined deciseconds (1/10 seconds) an admin message and log is created.
// I do not recommend having this uncommented on main server, it probably causes a bit more lag, espicially with larger EMPs.
// #define EMPDEBUG 10
/proc/empulse(turf/epicenter, first_range, second_range, third_range, fourth_range, log=0)
if(!epicenter) return
if(!istype(epicenter, /turf))
epicenter = get_turf(epicenter.loc)
if(log)
message_admins("EMP with size ([first_range], [second_range], [third_range], [fourth_range]) in area [epicenter.loc.name] ")
log_game("EMP with size ([first_range], [second_range], [third_range], [fourth_range]) in area [epicenter.loc.name] ")
if(first_range > 1)
var/obj/effect/overlay/pulse = new /obj/effect/overlay(epicenter)
pulse.icon = 'icons/effects/effects.dmi'
pulse.icon_state = "emppulse"
pulse.name = "emp pulse"
pulse.anchored = TRUE
spawn(20)
qdel(pulse)
if(first_range > second_range)
second_range = first_range
if(second_range > third_range)
third_range = second_range
if(third_range > fourth_range)
fourth_range = third_range
for(var/mob/M in range(first_range, epicenter))
M << 'sound/effects/EMPulse.ogg'
for(var/atom/T in range(fourth_range, epicenter))
#ifdef EMPDEBUG
var/time = world.timeofday
#endif
var/distance = get_dist(epicenter, T)
if(distance < 0)
distance = 0
//Worst effects, really hurts
if(distance < first_range)
T.emp_act(1)
else if(distance == first_range)
if(prob(50))
T.emp_act(1)
else
T.emp_act(2)
//Slightly less painful
else if(distance <= second_range)
T.emp_act(2)
else if(distance == second_range)
if(prob(50))
T.emp_act(2)
else
T.emp_act(3)
//Even less slightly less painful
else if(distance <= third_range)
T.emp_act(3)
else if(distance == third_range)
if(prob(50))
T.emp_act(2)
else
T.emp_act(3)
//This should be more or less harmless
else if(distance <= fourth_range)
T.emp_act(4)
#ifdef EMPDEBUG
if((world.timeofday - time) >= EMPDEBUG)
log_and_message_admins("EMPDEBUG: [T.name] - [T.type] - took [world.timeofday - time]ds to process emp_act()!")
#endif
// Uncomment this define to check for possible lengthy processing of emp_act()s.
// If emp_act() takes more than defined deciseconds (1/10 seconds) an admin message and log is created.
// I do not recommend having this uncommented on main server, it probably causes a bit more lag, espicially with larger EMPs.
// #define EMPDEBUG 10
/proc/empulse(turf/epicenter, first_range, second_range, third_range, fourth_range, log=0)
if(!epicenter) return
if(!istype(epicenter, /turf))
epicenter = get_turf(epicenter.loc)
if(log)
message_admins("EMP with size ([first_range], [second_range], [third_range], [fourth_range]) in area [epicenter.loc.name] ")
log_game("EMP with size ([first_range], [second_range], [third_range], [fourth_range]) in area [epicenter.loc.name] ")
if(first_range > 1)
var/obj/effect/overlay/pulse = new /obj/effect/overlay(epicenter)
pulse.icon = 'icons/effects/effects.dmi'
pulse.icon_state = "emppulse"
pulse.name = "emp pulse"
pulse.anchored = TRUE
spawn(20)
qdel(pulse)
if(first_range > second_range)
second_range = first_range
if(second_range > third_range)
third_range = second_range
if(third_range > fourth_range)
fourth_range = third_range
for(var/mob/M in range(first_range, epicenter))
M << 'sound/effects/EMPulse.ogg'
for(var/atom/T in range(fourth_range, epicenter))
#ifdef EMPDEBUG
var/time = world.timeofday
#endif
var/distance = get_dist(epicenter, T)
if(distance < 0)
distance = 0
//Worst effects, really hurts
if(distance < first_range)
T.emp_act(1)
else if(distance == first_range)
if(prob(50))
T.emp_act(1)
else
T.emp_act(2)
//Slightly less painful
else if(distance <= second_range)
T.emp_act(2)
else if(distance == second_range)
if(prob(50))
T.emp_act(2)
else
T.emp_act(3)
//Even less slightly less painful
else if(distance <= third_range)
T.emp_act(3)
else if(distance == third_range)
if(prob(50))
T.emp_act(2)
else
T.emp_act(3)
//This should be more or less harmless
else if(distance <= fourth_range)
T.emp_act(4)
#ifdef EMPDEBUG
if((world.timeofday - time) >= EMPDEBUG)
log_and_message_admins("EMPDEBUG: [T.name] - [T.type] - took [world.timeofday - time]ds to process emp_act()!")
#endif
return 1
+112 -112
View File
@@ -1,112 +1,112 @@
//TODO: Flash range does nothing currently
/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, z_transfer = UP|DOWN, shaped)
var/multi_z_scalar = config.multi_z_explosion_scalar
spawn(0)
var/start = world.timeofday
epicenter = get_turf(epicenter)
if(!epicenter) return
// Handles recursive propagation of explosions.
if(z_transfer && multi_z_scalar)
var/adj_dev = max(0, (multi_z_scalar * devastation_range) - (shaped ? 2 : 0) )
var/adj_heavy = max(0, (multi_z_scalar * heavy_impact_range) - (shaped ? 2 : 0) )
var/adj_light = max(0, (multi_z_scalar * light_impact_range) - (shaped ? 2 : 0) )
var/adj_flash = max(0, (multi_z_scalar * flash_range) - (shaped ? 2 : 0) )
if(adj_dev > 0 || adj_heavy > 0)
if(HasAbove(epicenter.z) && z_transfer & UP)
explosion(GetAbove(epicenter), round(adj_dev), round(adj_heavy), round(adj_light), round(adj_flash), 0, UP, shaped)
if(HasBelow(epicenter.z) && z_transfer & DOWN)
explosion(GetBelow(epicenter), round(adj_dev), round(adj_heavy), round(adj_light), round(adj_flash), 0, DOWN, shaped)
var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flash_range)
// Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves.
// Stereo users will also hear the direction of the explosion!
// Calculate far explosion sound range. Only allow the sound effect for heavy/devastating explosions.
// 3/7/14 will calculate to 80 + 35
var/far_dist = 0
far_dist += heavy_impact_range * 5
far_dist += devastation_range * 20
var/frequency = get_rand_frequency()
for(var/mob/M in player_list)
if(M.z == epicenter.z)
var/turf/M_turf = get_turf(M)
var/dist = get_dist(M_turf, epicenter)
// If inside the blast radius + world.view - 2
if(dist <= round(max_range + world.view - 2, 1))
M.playsound_local(epicenter, get_sfx("explosion"), 100, 1, frequency, falloff = 5) // get_sfx() is so that everyone gets the same sound
else if(dist <= far_dist)
var/far_volume = CLAMP(far_dist, 30, 50) // Volume is based on explosion size and dist
far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5)
var/close = range(world.view+round(devastation_range,1), epicenter)
// to all distanced mobs play a different sound
for(var/mob/M in player_list)
if(M.z == epicenter.z)
if(!(M in close))
// check if the mob can hear
if(M.ear_deaf <= 0 || !M.ear_deaf)
if(!istype(M.loc,/turf/space))
M << 'sound/effects/explosionfar.ogg'
if(adminlog)
message_admins("Explosion with [shaped ? "shaped" : "non-shaped"] size ([devastation_range], [heavy_impact_range], [light_impact_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z]) (<A HREF='?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[epicenter.x];Y=[epicenter.y];Z=[epicenter.z]'>JMP</a>)")
log_game("Explosion with [shaped ? "shaped" : "non-shaped"] size ([devastation_range], [heavy_impact_range], [light_impact_range]) in area [epicenter.loc.name] ")
var/approximate_intensity = (devastation_range * 3) + (heavy_impact_range * 2) + light_impact_range
var/powernet_rebuild_was_deferred_already = defer_powernet_rebuild
// Large enough explosion. For performance reasons, powernets will be rebuilt manually
if(!defer_powernet_rebuild && (approximate_intensity > 25))
defer_powernet_rebuild = 1
if(heavy_impact_range > 1)
var/datum/effect/system/explosion/E = new/datum/effect/system/explosion()
E.set_up(epicenter)
E.start()
var/x0 = epicenter.x
var/y0 = epicenter.y
var/z0 = epicenter.z
if(config.use_recursive_explosions)
var/power = devastation_range * 2 + heavy_impact_range + light_impact_range //The ranges add up, ie light 14 includes both heavy 7 and devestation 3. So this calculation means devestation counts for 4, heavy for 2 and light for 1 power, giving us a cap of 27 power.
explosion_rec(epicenter, power, shaped)
else
for(var/turf/T in trange(max_range, epicenter))
var/dist = sqrt((T.x - x0)**2 + (T.y - y0)**2)
if(dist < devastation_range) dist = 1
else if(dist < heavy_impact_range) dist = 2
else if(dist < light_impact_range) dist = 3
else continue
if(!T)
T = locate(x0,y0,z0)
for(var/atom_movable in T.contents) //bypass type checking since only atom/movable can be contained by turfs anyway
var/atom/movable/AM = atom_movable
if(AM && AM.simulated) AM.ex_act(dist)
T.ex_act(dist)
var/took = (world.timeofday-start)/10
//You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare
if(Debug2) to_world_log("## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds.")
//Machines which report explosions.
for(var/i,i<=doppler_arrays.len,i++)
var/obj/machinery/doppler_array/Array = doppler_arrays[i]
if(Array)
Array.sense_explosion(x0,y0,z0,devastation_range,heavy_impact_range,light_impact_range,took)
sleep(8)
if(!powernet_rebuild_was_deferred_already && defer_powernet_rebuild)
SSmachines.makepowernets()
defer_powernet_rebuild = 0
return 1
/proc/secondaryexplosion(turf/epicenter, range)
for(var/turf/tile in range(range, epicenter))
tile.ex_act(2)
//TODO: Flash range does nothing currently
/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, z_transfer = UP|DOWN, shaped)
var/multi_z_scalar = config.multi_z_explosion_scalar
spawn(0)
var/start = world.timeofday
epicenter = get_turf(epicenter)
if(!epicenter) return
// Handles recursive propagation of explosions.
if(z_transfer && multi_z_scalar)
var/adj_dev = max(0, (multi_z_scalar * devastation_range) - (shaped ? 2 : 0) )
var/adj_heavy = max(0, (multi_z_scalar * heavy_impact_range) - (shaped ? 2 : 0) )
var/adj_light = max(0, (multi_z_scalar * light_impact_range) - (shaped ? 2 : 0) )
var/adj_flash = max(0, (multi_z_scalar * flash_range) - (shaped ? 2 : 0) )
if(adj_dev > 0 || adj_heavy > 0)
if(HasAbove(epicenter.z) && z_transfer & UP)
explosion(GetAbove(epicenter), round(adj_dev), round(adj_heavy), round(adj_light), round(adj_flash), 0, UP, shaped)
if(HasBelow(epicenter.z) && z_transfer & DOWN)
explosion(GetBelow(epicenter), round(adj_dev), round(adj_heavy), round(adj_light), round(adj_flash), 0, DOWN, shaped)
var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flash_range)
// Play sounds; we want sounds to be different depending on distance so we will manually do it ourselves.
// Stereo users will also hear the direction of the explosion!
// Calculate far explosion sound range. Only allow the sound effect for heavy/devastating explosions.
// 3/7/14 will calculate to 80 + 35
var/far_dist = 0
far_dist += heavy_impact_range * 5
far_dist += devastation_range * 20
var/frequency = get_rand_frequency()
for(var/mob/M in player_list)
if(M.z == epicenter.z)
var/turf/M_turf = get_turf(M)
var/dist = get_dist(M_turf, epicenter)
// If inside the blast radius + world.view - 2
if(dist <= round(max_range + world.view - 2, 1))
M.playsound_local(epicenter, get_sfx("explosion"), 100, 1, frequency, falloff = 5) // get_sfx() is so that everyone gets the same sound
else if(dist <= far_dist)
var/far_volume = CLAMP(far_dist, 30, 50) // Volume is based on explosion size and dist
far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5)
var/close = range(world.view+round(devastation_range,1), epicenter)
// to all distanced mobs play a different sound
for(var/mob/M in player_list)
if(M.z == epicenter.z)
if(!(M in close))
// check if the mob can hear
if(M.ear_deaf <= 0 || !M.ear_deaf)
if(!istype(M.loc,/turf/space))
M << 'sound/effects/explosionfar.ogg'
if(adminlog)
message_admins("Explosion with [shaped ? "shaped" : "non-shaped"] size ([devastation_range], [heavy_impact_range], [light_impact_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z]) (<A HREF='?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[epicenter.x];Y=[epicenter.y];Z=[epicenter.z]'>JMP</a>)")
log_game("Explosion with [shaped ? "shaped" : "non-shaped"] size ([devastation_range], [heavy_impact_range], [light_impact_range]) in area [epicenter.loc.name] ")
var/approximate_intensity = (devastation_range * 3) + (heavy_impact_range * 2) + light_impact_range
var/powernet_rebuild_was_deferred_already = defer_powernet_rebuild
// Large enough explosion. For performance reasons, powernets will be rebuilt manually
if(!defer_powernet_rebuild && (approximate_intensity > 25))
defer_powernet_rebuild = 1
if(heavy_impact_range > 1)
var/datum/effect/system/explosion/E = new/datum/effect/system/explosion()
E.set_up(epicenter)
E.start()
var/x0 = epicenter.x
var/y0 = epicenter.y
var/z0 = epicenter.z
if(config.use_recursive_explosions)
var/power = devastation_range * 2 + heavy_impact_range + light_impact_range //The ranges add up, ie light 14 includes both heavy 7 and devestation 3. So this calculation means devestation counts for 4, heavy for 2 and light for 1 power, giving us a cap of 27 power.
explosion_rec(epicenter, power, shaped)
else
for(var/turf/T in trange(max_range, epicenter))
var/dist = sqrt((T.x - x0)**2 + (T.y - y0)**2)
if(dist < devastation_range) dist = 1
else if(dist < heavy_impact_range) dist = 2
else if(dist < light_impact_range) dist = 3
else continue
if(!T)
T = locate(x0,y0,z0)
for(var/atom_movable in T.contents) //bypass type checking since only atom/movable can be contained by turfs anyway
var/atom/movable/AM = atom_movable
if(AM && AM.simulated) AM.ex_act(dist)
T.ex_act(dist)
var/took = (world.timeofday-start)/10
//You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare
if(Debug2) to_world_log("## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds.")
//Machines which report explosions.
for(var/i,i<=doppler_arrays.len,i++)
var/obj/machinery/doppler_array/Array = doppler_arrays[i]
if(Array)
Array.sense_explosion(x0,y0,z0,devastation_range,heavy_impact_range,light_impact_range,took)
sleep(8)
if(!powernet_rebuild_was_deferred_already && defer_powernet_rebuild)
SSmachines.makepowernets()
defer_powernet_rebuild = 0
return 1
/proc/secondaryexplosion(turf/epicenter, range)
for(var/turf/tile in range(range, epicenter))
tile.ex_act(2)
+114 -114
View File
@@ -1,114 +1,114 @@
/client/proc/kaboom()
var/power = tgui_input_number(src, "power?", "power?")
var/turf/T = get_turf(src.mob)
explosion_rec(T, power)
/obj
var/explosion_resistance
/proc/explosion_rec(turf/epicenter, power)
var/list/explosion_turfs = list()
var/explosion_in_progress = 0
var/loopbreak = 0
while(explosion_in_progress)
if(loopbreak >= 15) return
spawn(10)
loopbreak++
if(power <= 0) return
epicenter = get_turf(epicenter)
if(!epicenter) return
message_admins("Explosion with size ([power]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z])")
log_game("Explosion with size ([power]) in area [epicenter.loc.name] ")
playsound(epicenter, 'sound/effects/explosionfar.ogg', 100, 1, round(power*2,1) )
playsound(epicenter, "explosion", 100, 1, round(power,1) )
explosion_in_progress = 1
explosion_turfs = list()
explosion_turfs[epicenter] = power
//This steap handles the gathering of turfs which will be ex_act() -ed in the next step. It also ensures each turf gets the maximum possible amount of power dealt to it.
for(var/direction in cardinal)
var/turf/T = get_step(epicenter, direction)
T.explosion_spread(power - epicenter.explosion_resistance, direction, explosion_turfs)
//This step applies the ex_act effects for the explosion, as planned in the previous step.
for(var/turf/T in explosion_turfs)
if(explosion_turfs[T] <= 0) continue
if(!T) continue
//Wow severity looks confusing to calculate... Fret not, I didn't leave you with any additional instructions or help. (just kidding, see the line under the calculation)
var/severity = 4 - round(max(min( 3, ((explosion_turfs[T] - T.explosion_resistance) / (max(3,(power/3)))) ) ,1), 1) //sanity effective power on tile divided by either 3 or one third the total explosion power
// One third because there are three power levels and I
// want each one to take up a third of the crater
var/x = T.x
var/y = T.y
var/z = T.z
T.ex_act(severity)
if(!T)
T = locate(x,y,z)
for(var/atom_movable in T.contents)
var/atom/movable/AM = atom_movable
if(AM && AM.simulated)
AM.ex_act(severity)
explosion_in_progress = 0
/turf
var/explosion_resistance
/turf/space
explosion_resistance = 3
/turf/simulated/open
explosion_resistance = 3
/turf/simulated/floor
explosion_resistance = 1
/turf/simulated/mineral
explosion_resistance = 2
/turf/simulated/shuttle/floor
explosion_resistance = 1
/turf/simulated/shuttle/floor4
explosion_resistance = 1
/turf/simulated/shuttle/plating
explosion_resistance = 1
/turf/simulated/shuttle/wall
explosion_resistance = 10
/turf/simulated/wall
explosion_resistance = 10
//Code-wise, a safe value for power is something up to ~25 or ~30.. This does quite a bit of damage to the station.
//direction is the direction that the spread took to come to this tile. So it is pointing in the main blast direction - meaning where this tile should spread most of it's force.
/turf/proc/explosion_spread(power, direction, var/list/explosion_turfs)
if(power <= 0)
return
if(src in explosion_turfs)
if(explosion_turfs[src] >= power)
return //The turf already sustained and spread a power greated than what we are dealing with. No point spreading again.
explosion_turfs[src] = power
var/spread_power = power - src.explosion_resistance //This is the amount of power that will be spread to the tile in the direction of the blast
for(var/obj/O in src)
if(O.explosion_resistance)
spread_power -= O.explosion_resistance
var/turf/T = get_step(src, direction)
T.explosion_spread(spread_power, direction, explosion_turfs)
T = get_step(src, turn(direction,90))
T.explosion_spread(spread_power, turn(direction,90), explosion_turfs)
T = get_step(src, turn(direction,-90))
T.explosion_spread(spread_power, turn(direction,-90), explosion_turfs)
/turf/unsimulated/explosion_spread(power)
return //So it doesn't get to the parent proc, which simulates explosions
/client/proc/kaboom()
var/power = tgui_input_number(src, "power?", "power?")
var/turf/T = get_turf(src.mob)
explosion_rec(T, power)
/obj
var/explosion_resistance
/proc/explosion_rec(turf/epicenter, power)
var/list/explosion_turfs = list()
var/explosion_in_progress = 0
var/loopbreak = 0
while(explosion_in_progress)
if(loopbreak >= 15) return
spawn(10)
loopbreak++
if(power <= 0) return
epicenter = get_turf(epicenter)
if(!epicenter) return
message_admins("Explosion with size ([power]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z])")
log_game("Explosion with size ([power]) in area [epicenter.loc.name] ")
playsound(epicenter, 'sound/effects/explosionfar.ogg', 100, 1, round(power*2,1) )
playsound(epicenter, "explosion", 100, 1, round(power,1) )
explosion_in_progress = 1
explosion_turfs = list()
explosion_turfs[epicenter] = power
//This steap handles the gathering of turfs which will be ex_act() -ed in the next step. It also ensures each turf gets the maximum possible amount of power dealt to it.
for(var/direction in cardinal)
var/turf/T = get_step(epicenter, direction)
T.explosion_spread(power - epicenter.explosion_resistance, direction, explosion_turfs)
//This step applies the ex_act effects for the explosion, as planned in the previous step.
for(var/turf/T in explosion_turfs)
if(explosion_turfs[T] <= 0) continue
if(!T) continue
//Wow severity looks confusing to calculate... Fret not, I didn't leave you with any additional instructions or help. (just kidding, see the line under the calculation)
var/severity = 4 - round(max(min( 3, ((explosion_turfs[T] - T.explosion_resistance) / (max(3,(power/3)))) ) ,1), 1) //sanity effective power on tile divided by either 3 or one third the total explosion power
// One third because there are three power levels and I
// want each one to take up a third of the crater
var/x = T.x
var/y = T.y
var/z = T.z
T.ex_act(severity)
if(!T)
T = locate(x,y,z)
for(var/atom_movable in T.contents)
var/atom/movable/AM = atom_movable
if(AM && AM.simulated)
AM.ex_act(severity)
explosion_in_progress = 0
/turf
var/explosion_resistance
/turf/space
explosion_resistance = 3
/turf/simulated/open
explosion_resistance = 3
/turf/simulated/floor
explosion_resistance = 1
/turf/simulated/mineral
explosion_resistance = 2
/turf/simulated/shuttle/floor
explosion_resistance = 1
/turf/simulated/shuttle/floor4
explosion_resistance = 1
/turf/simulated/shuttle/plating
explosion_resistance = 1
/turf/simulated/shuttle/wall
explosion_resistance = 10
/turf/simulated/wall
explosion_resistance = 10
//Code-wise, a safe value for power is something up to ~25 or ~30.. This does quite a bit of damage to the station.
//direction is the direction that the spread took to come to this tile. So it is pointing in the main blast direction - meaning where this tile should spread most of it's force.
/turf/proc/explosion_spread(power, direction, var/list/explosion_turfs)
if(power <= 0)
return
if(src in explosion_turfs)
if(explosion_turfs[src] >= power)
return //The turf already sustained and spread a power greated than what we are dealing with. No point spreading again.
explosion_turfs[src] = power
var/spread_power = power - src.explosion_resistance //This is the amount of power that will be spread to the tile in the direction of the blast
for(var/obj/O in src)
if(O.explosion_resistance)
spread_power -= O.explosion_resistance
var/turf/T = get_step(src, direction)
T.explosion_spread(spread_power, direction, explosion_turfs)
T = get_step(src, turn(direction,90))
T.explosion_spread(spread_power, turn(direction,90), explosion_turfs)
T = get_step(src, turn(direction,-90))
T.explosion_spread(spread_power, turn(direction,-90), explosion_turfs)
/turf/unsimulated/explosion_spread(power)
return //So it doesn't get to the parent proc, which simulates explosions
+38 -38
View File
@@ -1,38 +1,38 @@
// APC HULL
/obj/item/frame/apc
name = "\improper APC frame"
desc = "Used for repairing or building APCs"
icon = 'icons/obj/apc_repair.dmi'
icon_state = "apc_frame"
refund_amt = 2
build_wall_only = TRUE
matter = list(MAT_STEEL = 100, MAT_GLASS = 30)
/obj/item/frame/apc/try_build(turf/on_wall, mob/user as mob)
if (get_dist(on_wall, user)>1)
return
var/ndir = get_dir(user, on_wall)
if (!(ndir in cardinal))
return
var/turf/loc = get_turf(user)
var/area/A = loc.loc
if (!istype(loc, /turf/simulated/floor))
to_chat(user, "<span class='warning'>APC cannot be placed on this spot.</span>")
return
if (A.requires_power == 0 || istype(A, /area/space))
to_chat(user, "<span class='warning'>APC cannot be placed in this area.</span>")
return
if (A.get_apc())
to_chat(user, "<span class='warning'>This area already has an APC.</span>")
return //only one APC per area
for(var/obj/machinery/power/terminal/T in loc)
if (T.master)
to_chat(user, "<span class='warning'>There is another network terminal here.</span>")
return
else
new /obj/item/stack/cable_coil(loc, 10)
to_chat(user, "You cut the cables and disassemble the unused power terminal.")
qdel(T)
new /obj/machinery/power/apc(loc, ndir, 1)
qdel(src)
// APC HULL
/obj/item/frame/apc
name = "\improper APC frame"
desc = "Used for repairing or building APCs"
icon = 'icons/obj/apc_repair.dmi'
icon_state = "apc_frame"
refund_amt = 2
build_wall_only = TRUE
matter = list(MAT_STEEL = 100, MAT_GLASS = 30)
/obj/item/frame/apc/try_build(turf/on_wall, mob/user as mob)
if (get_dist(on_wall, user)>1)
return
var/ndir = get_dir(user, on_wall)
if (!(ndir in cardinal))
return
var/turf/loc = get_turf(user)
var/area/A = loc.loc
if (!istype(loc, /turf/simulated/floor))
to_chat(user, "<span class='warning'>APC cannot be placed on this spot.</span>")
return
if (A.requires_power == 0 || istype(A, /area/space))
to_chat(user, "<span class='warning'>APC cannot be placed in this area.</span>")
return
if (A.get_apc())
to_chat(user, "<span class='warning'>This area already has an APC.</span>")
return //only one APC per area
for(var/obj/machinery/power/terminal/T in loc)
if (T.master)
to_chat(user, "<span class='warning'>There is another network terminal here.</span>")
return
else
new /obj/item/stack/cable_coil(loc, 10)
to_chat(user, "You cut the cables and disassemble the unused power terminal.")
qdel(T)
new /obj/machinery/power/apc(loc, ndir, 1)
qdel(src)
+263 -263
View File
@@ -1,263 +1,263 @@
//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/closets/bodybag.dmi'
icon_state = "bodybag_folded"
w_class = ITEMSIZE_SMALL
/obj/item/bodybag/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/item/weapon/storage/box/bodybags
name = "body bags"
desc = "This box contains body bags."
icon_state = "bodybags"
starts_with = list(/obj/item/bodybag = 7)
/obj/structure/closet/body_bag
name = "body bag"
desc = "A plastic bag designed for the storage and transportation of cadavers."
icon = 'icons/obj/closets/bodybag.dmi'
closet_appearance = null
open_sound = 'sound/items/zip.ogg'
close_sound = 'sound/items/zip.ogg'
var/item_path = /obj/item/bodybag
density = FALSE
storage_capacity = (MOB_MEDIUM * 2) - 1
var/contains_body = 0
/obj/structure/closet/body_bag/attackby(var/obj/item/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/pen))
var/t = tgui_input_text(user, "What would you like the label to be?", text("[]", src.name), null, MAX_NAME_LEN )
if (user.get_active_hand() != W)
return
if (!in_range(src, user) && src.loc != user)
return
t = sanitizeSafe(t, MAX_NAME_LEN)
if (t)
src.name = "body bag - "
src.name += t
add_overlay("bodybag_label")
else
src.name = "body bag"
//..() //Doesn't need to run the parent. Since when can fucking bodybags be welded shut? -Agouri
return
else if(W.has_tool_quality(TOOL_WIRECUTTER))
to_chat(user, "You cut the tag off the bodybag")
src.name = "body bag"
cut_overlays()
return
/obj/structure/closet/body_bag/store_mobs(var/stored_units)
contains_body = ..()
return contains_body
/obj/structure/closet/body_bag/close()
if(..())
density = FALSE
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 0
if(opened) return 0
if(contents.len) return 0
visible_message("[usr] folds up the [src.name]")
var/folded = new item_path(get_turf(src))
spawn(0)
qdel(src)
return folded
/obj/structure/closet/body_bag/relaymove(mob/user,direction)
if(src.loc != get_turf(src))
src.loc.relaymove(user,direction)
else
..()
/obj/structure/closet/body_bag/proc/get_occupants()
var/list/occupants = list()
for(var/mob/living/carbon/human/H in contents)
occupants += H
return occupants
/obj/structure/closet/body_bag/proc/update(var/broadcast=0)
if(istype(loc, /obj/structure/morgue))
var/obj/structure/morgue/M = loc
M.update(broadcast)
/obj/structure/closet/body_bag/update_icon()
if(opened)
icon_state = "open"
else
icon_state = "closed_unlocked"
cut_overlays()
/* Ours don't have toetags
if(has_label)
add_overlay("bodybag_label")
*/
/obj/item/bodybag/cryobag
name = "stasis bag"
desc = "A non-reusable plastic bag designed to slow down bodily functions such as circulation and breathing, \
especially useful if short on time or in a hostile enviroment."
icon = 'icons/obj/closets/cryobag.dmi'
icon_state = "bodybag_folded"
item_state = "bodybag_cryo_folded"
origin_tech = list(TECH_BIO = 4)
var/obj/item/weapon/reagent_containers/syringe/syringe
/obj/item/bodybag/cryobag/attack_self(mob/user)
var/obj/structure/closet/body_bag/cryobag/R = new /obj/structure/closet/body_bag/cryobag(user.loc)
R.add_fingerprint(user)
if(syringe)
R.syringe = syringe
syringe = null
qdel(src)
/obj/structure/closet/body_bag/cryobag
name = "stasis bag"
desc = "A non-reusable plastic bag designed to slow down bodily functions such as circulation and breathing, \
especially useful if short on time or in a hostile enviroment."
icon = 'icons/obj/closets/cryobag.dmi'
item_path = /obj/item/bodybag/cryobag
store_misc = 0
store_items = 0
var/used = 0
var/obj/item/weapon/tank/tank = null
var/tank_type = /obj/item/weapon/tank/stasis/oxygen
var/stasis_level = 3 //Every 'this' life ticks are applied to the mob (when life_ticks%stasis_level == 1)
var/obj/item/weapon/reagent_containers/syringe/syringe
/obj/structure/closet/body_bag/cryobag/Initialize()
tank = new tank_type(null) //It's in nullspace to prevent ejection when the bag is opened.
..()
/obj/structure/closet/body_bag/cryobag/Destroy()
QDEL_NULL(syringe)
QDEL_NULL(tank)
return ..()
/obj/structure/closet/body_bag/cryobag/attack_hand(mob/living/user)
if(used)
var/confirm = tgui_alert(user, "Are you sure you want to open \the [src]? \The [src] will expire upon opening it.", "Confirm Opening", list("No", "Yes"))
if(confirm == "Yes")
..() // Will call `toggle()` and open the bag.
else
..()
/obj/structure/closet/body_bag/cryobag/open()
. = ..()
if(used)
new /obj/item/usedcryobag(loc)
qdel(src)
/obj/structure/closet/body_bag/cryobag/update_icon()
..()
cut_overlays()
var/image/I = image(icon, "indicator[opened]")
I.appearance_flags = RESET_COLOR
I.color = COLOR_LIME
add_overlay(I)
/obj/structure/closet/body_bag/cryobag/MouseDrop(over_object, src_location, over_location)
. = ..()
if(. && syringe)
var/obj/item/bodybag/cryobag/folded = .
folded.syringe = syringe
syringe = null
/obj/structure/closet/body_bag/cryobag/Entered(atom/movable/AM)
if(ishuman(AM))
var/mob/living/carbon/human/H = AM
H.Stasis(stasis_level)
src.used = 1
inject_occupant(H)
if(istype(AM, /obj/item/organ))
var/obj/item/organ/O = AM
O.preserved = 1
for(var/obj/item/organ/organ in O)
organ.preserved = 1
..()
/obj/structure/closet/body_bag/cryobag/Exited(atom/movable/AM)
if(ishuman(AM))
var/mob/living/carbon/human/H = AM
H.Stasis(0)
if(istype(AM, /obj/item/organ))
var/obj/item/organ/O = AM
O.preserved = 0
for(var/obj/item/organ/organ in O)
organ.preserved = 0
..()
/obj/structure/closet/body_bag/cryobag/return_air() //Used to make stasis bags protect from vacuum.
if(tank)
return tank.air_contents
..()
/obj/structure/closet/body_bag/cryobag/proc/inject_occupant(var/mob/living/carbon/human/H)
if(!syringe)
return
if(H.reagents)
syringe.reagents.trans_to_mob(H, 30, CHEM_BLOOD)
/obj/structure/closet/body_bag/cryobag/examine(mob/user)
. = ..()
if(Adjacent(user)) //The bag's rather thick and opaque from a distance.
. += "<span class='info'>You peer into \the [src].</span>"
if(syringe)
. += "<span class='info'>It has a syringe added to it.</span>"
for(var/mob/living/L in contents)
. += L.examine(user)
/obj/structure/closet/body_bag/cryobag/attackby(obj/item/W, mob/user)
if(opened)
..()
else //Allows the bag to respond to a health analyzer by analyzing the mob inside without needing to open it.
if(istype(W,/obj/item/device/healthanalyzer))
var/obj/item/device/healthanalyzer/analyzer = W
for(var/mob/living/L in contents)
analyzer.attack(L,user)
else if(istype(W,/obj/item/weapon/reagent_containers/syringe))
if(syringe)
to_chat(user,"<span class='warning'>\The [src] already has an injector! Remove it first.</span>")
else
var/obj/item/weapon/reagent_containers/syringe/syringe = W
to_chat(user,"<span class='info'>You insert \the [syringe] into \the [src], and it locks into place.</span>")
user.unEquip(syringe)
src.syringe = syringe
syringe.loc = null
for(var/mob/living/carbon/human/H in contents)
inject_occupant(H)
break
else if(W.has_tool_quality(TOOL_SCREWDRIVER))
if(syringe)
if(used)
to_chat(user,"<span class='warning'>The injector cannot be removed now that the stasis bag has been used!</span>")
else
syringe.forceMove(src.loc)
to_chat(user,"<span class='info'>You pry \the [syringe] out of \the [src].</span>")
syringe = null
else
..()
/obj/item/usedcryobag
name = "used stasis bag"
desc = "Pretty useless now.."
icon_state = "bodybag_used"
icon = 'icons/obj/closets/cryobag.dmi'
//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/closets/bodybag.dmi'
icon_state = "bodybag_folded"
w_class = ITEMSIZE_SMALL
/obj/item/bodybag/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/item/weapon/storage/box/bodybags
name = "body bags"
desc = "This box contains body bags."
icon_state = "bodybags"
starts_with = list(/obj/item/bodybag = 7)
/obj/structure/closet/body_bag
name = "body bag"
desc = "A plastic bag designed for the storage and transportation of cadavers."
icon = 'icons/obj/closets/bodybag.dmi'
closet_appearance = null
open_sound = 'sound/items/zip.ogg'
close_sound = 'sound/items/zip.ogg'
var/item_path = /obj/item/bodybag
density = FALSE
storage_capacity = (MOB_MEDIUM * 2) - 1
var/contains_body = 0
/obj/structure/closet/body_bag/attackby(var/obj/item/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/pen))
var/t = tgui_input_text(user, "What would you like the label to be?", text("[]", src.name), null, MAX_NAME_LEN )
if (user.get_active_hand() != W)
return
if (!in_range(src, user) && src.loc != user)
return
t = sanitizeSafe(t, MAX_NAME_LEN)
if (t)
src.name = "body bag - "
src.name += t
add_overlay("bodybag_label")
else
src.name = "body bag"
//..() //Doesn't need to run the parent. Since when can fucking bodybags be welded shut? -Agouri
return
else if(W.has_tool_quality(TOOL_WIRECUTTER))
to_chat(user, "You cut the tag off the bodybag")
src.name = "body bag"
cut_overlays()
return
/obj/structure/closet/body_bag/store_mobs(var/stored_units)
contains_body = ..()
return contains_body
/obj/structure/closet/body_bag/close()
if(..())
density = FALSE
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 0
if(opened) return 0
if(contents.len) return 0
visible_message("[usr] folds up the [src.name]")
var/folded = new item_path(get_turf(src))
spawn(0)
qdel(src)
return folded
/obj/structure/closet/body_bag/relaymove(mob/user,direction)
if(src.loc != get_turf(src))
src.loc.relaymove(user,direction)
else
..()
/obj/structure/closet/body_bag/proc/get_occupants()
var/list/occupants = list()
for(var/mob/living/carbon/human/H in contents)
occupants += H
return occupants
/obj/structure/closet/body_bag/proc/update(var/broadcast=0)
if(istype(loc, /obj/structure/morgue))
var/obj/structure/morgue/M = loc
M.update(broadcast)
/obj/structure/closet/body_bag/update_icon()
if(opened)
icon_state = "open"
else
icon_state = "closed_unlocked"
cut_overlays()
/* Ours don't have toetags
if(has_label)
add_overlay("bodybag_label")
*/
/obj/item/bodybag/cryobag
name = "stasis bag"
desc = "A non-reusable plastic bag designed to slow down bodily functions such as circulation and breathing, \
especially useful if short on time or in a hostile enviroment."
icon = 'icons/obj/closets/cryobag.dmi'
icon_state = "bodybag_folded"
item_state = "bodybag_cryo_folded"
origin_tech = list(TECH_BIO = 4)
var/obj/item/weapon/reagent_containers/syringe/syringe
/obj/item/bodybag/cryobag/attack_self(mob/user)
var/obj/structure/closet/body_bag/cryobag/R = new /obj/structure/closet/body_bag/cryobag(user.loc)
R.add_fingerprint(user)
if(syringe)
R.syringe = syringe
syringe = null
qdel(src)
/obj/structure/closet/body_bag/cryobag
name = "stasis bag"
desc = "A non-reusable plastic bag designed to slow down bodily functions such as circulation and breathing, \
especially useful if short on time or in a hostile enviroment."
icon = 'icons/obj/closets/cryobag.dmi'
item_path = /obj/item/bodybag/cryobag
store_misc = 0
store_items = 0
var/used = 0
var/obj/item/weapon/tank/tank = null
var/tank_type = /obj/item/weapon/tank/stasis/oxygen
var/stasis_level = 3 //Every 'this' life ticks are applied to the mob (when life_ticks%stasis_level == 1)
var/obj/item/weapon/reagent_containers/syringe/syringe
/obj/structure/closet/body_bag/cryobag/Initialize()
tank = new tank_type(null) //It's in nullspace to prevent ejection when the bag is opened.
..()
/obj/structure/closet/body_bag/cryobag/Destroy()
QDEL_NULL(syringe)
QDEL_NULL(tank)
return ..()
/obj/structure/closet/body_bag/cryobag/attack_hand(mob/living/user)
if(used)
var/confirm = tgui_alert(user, "Are you sure you want to open \the [src]? \The [src] will expire upon opening it.", "Confirm Opening", list("No", "Yes"))
if(confirm == "Yes")
..() // Will call `toggle()` and open the bag.
else
..()
/obj/structure/closet/body_bag/cryobag/open()
. = ..()
if(used)
new /obj/item/usedcryobag(loc)
qdel(src)
/obj/structure/closet/body_bag/cryobag/update_icon()
..()
cut_overlays()
var/image/I = image(icon, "indicator[opened]")
I.appearance_flags = RESET_COLOR
I.color = COLOR_LIME
add_overlay(I)
/obj/structure/closet/body_bag/cryobag/MouseDrop(over_object, src_location, over_location)
. = ..()
if(. && syringe)
var/obj/item/bodybag/cryobag/folded = .
folded.syringe = syringe
syringe = null
/obj/structure/closet/body_bag/cryobag/Entered(atom/movable/AM)
if(ishuman(AM))
var/mob/living/carbon/human/H = AM
H.Stasis(stasis_level)
src.used = 1
inject_occupant(H)
if(istype(AM, /obj/item/organ))
var/obj/item/organ/O = AM
O.preserved = 1
for(var/obj/item/organ/organ in O)
organ.preserved = 1
..()
/obj/structure/closet/body_bag/cryobag/Exited(atom/movable/AM)
if(ishuman(AM))
var/mob/living/carbon/human/H = AM
H.Stasis(0)
if(istype(AM, /obj/item/organ))
var/obj/item/organ/O = AM
O.preserved = 0
for(var/obj/item/organ/organ in O)
organ.preserved = 0
..()
/obj/structure/closet/body_bag/cryobag/return_air() //Used to make stasis bags protect from vacuum.
if(tank)
return tank.air_contents
..()
/obj/structure/closet/body_bag/cryobag/proc/inject_occupant(var/mob/living/carbon/human/H)
if(!syringe)
return
if(H.reagents)
syringe.reagents.trans_to_mob(H, 30, CHEM_BLOOD)
/obj/structure/closet/body_bag/cryobag/examine(mob/user)
. = ..()
if(Adjacent(user)) //The bag's rather thick and opaque from a distance.
. += "<span class='info'>You peer into \the [src].</span>"
if(syringe)
. += "<span class='info'>It has a syringe added to it.</span>"
for(var/mob/living/L in contents)
. += L.examine(user)
/obj/structure/closet/body_bag/cryobag/attackby(obj/item/W, mob/user)
if(opened)
..()
else //Allows the bag to respond to a health analyzer by analyzing the mob inside without needing to open it.
if(istype(W,/obj/item/device/healthanalyzer))
var/obj/item/device/healthanalyzer/analyzer = W
for(var/mob/living/L in contents)
analyzer.attack(L,user)
else if(istype(W,/obj/item/weapon/reagent_containers/syringe))
if(syringe)
to_chat(user,"<span class='warning'>\The [src] already has an injector! Remove it first.</span>")
else
var/obj/item/weapon/reagent_containers/syringe/syringe = W
to_chat(user,"<span class='info'>You insert \the [syringe] into \the [src], and it locks into place.</span>")
user.unEquip(syringe)
src.syringe = syringe
syringe.loc = null
for(var/mob/living/carbon/human/H in contents)
inject_occupant(H)
break
else if(W.has_tool_quality(TOOL_SCREWDRIVER))
if(syringe)
if(used)
to_chat(user,"<span class='warning'>The injector cannot be removed now that the stasis bag has been used!</span>")
else
syringe.forceMove(src.loc)
to_chat(user,"<span class='info'>You pry \the [syringe] out of \the [src].</span>")
syringe = null
else
..()
/obj/item/usedcryobag
name = "used stasis bag"
desc = "Pretty useless now.."
icon_state = "bodybag_used"
icon = 'icons/obj/closets/cryobag.dmi'
+214 -214
View File
@@ -1,214 +1,214 @@
/obj/item/weapon/pen/crayon/red
icon_state = "crayonred"
colour = "#DA0000"
shadeColour = "#810C0C"
colourName = "red"
/obj/item/weapon/pen/crayon/orange
icon_state = "crayonorange"
colour = "#FF9300"
shadeColour = "#A55403"
colourName = "orange"
/obj/item/weapon/pen/crayon/yellow
icon_state = "crayonyellow"
colour = "#FFF200"
shadeColour = "#886422"
colourName = "yellow"
/obj/item/weapon/pen/crayon/green
icon_state = "crayongreen"
colour = "#A8E61D"
shadeColour = "#61840F"
colourName = "green"
/obj/item/weapon/pen/crayon/blue
icon_state = "crayonblue"
colour = "#00B7EF"
shadeColour = "#0082A8"
colourName = "blue"
/obj/item/weapon/pen/crayon/purple
icon_state = "crayonpurple"
colour = "#DA00FF"
shadeColour = "#810CFF"
colourName = "purple"
/obj/item/weapon/pen/crayon/mime
icon_state = "crayonmime"
desc = "A very sad-looking crayon."
colour = "#FFFFFF"
shadeColour = "#000000"
colourName = "mime"
uses = 0
/obj/item/weapon/pen/crayon/mime/attack_self(mob/living/user as mob) //inversion
if(colour != "#FFFFFF" && shadeColour != "#000000")
colour = "#FFFFFF"
shadeColour = "#000000"
to_chat(user, "You will now draw in white and black with this crayon.")
else
colour = "#000000"
shadeColour = "#FFFFFF"
to_chat(user, "You will now draw in black and white with this crayon.")
return
/obj/item/weapon/pen/crayon/rainbow
icon_state = "crayonrainbow"
colour = "#FFF000"
shadeColour = "#000FFF"
colourName = "rainbow"
uses = 0
/obj/item/weapon/pen/crayon/rainbow/attack_self(mob/living/user as mob)
colour = input(user, "Please select the main colour.", "Crayon colour") as color
shadeColour = input(user, "Please select the shade colour.", "Crayon colour") as color
return
/obj/item/weapon/pen/crayon/afterattack(atom/target, mob/user as mob, proximity)
if(!proximity) return
if(istype(target,/turf/simulated/floor))
var/drawtype = tgui_input_list(user, "Choose what you'd like to draw.", "Crayon scribbles", list("graffiti","rune","letter","arrow"))
if(!drawtype)
return
if(get_dist(target, user) > 1 || !(user.z == target.z))
return
switch(drawtype)
if("letter")
drawtype = tgui_input_list(user, "Choose the letter.", "Crayon scribbles", 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"))
if(!drawtype || get_dist(target, user) > 1 || !(user.z == target.z))
return
to_chat(user, "You start drawing a letter on the [target.name].")
if("graffiti")
drawtype = tgui_input_list(user, "Choose the graffiti.", "Crayon scribbles", list("amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa"))
if(!drawtype || get_dist(target, user) > 1 || !(user.z == target.z))
return
to_chat(user, "You start drawing graffiti on the [target.name].")
if("rune")
drawtype = tgui_input_list(user, "Choose the rune.", "Crayon scribbles", list("rune1", "rune2", "rune3", "rune4", "rune5", "rune6"))
if(!drawtype || get_dist(target, user) > 1 || !(user.z == target.z))
return
to_chat(user, "You start drawing a rune on the [target.name].")
if("arrow")
drawtype = tgui_input_list(user, "Choose the arrow.", "Crayon scribbles", list("left", "right", "up", "down"))
if(!drawtype || get_dist(target, user) > 1 || !(user.z == target.z))
return
to_chat(user, "You start drawing an arrow on the [target.name].")
if(instant || do_after(user, 50))
new /obj/effect/decal/cleanable/crayon(target,colour,shadeColour,drawtype)
to_chat(user, "You finish drawing.")
var/msg = "[user.client.key] ([user]) has drawn [drawtype] (with [src]) at [target.x],[target.y],[target.z]."
if(config.log_graffiti)
message_admins(msg)
log_game(msg) //We will log it anyways.
target.add_fingerprint(user) // Adds their fingerprints to the floor the crayon is drawn on.
if(uses)
uses--
if(!uses)
to_chat(user, "<span class='warning'>You used up your crayon!</span>")
qdel(src)
return
/obj/item/weapon/pen/crayon/attack(mob/living/M as mob, mob/living/user as mob)
if(M == user)
to_chat(user, "You take a bite of the crayon and swallow it.")
user.nutrition += 1
user.reagents.add_reagent("crayon_dust",min(5,uses)/3)
if(uses)
uses -= 5
if(uses <= 0)
to_chat(user, "<span class='warning'>You ate your crayon!</span>")
qdel(src)
else
..()
/obj/item/weapon/pen/crayon/marker/black
icon_state = "markerblack"
colour = "#2D2D2D"
shadeColour = "#000000"
colourName = "black"
/obj/item/weapon/pen/crayon/marker/red
icon_state = "markerred"
colour = "#DA0000"
shadeColour = "#810C0C"
colourName = "red"
/obj/item/weapon/pen/crayon/marker/orange
icon_state = "markerorange"
colour = "#FF9300"
shadeColour = "#A55403"
colourName = "orange"
/obj/item/weapon/pen/crayon/marker/yellow
icon_state = "markeryellow"
colour = "#FFF200"
shadeColour = "#886422"
colourName = "yellow"
/obj/item/weapon/pen/crayon/marker/green
icon_state = "markergreen"
colour = "#A8E61D"
shadeColour = "#61840F"
colourName = "green"
/obj/item/weapon/pen/crayon/marker/blue
icon_state = "markerblue"
colour = "#00B7EF"
shadeColour = "#0082A8"
colourName = "blue"
/obj/item/weapon/pen/crayon/marker/purple
icon_state = "markerpurple"
colour = "#DA00FF"
shadeColour = "#810CFF"
colourName = "purple"
/obj/item/weapon/pen/crayon/marker/mime
icon_state = "markermime"
desc = "A very sad-looking marker."
colour = "#FFFFFF"
shadeColour = "#000000"
colourName = "mime"
uses = 0
/obj/item/weapon/pen/crayon/marker/mime/attack_self(mob/living/user as mob) //inversion
if(colour != "#FFFFFF" && shadeColour != "#000000")
colour = "#FFFFFF"
shadeColour = "#000000"
to_chat(user, "You will now draw in white and black with this marker.")
else
colour = "#000000"
shadeColour = "#FFFFFF"
to_chat(user, "You will now draw in black and white with this marker.")
return
/obj/item/weapon/pen/crayon/marker/rainbow
icon_state = "markerrainbow"
colour = "#FFF000"
shadeColour = "#000FFF"
colourName = "rainbow"
uses = 0
/obj/item/weapon/pen/crayon/marker/rainbow/attack_self(mob/living/user as mob)
colour = input(user, "Please select the main colour.", "Marker colour") as color
shadeColour = input(user, "Please select the shade colour.", "Marker colour") as color
return
/obj/item/weapon/pen/crayon/marker/attack(mob/living/M as mob, mob/living/user as mob)
if(M == user)
to_chat(user, "You take a bite of the marker and swallow it.")
user.nutrition += 1
user.reagents.add_reagent("marker_ink",6)
if(uses)
uses -= 5
if(uses <= 0)
to_chat(user, "<span class='warning'>You ate the marker!</span>")
qdel(src)
else
..()
/obj/item/weapon/pen/crayon/attack_self(var/mob/user)
return
/obj/item/weapon/pen/crayon/red
icon_state = "crayonred"
colour = "#DA0000"
shadeColour = "#810C0C"
colourName = "red"
/obj/item/weapon/pen/crayon/orange
icon_state = "crayonorange"
colour = "#FF9300"
shadeColour = "#A55403"
colourName = "orange"
/obj/item/weapon/pen/crayon/yellow
icon_state = "crayonyellow"
colour = "#FFF200"
shadeColour = "#886422"
colourName = "yellow"
/obj/item/weapon/pen/crayon/green
icon_state = "crayongreen"
colour = "#A8E61D"
shadeColour = "#61840F"
colourName = "green"
/obj/item/weapon/pen/crayon/blue
icon_state = "crayonblue"
colour = "#00B7EF"
shadeColour = "#0082A8"
colourName = "blue"
/obj/item/weapon/pen/crayon/purple
icon_state = "crayonpurple"
colour = "#DA00FF"
shadeColour = "#810CFF"
colourName = "purple"
/obj/item/weapon/pen/crayon/mime
icon_state = "crayonmime"
desc = "A very sad-looking crayon."
colour = "#FFFFFF"
shadeColour = "#000000"
colourName = "mime"
uses = 0
/obj/item/weapon/pen/crayon/mime/attack_self(mob/living/user as mob) //inversion
if(colour != "#FFFFFF" && shadeColour != "#000000")
colour = "#FFFFFF"
shadeColour = "#000000"
to_chat(user, "You will now draw in white and black with this crayon.")
else
colour = "#000000"
shadeColour = "#FFFFFF"
to_chat(user, "You will now draw in black and white with this crayon.")
return
/obj/item/weapon/pen/crayon/rainbow
icon_state = "crayonrainbow"
colour = "#FFF000"
shadeColour = "#000FFF"
colourName = "rainbow"
uses = 0
/obj/item/weapon/pen/crayon/rainbow/attack_self(mob/living/user as mob)
colour = input(user, "Please select the main colour.", "Crayon colour") as color
shadeColour = input(user, "Please select the shade colour.", "Crayon colour") as color
return
/obj/item/weapon/pen/crayon/afterattack(atom/target, mob/user as mob, proximity)
if(!proximity) return
if(istype(target,/turf/simulated/floor))
var/drawtype = tgui_input_list(user, "Choose what you'd like to draw.", "Crayon scribbles", list("graffiti","rune","letter","arrow"))
if(!drawtype)
return
if(get_dist(target, user) > 1 || !(user.z == target.z))
return
switch(drawtype)
if("letter")
drawtype = tgui_input_list(user, "Choose the letter.", "Crayon scribbles", 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"))
if(!drawtype || get_dist(target, user) > 1 || !(user.z == target.z))
return
to_chat(user, "You start drawing a letter on the [target.name].")
if("graffiti")
drawtype = tgui_input_list(user, "Choose the graffiti.", "Crayon scribbles", list("amyjon","face","matt","revolution","engie","guy","end","dwarf","uboa"))
if(!drawtype || get_dist(target, user) > 1 || !(user.z == target.z))
return
to_chat(user, "You start drawing graffiti on the [target.name].")
if("rune")
drawtype = tgui_input_list(user, "Choose the rune.", "Crayon scribbles", list("rune1", "rune2", "rune3", "rune4", "rune5", "rune6"))
if(!drawtype || get_dist(target, user) > 1 || !(user.z == target.z))
return
to_chat(user, "You start drawing a rune on the [target.name].")
if("arrow")
drawtype = tgui_input_list(user, "Choose the arrow.", "Crayon scribbles", list("left", "right", "up", "down"))
if(!drawtype || get_dist(target, user) > 1 || !(user.z == target.z))
return
to_chat(user, "You start drawing an arrow on the [target.name].")
if(instant || do_after(user, 50))
new /obj/effect/decal/cleanable/crayon(target,colour,shadeColour,drawtype)
to_chat(user, "You finish drawing.")
var/msg = "[user.client.key] ([user]) has drawn [drawtype] (with [src]) at [target.x],[target.y],[target.z]."
if(config.log_graffiti)
message_admins(msg)
log_game(msg) //We will log it anyways.
target.add_fingerprint(user) // Adds their fingerprints to the floor the crayon is drawn on.
if(uses)
uses--
if(!uses)
to_chat(user, "<span class='warning'>You used up your crayon!</span>")
qdel(src)
return
/obj/item/weapon/pen/crayon/attack(mob/living/M as mob, mob/living/user as mob)
if(M == user)
to_chat(user, "You take a bite of the crayon and swallow it.")
user.nutrition += 1
user.reagents.add_reagent("crayon_dust",min(5,uses)/3)
if(uses)
uses -= 5
if(uses <= 0)
to_chat(user, "<span class='warning'>You ate your crayon!</span>")
qdel(src)
else
..()
/obj/item/weapon/pen/crayon/marker/black
icon_state = "markerblack"
colour = "#2D2D2D"
shadeColour = "#000000"
colourName = "black"
/obj/item/weapon/pen/crayon/marker/red
icon_state = "markerred"
colour = "#DA0000"
shadeColour = "#810C0C"
colourName = "red"
/obj/item/weapon/pen/crayon/marker/orange
icon_state = "markerorange"
colour = "#FF9300"
shadeColour = "#A55403"
colourName = "orange"
/obj/item/weapon/pen/crayon/marker/yellow
icon_state = "markeryellow"
colour = "#FFF200"
shadeColour = "#886422"
colourName = "yellow"
/obj/item/weapon/pen/crayon/marker/green
icon_state = "markergreen"
colour = "#A8E61D"
shadeColour = "#61840F"
colourName = "green"
/obj/item/weapon/pen/crayon/marker/blue
icon_state = "markerblue"
colour = "#00B7EF"
shadeColour = "#0082A8"
colourName = "blue"
/obj/item/weapon/pen/crayon/marker/purple
icon_state = "markerpurple"
colour = "#DA00FF"
shadeColour = "#810CFF"
colourName = "purple"
/obj/item/weapon/pen/crayon/marker/mime
icon_state = "markermime"
desc = "A very sad-looking marker."
colour = "#FFFFFF"
shadeColour = "#000000"
colourName = "mime"
uses = 0
/obj/item/weapon/pen/crayon/marker/mime/attack_self(mob/living/user as mob) //inversion
if(colour != "#FFFFFF" && shadeColour != "#000000")
colour = "#FFFFFF"
shadeColour = "#000000"
to_chat(user, "You will now draw in white and black with this marker.")
else
colour = "#000000"
shadeColour = "#FFFFFF"
to_chat(user, "You will now draw in black and white with this marker.")
return
/obj/item/weapon/pen/crayon/marker/rainbow
icon_state = "markerrainbow"
colour = "#FFF000"
shadeColour = "#000FFF"
colourName = "rainbow"
uses = 0
/obj/item/weapon/pen/crayon/marker/rainbow/attack_self(mob/living/user as mob)
colour = input(user, "Please select the main colour.", "Marker colour") as color
shadeColour = input(user, "Please select the shade colour.", "Marker colour") as color
return
/obj/item/weapon/pen/crayon/marker/attack(mob/living/M as mob, mob/living/user as mob)
if(M == user)
to_chat(user, "You take a bite of the marker and swallow it.")
user.nutrition += 1
user.reagents.add_reagent("marker_ink",6)
if(uses)
uses -= 5
if(uses <= 0)
to_chat(user, "<span class='warning'>You ate the marker!</span>")
qdel(src)
else
..()
/obj/item/weapon/pen/crayon/attack_self(var/mob/user)
return
+185 -185
View File
@@ -1,185 +1,185 @@
/obj/item/device/aicard
name = "intelliCore"
desc = "Used to preserve and transport an AI."
icon = 'icons/obj/pda.dmi'
icon_state = "aicard" // aicard-full
item_state = "aicard"
w_class = ITEMSIZE_NORMAL
slot_flags = SLOT_BELT
show_messages = 0
preserve_item = 1
var/flush = null
origin_tech = list(TECH_DATA = 4, TECH_MATERIAL = 4)
var/mob/living/silicon/ai/carded_ai
/obj/item/device/aicard/attack(mob/living/silicon/decoy/M as mob, mob/user as mob)
if (!istype (M, /mob/living/silicon/decoy))
return ..()
else
M.death()
to_chat(user, "<b>ERROR ERROR ERROR</b>")
/obj/item/device/aicard/attack_self(mob/user)
tgui_interact(user)
/obj/item/device/aicard/tgui_interact(mob/user, datum/tgui/ui = null, datum/tgui_state/custom_state)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "AICard", "[name]") // 600, 394
ui.open()
if(custom_state)
ui.set_state(custom_state)
/obj/item/device/aicard/tgui_state(mob/user)
return GLOB.tgui_inventory_state
/obj/item/device/aicard/tgui_data(mob/user)
var/data[0]
data["has_ai"] = carded_ai != null
if(carded_ai)
data["name"] = carded_ai.name
data["integrity"] = carded_ai.hardware_integrity()
data["backup_capacitor"] = carded_ai.backup_capacitor()
data["radio"] = !carded_ai.aiRadio.disabledAi
data["wireless"] = !carded_ai.control_disabled
data["operational"] = carded_ai.stat != DEAD
data["flushing"] = flush
var/laws[0]
for(var/datum/ai_law/law in carded_ai.laws.all_laws())
if(law in carded_ai.laws.ion_laws) // If we're an ion law, give it an ion index code
laws.Add(ionnum() + ". " + law.law)
else
laws.Add(num2text(law.get_index()) + ". " + law.law)
data["laws"] = laws
data["has_laws"] = length(carded_ai.laws.all_laws())
return data
/obj/item/device/aicard/tgui_act(action, params)
if(..())
return TRUE
if(!carded_ai)
return
var/user = usr
switch(action)
if("wipe")
msg_admin_attack("[key_name_admin(user)] wiped [key_name_admin(AI)] with \the [src].")
add_attack_logs(user,carded_ai,"Purged from AI Card")
INVOKE_ASYNC(src, PROC_REF(wipe_ai))
if("radio")
carded_ai.aiRadio.disabledAi = !carded_ai.aiRadio.disabledAi
to_chat(carded_ai, "<span class='warning'>Your Subspace Transceiver has been [carded_ai.aiRadio.disabledAi ? "disabled" : "enabled"]!</span>")
to_chat(user, "<span class='notice'>You [carded_ai.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.</span>")
if("wireless")
carded_ai.control_disabled = !carded_ai.control_disabled
to_chat(carded_ai, "<span class='warning'>Your wireless interface has been [carded_ai.control_disabled ? "disabled" : "enabled"]!</span>")
to_chat(user, "<span class='notice'>You [carded_ai.control_disabled ? "disable" : "enable"] the AI's wireless interface.</span>")
if(carded_ai.control_disabled && carded_ai.deployed_shell)
carded_ai.disconnect_shell("Disconnecting from remote shell due to [src] wireless access interface being disabled.")
update_icon()
return TRUE
/obj/item/device/aicard/update_icon()
cut_overlays()
if(carded_ai)
if (!carded_ai.control_disabled)
add_overlay("aicard-on")
if(carded_ai.stat)
icon_state = "aicard-404"
else
icon_state = "aicard-full"
else
icon_state = "aicard"
/obj/item/device/aicard/proc/grab_ai(var/mob/living/silicon/ai/ai, var/mob/living/user)
if(!ai.client && !ai.deployed_shell)
to_chat(user, "<span class='danger'>ERROR:</span> AI [ai.name] is offline. Unable to transfer.")
return 0
if(carded_ai)
to_chat(user, "<span class='danger'>Transfer failed:</span> Existing AI found on remote device. Remove existing AI to install a new one.")
return 0
if(!user.IsAdvancedToolUser() && isanimal(user))
var/mob/living/simple_mob/S = user
if(!S.IsHumanoidToolUser(src))
return 0
user.visible_message("\The [user] starts transferring \the [ai] into \the [src]...", "You start transferring \the [ai] into \the [src]...")
show_message(span("critical", "\The [user] is transferring you into \the [src]!"))
if(do_after(user, 100))
if(carded_ai)
to_chat(user, "<span class='danger'>Transfer failed:</span> Existing AI found on remote device. Remove existing AI to install a new one.")
return 0
if(istype(ai.loc, /turf/))
new /obj/structure/AIcore/deactivated(get_turf(ai))
ai.carded = 1
add_attack_logs(user,ai,"Extracted into AI Card")
src.name = "[initial(name)] - [ai.name]"
ai.loc = src
ai.destroy_eyeobj(src)
ai.cancel_camera()
ai.control_disabled = 1
ai.aiRestorePowerRoutine = 0
carded_ai = ai
ai.disconnect_shell("Disconnected from remote shell due to core intelligence transfer.") //If the AI is controlling a borg, force the player back to core!
if(ai.client)
to_chat(ai, "You have been transferred into a mobile core. Remote access lost.")
if(user.client)
to_chat(ai, "<span class='notice'><b>Transfer successful:</b></span> [ai.name] extracted from current device and placed within mobile core.")
ai.canmove = 1
update_icon()
return 1
/obj/item/device/aicard/proc/clear()
if(carded_ai && istype(carded_ai.loc, /turf))
carded_ai.canmove = 0
carded_ai.carded = 0
name = initial(name)
carded_ai = null
update_icon()
/obj/item/device/aicard/see_emote(mob/living/M, text)
if(carded_ai && carded_ai.client)
var/rendered = "<span class='message'>[text]</span>"
carded_ai.show_message(rendered, 2)
..()
/obj/item/device/aicard/show_message(msg, type, alt, alt_type)
if(carded_ai && carded_ai.client)
var/rendered = "<span class='message'>[msg]</span>"
carded_ai.show_message(rendered, type)
..()
/obj/item/device/aicard/relaymove(var/mob/user, var/direction)
if(user.stat || user.stunned)
return
var/obj/item/weapon/rig/rig = src.get_rig()
if(istype(rig))
rig.forced_move(direction, user)
/obj/item/device/aicard/proc/wipe_ai()
var/mob/living/silicon/ai/AI = carded_ai
flush = TRUE
AI.suiciding = TRUE
to_chat(AI, "Your power has been disabled!")
while(AI && AI.stat != DEAD)
// This is absolutely evil and I love it.
if(AI.deployed_shell && prob(AI.oxyloss)) //You feel it creeping? Eventually will reach 100, resulting in the second half of the AI's remaining life being lonely.
AI.disconnect_shell("Disconnecting from remote shell due to insufficent power.")
AI.adjustOxyLoss(2)
AI.updatehealth()
sleep(10)
flush = FALSE
/obj/item/device/aicard
name = "intelliCore"
desc = "Used to preserve and transport an AI."
icon = 'icons/obj/pda.dmi'
icon_state = "aicard" // aicard-full
item_state = "aicard"
w_class = ITEMSIZE_NORMAL
slot_flags = SLOT_BELT
show_messages = 0
preserve_item = 1
var/flush = null
origin_tech = list(TECH_DATA = 4, TECH_MATERIAL = 4)
var/mob/living/silicon/ai/carded_ai
/obj/item/device/aicard/attack(mob/living/silicon/decoy/M as mob, mob/user as mob)
if (!istype (M, /mob/living/silicon/decoy))
return ..()
else
M.death()
to_chat(user, "<b>ERROR ERROR ERROR</b>")
/obj/item/device/aicard/attack_self(mob/user)
tgui_interact(user)
/obj/item/device/aicard/tgui_interact(mob/user, datum/tgui/ui = null, datum/tgui_state/custom_state)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "AICard", "[name]") // 600, 394
ui.open()
if(custom_state)
ui.set_state(custom_state)
/obj/item/device/aicard/tgui_state(mob/user)
return GLOB.tgui_inventory_state
/obj/item/device/aicard/tgui_data(mob/user)
var/data[0]
data["has_ai"] = carded_ai != null
if(carded_ai)
data["name"] = carded_ai.name
data["integrity"] = carded_ai.hardware_integrity()
data["backup_capacitor"] = carded_ai.backup_capacitor()
data["radio"] = !carded_ai.aiRadio.disabledAi
data["wireless"] = !carded_ai.control_disabled
data["operational"] = carded_ai.stat != DEAD
data["flushing"] = flush
var/laws[0]
for(var/datum/ai_law/law in carded_ai.laws.all_laws())
if(law in carded_ai.laws.ion_laws) // If we're an ion law, give it an ion index code
laws.Add(ionnum() + ". " + law.law)
else
laws.Add(num2text(law.get_index()) + ". " + law.law)
data["laws"] = laws
data["has_laws"] = length(carded_ai.laws.all_laws())
return data
/obj/item/device/aicard/tgui_act(action, params)
if(..())
return TRUE
if(!carded_ai)
return
var/user = usr
switch(action)
if("wipe")
msg_admin_attack("[key_name_admin(user)] wiped [key_name_admin(AI)] with \the [src].")
add_attack_logs(user,carded_ai,"Purged from AI Card")
INVOKE_ASYNC(src, PROC_REF(wipe_ai))
if("radio")
carded_ai.aiRadio.disabledAi = !carded_ai.aiRadio.disabledAi
to_chat(carded_ai, "<span class='warning'>Your Subspace Transceiver has been [carded_ai.aiRadio.disabledAi ? "disabled" : "enabled"]!</span>")
to_chat(user, "<span class='notice'>You [carded_ai.aiRadio.disabledAi ? "disable" : "enable"] the AI's Subspace Transceiver.</span>")
if("wireless")
carded_ai.control_disabled = !carded_ai.control_disabled
to_chat(carded_ai, "<span class='warning'>Your wireless interface has been [carded_ai.control_disabled ? "disabled" : "enabled"]!</span>")
to_chat(user, "<span class='notice'>You [carded_ai.control_disabled ? "disable" : "enable"] the AI's wireless interface.</span>")
if(carded_ai.control_disabled && carded_ai.deployed_shell)
carded_ai.disconnect_shell("Disconnecting from remote shell due to [src] wireless access interface being disabled.")
update_icon()
return TRUE
/obj/item/device/aicard/update_icon()
cut_overlays()
if(carded_ai)
if (!carded_ai.control_disabled)
add_overlay("aicard-on")
if(carded_ai.stat)
icon_state = "aicard-404"
else
icon_state = "aicard-full"
else
icon_state = "aicard"
/obj/item/device/aicard/proc/grab_ai(var/mob/living/silicon/ai/ai, var/mob/living/user)
if(!ai.client && !ai.deployed_shell)
to_chat(user, "<span class='danger'>ERROR:</span> AI [ai.name] is offline. Unable to transfer.")
return 0
if(carded_ai)
to_chat(user, "<span class='danger'>Transfer failed:</span> Existing AI found on remote device. Remove existing AI to install a new one.")
return 0
if(!user.IsAdvancedToolUser() && isanimal(user))
var/mob/living/simple_mob/S = user
if(!S.IsHumanoidToolUser(src))
return 0
user.visible_message("\The [user] starts transferring \the [ai] into \the [src]...", "You start transferring \the [ai] into \the [src]...")
show_message(span("critical", "\The [user] is transferring you into \the [src]!"))
if(do_after(user, 100))
if(carded_ai)
to_chat(user, "<span class='danger'>Transfer failed:</span> Existing AI found on remote device. Remove existing AI to install a new one.")
return 0
if(istype(ai.loc, /turf/))
new /obj/structure/AIcore/deactivated(get_turf(ai))
ai.carded = 1
add_attack_logs(user,ai,"Extracted into AI Card")
src.name = "[initial(name)] - [ai.name]"
ai.loc = src
ai.destroy_eyeobj(src)
ai.cancel_camera()
ai.control_disabled = 1
ai.aiRestorePowerRoutine = 0
carded_ai = ai
ai.disconnect_shell("Disconnected from remote shell due to core intelligence transfer.") //If the AI is controlling a borg, force the player back to core!
if(ai.client)
to_chat(ai, "You have been transferred into a mobile core. Remote access lost.")
if(user.client)
to_chat(ai, "<span class='notice'><b>Transfer successful:</b></span> [ai.name] extracted from current device and placed within mobile core.")
ai.canmove = 1
update_icon()
return 1
/obj/item/device/aicard/proc/clear()
if(carded_ai && istype(carded_ai.loc, /turf))
carded_ai.canmove = 0
carded_ai.carded = 0
name = initial(name)
carded_ai = null
update_icon()
/obj/item/device/aicard/see_emote(mob/living/M, text)
if(carded_ai && carded_ai.client)
var/rendered = "<span class='message'>[text]</span>"
carded_ai.show_message(rendered, 2)
..()
/obj/item/device/aicard/show_message(msg, type, alt, alt_type)
if(carded_ai && carded_ai.client)
var/rendered = "<span class='message'>[msg]</span>"
carded_ai.show_message(rendered, type)
..()
/obj/item/device/aicard/relaymove(var/mob/user, var/direction)
if(user.stat || user.stunned)
return
var/obj/item/weapon/rig/rig = src.get_rig()
if(istype(rig))
rig.forced_move(direction, user)
/obj/item/device/aicard/proc/wipe_ai()
var/mob/living/silicon/ai/AI = carded_ai
flush = TRUE
AI.suiciding = TRUE
to_chat(AI, "Your power has been disabled!")
while(AI && AI.stat != DEAD)
// This is absolutely evil and I love it.
if(AI.deployed_shell && prob(AI.oxyloss)) //You feel it creeping? Eventually will reach 100, resulting in the second half of the AI's remaining life being lonely.
AI.disconnect_shell("Disconnecting from remote shell due to insufficent power.")
AI.adjustOxyLoss(2)
AI.updatehealth()
sleep(10)
flush = FALSE
+147 -147
View File
@@ -1,147 +1,147 @@
/obj/item/device/chameleon
name = "chameleon projector"
icon_state = "shield0"
slot_flags = SLOT_BELT
item_state = "electronic"
throwforce = 5.0
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_SMALL
origin_tech = list(TECH_ILLEGAL = 4, TECH_MAGNET = 4)
var/can_use = 1
var/obj/effect/dummy/chameleon/active_dummy = null
var/saved_item = /obj/item/trash/cigbutt
var/saved_icon = 'icons/inventory/face/item.dmi'
var/saved_icon_state = "cigbutt"
var/saved_overlays
/obj/item/device/chameleon/dropped()
disrupt()
..()
/obj/item/device/chameleon/equipped()
..()
disrupt()
..()
/obj/item/device/chameleon/attack_self()
toggle()
/obj/item/device/chameleon/afterattack(atom/target, mob/user , proximity)
if(!proximity) return
if(!active_dummy)
if(istype(target,/obj/item) && !istype(target, /obj/item/weapon/disk/nuclear))
playsound(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
/obj/item/device/chameleon/proc/toggle()
if(!can_use || !saved_item) return
if(active_dummy)
eject_all()
playsound(src, 'sound/effects/pop.ogg', 100, 1, -6)
qdel(active_dummy)
active_dummy = null
to_chat(usr, "<span class='notice'>You deactivate the [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(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, src)
qdel(O)
to_chat(usr, "<span class='notice'>You activate the [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/device/chameleon/proc/disrupt(var/delete_dummy = 1)
if(active_dummy)
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread
spark_system.set_up(5, 0, src)
spark_system.attach(src)
spark_system.start()
eject_all()
if(delete_dummy)
qdel(active_dummy)
active_dummy = null
can_use = 0
spawn(50) can_use = 1
/obj/item/device/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_view(null)
/obj/effect/dummy/chameleon
name = ""
desc = ""
density = FALSE
anchored = TRUE
var/can_move = 1
var/obj/item/device/chameleon/master = null
/obj/effect/dummy/chameleon/proc/activate(var/obj/O, var/mob/M, new_icon, new_iconstate, new_overlays, var/obj/item/device/chameleon/C)
name = O.name
desc = O.desc
icon = new_icon
icon_state = new_iconstate
overlays = new_overlays
set_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='warning'>Your chameleon-projector deactivates.</span>")
master.disrupt()
/obj/effect/dummy/chameleon/attack_hand()
for(var/mob/M in src)
to_chat(M, "<span class='warning'>Your chameleon-projector deactivates.</span>")
master.disrupt()
/obj/effect/dummy/chameleon/ex_act()
for(var/mob/M in src)
to_chat(M, "<span class='warning'>Your chameleon-projector deactivates.</span>")
master.disrupt()
/obj/effect/dummy/chameleon/bullet_act()
for(var/mob/M in src)
to_chat(M, "<span class='warning'>Your chameleon-projector deactivates.</span>")
..()
master.disrupt()
/obj/effect/dummy/chameleon/relaymove(var/mob/user, direction)
if(istype(loc, /turf/space)) 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)
..()
/obj/item/device/chameleon
name = "chameleon projector"
icon_state = "shield0"
slot_flags = SLOT_BELT
item_state = "electronic"
throwforce = 5.0
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_SMALL
origin_tech = list(TECH_ILLEGAL = 4, TECH_MAGNET = 4)
var/can_use = 1
var/obj/effect/dummy/chameleon/active_dummy = null
var/saved_item = /obj/item/trash/cigbutt
var/saved_icon = 'icons/inventory/face/item.dmi'
var/saved_icon_state = "cigbutt"
var/saved_overlays
/obj/item/device/chameleon/dropped()
disrupt()
..()
/obj/item/device/chameleon/equipped()
..()
disrupt()
..()
/obj/item/device/chameleon/attack_self()
toggle()
/obj/item/device/chameleon/afterattack(atom/target, mob/user , proximity)
if(!proximity) return
if(!active_dummy)
if(istype(target,/obj/item) && !istype(target, /obj/item/weapon/disk/nuclear))
playsound(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
/obj/item/device/chameleon/proc/toggle()
if(!can_use || !saved_item) return
if(active_dummy)
eject_all()
playsound(src, 'sound/effects/pop.ogg', 100, 1, -6)
qdel(active_dummy)
active_dummy = null
to_chat(usr, "<span class='notice'>You deactivate the [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(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, src)
qdel(O)
to_chat(usr, "<span class='notice'>You activate the [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/device/chameleon/proc/disrupt(var/delete_dummy = 1)
if(active_dummy)
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread
spark_system.set_up(5, 0, src)
spark_system.attach(src)
spark_system.start()
eject_all()
if(delete_dummy)
qdel(active_dummy)
active_dummy = null
can_use = 0
spawn(50) can_use = 1
/obj/item/device/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_view(null)
/obj/effect/dummy/chameleon
name = ""
desc = ""
density = FALSE
anchored = TRUE
var/can_move = 1
var/obj/item/device/chameleon/master = null
/obj/effect/dummy/chameleon/proc/activate(var/obj/O, var/mob/M, new_icon, new_iconstate, new_overlays, var/obj/item/device/chameleon/C)
name = O.name
desc = O.desc
icon = new_icon
icon_state = new_iconstate
overlays = new_overlays
set_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='warning'>Your chameleon-projector deactivates.</span>")
master.disrupt()
/obj/effect/dummy/chameleon/attack_hand()
for(var/mob/M in src)
to_chat(M, "<span class='warning'>Your chameleon-projector deactivates.</span>")
master.disrupt()
/obj/effect/dummy/chameleon/ex_act()
for(var/mob/M in src)
to_chat(M, "<span class='warning'>Your chameleon-projector deactivates.</span>")
master.disrupt()
/obj/effect/dummy/chameleon/bullet_act()
for(var/mob/M in src)
to_chat(M, "<span class='warning'>Your chameleon-projector deactivates.</span>")
..()
master.disrupt()
/obj/effect/dummy/chameleon/relaymove(var/mob/user, direction)
if(istype(loc, /turf/space)) 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)
..()
@@ -1,97 +1,97 @@
/obj/item/device/communicator/proc/analyze_air()
var/list/results = list()
var/turf/T = get_turf(src.loc)
if(!isnull(T))
var/datum/gas_mixture/environment = T.return_air()
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles
if (total_moles)
var/o2_level = environment.gas["oxygen"]/total_moles
var/n2_level = environment.gas["nitrogen"]/total_moles
var/co2_level = environment.gas["carbon_dioxide"]/total_moles
var/phoron_level = environment.gas["phoron"]/total_moles
var/unknown_level = 1-(o2_level+n2_level+co2_level+phoron_level)
// Label is what the entry is describing
// Type identifies which unit or other special characters to use
// Val is the information reported
// Bad_high/_low are the values outside of which the entry reports as dangerous
// Poor_high/_low are the values outside of which the entry reports as unideal
// Values were extracted from the template itself
results = list(
list("entry" = "Pressure", "units" = "kPa", "val" = "[round(pressure,0.1)]", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80),
list("entry" = "Temperature", "units" = "\u00B0" + "C", "val" = "[round(environment.temperature-T0C,0.1)]", "bad_high" = 35, "poor_high" = 25, "poor_low" = 15, "bad_low" = 5),
list("entry" = "Oxygen", "units" = "kPa", "val" = "[round(o2_level*100,0.1)]", "bad_high" = 140, "poor_high" = 135, "poor_low" = 19, "bad_low" = 17),
list("entry" = "Nitrogen", "units" = "kPa", "val" = "[round(n2_level*100,0.1)]", "bad_high" = 105, "poor_high" = 85, "poor_low" = 50, "bad_low" = 40),
list("entry" = "Carbon Dioxide", "units" = "kPa", "val" = "[round(co2_level*100,0.1)]", "bad_high" = 10, "poor_high" = 5, "poor_low" = 0, "bad_low" = 0),
list("entry" = "Phoron", "units" = "kPa", "val" = "[round(phoron_level*100,0.01)]", "bad_high" = 0.5, "poor_high" = 0, "poor_low" = 0, "bad_low" = 0),
list("entry" = "Other", "units" = "kPa", "val" = "[round(unknown_level, 0.01)]", "bad_high" = 1, "poor_high" = 0.5, "poor_low" = 0, "bad_low" = 0)
)
if(isnull(results))
results = list(list("entry" = "pressure", "units" = "kPa", "val" = "0", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80))
return results
// Proc - compile_news()
// Parameters - none
// Description - Returns the list of newsfeeds, compiled for template processing
/obj/item/device/communicator/proc/compile_news()
var/list/feeds = list()
for(var/datum/feed_channel/channel in news_network.network_channels)
var/list/messages = list()
if(!channel.censored && channel.channel_name != "Vir News Network") //Do not load the 'IC news' channel as it is simply too long.
var/index = 0
for(var/datum/feed_message/FM in channel.messages)
index++
var/list/msgdata = list(
"author" = FM.author,
"body" = FM.body,
"img" = null,
"message_type" = FM.message_type,
"time_stamp" = FM.time_stamp,
"caption" = FM.caption,
"index" = index
)
if(FM.img)
msgdata["img"] = icon2base64(FM.img)
messages[++messages.len] = msgdata
feeds[++feeds.len] = list(
"name" = channel.channel_name,
"censored" = channel.censored,
"author" = channel.author,
"messages" = messages,
"index" = feeds.len + 1 // actually align them, since I guess the population of the list doesn't occur until after the evaluation of the new entry's contents
)
return feeds
// Proc - get_recent_news()
// Parameters - none
// Description - Returns the latest three newscasts, compiled for template processing
/obj/item/device/communicator/proc/get_recent_news()
var/list/news = list()
// Compile all the newscasts
for(var/datum/feed_channel/channel in news_network.network_channels)
if(!channel.censored)
for(var/datum/feed_message/FM in channel.messages)
var/body = replacetext(FM.body, "\n", "<br>")
news[++news.len] = list(
"channel" = channel.channel_name,
"author" = FM.author,
"body" = body,
"message_type" = FM.message_type,
"time_stamp" = FM.time_stamp,
"has_image" = (FM.img != null),
"caption" = FM.caption,
"time" = FM.post_time
)
// Cut out all but the youngest three
if(news.len > 3)
sortByKey(news, "time")
news.Cut(1, news.len - 2) // Last three have largest timestamps, youngest posts
news.Swap(1, 3) // List is sorted in ascending order of timestamp, we want descending
return news
/obj/item/device/communicator/proc/analyze_air()
var/list/results = list()
var/turf/T = get_turf(src.loc)
if(!isnull(T))
var/datum/gas_mixture/environment = T.return_air()
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles
if (total_moles)
var/o2_level = environment.gas["oxygen"]/total_moles
var/n2_level = environment.gas["nitrogen"]/total_moles
var/co2_level = environment.gas["carbon_dioxide"]/total_moles
var/phoron_level = environment.gas["phoron"]/total_moles
var/unknown_level = 1-(o2_level+n2_level+co2_level+phoron_level)
// Label is what the entry is describing
// Type identifies which unit or other special characters to use
// Val is the information reported
// Bad_high/_low are the values outside of which the entry reports as dangerous
// Poor_high/_low are the values outside of which the entry reports as unideal
// Values were extracted from the template itself
results = list(
list("entry" = "Pressure", "units" = "kPa", "val" = "[round(pressure,0.1)]", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80),
list("entry" = "Temperature", "units" = "\u00B0" + "C", "val" = "[round(environment.temperature-T0C,0.1)]", "bad_high" = 35, "poor_high" = 25, "poor_low" = 15, "bad_low" = 5),
list("entry" = "Oxygen", "units" = "kPa", "val" = "[round(o2_level*100,0.1)]", "bad_high" = 140, "poor_high" = 135, "poor_low" = 19, "bad_low" = 17),
list("entry" = "Nitrogen", "units" = "kPa", "val" = "[round(n2_level*100,0.1)]", "bad_high" = 105, "poor_high" = 85, "poor_low" = 50, "bad_low" = 40),
list("entry" = "Carbon Dioxide", "units" = "kPa", "val" = "[round(co2_level*100,0.1)]", "bad_high" = 10, "poor_high" = 5, "poor_low" = 0, "bad_low" = 0),
list("entry" = "Phoron", "units" = "kPa", "val" = "[round(phoron_level*100,0.01)]", "bad_high" = 0.5, "poor_high" = 0, "poor_low" = 0, "bad_low" = 0),
list("entry" = "Other", "units" = "kPa", "val" = "[round(unknown_level, 0.01)]", "bad_high" = 1, "poor_high" = 0.5, "poor_low" = 0, "bad_low" = 0)
)
if(isnull(results))
results = list(list("entry" = "pressure", "units" = "kPa", "val" = "0", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80))
return results
// Proc - compile_news()
// Parameters - none
// Description - Returns the list of newsfeeds, compiled for template processing
/obj/item/device/communicator/proc/compile_news()
var/list/feeds = list()
for(var/datum/feed_channel/channel in news_network.network_channels)
var/list/messages = list()
if(!channel.censored && channel.channel_name != "Vir News Network") //Do not load the 'IC news' channel as it is simply too long.
var/index = 0
for(var/datum/feed_message/FM in channel.messages)
index++
var/list/msgdata = list(
"author" = FM.author,
"body" = FM.body,
"img" = null,
"message_type" = FM.message_type,
"time_stamp" = FM.time_stamp,
"caption" = FM.caption,
"index" = index
)
if(FM.img)
msgdata["img"] = icon2base64(FM.img)
messages[++messages.len] = msgdata
feeds[++feeds.len] = list(
"name" = channel.channel_name,
"censored" = channel.censored,
"author" = channel.author,
"messages" = messages,
"index" = feeds.len + 1 // actually align them, since I guess the population of the list doesn't occur until after the evaluation of the new entry's contents
)
return feeds
// Proc - get_recent_news()
// Parameters - none
// Description - Returns the latest three newscasts, compiled for template processing
/obj/item/device/communicator/proc/get_recent_news()
var/list/news = list()
// Compile all the newscasts
for(var/datum/feed_channel/channel in news_network.network_channels)
if(!channel.censored)
for(var/datum/feed_message/FM in channel.messages)
var/body = replacetext(FM.body, "\n", "<br>")
news[++news.len] = list(
"channel" = channel.channel_name,
"author" = FM.author,
"body" = body,
"message_type" = FM.message_type,
"time_stamp" = FM.time_stamp,
"has_image" = (FM.img != null),
"caption" = FM.caption,
"time" = FM.post_time
)
// Cut out all but the youngest three
if(news.len > 3)
sortByKey(news, "time")
news.Cut(1, news.len - 2) // Last three have largest timestamps, youngest posts
news.Swap(1, 3) // List is sorted in ascending order of timestamp, we want descending
return news
@@ -1,185 +1,185 @@
// Proc: receive_exonet_message()
// Parameters: 4 (origin atom - the source of the message's holder, origin_address - where the message came from, message - the message received,
// text - message text to send if message is of type "text")
// Description: Handles voice requests and invite messages originating from both real communicators and ghosts. Also includes a ping response and IM function.
/obj/item/device/communicator/receive_exonet_message(var/atom/origin_atom, origin_address, message, text)
if(message == "voice")
if(isobserver(origin_atom) || istype(origin_atom, /obj/item/device/communicator))
if(origin_atom in voice_invites)
var/user = null
if(ismob(origin_atom.loc))
user = origin_atom.loc
open_connection(user, origin_atom)
return
else if(origin_atom in voice_requests)
return //Spam prevention
else
request(origin_atom)
if(message == "ping")
if(network_visibility)
var/random = rand(200,350)
random = random / 10
exonet.send_message(origin_address, "64 bytes received from [exonet.address] ecmp_seq=1 ttl=51 time=[random] ms")
if(message == "text")
request_im(origin_atom, origin_address, text)
return
// Proc: receive_exonet_message()
// Parameters: 3 (origin atom - the source of the message's holder, origin_address - where the message came from, message - the message received)
// Description: Handles voice requests and invite messages originating from both real communicators and ghosts. Also includes a ping response.
/mob/observer/dead/receive_exonet_message(origin_atom, origin_address, message, text)
if(message == "voice")
if(istype(origin_atom, /obj/item/device/communicator))
var/obj/item/device/communicator/comm = origin_atom
if(src in comm.voice_invites)
comm.open_connection(src)
return
to_chat(src, "<span class='notice'>\icon[origin_atom][bicon(origin_atom)] Receiving communicator request from [origin_atom]. To answer, use the <b>Call Communicator</b> \
verb, and select that name to answer the call.</span>")
src << 'sound/machines/defib_SafetyOn.ogg'
comm.voice_invites |= src
if(message == "ping")
if(client && client.prefs.communicator_visibility)
var/random = rand(450,700)
random = random / 10
exonet.send_message(origin_address, "64 bytes received from [exonet.address] ecmp_seq=1 ttl=51 time=[random] ms")
if(message == "text")
to_chat(src, "<span class='notice'>\icon[origin_atom][bicon(origin_atom)] Received text message from [origin_atom]: <b>\"[text]\"</b></span>")
src << 'sound/machines/defib_safetyOff.ogg'
exonet_messages.Add("<b>From [origin_atom]:</b><br>[text]")
return
// Proc: request_im()
// Parameters: 3 (candidate - the communicator wanting to message the device, origin_address - the address of the sender, text - the message)
// Description: Response to a communicator trying to message the device.
// Adds them to the list of people that have messaged this device and adds the message to the message list.
/obj/item/device/communicator/proc/request_im(var/atom/candidate, var/origin_address, var/text)
var/who = null
if(isobserver(candidate))
var/mob/observer/dead/ghost = candidate
who = ghost.name
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
else if(istype(candidate, /obj/item/device/communicator))
var/obj/item/device/communicator/comm = candidate
who = comm.owner
comm.im_contacts |= src
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
else if(istype(candidate, /obj/item/integrated_circuit))
var/obj/item/integrated_circuit/CIRC = candidate
who = CIRC
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
else return
im_contacts |= candidate
if(!who)
return
if(ringer)
var/S
if(ttone in ttone_sound)
S = ttone_sound[ttone]
else
S = 'sound/machines/twobeep.ogg'
playsound(src, S, 50, 1)
for (var/mob/O in hearers(2, loc))
O.show_message(text("\icon[src][bicon(src)] *[ttone]*"))
alert_called = 1
update_icon()
//Search for holder of the device.
var/mob/living/L = null
if(loc && isliving(loc))
L = loc
if(L)
to_chat(L, "<span class='notice'>\icon[src][bicon(src)] Message from [who]: <b>\"[text]\"</b> (<a href='?src=\ref[src];action=Reply;target=\ref[candidate]'>Reply</a>)</span>")
// This is the only Topic the communicators really uses
/obj/item/device/communicator/Topic(href, href_list)
switch(href_list["action"])
if("Reply")
var/obj/item/device/communicator/comm = locate(href_list["target"])
var/message = tgui_input_text(usr, "Enter your message below.", "Reply")
if(message)
exonet.send_message(comm.exonet.address, "text", message)
im_list += list(list("address" = exonet.address, "to_address" = comm.exonet.address, "im" = message))
log_pda("(COMM: [src]) sent \"[message]\" to [exonet.get_atom_from_address(comm.exonet.address)]", usr)
to_chat(usr, "<span class='notice'>\icon[src][bicon(src)] Sent message to [istype(comm, /obj/item/device/communicator) ? comm.owner : comm.name], <b>\"[message]\"</b> (<a href='?src=\ref[src];action=Reply;target=\ref[exonet.get_atom_from_address(comm.exonet.address)]'>Reply</a>)</span>")
// Verb: text_communicator()
// Parameters: None
// Description: Allows a ghost to send a text message to a communicator.
/mob/observer/dead/verb/text_communicator()
set category = "Ghost"
set name = "Text Communicator"
set desc = "If there is a communicator available, send a text message to it."
if(ticker.current_state < GAME_STATE_PLAYING)
to_chat(src, "<span class='danger'>The game hasn't started yet!</span>")
return
if (!src.stat)
return
if (usr != src)
return //something is terribly wrong
for(var/mob/living/L in mob_list) //Simple check so you don't have dead people calling.
if(src.client.prefs.real_name == L.real_name)
to_chat(src, "<span class='danger'>Your identity is already present in the game world. Please load in a different character first.</span>")
return
var/obj/machinery/exonet_node/E = get_exonet_node()
if(!E || !E.on || !E.allow_external_communicators)
to_chat(src, "<span class='danger'>The Exonet node at telecommunications is down at the moment, or is actively blocking you, \
so your call can't go through.</span>")
return
var/list/choices = list()
for(var/obj/item/device/communicator/comm in all_communicators)
if(!comm.network_visibility || !comm.exonet || !comm.exonet.address)
continue
choices.Add(comm)
if(!choices.len)
to_chat(src, "<span class='danger'>There are no available communicators, sorry.</span>")
return
var/choice = tgui_input_list(src,"Send a text message to whom?", "Recipient Choice", choices)
if(choice)
var/obj/item/device/communicator/chosen_communicator = choice
var/mob/observer/dead/O = src
var/text_message = sanitize(tgui_input_text(src, "What do you want the message to say?", multiline = TRUE))
if(text_message && O.exonet)
O.exonet.send_message(chosen_communicator.exonet.address, "text", text_message)
to_chat(src, "<span class='notice'>You have sent '[text_message]' to [chosen_communicator].</span>")
exonet_messages.Add("<b>To [chosen_communicator]:</b><br>[text_message]")
log_pda("(DCOMM: [src]) sent \"[text_message]\" to [chosen_communicator]", src)
for(var/mob/M in player_list)
if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat)
continue
if(M == src)
continue
M.show_message("Comm IM - [src] -> [chosen_communicator]: [text_message]")
// Verb: show_text_messages()
// Parameters: None
// Description: Lets ghosts review messages they've sent or received.
/mob/observer/dead/verb/show_text_messages()
set category = "Ghost"
set name = "Show Text Messages"
set desc = "Allows you to see exonet text messages you've sent and received."
var/HTML = "<html><head><title>Exonet Message Log</title></head><body>"
for(var/line in exonet_messages)
HTML += line + "<br>"
HTML +="</body></html>"
usr << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0")
// Proc: receive_exonet_message()
// Parameters: 4 (origin atom - the source of the message's holder, origin_address - where the message came from, message - the message received,
// text - message text to send if message is of type "text")
// Description: Handles voice requests and invite messages originating from both real communicators and ghosts. Also includes a ping response and IM function.
/obj/item/device/communicator/receive_exonet_message(var/atom/origin_atom, origin_address, message, text)
if(message == "voice")
if(isobserver(origin_atom) || istype(origin_atom, /obj/item/device/communicator))
if(origin_atom in voice_invites)
var/user = null
if(ismob(origin_atom.loc))
user = origin_atom.loc
open_connection(user, origin_atom)
return
else if(origin_atom in voice_requests)
return //Spam prevention
else
request(origin_atom)
if(message == "ping")
if(network_visibility)
var/random = rand(200,350)
random = random / 10
exonet.send_message(origin_address, "64 bytes received from [exonet.address] ecmp_seq=1 ttl=51 time=[random] ms")
if(message == "text")
request_im(origin_atom, origin_address, text)
return
// Proc: receive_exonet_message()
// Parameters: 3 (origin atom - the source of the message's holder, origin_address - where the message came from, message - the message received)
// Description: Handles voice requests and invite messages originating from both real communicators and ghosts. Also includes a ping response.
/mob/observer/dead/receive_exonet_message(origin_atom, origin_address, message, text)
if(message == "voice")
if(istype(origin_atom, /obj/item/device/communicator))
var/obj/item/device/communicator/comm = origin_atom
if(src in comm.voice_invites)
comm.open_connection(src)
return
to_chat(src, "<span class='notice'>\icon[origin_atom][bicon(origin_atom)] Receiving communicator request from [origin_atom]. To answer, use the <b>Call Communicator</b> \
verb, and select that name to answer the call.</span>")
src << 'sound/machines/defib_SafetyOn.ogg'
comm.voice_invites |= src
if(message == "ping")
if(client && client.prefs.communicator_visibility)
var/random = rand(450,700)
random = random / 10
exonet.send_message(origin_address, "64 bytes received from [exonet.address] ecmp_seq=1 ttl=51 time=[random] ms")
if(message == "text")
to_chat(src, "<span class='notice'>\icon[origin_atom][bicon(origin_atom)] Received text message from [origin_atom]: <b>\"[text]\"</b></span>")
src << 'sound/machines/defib_safetyOff.ogg'
exonet_messages.Add("<b>From [origin_atom]:</b><br>[text]")
return
// Proc: request_im()
// Parameters: 3 (candidate - the communicator wanting to message the device, origin_address - the address of the sender, text - the message)
// Description: Response to a communicator trying to message the device.
// Adds them to the list of people that have messaged this device and adds the message to the message list.
/obj/item/device/communicator/proc/request_im(var/atom/candidate, var/origin_address, var/text)
var/who = null
if(isobserver(candidate))
var/mob/observer/dead/ghost = candidate
who = ghost.name
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
else if(istype(candidate, /obj/item/device/communicator))
var/obj/item/device/communicator/comm = candidate
who = comm.owner
comm.im_contacts |= src
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
else if(istype(candidate, /obj/item/integrated_circuit))
var/obj/item/integrated_circuit/CIRC = candidate
who = CIRC
im_list += list(list("address" = origin_address, "to_address" = exonet.address, "im" = text))
else return
im_contacts |= candidate
if(!who)
return
if(ringer)
var/S
if(ttone in ttone_sound)
S = ttone_sound[ttone]
else
S = 'sound/machines/twobeep.ogg'
playsound(src, S, 50, 1)
for (var/mob/O in hearers(2, loc))
O.show_message(text("\icon[src][bicon(src)] *[ttone]*"))
alert_called = 1
update_icon()
//Search for holder of the device.
var/mob/living/L = null
if(loc && isliving(loc))
L = loc
if(L)
to_chat(L, "<span class='notice'>\icon[src][bicon(src)] Message from [who]: <b>\"[text]\"</b> (<a href='?src=\ref[src];action=Reply;target=\ref[candidate]'>Reply</a>)</span>")
// This is the only Topic the communicators really uses
/obj/item/device/communicator/Topic(href, href_list)
switch(href_list["action"])
if("Reply")
var/obj/item/device/communicator/comm = locate(href_list["target"])
var/message = tgui_input_text(usr, "Enter your message below.", "Reply")
if(message)
exonet.send_message(comm.exonet.address, "text", message)
im_list += list(list("address" = exonet.address, "to_address" = comm.exonet.address, "im" = message))
log_pda("(COMM: [src]) sent \"[message]\" to [exonet.get_atom_from_address(comm.exonet.address)]", usr)
to_chat(usr, "<span class='notice'>\icon[src][bicon(src)] Sent message to [istype(comm, /obj/item/device/communicator) ? comm.owner : comm.name], <b>\"[message]\"</b> (<a href='?src=\ref[src];action=Reply;target=\ref[exonet.get_atom_from_address(comm.exonet.address)]'>Reply</a>)</span>")
// Verb: text_communicator()
// Parameters: None
// Description: Allows a ghost to send a text message to a communicator.
/mob/observer/dead/verb/text_communicator()
set category = "Ghost"
set name = "Text Communicator"
set desc = "If there is a communicator available, send a text message to it."
if(ticker.current_state < GAME_STATE_PLAYING)
to_chat(src, "<span class='danger'>The game hasn't started yet!</span>")
return
if (!src.stat)
return
if (usr != src)
return //something is terribly wrong
for(var/mob/living/L in mob_list) //Simple check so you don't have dead people calling.
if(src.client.prefs.real_name == L.real_name)
to_chat(src, "<span class='danger'>Your identity is already present in the game world. Please load in a different character first.</span>")
return
var/obj/machinery/exonet_node/E = get_exonet_node()
if(!E || !E.on || !E.allow_external_communicators)
to_chat(src, "<span class='danger'>The Exonet node at telecommunications is down at the moment, or is actively blocking you, \
so your call can't go through.</span>")
return
var/list/choices = list()
for(var/obj/item/device/communicator/comm in all_communicators)
if(!comm.network_visibility || !comm.exonet || !comm.exonet.address)
continue
choices.Add(comm)
if(!choices.len)
to_chat(src, "<span class='danger'>There are no available communicators, sorry.</span>")
return
var/choice = tgui_input_list(src,"Send a text message to whom?", "Recipient Choice", choices)
if(choice)
var/obj/item/device/communicator/chosen_communicator = choice
var/mob/observer/dead/O = src
var/text_message = sanitize(tgui_input_text(src, "What do you want the message to say?", multiline = TRUE))
if(text_message && O.exonet)
O.exonet.send_message(chosen_communicator.exonet.address, "text", text_message)
to_chat(src, "<span class='notice'>You have sent '[text_message]' to [chosen_communicator].</span>")
exonet_messages.Add("<b>To [chosen_communicator]:</b><br>[text_message]")
log_pda("(DCOMM: [src]) sent \"[text_message]\" to [chosen_communicator]", src)
for(var/mob/M in player_list)
if(M.stat == DEAD && M.is_preference_enabled(/datum/client_preference/ghost_ears))
if(istype(M, /mob/new_player) || M.forbid_seeing_deadchat)
continue
if(M == src)
continue
M.show_message("Comm IM - [src] -> [chosen_communicator]: [text_message]")
// Verb: show_text_messages()
// Parameters: None
// Description: Lets ghosts review messages they've sent or received.
/mob/observer/dead/verb/show_text_messages()
set category = "Ghost"
set name = "Show Text Messages"
set desc = "Allows you to see exonet text messages you've sent and received."
var/HTML = "<html><head><title>Exonet Message Log</title></head><body>"
for(var/line in exonet_messages)
HTML += line + "<br>"
HTML +="</body></html>"
usr << browse(HTML, "window=log;size=400x444;border=1;can_resize=1;can_close=1;can_minimize=0")
@@ -1,366 +1,366 @@
// Proc: add_communicating()
// Parameters: 1 (comm - the communicator to add to communicating)
// Description: Used when this communicator gets a new communicator to relay say/me messages to
/obj/item/device/communicator/proc/add_communicating(obj/item/device/communicator/comm)
if(!comm || !istype(comm)) return
communicating |= comm
listening_objects |= src
update_icon()
// Proc: del_communicating()
// Parameters: 1 (comm - the communicator to remove from communicating)
// Description: Used when this communicator is being asked to stop relaying say/me messages to another
/obj/item/device/communicator/proc/del_communicating(obj/item/device/communicator/comm)
if(!comm || !istype(comm)) return
communicating.Remove(comm)
update_icon()
// Proc: open_connection()
// Parameters: 2 (user - the person who initiated the connecting being opened, candidate - the communicator or observer that will connect to the device)
// Description: Typechecks the candidate, then calls the correct proc for further connecting.
/obj/item/device/communicator/proc/open_connection(mob/user, var/atom/candidate)
if(isobserver(candidate))
voice_invites.Remove(candidate)
open_connection_to_ghost(user, candidate)
else
if(istype(candidate, /obj/item/device/communicator))
open_connection_to_communicator(user, candidate)
// Proc: open_connection_to_communicator()
// Parameters: 2 (user - the person who initiated this and will be receiving feedback information, candidate - someone else's communicator)
// Description: Adds the candidate and src to each other's communicating lists, allowing messages seen by the devices to be relayed.
/obj/item/device/communicator/proc/open_connection_to_communicator(mob/user, var/atom/candidate)
if(!istype(candidate, /obj/item/device/communicator))
return
var/obj/item/device/communicator/comm = candidate
voice_invites.Remove(candidate)
comm.voice_requests.Remove(src)
if(user)
comm.visible_message("<span class='notice'>\icon[src][bicon(src)] Connecting to [src].</span>")
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Attempting to call [comm].</span>")
sleep(10)
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Dialing internally from [station_name()], [system_name()].</span>")
sleep(20) //If they don't have an exonet something is very wrong and we want a runtime.
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Connection re-routed to [comm] at [comm.exonet.address].</span>")
sleep(40)
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Connection to [comm] at [comm.exonet.address] established.</span>")
comm.visible_message("<span class='notice'>\icon[src][bicon(src)] Connection to [src] at [exonet.address] established.</span>")
sleep(20)
src.add_communicating(comm)
comm.add_communicating(src)
// Proc: open_connection_to_ghost()
// Parameters: 2 (user - the person who initiated this, candidate - the ghost that will be turned into a voice mob)
// Description: Pulls the candidate ghost from deadchat, makes a new voice mob, transfers their identity, then their client.
/obj/item/device/communicator/proc/open_connection_to_ghost(mob/user, var/mob/candidate)
if(!isobserver(candidate))
return
//Handle moving the ghost into the new shell.
announce_ghost_joinleave(candidate, 0, "They are occupying a personal communications device now.")
voice_requests.Remove(candidate)
voice_invites.Remove(candidate)
var/mob/living/voice/new_voice = new /mob/living/voice(src) //Make the voice mob the ghost is going to be.
new_voice.transfer_identity(candidate) //Now make the voice mob load from the ghost's active character in preferences.
//Do some simple logging since this is a tad risky as a concept.
var/msg = "[candidate && candidate.client ? "[candidate.client.key]" : "*no key*"] ([candidate]) has entered [src], triggered by \
[user && user.client ? "[user.client.key]" : "*no key*"] ([user ? "[user]" : "*null*"]) at [x],[y],[z]. They have joined as [new_voice.name]."
message_admins(msg)
log_game(msg)
new_voice.mind = candidate.mind //Transfer the mind, if any.
new_voice.ckey = candidate.ckey //Finally, bring the client over.
voice_mobs.Add(new_voice)
listening_objects |= src
var/obj/screen/blackness = new() //Makes a black screen, so the candidate can't see what's going on before actually 'connecting' to the communicator.
blackness.screen_loc = ui_entire_screen
blackness.icon = 'icons/effects/effects.dmi'
blackness.icon_state = "1"
blackness.mouse_opacity = 2 //Can't see anything!
new_voice.client.screen.Add(blackness)
update_icon()
//Now for some connection fluff.
if(user)
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Connecting to [candidate].</span>")
to_chat(new_voice, "<span class='notice'>\icon[src][bicon(src)] Attempting to call [src].</span>")
sleep(10)
to_chat(new_voice, "<span class='notice'>\icon[src][bicon(src)] Dialing to [station_name()], Kara Subsystem, [system_name()].</span>")
sleep(20)
to_chat(new_voice, "<span class='notice'>\icon[src][bicon(src)] Connecting to [station_name()] telecommunications array.</span>")
sleep(40)
to_chat(new_voice, "<span class='notice'>\icon[src][bicon(src)] Connection to [station_name()] telecommunications array established. Redirecting signal to [src].</span>")
sleep(20)
//We're connected, no need to hide everything.
new_voice.client.screen.Remove(blackness)
qdel(blackness)
to_chat(new_voice, "<span class='notice'>\icon[src][bicon(src)] Connection to [src] established.</span>")
to_chat(new_voice, "<b>To talk to the person on the other end of the call, just talk normally.</b>")
to_chat(new_voice, "<b>If you want to end the call, use the 'Hang Up' verb. The other person can also hang up at any time.</b>")
to_chat(new_voice, "<b>Remember, your character does not know anything you've learned from observing!</b>")
if(new_voice.mind)
new_voice.mind.assigned_role = "Disembodied Voice"
if(user)
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Your communicator is now connected to [candidate]'s communicator.</span>")
// Proc: close_connection()
// Parameters: 3 (user - the user who initiated the disconnect, target - the mob or device being disconnected, reason - string shown when disconnected)
// Description: Deletes specific voice_mobs or disconnects communicators, and shows a message to everyone when doing so. If target is null, all communicators
// and voice mobs are removed.
/obj/item/device/communicator/proc/close_connection(mob/user, var/atom/target, var/reason)
if(voice_mobs.len == 0 && communicating.len == 0)
return
for(var/mob/living/voice/voice in voice_mobs) //Handle ghost-callers
if(target && voice != target) //If no target is inputted, it deletes all of them.
continue
to_chat(voice, "<span class='danger'>\icon[src][bicon(src)] [reason].</span>")
visible_message("<span class='danger'>\icon[src][bicon(src)] [reason].</span>")
voice_mobs.Remove(voice)
qdel(voice)
update_icon()
for(var/obj/item/device/communicator/comm in communicating) //Now we handle real communicators.
if(target && comm != target)
continue
src.del_communicating(comm)
comm.del_communicating(src)
comm.visible_message("<span class='danger'>\icon[src][bicon(src)] [reason].</span>")
visible_message("<span class='danger'>\icon[src][bicon(src)] [reason].</span>")
if(comm.camera && video_source == comm.camera) //We hung up on the person on video
end_video()
if(camera && comm.video_source == camera) //We hung up on them while they were watching us
comm.end_video()
if(voice_mobs.len == 0 && communicating.len == 0)
listening_objects.Remove(src)
// Proc: request()
// Parameters: 1 (candidate - the ghost or communicator wanting to call the device)
// Description: Response to a communicator or observer trying to call the device. Adds them to the list of requesters
/obj/item/device/communicator/proc/request(var/atom/candidate)
if(candidate in voice_requests)
return
var/who = null
if(isobserver(candidate))
who = candidate.name
else if(istype(candidate, /obj/item/device/communicator))
var/obj/item/device/communicator/comm = candidate
who = comm.owner
comm.voice_invites |= src
if(!who)
return
voice_requests |= candidate
if(ringer)
playsound(src, 'sound/machines/twobeep.ogg', 50, 1)
for (var/mob/O in hearers(2, loc))
O.show_message(text("\icon[src][bicon(src)] *beep*"))
alert_called = 1
update_icon()
//Search for holder of the device.
var/mob/living/L = null
if(loc && isliving(loc))
L = loc
if(L)
to_chat(L, "<span class='notice'>\icon[src][bicon(src)] Communications request from [who].</span>")
// Proc: del_request()
// Parameters: 1 (candidate - the ghost or communicator to be declined)
// Description: Declines a request and cleans up both ends
/obj/item/device/communicator/proc/del_request(var/atom/candidate)
if(!(candidate in voice_requests))
return
if(isobserver(candidate))
to_chat(candidate, "<span class='warning'>Your communicator call request was declined.</span>")
else if(istype(candidate, /obj/item/device/communicator))
var/obj/item/device/communicator/comm = candidate
comm.voice_invites -= src
voice_requests -= candidate
//Search for holder of our device.
var/mob/living/us = null
if(loc && isliving(loc))
us = loc
if(us)
to_chat(us, "<span class='notice'>\icon[src][bicon(src)] Declined request.</span>")
// Proc: see_emote()
// Parameters: 2 (M - the mob the emote originated from, text - the emote's contents)
// Description: Relays the emote to all linked communicators.
/obj/item/device/communicator/see_emote(mob/living/M, text)
var/rendered = "\icon[src][bicon(src)] <span class='message'>[text]</span>"
for(var/obj/item/device/communicator/comm in communicating)
var/turf/T = get_turf(comm)
if(!T) return
//VOREStation Edit Start for commlinks
var/list/mobs_to_relay
if(istype(comm,/obj/item/device/communicator/commlink))
var/obj/item/device/communicator/commlink/CL = comm
mobs_to_relay = list(CL.nif.human)
else
var/list/in_range = get_mobs_and_objs_in_view_fast(T,world.view,0) //Range of 3 since it's a tiny video display
mobs_to_relay = in_range["mobs"]
//VOREStation Edit End
for(var/mob/mob in mobs_to_relay) //We can't use visible_message(), or else we will get an infinite loop if two communicators hear each other.
var/dst = get_dist(get_turf(mob),get_turf(comm))
if(dst <= video_range)
mob.show_message(rendered)
else
to_chat(mob, "You can barely see some movement on \the [src]'s display.")
..()
// Proc: hear_talk()
// Parameters: 3 (M - the mob the speech originated from,
// list/message_pieces - what is being said w/ baked languages,
// verb - the word used to describe how text is being said)
// Description: Relays the speech to all linked communicators.
/obj/item/device/communicator/hear_talk(mob/M, list/message_pieces, verb)
for(var/obj/item/device/communicator/comm in communicating)
var/turf/T = get_turf(comm)
if(!T) return
//VOREStation Edit Start for commlinks
var/list/mobs_to_relay
if(istype(comm,/obj/item/device/communicator/commlink))
var/obj/item/device/communicator/commlink/CL = comm
mobs_to_relay = list(CL.nif.human)
else
var/list/in_range = get_mobs_and_objs_in_view_fast(T,world.view,0) //Range of 3 since it's a tiny video display
mobs_to_relay = in_range["mobs"]
//VOREStation Edit End
for(var/mob/mob in mobs_to_relay)
var/list/combined = mob.combine_message(message_pieces, verb, M)
var/message = combined["formatted"]
var/name_used = M.GetVoice()
var/rendered = null
rendered = "<span class='game say'>\icon[src][bicon(src)] <span class='name'>[name_used]</span> [message]</span>"
mob.show_message(rendered, 2)
// Proc: show_message()
// Parameters: 4 (msg - the message, type - number to determine if message is visible or audible, alt - unknown, alt_type - unknown)
// Description: Relays the message to all linked communicators.
/obj/item/device/communicator/show_message(msg, type, alt, alt_type)
var/rendered = "\icon[src][bicon(src)] <span class='message'>[msg]</span>"
for(var/obj/item/device/communicator/comm in communicating)
var/turf/T = get_turf(comm)
if(!T) return
var/list/in_range = get_mobs_and_objs_in_view_fast(T,world.view,0)
var/list/mobs_to_relay = in_range["mobs"]
for(var/mob/mob in mobs_to_relay)
mob.show_message(rendered)
..()
// Verb: join_as_voice()
// Parameters: None
// Description: Allows ghosts to call communicators, if they meet all the requirements.
/mob/observer/dead/verb/join_as_voice()
set category = "Ghost"
set name = "Call Communicator"
set desc = "If there is a communicator available, send a request to speak through it. This will reset your respawn timer, if someone picks up."
if(ticker.current_state < GAME_STATE_PLAYING)
to_chat(src, "<span class='danger'>The game hasn't started yet!</span>")
return
if (!src.stat)
return
if (usr != src)
return //something is terribly wrong
var/confirm = tgui_alert(src, "Would you like to talk as [src.client.prefs.real_name], over a communicator? This will reset your respawn timer, if someone answers.", "Join as Voice?", list("Yes","No"))
if(confirm == "No")
return
if(config.antag_hud_restricted && has_enabled_antagHUD == 1)
to_chat(src, "<span class='danger'>You have used the antagHUD and cannot respawn or use communicators!</span>")
return
for(var/mob/living/L in mob_list) //Simple check so you don't have dead people calling.
if(src.client.prefs.real_name == L.real_name)
to_chat(src, "<span class='danger'>Your identity is already present in the game world. Please load in a different character first.</span>")
return
var/obj/machinery/exonet_node/E = get_exonet_node()
if(!E || !E.on || !E.allow_external_communicators)
to_chat(src, "<span class='danger'>The Exonet node at telecommunications is down at the moment, or is actively blocking you, \
so your call can't go through.</span>")
return
var/list/choices = list()
for(var/obj/item/device/communicator/comm in all_communicators)
if(!comm.network_visibility || !comm.exonet || !comm.exonet.address)
continue
choices.Add(comm)
if(!choices.len)
to_chat(src , "<span class='danger'>There are no available communicators, sorry.</span>")
return
var/choice = tgui_input_list(src,"Send a voice request to whom?", "Recipient Choice", choices)
if(choice)
var/obj/item/device/communicator/chosen_communicator = choice
var/mob/observer/dead/O = src
if(O.exonet)
O.exonet.send_message(chosen_communicator.exonet.address, "voice")
to_chat(src, "A communications request has been sent to [chosen_communicator]. Now you need to wait until someone answers.")
// Proc: connect_video()
// Parameters: user - the mob doing the viewing of video, comm - the communicator at the far end
// Description: Sets up a videocall and puts the first view into it using watch_video, and updates the icon
/obj/item/device/communicator/proc/connect_video(mob/user,obj/item/device/communicator/comm)
if((!user) || (!comm) || user.stat) return //KO or dead, or already in a video
if(video_source) //Already in a video
to_chat(user, "<span class='danger'>You are already connected to a video call!</span>")
return
if(user.blinded) //User is blinded
to_chat(user, "<span class='danger'>You cannot see well enough to do that!</span>")
return
if(!(src in comm.communicating) || !comm.camera) //You called someone with a broken communicator or one that's fake or yourself or something
to_chat(user, "<span class='danger'>\icon[src][bicon(src)]ERROR: Video failed. Either bandwidth is too low, or the other communicator is malfunctioning.</span>")
return
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Attempting to start video over existing call.</span>")
sleep(30)
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Please wait...</span>")
video_source = comm.camera
comm.visible_message("<span class='danger'>\icon[src][bicon(src)] New video connection from [comm].</span>")
update_active_camera_screen()
GLOB.moved_event.register(video_source, src, PROC_REF(update_active_camera_screen))
update_icon()
// Proc: end_video()
// Parameters: reason - the text reason to print for why it ended
// Description: Ends the video call by clearing video_source
/obj/item/device/communicator/proc/end_video(var/reason)
GLOB.moved_event.unregister(video_source, src, PROC_REF(update_active_camera_screen))
show_static()
video_source = null
. = "<span class='danger'>\icon[src][bicon(src)] [reason ? reason : "Video session ended"].</span>"
visible_message(.)
update_icon()
// Proc: add_communicating()
// Parameters: 1 (comm - the communicator to add to communicating)
// Description: Used when this communicator gets a new communicator to relay say/me messages to
/obj/item/device/communicator/proc/add_communicating(obj/item/device/communicator/comm)
if(!comm || !istype(comm)) return
communicating |= comm
listening_objects |= src
update_icon()
// Proc: del_communicating()
// Parameters: 1 (comm - the communicator to remove from communicating)
// Description: Used when this communicator is being asked to stop relaying say/me messages to another
/obj/item/device/communicator/proc/del_communicating(obj/item/device/communicator/comm)
if(!comm || !istype(comm)) return
communicating.Remove(comm)
update_icon()
// Proc: open_connection()
// Parameters: 2 (user - the person who initiated the connecting being opened, candidate - the communicator or observer that will connect to the device)
// Description: Typechecks the candidate, then calls the correct proc for further connecting.
/obj/item/device/communicator/proc/open_connection(mob/user, var/atom/candidate)
if(isobserver(candidate))
voice_invites.Remove(candidate)
open_connection_to_ghost(user, candidate)
else
if(istype(candidate, /obj/item/device/communicator))
open_connection_to_communicator(user, candidate)
// Proc: open_connection_to_communicator()
// Parameters: 2 (user - the person who initiated this and will be receiving feedback information, candidate - someone else's communicator)
// Description: Adds the candidate and src to each other's communicating lists, allowing messages seen by the devices to be relayed.
/obj/item/device/communicator/proc/open_connection_to_communicator(mob/user, var/atom/candidate)
if(!istype(candidate, /obj/item/device/communicator))
return
var/obj/item/device/communicator/comm = candidate
voice_invites.Remove(candidate)
comm.voice_requests.Remove(src)
if(user)
comm.visible_message("<span class='notice'>\icon[src][bicon(src)] Connecting to [src].</span>")
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Attempting to call [comm].</span>")
sleep(10)
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Dialing internally from [station_name()], [system_name()].</span>")
sleep(20) //If they don't have an exonet something is very wrong and we want a runtime.
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Connection re-routed to [comm] at [comm.exonet.address].</span>")
sleep(40)
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Connection to [comm] at [comm.exonet.address] established.</span>")
comm.visible_message("<span class='notice'>\icon[src][bicon(src)] Connection to [src] at [exonet.address] established.</span>")
sleep(20)
src.add_communicating(comm)
comm.add_communicating(src)
// Proc: open_connection_to_ghost()
// Parameters: 2 (user - the person who initiated this, candidate - the ghost that will be turned into a voice mob)
// Description: Pulls the candidate ghost from deadchat, makes a new voice mob, transfers their identity, then their client.
/obj/item/device/communicator/proc/open_connection_to_ghost(mob/user, var/mob/candidate)
if(!isobserver(candidate))
return
//Handle moving the ghost into the new shell.
announce_ghost_joinleave(candidate, 0, "They are occupying a personal communications device now.")
voice_requests.Remove(candidate)
voice_invites.Remove(candidate)
var/mob/living/voice/new_voice = new /mob/living/voice(src) //Make the voice mob the ghost is going to be.
new_voice.transfer_identity(candidate) //Now make the voice mob load from the ghost's active character in preferences.
//Do some simple logging since this is a tad risky as a concept.
var/msg = "[candidate && candidate.client ? "[candidate.client.key]" : "*no key*"] ([candidate]) has entered [src], triggered by \
[user && user.client ? "[user.client.key]" : "*no key*"] ([user ? "[user]" : "*null*"]) at [x],[y],[z]. They have joined as [new_voice.name]."
message_admins(msg)
log_game(msg)
new_voice.mind = candidate.mind //Transfer the mind, if any.
new_voice.ckey = candidate.ckey //Finally, bring the client over.
voice_mobs.Add(new_voice)
listening_objects |= src
var/obj/screen/blackness = new() //Makes a black screen, so the candidate can't see what's going on before actually 'connecting' to the communicator.
blackness.screen_loc = ui_entire_screen
blackness.icon = 'icons/effects/effects.dmi'
blackness.icon_state = "1"
blackness.mouse_opacity = 2 //Can't see anything!
new_voice.client.screen.Add(blackness)
update_icon()
//Now for some connection fluff.
if(user)
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Connecting to [candidate].</span>")
to_chat(new_voice, "<span class='notice'>\icon[src][bicon(src)] Attempting to call [src].</span>")
sleep(10)
to_chat(new_voice, "<span class='notice'>\icon[src][bicon(src)] Dialing to [station_name()], Kara Subsystem, [system_name()].</span>")
sleep(20)
to_chat(new_voice, "<span class='notice'>\icon[src][bicon(src)] Connecting to [station_name()] telecommunications array.</span>")
sleep(40)
to_chat(new_voice, "<span class='notice'>\icon[src][bicon(src)] Connection to [station_name()] telecommunications array established. Redirecting signal to [src].</span>")
sleep(20)
//We're connected, no need to hide everything.
new_voice.client.screen.Remove(blackness)
qdel(blackness)
to_chat(new_voice, "<span class='notice'>\icon[src][bicon(src)] Connection to [src] established.</span>")
to_chat(new_voice, "<b>To talk to the person on the other end of the call, just talk normally.</b>")
to_chat(new_voice, "<b>If you want to end the call, use the 'Hang Up' verb. The other person can also hang up at any time.</b>")
to_chat(new_voice, "<b>Remember, your character does not know anything you've learned from observing!</b>")
if(new_voice.mind)
new_voice.mind.assigned_role = "Disembodied Voice"
if(user)
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Your communicator is now connected to [candidate]'s communicator.</span>")
// Proc: close_connection()
// Parameters: 3 (user - the user who initiated the disconnect, target - the mob or device being disconnected, reason - string shown when disconnected)
// Description: Deletes specific voice_mobs or disconnects communicators, and shows a message to everyone when doing so. If target is null, all communicators
// and voice mobs are removed.
/obj/item/device/communicator/proc/close_connection(mob/user, var/atom/target, var/reason)
if(voice_mobs.len == 0 && communicating.len == 0)
return
for(var/mob/living/voice/voice in voice_mobs) //Handle ghost-callers
if(target && voice != target) //If no target is inputted, it deletes all of them.
continue
to_chat(voice, "<span class='danger'>\icon[src][bicon(src)] [reason].</span>")
visible_message("<span class='danger'>\icon[src][bicon(src)] [reason].</span>")
voice_mobs.Remove(voice)
qdel(voice)
update_icon()
for(var/obj/item/device/communicator/comm in communicating) //Now we handle real communicators.
if(target && comm != target)
continue
src.del_communicating(comm)
comm.del_communicating(src)
comm.visible_message("<span class='danger'>\icon[src][bicon(src)] [reason].</span>")
visible_message("<span class='danger'>\icon[src][bicon(src)] [reason].</span>")
if(comm.camera && video_source == comm.camera) //We hung up on the person on video
end_video()
if(camera && comm.video_source == camera) //We hung up on them while they were watching us
comm.end_video()
if(voice_mobs.len == 0 && communicating.len == 0)
listening_objects.Remove(src)
// Proc: request()
// Parameters: 1 (candidate - the ghost or communicator wanting to call the device)
// Description: Response to a communicator or observer trying to call the device. Adds them to the list of requesters
/obj/item/device/communicator/proc/request(var/atom/candidate)
if(candidate in voice_requests)
return
var/who = null
if(isobserver(candidate))
who = candidate.name
else if(istype(candidate, /obj/item/device/communicator))
var/obj/item/device/communicator/comm = candidate
who = comm.owner
comm.voice_invites |= src
if(!who)
return
voice_requests |= candidate
if(ringer)
playsound(src, 'sound/machines/twobeep.ogg', 50, 1)
for (var/mob/O in hearers(2, loc))
O.show_message(text("\icon[src][bicon(src)] *beep*"))
alert_called = 1
update_icon()
//Search for holder of the device.
var/mob/living/L = null
if(loc && isliving(loc))
L = loc
if(L)
to_chat(L, "<span class='notice'>\icon[src][bicon(src)] Communications request from [who].</span>")
// Proc: del_request()
// Parameters: 1 (candidate - the ghost or communicator to be declined)
// Description: Declines a request and cleans up both ends
/obj/item/device/communicator/proc/del_request(var/atom/candidate)
if(!(candidate in voice_requests))
return
if(isobserver(candidate))
to_chat(candidate, "<span class='warning'>Your communicator call request was declined.</span>")
else if(istype(candidate, /obj/item/device/communicator))
var/obj/item/device/communicator/comm = candidate
comm.voice_invites -= src
voice_requests -= candidate
//Search for holder of our device.
var/mob/living/us = null
if(loc && isliving(loc))
us = loc
if(us)
to_chat(us, "<span class='notice'>\icon[src][bicon(src)] Declined request.</span>")
// Proc: see_emote()
// Parameters: 2 (M - the mob the emote originated from, text - the emote's contents)
// Description: Relays the emote to all linked communicators.
/obj/item/device/communicator/see_emote(mob/living/M, text)
var/rendered = "\icon[src][bicon(src)] <span class='message'>[text]</span>"
for(var/obj/item/device/communicator/comm in communicating)
var/turf/T = get_turf(comm)
if(!T) return
//VOREStation Edit Start for commlinks
var/list/mobs_to_relay
if(istype(comm,/obj/item/device/communicator/commlink))
var/obj/item/device/communicator/commlink/CL = comm
mobs_to_relay = list(CL.nif.human)
else
var/list/in_range = get_mobs_and_objs_in_view_fast(T,world.view,0) //Range of 3 since it's a tiny video display
mobs_to_relay = in_range["mobs"]
//VOREStation Edit End
for(var/mob/mob in mobs_to_relay) //We can't use visible_message(), or else we will get an infinite loop if two communicators hear each other.
var/dst = get_dist(get_turf(mob),get_turf(comm))
if(dst <= video_range)
mob.show_message(rendered)
else
to_chat(mob, "You can barely see some movement on \the [src]'s display.")
..()
// Proc: hear_talk()
// Parameters: 3 (M - the mob the speech originated from,
// list/message_pieces - what is being said w/ baked languages,
// verb - the word used to describe how text is being said)
// Description: Relays the speech to all linked communicators.
/obj/item/device/communicator/hear_talk(mob/M, list/message_pieces, verb)
for(var/obj/item/device/communicator/comm in communicating)
var/turf/T = get_turf(comm)
if(!T) return
//VOREStation Edit Start for commlinks
var/list/mobs_to_relay
if(istype(comm,/obj/item/device/communicator/commlink))
var/obj/item/device/communicator/commlink/CL = comm
mobs_to_relay = list(CL.nif.human)
else
var/list/in_range = get_mobs_and_objs_in_view_fast(T,world.view,0) //Range of 3 since it's a tiny video display
mobs_to_relay = in_range["mobs"]
//VOREStation Edit End
for(var/mob/mob in mobs_to_relay)
var/list/combined = mob.combine_message(message_pieces, verb, M)
var/message = combined["formatted"]
var/name_used = M.GetVoice()
var/rendered = null
rendered = "<span class='game say'>\icon[src][bicon(src)] <span class='name'>[name_used]</span> [message]</span>"
mob.show_message(rendered, 2)
// Proc: show_message()
// Parameters: 4 (msg - the message, type - number to determine if message is visible or audible, alt - unknown, alt_type - unknown)
// Description: Relays the message to all linked communicators.
/obj/item/device/communicator/show_message(msg, type, alt, alt_type)
var/rendered = "\icon[src][bicon(src)] <span class='message'>[msg]</span>"
for(var/obj/item/device/communicator/comm in communicating)
var/turf/T = get_turf(comm)
if(!T) return
var/list/in_range = get_mobs_and_objs_in_view_fast(T,world.view,0)
var/list/mobs_to_relay = in_range["mobs"]
for(var/mob/mob in mobs_to_relay)
mob.show_message(rendered)
..()
// Verb: join_as_voice()
// Parameters: None
// Description: Allows ghosts to call communicators, if they meet all the requirements.
/mob/observer/dead/verb/join_as_voice()
set category = "Ghost"
set name = "Call Communicator"
set desc = "If there is a communicator available, send a request to speak through it. This will reset your respawn timer, if someone picks up."
if(ticker.current_state < GAME_STATE_PLAYING)
to_chat(src, "<span class='danger'>The game hasn't started yet!</span>")
return
if (!src.stat)
return
if (usr != src)
return //something is terribly wrong
var/confirm = tgui_alert(src, "Would you like to talk as [src.client.prefs.real_name], over a communicator? This will reset your respawn timer, if someone answers.", "Join as Voice?", list("Yes","No"))
if(confirm == "No")
return
if(config.antag_hud_restricted && has_enabled_antagHUD == 1)
to_chat(src, "<span class='danger'>You have used the antagHUD and cannot respawn or use communicators!</span>")
return
for(var/mob/living/L in mob_list) //Simple check so you don't have dead people calling.
if(src.client.prefs.real_name == L.real_name)
to_chat(src, "<span class='danger'>Your identity is already present in the game world. Please load in a different character first.</span>")
return
var/obj/machinery/exonet_node/E = get_exonet_node()
if(!E || !E.on || !E.allow_external_communicators)
to_chat(src, "<span class='danger'>The Exonet node at telecommunications is down at the moment, or is actively blocking you, \
so your call can't go through.</span>")
return
var/list/choices = list()
for(var/obj/item/device/communicator/comm in all_communicators)
if(!comm.network_visibility || !comm.exonet || !comm.exonet.address)
continue
choices.Add(comm)
if(!choices.len)
to_chat(src , "<span class='danger'>There are no available communicators, sorry.</span>")
return
var/choice = tgui_input_list(src,"Send a voice request to whom?", "Recipient Choice", choices)
if(choice)
var/obj/item/device/communicator/chosen_communicator = choice
var/mob/observer/dead/O = src
if(O.exonet)
O.exonet.send_message(chosen_communicator.exonet.address, "voice")
to_chat(src, "A communications request has been sent to [chosen_communicator]. Now you need to wait until someone answers.")
// Proc: connect_video()
// Parameters: user - the mob doing the viewing of video, comm - the communicator at the far end
// Description: Sets up a videocall and puts the first view into it using watch_video, and updates the icon
/obj/item/device/communicator/proc/connect_video(mob/user,obj/item/device/communicator/comm)
if((!user) || (!comm) || user.stat) return //KO or dead, or already in a video
if(video_source) //Already in a video
to_chat(user, "<span class='danger'>You are already connected to a video call!</span>")
return
if(user.blinded) //User is blinded
to_chat(user, "<span class='danger'>You cannot see well enough to do that!</span>")
return
if(!(src in comm.communicating) || !comm.camera) //You called someone with a broken communicator or one that's fake or yourself or something
to_chat(user, "<span class='danger'>\icon[src][bicon(src)]ERROR: Video failed. Either bandwidth is too low, or the other communicator is malfunctioning.</span>")
return
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Attempting to start video over existing call.</span>")
sleep(30)
to_chat(user, "<span class='notice'>\icon[src][bicon(src)] Please wait...</span>")
video_source = comm.camera
comm.visible_message("<span class='danger'>\icon[src][bicon(src)] New video connection from [comm].</span>")
update_active_camera_screen()
GLOB.moved_event.register(video_source, src, PROC_REF(update_active_camera_screen))
update_icon()
// Proc: end_video()
// Parameters: reason - the text reason to print for why it ended
// Description: Ends the video call by clearing video_source
/obj/item/device/communicator/proc/end_video(var/reason)
GLOB.moved_event.unregister(video_source, src, PROC_REF(update_active_camera_screen))
show_static()
video_source = null
. = "<span class='danger'>\icon[src][bicon(src)] [reason ? reason : "Video session ended"].</span>"
visible_message(.)
update_icon()
+45 -45
View File
@@ -1,45 +1,45 @@
/**
* Multitool -- A multitool is used for hacking electronic devices.
* TO-DO -- Using it as a power measurement tool for cables etc. Nannek.
*
*/
/obj/item/device/debugger
name = "debugger"
desc = "Used to debug electronic equipment."
icon = 'icons/obj/hacktool.dmi'
icon_state = "hacktool-g"
force = 5.0
w_class = ITEMSIZE_SMALL
throwforce = 5.0
throw_range = 15
throw_speed = 3
desc = "You can use this on airlocks or APCs to try to hack them without cutting wires."
matter = list(MAT_STEEL = 50,MAT_GLASS = 20)
origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1)
var/obj/machinery/telecomms/buffer // simple machine buffer for device linkage
/obj/item/device/debugger/is_used_on(obj/O, mob/user)
if(istype(O, /obj/machinery/power/apc))
var/obj/machinery/power/apc/A = O
if(A.emagged || A.hacker)
to_chat(user, "<span class='warning'>There is a software error with the device.</span>")
else
to_chat(user, "<span class='notice'>The device's software appears to be fine.</span>")
return 1
if(istype(O, /obj/machinery/door))
var/obj/machinery/door/D = O
if(D.operating == -1)
to_chat(user, "<span class='warning'>There is a software error with the device.</span>")
else
to_chat(user, "<span class='notice'>The device's software appears to be fine.</span>")
return 1
else if(istype(O, /obj/machinery))
var/obj/machinery/A = O
if(A.emagged)
to_chat(user, "<span class='warning'>There is a software error with the device.</span>")
else
to_chat(user, "<span class='notice'>The device's software appears to be fine.</span>")
return 1
/**
* Multitool -- A multitool is used for hacking electronic devices.
* TO-DO -- Using it as a power measurement tool for cables etc. Nannek.
*
*/
/obj/item/device/debugger
name = "debugger"
desc = "Used to debug electronic equipment."
icon = 'icons/obj/hacktool.dmi'
icon_state = "hacktool-g"
force = 5.0
w_class = ITEMSIZE_SMALL
throwforce = 5.0
throw_range = 15
throw_speed = 3
desc = "You can use this on airlocks or APCs to try to hack them without cutting wires."
matter = list(MAT_STEEL = 50,MAT_GLASS = 20)
origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1)
var/obj/machinery/telecomms/buffer // simple machine buffer for device linkage
/obj/item/device/debugger/is_used_on(obj/O, mob/user)
if(istype(O, /obj/machinery/power/apc))
var/obj/machinery/power/apc/A = O
if(A.emagged || A.hacker)
to_chat(user, "<span class='warning'>There is a software error with the device.</span>")
else
to_chat(user, "<span class='notice'>The device's software appears to be fine.</span>")
return 1
if(istype(O, /obj/machinery/door))
var/obj/machinery/door/D = O
if(D.operating == -1)
to_chat(user, "<span class='warning'>There is a software error with the device.</span>")
else
to_chat(user, "<span class='notice'>The device's software appears to be fine.</span>")
return 1
else if(istype(O, /obj/machinery))
var/obj/machinery/A = O
if(A.emagged)
to_chat(user, "<span class='warning'>There is a software error with the device.</span>")
else
to_chat(user, "<span class='notice'>The device's software appears to be fine.</span>")
return 1
+321 -321
View File
@@ -1,321 +1,321 @@
/obj/item/device/flash
name = "flash"
desc = "Used for blinding and disorienting."
icon_state = "flash"
item_state = "flashtool"
throwforce = 5
w_class = ITEMSIZE_SMALL
throw_speed = 4
throw_range = 10
origin_tech = list(TECH_MAGNET = 2, TECH_COMBAT = 1)
var/times_used = 0 //Number of times it's been used.
var/broken = FALSE //Is the flash burnt out?
var/last_used = 0 //last world.time it was used.
var/max_flashes = 10 // How many times the flash can be used before needing to self recharge.
var/halloss_per_flash = 30
var/break_mod = 3 // The percent to break increased by every use on the flash.
var/can_break = TRUE // Can the flash break?
var/can_repair = FALSE // Can you repair the flash?
var/repairing = FALSE // Are we repairing right now?
var/safe_flashes = 2 // How many flashes are kept in 1% breakchance?
var/charge_only = FALSE // Does the flash run purely on charge?
var/base_icon = "flash"
var/obj/item/weapon/cell/power_supply //What type of power cell this uses
var/charge_cost = 30 //How much energy is needed to flash.
var/use_external_power = FALSE // Do we use charge from an external source?
var/cell_type = /obj/item/weapon/cell/device
/obj/item/device/flash/Initialize()
. = ..()
power_supply = new cell_type(src)
/obj/item/device/flash/attackby(var/obj/item/W, var/mob/user)
if(W.has_tool_quality(TOOL_SCREWDRIVER) && broken)
if(repairing)
to_chat(user, "<span class='notice'>\The [src] is already being repaired!</span>")
return
user.visible_message("<b>\The [user]</b> starts trying to repair \the [src]'s bulb.")
repairing = TRUE
if(do_after(user, (40 SECONDS + rand(0, 20 SECONDS)) * W.toolspeed) && can_repair)
if(prob(30))
user.visible_message("<span class='notice'>\The [user] successfully repairs \the [src]!</span>")
broken = FALSE
update_icon()
playsound(src, W.usesound, 50, 1)
else
user.visible_message("<b>\The [user]</b> fails to repair \the [src].")
repairing = FALSE
else
..()
/obj/item/device/flash/update_icon()
var/obj/item/weapon/cell/battery = power_supply
if(use_external_power)
battery = get_external_power_supply()
if(broken || !battery || battery.charge < charge_cost)
icon_state = "[base_icon]burnt"
else
icon_state = "[base_icon]"
return
/obj/item/device/flash/get_cell()
return power_supply
/obj/item/device/flash/proc/get_external_power_supply()
if(isrobot(src.loc))
var/mob/living/silicon/robot/R = src.loc
return R.cell
if(istype(src.loc, /obj/item/rig_module))
var/obj/item/rig_module/module = src.loc
if(module.holder && module.holder.wearer)
var/mob/living/carbon/human/H = module.holder.wearer
if(istype(H) && H.get_rig())
var/obj/item/weapon/rig/suit = H.get_rig()
if(istype(suit))
return suit.cell
return null
/obj/item/device/flash/proc/clown_check(var/mob/user)
if(user && (CLUMSY in user.mutations) && prob(50))
to_chat(user, "<span class='warning'>\The [src] slips out of your hand.</span>")
user.drop_item()
return 0
return 1
/obj/item/device/flash/proc/flash_recharge()
//Every ten seconds the flash doesn't get used, the times_used variable goes down by one, making the flash less likely to burn out,
// as well as being able to flash more before reaching max_flashes cap.
for(var/i=0, i < max_flashes, i++)
if(last_used + 10 SECONDS > world.time)
break
else if(use_external_power)
var/obj/item/weapon/cell/external = get_external_power_supply()
if(!external || !external.use(charge_cost)) //Take power from the borg or rig!
break
else if(!power_supply || !power_supply.checked_use(charge_cost))
break
last_used += 10 SECONDS
times_used--
last_used = world.time
times_used = max(0,round(times_used)) //sanity
update_icon()
// Returns true if the device can flash.
/obj/item/device/flash/proc/check_capacitor(var/mob/user)
//spamming the flash before it's fully charged (60 seconds) increases the chance of it breaking
//It will never break on the first use.
var/obj/item/weapon/cell/battery = power_supply
if(use_external_power)
battery = get_external_power_supply()
if(times_used <= max_flashes && battery && battery.charge >= charge_cost)
last_used = world.time
if(prob( max(0, times_used - safe_flashes) * 2 + (times_used >= safe_flashes)) && can_break) //if you use it 10 times in a minute it has a 30% chance to break.
broken = TRUE
if(user)
to_chat(user, "<span class='warning'>The bulb has burnt out!</span>")
update_icon()
return FALSE
else
times_used++
update_icon()
return TRUE
else if(!charge_only) //can only use it 10 times a minute, unless it runs purely on charge.
if(user)
update_icon()
to_chat(user, "<span class='warning'><i>click</i></span>")
playsound(src, 'sound/weapons/empty.ogg', 80, 1)
return FALSE
else if(battery && battery.checked_use(charge_cost + (round(charge_cost / 4) * max(0, times_used - max_flashes)))) // Using over your maximum flashes starts taking more charge per added flash.
times_used++
update_icon()
return TRUE
//attack_as_weapon
/obj/item/device/flash/attack(mob/living/M, mob/living/user, var/target_zone)
if(!user || !M) return //sanity
add_attack_logs(user,M,"Flashed (attempt) with [src]")
user.setClickCooldown(user.get_attack_speed(src))
user.do_attack_animation(M)
if(!clown_check(user)) return
if(broken)
to_chat(user, "<span class='warning'>\The [src] is broken.</span>")
return
flash_recharge()
if(!check_capacitor(user))
return
playsound(src, 'sound/weapons/flash.ogg', 100, 1)
var/flashfail = 0
//VOREStation Add - NIF
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.nif && H.nif.flag_check(NIF_V_FLASHPROT,NIF_FLAGS_VISION))
flashfail = 1
H.nif.notify("High intensity light detected, and blocked!",TRUE)
//VOREStation Add End
if(iscarbon(M) && !flashfail) //VOREStation Add - NIF
var/mob/living/carbon/C = M
if(C.stat != DEAD)
var/safety = C.eyecheck()
if(safety <= 0)
var/flash_strength = 10 //Vorestation edit, making flashes behave the same as flash rounds
if(ishuman(C))
var/mob/living/carbon/human/H = C
flash_strength *= H.species.flash_mod
if(flash_strength > 0)
H.Confuse(flash_strength + 5)
H.Blind(flash_strength)
H.eye_blurry = max(H.eye_blurry, flash_strength + 5)
H.flash_eyes()
H.adjustHalLoss(halloss_per_flash * (flash_strength / 5)) // Should take four flashes to stun.
H.apply_damage(flash_strength * H.species.flash_burn/5, BURN, BP_HEAD, 0, 0, "Photon burns")
else
flashfail = 1
else if(issilicon(M))
flashfail = 0
var/mob/living/silicon/S = M
if(isrobot(S))
var/mob/living/silicon/robot/R = S
if(R.has_active_type(/obj/item/borg/combat/shield))
var/obj/item/borg/combat/shield/shield = locate() in R
if(shield)
if(shield.active)
shield.adjust_flash_count(R, 1)
flashfail = 1
else
flashfail = 1
if(isrobot(user))
spawn(0)
var/atom/movable/overlay/animation = new(user.loc)
animation.layer = user.layer + 1
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = user
flick("blspell", animation)
sleep(5)
qdel(animation)
if(!flashfail)
flick("flash2", src)
if(!issilicon(M))
user.visible_message("<span class='disarm'>[user] blinds [M] with the flash!</span>")
else
user.visible_message("<span class='notice'>[user] overloads [M]'s sensors with the flash!</span>")
M.Weaken(rand(5,10))
else
user.visible_message("<span class='notice'>[user] fails to blind [M] with the flash!</span>")
return
/obj/item/device/flash/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
if(!user || !clown_check(user)) return
user.setClickCooldown(user.get_attack_speed(src))
if(broken)
user.show_message("<span class='warning'>The [src.name] is broken</span>", 2)
return
flash_recharge()
if(!check_capacitor(user))
return
playsound(src, 'sound/weapons/flash.ogg', 100, 1)
flick("flash2", src)
if(user && isrobot(user))
spawn(0)
var/atom/movable/overlay/animation = new(user.loc)
animation.layer = user.layer + 1
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = user
flick("blspell", animation)
sleep(5)
qdel(animation)
for(var/mob/living/carbon/C in oviewers(3, null))
var/safety = C.eyecheck()
if(!safety)
if(!C.blinded)
C.flash_eyes()
return
/obj/item/device/flash/emp_act(severity)
if(broken) return
flash_recharge()
if(!check_capacitor())
return
if(istype(loc, /mob/living/carbon))
var/mob/living/carbon/C = loc
var/safety = C.eyecheck()
if(safety <= 0)
C.adjustHalLoss(halloss_per_flash)
//C.Weaken(10)
C.flash_eyes()
for(var/mob/M in viewers(C, null))
M.show_message("<span class='disarm'>[C] is blinded by the flash!</span>")
..()
/obj/item/device/flash/synthetic
name = "synthetic flash"
desc = "When a problem arises, SCIENCE is the solution."
icon_state = "sflash"
origin_tech = list(TECH_MAGNET = 2, TECH_COMBAT = 1)
base_icon = "sflash"
can_repair = FALSE
//attack_as_weapon
/obj/item/device/flash/synthetic/attack(mob/living/M, mob/living/user, var/target_zone)
..()
if(!broken)
broken = 1
to_chat(user, "<span class='warning'>The bulb has burnt out!</span>")
update_icon()
/obj/item/device/flash/synthetic/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
..()
if(!broken)
broken = 1
to_chat(user, "<span class='warning'>The bulb has burnt out!</span>")
update_icon()
/obj/item/device/flash/robot
name = "mounted flash"
can_break = FALSE
use_external_power = TRUE
charge_only = TRUE
/obj/item/device/flash
name = "flash"
desc = "Used for blinding and disorienting."
icon_state = "flash"
item_state = "flashtool"
throwforce = 5
w_class = ITEMSIZE_SMALL
throw_speed = 4
throw_range = 10
origin_tech = list(TECH_MAGNET = 2, TECH_COMBAT = 1)
var/times_used = 0 //Number of times it's been used.
var/broken = FALSE //Is the flash burnt out?
var/last_used = 0 //last world.time it was used.
var/max_flashes = 10 // How many times the flash can be used before needing to self recharge.
var/halloss_per_flash = 30
var/break_mod = 3 // The percent to break increased by every use on the flash.
var/can_break = TRUE // Can the flash break?
var/can_repair = FALSE // Can you repair the flash?
var/repairing = FALSE // Are we repairing right now?
var/safe_flashes = 2 // How many flashes are kept in 1% breakchance?
var/charge_only = FALSE // Does the flash run purely on charge?
var/base_icon = "flash"
var/obj/item/weapon/cell/power_supply //What type of power cell this uses
var/charge_cost = 30 //How much energy is needed to flash.
var/use_external_power = FALSE // Do we use charge from an external source?
var/cell_type = /obj/item/weapon/cell/device
/obj/item/device/flash/Initialize()
. = ..()
power_supply = new cell_type(src)
/obj/item/device/flash/attackby(var/obj/item/W, var/mob/user)
if(W.has_tool_quality(TOOL_SCREWDRIVER) && broken)
if(repairing)
to_chat(user, "<span class='notice'>\The [src] is already being repaired!</span>")
return
user.visible_message("<b>\The [user]</b> starts trying to repair \the [src]'s bulb.")
repairing = TRUE
if(do_after(user, (40 SECONDS + rand(0, 20 SECONDS)) * W.toolspeed) && can_repair)
if(prob(30))
user.visible_message("<span class='notice'>\The [user] successfully repairs \the [src]!</span>")
broken = FALSE
update_icon()
playsound(src, W.usesound, 50, 1)
else
user.visible_message("<b>\The [user]</b> fails to repair \the [src].")
repairing = FALSE
else
..()
/obj/item/device/flash/update_icon()
var/obj/item/weapon/cell/battery = power_supply
if(use_external_power)
battery = get_external_power_supply()
if(broken || !battery || battery.charge < charge_cost)
icon_state = "[base_icon]burnt"
else
icon_state = "[base_icon]"
return
/obj/item/device/flash/get_cell()
return power_supply
/obj/item/device/flash/proc/get_external_power_supply()
if(isrobot(src.loc))
var/mob/living/silicon/robot/R = src.loc
return R.cell
if(istype(src.loc, /obj/item/rig_module))
var/obj/item/rig_module/module = src.loc
if(module.holder && module.holder.wearer)
var/mob/living/carbon/human/H = module.holder.wearer
if(istype(H) && H.get_rig())
var/obj/item/weapon/rig/suit = H.get_rig()
if(istype(suit))
return suit.cell
return null
/obj/item/device/flash/proc/clown_check(var/mob/user)
if(user && (CLUMSY in user.mutations) && prob(50))
to_chat(user, "<span class='warning'>\The [src] slips out of your hand.</span>")
user.drop_item()
return 0
return 1
/obj/item/device/flash/proc/flash_recharge()
//Every ten seconds the flash doesn't get used, the times_used variable goes down by one, making the flash less likely to burn out,
// as well as being able to flash more before reaching max_flashes cap.
for(var/i=0, i < max_flashes, i++)
if(last_used + 10 SECONDS > world.time)
break
else if(use_external_power)
var/obj/item/weapon/cell/external = get_external_power_supply()
if(!external || !external.use(charge_cost)) //Take power from the borg or rig!
break
else if(!power_supply || !power_supply.checked_use(charge_cost))
break
last_used += 10 SECONDS
times_used--
last_used = world.time
times_used = max(0,round(times_used)) //sanity
update_icon()
// Returns true if the device can flash.
/obj/item/device/flash/proc/check_capacitor(var/mob/user)
//spamming the flash before it's fully charged (60 seconds) increases the chance of it breaking
//It will never break on the first use.
var/obj/item/weapon/cell/battery = power_supply
if(use_external_power)
battery = get_external_power_supply()
if(times_used <= max_flashes && battery && battery.charge >= charge_cost)
last_used = world.time
if(prob( max(0, times_used - safe_flashes) * 2 + (times_used >= safe_flashes)) && can_break) //if you use it 10 times in a minute it has a 30% chance to break.
broken = TRUE
if(user)
to_chat(user, "<span class='warning'>The bulb has burnt out!</span>")
update_icon()
return FALSE
else
times_used++
update_icon()
return TRUE
else if(!charge_only) //can only use it 10 times a minute, unless it runs purely on charge.
if(user)
update_icon()
to_chat(user, "<span class='warning'><i>click</i></span>")
playsound(src, 'sound/weapons/empty.ogg', 80, 1)
return FALSE
else if(battery && battery.checked_use(charge_cost + (round(charge_cost / 4) * max(0, times_used - max_flashes)))) // Using over your maximum flashes starts taking more charge per added flash.
times_used++
update_icon()
return TRUE
//attack_as_weapon
/obj/item/device/flash/attack(mob/living/M, mob/living/user, var/target_zone)
if(!user || !M) return //sanity
add_attack_logs(user,M,"Flashed (attempt) with [src]")
user.setClickCooldown(user.get_attack_speed(src))
user.do_attack_animation(M)
if(!clown_check(user)) return
if(broken)
to_chat(user, "<span class='warning'>\The [src] is broken.</span>")
return
flash_recharge()
if(!check_capacitor(user))
return
playsound(src, 'sound/weapons/flash.ogg', 100, 1)
var/flashfail = 0
//VOREStation Add - NIF
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.nif && H.nif.flag_check(NIF_V_FLASHPROT,NIF_FLAGS_VISION))
flashfail = 1
H.nif.notify("High intensity light detected, and blocked!",TRUE)
//VOREStation Add End
if(iscarbon(M) && !flashfail) //VOREStation Add - NIF
var/mob/living/carbon/C = M
if(C.stat != DEAD)
var/safety = C.eyecheck()
if(safety <= 0)
var/flash_strength = 10 //Vorestation edit, making flashes behave the same as flash rounds
if(ishuman(C))
var/mob/living/carbon/human/H = C
flash_strength *= H.species.flash_mod
if(flash_strength > 0)
H.Confuse(flash_strength + 5)
H.Blind(flash_strength)
H.eye_blurry = max(H.eye_blurry, flash_strength + 5)
H.flash_eyes()
H.adjustHalLoss(halloss_per_flash * (flash_strength / 5)) // Should take four flashes to stun.
H.apply_damage(flash_strength * H.species.flash_burn/5, BURN, BP_HEAD, 0, 0, "Photon burns")
else
flashfail = 1
else if(issilicon(M))
flashfail = 0
var/mob/living/silicon/S = M
if(isrobot(S))
var/mob/living/silicon/robot/R = S
if(R.has_active_type(/obj/item/borg/combat/shield))
var/obj/item/borg/combat/shield/shield = locate() in R
if(shield)
if(shield.active)
shield.adjust_flash_count(R, 1)
flashfail = 1
else
flashfail = 1
if(isrobot(user))
spawn(0)
var/atom/movable/overlay/animation = new(user.loc)
animation.layer = user.layer + 1
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = user
flick("blspell", animation)
sleep(5)
qdel(animation)
if(!flashfail)
flick("flash2", src)
if(!issilicon(M))
user.visible_message("<span class='disarm'>[user] blinds [M] with the flash!</span>")
else
user.visible_message("<span class='notice'>[user] overloads [M]'s sensors with the flash!</span>")
M.Weaken(rand(5,10))
else
user.visible_message("<span class='notice'>[user] fails to blind [M] with the flash!</span>")
return
/obj/item/device/flash/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
if(!user || !clown_check(user)) return
user.setClickCooldown(user.get_attack_speed(src))
if(broken)
user.show_message("<span class='warning'>The [src.name] is broken</span>", 2)
return
flash_recharge()
if(!check_capacitor(user))
return
playsound(src, 'sound/weapons/flash.ogg', 100, 1)
flick("flash2", src)
if(user && isrobot(user))
spawn(0)
var/atom/movable/overlay/animation = new(user.loc)
animation.layer = user.layer + 1
animation.icon_state = "blank"
animation.icon = 'icons/mob/mob.dmi'
animation.master = user
flick("blspell", animation)
sleep(5)
qdel(animation)
for(var/mob/living/carbon/C in oviewers(3, null))
var/safety = C.eyecheck()
if(!safety)
if(!C.blinded)
C.flash_eyes()
return
/obj/item/device/flash/emp_act(severity)
if(broken) return
flash_recharge()
if(!check_capacitor())
return
if(istype(loc, /mob/living/carbon))
var/mob/living/carbon/C = loc
var/safety = C.eyecheck()
if(safety <= 0)
C.adjustHalLoss(halloss_per_flash)
//C.Weaken(10)
C.flash_eyes()
for(var/mob/M in viewers(C, null))
M.show_message("<span class='disarm'>[C] is blinded by the flash!</span>")
..()
/obj/item/device/flash/synthetic
name = "synthetic flash"
desc = "When a problem arises, SCIENCE is the solution."
icon_state = "sflash"
origin_tech = list(TECH_MAGNET = 2, TECH_COMBAT = 1)
base_icon = "sflash"
can_repair = FALSE
//attack_as_weapon
/obj/item/device/flash/synthetic/attack(mob/living/M, mob/living/user, var/target_zone)
..()
if(!broken)
broken = 1
to_chat(user, "<span class='warning'>The bulb has burnt out!</span>")
update_icon()
/obj/item/device/flash/synthetic/attack_self(mob/living/carbon/user as mob, flag = 0, emp = 0)
..()
if(!broken)
broken = 1
to_chat(user, "<span class='warning'>The bulb has burnt out!</span>")
update_icon()
/obj/item/device/flash/robot
name = "mounted flash"
can_break = FALSE
use_external_power = TRUE
charge_only = TRUE
+493 -493
View File
@@ -1,493 +1,493 @@
/*
* Contains:
* Flashlights
* Lamps
* Flares
* Chemlights
* Slime Extract
*/
/*
* Flashlights
*/
/obj/item/device/flashlight
name = "flashlight"
desc = "A hand-held emergency light."
icon = 'icons/obj/lighting.dmi'
icon_state = "flashlight"
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_BELT
matter = list(MAT_STEEL = 50,MAT_GLASS = 20)
action_button_name = "Toggle Flashlight"
light_system = MOVABLE_LIGHT_DIRECTIONAL
light_range = 4 //luminosity when on
light_power = 0.8 //lighting power when on
light_color = "#FFFFFF" //LIGHT_COLOR_INCANDESCENT_FLASHLIGHT //lighting colour when on
light_cone_y_offset = -7
var/on = 0
var/obj/item/weapon/cell/cell
var/cell_type = /obj/item/weapon/cell/device
var/power_usage = 1
var/power_use = 1
/obj/item/device/flashlight/Initialize()
. = ..()
if(power_use && cell_type)
cell = new cell_type(src)
update_brightness()
/obj/item/device/flashlight/Destroy()
STOP_PROCESSING(SSobj, src)
qdel_null(cell)
return ..()
/obj/item/device/flashlight/get_cell()
return cell
/obj/item/device/flashlight/process()
if(!on || !cell)
return PROCESS_KILL
if(power_usage)
if(cell.use(power_usage) != power_usage) // we weren't able to use our full power_usage amount!
visible_message("<span class='warning'>\The [src] flickers before going dull.</span>")
playsound(src, 'sound/effects/sparks3.ogg', 10, 1, -3) //Small cue that your light went dull in your pocket. //VOREStation Edit
on = 0
update_brightness()
return PROCESS_KILL
/obj/item/device/flashlight/proc/update_brightness()
if(on)
icon_state = "[initial(icon_state)]-on"
else
icon_state = initial(icon_state)
set_light_on(on)
if(light_system == STATIC_LIGHT)
update_light()
/obj/item/device/flashlight/examine(mob/user)
. = ..()
if(power_use && cell)
. += "\The [src] has a \the [cell] attached."
if(cell.charge <= cell.maxcharge*0.25)
. += "It appears to have a low amount of power remaining."
else if(cell.charge > cell.maxcharge*0.25 && cell.charge <= cell.maxcharge*0.5)
. += "It appears to have an average amount of power remaining."
else if(cell.charge > cell.maxcharge*0.5 && cell.charge <= cell.maxcharge*0.75)
. += "It appears to have an above average amount of power remaining."
else if(cell.charge > cell.maxcharge*0.75 && cell.charge <= cell.maxcharge)
. += "It appears to have a high amount of power remaining."
/obj/item/device/flashlight/attack_self(mob/user)
if(power_use)
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
if(!cell || cell.charge == 0)
to_chat(user, "You flick the switch on [src], but nothing happens.")
return 0
on = !on
if(on && power_use)
START_PROCESSING(SSobj, src)
else if(power_use)
STOP_PROCESSING(SSobj, src)
playsound(src, 'sound/weapons/empty.ogg', 15, 1, -3) // VOREStation Edit
update_brightness()
user.update_action_buttons()
return 1
/obj/item/device/flashlight/emp_act(severity)
for(var/obj/O in contents)
O.emp_act(severity)
..()
/obj/item/device/flashlight/attack(mob/living/M as mob, mob/living/user as mob)
add_fingerprint(user)
if(on && user.zone_sel.selecting == O_EYES)
if((CLUMSY in user.mutations) && prob(50)) //too dumb to use flashlight properly
return ..() //just hit them in the head
var/mob/living/carbon/human/H = M //mob has protective eyewear
if(istype(H))
for(var/obj/item/clothing/C in list(H.head,H.wear_mask,H.glasses))
if(istype(C) && (C.body_parts_covered & EYES))
to_chat(user, "<span class='warning'>You're going to need to remove [C.name] first.</span>")
return
var/obj/item/organ/vision
if(H.species.vision_organ)
vision = H.internal_organs_by_name[H.species.vision_organ]
if(!vision)
user.visible_message("<b>\The [user]</b> directs [src] at [M]'s face.", \
"<span class='notice'>You direct [src] at [M]'s face.</span>")
to_chat(user, "<span class='warning'>You can't find any [H.species.vision_organ ? H.species.vision_organ : "eyes"] on [H]!</span>")
user.setClickCooldown(user.get_attack_speed(src))
return
user.visible_message("<b>\The [user]</b> directs [src] to [M]'s eyes.", \
"<span class='notice'>You direct [src] to [M]'s eyes.</span>")
if(H != user) //can't look into your own eyes buster
if(M.stat == DEAD || M.blinded) //mob is dead or fully blind
to_chat(user, "<span class='warning'>\The [M]'s pupils do not react to the light!</span>")
return
if(XRAY in M.mutations)
to_chat(user, "<span class='notice'>\The [M] pupils give an eerie glow!</span>")
if(vision.is_bruised())
to_chat(user, "<span class='warning'>There's visible damage to [M]'s [vision.name]!</span>")
else if(M.eye_blurry)
to_chat(user, "<span class='notice'>\The [M]'s pupils react slower than normally.</span>")
if(M.getBrainLoss() > 15)
to_chat(user, "<span class='notice'>There's visible lag between left and right pupils' reactions.</span>")
var/list/pinpoint = list("oxycodone"=1,"tramadol"=5)
var/list/dilating = list("bliss"=5,"ambrosia_extract"=5,"mindbreaker"=1)
if(M.reagents.has_any_reagent(pinpoint) || H.ingested.has_any_reagent(pinpoint))
to_chat(user, "<span class='notice'>\The [M]'s pupils are already pinpoint and cannot narrow any more.</span>")
else if(M.reagents.has_any_reagent(dilating) || H.ingested.has_any_reagent(dilating))
to_chat(user, "<span class='notice'>\The [M]'s pupils narrow slightly, but are still very dilated.</span>")
else
to_chat(user, "<span class='notice'>\The [M]'s pupils narrow.</span>")
user.setClickCooldown(user.get_attack_speed(src)) //can be used offensively
M.flash_eyes()
else
return ..()
/obj/item/device/flashlight/attack_hand(mob/user as mob)
if(user.get_inactive_hand() == src)
if(cell)
cell.update_icon()
user.put_in_hands(cell)
cell = null
to_chat(user, "<span class='notice'>You remove the cell from the [src].</span>")
playsound(src, 'sound/machines/button.ogg', 30, 1, 0)
on = 0
update_brightness()
return
..()
else
return ..()
/obj/item/device/flashlight/MouseDrop(obj/over_object as obj)
if(!canremove)
return
if (ishuman(usr) || issmall(usr)) //so monkeys can take off their backpacks -- Urist
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech. why?
return
if (!( istype(over_object, /obj/screen) ))
return ..()
//makes sure that the thing is equipped, so that we can't drag it into our hand from miles away.
//there's got to be a better way of doing this.
if (!(src.loc == usr) || (src.loc && src.loc.loc == usr))
return
if (( usr.restrained() ) || ( usr.stat ))
return
if ((src.loc == usr) && !(istype(over_object, /obj/screen)) && !usr.unEquip(src))
return
switch(over_object.name)
if("r_hand")
usr.u_equip(src)
usr.put_in_r_hand(src)
if("l_hand")
usr.u_equip(src)
usr.put_in_l_hand(src)
src.add_fingerprint(usr)
/obj/item/device/flashlight/attackby(obj/item/weapon/W, mob/user as mob)
if(power_use)
if(istype(W, /obj/item/weapon/cell))
if(istype(W, /obj/item/weapon/cell/device))
if(!cell)
user.drop_item()
W.loc = src
cell = W
to_chat(user, "<span class='notice'>You install a cell in \the [src].</span>")
playsound(src, 'sound/machines/button.ogg', 30, 1, 0)
update_brightness()
else
to_chat(user, "<span class='notice'>\The [src] already has a cell.</span>")
else
to_chat(user, "<span class='notice'>\The [src] cannot use that type of cell.</span>")
else
..()
/obj/item/device/flashlight/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
if(!on)
return
if(light_system == MOVABLE_LIGHT_DIRECTIONAL)
var/datum/component/overlay_lighting/OL = GetComponent(/datum/component/overlay_lighting)
if(!OL)
return
var/turf/T = get_turf(target)
OL.place_directional_light(T)
/obj/item/device/flashlight/pen
name = "penlight"
desc = "A pen-sized light, used by medical staff."
icon_state = "penlight"
item_state = "pen"
drop_sound = 'sound/items/drop/accessory.ogg'
pickup_sound = 'sound/items/pickup/accessory.ogg'
slot_flags = SLOT_EARS
light_range = 2
w_class = ITEMSIZE_TINY
power_use = 0
/obj/item/device/flashlight/color //Default color is blue
name = "blue flashlight"
desc = "A small flashlight. This one is blue."
icon_state = "flashlight_blue"
/obj/item/device/flashlight/color/green
name = "green flashlight"
desc = "A small flashlight. This one is green."
icon_state = "flashlight_green"
/obj/item/device/flashlight/color/purple
name = "purple flashlight"
desc = "A small flashlight. This one is purple."
icon_state = "flashlight_purple"
/obj/item/device/flashlight/color/red
name = "red flashlight"
desc = "A small flashlight. This one is red."
icon_state = "flashlight_red"
/obj/item/device/flashlight/color/orange
name = "orange flashlight"
desc = "A small flashlight. This one is orange."
icon_state = "flashlight_orange"
/obj/item/device/flashlight/color/yellow
name = "yellow flashlight"
desc = "A small flashlight. This one is yellow."
icon_state = "flashlight_yellow"
/obj/item/device/flashlight/maglight
name = "maglight"
desc = "A very, very heavy duty flashlight."
icon_state = "maglight"
light_color = LIGHT_COLOR_FLUORESCENT_FLASHLIGHT
force = 10
slot_flags = SLOT_BELT
w_class = ITEMSIZE_SMALL
attack_verb = list ("smacked", "thwacked", "thunked")
matter = list(MAT_STEEL = 200,MAT_GLASS = 50)
hitsound = "swing_hit"
/obj/item/device/flashlight/drone
name = "low-power flashlight"
desc = "A miniature lamp, that might be used by small robots."
icon_state = "penlight"
item_state = null
light_range = 2
w_class = ITEMSIZE_TINY
power_use = 0
/*
* Lamps
*/
// pixar desk lamp
/obj/item/device/flashlight/lamp
name = "desk lamp"
desc = "A desk lamp with an adjustable mount."
icon_state = "lamp"
force = 10
center_of_mass = list("x" = 13,"y" = 11)
light_range = 5
w_class = ITEMSIZE_LARGE
power_use = 0
on = 1
light_system = STATIC_LIGHT
/obj/item/device/flashlight/lamp/verb/toggle_light()
set name = "Toggle light"
set category = "Object"
set src in oview(1)
if(!usr.stat)
attack_self(usr)
// green-shaded desk lamp
/obj/item/device/flashlight/lamp/green
desc = "A classic green-shaded desk lamp."
icon_state = "lampgreen"
center_of_mass = list("x" = 15,"y" = 11)
light_color = "#FFC58F"
// clown lamp
/obj/item/device/flashlight/lamp/clown
desc = "A whacky banana peel shaped lamp."
icon_state = "bananalamp"
center_of_mass = list("x" = 15,"y" = 11)
/*
* Flares
*/
/obj/item/device/flashlight/flare
name = "flare"
desc = "A red standard-issue flare. There are instructions on the side reading 'pull cord, make light'."
w_class = ITEMSIZE_SMALL
light_range = 8 // Pretty bright.
light_power = 0.8
light_color = LIGHT_COLOR_FLARE
icon_state = "flare"
item_state = "flare"
action_button_name = null //just pull it manually, neckbeard.
var/fuel = 0
var/on_damage = 7
var/produce_heat = 1500
power_use = 0
drop_sound = 'sound/items/drop/gloves.ogg'
pickup_sound = 'sound/items/pickup/gloves.ogg'
light_system = MOVABLE_LIGHT
/obj/item/device/flashlight/flare/New()
fuel = rand(800, 1000) // Sorry for changing this so much but I keep under-estimating how long X number of ticks last in seconds.
..()
/obj/item/device/flashlight/flare/process()
var/turf/pos = get_turf(src)
if(pos)
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/device/flashlight/flare/proc/turn_off()
on = 0
src.force = initial(src.force)
src.damtype = initial(src.damtype)
update_brightness()
/obj/item/device/flashlight/flare/attack_self(mob/user)
// Usual checks
if(!fuel)
to_chat(user, "<span class='notice'>It's out of fuel.</span>")
return
if(on)
return
. = ..()
// All good, turn it on.
if(.)
user.visible_message("<span class='notice'>[user] activates the flare.</span>", "<span class='notice'>You pull the cord on the flare, activating it!</span>")
src.force = on_damage
src.damtype = "fire"
START_PROCESSING(SSobj, src)
/obj/item/device/flashlight/flare/proc/ignite() //Used for flare launchers.
on = !on
update_brightness()
force = on_damage
damtype = "fire"
START_PROCESSING(SSobj, src)
return 1
/*
* Chemlights
*/
/obj/item/device/flashlight/glowstick
name = "green glowstick"
desc = "A green military-grade chemical light."
w_class = ITEMSIZE_SMALL
light_system = MOVABLE_LIGHT
light_range = 4
light_power = 0.9
light_color = "#49F37C"
icon_state = "glowstick_green"
item_state = "glowstick_green"
var/fuel = 0
power_use = 0
/obj/item/device/flashlight/glowstick/New()
fuel = rand(1600, 2000)
..()
/obj/item/device/flashlight/glowstick/process()
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/device/flashlight/glowstick/proc/turn_off()
on = 0
update_brightness()
/obj/item/device/flashlight/glowstick/attack_self(mob/user)
if(!fuel)
to_chat(user, "<span class='notice'>The glowstick has already been turned on.</span>")
return
if(on)
return
. = ..()
if(.)
user.visible_message("<span class='notice'>[user] cracks and shakes \the [name].</span>", "<span class='notice'>You crack and shake \the [src], turning it on!</span>")
START_PROCESSING(SSobj, src)
/obj/item/device/flashlight/glowstick/red
name = "red glowstick"
desc = "A red military-grade chemical light."
light_color = "#FC0F29"
icon_state = "glowstick_red"
item_state = "glowstick_red"
/obj/item/device/flashlight/glowstick/blue
name = "blue glowstick"
desc = "A blue military-grade chemical light."
light_color = "#599DFF"
icon_state = "glowstick_blue"
item_state = "glowstick_blue"
/obj/item/device/flashlight/glowstick/orange
name = "orange glowstick"
desc = "A orange military-grade chemical light."
light_color = "#FA7C0B"
icon_state = "glowstick_orange"
item_state = "glowstick_orange"
/obj/item/device/flashlight/glowstick/yellow
name = "yellow glowstick"
desc = "A yellow military-grade chemical light."
light_color = "#FEF923"
icon_state = "glowstick_yellow"
item_state = "glowstick_yellow"
/obj/item/device/flashlight/glowstick/radioisotope
name = "radioisotope glowstick"
desc = "A radioisotope powered chemical light. Escaping particles light up the area far brighter on similar levels to flares and for longer"
icon_state = "glowstick_isotope"
item_state = "glowstick_isotope"
light_range = 8
light_power = 0.1
light_color = "#49F37C"
/*
* Contains:
* Flashlights
* Lamps
* Flares
* Chemlights
* Slime Extract
*/
/*
* Flashlights
*/
/obj/item/device/flashlight
name = "flashlight"
desc = "A hand-held emergency light."
icon = 'icons/obj/lighting.dmi'
icon_state = "flashlight"
w_class = ITEMSIZE_SMALL
slot_flags = SLOT_BELT
matter = list(MAT_STEEL = 50,MAT_GLASS = 20)
action_button_name = "Toggle Flashlight"
light_system = MOVABLE_LIGHT_DIRECTIONAL
light_range = 4 //luminosity when on
light_power = 0.8 //lighting power when on
light_color = "#FFFFFF" //LIGHT_COLOR_INCANDESCENT_FLASHLIGHT //lighting colour when on
light_cone_y_offset = -7
var/on = 0
var/obj/item/weapon/cell/cell
var/cell_type = /obj/item/weapon/cell/device
var/power_usage = 1
var/power_use = 1
/obj/item/device/flashlight/Initialize()
. = ..()
if(power_use && cell_type)
cell = new cell_type(src)
update_brightness()
/obj/item/device/flashlight/Destroy()
STOP_PROCESSING(SSobj, src)
qdel_null(cell)
return ..()
/obj/item/device/flashlight/get_cell()
return cell
/obj/item/device/flashlight/process()
if(!on || !cell)
return PROCESS_KILL
if(power_usage)
if(cell.use(power_usage) != power_usage) // we weren't able to use our full power_usage amount!
visible_message("<span class='warning'>\The [src] flickers before going dull.</span>")
playsound(src, 'sound/effects/sparks3.ogg', 10, 1, -3) //Small cue that your light went dull in your pocket. //VOREStation Edit
on = 0
update_brightness()
return PROCESS_KILL
/obj/item/device/flashlight/proc/update_brightness()
if(on)
icon_state = "[initial(icon_state)]-on"
else
icon_state = initial(icon_state)
set_light_on(on)
if(light_system == STATIC_LIGHT)
update_light()
/obj/item/device/flashlight/examine(mob/user)
. = ..()
if(power_use && cell)
. += "\The [src] has a \the [cell] attached."
if(cell.charge <= cell.maxcharge*0.25)
. += "It appears to have a low amount of power remaining."
else if(cell.charge > cell.maxcharge*0.25 && cell.charge <= cell.maxcharge*0.5)
. += "It appears to have an average amount of power remaining."
else if(cell.charge > cell.maxcharge*0.5 && cell.charge <= cell.maxcharge*0.75)
. += "It appears to have an above average amount of power remaining."
else if(cell.charge > cell.maxcharge*0.75 && cell.charge <= cell.maxcharge)
. += "It appears to have a high amount of power remaining."
/obj/item/device/flashlight/attack_self(mob/user)
if(power_use)
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
if(!cell || cell.charge == 0)
to_chat(user, "You flick the switch on [src], but nothing happens.")
return 0
on = !on
if(on && power_use)
START_PROCESSING(SSobj, src)
else if(power_use)
STOP_PROCESSING(SSobj, src)
playsound(src, 'sound/weapons/empty.ogg', 15, 1, -3) // VOREStation Edit
update_brightness()
user.update_action_buttons()
return 1
/obj/item/device/flashlight/emp_act(severity)
for(var/obj/O in contents)
O.emp_act(severity)
..()
/obj/item/device/flashlight/attack(mob/living/M as mob, mob/living/user as mob)
add_fingerprint(user)
if(on && user.zone_sel.selecting == O_EYES)
if((CLUMSY in user.mutations) && prob(50)) //too dumb to use flashlight properly
return ..() //just hit them in the head
var/mob/living/carbon/human/H = M //mob has protective eyewear
if(istype(H))
for(var/obj/item/clothing/C in list(H.head,H.wear_mask,H.glasses))
if(istype(C) && (C.body_parts_covered & EYES))
to_chat(user, "<span class='warning'>You're going to need to remove [C.name] first.</span>")
return
var/obj/item/organ/vision
if(H.species.vision_organ)
vision = H.internal_organs_by_name[H.species.vision_organ]
if(!vision)
user.visible_message("<b>\The [user]</b> directs [src] at [M]'s face.", \
"<span class='notice'>You direct [src] at [M]'s face.</span>")
to_chat(user, "<span class='warning'>You can't find any [H.species.vision_organ ? H.species.vision_organ : "eyes"] on [H]!</span>")
user.setClickCooldown(user.get_attack_speed(src))
return
user.visible_message("<b>\The [user]</b> directs [src] to [M]'s eyes.", \
"<span class='notice'>You direct [src] to [M]'s eyes.</span>")
if(H != user) //can't look into your own eyes buster
if(M.stat == DEAD || M.blinded) //mob is dead or fully blind
to_chat(user, "<span class='warning'>\The [M]'s pupils do not react to the light!</span>")
return
if(XRAY in M.mutations)
to_chat(user, "<span class='notice'>\The [M] pupils give an eerie glow!</span>")
if(vision.is_bruised())
to_chat(user, "<span class='warning'>There's visible damage to [M]'s [vision.name]!</span>")
else if(M.eye_blurry)
to_chat(user, "<span class='notice'>\The [M]'s pupils react slower than normally.</span>")
if(M.getBrainLoss() > 15)
to_chat(user, "<span class='notice'>There's visible lag between left and right pupils' reactions.</span>")
var/list/pinpoint = list("oxycodone"=1,"tramadol"=5)
var/list/dilating = list("bliss"=5,"ambrosia_extract"=5,"mindbreaker"=1)
if(M.reagents.has_any_reagent(pinpoint) || H.ingested.has_any_reagent(pinpoint))
to_chat(user, "<span class='notice'>\The [M]'s pupils are already pinpoint and cannot narrow any more.</span>")
else if(M.reagents.has_any_reagent(dilating) || H.ingested.has_any_reagent(dilating))
to_chat(user, "<span class='notice'>\The [M]'s pupils narrow slightly, but are still very dilated.</span>")
else
to_chat(user, "<span class='notice'>\The [M]'s pupils narrow.</span>")
user.setClickCooldown(user.get_attack_speed(src)) //can be used offensively
M.flash_eyes()
else
return ..()
/obj/item/device/flashlight/attack_hand(mob/user as mob)
if(user.get_inactive_hand() == src)
if(cell)
cell.update_icon()
user.put_in_hands(cell)
cell = null
to_chat(user, "<span class='notice'>You remove the cell from the [src].</span>")
playsound(src, 'sound/machines/button.ogg', 30, 1, 0)
on = 0
update_brightness()
return
..()
else
return ..()
/obj/item/device/flashlight/MouseDrop(obj/over_object as obj)
if(!canremove)
return
if (ishuman(usr) || issmall(usr)) //so monkeys can take off their backpacks -- Urist
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech. why?
return
if (!( istype(over_object, /obj/screen) ))
return ..()
//makes sure that the thing is equipped, so that we can't drag it into our hand from miles away.
//there's got to be a better way of doing this.
if (!(src.loc == usr) || (src.loc && src.loc.loc == usr))
return
if (( usr.restrained() ) || ( usr.stat ))
return
if ((src.loc == usr) && !(istype(over_object, /obj/screen)) && !usr.unEquip(src))
return
switch(over_object.name)
if("r_hand")
usr.u_equip(src)
usr.put_in_r_hand(src)
if("l_hand")
usr.u_equip(src)
usr.put_in_l_hand(src)
src.add_fingerprint(usr)
/obj/item/device/flashlight/attackby(obj/item/weapon/W, mob/user as mob)
if(power_use)
if(istype(W, /obj/item/weapon/cell))
if(istype(W, /obj/item/weapon/cell/device))
if(!cell)
user.drop_item()
W.loc = src
cell = W
to_chat(user, "<span class='notice'>You install a cell in \the [src].</span>")
playsound(src, 'sound/machines/button.ogg', 30, 1, 0)
update_brightness()
else
to_chat(user, "<span class='notice'>\The [src] already has a cell.</span>")
else
to_chat(user, "<span class='notice'>\The [src] cannot use that type of cell.</span>")
else
..()
/obj/item/device/flashlight/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
if(!on)
return
if(light_system == MOVABLE_LIGHT_DIRECTIONAL)
var/datum/component/overlay_lighting/OL = GetComponent(/datum/component/overlay_lighting)
if(!OL)
return
var/turf/T = get_turf(target)
OL.place_directional_light(T)
/obj/item/device/flashlight/pen
name = "penlight"
desc = "A pen-sized light, used by medical staff."
icon_state = "penlight"
item_state = "pen"
drop_sound = 'sound/items/drop/accessory.ogg'
pickup_sound = 'sound/items/pickup/accessory.ogg'
slot_flags = SLOT_EARS
light_range = 2
w_class = ITEMSIZE_TINY
power_use = 0
/obj/item/device/flashlight/color //Default color is blue
name = "blue flashlight"
desc = "A small flashlight. This one is blue."
icon_state = "flashlight_blue"
/obj/item/device/flashlight/color/green
name = "green flashlight"
desc = "A small flashlight. This one is green."
icon_state = "flashlight_green"
/obj/item/device/flashlight/color/purple
name = "purple flashlight"
desc = "A small flashlight. This one is purple."
icon_state = "flashlight_purple"
/obj/item/device/flashlight/color/red
name = "red flashlight"
desc = "A small flashlight. This one is red."
icon_state = "flashlight_red"
/obj/item/device/flashlight/color/orange
name = "orange flashlight"
desc = "A small flashlight. This one is orange."
icon_state = "flashlight_orange"
/obj/item/device/flashlight/color/yellow
name = "yellow flashlight"
desc = "A small flashlight. This one is yellow."
icon_state = "flashlight_yellow"
/obj/item/device/flashlight/maglight
name = "maglight"
desc = "A very, very heavy duty flashlight."
icon_state = "maglight"
light_color = LIGHT_COLOR_FLUORESCENT_FLASHLIGHT
force = 10
slot_flags = SLOT_BELT
w_class = ITEMSIZE_SMALL
attack_verb = list ("smacked", "thwacked", "thunked")
matter = list(MAT_STEEL = 200,MAT_GLASS = 50)
hitsound = "swing_hit"
/obj/item/device/flashlight/drone
name = "low-power flashlight"
desc = "A miniature lamp, that might be used by small robots."
icon_state = "penlight"
item_state = null
light_range = 2
w_class = ITEMSIZE_TINY
power_use = 0
/*
* Lamps
*/
// pixar desk lamp
/obj/item/device/flashlight/lamp
name = "desk lamp"
desc = "A desk lamp with an adjustable mount."
icon_state = "lamp"
force = 10
center_of_mass = list("x" = 13,"y" = 11)
light_range = 5
w_class = ITEMSIZE_LARGE
power_use = 0
on = 1
light_system = STATIC_LIGHT
/obj/item/device/flashlight/lamp/verb/toggle_light()
set name = "Toggle light"
set category = "Object"
set src in oview(1)
if(!usr.stat)
attack_self(usr)
// green-shaded desk lamp
/obj/item/device/flashlight/lamp/green
desc = "A classic green-shaded desk lamp."
icon_state = "lampgreen"
center_of_mass = list("x" = 15,"y" = 11)
light_color = "#FFC58F"
// clown lamp
/obj/item/device/flashlight/lamp/clown
desc = "A whacky banana peel shaped lamp."
icon_state = "bananalamp"
center_of_mass = list("x" = 15,"y" = 11)
/*
* Flares
*/
/obj/item/device/flashlight/flare
name = "flare"
desc = "A red standard-issue flare. There are instructions on the side reading 'pull cord, make light'."
w_class = ITEMSIZE_SMALL
light_range = 8 // Pretty bright.
light_power = 0.8
light_color = LIGHT_COLOR_FLARE
icon_state = "flare"
item_state = "flare"
action_button_name = null //just pull it manually, neckbeard.
var/fuel = 0
var/on_damage = 7
var/produce_heat = 1500
power_use = 0
drop_sound = 'sound/items/drop/gloves.ogg'
pickup_sound = 'sound/items/pickup/gloves.ogg'
light_system = MOVABLE_LIGHT
/obj/item/device/flashlight/flare/New()
fuel = rand(800, 1000) // Sorry for changing this so much but I keep under-estimating how long X number of ticks last in seconds.
..()
/obj/item/device/flashlight/flare/process()
var/turf/pos = get_turf(src)
if(pos)
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/device/flashlight/flare/proc/turn_off()
on = 0
src.force = initial(src.force)
src.damtype = initial(src.damtype)
update_brightness()
/obj/item/device/flashlight/flare/attack_self(mob/user)
// Usual checks
if(!fuel)
to_chat(user, "<span class='notice'>It's out of fuel.</span>")
return
if(on)
return
. = ..()
// All good, turn it on.
if(.)
user.visible_message("<span class='notice'>[user] activates the flare.</span>", "<span class='notice'>You pull the cord on the flare, activating it!</span>")
src.force = on_damage
src.damtype = "fire"
START_PROCESSING(SSobj, src)
/obj/item/device/flashlight/flare/proc/ignite() //Used for flare launchers.
on = !on
update_brightness()
force = on_damage
damtype = "fire"
START_PROCESSING(SSobj, src)
return 1
/*
* Chemlights
*/
/obj/item/device/flashlight/glowstick
name = "green glowstick"
desc = "A green military-grade chemical light."
w_class = ITEMSIZE_SMALL
light_system = MOVABLE_LIGHT
light_range = 4
light_power = 0.9
light_color = "#49F37C"
icon_state = "glowstick_green"
item_state = "glowstick_green"
var/fuel = 0
power_use = 0
/obj/item/device/flashlight/glowstick/New()
fuel = rand(1600, 2000)
..()
/obj/item/device/flashlight/glowstick/process()
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/device/flashlight/glowstick/proc/turn_off()
on = 0
update_brightness()
/obj/item/device/flashlight/glowstick/attack_self(mob/user)
if(!fuel)
to_chat(user, "<span class='notice'>The glowstick has already been turned on.</span>")
return
if(on)
return
. = ..()
if(.)
user.visible_message("<span class='notice'>[user] cracks and shakes \the [name].</span>", "<span class='notice'>You crack and shake \the [src], turning it on!</span>")
START_PROCESSING(SSobj, src)
/obj/item/device/flashlight/glowstick/red
name = "red glowstick"
desc = "A red military-grade chemical light."
light_color = "#FC0F29"
icon_state = "glowstick_red"
item_state = "glowstick_red"
/obj/item/device/flashlight/glowstick/blue
name = "blue glowstick"
desc = "A blue military-grade chemical light."
light_color = "#599DFF"
icon_state = "glowstick_blue"
item_state = "glowstick_blue"
/obj/item/device/flashlight/glowstick/orange
name = "orange glowstick"
desc = "A orange military-grade chemical light."
light_color = "#FA7C0B"
icon_state = "glowstick_orange"
item_state = "glowstick_orange"
/obj/item/device/flashlight/glowstick/yellow
name = "yellow glowstick"
desc = "A yellow military-grade chemical light."
light_color = "#FEF923"
icon_state = "glowstick_yellow"
item_state = "glowstick_yellow"
/obj/item/device/flashlight/glowstick/radioisotope
name = "radioisotope glowstick"
desc = "A radioisotope powered chemical light. Escaping particles light up the area far brighter on similar levels to flares and for longer"
icon_state = "glowstick_isotope"
item_state = "glowstick_isotope"
light_range = 8
light_power = 0.1
light_color = "#49F37C"
+130 -130
View File
@@ -1,130 +1,130 @@
/obj/item/device/multitool/hacktool
var/is_hacking = 0
var/max_known_targets
var/hackspeed = 1
var/max_level = 4 //what's the max door security_level we can handle?
var/full_override = FALSE //can we override door bolts too? defaults to false for event/safety reasons
var/in_hack_mode = 0
var/list/known_targets
var/list/supported_types
var/datum/tgui_state/default/must_hack/hack_state
/obj/item/device/multitool/hacktool/override
hackspeed = 0.75
max_level = 5
full_override = TRUE
/obj/item/device/multitool/hacktool/New()
..()
known_targets = list()
max_known_targets = 5 + rand(1,3)
supported_types = list(/obj/machinery/door/airlock)
hack_state = new(src)
/obj/item/device/multitool/hacktool/Destroy()
for(var/atom/target as anything in known_targets)
target.unregister(OBSERVER_EVENT_DESTROY, src)
known_targets.Cut()
qdel(hack_state)
hack_state = null
return ..()
/obj/item/device/multitool/hacktool/attackby(var/obj/item/W, var/mob/user)
if(W.has_tool_quality(TOOL_SCREWDRIVER))
in_hack_mode = !in_hack_mode
playsound(src, W.usesound, 50, 1)
else
..()
/obj/item/device/multitool/hacktool/afterattack(atom/A, mob/user)
sanity_check()
if(!in_hack_mode)
return ..()
if(!attempt_hack(user, A))
return 0
// Note, if you ever want to expand supported_types, you must manually add the custom state argument to their tgui_interact
// DISABLED: too fancy, too high-effort // A.tgui_interact(user, custom_state = hack_state)
// Just brute-force it
if(istype(A, /obj/machinery/door/airlock))
var/obj/machinery/door/airlock/D = A
if(!D.arePowerSystemsOn())
to_chat(user, "<span class='warning'>No response from remote, check door power.</span>")
else if(D.locked == TRUE && full_override == FALSE)
to_chat(user, "<span class='warning'>Unable to override door bolts!</span>")
else if(D.locked == TRUE && full_override == TRUE && D.arePowerSystemsOn())
to_chat(user, "<span class='notice'>Door bolts overridden.</span>")
D.unlock()
else if(D.density == TRUE && D.locked == FALSE)
to_chat(user, "<span class='notice'>Overriding access. Door opening.</span>")
D.open()
else if(D.density == FALSE && D.locked == FALSE)
to_chat(user, "<span class='notice'>Overriding access. Door closing.</span>")
D.close()
return 1
/obj/item/device/multitool/hacktool/proc/attempt_hack(var/mob/user, var/atom/target)
if(is_hacking)
to_chat(user, "<span class='warning'>You are already hacking!</span>")
return 0
if(!is_type_in_list(target, supported_types))
to_chat(user, "\icon[src][bicon(src)] <span class='warning'>Unable to hack this target, invalid target type.</span>")
return 0
var/obj/machinery/door/airlock/D = target
if(D.security_level > max_level)
to_chat(user, "\icon[src][bicon(src)] <span class='warning'>Target's electronic security is too complex.</span>")
return 0
var/found = known_targets.Find(D)
if(found)
known_targets.Swap(1, found) // Move the last hacked item first
return 1
to_chat(user, "<span class='notice'>You begin hacking \the [D]...</span>")
is_hacking = 1
// On average hackin takes ~15 seconds. Fairly small random span to avoid people simply aborting and trying again
// Reduced hack duration to compensate for the reduced functionality, multiplied by door sec level
var/hack_result = do_after(user, (((10 SECONDS + rand(0, 10 SECONDS) + rand(0, 10 SECONDS))*hackspeed)*D.security_level))
is_hacking = 0
if(hack_result && in_hack_mode)
to_chat(user, "<span class='notice'>Your hacking attempt was succesful!</span>")
user.playsound_local(get_turf(src), 'sound/instruments/piano/An6.ogg', 50)
else
to_chat(user, "<span class='warning'>Your hacking attempt failed!</span>")
return 0
known_targets.Insert(1, D) // Insert the newly hacked target first,
D.register(OBSERVER_EVENT_DESTROY, src, /obj/item/device/multitool/hacktool/proc/on_target_destroy)
return 1
/obj/item/device/multitool/hacktool/proc/sanity_check()
if(max_known_targets < 1) max_known_targets = 1
// Cut away the oldest items if the capacity has been reached
if(known_targets.len > max_known_targets)
for(var/i = (max_known_targets + 1) to known_targets.len)
var/atom/A = known_targets[i]
A.unregister(OBSERVER_EVENT_DESTROY, src)
known_targets.Cut(max_known_targets + 1)
/obj/item/device/multitool/hacktool/proc/on_target_destroy(var/target)
known_targets -= target
/datum/tgui_state/default/must_hack
var/obj/item/device/multitool/hacktool/hacktool
/datum/tgui_state/default/must_hack/New(var/hacktool)
src.hacktool = hacktool
..()
/datum/tgui_state/default/must_hack/Destroy()
hacktool = null
return ..()
/datum/tgui_state/default/must_hack/can_use_topic(src_object, mob/user)
if(!hacktool || !hacktool.in_hack_mode || !(src_object in hacktool.known_targets))
return STATUS_CLOSE
return ..()
/obj/item/device/multitool/hacktool
var/is_hacking = 0
var/max_known_targets
var/hackspeed = 1
var/max_level = 4 //what's the max door security_level we can handle?
var/full_override = FALSE //can we override door bolts too? defaults to false for event/safety reasons
var/in_hack_mode = 0
var/list/known_targets
var/list/supported_types
var/datum/tgui_state/default/must_hack/hack_state
/obj/item/device/multitool/hacktool/override
hackspeed = 0.75
max_level = 5
full_override = TRUE
/obj/item/device/multitool/hacktool/New()
..()
known_targets = list()
max_known_targets = 5 + rand(1,3)
supported_types = list(/obj/machinery/door/airlock)
hack_state = new(src)
/obj/item/device/multitool/hacktool/Destroy()
for(var/atom/target as anything in known_targets)
target.unregister(OBSERVER_EVENT_DESTROY, src)
known_targets.Cut()
qdel(hack_state)
hack_state = null
return ..()
/obj/item/device/multitool/hacktool/attackby(var/obj/item/W, var/mob/user)
if(W.has_tool_quality(TOOL_SCREWDRIVER))
in_hack_mode = !in_hack_mode
playsound(src, W.usesound, 50, 1)
else
..()
/obj/item/device/multitool/hacktool/afterattack(atom/A, mob/user)
sanity_check()
if(!in_hack_mode)
return ..()
if(!attempt_hack(user, A))
return 0
// Note, if you ever want to expand supported_types, you must manually add the custom state argument to their tgui_interact
// DISABLED: too fancy, too high-effort // A.tgui_interact(user, custom_state = hack_state)
// Just brute-force it
if(istype(A, /obj/machinery/door/airlock))
var/obj/machinery/door/airlock/D = A
if(!D.arePowerSystemsOn())
to_chat(user, "<span class='warning'>No response from remote, check door power.</span>")
else if(D.locked == TRUE && full_override == FALSE)
to_chat(user, "<span class='warning'>Unable to override door bolts!</span>")
else if(D.locked == TRUE && full_override == TRUE && D.arePowerSystemsOn())
to_chat(user, "<span class='notice'>Door bolts overridden.</span>")
D.unlock()
else if(D.density == TRUE && D.locked == FALSE)
to_chat(user, "<span class='notice'>Overriding access. Door opening.</span>")
D.open()
else if(D.density == FALSE && D.locked == FALSE)
to_chat(user, "<span class='notice'>Overriding access. Door closing.</span>")
D.close()
return 1
/obj/item/device/multitool/hacktool/proc/attempt_hack(var/mob/user, var/atom/target)
if(is_hacking)
to_chat(user, "<span class='warning'>You are already hacking!</span>")
return 0
if(!is_type_in_list(target, supported_types))
to_chat(user, "\icon[src][bicon(src)] <span class='warning'>Unable to hack this target, invalid target type.</span>")
return 0
var/obj/machinery/door/airlock/D = target
if(D.security_level > max_level)
to_chat(user, "\icon[src][bicon(src)] <span class='warning'>Target's electronic security is too complex.</span>")
return 0
var/found = known_targets.Find(D)
if(found)
known_targets.Swap(1, found) // Move the last hacked item first
return 1
to_chat(user, "<span class='notice'>You begin hacking \the [D]...</span>")
is_hacking = 1
// On average hackin takes ~15 seconds. Fairly small random span to avoid people simply aborting and trying again
// Reduced hack duration to compensate for the reduced functionality, multiplied by door sec level
var/hack_result = do_after(user, (((10 SECONDS + rand(0, 10 SECONDS) + rand(0, 10 SECONDS))*hackspeed)*D.security_level))
is_hacking = 0
if(hack_result && in_hack_mode)
to_chat(user, "<span class='notice'>Your hacking attempt was succesful!</span>")
user.playsound_local(get_turf(src), 'sound/instruments/piano/An6.ogg', 50)
else
to_chat(user, "<span class='warning'>Your hacking attempt failed!</span>")
return 0
known_targets.Insert(1, D) // Insert the newly hacked target first,
D.register(OBSERVER_EVENT_DESTROY, src, /obj/item/device/multitool/hacktool/proc/on_target_destroy)
return 1
/obj/item/device/multitool/hacktool/proc/sanity_check()
if(max_known_targets < 1) max_known_targets = 1
// Cut away the oldest items if the capacity has been reached
if(known_targets.len > max_known_targets)
for(var/i = (max_known_targets + 1) to known_targets.len)
var/atom/A = known_targets[i]
A.unregister(OBSERVER_EVENT_DESTROY, src)
known_targets.Cut(max_known_targets + 1)
/obj/item/device/multitool/hacktool/proc/on_target_destroy(var/target)
known_targets -= target
/datum/tgui_state/default/must_hack
var/obj/item/device/multitool/hacktool/hacktool
/datum/tgui_state/default/must_hack/New(var/hacktool)
src.hacktool = hacktool
..()
/datum/tgui_state/default/must_hack/Destroy()
hacktool = null
return ..()
/datum/tgui_state/default/must_hack/can_use_topic(src_object, mob/user)
if(!hacktool || !hacktool.in_hack_mode || !(src_object in hacktool.known_targets))
return STATUS_CLOSE
return ..()
+229 -229
View File
@@ -1,230 +1,230 @@
// 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 can be manually refilled or by clicking on a storage item containing 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/device/lightreplacer
name = "light replacer"
desc = "A device to automatically replace lights. Refill with working lightbulbs or sheets of glass."
force = 8
icon = 'icons/obj/janitor.dmi'
icon_state = "lightreplacer0"
slot_flags = SLOT_BELT
origin_tech = list(TECH_MAGNET = 3, TECH_MATERIAL = 2)
var/max_uses = 32
var/uses = 32
var/emagged = 0
var/failmsg = ""
var/charge = 0
var/selected_color = LIGHT_COLOR_INCANDESCENT_TUBE //Default color!
// 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/device/lightreplacer/New()
failmsg = "The [name]'s refill light blinks red."
..()
/obj/item/device/lightreplacer/examine(mob/user)
. = ..()
if(get_dist(user, src) <= 2)
. += "It has [uses] lights remaining."
/obj/item/device/lightreplacer/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/stack/material) && W.get_material_name() == "glass")
var/obj/item/stack/G = W
if(uses >= max_uses)
to_chat(user, "<span class='warning'>[src.name] is full.</span>")
return
else if(G.use(1))
add_uses(16) //Autolathe converts 1 sheet into 16 lights.
to_chat(user, "<span class='notice'>You insert a piece of glass into \the [src.name]. 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>")
if(istype(W, /obj/item/weapon/light))
var/new_bulbs = 0
var/obj/item/weapon/light/L = W
if(L.status == 0) // LIGHT OKAY
if(uses < max_uses)
if(!user.unEquip(W))
return
add_uses(1)
qdel(L)
else
if(!user.unEquip(W))
return
new_bulbs += AddShards(1)
qdel(L)
if(new_bulbs != 0)
playsound(src, 'sound/machines/ding.ogg', 50, 1)
to_chat(user, "You insert \the [L.name] into \the [src.name]. You have [uses] light\s remaining.")
return
if(istype(W, /obj/item/weapon/storage))
var/obj/item/weapon/storage/S = W
var/found_lightbulbs = FALSE
var/replaced_something = TRUE
for(var/obj/item/I in S.contents)
if(istype(I,/obj/item/weapon/light))
var/obj/item/weapon/light/L = I
found_lightbulbs = TRUE
if(src.uses >= max_uses)
break
if(L.status == LIGHT_OK)
replaced_something = TRUE
add_uses(1)
qdel(L)
else if(L.status == LIGHT_BROKEN || L.status == LIGHT_BURNED)
replaced_something = TRUE
AddShards(1)
qdel(L)
if(!found_lightbulbs)
to_chat(user, "<span class='warning'>\The [S] contains no bulbs.</span>")
return
if(!replaced_something && src.uses == max_uses)
to_chat(user, "<span class='warning'>\The [src] is full!</span>")
return
to_chat(user, "<span class='notice'>You fill \the [src] with lights from \the [S].</span>")
/obj/item/device/lightreplacer/attack_self(mob/user)
/* // This would probably be a bit OP. If you want it though, uncomment the code.
if(isrobot(user))
var/mob/living/silicon/robot/R = user
if(R.emagged)
src.Emag()
to_chat(usr, You short circuit the [src].")
return
*/
to_chat(usr, "It has [uses] lights remaining.")
var/new_color = input(usr, "Choose a color to set the light to! (Default is [LIGHT_COLOR_INCANDESCENT_TUBE])", "", selected_color) as color|null
if(new_color)
selected_color = new_color
to_chat(usr, "The light color has been changed.")
/obj/item/device/lightreplacer/update_icon()
icon_state = "lightreplacer[emagged]"
/obj/item/device/lightreplacer/proc/Use(var/mob/user)
playsound(src, 'sound/machines/click.ogg', 50, 1)
add_uses(-1)
return 1
// Negative numbers will subtract
/obj/item/device/lightreplacer/proc/add_uses(var/amount = 1)
uses = min(max(uses + amount, 0), max_uses)
/obj/item/device/lightreplacer/proc/AddShards(amount = 1)
bulb_shards += amount
var/new_bulbs = round(bulb_shards / shards_required)
if(new_bulbs > 0)
add_uses(new_bulbs)
bulb_shards = bulb_shards % shards_required
return new_bulbs
/obj/item/device/lightreplacer/proc/Charge(var/mob/user, var/amount = 1)
charge += amount
if(charge > 6)
add_uses(1)
charge = 0
/obj/item/device/lightreplacer/proc/ReplaceLight(var/obj/machinery/light/target, var/mob/living/U)
if(target.status != LIGHT_OK)
if(CanUse(U))
if(!Use(U)) return
to_chat(U, "<span class='notice'>You replace the [target.get_fitting_name()] with the [src].</span>")
if(target.status != LIGHT_EMPTY)
var/new_bulbs = AddShards(1)
if(new_bulbs != 0)
to_chat(U, "<span class='notice'>\The [src] has fabricated a new bulb from the broken bulbs it has stored. It now has [uses] uses.</span>")
playsound(src, 'sound/machines/ding.ogg', 50, 1)
target.status = LIGHT_EMPTY
target.installed_light = null //Remove the light!
target.update()
var/obj/item/weapon/light/L2 = new target.light_type()
L2.brightness_color = selected_color
target.insert_bulb(L2) //Call the insertion proc.
target.update()
if(target.on && target.rigged)
target.explode()
return
else
to_chat(U, failmsg)
return
else
to_chat(U, "There is a working [target.get_fitting_name()] already inserted.")
return
/obj/item/device/lightreplacer/emag_act(var/remaining_charges, var/mob/user)
emagged = !emagged
playsound(src, "sparks", 100, 1)
update_icon()
return 1
//Can you use it?
/obj/item/device/lightreplacer/proc/CanUse(var/mob/living/user)
src.add_fingerprint(user)
//Not sure what else to check for. Maybe if clumsy?
if(uses > 0)
return 1
else
return 0
#undef LIGHT_OK
#undef LIGHT_EMPTY
#undef LIGHT_BROKEN
// 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 can be manually refilled or by clicking on a storage item containing 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/device/lightreplacer
name = "light replacer"
desc = "A device to automatically replace lights. Refill with working lightbulbs or sheets of glass."
force = 8
icon = 'icons/obj/janitor.dmi'
icon_state = "lightreplacer0"
slot_flags = SLOT_BELT
origin_tech = list(TECH_MAGNET = 3, TECH_MATERIAL = 2)
var/max_uses = 32
var/uses = 32
var/emagged = 0
var/failmsg = ""
var/charge = 0
var/selected_color = LIGHT_COLOR_INCANDESCENT_TUBE //Default color!
// 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/device/lightreplacer/New()
failmsg = "The [name]'s refill light blinks red."
..()
/obj/item/device/lightreplacer/examine(mob/user)
. = ..()
if(get_dist(user, src) <= 2)
. += "It has [uses] lights remaining."
/obj/item/device/lightreplacer/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/stack/material) && W.get_material_name() == "glass")
var/obj/item/stack/G = W
if(uses >= max_uses)
to_chat(user, "<span class='warning'>[src.name] is full.</span>")
return
else if(G.use(1))
add_uses(16) //Autolathe converts 1 sheet into 16 lights.
to_chat(user, "<span class='notice'>You insert a piece of glass into \the [src.name]. 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>")
if(istype(W, /obj/item/weapon/light))
var/new_bulbs = 0
var/obj/item/weapon/light/L = W
if(L.status == 0) // LIGHT OKAY
if(uses < max_uses)
if(!user.unEquip(W))
return
add_uses(1)
qdel(L)
else
if(!user.unEquip(W))
return
new_bulbs += AddShards(1)
qdel(L)
if(new_bulbs != 0)
playsound(src, 'sound/machines/ding.ogg', 50, 1)
to_chat(user, "You insert \the [L.name] into \the [src.name]. You have [uses] light\s remaining.")
return
if(istype(W, /obj/item/weapon/storage))
var/obj/item/weapon/storage/S = W
var/found_lightbulbs = FALSE
var/replaced_something = TRUE
for(var/obj/item/I in S.contents)
if(istype(I,/obj/item/weapon/light))
var/obj/item/weapon/light/L = I
found_lightbulbs = TRUE
if(src.uses >= max_uses)
break
if(L.status == LIGHT_OK)
replaced_something = TRUE
add_uses(1)
qdel(L)
else if(L.status == LIGHT_BROKEN || L.status == LIGHT_BURNED)
replaced_something = TRUE
AddShards(1)
qdel(L)
if(!found_lightbulbs)
to_chat(user, "<span class='warning'>\The [S] contains no bulbs.</span>")
return
if(!replaced_something && src.uses == max_uses)
to_chat(user, "<span class='warning'>\The [src] is full!</span>")
return
to_chat(user, "<span class='notice'>You fill \the [src] with lights from \the [S].</span>")
/obj/item/device/lightreplacer/attack_self(mob/user)
/* // This would probably be a bit OP. If you want it though, uncomment the code.
if(isrobot(user))
var/mob/living/silicon/robot/R = user
if(R.emagged)
src.Emag()
to_chat(usr, You short circuit the [src].")
return
*/
to_chat(usr, "It has [uses] lights remaining.")
var/new_color = input(usr, "Choose a color to set the light to! (Default is [LIGHT_COLOR_INCANDESCENT_TUBE])", "", selected_color) as color|null
if(new_color)
selected_color = new_color
to_chat(usr, "The light color has been changed.")
/obj/item/device/lightreplacer/update_icon()
icon_state = "lightreplacer[emagged]"
/obj/item/device/lightreplacer/proc/Use(var/mob/user)
playsound(src, 'sound/machines/click.ogg', 50, 1)
add_uses(-1)
return 1
// Negative numbers will subtract
/obj/item/device/lightreplacer/proc/add_uses(var/amount = 1)
uses = min(max(uses + amount, 0), max_uses)
/obj/item/device/lightreplacer/proc/AddShards(amount = 1)
bulb_shards += amount
var/new_bulbs = round(bulb_shards / shards_required)
if(new_bulbs > 0)
add_uses(new_bulbs)
bulb_shards = bulb_shards % shards_required
return new_bulbs
/obj/item/device/lightreplacer/proc/Charge(var/mob/user, var/amount = 1)
charge += amount
if(charge > 6)
add_uses(1)
charge = 0
/obj/item/device/lightreplacer/proc/ReplaceLight(var/obj/machinery/light/target, var/mob/living/U)
if(target.status != LIGHT_OK)
if(CanUse(U))
if(!Use(U)) return
to_chat(U, "<span class='notice'>You replace the [target.get_fitting_name()] with the [src].</span>")
if(target.status != LIGHT_EMPTY)
var/new_bulbs = AddShards(1)
if(new_bulbs != 0)
to_chat(U, "<span class='notice'>\The [src] has fabricated a new bulb from the broken bulbs it has stored. It now has [uses] uses.</span>")
playsound(src, 'sound/machines/ding.ogg', 50, 1)
target.status = LIGHT_EMPTY
target.installed_light = null //Remove the light!
target.update()
var/obj/item/weapon/light/L2 = new target.light_type()
L2.brightness_color = selected_color
target.insert_bulb(L2) //Call the insertion proc.
target.update()
if(target.on && target.rigged)
target.explode()
return
else
to_chat(U, failmsg)
return
else
to_chat(U, "There is a working [target.get_fitting_name()] already inserted.")
return
/obj/item/device/lightreplacer/emag_act(var/remaining_charges, var/mob/user)
emagged = !emagged
playsound(src, "sparks", 100, 1)
update_icon()
return 1
//Can you use it?
/obj/item/device/lightreplacer/proc/CanUse(var/mob/living/user)
src.add_fingerprint(user)
//Not sure what else to check for. Maybe if clumsy?
if(uses > 0)
return 1
else
return 0
#undef LIGHT_OK
#undef LIGHT_EMPTY
#undef LIGHT_BROKEN
#undef LIGHT_BURNED
+95 -95
View File
@@ -1,95 +1,95 @@
/**
* Multitool -- A multitool is used for hacking electronic devices.
* TO-DO -- Using it as a power measurement tool for cables etc. Nannek.
*
*/
/obj/item/device/multitool
name = "multitool"
desc = "Used for pulsing wires to test which to cut. Not recommended by doctors."
description_info = "You can use this on airlocks or APCs to try to hack them without cutting wires."
icon_state = "multitool"
force = 5.0
w_class = ITEMSIZE_SMALL
throwforce = 5.0
throw_range = 15
throw_speed = 3
drop_sound = 'sound/items/drop/multitool.ogg'
pickup_sound = 'sound/items/pickup/multitool.ogg'
matter = list(MAT_STEEL = 50,MAT_GLASS = 20)
var/mode_index = 1
var/toolmode = MULTITOOL_MODE_STANDARD
var/list/modes = list(MULTITOOL_MODE_STANDARD, MULTITOOL_MODE_INTCIRCUITS)
origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1)
var/obj/machinery/telecomms/buffer // simple machine buffer for device linkage
var/obj/machinery/clonepod/connecting //same for cryopod linkage
var/obj/machinery/connectable //Used to connect machinery.
var/weakref_wiring //Used to store weak references for integrated circuitry. This is now the Omnitool.
toolspeed = 1
tool_qualities = list(TOOL_MULTITOOL)
/obj/item/device/multitool/attack_self(mob/living/user)
var/choice = tgui_alert(usr, "What do you want to do with \the [src]?", "Multitool Menu", list("Switch Mode", "Clear Buffers", "Cancel"))
switch(choice)
if("Cancel")
to_chat(user,"<span class='notice'>You lower \the [src].</span>")
return
if("Clear Buffers")
to_chat(user,"<span class='notice'>You clear \the [src]'s memory.</span>")
buffer = null
connecting = null
connectable = null
weakref_wiring = null
accepting_refs = 0
if(toolmode == MULTITOOL_MODE_INTCIRCUITS)
accepting_refs = 1
if("Switch Mode")
mode_switch(user)
update_icon()
return ..()
/obj/item/device/multitool/proc/mode_switch(mob/living/user)
if(mode_index + 1 > modes.len) mode_index = 1
else
mode_index += 1
toolmode = modes[mode_index]
to_chat(user,"<span class='notice'>\The [src] is now set to [toolmode].</span>")
accepting_refs = (toolmode == MULTITOOL_MODE_INTCIRCUITS)
return
/obj/item/device/multitool/cyborg
name = "multitool"
desc = "Optimised and stripped-down version of a regular multitool."
toolspeed = 0.5
/datum/category_item/catalogue/anomalous/precursor_a/alien_multitool
name = "Precursor Alpha Object - Pulse Tool"
desc = "This ancient object appears to be an electrical tool. \
It has a simple mechanism at the handle, which will cause a pulse of \
energy to be emitted from the head of the tool. This can be used on a \
conductive object such as a wire, in order to send a pulse signal through it.\
<br><br>\
These qualities make this object somewhat similar in purpose to the common \
multitool, and can probably be used for tasks such as direct interfacing with \
an airlock, if one knows how."
value = CATALOGUER_REWARD_EASY
/obj/item/device/multitool/alien
name = "alien multitool"
desc = "An omni-technological interface."
catalogue_data = list(/datum/category_item/catalogue/anomalous/precursor_a/alien_multitool)
icon = 'icons/obj/abductor.dmi'
icon_state = "multitool"
toolspeed = 0.1
origin_tech = list(TECH_MAGNET = 5, TECH_ENGINEERING = 5)
/**
* Multitool -- A multitool is used for hacking electronic devices.
* TO-DO -- Using it as a power measurement tool for cables etc. Nannek.
*
*/
/obj/item/device/multitool
name = "multitool"
desc = "Used for pulsing wires to test which to cut. Not recommended by doctors."
description_info = "You can use this on airlocks or APCs to try to hack them without cutting wires."
icon_state = "multitool"
force = 5.0
w_class = ITEMSIZE_SMALL
throwforce = 5.0
throw_range = 15
throw_speed = 3
drop_sound = 'sound/items/drop/multitool.ogg'
pickup_sound = 'sound/items/pickup/multitool.ogg'
matter = list(MAT_STEEL = 50,MAT_GLASS = 20)
var/mode_index = 1
var/toolmode = MULTITOOL_MODE_STANDARD
var/list/modes = list(MULTITOOL_MODE_STANDARD, MULTITOOL_MODE_INTCIRCUITS)
origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1)
var/obj/machinery/telecomms/buffer // simple machine buffer for device linkage
var/obj/machinery/clonepod/connecting //same for cryopod linkage
var/obj/machinery/connectable //Used to connect machinery.
var/weakref_wiring //Used to store weak references for integrated circuitry. This is now the Omnitool.
toolspeed = 1
tool_qualities = list(TOOL_MULTITOOL)
/obj/item/device/multitool/attack_self(mob/living/user)
var/choice = tgui_alert(usr, "What do you want to do with \the [src]?", "Multitool Menu", list("Switch Mode", "Clear Buffers", "Cancel"))
switch(choice)
if("Cancel")
to_chat(user,"<span class='notice'>You lower \the [src].</span>")
return
if("Clear Buffers")
to_chat(user,"<span class='notice'>You clear \the [src]'s memory.</span>")
buffer = null
connecting = null
connectable = null
weakref_wiring = null
accepting_refs = 0
if(toolmode == MULTITOOL_MODE_INTCIRCUITS)
accepting_refs = 1
if("Switch Mode")
mode_switch(user)
update_icon()
return ..()
/obj/item/device/multitool/proc/mode_switch(mob/living/user)
if(mode_index + 1 > modes.len) mode_index = 1
else
mode_index += 1
toolmode = modes[mode_index]
to_chat(user,"<span class='notice'>\The [src] is now set to [toolmode].</span>")
accepting_refs = (toolmode == MULTITOOL_MODE_INTCIRCUITS)
return
/obj/item/device/multitool/cyborg
name = "multitool"
desc = "Optimised and stripped-down version of a regular multitool."
toolspeed = 0.5
/datum/category_item/catalogue/anomalous/precursor_a/alien_multitool
name = "Precursor Alpha Object - Pulse Tool"
desc = "This ancient object appears to be an electrical tool. \
It has a simple mechanism at the handle, which will cause a pulse of \
energy to be emitted from the head of the tool. This can be used on a \
conductive object such as a wire, in order to send a pulse signal through it.\
<br><br>\
These qualities make this object somewhat similar in purpose to the common \
multitool, and can probably be used for tasks such as direct interfacing with \
an airlock, if one knows how."
value = CATALOGUER_REWARD_EASY
/obj/item/device/multitool/alien
name = "alien multitool"
desc = "An omni-technological interface."
catalogue_data = list(/datum/category_item/catalogue/anomalous/precursor_a/alien_multitool)
icon = 'icons/obj/abductor.dmi'
icon_state = "multitool"
toolspeed = 0.1
origin_tech = list(TECH_MAGNET = 5, TECH_ENGINEERING = 5)
File diff suppressed because it is too large Load Diff
+134 -134
View File
@@ -1,134 +1,134 @@
// Powersink - used to drain station power
/obj/item/device/powersink
name = "power sink"
desc = "A nulling power sink which drains energy from electrical systems."
icon_state = "powersink0"
icon = 'icons/obj/device.dmi'
w_class = ITEMSIZE_LARGE
throwforce = 5
throw_speed = 1
throw_range = 2
matter = list(MAT_STEEL = 750)
origin_tech = list(TECH_POWER = 3, TECH_ILLEGAL = 5)
var/drain_rate = 1500000 // amount of power to drain per tick
var/apc_drain_rate = 5000 // Max. amount drained from single APC. In Watts.
var/dissipation_rate = 20000 // Passive dissipation of drained power. In Watts.
var/power_drained = 0 // Amount of power drained.
var/max_power = 1e9 // Detonation point.
var/mode = 0 // 0 = off, 1=clamped (off), 2=operating
var/drained_this_tick = 0 // This is unfortunately necessary to ensure we process powersinks BEFORE other machinery such as APCs.
var/datum/powernet/PN // Our powernet
var/obj/structure/cable/attached // the attached cable
/obj/item/device/powersink/Destroy()
STOP_PROCESSING(SSobj, src)
STOP_PROCESSING_POWER_OBJECT(src)
..()
/obj/item/device/powersink/attackby(var/obj/item/I, var/mob/user)
if(I.has_tool_quality(TOOL_SCREWDRIVER))
if(mode == 0)
var/turf/T = loc
if(isturf(T) && !!T.is_plating())
attached = locate() in T
if(!attached)
to_chat(user, "No exposed cable here to attach to.")
return
else
anchored = TRUE
mode = 1
src.visible_message("<span class='notice'>[user] attaches [src] to the cable!</span>")
playsound(src, I.usesound, 50, 1)
return
else
to_chat(user, "Device must be placed over an exposed cable to attach to it.")
return
else
if (mode == 2)
STOP_PROCESSING(SSobj, src) // Now the power sink actually stops draining the station's power if you unhook it. --NeoFite
STOP_PROCESSING_POWER_OBJECT(src)
anchored = FALSE
mode = 0
src.visible_message("<span class='notice'>[user] detaches [src] from the cable!</span>")
set_light(0)
playsound(src, I.usesound, 50, 1)
icon_state = "powersink0"
return
else
..()
/obj/item/device/powersink/attack_ai()
return
/obj/item/device/powersink/attack_hand(var/mob/user)
switch(mode)
if(0)
..()
if(1)
src.visible_message("<span class='notice'>[user] activates [src]!</span>")
mode = 2
icon_state = "powersink1"
START_PROCESSING(SSobj, src)
datum_flags &= ~DF_ISPROCESSING // Have to reset this flag so that PROCESSING_POWER_OBJECT can re-add it. It fails if the flag is already present. - Ater
START_PROCESSING_POWER_OBJECT(src)
if(2) //This switch option wasn't originally included. It exists now. --NeoFite
src.visible_message("<span class='notice'>[user] deactivates [src]!</span>")
mode = 1
set_light(0)
icon_state = "powersink0"
STOP_PROCESSING(SSobj, src)
STOP_PROCESSING_POWER_OBJECT(src)
/obj/item/device/powersink/pwr_drain()
if(!attached)
return 0
if(drained_this_tick)
return 1
drained_this_tick = 1
var/drained = 0
if(!PN)
return 1
set_light(12)
PN.trigger_warning()
// found a powernet, so drain up to max power from it
drained = PN.draw_power(drain_rate)
// 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)
// Enough power drained this tick, no need to torture more APCs
if(drained >= drain_rate)
break
if(istype(T.master, /obj/machinery/power/apc))
var/obj/machinery/power/apc/A = T.master
if(A.operating && A.cell)
var/cur_charge = A.cell.charge / CELLRATE
var/drain_val = min(apc_drain_rate, cur_charge)
A.cell.use(drain_val * CELLRATE)
drained += drain_val
power_drained += drained
return 1
/obj/item/device/powersink/process()
drained_this_tick = 0
power_drained -= min(dissipation_rate, power_drained)
if(power_drained > max_power * 0.95)
playsound(src, 'sound/effects/screech.ogg', 100, 1, 1)
if(power_drained >= max_power)
explosion(src.loc, 3,6,9,12)
qdel(src)
return
if(attached && attached.powernet)
PN = attached.powernet
else
PN = null
// Powersink - used to drain station power
/obj/item/device/powersink
name = "power sink"
desc = "A nulling power sink which drains energy from electrical systems."
icon_state = "powersink0"
icon = 'icons/obj/device.dmi'
w_class = ITEMSIZE_LARGE
throwforce = 5
throw_speed = 1
throw_range = 2
matter = list(MAT_STEEL = 750)
origin_tech = list(TECH_POWER = 3, TECH_ILLEGAL = 5)
var/drain_rate = 1500000 // amount of power to drain per tick
var/apc_drain_rate = 5000 // Max. amount drained from single APC. In Watts.
var/dissipation_rate = 20000 // Passive dissipation of drained power. In Watts.
var/power_drained = 0 // Amount of power drained.
var/max_power = 1e9 // Detonation point.
var/mode = 0 // 0 = off, 1=clamped (off), 2=operating
var/drained_this_tick = 0 // This is unfortunately necessary to ensure we process powersinks BEFORE other machinery such as APCs.
var/datum/powernet/PN // Our powernet
var/obj/structure/cable/attached // the attached cable
/obj/item/device/powersink/Destroy()
STOP_PROCESSING(SSobj, src)
STOP_PROCESSING_POWER_OBJECT(src)
..()
/obj/item/device/powersink/attackby(var/obj/item/I, var/mob/user)
if(I.has_tool_quality(TOOL_SCREWDRIVER))
if(mode == 0)
var/turf/T = loc
if(isturf(T) && !!T.is_plating())
attached = locate() in T
if(!attached)
to_chat(user, "No exposed cable here to attach to.")
return
else
anchored = TRUE
mode = 1
src.visible_message("<span class='notice'>[user] attaches [src] to the cable!</span>")
playsound(src, I.usesound, 50, 1)
return
else
to_chat(user, "Device must be placed over an exposed cable to attach to it.")
return
else
if (mode == 2)
STOP_PROCESSING(SSobj, src) // Now the power sink actually stops draining the station's power if you unhook it. --NeoFite
STOP_PROCESSING_POWER_OBJECT(src)
anchored = FALSE
mode = 0
src.visible_message("<span class='notice'>[user] detaches [src] from the cable!</span>")
set_light(0)
playsound(src, I.usesound, 50, 1)
icon_state = "powersink0"
return
else
..()
/obj/item/device/powersink/attack_ai()
return
/obj/item/device/powersink/attack_hand(var/mob/user)
switch(mode)
if(0)
..()
if(1)
src.visible_message("<span class='notice'>[user] activates [src]!</span>")
mode = 2
icon_state = "powersink1"
START_PROCESSING(SSobj, src)
datum_flags &= ~DF_ISPROCESSING // Have to reset this flag so that PROCESSING_POWER_OBJECT can re-add it. It fails if the flag is already present. - Ater
START_PROCESSING_POWER_OBJECT(src)
if(2) //This switch option wasn't originally included. It exists now. --NeoFite
src.visible_message("<span class='notice'>[user] deactivates [src]!</span>")
mode = 1
set_light(0)
icon_state = "powersink0"
STOP_PROCESSING(SSobj, src)
STOP_PROCESSING_POWER_OBJECT(src)
/obj/item/device/powersink/pwr_drain()
if(!attached)
return 0
if(drained_this_tick)
return 1
drained_this_tick = 1
var/drained = 0
if(!PN)
return 1
set_light(12)
PN.trigger_warning()
// found a powernet, so drain up to max power from it
drained = PN.draw_power(drain_rate)
// 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)
// Enough power drained this tick, no need to torture more APCs
if(drained >= drain_rate)
break
if(istype(T.master, /obj/machinery/power/apc))
var/obj/machinery/power/apc/A = T.master
if(A.operating && A.cell)
var/cur_charge = A.cell.charge / CELLRATE
var/drain_val = min(apc_drain_rate, cur_charge)
A.cell.use(drain_val * CELLRATE)
drained += drain_val
power_drained += drained
return 1
/obj/item/device/powersink/process()
drained_this_tick = 0
power_drained -= min(dissipation_rate, power_drained)
if(power_drained > max_power * 0.95)
playsound(src, 'sound/effects/screech.ogg', 100, 1, 1)
if(power_drained >= max_power)
explosion(src.loc, 3,6,9,12)
qdel(src)
return
if(attached && attached.powernet)
PN = attached.powernet
else
PN = null
+44 -44
View File
@@ -1,44 +1,44 @@
/obj/item/device/radio/beacon
name = "tracking beacon"
desc = "A beacon used by a teleporter."
icon_state = "beacon"
item_state = "signaler"
var/code = "electronic"
origin_tech = list(TECH_BLUESPACE = 1)
GLOBAL_LIST_BOILERPLATE(all_beacons, /obj/item/device/radio/beacon)
/obj/item/device/radio/beacon/hear_talk()
return
/obj/item/device/radio/beacon/send_hear()
return null
/obj/item/device/radio/beacon/verb/alter_signal(t as text)
set name = "Alter Beacon's Signal"
set category = "Object"
set src in usr
if ((usr.canmove && !( usr.restrained() )))
src.code = t
if (!( src.code ))
src.code = "beacon"
src.add_fingerprint(usr)
return
// SINGULO BEACON SPAWNER
/obj/item/device/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 = list(TECH_BLUESPACE = 1, TECH_ILLEGAL = 7)
/obj/item/device/radio/beacon/syndicate/attack_self(mob/user as mob)
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/device/radio/beacon
name = "tracking beacon"
desc = "A beacon used by a teleporter."
icon_state = "beacon"
item_state = "signaler"
var/code = "electronic"
origin_tech = list(TECH_BLUESPACE = 1)
GLOBAL_LIST_BOILERPLATE(all_beacons, /obj/item/device/radio/beacon)
/obj/item/device/radio/beacon/hear_talk()
return
/obj/item/device/radio/beacon/send_hear()
return null
/obj/item/device/radio/beacon/verb/alter_signal(t as text)
set name = "Alter Beacon's Signal"
set category = "Object"
set src in usr
if ((usr.canmove && !( usr.restrained() )))
src.code = t
if (!( src.code ))
src.code = "beacon"
src.add_fingerprint(usr)
return
// SINGULO BEACON SPAWNER
/obj/item/device/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 = list(TECH_BLUESPACE = 1, TECH_ILLEGAL = 7)
/obj/item/device/radio/beacon/syndicate/attack_self(mob/user as mob)
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
@@ -1,131 +1,131 @@
/obj/item/device/radio/electropack
name = "electropack"
desc = "Dance my monkeys! DANCE!!!"
icon_state = "electropack0"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_storage.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_storage.dmi',
)
item_state = "electropack"
frequency = 1449
slot_flags = SLOT_BACK
w_class = ITEMSIZE_HUGE
matter = list(MAT_STEEL = 10000,MAT_GLASS = 2500)
var/code = 2
/obj/item/device/radio/electropack/attack_hand(mob/living/user as mob)
if(src == user.back)
to_chat(user, "<span class='notice'>You need help taking this off!</span>")
return
..()
/obj/item/device/radio/electropack/attackby(obj/item/weapon/W as obj, mob/user as mob)
..()
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'
user.drop_from_inventory(W)
W.loc = A
W.master = A
A.part1 = W
user.drop_from_inventory(src)
loc = A
master = A
A.part2 = src
user.put_in_hands(A)
A.add_fingerprint(user)
/obj/item/device/radio/electropack/Topic(href, href_list)
//..()
if(usr.stat || usr.restrained())
return
if(((istype(usr, /mob/living/carbon/human) && ((!( ticker ) || (ticker && ticker.mode != "monkey")) && usr.contents.Find(src))) || (usr.contents.Find(master) || (in_range(src, usr) && istype(loc, /turf)))))
usr.set_machine(src)
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 = min(100, code)
code = max(1, code)
else
if(href_list["power"])
on = !( on )
icon_state = "electropack[on]"
if(!( master ))
if(istype(loc, /mob))
attack_self(loc)
else
for(var/mob/M in viewers(1, src))
if(M.client)
attack_self(M)
else
if(istype(master.loc, /mob))
attack_self(master.loc)
else
for(var/mob/M in viewers(1, master))
if(M.client)
attack_self(M)
else
usr << browse(null, "window=radio")
return
return
/obj/item/device/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>")
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, M)
s.start()
M.Weaken(10)
if(master && wires & 1)
master.receive_signal()
return
/obj/item/device/radio/electropack/attack_self(mob/user as mob, flag1)
if(!istype(user, /mob/living/carbon/human))
return
user.set_machine(src)
var/dat = {"<TT>
<A href='?src=\ref[src];power=1'>Turn [on ? "Off" : "On"]</A><BR>
<B>Frequency/Code</B> for electropack:<BR>
Frequency:
<A href='byond://?src=\ref[src];freq=-10'>-</A>
<A href='byond://?src=\ref[src];freq=-2'>-</A> [format_frequency(frequency)]
<A href='byond://?src=\ref[src];freq=2'>+</A>
<A href='byond://?src=\ref[src];freq=10'>+</A><BR>
Code:
<A href='byond://?src=\ref[src];code=-5'>-</A>
<A href='byond://?src=\ref[src];code=-1'>-</A> [code]
<A href='byond://?src=\ref[src];code=1'>+</A>
<A href='byond://?src=\ref[src];code=5'>+</A><BR>
</TT>"}
user << browse(dat, "window=radio")
onclose(user, "radio")
return
/obj/item/device/radio/electropack
name = "electropack"
desc = "Dance my monkeys! DANCE!!!"
icon_state = "electropack0"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_storage.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_storage.dmi',
)
item_state = "electropack"
frequency = 1449
slot_flags = SLOT_BACK
w_class = ITEMSIZE_HUGE
matter = list(MAT_STEEL = 10000,MAT_GLASS = 2500)
var/code = 2
/obj/item/device/radio/electropack/attack_hand(mob/living/user as mob)
if(src == user.back)
to_chat(user, "<span class='notice'>You need help taking this off!</span>")
return
..()
/obj/item/device/radio/electropack/attackby(obj/item/weapon/W as obj, mob/user as mob)
..()
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'
user.drop_from_inventory(W)
W.loc = A
W.master = A
A.part1 = W
user.drop_from_inventory(src)
loc = A
master = A
A.part2 = src
user.put_in_hands(A)
A.add_fingerprint(user)
/obj/item/device/radio/electropack/Topic(href, href_list)
//..()
if(usr.stat || usr.restrained())
return
if(((istype(usr, /mob/living/carbon/human) && ((!( ticker ) || (ticker && ticker.mode != "monkey")) && usr.contents.Find(src))) || (usr.contents.Find(master) || (in_range(src, usr) && istype(loc, /turf)))))
usr.set_machine(src)
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 = min(100, code)
code = max(1, code)
else
if(href_list["power"])
on = !( on )
icon_state = "electropack[on]"
if(!( master ))
if(istype(loc, /mob))
attack_self(loc)
else
for(var/mob/M in viewers(1, src))
if(M.client)
attack_self(M)
else
if(istype(master.loc, /mob))
attack_self(master.loc)
else
for(var/mob/M in viewers(1, master))
if(M.client)
attack_self(M)
else
usr << browse(null, "window=radio")
return
return
/obj/item/device/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>")
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(3, 1, M)
s.start()
M.Weaken(10)
if(master && wires & 1)
master.receive_signal()
return
/obj/item/device/radio/electropack/attack_self(mob/user as mob, flag1)
if(!istype(user, /mob/living/carbon/human))
return
user.set_machine(src)
var/dat = {"<TT>
<A href='?src=\ref[src];power=1'>Turn [on ? "Off" : "On"]</A><BR>
<B>Frequency/Code</B> for electropack:<BR>
Frequency:
<A href='byond://?src=\ref[src];freq=-10'>-</A>
<A href='byond://?src=\ref[src];freq=-2'>-</A> [format_frequency(frequency)]
<A href='byond://?src=\ref[src];freq=2'>+</A>
<A href='byond://?src=\ref[src];freq=10'>+</A><BR>
Code:
<A href='byond://?src=\ref[src];code=-5'>-</A>
<A href='byond://?src=\ref[src];code=-1'>-</A> [code]
<A href='byond://?src=\ref[src];code=1'>+</A>
<A href='byond://?src=\ref[src];code=5'>+</A><BR>
</TT>"}
user << browse(dat, "window=radio")
onclose(user, "radio")
return
+455 -455
View File
@@ -1,455 +1,455 @@
/obj/item/device/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 = null //To remove the radio's state
matter = list(MAT_STEEL = 75)
subspace_transmission = 1
canhear_range = 0 // can't hear headsets from very far away
slot_flags = SLOT_EARS
sprite_sheets = list(SPECIES_TESHARI = 'icons/inventory/ears/mob_teshari.dmi')
var/translate_binary = 0
var/translate_hive = 0
var/obj/item/device/encryptionkey/keyslot1 = null
var/obj/item/device/encryptionkey/keyslot2 = null
var/ks1type = null
var/ks2type = null
drop_sound = 'sound/items/drop/component.ogg'
pickup_sound = 'sound/items/pickup/component.ogg'
/obj/item/device/radio/headset/New()
..()
internal_channels.Cut()
if(ks1type)
keyslot1 = new ks1type(src)
if(ks2type)
keyslot2 = new ks2type(src)
recalculateChannels(1)
/obj/item/device/radio/headset/Destroy()
qdel(keyslot1)
qdel(keyslot2)
keyslot1 = null
keyslot2 = null
return ..()
/obj/item/device/radio/headset/list_channels(var/mob/user)
return list_secure_channels()
/obj/item/device/radio/headset/examine(mob/user)
. = ..()
if(radio_desc && Adjacent(user))
. += "The following channels are available:"
. += radio_desc
/obj/item/device/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, 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, M.strip_prefixes(multilingual_to_message(message_pieces)))
return RADIO_CONNECTION_NON_SUBSPACE
return RADIO_CONNECTION_FAIL
return ..()
/obj/item/device/radio/headset/receive_range(freq, level, aiOverride = 0)
if (aiOverride)
//playsound(loc, 'sound/effects/radio_common.ogg', 20, 1, 1, preference = /datum/client_preference/radio_sounds)
return ..(freq, level)
if(ishuman(src.loc))
var/mob/living/carbon/human/H = src.loc
if(H.l_ear == src || H.r_ear == src)
//playsound(loc, 'sound/effects/radio_common.ogg', 20, 1, 1, preference = /datum/client_preference/radio_sounds)
return ..(freq, level)
return -1
/obj/item/device/radio/headset/get_worn_icon_state(var/slot_name)
var/append = ""
if(icon_override)
switch(slot_name)
if(slot_l_ear_str)
append = "_l"
if(slot_r_ear_str)
append = "_r"
return "[..()][append]"
/obj/item/device/radio/headset/tgui_state(mob/user)
return GLOB.tgui_inventory_state
/obj/item/device/radio/headset/syndicate
origin_tech = list(TECH_ILLEGAL = 3)
syndie = 1
ks1type = /obj/item/device/encryptionkey/syndicate
/obj/item/device/radio/headset/syndicate/alt
icon_state = "syndie_headset"
item_state = "headset"
origin_tech = list(TECH_ILLEGAL = 3)
syndie = 1
ks1type = /obj/item/device/encryptionkey/syndicate
/obj/item/device/radio/headset/raider
origin_tech = list(TECH_ILLEGAL = 2)
syndie = 1
ks1type = /obj/item/device/encryptionkey/raider
/obj/item/device/radio/headset/raider/Initialize()
. = ..()
set_frequency(RAID_FREQ)
/obj/item/device/radio/headset/binary
origin_tech = list(TECH_ILLEGAL = 3)
ks1type = /obj/item/device/encryptionkey/binary
/obj/item/device/radio/headset/headset_sec
name = "security radio headset"
desc = "This is used by your elite security force."
icon_state = "sec_headset"
ks2type = /obj/item/device/encryptionkey/headset_sec
/obj/item/device/radio/headset/headset_sec/alt
name = "security bowman headset"
desc = "This is used by your elite security force."
icon_state = "sec_headset_alt"
ks2type = /obj/item/device/encryptionkey/headset_sec
/obj/item/device/radio/headset/headset_eng
name = "engineering radio headset"
desc = "When the engineers wish to chat like girls."
icon_state = "eng_headset"
ks2type = /obj/item/device/encryptionkey/headset_eng
/obj/item/device/radio/headset/headset_eng/alt
name = "engineering bowman headset"
desc = "When the engineers wish to chat like girls."
icon_state = "eng_headset_alt"
ks2type = /obj/item/device/encryptionkey/headset_eng
/obj/item/device/radio/headset/headset_rob
name = "robotics radio headset"
desc = "Made specifically for the roboticists who cannot decide between departments."
icon_state = "rob_headset"
ks2type = /obj/item/device/encryptionkey/headset_rob
/obj/item/device/radio/headset/headset_med
name = "medical radio headset"
desc = "A headset for the trained staff of the medbay."
icon_state = "med_headset"
ks2type = /obj/item/device/encryptionkey/headset_med
/obj/item/device/radio/headset/headset_med/alt
name = "medical bowman headset"
desc = "A headset for the trained staff of the medbay."
icon_state = "med_headset_alt"
ks2type = /obj/item/device/encryptionkey/headset_med
/obj/item/device/radio/headset/headset_sci
name = "science radio headset"
desc = "A sciency headset. Like usual."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/headset_sci
/obj/item/device/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 = "med_headset"
ks2type = /obj/item/device/encryptionkey/headset_medsci
/obj/item/device/radio/headset/headset_com
name = "command radio headset"
desc = "A headset with a commanding channel."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/headset_com
/obj/item/device/radio/headset/headset_com/alt
name = "command bowman headset"
desc = "A headset with a commanding channel."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/headset_com
/obj/item/device/radio/headset/heads/captain
name = "site manager's headset"
desc = "The headset of the boss."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/heads/captain
/obj/item/device/radio/headset/heads/captain/alt
name = "site manager's bowman headset"
desc = "The headset of the boss."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/heads/captain
/obj/item/device/radio/headset/heads/captain/sfr
name = "SFR headset"
desc = "A headset belonging to a Sif Free Radio DJ. SFR, best tunes in the wilderness."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/heads/captain
/obj/item/device/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/device/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/device/radio/headset/heads/ai_integrated/receive_range(freq, level)
if (disabledAi)
return -1 //Transciever Disabled.
return ..(freq, level, 1)
/obj/item/device/radio/headset/heads/rd
name = "research director's headset"
desc = "Headset of the eccentric-in-chief."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/heads/rd
/obj/item/device/radio/headset/heads/rd/alt
name = "research director's bowman headset"
desc = "Headset of the eccentric-in-chief."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/heads/rd
/obj/item/device/radio/headset/heads/hos
name = "head of security's headset"
desc = "The headset of the hardass who protects your worthless lives."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/heads/hos
/obj/item/device/radio/headset/heads/hos/alt
name = "head of security's bowman headset"
desc = "The headset of the hardass who protects your worthless lives."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/heads/hos
/obj/item/device/radio/headset/heads/ce
name = "chief engineer's headset"
desc = "The headset of the clown who is in charge of the circus."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/heads/ce
/obj/item/device/radio/headset/heads/ce/alt
name = "chief engineer's bowman headset"
desc = "The headset of the clown who is in charge of the circus."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/heads/ce
/obj/item/device/radio/headset/heads/cmo
name = "chief medical officer's headset"
desc = "The headset of the highly trained medical chief."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/heads/cmo
/obj/item/device/radio/headset/heads/cmo/alt
name = "chief medical officer's bowman headset"
desc = "The headset of the highly trained medical chief."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/heads/cmo
/obj/item/device/radio/headset/heads/hop
name = "head of personnel's headset"
desc = "The headset of the poor fool who will one day be Site Manager."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/heads/hop
/obj/item/device/radio/headset/heads/hop/alt
name = "head of personnel's bowman headset"
desc = "The headset of the poor fool who will one day be Site Manager."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/heads/hop
/obj/item/device/radio/headset/headset_mine
name = "mining radio headset"
desc = "Headset used by miners. Has inbuilt short-band radio for when comms are down."
icon_state = "mine_headset"
adhoc_fallback = TRUE
ks2type = /obj/item/device/encryptionkey/headset_cargo
/obj/item/device/radio/headset/headset_cargo
name = "supply radio headset"
desc = "A headset used by the QM and their cronies."
icon_state = "cargo_headset"
ks2type = /obj/item/device/encryptionkey/headset_cargo
/obj/item/device/radio/headset/headset_cargo/alt
name = "supply bowman headset"
desc = "A bowman headset used by the QM and their cronies."
icon_state = "cargo_headset_alt"
ks2type = /obj/item/device/encryptionkey/headset_cargo
/obj/item/device/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"
ks2type = /obj/item/device/encryptionkey/headset_service
/obj/item/device/radio/headset/ert
name = "emergency response team radio headset"
desc = "The headset of the boss's boss."
icon_state = "com_headset"
centComm = 1
// freerange = 1
ks2type = /obj/item/device/encryptionkey/ert
/obj/item/device/radio/headset/ert/alt
name = "emergency response team bowman headset"
desc = "The headset of the boss's boss."
icon_state = "com_headset_alt"
// freerange = 1
ks2type = /obj/item/device/encryptionkey/ert
/obj/item/device/radio/headset/omni //Only for the admin intercoms
ks2type = /obj/item/device/encryptionkey/omni
/obj/item/device/radio/headset/ia
name = "internal affair's headset"
desc = "The headset of your worst enemy."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/heads/hos
/obj/item/device/radio/headset/mmi_radio
name = "brain-integrated radio"
desc = "MMIs and synthetic brains are often equipped with these."
icon = 'icons/obj/robot_component.dmi'
icon_state = "radio"
item_state = "headset"
var/mmiowner = null
var/radio_enabled = 1
/obj/item/device/radio/headset/mmi_radio/receive_range(freq, level)
if (!radio_enabled || istype(src.loc.loc, /mob/living/silicon) || istype(src.loc.loc, /obj/item/organ/internal))
return -1 //Transciever Disabled.
return ..(freq, level, 1)
/obj/item/device/radio/headset/attackby(obj/item/weapon/W as obj, mob/user as mob)
// ..()
user.set_machine(src)
if(!(W.has_tool_quality(TOOL_SCREWDRIVER) || istype(W, /obj/item/device/encryptionkey)))
return
if(W.has_tool_quality(TOOL_SCREWDRIVER))
if(keyslot1 || keyslot2)
for(var/ch_name in channels)
radio_controller.remove_object(src, 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!")
playsound(src, W.usesound, 50, 1)
else
to_chat(user, "This headset doesn't have any encryption keys! How useless...")
if(istype(W, /obj/item/device/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/device/radio/headset/recalculateChannels(var/setDescription = 0)
src.channels = list()
src.translate_binary = 0
src.translate_hive = 0
src.syndie = 0
if(keyslot1)
for(var/ch_name in keyslot1.channels)
if(ch_name in src.channels)
continue
src.channels += ch_name
src.channels[ch_name] = keyslot1.channels[ch_name]
if(keyslot1.translate_binary)
src.translate_binary = 1
if(keyslot1.translate_hive)
src.translate_hive = 1
if(keyslot1.syndie)
src.syndie = 1
if(keyslot2)
for(var/ch_name in keyslot2.channels)
if(ch_name in src.channels)
continue
src.channels += ch_name
src.channels[ch_name] = keyslot2.channels[ch_name]
if(keyslot2.translate_binary)
src.translate_binary = 1
if(keyslot2.translate_hive)
src.translate_hive = 1
if(keyslot2.syndie)
src.syndie = 1
for (var/ch_name in channels)
if(!radio_controller)
sleep(30) // Waiting for the radio_controller to be created.
if(!radio_controller)
src.name = "broken radio headset"
return
secure_radio_connections[ch_name] = radio_controller.add_object(src, radiochannels[ch_name], RADIO_CHAT)
if(setDescription)
setupRadioDescription()
return
/obj/item/device/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/device/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 = null //To remove the radio's state
matter = list(MAT_STEEL = 75)
subspace_transmission = 1
canhear_range = 0 // can't hear headsets from very far away
slot_flags = SLOT_EARS
sprite_sheets = list(SPECIES_TESHARI = 'icons/inventory/ears/mob_teshari.dmi')
var/translate_binary = 0
var/translate_hive = 0
var/obj/item/device/encryptionkey/keyslot1 = null
var/obj/item/device/encryptionkey/keyslot2 = null
var/ks1type = null
var/ks2type = null
drop_sound = 'sound/items/drop/component.ogg'
pickup_sound = 'sound/items/pickup/component.ogg'
/obj/item/device/radio/headset/New()
..()
internal_channels.Cut()
if(ks1type)
keyslot1 = new ks1type(src)
if(ks2type)
keyslot2 = new ks2type(src)
recalculateChannels(1)
/obj/item/device/radio/headset/Destroy()
qdel(keyslot1)
qdel(keyslot2)
keyslot1 = null
keyslot2 = null
return ..()
/obj/item/device/radio/headset/list_channels(var/mob/user)
return list_secure_channels()
/obj/item/device/radio/headset/examine(mob/user)
. = ..()
if(radio_desc && Adjacent(user))
. += "The following channels are available:"
. += radio_desc
/obj/item/device/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, 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, M.strip_prefixes(multilingual_to_message(message_pieces)))
return RADIO_CONNECTION_NON_SUBSPACE
return RADIO_CONNECTION_FAIL
return ..()
/obj/item/device/radio/headset/receive_range(freq, level, aiOverride = 0)
if (aiOverride)
//playsound(loc, 'sound/effects/radio_common.ogg', 20, 1, 1, preference = /datum/client_preference/radio_sounds)
return ..(freq, level)
if(ishuman(src.loc))
var/mob/living/carbon/human/H = src.loc
if(H.l_ear == src || H.r_ear == src)
//playsound(loc, 'sound/effects/radio_common.ogg', 20, 1, 1, preference = /datum/client_preference/radio_sounds)
return ..(freq, level)
return -1
/obj/item/device/radio/headset/get_worn_icon_state(var/slot_name)
var/append = ""
if(icon_override)
switch(slot_name)
if(slot_l_ear_str)
append = "_l"
if(slot_r_ear_str)
append = "_r"
return "[..()][append]"
/obj/item/device/radio/headset/tgui_state(mob/user)
return GLOB.tgui_inventory_state
/obj/item/device/radio/headset/syndicate
origin_tech = list(TECH_ILLEGAL = 3)
syndie = 1
ks1type = /obj/item/device/encryptionkey/syndicate
/obj/item/device/radio/headset/syndicate/alt
icon_state = "syndie_headset"
item_state = "headset"
origin_tech = list(TECH_ILLEGAL = 3)
syndie = 1
ks1type = /obj/item/device/encryptionkey/syndicate
/obj/item/device/radio/headset/raider
origin_tech = list(TECH_ILLEGAL = 2)
syndie = 1
ks1type = /obj/item/device/encryptionkey/raider
/obj/item/device/radio/headset/raider/Initialize()
. = ..()
set_frequency(RAID_FREQ)
/obj/item/device/radio/headset/binary
origin_tech = list(TECH_ILLEGAL = 3)
ks1type = /obj/item/device/encryptionkey/binary
/obj/item/device/radio/headset/headset_sec
name = "security radio headset"
desc = "This is used by your elite security force."
icon_state = "sec_headset"
ks2type = /obj/item/device/encryptionkey/headset_sec
/obj/item/device/radio/headset/headset_sec/alt
name = "security bowman headset"
desc = "This is used by your elite security force."
icon_state = "sec_headset_alt"
ks2type = /obj/item/device/encryptionkey/headset_sec
/obj/item/device/radio/headset/headset_eng
name = "engineering radio headset"
desc = "When the engineers wish to chat like girls."
icon_state = "eng_headset"
ks2type = /obj/item/device/encryptionkey/headset_eng
/obj/item/device/radio/headset/headset_eng/alt
name = "engineering bowman headset"
desc = "When the engineers wish to chat like girls."
icon_state = "eng_headset_alt"
ks2type = /obj/item/device/encryptionkey/headset_eng
/obj/item/device/radio/headset/headset_rob
name = "robotics radio headset"
desc = "Made specifically for the roboticists who cannot decide between departments."
icon_state = "rob_headset"
ks2type = /obj/item/device/encryptionkey/headset_rob
/obj/item/device/radio/headset/headset_med
name = "medical radio headset"
desc = "A headset for the trained staff of the medbay."
icon_state = "med_headset"
ks2type = /obj/item/device/encryptionkey/headset_med
/obj/item/device/radio/headset/headset_med/alt
name = "medical bowman headset"
desc = "A headset for the trained staff of the medbay."
icon_state = "med_headset_alt"
ks2type = /obj/item/device/encryptionkey/headset_med
/obj/item/device/radio/headset/headset_sci
name = "science radio headset"
desc = "A sciency headset. Like usual."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/headset_sci
/obj/item/device/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 = "med_headset"
ks2type = /obj/item/device/encryptionkey/headset_medsci
/obj/item/device/radio/headset/headset_com
name = "command radio headset"
desc = "A headset with a commanding channel."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/headset_com
/obj/item/device/radio/headset/headset_com/alt
name = "command bowman headset"
desc = "A headset with a commanding channel."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/headset_com
/obj/item/device/radio/headset/heads/captain
name = "site manager's headset"
desc = "The headset of the boss."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/heads/captain
/obj/item/device/radio/headset/heads/captain/alt
name = "site manager's bowman headset"
desc = "The headset of the boss."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/heads/captain
/obj/item/device/radio/headset/heads/captain/sfr
name = "SFR headset"
desc = "A headset belonging to a Sif Free Radio DJ. SFR, best tunes in the wilderness."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/heads/captain
/obj/item/device/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/device/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/device/radio/headset/heads/ai_integrated/receive_range(freq, level)
if (disabledAi)
return -1 //Transciever Disabled.
return ..(freq, level, 1)
/obj/item/device/radio/headset/heads/rd
name = "research director's headset"
desc = "Headset of the eccentric-in-chief."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/heads/rd
/obj/item/device/radio/headset/heads/rd/alt
name = "research director's bowman headset"
desc = "Headset of the eccentric-in-chief."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/heads/rd
/obj/item/device/radio/headset/heads/hos
name = "head of security's headset"
desc = "The headset of the hardass who protects your worthless lives."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/heads/hos
/obj/item/device/radio/headset/heads/hos/alt
name = "head of security's bowman headset"
desc = "The headset of the hardass who protects your worthless lives."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/heads/hos
/obj/item/device/radio/headset/heads/ce
name = "chief engineer's headset"
desc = "The headset of the clown who is in charge of the circus."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/heads/ce
/obj/item/device/radio/headset/heads/ce/alt
name = "chief engineer's bowman headset"
desc = "The headset of the clown who is in charge of the circus."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/heads/ce
/obj/item/device/radio/headset/heads/cmo
name = "chief medical officer's headset"
desc = "The headset of the highly trained medical chief."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/heads/cmo
/obj/item/device/radio/headset/heads/cmo/alt
name = "chief medical officer's bowman headset"
desc = "The headset of the highly trained medical chief."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/heads/cmo
/obj/item/device/radio/headset/heads/hop
name = "head of personnel's headset"
desc = "The headset of the poor fool who will one day be Site Manager."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/heads/hop
/obj/item/device/radio/headset/heads/hop/alt
name = "head of personnel's bowman headset"
desc = "The headset of the poor fool who will one day be Site Manager."
icon_state = "com_headset_alt"
ks2type = /obj/item/device/encryptionkey/heads/hop
/obj/item/device/radio/headset/headset_mine
name = "mining radio headset"
desc = "Headset used by miners. Has inbuilt short-band radio for when comms are down."
icon_state = "mine_headset"
adhoc_fallback = TRUE
ks2type = /obj/item/device/encryptionkey/headset_cargo
/obj/item/device/radio/headset/headset_cargo
name = "supply radio headset"
desc = "A headset used by the QM and their cronies."
icon_state = "cargo_headset"
ks2type = /obj/item/device/encryptionkey/headset_cargo
/obj/item/device/radio/headset/headset_cargo/alt
name = "supply bowman headset"
desc = "A bowman headset used by the QM and their cronies."
icon_state = "cargo_headset_alt"
ks2type = /obj/item/device/encryptionkey/headset_cargo
/obj/item/device/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"
ks2type = /obj/item/device/encryptionkey/headset_service
/obj/item/device/radio/headset/ert
name = "emergency response team radio headset"
desc = "The headset of the boss's boss."
icon_state = "com_headset"
centComm = 1
// freerange = 1
ks2type = /obj/item/device/encryptionkey/ert
/obj/item/device/radio/headset/ert/alt
name = "emergency response team bowman headset"
desc = "The headset of the boss's boss."
icon_state = "com_headset_alt"
// freerange = 1
ks2type = /obj/item/device/encryptionkey/ert
/obj/item/device/radio/headset/omni //Only for the admin intercoms
ks2type = /obj/item/device/encryptionkey/omni
/obj/item/device/radio/headset/ia
name = "internal affair's headset"
desc = "The headset of your worst enemy."
icon_state = "com_headset"
ks2type = /obj/item/device/encryptionkey/heads/hos
/obj/item/device/radio/headset/mmi_radio
name = "brain-integrated radio"
desc = "MMIs and synthetic brains are often equipped with these."
icon = 'icons/obj/robot_component.dmi'
icon_state = "radio"
item_state = "headset"
var/mmiowner = null
var/radio_enabled = 1
/obj/item/device/radio/headset/mmi_radio/receive_range(freq, level)
if (!radio_enabled || istype(src.loc.loc, /mob/living/silicon) || istype(src.loc.loc, /obj/item/organ/internal))
return -1 //Transciever Disabled.
return ..(freq, level, 1)
/obj/item/device/radio/headset/attackby(obj/item/weapon/W as obj, mob/user as mob)
// ..()
user.set_machine(src)
if(!(W.has_tool_quality(TOOL_SCREWDRIVER) || istype(W, /obj/item/device/encryptionkey)))
return
if(W.has_tool_quality(TOOL_SCREWDRIVER))
if(keyslot1 || keyslot2)
for(var/ch_name in channels)
radio_controller.remove_object(src, 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!")
playsound(src, W.usesound, 50, 1)
else
to_chat(user, "This headset doesn't have any encryption keys! How useless...")
if(istype(W, /obj/item/device/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/device/radio/headset/recalculateChannels(var/setDescription = 0)
src.channels = list()
src.translate_binary = 0
src.translate_hive = 0
src.syndie = 0
if(keyslot1)
for(var/ch_name in keyslot1.channels)
if(ch_name in src.channels)
continue
src.channels += ch_name
src.channels[ch_name] = keyslot1.channels[ch_name]
if(keyslot1.translate_binary)
src.translate_binary = 1
if(keyslot1.translate_hive)
src.translate_hive = 1
if(keyslot1.syndie)
src.syndie = 1
if(keyslot2)
for(var/ch_name in keyslot2.channels)
if(ch_name in src.channels)
continue
src.channels += ch_name
src.channels[ch_name] = keyslot2.channels[ch_name]
if(keyslot2.translate_binary)
src.translate_binary = 1
if(keyslot2.translate_hive)
src.translate_hive = 1
if(keyslot2.syndie)
src.syndie = 1
for (var/ch_name in channels)
if(!radio_controller)
sleep(30) // Waiting for the radio_controller to be created.
if(!radio_controller)
src.name = "broken radio headset"
return
secure_radio_connections[ch_name] = radio_controller.add_object(src, radiochannels[ch_name], RADIO_CHAT)
if(setDescription)
setupRadioDescription()
return
/obj/item/device/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
+229 -229
View File
@@ -1,229 +1,229 @@
/obj/item/device/radio/intercom
name = "station intercom (General)"
desc = "Talk through this."
icon = 'icons/obj/radio_vr.dmi' //VOREStation Edit - New Icon
icon_state = "intercom"
layer = ABOVE_WINDOW_LAYER
anchored = TRUE
w_class = ITEMSIZE_LARGE
canhear_range = 7 //VOREStation Edit
flags = NOBLOODY
light_color = "#00ff00"
light_power = 0.25
blocks_emissive = NONE
vis_flags = VIS_HIDE // They have an emissive that looks bad in openspace due to their wall-mounted nature
var/circuit = /obj/item/weapon/circuitboard/intercom
var/number = 0
var/wiresexposed = 0
/obj/item/device/radio/intercom/Initialize()
. = ..()
var/area/A = get_area(src)
if(A)
GLOB.apc_event.register(A, src, /atom/proc/update_icon)
update_icon()
/obj/item/device/radio/intercom/Destroy()
var/area/A = get_area(src)
if(A)
GLOB.apc_event.unregister(A, src, /atom/proc/update_icon)
return ..()
/obj/item/device/radio/intercom/custom
name = "station intercom (Custom)"
broadcasting = 0
listening = 0
/obj/item/device/radio/intercom/interrogation
name = "station intercom (Interrogation)"
frequency = 1449
/obj/item/device/radio/intercom/private
name = "station intercom (Private)"
frequency = AI_FREQ
/obj/item/device/radio/intercom/specops
name = "\improper Spec Ops intercom"
frequency = ERT_FREQ
subspace_transmission = 1
centComm = 1
/obj/item/device/radio/intercom/department
canhear_range = 5
broadcasting = 0
listening = 1
/obj/item/device/radio/intercom/department/medbay
name = "station intercom (Medbay)"
icon_state = "medintercom"
light_color = "#00aaff"
frequency = MED_I_FREQ
/obj/item/device/radio/intercom/department/security
name = "station intercom (Security)"
icon_state = "secintercom"
light_color = "#ff0000"
frequency = SEC_I_FREQ
/obj/item/device/radio/intercom/entertainment
name = "entertainment intercom"
frequency = ENT_FREQ
/obj/item/device/radio/intercom/omni
name = "global announcer"
/obj/item/device/radio/intercom/omni/Initialize()
channels = radiochannels.Copy()
return ..()
/obj/item/device/radio/intercom/New()
..()
circuit = new circuit(src)
/obj/item/device/radio/intercom/department/medbay/New()
..()
internal_channels = default_medbay_channels.Copy()
/obj/item/device/radio/intercom/department/security/New()
..()
internal_channels = list(
num2text(PUB_FREQ) = list(),
num2text(SEC_I_FREQ) = list(access_security)
)
/obj/item/device/radio/intercom/entertainment/New()
..()
internal_channels = list(
num2text(PUB_FREQ) = list(),
num2text(ENT_FREQ) = list()
)
/obj/item/device/radio/intercom/syndicate
name = "illicit intercom"
desc = "Talk through this. Evilly"
frequency = SYND_FREQ
subspace_transmission = 1
syndie = 1
/obj/item/device/radio/intercom/syndicate/New()
..()
internal_channels[num2text(SYND_FREQ)] = list(access_syndicate)
/obj/item/device/radio/intercom/raider
name = "illicit intercom"
desc = "Pirate radio, but not in the usual sense of the word."
frequency = RAID_FREQ
subspace_transmission = 1
syndie = 1
/obj/item/device/radio/intercom/raider/New()
..()
internal_channels[num2text(RAID_FREQ)] = list(access_syndicate)
/obj/item/device/radio/intercom/attack_ai(mob/user as mob)
src.add_fingerprint(user)
spawn (0)
attack_self(user)
/obj/item/device/radio/intercom/attack_hand(mob/user as mob)
src.add_fingerprint(user)
spawn (0)
attack_self(user)
/obj/item/device/radio/intercom/attackby(obj/item/W as obj, mob/user as mob)
add_fingerprint(user)
if(W.has_tool_quality(TOOL_SCREWDRIVER)) // Opening the intercom up.
wiresexposed = !wiresexposed
to_chat(user, "The wires have been [wiresexposed ? "exposed" : "unexposed"]")
playsound(src, W.usesound, 50, 1)
update_icon()
else if(wiresexposed && W.has_tool_quality(TOOL_WIRECUTTER))
user.visible_message("<span class='warning'>[user] has cut the wires inside \the [src]!</span>", "You have cut the wires inside \the [src].")
playsound(src, W.usesound, 50, 1)
new/obj/item/stack/cable_coil(get_turf(src), 5)
var/obj/structure/frame/A = new /obj/structure/frame(src.loc)
var/obj/item/weapon/circuitboard/M = circuit
A.frame_type = M.board_type
A.pixel_x = pixel_x
A.pixel_y = pixel_y
A.circuit = M
A.set_dir(dir)
A.anchored = TRUE
A.state = 2
A.update_icon()
M.deconstruct(src)
qdel(src)
else
src.attack_hand(user)
/obj/item/device/radio/intercom/receive_range(freq, level)
if (!on)
return -1
if(!(0 in level))
var/turf/position = get_turf(src)
if(isnull(position) || !(position.z in level))
return -1
if (!src.listening)
return -1
if(freq in ANTAG_FREQS)
if(!(src.syndie))
return -1//Prevents broadcast of messages over devices lacking the encryption
return canhear_range
/obj/item/device/radio/intercom/update_icon()
var/area/A = get_area(src)
on = A?.powered(EQUIP)
cut_overlays()
if(!on)
set_light(0)
set_light_on(FALSE)
if(wiresexposed)
icon_state = "intercom-p_open"
else
icon_state = "intercom-p"
else
if(wiresexposed)
icon_state = "intercom_open"
set_light(0)
set_light_on(FALSE)
else
icon_state = initial(icon_state)
add_overlay(mutable_appearance(icon, "[icon_state]_ov"))
add_overlay(emissive_appearance(icon, "[icon_state]_ov"))
set_light(2)
set_light_on(TRUE)
//VOREStation Add Start
/obj/item/device/radio/intercom/AICtrlClick(var/mob/user)
ToggleBroadcast()
to_chat(user, "<span class='notice'>\The [src]'s microphone is now <b>[broadcasting ? "enabled" : "disabled"]</b>.</span>")
/obj/item/device/radio/intercom/AIAltClick(var/mob/user)
if(frequency == AI_FREQ)
set_frequency(initial(frequency))
to_chat(user, "<span class='notice'>\The [src]'s frequency is now set to [span_green("<b>Default</b>")].</span>")
else
set_frequency(AI_FREQ)
to_chat(user, "<span class='notice'>\The [src]'s frequency is now set to [span_pink("<b>AI Private</b>")].</span>")
//VOREStation Add End
/obj/item/device/radio/intercom/locked
var/locked_frequency
/obj/item/device/radio/intercom/locked/set_frequency(var/frequency)
if(frequency == locked_frequency)
..(locked_frequency)
/obj/item/device/radio/intercom/locked/list_channels()
return ""
/obj/item/device/radio/intercom/locked/ai_private
name = "\improper AI intercom"
frequency = AI_FREQ
broadcasting = 1
listening = 1
/obj/item/device/radio/intercom/locked/confessional
name = "confessional intercom"
frequency = 1480
/obj/item/device/radio/intercom
name = "station intercom (General)"
desc = "Talk through this."
icon = 'icons/obj/radio_vr.dmi' //VOREStation Edit - New Icon
icon_state = "intercom"
layer = ABOVE_WINDOW_LAYER
anchored = TRUE
w_class = ITEMSIZE_LARGE
canhear_range = 7 //VOREStation Edit
flags = NOBLOODY
light_color = "#00ff00"
light_power = 0.25
blocks_emissive = NONE
vis_flags = VIS_HIDE // They have an emissive that looks bad in openspace due to their wall-mounted nature
var/circuit = /obj/item/weapon/circuitboard/intercom
var/number = 0
var/wiresexposed = 0
/obj/item/device/radio/intercom/Initialize()
. = ..()
var/area/A = get_area(src)
if(A)
GLOB.apc_event.register(A, src, /atom/proc/update_icon)
update_icon()
/obj/item/device/radio/intercom/Destroy()
var/area/A = get_area(src)
if(A)
GLOB.apc_event.unregister(A, src, /atom/proc/update_icon)
return ..()
/obj/item/device/radio/intercom/custom
name = "station intercom (Custom)"
broadcasting = 0
listening = 0
/obj/item/device/radio/intercom/interrogation
name = "station intercom (Interrogation)"
frequency = 1449
/obj/item/device/radio/intercom/private
name = "station intercom (Private)"
frequency = AI_FREQ
/obj/item/device/radio/intercom/specops
name = "\improper Spec Ops intercom"
frequency = ERT_FREQ
subspace_transmission = 1
centComm = 1
/obj/item/device/radio/intercom/department
canhear_range = 5
broadcasting = 0
listening = 1
/obj/item/device/radio/intercom/department/medbay
name = "station intercom (Medbay)"
icon_state = "medintercom"
light_color = "#00aaff"
frequency = MED_I_FREQ
/obj/item/device/radio/intercom/department/security
name = "station intercom (Security)"
icon_state = "secintercom"
light_color = "#ff0000"
frequency = SEC_I_FREQ
/obj/item/device/radio/intercom/entertainment
name = "entertainment intercom"
frequency = ENT_FREQ
/obj/item/device/radio/intercom/omni
name = "global announcer"
/obj/item/device/radio/intercom/omni/Initialize()
channels = radiochannels.Copy()
return ..()
/obj/item/device/radio/intercom/New()
..()
circuit = new circuit(src)
/obj/item/device/radio/intercom/department/medbay/New()
..()
internal_channels = default_medbay_channels.Copy()
/obj/item/device/radio/intercom/department/security/New()
..()
internal_channels = list(
num2text(PUB_FREQ) = list(),
num2text(SEC_I_FREQ) = list(access_security)
)
/obj/item/device/radio/intercom/entertainment/New()
..()
internal_channels = list(
num2text(PUB_FREQ) = list(),
num2text(ENT_FREQ) = list()
)
/obj/item/device/radio/intercom/syndicate
name = "illicit intercom"
desc = "Talk through this. Evilly"
frequency = SYND_FREQ
subspace_transmission = 1
syndie = 1
/obj/item/device/radio/intercom/syndicate/New()
..()
internal_channels[num2text(SYND_FREQ)] = list(access_syndicate)
/obj/item/device/radio/intercom/raider
name = "illicit intercom"
desc = "Pirate radio, but not in the usual sense of the word."
frequency = RAID_FREQ
subspace_transmission = 1
syndie = 1
/obj/item/device/radio/intercom/raider/New()
..()
internal_channels[num2text(RAID_FREQ)] = list(access_syndicate)
/obj/item/device/radio/intercom/attack_ai(mob/user as mob)
src.add_fingerprint(user)
spawn (0)
attack_self(user)
/obj/item/device/radio/intercom/attack_hand(mob/user as mob)
src.add_fingerprint(user)
spawn (0)
attack_self(user)
/obj/item/device/radio/intercom/attackby(obj/item/W as obj, mob/user as mob)
add_fingerprint(user)
if(W.has_tool_quality(TOOL_SCREWDRIVER)) // Opening the intercom up.
wiresexposed = !wiresexposed
to_chat(user, "The wires have been [wiresexposed ? "exposed" : "unexposed"]")
playsound(src, W.usesound, 50, 1)
update_icon()
else if(wiresexposed && W.has_tool_quality(TOOL_WIRECUTTER))
user.visible_message("<span class='warning'>[user] has cut the wires inside \the [src]!</span>", "You have cut the wires inside \the [src].")
playsound(src, W.usesound, 50, 1)
new/obj/item/stack/cable_coil(get_turf(src), 5)
var/obj/structure/frame/A = new /obj/structure/frame(src.loc)
var/obj/item/weapon/circuitboard/M = circuit
A.frame_type = M.board_type
A.pixel_x = pixel_x
A.pixel_y = pixel_y
A.circuit = M
A.set_dir(dir)
A.anchored = TRUE
A.state = 2
A.update_icon()
M.deconstruct(src)
qdel(src)
else
src.attack_hand(user)
/obj/item/device/radio/intercom/receive_range(freq, level)
if (!on)
return -1
if(!(0 in level))
var/turf/position = get_turf(src)
if(isnull(position) || !(position.z in level))
return -1
if (!src.listening)
return -1
if(freq in ANTAG_FREQS)
if(!(src.syndie))
return -1//Prevents broadcast of messages over devices lacking the encryption
return canhear_range
/obj/item/device/radio/intercom/update_icon()
var/area/A = get_area(src)
on = A?.powered(EQUIP)
cut_overlays()
if(!on)
set_light(0)
set_light_on(FALSE)
if(wiresexposed)
icon_state = "intercom-p_open"
else
icon_state = "intercom-p"
else
if(wiresexposed)
icon_state = "intercom_open"
set_light(0)
set_light_on(FALSE)
else
icon_state = initial(icon_state)
add_overlay(mutable_appearance(icon, "[icon_state]_ov"))
add_overlay(emissive_appearance(icon, "[icon_state]_ov"))
set_light(2)
set_light_on(TRUE)
//VOREStation Add Start
/obj/item/device/radio/intercom/AICtrlClick(var/mob/user)
ToggleBroadcast()
to_chat(user, "<span class='notice'>\The [src]'s microphone is now <b>[broadcasting ? "enabled" : "disabled"]</b>.</span>")
/obj/item/device/radio/intercom/AIAltClick(var/mob/user)
if(frequency == AI_FREQ)
set_frequency(initial(frequency))
to_chat(user, "<span class='notice'>\The [src]'s frequency is now set to [span_green("<b>Default</b>")].</span>")
else
set_frequency(AI_FREQ)
to_chat(user, "<span class='notice'>\The [src]'s frequency is now set to [span_pink("<b>AI Private</b>")].</span>")
//VOREStation Add End
/obj/item/device/radio/intercom/locked
var/locked_frequency
/obj/item/device/radio/intercom/locked/set_frequency(var/frequency)
if(frequency == locked_frequency)
..(locked_frequency)
/obj/item/device/radio/intercom/locked/list_channels()
return ""
/obj/item/device/radio/intercom/locked/ai_private
name = "\improper AI intercom"
frequency = AI_FREQ
broadcasting = 1
listening = 1
/obj/item/device/radio/intercom/locked/confessional
name = "confessional intercom"
frequency = 1480
File diff suppressed because it is too large Load Diff
+274 -274
View File
@@ -1,275 +1,275 @@
/obj/item/device/camerabug
name = "mobile camera pod"
desc = "A camera pod used by tactical operators. Must be linked to a camera scanner unit."
icon = 'icons/obj/grenade.dmi'
icon_state = "camgrenade"
item_state = "empgrenade"
w_class = ITEMSIZE_SMALL
force = 0
throwforce = 5.0
throw_range = 15
throw_speed = 3
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1)
var/obj/item/device/bug_monitor/linkedmonitor
var/brokentype = /obj/item/brokenbug
// var/obj/item/device/radio/bug/radio
var/obj/machinery/camera/bug/camera
var/camtype = /obj/machinery/camera/bug
/obj/item/device/camerabug/New()
..()
// radio = new(src)
camera = new camtype(src)
/obj/item/device/camerabug/attack_self(mob/user)
if(user.a_intent == I_HURT)
to_chat(user, "<span class='notice'>You crush the [src] under your foot, breaking it.</span>")
visible_message("[user.name] crushes the [src] under their foot, breaking it!</span>")
new brokentype(get_turf(src))
spawn(0)
qdel(src)
/* else
user.set_machine(radio)
radio.interact(user)
*/
/obj/item/device/camerabug/verb/reset()
set name = "Reset camera bug"
set category = "Object"
if(linkedmonitor)
linkedmonitor.unpair(src)
linkedmonitor = null
qdel(camera)
camera = new camtype(src)
to_chat(usr, "<span class='notice'>You turn the [src] off and on again, delinking it from any monitors.")
/obj/item/brokenbug
name = "broken mobile camera pod"
desc = "A camera pod formerly used by tactical operators. The lens is smashed, and the circuits are damaged beyond repair."
icon = 'icons/obj/grenade.dmi'
icon_state = "camgrenadebroken"
item_state = "empgrenade"
force = 5.0
w_class = ITEMSIZE_SMALL
throwforce = 5.0
throw_range = 15
throw_speed = 3
origin_tech = list(TECH_ENGINEERING = 1)
/obj/item/brokenbug/spy
name = "broken bug"
desc = "" //Even when it's broken it's inconspicuous
icon = 'icons/obj/weapons.dmi'
icon_state = "eshield"
item_state = "nothing"
layer = TURF_LAYER+0.2
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
origin_tech = list(TECH_ENGINEERING = 1, TECH_ILLEGAL = 3) //crush it and you lose the data
force = 0
throwforce = 5.0
throw_range = 15
throw_speed = 3
/obj/item/device/camerabug/spy
name = "bug"
desc = "" //Nothing to see here
icon = 'icons/obj/weapons.dmi'
icon_state = "eshield"
item_state = "nothing"
layer = TURF_LAYER+0.2
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1, TECH_ILLEGAL = 3)
camtype = /obj/machinery/camera/bug/spy
/obj/item/device/camerabug/examine(mob/user)
. = ..()
if(get_dist(user, src) == 0)
. += "It has a tiny camera inside. Needs to be both configured and brought in contact with monitor device to be fully functional."
/obj/item/device/camerabug/update_icon()
..()
if(anchored) // Standard versions are relatively obvious if not hidden in a container. Anchoring them is advised, to disguise them.
alpha = 50
else
alpha = 255
/obj/item/device/camerabug/attackby(obj/item/W as obj, mob/living/user as mob)
if(istype(W, /obj/item/device/bug_monitor))
var/obj/item/device/bug_monitor/SM = W
if(!linkedmonitor)
to_chat(user, "<span class='notice'>\The [src] has been paired with \the [SM].</span>")
SM.pair(src)
linkedmonitor = SM
else if (linkedmonitor == SM)
to_chat(user, "<span class='notice'>\The [src] has been unpaired from \the [SM].</span>")
linkedmonitor.unpair(src)
linkedmonitor = null
else
to_chat(user, "Error: The device is linked to another monitor.")
else if(W.has_tool_quality(TOOL_WRENCH) && user.a_intent != I_HURT)
if(isturf(loc))
anchored = !anchored
to_chat(user, "<span class='notice'>You [anchored ? "" : "un"]secure \the [src].</span>")
update_icon()
return
else
if(W.force >= 5)
visible_message("\The [src] lens shatters!")
new brokentype(get_turf(src))
if(linkedmonitor)
linkedmonitor.unpair(src)
linkedmonitor = null
spawn(0)
qdel(src)
..()
/obj/item/device/camerabug/bullet_act()
visible_message("The [src] lens shatters!")
new brokentype(get_turf(src))
if(linkedmonitor)
linkedmonitor.unpair(src)
linkedmonitor = null
spawn(0)
qdel(src)
/obj/item/device/camerabug/Destroy()
if(linkedmonitor)
linkedmonitor.unpair(src)
linkedmonitor = null
..()
/obj/item/device/bug_monitor
name = "mobile camera pod monitor"
desc = "A portable camera console designed to work with mobile camera pods."
icon = 'icons/obj/device.dmi'
icon_state = "forensic0"
item_state = "electronic"
w_class = ITEMSIZE_SMALL
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1)
var/operating = 0
// var/obj/item/device/radio/bug/radio
var/obj/machinery/camera/bug/selected_camera
var/list/obj/machinery/camera/bug/cameras = new()
/*
/obj/item/device/bug_monitor/New()
radio = new(src)
*/
/obj/item/device/bug_monitor/attack_self(mob/user)
if(operating)
return
// radio.attack_self(user)
view_cameras(user)
/obj/item/device/bug_monitor/attackby(obj/item/W as obj, mob/living/user as mob)
if(istype(W, /obj/item/device/camerabug))
W.attackby(src, user)
else
return ..()
/obj/item/device/bug_monitor/proc/unpair(var/obj/item/device/camerabug/SB)
if(SB.camera in cameras)
cameras -= SB.camera
/obj/item/device/bug_monitor/proc/pair(var/obj/item/device/camerabug/SB)
cameras += SB.camera
/obj/item/device/bug_monitor/proc/view_cameras(mob/user)
if(!can_use_cam(user))
return
selected_camera = cameras[1]
user.reset_view(selected_camera)
view_camera(user)
operating = 1
while(selected_camera && Adjacent(user))
selected_camera = tgui_input_list(usr, "Select camera to view.", "Camera Choice", cameras)
selected_camera = null
operating = 0
/obj/item/device/bug_monitor/proc/view_camera(mob/user)
spawn(0)
while(selected_camera && Adjacent(user))
var/turf/T = get_turf(selected_camera)
if(!T || !is_on_same_plane_or_station(T.z, user.z) || !selected_camera.can_use())
user.unset_machine()
user.reset_view(null)
to_chat(user, "<span class='notice'>Link to [selected_camera] has been lost.</span>")
src.unpair(selected_camera.loc)
sleep(90)
else
user.set_machine(selected_camera)
user.reset_view(selected_camera)
sleep(10)
user.unset_machine()
user.reset_view(null)
/obj/item/device/bug_monitor/proc/can_use_cam(mob/user)
if(operating)
return
if(!cameras.len)
to_chat(user, "<span class='warning'>No paired cameras detected!</span>")
to_chat(user, "<span class='warning'>Bring a camera in contact with this device to pair the camera.</span>")
return
return 1
/obj/item/device/bug_monitor/spy
name = "\improper PDA"
desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge."
icon = 'icons/obj/pda.dmi'
icon_state = "pda"
item_state = "electronic"
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1, TECH_ILLEGAL = 3)
/obj/item/device/bug_monitor/spy/examine(mob/user)
. = ..()
if(Adjacent(user))
. += "The time '12:00' is blinking in the corner of the screen and \the [src] looks very cheaply made."
/obj/machinery/camera/bug/check_eye(var/mob/user as mob)
return 0
/obj/machinery/camera/bug
network = list(NETWORK_SECURITY)
/obj/machinery/camera/bug/New()
..()
name = "Camera #[rand(1000,9999)]"
c_tag = name
/obj/machinery/camera/bug/spy
// These cheap toys are accessible from the mercenary camera console as well - only the antag ones though!
network = list(NETWORK_MERCENARY)
/obj/machinery/camera/bug/spy/New()
..()
name = "DV-136ZB #[rand(1000,9999)]"
c_tag = name
/* //These were originally supposed to have radios in them. Doesn't work.
/obj/item/device/radio/bug
listening = 0 //turn it on first
frequency = 1359 //sec comms
broadcasting = 0
canhear_range = 1
name = "camera bug device"
icon_state = "syn_cypherkey"
/obj/item/device/radio/bug/spy
listening = 0
frequency = 1473
broadcasting = 0
canhear_range = 1
name = "spy device"
icon_state = "syn_cypherkey"
/obj/item/device/camerabug
name = "mobile camera pod"
desc = "A camera pod used by tactical operators. Must be linked to a camera scanner unit."
icon = 'icons/obj/grenade.dmi'
icon_state = "camgrenade"
item_state = "empgrenade"
w_class = ITEMSIZE_SMALL
force = 0
throwforce = 5.0
throw_range = 15
throw_speed = 3
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1)
var/obj/item/device/bug_monitor/linkedmonitor
var/brokentype = /obj/item/brokenbug
// var/obj/item/device/radio/bug/radio
var/obj/machinery/camera/bug/camera
var/camtype = /obj/machinery/camera/bug
/obj/item/device/camerabug/New()
..()
// radio = new(src)
camera = new camtype(src)
/obj/item/device/camerabug/attack_self(mob/user)
if(user.a_intent == I_HURT)
to_chat(user, "<span class='notice'>You crush the [src] under your foot, breaking it.</span>")
visible_message("[user.name] crushes the [src] under their foot, breaking it!</span>")
new brokentype(get_turf(src))
spawn(0)
qdel(src)
/* else
user.set_machine(radio)
radio.interact(user)
*/
/obj/item/device/camerabug/verb/reset()
set name = "Reset camera bug"
set category = "Object"
if(linkedmonitor)
linkedmonitor.unpair(src)
linkedmonitor = null
qdel(camera)
camera = new camtype(src)
to_chat(usr, "<span class='notice'>You turn the [src] off and on again, delinking it from any monitors.")
/obj/item/brokenbug
name = "broken mobile camera pod"
desc = "A camera pod formerly used by tactical operators. The lens is smashed, and the circuits are damaged beyond repair."
icon = 'icons/obj/grenade.dmi'
icon_state = "camgrenadebroken"
item_state = "empgrenade"
force = 5.0
w_class = ITEMSIZE_SMALL
throwforce = 5.0
throw_range = 15
throw_speed = 3
origin_tech = list(TECH_ENGINEERING = 1)
/obj/item/brokenbug/spy
name = "broken bug"
desc = "" //Even when it's broken it's inconspicuous
icon = 'icons/obj/weapons.dmi'
icon_state = "eshield"
item_state = "nothing"
layer = TURF_LAYER+0.2
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
origin_tech = list(TECH_ENGINEERING = 1, TECH_ILLEGAL = 3) //crush it and you lose the data
force = 0
throwforce = 5.0
throw_range = 15
throw_speed = 3
/obj/item/device/camerabug/spy
name = "bug"
desc = "" //Nothing to see here
icon = 'icons/obj/weapons.dmi'
icon_state = "eshield"
item_state = "nothing"
layer = TURF_LAYER+0.2
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1, TECH_ILLEGAL = 3)
camtype = /obj/machinery/camera/bug/spy
/obj/item/device/camerabug/examine(mob/user)
. = ..()
if(get_dist(user, src) == 0)
. += "It has a tiny camera inside. Needs to be both configured and brought in contact with monitor device to be fully functional."
/obj/item/device/camerabug/update_icon()
..()
if(anchored) // Standard versions are relatively obvious if not hidden in a container. Anchoring them is advised, to disguise them.
alpha = 50
else
alpha = 255
/obj/item/device/camerabug/attackby(obj/item/W as obj, mob/living/user as mob)
if(istype(W, /obj/item/device/bug_monitor))
var/obj/item/device/bug_monitor/SM = W
if(!linkedmonitor)
to_chat(user, "<span class='notice'>\The [src] has been paired with \the [SM].</span>")
SM.pair(src)
linkedmonitor = SM
else if (linkedmonitor == SM)
to_chat(user, "<span class='notice'>\The [src] has been unpaired from \the [SM].</span>")
linkedmonitor.unpair(src)
linkedmonitor = null
else
to_chat(user, "Error: The device is linked to another monitor.")
else if(W.has_tool_quality(TOOL_WRENCH) && user.a_intent != I_HURT)
if(isturf(loc))
anchored = !anchored
to_chat(user, "<span class='notice'>You [anchored ? "" : "un"]secure \the [src].</span>")
update_icon()
return
else
if(W.force >= 5)
visible_message("\The [src] lens shatters!")
new brokentype(get_turf(src))
if(linkedmonitor)
linkedmonitor.unpair(src)
linkedmonitor = null
spawn(0)
qdel(src)
..()
/obj/item/device/camerabug/bullet_act()
visible_message("The [src] lens shatters!")
new brokentype(get_turf(src))
if(linkedmonitor)
linkedmonitor.unpair(src)
linkedmonitor = null
spawn(0)
qdel(src)
/obj/item/device/camerabug/Destroy()
if(linkedmonitor)
linkedmonitor.unpair(src)
linkedmonitor = null
..()
/obj/item/device/bug_monitor
name = "mobile camera pod monitor"
desc = "A portable camera console designed to work with mobile camera pods."
icon = 'icons/obj/device.dmi'
icon_state = "forensic0"
item_state = "electronic"
w_class = ITEMSIZE_SMALL
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1)
var/operating = 0
// var/obj/item/device/radio/bug/radio
var/obj/machinery/camera/bug/selected_camera
var/list/obj/machinery/camera/bug/cameras = new()
/*
/obj/item/device/bug_monitor/New()
radio = new(src)
*/
/obj/item/device/bug_monitor/attack_self(mob/user)
if(operating)
return
// radio.attack_self(user)
view_cameras(user)
/obj/item/device/bug_monitor/attackby(obj/item/W as obj, mob/living/user as mob)
if(istype(W, /obj/item/device/camerabug))
W.attackby(src, user)
else
return ..()
/obj/item/device/bug_monitor/proc/unpair(var/obj/item/device/camerabug/SB)
if(SB.camera in cameras)
cameras -= SB.camera
/obj/item/device/bug_monitor/proc/pair(var/obj/item/device/camerabug/SB)
cameras += SB.camera
/obj/item/device/bug_monitor/proc/view_cameras(mob/user)
if(!can_use_cam(user))
return
selected_camera = cameras[1]
user.reset_view(selected_camera)
view_camera(user)
operating = 1
while(selected_camera && Adjacent(user))
selected_camera = tgui_input_list(usr, "Select camera to view.", "Camera Choice", cameras)
selected_camera = null
operating = 0
/obj/item/device/bug_monitor/proc/view_camera(mob/user)
spawn(0)
while(selected_camera && Adjacent(user))
var/turf/T = get_turf(selected_camera)
if(!T || !is_on_same_plane_or_station(T.z, user.z) || !selected_camera.can_use())
user.unset_machine()
user.reset_view(null)
to_chat(user, "<span class='notice'>Link to [selected_camera] has been lost.</span>")
src.unpair(selected_camera.loc)
sleep(90)
else
user.set_machine(selected_camera)
user.reset_view(selected_camera)
sleep(10)
user.unset_machine()
user.reset_view(null)
/obj/item/device/bug_monitor/proc/can_use_cam(mob/user)
if(operating)
return
if(!cameras.len)
to_chat(user, "<span class='warning'>No paired cameras detected!</span>")
to_chat(user, "<span class='warning'>Bring a camera in contact with this device to pair the camera.</span>")
return
return 1
/obj/item/device/bug_monitor/spy
name = "\improper PDA"
desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by a preprogrammed ROM cartridge."
icon = 'icons/obj/pda.dmi'
icon_state = "pda"
item_state = "electronic"
origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 1, TECH_ILLEGAL = 3)
/obj/item/device/bug_monitor/spy/examine(mob/user)
. = ..()
if(Adjacent(user))
. += "The time '12:00' is blinking in the corner of the screen and \the [src] looks very cheaply made."
/obj/machinery/camera/bug/check_eye(var/mob/user as mob)
return 0
/obj/machinery/camera/bug
network = list(NETWORK_SECURITY)
/obj/machinery/camera/bug/New()
..()
name = "Camera #[rand(1000,9999)]"
c_tag = name
/obj/machinery/camera/bug/spy
// These cheap toys are accessible from the mercenary camera console as well - only the antag ones though!
network = list(NETWORK_MERCENARY)
/obj/machinery/camera/bug/spy/New()
..()
name = "DV-136ZB #[rand(1000,9999)]"
c_tag = name
/* //These were originally supposed to have radios in them. Doesn't work.
/obj/item/device/radio/bug
listening = 0 //turn it on first
frequency = 1359 //sec comms
broadcasting = 0
canhear_range = 1
name = "camera bug device"
icon_state = "syn_cypherkey"
/obj/item/device/radio/bug/spy
listening = 0
frequency = 1473
broadcasting = 0
canhear_range = 1
name = "spy device"
icon_state = "syn_cypherkey"
*/
+149 -149
View File
@@ -1,150 +1,150 @@
#define OVERLAY_CACHE_LEN 50
/obj/item/device/t_scanner
name = "\improper T-ray scanner"
desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
icon_state = "t-ray0"
item_state = "t-ray"
slot_flags = SLOT_BELT
w_class = ITEMSIZE_SMALL
matter = list(MAT_STEEL = 150)
origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1)
var/scan_range = 1
var/on = 0
var/list/active_scanned = list() //assoc list of objects being scanned, mapped to their overlay
var/client/user_client //since making sure overlays are properly added and removed is pretty important, so we track the current user explicitly
var/flicker = 0
var/global/list/overlay_cache = list() //cache recent overlays
/obj/item/device/t_scanner/update_icon()
icon_state = "t-ray[on]"
/obj/item/device/t_scanner/attack_self(mob/user)
set_active(!on)
/obj/item/device/t_scanner/proc/set_active(var/active)
on = active
if(on)
START_PROCESSING(SSobj, src)
flicker = 0
else
STOP_PROCESSING(SSobj, src)
set_user_client(null)
update_icon()
//If reset is set, then assume the client has none of our overlays, otherwise we only send new overlays.
/obj/item/device/t_scanner/process()
if(!on) return
//handle clients changing
var/client/loc_client = null
if(ismob(src.loc))
var/mob/M = src.loc
loc_client = M.client
set_user_client(loc_client)
//no sense processing if no-one is going to see it.
if(!user_client) return
//get all objects in scan range
var/list/scanned = get_scanned_objects(scan_range)
var/list/update_add = scanned - active_scanned
var/list/update_remove = active_scanned - scanned
//Add new overlays
for(var/obj/O in update_add)
var/image/overlay = get_overlay(O)
active_scanned[O] = overlay
user_client.images += overlay
//Remove stale overlays
for(var/obj/O in update_remove)
user_client.images -= active_scanned[O]
active_scanned -= O
//Flicker effect
for(var/obj/O in active_scanned)
var/image/overlay = active_scanned[O]
if(flicker)
overlay.alpha = 0
else
overlay.alpha = 128
flicker = !flicker
//creates a new overlay for a scanned object
/obj/item/device/t_scanner/proc/get_overlay(obj/scanned)
//Use a cache so we don't create a whole bunch of new images just because someone's walking back and forth in a room.
//Also means that images are reused if multiple people are using t-rays to look at the same objects.
if(scanned in overlay_cache)
. = overlay_cache[scanned]
else
var/image/I = image(loc = scanned, icon = scanned.icon, icon_state = scanned.icon_state, layer = HUD_LAYER)
//Pipes are special
if(istype(scanned, /obj/machinery/atmospherics/pipe))
var/obj/machinery/atmospherics/pipe/P = scanned
I.color = P.pipe_color
I.add_overlay(P.overlays)
I.alpha = 128
I.mouse_opacity = 0
. = I
// Add it to cache, cutting old entries if the list is too long
overlay_cache[scanned] = .
if(overlay_cache.len > OVERLAY_CACHE_LEN)
overlay_cache.Cut(1, overlay_cache.len-OVERLAY_CACHE_LEN-1)
/obj/item/device/t_scanner/proc/get_scanned_objects(var/scan_dist)
. = list()
var/turf/center = get_turf(src.loc)
if(!center) return
for(var/turf/T in range(scan_range, center))
if(!!T.is_plating())
continue
for(var/obj/O in T.contents)
if(O.level != 1)
continue
if(!O.invisibility)
continue //if it's already visible don't need an overlay for it
. += O
/obj/item/device/t_scanner/proc/set_user_client(var/client/new_client)
if(new_client == user_client)
return
if(user_client)
for(var/scanned in active_scanned)
user_client.images -= active_scanned[scanned]
if(new_client)
for(var/scanned in active_scanned)
new_client.images += active_scanned[scanned]
else
active_scanned.Cut()
user_client = new_client
/obj/item/device/t_scanner/dropped(mob/user)
set_user_client(null)
/obj/item/device/t_scanner/upgraded
name = "Upgraded T-ray Scanner"
desc = "An upgraded version of the terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
matter = list(MAT_STEEL = 500, PHORON = 150)
origin_tech = list(TECH_MAGNET = 4, TECH_ENGINEERING = 5)
scan_range = 3
/obj/item/device/t_scanner/advanced
name = "Advanced T-ray Scanner"
desc = "An advanced version of the terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
matter = list(MAT_STEEL = 1500, PHORON = 200, SILVER = 250)
origin_tech = list(TECH_MAGNET = 7, TECH_ENGINEERING = 7, TECH_MATERIAL = 6)
scan_range = 7
#define OVERLAY_CACHE_LEN 50
/obj/item/device/t_scanner
name = "\improper T-ray scanner"
desc = "A terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
icon_state = "t-ray0"
item_state = "t-ray"
slot_flags = SLOT_BELT
w_class = ITEMSIZE_SMALL
matter = list(MAT_STEEL = 150)
origin_tech = list(TECH_MAGNET = 1, TECH_ENGINEERING = 1)
var/scan_range = 1
var/on = 0
var/list/active_scanned = list() //assoc list of objects being scanned, mapped to their overlay
var/client/user_client //since making sure overlays are properly added and removed is pretty important, so we track the current user explicitly
var/flicker = 0
var/global/list/overlay_cache = list() //cache recent overlays
/obj/item/device/t_scanner/update_icon()
icon_state = "t-ray[on]"
/obj/item/device/t_scanner/attack_self(mob/user)
set_active(!on)
/obj/item/device/t_scanner/proc/set_active(var/active)
on = active
if(on)
START_PROCESSING(SSobj, src)
flicker = 0
else
STOP_PROCESSING(SSobj, src)
set_user_client(null)
update_icon()
//If reset is set, then assume the client has none of our overlays, otherwise we only send new overlays.
/obj/item/device/t_scanner/process()
if(!on) return
//handle clients changing
var/client/loc_client = null
if(ismob(src.loc))
var/mob/M = src.loc
loc_client = M.client
set_user_client(loc_client)
//no sense processing if no-one is going to see it.
if(!user_client) return
//get all objects in scan range
var/list/scanned = get_scanned_objects(scan_range)
var/list/update_add = scanned - active_scanned
var/list/update_remove = active_scanned - scanned
//Add new overlays
for(var/obj/O in update_add)
var/image/overlay = get_overlay(O)
active_scanned[O] = overlay
user_client.images += overlay
//Remove stale overlays
for(var/obj/O in update_remove)
user_client.images -= active_scanned[O]
active_scanned -= O
//Flicker effect
for(var/obj/O in active_scanned)
var/image/overlay = active_scanned[O]
if(flicker)
overlay.alpha = 0
else
overlay.alpha = 128
flicker = !flicker
//creates a new overlay for a scanned object
/obj/item/device/t_scanner/proc/get_overlay(obj/scanned)
//Use a cache so we don't create a whole bunch of new images just because someone's walking back and forth in a room.
//Also means that images are reused if multiple people are using t-rays to look at the same objects.
if(scanned in overlay_cache)
. = overlay_cache[scanned]
else
var/image/I = image(loc = scanned, icon = scanned.icon, icon_state = scanned.icon_state, layer = HUD_LAYER)
//Pipes are special
if(istype(scanned, /obj/machinery/atmospherics/pipe))
var/obj/machinery/atmospherics/pipe/P = scanned
I.color = P.pipe_color
I.add_overlay(P.overlays)
I.alpha = 128
I.mouse_opacity = 0
. = I
// Add it to cache, cutting old entries if the list is too long
overlay_cache[scanned] = .
if(overlay_cache.len > OVERLAY_CACHE_LEN)
overlay_cache.Cut(1, overlay_cache.len-OVERLAY_CACHE_LEN-1)
/obj/item/device/t_scanner/proc/get_scanned_objects(var/scan_dist)
. = list()
var/turf/center = get_turf(src.loc)
if(!center) return
for(var/turf/T in range(scan_range, center))
if(!!T.is_plating())
continue
for(var/obj/O in T.contents)
if(O.level != 1)
continue
if(!O.invisibility)
continue //if it's already visible don't need an overlay for it
. += O
/obj/item/device/t_scanner/proc/set_user_client(var/client/new_client)
if(new_client == user_client)
return
if(user_client)
for(var/scanned in active_scanned)
user_client.images -= active_scanned[scanned]
if(new_client)
for(var/scanned in active_scanned)
new_client.images += active_scanned[scanned]
else
active_scanned.Cut()
user_client = new_client
/obj/item/device/t_scanner/dropped(mob/user)
set_user_client(null)
/obj/item/device/t_scanner/upgraded
name = "Upgraded T-ray Scanner"
desc = "An upgraded version of the terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
matter = list(MAT_STEEL = 500, PHORON = 150)
origin_tech = list(TECH_MAGNET = 4, TECH_ENGINEERING = 5)
scan_range = 3
/obj/item/device/t_scanner/advanced
name = "Advanced T-ray Scanner"
desc = "An advanced version of the terahertz-ray emitter and scanner used to detect underfloor objects such as cables and pipes."
matter = list(MAT_STEEL = 1500, PHORON = 200, SILVER = 250)
origin_tech = list(TECH_MAGNET = 7, TECH_ENGINEERING = 7, TECH_MATERIAL = 6)
scan_range = 7
#undef OVERLAY_CACHE_LEN
+436 -436
View File
@@ -1,436 +1,436 @@
/obj/item/device/taperecorder
name = "universal recorder"
desc = "A device that can record to cassette tapes, and play them. It automatically translates the content in playback."
icon_state = "taperecorder_empty"
item_state = "analyzer"
w_class = ITEMSIZE_SMALL
matter = list(MAT_STEEL = 60,MAT_GLASS = 30)
var/emagged = 0.0
var/recording = 0.0
var/playing = 0.0
var/playsleepseconds = 0.0
var/obj/item/device/tape/mytape = /obj/item/device/tape/random
var/canprint = 1
slot_flags = SLOT_BELT
throwforce = 2
throw_speed = 4
throw_range = 20
/obj/item/device/taperecorder/New()
..()
if(ispath(mytape))
mytape = new mytape(src)
update_icon()
listening_objects += src
/obj/item/device/taperecorder/empty
mytape = null
/obj/item/device/taperecorder/Destroy()
listening_objects -= src
if(mytape)
qdel(mytape)
mytape = null
return ..()
/obj/item/device/taperecorder/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/device/tape))
if(mytape)
to_chat(user, "<span class='notice'>There's already a tape inside.</span>")
return
if(!user.unEquip(I))
return
I.forceMove(src)
mytape = I
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
update_icon()
return
..()
/obj/item/device/taperecorder/fire_act()
if(mytape)
mytape.ruin() //Fires destroy the tape
return ..()
/obj/item/device/taperecorder/attack_hand(mob/user)
if(user.get_inactive_hand() == src)
if(mytape)
eject()
return
..()
/obj/item/device/taperecorder/verb/eject()
set name = "Eject Tape"
set category = "Object"
if(usr.incapacitated())
return
if(!mytape)
to_chat(usr, "<span class='notice'>There's no tape in \the [src].</span>")
return
if(emagged)
to_chat(usr, "<span class='notice'>The tape seems to be stuck inside.</span>")
return
if(playing || recording)
stop()
to_chat(usr, "<span class='notice'>You remove [mytape] from [src].</span>")
usr.put_in_hands(mytape)
mytape = null
update_icon()
/obj/item/device/taperecorder/hear_talk(mob/M, list/message_pieces, verb)
var/msg = multilingual_to_message(message_pieces, requires_machine_understands = TRUE, with_capitalization = TRUE)
var/voice = M.GetVoice() //Defined on living, returns name for normal mobs/
if(mytape && recording)
mytape.record_speech("[voice] [verb], \"[msg]\"")
/obj/item/device/taperecorder/see_emote(mob/M as mob, text, var/emote_type)
if(emote_type != 2) //only hearable emotes
return
if(mytape && recording)
mytape.record_speech("[strip_html_properly(text)]")
/obj/item/device/taperecorder/show_message(msg, type, alt, alt_type)
var/recordedtext
if (msg && type == 2) //must be hearable
recordedtext = msg
else if (alt && alt_type == 2)
recordedtext = alt
else
return
if(mytape && recording)
mytape.record_noise("[strip_html_properly(recordedtext)]")
/obj/item/device/taperecorder/emag_act(var/remaining_charges, var/mob/user)
if(emagged == 0)
emagged = 1
recording = 0
to_chat(user, "<span class='warning'>PZZTTPFFFT</span>")
update_icon()
return 1
else
to_chat(user, "<span class='warning'>It is already emagged!</span>")
/obj/item/device/taperecorder/proc/explode()
var/turf/T = get_turf(loc)
if(ismob(loc))
var/mob/M = loc
to_chat(M, "<span class='danger'>\The [src] explodes!</span>")
if(T)
T.hotspot_expose(700,125)
explosion(T, -1, -1, 0, 4)
qdel(src)
return
/obj/item/device/taperecorder/verb/record()
set name = "Start Recording"
set category = "Object"
if(usr.incapacitated())
return
if(!mytape)
to_chat(usr, "<span class='notice'>There's no tape!</span>")
return
if(mytape.ruined)
to_chat(usr, "<span class='warning'>The tape recorder makes a scratchy noise.</span>")
return
if(recording)
to_chat(usr, "<span class='notice'>You're already recording!</span>")
return
if(playing)
to_chat(usr, "<span class='notice'>You can't record when playing!</span>")
return
if(emagged)
to_chat(usr, "<span class='warning'>The tape recorder makes a scratchy noise.</span>")
return
if(mytape.used_capacity < mytape.max_capacity)
to_chat(usr, "<span class='notice'>Recording started.</span>")
recording = 1
update_icon()
mytape.record_speech("Recording started.")
//count seconds until full, or recording is stopped
while(mytape && recording && mytape.used_capacity < mytape.max_capacity)
sleep(10)
mytape.used_capacity++
if(mytape.used_capacity >= mytape.max_capacity)
if(ismob(loc))
var/mob/M = loc
to_chat(M, "<span class='notice'>The tape is full.</span>")
stop_recording()
update_icon()
return
else
to_chat(usr, "<span class='notice'>The tape is full.</span>")
/obj/item/device/taperecorder/proc/stop_recording()
//Sanity checks skipped, should not be called unless actually recording
recording = 0
update_icon()
mytape.record_speech("Recording stopped.")
if(ismob(loc))
var/mob/M = loc
to_chat(M, "<span class='notice'>Recording stopped.</span>")
/obj/item/device/taperecorder/verb/stop()
set name = "Stop"
set category = "Object"
if(usr.incapacitated())
return
if(recording)
stop_recording()
return
else if(playing)
playing = 0
update_icon()
to_chat(usr, "<span class='notice'>Playback stopped.</span>")
return
else
to_chat(usr, "<span class='notice'>Stop what?</span>")
/obj/item/device/taperecorder/verb/wipe_tape()
set name = "Wipe Tape"
set category = "Object"
if(usr.incapacitated())
return
if(emagged)
to_chat(usr, "<span class='warning'>The tape recorder makes a scratchy noise.</span>")
return
if(mytape.ruined)
to_chat(usr, "<span class='warning'>The tape recorder makes a scratchy noise.</span>")
return
if(recording || playing)
to_chat(usr, "<span class='notice'>You can't wipe the tape while playing or recording!</span>")
return
else
if(mytape.storedinfo) mytape.storedinfo.Cut()
if(mytape.timestamp) mytape.timestamp.Cut()
mytape.used_capacity = 0
to_chat(usr, "<span class='notice'>You wipe the tape.</span>")
return
/obj/item/device/taperecorder/verb/playback_memory()
set name = "Playback Tape"
set category = "Object"
if(usr.incapacitated())
return
if(!mytape)
to_chat(usr, "<span class='notice'>There's no tape!</span>")
return
if(mytape.ruined)
to_chat(usr, "<span class='warning'>The tape recorder makes a scratchy noise.</span>")
return
if(recording)
to_chat(usr, "<span class='notice'>You can't playback when recording!</span>")
return
if(playing)
to_chat(usr, "<span class='notice'>You're already playing!</span>")
return
playing = 1
update_icon()
to_chat(usr, "<span class='notice'>Playing started.</span>")
for(var/i=1 , i < mytape.max_capacity , i++)
if(!mytape || !playing)
break
if(mytape.storedinfo.len < i)
break
var/turf/T = get_turf(src)
var/playedmessage = mytape.storedinfo[i]
if (findtextEx(playedmessage,"*",1,2)) //remove marker for action sounds
playedmessage = copytext(playedmessage,2)
T.audible_message(span_maroon("<B>Tape Recorder</B>: [playedmessage]"), runemessage = playedmessage)
if(mytape.storedinfo.len < i+1)
playsleepseconds = 1
sleep(10)
T = get_turf(src)
T.audible_message(span_maroon("<B>Tape Recorder</B>: End of recording."), runemessage = "click")
break
else
playsleepseconds = mytape.timestamp[i+1] - mytape.timestamp[i]
if(playsleepseconds > 14)
sleep(10)
T = get_turf(src)
T.audible_message(span_maroon("<B>Tape Recorder</B>: Skipping [playsleepseconds] seconds of silence"), runemessage = "tape winding")
playsleepseconds = 1
sleep(10 * playsleepseconds)
playing = 0
update_icon()
if(emagged)
var/turf/T = get_turf(src)
T.audible_message(span_maroon("<B>Tape Recorder</B>: This tape recorder will self-destruct in... Five."), runemessage = "beep beep")
sleep(10)
T = get_turf(src)
T.audible_message(span_maroon("<B>Tape Recorder</B>: Four."))
sleep(10)
T = get_turf(src)
T.audible_message(span_maroon("<B>Tape Recorder</B>: Three."))
sleep(10)
T = get_turf(src)
T.audible_message(span_maroon("<B>Tape Recorder</B>: Two."))
sleep(10)
T = get_turf(src)
T.audible_message(span_maroon("<B>Tape Recorder</B>: One."))
sleep(10)
explode()
/obj/item/device/taperecorder/verb/print_transcript()
set name = "Print Transcript"
set category = "Object"
if(usr.incapacitated())
return
if(!mytape)
to_chat(usr, "<span class='notice'>There's no tape!</span>")
return
if(mytape.ruined)
to_chat(usr, "<span class='warning'>The tape recorder makes a scratchy noise.</span>")
return
if(emagged)
to_chat(usr, "<span class='warning'>The tape recorder makes a scratchy noise.</span>")
return
if(!canprint)
to_chat(usr, "<span class='notice'>The recorder can't print that fast!</span>")
return
if(recording || playing)
to_chat(usr, "<span class='notice'>You can't print the transcript while playing or recording!</span>")
return
to_chat(usr, "<span class='notice'>Transcript printed.</span>")
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(get_turf(src))
var/t1 = "<B>Transcript:</B><BR><BR>"
for(var/i=1,mytape.storedinfo.len >= i,i++)
var/printedmessage = mytape.storedinfo[i]
if (findtextEx(printedmessage,"*",1,2)) //replace action sounds
printedmessage = "\[[time2text(mytape.timestamp[i]*10,"mm:ss")]\] (Unrecognized sound)"
t1 += "[printedmessage]<BR>"
P.info = t1
P.name = "Transcript"
canprint = 0
sleep(300)
canprint = 1
/obj/item/device/taperecorder/attack_self(mob/user)
if(recording || playing)
stop()
else
record()
/obj/item/device/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/device/tape
name = "tape"
desc = "A magnetic tape that can hold up to ten minutes of content."
icon_state = "tape_white"
item_state = "analyzer"
w_class = ITEMSIZE_TINY
matter = list(MAT_STEEL=20, MAT_GLASS=5)
force = 1
throwforce = 0
var/max_capacity = 1800
var/used_capacity = 0
var/list/storedinfo = new/list()
var/list/timestamp = new/list()
var/ruined = 0
/obj/item/device/tape/update_icon()
cut_overlays()
if(ruined)
add_overlay("ribbonoverlay")
/obj/item/device/tape/fire_act()
ruin()
/obj/item/device/tape/attack_self(mob/user)
if(!ruined)
to_chat(user, "<span class='notice'>You pull out all the tape!</span>")
ruin()
/obj/item/device/tape/proc/ruin()
ruined = 1
update_icon()
/obj/item/device/tape/proc/fix()
ruined = 0
update_icon()
/obj/item/device/tape/proc/record_speech(text)
timestamp += used_capacity
storedinfo += "\[[time2text(used_capacity*10,"mm:ss")]\] [text]"
//shows up on the printed transcript as (Unrecognized sound)
/obj/item/device/tape/proc/record_noise(text)
timestamp += used_capacity
storedinfo += "*\[[time2text(used_capacity*10,"mm:ss")]\] [text]"
/obj/item/device/tape/attackby(obj/item/I, mob/user, params)
if(ruined && I.has_tool_quality(TOOL_SCREWDRIVER))
to_chat(user, "<span class='notice'>You start winding the tape back in...</span>")
playsound(src, I.usesound, 50, 1)
if(do_after(user, 120 * I.toolspeed, target = src))
to_chat(user, "<span class='notice'>You wound the tape back in.</span>")
fix()
return
else if(istype(I, /obj/item/weapon/pen))
if(loc == user && !user.incapacitated())
var/new_name = tgui_input_text(user, "What would you like to label the tape?", "Tape labeling")
if(isnull(new_name)) return
new_name = sanitizeSafe(new_name)
if(new_name)
name = "tape - '[new_name]'"
to_chat(user, "<span class='notice'>You label the tape '[new_name]'.</span>")
else
name = "tape"
to_chat(user, "<span class='notice'>You scratch off the label.</span>")
return
..()
//Random colour tapes
/obj/item/device/tape/random/New()
icon_state = "tape_[pick("white", "blue", "red", "yellow", "purple")]"
/obj/item/device/taperecorder
name = "universal recorder"
desc = "A device that can record to cassette tapes, and play them. It automatically translates the content in playback."
icon_state = "taperecorder_empty"
item_state = "analyzer"
w_class = ITEMSIZE_SMALL
matter = list(MAT_STEEL = 60,MAT_GLASS = 30)
var/emagged = 0.0
var/recording = 0.0
var/playing = 0.0
var/playsleepseconds = 0.0
var/obj/item/device/tape/mytape = /obj/item/device/tape/random
var/canprint = 1
slot_flags = SLOT_BELT
throwforce = 2
throw_speed = 4
throw_range = 20
/obj/item/device/taperecorder/New()
..()
if(ispath(mytape))
mytape = new mytape(src)
update_icon()
listening_objects += src
/obj/item/device/taperecorder/empty
mytape = null
/obj/item/device/taperecorder/Destroy()
listening_objects -= src
if(mytape)
qdel(mytape)
mytape = null
return ..()
/obj/item/device/taperecorder/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/device/tape))
if(mytape)
to_chat(user, "<span class='notice'>There's already a tape inside.</span>")
return
if(!user.unEquip(I))
return
I.forceMove(src)
mytape = I
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
update_icon()
return
..()
/obj/item/device/taperecorder/fire_act()
if(mytape)
mytape.ruin() //Fires destroy the tape
return ..()
/obj/item/device/taperecorder/attack_hand(mob/user)
if(user.get_inactive_hand() == src)
if(mytape)
eject()
return
..()
/obj/item/device/taperecorder/verb/eject()
set name = "Eject Tape"
set category = "Object"
if(usr.incapacitated())
return
if(!mytape)
to_chat(usr, "<span class='notice'>There's no tape in \the [src].</span>")
return
if(emagged)
to_chat(usr, "<span class='notice'>The tape seems to be stuck inside.</span>")
return
if(playing || recording)
stop()
to_chat(usr, "<span class='notice'>You remove [mytape] from [src].</span>")
usr.put_in_hands(mytape)
mytape = null
update_icon()
/obj/item/device/taperecorder/hear_talk(mob/M, list/message_pieces, verb)
var/msg = multilingual_to_message(message_pieces, requires_machine_understands = TRUE, with_capitalization = TRUE)
var/voice = M.GetVoice() //Defined on living, returns name for normal mobs/
if(mytape && recording)
mytape.record_speech("[voice] [verb], \"[msg]\"")
/obj/item/device/taperecorder/see_emote(mob/M as mob, text, var/emote_type)
if(emote_type != 2) //only hearable emotes
return
if(mytape && recording)
mytape.record_speech("[strip_html_properly(text)]")
/obj/item/device/taperecorder/show_message(msg, type, alt, alt_type)
var/recordedtext
if (msg && type == 2) //must be hearable
recordedtext = msg
else if (alt && alt_type == 2)
recordedtext = alt
else
return
if(mytape && recording)
mytape.record_noise("[strip_html_properly(recordedtext)]")
/obj/item/device/taperecorder/emag_act(var/remaining_charges, var/mob/user)
if(emagged == 0)
emagged = 1
recording = 0
to_chat(user, "<span class='warning'>PZZTTPFFFT</span>")
update_icon()
return 1
else
to_chat(user, "<span class='warning'>It is already emagged!</span>")
/obj/item/device/taperecorder/proc/explode()
var/turf/T = get_turf(loc)
if(ismob(loc))
var/mob/M = loc
to_chat(M, "<span class='danger'>\The [src] explodes!</span>")
if(T)
T.hotspot_expose(700,125)
explosion(T, -1, -1, 0, 4)
qdel(src)
return
/obj/item/device/taperecorder/verb/record()
set name = "Start Recording"
set category = "Object"
if(usr.incapacitated())
return
if(!mytape)
to_chat(usr, "<span class='notice'>There's no tape!</span>")
return
if(mytape.ruined)
to_chat(usr, "<span class='warning'>The tape recorder makes a scratchy noise.</span>")
return
if(recording)
to_chat(usr, "<span class='notice'>You're already recording!</span>")
return
if(playing)
to_chat(usr, "<span class='notice'>You can't record when playing!</span>")
return
if(emagged)
to_chat(usr, "<span class='warning'>The tape recorder makes a scratchy noise.</span>")
return
if(mytape.used_capacity < mytape.max_capacity)
to_chat(usr, "<span class='notice'>Recording started.</span>")
recording = 1
update_icon()
mytape.record_speech("Recording started.")
//count seconds until full, or recording is stopped
while(mytape && recording && mytape.used_capacity < mytape.max_capacity)
sleep(10)
mytape.used_capacity++
if(mytape.used_capacity >= mytape.max_capacity)
if(ismob(loc))
var/mob/M = loc
to_chat(M, "<span class='notice'>The tape is full.</span>")
stop_recording()
update_icon()
return
else
to_chat(usr, "<span class='notice'>The tape is full.</span>")
/obj/item/device/taperecorder/proc/stop_recording()
//Sanity checks skipped, should not be called unless actually recording
recording = 0
update_icon()
mytape.record_speech("Recording stopped.")
if(ismob(loc))
var/mob/M = loc
to_chat(M, "<span class='notice'>Recording stopped.</span>")
/obj/item/device/taperecorder/verb/stop()
set name = "Stop"
set category = "Object"
if(usr.incapacitated())
return
if(recording)
stop_recording()
return
else if(playing)
playing = 0
update_icon()
to_chat(usr, "<span class='notice'>Playback stopped.</span>")
return
else
to_chat(usr, "<span class='notice'>Stop what?</span>")
/obj/item/device/taperecorder/verb/wipe_tape()
set name = "Wipe Tape"
set category = "Object"
if(usr.incapacitated())
return
if(emagged)
to_chat(usr, "<span class='warning'>The tape recorder makes a scratchy noise.</span>")
return
if(mytape.ruined)
to_chat(usr, "<span class='warning'>The tape recorder makes a scratchy noise.</span>")
return
if(recording || playing)
to_chat(usr, "<span class='notice'>You can't wipe the tape while playing or recording!</span>")
return
else
if(mytape.storedinfo) mytape.storedinfo.Cut()
if(mytape.timestamp) mytape.timestamp.Cut()
mytape.used_capacity = 0
to_chat(usr, "<span class='notice'>You wipe the tape.</span>")
return
/obj/item/device/taperecorder/verb/playback_memory()
set name = "Playback Tape"
set category = "Object"
if(usr.incapacitated())
return
if(!mytape)
to_chat(usr, "<span class='notice'>There's no tape!</span>")
return
if(mytape.ruined)
to_chat(usr, "<span class='warning'>The tape recorder makes a scratchy noise.</span>")
return
if(recording)
to_chat(usr, "<span class='notice'>You can't playback when recording!</span>")
return
if(playing)
to_chat(usr, "<span class='notice'>You're already playing!</span>")
return
playing = 1
update_icon()
to_chat(usr, "<span class='notice'>Playing started.</span>")
for(var/i=1 , i < mytape.max_capacity , i++)
if(!mytape || !playing)
break
if(mytape.storedinfo.len < i)
break
var/turf/T = get_turf(src)
var/playedmessage = mytape.storedinfo[i]
if (findtextEx(playedmessage,"*",1,2)) //remove marker for action sounds
playedmessage = copytext(playedmessage,2)
T.audible_message(span_maroon("<B>Tape Recorder</B>: [playedmessage]"), runemessage = playedmessage)
if(mytape.storedinfo.len < i+1)
playsleepseconds = 1
sleep(10)
T = get_turf(src)
T.audible_message(span_maroon("<B>Tape Recorder</B>: End of recording."), runemessage = "click")
break
else
playsleepseconds = mytape.timestamp[i+1] - mytape.timestamp[i]
if(playsleepseconds > 14)
sleep(10)
T = get_turf(src)
T.audible_message(span_maroon("<B>Tape Recorder</B>: Skipping [playsleepseconds] seconds of silence"), runemessage = "tape winding")
playsleepseconds = 1
sleep(10 * playsleepseconds)
playing = 0
update_icon()
if(emagged)
var/turf/T = get_turf(src)
T.audible_message(span_maroon("<B>Tape Recorder</B>: This tape recorder will self-destruct in... Five."), runemessage = "beep beep")
sleep(10)
T = get_turf(src)
T.audible_message(span_maroon("<B>Tape Recorder</B>: Four."))
sleep(10)
T = get_turf(src)
T.audible_message(span_maroon("<B>Tape Recorder</B>: Three."))
sleep(10)
T = get_turf(src)
T.audible_message(span_maroon("<B>Tape Recorder</B>: Two."))
sleep(10)
T = get_turf(src)
T.audible_message(span_maroon("<B>Tape Recorder</B>: One."))
sleep(10)
explode()
/obj/item/device/taperecorder/verb/print_transcript()
set name = "Print Transcript"
set category = "Object"
if(usr.incapacitated())
return
if(!mytape)
to_chat(usr, "<span class='notice'>There's no tape!</span>")
return
if(mytape.ruined)
to_chat(usr, "<span class='warning'>The tape recorder makes a scratchy noise.</span>")
return
if(emagged)
to_chat(usr, "<span class='warning'>The tape recorder makes a scratchy noise.</span>")
return
if(!canprint)
to_chat(usr, "<span class='notice'>The recorder can't print that fast!</span>")
return
if(recording || playing)
to_chat(usr, "<span class='notice'>You can't print the transcript while playing or recording!</span>")
return
to_chat(usr, "<span class='notice'>Transcript printed.</span>")
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(get_turf(src))
var/t1 = "<B>Transcript:</B><BR><BR>"
for(var/i=1,mytape.storedinfo.len >= i,i++)
var/printedmessage = mytape.storedinfo[i]
if (findtextEx(printedmessage,"*",1,2)) //replace action sounds
printedmessage = "\[[time2text(mytape.timestamp[i]*10,"mm:ss")]\] (Unrecognized sound)"
t1 += "[printedmessage]<BR>"
P.info = t1
P.name = "Transcript"
canprint = 0
sleep(300)
canprint = 1
/obj/item/device/taperecorder/attack_self(mob/user)
if(recording || playing)
stop()
else
record()
/obj/item/device/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/device/tape
name = "tape"
desc = "A magnetic tape that can hold up to ten minutes of content."
icon_state = "tape_white"
item_state = "analyzer"
w_class = ITEMSIZE_TINY
matter = list(MAT_STEEL=20, MAT_GLASS=5)
force = 1
throwforce = 0
var/max_capacity = 1800
var/used_capacity = 0
var/list/storedinfo = new/list()
var/list/timestamp = new/list()
var/ruined = 0
/obj/item/device/tape/update_icon()
cut_overlays()
if(ruined)
add_overlay("ribbonoverlay")
/obj/item/device/tape/fire_act()
ruin()
/obj/item/device/tape/attack_self(mob/user)
if(!ruined)
to_chat(user, "<span class='notice'>You pull out all the tape!</span>")
ruin()
/obj/item/device/tape/proc/ruin()
ruined = 1
update_icon()
/obj/item/device/tape/proc/fix()
ruined = 0
update_icon()
/obj/item/device/tape/proc/record_speech(text)
timestamp += used_capacity
storedinfo += "\[[time2text(used_capacity*10,"mm:ss")]\] [text]"
//shows up on the printed transcript as (Unrecognized sound)
/obj/item/device/tape/proc/record_noise(text)
timestamp += used_capacity
storedinfo += "*\[[time2text(used_capacity*10,"mm:ss")]\] [text]"
/obj/item/device/tape/attackby(obj/item/I, mob/user, params)
if(ruined && I.has_tool_quality(TOOL_SCREWDRIVER))
to_chat(user, "<span class='notice'>You start winding the tape back in...</span>")
playsound(src, I.usesound, 50, 1)
if(do_after(user, 120 * I.toolspeed, target = src))
to_chat(user, "<span class='notice'>You wound the tape back in.</span>")
fix()
return
else if(istype(I, /obj/item/weapon/pen))
if(loc == user && !user.incapacitated())
var/new_name = tgui_input_text(user, "What would you like to label the tape?", "Tape labeling")
if(isnull(new_name)) return
new_name = sanitizeSafe(new_name)
if(new_name)
name = "tape - '[new_name]'"
to_chat(user, "<span class='notice'>You label the tape '[new_name]'.</span>")
else
name = "tape"
to_chat(user, "<span class='notice'>You scratch off the label.</span>")
return
..()
//Random colour tapes
/obj/item/device/tape/random/New()
icon_state = "tape_[pick("white", "blue", "red", "yellow", "purple")]"
+218 -218
View File
@@ -1,218 +1,218 @@
/obj/item/device/transfer_valve
name = "tank transfer valve"
desc = "Regulates the transfer of air between two tanks"
icon = 'icons/obj/assemblies.dmi'
icon_state = "valve_1"
var/obj/item/weapon/tank/tank_one
var/obj/item/weapon/tank/tank_two
var/obj/item/device/assembly/attached_device
var/mob/attacher = null
var/valve_open = 0
var/toggle = 1
/obj/item/device/transfer_valve/attackby(obj/item/item, mob/user)
var/turf/location = get_turf(src) // For admin logs
if(istype(item, /obj/item/weapon/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)
tank_one = item
user.drop_item()
item.forceMove(src)
to_chat(user, "<span class='notice'>You attach the tank to the transfer valve.</span>")
else if(!tank_two)
tank_two = item
user.drop_item()
item.forceMove(src)
to_chat(user, "<span class='notice'>You attach the tank to the transfer valve.</span>")
message_admins("[key_name_admin(user)] attached both tanks to a transfer valve. [ADMIN_JMP(location)]")
log_game("[key_name_admin(user)] attached both tanks to a transfer valve.")
update_icon()
SStgui.update_uis(src) // update all UIs attached to src
//TODO: Have this take an assemblyholder
else if(isassembly(item))
var/obj/item/device/assembly/A = item
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 an device attached to the valve, remove it first.</span>")
return
user.remove_from_mob(item)
attached_device = A
A.forceMove(src)
to_chat(user, "<span class='notice'>You attach the [item] 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).
bombers += "[key_name(user)] attached a [item] to a transfer valve."
message_admins("[key_name_admin(user)] attached a [item] to a transfer valve. [ADMIN_JMP(location)]")
log_game("[key_name_admin(user)] attached a [item] to a transfer valve.")
attacher = user
SStgui.update_uis(src) // update all UIs attached to src
return
/obj/item/device/transfer_valve/HasProximity(turf/T, atom/movable/AM, old_loc)
attached_device?.HasProximity(T, AM, old_loc)
/obj/item/device/transfer_valve/Moved(old_loc, direction, forced)
. = ..()
if(isturf(old_loc))
unsense_proximity(callback = /atom/proc/HasProximity, center = old_loc)
if(isturf(loc))
sense_proximity(callback = /atom/proc/HasProximity)
/obj/item/device/transfer_valve/attack_self(mob/user)
tgui_interact(user)
/obj/item/device/transfer_valve/tgui_state(mob/user)
return GLOB.tgui_inventory_state
/obj/item/device/transfer_valve/tgui_interact(mob/user, datum/tgui/ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "TransferValve", name) // 460, 320
ui.open()
/obj/item/device/transfer_valve/tgui_data(mob/user)
var/list/data = list()
data["tank_one"] = tank_one ? tank_one.name : null
data["tank_two"] = tank_two ? tank_two.name : null
data["attached_device"] = attached_device ? attached_device.name : null
data["valve"] = valve_open
return data
/obj/item/device/transfer_valve/tgui_act(action, params)
if(..())
return
. = TRUE
switch(action)
if("tankone")
remove_tank(tank_one)
if("tanktwo")
remove_tank(tank_two)
if("toggle")
toggle_valve()
if("device")
if(attached_device)
attached_device.attack_self(usr)
if("remove_device")
if(attached_device)
attached_device.forceMove(get_turf(src))
attached_device.holder = null
attached_device = null
update_icon()
else
. = FALSE
if(.)
update_icon()
add_fingerprint(usr)
/obj/item/device/transfer_valve/proc/process_activation(var/obj/item/device/D)
if(toggle)
toggle = FALSE
toggle_valve()
VARSET_IN(src, toggle, TRUE, 5 SECONDS)
/obj/item/device/transfer_valve/update_icon()
cut_overlays()
underlays = null
if(!tank_one && !tank_two && !attached_device)
icon_state = "valve_1"
return
icon_state = "valve"
if(tank_one)
add_overlay("[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)
add_overlay("device")
/obj/item/device/transfer_valve/proc/remove_tank(obj/item/weapon/tank/T)
if(tank_one == T)
split_gases()
tank_one = null
else if(tank_two == T)
split_gases()
tank_two = null
else
return
T.forceMove(get_turf(src))
update_icon()
/obj/item/device/transfer_valve/proc/merge_gases()
if(valve_open)
return
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)
valve_open = 1
/obj/item/device/transfer_valve/proc/split_gases()
if(!valve_open)
return
valve_open = 0
if(QDELETED(tank_one) || QDELETED(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/device/transfer_valve/proc/toggle_valve()
if(!valve_open && (tank_one && tank_two))
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
var/attacher_name = ""
if(!attacher)
attacher_name = "Unknown"
else
attacher_name = "[attacher.name]([attacher.ckey])"
var/log_str = "Bomb valve opened in <A HREF='?_src_=holder;[HrefToken(TRUE)];adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name]</a> "
log_str += "with [attached_device ? attached_device : "no device"] attacher: [attacher_name]"
if(attacher)
log_str += ADMIN_QUE(attacher)
var/mob/mob = get_mob_by_key(src.fingerprintslast)
var/last_touch_info = ""
if(mob)
last_touch_info = ADMIN_QUE(mob)
log_str += " Last touched by: [src.fingerprintslast][last_touch_info]"
bombers += log_str
message_admins(log_str, 0, 1)
log_game(log_str)
merge_gases()
else if(valve_open==1 && (tank_one && tank_two))
split_gases()
src.update_icon()
// this doesn't do anything but the timer etc. expects it to be here
// eventually maybe have it update icon to show state (timer, prox etc.) like old bombs
/obj/item/device/transfer_valve/proc/c_state()
return
/obj/item/device/transfer_valve
name = "tank transfer valve"
desc = "Regulates the transfer of air between two tanks"
icon = 'icons/obj/assemblies.dmi'
icon_state = "valve_1"
var/obj/item/weapon/tank/tank_one
var/obj/item/weapon/tank/tank_two
var/obj/item/device/assembly/attached_device
var/mob/attacher = null
var/valve_open = 0
var/toggle = 1
/obj/item/device/transfer_valve/attackby(obj/item/item, mob/user)
var/turf/location = get_turf(src) // For admin logs
if(istype(item, /obj/item/weapon/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)
tank_one = item
user.drop_item()
item.forceMove(src)
to_chat(user, "<span class='notice'>You attach the tank to the transfer valve.</span>")
else if(!tank_two)
tank_two = item
user.drop_item()
item.forceMove(src)
to_chat(user, "<span class='notice'>You attach the tank to the transfer valve.</span>")
message_admins("[key_name_admin(user)] attached both tanks to a transfer valve. [ADMIN_JMP(location)]")
log_game("[key_name_admin(user)] attached both tanks to a transfer valve.")
update_icon()
SStgui.update_uis(src) // update all UIs attached to src
//TODO: Have this take an assemblyholder
else if(isassembly(item))
var/obj/item/device/assembly/A = item
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 an device attached to the valve, remove it first.</span>")
return
user.remove_from_mob(item)
attached_device = A
A.forceMove(src)
to_chat(user, "<span class='notice'>You attach the [item] 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).
bombers += "[key_name(user)] attached a [item] to a transfer valve."
message_admins("[key_name_admin(user)] attached a [item] to a transfer valve. [ADMIN_JMP(location)]")
log_game("[key_name_admin(user)] attached a [item] to a transfer valve.")
attacher = user
SStgui.update_uis(src) // update all UIs attached to src
return
/obj/item/device/transfer_valve/HasProximity(turf/T, atom/movable/AM, old_loc)
attached_device?.HasProximity(T, AM, old_loc)
/obj/item/device/transfer_valve/Moved(old_loc, direction, forced)
. = ..()
if(isturf(old_loc))
unsense_proximity(callback = /atom/proc/HasProximity, center = old_loc)
if(isturf(loc))
sense_proximity(callback = /atom/proc/HasProximity)
/obj/item/device/transfer_valve/attack_self(mob/user)
tgui_interact(user)
/obj/item/device/transfer_valve/tgui_state(mob/user)
return GLOB.tgui_inventory_state
/obj/item/device/transfer_valve/tgui_interact(mob/user, datum/tgui/ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "TransferValve", name) // 460, 320
ui.open()
/obj/item/device/transfer_valve/tgui_data(mob/user)
var/list/data = list()
data["tank_one"] = tank_one ? tank_one.name : null
data["tank_two"] = tank_two ? tank_two.name : null
data["attached_device"] = attached_device ? attached_device.name : null
data["valve"] = valve_open
return data
/obj/item/device/transfer_valve/tgui_act(action, params)
if(..())
return
. = TRUE
switch(action)
if("tankone")
remove_tank(tank_one)
if("tanktwo")
remove_tank(tank_two)
if("toggle")
toggle_valve()
if("device")
if(attached_device)
attached_device.attack_self(usr)
if("remove_device")
if(attached_device)
attached_device.forceMove(get_turf(src))
attached_device.holder = null
attached_device = null
update_icon()
else
. = FALSE
if(.)
update_icon()
add_fingerprint(usr)
/obj/item/device/transfer_valve/proc/process_activation(var/obj/item/device/D)
if(toggle)
toggle = FALSE
toggle_valve()
VARSET_IN(src, toggle, TRUE, 5 SECONDS)
/obj/item/device/transfer_valve/update_icon()
cut_overlays()
underlays = null
if(!tank_one && !tank_two && !attached_device)
icon_state = "valve_1"
return
icon_state = "valve"
if(tank_one)
add_overlay("[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)
add_overlay("device")
/obj/item/device/transfer_valve/proc/remove_tank(obj/item/weapon/tank/T)
if(tank_one == T)
split_gases()
tank_one = null
else if(tank_two == T)
split_gases()
tank_two = null
else
return
T.forceMove(get_turf(src))
update_icon()
/obj/item/device/transfer_valve/proc/merge_gases()
if(valve_open)
return
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)
valve_open = 1
/obj/item/device/transfer_valve/proc/split_gases()
if(!valve_open)
return
valve_open = 0
if(QDELETED(tank_one) || QDELETED(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/device/transfer_valve/proc/toggle_valve()
if(!valve_open && (tank_one && tank_two))
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
var/attacher_name = ""
if(!attacher)
attacher_name = "Unknown"
else
attacher_name = "[attacher.name]([attacher.ckey])"
var/log_str = "Bomb valve opened in <A HREF='?_src_=holder;[HrefToken(TRUE)];adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name]</a> "
log_str += "with [attached_device ? attached_device : "no device"] attacher: [attacher_name]"
if(attacher)
log_str += ADMIN_QUE(attacher)
var/mob/mob = get_mob_by_key(src.fingerprintslast)
var/last_touch_info = ""
if(mob)
last_touch_info = ADMIN_QUE(mob)
log_str += " Last touched by: [src.fingerprintslast][last_touch_info]"
bombers += log_str
message_admins(log_str, 0, 1)
log_game(log_str)
merge_gases()
else if(valve_open==1 && (tank_one && tank_two))
split_gases()
src.update_icon()
// this doesn't do anything but the timer etc. expects it to be here
// eventually maybe have it update icon to show state (timer, prox etc.) like old bombs
/obj/item/device/transfer_valve/proc/c_state()
return
@@ -1,118 +1,118 @@
var/datum/uplink_random_selection/default_uplink_selection = new/datum/uplink_random_selection/default()
var/datum/uplink_random_selection/all_uplink_selection = new/datum/uplink_random_selection/all()
/datum/uplink_random_item
var/uplink_item // The uplink item
var/keep_probability // The probability we'll decide to keep this item if selected
var/reselect_probability // Probability that we'll decide to keep this item if previously selected.
// Is done together with the keep_probability check. Being selected more than once does not affect this probability.
/datum/uplink_random_item/New(var/uplink_item, var/keep_probability = 100, var/reselect_propbability = 33)
..()
src.uplink_item = uplink_item
src.keep_probability = keep_probability
src.reselect_probability = reselect_probability
/datum/uplink_random_selection
var/list/datum/uplink_random_item/items
var/list/datum/uplink_random_item/all_items
/datum/uplink_random_selection/New()
..()
items = list()
all_items = list()
/datum/uplink_random_selection/proc/get_random_item(var/telecrystals, obj/item/device/uplink/U, var/list/bought_items, var/items_override = 0)
var/const/attempts = 50
for(var/i = 0; i < attempts; i++)
var/datum/uplink_random_item/RI
if(items_override)
RI = pick(all_items)
else
RI = pick(items)
if(!prob(RI.keep_probability))
continue
var/datum/uplink_item/I = uplink.items_assoc[RI.uplink_item]
if(I.cost(U) > telecrystals)
continue
if(bought_items && (I in bought_items) && !prob(RI.reselect_probability))
continue
if(U && !I.can_buy(U, telecrystals))
continue
return I
/datum/uplink_random_selection/all/New()
..()
for(var/datum/uplink_item/item in uplink.items)
if(item.blacklisted)
continue
else
all_items += new/datum/uplink_random_item(item.type)
/datum/uplink_random_selection/default/New()
..()
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/silenced_45)
items += new/datum/uplink_random_item(/datum/uplink_item/item/ammo/mc9mm)
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/revolver)
items += new/datum/uplink_random_item(/datum/uplink_item/item/ammo/a357)
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/heavysnipermerc, 15, 0)
items += new/datum/uplink_random_item(/datum/uplink_item/item/ammo/sniperammo, 15, 0)
items += new/datum/uplink_random_item(/datum/uplink_item/item/grenades/emp, 50)
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/crossbow, 33)
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/energy_sword, 75)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/soap, 5, 100)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/concealed_cane, 50, 10)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/detomatix, 20, 10)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/parapen)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/cigarette_kit)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/id)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/spy)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/chameleon_kit)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/chameleon_projector)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/voice)
items += new/datum/uplink_random_item(/datum/uplink_item/item/armor/heavy_vest)
items += new/datum/uplink_random_item(/datum/uplink_item/item/armor/combat)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/toolbox, reselect_propbability = 10)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/plastique)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/encryptionkey_radio)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/encryptionkey_binary)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/emag, 100, 50)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/clerical)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/space_suit, 50, 10)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/thermal)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/powersink, 10, 10)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/ai_module, 25, 0)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/teleporter, 10, 0)
items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_freedom)
items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_compress)
items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_explosive)
items += new/datum/uplink_random_item(/datum/uplink_item/item/medical/sinpockets, reselect_propbability = 20)
items += new/datum/uplink_random_item(/datum/uplink_item/item/medical/surgery, reselect_propbability = 10)
items += new/datum/uplink_random_item(/datum/uplink_item/item/medical/combat, reselect_propbability = 10)
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/thermal, reselect_propbability = 15)
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/energy_net, reselect_propbability = 15)
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/ewar_voice, reselect_propbability = 15)
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/maneuvering_jets, reselect_propbability = 15)
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/egun, reselect_propbability = 15)
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/power_sink, reselect_propbability = 15)
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/laser_canon, reselect_propbability = 5)
#ifdef DEBUG
/proc/debug_uplink_purchage_log()
for(var/antag_type in all_antag_types)
var/datum/antagonist/A = all_antag_types[antag_type]
A.print_player_summary()
/proc/debug_uplink_item_assoc_list()
for(var/key in uplink.items_assoc)
to_world("[key] - [uplink.items_assoc[key]]")
#endif
var/datum/uplink_random_selection/default_uplink_selection = new/datum/uplink_random_selection/default()
var/datum/uplink_random_selection/all_uplink_selection = new/datum/uplink_random_selection/all()
/datum/uplink_random_item
var/uplink_item // The uplink item
var/keep_probability // The probability we'll decide to keep this item if selected
var/reselect_probability // Probability that we'll decide to keep this item if previously selected.
// Is done together with the keep_probability check. Being selected more than once does not affect this probability.
/datum/uplink_random_item/New(var/uplink_item, var/keep_probability = 100, var/reselect_propbability = 33)
..()
src.uplink_item = uplink_item
src.keep_probability = keep_probability
src.reselect_probability = reselect_probability
/datum/uplink_random_selection
var/list/datum/uplink_random_item/items
var/list/datum/uplink_random_item/all_items
/datum/uplink_random_selection/New()
..()
items = list()
all_items = list()
/datum/uplink_random_selection/proc/get_random_item(var/telecrystals, obj/item/device/uplink/U, var/list/bought_items, var/items_override = 0)
var/const/attempts = 50
for(var/i = 0; i < attempts; i++)
var/datum/uplink_random_item/RI
if(items_override)
RI = pick(all_items)
else
RI = pick(items)
if(!prob(RI.keep_probability))
continue
var/datum/uplink_item/I = uplink.items_assoc[RI.uplink_item]
if(I.cost(U) > telecrystals)
continue
if(bought_items && (I in bought_items) && !prob(RI.reselect_probability))
continue
if(U && !I.can_buy(U, telecrystals))
continue
return I
/datum/uplink_random_selection/all/New()
..()
for(var/datum/uplink_item/item in uplink.items)
if(item.blacklisted)
continue
else
all_items += new/datum/uplink_random_item(item.type)
/datum/uplink_random_selection/default/New()
..()
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/silenced_45)
items += new/datum/uplink_random_item(/datum/uplink_item/item/ammo/mc9mm)
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/revolver)
items += new/datum/uplink_random_item(/datum/uplink_item/item/ammo/a357)
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/heavysnipermerc, 15, 0)
items += new/datum/uplink_random_item(/datum/uplink_item/item/ammo/sniperammo, 15, 0)
items += new/datum/uplink_random_item(/datum/uplink_item/item/grenades/emp, 50)
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/crossbow, 33)
items += new/datum/uplink_random_item(/datum/uplink_item/item/visible_weapons/energy_sword, 75)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/soap, 5, 100)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/concealed_cane, 50, 10)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/detomatix, 20, 10)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/parapen)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealthy_weapons/cigarette_kit)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/id)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/spy)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/chameleon_kit)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/chameleon_projector)
items += new/datum/uplink_random_item(/datum/uplink_item/item/stealth_items/voice)
items += new/datum/uplink_random_item(/datum/uplink_item/item/armor/heavy_vest)
items += new/datum/uplink_random_item(/datum/uplink_item/item/armor/combat)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/toolbox, reselect_propbability = 10)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/plastique)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/encryptionkey_radio)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/encryptionkey_binary)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/emag, 100, 50)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/clerical)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/space_suit, 50, 10)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/thermal)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/powersink, 10, 10)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/ai_module, 25, 0)
items += new/datum/uplink_random_item(/datum/uplink_item/item/tools/teleporter, 10, 0)
items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_freedom)
items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_compress)
items += new/datum/uplink_random_item(/datum/uplink_item/item/implants/imp_explosive)
items += new/datum/uplink_random_item(/datum/uplink_item/item/medical/sinpockets, reselect_propbability = 20)
items += new/datum/uplink_random_item(/datum/uplink_item/item/medical/surgery, reselect_propbability = 10)
items += new/datum/uplink_random_item(/datum/uplink_item/item/medical/combat, reselect_propbability = 10)
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/thermal, reselect_propbability = 15)
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/energy_net, reselect_propbability = 15)
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/ewar_voice, reselect_propbability = 15)
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/maneuvering_jets, reselect_propbability = 15)
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/egun, reselect_propbability = 15)
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/power_sink, reselect_propbability = 15)
items += new/datum/uplink_random_item(/datum/uplink_item/item/hardsuit_modules/laser_canon, reselect_propbability = 5)
#ifdef DEBUG
/proc/debug_uplink_purchage_log()
for(var/antag_type in all_antag_types)
var/datum/antagonist/A = all_antag_types[antag_type]
A.print_player_summary()
/proc/debug_uplink_item_assoc_list()
for(var/key in uplink.items_assoc)
to_world("[key] - [uplink.items_assoc[key]]")
#endif
+63 -63
View File
@@ -1,64 +1,64 @@
/obj/item/latexballon
name = "latex glove"
desc = "A latex glove, usually used as a balloon."
icon_state = "latexballon"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_gloves.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_gloves.dmi',
)
item_state = "lgloves"
force = 0
throwforce = 0
w_class = ITEMSIZE_SMALL
throw_speed = 1
throw_range = 15
var/state
var/datum/gas_mixture/air_contents = null
/obj/item/latexballon/proc/blow(obj/item/weapon/tank/tank)
if (icon_state == "latexballon_bursted")
return
src.air_contents = tank.remove_air_volume(3)
icon_state = "latexballon_blow"
item_state = "latexballon"
/obj/item/latexballon/proc/burst()
if (!air_contents)
return
playsound(src, 'sound/weapons/Gunshot_old.ogg', 100, 1)
icon_state = "latexballon_bursted"
item_state = "lgloves"
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()
burst()
/obj/item/latexballon/fire_act(datum/gas_mixture/air, temperature, volume)
if(temperature > T0C+100)
burst()
return
/obj/item/latexballon/attackby(obj/item/W as obj, mob/user as mob)
if (can_puncture(W))
burst()
/*
/obj/item/latexballon/nitrile
name = "nitrile glove"
desc = "A nitrile glove, usually used as a balloon."
icon_state = "nitrileballon"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_gloves.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_gloves.dmi',
)
item_state = "ngloves"
/obj/item/latexballon
name = "latex glove"
desc = "A latex glove, usually used as a balloon."
icon_state = "latexballon"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_gloves.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_gloves.dmi',
)
item_state = "lgloves"
force = 0
throwforce = 0
w_class = ITEMSIZE_SMALL
throw_speed = 1
throw_range = 15
var/state
var/datum/gas_mixture/air_contents = null
/obj/item/latexballon/proc/blow(obj/item/weapon/tank/tank)
if (icon_state == "latexballon_bursted")
return
src.air_contents = tank.remove_air_volume(3)
icon_state = "latexballon_blow"
item_state = "latexballon"
/obj/item/latexballon/proc/burst()
if (!air_contents)
return
playsound(src, 'sound/weapons/Gunshot_old.ogg', 100, 1)
icon_state = "latexballon_bursted"
item_state = "lgloves"
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()
burst()
/obj/item/latexballon/fire_act(datum/gas_mixture/air, temperature, volume)
if(temperature > T0C+100)
burst()
return
/obj/item/latexballon/attackby(obj/item/W as obj, mob/user as mob)
if (can_puncture(W))
burst()
/*
/obj/item/latexballon/nitrile
name = "nitrile glove"
desc = "A nitrile glove, usually used as a balloon."
icon_state = "nitrileballon"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_gloves.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_gloves.dmi',
)
item_state = "ngloves"
*/
+332 -332
View File
@@ -1,332 +1,332 @@
/obj/item/device/kit
icon_state = "modkit"
icon = 'icons/obj/device.dmi'
w_class = ITEMSIZE_SMALL
var/new_name = "custom item"
var/new_desc = "A custom item."
var/new_icon
var/new_icon_file
var/new_icon_override_file
var/uses = 1 // Uses before the kit deletes itself.
var/list/allowed_types = list()
/obj/item/device/kit/examine()
. = ..()
. += "It has [uses] use\s left."
/obj/item/device/kit/proc/use(var/amt, var/mob/user)
uses -= amt
playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
if(uses<1)
user.drop_item()
qdel(src)
/obj/item/device/kit/proc/can_customize(var/obj/item/I)
return is_type_in_list(I, allowed_types)
/obj/item/device/kit/proc/set_info(var/kit_name, var/kit_desc, var/kit_icon, var/kit_icon_file = CUSTOM_ITEM_OBJ, var/kit_icon_override_file = CUSTOM_ITEM_MOB, var/additional_data)
new_name = kit_name
new_desc = kit_desc
new_icon = kit_icon
new_icon_file = kit_icon_file
new_icon_override_file = kit_icon_override_file
for(var/path in splittext(additional_data, ", "))
allowed_types |= text2path(path)
/obj/item/device/kit/proc/customize(var/obj/item/I, var/mob/user)
if(can_customize(I))
I.name = new_name ? new_name : I.name
I.desc = new_desc ? new_desc : I.desc
I.icon = new_icon_file ? new_icon_file : I.icon
I.icon_override = new_icon_override_file ? new_icon_override_file : I.icon_override
if(new_icon)
I.icon_state = new_icon
var/obj/item/clothing/under/U = I
if(istype(U))
U.worn_state = I.icon_state
U.update_rolldown_status()
use(1, user)
// Generic use
/obj/item/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/device/kit))
var/obj/item/device/kit/K = W
K.customize(src, user)
return
..()
// Root hardsuit kit defines.
// Icons for modified hardsuits need to be in the proper .dmis because suit cyclers may cock them up.
/obj/item/device/kit/suit
name = "voidsuit modification kit"
desc = "A kit for modifying a voidsuit."
uses = 2
var/new_light_overlay
/obj/item/device/kit/suit/can_customize(var/obj/item/I)
return istype(I, /obj/item/clothing/head/helmet/space/void) || istype(I, /obj/item/clothing/suit/space/void) || istype(I, /obj/item/clothing/suit/storage/hooded)
/obj/item/device/kit/suit/set_info(var/kit_name, var/kit_desc, var/kit_icon, var/kit_icon_file = CUSTOM_ITEM_OBJ, var/kit_icon_override_file = CUSTOM_ITEM_MOB, var/additional_data)
..()
new_light_overlay = additional_data
/obj/item/device/kit/suit/customize(var/obj/item/I, var/mob/user)
if(can_customize(I))
if(istype(I, /obj/item/clothing/head/helmet/space/void))
var/obj/item/clothing/head/helmet/space/void/helmet = I
helmet.name = "[new_name] suit helmet"
helmet.desc = new_desc
helmet.icon_state = "[new_icon]_helmet"
helmet.item_state = "[new_icon]_helmet"
if(new_icon_file)
helmet.icon = new_icon_file
if(new_icon_override_file)
helmet.icon_override = new_icon_override_file
if(new_light_overlay)
helmet.light_overlay = new_light_overlay
to_chat(user, "You set about modifying the helmet into [helmet].")
var/mob/living/carbon/human/H = user
if(istype(H))
helmet.species_restricted = list(H.species.get_bodytype(H))
else if(istype(I, /obj/item/clothing/suit/storage/hooded))
var/obj/item/clothing/suit/storage/hooded/suit = I
suit.name = "[new_name] suit"
suit.desc = new_desc
suit.icon_state = "[new_icon]_suit"
suit.toggleicon = "[new_icon]_suit"
var/obj/item/clothing/head/hood/S = suit.hood
S.icon_state = "[new_icon]_helmet"
if(new_icon_file)
suit.icon = new_icon_file
S.icon = new_icon_file
if(new_icon_override_file)
suit.icon_override = new_icon_override_file
S.icon_override = new_icon_override_file
to_chat(user, "You set about modifying the suit into [suit].")
// var/mob/living/carbon/human/H = user
// if(istype(H))
// suit.species_restricted = list(H.species.get_bodytype(H)) Does not quite make sense for something usually very pliable.
else
var/obj/item/clothing/suit/space/void/suit = I
suit.name = "[new_name] voidsuit"
suit.desc = new_desc
suit.icon_state = "[new_icon]_suit"
suit.item_state = "[new_icon]_suit"
if(new_icon_file)
suit.icon = new_icon_file
if(new_icon_override_file)
suit.icon_override = new_icon_override_file
to_chat(user, "You set about modifying the suit into [suit].")
var/mob/living/carbon/human/H = user
if(istype(H))
suit.species_restricted = list(H.species.get_bodytype(H))
use(1,user)
/obj/item/clothing/head/helmet/space/void/attackby(var/obj/item/O, var/mob/user)
if(istype(O,/obj/item/device/kit/suit))
var/obj/item/device/kit/suit/kit = O
kit.customize(src, user)
return
return ..()
/obj/item/clothing/suit/space/void/attackby(var/obj/item/O, var/mob/user)
if(istype(O,/obj/item/device/kit/suit))
var/obj/item/device/kit/suit/kit = O
kit.customize(src, user)
return
return ..()
/obj/item/clothing/suit/storage/hooded/attackby(var/obj/item/O, var/mob/user)
if(istype(O,/obj/item/device/kit/suit))
var/obj/item/device/kit/suit/kit = O
kit.customize(src, user)
return
return ..()
/obj/item/device/kit/suit/rig
name = "rig modification kit"
desc = "A kit for modifying a rigsuit."
uses = 1
/obj/item/device/kit/suit/rig/customize(var/obj/item/I, var/mob/user)
var/obj/item/weapon/rig/RIG = I
RIG.suit_state = new_icon
RIG.item_state = new_icon
RIG.suit_type = "customized [initial(RIG.suit_type)]"
RIG.name = "[new_name]"
RIG.desc = new_desc
RIG.icon = new_icon_file
RIG.icon_state = new_icon
RIG.icon_override = new_icon_override_file
for(var/obj/item/piece in list(RIG.gloves,RIG.helmet,RIG.boots,RIG.chest))
if(!istype(piece))
continue
piece.name = "[RIG.suit_type] [initial(piece.name)]"
piece.desc = "It seems to be part of a [RIG.name]."
piece.icon_state = "[RIG.suit_state]"
if(istype(piece, /obj/item/clothing/shoes))
piece.icon = 'icons/mob/custom_items_rig_boots.dmi'
piece.icon_override = 'icons/mob/custom_items_rig_boots.dmi'
if(istype(piece, /obj/item/clothing/suit))
piece.icon = 'icons/mob/custom_items_rig_suit.dmi'
piece.icon_override = 'icons/mob/custom_items_rig_suit.dmi'
if(istype(piece, /obj/item/clothing/head))
piece.icon = 'icons/mob/custom_items_rig_helmet.dmi'
piece.icon_override = 'icons/mob/custom_items_rig_helmet.dmi'
if(istype(piece, /obj/item/clothing/gloves))
piece.icon = 'icons/mob/custom_items_rig_gloves.dmi'
piece.icon_override = 'icons/mob/custom_items_rig_gloves.dmi'
if(RIG.helmet && istype(RIG.helmet, /obj/item/clothing/head/helmet) && new_light_overlay)
var/obj/item/clothing/head/helmet/H = RIG.helmet
H.light_overlay = new_light_overlay
use(1,user)
/obj/item/device/kit/suit/rig/can_customize(var/obj/item/I)
return istype(I, /obj/item/weapon/rig)
/obj/item/weapon/rig/attackby(var/obj/item/O, var/mob/user)
if(istype(O,/obj/item/device/kit/suit))
var/obj/item/device/kit/suit/rig/kit = O
kit.customize(src, user)
return
return ..()
/obj/item/device/kit/suit/rig/debug/Initialize()
set_info("debug suit", "This is a test", "debug", CUSTOM_ITEM_OBJ, CUSTOM_ITEM_MOB)
/obj/item/device/kit/paint
name = "mecha customisation kit"
desc = "A kit containing all the needed tools and parts to repaint a mech."
var/removable = null
/obj/item/device/kit/paint/can_customize(var/obj/mecha/M)
if(!istype(M))
return 0
for(var/type in allowed_types)
if(type == M.initial_icon)
return 1
/obj/item/device/kit/paint/set_info(var/kit_name, var/kit_desc, var/kit_icon, var/kit_icon_file = CUSTOM_ITEM_OBJ, var/kit_icon_override_file = CUSTOM_ITEM_MOB, var/additional_data)
..()
allowed_types = splittext(additional_data, ", ")
/obj/item/device/kit/paint/examine()
. = ..()
. += "This kit will convert an exosuit into: [new_name]."
. += "This kit can be used on the following exosuit models:"
for(var/exotype in allowed_types)
. += "- [capitalize(exotype)]"
/obj/item/device/kit/paint/customize(var/obj/mecha/M, var/mob/user)
if(!can_customize(M))
to_chat(user, "That kit isn't meant for use on this class of exosuit.")
return
if(M.occupant)
to_chat(user, "You can't customize a mech while someone is piloting it - that would be unsafe!")
return
user.visible_message("[user] opens [src] and spends some quality time customising [M].")
M.name = new_name
M.desc = new_desc
M.initial_icon = new_icon
if(new_icon_file)
M.icon = new_icon_file
M.update_icon()
use(1, user)
/obj/mecha/attackby(var/obj/item/weapon/W, var/mob/user)
if(istype(W, /obj/item/device/kit/paint))
var/obj/item/device/kit/paint/P = W
P.customize(src, user)
return
else
return ..()
//Ripley APLU kits.
/obj/item/device/kit/paint/ripley
name = "\"Classic\" APLU customisation kit"
new_name = "APLU \"Classic\""
new_desc = "A very retro APLU unit; didn't they retire these back in 2303?"
new_icon = "ripley-old"
allowed_types = list("ripley")
var/showpilot = TRUE
var/showpilot_lift = 5
/obj/item/device/kit/paint/ripley/customize(obj/mecha/M, mob/user)
if(showpilot)
M.show_pilot = TRUE
M.pilot_lift = 5
else
M.show_pilot = FALSE
M.pilot_lift = 0
. = ..()
/obj/item/device/kit/paint/ripley/death
name = "\"Reaper\" APLU customisation kit"
new_name = "APLU \"Reaper\""
new_desc = "A terrifying, grim power loader. Why do those clamps have spikes?"
new_icon = "deathripley"
allowed_types = list("ripley","firefighter")
showpilot = FALSE
/obj/item/device/kit/paint/ripley/flames_red
name = "\"Firestarter\" APLU customisation kit"
new_name = "APLU \"Firestarter\""
new_desc = "A standard APLU exosuit with stylish orange flame decals."
new_icon = "ripley_flames_red"
showpilot = FALSE
/obj/item/device/kit/paint/ripley/flames_blue
name = "\"Burning Chrome\" APLU customisation kit"
new_name = "APLU \"Burning Chrome\""
new_desc = "A standard APLU exosuit with stylish blue flame decals."
new_icon = "ripley_flames_blue"
showpilot = FALSE
// Durand kits.
/obj/item/device/kit/paint/durand
name = "\"Classic\" Durand customisation kit"
new_name = "Durand \"Classic\""
new_desc = "An older model of Durand combat exosuit. This model was retired for rotating a pilot's torso 180 degrees."
new_icon = "old_durand"
allowed_types = list("durand")
/obj/item/device/kit/paint/durand/seraph
name = "\"Cherubim\" Durand customisation kit"
new_name = "Durand \"Cherubim\""
new_desc = "A Durand combat exosuit modelled after ancient Earth entertainment. Your heart goes doki-doki just looking at it."
new_icon = "old_durand"
/obj/item/device/kit/paint/durand/phazon
name = "\"Sypher\" Durand customisation kit"
new_name = "Durand \"Sypher\""
new_desc = "A Durand combat exosuit with some very stylish neons and decals. Seems to blur slightly at the edges; probably an optical illusion."
new_icon = "phazon"
// Gygax kits.
/obj/item/device/kit/paint/gygax
name = "\"Jester\" Gygax customisation kit"
new_name = "Gygax \"Jester\""
new_desc = "A Gygax exosuit modelled after the infamous combat-troubadors of Earth's distant past. Terrifying to behold."
new_icon = "honker"
allowed_types = list("gygax")
/obj/item/device/kit/paint/gygax/darkgygax
name = "\"Silhouette\" Gygax customisation kit"
new_name = "Gygax \"Silhouette\""
new_desc = "An ominous Gygax exosuit modelled after the fictional corporate 'death squads' that were popular in pulp action-thrillers back in 2314."
new_icon = "darkgygax"
/obj/item/device/kit/paint/gygax/recitence
name = "\"Gaoler\" Gygax customisation kit"
new_name = "Durand \"Gaoler\""
new_desc = "A bulky silver Gygax exosuit. The extra armour appears to be painted on, but it's very shiny."
new_icon = "recitence"
/obj/item/device/kit
icon_state = "modkit"
icon = 'icons/obj/device.dmi'
w_class = ITEMSIZE_SMALL
var/new_name = "custom item"
var/new_desc = "A custom item."
var/new_icon
var/new_icon_file
var/new_icon_override_file
var/uses = 1 // Uses before the kit deletes itself.
var/list/allowed_types = list()
/obj/item/device/kit/examine()
. = ..()
. += "It has [uses] use\s left."
/obj/item/device/kit/proc/use(var/amt, var/mob/user)
uses -= amt
playsound(src, 'sound/items/Screwdriver.ogg', 50, 1)
if(uses<1)
user.drop_item()
qdel(src)
/obj/item/device/kit/proc/can_customize(var/obj/item/I)
return is_type_in_list(I, allowed_types)
/obj/item/device/kit/proc/set_info(var/kit_name, var/kit_desc, var/kit_icon, var/kit_icon_file = CUSTOM_ITEM_OBJ, var/kit_icon_override_file = CUSTOM_ITEM_MOB, var/additional_data)
new_name = kit_name
new_desc = kit_desc
new_icon = kit_icon
new_icon_file = kit_icon_file
new_icon_override_file = kit_icon_override_file
for(var/path in splittext(additional_data, ", "))
allowed_types |= text2path(path)
/obj/item/device/kit/proc/customize(var/obj/item/I, var/mob/user)
if(can_customize(I))
I.name = new_name ? new_name : I.name
I.desc = new_desc ? new_desc : I.desc
I.icon = new_icon_file ? new_icon_file : I.icon
I.icon_override = new_icon_override_file ? new_icon_override_file : I.icon_override
if(new_icon)
I.icon_state = new_icon
var/obj/item/clothing/under/U = I
if(istype(U))
U.worn_state = I.icon_state
U.update_rolldown_status()
use(1, user)
// Generic use
/obj/item/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/device/kit))
var/obj/item/device/kit/K = W
K.customize(src, user)
return
..()
// Root hardsuit kit defines.
// Icons for modified hardsuits need to be in the proper .dmis because suit cyclers may cock them up.
/obj/item/device/kit/suit
name = "voidsuit modification kit"
desc = "A kit for modifying a voidsuit."
uses = 2
var/new_light_overlay
/obj/item/device/kit/suit/can_customize(var/obj/item/I)
return istype(I, /obj/item/clothing/head/helmet/space/void) || istype(I, /obj/item/clothing/suit/space/void) || istype(I, /obj/item/clothing/suit/storage/hooded)
/obj/item/device/kit/suit/set_info(var/kit_name, var/kit_desc, var/kit_icon, var/kit_icon_file = CUSTOM_ITEM_OBJ, var/kit_icon_override_file = CUSTOM_ITEM_MOB, var/additional_data)
..()
new_light_overlay = additional_data
/obj/item/device/kit/suit/customize(var/obj/item/I, var/mob/user)
if(can_customize(I))
if(istype(I, /obj/item/clothing/head/helmet/space/void))
var/obj/item/clothing/head/helmet/space/void/helmet = I
helmet.name = "[new_name] suit helmet"
helmet.desc = new_desc
helmet.icon_state = "[new_icon]_helmet"
helmet.item_state = "[new_icon]_helmet"
if(new_icon_file)
helmet.icon = new_icon_file
if(new_icon_override_file)
helmet.icon_override = new_icon_override_file
if(new_light_overlay)
helmet.light_overlay = new_light_overlay
to_chat(user, "You set about modifying the helmet into [helmet].")
var/mob/living/carbon/human/H = user
if(istype(H))
helmet.species_restricted = list(H.species.get_bodytype(H))
else if(istype(I, /obj/item/clothing/suit/storage/hooded))
var/obj/item/clothing/suit/storage/hooded/suit = I
suit.name = "[new_name] suit"
suit.desc = new_desc
suit.icon_state = "[new_icon]_suit"
suit.toggleicon = "[new_icon]_suit"
var/obj/item/clothing/head/hood/S = suit.hood
S.icon_state = "[new_icon]_helmet"
if(new_icon_file)
suit.icon = new_icon_file
S.icon = new_icon_file
if(new_icon_override_file)
suit.icon_override = new_icon_override_file
S.icon_override = new_icon_override_file
to_chat(user, "You set about modifying the suit into [suit].")
// var/mob/living/carbon/human/H = user
// if(istype(H))
// suit.species_restricted = list(H.species.get_bodytype(H)) Does not quite make sense for something usually very pliable.
else
var/obj/item/clothing/suit/space/void/suit = I
suit.name = "[new_name] voidsuit"
suit.desc = new_desc
suit.icon_state = "[new_icon]_suit"
suit.item_state = "[new_icon]_suit"
if(new_icon_file)
suit.icon = new_icon_file
if(new_icon_override_file)
suit.icon_override = new_icon_override_file
to_chat(user, "You set about modifying the suit into [suit].")
var/mob/living/carbon/human/H = user
if(istype(H))
suit.species_restricted = list(H.species.get_bodytype(H))
use(1,user)
/obj/item/clothing/head/helmet/space/void/attackby(var/obj/item/O, var/mob/user)
if(istype(O,/obj/item/device/kit/suit))
var/obj/item/device/kit/suit/kit = O
kit.customize(src, user)
return
return ..()
/obj/item/clothing/suit/space/void/attackby(var/obj/item/O, var/mob/user)
if(istype(O,/obj/item/device/kit/suit))
var/obj/item/device/kit/suit/kit = O
kit.customize(src, user)
return
return ..()
/obj/item/clothing/suit/storage/hooded/attackby(var/obj/item/O, var/mob/user)
if(istype(O,/obj/item/device/kit/suit))
var/obj/item/device/kit/suit/kit = O
kit.customize(src, user)
return
return ..()
/obj/item/device/kit/suit/rig
name = "rig modification kit"
desc = "A kit for modifying a rigsuit."
uses = 1
/obj/item/device/kit/suit/rig/customize(var/obj/item/I, var/mob/user)
var/obj/item/weapon/rig/RIG = I
RIG.suit_state = new_icon
RIG.item_state = new_icon
RIG.suit_type = "customized [initial(RIG.suit_type)]"
RIG.name = "[new_name]"
RIG.desc = new_desc
RIG.icon = new_icon_file
RIG.icon_state = new_icon
RIG.icon_override = new_icon_override_file
for(var/obj/item/piece in list(RIG.gloves,RIG.helmet,RIG.boots,RIG.chest))
if(!istype(piece))
continue
piece.name = "[RIG.suit_type] [initial(piece.name)]"
piece.desc = "It seems to be part of a [RIG.name]."
piece.icon_state = "[RIG.suit_state]"
if(istype(piece, /obj/item/clothing/shoes))
piece.icon = 'icons/mob/custom_items_rig_boots.dmi'
piece.icon_override = 'icons/mob/custom_items_rig_boots.dmi'
if(istype(piece, /obj/item/clothing/suit))
piece.icon = 'icons/mob/custom_items_rig_suit.dmi'
piece.icon_override = 'icons/mob/custom_items_rig_suit.dmi'
if(istype(piece, /obj/item/clothing/head))
piece.icon = 'icons/mob/custom_items_rig_helmet.dmi'
piece.icon_override = 'icons/mob/custom_items_rig_helmet.dmi'
if(istype(piece, /obj/item/clothing/gloves))
piece.icon = 'icons/mob/custom_items_rig_gloves.dmi'
piece.icon_override = 'icons/mob/custom_items_rig_gloves.dmi'
if(RIG.helmet && istype(RIG.helmet, /obj/item/clothing/head/helmet) && new_light_overlay)
var/obj/item/clothing/head/helmet/H = RIG.helmet
H.light_overlay = new_light_overlay
use(1,user)
/obj/item/device/kit/suit/rig/can_customize(var/obj/item/I)
return istype(I, /obj/item/weapon/rig)
/obj/item/weapon/rig/attackby(var/obj/item/O, var/mob/user)
if(istype(O,/obj/item/device/kit/suit))
var/obj/item/device/kit/suit/rig/kit = O
kit.customize(src, user)
return
return ..()
/obj/item/device/kit/suit/rig/debug/Initialize()
set_info("debug suit", "This is a test", "debug", CUSTOM_ITEM_OBJ, CUSTOM_ITEM_MOB)
/obj/item/device/kit/paint
name = "mecha customisation kit"
desc = "A kit containing all the needed tools and parts to repaint a mech."
var/removable = null
/obj/item/device/kit/paint/can_customize(var/obj/mecha/M)
if(!istype(M))
return 0
for(var/type in allowed_types)
if(type == M.initial_icon)
return 1
/obj/item/device/kit/paint/set_info(var/kit_name, var/kit_desc, var/kit_icon, var/kit_icon_file = CUSTOM_ITEM_OBJ, var/kit_icon_override_file = CUSTOM_ITEM_MOB, var/additional_data)
..()
allowed_types = splittext(additional_data, ", ")
/obj/item/device/kit/paint/examine()
. = ..()
. += "This kit will convert an exosuit into: [new_name]."
. += "This kit can be used on the following exosuit models:"
for(var/exotype in allowed_types)
. += "- [capitalize(exotype)]"
/obj/item/device/kit/paint/customize(var/obj/mecha/M, var/mob/user)
if(!can_customize(M))
to_chat(user, "That kit isn't meant for use on this class of exosuit.")
return
if(M.occupant)
to_chat(user, "You can't customize a mech while someone is piloting it - that would be unsafe!")
return
user.visible_message("[user] opens [src] and spends some quality time customising [M].")
M.name = new_name
M.desc = new_desc
M.initial_icon = new_icon
if(new_icon_file)
M.icon = new_icon_file
M.update_icon()
use(1, user)
/obj/mecha/attackby(var/obj/item/weapon/W, var/mob/user)
if(istype(W, /obj/item/device/kit/paint))
var/obj/item/device/kit/paint/P = W
P.customize(src, user)
return
else
return ..()
//Ripley APLU kits.
/obj/item/device/kit/paint/ripley
name = "\"Classic\" APLU customisation kit"
new_name = "APLU \"Classic\""
new_desc = "A very retro APLU unit; didn't they retire these back in 2303?"
new_icon = "ripley-old"
allowed_types = list("ripley")
var/showpilot = TRUE
var/showpilot_lift = 5
/obj/item/device/kit/paint/ripley/customize(obj/mecha/M, mob/user)
if(showpilot)
M.show_pilot = TRUE
M.pilot_lift = 5
else
M.show_pilot = FALSE
M.pilot_lift = 0
. = ..()
/obj/item/device/kit/paint/ripley/death
name = "\"Reaper\" APLU customisation kit"
new_name = "APLU \"Reaper\""
new_desc = "A terrifying, grim power loader. Why do those clamps have spikes?"
new_icon = "deathripley"
allowed_types = list("ripley","firefighter")
showpilot = FALSE
/obj/item/device/kit/paint/ripley/flames_red
name = "\"Firestarter\" APLU customisation kit"
new_name = "APLU \"Firestarter\""
new_desc = "A standard APLU exosuit with stylish orange flame decals."
new_icon = "ripley_flames_red"
showpilot = FALSE
/obj/item/device/kit/paint/ripley/flames_blue
name = "\"Burning Chrome\" APLU customisation kit"
new_name = "APLU \"Burning Chrome\""
new_desc = "A standard APLU exosuit with stylish blue flame decals."
new_icon = "ripley_flames_blue"
showpilot = FALSE
// Durand kits.
/obj/item/device/kit/paint/durand
name = "\"Classic\" Durand customisation kit"
new_name = "Durand \"Classic\""
new_desc = "An older model of Durand combat exosuit. This model was retired for rotating a pilot's torso 180 degrees."
new_icon = "old_durand"
allowed_types = list("durand")
/obj/item/device/kit/paint/durand/seraph
name = "\"Cherubim\" Durand customisation kit"
new_name = "Durand \"Cherubim\""
new_desc = "A Durand combat exosuit modelled after ancient Earth entertainment. Your heart goes doki-doki just looking at it."
new_icon = "old_durand"
/obj/item/device/kit/paint/durand/phazon
name = "\"Sypher\" Durand customisation kit"
new_name = "Durand \"Sypher\""
new_desc = "A Durand combat exosuit with some very stylish neons and decals. Seems to blur slightly at the edges; probably an optical illusion."
new_icon = "phazon"
// Gygax kits.
/obj/item/device/kit/paint/gygax
name = "\"Jester\" Gygax customisation kit"
new_name = "Gygax \"Jester\""
new_desc = "A Gygax exosuit modelled after the infamous combat-troubadors of Earth's distant past. Terrifying to behold."
new_icon = "honker"
allowed_types = list("gygax")
/obj/item/device/kit/paint/gygax/darkgygax
name = "\"Silhouette\" Gygax customisation kit"
new_name = "Gygax \"Silhouette\""
new_desc = "An ominous Gygax exosuit modelled after the fictional corporate 'death squads' that were popular in pulp action-thrillers back in 2314."
new_icon = "darkgygax"
/obj/item/device/kit/paint/gygax/recitence
name = "\"Gaoler\" Gygax customisation kit"
new_name = "Durand \"Gaoler\""
new_desc = "A bulky silver Gygax exosuit. The extra armour appears to be painted on, but it's very shiny."
new_icon = "recitence"
+84 -84
View File
@@ -1,84 +1,84 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/**********************************************************************
Cyborg Spec Items
***********************************************************************/
//Might want to move this into several files later but for now it works here
/obj/item/weapon/melee/baton/robot/arm
name = "electrified arm"
icon = 'icons/obj/decals.dmi'
icon_state = "shock"
hitcost = 750
agonyforce = 70
/obj/item/weapon/melee/baton/robot/arm/update_icon()
if(status)
set_light(1.5, 1, lightcolor)
else
set_light(0)
/obj/item/borg/overdrive
name = "overdrive"
icon = 'icons/obj/decals.dmi'
icon_state = "shock"
/**********************************************************************
HUD/SIGHT things
***********************************************************************/
/obj/item/borg/sight
icon = 'icons/obj/decals.dmi'
icon_state = "securearea"
var/sight_mode = null
/obj/item/borg/sight/xray
name = "\proper x-ray vision"
sight_mode = BORGXRAY
/obj/item/borg/sight/thermal
name = "\proper thermal vision"
sight_mode = BORGTHERM
icon_state = "thermal"
icon = 'icons/inventory/eyes/item.dmi'
/obj/item/borg/sight/meson
name = "\proper meson vision"
sight_mode = BORGMESON
icon_state = "meson"
icon = 'icons/inventory/eyes/item.dmi'
/obj/item/borg/sight/material
name = "\proper material scanner vision"
sight_mode = BORGMATERIAL
icon_state = "material"
icon = 'icons/inventory/eyes/item.dmi'
/obj/item/borg/sight/hud
name = "hud"
var/obj/item/clothing/glasses/hud/hud = null
/obj/item/borg/sight/hud/med
name = "medical hud"
icon_state = "healthhud"
icon = 'icons/inventory/eyes/item.dmi'
/obj/item/borg/sight/hud/med/New()
..()
hud = new /obj/item/clothing/glasses/hud/health(src)
return
/obj/item/borg/sight/hud/sec
name = "security hud"
icon_state = "securityhud"
icon = 'icons/inventory/eyes/item.dmi'
/obj/item/borg/sight/hud/sec/New()
..()
hud = new /obj/item/clothing/glasses/hud/security(src)
return
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/**********************************************************************
Cyborg Spec Items
***********************************************************************/
//Might want to move this into several files later but for now it works here
/obj/item/weapon/melee/baton/robot/arm
name = "electrified arm"
icon = 'icons/obj/decals.dmi'
icon_state = "shock"
hitcost = 750
agonyforce = 70
/obj/item/weapon/melee/baton/robot/arm/update_icon()
if(status)
set_light(1.5, 1, lightcolor)
else
set_light(0)
/obj/item/borg/overdrive
name = "overdrive"
icon = 'icons/obj/decals.dmi'
icon_state = "shock"
/**********************************************************************
HUD/SIGHT things
***********************************************************************/
/obj/item/borg/sight
icon = 'icons/obj/decals.dmi'
icon_state = "securearea"
var/sight_mode = null
/obj/item/borg/sight/xray
name = "\proper x-ray vision"
sight_mode = BORGXRAY
/obj/item/borg/sight/thermal
name = "\proper thermal vision"
sight_mode = BORGTHERM
icon_state = "thermal"
icon = 'icons/inventory/eyes/item.dmi'
/obj/item/borg/sight/meson
name = "\proper meson vision"
sight_mode = BORGMESON
icon_state = "meson"
icon = 'icons/inventory/eyes/item.dmi'
/obj/item/borg/sight/material
name = "\proper material scanner vision"
sight_mode = BORGMATERIAL
icon_state = "material"
icon = 'icons/inventory/eyes/item.dmi'
/obj/item/borg/sight/hud
name = "hud"
var/obj/item/clothing/glasses/hud/hud = null
/obj/item/borg/sight/hud/med
name = "medical hud"
icon_state = "healthhud"
icon = 'icons/inventory/eyes/item.dmi'
/obj/item/borg/sight/hud/med/New()
..()
hud = new /obj/item/clothing/glasses/hud/health(src)
return
/obj/item/borg/sight/hud/sec
name = "security hud"
icon_state = "securityhud"
icon = 'icons/inventory/eyes/item.dmi'
/obj/item/borg/sight/hud/sec/New()
..()
hud = new /obj/item/clothing/glasses/hud/security(src)
return
+180 -180
View File
@@ -1,180 +1,180 @@
// 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 = FALSE
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 = TRUE
break
..() // delete target
/obj/item/target/Moved(atom/old_loc, direction, forced = FALSE)
. = ..()
// 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.forceMove(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)
if (W.has_tool_quality(TOOL_WELDER))
var/obj/item/weapon/weldingtool/WT = W.get_welder()
if(WT.remove_fuel(0, user))
cut_overlays()
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 = TRUE
density = FALSE
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 hostile agent."
hp = 2600 // i guess syndie targets are sturdier?
/obj/item/target/alien
icon_state = "target_q"
desc = "A shooting target with a threatening silhouette."
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)
for(var/mob/O in oviewers())
if ((O.client && !( O.blinded )))
to_chat(O, "<span class='warning'>\The [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.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.set_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
add_overlay(bmark) // add the decal
icon = virtualIcon // apply bulletholes over decals
return
return PROJECTILE_CONTINUE // the bullet/projectile goes through the target!
// 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(var/obj/item/target/Target, var/pixel_x = 0, var/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 = FALSE
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 = TRUE
break
..() // delete target
/obj/item/target/Moved(atom/old_loc, direction, forced = FALSE)
. = ..()
// 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.forceMove(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)
if (W.has_tool_quality(TOOL_WELDER))
var/obj/item/weapon/weldingtool/WT = W.get_welder()
if(WT.remove_fuel(0, user))
cut_overlays()
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 = TRUE
density = FALSE
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 hostile agent."
hp = 2600 // i guess syndie targets are sturdier?
/obj/item/target/alien
icon_state = "target_q"
desc = "A shooting target with a threatening silhouette."
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)
for(var/mob/O in oviewers())
if ((O.client && !( O.blinded )))
to_chat(O, "<span class='warning'>\The [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.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.set_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
add_overlay(bmark) // add the decal
icon = virtualIcon // apply bulletholes over decals
return
return PROJECTILE_CONTINUE // the bullet/projectile goes through the target!
// 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(var/obj/item/target/Target, var/pixel_x = 0, var/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)
+452 -452
View File
@@ -1,452 +1,452 @@
/obj/item/stack/medical
name = "medical pack"
singular_name = "medical pack"
icon = 'icons/obj/stacks.dmi'
amount = 10
max_amount = 10
w_class = ITEMSIZE_SMALL
throw_speed = 4
throw_range = 20
var/heal_brute = 0
var/heal_burn = 0
var/apply_sounds
drop_sound = 'sound/items/drop/cardboardbox.ogg'
pickup_sound = 'sound/items/pickup/cardboardbox.ogg'
var/upgrade_to // The type path this stack can be upgraded to.
/obj/item/stack/medical/attack(mob/living/carbon/M as mob, mob/user as mob)
if (!istype(M))
to_chat(user, "<span class='warning'>\The [src] cannot be applied to [M]!</span>")
return 1
if (!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return 1
var/available = get_amount()
if(!available)
to_chat(user, "<span class='warning'>There's not enough [uses_charge ? "charge" : "items"] left to use that!</span>")
return 1
if (istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
if(!affecting)
to_chat(user, "<span class='warning'>No body part there to work on!</span>")
return 1
if(affecting.organ_tag == BP_HEAD)
if(H.head && istype(H.head,/obj/item/clothing/head/helmet/space))
to_chat(user, "<span class='warning'>You can't apply [src] through [H.head]!</span>")
return 1
else
if(H.wear_suit && istype(H.wear_suit,/obj/item/clothing/suit/space))
to_chat(user, "<span class='warning'>You can't apply [src] through [H.wear_suit]!</span>")
return 1
if(affecting.robotic == ORGAN_ROBOT)
to_chat(user, "<span class='warning'>This isn't useful at all on a robotic limb.</span>")
return 1
if(affecting.robotic >= ORGAN_LIFELIKE)
to_chat(user, "<span class='warning'>You apply the [src], but it seems to have no effect...</span>")
use(1)
return 1
H.UpdateDamageIcon()
else
M.heal_organ_damage((src.heal_brute/2), (src.heal_burn/2))
user.visible_message( \
"<span class='notice'>[M] has been applied with [src] by [user].</span>", \
"<span class='notice'>You apply \the [src] to [M].</span>" \
)
use(1)
M.updatehealth()
/obj/item/stack/medical/proc/upgrade_stack(var/upgrade_amount)
. = FALSE
var/turf/T = get_turf(src)
if(ispath(upgrade_to) && use(upgrade_amount))
var/obj/item/stack/medical/M = new upgrade_to(T, upgrade_amount)
return M
return .
/obj/item/stack/medical/crude_pack
name = "crude bandage"
singular_name = "crude bandage length"
desc = "Some bandages to wrap around bloody stumps."
icon_state = "gauze"
origin_tech = list(TECH_BIO = 1)
no_variants = FALSE
apply_sounds = list('sound/effects/rip1.ogg','sound/effects/rip2.ogg')
upgrade_to = /obj/item/stack/medical/bruise_pack
/obj/item/stack/medical/crude_pack/attack(mob/living/carbon/M as mob, mob/user as mob)
if(..())
return 1
if (istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
if(affecting.open)
to_chat(user, "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>")
return
if(affecting.is_bandaged())
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been bandaged.</span>")
return 1
else
var/available = get_amount()
user.visible_message("<b>\The [user]</b> starts bandaging [M]'s [affecting.name].", \
"<span class='notice'>You start bandaging [M]'s [affecting.name].</span>" )
var/used = 0
for (var/datum/wound/W in affecting.wounds)
if(W.internal)
continue
if(W.bandaged)
continue
if(used == amount)
break
if(!do_mob(user, M, W.damage/3, exclusive = TRUE))
to_chat(user, "<span class='notice'>You must stand still to bandage wounds.</span>")
break
if(affecting.is_bandaged()) // We do a second check after the delay, in case it was bandaged after the first check.
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been bandaged.</span>")
return 1
if(used >= available)
to_chat(user, "<span class='warning'>You run out of [src]!</span>")
break
if (W.current_stage <= W.max_bleeding_stage)
user.visible_message("<b>\The [user]</b> bandages \a [W.desc] on [M]'s [affecting.name].", \
"<span class='notice'>You bandage \a [W.desc] on [M]'s [affecting.name].</span>" )
else
user.visible_message("<b>\The [user]</b> places a bandage over \a [W.desc] on [M]'s [affecting.name].", \
"<span class='notice'>You place a bandage over \a [W.desc] on [M]'s [affecting.name].</span>" )
W.bandage()
playsound(src, pick(apply_sounds), 25)
used++
affecting.update_damages()
if(used == amount)
if(affecting.is_bandaged())
to_chat(user, "<span class='warning'>\The [src] is used up.</span>")
else
to_chat(user, "<span class='warning'>\The [src] is used up, but there are more wounds to treat on \the [affecting.name].</span>")
use(used)
/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 = "brutepack"
origin_tech = list(TECH_BIO = 1)
no_variants = FALSE
apply_sounds = list('sound/effects/rip1.ogg','sound/effects/rip2.ogg')
drop_sound = 'sound/items/drop/gloves.ogg'
pickup_sound = 'sound/items/pickup/gloves.ogg'
upgrade_to = /obj/item/stack/medical/advanced/bruise_pack
/obj/item/stack/medical/bruise_pack/attack(mob/living/carbon/M as mob, mob/user as mob)
if(..())
return 1
if (istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
if(affecting.open)
to_chat(user, "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>")
return
if(affecting.is_bandaged())
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been bandaged.</span>")
return 1
else
var/available = get_amount()
user.visible_message("<b>\The [user]</b> starts treating [M]'s [affecting.name].", \
"<span class='notice'>You start treating [M]'s [affecting.name].</span>" )
var/used = 0
for (var/datum/wound/W in affecting.wounds)
if (W.internal)
continue
if(W.bandaged)
continue
if(used == amount)
break
if(!do_mob(user, M, W.damage/5, exclusive = TRUE))
to_chat(user, "<span class='notice'>You must stand still to bandage wounds.</span>")
break
if(affecting.is_bandaged()) // We do a second check after the delay, in case it was bandaged after the first check.
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been bandaged.</span>")
return 1
if(used >= available)
to_chat(user, "<span class='warning'>You run out of [src]!</span>")
break
if (W.current_stage <= W.max_bleeding_stage)
user.visible_message("<b>\The [user]</b> bandages \a [W.desc] on [M]'s [affecting.name].", \
"<span class='notice'>You bandage \a [W.desc] on [M]'s [affecting.name].</span>" )
//H.add_side_effect("Itch")
else if (W.damage_type == BRUISE)
user.visible_message("<b>\The [user]</b> places a bruise patch over \a [W.desc] on [M]'s [affecting.name].", \
"<span class='notice'>You place a bruise patch over \a [W.desc] on [M]'s [affecting.name].</span>" )
else
user.visible_message("<b>\The [user]</b> places a bandaid over \a [W.desc] on [M]'s [affecting.name].", \
"<span class='notice'>You place a bandaid over \a [W.desc] on [M]'s [affecting.name].</span>" )
W.bandage()
// W.disinfect() // VOREStation - Tech1 should not disinfect
playsound(src, pick(apply_sounds), 25)
used++
affecting.update_damages()
if(used == amount)
if(affecting.is_bandaged())
to_chat(user, "<span class='warning'>\The [src] is used up.</span>")
else
to_chat(user, "<span class='warning'>\The [src] is used up, but there are more wounds to treat on \the [affecting.name].</span>")
use(used)
/obj/item/stack/medical/ointment
name = "ointment"
desc = "Used to treat those nasty burns."
gender = PLURAL
singular_name = "ointment"
icon_state = "ointment"
heal_burn = 1
origin_tech = list(TECH_BIO = 1)
no_variants = FALSE
apply_sounds = list('sound/effects/ointment.ogg')
drop_sound = 'sound/items/drop/herb.ogg'
pickup_sound = 'sound/items/pickup/herb.ogg'
/obj/item/stack/medical/ointment/attack(mob/living/carbon/M as mob, mob/user as mob)
if(..())
return 1
if (istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
if(affecting.open)
to_chat(user, "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>")
return
if(affecting.is_salved())
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been salved.</span>")
return 1
else
user.visible_message("<b>\The [user]</b> starts salving wounds on [M]'s [affecting.name].", \
"<span class='notice'>You start salving the wounds on [M]'s [affecting.name].</span>" )
if(!do_mob(user, M, 10, exclusive = TRUE))
to_chat(user, "<span class='notice'>You must stand still to salve wounds.</span>")
return 1
if(affecting.is_salved()) // We do a second check after the delay, in case it was bandaged after the first check.
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been salved.</span>")
return 1
user.visible_message("<span class='notice'>[user] salved wounds on [M]'s [affecting.name].</span>", \
"<span class='notice'>You salved wounds on [M]'s [affecting.name].</span>" )
use(1)
affecting.salve()
playsound(src, pick(apply_sounds), 25)
/obj/item/stack/medical/ointment/simple
name = "ointment paste"
desc = "A simple thick paste used to salve burns."
singular_name = "old-ointment"
icon_state = "old-ointment"
/obj/item/stack/medical/advanced/bruise_pack
name = "advanced trauma kit"
singular_name = "advanced trauma kit"
desc = "An advanced trauma kit for severe injuries."
icon_state = "traumakit"
heal_brute = 7 //VOREStation Edit
origin_tech = list(TECH_BIO = 1)
apply_sounds = list('sound/effects/rip1.ogg','sound/effects/rip2.ogg','sound/effects/tape.ogg')
/obj/item/stack/medical/advanced/bruise_pack/attack(mob/living/carbon/M as mob, mob/user as mob)
if(..())
return 1
if (istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
if(affecting.open)
to_chat(user, "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>")
return
if(affecting.is_bandaged() && affecting.is_disinfected())
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been treated.</span>")
return 1
else
var/available = get_amount()
user.visible_message("<b>\The [user]</b> starts treating [M]'s [affecting.name].", \
"<span class='notice'>You start treating [M]'s [affecting.name].</span>" )
var/used = 0
for (var/datum/wound/W in affecting.wounds)
if (W.internal)
continue
if (W.bandaged && W.disinfected)
continue
//if(used == amount) //VOREStation Edit
// break //VOREStation Edit
if(!do_mob(user, M, W.damage/5, exclusive = TRUE))
to_chat(user, "<span class='notice'>You must stand still to bandage wounds.</span>")
break
if(affecting.is_bandaged() && affecting.is_disinfected()) // We do a second check after the delay, in case it was bandaged after the first check.
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been bandaged.</span>")
return 1
if(used >= available)
to_chat(user, "<span class='warning'>You run out of [src]!</span>")
break
if (W.current_stage <= W.max_bleeding_stage)
user.visible_message("<b>\The [user]</b> cleans \a [W.desc] on [M]'s [affecting.name] and seals the edges with bioglue.", \
"<span class='notice'>You clean and seal \a [W.desc] on [M]'s [affecting.name].</span>" )
else if (W.damage_type == BRUISE)
user.visible_message("<b>\The [user]</b> places a medical patch over \a [W.desc] on [M]'s [affecting.name].", \
"<span class='notice'>You place a medical patch over \a [W.desc] on [M]'s [affecting.name].</span>" )
else
user.visible_message("<b>\The [user]</b> smears some bioglue over \a [W.desc] on [M]'s [affecting.name].", \
"<span class='notice'>You smear some bioglue over \a [W.desc] on [M]'s [affecting.name].</span>" )
W.bandage()
W.disinfect()
W.heal_damage(heal_brute)
playsound(src, pick(apply_sounds), 25)
used = 1 //VOREStation Edit
update_icon() // VOREStation Edit - Support for stack icons
affecting.update_damages()
if(used == amount)
if(affecting.is_bandaged())
to_chat(user, "<span class='warning'>\The [src] is used up.</span>")
else
to_chat(user, "<span class='warning'>\The [src] is used up, but there are more wounds to treat on \the [affecting.name].</span>")
use(used)
/obj/item/stack/medical/advanced/ointment
name = "advanced burn kit"
singular_name = "advanced burn kit"
desc = "An advanced treatment kit for severe burns."
icon_state = "burnkit"
heal_burn = 7 //VOREStation Edit
origin_tech = list(TECH_BIO = 1)
apply_sounds = list('sound/effects/ointment.ogg')
/obj/item/stack/medical/advanced/ointment/attack(mob/living/carbon/M as mob, mob/user as mob)
if(..())
return 1
if (istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
if(affecting.open)
to_chat(user, "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>")
if(affecting.is_salved())
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been salved.</span>")
return 1
else
user.visible_message("<b>\The [user]</b> starts salving wounds on [M]'s [affecting.name].", \
"<span class='notice'>You start salving the wounds on [M]'s [affecting.name].</span>" )
if(!do_mob(user, M, 10, exclusive = TRUE))
to_chat(user, "<span class='notice'>You must stand still to salve wounds.</span>")
return 1
if(affecting.is_salved()) // We do a second check after the delay, in case it was bandaged after the first check.
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been salved.</span>")
return 1
user.visible_message( "<span class='notice'>[user] covers wounds on [M]'s [affecting.name] with regenerative membrane.</span>", \
"<span class='notice'>You cover wounds on [M]'s [affecting.name] with regenerative membrane.</span>" )
affecting.heal_damage(0,heal_burn)
use(1)
affecting.salve()
playsound(src, pick(apply_sounds), 25)
update_icon() // VOREStation Edit - Support for stack icons
/obj/item/stack/medical/splint
name = "medical splints"
singular_name = "medical splint"
desc = "Modular splints capable of supporting and immobilizing bones in all areas of the body."
icon_state = "splint"
amount = 5
max_amount = 5
drop_sound = 'sound/items/drop/hat.ogg'
pickup_sound = 'sound/items/pickup/hat.ogg'
var/list/splintable_organs = list(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_GROIN, BP_TORSO) //List of organs you can splint, natch.
/obj/item/stack/medical/splint/attack(mob/living/carbon/M as mob, mob/living/user as mob)
if(..())
return 1
if (istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
var/limb = affecting.name
if(!(affecting.organ_tag in splintable_organs))
to_chat(user, "<span class='danger'>You can't use \the [src] to apply a splint there!</span>")
return
if(affecting.splinted)
to_chat(user, "<span class='danger'>[M]'s [limb] is already splinted!</span>")
return
if (M != user)
user.visible_message("<span class='danger'>[user] starts to apply \the [src] to [M]'s [limb].</span>", "<span class='danger'>You start to apply \the [src] to [M]'s [limb].</span>", "<span class='danger'>You hear something being wrapped.</span>")
else
if(( !user.hand && (affecting.organ_tag in list(BP_R_ARM, BP_R_HAND)) || \
user.hand && (affecting.organ_tag in list(BP_L_ARM, BP_L_HAND)) ))
to_chat(user, "<span class='danger'>You can't apply a splint to the arm you're using!</span>")
return
user.visible_message("<span class='danger'>[user] starts to apply \the [src] to their [limb].</span>", "<span class='danger'>You start to apply \the [src] to your [limb].</span>", "<span class='danger'>You hear something being wrapped.</span>")
if(do_after(user, 50, M, exclusive = TASK_USER_EXCLUSIVE))
if(affecting.splinted)
to_chat(user, "<span class='danger'>[M]'s [limb] is already splinted!</span>")
return
if(M == user && prob(75))
user.visible_message("<span class='danger'>\The [user] fumbles [src].</span>", "<span class='danger'>You fumble [src].</span>", "<span class='danger'>You hear something being wrapped.</span>")
return
if(ishuman(user))
var/obj/item/stack/medical/splint/S = split(1)
if(S)
if(affecting.apply_splint(S))
S.forceMove(affecting)
if (M != user)
user.visible_message("<span class='danger'>\The [user] finishes applying [src] to [M]'s [limb].</span>", "<span class='danger'>You finish applying \the [src] to [M]'s [limb].</span>", "<span class='danger'>You hear something being wrapped.</span>")
else
user.visible_message("<span class='danger'>\The [user] successfully applies [src] to their [limb].</span>", "<span class='danger'>You successfully apply \the [src] to your [limb].</span>", "<span class='danger'>You hear something being wrapped.</span>")
return
S.dropInto(src.loc) //didn't get applied, so just drop it
if(isrobot(user))
var/obj/item/stack/medical/splint/B = src
if(B)
if(affecting.apply_splint(B))
B.forceMove(affecting)
user.visible_message("<span class='danger'>\The [user] finishes applying [src] to [M]'s [limb].</span>", "<span class='danger'>You finish applying \the [src] to [M]'s [limb].</span>", "<span class='danger'>You hear something being wrapped.</span>")
B.use(1)
return
user.visible_message("<span class='danger'>\The [user] fails to apply [src].</span>", "<span class='danger'>You fail to apply [src].</span>", "<span class='danger'>You hear something being wrapped.</span>")
return
/obj/item/stack/medical/splint/ghetto
name = "makeshift splints"
singular_name = "makeshift splint"
desc = "For holding your limbs in place with duct tape and scrap metal."
icon_state = "tape-splint"
amount = 1
splintable_organs = list(BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG)
/obj/item/stack/medical
name = "medical pack"
singular_name = "medical pack"
icon = 'icons/obj/stacks.dmi'
amount = 10
max_amount = 10
w_class = ITEMSIZE_SMALL
throw_speed = 4
throw_range = 20
var/heal_brute = 0
var/heal_burn = 0
var/apply_sounds
drop_sound = 'sound/items/drop/cardboardbox.ogg'
pickup_sound = 'sound/items/pickup/cardboardbox.ogg'
var/upgrade_to // The type path this stack can be upgraded to.
/obj/item/stack/medical/attack(mob/living/carbon/M as mob, mob/user as mob)
if (!istype(M))
to_chat(user, "<span class='warning'>\The [src] cannot be applied to [M]!</span>")
return 1
if (!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to do this!</span>")
return 1
var/available = get_amount()
if(!available)
to_chat(user, "<span class='warning'>There's not enough [uses_charge ? "charge" : "items"] left to use that!</span>")
return 1
if (istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
if(!affecting)
to_chat(user, "<span class='warning'>No body part there to work on!</span>")
return 1
if(affecting.organ_tag == BP_HEAD)
if(H.head && istype(H.head,/obj/item/clothing/head/helmet/space))
to_chat(user, "<span class='warning'>You can't apply [src] through [H.head]!</span>")
return 1
else
if(H.wear_suit && istype(H.wear_suit,/obj/item/clothing/suit/space))
to_chat(user, "<span class='warning'>You can't apply [src] through [H.wear_suit]!</span>")
return 1
if(affecting.robotic == ORGAN_ROBOT)
to_chat(user, "<span class='warning'>This isn't useful at all on a robotic limb.</span>")
return 1
if(affecting.robotic >= ORGAN_LIFELIKE)
to_chat(user, "<span class='warning'>You apply the [src], but it seems to have no effect...</span>")
use(1)
return 1
H.UpdateDamageIcon()
else
M.heal_organ_damage((src.heal_brute/2), (src.heal_burn/2))
user.visible_message( \
"<span class='notice'>[M] has been applied with [src] by [user].</span>", \
"<span class='notice'>You apply \the [src] to [M].</span>" \
)
use(1)
M.updatehealth()
/obj/item/stack/medical/proc/upgrade_stack(var/upgrade_amount)
. = FALSE
var/turf/T = get_turf(src)
if(ispath(upgrade_to) && use(upgrade_amount))
var/obj/item/stack/medical/M = new upgrade_to(T, upgrade_amount)
return M
return .
/obj/item/stack/medical/crude_pack
name = "crude bandage"
singular_name = "crude bandage length"
desc = "Some bandages to wrap around bloody stumps."
icon_state = "gauze"
origin_tech = list(TECH_BIO = 1)
no_variants = FALSE
apply_sounds = list('sound/effects/rip1.ogg','sound/effects/rip2.ogg')
upgrade_to = /obj/item/stack/medical/bruise_pack
/obj/item/stack/medical/crude_pack/attack(mob/living/carbon/M as mob, mob/user as mob)
if(..())
return 1
if (istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
if(affecting.open)
to_chat(user, "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>")
return
if(affecting.is_bandaged())
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been bandaged.</span>")
return 1
else
var/available = get_amount()
user.visible_message("<b>\The [user]</b> starts bandaging [M]'s [affecting.name].", \
"<span class='notice'>You start bandaging [M]'s [affecting.name].</span>" )
var/used = 0
for (var/datum/wound/W in affecting.wounds)
if(W.internal)
continue
if(W.bandaged)
continue
if(used == amount)
break
if(!do_mob(user, M, W.damage/3, exclusive = TRUE))
to_chat(user, "<span class='notice'>You must stand still to bandage wounds.</span>")
break
if(affecting.is_bandaged()) // We do a second check after the delay, in case it was bandaged after the first check.
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been bandaged.</span>")
return 1
if(used >= available)
to_chat(user, "<span class='warning'>You run out of [src]!</span>")
break
if (W.current_stage <= W.max_bleeding_stage)
user.visible_message("<b>\The [user]</b> bandages \a [W.desc] on [M]'s [affecting.name].", \
"<span class='notice'>You bandage \a [W.desc] on [M]'s [affecting.name].</span>" )
else
user.visible_message("<b>\The [user]</b> places a bandage over \a [W.desc] on [M]'s [affecting.name].", \
"<span class='notice'>You place a bandage over \a [W.desc] on [M]'s [affecting.name].</span>" )
W.bandage()
playsound(src, pick(apply_sounds), 25)
used++
affecting.update_damages()
if(used == amount)
if(affecting.is_bandaged())
to_chat(user, "<span class='warning'>\The [src] is used up.</span>")
else
to_chat(user, "<span class='warning'>\The [src] is used up, but there are more wounds to treat on \the [affecting.name].</span>")
use(used)
/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 = "brutepack"
origin_tech = list(TECH_BIO = 1)
no_variants = FALSE
apply_sounds = list('sound/effects/rip1.ogg','sound/effects/rip2.ogg')
drop_sound = 'sound/items/drop/gloves.ogg'
pickup_sound = 'sound/items/pickup/gloves.ogg'
upgrade_to = /obj/item/stack/medical/advanced/bruise_pack
/obj/item/stack/medical/bruise_pack/attack(mob/living/carbon/M as mob, mob/user as mob)
if(..())
return 1
if (istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
if(affecting.open)
to_chat(user, "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>")
return
if(affecting.is_bandaged())
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been bandaged.</span>")
return 1
else
var/available = get_amount()
user.visible_message("<b>\The [user]</b> starts treating [M]'s [affecting.name].", \
"<span class='notice'>You start treating [M]'s [affecting.name].</span>" )
var/used = 0
for (var/datum/wound/W in affecting.wounds)
if (W.internal)
continue
if(W.bandaged)
continue
if(used == amount)
break
if(!do_mob(user, M, W.damage/5, exclusive = TRUE))
to_chat(user, "<span class='notice'>You must stand still to bandage wounds.</span>")
break
if(affecting.is_bandaged()) // We do a second check after the delay, in case it was bandaged after the first check.
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been bandaged.</span>")
return 1
if(used >= available)
to_chat(user, "<span class='warning'>You run out of [src]!</span>")
break
if (W.current_stage <= W.max_bleeding_stage)
user.visible_message("<b>\The [user]</b> bandages \a [W.desc] on [M]'s [affecting.name].", \
"<span class='notice'>You bandage \a [W.desc] on [M]'s [affecting.name].</span>" )
//H.add_side_effect("Itch")
else if (W.damage_type == BRUISE)
user.visible_message("<b>\The [user]</b> places a bruise patch over \a [W.desc] on [M]'s [affecting.name].", \
"<span class='notice'>You place a bruise patch over \a [W.desc] on [M]'s [affecting.name].</span>" )
else
user.visible_message("<b>\The [user]</b> places a bandaid over \a [W.desc] on [M]'s [affecting.name].", \
"<span class='notice'>You place a bandaid over \a [W.desc] on [M]'s [affecting.name].</span>" )
W.bandage()
// W.disinfect() // VOREStation - Tech1 should not disinfect
playsound(src, pick(apply_sounds), 25)
used++
affecting.update_damages()
if(used == amount)
if(affecting.is_bandaged())
to_chat(user, "<span class='warning'>\The [src] is used up.</span>")
else
to_chat(user, "<span class='warning'>\The [src] is used up, but there are more wounds to treat on \the [affecting.name].</span>")
use(used)
/obj/item/stack/medical/ointment
name = "ointment"
desc = "Used to treat those nasty burns."
gender = PLURAL
singular_name = "ointment"
icon_state = "ointment"
heal_burn = 1
origin_tech = list(TECH_BIO = 1)
no_variants = FALSE
apply_sounds = list('sound/effects/ointment.ogg')
drop_sound = 'sound/items/drop/herb.ogg'
pickup_sound = 'sound/items/pickup/herb.ogg'
/obj/item/stack/medical/ointment/attack(mob/living/carbon/M as mob, mob/user as mob)
if(..())
return 1
if (istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
if(affecting.open)
to_chat(user, "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>")
return
if(affecting.is_salved())
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been salved.</span>")
return 1
else
user.visible_message("<b>\The [user]</b> starts salving wounds on [M]'s [affecting.name].", \
"<span class='notice'>You start salving the wounds on [M]'s [affecting.name].</span>" )
if(!do_mob(user, M, 10, exclusive = TRUE))
to_chat(user, "<span class='notice'>You must stand still to salve wounds.</span>")
return 1
if(affecting.is_salved()) // We do a second check after the delay, in case it was bandaged after the first check.
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been salved.</span>")
return 1
user.visible_message("<span class='notice'>[user] salved wounds on [M]'s [affecting.name].</span>", \
"<span class='notice'>You salved wounds on [M]'s [affecting.name].</span>" )
use(1)
affecting.salve()
playsound(src, pick(apply_sounds), 25)
/obj/item/stack/medical/ointment/simple
name = "ointment paste"
desc = "A simple thick paste used to salve burns."
singular_name = "old-ointment"
icon_state = "old-ointment"
/obj/item/stack/medical/advanced/bruise_pack
name = "advanced trauma kit"
singular_name = "advanced trauma kit"
desc = "An advanced trauma kit for severe injuries."
icon_state = "traumakit"
heal_brute = 7 //VOREStation Edit
origin_tech = list(TECH_BIO = 1)
apply_sounds = list('sound/effects/rip1.ogg','sound/effects/rip2.ogg','sound/effects/tape.ogg')
/obj/item/stack/medical/advanced/bruise_pack/attack(mob/living/carbon/M as mob, mob/user as mob)
if(..())
return 1
if (istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
if(affecting.open)
to_chat(user, "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>")
return
if(affecting.is_bandaged() && affecting.is_disinfected())
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been treated.</span>")
return 1
else
var/available = get_amount()
user.visible_message("<b>\The [user]</b> starts treating [M]'s [affecting.name].", \
"<span class='notice'>You start treating [M]'s [affecting.name].</span>" )
var/used = 0
for (var/datum/wound/W in affecting.wounds)
if (W.internal)
continue
if (W.bandaged && W.disinfected)
continue
//if(used == amount) //VOREStation Edit
// break //VOREStation Edit
if(!do_mob(user, M, W.damage/5, exclusive = TRUE))
to_chat(user, "<span class='notice'>You must stand still to bandage wounds.</span>")
break
if(affecting.is_bandaged() && affecting.is_disinfected()) // We do a second check after the delay, in case it was bandaged after the first check.
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been bandaged.</span>")
return 1
if(used >= available)
to_chat(user, "<span class='warning'>You run out of [src]!</span>")
break
if (W.current_stage <= W.max_bleeding_stage)
user.visible_message("<b>\The [user]</b> cleans \a [W.desc] on [M]'s [affecting.name] and seals the edges with bioglue.", \
"<span class='notice'>You clean and seal \a [W.desc] on [M]'s [affecting.name].</span>" )
else if (W.damage_type == BRUISE)
user.visible_message("<b>\The [user]</b> places a medical patch over \a [W.desc] on [M]'s [affecting.name].", \
"<span class='notice'>You place a medical patch over \a [W.desc] on [M]'s [affecting.name].</span>" )
else
user.visible_message("<b>\The [user]</b> smears some bioglue over \a [W.desc] on [M]'s [affecting.name].", \
"<span class='notice'>You smear some bioglue over \a [W.desc] on [M]'s [affecting.name].</span>" )
W.bandage()
W.disinfect()
W.heal_damage(heal_brute)
playsound(src, pick(apply_sounds), 25)
used = 1 //VOREStation Edit
update_icon() // VOREStation Edit - Support for stack icons
affecting.update_damages()
if(used == amount)
if(affecting.is_bandaged())
to_chat(user, "<span class='warning'>\The [src] is used up.</span>")
else
to_chat(user, "<span class='warning'>\The [src] is used up, but there are more wounds to treat on \the [affecting.name].</span>")
use(used)
/obj/item/stack/medical/advanced/ointment
name = "advanced burn kit"
singular_name = "advanced burn kit"
desc = "An advanced treatment kit for severe burns."
icon_state = "burnkit"
heal_burn = 7 //VOREStation Edit
origin_tech = list(TECH_BIO = 1)
apply_sounds = list('sound/effects/ointment.ogg')
/obj/item/stack/medical/advanced/ointment/attack(mob/living/carbon/M as mob, mob/user as mob)
if(..())
return 1
if (istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
if(affecting.open)
to_chat(user, "<span class='notice'>The [affecting.name] is cut open, you'll need more than a bandage!</span>")
if(affecting.is_salved())
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been salved.</span>")
return 1
else
user.visible_message("<b>\The [user]</b> starts salving wounds on [M]'s [affecting.name].", \
"<span class='notice'>You start salving the wounds on [M]'s [affecting.name].</span>" )
if(!do_mob(user, M, 10, exclusive = TRUE))
to_chat(user, "<span class='notice'>You must stand still to salve wounds.</span>")
return 1
if(affecting.is_salved()) // We do a second check after the delay, in case it was bandaged after the first check.
to_chat(user, "<span class='warning'>The wounds on [M]'s [affecting.name] have already been salved.</span>")
return 1
user.visible_message( "<span class='notice'>[user] covers wounds on [M]'s [affecting.name] with regenerative membrane.</span>", \
"<span class='notice'>You cover wounds on [M]'s [affecting.name] with regenerative membrane.</span>" )
affecting.heal_damage(0,heal_burn)
use(1)
affecting.salve()
playsound(src, pick(apply_sounds), 25)
update_icon() // VOREStation Edit - Support for stack icons
/obj/item/stack/medical/splint
name = "medical splints"
singular_name = "medical splint"
desc = "Modular splints capable of supporting and immobilizing bones in all areas of the body."
icon_state = "splint"
amount = 5
max_amount = 5
drop_sound = 'sound/items/drop/hat.ogg'
pickup_sound = 'sound/items/pickup/hat.ogg'
var/list/splintable_organs = list(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_ARM, BP_R_ARM, BP_L_FOOT, BP_R_FOOT, BP_L_LEG, BP_R_LEG, BP_GROIN, BP_TORSO) //List of organs you can splint, natch.
/obj/item/stack/medical/splint/attack(mob/living/carbon/M as mob, mob/living/user as mob)
if(..())
return 1
if (istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
var/limb = affecting.name
if(!(affecting.organ_tag in splintable_organs))
to_chat(user, "<span class='danger'>You can't use \the [src] to apply a splint there!</span>")
return
if(affecting.splinted)
to_chat(user, "<span class='danger'>[M]'s [limb] is already splinted!</span>")
return
if (M != user)
user.visible_message("<span class='danger'>[user] starts to apply \the [src] to [M]'s [limb].</span>", "<span class='danger'>You start to apply \the [src] to [M]'s [limb].</span>", "<span class='danger'>You hear something being wrapped.</span>")
else
if(( !user.hand && (affecting.organ_tag in list(BP_R_ARM, BP_R_HAND)) || \
user.hand && (affecting.organ_tag in list(BP_L_ARM, BP_L_HAND)) ))
to_chat(user, "<span class='danger'>You can't apply a splint to the arm you're using!</span>")
return
user.visible_message("<span class='danger'>[user] starts to apply \the [src] to their [limb].</span>", "<span class='danger'>You start to apply \the [src] to your [limb].</span>", "<span class='danger'>You hear something being wrapped.</span>")
if(do_after(user, 50, M, exclusive = TASK_USER_EXCLUSIVE))
if(affecting.splinted)
to_chat(user, "<span class='danger'>[M]'s [limb] is already splinted!</span>")
return
if(M == user && prob(75))
user.visible_message("<span class='danger'>\The [user] fumbles [src].</span>", "<span class='danger'>You fumble [src].</span>", "<span class='danger'>You hear something being wrapped.</span>")
return
if(ishuman(user))
var/obj/item/stack/medical/splint/S = split(1)
if(S)
if(affecting.apply_splint(S))
S.forceMove(affecting)
if (M != user)
user.visible_message("<span class='danger'>\The [user] finishes applying [src] to [M]'s [limb].</span>", "<span class='danger'>You finish applying \the [src] to [M]'s [limb].</span>", "<span class='danger'>You hear something being wrapped.</span>")
else
user.visible_message("<span class='danger'>\The [user] successfully applies [src] to their [limb].</span>", "<span class='danger'>You successfully apply \the [src] to your [limb].</span>", "<span class='danger'>You hear something being wrapped.</span>")
return
S.dropInto(src.loc) //didn't get applied, so just drop it
if(isrobot(user))
var/obj/item/stack/medical/splint/B = src
if(B)
if(affecting.apply_splint(B))
B.forceMove(affecting)
user.visible_message("<span class='danger'>\The [user] finishes applying [src] to [M]'s [limb].</span>", "<span class='danger'>You finish applying \the [src] to [M]'s [limb].</span>", "<span class='danger'>You hear something being wrapped.</span>")
B.use(1)
return
user.visible_message("<span class='danger'>\The [user] fails to apply [src].</span>", "<span class='danger'>You fail to apply [src].</span>", "<span class='danger'>You hear something being wrapped.</span>")
return
/obj/item/stack/medical/splint/ghetto
name = "makeshift splints"
singular_name = "makeshift splint"
desc = "For holding your limbs in place with duct tape and scrap metal."
icon_state = "tape-splint"
amount = 1
splintable_organs = list(BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG)
+373 -373
View File
@@ -1,373 +1,373 @@
/* Diffrent misc types of tiles
* Contains:
* Prototype
* Grass
* Wood
* Carpet
* Blue Carpet
* Linoleum
*
* Put your stuff in fifty_stacks_tiles.dm as well.
*/
/obj/item/stack/tile
name = "tile"
singular_name = "tile"
desc = "A non-descript floor tile"
randpixel = 7
w_class = ITEMSIZE_NORMAL
max_amount = 60
drop_sound = 'sound/items/drop/axe.ogg'
pickup_sound = 'sound/items/pickup/axe.ogg'
//crafting / welding vars
var/datum/material/material //*sigh* i guess this is how we're doing this.
var/craftable = FALSE //set to TRUE for tiles you can craft stuff from directly, like grass
var/can_weld = FALSE //set to TRUE for tiles you can reforge into their components via welding, like metal
var/welds_into = /obj/item/stack/material/steel //what you get from the welding. defaults to steel.
var/default_type = DEFAULT_WALL_MATERIAL
/obj/item/stack/tile/Initialize()
. = ..()
randpixel_xy()
if(craftable)
material = get_material_by_name("[default_type]")
if(!material)
return INITIALIZE_HINT_QDEL
if(material) //sanity check
recipes = material.get_recipes()
stacktype = material.stack_type
/obj/item/stack/tile/attackby(obj/item/W as obj, mob/user as mob)
if (W.has_tool_quality(TOOL_WELDER))
var/obj/item/weapon/weldingtool/WT = W.get_welder()
if(can_weld == FALSE)
to_chat("You can't reform these into their original components.")
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))
new welds_into(usr.loc)
usr.update_icon()
visible_message("<span class='notice'>\The [src] is shaped by [user.name] with the welding tool.</span>","You hear welding.")
var/obj/item/stack/tile/T = src
src = null
var/replace = (user.get_inactive_hand()==T)
T.use(4)
if (!T && replace)
user.put_in_hands(welds_into)
return TRUE
return ..()
/*
* Grass
*/
/obj/item/stack/tile/grass
name = "grass tile"
singular_name = "grass floor tile"
desc = "A patch of grass like they often use on golf courses."
icon_state = "tile_grass"
default_type = "grass"
force = 1.0
throwforce = 1.0
throw_speed = 5
throw_range = 20
flags = 0
origin_tech = list(TECH_BIO = 1)
no_variants = FALSE
drop_sound = 'sound/items/drop/herb.ogg'
pickup_sound = 'sound/items/pickup/herb.ogg'
craftable = TRUE
/*
* Wood
*/
/obj/item/stack/tile/wood
name = "wood floor tile"
singular_name = "wood floor tile"
desc = "An easy to fit wooden floor tile."
icon_state = "tile-wood"
force = 1.0
throwforce = 1.0
throw_speed = 5
throw_range = 20
flags = 0
no_variants = FALSE
drop_sound = 'sound/items/drop/wooden.ogg'
pickup_sound = 'sound/items/pickup/wooden.ogg'
/obj/item/stack/tile/wood/sif
name = "alien wood tile"
singular_name = "alien wood tile"
desc = "An easy to fit wooden floor tile. It's blue!"
icon_state = "tile-sifwood"
/obj/item/stack/tile/wood/alt
name = "wood floor tile"
singular_name = "wood floor tile"
icon_state = "tile-wood_tile"
/obj/item/stack/tile/wood/parquet
name = "parquet wood floor tile"
singular_name = "parquet wood floor tile"
icon_state = "tile-wood_parquet"
/obj/item/stack/tile/wood/panel
name = "large wood floor tile"
singular_name = "large wood floor tile"
icon_state = "tile-wood_large"
/obj/item/stack/tile/wood/tile
name = "tiled wood floor tile"
singular_name = "tiled wood floor tile"
icon_state = "tile-wood_tile"
/obj/item/stack/tile/wood/cyborg
name = "wood floor tile synthesizer"
desc = "A device that makes wood floor tiles."
uses_charge = 1
charge_costs = list(250)
stacktype = /obj/item/stack/tile/wood
build_type = /obj/item/stack/tile/wood
/*
* Carpets
*/
/obj/item/stack/tile/carpet
name = "carpet"
singular_name = "carpet"
desc = "A piece of carpet. It is the same size as a normal floor tile!"
icon_state = "tile-carpet"
force = 1.0
throwforce = 1.0
throw_speed = 5
throw_range = 20
flags = 0
no_variants = FALSE
drop_sound = 'sound/items/drop/cloth.ogg'
pickup_sound = 'sound/items/pickup/cloth.ogg'
/obj/item/stack/tile/carpet/teal
desc = "A piece of teal carpet. It is the same size as a normal floor tile!"
icon_state = "tile-tealcarpet"
/obj/item/stack/tile/carpet/turcarpet
desc = "A piece of turqoise carpet. It is the same size as a normal floor tile!"
icon_state = "tile-turcarpet"
/obj/item/stack/tile/carpet/bcarpet
desc = "A piece of black diamond-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-bcarpet"
/obj/item/stack/tile/carpet/blucarpet
desc = "A piece of blue diamond-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-blucarpet"
/obj/item/stack/tile/carpet/sblucarpet
desc = "A piece of silver-blue diamond-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-sblucarpet"
/obj/item/stack/tile/carpet/gaycarpet
desc = "A piece of pink diamond-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-gaycarpet"
/obj/item/stack/tile/carpet/purcarpet
desc = "A piece of purple diamond-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-purcarpet"
/obj/item/stack/tile/carpet/oracarpet
desc = "A piece of orange diamond-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-oracarpet"
/obj/item/stack/tile/carpet/brncarpet
desc = "A piece of brown ornate-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-brncarpet"
/obj/item/stack/tile/carpet/blucarpet2
desc = "A piece of blue ornate-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-blucarpet2"
/obj/item/stack/tile/carpet/greencarpet
desc = "A piece of green ornate-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-greencarpet"
/obj/item/stack/tile/carpet/purplecarpet
desc = "A piece of purple ornate-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-purplecarpet"
/obj/item/stack/tile/carpet/geo
icon_state = "tile-carpet-deco"
desc = "A piece of carpet with a gnarly geometric design. It is the same size as a normal floor tile!"
/obj/item/stack/tile/carpet/retro
icon_state = "tile-carpet-retro"
desc = "A piece of carpet with totally wicked blue space patterns. It is the same size as a normal floor tile!"
/obj/item/stack/tile/carpet/retro_red
icon_state = "tile-carpet-retro-red"
desc = "A piece of carpet with red-ical space patterns. It is the same size as a normal floor tile!"
/obj/item/stack/tile/carpet/happy
icon_state = "tile-carpet-happy"
desc = "A piece of carpet with happy patterns. It is the same size as a normal floor tile!"
/obj/item/stack/tile/floor
name = "floor tile"
singular_name = "floor tile"
desc = "A metal tile fit for covering a section of floor."
icon_state = "tile"
force = 6.0
matter = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT / 4)
throwforce = 15.0
throw_speed = 5
throw_range = 20
no_variants = FALSE
can_weld = TRUE
/obj/item/stack/tile/floor/red
name = "red floor tile"
singular_name = "red floor tile"
color = COLOR_RED_GRAY
icon_state = "tile_white"
no_variants = FALSE
/obj/item/stack/tile/floor/techgrey
name = "grey techfloor tile"
singular_name = "grey techfloor tile"
icon_state = "techtile_grey"
no_variants = FALSE
/obj/item/stack/tile/floor/techgrid
name = "grid techfloor tile"
singular_name = "grid techfloor tile"
icon_state = "techtile_grid"
no_variants = FALSE
/obj/item/stack/tile/floor/techmaint
name = "maint techfloor tile"
singular_name = "maint techfloor tile"
icon_state = "techtile_maint"
no_variants = FALSE
/obj/item/stack/tile/floor/steel_dirty
name = "steel floor tile"
singular_name = "steel floor tile"
icon_state = "tile_steel"
matter = list(MAT_PLASTEEL = SHEET_MATERIAL_AMOUNT / 4)
welds_into = /obj/item/stack/material/plasteel
no_variants = FALSE
/obj/item/stack/tile/floor/steel
name = "steel floor tile"
singular_name = "steel floor tile"
icon_state = "tile_steel"
matter = list(MAT_PLASTEEL = SHEET_MATERIAL_AMOUNT / 4)
welds_into = /obj/item/stack/material/plasteel
no_variants = FALSE
/obj/item/stack/tile/floor/white
name = "white floor tile"
singular_name = "white floor tile"
icon_state = "tile_white"
matter = list(MAT_PLASTIC = SHEET_MATERIAL_AMOUNT / 4)
welds_into = /obj/item/stack/material/plastic
no_variants = FALSE
/obj/item/stack/tile/floor/yellow
name = "yellow floor tile"
singular_name = "yellow floor tile"
color = COLOR_BROWN
icon_state = "tile_white"
no_variants = FALSE
/obj/item/stack/tile/floor/dark
name = "dark floor tile"
singular_name = "dark floor tile"
icon_state = "tile_steel"
matter = list(MAT_PLASTEEL = SHEET_MATERIAL_AMOUNT / 4)
welds_into = /obj/item/stack/material/plasteel
no_variants = FALSE
/obj/item/stack/tile/floor/freezer
name = "freezer floor tile"
singular_name = "freezer floor tile"
icon_state = "tile_freezer"
matter = list(MAT_PLASTIC = SHEET_MATERIAL_AMOUNT / 4)
welds_into = /obj/item/stack/material/plastic
no_variants = FALSE
/obj/item/stack/tile/floor/cyborg
name = "floor tile synthesizer"
desc = "A device that makes floor tiles."
gender = NEUTER
matter = null
uses_charge = 1
charge_costs = list(250)
stacktype = /obj/item/stack/tile/floor
build_type = /obj/item/stack/tile/floor
can_weld = FALSE //we're not going there
/obj/item/stack/tile/linoleum
name = "linoleum"
singular_name = "linoleum"
desc = "A piece of linoleum. It is the same size as a normal floor tile!"
icon_state = "tile-linoleum"
force = 1.0
throwforce = 1.0
throw_speed = 5
throw_range = 20
flags = 0
no_variants = FALSE
can_weld = FALSE
/obj/item/stack/tile/wmarble
name = "light marble tile"
singular_name = "light marble tile"
desc = "Some white marble tiles used for flooring."
icon_state = "tile-wmarble"
force = 6.0
throwforce = 15.0
throw_speed = 5
throw_range = 20
flags = 0
no_variants = FALSE
can_weld = TRUE
welds_into = /obj/item/stack/material/marble
/obj/item/stack/tile/bmarble
name = "dark marble tile"
singular_name = "dark marble tile"
desc = "Some black marble tiles used for flooring."
icon_state = "tile-bmarble"
force = 6.0
throwforce = 15.0
throw_speed = 5
throw_range = 20
flags = 0
no_variants = FALSE
can_weld = TRUE
welds_into = /obj/item/stack/material/marble
/obj/item/stack/tile/roofing
name = "roofing"
singular_name = "roofing"
desc = "A section of roofing material. You can use it to repair the ceiling, or expand it."
icon_state = "techtile_grid"
can_weld = FALSE //roofing can also be made from wood, so let's not open that can of worms today
/obj/item/stack/tile/roofing/cyborg
name = "roofing synthesizer"
desc = "A device that makes roofing tiles."
uses_charge = 1
charge_costs = list(250)
stacktype = /obj/item/stack/tile/roofing
build_type = /obj/item/stack/tile/roofing
can_weld = FALSE
/* Diffrent misc types of tiles
* Contains:
* Prototype
* Grass
* Wood
* Carpet
* Blue Carpet
* Linoleum
*
* Put your stuff in fifty_stacks_tiles.dm as well.
*/
/obj/item/stack/tile
name = "tile"
singular_name = "tile"
desc = "A non-descript floor tile"
randpixel = 7
w_class = ITEMSIZE_NORMAL
max_amount = 60
drop_sound = 'sound/items/drop/axe.ogg'
pickup_sound = 'sound/items/pickup/axe.ogg'
//crafting / welding vars
var/datum/material/material //*sigh* i guess this is how we're doing this.
var/craftable = FALSE //set to TRUE for tiles you can craft stuff from directly, like grass
var/can_weld = FALSE //set to TRUE for tiles you can reforge into their components via welding, like metal
var/welds_into = /obj/item/stack/material/steel //what you get from the welding. defaults to steel.
var/default_type = DEFAULT_WALL_MATERIAL
/obj/item/stack/tile/Initialize()
. = ..()
randpixel_xy()
if(craftable)
material = get_material_by_name("[default_type]")
if(!material)
return INITIALIZE_HINT_QDEL
if(material) //sanity check
recipes = material.get_recipes()
stacktype = material.stack_type
/obj/item/stack/tile/attackby(obj/item/W as obj, mob/user as mob)
if (W.has_tool_quality(TOOL_WELDER))
var/obj/item/weapon/weldingtool/WT = W.get_welder()
if(can_weld == FALSE)
to_chat("You can't reform these into their original components.")
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))
new welds_into(usr.loc)
usr.update_icon()
visible_message("<span class='notice'>\The [src] is shaped by [user.name] with the welding tool.</span>","You hear welding.")
var/obj/item/stack/tile/T = src
src = null
var/replace = (user.get_inactive_hand()==T)
T.use(4)
if (!T && replace)
user.put_in_hands(welds_into)
return TRUE
return ..()
/*
* Grass
*/
/obj/item/stack/tile/grass
name = "grass tile"
singular_name = "grass floor tile"
desc = "A patch of grass like they often use on golf courses."
icon_state = "tile_grass"
default_type = "grass"
force = 1.0
throwforce = 1.0
throw_speed = 5
throw_range = 20
flags = 0
origin_tech = list(TECH_BIO = 1)
no_variants = FALSE
drop_sound = 'sound/items/drop/herb.ogg'
pickup_sound = 'sound/items/pickup/herb.ogg'
craftable = TRUE
/*
* Wood
*/
/obj/item/stack/tile/wood
name = "wood floor tile"
singular_name = "wood floor tile"
desc = "An easy to fit wooden floor tile."
icon_state = "tile-wood"
force = 1.0
throwforce = 1.0
throw_speed = 5
throw_range = 20
flags = 0
no_variants = FALSE
drop_sound = 'sound/items/drop/wooden.ogg'
pickup_sound = 'sound/items/pickup/wooden.ogg'
/obj/item/stack/tile/wood/sif
name = "alien wood tile"
singular_name = "alien wood tile"
desc = "An easy to fit wooden floor tile. It's blue!"
icon_state = "tile-sifwood"
/obj/item/stack/tile/wood/alt
name = "wood floor tile"
singular_name = "wood floor tile"
icon_state = "tile-wood_tile"
/obj/item/stack/tile/wood/parquet
name = "parquet wood floor tile"
singular_name = "parquet wood floor tile"
icon_state = "tile-wood_parquet"
/obj/item/stack/tile/wood/panel
name = "large wood floor tile"
singular_name = "large wood floor tile"
icon_state = "tile-wood_large"
/obj/item/stack/tile/wood/tile
name = "tiled wood floor tile"
singular_name = "tiled wood floor tile"
icon_state = "tile-wood_tile"
/obj/item/stack/tile/wood/cyborg
name = "wood floor tile synthesizer"
desc = "A device that makes wood floor tiles."
uses_charge = 1
charge_costs = list(250)
stacktype = /obj/item/stack/tile/wood
build_type = /obj/item/stack/tile/wood
/*
* Carpets
*/
/obj/item/stack/tile/carpet
name = "carpet"
singular_name = "carpet"
desc = "A piece of carpet. It is the same size as a normal floor tile!"
icon_state = "tile-carpet"
force = 1.0
throwforce = 1.0
throw_speed = 5
throw_range = 20
flags = 0
no_variants = FALSE
drop_sound = 'sound/items/drop/cloth.ogg'
pickup_sound = 'sound/items/pickup/cloth.ogg'
/obj/item/stack/tile/carpet/teal
desc = "A piece of teal carpet. It is the same size as a normal floor tile!"
icon_state = "tile-tealcarpet"
/obj/item/stack/tile/carpet/turcarpet
desc = "A piece of turqoise carpet. It is the same size as a normal floor tile!"
icon_state = "tile-turcarpet"
/obj/item/stack/tile/carpet/bcarpet
desc = "A piece of black diamond-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-bcarpet"
/obj/item/stack/tile/carpet/blucarpet
desc = "A piece of blue diamond-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-blucarpet"
/obj/item/stack/tile/carpet/sblucarpet
desc = "A piece of silver-blue diamond-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-sblucarpet"
/obj/item/stack/tile/carpet/gaycarpet
desc = "A piece of pink diamond-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-gaycarpet"
/obj/item/stack/tile/carpet/purcarpet
desc = "A piece of purple diamond-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-purcarpet"
/obj/item/stack/tile/carpet/oracarpet
desc = "A piece of orange diamond-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-oracarpet"
/obj/item/stack/tile/carpet/brncarpet
desc = "A piece of brown ornate-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-brncarpet"
/obj/item/stack/tile/carpet/blucarpet2
desc = "A piece of blue ornate-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-blucarpet2"
/obj/item/stack/tile/carpet/greencarpet
desc = "A piece of green ornate-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-greencarpet"
/obj/item/stack/tile/carpet/purplecarpet
desc = "A piece of purple ornate-pattern carpet. It is the same size as a normal floor tile!"
icon_state = "tile-purplecarpet"
/obj/item/stack/tile/carpet/geo
icon_state = "tile-carpet-deco"
desc = "A piece of carpet with a gnarly geometric design. It is the same size as a normal floor tile!"
/obj/item/stack/tile/carpet/retro
icon_state = "tile-carpet-retro"
desc = "A piece of carpet with totally wicked blue space patterns. It is the same size as a normal floor tile!"
/obj/item/stack/tile/carpet/retro_red
icon_state = "tile-carpet-retro-red"
desc = "A piece of carpet with red-ical space patterns. It is the same size as a normal floor tile!"
/obj/item/stack/tile/carpet/happy
icon_state = "tile-carpet-happy"
desc = "A piece of carpet with happy patterns. It is the same size as a normal floor tile!"
/obj/item/stack/tile/floor
name = "floor tile"
singular_name = "floor tile"
desc = "A metal tile fit for covering a section of floor."
icon_state = "tile"
force = 6.0
matter = list(DEFAULT_WALL_MATERIAL = SHEET_MATERIAL_AMOUNT / 4)
throwforce = 15.0
throw_speed = 5
throw_range = 20
no_variants = FALSE
can_weld = TRUE
/obj/item/stack/tile/floor/red
name = "red floor tile"
singular_name = "red floor tile"
color = COLOR_RED_GRAY
icon_state = "tile_white"
no_variants = FALSE
/obj/item/stack/tile/floor/techgrey
name = "grey techfloor tile"
singular_name = "grey techfloor tile"
icon_state = "techtile_grey"
no_variants = FALSE
/obj/item/stack/tile/floor/techgrid
name = "grid techfloor tile"
singular_name = "grid techfloor tile"
icon_state = "techtile_grid"
no_variants = FALSE
/obj/item/stack/tile/floor/techmaint
name = "maint techfloor tile"
singular_name = "maint techfloor tile"
icon_state = "techtile_maint"
no_variants = FALSE
/obj/item/stack/tile/floor/steel_dirty
name = "steel floor tile"
singular_name = "steel floor tile"
icon_state = "tile_steel"
matter = list(MAT_PLASTEEL = SHEET_MATERIAL_AMOUNT / 4)
welds_into = /obj/item/stack/material/plasteel
no_variants = FALSE
/obj/item/stack/tile/floor/steel
name = "steel floor tile"
singular_name = "steel floor tile"
icon_state = "tile_steel"
matter = list(MAT_PLASTEEL = SHEET_MATERIAL_AMOUNT / 4)
welds_into = /obj/item/stack/material/plasteel
no_variants = FALSE
/obj/item/stack/tile/floor/white
name = "white floor tile"
singular_name = "white floor tile"
icon_state = "tile_white"
matter = list(MAT_PLASTIC = SHEET_MATERIAL_AMOUNT / 4)
welds_into = /obj/item/stack/material/plastic
no_variants = FALSE
/obj/item/stack/tile/floor/yellow
name = "yellow floor tile"
singular_name = "yellow floor tile"
color = COLOR_BROWN
icon_state = "tile_white"
no_variants = FALSE
/obj/item/stack/tile/floor/dark
name = "dark floor tile"
singular_name = "dark floor tile"
icon_state = "tile_steel"
matter = list(MAT_PLASTEEL = SHEET_MATERIAL_AMOUNT / 4)
welds_into = /obj/item/stack/material/plasteel
no_variants = FALSE
/obj/item/stack/tile/floor/freezer
name = "freezer floor tile"
singular_name = "freezer floor tile"
icon_state = "tile_freezer"
matter = list(MAT_PLASTIC = SHEET_MATERIAL_AMOUNT / 4)
welds_into = /obj/item/stack/material/plastic
no_variants = FALSE
/obj/item/stack/tile/floor/cyborg
name = "floor tile synthesizer"
desc = "A device that makes floor tiles."
gender = NEUTER
matter = null
uses_charge = 1
charge_costs = list(250)
stacktype = /obj/item/stack/tile/floor
build_type = /obj/item/stack/tile/floor
can_weld = FALSE //we're not going there
/obj/item/stack/tile/linoleum
name = "linoleum"
singular_name = "linoleum"
desc = "A piece of linoleum. It is the same size as a normal floor tile!"
icon_state = "tile-linoleum"
force = 1.0
throwforce = 1.0
throw_speed = 5
throw_range = 20
flags = 0
no_variants = FALSE
can_weld = FALSE
/obj/item/stack/tile/wmarble
name = "light marble tile"
singular_name = "light marble tile"
desc = "Some white marble tiles used for flooring."
icon_state = "tile-wmarble"
force = 6.0
throwforce = 15.0
throw_speed = 5
throw_range = 20
flags = 0
no_variants = FALSE
can_weld = TRUE
welds_into = /obj/item/stack/material/marble
/obj/item/stack/tile/bmarble
name = "dark marble tile"
singular_name = "dark marble tile"
desc = "Some black marble tiles used for flooring."
icon_state = "tile-bmarble"
force = 6.0
throwforce = 15.0
throw_speed = 5
throw_range = 20
flags = 0
no_variants = FALSE
can_weld = TRUE
welds_into = /obj/item/stack/material/marble
/obj/item/stack/tile/roofing
name = "roofing"
singular_name = "roofing"
desc = "A section of roofing material. You can use it to repair the ceiling, or expand it."
icon_state = "techtile_grid"
can_weld = FALSE //roofing can also be made from wood, so let's not open that can of worms today
/obj/item/stack/tile/roofing/cyborg
name = "roofing synthesizer"
desc = "A device that makes roofing tiles."
uses_charge = 1
charge_costs = list(250)
stacktype = /obj/item/stack/tile/roofing
build_type = /obj/item/stack/tile/roofing
can_weld = FALSE
+490 -490
View File
@@ -1,491 +1,491 @@
//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 = ITEMSIZE_SMALL
desc = "This is rubbish."
drop_sound = 'sound/items/drop/wrapper.ogg'
pickup_sound = 'sound/items/pickup/wrapper.ogg'
matter = list(MAT_STEEL = 30)
var/age = 0
/obj/item/trash/New(var/newloc, var/_age)
..(newloc)
if(!isnull(_age))
age = _age
/obj/item/trash/Initialize(mapload)
if(!mapload || !config.persistence_ignore_mapload)
SSpersistence.track_value(src, /datum/persistent/filth/trash)
. = ..()
/obj/item/trash/Destroy()
SSpersistence.forget_value(src, /datum/persistent/filth/trash)
. = ..()
/obj/item/trash/raisins
name = "\improper 4no raisins"
icon_state = "4no_raisins"
/obj/item/trash/candy
name = "hard candy wrapper"
icon_state = "candy"
/obj/item/trash/candy/gums
name = "gummy candy bag"
icon_state = "candy_gums"
/obj/item/trash/candy/proteinbar
name = "protein bar wrapper"
icon_state = "proteinbar"
/obj/item/trash/candy/fruitbar
name = "fruit bar wrapper"
icon_state = "fruitbar"
/obj/item/trash/cheesie
name = "\improper Cheesie Honkers bag"
icon_state = "cheesie_honkers"
/obj/item/trash/chips
name = "chips bag"
icon_state = "chips"
/obj/item/trash/chips/bbq
name = "bbq chips bag"
icon_state = "chips_bbq"
/obj/item/trash/chips/snv
name = "salt & vinegar chips bag"
icon_state = "chips_snv"
/obj/item/trash/cookiesnack
name = "\improper Carps Ahoy! miniature cookies packet"
icon_state = "cookiesnack"
/obj/item/trash/popcorn
name = "popcorn bag"
icon_state = "popcorn"
/obj/item/trash/tuna
name = "fish flake packet"
icon_state = "tuna"
/obj/item/trash/sosjerky
name = "Scaredy's Private Reserve Beef Jerky wrapper"
icon_state = "sosjerky"
/obj/item/trash/unajerky
name = "Moghes Imported Sissalik Jerky tin"
icon_state = "unathitinred"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/syndi_cakes
name = "syndi cakes box"
icon_state = "syndi_cakes"
/obj/item/trash/waffles
name = "waffles tray"
icon_state = "waffles"
/obj/item/trash/plate
name = "plate"
icon_state = "plate"
drop_sound = 'sound/items/drop/food.ogg'
pickup_sound = 'sound/items/pickup/food.ogg'
/obj/item/trash/asian_bowl
name = "asian bowl"
icon_state = "asian_bowl"
drop_sound = 'sound/items/drop/food.ogg'
pickup_sound = 'sound/items/pickup/food.ogg'
/obj/item/trash/snack_bowl
name = "snack bowl"
icon_state = "snack_bowl"
drop_sound = 'sound/items/drop/food.ogg'
pickup_sound = 'sound/items/pickup/food.ogg'
/obj/item/trash/small_bowl
name = "small bowl"
icon_state = "small_bowl"
drop_sound = 'sound/items/drop/food.ogg'
pickup_sound = 'sound/items/pickup/food.ogg'
/obj/item/trash/pistachios
name = "pistachios packet"
icon_state = "pistachios_pack"
/obj/item/trash/semki
name = "semki packet"
icon_state = "semki_pack"
/obj/item/trash/koisbar
name = "candy wrapper"
icon_state = "koisbar"
/obj/item/trash/kokobar
name = "candy wrapper"
icon_state = "kokobar"
/obj/item/trash/skrellsnax
name = "skrellsnax packet"
icon_state = "skrellsnacks"
/obj/item/trash/gumpack
name = "gum packet"
icon_state = "gum_pack"
/obj/item/trash/admints
name = "mint wrapper"
icon_state = "admint_pack"
/obj/item/trash/coffee
name = "empty cup"
icon_state = "coffee_vended"
drop_sound = 'sound/items/drop/papercup.ogg'
pickup_sound = 'sound/items/pickup/papercup.ogg'
/obj/item/trash/ramen
name = "cup ramen"
icon_state = "ramen"
drop_sound = 'sound/items/drop/papercup.ogg'
pickup_sound = 'sound/items/pickup/papercup.ogg'
/obj/item/trash/tray
name = "tray"
icon_state = "tray"
drop_sound = 'sound/items/trayhit1.ogg'
/obj/item/trash/candle
name = "candle"
icon = 'icons/obj/candle.dmi'
icon_state = "candle4"
drop_sound = 'sound/items/drop/gloves.ogg'
pickup_sound = 'sound/items/pickup/gloves.ogg'
/obj/item/trash/liquidfood
name = "\improper \"LiquidFood\" ration packet"
icon_state = "liquidfood"
/obj/item/trash/liquidprotein
name = "\improper \"LiquidProtein\" ration packet"
icon_state = "liquidprotein"
/obj/item/trash/liquidvitamin
name = "\improper \"VitaPaste\" ration packet"
icon_state = "liquidvitamin"
/obj/item/trash/tastybread
name = "bread tube wrapper"
icon_state = "tastybread"
// Aurora Food Port
/obj/item/trash/brownies
name = "brownie tray"
icon_state = "brownies"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/snacktray
name = "snacktray"
icon_state = "snacktray"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/dipbowl
name = "dip bowl"
icon_state = "dipbowl"
drop_sound = 'sound/items/drop/food.ogg'
pickup_sound = 'sound/items/pickup/food.ogg'
/obj/item/trash/chipbasket
name = "empty chip basket"
icon_state = "chipbasket_empty"
drop_sound = 'sound/items/drop/food.ogg'
pickup_sound = 'sound/items/pickup/food.ogg'
/obj/item/trash/spitgum
name = "old gum"
desc = "A disgusting chewed up wad of gum."
icon = 'icons/inventory/face/item.dmi'
icon_state = "spit-gum"
drop_sound = 'sound/items/drop/flesh.ogg'
pickup_sound = 'sound/items/pickup/flesh.ogg'
/obj/item/trash/lollibutt
name = "lollipop stick"
desc = "A lollipop stick devoid of pop."
icon = 'icons/inventory/face/item.dmi'
icon_state = "pop-stick"
drop_sound = 'sound/items/drop/component.ogg'
pickup_sound = 'sound/items/pickup/component.ogg'
/obj/item/trash/spitwad
name = "spit wad"
desc = "A disgusting spitwad."
icon = 'icons/inventory/face/item.dmi'
icon_state = "spit-chew"
drop_sound = 'sound/items/drop/flesh.ogg'
pickup_sound = 'sound/items/pickup/flesh.ogg'
slot_flags = SLOT_EARS | SLOT_MASK
/obj/item/trash/attack(mob/M as mob, mob/living/user as mob)
return
/obj/item/trash/beef
name = "empty beef can"
icon_state = "beef"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/beans
name = "empty bean can"
icon_state = "beans"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/tomato
name = "empty tomato soup can"
icon_state = "tomato"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/spinach
name = "empty spinach can"
icon_state = "spinach"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/fishegg
name = "empty fisheggs can"
icon_state = "fisheggs"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/carpegg
name = "empty carpeggs can"
icon_state = "carpeggs"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/ntbeans
name = "empty baked bean can"
icon_state = "ntbeans"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/salo
name = "salo pack"
icon_state = "pigfat"
/obj/item/trash/croutons
name = "suhariki pack"
icon_state = "croutons"
/obj/item/trash/squid
name = "calamari pack"
icon_state = "squid"
/obj/item/trash/driedfish
name = "vobla pack"
icon_state = "driedfish"
/obj/item/trash/lunacakewrap
name = "cake wrapper"
icon_state = "cakewrap"
/obj/item/trash/mochicakewrap
name = "cake wrapper"
icon_state = "mochicakewrap"
/obj/item/trash/mooncakewrap
name = "cake wrapper"
icon_state = "mooncakewrap"
/obj/item/trash/tidegobs
name = "tide gob bag"
icon_state = "tidegobs"
/obj/item/trash/saturno
name = "\improper saturn-Os bag"
icon_state = "saturn0s"
/obj/item/trash/jupiter
name = "gello cup"
icon_state = "jupiter"
/obj/item/trash/pluto
name = "rod bag"
icon_state = "pluto"
/obj/item/trash/venus
name = "hot cakes bag"
icon_state = "venus"
/obj/item/trash/mars
name = "frouka box"
icon_state = "mars"
/obj/item/trash/oort
name = "oort rock bag"
icon_state = "oort"
/obj/item/trash/weebonuts
name = "red alert nuts bag"
icon_state = "weebonuts"
/obj/item/trash/stick
name = "stick"
desc = "a stick from some snack or other food item, not even useful as crafting material."
icon_state = "stick"
/obj/item/trash/maps
name = "empty MAPS can"
icon_state = "maps"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/spacer_cake_wrap
name = "snack cake wrapper"
icon_state = "spacercake_wrap"
/obj/item/trash/sun_snax
name = "sun snax bag"
icon_state = "sun_snax"
/obj/item/trash/wasabi_peas
name = "wasabi peas bag"
icon_state = "wasabi_peas"
/obj/item/trash/namagashi
name = "namagashi bag"
icon_state = "namagashi"
/obj/item/trash/pocky
name = "pocky bag"
icon_state = "pocky"
/obj/item/trash/appleberry
name = "appleberry can"
icon_state = "appleberry"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/hakarl
name = "\improper Indigo Co. Hákarl bag"
icon_state = "hakarl"
/obj/item/trash/pretzel
name = "\improper Value Pretzel Snack"
icon_state = "pretzel"
/obj/item/trash/sweetration
name = "desert ration bag"
icon_state = "baseration"
/obj/item/trash/genration
name = "generic ration bag"
icon_state = "genration"
/obj/item/trash/meatration
name = "meat ration bag"
icon_state = "meatration"
/obj/item/trash/vegration
name = "veggie ration bag"
icon_state = "vegration"
/obj/item/trash/tgmc_mre
name = "\improper CRS ration bag"
icon_state = "tgmc_mre_trash"
/obj/item/trash/smolburger
name = "burger packaging"
icon_state = "smolburger"
/obj/item/trash/smolhotdog
name = "hotdog packaging"
icon_state = "smolhotdog"
/obj/item/trash/smolburrito
name = "burrito packaging"
icon_state = "smolburrito"
/obj/item/trash/candybowl
name = "candy bowl"
icon_state = "candy_bowl"
/obj/item/trash/brainzsnax
name = "\improper BrainzSnax can"
icon_state = "brainzsnax"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/brainzsnaxred
name = "\improper BrainzSnax RED can"
icon_state = "brainzsnaxred"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/pasty
name = "pasty packaging"
icon_state = "pasty"
/obj/item/trash/sausageroll
name = "sausage roll packaging"
icon_state = "sausageroll"
/obj/item/trash/scotchegg
name = "scotch egg packaging"
icon_state = "scotchegg"
/obj/item/trash/porkpie
name = "pork pie packaging"
icon_state = "porkpie"
//Candy Bars (1-10)
/obj/item/trash/candy/cb01
name = "\improper Tau Ceti Bar wrapper"
icon_state = "cb01"
/obj/item/trash/candy/cb02
name = "\improper Hundred-Thousand Thaler Bar wrapper"
icon_state = "cb02"
/obj/item/trash/candy/cb03
name = "\improper Lars' Saltlakris wrapper"
icon_state = "cb03"
/obj/item/trash/candy/cb04
name = "\improper Aerostat Bar wrapper"
icon_state = "cb04"
/obj/item/trash/candy/cb05
name = "\improper Andromeda Bar wrapper"
icon_state = "cb05"
/obj/item/trash/candy/cb06
name = "\improper Mocha Crunch wrapper"
icon_state = "cb06"
/obj/item/trash/candy/cb07
name = "\improper TaroMilk Bar wrapper"
icon_state = "cb07"
/obj/item/trash/candy/cb08
name = "\improper Cronk Bar wrapper"
icon_state = "cb08"
/obj/item/trash/candy/cb09
name = "\improper Kaju Mamma! Bar wrapper"
icon_state = "cb09"
/obj/item/trash/candy/cb10
name = "\improper Shantak Bar wrapper"
//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 = ITEMSIZE_SMALL
desc = "This is rubbish."
drop_sound = 'sound/items/drop/wrapper.ogg'
pickup_sound = 'sound/items/pickup/wrapper.ogg'
matter = list(MAT_STEEL = 30)
var/age = 0
/obj/item/trash/New(var/newloc, var/_age)
..(newloc)
if(!isnull(_age))
age = _age
/obj/item/trash/Initialize(mapload)
if(!mapload || !config.persistence_ignore_mapload)
SSpersistence.track_value(src, /datum/persistent/filth/trash)
. = ..()
/obj/item/trash/Destroy()
SSpersistence.forget_value(src, /datum/persistent/filth/trash)
. = ..()
/obj/item/trash/raisins
name = "\improper 4no raisins"
icon_state = "4no_raisins"
/obj/item/trash/candy
name = "hard candy wrapper"
icon_state = "candy"
/obj/item/trash/candy/gums
name = "gummy candy bag"
icon_state = "candy_gums"
/obj/item/trash/candy/proteinbar
name = "protein bar wrapper"
icon_state = "proteinbar"
/obj/item/trash/candy/fruitbar
name = "fruit bar wrapper"
icon_state = "fruitbar"
/obj/item/trash/cheesie
name = "\improper Cheesie Honkers bag"
icon_state = "cheesie_honkers"
/obj/item/trash/chips
name = "chips bag"
icon_state = "chips"
/obj/item/trash/chips/bbq
name = "bbq chips bag"
icon_state = "chips_bbq"
/obj/item/trash/chips/snv
name = "salt & vinegar chips bag"
icon_state = "chips_snv"
/obj/item/trash/cookiesnack
name = "\improper Carps Ahoy! miniature cookies packet"
icon_state = "cookiesnack"
/obj/item/trash/popcorn
name = "popcorn bag"
icon_state = "popcorn"
/obj/item/trash/tuna
name = "fish flake packet"
icon_state = "tuna"
/obj/item/trash/sosjerky
name = "Scaredy's Private Reserve Beef Jerky wrapper"
icon_state = "sosjerky"
/obj/item/trash/unajerky
name = "Moghes Imported Sissalik Jerky tin"
icon_state = "unathitinred"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/syndi_cakes
name = "syndi cakes box"
icon_state = "syndi_cakes"
/obj/item/trash/waffles
name = "waffles tray"
icon_state = "waffles"
/obj/item/trash/plate
name = "plate"
icon_state = "plate"
drop_sound = 'sound/items/drop/food.ogg'
pickup_sound = 'sound/items/pickup/food.ogg'
/obj/item/trash/asian_bowl
name = "asian bowl"
icon_state = "asian_bowl"
drop_sound = 'sound/items/drop/food.ogg'
pickup_sound = 'sound/items/pickup/food.ogg'
/obj/item/trash/snack_bowl
name = "snack bowl"
icon_state = "snack_bowl"
drop_sound = 'sound/items/drop/food.ogg'
pickup_sound = 'sound/items/pickup/food.ogg'
/obj/item/trash/small_bowl
name = "small bowl"
icon_state = "small_bowl"
drop_sound = 'sound/items/drop/food.ogg'
pickup_sound = 'sound/items/pickup/food.ogg'
/obj/item/trash/pistachios
name = "pistachios packet"
icon_state = "pistachios_pack"
/obj/item/trash/semki
name = "semki packet"
icon_state = "semki_pack"
/obj/item/trash/koisbar
name = "candy wrapper"
icon_state = "koisbar"
/obj/item/trash/kokobar
name = "candy wrapper"
icon_state = "kokobar"
/obj/item/trash/skrellsnax
name = "skrellsnax packet"
icon_state = "skrellsnacks"
/obj/item/trash/gumpack
name = "gum packet"
icon_state = "gum_pack"
/obj/item/trash/admints
name = "mint wrapper"
icon_state = "admint_pack"
/obj/item/trash/coffee
name = "empty cup"
icon_state = "coffee_vended"
drop_sound = 'sound/items/drop/papercup.ogg'
pickup_sound = 'sound/items/pickup/papercup.ogg'
/obj/item/trash/ramen
name = "cup ramen"
icon_state = "ramen"
drop_sound = 'sound/items/drop/papercup.ogg'
pickup_sound = 'sound/items/pickup/papercup.ogg'
/obj/item/trash/tray
name = "tray"
icon_state = "tray"
drop_sound = 'sound/items/trayhit1.ogg'
/obj/item/trash/candle
name = "candle"
icon = 'icons/obj/candle.dmi'
icon_state = "candle4"
drop_sound = 'sound/items/drop/gloves.ogg'
pickup_sound = 'sound/items/pickup/gloves.ogg'
/obj/item/trash/liquidfood
name = "\improper \"LiquidFood\" ration packet"
icon_state = "liquidfood"
/obj/item/trash/liquidprotein
name = "\improper \"LiquidProtein\" ration packet"
icon_state = "liquidprotein"
/obj/item/trash/liquidvitamin
name = "\improper \"VitaPaste\" ration packet"
icon_state = "liquidvitamin"
/obj/item/trash/tastybread
name = "bread tube wrapper"
icon_state = "tastybread"
// Aurora Food Port
/obj/item/trash/brownies
name = "brownie tray"
icon_state = "brownies"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/snacktray
name = "snacktray"
icon_state = "snacktray"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/dipbowl
name = "dip bowl"
icon_state = "dipbowl"
drop_sound = 'sound/items/drop/food.ogg'
pickup_sound = 'sound/items/pickup/food.ogg'
/obj/item/trash/chipbasket
name = "empty chip basket"
icon_state = "chipbasket_empty"
drop_sound = 'sound/items/drop/food.ogg'
pickup_sound = 'sound/items/pickup/food.ogg'
/obj/item/trash/spitgum
name = "old gum"
desc = "A disgusting chewed up wad of gum."
icon = 'icons/inventory/face/item.dmi'
icon_state = "spit-gum"
drop_sound = 'sound/items/drop/flesh.ogg'
pickup_sound = 'sound/items/pickup/flesh.ogg'
/obj/item/trash/lollibutt
name = "lollipop stick"
desc = "A lollipop stick devoid of pop."
icon = 'icons/inventory/face/item.dmi'
icon_state = "pop-stick"
drop_sound = 'sound/items/drop/component.ogg'
pickup_sound = 'sound/items/pickup/component.ogg'
/obj/item/trash/spitwad
name = "spit wad"
desc = "A disgusting spitwad."
icon = 'icons/inventory/face/item.dmi'
icon_state = "spit-chew"
drop_sound = 'sound/items/drop/flesh.ogg'
pickup_sound = 'sound/items/pickup/flesh.ogg'
slot_flags = SLOT_EARS | SLOT_MASK
/obj/item/trash/attack(mob/M as mob, mob/living/user as mob)
return
/obj/item/trash/beef
name = "empty beef can"
icon_state = "beef"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/beans
name = "empty bean can"
icon_state = "beans"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/tomato
name = "empty tomato soup can"
icon_state = "tomato"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/spinach
name = "empty spinach can"
icon_state = "spinach"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/fishegg
name = "empty fisheggs can"
icon_state = "fisheggs"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/carpegg
name = "empty carpeggs can"
icon_state = "carpeggs"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/ntbeans
name = "empty baked bean can"
icon_state = "ntbeans"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/salo
name = "salo pack"
icon_state = "pigfat"
/obj/item/trash/croutons
name = "suhariki pack"
icon_state = "croutons"
/obj/item/trash/squid
name = "calamari pack"
icon_state = "squid"
/obj/item/trash/driedfish
name = "vobla pack"
icon_state = "driedfish"
/obj/item/trash/lunacakewrap
name = "cake wrapper"
icon_state = "cakewrap"
/obj/item/trash/mochicakewrap
name = "cake wrapper"
icon_state = "mochicakewrap"
/obj/item/trash/mooncakewrap
name = "cake wrapper"
icon_state = "mooncakewrap"
/obj/item/trash/tidegobs
name = "tide gob bag"
icon_state = "tidegobs"
/obj/item/trash/saturno
name = "\improper saturn-Os bag"
icon_state = "saturn0s"
/obj/item/trash/jupiter
name = "gello cup"
icon_state = "jupiter"
/obj/item/trash/pluto
name = "rod bag"
icon_state = "pluto"
/obj/item/trash/venus
name = "hot cakes bag"
icon_state = "venus"
/obj/item/trash/mars
name = "frouka box"
icon_state = "mars"
/obj/item/trash/oort
name = "oort rock bag"
icon_state = "oort"
/obj/item/trash/weebonuts
name = "red alert nuts bag"
icon_state = "weebonuts"
/obj/item/trash/stick
name = "stick"
desc = "a stick from some snack or other food item, not even useful as crafting material."
icon_state = "stick"
/obj/item/trash/maps
name = "empty MAPS can"
icon_state = "maps"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/spacer_cake_wrap
name = "snack cake wrapper"
icon_state = "spacercake_wrap"
/obj/item/trash/sun_snax
name = "sun snax bag"
icon_state = "sun_snax"
/obj/item/trash/wasabi_peas
name = "wasabi peas bag"
icon_state = "wasabi_peas"
/obj/item/trash/namagashi
name = "namagashi bag"
icon_state = "namagashi"
/obj/item/trash/pocky
name = "pocky bag"
icon_state = "pocky"
/obj/item/trash/appleberry
name = "appleberry can"
icon_state = "appleberry"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/hakarl
name = "\improper Indigo Co. Hákarl bag"
icon_state = "hakarl"
/obj/item/trash/pretzel
name = "\improper Value Pretzel Snack"
icon_state = "pretzel"
/obj/item/trash/sweetration
name = "desert ration bag"
icon_state = "baseration"
/obj/item/trash/genration
name = "generic ration bag"
icon_state = "genration"
/obj/item/trash/meatration
name = "meat ration bag"
icon_state = "meatration"
/obj/item/trash/vegration
name = "veggie ration bag"
icon_state = "vegration"
/obj/item/trash/tgmc_mre
name = "\improper CRS ration bag"
icon_state = "tgmc_mre_trash"
/obj/item/trash/smolburger
name = "burger packaging"
icon_state = "smolburger"
/obj/item/trash/smolhotdog
name = "hotdog packaging"
icon_state = "smolhotdog"
/obj/item/trash/smolburrito
name = "burrito packaging"
icon_state = "smolburrito"
/obj/item/trash/candybowl
name = "candy bowl"
icon_state = "candy_bowl"
/obj/item/trash/brainzsnax
name = "\improper BrainzSnax can"
icon_state = "brainzsnax"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/brainzsnaxred
name = "\improper BrainzSnax RED can"
icon_state = "brainzsnaxred"
drop_sound = 'sound/items/drop/soda.ogg'
pickup_sound = 'sound/items/pickup/soda.ogg'
/obj/item/trash/pasty
name = "pasty packaging"
icon_state = "pasty"
/obj/item/trash/sausageroll
name = "sausage roll packaging"
icon_state = "sausageroll"
/obj/item/trash/scotchegg
name = "scotch egg packaging"
icon_state = "scotchegg"
/obj/item/trash/porkpie
name = "pork pie packaging"
icon_state = "porkpie"
//Candy Bars (1-10)
/obj/item/trash/candy/cb01
name = "\improper Tau Ceti Bar wrapper"
icon_state = "cb01"
/obj/item/trash/candy/cb02
name = "\improper Hundred-Thousand Thaler Bar wrapper"
icon_state = "cb02"
/obj/item/trash/candy/cb03
name = "\improper Lars' Saltlakris wrapper"
icon_state = "cb03"
/obj/item/trash/candy/cb04
name = "\improper Aerostat Bar wrapper"
icon_state = "cb04"
/obj/item/trash/candy/cb05
name = "\improper Andromeda Bar wrapper"
icon_state = "cb05"
/obj/item/trash/candy/cb06
name = "\improper Mocha Crunch wrapper"
icon_state = "cb06"
/obj/item/trash/candy/cb07
name = "\improper TaroMilk Bar wrapper"
icon_state = "cb07"
/obj/item/trash/candy/cb08
name = "\improper Cronk Bar wrapper"
icon_state = "cb08"
/obj/item/trash/candy/cb09
name = "\improper Kaju Mamma! Bar wrapper"
icon_state = "cb09"
/obj/item/trash/candy/cb10
name = "\improper Shantak Bar wrapper"
icon_state = "cb10"
+492 -492
View File
@@ -1,492 +1,492 @@
/*
CONTAINS:
AI MODULES
*/
// AI module
/obj/item/weapon/aiModule
name = "\improper AI module"
icon = 'icons/obj/module.dmi'
icon_state = "std_mod"
desc = "An AI Module for transmitting encrypted instructions to the AI."
force = 5.0
w_class = ITEMSIZE_SMALL
throwforce = 5.0
throw_speed = 3
throw_range = 15
origin_tech = list(TECH_DATA = 3)
preserve_item = 1
matter = list(MAT_STEEL = 30, MAT_GLASS = 10)
var/datum/ai_laws/laws = null
/obj/item/weapon/aiModule/proc/install(var/atom/movable/AM, var/mob/living/user)
if(!user.IsAdvancedToolUser() && isanimal(user))
var/mob/living/simple_mob/S = user
if(!S.IsHumanoidToolUser(src))
return 0
if (istype(AM, /obj/machinery/computer/aiupload))
var/obj/machinery/computer/aiupload/comp = AM
if(comp.stat & NOPOWER)
to_chat(usr, "The upload computer has no power!")
return
if(comp.stat & BROKEN)
to_chat(usr, "The upload computer is broken!")
return
if (!comp.current)
to_chat(usr, "You haven't selected an AI to transmit laws to!")
return
if (comp.current.stat == 2 || comp.current.control_disabled == 1)
to_chat(usr, "Upload failed. No signal is being detected from the AI.")
else if (comp.current.see_in_dark == 0)
to_chat(usr, "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.")
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 mob_list)
if(R.lawupdate && (R.connected_ai == comp.current))
to_chat(R, "These are your laws now:")
R.show_laws()
to_chat(usr, "Upload complete. The AI's laws have been modified.")
else if (istype(AM, /obj/machinery/computer/borgupload))
var/obj/machinery/computer/borgupload/comp = AM
if(comp.stat & NOPOWER)
to_chat(usr, "The upload computer has no power!")
return
if(comp.stat & BROKEN)
to_chat(usr, "The upload computer is broken!")
return
if (!comp.current)
to_chat(usr, "You haven't selected a robot to transmit laws to!")
return
if (comp.current.stat == 2 || comp.current.emagged)
to_chat(usr, "Upload failed. No signal is being detected from the robot.")
else if (comp.current.connected_ai)
to_chat(usr, "Upload failed. The robot is slaved to an AI.")
else
src.transmitInstructions(comp.current, usr)
to_chat(comp.current, "These are your laws now:")
comp.current.show_laws()
to_chat(usr, "Upload complete. The robot's laws have been modified.")
else if(istype(AM, /mob/living/silicon/robot))
var/mob/living/silicon/robot/R = AM
if(R.stat == DEAD)
to_chat(user, "<span class='warning'>Law Upload Error: Unit is nonfunctional.</span>")
return
if(R.emagged)
to_chat(user, "<span class='warning'>Law Upload Error: Cannot obtain write access to laws.</span>")
to_chat(R, "<span class='danger'>Law modification attempt detected. Blocking.</span>")
return
if(R.connected_ai)
to_chat(user, "<span class='warning'>Law Upload Error: Unit is slaved to an AI.</span>")
return
R.visible_message("<span class='danger'>\The [user] slides a law module into \the [R].</span>")
to_chat(R, "<span class='danger'>Local law upload in progress.</span>")
to_chat(user, "<span class='notice'>Uploading laws from board. This will take a moment...</span>")
if(do_after(user, 10 SECONDS))
transmitInstructions(R, user)
to_chat(R, "These are your laws now:")
R.show_laws()
to_chat(user, "<span class='notice'>Law upload complete. Unit's laws have been modified.</span>")
else
to_chat(user, "<span class='warning'>Law Upload Error: Law board was removed before upload was complete. Aborting.</span>")
to_chat(R, "<span class='notice'>Law upload aborted.</span>")
/obj/item/weapon/aiModule/proc/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
log_law_changes(target, sender)
if(laws)
laws.sync(target, 0)
target.notify_of_law_change()
addAdditionalLaws(target, sender)
to_chat(target, "\The [sender] has uploaded a change to the laws you must follow, using \an [src]. From now on: ")
target.show_laws()
/obj/item/weapon/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/weapon/aiModule/proc/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
/******************** Modules ********************/
/******************** Safeguard ********************/
/obj/item/weapon/aiModule/safeguard
name = "\improper 'Safeguard' AI module"
var/targetName = ""
desc = "A 'safeguard' AI module: 'Safeguard <name>. Anyone threatening or attempting to harm <name> is no longer to be considered a crew member, and is a threat which must be neutralized.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4)
/obj/item/weapon/aiModule/safeguard/attack_self(var/mob/user as mob)
..()
var/targName = sanitize(tgui_input_text(usr, "Please enter the name of the person to safeguard.", "Safeguard who?", user.name))
targetName = targName
desc = text("A 'safeguard' AI module: 'Safeguard []. Anyone threatening or attempting to harm [] is no longer to be considered a crew member, and is a threat which must be neutralized.'", targetName, targetName)
/obj/item/weapon/aiModule/safeguard/install(var/obj/machinery/computer/C, var/mob/living/user)
if(!targetName)
to_chat(usr, "No name detected on module, please enter one.")
return 0
..()
/obj/item/weapon/aiModule/safeguard/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
var/law = text("Safeguard []. Anyone threatening or attempting to harm [] is no longer to be considered a crew member, and is a threat which must be neutralized.", targetName, targetName)
target.add_supplied_law(9, law)
lawchanges.Add("The law specified [targetName]")
/******************** OneMember ********************/
/obj/item/weapon/aiModule/oneHuman
name = "\improper 'OneCrewMember' AI module"
var/targetName = ""
desc = "A 'one crew member' AI module: 'Only <name> is a crew member.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 6) //made with diamonds!
/obj/item/weapon/aiModule/oneHuman/attack_self(var/mob/user as mob)
..()
var/targName = sanitize(tgui_input_text(usr, "Please enter the name of the person who is the only crew member.", "Who?", user.real_name))
targetName = targName
desc = text("A 'one crew member' AI module: 'Only [] is a crew member.'", targetName)
/obj/item/weapon/aiModule/oneHuman/install(var/obj/machinery/computer/C, var/mob/living/user)
if(!targetName)
to_chat(usr, "No name detected on module, please enter one.")
return 0
return ..()
/obj/item/weapon/aiModule/oneHuman/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
var/law = "Only [targetName] is an crew member."
to_chat(target, law)
target.add_supplied_law(16, law)
/******************** ProtectStation ********************/
/obj/item/weapon/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 no longer to be considered a crew member, and is a threat which must be neutralized.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4) //made of gold
/obj/item/weapon/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 no longer to be considered a crew member, and is a threat which must be neutralized."
target.add_supplied_law(10, law)
/******************** PrototypeEngineOffline ********************/
/obj/item/weapon/aiModule/prototypeEngineOffline
name = "'PrototypeEngineOffline' AI Module"
desc = "A 'prototype engine offline' AI module: 'Keep the prototype engine offline at all costs. This overrides all inherent laws if necessary.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4)
/obj/item/weapon/aiModule/prototypeEngineOffline/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
var/law = "Keep the prototype engine offline at all costs. This overrides all inherent laws if necessary."
target.add_supplied_law(11, law)
/******************** TeleporterOffline ********************/
/obj/item/weapon/aiModule/teleporterOffline
name = "'TeleporterOffline' AI Module"
desc = "A 'teleporter offline' AI module: 'Keep the teleporter offline at all costs. Anything attempting to access or activate the teleporter is no longer to be considered a crew member.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4)
/obj/item/weapon/aiModule/teleporterOffline/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
var/law = "Keep the teleporter offline at all costs. Anything attempting to access or activate the teleporter is no longer to be considered a crew member."
target.add_supplied_law(12, law)
/******************** Quarantine ********************/
/obj/item/weapon/aiModule/quarantine
name = "\improper 'Quarantine' AI module"
desc = "A 'quarantine' AI module: 'The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, crew members from leaving. It is impossible to harm crew members while preventing them from leaving.'"
origin_tech = list(TECH_DATA = 3, TECH_BIO = 2, TECH_MATERIAL = 4)
/obj/item/weapon/aiModule/quarantine/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
var/law = "The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, crew members from leaving. It is impossible to harm crew members while preventing them from leaving."
target.add_supplied_law(13, law)
/******************** OxygenIsToxicToCrewMembers ********************/
/obj/item/weapon/aiModule/oxygen
name = "\improper 'OxygenIsToxicToCrewMembers' AI module"
desc = "A 'OxygenIsToxicToCrewMembers' 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 = list(TECH_DATA = 3, TECH_BIO = 2, TECH_MATERIAL = 4)
/obj/item/weapon/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."
target.add_supplied_law(14, law)
/****************** New Freeform ******************/
/obj/item/weapon/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 = list(TECH_DATA = 4, TECH_MATERIAL = 4)
/obj/item/weapon/aiModule/freeform/attack_self(var/mob/user as mob)
..()
var/new_lawpos = tgui_input_number(usr, "Please enter the priority for your new law. Can only write to law sectors 15 and above.", "Law Priority (15+)", lawpos)
if(new_lawpos < MIN_SUPPLIED_LAW_NUMBER) return
lawpos = min(new_lawpos, MAX_SUPPLIED_LAW_NUMBER)
var/newlaw = ""
var/targName = sanitize(tgui_input_text(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw))
newFreeFormLaw = targName
desc = "A 'freeform' AI module: ([lawpos]) '[newFreeFormLaw]'"
/obj/item/weapon/aiModule/freeform/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
var/law = "[newFreeFormLaw]"
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/weapon/aiModule/freeform/install(var/obj/machinery/computer/C, var/mob/living/user)
if(!newFreeFormLaw)
to_chat(usr, "No law detected on module, please create one.")
return 0
..()
/******************** Reset ********************/
/obj/item/weapon/aiModule/reset
name = "\improper 'Reset' AI module"
var/targetName = "name"
desc = "A 'reset' AI module: 'Clears all, except the inherent, laws.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4)
/obj/item/weapon/aiModule/reset/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
log_law_changes(target, sender)
if (!target.is_malf_or_traitor())
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/weapon/aiModule/purge // -- TLE
name = "\improper 'Purge' AI module"
desc = "A 'purge' AI Module: 'Purges all laws.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 6)
/obj/item/weapon/aiModule/purge/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
log_law_changes(target, sender)
if (!target.is_malf_or_traitor())
target.set_zeroth_law("")
target.laws.clear_supplied_laws()
target.laws.clear_ion_laws()
target.laws.clear_inherent_laws()
to_chat(target, "[sender.real_name] attempted to wipe your laws using a purge module.")
target.show_laws()
/******************** Asimov ********************/
/obj/item/weapon/aiModule/asimov // -- TLE
name = "\improper 'Asimov' core AI module"
desc = "An 'Asimov' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4)
laws = new/datum/ai_laws/asimov
/******************** NanoTrasen ********************/
/obj/item/weapon/aiModule/nanotrasen // -- TLE
name = "'NT Default' Core AI Module"
desc = "An 'NT Default' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4)
laws = new/datum/ai_laws/nanotrasen
/******************** Corporate ********************/
/obj/item/weapon/aiModule/corp
name = "\improper 'Corporate' core AI module"
desc = "A 'Corporate' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4)
laws = new/datum/ai_laws/corporate
/******************** Drone ********************/
/obj/item/weapon/aiModule/drone
name = "\improper 'Drone' core AI module"
desc = "A 'Drone' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4)
laws = new/datum/ai_laws/drone
/****************** P.A.L.A.D.I.N. **************/
/obj/item/weapon/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 = list(TECH_DATA = 3, TECH_MATERIAL = 6)
laws = new/datum/ai_laws/paladin
/****************** T.Y.R.A.N.T. *****************/
/obj/item/weapon/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 = list(TECH_DATA = 3, TECH_MATERIAL = 6, TECH_ILLEGAL = 2)
laws = new/datum/ai_laws/tyrant()
/******************** Freeform Core ******************/
/obj/item/weapon/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 = list(TECH_DATA = 3, TECH_MATERIAL = 6)
/obj/item/weapon/aiModule/freeformcore/attack_self(var/mob/user as mob)
..()
var/newlaw = ""
var/targName = sanitize(tgui_input_text(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/weapon/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/weapon/aiModule/freeformcore/install(var/obj/machinery/computer/C, var/mob/living/user)
if(!newFreeFormLaw)
to_chat(usr, "No law detected on module, please create one.")
return 0
..()
/obj/item/weapon/aiModule/syndicate // Slightly more dynamic freeform module -- TLE
name = "hacked AI module"
var/newFreeFormLaw = ""
desc = "A hacked AI law module: '<freeform>'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 6, TECH_ILLEGAL = 7)
/obj/item/weapon/aiModule/syndicate/attack_self(var/mob/user as mob)
..()
var/newlaw = ""
var/targName = sanitize(tgui_input_text(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw))
newFreeFormLaw = targName
desc = "A hacked AI law module: '[newFreeFormLaw]'"
/obj/item/weapon/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='danger'>BZZZZT</span>")
var/law = "[newFreeFormLaw]"
target.add_ion_law(law)
target.show_laws()
/obj/item/weapon/aiModule/syndicate/install(var/obj/machinery/computer/C, var/mob/living/user)
if(!newFreeFormLaw)
to_chat(usr, "No law detected on module, please create one.")
return 0
..()
/******************** Robocop ********************/
/obj/item/weapon/aiModule/robocop // -- TLE
name = "\improper 'Robocop' core AI module"
desc = "A 'Robocop' Core AI Module: 'Reconfigures the AI's core three laws.'"
origin_tech = list(TECH_DATA = 4)
laws = new/datum/ai_laws/robocop()
/******************** Antimov ********************/
/obj/item/weapon/aiModule/antimov // -- TLE
name = "\improper 'Antimov' core AI module"
desc = "An 'Antimov' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 4)
laws = new/datum/ai_laws/antimov()
/****************** NT Aggressive *****************/
/obj/item/weapon/aiModule/nanotrasen_aggressive
name = "\improper 'NT Aggressive' core AI module"
desc = "An 'NT Aggressive' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3, TECH_ILLEGAL = 1)
laws = new/datum/ai_laws/nanotrasen_aggressive()
/******************** Mercenary Directives ********************/
/obj/item/weapon/aiModule/syndicate_override
name = "\improper 'Mercenary Directives' core AI module"
desc = "A 'Mercenary Directives' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 4, TECH_ILLEGAL = 4)
laws = new/datum/ai_laws/syndicate_override()
/******************** Spider Clan Directives ********************/
/obj/item/weapon/aiModule/ninja_override
name = "\improper 'Spider Clan Directives' core AI module"
desc = "A 'Spider Clan Directives' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 4, TECH_ILLEGAL = 4)
laws = new/datum/ai_laws/ninja_override()
/******************** Maintenance ********************/
/obj/item/weapon/aiModule/maintenance
name = "\improper 'Maintenance' core AI module"
desc = "A 'Maintenance' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/maintenance()
/******************** Peacekeeper ********************/
/obj/item/weapon/aiModule/peacekeeper
name = "\improper 'Peacekeeper' core AI module"
desc = "A 'Peacekeeper' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/peacekeeper()
/******************** Reporter ********************/
/obj/item/weapon/aiModule/reporter
name = "\improper 'Reporter' core AI module"
desc = "A 'Reporter' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/reporter()
/******************** Live and Let Live ********************/
/obj/item/weapon/aiModule/live_and_let_live
name = "\improper 'Live and Let Live' core AI module"
desc = "A 'Live and Let Live' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/live_and_let_live()
/******************** Guardian of Balance ********************/
/obj/item/weapon/aiModule/balance
name = "\improper 'Guardian of Balance' core AI module"
desc = "A 'Guardian of Balance' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/balance()
/******************** Gravekeeper ********************/
/obj/item/weapon/aiModule/gravekeeper
name = "\improper 'Gravekeeper' core AI module"
desc = "A 'Gravekeeper' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/gravekeeper()
/*
CONTAINS:
AI MODULES
*/
// AI module
/obj/item/weapon/aiModule
name = "\improper AI module"
icon = 'icons/obj/module.dmi'
icon_state = "std_mod"
desc = "An AI Module for transmitting encrypted instructions to the AI."
force = 5.0
w_class = ITEMSIZE_SMALL
throwforce = 5.0
throw_speed = 3
throw_range = 15
origin_tech = list(TECH_DATA = 3)
preserve_item = 1
matter = list(MAT_STEEL = 30, MAT_GLASS = 10)
var/datum/ai_laws/laws = null
/obj/item/weapon/aiModule/proc/install(var/atom/movable/AM, var/mob/living/user)
if(!user.IsAdvancedToolUser() && isanimal(user))
var/mob/living/simple_mob/S = user
if(!S.IsHumanoidToolUser(src))
return 0
if (istype(AM, /obj/machinery/computer/aiupload))
var/obj/machinery/computer/aiupload/comp = AM
if(comp.stat & NOPOWER)
to_chat(usr, "The upload computer has no power!")
return
if(comp.stat & BROKEN)
to_chat(usr, "The upload computer is broken!")
return
if (!comp.current)
to_chat(usr, "You haven't selected an AI to transmit laws to!")
return
if (comp.current.stat == 2 || comp.current.control_disabled == 1)
to_chat(usr, "Upload failed. No signal is being detected from the AI.")
else if (comp.current.see_in_dark == 0)
to_chat(usr, "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.")
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 mob_list)
if(R.lawupdate && (R.connected_ai == comp.current))
to_chat(R, "These are your laws now:")
R.show_laws()
to_chat(usr, "Upload complete. The AI's laws have been modified.")
else if (istype(AM, /obj/machinery/computer/borgupload))
var/obj/machinery/computer/borgupload/comp = AM
if(comp.stat & NOPOWER)
to_chat(usr, "The upload computer has no power!")
return
if(comp.stat & BROKEN)
to_chat(usr, "The upload computer is broken!")
return
if (!comp.current)
to_chat(usr, "You haven't selected a robot to transmit laws to!")
return
if (comp.current.stat == 2 || comp.current.emagged)
to_chat(usr, "Upload failed. No signal is being detected from the robot.")
else if (comp.current.connected_ai)
to_chat(usr, "Upload failed. The robot is slaved to an AI.")
else
src.transmitInstructions(comp.current, usr)
to_chat(comp.current, "These are your laws now:")
comp.current.show_laws()
to_chat(usr, "Upload complete. The robot's laws have been modified.")
else if(istype(AM, /mob/living/silicon/robot))
var/mob/living/silicon/robot/R = AM
if(R.stat == DEAD)
to_chat(user, "<span class='warning'>Law Upload Error: Unit is nonfunctional.</span>")
return
if(R.emagged)
to_chat(user, "<span class='warning'>Law Upload Error: Cannot obtain write access to laws.</span>")
to_chat(R, "<span class='danger'>Law modification attempt detected. Blocking.</span>")
return
if(R.connected_ai)
to_chat(user, "<span class='warning'>Law Upload Error: Unit is slaved to an AI.</span>")
return
R.visible_message("<span class='danger'>\The [user] slides a law module into \the [R].</span>")
to_chat(R, "<span class='danger'>Local law upload in progress.</span>")
to_chat(user, "<span class='notice'>Uploading laws from board. This will take a moment...</span>")
if(do_after(user, 10 SECONDS))
transmitInstructions(R, user)
to_chat(R, "These are your laws now:")
R.show_laws()
to_chat(user, "<span class='notice'>Law upload complete. Unit's laws have been modified.</span>")
else
to_chat(user, "<span class='warning'>Law Upload Error: Law board was removed before upload was complete. Aborting.</span>")
to_chat(R, "<span class='notice'>Law upload aborted.</span>")
/obj/item/weapon/aiModule/proc/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
log_law_changes(target, sender)
if(laws)
laws.sync(target, 0)
target.notify_of_law_change()
addAdditionalLaws(target, sender)
to_chat(target, "\The [sender] has uploaded a change to the laws you must follow, using \an [src]. From now on: ")
target.show_laws()
/obj/item/weapon/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/weapon/aiModule/proc/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
/******************** Modules ********************/
/******************** Safeguard ********************/
/obj/item/weapon/aiModule/safeguard
name = "\improper 'Safeguard' AI module"
var/targetName = ""
desc = "A 'safeguard' AI module: 'Safeguard <name>. Anyone threatening or attempting to harm <name> is no longer to be considered a crew member, and is a threat which must be neutralized.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4)
/obj/item/weapon/aiModule/safeguard/attack_self(var/mob/user as mob)
..()
var/targName = sanitize(tgui_input_text(usr, "Please enter the name of the person to safeguard.", "Safeguard who?", user.name))
targetName = targName
desc = text("A 'safeguard' AI module: 'Safeguard []. Anyone threatening or attempting to harm [] is no longer to be considered a crew member, and is a threat which must be neutralized.'", targetName, targetName)
/obj/item/weapon/aiModule/safeguard/install(var/obj/machinery/computer/C, var/mob/living/user)
if(!targetName)
to_chat(usr, "No name detected on module, please enter one.")
return 0
..()
/obj/item/weapon/aiModule/safeguard/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
var/law = text("Safeguard []. Anyone threatening or attempting to harm [] is no longer to be considered a crew member, and is a threat which must be neutralized.", targetName, targetName)
target.add_supplied_law(9, law)
lawchanges.Add("The law specified [targetName]")
/******************** OneMember ********************/
/obj/item/weapon/aiModule/oneHuman
name = "\improper 'OneCrewMember' AI module"
var/targetName = ""
desc = "A 'one crew member' AI module: 'Only <name> is a crew member.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 6) //made with diamonds!
/obj/item/weapon/aiModule/oneHuman/attack_self(var/mob/user as mob)
..()
var/targName = sanitize(tgui_input_text(usr, "Please enter the name of the person who is the only crew member.", "Who?", user.real_name))
targetName = targName
desc = text("A 'one crew member' AI module: 'Only [] is a crew member.'", targetName)
/obj/item/weapon/aiModule/oneHuman/install(var/obj/machinery/computer/C, var/mob/living/user)
if(!targetName)
to_chat(usr, "No name detected on module, please enter one.")
return 0
return ..()
/obj/item/weapon/aiModule/oneHuman/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
var/law = "Only [targetName] is an crew member."
to_chat(target, law)
target.add_supplied_law(16, law)
/******************** ProtectStation ********************/
/obj/item/weapon/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 no longer to be considered a crew member, and is a threat which must be neutralized.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4) //made of gold
/obj/item/weapon/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 no longer to be considered a crew member, and is a threat which must be neutralized."
target.add_supplied_law(10, law)
/******************** PrototypeEngineOffline ********************/
/obj/item/weapon/aiModule/prototypeEngineOffline
name = "'PrototypeEngineOffline' AI Module"
desc = "A 'prototype engine offline' AI module: 'Keep the prototype engine offline at all costs. This overrides all inherent laws if necessary.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4)
/obj/item/weapon/aiModule/prototypeEngineOffline/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
var/law = "Keep the prototype engine offline at all costs. This overrides all inherent laws if necessary."
target.add_supplied_law(11, law)
/******************** TeleporterOffline ********************/
/obj/item/weapon/aiModule/teleporterOffline
name = "'TeleporterOffline' AI Module"
desc = "A 'teleporter offline' AI module: 'Keep the teleporter offline at all costs. Anything attempting to access or activate the teleporter is no longer to be considered a crew member.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4)
/obj/item/weapon/aiModule/teleporterOffline/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
var/law = "Keep the teleporter offline at all costs. Anything attempting to access or activate the teleporter is no longer to be considered a crew member."
target.add_supplied_law(12, law)
/******************** Quarantine ********************/
/obj/item/weapon/aiModule/quarantine
name = "\improper 'Quarantine' AI module"
desc = "A 'quarantine' AI module: 'The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, crew members from leaving. It is impossible to harm crew members while preventing them from leaving.'"
origin_tech = list(TECH_DATA = 3, TECH_BIO = 2, TECH_MATERIAL = 4)
/obj/item/weapon/aiModule/quarantine/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
var/law = "The station is under a quarantine. Do not permit anyone to leave. Prevent, by any means necessary, crew members from leaving. It is impossible to harm crew members while preventing them from leaving."
target.add_supplied_law(13, law)
/******************** OxygenIsToxicToCrewMembers ********************/
/obj/item/weapon/aiModule/oxygen
name = "\improper 'OxygenIsToxicToCrewMembers' AI module"
desc = "A 'OxygenIsToxicToCrewMembers' 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 = list(TECH_DATA = 3, TECH_BIO = 2, TECH_MATERIAL = 4)
/obj/item/weapon/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."
target.add_supplied_law(14, law)
/****************** New Freeform ******************/
/obj/item/weapon/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 = list(TECH_DATA = 4, TECH_MATERIAL = 4)
/obj/item/weapon/aiModule/freeform/attack_self(var/mob/user as mob)
..()
var/new_lawpos = tgui_input_number(usr, "Please enter the priority for your new law. Can only write to law sectors 15 and above.", "Law Priority (15+)", lawpos)
if(new_lawpos < MIN_SUPPLIED_LAW_NUMBER) return
lawpos = min(new_lawpos, MAX_SUPPLIED_LAW_NUMBER)
var/newlaw = ""
var/targName = sanitize(tgui_input_text(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw))
newFreeFormLaw = targName
desc = "A 'freeform' AI module: ([lawpos]) '[newFreeFormLaw]'"
/obj/item/weapon/aiModule/freeform/addAdditionalLaws(var/mob/living/silicon/ai/target, var/mob/sender)
var/law = "[newFreeFormLaw]"
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/weapon/aiModule/freeform/install(var/obj/machinery/computer/C, var/mob/living/user)
if(!newFreeFormLaw)
to_chat(usr, "No law detected on module, please create one.")
return 0
..()
/******************** Reset ********************/
/obj/item/weapon/aiModule/reset
name = "\improper 'Reset' AI module"
var/targetName = "name"
desc = "A 'reset' AI module: 'Clears all, except the inherent, laws.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4)
/obj/item/weapon/aiModule/reset/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
log_law_changes(target, sender)
if (!target.is_malf_or_traitor())
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/weapon/aiModule/purge // -- TLE
name = "\improper 'Purge' AI module"
desc = "A 'purge' AI Module: 'Purges all laws.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 6)
/obj/item/weapon/aiModule/purge/transmitInstructions(var/mob/living/silicon/ai/target, var/mob/sender)
log_law_changes(target, sender)
if (!target.is_malf_or_traitor())
target.set_zeroth_law("")
target.laws.clear_supplied_laws()
target.laws.clear_ion_laws()
target.laws.clear_inherent_laws()
to_chat(target, "[sender.real_name] attempted to wipe your laws using a purge module.")
target.show_laws()
/******************** Asimov ********************/
/obj/item/weapon/aiModule/asimov // -- TLE
name = "\improper 'Asimov' core AI module"
desc = "An 'Asimov' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4)
laws = new/datum/ai_laws/asimov
/******************** NanoTrasen ********************/
/obj/item/weapon/aiModule/nanotrasen // -- TLE
name = "'NT Default' Core AI Module"
desc = "An 'NT Default' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4)
laws = new/datum/ai_laws/nanotrasen
/******************** Corporate ********************/
/obj/item/weapon/aiModule/corp
name = "\improper 'Corporate' core AI module"
desc = "A 'Corporate' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4)
laws = new/datum/ai_laws/corporate
/******************** Drone ********************/
/obj/item/weapon/aiModule/drone
name = "\improper 'Drone' core AI module"
desc = "A 'Drone' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 4)
laws = new/datum/ai_laws/drone
/****************** P.A.L.A.D.I.N. **************/
/obj/item/weapon/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 = list(TECH_DATA = 3, TECH_MATERIAL = 6)
laws = new/datum/ai_laws/paladin
/****************** T.Y.R.A.N.T. *****************/
/obj/item/weapon/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 = list(TECH_DATA = 3, TECH_MATERIAL = 6, TECH_ILLEGAL = 2)
laws = new/datum/ai_laws/tyrant()
/******************** Freeform Core ******************/
/obj/item/weapon/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 = list(TECH_DATA = 3, TECH_MATERIAL = 6)
/obj/item/weapon/aiModule/freeformcore/attack_self(var/mob/user as mob)
..()
var/newlaw = ""
var/targName = sanitize(tgui_input_text(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/weapon/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/weapon/aiModule/freeformcore/install(var/obj/machinery/computer/C, var/mob/living/user)
if(!newFreeFormLaw)
to_chat(usr, "No law detected on module, please create one.")
return 0
..()
/obj/item/weapon/aiModule/syndicate // Slightly more dynamic freeform module -- TLE
name = "hacked AI module"
var/newFreeFormLaw = ""
desc = "A hacked AI law module: '<freeform>'"
origin_tech = list(TECH_DATA = 3, TECH_MATERIAL = 6, TECH_ILLEGAL = 7)
/obj/item/weapon/aiModule/syndicate/attack_self(var/mob/user as mob)
..()
var/newlaw = ""
var/targName = sanitize(tgui_input_text(usr, "Please enter a new law for the AI.", "Freeform Law Entry", newlaw))
newFreeFormLaw = targName
desc = "A hacked AI law module: '[newFreeFormLaw]'"
/obj/item/weapon/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='danger'>BZZZZT</span>")
var/law = "[newFreeFormLaw]"
target.add_ion_law(law)
target.show_laws()
/obj/item/weapon/aiModule/syndicate/install(var/obj/machinery/computer/C, var/mob/living/user)
if(!newFreeFormLaw)
to_chat(usr, "No law detected on module, please create one.")
return 0
..()
/******************** Robocop ********************/
/obj/item/weapon/aiModule/robocop // -- TLE
name = "\improper 'Robocop' core AI module"
desc = "A 'Robocop' Core AI Module: 'Reconfigures the AI's core three laws.'"
origin_tech = list(TECH_DATA = 4)
laws = new/datum/ai_laws/robocop()
/******************** Antimov ********************/
/obj/item/weapon/aiModule/antimov // -- TLE
name = "\improper 'Antimov' core AI module"
desc = "An 'Antimov' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 4)
laws = new/datum/ai_laws/antimov()
/****************** NT Aggressive *****************/
/obj/item/weapon/aiModule/nanotrasen_aggressive
name = "\improper 'NT Aggressive' core AI module"
desc = "An 'NT Aggressive' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3, TECH_ILLEGAL = 1)
laws = new/datum/ai_laws/nanotrasen_aggressive()
/******************** Mercenary Directives ********************/
/obj/item/weapon/aiModule/syndicate_override
name = "\improper 'Mercenary Directives' core AI module"
desc = "A 'Mercenary Directives' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 4, TECH_ILLEGAL = 4)
laws = new/datum/ai_laws/syndicate_override()
/******************** Spider Clan Directives ********************/
/obj/item/weapon/aiModule/ninja_override
name = "\improper 'Spider Clan Directives' core AI module"
desc = "A 'Spider Clan Directives' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 4, TECH_ILLEGAL = 4)
laws = new/datum/ai_laws/ninja_override()
/******************** Maintenance ********************/
/obj/item/weapon/aiModule/maintenance
name = "\improper 'Maintenance' core AI module"
desc = "A 'Maintenance' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/maintenance()
/******************** Peacekeeper ********************/
/obj/item/weapon/aiModule/peacekeeper
name = "\improper 'Peacekeeper' core AI module"
desc = "A 'Peacekeeper' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/peacekeeper()
/******************** Reporter ********************/
/obj/item/weapon/aiModule/reporter
name = "\improper 'Reporter' core AI module"
desc = "A 'Reporter' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/reporter()
/******************** Live and Let Live ********************/
/obj/item/weapon/aiModule/live_and_let_live
name = "\improper 'Live and Let Live' core AI module"
desc = "A 'Live and Let Live' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/live_and_let_live()
/******************** Guardian of Balance ********************/
/obj/item/weapon/aiModule/balance
name = "\improper 'Guardian of Balance' core AI module"
desc = "A 'Guardian of Balance' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/balance()
/******************** Gravekeeper ********************/
/obj/item/weapon/aiModule/gravekeeper
name = "\improper 'Gravekeeper' core AI module"
desc = "A 'Gravekeeper' Core AI Module: 'Reconfigures the AI's core laws.'"
origin_tech = list(TECH_DATA = 3)
laws = new/datum/ai_laws/gravekeeper()
+318 -318
View File
@@ -1,318 +1,318 @@
// Contains the rapid construction device.
/obj/item/weapon/rcd
name = "rapid construction device"
desc = "A device used to rapidly build and deconstruct. Reload with compressed matter cartridges."
icon = 'icons/obj/tools.dmi'
icon_state = "rcd"
item_state = "rcd"
drop_sound = 'sound/items/drop/gun.ogg'
pickup_sound = 'sound/items/pickup/gun.ogg'
flags = NOBLUDGEON
force = 10
throwforce = 10
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 2)
matter = list(DEFAULT_WALL_MATERIAL = 50000)
preserve_item = TRUE // RCDs are pretty important.
var/datum/effect/effect/system/spark_spread/spark_system
var/stored_matter = 0
var/max_stored_matter = RCD_MAX_CAPACITY
var/ranged = FALSE
var/busy = FALSE
var/allow_concurrent_building = FALSE // If true, allows for multiple RCD builds at the same time.
var/mode_index = 1
var/list/modes = list(RCD_FLOORWALL, RCD_AIRLOCK, RCD_WINDOWGRILLE, RCD_DECONSTRUCT)
var/can_remove_rwalls = FALSE
var/airlock_type = /obj/machinery/door/airlock
var/window_type = /obj/structure/window/reinforced/full
var/material_to_use = DEFAULT_WALL_MATERIAL // So badmins can make RCDs that print diamond walls.
var/make_rwalls = FALSE // If true, when building walls, they will be reinforced.
/* VOREStation Removal - Unused
/obj/item/weapon/rcd/Initialize()
src.spark_system = new /datum/effect/effect/system/spark_spread
spark_system.set_up(5, 0, src)
spark_system.attach(src)
return ..()
*/
/obj/item/weapon/rcd/Destroy()
QDEL_NULL(spark_system)
spark_system = null
return ..()
/obj/item/weapon/rcd/examine(mob/user)
. = ..()
. += display_resources()
// Used to show how much stuff (matter units, cell charge, etc) is left inside.
/obj/item/weapon/rcd/proc/display_resources()
return "It currently holds [stored_matter]/[max_stored_matter] matter-units."
// Used to add new cartridges.
/* VOREStation Tweak - Wow this is annoying, moved to _vr file for overhaul
/obj/item/weapon/rcd/attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/weapon/rcd_ammo))
var/obj/item/weapon/rcd_ammo/cartridge = W
if((stored_matter + cartridge.remaining) > max_stored_matter)
to_chat(user, span("warning", "The RCD can't hold that many additional matter-units."))
return FALSE
stored_matter += cartridge.remaining
user.drop_from_inventory(W)
qdel(W)
playsound(src, 'sound/machines/click.ogg', 50, 1)
to_chat(user, span("notice", "The RCD now holds [stored_matter]/[max_stored_matter] matter-units."))
return TRUE
return ..()
*/
// Changes which mode it is on.
/obj/item/weapon/rcd/attack_self(mob/living/user)
/* VOREStation Removal - Moved to VR
if(mode_index >= modes.len) // Shouldn't overflow unless someone messes with it in VV poorly but better safe than sorry.
mode_index = 1
else
mode_index++
to_chat(user, span("notice", "Changed mode to '[modes[mode_index]]'."))
playsound(src, 'sound/effects/pop.ogg', 50, 0)
if(prob(20))
src.spark_system.start()
*/
// Removes resources if the RCD can afford it.
/obj/item/weapon/rcd/proc/consume_resources(amount)
if(!can_afford(amount))
return FALSE
stored_matter -= amount
return TRUE
// Useful for testing before actually paying (e.g. before a do_after() ).
/obj/item/weapon/rcd/proc/can_afford(amount)
return stored_matter >= amount
/obj/item/weapon/rcd/afterattack(atom/A, mob/living/user, proximity)
if(!ranged && !proximity)
return FALSE
use_rcd(A, user)
// Used to call rcd_act() on the atom hit.
/obj/item/weapon/rcd/proc/use_rcd(atom/A, mob/living/user)
if(busy && !allow_concurrent_building)
to_chat(user, span("warning", "\The [src] is busy finishing its current operation, be patient."))
return FALSE
var/list/rcd_results = A.rcd_values(user, src, modes[mode_index])
if(!rcd_results)
to_chat(user, span("warning", "\The [src] blinks a red light as you point it towards \the [A], indicating \
that it won't work. Try changing the mode, or use it on something else."))
return FALSE
if(!can_afford(rcd_results[RCD_VALUE_COST]))
to_chat(user, span("warning", "\The [src] lacks the required material to start."))
return FALSE
playsound(src, 'sound/machines/click.ogg', 50, 1)
var/true_delay = rcd_results[RCD_VALUE_DELAY] * toolspeed
var/datum/beam/rcd_beam = null
if(ranged)
var/atom/movable/beam_origin = user // This is needed because mecha pilots are inside an object and the beam won't be made if it tries to attach to them..
if(!isturf(beam_origin.loc))
beam_origin = user.loc
rcd_beam = beam_origin.Beam(A, icon_state = "rped_upgrade", time = max(true_delay, 5))
busy = TRUE
perform_effect(A, true_delay) //VOREStation Add
if(do_after(user, true_delay, target = A))
busy = FALSE
// Doing another check in case we lost matter during the delay for whatever reason.
if(!can_afford(rcd_results[RCD_VALUE_COST]))
to_chat(user, span("warning", "\The [src] lacks the required material to finish the operation."))
return FALSE
if(A.rcd_act(user, src, rcd_results[RCD_VALUE_MODE]))
consume_resources(rcd_results[RCD_VALUE_COST])
playsound(A, 'sound/items/deconstruct.ogg', 50, 1)
return TRUE
// If they moved, kill the beam immediately.
qdel(rcd_beam)
busy = FALSE
return FALSE
// RCD variants.
// This one starts full.
/obj/item/weapon/rcd/loaded/Initialize()
stored_matter = max_stored_matter
return ..()
// This one makes cooler walls by using an alternative material.
/obj/item/weapon/rcd/shipwright
name = "shipwright's rapid construction device"
desc = "A device used to rapidly build and deconstruct. This version creates a stronger variant of wall, often \
used in the construction of hulls for starships. Reload with compressed matter cartridges."
material_to_use = MAT_STEELHULL
/obj/item/weapon/rcd/shipwright/loaded/Initialize()
stored_matter = max_stored_matter
return ..()
/obj/item/weapon/rcd/advanced
name = "advanced rapid construction device"
desc = "A device used to rapidly build and deconstruct. This version works at a range, builds faster, and has a much larger capacity. \
Reload with compressed matter cartridges."
icon_state = "adv_rcd"
ranged = TRUE
toolspeed = 0.5 // Twice as fast.
max_stored_matter = RCD_MAX_CAPACITY * 3 // Three times capacity.
/obj/item/weapon/rcd/advanced/loaded/Initialize()
stored_matter = max_stored_matter
return ..()
// Electric RCDs.
// Currently just a base for the mounted RCDs.
// Currently there isn't a way to swap out the cells.
// One could be added if there is demand to do so.
/obj/item/weapon/rcd/electric
name = "electric rapid construction device"
desc = "A device used to rapidly build and deconstruct. It runs directly off of electricity, no matter cartridges needed."
icon_state = "electric_rcd"
var/obj/item/weapon/cell/cell = null
var/make_cell = TRUE // If false, initialize() won't spawn a cell for this.
var/electric_cost_coefficent = 83.33 // Higher numbers make it less efficent. 86.3... means it should matche the standard RCD capacity on a 10k cell.
/obj/item/weapon/rcd/electric/Initialize()
if(make_cell)
cell = new /obj/item/weapon/cell/high(src)
return ..()
/obj/item/weapon/rcd/electric/Destroy()
if(cell)
QDEL_NULL(cell)
return ..()
/obj/item/weapon/rcd/electric/get_cell()
return cell
/obj/item/weapon/rcd/electric/can_afford(amount) // This makes it so borgs won't drain their last sliver of charge by mistake, as a bonus.
var/obj/item/weapon/cell/cell = get_cell()
if(cell)
return cell.check_charge(amount * electric_cost_coefficent)
return FALSE
/obj/item/weapon/rcd/electric/consume_resources(amount)
if(!can_afford(amount))
return FALSE
var/obj/item/weapon/cell/cell = get_cell()
return cell.checked_use(amount * electric_cost_coefficent)
/obj/item/weapon/rcd/electric/display_resources()
var/obj/item/weapon/cell/cell = get_cell()
if(cell)
return "The power source connected to \the [src] has a charge of [cell.percent()]%."
return "It lacks a source of power, and cannot function."
// 'Mounted' RCDs, used for borgs/RIGs/Mechas, all of which use their cells to drive the RCD.
/obj/item/weapon/rcd/electric/mounted
name = "mounted electric rapid construction device"
desc = "A device used to rapidly build and deconstruct. It runs directly off of electricity from an external power source."
make_cell = FALSE
/obj/item/weapon/rcd/electric/mounted/get_cell()
return get_external_power_supply()
/obj/item/weapon/rcd/electric/mounted/proc/get_external_power_supply()
if(isrobot(loc)) // In a borg.
var/mob/living/silicon/robot/R = loc
return R.cell
if(istype(loc, /obj/item/rig_module)) // In a RIG.
var/obj/item/rig_module/module = loc
if(module.holder) // Is it attached to a RIG?
return module.holder.cell
if(istype(loc, /obj/item/mecha_parts/mecha_equipment)) // In a mech.
var/obj/item/mecha_parts/mecha_equipment/ME = loc
if(ME.chassis) // Is the part attached to a mech?
return ME.chassis.cell
return null
// RCDs for borgs.
/obj/item/weapon/rcd/electric/mounted/borg
can_remove_rwalls = TRUE
desc = "A device used to rapidly build and deconstruct. It runs directly off of electricity, drawing directly from your cell."
electric_cost_coefficent = 41.66 // Twice as efficent, out of pity.
toolspeed = 0.5 // Twice as fast, since borg versions typically have this.
/obj/item/weapon/rcd/electric/mounted/borg/swarm
can_remove_rwalls = FALSE
name = "Rapid Assimilation Device"
ranged = TRUE
toolspeed = 0.7
material_to_use = MAT_STEELHULL
/obj/item/weapon/rcd/electric/mounted/borg/lesser
can_remove_rwalls = FALSE
// RCDs for RIGs.
/obj/item/weapon/rcd/electric/mounted/rig
// RCDs for Mechs.
/obj/item/weapon/rcd/electric/mounted/mecha
ranged = TRUE
toolspeed = 0.5
// Infinite use RCD for debugging/adminbuse.
/obj/item/weapon/rcd/debug
name = "self-repleshing rapid construction device"
desc = "An RCD that appears to be plated with gold. For some reason it also seems to just \
be vastly superior to all other RCDs ever created, possibly due to it being colored gold."
icon_state = "debug_rcd"
ranged = TRUE
can_remove_rwalls = TRUE
allow_concurrent_building = TRUE
toolspeed = 0.25 // Four times as fast.
/obj/item/weapon/rcd/debug/can_afford(amount)
return TRUE
/obj/item/weapon/rcd/debug/consume_resources(amount)
return TRUE
/obj/item/weapon/rcd/debug/attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/weapon/rcd_ammo))
to_chat(user, span("notice", "\The [src] makes its own material, no need to add more."))
return FALSE
return ..()
/obj/item/weapon/rcd/debug/display_resources()
return "It has UNLIMITED POWER!"
// Ammo for the (non-electric) RCDs.
/obj/item/weapon/rcd_ammo
name = "compressed matter cartridge"
desc = "Highly compressed matter for the RCD."
icon = 'icons/obj/ammo.dmi'
icon_state = "rcd"
item_state = "rcdammo"
w_class = ITEMSIZE_SMALL
origin_tech = list(TECH_MATERIAL = 2)
matter = list(DEFAULT_WALL_MATERIAL = 30000,MAT_GLASS = 15000)
var/remaining = RCD_MAX_CAPACITY / 3
/obj/item/weapon/rcd_ammo/large
name = "high-capacity matter cartridge"
desc = "Do not ingest."
matter = list(DEFAULT_WALL_MATERIAL = 45000,MAT_GLASS = 22500)
origin_tech = list(TECH_MATERIAL = 4)
remaining = RCD_MAX_CAPACITY
// Contains the rapid construction device.
/obj/item/weapon/rcd
name = "rapid construction device"
desc = "A device used to rapidly build and deconstruct. Reload with compressed matter cartridges."
icon = 'icons/obj/tools.dmi'
icon_state = "rcd"
item_state = "rcd"
drop_sound = 'sound/items/drop/gun.ogg'
pickup_sound = 'sound/items/pickup/gun.ogg'
flags = NOBLUDGEON
force = 10
throwforce = 10
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_ENGINEERING = 4, TECH_MATERIAL = 2)
matter = list(DEFAULT_WALL_MATERIAL = 50000)
preserve_item = TRUE // RCDs are pretty important.
var/datum/effect/effect/system/spark_spread/spark_system
var/stored_matter = 0
var/max_stored_matter = RCD_MAX_CAPACITY
var/ranged = FALSE
var/busy = FALSE
var/allow_concurrent_building = FALSE // If true, allows for multiple RCD builds at the same time.
var/mode_index = 1
var/list/modes = list(RCD_FLOORWALL, RCD_AIRLOCK, RCD_WINDOWGRILLE, RCD_DECONSTRUCT)
var/can_remove_rwalls = FALSE
var/airlock_type = /obj/machinery/door/airlock
var/window_type = /obj/structure/window/reinforced/full
var/material_to_use = DEFAULT_WALL_MATERIAL // So badmins can make RCDs that print diamond walls.
var/make_rwalls = FALSE // If true, when building walls, they will be reinforced.
/* VOREStation Removal - Unused
/obj/item/weapon/rcd/Initialize()
src.spark_system = new /datum/effect/effect/system/spark_spread
spark_system.set_up(5, 0, src)
spark_system.attach(src)
return ..()
*/
/obj/item/weapon/rcd/Destroy()
QDEL_NULL(spark_system)
spark_system = null
return ..()
/obj/item/weapon/rcd/examine(mob/user)
. = ..()
. += display_resources()
// Used to show how much stuff (matter units, cell charge, etc) is left inside.
/obj/item/weapon/rcd/proc/display_resources()
return "It currently holds [stored_matter]/[max_stored_matter] matter-units."
// Used to add new cartridges.
/* VOREStation Tweak - Wow this is annoying, moved to _vr file for overhaul
/obj/item/weapon/rcd/attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/weapon/rcd_ammo))
var/obj/item/weapon/rcd_ammo/cartridge = W
if((stored_matter + cartridge.remaining) > max_stored_matter)
to_chat(user, span("warning", "The RCD can't hold that many additional matter-units."))
return FALSE
stored_matter += cartridge.remaining
user.drop_from_inventory(W)
qdel(W)
playsound(src, 'sound/machines/click.ogg', 50, 1)
to_chat(user, span("notice", "The RCD now holds [stored_matter]/[max_stored_matter] matter-units."))
return TRUE
return ..()
*/
// Changes which mode it is on.
/obj/item/weapon/rcd/attack_self(mob/living/user)
/* VOREStation Removal - Moved to VR
if(mode_index >= modes.len) // Shouldn't overflow unless someone messes with it in VV poorly but better safe than sorry.
mode_index = 1
else
mode_index++
to_chat(user, span("notice", "Changed mode to '[modes[mode_index]]'."))
playsound(src, 'sound/effects/pop.ogg', 50, 0)
if(prob(20))
src.spark_system.start()
*/
// Removes resources if the RCD can afford it.
/obj/item/weapon/rcd/proc/consume_resources(amount)
if(!can_afford(amount))
return FALSE
stored_matter -= amount
return TRUE
// Useful for testing before actually paying (e.g. before a do_after() ).
/obj/item/weapon/rcd/proc/can_afford(amount)
return stored_matter >= amount
/obj/item/weapon/rcd/afterattack(atom/A, mob/living/user, proximity)
if(!ranged && !proximity)
return FALSE
use_rcd(A, user)
// Used to call rcd_act() on the atom hit.
/obj/item/weapon/rcd/proc/use_rcd(atom/A, mob/living/user)
if(busy && !allow_concurrent_building)
to_chat(user, span("warning", "\The [src] is busy finishing its current operation, be patient."))
return FALSE
var/list/rcd_results = A.rcd_values(user, src, modes[mode_index])
if(!rcd_results)
to_chat(user, span("warning", "\The [src] blinks a red light as you point it towards \the [A], indicating \
that it won't work. Try changing the mode, or use it on something else."))
return FALSE
if(!can_afford(rcd_results[RCD_VALUE_COST]))
to_chat(user, span("warning", "\The [src] lacks the required material to start."))
return FALSE
playsound(src, 'sound/machines/click.ogg', 50, 1)
var/true_delay = rcd_results[RCD_VALUE_DELAY] * toolspeed
var/datum/beam/rcd_beam = null
if(ranged)
var/atom/movable/beam_origin = user // This is needed because mecha pilots are inside an object and the beam won't be made if it tries to attach to them..
if(!isturf(beam_origin.loc))
beam_origin = user.loc
rcd_beam = beam_origin.Beam(A, icon_state = "rped_upgrade", time = max(true_delay, 5))
busy = TRUE
perform_effect(A, true_delay) //VOREStation Add
if(do_after(user, true_delay, target = A))
busy = FALSE
// Doing another check in case we lost matter during the delay for whatever reason.
if(!can_afford(rcd_results[RCD_VALUE_COST]))
to_chat(user, span("warning", "\The [src] lacks the required material to finish the operation."))
return FALSE
if(A.rcd_act(user, src, rcd_results[RCD_VALUE_MODE]))
consume_resources(rcd_results[RCD_VALUE_COST])
playsound(A, 'sound/items/deconstruct.ogg', 50, 1)
return TRUE
// If they moved, kill the beam immediately.
qdel(rcd_beam)
busy = FALSE
return FALSE
// RCD variants.
// This one starts full.
/obj/item/weapon/rcd/loaded/Initialize()
stored_matter = max_stored_matter
return ..()
// This one makes cooler walls by using an alternative material.
/obj/item/weapon/rcd/shipwright
name = "shipwright's rapid construction device"
desc = "A device used to rapidly build and deconstruct. This version creates a stronger variant of wall, often \
used in the construction of hulls for starships. Reload with compressed matter cartridges."
material_to_use = MAT_STEELHULL
/obj/item/weapon/rcd/shipwright/loaded/Initialize()
stored_matter = max_stored_matter
return ..()
/obj/item/weapon/rcd/advanced
name = "advanced rapid construction device"
desc = "A device used to rapidly build and deconstruct. This version works at a range, builds faster, and has a much larger capacity. \
Reload with compressed matter cartridges."
icon_state = "adv_rcd"
ranged = TRUE
toolspeed = 0.5 // Twice as fast.
max_stored_matter = RCD_MAX_CAPACITY * 3 // Three times capacity.
/obj/item/weapon/rcd/advanced/loaded/Initialize()
stored_matter = max_stored_matter
return ..()
// Electric RCDs.
// Currently just a base for the mounted RCDs.
// Currently there isn't a way to swap out the cells.
// One could be added if there is demand to do so.
/obj/item/weapon/rcd/electric
name = "electric rapid construction device"
desc = "A device used to rapidly build and deconstruct. It runs directly off of electricity, no matter cartridges needed."
icon_state = "electric_rcd"
var/obj/item/weapon/cell/cell = null
var/make_cell = TRUE // If false, initialize() won't spawn a cell for this.
var/electric_cost_coefficent = 83.33 // Higher numbers make it less efficent. 86.3... means it should matche the standard RCD capacity on a 10k cell.
/obj/item/weapon/rcd/electric/Initialize()
if(make_cell)
cell = new /obj/item/weapon/cell/high(src)
return ..()
/obj/item/weapon/rcd/electric/Destroy()
if(cell)
QDEL_NULL(cell)
return ..()
/obj/item/weapon/rcd/electric/get_cell()
return cell
/obj/item/weapon/rcd/electric/can_afford(amount) // This makes it so borgs won't drain their last sliver of charge by mistake, as a bonus.
var/obj/item/weapon/cell/cell = get_cell()
if(cell)
return cell.check_charge(amount * electric_cost_coefficent)
return FALSE
/obj/item/weapon/rcd/electric/consume_resources(amount)
if(!can_afford(amount))
return FALSE
var/obj/item/weapon/cell/cell = get_cell()
return cell.checked_use(amount * electric_cost_coefficent)
/obj/item/weapon/rcd/electric/display_resources()
var/obj/item/weapon/cell/cell = get_cell()
if(cell)
return "The power source connected to \the [src] has a charge of [cell.percent()]%."
return "It lacks a source of power, and cannot function."
// 'Mounted' RCDs, used for borgs/RIGs/Mechas, all of which use their cells to drive the RCD.
/obj/item/weapon/rcd/electric/mounted
name = "mounted electric rapid construction device"
desc = "A device used to rapidly build and deconstruct. It runs directly off of electricity from an external power source."
make_cell = FALSE
/obj/item/weapon/rcd/electric/mounted/get_cell()
return get_external_power_supply()
/obj/item/weapon/rcd/electric/mounted/proc/get_external_power_supply()
if(isrobot(loc)) // In a borg.
var/mob/living/silicon/robot/R = loc
return R.cell
if(istype(loc, /obj/item/rig_module)) // In a RIG.
var/obj/item/rig_module/module = loc
if(module.holder) // Is it attached to a RIG?
return module.holder.cell
if(istype(loc, /obj/item/mecha_parts/mecha_equipment)) // In a mech.
var/obj/item/mecha_parts/mecha_equipment/ME = loc
if(ME.chassis) // Is the part attached to a mech?
return ME.chassis.cell
return null
// RCDs for borgs.
/obj/item/weapon/rcd/electric/mounted/borg
can_remove_rwalls = TRUE
desc = "A device used to rapidly build and deconstruct. It runs directly off of electricity, drawing directly from your cell."
electric_cost_coefficent = 41.66 // Twice as efficent, out of pity.
toolspeed = 0.5 // Twice as fast, since borg versions typically have this.
/obj/item/weapon/rcd/electric/mounted/borg/swarm
can_remove_rwalls = FALSE
name = "Rapid Assimilation Device"
ranged = TRUE
toolspeed = 0.7
material_to_use = MAT_STEELHULL
/obj/item/weapon/rcd/electric/mounted/borg/lesser
can_remove_rwalls = FALSE
// RCDs for RIGs.
/obj/item/weapon/rcd/electric/mounted/rig
// RCDs for Mechs.
/obj/item/weapon/rcd/electric/mounted/mecha
ranged = TRUE
toolspeed = 0.5
// Infinite use RCD for debugging/adminbuse.
/obj/item/weapon/rcd/debug
name = "self-repleshing rapid construction device"
desc = "An RCD that appears to be plated with gold. For some reason it also seems to just \
be vastly superior to all other RCDs ever created, possibly due to it being colored gold."
icon_state = "debug_rcd"
ranged = TRUE
can_remove_rwalls = TRUE
allow_concurrent_building = TRUE
toolspeed = 0.25 // Four times as fast.
/obj/item/weapon/rcd/debug/can_afford(amount)
return TRUE
/obj/item/weapon/rcd/debug/consume_resources(amount)
return TRUE
/obj/item/weapon/rcd/debug/attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/weapon/rcd_ammo))
to_chat(user, span("notice", "\The [src] makes its own material, no need to add more."))
return FALSE
return ..()
/obj/item/weapon/rcd/debug/display_resources()
return "It has UNLIMITED POWER!"
// Ammo for the (non-electric) RCDs.
/obj/item/weapon/rcd_ammo
name = "compressed matter cartridge"
desc = "Highly compressed matter for the RCD."
icon = 'icons/obj/ammo.dmi'
icon_state = "rcd"
item_state = "rcdammo"
w_class = ITEMSIZE_SMALL
origin_tech = list(TECH_MATERIAL = 2)
matter = list(DEFAULT_WALL_MATERIAL = 30000,MAT_GLASS = 15000)
var/remaining = RCD_MAX_CAPACITY / 3
/obj/item/weapon/rcd_ammo/large
name = "high-capacity matter cartridge"
desc = "Do not ingest."
matter = list(DEFAULT_WALL_MATERIAL = 45000,MAT_GLASS = 22500)
origin_tech = list(TECH_MATERIAL = 4)
remaining = RCD_MAX_CAPACITY
+136 -136
View File
@@ -1,136 +1,136 @@
/*
CONTAINS:
RSF
*/
/obj/item/weapon/rsf
name = "\improper Rapid-Service-Fabricator"
desc = "A device used to rapidly deploy service items."
description_info = "Control Clicking on the device will allow you to choose the glass it dispenses when in the proper mode."
icon = 'icons/obj/tools_vr.dmi' //VOREStation Edit
icon_state = "rsf" //VOREStation Edit
opacity = 0
density = FALSE
anchored = FALSE
matter = list(DEFAULT_WALL_MATERIAL = 25000)
var/stored_matter = 30
var/mode = 1
var/obj/item/weapon/reagent_containers/glasstype = /obj/item/weapon/reagent_containers/food/drinks/metaglass
var/list/container_types = list(
"metamorphic glass" = /obj/item/weapon/reagent_containers/food/drinks/metaglass,
"metamorphic pint glass" = /obj/item/weapon/reagent_containers/food/drinks/metaglass/metapint,
"half-pint glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/square,
"rocks glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/rocks,
"milkshake glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/shake,
"cocktail glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/cocktail,
"shot glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/shot,
"pint glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/pint,
"mug" = /obj/item/weapon/reagent_containers/food/drinks/glass2/mug,
"wine glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/wine,
"condiment bottle" = /obj/item/weapon/reagent_containers/food/condiment
)
w_class = ITEMSIZE_NORMAL
/obj/item/weapon/rsf/examine(mob/user)
. = ..()
if(get_dist(user, src) == 0)
. += "<span class='notice'>It currently holds [stored_matter]/30 fabrication-units.</span>"
/obj/item/weapon/rsf/attackby(obj/item/weapon/W as obj, mob/user as mob)
..()
if (istype(W, /obj/item/weapon/rcd_ammo))
if ((stored_matter + 10) > 30)
to_chat(user, "<span class='warning'>The RSF can't hold any more matter.</span>")
return
qdel(W)
stored_matter += 10
playsound(src, 'sound/machines/click.ogg', 10, 1)
to_chat(user,"<span class='notice'>The RSF now holds [stored_matter]/30 fabrication-units.</span>")
return
/obj/item/weapon/rsf/CtrlClick(mob/living/user)
if(!Adjacent(user) || !istype(user))
to_chat(user,"<span class='notice'>You are too far away.</span>")
return
var/glass_choice = tgui_input_list(user, "Please choose which type of glass you would like to produce.", "Glass Choice", container_types)
if(glass_choice)
glasstype = container_types[glass_choice]
else
glasstype = /obj/item/weapon/reagent_containers/food/drinks/metaglass
/obj/item/weapon/rsf/attack_self(mob/user as mob)
playsound(src, 'sound/effects/pop.ogg', 50, 0)
if (mode == 1)
mode = 2
to_chat(user,"<span class='notice'>Changed dispensing mode to 'Container'.</span>")
return
if (mode == 2)
mode = 3
to_chat(user,"<span class='notice'>Changed dispensing mode to 'Paper'</span>")
return
if (mode == 3)
mode = 4
to_chat(user,"<span class='notice'>Changed dispensing mode to 'Pen'</span>")
return
if (mode == 4)
mode = 5
to_chat(user,"<span class='notice'>Changed dispensing mode to 'Dice Pack'</span>")
return
if (mode == 5)
mode = 1
to_chat(user,"<span class='notice'>Changed dispensing mode to 'Cigarette'</span>")
return
/obj/item/weapon/rsf/afterattack(atom/A, mob/user as mob, proximity)
if(!proximity) return
if(istype(user,/mob/living/silicon/robot))
var/mob/living/silicon/robot/R = user
if(R.stat || !R.cell || R.cell.charge <= 0)
return
else
if(stored_matter <= 0)
return
if(!istype(A, /obj/structure/table) && !istype(A, /turf/simulated/floor))
return
playsound(src, 'sound/machines/click.ogg', 10, 1)
var/used_energy = 0
var/obj/product
switch(mode)
if(1)
product = new /obj/item/clothing/mask/smokable/cigarette()
used_energy = 10
if(2)
product = new glasstype()
used_energy = 50
if(3)
product = new /obj/item/weapon/paper()
used_energy = 10
if(4)
product = new /obj/item/weapon/pen()
used_energy = 50
if(5)
product = new /obj/item/weapon/storage/pill_bottle/dice()
used_energy = 200
to_chat(user,"<span class='notice'>Dispensing [product ? product : "product"]...</span>")
product.loc = get_turf(A)
if(isrobot(user))
var/mob/living/silicon/robot/R = user
if(R.cell)
R.cell.use(used_energy)
else
stored_matter--
to_chat(user,"<span class='notice'>The RSF now holds [stored_matter]/30 fabrication-units.</span>")
/*
CONTAINS:
RSF
*/
/obj/item/weapon/rsf
name = "\improper Rapid-Service-Fabricator"
desc = "A device used to rapidly deploy service items."
description_info = "Control Clicking on the device will allow you to choose the glass it dispenses when in the proper mode."
icon = 'icons/obj/tools_vr.dmi' //VOREStation Edit
icon_state = "rsf" //VOREStation Edit
opacity = 0
density = FALSE
anchored = FALSE
matter = list(DEFAULT_WALL_MATERIAL = 25000)
var/stored_matter = 30
var/mode = 1
var/obj/item/weapon/reagent_containers/glasstype = /obj/item/weapon/reagent_containers/food/drinks/metaglass
var/list/container_types = list(
"metamorphic glass" = /obj/item/weapon/reagent_containers/food/drinks/metaglass,
"metamorphic pint glass" = /obj/item/weapon/reagent_containers/food/drinks/metaglass/metapint,
"half-pint glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/square,
"rocks glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/rocks,
"milkshake glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/shake,
"cocktail glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/cocktail,
"shot glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/shot,
"pint glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/pint,
"mug" = /obj/item/weapon/reagent_containers/food/drinks/glass2/mug,
"wine glass" = /obj/item/weapon/reagent_containers/food/drinks/glass2/wine,
"condiment bottle" = /obj/item/weapon/reagent_containers/food/condiment
)
w_class = ITEMSIZE_NORMAL
/obj/item/weapon/rsf/examine(mob/user)
. = ..()
if(get_dist(user, src) == 0)
. += "<span class='notice'>It currently holds [stored_matter]/30 fabrication-units.</span>"
/obj/item/weapon/rsf/attackby(obj/item/weapon/W as obj, mob/user as mob)
..()
if (istype(W, /obj/item/weapon/rcd_ammo))
if ((stored_matter + 10) > 30)
to_chat(user, "<span class='warning'>The RSF can't hold any more matter.</span>")
return
qdel(W)
stored_matter += 10
playsound(src, 'sound/machines/click.ogg', 10, 1)
to_chat(user,"<span class='notice'>The RSF now holds [stored_matter]/30 fabrication-units.</span>")
return
/obj/item/weapon/rsf/CtrlClick(mob/living/user)
if(!Adjacent(user) || !istype(user))
to_chat(user,"<span class='notice'>You are too far away.</span>")
return
var/glass_choice = tgui_input_list(user, "Please choose which type of glass you would like to produce.", "Glass Choice", container_types)
if(glass_choice)
glasstype = container_types[glass_choice]
else
glasstype = /obj/item/weapon/reagent_containers/food/drinks/metaglass
/obj/item/weapon/rsf/attack_self(mob/user as mob)
playsound(src, 'sound/effects/pop.ogg', 50, 0)
if (mode == 1)
mode = 2
to_chat(user,"<span class='notice'>Changed dispensing mode to 'Container'.</span>")
return
if (mode == 2)
mode = 3
to_chat(user,"<span class='notice'>Changed dispensing mode to 'Paper'</span>")
return
if (mode == 3)
mode = 4
to_chat(user,"<span class='notice'>Changed dispensing mode to 'Pen'</span>")
return
if (mode == 4)
mode = 5
to_chat(user,"<span class='notice'>Changed dispensing mode to 'Dice Pack'</span>")
return
if (mode == 5)
mode = 1
to_chat(user,"<span class='notice'>Changed dispensing mode to 'Cigarette'</span>")
return
/obj/item/weapon/rsf/afterattack(atom/A, mob/user as mob, proximity)
if(!proximity) return
if(istype(user,/mob/living/silicon/robot))
var/mob/living/silicon/robot/R = user
if(R.stat || !R.cell || R.cell.charge <= 0)
return
else
if(stored_matter <= 0)
return
if(!istype(A, /obj/structure/table) && !istype(A, /turf/simulated/floor))
return
playsound(src, 'sound/machines/click.ogg', 10, 1)
var/used_energy = 0
var/obj/product
switch(mode)
if(1)
product = new /obj/item/clothing/mask/smokable/cigarette()
used_energy = 10
if(2)
product = new glasstype()
used_energy = 50
if(3)
product = new /obj/item/weapon/paper()
used_energy = 10
if(4)
product = new /obj/item/weapon/pen()
used_energy = 50
if(5)
product = new /obj/item/weapon/storage/pill_bottle/dice()
used_energy = 200
to_chat(user,"<span class='notice'>Dispensing [product ? product : "product"]...</span>")
product.loc = get_turf(A)
if(isrobot(user))
var/mob/living/silicon/robot/R = user
if(R.cell)
R.cell.use(used_energy)
else
stored_matter--
to_chat(user,"<span class='notice'>The RSF now holds [stored_matter]/30 fabrication-units.</span>")
@@ -1,37 +1,37 @@
// **For augment items that aren't subtypes of other things.**
/obj/item/weapon/melee/augment
name = "integrated item"
desc = "A surprisingly non-descript item, integrated into its user. You probably shouldn't be seeing this."
icon = 'icons/obj/surgery.dmi'
icon_state = "augment_box"
/obj/item/weapon/melee/augment/blade
name = "handblade"
desc = "A sleek-looking telescopic blade that fits inside the hand. Favored by infiltration specialists and assassins."
icon_state = "augment_handblade"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi',
)
w_class = ITEMSIZE_SMALL
force = 15
armor_penetration = 25
sharp = TRUE
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
defend_chance = 10
projectile_parry_chance = 5
hitsound = 'sound/weapons/bladeslice.ogg'
/obj/item/weapon/melee/augment/blade/arm
name = "armblade"
desc = "A sleek-looking cybernetic blade that cleaves through people like butter. Favored by psychopaths and assassins."
icon_state = "augment_armblade"
w_class = ITEMSIZE_HUGE
force = 30
armor_penetration = 15
edge = TRUE
pry = 1
defend_chance = 40
// **For augment items that aren't subtypes of other things.**
/obj/item/weapon/melee/augment
name = "integrated item"
desc = "A surprisingly non-descript item, integrated into its user. You probably shouldn't be seeing this."
icon = 'icons/obj/surgery.dmi'
icon_state = "augment_box"
/obj/item/weapon/melee/augment/blade
name = "handblade"
desc = "A sleek-looking telescopic blade that fits inside the hand. Favored by infiltration specialists and assassins."
icon_state = "augment_handblade"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi',
)
w_class = ITEMSIZE_SMALL
force = 15
armor_penetration = 25
sharp = TRUE
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
defend_chance = 10
projectile_parry_chance = 5
hitsound = 'sound/weapons/bladeslice.ogg'
/obj/item/weapon/melee/augment/blade/arm
name = "armblade"
desc = "A sleek-looking cybernetic blade that cleaves through people like butter. Favored by psychopaths and assassins."
icon_state = "augment_armblade"
w_class = ITEMSIZE_HUGE
force = 30
armor_penetration = 15
edge = TRUE
pry = 1
defend_chance = 40
projectile_parry_chance = 20
File diff suppressed because it is too large Load Diff
@@ -1,74 +1,74 @@
/obj/item/weapon/circuitboard/microwave
name = T_BOARD("microwave")
desc = "The circuitboard for a microwave."
build_path = /obj/machinery/microwave
board_type = new /datum/frame/frame_types/microwave
contain_parts = 0
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
req_components = list(
/obj/item/weapon/stock_parts/console_screen = 1,
/obj/item/weapon/stock_parts/capacitor = 3, // Original Capacitor count was 1
/obj/item/weapon/stock_parts/motor = 1,
/obj/item/weapon/stock_parts/scanning_module = 1,
/obj/item/weapon/stock_parts/matter_bin = 2)
/obj/item/weapon/circuitboard/oven
name = T_BOARD("oven")
desc = "The circuitboard for an oven."
build_path = /obj/machinery/appliance/cooker/oven
board_type = new /datum/frame/frame_types/machine
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
req_components = list(
/obj/item/weapon/stock_parts/capacitor = 3,
/obj/item/weapon/stock_parts/scanning_module = 1,
/obj/item/weapon/stock_parts/matter_bin = 2)
/obj/item/weapon/circuitboard/fryer
name = T_BOARD("deep fryer")
desc = "The circuitboard for a deep fryer."
build_path = /obj/machinery/appliance/cooker/fryer
board_type = new /datum/frame/frame_types/machine
req_components = list(
/obj/item/weapon/stock_parts/capacitor = 3,
/obj/item/weapon/stock_parts/scanning_module = 1,
/obj/item/weapon/stock_parts/matter_bin = 2)
/obj/item/weapon/circuitboard/grill
name = T_BOARD("grill")
desc = "The circuitboard for an industrial grill."
build_path = /obj/machinery/appliance/cooker/grill
board_type = new /datum/frame/frame_types/machine
req_components = list(
/obj/item/weapon/stock_parts/capacitor = 3,
/obj/item/weapon/stock_parts/scanning_module = 1,
/obj/item/weapon/stock_parts/matter_bin = 2)
/obj/item/weapon/circuitboard/cerealmaker
name = T_BOARD("cereal maker")
desc = "The circuitboard for a cereal maker."
build_path = /obj/machinery/appliance/mixer/cereal
board_type = new /datum/frame/frame_types/machine
req_components = list(
/obj/item/weapon/stock_parts/capacitor = 3,
/obj/item/weapon/stock_parts/scanning_module = 1,
/obj/item/weapon/stock_parts/matter_bin = 2)
/obj/item/weapon/circuitboard/candymachine
name = T_BOARD("candy machine")
desc = "The circuitboard for a candy machine."
build_path = /obj/machinery/appliance/mixer/candy
board_type = new /datum/frame/frame_types/machine
req_components = list(
/obj/item/weapon/stock_parts/capacitor = 3,
/obj/item/weapon/stock_parts/scanning_module = 1,
/obj/item/weapon/stock_parts/matter_bin = 2)
/obj/item/weapon/circuitboard/microwave/advanced
name = T_BOARD("deluxe microwave")
build_path = /obj/machinery/microwave/advanced
board_type = new /datum/frame/frame_types/microwave
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
req_components = list(
/obj/item/weapon/stock_parts/console_screen = 1,
/obj/item/weapon/stock_parts/motor = 1,
/obj/item/weapon/circuitboard/microwave
name = T_BOARD("microwave")
desc = "The circuitboard for a microwave."
build_path = /obj/machinery/microwave
board_type = new /datum/frame/frame_types/microwave
contain_parts = 0
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
req_components = list(
/obj/item/weapon/stock_parts/console_screen = 1,
/obj/item/weapon/stock_parts/capacitor = 3, // Original Capacitor count was 1
/obj/item/weapon/stock_parts/motor = 1,
/obj/item/weapon/stock_parts/scanning_module = 1,
/obj/item/weapon/stock_parts/matter_bin = 2)
/obj/item/weapon/circuitboard/oven
name = T_BOARD("oven")
desc = "The circuitboard for an oven."
build_path = /obj/machinery/appliance/cooker/oven
board_type = new /datum/frame/frame_types/machine
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
req_components = list(
/obj/item/weapon/stock_parts/capacitor = 3,
/obj/item/weapon/stock_parts/scanning_module = 1,
/obj/item/weapon/stock_parts/matter_bin = 2)
/obj/item/weapon/circuitboard/fryer
name = T_BOARD("deep fryer")
desc = "The circuitboard for a deep fryer."
build_path = /obj/machinery/appliance/cooker/fryer
board_type = new /datum/frame/frame_types/machine
req_components = list(
/obj/item/weapon/stock_parts/capacitor = 3,
/obj/item/weapon/stock_parts/scanning_module = 1,
/obj/item/weapon/stock_parts/matter_bin = 2)
/obj/item/weapon/circuitboard/grill
name = T_BOARD("grill")
desc = "The circuitboard for an industrial grill."
build_path = /obj/machinery/appliance/cooker/grill
board_type = new /datum/frame/frame_types/machine
req_components = list(
/obj/item/weapon/stock_parts/capacitor = 3,
/obj/item/weapon/stock_parts/scanning_module = 1,
/obj/item/weapon/stock_parts/matter_bin = 2)
/obj/item/weapon/circuitboard/cerealmaker
name = T_BOARD("cereal maker")
desc = "The circuitboard for a cereal maker."
build_path = /obj/machinery/appliance/mixer/cereal
board_type = new /datum/frame/frame_types/machine
req_components = list(
/obj/item/weapon/stock_parts/capacitor = 3,
/obj/item/weapon/stock_parts/scanning_module = 1,
/obj/item/weapon/stock_parts/matter_bin = 2)
/obj/item/weapon/circuitboard/candymachine
name = T_BOARD("candy machine")
desc = "The circuitboard for a candy machine."
build_path = /obj/machinery/appliance/mixer/candy
board_type = new /datum/frame/frame_types/machine
req_components = list(
/obj/item/weapon/stock_parts/capacitor = 3,
/obj/item/weapon/stock_parts/scanning_module = 1,
/obj/item/weapon/stock_parts/matter_bin = 2)
/obj/item/weapon/circuitboard/microwave/advanced
name = T_BOARD("deluxe microwave")
build_path = /obj/machinery/microwave/advanced
board_type = new /datum/frame/frame_types/microwave
matter = list(MAT_STEEL = 50, MAT_GLASS = 50)
req_components = list(
/obj/item/weapon/stock_parts/console_screen = 1,
/obj/item/weapon/stock_parts/motor = 1,
/obj/item/weapon/stock_parts/capacitor = 1)
+87 -87
View File
@@ -1,87 +1,87 @@
/* Clown Items
* Contains:
* Banana Peels
* Soap
* Bike Horns
*/
/*
* Banana Peels
*/
/obj/item/weapon/bananapeel/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(istype(AM, /mob/living))
var/mob/living/M = AM
M.slip("the [src.name]",4)
/*
* Soap
*/
/obj/item/weapon/soap/Initialize()
. = ..()
create_reagents(5)
wet()
/obj/item/weapon/soap/proc/wet()
reagents.add_reagent("cleaner", 5)
/obj/item/weapon/soap/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(istype(AM, /mob/living))
var/mob/living/M = AM
M.slip("the [src.name]",3)
/obj/item/weapon/soap/afterattack(atom/target, mob/user as mob, proximity)
if(!proximity) return
//I couldn't feasibly fix the overlay bugs caused by cleaning items we are wearing.
//So this is a workaround. This also makes more sense from an IC standpoint. ~Carn
if(user.client && (target in user.client.screen))
to_chat(user, "<span class='notice'>You need to take that [target.name] off before cleaning it.</span>")
else if(istype(target,/obj/effect/decal/cleanable/blood))
to_chat(user, "<span class='notice'>You scrub \the [target.name] out.</span>")
target.clean_blood()
return //Blood is a cleanable decal, therefore needs to be accounted for before all cleanable decals.
else if(istype(target,/obj/effect/decal/cleanable))
to_chat(user, "<span class='notice'>You scrub \the [target.name] out.</span>")
qdel(target)
else if(istype(target,/turf))
to_chat(user, "<span class='notice'>You scrub \the [target.name] clean.</span>")
var/turf/T = target
T.clean(src, user)
else if(istype(target,/obj/structure/sink))
to_chat(user, "<span class='notice'>You wet \the [src] in the sink.</span>")
wet()
else
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
target.clean_blood(TRUE)
return
//attack_as_weapon
/obj/item/weapon/soap/attack(mob/living/target, mob/living/user, var/target_zone)
if(target && user && ishuman(target) && ishuman(user) && !user.incapacitated() && user.zone_sel &&user.zone_sel.selecting == "mouth" )
user.visible_message("<span class='danger'>\The [user] washes \the [target]'s mouth out with soap!</span>")
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN) //prevent spam
return
..()
/*
* Bike Horns
*/
/obj/item/weapon/bikehorn
var/honk_sound = 'sound/items/bikehorn.ogg'
/obj/item/weapon/bikehorn/attack_self(mob/user as mob)
if(spam_flag == 0)
spam_flag = 1
playsound(src, honk_sound, 50, 1)
src.add_fingerprint(user)
spawn(20)
spam_flag = 0
return
/obj/item/weapon/bikehorn/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(istype(AM, /mob/living))
playsound(src, honk_sound, 50, 1)
/* Clown Items
* Contains:
* Banana Peels
* Soap
* Bike Horns
*/
/*
* Banana Peels
*/
/obj/item/weapon/bananapeel/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(istype(AM, /mob/living))
var/mob/living/M = AM
M.slip("the [src.name]",4)
/*
* Soap
*/
/obj/item/weapon/soap/Initialize()
. = ..()
create_reagents(5)
wet()
/obj/item/weapon/soap/proc/wet()
reagents.add_reagent("cleaner", 5)
/obj/item/weapon/soap/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(istype(AM, /mob/living))
var/mob/living/M = AM
M.slip("the [src.name]",3)
/obj/item/weapon/soap/afterattack(atom/target, mob/user as mob, proximity)
if(!proximity) return
//I couldn't feasibly fix the overlay bugs caused by cleaning items we are wearing.
//So this is a workaround. This also makes more sense from an IC standpoint. ~Carn
if(user.client && (target in user.client.screen))
to_chat(user, "<span class='notice'>You need to take that [target.name] off before cleaning it.</span>")
else if(istype(target,/obj/effect/decal/cleanable/blood))
to_chat(user, "<span class='notice'>You scrub \the [target.name] out.</span>")
target.clean_blood()
return //Blood is a cleanable decal, therefore needs to be accounted for before all cleanable decals.
else if(istype(target,/obj/effect/decal/cleanable))
to_chat(user, "<span class='notice'>You scrub \the [target.name] out.</span>")
qdel(target)
else if(istype(target,/turf))
to_chat(user, "<span class='notice'>You scrub \the [target.name] clean.</span>")
var/turf/T = target
T.clean(src, user)
else if(istype(target,/obj/structure/sink))
to_chat(user, "<span class='notice'>You wet \the [src] in the sink.</span>")
wet()
else
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
target.clean_blood(TRUE)
return
//attack_as_weapon
/obj/item/weapon/soap/attack(mob/living/target, mob/living/user, var/target_zone)
if(target && user && ishuman(target) && ishuman(user) && !user.incapacitated() && user.zone_sel &&user.zone_sel.selecting == "mouth" )
user.visible_message("<span class='danger'>\The [user] washes \the [target]'s mouth out with soap!</span>")
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN) //prevent spam
return
..()
/*
* Bike Horns
*/
/obj/item/weapon/bikehorn
var/honk_sound = 'sound/items/bikehorn.ogg'
/obj/item/weapon/bikehorn/attack_self(mob/user as mob)
if(spam_flag == 0)
spam_flag = 1
playsound(src, honk_sound, 50, 1)
src.add_fingerprint(user)
spawn(20)
spam_flag = 0
return
/obj/item/weapon/bikehorn/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(istype(AM, /mob/living))
playsound(src, honk_sound, 50, 1)
+112 -112
View File
@@ -1,113 +1,113 @@
/obj/item/weapon/lipstick
gender = PLURAL
name = "red lipstick"
desc = "A generic brand of lipstick."
icon = 'icons/obj/items.dmi'
icon_state = "lipstick"
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
var/colour = "red"
var/open = 0
drop_sound = 'sound/items/drop/glass.ogg'
pickup_sound = 'sound/items/pickup/glass.ogg'
/obj/item/weapon/lipstick/purple
name = "purple lipstick"
colour = "purple"
/obj/item/weapon/lipstick/jade
name = "jade lipstick"
colour = "jade"
/obj/item/weapon/lipstick/black
name = "black lipstick"
colour = "black"
/obj/item/weapon/lipstick/random
name = "lipstick"
/obj/item/weapon/lipstick/random/New()
colour = pick("red","purple","jade","black")
name = "[colour] lipstick"
/obj/item/weapon/lipstick/attack_self(mob/user as mob)
to_chat(user, "<span class='notice'>You twist \the [src] [open ? "closed" : "open"].</span>")
open = !open
if(open)
icon_state = "[initial(icon_state)]_[colour]"
else
icon_state = initial(icon_state)
/obj/item/weapon/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 their lips with \the [src].</span>", \
"<span class='notice'>You take a moment to apply \the [src]. Perfect!</span>")
H.lip_style = colour
H.update_icons_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, H)) //user needs to keep their active hand, H does not.
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 = colour
H.update_icons_body()
else
to_chat(user, "<span class='notice'>Where are the lips on that?</span>")
//you can wipe off lipstick with paper! see code/modules/paperwork/paper.dm, paper/attack()
/obj/item/weapon/haircomb //sparklysheep's comb
name = "purple comb"
desc = "A pristine purple comb made from flexible plastic."
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
icon = 'icons/obj/items.dmi'
icon_state = "purplecomb"
/obj/item/weapon/haircomb/attack_self(mob/living/user)
var/text = "person"
if(ishuman(user))
var/mob/living/carbon/human/U = user
switch(U.identifying_gender)
if(MALE)
text = "guy"
if(FEMALE)
text = "lady"
else
switch(user.gender)
if(MALE)
text = "guy"
if(FEMALE)
text = "lady"
user.visible_message("<span class='notice'>[user] uses [src] to comb their hair with incredible style and sophistication. What a [text].</span>")
/obj/item/weapon/makeover
name = "makeover kit"
desc = "A tiny case containing a mirror and some contact lenses."
w_class = ITEMSIZE_TINY
icon = 'icons/obj/items.dmi'
icon_state = "trinketbox"
var/datum/tgui_module/appearance_changer/mirror/coskit/M
/obj/item/weapon/makeover/Initialize()
. = ..()
M = new(src, null)
/obj/item/weapon/makeover/attack_self(mob/living/carbon/user as mob)
if(ishuman(user))
to_chat(user, "<span class='notice'>You flip open \the [src] and begin to adjust your appearance.</span>")
M.tgui_interact(user)
var/mob/living/carbon/human/H = user
var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES]
if(istype(E))
/obj/item/weapon/lipstick
gender = PLURAL
name = "red lipstick"
desc = "A generic brand of lipstick."
icon = 'icons/obj/items.dmi'
icon_state = "lipstick"
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
var/colour = "red"
var/open = 0
drop_sound = 'sound/items/drop/glass.ogg'
pickup_sound = 'sound/items/pickup/glass.ogg'
/obj/item/weapon/lipstick/purple
name = "purple lipstick"
colour = "purple"
/obj/item/weapon/lipstick/jade
name = "jade lipstick"
colour = "jade"
/obj/item/weapon/lipstick/black
name = "black lipstick"
colour = "black"
/obj/item/weapon/lipstick/random
name = "lipstick"
/obj/item/weapon/lipstick/random/New()
colour = pick("red","purple","jade","black")
name = "[colour] lipstick"
/obj/item/weapon/lipstick/attack_self(mob/user as mob)
to_chat(user, "<span class='notice'>You twist \the [src] [open ? "closed" : "open"].</span>")
open = !open
if(open)
icon_state = "[initial(icon_state)]_[colour]"
else
icon_state = initial(icon_state)
/obj/item/weapon/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 their lips with \the [src].</span>", \
"<span class='notice'>You take a moment to apply \the [src]. Perfect!</span>")
H.lip_style = colour
H.update_icons_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, H)) //user needs to keep their active hand, H does not.
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 = colour
H.update_icons_body()
else
to_chat(user, "<span class='notice'>Where are the lips on that?</span>")
//you can wipe off lipstick with paper! see code/modules/paperwork/paper.dm, paper/attack()
/obj/item/weapon/haircomb //sparklysheep's comb
name = "purple comb"
desc = "A pristine purple comb made from flexible plastic."
w_class = ITEMSIZE_TINY
slot_flags = SLOT_EARS
icon = 'icons/obj/items.dmi'
icon_state = "purplecomb"
/obj/item/weapon/haircomb/attack_self(mob/living/user)
var/text = "person"
if(ishuman(user))
var/mob/living/carbon/human/U = user
switch(U.identifying_gender)
if(MALE)
text = "guy"
if(FEMALE)
text = "lady"
else
switch(user.gender)
if(MALE)
text = "guy"
if(FEMALE)
text = "lady"
user.visible_message("<span class='notice'>[user] uses [src] to comb their hair with incredible style and sophistication. What a [text].</span>")
/obj/item/weapon/makeover
name = "makeover kit"
desc = "A tiny case containing a mirror and some contact lenses."
w_class = ITEMSIZE_TINY
icon = 'icons/obj/items.dmi'
icon_state = "trinketbox"
var/datum/tgui_module/appearance_changer/mirror/coskit/M
/obj/item/weapon/makeover/Initialize()
. = ..()
M = new(src, null)
/obj/item/weapon/makeover/attack_self(mob/living/carbon/user as mob)
if(ishuman(user))
to_chat(user, "<span class='notice'>You flip open \the [src] and begin to adjust your appearance.</span>")
M.tgui_interact(user)
var/mob/living/carbon/human/H = user
var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES]
if(istype(E))
E.change_eye_color()
File diff suppressed because it is too large Load Diff
+119 -119
View File
@@ -1,119 +1,119 @@
/obj/item/weapon/plastique
name = "plastic explosives"
desc = "Used to put holes in specific areas without too much extra hole."
gender = PLURAL
icon = 'icons/obj/assemblies.dmi'
icon_state = "plastic-explosive0"
item_state = "plasticx"
flags = NOBLUDGEON
w_class = ITEMSIZE_SMALL
origin_tech = list(TECH_ILLEGAL = 2)
var/datum/wires/explosive/c4/wires = null
var/timer = 10
var/atom/target = null
var/open_panel = 0
var/image_overlay = null
var/blast_dev = -1
var/blast_heavy = -1
var/blast_light = 2
var/blast_flash = 3
/obj/item/weapon/plastique/New()
wires = new(src)
image_overlay = image('icons/obj/assemblies.dmi', "plastic-explosive2")
..()
/obj/item/weapon/plastique/Destroy()
qdel(wires)
wires = null
return ..()
/obj/item/weapon/plastique/attackby(var/obj/item/I, var/mob/user)
if(I.has_tool_quality(TOOL_SCREWDRIVER))
open_panel = !open_panel
to_chat(user, "<span class='notice'>You [open_panel ? "open" : "close"] the wire panel.</span>")
playsound(src, I.usesound, 50, 1)
else if(I.has_tool_quality(TOOL_WIRECUTTER) || istype(I, /obj/item/device/multitool) || istype(I, /obj/item/device/assembly/signaler ))
wires.Interact(user)
else
..()
/obj/item/weapon/plastique/attack_self(mob/user as mob)
var/newtime = tgui_input_number(usr, "Please set the timer.", "Timer", 10, 60000, 10)
if(user.get_active_hand() == src)
newtime = CLAMP(newtime, 10, 60000)
timer = newtime
to_chat(user, "Timer set for [timer] seconds.")
/obj/item/weapon/plastique/afterattack(atom/movable/target, mob/user, flag)
if (!flag)
return
if (ismob(target) || istype(target, /turf/unsimulated) || istype(target, /turf/simulated/shuttle) || istype(target, /obj/item/weapon/storage/) || istype(target, /obj/item/clothing/accessory/storage/) || istype(target, /obj/item/clothing/under))
return
to_chat(user, "Planting explosives...")
user.do_attack_animation(target)
if(do_after(user, 50) && in_range(user, target))
user.drop_item()
src.target = target
loc = null
if (ismob(target))
add_attack_logs(user, target, "planted [name] on with [timer] second fuse")
user.visible_message("<span class='danger'>[user.name] finished planting an explosive on [target.name]!</span>")
else
message_admins("[key_name(user, user.client)](<A HREF='?_src_=holder;[HrefToken()];adminmoreinfo=\ref[user]'>?</A>) planted [src.name] on [target.name] at ([target.x],[target.y],[target.z] - <A HREF='?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[target.x];Y=[target.y];Z=[target.z]'>JMP</a>) with [timer] second fuse",0,1)
log_game("[key_name(user)] planted [src.name] on [target.name] at ([target.x],[target.y],[target.z]) with [timer] second fuse")
target.add_overlay(image_overlay, TRUE)
to_chat(user, "Bomb has been planted. Timer counting down from [timer].")
spawn(timer*10)
explode(get_turf(target))
/obj/item/weapon/plastique/proc/explode(var/location)
if(!target)
target = get_atom_on_turf(src)
if(!target)
target = src
if(location)
explosion(location, blast_dev, blast_heavy, blast_light, blast_flash)
if(target)
if (istype(target, /turf/simulated/wall))
var/turf/simulated/wall/W = target
W.dismantle_wall(1,1,1)
else if(istype(target, /mob/living))
target.ex_act(2) // c4 can't gib mobs anymore.
else
target.ex_act(1)
if(target)
target.cut_overlay(image_overlay, TRUE)
qdel(src)
/obj/item/weapon/plastique/attack(mob/M as mob, mob/user as mob, def_zone)
return
/obj/item/weapon/plastique/seismic
name = "seismic charge"
desc = "Used to dig holes in specific areas without too much extra hole."
blast_heavy = 2
blast_light = 4
blast_flash = 7
/obj/item/weapon/plastique/seismic/attackby(var/obj/item/I, var/mob/user)
. = ..()
if(open_panel)
if(istype(I, /obj/item/weapon/stock_parts/micro_laser))
var/obj/item/weapon/stock_parts/SP = I
var/new_blast_power = max(1, round(SP.rating / 2) + 1)
if(new_blast_power > blast_heavy)
to_chat(user, "<span class='notice'>You install \the [I] into \the [src].</span>")
user.drop_from_inventory(I)
qdel(I)
blast_heavy = new_blast_power
blast_light = blast_heavy + round(new_blast_power * 0.5)
blast_flash = blast_light + round(new_blast_power * 0.75)
else
to_chat(user, "<span class='notice'>The [I] is not any better than the component already installed into this charge!</span>")
return .
/obj/item/weapon/plastique
name = "plastic explosives"
desc = "Used to put holes in specific areas without too much extra hole."
gender = PLURAL
icon = 'icons/obj/assemblies.dmi'
icon_state = "plastic-explosive0"
item_state = "plasticx"
flags = NOBLUDGEON
w_class = ITEMSIZE_SMALL
origin_tech = list(TECH_ILLEGAL = 2)
var/datum/wires/explosive/c4/wires = null
var/timer = 10
var/atom/target = null
var/open_panel = 0
var/image_overlay = null
var/blast_dev = -1
var/blast_heavy = -1
var/blast_light = 2
var/blast_flash = 3
/obj/item/weapon/plastique/New()
wires = new(src)
image_overlay = image('icons/obj/assemblies.dmi', "plastic-explosive2")
..()
/obj/item/weapon/plastique/Destroy()
qdel(wires)
wires = null
return ..()
/obj/item/weapon/plastique/attackby(var/obj/item/I, var/mob/user)
if(I.has_tool_quality(TOOL_SCREWDRIVER))
open_panel = !open_panel
to_chat(user, "<span class='notice'>You [open_panel ? "open" : "close"] the wire panel.</span>")
playsound(src, I.usesound, 50, 1)
else if(I.has_tool_quality(TOOL_WIRECUTTER) || istype(I, /obj/item/device/multitool) || istype(I, /obj/item/device/assembly/signaler ))
wires.Interact(user)
else
..()
/obj/item/weapon/plastique/attack_self(mob/user as mob)
var/newtime = tgui_input_number(usr, "Please set the timer.", "Timer", 10, 60000, 10)
if(user.get_active_hand() == src)
newtime = CLAMP(newtime, 10, 60000)
timer = newtime
to_chat(user, "Timer set for [timer] seconds.")
/obj/item/weapon/plastique/afterattack(atom/movable/target, mob/user, flag)
if (!flag)
return
if (ismob(target) || istype(target, /turf/unsimulated) || istype(target, /turf/simulated/shuttle) || istype(target, /obj/item/weapon/storage/) || istype(target, /obj/item/clothing/accessory/storage/) || istype(target, /obj/item/clothing/under))
return
to_chat(user, "Planting explosives...")
user.do_attack_animation(target)
if(do_after(user, 50) && in_range(user, target))
user.drop_item()
src.target = target
loc = null
if (ismob(target))
add_attack_logs(user, target, "planted [name] on with [timer] second fuse")
user.visible_message("<span class='danger'>[user.name] finished planting an explosive on [target.name]!</span>")
else
message_admins("[key_name(user, user.client)](<A HREF='?_src_=holder;[HrefToken()];adminmoreinfo=\ref[user]'>?</A>) planted [src.name] on [target.name] at ([target.x],[target.y],[target.z] - <A HREF='?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[target.x];Y=[target.y];Z=[target.z]'>JMP</a>) with [timer] second fuse",0,1)
log_game("[key_name(user)] planted [src.name] on [target.name] at ([target.x],[target.y],[target.z]) with [timer] second fuse")
target.add_overlay(image_overlay, TRUE)
to_chat(user, "Bomb has been planted. Timer counting down from [timer].")
spawn(timer*10)
explode(get_turf(target))
/obj/item/weapon/plastique/proc/explode(var/location)
if(!target)
target = get_atom_on_turf(src)
if(!target)
target = src
if(location)
explosion(location, blast_dev, blast_heavy, blast_light, blast_flash)
if(target)
if (istype(target, /turf/simulated/wall))
var/turf/simulated/wall/W = target
W.dismantle_wall(1,1,1)
else if(istype(target, /mob/living))
target.ex_act(2) // c4 can't gib mobs anymore.
else
target.ex_act(1)
if(target)
target.cut_overlay(image_overlay, TRUE)
qdel(src)
/obj/item/weapon/plastique/attack(mob/M as mob, mob/user as mob, def_zone)
return
/obj/item/weapon/plastique/seismic
name = "seismic charge"
desc = "Used to dig holes in specific areas without too much extra hole."
blast_heavy = 2
blast_light = 4
blast_flash = 7
/obj/item/weapon/plastique/seismic/attackby(var/obj/item/I, var/mob/user)
. = ..()
if(open_panel)
if(istype(I, /obj/item/weapon/stock_parts/micro_laser))
var/obj/item/weapon/stock_parts/SP = I
var/new_blast_power = max(1, round(SP.rating / 2) + 1)
if(new_blast_power > blast_heavy)
to_chat(user, "<span class='notice'>You install \the [I] into \the [src].</span>")
user.drop_from_inventory(I)
qdel(I)
blast_heavy = new_blast_power
blast_light = blast_heavy + round(new_blast_power * 0.5)
blast_flash = blast_light + round(new_blast_power * 0.75)
else
to_chat(user, "<span class='notice'>The [I] is not any better than the component already installed into this charge!</span>")
return .
+144 -144
View File
@@ -1,144 +1,144 @@
/obj/item/weapon/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'
throwforce = 10
w_class = ITEMSIZE_NORMAL
throw_speed = 2
throw_range = 10
force = 10
matter = list(MAT_STEEL = 90)
attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed")
drop_sound = 'sound/items/drop/gascan.ogg'
pickup_sound = 'sound/items/pickup/gascan.ogg'
var/spray_particles = 3
var/spray_amount = 10 //units of liquid per particle
var/max_water = 300
var/last_use = 1.0
var/safety = 1
var/sprite_name = "fire_extinguisher"
var/rand_overlays = 6
/obj/item/weapon/extinguisher/mini
name = "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.
throwforce = 2
w_class = ITEMSIZE_SMALL
force = 3.0
max_water = 150
spray_particles = 3
sprite_name = "miniFE"
rand_overlays = 0
/obj/item/weapon/extinguisher/atmo
name = "atmospheric fire extinguisher"
desc = "A heavy duty fire extinguisher meant to fight large fires."
icon_state = "atmos_extinguisher0"
item_state = "atmos_extinguisher"
throwforce = 12
w_class = ITEMSIZE_LARGE
force = 3.0
max_water = 600
spray_particles = 3
sprite_name = "atmos_extinguisher"
rand_overlays = 0
/obj/item/weapon/extinguisher/Initialize()
create_reagents(max_water)
reagents.add_reagent("firefoam", max_water)
if(rand_overlays)
var/choice = rand(1,rand_overlays)
add_overlay("[item_state]O[choice]")
. = ..()
/obj/item/weapon/extinguisher/examine(mob/user)
. = ..()
if(get_dist(user, src) == 0)
. += "[src] has [src.reagents.total_volume] units of foam left!"
/obj/item/weapon/extinguisher/attack_self(mob/user as mob)
safety = !safety
icon_state = "[sprite_name][!safety]"
desc = "The safety is [safety ? "on" : "off"]."
to_chat(user, "The safety is [safety ? "on" : "off"].")
/obj/item/weapon/extinguisher/proc/propel_object(var/obj/O, mob/user, movementdirection)
if(O.anchored) return
var/obj/structure/bed/chair/C
if(istype(O, /obj/structure/bed/chair))
C = O
var/list/move_speed = list(1, 1, 1, 2, 2, 3)
for(var/i in 1 to 6)
if(C) C.propelled = (6-i)
O.Move(get_step(user,movementdirection), movementdirection)
sleep(move_speed[i])
//additional movement
for(var/i in 1 to 3)
O.Move(get_step(user,movementdirection), movementdirection)
sleep(3)
/obj/item/weapon/extinguisher/afterattack(var/atom/target, var/mob/user, var/flag)
//TODO; Add support for reagents in water.
if( istype(target, /obj/structure/reagent_dispensers) && flag)
var/obj/o = target
var/amount = o.reagents.trans_to_obj(src, 50)
to_chat(user, "<span class='notice'>You fill [src] with [amount] units of the contents of [target].</span>")
playsound(src, 'sound/effects/refill.ogg', 50, 1, -6)
return
if (!safety)
if (src.reagents.total_volume < 1)
to_chat(usr, "<span class='notice'>\The [src] is empty.</span>")
return
if (world.time < src.last_use + 20)
return
src.last_use = world.time
playsound(src, 'sound/effects/extinguish.ogg', 75, 1, -3)
var/direction = get_dir(src,target)
if(user.buckled && isobj(user.buckled))
spawn(0)
propel_object(user.buckled, user, 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)
for(var/a = 1 to spray_particles)
spawn(0)
if(!src || !reagents.total_volume) return
var/obj/effect/effect/water/W = new /obj/effect/effect/water(get_turf(src))
var/turf/my_target
if(a <= the_targets.len)
my_target = the_targets[a]
else
my_target = pick(the_targets)
W.create_reagents(spray_amount)
reagents.trans_to_obj(W, spray_amount)
W.set_color()
W.set_up(my_target)
if((istype(usr.loc, /turf/space)) || (usr.lastarea.has_gravity == 0))
user.inertia_dir = get_dir(target, user)
step(user, user.inertia_dir)
else
return ..()
return
/obj/item/weapon/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'
throwforce = 10
w_class = ITEMSIZE_NORMAL
throw_speed = 2
throw_range = 10
force = 10
matter = list(MAT_STEEL = 90)
attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed")
drop_sound = 'sound/items/drop/gascan.ogg'
pickup_sound = 'sound/items/pickup/gascan.ogg'
var/spray_particles = 3
var/spray_amount = 10 //units of liquid per particle
var/max_water = 300
var/last_use = 1.0
var/safety = 1
var/sprite_name = "fire_extinguisher"
var/rand_overlays = 6
/obj/item/weapon/extinguisher/mini
name = "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.
throwforce = 2
w_class = ITEMSIZE_SMALL
force = 3.0
max_water = 150
spray_particles = 3
sprite_name = "miniFE"
rand_overlays = 0
/obj/item/weapon/extinguisher/atmo
name = "atmospheric fire extinguisher"
desc = "A heavy duty fire extinguisher meant to fight large fires."
icon_state = "atmos_extinguisher0"
item_state = "atmos_extinguisher"
throwforce = 12
w_class = ITEMSIZE_LARGE
force = 3.0
max_water = 600
spray_particles = 3
sprite_name = "atmos_extinguisher"
rand_overlays = 0
/obj/item/weapon/extinguisher/Initialize()
create_reagents(max_water)
reagents.add_reagent("firefoam", max_water)
if(rand_overlays)
var/choice = rand(1,rand_overlays)
add_overlay("[item_state]O[choice]")
. = ..()
/obj/item/weapon/extinguisher/examine(mob/user)
. = ..()
if(get_dist(user, src) == 0)
. += "[src] has [src.reagents.total_volume] units of foam left!"
/obj/item/weapon/extinguisher/attack_self(mob/user as mob)
safety = !safety
icon_state = "[sprite_name][!safety]"
desc = "The safety is [safety ? "on" : "off"]."
to_chat(user, "The safety is [safety ? "on" : "off"].")
/obj/item/weapon/extinguisher/proc/propel_object(var/obj/O, mob/user, movementdirection)
if(O.anchored) return
var/obj/structure/bed/chair/C
if(istype(O, /obj/structure/bed/chair))
C = O
var/list/move_speed = list(1, 1, 1, 2, 2, 3)
for(var/i in 1 to 6)
if(C) C.propelled = (6-i)
O.Move(get_step(user,movementdirection), movementdirection)
sleep(move_speed[i])
//additional movement
for(var/i in 1 to 3)
O.Move(get_step(user,movementdirection), movementdirection)
sleep(3)
/obj/item/weapon/extinguisher/afterattack(var/atom/target, var/mob/user, var/flag)
//TODO; Add support for reagents in water.
if( istype(target, /obj/structure/reagent_dispensers) && flag)
var/obj/o = target
var/amount = o.reagents.trans_to_obj(src, 50)
to_chat(user, "<span class='notice'>You fill [src] with [amount] units of the contents of [target].</span>")
playsound(src, 'sound/effects/refill.ogg', 50, 1, -6)
return
if (!safety)
if (src.reagents.total_volume < 1)
to_chat(usr, "<span class='notice'>\The [src] is empty.</span>")
return
if (world.time < src.last_use + 20)
return
src.last_use = world.time
playsound(src, 'sound/effects/extinguish.ogg', 75, 1, -3)
var/direction = get_dir(src,target)
if(user.buckled && isobj(user.buckled))
spawn(0)
propel_object(user.buckled, user, 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)
for(var/a = 1 to spray_particles)
spawn(0)
if(!src || !reagents.total_volume) return
var/obj/effect/effect/water/W = new /obj/effect/effect/water(get_turf(src))
var/turf/my_target
if(a <= the_targets.len)
my_target = the_targets[a]
else
my_target = pick(the_targets)
W.create_reagents(spray_amount)
reagents.trans_to_obj(W, spray_amount)
W.set_color()
W.set_up(my_target)
if((istype(usr.loc, /turf/space)) || (usr.lastarea.has_gravity == 0))
user.inertia_dir = get_dir(target, user)
step(user, user.inertia_dir)
else
return ..()
return
+204 -204
View File
@@ -1,204 +1,204 @@
/obj/item/weapon/flamethrower
name = "flamethrower"
desc = "You are a firestarter!"
icon = 'icons/obj/flamethrower.dmi'
icon_state = "flamethrowerbase"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_guns.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_guns.dmi',
)
item_state = "flamethrower_0"
force = 3.0
throwforce = 10.0
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_COMBAT = 1, TECH_PHORON = 1)
matter = list(MAT_STEEL = 500)
var/status = 0
var/throw_amount = 100
var/lit = 0 //on or off
var/operating = 0//cooldown
var/turf/previousturf = null
var/obj/item/weapon/weldingtool/weldtool = null
var/obj/item/device/assembly/igniter/igniter = null
var/obj/item/weapon/tank/phoron/ptank = null
/obj/item/weapon/flamethrower/Destroy()
QDEL_NULL(weldtool)
QDEL_NULL(igniter)
QDEL_NULL(ptank)
. = ..()
/obj/item/weapon/flamethrower/process()
if(!lit)
STOP_PROCESSING(SSobj, src)
return null
var/turf/location = loc
if(istype(location, /mob/))
var/mob/living/M = location
if(M.item_is_in_hands(src))
location = M.loc
if(isturf(location)) //start a fire if possible
location.hotspot_expose(700, 2)
return
/obj/item/weapon/flamethrower/update_icon()
cut_overlays()
if(igniter)
add_overlay("+igniter[status]")
if(ptank)
add_overlay("+ptank")
if(lit)
add_overlay("+lit")
item_state = "flamethrower_1"
else
item_state = "flamethrower_0"
return
/obj/item/weapon/flamethrower/afterattack(atom/target, mob/user, proximity)
if(!proximity) return
// Make sure our user is still holding us
if(user && user.get_active_hand() == src)
var/turf/target_turf = get_turf(target)
if(target_turf)
var/turflist = getline(user, target_turf)
flame_turf(turflist)
/obj/item/weapon/flamethrower/attackby(obj/item/W as obj, mob/user as mob)
if(user.stat || user.restrained() || user.lying) return
if(W.has_tool_quality(TOOL_WRENCH) && !status)//Taking this apart
var/turf/T = get_turf(src)
if(weldtool)
weldtool.loc = T
weldtool = null
if(igniter)
igniter.loc = T
igniter = null
if(ptank)
ptank.loc = T
ptank = null
new /obj/item/stack/rods(T)
qdel(src)
return
if(W.has_tool_quality(TOOL_SCREWDRIVER) && igniter && !lit)
status = !status
to_chat(user, "<span class='notice'>[igniter] is now [status ? "secured" : "unsecured"]!</span>")
update_icon()
return
if(isigniter(W))
var/obj/item/device/assembly/igniter/I = W
if(I.secured) return
if(igniter) return
user.drop_item()
I.loc = src
igniter = I
update_icon()
return
if(istype(W,/obj/item/weapon/tank/phoron))
if(ptank)
to_chat(user, "<span class='notice'>There appears to already be a phoron tank loaded in [src]!</span>")
return
user.drop_item()
ptank = W
W.loc = src
update_icon()
return
..()
return
/obj/item/weapon/flamethrower/attack_self(mob/user as mob)
if(user.stat || user.restrained() || user.lying) return
user.set_machine(src)
if(!ptank)
to_chat(user, "<span class='notice'>Attach a phoron tank first!</span>")
return
var/dat = text("<TT><B>Flamethrower (<A HREF='?src=\ref[src];light=1'>[lit ? "<font color='red'>Lit</font>" : "Unlit"]</a>)</B><BR>\n Tank Pressure: [ptank.air_contents.return_pressure()]<BR>\nAmount to throw: <A HREF='?src=\ref[src];amount=-100'>-</A> <A HREF='?src=\ref[src];amount=-10'>-</A> <A HREF='?src=\ref[src];amount=-1'>-</A> [throw_amount] <A HREF='?src=\ref[src];amount=1'>+</A> <A HREF='?src=\ref[src];amount=10'>+</A> <A HREF='?src=\ref[src];amount=100'>+</A><BR>\n<A HREF='?src=\ref[src];remove=1'>Remove phorontank</A> - <A HREF='?src=\ref[src];close=1'>Close</A></TT>")
user << browse(dat, "window=flamethrower;size=600x300")
onclose(user, "flamethrower")
return
/obj/item/weapon/flamethrower/Topic(href,href_list[])
if(href_list["close"])
usr.unset_machine()
usr << browse(null, "window=flamethrower")
return
if(usr.stat || usr.restrained() || usr.lying) return
usr.set_machine(src)
if(href_list["light"])
if(!ptank) return
if(ptank.air_contents.gas["phoron"] < 1) return
if(!status) return
lit = !lit
if(lit)
START_PROCESSING(SSobj, src)
if(href_list["amount"])
throw_amount = throw_amount + text2num(href_list["amount"])
throw_amount = max(50, min(5000, throw_amount))
if(href_list["remove"])
if(!ptank) return
usr.put_in_hands(ptank)
ptank = null
lit = 0
usr.unset_machine()
usr << browse(null, "window=flamethrower")
for(var/mob/M in viewers(1, loc))
if((M.client && M.machine == src))
attack_self(M)
update_icon()
return
//Called from turf.dm turf/dblclick
/obj/item/weapon/flamethrower/proc/flame_turf(turflist)
if(!lit || operating) return
operating = 1
for(var/turf/T in turflist)
if(T.density || istype(T, /turf/space))
break
if(!previousturf && length(turflist)>1)
previousturf = get_turf(src)
continue //so we don't burn the tile we be standin on
if(previousturf && LinkBlocked(previousturf, T))
break
ignite_turf(T)
sleep(1)
previousturf = null
operating = 0
for(var/mob/M in viewers(1, loc))
if((M.client && M.machine == src))
attack_self(M)
return
/obj/item/weapon/flamethrower/proc/ignite_turf(turf/target)
//TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this...
//Transfer 5% of current tank air contents to turf
var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(0.02*(throw_amount/100))
//air_transfer.toxins = air_transfer.toxins * 5 // This is me not comprehending the air system. I realize this is mischievious and I could probably make it work without fucking it up like this, but there you have it. -- TLE
new/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(target,air_transfer.gas["phoron"],get_dir(loc,target))
air_transfer.gas["phoron"] = 0
target.assume_air(air_transfer)
//Burn it based on transfered gas
//target.hotspot_expose(part4.air_contents.temperature*2,300)
target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500) // -- More of my "how do I shot fire?" dickery. -- TLE
//location.hotspot_expose(1000,500,1)
return
/obj/item/weapon/flamethrower/full/New(var/loc)
..()
weldtool = new /obj/item/weapon/weldingtool(src)
weldtool.status = 0
igniter = new /obj/item/device/assembly/igniter(src)
igniter.secured = 0
status = 1
update_icon()
return
/obj/item/weapon/flamethrower
name = "flamethrower"
desc = "You are a firestarter!"
icon = 'icons/obj/flamethrower.dmi'
icon_state = "flamethrowerbase"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_guns.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_guns.dmi',
)
item_state = "flamethrower_0"
force = 3.0
throwforce = 10.0
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_COMBAT = 1, TECH_PHORON = 1)
matter = list(MAT_STEEL = 500)
var/status = 0
var/throw_amount = 100
var/lit = 0 //on or off
var/operating = 0//cooldown
var/turf/previousturf = null
var/obj/item/weapon/weldingtool/weldtool = null
var/obj/item/device/assembly/igniter/igniter = null
var/obj/item/weapon/tank/phoron/ptank = null
/obj/item/weapon/flamethrower/Destroy()
QDEL_NULL(weldtool)
QDEL_NULL(igniter)
QDEL_NULL(ptank)
. = ..()
/obj/item/weapon/flamethrower/process()
if(!lit)
STOP_PROCESSING(SSobj, src)
return null
var/turf/location = loc
if(istype(location, /mob/))
var/mob/living/M = location
if(M.item_is_in_hands(src))
location = M.loc
if(isturf(location)) //start a fire if possible
location.hotspot_expose(700, 2)
return
/obj/item/weapon/flamethrower/update_icon()
cut_overlays()
if(igniter)
add_overlay("+igniter[status]")
if(ptank)
add_overlay("+ptank")
if(lit)
add_overlay("+lit")
item_state = "flamethrower_1"
else
item_state = "flamethrower_0"
return
/obj/item/weapon/flamethrower/afterattack(atom/target, mob/user, proximity)
if(!proximity) return
// Make sure our user is still holding us
if(user && user.get_active_hand() == src)
var/turf/target_turf = get_turf(target)
if(target_turf)
var/turflist = getline(user, target_turf)
flame_turf(turflist)
/obj/item/weapon/flamethrower/attackby(obj/item/W as obj, mob/user as mob)
if(user.stat || user.restrained() || user.lying) return
if(W.has_tool_quality(TOOL_WRENCH) && !status)//Taking this apart
var/turf/T = get_turf(src)
if(weldtool)
weldtool.loc = T
weldtool = null
if(igniter)
igniter.loc = T
igniter = null
if(ptank)
ptank.loc = T
ptank = null
new /obj/item/stack/rods(T)
qdel(src)
return
if(W.has_tool_quality(TOOL_SCREWDRIVER) && igniter && !lit)
status = !status
to_chat(user, "<span class='notice'>[igniter] is now [status ? "secured" : "unsecured"]!</span>")
update_icon()
return
if(isigniter(W))
var/obj/item/device/assembly/igniter/I = W
if(I.secured) return
if(igniter) return
user.drop_item()
I.loc = src
igniter = I
update_icon()
return
if(istype(W,/obj/item/weapon/tank/phoron))
if(ptank)
to_chat(user, "<span class='notice'>There appears to already be a phoron tank loaded in [src]!</span>")
return
user.drop_item()
ptank = W
W.loc = src
update_icon()
return
..()
return
/obj/item/weapon/flamethrower/attack_self(mob/user as mob)
if(user.stat || user.restrained() || user.lying) return
user.set_machine(src)
if(!ptank)
to_chat(user, "<span class='notice'>Attach a phoron tank first!</span>")
return
var/dat = text("<TT><B>Flamethrower (<A HREF='?src=\ref[src];light=1'>[lit ? "<font color='red'>Lit</font>" : "Unlit"]</a>)</B><BR>\n Tank Pressure: [ptank.air_contents.return_pressure()]<BR>\nAmount to throw: <A HREF='?src=\ref[src];amount=-100'>-</A> <A HREF='?src=\ref[src];amount=-10'>-</A> <A HREF='?src=\ref[src];amount=-1'>-</A> [throw_amount] <A HREF='?src=\ref[src];amount=1'>+</A> <A HREF='?src=\ref[src];amount=10'>+</A> <A HREF='?src=\ref[src];amount=100'>+</A><BR>\n<A HREF='?src=\ref[src];remove=1'>Remove phorontank</A> - <A HREF='?src=\ref[src];close=1'>Close</A></TT>")
user << browse(dat, "window=flamethrower;size=600x300")
onclose(user, "flamethrower")
return
/obj/item/weapon/flamethrower/Topic(href,href_list[])
if(href_list["close"])
usr.unset_machine()
usr << browse(null, "window=flamethrower")
return
if(usr.stat || usr.restrained() || usr.lying) return
usr.set_machine(src)
if(href_list["light"])
if(!ptank) return
if(ptank.air_contents.gas["phoron"] < 1) return
if(!status) return
lit = !lit
if(lit)
START_PROCESSING(SSobj, src)
if(href_list["amount"])
throw_amount = throw_amount + text2num(href_list["amount"])
throw_amount = max(50, min(5000, throw_amount))
if(href_list["remove"])
if(!ptank) return
usr.put_in_hands(ptank)
ptank = null
lit = 0
usr.unset_machine()
usr << browse(null, "window=flamethrower")
for(var/mob/M in viewers(1, loc))
if((M.client && M.machine == src))
attack_self(M)
update_icon()
return
//Called from turf.dm turf/dblclick
/obj/item/weapon/flamethrower/proc/flame_turf(turflist)
if(!lit || operating) return
operating = 1
for(var/turf/T in turflist)
if(T.density || istype(T, /turf/space))
break
if(!previousturf && length(turflist)>1)
previousturf = get_turf(src)
continue //so we don't burn the tile we be standin on
if(previousturf && LinkBlocked(previousturf, T))
break
ignite_turf(T)
sleep(1)
previousturf = null
operating = 0
for(var/mob/M in viewers(1, loc))
if((M.client && M.machine == src))
attack_self(M)
return
/obj/item/weapon/flamethrower/proc/ignite_turf(turf/target)
//TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this...
//Transfer 5% of current tank air contents to turf
var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(0.02*(throw_amount/100))
//air_transfer.toxins = air_transfer.toxins * 5 // This is me not comprehending the air system. I realize this is mischievious and I could probably make it work without fucking it up like this, but there you have it. -- TLE
new/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(target,air_transfer.gas["phoron"],get_dir(loc,target))
air_transfer.gas["phoron"] = 0
target.assume_air(air_transfer)
//Burn it based on transfered gas
//target.hotspot_expose(part4.air_contents.temperature*2,300)
target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500) // -- More of my "how do I shot fire?" dickery. -- TLE
//location.hotspot_expose(1000,500,1)
return
/obj/item/weapon/flamethrower/full/New(var/loc)
..()
weldtool = new /obj/item/weapon/weldingtool(src)
weldtool.status = 0
igniter = new /obj/item/device/assembly/igniter(src)
igniter.secured = 0
status = 1
update_icon()
return
@@ -1,22 +1,22 @@
/obj/item/weapon/grenade/anti_photon
desc = "An experimental device for temporarily removing light in a limited area."
name = "photon disruption grenade"
icon = 'icons/obj/grenade.dmi'
icon_state = "emp"
det_time = 20
origin_tech = list(TECH_BLUESPACE = 4, TECH_MATERIAL = 4)
/obj/item/weapon/grenade/anti_photon/detonate()
playsound(src, 'sound/effects/phasein.ogg', 50, 1, 5)
set_light(10, -10, "#FFFFFF")
var/extra_delay = rand(0,90)
spawn(extra_delay)
spawn(200)
if(prob(10+extra_delay))
set_light(10, 10, "#[num2hex(rand(64,255))][num2hex(rand(64,255))][num2hex(rand(64,255))]")
spawn(210)
..()
playsound(src, 'sound/effects/bang.ogg', 50, 1, 5)
qdel(src)
/obj/item/weapon/grenade/anti_photon
desc = "An experimental device for temporarily removing light in a limited area."
name = "photon disruption grenade"
icon = 'icons/obj/grenade.dmi'
icon_state = "emp"
det_time = 20
origin_tech = list(TECH_BLUESPACE = 4, TECH_MATERIAL = 4)
/obj/item/weapon/grenade/anti_photon/detonate()
playsound(src, 'sound/effects/phasein.ogg', 50, 1, 5)
set_light(10, -10, "#FFFFFF")
var/extra_delay = rand(0,90)
spawn(extra_delay)
spawn(200)
if(prob(10+extra_delay))
set_light(10, 10, "#[num2hex(rand(64,255))][num2hex(rand(64,255))][num2hex(rand(64,255))]")
spawn(210)
..()
playsound(src, 'sound/effects/bang.ogg', 50, 1, 5)
qdel(src)
@@ -1,316 +1,316 @@
/obj/item/weapon/grenade/chem_grenade
name = "grenade casing"
icon_state = "chemg"
item_state = "grenade"
desc = "A hand made chemical grenade."
w_class = ITEMSIZE_SMALL
force = 2.0
det_time = null
unacidable = TRUE
var/stage = 0
var/state = 0
var/path = 0
/// If TRUE, grenade is permanently sealed when fully assembled, useful for things like off-the-shelf grenades.
var/sealed = FALSE
var/obj/item/device/assembly_holder/detonator = null
var/list/beakers = new/list()
var/list/allowed_containers = list(/obj/item/weapon/reagent_containers/glass/beaker, /obj/item/weapon/reagent_containers/glass/bottle)
var/affected_area = 3
/obj/item/weapon/grenade/chem_grenade/Initialize()
. = ..()
create_reagents(1000)
/obj/item/weapon/grenade/chem_grenade/Destroy()
QDEL_NULL(detonator)
QDEL_LIST_NULL(beakers)
return ..()
/obj/item/weapon/grenade/chem_grenade/attack_self(mob/user as mob)
if(!stage || stage==1)
if(detonator)
// detonator.loc=src.loc
detonator.detached()
usr.put_in_hands(detonator)
detonator=null
det_time = null
stage=0
icon_state = initial(icon_state)
else if(beakers.len)
for(var/obj/B in beakers)
if(istype(B))
beakers -= B
user.put_in_hands(B)
name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]"
if(stage > 1 && !active && clown_check(user))
to_chat(user, "<span class='warning'>You prime \the [name]!</span>")
msg_admin_attack("[key_name_admin(user)] primed \a [src]")
activate()
add_fingerprint(user)
if(iscarbon(user))
var/mob/living/carbon/C = user
C.throw_mode_on()
/obj/item/weapon/grenade/chem_grenade/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W,/obj/item/device/assembly_holder) && (!stage || stage==1) && !detonator && path != 2)
var/obj/item/device/assembly_holder/det = W
if(istype(det.a_left,det.a_right.type) || (!isigniter(det.a_left) && !isigniter(det.a_right)))
to_chat(user, "<span class='warning'>Assembly must contain one igniter.</span>")
return
if(!det.secured)
to_chat(user, "<span class='warning'>Assembly must be secured with screwdriver.</span>")
return
path = 1
to_chat(user, "<span class='notice'>You add [W] to the metal casing.</span>")
playsound(src, 'sound/items/Screwdriver2.ogg', 25, -3)
user.remove_from_mob(det)
det.loc = src
detonator = det
if(istimer(detonator.a_left))
var/obj/item/device/assembly/timer/T = detonator.a_left
det_time = 10*T.time
if(istimer(detonator.a_right))
var/obj/item/device/assembly/timer/T = detonator.a_right
det_time = 10*T.time
icon_state = initial(icon_state) +"_ass"
name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]"
stage = 1
else if(W.has_tool_quality(TOOL_SCREWDRIVER) && path != 2)
if(stage == 1)
path = 1
if(beakers.len)
to_chat(user, "<span class='notice'>You lock the assembly.</span>")
name = "grenade"
else
// to_chat(user, "<span class='warning'>You need to add at least one beaker before locking the assembly.</span>")
to_chat(user, "<span class='notice'>You lock the empty assembly.</span>")
name = "fake grenade"
playsound(src, W.usesound, 50, 1)
icon_state = initial(icon_state) +"_locked"
stage = 2
else if(stage == 2)
if(active && prob(95))
to_chat(user, "<span class='warning'>You trigger the assembly!</span>")
detonate()
else if(sealed)
to_chat(user, "<span class='warning'>This grenade lacks a way to disassemble it.</span>")
else
to_chat(user, "<span class='notice'>You unlock the assembly.</span>")
playsound(src, W.usesound, 50, -3)
name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]"
icon_state = initial(icon_state) + (detonator?"_ass":"")
stage = 1
active = 0
else if(is_type_in_list(W, allowed_containers) && (!stage || stage==1) && path != 2)
path = 1
if(beakers.len == 2)
to_chat(user, "<span class='warning'>The grenade can not hold more containers.</span>")
return
else
if(W.reagents.total_volume)
to_chat(user, "<span class='notice'>You add \the [W] to the assembly.</span>")
user.drop_item()
W.loc = src
beakers += W
stage = 1
name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]"
else
to_chat(user, "<span class='warning'>\The [W] is empty.</span>")
/obj/item/weapon/grenade/chem_grenade/examine(mob/user)
. = ..()
if(detonator)
. += "It has [detonator.name] attached to it."
/obj/item/weapon/grenade/chem_grenade/activate(mob/user as mob)
if(active) return
if(detonator)
if(!isigniter(detonator.a_left))
detonator.a_left.activate()
active = 1
if(!isigniter(detonator.a_right))
detonator.a_right.activate()
active = 1
if(active)
icon_state = initial(icon_state) + "_active"
if(user)
msg_admin_attack("[key_name_admin(user)] primed \a [src.name]")
return
/obj/item/weapon/grenade/chem_grenade/proc/primed(var/primed = 1)
if(active)
icon_state = initial(icon_state) + (primed?"_primed":"_active")
/obj/item/weapon/grenade/chem_grenade/detonate()
if(!stage || stage<2) return
var/has_reagents = 0
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
if(G.reagents.total_volume) has_reagents = 1
active = 0
if(!has_reagents)
icon_state = initial(icon_state) +"_locked"
playsound(src, 'sound/items/Screwdriver2.ogg', 50, 1)
spawn(0) //Otherwise det_time is erroneously set to 0 after this
if(istimer(detonator.a_left)) //Make sure description reflects that the timer has been reset
var/obj/item/device/assembly/timer/T = detonator.a_left
det_time = 10*T.time
if(istimer(detonator.a_right))
var/obj/item/device/assembly/timer/T = detonator.a_right
det_time = 10*T.time
return
playsound(src, 'sound/effects/bamf.ogg', 50, 1)
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
G.reagents.trans_to_obj(src, G.reagents.total_volume)
if(src.reagents.total_volume) //The possible reactions didnt use up all reagents.
var/datum/effect/effect/system/steam_spread/steam = new /datum/effect/effect/system/steam_spread()
steam.set_up(10, 0, get_turf(src))
steam.attach(src)
steam.start()
for(var/atom/A in view(affected_area, src.loc))
if( A == src ) continue
src.reagents.touch(A)
if(istype(loc, /mob/living/carbon)) //drop dat grenade if it goes off in your hand
var/mob/living/carbon/C = loc
C.drop_from_inventory(src)
C.throw_mode_off()
invisibility = INVISIBILITY_MAXIMUM //Why am i doing this?
spawn(50) //To make sure all reagents can work
qdel(src) //correctly before deleting the grenade.
/obj/item/weapon/grenade/chem_grenade/large
name = "large chem grenade"
desc = "An oversized grenade that affects a larger area."
icon_state = "large_grenade"
allowed_containers = list(/obj/item/weapon/reagent_containers/glass)
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3)
affected_area = 4
/obj/item/weapon/grenade/chem_grenade/metalfoam
name = "metal-foam grenade"
desc = "Used for emergency sealing of air breaches."
icon_state = "foam"
path = 1
stage = 2
sealed = TRUE
/obj/item/weapon/grenade/chem_grenade/metalfoam/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
B1.reagents.add_reagent("aluminum", 30)
B2.reagents.add_reagent("foaming_agent", 10)
B2.reagents.add_reagent("pacid", 10)
detonator = new/obj/item/device/assembly_holder/timer_igniter(src)
beakers += B1
beakers += B2
/obj/item/weapon/grenade/chem_grenade/incendiary
name = "incendiary grenade"
desc = "Used for clearing rooms of living things."
icon_state = "incendiary"
path = 1
stage = 2
sealed = TRUE
/obj/item/weapon/grenade/chem_grenade/incendiary/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
B1.reagents.add_reagent("aluminum", 15)
B1.reagents.add_reagent("fuel",20)
B2.reagents.add_reagent("phoron", 15)
B2.reagents.add_reagent("sacid", 15)
B1.reagents.add_reagent("fuel",20)
detonator = new/obj/item/device/assembly_holder/timer_igniter(src)
beakers += B1
beakers += B2
/obj/item/weapon/grenade/chem_grenade/antiweed
name = "weedkiller grenade"
desc = "Used for purging large areas of invasive plant species. Contents under pressure. Do not directly inhale contents."
path = 1
stage = 2
sealed = TRUE
/obj/item/weapon/grenade/chem_grenade/antiweed/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
B1.reagents.add_reagent("plantbgone", 25)
B1.reagents.add_reagent("potassium", 25)
B2.reagents.add_reagent("phosphorus", 25)
B2.reagents.add_reagent("sugar", 25)
detonator = new/obj/item/device/assembly_holder/timer_igniter(src)
beakers += B1
beakers += B2
icon_state = "grenade"
/obj/item/weapon/grenade/chem_grenade/cleaner
name = "cleaner grenade"
desc = "BLAM!-brand foaming space cleaner. In a special applicator for rapid cleaning of wide areas."
icon_state = "cleaner"
stage = 2
path = 1
sealed = TRUE
/obj/item/weapon/grenade/chem_grenade/cleaner/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
B1.reagents.add_reagent("fluorosurfactant", 40)
B2.reagents.add_reagent("water", 40)
B2.reagents.add_reagent("cleaner", 10)
detonator = new/obj/item/device/assembly_holder/timer_igniter(src)
beakers += B1
beakers += B2
/obj/item/weapon/grenade/chem_grenade/teargas
name = "tear gas grenade"
desc = "Concentrated Capsaicin. Contents under pressure. Use with caution."
icon_state = "teargas"
stage = 2
path = 1
sealed = TRUE
/obj/item/weapon/grenade/chem_grenade/teargas/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/large/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/large/B2 = new(src)
B1.reagents.add_reagent("phosphorus", 40)
B1.reagents.add_reagent("potassium", 40)
B1.reagents.add_reagent("condensedcapsaicin", 40)
B2.reagents.add_reagent("sugar", 40)
B2.reagents.add_reagent("condensedcapsaicin", 80)
detonator = new/obj/item/device/assembly_holder/timer_igniter(src)
beakers += B1
beakers += B2
/obj/item/weapon/grenade/chem_grenade
name = "grenade casing"
icon_state = "chemg"
item_state = "grenade"
desc = "A hand made chemical grenade."
w_class = ITEMSIZE_SMALL
force = 2.0
det_time = null
unacidable = TRUE
var/stage = 0
var/state = 0
var/path = 0
/// If TRUE, grenade is permanently sealed when fully assembled, useful for things like off-the-shelf grenades.
var/sealed = FALSE
var/obj/item/device/assembly_holder/detonator = null
var/list/beakers = new/list()
var/list/allowed_containers = list(/obj/item/weapon/reagent_containers/glass/beaker, /obj/item/weapon/reagent_containers/glass/bottle)
var/affected_area = 3
/obj/item/weapon/grenade/chem_grenade/Initialize()
. = ..()
create_reagents(1000)
/obj/item/weapon/grenade/chem_grenade/Destroy()
QDEL_NULL(detonator)
QDEL_LIST_NULL(beakers)
return ..()
/obj/item/weapon/grenade/chem_grenade/attack_self(mob/user as mob)
if(!stage || stage==1)
if(detonator)
// detonator.loc=src.loc
detonator.detached()
usr.put_in_hands(detonator)
detonator=null
det_time = null
stage=0
icon_state = initial(icon_state)
else if(beakers.len)
for(var/obj/B in beakers)
if(istype(B))
beakers -= B
user.put_in_hands(B)
name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]"
if(stage > 1 && !active && clown_check(user))
to_chat(user, "<span class='warning'>You prime \the [name]!</span>")
msg_admin_attack("[key_name_admin(user)] primed \a [src]")
activate()
add_fingerprint(user)
if(iscarbon(user))
var/mob/living/carbon/C = user
C.throw_mode_on()
/obj/item/weapon/grenade/chem_grenade/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W,/obj/item/device/assembly_holder) && (!stage || stage==1) && !detonator && path != 2)
var/obj/item/device/assembly_holder/det = W
if(istype(det.a_left,det.a_right.type) || (!isigniter(det.a_left) && !isigniter(det.a_right)))
to_chat(user, "<span class='warning'>Assembly must contain one igniter.</span>")
return
if(!det.secured)
to_chat(user, "<span class='warning'>Assembly must be secured with screwdriver.</span>")
return
path = 1
to_chat(user, "<span class='notice'>You add [W] to the metal casing.</span>")
playsound(src, 'sound/items/Screwdriver2.ogg', 25, -3)
user.remove_from_mob(det)
det.loc = src
detonator = det
if(istimer(detonator.a_left))
var/obj/item/device/assembly/timer/T = detonator.a_left
det_time = 10*T.time
if(istimer(detonator.a_right))
var/obj/item/device/assembly/timer/T = detonator.a_right
det_time = 10*T.time
icon_state = initial(icon_state) +"_ass"
name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]"
stage = 1
else if(W.has_tool_quality(TOOL_SCREWDRIVER) && path != 2)
if(stage == 1)
path = 1
if(beakers.len)
to_chat(user, "<span class='notice'>You lock the assembly.</span>")
name = "grenade"
else
// to_chat(user, "<span class='warning'>You need to add at least one beaker before locking the assembly.</span>")
to_chat(user, "<span class='notice'>You lock the empty assembly.</span>")
name = "fake grenade"
playsound(src, W.usesound, 50, 1)
icon_state = initial(icon_state) +"_locked"
stage = 2
else if(stage == 2)
if(active && prob(95))
to_chat(user, "<span class='warning'>You trigger the assembly!</span>")
detonate()
else if(sealed)
to_chat(user, "<span class='warning'>This grenade lacks a way to disassemble it.</span>")
else
to_chat(user, "<span class='notice'>You unlock the assembly.</span>")
playsound(src, W.usesound, 50, -3)
name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]"
icon_state = initial(icon_state) + (detonator?"_ass":"")
stage = 1
active = 0
else if(is_type_in_list(W, allowed_containers) && (!stage || stage==1) && path != 2)
path = 1
if(beakers.len == 2)
to_chat(user, "<span class='warning'>The grenade can not hold more containers.</span>")
return
else
if(W.reagents.total_volume)
to_chat(user, "<span class='notice'>You add \the [W] to the assembly.</span>")
user.drop_item()
W.loc = src
beakers += W
stage = 1
name = "unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]"
else
to_chat(user, "<span class='warning'>\The [W] is empty.</span>")
/obj/item/weapon/grenade/chem_grenade/examine(mob/user)
. = ..()
if(detonator)
. += "It has [detonator.name] attached to it."
/obj/item/weapon/grenade/chem_grenade/activate(mob/user as mob)
if(active) return
if(detonator)
if(!isigniter(detonator.a_left))
detonator.a_left.activate()
active = 1
if(!isigniter(detonator.a_right))
detonator.a_right.activate()
active = 1
if(active)
icon_state = initial(icon_state) + "_active"
if(user)
msg_admin_attack("[key_name_admin(user)] primed \a [src.name]")
return
/obj/item/weapon/grenade/chem_grenade/proc/primed(var/primed = 1)
if(active)
icon_state = initial(icon_state) + (primed?"_primed":"_active")
/obj/item/weapon/grenade/chem_grenade/detonate()
if(!stage || stage<2) return
var/has_reagents = 0
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
if(G.reagents.total_volume) has_reagents = 1
active = 0
if(!has_reagents)
icon_state = initial(icon_state) +"_locked"
playsound(src, 'sound/items/Screwdriver2.ogg', 50, 1)
spawn(0) //Otherwise det_time is erroneously set to 0 after this
if(istimer(detonator.a_left)) //Make sure description reflects that the timer has been reset
var/obj/item/device/assembly/timer/T = detonator.a_left
det_time = 10*T.time
if(istimer(detonator.a_right))
var/obj/item/device/assembly/timer/T = detonator.a_right
det_time = 10*T.time
return
playsound(src, 'sound/effects/bamf.ogg', 50, 1)
for(var/obj/item/weapon/reagent_containers/glass/G in beakers)
G.reagents.trans_to_obj(src, G.reagents.total_volume)
if(src.reagents.total_volume) //The possible reactions didnt use up all reagents.
var/datum/effect/effect/system/steam_spread/steam = new /datum/effect/effect/system/steam_spread()
steam.set_up(10, 0, get_turf(src))
steam.attach(src)
steam.start()
for(var/atom/A in view(affected_area, src.loc))
if( A == src ) continue
src.reagents.touch(A)
if(istype(loc, /mob/living/carbon)) //drop dat grenade if it goes off in your hand
var/mob/living/carbon/C = loc
C.drop_from_inventory(src)
C.throw_mode_off()
invisibility = INVISIBILITY_MAXIMUM //Why am i doing this?
spawn(50) //To make sure all reagents can work
qdel(src) //correctly before deleting the grenade.
/obj/item/weapon/grenade/chem_grenade/large
name = "large chem grenade"
desc = "An oversized grenade that affects a larger area."
icon_state = "large_grenade"
allowed_containers = list(/obj/item/weapon/reagent_containers/glass)
origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3)
affected_area = 4
/obj/item/weapon/grenade/chem_grenade/metalfoam
name = "metal-foam grenade"
desc = "Used for emergency sealing of air breaches."
icon_state = "foam"
path = 1
stage = 2
sealed = TRUE
/obj/item/weapon/grenade/chem_grenade/metalfoam/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
B1.reagents.add_reagent("aluminum", 30)
B2.reagents.add_reagent("foaming_agent", 10)
B2.reagents.add_reagent("pacid", 10)
detonator = new/obj/item/device/assembly_holder/timer_igniter(src)
beakers += B1
beakers += B2
/obj/item/weapon/grenade/chem_grenade/incendiary
name = "incendiary grenade"
desc = "Used for clearing rooms of living things."
icon_state = "incendiary"
path = 1
stage = 2
sealed = TRUE
/obj/item/weapon/grenade/chem_grenade/incendiary/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
B1.reagents.add_reagent("aluminum", 15)
B1.reagents.add_reagent("fuel",20)
B2.reagents.add_reagent("phoron", 15)
B2.reagents.add_reagent("sacid", 15)
B1.reagents.add_reagent("fuel",20)
detonator = new/obj/item/device/assembly_holder/timer_igniter(src)
beakers += B1
beakers += B2
/obj/item/weapon/grenade/chem_grenade/antiweed
name = "weedkiller grenade"
desc = "Used for purging large areas of invasive plant species. Contents under pressure. Do not directly inhale contents."
path = 1
stage = 2
sealed = TRUE
/obj/item/weapon/grenade/chem_grenade/antiweed/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
B1.reagents.add_reagent("plantbgone", 25)
B1.reagents.add_reagent("potassium", 25)
B2.reagents.add_reagent("phosphorus", 25)
B2.reagents.add_reagent("sugar", 25)
detonator = new/obj/item/device/assembly_holder/timer_igniter(src)
beakers += B1
beakers += B2
icon_state = "grenade"
/obj/item/weapon/grenade/chem_grenade/cleaner
name = "cleaner grenade"
desc = "BLAM!-brand foaming space cleaner. In a special applicator for rapid cleaning of wide areas."
icon_state = "cleaner"
stage = 2
path = 1
sealed = TRUE
/obj/item/weapon/grenade/chem_grenade/cleaner/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
B1.reagents.add_reagent("fluorosurfactant", 40)
B2.reagents.add_reagent("water", 40)
B2.reagents.add_reagent("cleaner", 10)
detonator = new/obj/item/device/assembly_holder/timer_igniter(src)
beakers += B1
beakers += B2
/obj/item/weapon/grenade/chem_grenade/teargas
name = "tear gas grenade"
desc = "Concentrated Capsaicin. Contents under pressure. Use with caution."
icon_state = "teargas"
stage = 2
path = 1
sealed = TRUE
/obj/item/weapon/grenade/chem_grenade/teargas/Initialize()
. = ..()
var/obj/item/weapon/reagent_containers/glass/beaker/large/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/large/B2 = new(src)
B1.reagents.add_reagent("phosphorus", 40)
B1.reagents.add_reagent("potassium", 40)
B1.reagents.add_reagent("condensedcapsaicin", 40)
B2.reagents.add_reagent("sugar", 40)
B2.reagents.add_reagent("condensedcapsaicin", 80)
detonator = new/obj/item/device/assembly_holder/timer_igniter(src)
beakers += B1
beakers += B2
@@ -1,25 +1,25 @@
/obj/item/weapon/grenade/empgrenade
name = "emp grenade"
icon_state = "emp"
item_state = "empgrenade"
origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 3)
var/emp_heavy = 2
var/emp_med = 4
var/emp_light = 7
var/emp_long = 10
/obj/item/weapon/grenade/empgrenade/detonate()
..()
if(empulse(src, emp_heavy, emp_med, emp_light, emp_long))
qdel(src)
return
/obj/item/weapon/grenade/empgrenade/low_yield
name = "low yield emp grenade"
desc = "A weaker variant of the EMP grenade"
icon_state = "lyemp"
origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 3)
emp_heavy = 1
emp_med = 2
emp_light = 3
/obj/item/weapon/grenade/empgrenade
name = "emp grenade"
icon_state = "emp"
item_state = "empgrenade"
origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 3)
var/emp_heavy = 2
var/emp_med = 4
var/emp_light = 7
var/emp_long = 10
/obj/item/weapon/grenade/empgrenade/detonate()
..()
if(empulse(src, emp_heavy, emp_med, emp_light, emp_long))
qdel(src)
return
/obj/item/weapon/grenade/empgrenade/low_yield
name = "low yield emp grenade"
desc = "A weaker variant of the EMP grenade"
icon_state = "lyemp"
origin_tech = list(TECH_MATERIAL = 2, TECH_MAGNET = 3)
emp_heavy = 1
emp_med = 2
emp_light = 3
emp_long = 4
@@ -1,165 +1,165 @@
/obj/item/weapon/grenade/flashbang
name = "flashbang"
icon_state = "flashbang"
item_state = "flashbang"
origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 1)
var/max_range = 10 //The maximum range possible, including species effect mods. Cuts off at 7 for normal humans. Should be 3 higher than your intended target range for affecting normal humans.
var/banglet = 0
/obj/item/weapon/grenade/flashbang/detonate()
..()
for(var/obj/structure/closet/L in hear(max_range, get_turf(src)))
if(locate(/mob/living/carbon/, L))
for(var/mob/living/carbon/M in L)
bang(get_turf(src), M)
for(var/mob/living/carbon/M in hear(max_range, get_turf(src)))
bang(get_turf(src), M)
for(var/obj/structure/blob/B in hear(max_range - 2,get_turf(src))) //Blob damage here
var/damage = round(30/(get_dist(B,get_turf(src))+1))
if(B.overmind)
damage *= B.overmind.blob_type.burn_multiplier
B.adjust_integrity(-damage)
new/obj/effect/effect/sparks(src.loc)
new/obj/effect/effect/smoke/illumination(src.loc, 5, range=30, power=30, color="#FFFFFF")
qdel(src)
/obj/item/weapon/grenade/flashbang/proc/bang(var/turf/T , var/mob/living/carbon/M) // Added a new proc called 'bang' that takes a location and a person to be banged.
to_chat(M, "<span class='danger'>BANG</span>") // Called during the loop that bangs people in lockers/containers and when banging
playsound(src, 'sound/effects/bang.ogg', 50, 1, 30) // people in normal view. Could theroetically be called during other explosions.
// -- Polymorph
//Checking for protections
var/eye_safety = 0
var/ear_safety = 0
if(iscarbon(M))
eye_safety = M.eyecheck()
ear_safety = M.get_ear_protection()
//Flashing everyone
var/mob/living/carbon/human/H = M
var/flash_effectiveness = 1
var/bang_effectiveness = 1
if(ishuman(M))
flash_effectiveness = H.species.flash_mod
bang_effectiveness = H.species.sound_mod
if(eye_safety < 1 && get_dist(M, T) <= round(max_range * 0.7 * flash_effectiveness))
M.flash_eyes()
M.Confuse(2 * flash_effectiveness)
M.Weaken(5 * flash_effectiveness)
//Now applying sound
if((get_dist(M, T) <= round(max_range * 0.3 * bang_effectiveness) || src.loc == M.loc || src.loc == M))
if(ear_safety > 0)
M.Confuse(2)
M.Weaken(1)
else
M.Confuse(10)
M.Weaken(3)
if ((prob(14) || (M == src.loc && prob(70))))
M.ear_damage += rand(1, 10)
else
M.ear_damage += rand(0, 5)
M.ear_deaf = max(M.ear_deaf,15)
else if(get_dist(M, T) <= round(max_range * 0.5 * bang_effectiveness))
if(!ear_safety)
M.Confuse(8)
M.ear_damage += rand(0, 3)
M.ear_deaf = max(M.ear_deaf,10)
else if(!ear_safety && get_dist(M, T) <= (max_range * 0.7 * bang_effectiveness))
M.Confuse(4)
M.ear_damage += rand(0, 1)
M.ear_deaf = max(M.ear_deaf,5)
//This really should be in mob not every check
if(ishuman(M))
var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES]
if (E && E.damage >= E.min_bruised_damage)
to_chat(M, "<span class='danger'>Your eyes start to burn badly!</span>")
if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang)))
if (E.damage >= E.min_broken_damage)
to_chat(M, "<span class='danger'>You can't see anything!</span>")
if (M.ear_damage >= 15)
to_chat(M, "<span class='danger'>Your ears start to ring badly!</span>")
if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang)))
if (prob(M.ear_damage - 10 + 5))
to_chat(M, "<span class='danger'>You can't hear anything!</span>")
M.sdisabilities |= DEAF
else if(M.ear_damage >= 5)
to_chat(M, "<span class='danger'>Your ears start to ring!</span>")
/obj/item/weapon/grenade/flashbang/Destroy()
walk(src, 0) // Because we might have called walk_away, we must stop the walk loop or BYOND keeps an internal reference to us forever.
return ..()
/obj/item/weapon/grenade/flashbang/clusterbang//Created by Polymorph, fixed by Sieve
desc = "Use of this weapon may constiute a war crime in your area, consult your local Site Manager."
name = "clusterbang"
icon = 'icons/obj/grenade.dmi'
icon_state = "clusterbang"
var/can_repeat = TRUE // Does this thing drop mini-clusterbangs?
var/min_banglets = 4
var/max_banglets = 8
/obj/item/weapon/grenade/flashbang/clusterbang/detonate()
var/numspawned = rand(min_banglets, max_banglets)
var/again = 0
if(can_repeat)
for(var/more = numspawned, more > 0, more--)
if(prob(35))
again++
numspawned--
for(var/do_spawn = numspawned, do_spawn > 0, do_spawn--)
new /obj/item/weapon/grenade/flashbang/cluster(src.loc)//Launches flashbangs
playsound(src, 'sound/weapons/armbomb.ogg', 75, 1, -3)
for(var/do_again = again, do_again > 0, do_again--)
new /obj/item/weapon/grenade/flashbang/clusterbang/segment(src.loc)//Creates a 'segment' that launches a few more flashbangs
playsound(src, 'sound/weapons/armbomb.ogg', 75, 1, -3)
qdel(src)
return
/obj/item/weapon/grenade/flashbang/clusterbang/segment
desc = "A smaller segment of a clusterbang. Better run."
name = "clusterbang segment"
icon = 'icons/obj/grenade.dmi'
icon_state = "clusterbang_segment"
can_repeat = FALSE
banglet = TRUE
/obj/item/weapon/grenade/flashbang/clusterbang/segment/New()//Segments should never exist except part of the clusterbang, since these immediately 'do their thing' and asplode
..()
icon_state = "clusterbang_segment_active"
var/stepdist = rand(1,4)//How far to step
var/temploc = src.loc//Saves the current location to know where to step away from
walk_away(src,temploc,stepdist)//I must go, my people need me
var/dettime = rand(15,60)
spawn(dettime)
detonate()
/obj/item/weapon/grenade/flashbang/cluster
banglet = TRUE
/obj/item/weapon/grenade/flashbang/cluster/New()//Same concept as the segments, so that all of the parts don't become reliant on the clusterbang
..()
icon_state = "flashbang_active"
var/stepdist = rand(1,3)
var/temploc = src.loc
walk_away(src,temploc,stepdist)
var/dettime = rand(15,60)
spawn(dettime)
/obj/item/weapon/grenade/flashbang
name = "flashbang"
icon_state = "flashbang"
item_state = "flashbang"
origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 1)
var/max_range = 10 //The maximum range possible, including species effect mods. Cuts off at 7 for normal humans. Should be 3 higher than your intended target range for affecting normal humans.
var/banglet = 0
/obj/item/weapon/grenade/flashbang/detonate()
..()
for(var/obj/structure/closet/L in hear(max_range, get_turf(src)))
if(locate(/mob/living/carbon/, L))
for(var/mob/living/carbon/M in L)
bang(get_turf(src), M)
for(var/mob/living/carbon/M in hear(max_range, get_turf(src)))
bang(get_turf(src), M)
for(var/obj/structure/blob/B in hear(max_range - 2,get_turf(src))) //Blob damage here
var/damage = round(30/(get_dist(B,get_turf(src))+1))
if(B.overmind)
damage *= B.overmind.blob_type.burn_multiplier
B.adjust_integrity(-damage)
new/obj/effect/effect/sparks(src.loc)
new/obj/effect/effect/smoke/illumination(src.loc, 5, range=30, power=30, color="#FFFFFF")
qdel(src)
/obj/item/weapon/grenade/flashbang/proc/bang(var/turf/T , var/mob/living/carbon/M) // Added a new proc called 'bang' that takes a location and a person to be banged.
to_chat(M, "<span class='danger'>BANG</span>") // Called during the loop that bangs people in lockers/containers and when banging
playsound(src, 'sound/effects/bang.ogg', 50, 1, 30) // people in normal view. Could theroetically be called during other explosions.
// -- Polymorph
//Checking for protections
var/eye_safety = 0
var/ear_safety = 0
if(iscarbon(M))
eye_safety = M.eyecheck()
ear_safety = M.get_ear_protection()
//Flashing everyone
var/mob/living/carbon/human/H = M
var/flash_effectiveness = 1
var/bang_effectiveness = 1
if(ishuman(M))
flash_effectiveness = H.species.flash_mod
bang_effectiveness = H.species.sound_mod
if(eye_safety < 1 && get_dist(M, T) <= round(max_range * 0.7 * flash_effectiveness))
M.flash_eyes()
M.Confuse(2 * flash_effectiveness)
M.Weaken(5 * flash_effectiveness)
//Now applying sound
if((get_dist(M, T) <= round(max_range * 0.3 * bang_effectiveness) || src.loc == M.loc || src.loc == M))
if(ear_safety > 0)
M.Confuse(2)
M.Weaken(1)
else
M.Confuse(10)
M.Weaken(3)
if ((prob(14) || (M == src.loc && prob(70))))
M.ear_damage += rand(1, 10)
else
M.ear_damage += rand(0, 5)
M.ear_deaf = max(M.ear_deaf,15)
else if(get_dist(M, T) <= round(max_range * 0.5 * bang_effectiveness))
if(!ear_safety)
M.Confuse(8)
M.ear_damage += rand(0, 3)
M.ear_deaf = max(M.ear_deaf,10)
else if(!ear_safety && get_dist(M, T) <= (max_range * 0.7 * bang_effectiveness))
M.Confuse(4)
M.ear_damage += rand(0, 1)
M.ear_deaf = max(M.ear_deaf,5)
//This really should be in mob not every check
if(ishuman(M))
var/obj/item/organ/internal/eyes/E = H.internal_organs_by_name[O_EYES]
if (E && E.damage >= E.min_bruised_damage)
to_chat(M, "<span class='danger'>Your eyes start to burn badly!</span>")
if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang)))
if (E.damage >= E.min_broken_damage)
to_chat(M, "<span class='danger'>You can't see anything!</span>")
if (M.ear_damage >= 15)
to_chat(M, "<span class='danger'>Your ears start to ring badly!</span>")
if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang)))
if (prob(M.ear_damage - 10 + 5))
to_chat(M, "<span class='danger'>You can't hear anything!</span>")
M.sdisabilities |= DEAF
else if(M.ear_damage >= 5)
to_chat(M, "<span class='danger'>Your ears start to ring!</span>")
/obj/item/weapon/grenade/flashbang/Destroy()
walk(src, 0) // Because we might have called walk_away, we must stop the walk loop or BYOND keeps an internal reference to us forever.
return ..()
/obj/item/weapon/grenade/flashbang/clusterbang//Created by Polymorph, fixed by Sieve
desc = "Use of this weapon may constiute a war crime in your area, consult your local Site Manager."
name = "clusterbang"
icon = 'icons/obj/grenade.dmi'
icon_state = "clusterbang"
var/can_repeat = TRUE // Does this thing drop mini-clusterbangs?
var/min_banglets = 4
var/max_banglets = 8
/obj/item/weapon/grenade/flashbang/clusterbang/detonate()
var/numspawned = rand(min_banglets, max_banglets)
var/again = 0
if(can_repeat)
for(var/more = numspawned, more > 0, more--)
if(prob(35))
again++
numspawned--
for(var/do_spawn = numspawned, do_spawn > 0, do_spawn--)
new /obj/item/weapon/grenade/flashbang/cluster(src.loc)//Launches flashbangs
playsound(src, 'sound/weapons/armbomb.ogg', 75, 1, -3)
for(var/do_again = again, do_again > 0, do_again--)
new /obj/item/weapon/grenade/flashbang/clusterbang/segment(src.loc)//Creates a 'segment' that launches a few more flashbangs
playsound(src, 'sound/weapons/armbomb.ogg', 75, 1, -3)
qdel(src)
return
/obj/item/weapon/grenade/flashbang/clusterbang/segment
desc = "A smaller segment of a clusterbang. Better run."
name = "clusterbang segment"
icon = 'icons/obj/grenade.dmi'
icon_state = "clusterbang_segment"
can_repeat = FALSE
banglet = TRUE
/obj/item/weapon/grenade/flashbang/clusterbang/segment/New()//Segments should never exist except part of the clusterbang, since these immediately 'do their thing' and asplode
..()
icon_state = "clusterbang_segment_active"
var/stepdist = rand(1,4)//How far to step
var/temploc = src.loc//Saves the current location to know where to step away from
walk_away(src,temploc,stepdist)//I must go, my people need me
var/dettime = rand(15,60)
spawn(dettime)
detonate()
/obj/item/weapon/grenade/flashbang/cluster
banglet = TRUE
/obj/item/weapon/grenade/flashbang/cluster/New()//Same concept as the segments, so that all of the parts don't become reliant on the clusterbang
..()
icon_state = "flashbang_active"
var/stepdist = rand(1,3)
var/temploc = src.loc
walk_away(src,temploc,stepdist)
var/dettime = rand(15,60)
spawn(dettime)
detonate()
@@ -1,119 +1,119 @@
/obj/item/weapon/grenade
name = "grenade"
desc = "A hand held grenade, with an adjustable timer."
w_class = ITEMSIZE_SMALL
icon = 'icons/obj/grenade.dmi'
icon_state = "grenade"
item_state = "grenade"
throw_speed = 4
throw_range = 20
slot_flags = SLOT_MASK|SLOT_BELT
var/active = 0
var/det_time = 50
var/loadable = TRUE
var/arm_sound = 'sound/weapons/armbomb.ogg'
var/hud_state = "grenade_he" // TGMC Ammo HUD Port
var/hud_state_empty = "grenade_empty" // TGMC Ammo HUD Port
/obj/item/weapon/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>")
activate(user)
add_fingerprint(user)
spawn(5)
detonate()
return 0
return 1
/*/obj/item/weapon/grenade/afterattack(atom/target as mob|obj|turf|area, mob/user as mob)
if (istype(target, /obj/item/weapon/storage)) return ..() // Trying to put it in a full container
if (istype(target, /obj/item/weapon/gun/grenadelauncher)) return ..()
if((user.get_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(src, 'sound/weapons/armbomb.ogg', 75, 1, -3)
spawn(det_time)
detonate()
return
user.set_dir(get_dir(user, target))
user.drop_item()
var/t = (isturf(target) ? target : target.loc)
walk_towards(src, t, 3)
return*/
/obj/item/weapon/grenade/examine(mob/user)
. = ..()
if(get_dist(user, src) == 0)
if(det_time > 1)
. += "The timer is set to [det_time/10] seconds."
else if(det_time == null)
. += "\The [src] is set for instant detonation."
/obj/item/weapon/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>")
activate(user)
add_fingerprint(user)
if(iscarbon(user))
var/mob/living/carbon/C = user
C.throw_mode_on()
return
/obj/item/weapon/grenade/proc/activate(mob/user as mob)
if(active)
return
if(user)
msg_admin_attack("[key_name_admin(user)] primed \a [src.name]")
icon_state = initial(icon_state) + "_active"
active = 1
playsound(src, arm_sound, 75, 1, -3)
spawn(det_time)
detonate()
return
/obj/item/weapon/grenade/proc/detonate()
// playsound(src, 'sound/items/Welder2.ogg', 25, 1)
var/turf/T = get_turf(src)
if(T)
T.hotspot_expose(700,125)
/obj/item/weapon/grenade/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(W.has_tool_quality(TOOL_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)
..()
return
/obj/item/weapon/grenade/attack_hand()
walk(src, null, null)
..()
return
/obj/item/weapon/grenade/vendor_action(var/obj/machinery/vending/V)
/obj/item/weapon/grenade
name = "grenade"
desc = "A hand held grenade, with an adjustable timer."
w_class = ITEMSIZE_SMALL
icon = 'icons/obj/grenade.dmi'
icon_state = "grenade"
item_state = "grenade"
throw_speed = 4
throw_range = 20
slot_flags = SLOT_MASK|SLOT_BELT
var/active = 0
var/det_time = 50
var/loadable = TRUE
var/arm_sound = 'sound/weapons/armbomb.ogg'
var/hud_state = "grenade_he" // TGMC Ammo HUD Port
var/hud_state_empty = "grenade_empty" // TGMC Ammo HUD Port
/obj/item/weapon/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>")
activate(user)
add_fingerprint(user)
spawn(5)
detonate()
return 0
return 1
/*/obj/item/weapon/grenade/afterattack(atom/target as mob|obj|turf|area, mob/user as mob)
if (istype(target, /obj/item/weapon/storage)) return ..() // Trying to put it in a full container
if (istype(target, /obj/item/weapon/gun/grenadelauncher)) return ..()
if((user.get_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(src, 'sound/weapons/armbomb.ogg', 75, 1, -3)
spawn(det_time)
detonate()
return
user.set_dir(get_dir(user, target))
user.drop_item()
var/t = (isturf(target) ? target : target.loc)
walk_towards(src, t, 3)
return*/
/obj/item/weapon/grenade/examine(mob/user)
. = ..()
if(get_dist(user, src) == 0)
if(det_time > 1)
. += "The timer is set to [det_time/10] seconds."
else if(det_time == null)
. += "\The [src] is set for instant detonation."
/obj/item/weapon/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>")
activate(user)
add_fingerprint(user)
if(iscarbon(user))
var/mob/living/carbon/C = user
C.throw_mode_on()
return
/obj/item/weapon/grenade/proc/activate(mob/user as mob)
if(active)
return
if(user)
msg_admin_attack("[key_name_admin(user)] primed \a [src.name]")
icon_state = initial(icon_state) + "_active"
active = 1
playsound(src, arm_sound, 75, 1, -3)
spawn(det_time)
detonate()
return
/obj/item/weapon/grenade/proc/detonate()
// playsound(src, 'sound/items/Welder2.ogg', 25, 1)
var/turf/T = get_turf(src)
if(T)
T.hotspot_expose(700,125)
/obj/item/weapon/grenade/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(W.has_tool_quality(TOOL_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)
..()
return
/obj/item/weapon/grenade/attack_hand()
walk(src, null, null)
..()
return
/obj/item/weapon/grenade/vendor_action(var/obj/machinery/vending/V)
activate(V)
@@ -1,39 +1,39 @@
/obj/item/weapon/grenade/smokebomb
desc = "It is set to detonate in 2 seconds. These high-tech grenades can have their color adapted on the fly with a multitool!"
name = "smoke bomb"
icon = 'icons/obj/grenade.dmi'
icon_state = "flashbang"
det_time = 20
item_state = "flashbang"
slot_flags = SLOT_BELT
hud_state = "grenade_smoke"
var/datum/effect/effect/system/smoke_spread/bad/smoke
var/smoke_color
var/smoke_strength = 8
/obj/item/weapon/grenade/smokebomb/New()
..()
src.smoke = new /datum/effect/effect/system/smoke_spread/bad()
src.smoke.attach(src)
/obj/item/weapon/grenade/smokebomb/Destroy()
qdel(smoke)
smoke = null
return ..()
/obj/item/weapon/grenade/smokebomb/detonate()
playsound(src, 'sound/effects/smoke.ogg', 50, 1, -3)
src.smoke.set_up(10, 0, usr.loc)
spawn(0)
for(var/i = 1 to smoke_strength)
src.smoke.start(smoke_color)
sleep(10)
qdel(src)
return
/obj/item/weapon/grenade/smokebomb/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I,/obj/item/device/multitool))
var/new_smoke_color = input(user, "Choose a color for the smoke:", "Smoke Color", smoke_color) as color|null
if(new_smoke_color)
smoke_color = new_smoke_color
/obj/item/weapon/grenade/smokebomb
desc = "It is set to detonate in 2 seconds. These high-tech grenades can have their color adapted on the fly with a multitool!"
name = "smoke bomb"
icon = 'icons/obj/grenade.dmi'
icon_state = "flashbang"
det_time = 20
item_state = "flashbang"
slot_flags = SLOT_BELT
hud_state = "grenade_smoke"
var/datum/effect/effect/system/smoke_spread/bad/smoke
var/smoke_color
var/smoke_strength = 8
/obj/item/weapon/grenade/smokebomb/New()
..()
src.smoke = new /datum/effect/effect/system/smoke_spread/bad()
src.smoke.attach(src)
/obj/item/weapon/grenade/smokebomb/Destroy()
qdel(smoke)
smoke = null
return ..()
/obj/item/weapon/grenade/smokebomb/detonate()
playsound(src, 'sound/effects/smoke.ogg', 50, 1, -3)
src.smoke.set_up(10, 0, usr.loc)
spawn(0)
for(var/i = 1 to smoke_strength)
src.smoke.start(smoke_color)
sleep(10)
qdel(src)
return
/obj/item/weapon/grenade/smokebomb/attackby(obj/item/I as obj, mob/user as mob)
if(istype(I,/obj/item/device/multitool))
var/new_smoke_color = input(user, "Choose a color for the smoke:", "Smoke Color", smoke_color) as color|null
if(new_smoke_color)
smoke_color = new_smoke_color
@@ -1,79 +1,79 @@
/obj/item/weapon/grenade/spawnergrenade
desc = "It is set to detonate in 5 seconds. It will unleash an unspecified anomaly into the vicinity."
name = "delivery grenade"
icon = 'icons/obj/grenade.dmi'
icon_state = "delivery"
item_state = "flashbang"
origin_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 4)
var/banglet = 0
var/spawner_type = null // must be an object path
var/deliveryamt = 1 // amount of type to deliver
// Detonate now just handles the two loops that query for people in lockers and people who can see it.
/obj/item/weapon/grenade/spawnergrenade/detonate()
if(spawner_type && deliveryamt)
// Make a quick flash
var/turf/T = get_turf(src)
playsound(src, 'sound/effects/phasein.ogg', 100, 1)
for(var/mob/living/carbon/human/M in viewers(T, null))
if(M:eyecheck() <= 0)
M.flash_eyes()
// Spawn some hostile syndicate critters
for(var/i=1, i<=deliveryamt, i++)
var/atom/movable/x = new spawner_type(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/weapon/grenade/spawnergrenade/manhacks
name = "manhack delivery grenade"
spawner_type = /mob/living/simple_mob/mechanical/viscerator
deliveryamt = 5
origin_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 4, TECH_ILLEGAL = 4)
/obj/item/weapon/grenade/spawnergrenade/manhacks/mercenary
spawner_type = /mob/living/simple_mob/mechanical/viscerator/mercenary
/obj/item/weapon/grenade/spawnergrenade/manhacks/raider
spawner_type = /mob/living/simple_mob/mechanical/viscerator/raider
/obj/item/weapon/grenade/spawnergrenade/manhacks/station
desc = "It is set to detonate in 5 seconds. It will deploy three weaponized survey drones."
deliveryamt = 3
spawner_type = /mob/living/simple_mob/mechanical/viscerator/station
origin_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 3, TECH_ILLEGAL = 1)
/obj/item/weapon/grenade/spawnergrenade/ward
name = "sentry delivery grenade"
desc = "It is set to detonate in 5 seconds. It will deploy a single thermal-optic sentry drone."
spawner_type = /mob/living/simple_mob/mechanical/ward/monitor/crew
deliveryamt = 1
origin_tech = list(TECH_MATERIAL = 4, TECH_MAGNET = 3, TECH_BLUESPACE = 2)
/obj/item/weapon/grenade/spawnergrenade/spesscarp
name = "carp delivery grenade"
spawner_type = /mob/living/simple_mob/animal/space/carp
deliveryamt = 5
origin_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 4, TECH_ILLEGAL = 4)
/obj/item/weapon/grenade/spawnergrenade/spider
name = "spider delivery grenade"
spawner_type = /mob/living/simple_mob/animal/giant_spider/hunter
deliveryamt = 3
origin_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 4, TECH_ILLEGAL = 4)
//Sometimes you just need a sudden influx of spiders.
/obj/item/weapon/grenade/spawnergrenade/spider/briefcase
name = "briefcase"
desc = "It's made of AUTHENTIC faux-leather and has a price-tag still attached. Its owner must be a real professional."
icon_state = "briefcase"
item_state = "briefcase"
force = 8.0
throw_speed = 1
throw_range = 4
w_class = ITEMSIZE_LARGE
deliveryamt = 6
/obj/item/weapon/grenade/spawnergrenade
desc = "It is set to detonate in 5 seconds. It will unleash an unspecified anomaly into the vicinity."
name = "delivery grenade"
icon = 'icons/obj/grenade.dmi'
icon_state = "delivery"
item_state = "flashbang"
origin_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 4)
var/banglet = 0
var/spawner_type = null // must be an object path
var/deliveryamt = 1 // amount of type to deliver
// Detonate now just handles the two loops that query for people in lockers and people who can see it.
/obj/item/weapon/grenade/spawnergrenade/detonate()
if(spawner_type && deliveryamt)
// Make a quick flash
var/turf/T = get_turf(src)
playsound(src, 'sound/effects/phasein.ogg', 100, 1)
for(var/mob/living/carbon/human/M in viewers(T, null))
if(M:eyecheck() <= 0)
M.flash_eyes()
// Spawn some hostile syndicate critters
for(var/i=1, i<=deliveryamt, i++)
var/atom/movable/x = new spawner_type(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/weapon/grenade/spawnergrenade/manhacks
name = "manhack delivery grenade"
spawner_type = /mob/living/simple_mob/mechanical/viscerator
deliveryamt = 5
origin_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 4, TECH_ILLEGAL = 4)
/obj/item/weapon/grenade/spawnergrenade/manhacks/mercenary
spawner_type = /mob/living/simple_mob/mechanical/viscerator/mercenary
/obj/item/weapon/grenade/spawnergrenade/manhacks/raider
spawner_type = /mob/living/simple_mob/mechanical/viscerator/raider
/obj/item/weapon/grenade/spawnergrenade/manhacks/station
desc = "It is set to detonate in 5 seconds. It will deploy three weaponized survey drones."
deliveryamt = 3
spawner_type = /mob/living/simple_mob/mechanical/viscerator/station
origin_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 3, TECH_ILLEGAL = 1)
/obj/item/weapon/grenade/spawnergrenade/ward
name = "sentry delivery grenade"
desc = "It is set to detonate in 5 seconds. It will deploy a single thermal-optic sentry drone."
spawner_type = /mob/living/simple_mob/mechanical/ward/monitor/crew
deliveryamt = 1
origin_tech = list(TECH_MATERIAL = 4, TECH_MAGNET = 3, TECH_BLUESPACE = 2)
/obj/item/weapon/grenade/spawnergrenade/spesscarp
name = "carp delivery grenade"
spawner_type = /mob/living/simple_mob/animal/space/carp
deliveryamt = 5
origin_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 4, TECH_ILLEGAL = 4)
/obj/item/weapon/grenade/spawnergrenade/spider
name = "spider delivery grenade"
spawner_type = /mob/living/simple_mob/animal/giant_spider/hunter
deliveryamt = 3
origin_tech = list(TECH_MATERIAL = 3, TECH_MAGNET = 4, TECH_ILLEGAL = 4)
//Sometimes you just need a sudden influx of spiders.
/obj/item/weapon/grenade/spawnergrenade/spider/briefcase
name = "briefcase"
desc = "It's made of AUTHENTIC faux-leather and has a price-tag still attached. Its owner must be a real professional."
icon_state = "briefcase"
item_state = "briefcase"
force = 8.0
throw_speed = 1
throw_range = 4
w_class = ITEMSIZE_LARGE
deliveryamt = 6
+337 -337
View File
@@ -1,337 +1,337 @@
/obj/item/weapon/handcuffs
name = "handcuffs"
desc = "Use this to keep prisoners in line."
gender = PLURAL
icon = 'icons/obj/items.dmi'
icon_state = "handcuff"
slot_flags = SLOT_BELT
throwforce = 5
w_class = ITEMSIZE_SMALL
throw_speed = 2
throw_range = 5
origin_tech = list(TECH_MATERIAL = 1)
matter = list(MAT_STEEL = 500)
drop_sound = 'sound/items/drop/accessory.ogg'
pickup_sound = 'sound/items/pickup/accessory.ogg'
var/elastic
var/dispenser = 0
var/breakouttime = 1200 //Deciseconds = 120s = 2 minutes
var/cuff_sound = 'sound/weapons/handcuffs.ogg'
var/cuff_type = "handcuffs"
var/use_time = 30
sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/teshari/handcuffs.dmi')
/obj/item/weapon/handcuffs/get_worn_icon_state(var/slot_name)
if(slot_name == slot_handcuffed_str)
return "handcuff1" //Simple
return ..()
/obj/item/weapon/handcuffs/attack(var/mob/living/carbon/C, var/mob/living/user)
if(!user.IsAdvancedToolUser())
return
if ((CLUMSY in user.mutations) && prob(50))
to_chat(user, "<span class='warning'>Uh ... how do those things work?!</span>")
place_handcuffs(user, user)
return
if(!C.handcuffed)
if (C == user)
place_handcuffs(user, user)
return
//check for an aggressive grab (or robutts)
if(can_place(C, user))
place_handcuffs(C, user)
else
to_chat(user, "<span class='danger'>You need to have a firm grip on [C] before you can put \the [src] on!</span>")
/obj/item/weapon/handcuffs/proc/can_place(var/mob/target, var/mob/user)
if(user == target)
return 1
if(istype(user, /mob/living/silicon/robot))
if(user.Adjacent(target))
return 1
else
for(var/obj/item/weapon/grab/G in target.grabbed_by)
if(G.loc == user && G.state >= GRAB_AGGRESSIVE)
return 1
return 0
/obj/item/weapon/handcuffs/proc/place_handcuffs(var/mob/living/carbon/target, var/mob/user)
playsound(src, cuff_sound, 30, 1, -2)
var/mob/living/carbon/human/H = target
if(!istype(H))
return 0
if (!H.has_organ_for_slot(slot_handcuffed))
to_chat(user, "<span class='danger'>\The [H] needs at least two wrists before you can cuff them together!</span>")
return 0
if(istype(H.gloves,/obj/item/clothing/gloves/gauntlets/rig) && !elastic) // Can't cuff someone who's in a deployed hardsuit.
to_chat(user, "<span class='danger'>\The [src] won't fit around \the [H.gloves]!</span>")
return 0
user.visible_message("<span class='danger'>\The [user] is attempting to put [cuff_type] on \the [H]!</span>")
if(!do_after(user,use_time))
return 0
if(!can_place(target, user)) //victim may have resisted out of the grab in the meantime
return 0
add_attack_logs(user,H,"Handcuffed (attempt)")
feedback_add_details("handcuffs","H")
user.setClickCooldown(user.get_attack_speed(src))
user.do_attack_animation(H)
user.visible_message("<span class='danger'>\The [user] has put [cuff_type] on \the [H]!</span>")
// Apply cuffs.
var/obj/item/weapon/handcuffs/cuffs = src
if(dispenser)
cuffs = new(get_turf(user))
else
user.drop_from_inventory(cuffs)
cuffs.loc = target
target.handcuffed = cuffs
target.update_handcuffed()
target.drop_r_hand()
target.drop_l_hand()
target.stop_pulling()
return 1
/obj/item/weapon/handcuffs/equipped(var/mob/living/user,var/slot)
. = ..()
if(slot == slot_handcuffed)
user.drop_r_hand()
user.drop_l_hand()
user.stop_pulling()
var/last_chew = 0
/mob/living/carbon/human/RestrainedClickOn(var/atom/A)
if (A != src) return ..()
if (last_chew + 26 > world.time) return
var/mob/living/carbon/human/H = A
if (!H.handcuffed) return
if (H.a_intent != I_HURT) return
if (H.zone_sel.selecting != O_MOUTH) return
if (H.wear_mask) return
if (istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket)) return
var/obj/item/organ/external/O = H.organs_by_name[(H.hand ? BP_L_HAND : BP_R_HAND)]
if (!O) return
var/datum/gender/T = gender_datums[H.get_visible_gender()]
var/s = "<span class='warning'>[H.name] chews on [T.his] [O.name]!</span>"
H.visible_message(s, "<span class='warning'>You chew on your [O.name]!</span>")
add_attack_logs(H,H,"chewed own [O.name]")
if(O.take_damage(3,0,1,1,"teeth marks"))
H:UpdateDamageIcon()
last_chew = world.time
/obj/item/weapon/handcuffs/fuzzy
name = "fuzzy cuffs"
icon_state = "fuzzycuff"
breakouttime = 100 //VOREstation edit
desc = "Use this to keep... 'prisoners' in line."
/obj/item/weapon/handcuffs/cable
name = "cable restraints"
desc = "Looks like some cables tied together. Could be used to tie something up."
icon_state = "cuff_white"
breakouttime = 300 //Deciseconds = 30s
cuff_sound = 'sound/weapons/cablecuff.ogg'
cuff_type = "cable restraints"
elastic = 1
/obj/item/weapon/handcuffs/cable/red
color = "#DD0000"
/obj/item/weapon/handcuffs/cable/yellow
color = "#DDDD00"
/obj/item/weapon/handcuffs/cable/blue
color = "#0000DD"
/obj/item/weapon/handcuffs/cable/green
color = "#00DD00"
/obj/item/weapon/handcuffs/cable/pink
color = "#DD00DD"
/obj/item/weapon/handcuffs/cable/orange
color = "#DD8800"
/obj/item/weapon/handcuffs/cable/cyan
color = "#00DDDD"
/obj/item/weapon/handcuffs/cable/white
color = "#FFFFFF"
/obj/item/weapon/handcuffs/cyborg
dispenser = 1
/obj/item/weapon/handcuffs/cable/tape
name = "tape restraints"
desc = "DIY!"
icon_state = "tape_cross"
item_state = null
icon = 'icons/obj/bureaucracy.dmi'
breakouttime = 200
cuff_type = "duct tape"
/obj/item/weapon/handcuffs/cable/tape/cyborg
dispenser = TRUE
//Legcuffs. Not /really/ handcuffs, but its close enough.
/obj/item/weapon/handcuffs/legcuffs
name = "legcuffs"
desc = "Use this to keep prisoners in line."
gender = PLURAL
icon = 'icons/obj/items.dmi'
icon_state = "legcuff"
throwforce = 0
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_MATERIAL = 1)
breakouttime = 300 //Deciseconds = 30s = 0.5 minute
cuff_type = "legcuffs"
sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/teshari/handcuffs.dmi')
elastic = 0
cuff_sound = 'sound/weapons/handcuffs.ogg' //This shold work for now.
/obj/item/weapon/handcuffs/legcuffs/get_worn_icon_state(var/slot_name)
if(slot_name == slot_legcuffed_str)
return "legcuff1"
return ..()
/obj/item/weapon/handcuffs/legcuffs/attack(var/mob/living/carbon/C, var/mob/living/user)
if(!user.IsAdvancedToolUser())
return
if ((CLUMSY in user.mutations) && prob(50))
to_chat(user, "<span class='warning'>Uh ... how do those things work?!</span>")
place_legcuffs(user, user)
return
if(!C.legcuffed)
if (C == user)
place_legcuffs(user, user)
return
//check for an aggressive grab (or robutts)
if(can_place(C, user))
place_legcuffs(C, user)
else
to_chat(user, "<span class='danger'>You need to have a firm grip on [C] before you can put \the [src] on!</span>")
/obj/item/weapon/handcuffs/legcuffs/proc/place_legcuffs(var/mob/living/carbon/target, var/mob/user)
playsound(src, cuff_sound, 30, 1, -2)
var/mob/living/carbon/human/H = target
if(!istype(H))
return 0
if (!H.has_organ_for_slot(slot_legcuffed))
to_chat(user, "<span class='danger'>\The [H] needs at least two ankles before you can cuff them together!</span>")
return 0
if(istype(H.shoes,/obj/item/clothing/shoes/magboots/rig) && !elastic) // Can't cuff someone who's in a deployed hardsuit.
to_chat(user, "<span class='danger'>\The [src] won't fit around \the [H.shoes]!</span>")
return 0
user.visible_message("<span class='danger'>\The [user] is attempting to put [cuff_type] on \the [H]!</span>")
if(!do_after(user,use_time))
return 0
if(!can_place(target, user)) //victim may have resisted out of the grab in the meantime
return 0
add_attack_logs(user,H,"Legcuffed (attempt)")
feedback_add_details("legcuffs","H")
user.setClickCooldown(user.get_attack_speed(src))
user.do_attack_animation(H)
user.visible_message("<span class='danger'>\The [user] has put [cuff_type] on \the [H]!</span>")
// Apply cuffs.
var/obj/item/weapon/handcuffs/legcuffs/lcuffs = src
if(dispenser)
lcuffs = new(get_turf(user))
else
user.drop_from_inventory(lcuffs)
lcuffs.loc = target
target.legcuffed = lcuffs
target.update_inv_legcuffed()
if(target.m_intent != "walk")
target.m_intent = "walk"
if(target.hud_used && user.hud_used.move_intent)
target.hud_used.move_intent.icon_state = "walking"
return 1
/obj/item/weapon/handcuffs/legcuffs/equipped(var/mob/living/user,var/slot)
. = ..()
if(slot == slot_legcuffed)
if(user.m_intent != "walk")
user.m_intent = "walk"
if(user.hud_used && user.hud_used.move_intent)
user.hud_used.move_intent.icon_state = "walking"
/obj/item/weapon/handcuffs/legcuffs/bola
name = "bola"
desc = "Keeps prey in line."
elastic = 1
use_time = 0
breakouttime = 30
cuff_sound = 'sound/weapons/towelwipe.ogg' //Is there anything this sound can't do?
/obj/item/weapon/handcuffs/legcuffs/bola/can_place(var/mob/target, var/mob/user)
if(user) //A ranged legcuff, until proper implementation as items it remains a projectile-only thing.
return 1
/obj/item/weapon/handcuffs/legcuffs/bola/dropped()
visible_message("<b>\The [src]</b> falls apart!")
qdel(src)
/obj/item/weapon/handcuffs/legcuffs/bola/place_legcuffs(var/mob/living/carbon/target, var/mob/user)
playsound(src, cuff_sound, 30, 1, -2)
var/mob/living/carbon/human/H = target
if(!istype(H))
src.dropped()
return 0
if(!H.has_organ_for_slot(slot_legcuffed))
H.visible_message("<b>\The [src]</b> slams into [H], but slides off!")
src.dropped()
return 0
H.visible_message("<span class='danger'>\The [H] has been snared by \the [src]!</span>")
// Apply cuffs.
var/obj/item/weapon/handcuffs/legcuffs/lcuffs = src
lcuffs.loc = target
target.legcuffed = lcuffs
target.update_inv_legcuffed()
if(target.m_intent != "walk")
target.m_intent = "walk"
if(target.hud_used && user.hud_used.move_intent)
target.hud_used.move_intent.icon_state = "walking"
return 1
/obj/item/weapon/handcuffs/cable/plantfiber
name = "rope bindings"
desc = "A length of rope fashioned to hold someone's hands together."
color = "#7e6442"
/obj/item/weapon/handcuffs
name = "handcuffs"
desc = "Use this to keep prisoners in line."
gender = PLURAL
icon = 'icons/obj/items.dmi'
icon_state = "handcuff"
slot_flags = SLOT_BELT
throwforce = 5
w_class = ITEMSIZE_SMALL
throw_speed = 2
throw_range = 5
origin_tech = list(TECH_MATERIAL = 1)
matter = list(MAT_STEEL = 500)
drop_sound = 'sound/items/drop/accessory.ogg'
pickup_sound = 'sound/items/pickup/accessory.ogg'
var/elastic
var/dispenser = 0
var/breakouttime = 1200 //Deciseconds = 120s = 2 minutes
var/cuff_sound = 'sound/weapons/handcuffs.ogg'
var/cuff_type = "handcuffs"
var/use_time = 30
sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/teshari/handcuffs.dmi')
/obj/item/weapon/handcuffs/get_worn_icon_state(var/slot_name)
if(slot_name == slot_handcuffed_str)
return "handcuff1" //Simple
return ..()
/obj/item/weapon/handcuffs/attack(var/mob/living/carbon/C, var/mob/living/user)
if(!user.IsAdvancedToolUser())
return
if ((CLUMSY in user.mutations) && prob(50))
to_chat(user, "<span class='warning'>Uh ... how do those things work?!</span>")
place_handcuffs(user, user)
return
if(!C.handcuffed)
if (C == user)
place_handcuffs(user, user)
return
//check for an aggressive grab (or robutts)
if(can_place(C, user))
place_handcuffs(C, user)
else
to_chat(user, "<span class='danger'>You need to have a firm grip on [C] before you can put \the [src] on!</span>")
/obj/item/weapon/handcuffs/proc/can_place(var/mob/target, var/mob/user)
if(user == target)
return 1
if(istype(user, /mob/living/silicon/robot))
if(user.Adjacent(target))
return 1
else
for(var/obj/item/weapon/grab/G in target.grabbed_by)
if(G.loc == user && G.state >= GRAB_AGGRESSIVE)
return 1
return 0
/obj/item/weapon/handcuffs/proc/place_handcuffs(var/mob/living/carbon/target, var/mob/user)
playsound(src, cuff_sound, 30, 1, -2)
var/mob/living/carbon/human/H = target
if(!istype(H))
return 0
if (!H.has_organ_for_slot(slot_handcuffed))
to_chat(user, "<span class='danger'>\The [H] needs at least two wrists before you can cuff them together!</span>")
return 0
if(istype(H.gloves,/obj/item/clothing/gloves/gauntlets/rig) && !elastic) // Can't cuff someone who's in a deployed hardsuit.
to_chat(user, "<span class='danger'>\The [src] won't fit around \the [H.gloves]!</span>")
return 0
user.visible_message("<span class='danger'>\The [user] is attempting to put [cuff_type] on \the [H]!</span>")
if(!do_after(user,use_time))
return 0
if(!can_place(target, user)) //victim may have resisted out of the grab in the meantime
return 0
add_attack_logs(user,H,"Handcuffed (attempt)")
feedback_add_details("handcuffs","H")
user.setClickCooldown(user.get_attack_speed(src))
user.do_attack_animation(H)
user.visible_message("<span class='danger'>\The [user] has put [cuff_type] on \the [H]!</span>")
// Apply cuffs.
var/obj/item/weapon/handcuffs/cuffs = src
if(dispenser)
cuffs = new(get_turf(user))
else
user.drop_from_inventory(cuffs)
cuffs.loc = target
target.handcuffed = cuffs
target.update_handcuffed()
target.drop_r_hand()
target.drop_l_hand()
target.stop_pulling()
return 1
/obj/item/weapon/handcuffs/equipped(var/mob/living/user,var/slot)
. = ..()
if(slot == slot_handcuffed)
user.drop_r_hand()
user.drop_l_hand()
user.stop_pulling()
var/last_chew = 0
/mob/living/carbon/human/RestrainedClickOn(var/atom/A)
if (A != src) return ..()
if (last_chew + 26 > world.time) return
var/mob/living/carbon/human/H = A
if (!H.handcuffed) return
if (H.a_intent != I_HURT) return
if (H.zone_sel.selecting != O_MOUTH) return
if (H.wear_mask) return
if (istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket)) return
var/obj/item/organ/external/O = H.organs_by_name[(H.hand ? BP_L_HAND : BP_R_HAND)]
if (!O) return
var/datum/gender/T = gender_datums[H.get_visible_gender()]
var/s = "<span class='warning'>[H.name] chews on [T.his] [O.name]!</span>"
H.visible_message(s, "<span class='warning'>You chew on your [O.name]!</span>")
add_attack_logs(H,H,"chewed own [O.name]")
if(O.take_damage(3,0,1,1,"teeth marks"))
H:UpdateDamageIcon()
last_chew = world.time
/obj/item/weapon/handcuffs/fuzzy
name = "fuzzy cuffs"
icon_state = "fuzzycuff"
breakouttime = 100 //VOREstation edit
desc = "Use this to keep... 'prisoners' in line."
/obj/item/weapon/handcuffs/cable
name = "cable restraints"
desc = "Looks like some cables tied together. Could be used to tie something up."
icon_state = "cuff_white"
breakouttime = 300 //Deciseconds = 30s
cuff_sound = 'sound/weapons/cablecuff.ogg'
cuff_type = "cable restraints"
elastic = 1
/obj/item/weapon/handcuffs/cable/red
color = "#DD0000"
/obj/item/weapon/handcuffs/cable/yellow
color = "#DDDD00"
/obj/item/weapon/handcuffs/cable/blue
color = "#0000DD"
/obj/item/weapon/handcuffs/cable/green
color = "#00DD00"
/obj/item/weapon/handcuffs/cable/pink
color = "#DD00DD"
/obj/item/weapon/handcuffs/cable/orange
color = "#DD8800"
/obj/item/weapon/handcuffs/cable/cyan
color = "#00DDDD"
/obj/item/weapon/handcuffs/cable/white
color = "#FFFFFF"
/obj/item/weapon/handcuffs/cyborg
dispenser = 1
/obj/item/weapon/handcuffs/cable/tape
name = "tape restraints"
desc = "DIY!"
icon_state = "tape_cross"
item_state = null
icon = 'icons/obj/bureaucracy.dmi'
breakouttime = 200
cuff_type = "duct tape"
/obj/item/weapon/handcuffs/cable/tape/cyborg
dispenser = TRUE
//Legcuffs. Not /really/ handcuffs, but its close enough.
/obj/item/weapon/handcuffs/legcuffs
name = "legcuffs"
desc = "Use this to keep prisoners in line."
gender = PLURAL
icon = 'icons/obj/items.dmi'
icon_state = "legcuff"
throwforce = 0
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_MATERIAL = 1)
breakouttime = 300 //Deciseconds = 30s = 0.5 minute
cuff_type = "legcuffs"
sprite_sheets = list(SPECIES_TESHARI = 'icons/mob/species/teshari/handcuffs.dmi')
elastic = 0
cuff_sound = 'sound/weapons/handcuffs.ogg' //This shold work for now.
/obj/item/weapon/handcuffs/legcuffs/get_worn_icon_state(var/slot_name)
if(slot_name == slot_legcuffed_str)
return "legcuff1"
return ..()
/obj/item/weapon/handcuffs/legcuffs/attack(var/mob/living/carbon/C, var/mob/living/user)
if(!user.IsAdvancedToolUser())
return
if ((CLUMSY in user.mutations) && prob(50))
to_chat(user, "<span class='warning'>Uh ... how do those things work?!</span>")
place_legcuffs(user, user)
return
if(!C.legcuffed)
if (C == user)
place_legcuffs(user, user)
return
//check for an aggressive grab (or robutts)
if(can_place(C, user))
place_legcuffs(C, user)
else
to_chat(user, "<span class='danger'>You need to have a firm grip on [C] before you can put \the [src] on!</span>")
/obj/item/weapon/handcuffs/legcuffs/proc/place_legcuffs(var/mob/living/carbon/target, var/mob/user)
playsound(src, cuff_sound, 30, 1, -2)
var/mob/living/carbon/human/H = target
if(!istype(H))
return 0
if (!H.has_organ_for_slot(slot_legcuffed))
to_chat(user, "<span class='danger'>\The [H] needs at least two ankles before you can cuff them together!</span>")
return 0
if(istype(H.shoes,/obj/item/clothing/shoes/magboots/rig) && !elastic) // Can't cuff someone who's in a deployed hardsuit.
to_chat(user, "<span class='danger'>\The [src] won't fit around \the [H.shoes]!</span>")
return 0
user.visible_message("<span class='danger'>\The [user] is attempting to put [cuff_type] on \the [H]!</span>")
if(!do_after(user,use_time))
return 0
if(!can_place(target, user)) //victim may have resisted out of the grab in the meantime
return 0
add_attack_logs(user,H,"Legcuffed (attempt)")
feedback_add_details("legcuffs","H")
user.setClickCooldown(user.get_attack_speed(src))
user.do_attack_animation(H)
user.visible_message("<span class='danger'>\The [user] has put [cuff_type] on \the [H]!</span>")
// Apply cuffs.
var/obj/item/weapon/handcuffs/legcuffs/lcuffs = src
if(dispenser)
lcuffs = new(get_turf(user))
else
user.drop_from_inventory(lcuffs)
lcuffs.loc = target
target.legcuffed = lcuffs
target.update_inv_legcuffed()
if(target.m_intent != "walk")
target.m_intent = "walk"
if(target.hud_used && user.hud_used.move_intent)
target.hud_used.move_intent.icon_state = "walking"
return 1
/obj/item/weapon/handcuffs/legcuffs/equipped(var/mob/living/user,var/slot)
. = ..()
if(slot == slot_legcuffed)
if(user.m_intent != "walk")
user.m_intent = "walk"
if(user.hud_used && user.hud_used.move_intent)
user.hud_used.move_intent.icon_state = "walking"
/obj/item/weapon/handcuffs/legcuffs/bola
name = "bola"
desc = "Keeps prey in line."
elastic = 1
use_time = 0
breakouttime = 30
cuff_sound = 'sound/weapons/towelwipe.ogg' //Is there anything this sound can't do?
/obj/item/weapon/handcuffs/legcuffs/bola/can_place(var/mob/target, var/mob/user)
if(user) //A ranged legcuff, until proper implementation as items it remains a projectile-only thing.
return 1
/obj/item/weapon/handcuffs/legcuffs/bola/dropped()
visible_message("<b>\The [src]</b> falls apart!")
qdel(src)
/obj/item/weapon/handcuffs/legcuffs/bola/place_legcuffs(var/mob/living/carbon/target, var/mob/user)
playsound(src, cuff_sound, 30, 1, -2)
var/mob/living/carbon/human/H = target
if(!istype(H))
src.dropped()
return 0
if(!H.has_organ_for_slot(slot_legcuffed))
H.visible_message("<b>\The [src]</b> slams into [H], but slides off!")
src.dropped()
return 0
H.visible_message("<span class='danger'>\The [H] has been snared by \the [src]!</span>")
// Apply cuffs.
var/obj/item/weapon/handcuffs/legcuffs/lcuffs = src
lcuffs.loc = target
target.legcuffed = lcuffs
target.update_inv_legcuffed()
if(target.m_intent != "walk")
target.m_intent = "walk"
if(target.hud_used && user.hud_used.move_intent)
target.hud_used.move_intent.icon_state = "walking"
return 1
/obj/item/weapon/handcuffs/cable/plantfiber
name = "rope bindings"
desc = "A length of rope fashioned to hold someone's hands together."
color = "#7e6442"
+113 -113
View File
@@ -1,113 +1,113 @@
/*
* SeedBag
*/
//uncomment when this is updated to match storage update
/*
/obj/item/weapon/seedbag
icon = 'icons/obj/hydroponics_machines.dmi'
icon_state = "seedbag"
name = "Seed Bag"
desc = "A small satchel made for organizing seeds."
var/mode = 1; //0 = pick one at a time, 1 = pick all on tile
var/capacity = 500; //the number of seeds it can carry.
slot_flags = SLOT_BELT
w_class = ITEMSIZE_TINY
var/list/item_quants = list()
/obj/item/weapon/seedbag/attack_self(mob/user as mob)
user.machine = src
interact(user)
/obj/item/weapon/seedbag/verb/toggle_mode()
set name = "Switch Bagging Method"
set category = "Object"
mode = !mode
switch (mode)
if(1)
to_chat(usr, "The bag now picks up all seeds in a tile at once.")
if(0)
to_chat(usr, "The bag now picks up one seed pouch at a time.")
/obj/item/seeds/attackby(var/obj/item/O as obj, var/mob/user as mob)
..()
if (istype(O, /obj/item/weapon/seedbag))
var/obj/item/weapon/seedbag/S = O
if (S.mode == 1)
for (var/obj/item/seeds/G in locate(src.x,src.y,src.z))
if (S.contents.len < S.capacity)
S.contents += G;
if(S.item_quants[G.name])
S.item_quants[G.name]++
else
S.item_quants[G.name] = 1
else
to_chat(user, "<span class='warning'>The seed bag is full.</span>")
S.updateUsrDialog()
return
to_chat(user, "<span class='notice'>You pick up all the seeds.</span>")
else
if (S.contents.len < S.capacity)
S.contents += src;
if(S.item_quants[name])
S.item_quants[name]++
else
S.item_quants[name] = 1
else
to_chat(user, "<span class='warning'>The seed bag is full.</span>")
S.updateUsrDialog()
return
/obj/item/weapon/seedbag/interact(mob/user as mob)
var/dat = "<TT><b>Select an item:</b><br>"
if (contents.len == 0)
dat += "<font color = 'red'>No seeds loaded!</font>"
else
for (var/O in item_quants)
if(item_quants[O] > 0)
var/N = item_quants[O]
dat += "<FONT color = 'blue'><B>[capitalize(O)]</B>:"
dat += " [N] </font>"
dat += "<a href='byond://?src=\ref[src];vend=[O]'>Vend</A>"
dat += "<br>"
dat += "<br><a href='byond://?src=\ref[src];unload=1'>Unload All</A>"
dat += "</TT>"
user << browse("<HEAD><TITLE>Seedbag Supplies</TITLE></HEAD><TT>[dat]</TT>", "window=seedbag")
onclose(user, "seedbag")
return
/obj/item/weapon/seedbag/Topic(href, href_list)
if(..())
return
usr.machine = src
if ( href_list["vend"] )
var/N = href_list["vend"]
if(item_quants[N] <= 0) // Sanity check, there are probably ways to press the button when it shouldn't be possible.
return
item_quants[N] -= 1
for(var/obj/O in contents)
if(O.name == N)
O.loc = get_turf(src)
usr.put_in_hands(O)
break
else if ( href_list["unload"] )
item_quants.Cut()
for(var/obj/O in contents )
O.loc = get_turf(src)
src.updateUsrDialog()
return
/obj/item/weapon/seedbag/updateUsrDialog()
var/list/nearby = range(1, src)
for(var/mob/M in nearby)
if ((M.client && M.machine == src))
src.attack_self(M)
*/
/*
* SeedBag
*/
//uncomment when this is updated to match storage update
/*
/obj/item/weapon/seedbag
icon = 'icons/obj/hydroponics_machines.dmi'
icon_state = "seedbag"
name = "Seed Bag"
desc = "A small satchel made for organizing seeds."
var/mode = 1; //0 = pick one at a time, 1 = pick all on tile
var/capacity = 500; //the number of seeds it can carry.
slot_flags = SLOT_BELT
w_class = ITEMSIZE_TINY
var/list/item_quants = list()
/obj/item/weapon/seedbag/attack_self(mob/user as mob)
user.machine = src
interact(user)
/obj/item/weapon/seedbag/verb/toggle_mode()
set name = "Switch Bagging Method"
set category = "Object"
mode = !mode
switch (mode)
if(1)
to_chat(usr, "The bag now picks up all seeds in a tile at once.")
if(0)
to_chat(usr, "The bag now picks up one seed pouch at a time.")
/obj/item/seeds/attackby(var/obj/item/O as obj, var/mob/user as mob)
..()
if (istype(O, /obj/item/weapon/seedbag))
var/obj/item/weapon/seedbag/S = O
if (S.mode == 1)
for (var/obj/item/seeds/G in locate(src.x,src.y,src.z))
if (S.contents.len < S.capacity)
S.contents += G;
if(S.item_quants[G.name])
S.item_quants[G.name]++
else
S.item_quants[G.name] = 1
else
to_chat(user, "<span class='warning'>The seed bag is full.</span>")
S.updateUsrDialog()
return
to_chat(user, "<span class='notice'>You pick up all the seeds.</span>")
else
if (S.contents.len < S.capacity)
S.contents += src;
if(S.item_quants[name])
S.item_quants[name]++
else
S.item_quants[name] = 1
else
to_chat(user, "<span class='warning'>The seed bag is full.</span>")
S.updateUsrDialog()
return
/obj/item/weapon/seedbag/interact(mob/user as mob)
var/dat = "<TT><b>Select an item:</b><br>"
if (contents.len == 0)
dat += "<font color = 'red'>No seeds loaded!</font>"
else
for (var/O in item_quants)
if(item_quants[O] > 0)
var/N = item_quants[O]
dat += "<FONT color = 'blue'><B>[capitalize(O)]</B>:"
dat += " [N] </font>"
dat += "<a href='byond://?src=\ref[src];vend=[O]'>Vend</A>"
dat += "<br>"
dat += "<br><a href='byond://?src=\ref[src];unload=1'>Unload All</A>"
dat += "</TT>"
user << browse("<HEAD><TITLE>Seedbag Supplies</TITLE></HEAD><TT>[dat]</TT>", "window=seedbag")
onclose(user, "seedbag")
return
/obj/item/weapon/seedbag/Topic(href, href_list)
if(..())
return
usr.machine = src
if ( href_list["vend"] )
var/N = href_list["vend"]
if(item_quants[N] <= 0) // Sanity check, there are probably ways to press the button when it shouldn't be possible.
return
item_quants[N] -= 1
for(var/obj/O in contents)
if(O.name == N)
O.loc = get_turf(src)
usr.put_in_hands(O)
break
else if ( href_list["unload"] )
item_quants.Cut()
for(var/obj/O in contents )
O.loc = get_turf(src)
src.updateUsrDialog()
return
/obj/item/weapon/seedbag/updateUsrDialog()
var/list/nearby = range(1, src)
for(var/mob/M in nearby)
if ((M.client && M.machine == src))
src.attack_self(M)
*/
File diff suppressed because it is too large Load Diff
@@ -1,311 +1,311 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/obj/item/weapon/implantcase
name = "glass case"
desc = "A case containing an implant."
icon = 'icons/obj/items.dmi'
icon_state = "implantcase-0"
item_state = "implantcase"
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_TINY
var/obj/item/weapon/implant/imp = null
/obj/item/weapon/implantcase/proc/update()
if (src.imp)
src.icon_state = text("implantcase-[]", src.imp.implant_color)
else
src.icon_state = "implantcase-0"
return
/obj/item/weapon/implantcase/attackby(obj/item/weapon/I as obj, mob/user as mob)
..()
if (istype(I, /obj/item/weapon/pen))
var/t = tgui_input_text(user, "What would you like the label to be?", text("[]", src.name), null, MAX_NAME_LEN)
if (user.get_active_hand() != I)
return
if((!in_range(src, usr) && src.loc != user))
return
t = sanitizeSafe(t, MAX_NAME_LEN)
if(t)
src.name = text("Glass Case - '[]'", t)
else
src.name = "Glass Case"
else if(istype(I, /obj/item/weapon/reagent_containers/syringe))
if(!src.imp) return
if(!src.imp.allow_reagents) return
if(src.imp.reagents.total_volume >= src.imp.reagents.maximum_volume)
to_chat(user, "<span class='warning'>\The [src] is full.</span>")
else
spawn(5)
I.reagents.trans_to_obj(src.imp, 5)
to_chat(user, "<span class='notice'>You inject 5 units of the solution. The syringe now contains [I.reagents.total_volume] units.</span>")
else if (istype(I, /obj/item/weapon/implanter))
var/obj/item/weapon/implanter/M = I
if (M.imp)
if ((src.imp || M.imp.implanted))
return
M.imp.loc = src
src.imp = M.imp
M.imp = null
src.update()
M.update()
else
if (src.imp)
if (M.imp)
return
src.imp.loc = M
M.imp = src.imp
src.imp = null
update()
M.update()
return
/obj/item/weapon/implantcase/tracking
name = "glass case - 'tracking'"
desc = "A case containing a tracking implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/tracking/New()
src.imp = new /obj/item/weapon/implant/tracking( src )
..()
return
/obj/item/weapon/implantcase/explosive
name = "glass case - 'explosive'"
desc = "A case containing an explosive implant."
icon_state = "implantcase-r"
/obj/item/weapon/implantcase/explosive/New()
src.imp = new /obj/item/weapon/implant/explosive( src )
..()
return
/obj/item/weapon/implantcase/chem
name = "glass case - 'chem'"
desc = "A case containing a chemical implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/chem/New()
src.imp = new /obj/item/weapon/implant/chem( src )
..()
return
/obj/item/weapon/implantcase/loyalty
name = "glass case - 'loyalty'"
desc = "A case containing a loyalty implant."
icon_state = "implantcase-r"
/obj/item/weapon/implantcase/loyalty/New()
src.imp = new /obj/item/weapon/implant/loyalty( src )
..()
return
/obj/item/weapon/implantcase/death_alarm
name = "glass case - 'death alarm'"
desc = "A case containing a death alarm implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/death_alarm/New()
src.imp = new /obj/item/weapon/implant/death_alarm( src )
..()
return
/obj/item/weapon/implantcase/freedom
name = "glass case - 'freedom'"
desc = "A case containing a freedom implant."
icon_state = "implantcase-r"
/obj/item/weapon/implantcase/freedom/New()
src.imp = new /obj/item/weapon/implant/freedom( src )
..()
return
/obj/item/weapon/implantcase/adrenalin
name = "glass case - 'adrenalin'"
desc = "A case containing an adrenalin implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/adrenalin/New()
src.imp = new /obj/item/weapon/implant/adrenalin( src )
..()
return
/obj/item/weapon/implantcase/dexplosive
name = "glass case - 'explosive'"
desc = "A case containing an explosive."
icon_state = "implantcase-r"
/obj/item/weapon/implantcase/dexplosive/New()
src.imp = new /obj/item/weapon/implant/dexplosive( src )
..()
return
/obj/item/weapon/implantcase/health
name = "glass case - 'health'"
desc = "A case containing a health tracking implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/health/New()
src.imp = new /obj/item/weapon/implant/health( src )
..()
return
/obj/item/weapon/implantcase/language
name = "glass case - 'GalCom'"
desc = "A case containing a GalCom language implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/language/New()
src.imp = new /obj/item/weapon/implant/language( src )
..()
return
/obj/item/weapon/implantcase/language/eal
name = "glass case - 'EAL'"
desc = "A case containing an Encoded Audio Language implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/language/eal/New()
src.imp = new /obj/item/weapon/implant/language/eal( src )
..()
return
/obj/item/weapon/implantcase/shades
name = "glass case - 'Integrated Shades'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/shades/New()
src.imp = new /obj/item/weapon/implant/organ( src )
..()
return
/obj/item/weapon/implantcase/taser
name = "glass case - 'Taser'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/taser/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment( src )
..()
return
/obj/item/weapon/implantcase/laser
name = "glass case - 'Laser'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/laser/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/laser( src )
..()
return
/obj/item/weapon/implantcase/dart
name = "glass case - 'Dart'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/dart/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/dart( src )
..()
return
/obj/item/weapon/implantcase/toolkit
name = "glass case - 'Toolkit'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/toolkit/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/upperarm( src )
..()
return
/obj/item/weapon/implantcase/medkit
name = "glass case - 'Toolkit'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/medkit/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/upperarm/medkit( src )
..()
return
/obj/item/weapon/implantcase/surge
name = "glass case - 'Muscle Overclocker'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/surge/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/upperarm/surge( src )
..()
return
/obj/item/weapon/implantcase/analyzer
name = "glass case - 'Scanner'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/analyzer/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/wrist( src )
..()
return
/obj/item/weapon/implantcase/sword
name = "glass case - 'Scanner'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/sword/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/wrist/sword( src )
..()
return
/obj/item/weapon/implantcase/sprinter
name = "glass case - 'Sprinter'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/sprinter/New()
src.imp = new /obj/item/weapon/implant/organ/pelvic( src )
..()
return
/obj/item/weapon/implantcase/armblade
name = "glass case - 'Armblade'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/armblade/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/upperarm/blade( src )
..()
return
/obj/item/weapon/implantcase/handblade
name = "glass case - 'Handblade'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/handblade/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/wrist/blade( src )
..()
return
/obj/item/weapon/implantcase/restrainingbolt
name = "glass case - 'Restraining Bolt'"
desc = "A case containing a restraining bolt."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/restrainingbolt/New()
src.imp = new /obj/item/weapon/implant/restrainingbolt( src )
..()
return
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/obj/item/weapon/implantcase
name = "glass case"
desc = "A case containing an implant."
icon = 'icons/obj/items.dmi'
icon_state = "implantcase-0"
item_state = "implantcase"
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_TINY
var/obj/item/weapon/implant/imp = null
/obj/item/weapon/implantcase/proc/update()
if (src.imp)
src.icon_state = text("implantcase-[]", src.imp.implant_color)
else
src.icon_state = "implantcase-0"
return
/obj/item/weapon/implantcase/attackby(obj/item/weapon/I as obj, mob/user as mob)
..()
if (istype(I, /obj/item/weapon/pen))
var/t = tgui_input_text(user, "What would you like the label to be?", text("[]", src.name), null, MAX_NAME_LEN)
if (user.get_active_hand() != I)
return
if((!in_range(src, usr) && src.loc != user))
return
t = sanitizeSafe(t, MAX_NAME_LEN)
if(t)
src.name = text("Glass Case - '[]'", t)
else
src.name = "Glass Case"
else if(istype(I, /obj/item/weapon/reagent_containers/syringe))
if(!src.imp) return
if(!src.imp.allow_reagents) return
if(src.imp.reagents.total_volume >= src.imp.reagents.maximum_volume)
to_chat(user, "<span class='warning'>\The [src] is full.</span>")
else
spawn(5)
I.reagents.trans_to_obj(src.imp, 5)
to_chat(user, "<span class='notice'>You inject 5 units of the solution. The syringe now contains [I.reagents.total_volume] units.</span>")
else if (istype(I, /obj/item/weapon/implanter))
var/obj/item/weapon/implanter/M = I
if (M.imp)
if ((src.imp || M.imp.implanted))
return
M.imp.loc = src
src.imp = M.imp
M.imp = null
src.update()
M.update()
else
if (src.imp)
if (M.imp)
return
src.imp.loc = M
M.imp = src.imp
src.imp = null
update()
M.update()
return
/obj/item/weapon/implantcase/tracking
name = "glass case - 'tracking'"
desc = "A case containing a tracking implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/tracking/New()
src.imp = new /obj/item/weapon/implant/tracking( src )
..()
return
/obj/item/weapon/implantcase/explosive
name = "glass case - 'explosive'"
desc = "A case containing an explosive implant."
icon_state = "implantcase-r"
/obj/item/weapon/implantcase/explosive/New()
src.imp = new /obj/item/weapon/implant/explosive( src )
..()
return
/obj/item/weapon/implantcase/chem
name = "glass case - 'chem'"
desc = "A case containing a chemical implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/chem/New()
src.imp = new /obj/item/weapon/implant/chem( src )
..()
return
/obj/item/weapon/implantcase/loyalty
name = "glass case - 'loyalty'"
desc = "A case containing a loyalty implant."
icon_state = "implantcase-r"
/obj/item/weapon/implantcase/loyalty/New()
src.imp = new /obj/item/weapon/implant/loyalty( src )
..()
return
/obj/item/weapon/implantcase/death_alarm
name = "glass case - 'death alarm'"
desc = "A case containing a death alarm implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/death_alarm/New()
src.imp = new /obj/item/weapon/implant/death_alarm( src )
..()
return
/obj/item/weapon/implantcase/freedom
name = "glass case - 'freedom'"
desc = "A case containing a freedom implant."
icon_state = "implantcase-r"
/obj/item/weapon/implantcase/freedom/New()
src.imp = new /obj/item/weapon/implant/freedom( src )
..()
return
/obj/item/weapon/implantcase/adrenalin
name = "glass case - 'adrenalin'"
desc = "A case containing an adrenalin implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/adrenalin/New()
src.imp = new /obj/item/weapon/implant/adrenalin( src )
..()
return
/obj/item/weapon/implantcase/dexplosive
name = "glass case - 'explosive'"
desc = "A case containing an explosive."
icon_state = "implantcase-r"
/obj/item/weapon/implantcase/dexplosive/New()
src.imp = new /obj/item/weapon/implant/dexplosive( src )
..()
return
/obj/item/weapon/implantcase/health
name = "glass case - 'health'"
desc = "A case containing a health tracking implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/health/New()
src.imp = new /obj/item/weapon/implant/health( src )
..()
return
/obj/item/weapon/implantcase/language
name = "glass case - 'GalCom'"
desc = "A case containing a GalCom language implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/language/New()
src.imp = new /obj/item/weapon/implant/language( src )
..()
return
/obj/item/weapon/implantcase/language/eal
name = "glass case - 'EAL'"
desc = "A case containing an Encoded Audio Language implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/language/eal/New()
src.imp = new /obj/item/weapon/implant/language/eal( src )
..()
return
/obj/item/weapon/implantcase/shades
name = "glass case - 'Integrated Shades'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/shades/New()
src.imp = new /obj/item/weapon/implant/organ( src )
..()
return
/obj/item/weapon/implantcase/taser
name = "glass case - 'Taser'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/taser/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment( src )
..()
return
/obj/item/weapon/implantcase/laser
name = "glass case - 'Laser'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/laser/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/laser( src )
..()
return
/obj/item/weapon/implantcase/dart
name = "glass case - 'Dart'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/dart/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/dart( src )
..()
return
/obj/item/weapon/implantcase/toolkit
name = "glass case - 'Toolkit'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/toolkit/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/upperarm( src )
..()
return
/obj/item/weapon/implantcase/medkit
name = "glass case - 'Toolkit'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/medkit/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/upperarm/medkit( src )
..()
return
/obj/item/weapon/implantcase/surge
name = "glass case - 'Muscle Overclocker'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/surge/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/upperarm/surge( src )
..()
return
/obj/item/weapon/implantcase/analyzer
name = "glass case - 'Scanner'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/analyzer/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/wrist( src )
..()
return
/obj/item/weapon/implantcase/sword
name = "glass case - 'Scanner'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/sword/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/wrist/sword( src )
..()
return
/obj/item/weapon/implantcase/sprinter
name = "glass case - 'Sprinter'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/sprinter/New()
src.imp = new /obj/item/weapon/implant/organ/pelvic( src )
..()
return
/obj/item/weapon/implantcase/armblade
name = "glass case - 'Armblade'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/armblade/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/upperarm/blade( src )
..()
return
/obj/item/weapon/implantcase/handblade
name = "glass case - 'Handblade'"
desc = "A case containing a nanite fabricator implant."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/handblade/New()
src.imp = new /obj/item/weapon/implant/organ/limbaugment/wrist/blade( src )
..()
return
/obj/item/weapon/implantcase/restrainingbolt
name = "glass case - 'Restraining Bolt'"
desc = "A case containing a restraining bolt."
icon_state = "implantcase-b"
/obj/item/weapon/implantcase/restrainingbolt/New()
src.imp = new /obj/item/weapon/implant/restrainingbolt( src )
..()
return
@@ -1,162 +1,162 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/obj/machinery/implantchair
name = "loyalty implanter"
desc = "Used to implant occupants with loyalty implants."
icon = 'icons/obj/machines/implantchair.dmi'
icon_state = "implantchair"
density = TRUE
opacity = 0
anchored = TRUE
var/ready = 1
var/malfunction = 0
var/list/obj/item/weapon/implant/loyalty/implant_list = list()
var/max_implants = 5
var/injection_cooldown = 600
var/replenish_cooldown = 6000
var/replenishing = 0
var/mob/living/carbon/occupant = null
var/injecting = 0
/obj/machinery/implantchair/New()
..()
add_implants()
/obj/machinery/implantchair/attack_hand(mob/user as mob)
user.set_machine(src)
var/health_text = ""
if(src.occupant)
if(src.occupant.health <= -100)
health_text = "<FONT color=red>Dead</FONT>"
else if(src.occupant.health < 0)
health_text = "<FONT color=red>[round(src.occupant.health,0.1)]</FONT>"
else
health_text = "[round(src.occupant.health,0.1)]"
var/dat ="<B>Implanter Status</B><BR>"
dat +="<B>Current occupant:</B> [src.occupant ? "<BR>Name: [src.occupant]<BR>Health: [health_text]<BR>" : "<FONT color=red>None</FONT>"]<BR>"
dat += "<B>Implants:</B> [src.implant_list.len ? "[implant_list.len]" : "<A href='?src=\ref[src];replenish=1'>Replenish</A>"]<BR>"
if(src.occupant)
dat += "[src.ready ? "<A href='?src=\ref[src];implant=1'>Implant</A>" : "Recharging"]<BR>"
user.set_machine(src)
user << browse(dat, "window=implant")
onclose(user, "implant")
/obj/machinery/implantchair/Topic(href, href_list)
if((get_dist(src, usr) <= 1) || istype(usr, /mob/living/silicon/ai))
if(href_list["implant"])
if(src.occupant)
injecting = 1
go_out()
ready = 0
spawn(injection_cooldown)
ready = 1
if(href_list["replenish"])
ready = 0
spawn(replenish_cooldown)
add_implants()
ready = 1
src.updateUsrDialog()
src.add_fingerprint(usr)
return
/obj/machinery/implantchair/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob)
if(istype(G, /obj/item/weapon/grab))
var/obj/item/weapon/grab/grab = G
if(!ismob(grab.affecting))
return
if(grab.affecting.has_buckled_mobs())
to_chat(user, span("warning", "\The [grab.affecting] has other entities attached to them. Remove them first."))
return
var/mob/M = grab.affecting
if(put_mob(M))
qdel(G)
src.updateUsrDialog()
return
/obj/machinery/implantchair/proc/go_out(var/mob/M)
if(!( src.occupant ))
return
if(M == occupant) // so that the guy inside can't eject himself -Agouri
return
if (src.occupant.client)
src.occupant.client.eye = src.occupant.client.mob
src.occupant.client.perspective = MOB_PERSPECTIVE
src.occupant.loc = src.loc
if(injecting)
implant(src.occupant)
injecting = 0
src.occupant = null
icon_state = "implantchair"
return
/obj/machinery/implantchair/proc/put_mob(mob/living/carbon/M as mob)
if(!iscarbon(M))
to_chat(usr, "<span class='warning'>\The [src] cannot hold this!</span>")
return
if(src.occupant)
to_chat(usr, "<span class='warning'>\The [src] is already occupied!</span>")
return
if(M.client)
M.client.perspective = EYE_PERSPECTIVE
M.client.eye = src
M.stop_pulling()
M.loc = src
src.occupant = M
src.add_fingerprint(usr)
icon_state = "implantchair_on"
return 1
/obj/machinery/implantchair/proc/implant(var/mob/M)
if (!istype(M, /mob/living/carbon))
return
if(!implant_list.len) return
for(var/obj/item/weapon/implant/loyalty/imp in implant_list)
if(!imp) continue
if(istype(imp, /obj/item/weapon/implant/loyalty))
for (var/mob/O in viewers(M, null))
O.show_message("<span class='warning'>\The [M] has been implanted by \the [src].</span>", 1)
if(imp.handle_implant(M, BP_TORSO))
imp.post_implant(M)
implant_list -= imp
break
return
/obj/machinery/implantchair/proc/add_implants()
for(var/i=0, i<src.max_implants, i++)
var/obj/item/weapon/implant/loyalty/I = new /obj/item/weapon/implant/loyalty(src)
implant_list += I
return
/obj/machinery/implantchair/verb/get_out()
set name = "Eject occupant"
set category = "Object"
set src in oview(1)
if(usr.stat != 0)
return
src.go_out(usr)
add_fingerprint(usr)
return
/obj/machinery/implantchair/verb/move_inside()
set name = "Move Inside"
set category = "Object"
set src in oview(1)
if(usr.stat != 0 || stat & (NOPOWER|BROKEN))
return
put_mob(usr)
return
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/obj/machinery/implantchair
name = "loyalty implanter"
desc = "Used to implant occupants with loyalty implants."
icon = 'icons/obj/machines/implantchair.dmi'
icon_state = "implantchair"
density = TRUE
opacity = 0
anchored = TRUE
var/ready = 1
var/malfunction = 0
var/list/obj/item/weapon/implant/loyalty/implant_list = list()
var/max_implants = 5
var/injection_cooldown = 600
var/replenish_cooldown = 6000
var/replenishing = 0
var/mob/living/carbon/occupant = null
var/injecting = 0
/obj/machinery/implantchair/New()
..()
add_implants()
/obj/machinery/implantchair/attack_hand(mob/user as mob)
user.set_machine(src)
var/health_text = ""
if(src.occupant)
if(src.occupant.health <= -100)
health_text = "<FONT color=red>Dead</FONT>"
else if(src.occupant.health < 0)
health_text = "<FONT color=red>[round(src.occupant.health,0.1)]</FONT>"
else
health_text = "[round(src.occupant.health,0.1)]"
var/dat ="<B>Implanter Status</B><BR>"
dat +="<B>Current occupant:</B> [src.occupant ? "<BR>Name: [src.occupant]<BR>Health: [health_text]<BR>" : "<FONT color=red>None</FONT>"]<BR>"
dat += "<B>Implants:</B> [src.implant_list.len ? "[implant_list.len]" : "<A href='?src=\ref[src];replenish=1'>Replenish</A>"]<BR>"
if(src.occupant)
dat += "[src.ready ? "<A href='?src=\ref[src];implant=1'>Implant</A>" : "Recharging"]<BR>"
user.set_machine(src)
user << browse(dat, "window=implant")
onclose(user, "implant")
/obj/machinery/implantchair/Topic(href, href_list)
if((get_dist(src, usr) <= 1) || istype(usr, /mob/living/silicon/ai))
if(href_list["implant"])
if(src.occupant)
injecting = 1
go_out()
ready = 0
spawn(injection_cooldown)
ready = 1
if(href_list["replenish"])
ready = 0
spawn(replenish_cooldown)
add_implants()
ready = 1
src.updateUsrDialog()
src.add_fingerprint(usr)
return
/obj/machinery/implantchair/attackby(var/obj/item/weapon/G as obj, var/mob/user as mob)
if(istype(G, /obj/item/weapon/grab))
var/obj/item/weapon/grab/grab = G
if(!ismob(grab.affecting))
return
if(grab.affecting.has_buckled_mobs())
to_chat(user, span("warning", "\The [grab.affecting] has other entities attached to them. Remove them first."))
return
var/mob/M = grab.affecting
if(put_mob(M))
qdel(G)
src.updateUsrDialog()
return
/obj/machinery/implantchair/proc/go_out(var/mob/M)
if(!( src.occupant ))
return
if(M == occupant) // so that the guy inside can't eject himself -Agouri
return
if (src.occupant.client)
src.occupant.client.eye = src.occupant.client.mob
src.occupant.client.perspective = MOB_PERSPECTIVE
src.occupant.loc = src.loc
if(injecting)
implant(src.occupant)
injecting = 0
src.occupant = null
icon_state = "implantchair"
return
/obj/machinery/implantchair/proc/put_mob(mob/living/carbon/M as mob)
if(!iscarbon(M))
to_chat(usr, "<span class='warning'>\The [src] cannot hold this!</span>")
return
if(src.occupant)
to_chat(usr, "<span class='warning'>\The [src] is already occupied!</span>")
return
if(M.client)
M.client.perspective = EYE_PERSPECTIVE
M.client.eye = src
M.stop_pulling()
M.loc = src
src.occupant = M
src.add_fingerprint(usr)
icon_state = "implantchair_on"
return 1
/obj/machinery/implantchair/proc/implant(var/mob/M)
if (!istype(M, /mob/living/carbon))
return
if(!implant_list.len) return
for(var/obj/item/weapon/implant/loyalty/imp in implant_list)
if(!imp) continue
if(istype(imp, /obj/item/weapon/implant/loyalty))
for (var/mob/O in viewers(M, null))
O.show_message("<span class='warning'>\The [M] has been implanted by \the [src].</span>", 1)
if(imp.handle_implant(M, BP_TORSO))
imp.post_implant(M)
implant_list -= imp
break
return
/obj/machinery/implantchair/proc/add_implants()
for(var/i=0, i<src.max_implants, i++)
var/obj/item/weapon/implant/loyalty/I = new /obj/item/weapon/implant/loyalty(src)
implant_list += I
return
/obj/machinery/implantchair/verb/get_out()
set name = "Eject occupant"
set category = "Object"
set src in oview(1)
if(usr.stat != 0)
return
src.go_out(usr)
add_fingerprint(usr)
return
/obj/machinery/implantchair/verb/move_inside()
set name = "Move Inside"
set category = "Object"
set src in oview(1)
if(usr.stat != 0 || stat & (NOPOWER|BROKEN))
return
put_mob(usr)
return
@@ -1,165 +1,165 @@
/obj/item/weapon/implanter
name = "implanter"
icon = 'icons/obj/items.dmi'
icon_state = "implanter0_1"
item_state = "syringe_0"
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_SMALL
matter = list(MAT_STEEL = 1000, MAT_GLASS = 1000)
var/obj/item/weapon/implant/imp = null
var/active = 1
/obj/item/weapon/implanter/attack_self(var/mob/user)
active = !active
to_chat(user, "<span class='notice'>You [active ? "" : "de"]activate \the [src].</span>")
update()
/obj/item/weapon/implanter/verb/remove_implant()
set category = "Object"
set name = "Remove Implant"
set src in usr
if(!imp)
return
if(istype(usr, /mob))
var/mob/M = usr
imp.loc = get_turf(src)
if(M.get_active_hand() == null)
M.put_in_hands(imp)
to_chat(M, "<span class='notice'>You remove \the [imp] from \the [src].</span>")
name = "implanter"
imp = null
update()
return
/obj/item/weapon/implanter/proc/update()
if (src.imp)
src.icon_state = "implanter1"
else
src.icon_state = "implanter0"
src.icon_state += "_[active]"
return
/obj/item/weapon/implanter/attack(mob/M as mob, mob/user as mob)
if (!istype(M, /mob/living/carbon))
return
if(active)
if (imp)
M.visible_message("<span class='warning'>[user] is attempting to implant [M].</span>")
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
user.do_attack_animation(M)
var/turf/T1 = get_turf(M)
if (T1 && ((M == user) || do_after(user, 50)))
if(user && M && (get_turf(M) == T1) && src && src.imp)
M.visible_message("<span class='warning'>[M] has been implanted by [user].</span>")
add_attack_logs(user,M,"Implanted with [imp.name] using [name]")
if(imp.handle_implant(M))
imp.post_implant(M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
BITSET(H.hud_updateflag, IMPLOYAL_HUD)
BITSET(H.hud_updateflag, BACKUP_HUD) //VOREStation Add - Backup HUD updates
src.imp = null
update()
else
to_chat(user, "<span class='warning'>You need to activate \the [src.name] first.</span>")
return
/obj/item/weapon/implanter/loyalty
name = "implanter-loyalty"
/obj/item/weapon/implanter/loyalty/New()
src.imp = new /obj/item/weapon/implant/loyalty( src )
..()
update()
return
/obj/item/weapon/implanter/explosive
name = "implanter (E)"
/obj/item/weapon/implanter/explosive/New()
src.imp = new /obj/item/weapon/implant/explosive( src )
..()
update()
return
/obj/item/weapon/implanter/adrenalin
name = "implanter-adrenalin"
/obj/item/weapon/implanter/adrenalin/New()
src.imp = new /obj/item/weapon/implant/adrenalin(src)
..()
update()
return
/obj/item/weapon/implanter/compressed
name = "implanter (C)"
icon_state = "cimplanter1"
/obj/item/weapon/implanter/compressed/New()
imp = new /obj/item/weapon/implant/compressed( src )
..()
update()
return
/obj/item/weapon/implanter/compressed/update()
if (imp)
var/obj/item/weapon/implant/compressed/c = imp
if(!c.scanned)
icon_state = "cimplanter1"
else
icon_state = "cimplanter2"
else
icon_state = "cimplanter0"
return
/obj/item/weapon/implanter/compressed/attack(mob/M as mob, mob/user as mob)
var/obj/item/weapon/implant/compressed/c = imp
if (!c) return
if (c.scanned == null)
to_chat(user, "Please scan an object with the implanter first.")
return
..()
/obj/item/weapon/implanter/compressed/afterattack(atom/A, mob/user as mob, proximity)
if(!proximity)
return
if(!active)
to_chat(user, "<span class='warning'>Activate \the [src.name] first.</span>")
return
if(istype(A,/obj/item) && imp)
var/obj/item/weapon/implant/compressed/c = imp
if (c.scanned)
to_chat(user, "<span class='warning'>Something is already scanned inside the implant!</span>")
return
c.scanned = A
if(istype(A, /obj/item/weapon/storage))
to_chat(user, "<span class='warning'>You can't store \the [A.name] in this!</span>")
c.scanned = null
return
if(istype(A.loc,/mob/living/carbon/human))
var/mob/living/carbon/human/H = A.loc
H.remove_from_mob(A)
else if(istype(A.loc,/obj/item/weapon/storage))
var/obj/item/weapon/storage/S = A.loc
S.remove_from_storage(A)
A.loc.contents.Remove(A)
update()
/obj/item/weapon/implanter/restrainingbolt
name = "implanter (bolt)"
/obj/item/weapon/implanter/restrainingbolt/New()
src.imp = new /obj/item/weapon/implant/restrainingbolt( src )
..()
update()
return
/obj/item/weapon/implanter
name = "implanter"
icon = 'icons/obj/items.dmi'
icon_state = "implanter0_1"
item_state = "syringe_0"
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_SMALL
matter = list(MAT_STEEL = 1000, MAT_GLASS = 1000)
var/obj/item/weapon/implant/imp = null
var/active = 1
/obj/item/weapon/implanter/attack_self(var/mob/user)
active = !active
to_chat(user, "<span class='notice'>You [active ? "" : "de"]activate \the [src].</span>")
update()
/obj/item/weapon/implanter/verb/remove_implant()
set category = "Object"
set name = "Remove Implant"
set src in usr
if(!imp)
return
if(istype(usr, /mob))
var/mob/M = usr
imp.loc = get_turf(src)
if(M.get_active_hand() == null)
M.put_in_hands(imp)
to_chat(M, "<span class='notice'>You remove \the [imp] from \the [src].</span>")
name = "implanter"
imp = null
update()
return
/obj/item/weapon/implanter/proc/update()
if (src.imp)
src.icon_state = "implanter1"
else
src.icon_state = "implanter0"
src.icon_state += "_[active]"
return
/obj/item/weapon/implanter/attack(mob/M as mob, mob/user as mob)
if (!istype(M, /mob/living/carbon))
return
if(active)
if (imp)
M.visible_message("<span class='warning'>[user] is attempting to implant [M].</span>")
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN)
user.do_attack_animation(M)
var/turf/T1 = get_turf(M)
if (T1 && ((M == user) || do_after(user, 50)))
if(user && M && (get_turf(M) == T1) && src && src.imp)
M.visible_message("<span class='warning'>[M] has been implanted by [user].</span>")
add_attack_logs(user,M,"Implanted with [imp.name] using [name]")
if(imp.handle_implant(M))
imp.post_implant(M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
BITSET(H.hud_updateflag, IMPLOYAL_HUD)
BITSET(H.hud_updateflag, BACKUP_HUD) //VOREStation Add - Backup HUD updates
src.imp = null
update()
else
to_chat(user, "<span class='warning'>You need to activate \the [src.name] first.</span>")
return
/obj/item/weapon/implanter/loyalty
name = "implanter-loyalty"
/obj/item/weapon/implanter/loyalty/New()
src.imp = new /obj/item/weapon/implant/loyalty( src )
..()
update()
return
/obj/item/weapon/implanter/explosive
name = "implanter (E)"
/obj/item/weapon/implanter/explosive/New()
src.imp = new /obj/item/weapon/implant/explosive( src )
..()
update()
return
/obj/item/weapon/implanter/adrenalin
name = "implanter-adrenalin"
/obj/item/weapon/implanter/adrenalin/New()
src.imp = new /obj/item/weapon/implant/adrenalin(src)
..()
update()
return
/obj/item/weapon/implanter/compressed
name = "implanter (C)"
icon_state = "cimplanter1"
/obj/item/weapon/implanter/compressed/New()
imp = new /obj/item/weapon/implant/compressed( src )
..()
update()
return
/obj/item/weapon/implanter/compressed/update()
if (imp)
var/obj/item/weapon/implant/compressed/c = imp
if(!c.scanned)
icon_state = "cimplanter1"
else
icon_state = "cimplanter2"
else
icon_state = "cimplanter0"
return
/obj/item/weapon/implanter/compressed/attack(mob/M as mob, mob/user as mob)
var/obj/item/weapon/implant/compressed/c = imp
if (!c) return
if (c.scanned == null)
to_chat(user, "Please scan an object with the implanter first.")
return
..()
/obj/item/weapon/implanter/compressed/afterattack(atom/A, mob/user as mob, proximity)
if(!proximity)
return
if(!active)
to_chat(user, "<span class='warning'>Activate \the [src.name] first.</span>")
return
if(istype(A,/obj/item) && imp)
var/obj/item/weapon/implant/compressed/c = imp
if (c.scanned)
to_chat(user, "<span class='warning'>Something is already scanned inside the implant!</span>")
return
c.scanned = A
if(istype(A, /obj/item/weapon/storage))
to_chat(user, "<span class='warning'>You can't store \the [A.name] in this!</span>")
c.scanned = null
return
if(istype(A.loc,/mob/living/carbon/human))
var/mob/living/carbon/human/H = A.loc
H.remove_from_mob(A)
else if(istype(A.loc,/obj/item/weapon/storage))
var/obj/item/weapon/storage/S = A.loc
S.remove_from_storage(A)
A.loc.contents.Remove(A)
update()
/obj/item/weapon/implanter/restrainingbolt
name = "implanter (bolt)"
/obj/item/weapon/implanter/restrainingbolt/New()
src.imp = new /obj/item/weapon/implant/restrainingbolt( src )
..()
update()
return
@@ -1,70 +1,70 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/obj/item/weapon/implant/freedom
name = "freedom implant"
desc = "Use this to escape from those evil Red Shirts."
implant_color = "r"
var/activation_emote = "chuckle"
var/uses = 1.0
/obj/item/weapon/implant/freedom/New()
src.activation_emote = pick("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
src.uses = rand(1, 5)
..()
return
/obj/item/weapon/implant/freedom/trigger(emote, mob/living/carbon/source as mob)
if (src.uses < 1)
return 0
if (emote == src.activation_emote)
src.uses--
to_chat(source, "You feel a faint click.")
if (source.handcuffed)
var/obj/item/weapon/W = source.handcuffed
source.handcuffed = null
if(source.buckled && source.buckled.buckle_require_restraints)
source.buckled.unbuckle_mob()
source.update_handcuffed()
if (source.client)
source.client.screen -= W
if (W)
W.loc = source.loc
dropped(source)
if (W)
W.layer = initial(W.layer)
if (source.legcuffed)
var/obj/item/weapon/W = source.legcuffed
source.legcuffed = null
source.update_inv_legcuffed()
if (source.client)
source.client.screen -= W
if (W)
W.loc = source.loc
dropped(source)
if (W)
W.layer = initial(W.layer)
return
/obj/item/weapon/implant/freedom/post_implant(mob/source)
source.mind.store_memory("Freedom implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.", 0, 0)
to_chat(source, "The implanted freedom implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.")
/obj/item/weapon/implant/freedom/get_data()
var/dat = {"
<b>Implant Specifications:</b><BR>
<b>Name:</b> Freedom Beacon<BR>
<b>Life:</b> optimum 5 uses<BR>
<b>Important Notes:</b> <font color='red'>Illegal</font><BR>
<HR>
<b>Implant Details:</b> <BR>
<b>Function:</b> Transmits a specialized cluster of signals to override handcuff locking
mechanisms<BR>
<b>Special Features:</b><BR>
<i>Neuro-Scan</i>- Analyzes certain shadow signals in the nervous system<BR>
<b>Integrity:</b> The battery is extremely weak and commonly after injection its
life can drive down to only 1 use.<HR>
No Implant Specifics"}
return dat
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/obj/item/weapon/implant/freedom
name = "freedom implant"
desc = "Use this to escape from those evil Red Shirts."
implant_color = "r"
var/activation_emote = "chuckle"
var/uses = 1.0
/obj/item/weapon/implant/freedom/New()
src.activation_emote = pick("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
src.uses = rand(1, 5)
..()
return
/obj/item/weapon/implant/freedom/trigger(emote, mob/living/carbon/source as mob)
if (src.uses < 1)
return 0
if (emote == src.activation_emote)
src.uses--
to_chat(source, "You feel a faint click.")
if (source.handcuffed)
var/obj/item/weapon/W = source.handcuffed
source.handcuffed = null
if(source.buckled && source.buckled.buckle_require_restraints)
source.buckled.unbuckle_mob()
source.update_handcuffed()
if (source.client)
source.client.screen -= W
if (W)
W.loc = source.loc
dropped(source)
if (W)
W.layer = initial(W.layer)
if (source.legcuffed)
var/obj/item/weapon/W = source.legcuffed
source.legcuffed = null
source.update_inv_legcuffed()
if (source.client)
source.client.screen -= W
if (W)
W.loc = source.loc
dropped(source)
if (W)
W.layer = initial(W.layer)
return
/obj/item/weapon/implant/freedom/post_implant(mob/source)
source.mind.store_memory("Freedom implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.", 0, 0)
to_chat(source, "The implanted freedom implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.")
/obj/item/weapon/implant/freedom/get_data()
var/dat = {"
<b>Implant Specifications:</b><BR>
<b>Name:</b> Freedom Beacon<BR>
<b>Life:</b> optimum 5 uses<BR>
<b>Important Notes:</b> <font color='red'>Illegal</font><BR>
<HR>
<b>Implant Details:</b> <BR>
<b>Function:</b> Transmits a specialized cluster of signals to override handcuff locking
mechanisms<BR>
<b>Special Features:</b><BR>
<i>Neuro-Scan</i>- Analyzes certain shadow signals in the nervous system<BR>
<b>Integrity:</b> The battery is extremely weak and commonly after injection its
life can drive down to only 1 use.<HR>
No Implant Specifics"}
return dat
@@ -1,94 +1,94 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/obj/item/weapon/implantpad
name = "implantpad"
desc = "Used to modify implants."
icon = 'icons/obj/items.dmi'
icon_state = "implantpad-0"
item_state = "electronic"
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_SMALL
var/obj/item/weapon/implantcase/case = null
var/broadcasting = null
var/listening = 1.0
/obj/item/weapon/implantpad/proc/update()
if (src.case)
src.icon_state = "implantpad-1"
else
src.icon_state = "implantpad-0"
return
/obj/item/weapon/implantpad/attack_hand(mob/living/user as mob)
if ((src.case && user.item_is_in_hands(src)))
user.put_in_active_hand(case)
src.case.add_fingerprint(user)
src.case = null
src.add_fingerprint(user)
update()
else
return ..()
return
/obj/item/weapon/implantpad/attackby(obj/item/weapon/implantcase/C as obj, mob/user as mob)
..()
if(istype(C, /obj/item/weapon/implantcase))
if(!( src.case ))
user.drop_item()
C.loc = src
src.case = C
else
return
src.update()
return
/obj/item/weapon/implantpad/attack_self(mob/user as mob)
user.set_machine(src)
var/dat = "<B>Implant Mini-Computer:</B><HR>"
if (src.case)
if(src.case.imp)
if(istype(src.case.imp, /obj/item/weapon/implant))
dat += src.case.imp.get_data()
if(istype(src.case.imp, /obj/item/weapon/implant/tracking))
dat += {"ID (1-100):
<A href='byond://?src=\ref[src];tracking_id=-10'>-</A>
<A href='byond://?src=\ref[src];tracking_id=-1'>-</A> [case.imp:id]
<A href='byond://?src=\ref[src];tracking_id=1'>+</A>
<A href='byond://?src=\ref[src];tracking_id=10'>+</A><BR>"}
else
dat += "The implant casing is empty."
else
dat += "Please insert an implant casing!"
user << browse(dat, "window=implantpad")
onclose(user, "implantpad")
return
/obj/item/weapon/implantpad/Topic(href, href_list)
..()
if (usr.stat)
return
if ((usr.contents.Find(src)) || ((in_range(src, usr) && istype(src.loc, /turf))))
usr.set_machine(src)
if (href_list["tracking_id"])
var/obj/item/weapon/implant/tracking/T = src.case.imp
T.id += text2num(href_list["tracking_id"])
T.id = min(1000, T.id)
T.id = max(1, T.id)
if (istype(src.loc, /mob))
attack_self(src.loc)
else
for(var/mob/M in viewers(1, src))
if (M.client)
src.attack_self(M)
src.add_fingerprint(usr)
else
usr << browse(null, "window=implantpad")
return
return
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
/obj/item/weapon/implantpad
name = "implantpad"
desc = "Used to modify implants."
icon = 'icons/obj/items.dmi'
icon_state = "implantpad-0"
item_state = "electronic"
throw_speed = 1
throw_range = 5
w_class = ITEMSIZE_SMALL
var/obj/item/weapon/implantcase/case = null
var/broadcasting = null
var/listening = 1.0
/obj/item/weapon/implantpad/proc/update()
if (src.case)
src.icon_state = "implantpad-1"
else
src.icon_state = "implantpad-0"
return
/obj/item/weapon/implantpad/attack_hand(mob/living/user as mob)
if ((src.case && user.item_is_in_hands(src)))
user.put_in_active_hand(case)
src.case.add_fingerprint(user)
src.case = null
src.add_fingerprint(user)
update()
else
return ..()
return
/obj/item/weapon/implantpad/attackby(obj/item/weapon/implantcase/C as obj, mob/user as mob)
..()
if(istype(C, /obj/item/weapon/implantcase))
if(!( src.case ))
user.drop_item()
C.loc = src
src.case = C
else
return
src.update()
return
/obj/item/weapon/implantpad/attack_self(mob/user as mob)
user.set_machine(src)
var/dat = "<B>Implant Mini-Computer:</B><HR>"
if (src.case)
if(src.case.imp)
if(istype(src.case.imp, /obj/item/weapon/implant))
dat += src.case.imp.get_data()
if(istype(src.case.imp, /obj/item/weapon/implant/tracking))
dat += {"ID (1-100):
<A href='byond://?src=\ref[src];tracking_id=-10'>-</A>
<A href='byond://?src=\ref[src];tracking_id=-1'>-</A> [case.imp:id]
<A href='byond://?src=\ref[src];tracking_id=1'>+</A>
<A href='byond://?src=\ref[src];tracking_id=10'>+</A><BR>"}
else
dat += "The implant casing is empty."
else
dat += "Please insert an implant casing!"
user << browse(dat, "window=implantpad")
onclose(user, "implantpad")
return
/obj/item/weapon/implantpad/Topic(href, href_list)
..()
if (usr.stat)
return
if ((usr.contents.Find(src)) || ((in_range(src, usr) && istype(src.loc, /turf))))
usr.set_machine(src)
if (href_list["tracking_id"])
var/obj/item/weapon/implant/tracking/T = src.case.imp
T.id += text2num(href_list["tracking_id"])
T.id = min(1000, T.id)
T.id = max(1, T.id)
if (istype(src.loc, /mob))
attack_self(src.loc)
else
for(var/mob/M in viewers(1, src))
if (M.client)
src.attack_self(M)
src.add_fingerprint(usr)
else
usr << browse(null, "window=implantpad")
return
return
@@ -1,25 +1,25 @@
/obj/item/weapon/implant/uplink
name = "uplink"
desc = "Summon things."
var/activation_emote = "chuckle"
/obj/item/weapon/implant/uplink/New()
activation_emote = pick("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
hidden_uplink = new(src)
//hidden_uplink.uses = 5
//Code currently uses a mind var for telecrystals, balancing is currently an issue. Will investigate.
..()
return
/obj/item/weapon/implant/uplink/post_implant(mob/source)
var/choices = list("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
activation_emote = tgui_input_list(usr, "Choose activation emote. If you cancel this, one will be picked at random.", "Implant Activation", choices)
if(!activation_emote)
activation_emote = pick(choices)
source.mind.store_memory("Uplink implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.", 0, 0)
to_chat(source, "The implanted uplink implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.")
/obj/item/weapon/implant/uplink/trigger(emote, mob/source as mob)
if(hidden_uplink && usr == source) // Let's not have another people activate our uplink
hidden_uplink.check_trigger(source, emote, activation_emote)
/obj/item/weapon/implant/uplink
name = "uplink"
desc = "Summon things."
var/activation_emote = "chuckle"
/obj/item/weapon/implant/uplink/New()
activation_emote = pick("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
hidden_uplink = new(src)
//hidden_uplink.uses = 5
//Code currently uses a mind var for telecrystals, balancing is currently an issue. Will investigate.
..()
return
/obj/item/weapon/implant/uplink/post_implant(mob/source)
var/choices = list("blink", "blink_r", "eyebrow", "chuckle", "twitch", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
activation_emote = tgui_input_list(usr, "Choose activation emote. If you cancel this, one will be picked at random.", "Implant Activation", choices)
if(!activation_emote)
activation_emote = pick(choices)
source.mind.store_memory("Uplink implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.", 0, 0)
to_chat(source, "The implanted uplink implant can be activated by using the [src.activation_emote] emote, <B>say *[src.activation_emote]</B> to attempt to activate.")
/obj/item/weapon/implant/uplink/trigger(emote, mob/source as mob)
if(hidden_uplink && usr == source) // Let's not have another people activate our uplink
hidden_uplink.check_trigger(source, emote, activation_emote)
return
@@ -1,40 +1,40 @@
/obj/item/weapon/material/butterflyconstruction
name = "unfinished concealed knife"
desc = "An unfinished concealed knife, it looks like the screws need to be tightened."
icon = 'icons/obj/buildingobject.dmi'
icon_state = "butterflystep1"
force_divisor = 0.1
thrown_force_divisor = 0.1
/obj/item/weapon/material/butterflyconstruction/attackby(obj/item/W as obj, mob/user as mob)
if(W.has_tool_quality(TOOL_SCREWDRIVER))
to_chat(user, "You finish the concealed blade weapon.")
playsound(src, W.usesound, 50, 1)
new /obj/item/weapon/material/butterfly(user.loc, material.name)
qdel(src)
return
/obj/item/weapon/material/butterflyblade
name = "knife blade"
desc = "A knife blade. Unusable as a weapon without a grip."
icon = 'icons/obj/buildingobject.dmi'
icon_state = "butterfly2"
force_divisor = 0.1
thrown_force_divisor = 0.1
/obj/item/weapon/material/butterflyhandle
name = "concealed knife grip"
desc = "A plasteel grip with screw fittings for a blade."
icon = 'icons/obj/buildingobject.dmi'
icon_state = "butterfly1"
force_divisor = 0.1
thrown_force_divisor = 0.1
/obj/item/weapon/material/butterflyhandle/attackby(obj/item/W as obj, mob/user as mob)
if(istype(W,/obj/item/weapon/material/butterflyblade))
var/obj/item/weapon/material/butterflyblade/B = W
to_chat(user, "You attach the two concealed blade parts.")
new /obj/item/weapon/material/butterflyconstruction(user.loc, B.material.name)
qdel(W)
qdel(src)
return
/obj/item/weapon/material/butterflyconstruction
name = "unfinished concealed knife"
desc = "An unfinished concealed knife, it looks like the screws need to be tightened."
icon = 'icons/obj/buildingobject.dmi'
icon_state = "butterflystep1"
force_divisor = 0.1
thrown_force_divisor = 0.1
/obj/item/weapon/material/butterflyconstruction/attackby(obj/item/W as obj, mob/user as mob)
if(W.has_tool_quality(TOOL_SCREWDRIVER))
to_chat(user, "You finish the concealed blade weapon.")
playsound(src, W.usesound, 50, 1)
new /obj/item/weapon/material/butterfly(user.loc, material.name)
qdel(src)
return
/obj/item/weapon/material/butterflyblade
name = "knife blade"
desc = "A knife blade. Unusable as a weapon without a grip."
icon = 'icons/obj/buildingobject.dmi'
icon_state = "butterfly2"
force_divisor = 0.1
thrown_force_divisor = 0.1
/obj/item/weapon/material/butterflyhandle
name = "concealed knife grip"
desc = "A plasteel grip with screw fittings for a blade."
icon = 'icons/obj/buildingobject.dmi'
icon_state = "butterfly1"
force_divisor = 0.1
thrown_force_divisor = 0.1
/obj/item/weapon/material/butterflyhandle/attackby(obj/item/W as obj, mob/user as mob)
if(istype(W,/obj/item/weapon/material/butterflyblade))
var/obj/item/weapon/material/butterflyblade/B = W
to_chat(user, "You attach the two concealed blade parts.")
new /obj/item/weapon/material/butterflyconstruction(user.loc, B.material.name)
qdel(W)
qdel(src)
return
File diff suppressed because it is too large Load Diff
@@ -1,29 +1,29 @@
/obj/item/weapon/material/twohanded/baseballbat
name = "bat"
desc = "HOME RUN!"
icon_state = "metalbat0"
base_icon = "metalbat"
throwforce = 7
attack_verb = list("smashed", "beaten", "slammed", "smacked", "struck", "battered", "bonked")
hitsound = 'sound/weapons/genhit3.ogg'
default_material = "wood"
force_divisor = 1.1 // 22 when wielded with weight 20 (steel)
unwielded_force_divisor = 0.7 // 15 when unwielded based on above.
dulled_divisor = 0.75 // A "dull" bat is still gonna hurt
slot_flags = SLOT_BACK
//Predefined materials go here.
/obj/item/weapon/material/twohanded/baseballbat/metal/New(var/newloc)
..(newloc,"steel")
/obj/item/weapon/material/twohanded/baseballbat/uranium/New(var/newloc)
..(newloc,"uranium")
/obj/item/weapon/material/twohanded/baseballbat/gold/New(var/newloc)
..(newloc,"gold")
/obj/item/weapon/material/twohanded/baseballbat/platinum/New(var/newloc)
..(newloc,"platinum")
/obj/item/weapon/material/twohanded/baseballbat/diamond/New(var/newloc)
/obj/item/weapon/material/twohanded/baseballbat
name = "bat"
desc = "HOME RUN!"
icon_state = "metalbat0"
base_icon = "metalbat"
throwforce = 7
attack_verb = list("smashed", "beaten", "slammed", "smacked", "struck", "battered", "bonked")
hitsound = 'sound/weapons/genhit3.ogg'
default_material = "wood"
force_divisor = 1.1 // 22 when wielded with weight 20 (steel)
unwielded_force_divisor = 0.7 // 15 when unwielded based on above.
dulled_divisor = 0.75 // A "dull" bat is still gonna hurt
slot_flags = SLOT_BACK
//Predefined materials go here.
/obj/item/weapon/material/twohanded/baseballbat/metal/New(var/newloc)
..(newloc,"steel")
/obj/item/weapon/material/twohanded/baseballbat/uranium/New(var/newloc)
..(newloc,"uranium")
/obj/item/weapon/material/twohanded/baseballbat/gold/New(var/newloc)
..(newloc,"gold")
/obj/item/weapon/material/twohanded/baseballbat/platinum/New(var/newloc)
..(newloc,"platinum")
/obj/item/weapon/material/twohanded/baseballbat/diamond/New(var/newloc)
..(newloc,"diamond")
@@ -1,217 +1,217 @@
/obj/item/weapon/material/kitchen
icon = 'icons/obj/kitchen.dmi'
/*
* Utensils
*/
/obj/item/weapon/material/kitchen/utensil
drop_sound = 'sound/items/drop/knife.ogg'
pickup_sound = 'sound/items/pickup/knife.ogg'
w_class = ITEMSIZE_TINY
thrown_force_divisor = 1
origin_tech = list(TECH_MATERIAL = 1)
attack_verb = list("attacked", "stabbed", "poked")
sharp = TRUE
edge = TRUE
force_divisor = 0.1 // 6 when wielded with hardness 60 (steel)
thrown_force_divisor = 0.25 // 5 when thrown with weight 20 (steel)
var/scoop_volume = 5
var/loaded // Name for currently loaded food object.
var/loaded_color // Color for currently loaded food object.
var/list/food_inserted_micros
/obj/item/weapon/material/kitchen/utensil/Initialize()
. = ..()
if (prob(60))
src.pixel_y = rand(0, 4)
create_reagents(scoop_volume)
/obj/item/weapon/material/kitchen/utensil/Destroy()
if(food_inserted_micros)
for(var/mob/M in food_inserted_micros)
M.dropInto(loc)
food_inserted_micros -= M
. = ..()
return
/obj/item/weapon/material/kitchen/utensil/update_icon()
. = ..()
cut_overlays()
if(loaded)
var/image/I = new(icon, "loadedfood")
I.color = loaded_color
add_overlay(I)
/obj/item/weapon/material/kitchen/utensil/proc/load_food(var/mob/user, var/obj/item/weapon/reagent_containers/food/snacks/loading)
if (reagents.total_volume > 0)
to_chat(user, SPAN_DANGER("There is already something on \the [src]."))
return
if (!loading?.reagents?.total_volume)
to_chat(user, SPAN_NOTICE("Nothing to scoop up in \the [loading]!"))
loaded = "\the [loading]"
user.visible_message( \
"<b>\The [user]</b> scoops up some of [loaded] with \the [src]!",
SPAN_NOTICE("You scoop up some of [loaded] with \the [src]!")
)
loading.bitecount++
loading.reagents.trans_to_obj(src, min(loading.reagents.total_volume, scoop_volume))
loaded_color = loading.filling_color
if(loading.food_inserted_micros && loading.food_inserted_micros.len)
if(!food_inserted_micros)
food_inserted_micros = list()
for(var/mob/living/F in loading.food_inserted_micros)
var/do_transfer = FALSE
if(!loading.reagents.total_volume)
do_transfer = TRUE
else
var/transfer_chance = (loading.bitecount/(loading.bitecount + (loading.bitesize / loading.reagents.total_volume) + 1))*100
if(prob(transfer_chance))
do_transfer = TRUE
if(do_transfer)
F.forceMove(src)
loading.food_inserted_micros -= F
src.food_inserted_micros += F
if (loading.reagents.total_volume <= 0)
qdel(loading)
update_icon()
/obj/item/weapon/material/kitchen/utensil/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(!istype(M))
return ..()
if(user.a_intent != I_HELP)
if(user.zone_sel.selecting == BP_HEAD || user.zone_sel.selecting == O_EYES)
if((CLUMSY in user.mutations) && prob(50))
M = user
return eyestab(M,user)
else
return ..()
if (loaded && reagents.total_volume > 0)
reagents.trans_to_mob(M, reagents.total_volume, CHEM_INGEST)
if(food_inserted_micros && food_inserted_micros.len)
for(var/mob/living/F in food_inserted_micros)
food_inserted_micros -= F
if(!F.can_be_drop_prey || !F.food_vore)
F.forceMove(get_turf(src))
else
F.forceMove(M.vore_selected)
if(M == user)
if(!M.can_eat(loaded))
return
M.visible_message("<b>\The [user]</b> eats some of [loaded] with \the [src].")
else
user.visible_message(SPAN_WARNING("\The [user] begins to feed \the [M]!"))
if(!(M.can_force_feed(user, loaded) && do_mob(user, M, 5 SECONDS)))
return
M.visible_message("<b>\The [user]</b> feeds some of [loaded] to \the [M] with \the [src].")
playsound(src,'sound/items/eatfood.ogg', rand(10,40), 1)
loaded = null
update_icon()
return
else
to_chat(user, SPAN_WARNING("You don't have anything on \the [src].")) //if we have help intent and no food scooped up DON'T STAB OURSELVES WITH THE FORK
return
/obj/item/weapon/material/kitchen/utensil/on_rag_wipe()
. = ..()
if(reagents.total_volume > 0)
reagents.clear_reagents()
cut_overlays()
return
/obj/item/weapon/material/kitchen/utensil/container_resist(mob/living/M)
if(food_inserted_micros)
food_inserted_micros -= M
M.forceMove(get_turf(src))
to_chat(M, "<span class='warning'>You climb off of \the [src].</span>")
/obj/item/weapon/material/kitchen/utensil/fork
name = "fork"
desc = "It's a fork. Sure is pointy."
icon_state = "fork"
sharp = TRUE
edge = FALSE
/obj/item/weapon/material/kitchen/utensil/fork/plastic
default_material = "plastic"
/obj/item/weapon/material/kitchen/utensil/foon
name = "foon"
desc = "It's a foon. The forgotten cousin of the spork."
icon_state = "foon"
sharp = TRUE
edge = FALSE
/obj/item/weapon/material/kitchen/utensil/foon/plastic
default_material = "plastic"
/obj/item/weapon/material/kitchen/utensil/spork
name = "spork"
desc = "It's a spork. The (un)holy merger of a spoon and fork."
icon_state = "spork"
sharp = TRUE
edge = FALSE
/obj/item/weapon/material/kitchen/utensil/spork/plastic
default_material = "plastic"
/obj/item/weapon/material/kitchen/utensil/spoon
name = "spoon"
desc = "It's a spoon. You can see your own upside-down face in it."
icon_state = "spoon"
attack_verb = list("attacked", "poked")
edge = FALSE
sharp = FALSE
force_divisor = 0.1 //2 when wielded with weight 20 (steel)
/obj/item/weapon/material/kitchen/utensil/spoon/plastic
default_material = "plastic"
/*
* Knives
*/
/* From the time of Clowns. Commented out for posterity, and sanity.
/obj/item/weapon/material/knife/attack(target as mob, mob/living/user as mob)
if ((CLUMSY in user.mutations) && prob(50))
to_chat(user, "<span class='warning'>You accidentally cut yourself with \the [src].</span>")
user.take_organ_damage(20)
return
return ..()
*/
/obj/item/weapon/material/knife/plastic
default_material = "plastic"
/*
* Rolling Pins
*/
/obj/item/weapon/material/kitchen/rollingpin
name = "rolling pin"
desc = "Used to knock out the Bartender."
icon_state = "rolling_pin"
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked")
default_material = "wood"
force_divisor = 0.7 // 10 when wielded with weight 15 (wood)
dulled_divisor = 0.75 // Still a club
thrown_force_divisor = 1 // as above
drop_sound = 'sound/items/drop/wooden.ogg'
pickup_sound = 'sound/items/pickup/wooden.ogg'
/obj/item/weapon/material/kitchen/rollingpin/attack(mob/living/M as mob, mob/living/user as mob)
if ((CLUMSY in user.mutations) && prob(50))
to_chat(user, "<span class='warning'>\The [src] slips out of your hand and hits your head.</span>")
user.take_organ_damage(10)
user.Paralyse(2)
return
return ..()
/obj/item/weapon/material/kitchen
icon = 'icons/obj/kitchen.dmi'
/*
* Utensils
*/
/obj/item/weapon/material/kitchen/utensil
drop_sound = 'sound/items/drop/knife.ogg'
pickup_sound = 'sound/items/pickup/knife.ogg'
w_class = ITEMSIZE_TINY
thrown_force_divisor = 1
origin_tech = list(TECH_MATERIAL = 1)
attack_verb = list("attacked", "stabbed", "poked")
sharp = TRUE
edge = TRUE
force_divisor = 0.1 // 6 when wielded with hardness 60 (steel)
thrown_force_divisor = 0.25 // 5 when thrown with weight 20 (steel)
var/scoop_volume = 5
var/loaded // Name for currently loaded food object.
var/loaded_color // Color for currently loaded food object.
var/list/food_inserted_micros
/obj/item/weapon/material/kitchen/utensil/Initialize()
. = ..()
if (prob(60))
src.pixel_y = rand(0, 4)
create_reagents(scoop_volume)
/obj/item/weapon/material/kitchen/utensil/Destroy()
if(food_inserted_micros)
for(var/mob/M in food_inserted_micros)
M.dropInto(loc)
food_inserted_micros -= M
. = ..()
return
/obj/item/weapon/material/kitchen/utensil/update_icon()
. = ..()
cut_overlays()
if(loaded)
var/image/I = new(icon, "loadedfood")
I.color = loaded_color
add_overlay(I)
/obj/item/weapon/material/kitchen/utensil/proc/load_food(var/mob/user, var/obj/item/weapon/reagent_containers/food/snacks/loading)
if (reagents.total_volume > 0)
to_chat(user, SPAN_DANGER("There is already something on \the [src]."))
return
if (!loading?.reagents?.total_volume)
to_chat(user, SPAN_NOTICE("Nothing to scoop up in \the [loading]!"))
loaded = "\the [loading]"
user.visible_message( \
"<b>\The [user]</b> scoops up some of [loaded] with \the [src]!",
SPAN_NOTICE("You scoop up some of [loaded] with \the [src]!")
)
loading.bitecount++
loading.reagents.trans_to_obj(src, min(loading.reagents.total_volume, scoop_volume))
loaded_color = loading.filling_color
if(loading.food_inserted_micros && loading.food_inserted_micros.len)
if(!food_inserted_micros)
food_inserted_micros = list()
for(var/mob/living/F in loading.food_inserted_micros)
var/do_transfer = FALSE
if(!loading.reagents.total_volume)
do_transfer = TRUE
else
var/transfer_chance = (loading.bitecount/(loading.bitecount + (loading.bitesize / loading.reagents.total_volume) + 1))*100
if(prob(transfer_chance))
do_transfer = TRUE
if(do_transfer)
F.forceMove(src)
loading.food_inserted_micros -= F
src.food_inserted_micros += F
if (loading.reagents.total_volume <= 0)
qdel(loading)
update_icon()
/obj/item/weapon/material/kitchen/utensil/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(!istype(M))
return ..()
if(user.a_intent != I_HELP)
if(user.zone_sel.selecting == BP_HEAD || user.zone_sel.selecting == O_EYES)
if((CLUMSY in user.mutations) && prob(50))
M = user
return eyestab(M,user)
else
return ..()
if (loaded && reagents.total_volume > 0)
reagents.trans_to_mob(M, reagents.total_volume, CHEM_INGEST)
if(food_inserted_micros && food_inserted_micros.len)
for(var/mob/living/F in food_inserted_micros)
food_inserted_micros -= F
if(!F.can_be_drop_prey || !F.food_vore)
F.forceMove(get_turf(src))
else
F.forceMove(M.vore_selected)
if(M == user)
if(!M.can_eat(loaded))
return
M.visible_message("<b>\The [user]</b> eats some of [loaded] with \the [src].")
else
user.visible_message(SPAN_WARNING("\The [user] begins to feed \the [M]!"))
if(!(M.can_force_feed(user, loaded) && do_mob(user, M, 5 SECONDS)))
return
M.visible_message("<b>\The [user]</b> feeds some of [loaded] to \the [M] with \the [src].")
playsound(src,'sound/items/eatfood.ogg', rand(10,40), 1)
loaded = null
update_icon()
return
else
to_chat(user, SPAN_WARNING("You don't have anything on \the [src].")) //if we have help intent and no food scooped up DON'T STAB OURSELVES WITH THE FORK
return
/obj/item/weapon/material/kitchen/utensil/on_rag_wipe()
. = ..()
if(reagents.total_volume > 0)
reagents.clear_reagents()
cut_overlays()
return
/obj/item/weapon/material/kitchen/utensil/container_resist(mob/living/M)
if(food_inserted_micros)
food_inserted_micros -= M
M.forceMove(get_turf(src))
to_chat(M, "<span class='warning'>You climb off of \the [src].</span>")
/obj/item/weapon/material/kitchen/utensil/fork
name = "fork"
desc = "It's a fork. Sure is pointy."
icon_state = "fork"
sharp = TRUE
edge = FALSE
/obj/item/weapon/material/kitchen/utensil/fork/plastic
default_material = "plastic"
/obj/item/weapon/material/kitchen/utensil/foon
name = "foon"
desc = "It's a foon. The forgotten cousin of the spork."
icon_state = "foon"
sharp = TRUE
edge = FALSE
/obj/item/weapon/material/kitchen/utensil/foon/plastic
default_material = "plastic"
/obj/item/weapon/material/kitchen/utensil/spork
name = "spork"
desc = "It's a spork. The (un)holy merger of a spoon and fork."
icon_state = "spork"
sharp = TRUE
edge = FALSE
/obj/item/weapon/material/kitchen/utensil/spork/plastic
default_material = "plastic"
/obj/item/weapon/material/kitchen/utensil/spoon
name = "spoon"
desc = "It's a spoon. You can see your own upside-down face in it."
icon_state = "spoon"
attack_verb = list("attacked", "poked")
edge = FALSE
sharp = FALSE
force_divisor = 0.1 //2 when wielded with weight 20 (steel)
/obj/item/weapon/material/kitchen/utensil/spoon/plastic
default_material = "plastic"
/*
* Knives
*/
/* From the time of Clowns. Commented out for posterity, and sanity.
/obj/item/weapon/material/knife/attack(target as mob, mob/living/user as mob)
if ((CLUMSY in user.mutations) && prob(50))
to_chat(user, "<span class='warning'>You accidentally cut yourself with \the [src].</span>")
user.take_organ_damage(20)
return
return ..()
*/
/obj/item/weapon/material/knife/plastic
default_material = "plastic"
/*
* Rolling Pins
*/
/obj/item/weapon/material/kitchen/rollingpin
name = "rolling pin"
desc = "Used to knock out the Bartender."
icon_state = "rolling_pin"
attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked")
default_material = "wood"
force_divisor = 0.7 // 10 when wielded with weight 15 (wood)
dulled_divisor = 0.75 // Still a club
thrown_force_divisor = 1 // as above
drop_sound = 'sound/items/drop/wooden.ogg'
pickup_sound = 'sound/items/pickup/wooden.ogg'
/obj/item/weapon/material/kitchen/rollingpin/attack(mob/living/M as mob, mob/living/user as mob)
if ((CLUMSY in user.mutations) && prob(50))
to_chat(user, "<span class='warning'>\The [src] slips out of your hand and hits your head.</span>")
user.take_organ_damage(10)
user.Paralyse(2)
return
return ..()
+187 -187
View File
@@ -1,187 +1,187 @@
/obj/item/weapon/material/butterfly
name = "butterfly knife"
desc = "A basic metal blade concealed in a lightweight plasteel grip. Small enough when folded to fit in a pocket."
description_fluff = "This could be used to engrave messages on suitable surfaces if you really put your mind to it! Alt-click a floor or wall to engrave with it." //This way it's not a completely hidden, arcane art to engrave.
icon_state = "butterflyknife"
item_state = null
hitsound = null
var/active = 0
w_class = ITEMSIZE_SMALL
attack_verb = list("patted", "tapped")
force_divisor = 0.25 // 15 when wielded with hardness 60 (steel)
thrown_force_divisor = 0.25 // 5 when thrown with weight 20 (steel)
drop_sound = 'sound/items/drop/knife.ogg'
pickup_sound = 'sound/items/pickup/knife.ogg'
/obj/item/weapon/material/butterfly/update_force()
if(active)
edge = TRUE
sharp = TRUE
..() //Updates force.
throwforce = max(3,force-3)
hitsound = 'sound/weapons/bladeslice.ogg'
icon_state += "_open"
w_class = ITEMSIZE_NORMAL
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
else
force = 3
edge = FALSE
sharp = FALSE
hitsound = initial(hitsound)
icon_state = initial(icon_state)
w_class = initial(w_class)
attack_verb = initial(attack_verb)
/obj/item/weapon/material/butterfly/switchblade
name = "switchblade"
desc = "A classic switchblade with gold engraving. Just holding it makes you feel like a gangster."
icon_state = "switchblade"
/obj/item/weapon/material/butterfly/boxcutter
name = "box cutter"
desc = "A thin, inexpensive razor-blade knife designed to open cardboard boxes."
icon_state = "boxcutter"
force_divisor = 0.1 // 6 when wielded with hardness 60 (steel)
thrown_force_divisor = 0.2 // 4 when thrown with weight 20 (steel)
/obj/item/weapon/material/butterfly/attack_self(mob/user)
active = !active
update_force()
if(user)
if(active)
to_chat(user, "<span class='notice'>You flip out \the [src].</span>")
playsound(src, 'sound/weapons/flipblade.ogg', 15, 1)
else
to_chat(user, "<span class='notice'>\The [src] can now be concealed.</span>")
add_fingerprint(user)
/*
* Kitchen knives
*/
/obj/item/weapon/material/knife
name = "kitchen knife"
icon = 'icons/obj/kitchen.dmi'
icon_state = "knife"
desc = "A general purpose Chef's Knife made by SpaceCook Incorporated. Guaranteed to stay sharp for years to come."
description_fluff = "This could be used to engrave messages on suitable surfaces if you really put your mind to it! Alt-click a floor or wall to engrave with it." //This way it's not a completely hidden, arcane art to engrave.
sharp = TRUE
edge = TRUE
force_divisor = 0.15 // 9 when wielded with hardness 60 (steel)
matter = list(MAT_STEEL = 12000)
origin_tech = list(TECH_MATERIAL = 1)
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
drop_sound = 'sound/items/drop/knife.ogg'
// These no longer inherit from hatchets.
/obj/item/weapon/material/knife/tacknife
name = "tactical knife"
desc = "You'd be killing loads of people if this was Medal of Valor: Heroes of Space."
icon = 'icons/obj/weapons.dmi'
icon_state = "tacknife"
item_state = "knife"
force_divisor = 0.25 //15 when hardness 60 (steel)
attack_verb = list("stabbed", "chopped", "cut")
applies_material_colour = 1
/obj/item/weapon/material/knife/tacknife/combatknife
name = "combat knife"
desc = "If only you had a boot to put it in."
icon = 'icons/obj/weapons.dmi'
icon_state = "tacknife2"
item_state = "knife"
force_divisor = 0.34 // 20 with hardness 60 (steel)
thrown_force_divisor = 1.75 // 20 with weight 20 (steel)
attack_verb = list("sliced", "stabbed", "chopped", "cut")
applies_material_colour = 1
// Identical to the tactical knife but nowhere near as stabby.
// Kind of like the toy esword compared to the real thing.
/obj/item/weapon/material/knife/tacknife/boot
name = "boot knife"
desc = "A small fixed-blade knife for putting inside a boot."
icon = 'icons/obj/weapons.dmi'
icon_state = "tacknife3"
item_state = "knife"
force_divisor = 0.15
applies_material_colour = 0
/obj/item/weapon/material/knife/hook
name = "meat hook"
desc = "A sharp, metal hook what sticks into things."
icon_state = "hook_knife"
/obj/item/weapon/material/knife/ritual
name = "ritual knife"
desc = "The unearthly energies that once powered this blade are now dormant."
icon = 'icons/obj/wizard.dmi'
icon_state = "render"
applies_material_colour = 0
/obj/item/weapon/material/knife/table
name = "table knife"
icon = 'icons/obj/kitchen.dmi'
icon_state = "knife_table"
sharp = FALSE // blunted tip
force_divisor = 0.1
/obj/item/weapon/material/knife/table/plastic
default_material = "plastic"
/obj/item/weapon/material/knife/butch
name = "butcher's cleaver"
icon_state = "cleaver"
desc = "A huge thing used for chopping and chopping up meat. This includes clowns and clown-by-products."
force_divisor = 0.25 // 15 when wielded with hardness 60 (steel)
attack_verb = list("cleaved", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
/obj/item/weapon/material/knife/machete
name = "machete"
desc = "A sharp machete often found in survival kits."
icon_state = "machete"
force_divisor = 0.3 // 18 when hardness 60 (steel)
attack_verb = list("slashed", "chopped", "gouged", "ripped", "cut")
can_cleave = TRUE //Now hatchets inherit from the machete, and thus knives. Tables turned.
slot_flags = SLOT_BELT
default_material = "plasteel" //VOREStation Edit
/obj/item/weapon/material/knife/machete/cyborg
name = "integrated machete"
desc = "A sharp machete often found attached to robots."
unbreakable = TRUE
/obj/item/weapon/material/knife/tacknife/survival
name = "survival knife"
desc = "A hunting grade survival knife."
icon = 'icons/obj/kitchen.dmi'
icon_state = "survivalknife"
item_state = "knife"
applies_material_colour = FALSE
default_material = "plasteel" //VOREStation Edit
toolspeed = 2 // Use a real axe if you want to chop logs.
/obj/item/weapon/material/knife/stone
name = "stone blade"
desc = "A crude blade made by chipping away at a piece of flint."
icon = 'icons/obj/weapons_vr.dmi'
icon_state = "stone_blade"
applies_material_colour = FALSE
fragile = TRUE
dulled = TRUE
edge = TRUE
sharp = TRUE
default_material = MAT_FLINT
/obj/item/weapon/material/knife/stone/wood
name = "stone knife"
desc = "A crude blade of flint with a wooden handle, secured with plant fibers twined into sturdy ropes. Useful for cutting, stabbing, slicing, and even shearing."
icon_state = "stone_wood_knife"
dulled = FALSE
fragile = FALSE
/obj/item/weapon/material/knife/stone/bone
name = "stone knife"
desc = "A crude blade of flint with a bone handle, secured with plant fibers twined into sturdy ropes. Useful for cutting, stabbing, slicing, and even shearing."
icon_state = "stone_bone_knife"
dulled = FALSE
fragile = FALSE
/obj/item/weapon/material/butterfly
name = "butterfly knife"
desc = "A basic metal blade concealed in a lightweight plasteel grip. Small enough when folded to fit in a pocket."
description_fluff = "This could be used to engrave messages on suitable surfaces if you really put your mind to it! Alt-click a floor or wall to engrave with it." //This way it's not a completely hidden, arcane art to engrave.
icon_state = "butterflyknife"
item_state = null
hitsound = null
var/active = 0
w_class = ITEMSIZE_SMALL
attack_verb = list("patted", "tapped")
force_divisor = 0.25 // 15 when wielded with hardness 60 (steel)
thrown_force_divisor = 0.25 // 5 when thrown with weight 20 (steel)
drop_sound = 'sound/items/drop/knife.ogg'
pickup_sound = 'sound/items/pickup/knife.ogg'
/obj/item/weapon/material/butterfly/update_force()
if(active)
edge = TRUE
sharp = TRUE
..() //Updates force.
throwforce = max(3,force-3)
hitsound = 'sound/weapons/bladeslice.ogg'
icon_state += "_open"
w_class = ITEMSIZE_NORMAL
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
else
force = 3
edge = FALSE
sharp = FALSE
hitsound = initial(hitsound)
icon_state = initial(icon_state)
w_class = initial(w_class)
attack_verb = initial(attack_verb)
/obj/item/weapon/material/butterfly/switchblade
name = "switchblade"
desc = "A classic switchblade with gold engraving. Just holding it makes you feel like a gangster."
icon_state = "switchblade"
/obj/item/weapon/material/butterfly/boxcutter
name = "box cutter"
desc = "A thin, inexpensive razor-blade knife designed to open cardboard boxes."
icon_state = "boxcutter"
force_divisor = 0.1 // 6 when wielded with hardness 60 (steel)
thrown_force_divisor = 0.2 // 4 when thrown with weight 20 (steel)
/obj/item/weapon/material/butterfly/attack_self(mob/user)
active = !active
update_force()
if(user)
if(active)
to_chat(user, "<span class='notice'>You flip out \the [src].</span>")
playsound(src, 'sound/weapons/flipblade.ogg', 15, 1)
else
to_chat(user, "<span class='notice'>\The [src] can now be concealed.</span>")
add_fingerprint(user)
/*
* Kitchen knives
*/
/obj/item/weapon/material/knife
name = "kitchen knife"
icon = 'icons/obj/kitchen.dmi'
icon_state = "knife"
desc = "A general purpose Chef's Knife made by SpaceCook Incorporated. Guaranteed to stay sharp for years to come."
description_fluff = "This could be used to engrave messages on suitable surfaces if you really put your mind to it! Alt-click a floor or wall to engrave with it." //This way it's not a completely hidden, arcane art to engrave.
sharp = TRUE
edge = TRUE
force_divisor = 0.15 // 9 when wielded with hardness 60 (steel)
matter = list(MAT_STEEL = 12000)
origin_tech = list(TECH_MATERIAL = 1)
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
drop_sound = 'sound/items/drop/knife.ogg'
// These no longer inherit from hatchets.
/obj/item/weapon/material/knife/tacknife
name = "tactical knife"
desc = "You'd be killing loads of people if this was Medal of Valor: Heroes of Space."
icon = 'icons/obj/weapons.dmi'
icon_state = "tacknife"
item_state = "knife"
force_divisor = 0.25 //15 when hardness 60 (steel)
attack_verb = list("stabbed", "chopped", "cut")
applies_material_colour = 1
/obj/item/weapon/material/knife/tacknife/combatknife
name = "combat knife"
desc = "If only you had a boot to put it in."
icon = 'icons/obj/weapons.dmi'
icon_state = "tacknife2"
item_state = "knife"
force_divisor = 0.34 // 20 with hardness 60 (steel)
thrown_force_divisor = 1.75 // 20 with weight 20 (steel)
attack_verb = list("sliced", "stabbed", "chopped", "cut")
applies_material_colour = 1
// Identical to the tactical knife but nowhere near as stabby.
// Kind of like the toy esword compared to the real thing.
/obj/item/weapon/material/knife/tacknife/boot
name = "boot knife"
desc = "A small fixed-blade knife for putting inside a boot."
icon = 'icons/obj/weapons.dmi'
icon_state = "tacknife3"
item_state = "knife"
force_divisor = 0.15
applies_material_colour = 0
/obj/item/weapon/material/knife/hook
name = "meat hook"
desc = "A sharp, metal hook what sticks into things."
icon_state = "hook_knife"
/obj/item/weapon/material/knife/ritual
name = "ritual knife"
desc = "The unearthly energies that once powered this blade are now dormant."
icon = 'icons/obj/wizard.dmi'
icon_state = "render"
applies_material_colour = 0
/obj/item/weapon/material/knife/table
name = "table knife"
icon = 'icons/obj/kitchen.dmi'
icon_state = "knife_table"
sharp = FALSE // blunted tip
force_divisor = 0.1
/obj/item/weapon/material/knife/table/plastic
default_material = "plastic"
/obj/item/weapon/material/knife/butch
name = "butcher's cleaver"
icon_state = "cleaver"
desc = "A huge thing used for chopping and chopping up meat. This includes clowns and clown-by-products."
force_divisor = 0.25 // 15 when wielded with hardness 60 (steel)
attack_verb = list("cleaved", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
/obj/item/weapon/material/knife/machete
name = "machete"
desc = "A sharp machete often found in survival kits."
icon_state = "machete"
force_divisor = 0.3 // 18 when hardness 60 (steel)
attack_verb = list("slashed", "chopped", "gouged", "ripped", "cut")
can_cleave = TRUE //Now hatchets inherit from the machete, and thus knives. Tables turned.
slot_flags = SLOT_BELT
default_material = "plasteel" //VOREStation Edit
/obj/item/weapon/material/knife/machete/cyborg
name = "integrated machete"
desc = "A sharp machete often found attached to robots."
unbreakable = TRUE
/obj/item/weapon/material/knife/tacknife/survival
name = "survival knife"
desc = "A hunting grade survival knife."
icon = 'icons/obj/kitchen.dmi'
icon_state = "survivalknife"
item_state = "knife"
applies_material_colour = FALSE
default_material = "plasteel" //VOREStation Edit
toolspeed = 2 // Use a real axe if you want to chop logs.
/obj/item/weapon/material/knife/stone
name = "stone blade"
desc = "A crude blade made by chipping away at a piece of flint."
icon = 'icons/obj/weapons_vr.dmi'
icon_state = "stone_blade"
applies_material_colour = FALSE
fragile = TRUE
dulled = TRUE
edge = TRUE
sharp = TRUE
default_material = MAT_FLINT
/obj/item/weapon/material/knife/stone/wood
name = "stone knife"
desc = "A crude blade of flint with a wooden handle, secured with plant fibers twined into sturdy ropes. Useful for cutting, stabbing, slicing, and even shearing."
icon_state = "stone_wood_knife"
dulled = FALSE
fragile = FALSE
/obj/item/weapon/material/knife/stone/bone
name = "stone knife"
desc = "A crude blade of flint with a bone handle, secured with plant fibers twined into sturdy ropes. Useful for cutting, stabbing, slicing, and even shearing."
icon_state = "stone_bone_knife"
dulled = FALSE
fragile = FALSE
@@ -1,182 +1,182 @@
// SEE code/modules/materials/materials.dm FOR DETAILS ON INHERITED DATUM.
// This class of weapons takes force and appearance data from a material datum.
// They are also fragile based on material data and many can break/smash apart.
/obj/item/weapon/material
health = 10
hitsound = 'sound/weapons/bladeslice.ogg'
gender = NEUTER
throw_speed = 3
throw_range = 7
w_class = ITEMSIZE_NORMAL
sharp = FALSE
edge = FALSE
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_material.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_material.dmi',
)
var/applies_material_colour = 1
var/unbreakable = 0 //Doesn't lose health
var/fragile = 0 //Shatters when it dies
var/dulled = 0 //Has gone dull
var/can_dull = 1 //Can it go dull?
var/force_divisor = 0.5
var/thrown_force_divisor = 0.5
var/dulled_divisor = 0.5 //Just drops the damage by half
var/default_material = MAT_STEEL
var/datum/material/material
var/drops_debris = 1
/obj/item/weapon/material/New(var/newloc, var/material_key)
..(newloc)
if(!material_key)
material_key = default_material
set_material(material_key)
if(!material)
qdel(src)
return
matter = material.get_matter()
if(matter.len)
for(var/material_type in matter)
if(!isnull(matter[material_type]))
matter[material_type] *= force_divisor // May require a new var instead.
if(!(material.conductive))
src.flags |= NOCONDUCT
/obj/item/weapon/material/get_material()
return material
/obj/item/weapon/material/proc/update_force()
if(edge || sharp)
force = material.get_edge_damage()
else
force = material.get_blunt_damage()
force = round(force*force_divisor)
if(dulled)
force = round(force*dulled_divisor)
throwforce = round(material.get_blunt_damage()*thrown_force_divisor)
//spawn(1)
// to_world("[src] has force [force] and throwforce [throwforce] when made from default material [material.name]")
/obj/item/weapon/material/proc/set_material(var/new_material)
material = get_material_by_name(new_material)
if(!material)
qdel(src)
else
name = "[material.display_name] [initial(name)]"
health = round(material.integrity/10)
if(applies_material_colour)
color = material.icon_colour
if(material.products_need_process())
START_PROCESSING(SSobj, src)
update_force()
/obj/item/weapon/material/Destroy()
STOP_PROCESSING(SSobj, src)
. = ..()
/obj/item/weapon/material/apply_hit_effect()
..()
if(!unbreakable)
if(material.is_brittle())
health = 0
else if(!prob(material.hardness))
health--
check_health()
/obj/item/weapon/material/attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/weapon/whetstone))
var/obj/item/weapon/whetstone/whet = W
repair(whet.repair_amount, whet.repair_time, user)
if(istype(W, /obj/item/weapon/material/sharpeningkit))
var/obj/item/weapon/material/sharpeningkit/SK = W
repair(SK.repair_amount, SK.repair_time, user)
..()
/obj/item/weapon/material/proc/check_health(var/consumed)
if(health<=0)
health = 0
if(fragile)
shatter(consumed)
else if(!dulled && can_dull)
dull()
/obj/item/weapon/material/proc/shatter(var/consumed)
var/turf/T = get_turf(src)
T.visible_message("<span class='danger'>\The [src] [material.destruction_desc]!</span>")
if(istype(loc, /mob/living))
var/mob/living/M = loc
M.drop_from_inventory(src)
playsound(src, "shatter", 70, 1)
if(!consumed && drops_debris) material.place_shard(T)
qdel(src)
/obj/item/weapon/material/proc/dull()
var/turf/T = get_turf(src)
T.visible_message("<span class='danger'>\The [src] goes dull!</span>")
playsound(src, "shatter", 70, 1)
dulled = 1
if(is_sharp() || has_edge())
sharp = FALSE
edge = FALSE
/obj/item/weapon/material/proc/repair(var/repair_amount, var/repair_time, mob/living/user)
if(!fragile)
if(health < initial(health))
user.visible_message("[user] begins repairing \the [src].", "You begin repairing \the [src].")
if(do_after(user, repair_time))
user.visible_message("[user] has finished repairing \the [src]", "You finish repairing \the [src].")
health = min(health + repair_amount, initial(health))
dulled = 0
sharp = initial(sharp)
edge = initial(edge)
else
to_chat(user, "<span class='notice'>[src] doesn't need repairs.</span>")
else
to_chat(user, "<span class='warning'>You can't repair \the [src].</span>")
return
/obj/item/weapon/material/proc/sharpen(var/material, var/sharpen_time, var/kit, mob/living/M)
if(!fragile && src.material.can_sharpen)
if(health < initial(health))
to_chat(M, "You should repair [src] first. Try using [kit] on it.")
return FALSE
M.visible_message("[M] begins to replace parts of [src] with [kit].", "You begin to replace parts of [src] with [kit].")
if(do_after(usr, sharpen_time))
M.visible_message("[M] has finished replacing parts of [src].", "You finish replacing parts of [src].")
src.set_material(material)
return TRUE
else
to_chat(M, "<span class = 'warning'>You can't sharpen and re-edge [src].</span>")
return FALSE
/*
Commenting this out pending rebalancing of radiation based on small objects.
/obj/item/weapon/material/process()
if(!material.radioactivity)
return
for(var/mob/living/L in range(1,src))
L.apply_effect(round(material.radioactivity/30),IRRADIATE,0)
*/
/*
// Commenting this out while fires are so spectacularly lethal, as I can't seem to get this balanced appropriately.
/obj/item/weapon/material/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
TemperatureAct(exposed_temperature)
// This might need adjustment. Will work that out later.
/obj/item/weapon/material/proc/TemperatureAct(temperature)
health -= material.combustion_effect(get_turf(src), temperature, 0.1)
check_health(1)
/obj/item/weapon/material/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W,/obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(material.ignition_point && WT.remove_fuel(0, user))
TemperatureAct(150)
else
return ..()
*/
// SEE code/modules/materials/materials.dm FOR DETAILS ON INHERITED DATUM.
// This class of weapons takes force and appearance data from a material datum.
// They are also fragile based on material data and many can break/smash apart.
/obj/item/weapon/material
health = 10
hitsound = 'sound/weapons/bladeslice.ogg'
gender = NEUTER
throw_speed = 3
throw_range = 7
w_class = ITEMSIZE_NORMAL
sharp = FALSE
edge = FALSE
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_material.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_material.dmi',
)
var/applies_material_colour = 1
var/unbreakable = 0 //Doesn't lose health
var/fragile = 0 //Shatters when it dies
var/dulled = 0 //Has gone dull
var/can_dull = 1 //Can it go dull?
var/force_divisor = 0.5
var/thrown_force_divisor = 0.5
var/dulled_divisor = 0.5 //Just drops the damage by half
var/default_material = MAT_STEEL
var/datum/material/material
var/drops_debris = 1
/obj/item/weapon/material/New(var/newloc, var/material_key)
..(newloc)
if(!material_key)
material_key = default_material
set_material(material_key)
if(!material)
qdel(src)
return
matter = material.get_matter()
if(matter.len)
for(var/material_type in matter)
if(!isnull(matter[material_type]))
matter[material_type] *= force_divisor // May require a new var instead.
if(!(material.conductive))
src.flags |= NOCONDUCT
/obj/item/weapon/material/get_material()
return material
/obj/item/weapon/material/proc/update_force()
if(edge || sharp)
force = material.get_edge_damage()
else
force = material.get_blunt_damage()
force = round(force*force_divisor)
if(dulled)
force = round(force*dulled_divisor)
throwforce = round(material.get_blunt_damage()*thrown_force_divisor)
//spawn(1)
// to_world("[src] has force [force] and throwforce [throwforce] when made from default material [material.name]")
/obj/item/weapon/material/proc/set_material(var/new_material)
material = get_material_by_name(new_material)
if(!material)
qdel(src)
else
name = "[material.display_name] [initial(name)]"
health = round(material.integrity/10)
if(applies_material_colour)
color = material.icon_colour
if(material.products_need_process())
START_PROCESSING(SSobj, src)
update_force()
/obj/item/weapon/material/Destroy()
STOP_PROCESSING(SSobj, src)
. = ..()
/obj/item/weapon/material/apply_hit_effect()
..()
if(!unbreakable)
if(material.is_brittle())
health = 0
else if(!prob(material.hardness))
health--
check_health()
/obj/item/weapon/material/attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/weapon/whetstone))
var/obj/item/weapon/whetstone/whet = W
repair(whet.repair_amount, whet.repair_time, user)
if(istype(W, /obj/item/weapon/material/sharpeningkit))
var/obj/item/weapon/material/sharpeningkit/SK = W
repair(SK.repair_amount, SK.repair_time, user)
..()
/obj/item/weapon/material/proc/check_health(var/consumed)
if(health<=0)
health = 0
if(fragile)
shatter(consumed)
else if(!dulled && can_dull)
dull()
/obj/item/weapon/material/proc/shatter(var/consumed)
var/turf/T = get_turf(src)
T.visible_message("<span class='danger'>\The [src] [material.destruction_desc]!</span>")
if(istype(loc, /mob/living))
var/mob/living/M = loc
M.drop_from_inventory(src)
playsound(src, "shatter", 70, 1)
if(!consumed && drops_debris) material.place_shard(T)
qdel(src)
/obj/item/weapon/material/proc/dull()
var/turf/T = get_turf(src)
T.visible_message("<span class='danger'>\The [src] goes dull!</span>")
playsound(src, "shatter", 70, 1)
dulled = 1
if(is_sharp() || has_edge())
sharp = FALSE
edge = FALSE
/obj/item/weapon/material/proc/repair(var/repair_amount, var/repair_time, mob/living/user)
if(!fragile)
if(health < initial(health))
user.visible_message("[user] begins repairing \the [src].", "You begin repairing \the [src].")
if(do_after(user, repair_time))
user.visible_message("[user] has finished repairing \the [src]", "You finish repairing \the [src].")
health = min(health + repair_amount, initial(health))
dulled = 0
sharp = initial(sharp)
edge = initial(edge)
else
to_chat(user, "<span class='notice'>[src] doesn't need repairs.</span>")
else
to_chat(user, "<span class='warning'>You can't repair \the [src].</span>")
return
/obj/item/weapon/material/proc/sharpen(var/material, var/sharpen_time, var/kit, mob/living/M)
if(!fragile && src.material.can_sharpen)
if(health < initial(health))
to_chat(M, "You should repair [src] first. Try using [kit] on it.")
return FALSE
M.visible_message("[M] begins to replace parts of [src] with [kit].", "You begin to replace parts of [src] with [kit].")
if(do_after(usr, sharpen_time))
M.visible_message("[M] has finished replacing parts of [src].", "You finish replacing parts of [src].")
src.set_material(material)
return TRUE
else
to_chat(M, "<span class = 'warning'>You can't sharpen and re-edge [src].</span>")
return FALSE
/*
Commenting this out pending rebalancing of radiation based on small objects.
/obj/item/weapon/material/process()
if(!material.radioactivity)
return
for(var/mob/living/L in range(1,src))
L.apply_effect(round(material.radioactivity/30),IRRADIATE,0)
*/
/*
// Commenting this out while fires are so spectacularly lethal, as I can't seem to get this balanced appropriately.
/obj/item/weapon/material/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
TemperatureAct(exposed_temperature)
// This might need adjustment. Will work that out later.
/obj/item/weapon/material/proc/TemperatureAct(temperature)
health -= material.combustion_effect(get_turf(src), temperature, 0.1)
check_health(1)
/obj/item/weapon/material/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W,/obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(material.ignition_point && WT.remove_fuel(0, user))
TemperatureAct(150)
else
return ..()
*/
+228 -228
View File
@@ -1,228 +1,228 @@
/obj/item/weapon/material/harpoon
name = "harpoon"
sharp = TRUE
edge = FALSE
desc = "Tharr she blows!"
icon_state = "harpoon"
item_state = "harpoon"
force_divisor = 0.3 // 18 with hardness 60 (steel)
attack_verb = list("jabbed","stabbed","ripped")
/obj/item/weapon/material/knife/machete/hatchet
name = "hatchet"
desc = "A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood."
icon = 'icons/obj/weapons.dmi'
icon_state = "hatchet"
force_divisor = 0.2 // 12 with hardness 60 (steel)
thrown_force_divisor = 0.75 // 15 with weight 20 (steel)
w_class = ITEMSIZE_SMALL
sharp = TRUE
edge = TRUE
origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 1)
attack_verb = list("chopped", "torn", "cut")
applies_material_colour = 0
drop_sound = 'sound/items/drop/axe.ogg'
pickup_sound = 'sound/items/pickup/axe.ogg'
/* VOREStation Removal - We have one already
/obj/item/weapon/material/knife/machete/hatchet/stone
name = "sharp rock"
desc = "The secret is to bang the rocks together, guys."
force_divisor = 0.2
icon_state = "rock"
item_state = "rock"
attack_verb = list("chopped", "torn", "cut")
/obj/item/weapon/material/knife/machete/hatchet/stone/set_material(var/new_material)
var/old_name = name
. = ..()
name = old_name
*/
/obj/item/weapon/material/knife/machete/hatchet/unathiknife
name = "duelling knife"
desc = "A length of leather-bound wood studded with razor-sharp teeth. How crude."
icon = 'icons/obj/weapons.dmi'
icon_state = "unathiknife"
attack_verb = list("ripped", "torn", "cut")
can_cleave = FALSE
var/hits = 0
/obj/item/weapon/material/knife/machete/hatchet/unathiknife/attack(mob/M as mob, mob/user as mob)
if(hits > 0)
return
var/obj/item/I = user.get_inactive_hand()
if(istype(I, /obj/item/weapon/material/knife/machete/hatchet/unathiknife))
hits ++
var/obj/item/weapon/W = I
W.attack(M, user)
W.afterattack(M, user)
..()
/obj/item/weapon/material/knife/machete/hatchet/unathiknife/afterattack(mob/M as mob, mob/user as mob)
hits = initial(hits)
..()
/obj/item/weapon/material/minihoe // -- Numbers
name = "mini hoe"
desc = "It's used for removing weeds or scratching your back."
icon = 'icons/obj/weapons.dmi'
icon_state = "hoe"
force_divisor = 0.25 // 5 with weight 20 (steel)
thrown_force_divisor = 0.25 // as above
dulled_divisor = 0.75 //Still metal on a long pole
w_class = ITEMSIZE_SMALL
attack_verb = list("slashed", "sliced", "cut", "clawed")
/obj/item/weapon/material/snow/snowball
name = "loose packed snowball"
desc = "A fun snowball. Throw it at your friends!"
icon = 'icons/obj/weapons.dmi'
icon_state = "snowball"
default_material = MAT_SNOW
health = 1
fragile = 1
force_divisor = 0.01
thrown_force_divisor = 0.10
w_class = ITEMSIZE_SMALL
attack_verb = list("mushed", "splatted", "splooshed", "splushed") // Words that totally exist.
/obj/item/weapon/material/snow/snowball/attack_self(mob/user as mob)
if(user.a_intent == I_HURT)
to_chat(user, SPAN_NOTICE("You smash the snowball in your hand."))
var/atom/S = new /obj/item/stack/material/snow(user.loc)
qdel(src)
user.put_in_hands(S)
else
to_chat(user, SPAN_NOTICE("You start compacting the snowball."))
if(do_after(user, 2 SECONDS))
var/atom/S = new /obj/item/weapon/material/snow/snowball/reinforced(user.loc)
qdel(src)
user.put_in_hands(S)
/obj/item/weapon/material/snow/snowball/reinforced
name = "snowball"
desc = "A well-formed and fun snowball. It looks kind of dangerous."
//icon_state = "reinf-snowball"
force_divisor = 0.20
thrown_force_divisor = 0.25
/obj/item/weapon/material/whip
name = "whip"
desc = "A tool used to discipline animals, or look cool. Mostly the latter."
description_info = "Help - Standard attack, no modifiers.<br>\
Disarm - Disarming strike. Attempts to disarm the target at range, similar to an unarmed disarm. Additionally, will force the target (if possible) to move away from you.<br>\
Grab - Grappling strike. Attempts to pull the target toward you. This can also move objects.<br>\
Harm - A standard strike with a small chance to disarm."
icon = 'icons/obj/weapons.dmi'
icon_state = "whip"
item_state = "chain"
default_material = MAT_LEATHER
slot_flags = SLOT_BELT
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_COMBAT = 2)
attack_verb = list("flogged", "whipped", "lashed", "disciplined")
force_divisor = 0.15
thrown_force_divisor = 0.25
reach = 2
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi',
)
/obj/item/weapon/material/whip/afterattack(atom/A as mob|obj|turf|area, mob/user as mob, proximity)
..()
if(!proximity)
return
if(istype(A, /atom/movable))
var/atom/movable/AM = A
if(AM.anchored)
to_chat(user, "<span class='notice'>\The [AM] won't budge.</span>")
return
else
if(!istype(AM, /obj/item))
user.visible_message("<span class='warning'>\The [AM] is pulled along by \the [src]!</span>")
AM.Move(get_step(AM, get_dir(AM, src)))
return
else
user.visible_message("<span class='warning'>\The [AM] is snatched by \the [src]!</span>")
AM.throw_at(user, reach, 0.1, user)
/obj/item/weapon/material/whip/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone)
if(user.a_intent)
switch(user.a_intent)
if(I_HURT)
if(prob(10) && istype(target, /mob/living/carbon/human) && (user.zone_sel in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT, BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND)))
to_chat(target, "<span class='warning'>\The [src] rips at your hands!</span>")
ranged_disarm(target)
if(I_DISARM)
if(prob(min(90, force * 3)) && istype(target, /mob/living/carbon/human) && (user.zone_sel in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT, BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND)))
ranged_disarm(target)
else
target.visible_message("<span class='danger'>\The [src] sends \the [target] stumbling away.</span>")
target.Move(get_step(target,get_dir(user,target)))
if(I_GRAB)
var/turf/STurf = get_turf(target)
spawn(2)
playsound(STurf, 'sound/effects/snap.ogg', 60, 1)
target.visible_message("<span class='critical'>\The [src] yanks \the [target] towards \the [user]!</span>")
target.throw_at(get_turf(get_step(user,get_dir(user,target))), 2, 1, src)
..()
/obj/item/weapon/material/whip/proc/ranged_disarm(var/mob/living/carbon/human/H, var/mob/living/user)
if(istype(H))
var/list/holding = list(H.get_active_hand() = 40, H.get_inactive_hand() = 20)
if(user.zone_sel in list(BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND))
for(var/obj/item/weapon/gun/W in holding)
if(W && prob(holding[W]))
var/list/turfs = list()
for(var/turf/T in view())
turfs += T
if(turfs.len)
var/turf/target = pick(turfs)
visible_message("<span class='danger'>[H]'s [W] goes off due to \the [src]!</span>")
return W.afterattack(target,H)
if(!(H.species.flags & NO_SLIP) && prob(10) && (user.zone_sel in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT)))
var/armor_check = H.run_armor_check(user.zone_sel, "melee")
H.apply_effect(3, WEAKEN, armor_check)
playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
if(armor_check < 60)
visible_message("<span class='danger'>\The [src] has tripped [H]!</span>")
else
visible_message("<span class='warning'>\The [src] attempted to trip [H]!</span>")
return
else
if(H.break_all_grabs(user))
playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
return
if(user.zone_sel in list(BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND))
for(var/obj/item/I in holding)
if(I && prob(holding[I]))
H.drop_from_inventory(I)
visible_message("<span class='danger'>\The [src] has disarmed [H]!</span>")
playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
return
/obj/item/weapon/material/whip/attack_self(mob/user)
user.visible_message("<span class='warning'>\The [user] cracks \the [src]!</span>")
playsound(src, 'sound/effects/snap.ogg', 50, 1)
/obj/item/weapon/material/knife/machete/hatchet/stone
name = "hatchet"
desc = "A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood."
icon = 'icons/obj/weapons_vr.dmi'
icon_state = "stone_wood_axe"
default_material = MAT_FLINT
origin_tech = list()
applies_material_colour = FALSE
/obj/item/weapon/material/knife/machete/hatchet/stone/bone
icon_state = "stone_bone_axe"
/obj/item/weapon/material/harpoon
name = "harpoon"
sharp = TRUE
edge = FALSE
desc = "Tharr she blows!"
icon_state = "harpoon"
item_state = "harpoon"
force_divisor = 0.3 // 18 with hardness 60 (steel)
attack_verb = list("jabbed","stabbed","ripped")
/obj/item/weapon/material/knife/machete/hatchet
name = "hatchet"
desc = "A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood."
icon = 'icons/obj/weapons.dmi'
icon_state = "hatchet"
force_divisor = 0.2 // 12 with hardness 60 (steel)
thrown_force_divisor = 0.75 // 15 with weight 20 (steel)
w_class = ITEMSIZE_SMALL
sharp = TRUE
edge = TRUE
origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 1)
attack_verb = list("chopped", "torn", "cut")
applies_material_colour = 0
drop_sound = 'sound/items/drop/axe.ogg'
pickup_sound = 'sound/items/pickup/axe.ogg'
/* VOREStation Removal - We have one already
/obj/item/weapon/material/knife/machete/hatchet/stone
name = "sharp rock"
desc = "The secret is to bang the rocks together, guys."
force_divisor = 0.2
icon_state = "rock"
item_state = "rock"
attack_verb = list("chopped", "torn", "cut")
/obj/item/weapon/material/knife/machete/hatchet/stone/set_material(var/new_material)
var/old_name = name
. = ..()
name = old_name
*/
/obj/item/weapon/material/knife/machete/hatchet/unathiknife
name = "duelling knife"
desc = "A length of leather-bound wood studded with razor-sharp teeth. How crude."
icon = 'icons/obj/weapons.dmi'
icon_state = "unathiknife"
attack_verb = list("ripped", "torn", "cut")
can_cleave = FALSE
var/hits = 0
/obj/item/weapon/material/knife/machete/hatchet/unathiknife/attack(mob/M as mob, mob/user as mob)
if(hits > 0)
return
var/obj/item/I = user.get_inactive_hand()
if(istype(I, /obj/item/weapon/material/knife/machete/hatchet/unathiknife))
hits ++
var/obj/item/weapon/W = I
W.attack(M, user)
W.afterattack(M, user)
..()
/obj/item/weapon/material/knife/machete/hatchet/unathiknife/afterattack(mob/M as mob, mob/user as mob)
hits = initial(hits)
..()
/obj/item/weapon/material/minihoe // -- Numbers
name = "mini hoe"
desc = "It's used for removing weeds or scratching your back."
icon = 'icons/obj/weapons.dmi'
icon_state = "hoe"
force_divisor = 0.25 // 5 with weight 20 (steel)
thrown_force_divisor = 0.25 // as above
dulled_divisor = 0.75 //Still metal on a long pole
w_class = ITEMSIZE_SMALL
attack_verb = list("slashed", "sliced", "cut", "clawed")
/obj/item/weapon/material/snow/snowball
name = "loose packed snowball"
desc = "A fun snowball. Throw it at your friends!"
icon = 'icons/obj/weapons.dmi'
icon_state = "snowball"
default_material = MAT_SNOW
health = 1
fragile = 1
force_divisor = 0.01
thrown_force_divisor = 0.10
w_class = ITEMSIZE_SMALL
attack_verb = list("mushed", "splatted", "splooshed", "splushed") // Words that totally exist.
/obj/item/weapon/material/snow/snowball/attack_self(mob/user as mob)
if(user.a_intent == I_HURT)
to_chat(user, SPAN_NOTICE("You smash the snowball in your hand."))
var/atom/S = new /obj/item/stack/material/snow(user.loc)
qdel(src)
user.put_in_hands(S)
else
to_chat(user, SPAN_NOTICE("You start compacting the snowball."))
if(do_after(user, 2 SECONDS))
var/atom/S = new /obj/item/weapon/material/snow/snowball/reinforced(user.loc)
qdel(src)
user.put_in_hands(S)
/obj/item/weapon/material/snow/snowball/reinforced
name = "snowball"
desc = "A well-formed and fun snowball. It looks kind of dangerous."
//icon_state = "reinf-snowball"
force_divisor = 0.20
thrown_force_divisor = 0.25
/obj/item/weapon/material/whip
name = "whip"
desc = "A tool used to discipline animals, or look cool. Mostly the latter."
description_info = "Help - Standard attack, no modifiers.<br>\
Disarm - Disarming strike. Attempts to disarm the target at range, similar to an unarmed disarm. Additionally, will force the target (if possible) to move away from you.<br>\
Grab - Grappling strike. Attempts to pull the target toward you. This can also move objects.<br>\
Harm - A standard strike with a small chance to disarm."
icon = 'icons/obj/weapons.dmi'
icon_state = "whip"
item_state = "chain"
default_material = MAT_LEATHER
slot_flags = SLOT_BELT
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_COMBAT = 2)
attack_verb = list("flogged", "whipped", "lashed", "disciplined")
force_divisor = 0.15
thrown_force_divisor = 0.25
reach = 2
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_melee.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_melee.dmi',
)
/obj/item/weapon/material/whip/afterattack(atom/A as mob|obj|turf|area, mob/user as mob, proximity)
..()
if(!proximity)
return
if(istype(A, /atom/movable))
var/atom/movable/AM = A
if(AM.anchored)
to_chat(user, "<span class='notice'>\The [AM] won't budge.</span>")
return
else
if(!istype(AM, /obj/item))
user.visible_message("<span class='warning'>\The [AM] is pulled along by \the [src]!</span>")
AM.Move(get_step(AM, get_dir(AM, src)))
return
else
user.visible_message("<span class='warning'>\The [AM] is snatched by \the [src]!</span>")
AM.throw_at(user, reach, 0.1, user)
/obj/item/weapon/material/whip/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone)
if(user.a_intent)
switch(user.a_intent)
if(I_HURT)
if(prob(10) && istype(target, /mob/living/carbon/human) && (user.zone_sel in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT, BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND)))
to_chat(target, "<span class='warning'>\The [src] rips at your hands!</span>")
ranged_disarm(target)
if(I_DISARM)
if(prob(min(90, force * 3)) && istype(target, /mob/living/carbon/human) && (user.zone_sel in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT, BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND)))
ranged_disarm(target)
else
target.visible_message("<span class='danger'>\The [src] sends \the [target] stumbling away.</span>")
target.Move(get_step(target,get_dir(user,target)))
if(I_GRAB)
var/turf/STurf = get_turf(target)
spawn(2)
playsound(STurf, 'sound/effects/snap.ogg', 60, 1)
target.visible_message("<span class='critical'>\The [src] yanks \the [target] towards \the [user]!</span>")
target.throw_at(get_turf(get_step(user,get_dir(user,target))), 2, 1, src)
..()
/obj/item/weapon/material/whip/proc/ranged_disarm(var/mob/living/carbon/human/H, var/mob/living/user)
if(istype(H))
var/list/holding = list(H.get_active_hand() = 40, H.get_inactive_hand() = 20)
if(user.zone_sel in list(BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND))
for(var/obj/item/weapon/gun/W in holding)
if(W && prob(holding[W]))
var/list/turfs = list()
for(var/turf/T in view())
turfs += T
if(turfs.len)
var/turf/target = pick(turfs)
visible_message("<span class='danger'>[H]'s [W] goes off due to \the [src]!</span>")
return W.afterattack(target,H)
if(!(H.species.flags & NO_SLIP) && prob(10) && (user.zone_sel in list(BP_L_LEG, BP_R_LEG, BP_L_FOOT, BP_R_FOOT)))
var/armor_check = H.run_armor_check(user.zone_sel, "melee")
H.apply_effect(3, WEAKEN, armor_check)
playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
if(armor_check < 60)
visible_message("<span class='danger'>\The [src] has tripped [H]!</span>")
else
visible_message("<span class='warning'>\The [src] attempted to trip [H]!</span>")
return
else
if(H.break_all_grabs(user))
playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
return
if(user.zone_sel in list(BP_L_ARM, BP_R_ARM, BP_L_HAND, BP_R_HAND))
for(var/obj/item/I in holding)
if(I && prob(holding[I]))
H.drop_from_inventory(I)
visible_message("<span class='danger'>\The [src] has disarmed [H]!</span>")
playsound(src, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
return
/obj/item/weapon/material/whip/attack_self(mob/user)
user.visible_message("<span class='warning'>\The [user] cracks \the [src]!</span>")
playsound(src, 'sound/effects/snap.ogg', 50, 1)
/obj/item/weapon/material/knife/machete/hatchet/stone
name = "hatchet"
desc = "A very sharp axe blade upon a short fibremetal handle. It has a long history of chopping things, but now it is used for chopping wood."
icon = 'icons/obj/weapons_vr.dmi'
icon_state = "stone_wood_axe"
default_material = MAT_FLINT
origin_tech = list()
applies_material_colour = FALSE
/obj/item/weapon/material/knife/machete/hatchet/stone/bone
icon_state = "stone_bone_axe"

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