Merge branch 'master' into upstream-merge-30544

This commit is contained in:
LetterJay
2017-09-11 23:21:00 -05:00
committed by GitHub
114 changed files with 4762 additions and 3743 deletions
+2 -1
View File
@@ -549,9 +549,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
transfer_blood = 0
/obj/item/singularity_pull(S, current_size)
..()
if(current_size >= STAGE_FOUR)
throw_at(S,14,3, spin=0)
else ..()
else return
/obj/item/throw_impact(atom/A)
if(A && !QDELETED(A))
@@ -90,7 +90,7 @@
return
if(!isnull(target) && !target.toff)
charges--
var/lock_code = "[rand(100,999)] [pick("Alpha","Bravo","Charlie","Delta","Echo","Foxtrot","Golf","Hotel","India","Juliet","Kilo","Lima","Mike","November","Oscar","Papa","Quebec","Romeo","Sierra","Tango","Uniform","Victor","Whiskey","X-ray","Yankee","Zulu")]"
var/lock_code = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]"
to_chat(U, "<span class='notice'>Virus Sent! The unlock code to the target is: [lock_code]</span>")
if(!target.hidden_uplink)
var/obj/item/device/uplink/uplink = new(target)
@@ -428,7 +428,7 @@
/obj/item/device/flashlight/glowstick/update_icon()
item_state = "glowstick"
overlays.Cut()
cut_overlays()
if(!fuel)
icon_state = "glowstick-empty"
cut_overlays()
@@ -0,0 +1,152 @@
//Pinpointers are used to track atoms from a distance as long as they're on the same z-level. The captain and nuke ops have ones that track the nuclear authentication disk.
/obj/item/weapon/pinpointer
name = "pinpointer"
desc = "A handheld tracking device that locks onto certain signals."
icon = 'icons/obj/device.dmi'
icon_state = "pinpointer"
flags = CONDUCT
slot_flags = SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL = 500, MAT_GLASS = 250)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/active = FALSE
var/atom/movable/target = null //The thing we're searching for
var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination
var/alert = FALSE // TRUE to display things more seriously
/obj/item/weapon/pinpointer/New()
..()
GLOB.pinpointer_list += src
/obj/item/weapon/pinpointer/Destroy()
STOP_PROCESSING(SSfastprocess, src)
GLOB.pinpointer_list -= src
return ..()
/obj/item/weapon/pinpointer/attack_self(mob/living/user)
active = !active
user.visible_message("<span class='notice'>[user] [active ? "" : "de"]activates their pinpointer.</span>", "<span class='notice'>You [active ? "" : "de"]activate your pinpointer.</span>")
playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
if(active)
START_PROCESSING(SSfastprocess, src)
else
target = null
STOP_PROCESSING(SSfastprocess, src)
update_pointer_overlay()
/obj/item/weapon/pinpointer/process()
if(!active)
STOP_PROCESSING(SSfastprocess, src)
return
scan_for_target()
update_pointer_overlay()
/obj/item/weapon/pinpointer/proc/scan_for_target()
return
/obj/item/weapon/pinpointer/proc/update_pointer_overlay()
cut_overlays()
if(!active)
return
if(!target)
add_overlay("pinon[alert ? "alert" : ""]null")
var/turf/here = get_turf(src)
var/turf/there = get_turf(target)
if(here.z != there.z)
add_overlay("pinon[alert ? "alert" : ""]null")
return
if(get_dist_euclidian(here,there) <= minimum_range)
add_overlay("pinon[alert ? "alert" : ""]direct")
else
setDir(get_dir(here, there))
switch(get_dist(here, there))
if(1 to 8)
add_overlay("pinon[alert ? "alert" : "close"]")
if(9 to 16)
add_overlay("pinon[alert ? "alert" : "medium"]")
if(16 to INFINITY)
add_overlay("pinon[alert ? "alert" : "far"]")
/obj/item/weapon/pinpointer/crew // A replacement for the old crew monitoring consoles
name = "crew pinpointer"
desc = "A handheld tracking device that points to crew suit sensors."
icon_state = "pinpointer_crew"
/obj/item/weapon/pinpointer/crew/proc/trackable(mob/living/carbon/human/H)
var/turf/here = get_turf(src)
if((H.z == 0 || H.z == here.z) && istype(H.w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/U = H.w_uniform
// Suit sensors must be on maximum.
if(!U.has_sensor || U.sensor_mode < SENSOR_COORDS)
return FALSE
var/turf/there = get_turf(H)
return (H.z != 0 || (there && there.z == H.z))
return FALSE
/obj/item/weapon/pinpointer/crew/attack_self(mob/living/user)
if(active)
active = FALSE
user.visible_message("<span class='notice'>[user] deactivates their pinpointer.</span>", "<span class='notice'>You deactivate your pinpointer.</span>")
playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
target = null //Restarting the pinpointer forces a target reset
STOP_PROCESSING(SSfastprocess, src)
update_pointer_overlay()
return
var/list/name_counts = list()
var/list/names = list()
for(var/mob/living/carbon/human/H in GLOB.mob_list)
if(!trackable(H))
continue
var/name = "Unknown"
if(H.wear_id)
var/obj/item/weapon/card/id/I = H.wear_id.GetID()
name = I.registered_name
while(name in name_counts)
name_counts[name]++
name = text("[] ([])", name, name_counts[name])
names[name] = H
name_counts[name] = 1
if(!names.len)
user.visible_message("<span class='notice'>[user]'s pinpointer fails to detect a signal.</span>", "<span class='notice'>Your pinpointer fails to detect a signal.</span>")
return
var/A = input(user, "Person to track", "Pinpoint") in names
if(!src || QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated() || !A)
return
target = names[A]
active = TRUE
user.visible_message("<span class='notice'>[user] activates their pinpointer.</span>", "<span class='notice'>You activate your pinpointer.</span>")
playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
START_PROCESSING(SSfastprocess, src)
update_pointer_overlay()
/obj/item/weapon/pinpointer/crew/scan_for_target()
if(target)
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(!trackable(H))
target = null
if(!target)
active = FALSE
/obj/item/weapon/pinpointer/process()
if(!active)
STOP_PROCESSING(SSfastprocess, src)
return
scan_for_target()
update_pointer_overlay()
@@ -86,7 +86,7 @@
icon_state = null
active = TRUE
if(tile_overlay)
loc.overlays += tile_overlay
loc.add_overlay(tile_overlay)
else
if(crossed)
trigger() //no cheesing.
+188 -187
View File
@@ -1,187 +1,188 @@
/obj/machinery/implantchair
name = "mindshield implanter"
desc = "Used to implant occupants with mindshield implants."
icon = 'icons/obj/machines/implantchair.dmi'
icon_state = "implantchair"
density = TRUE
opacity = 0
anchored = TRUE
var/ready = TRUE
var/replenishing = FALSE
var/ready_implants = 5
var/max_implants = 5
var/injection_cooldown = 600
var/replenish_cooldown = 6000
var/implant_type = /obj/item/implant/mindshield
var/auto_inject = FALSE
var/auto_replenish = TRUE
var/special = FALSE
var/special_name = "special function"
/obj/machinery/implantchair/Initialize()
. = ..()
open_machine()
update_icon()
/obj/machinery/implantchair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "implantchair", name, 375, 280, master_ui, state)
ui.open()
/obj/machinery/implantchair/ui_data()
var/list/data = list()
data["occupied"] = occupant ? 1 : 0
data["open"] = state_open
data["occupant"] = list()
if(occupant)
var/mob/living/mob_occupant = occupant
data["occupant"]["name"] = mob_occupant.name
data["occupant"]["stat"] = mob_occupant.stat
data["special_name"] = special ? special_name : null
data["ready_implants"] = ready_implants
data["ready"] = ready
data["replenishing"] = replenishing
return data
/obj/machinery/implantchair/ui_act(action, params)
if(..())
return
switch(action)
if("door")
if(state_open)
close_machine()
else
open_machine()
. = TRUE
if("implant")
implant(occupant,usr)
. = TRUE
/obj/machinery/implantchair/proc/implant(mob/living/M,mob/user)
if (!istype(M))
return
if(!ready_implants || !ready)
return
if(implant_action(M,user))
ready_implants--
if(!replenishing && auto_replenish)
replenishing = TRUE
addtimer(CALLBACK(src,"replenish"),replenish_cooldown)
if(injection_cooldown > 0)
ready = FALSE
addtimer(CALLBACK(src,"set_ready"),injection_cooldown)
else
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, 1)
update_icon()
/obj/machinery/implantchair/proc/implant_action(mob/living/M)
var/obj/item/implant/I = new implant_type
if(I.implant(M))
visible_message("<span class='warning'>[M] has been implanted by the [name].</span>")
return 1
/obj/machinery/implantchair/update_icon()
icon_state = initial(icon_state)
if(state_open)
icon_state += "_open"
if(occupant)
icon_state += "_occupied"
if(ready)
add_overlay("ready")
else
cut_overlays()
/obj/machinery/implantchair/proc/replenish()
if(ready_implants < max_implants)
ready_implants++
if(ready_implants < max_implants)
addtimer(CALLBACK(src,"replenish"),replenish_cooldown)
else
replenishing = FALSE
/obj/machinery/implantchair/proc/set_ready()
ready = TRUE
update_icon()
/obj/machinery/implantchair/container_resist(mob/living/user)
if(state_open)
return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
to_chat(user, "<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about about a minute.)</span>")
audible_message("<span class='italics'>You hear a metallic creaking from [src]!</span>",hearing_distance = 2)
if(do_after(user, 600, target = src))
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open)
return
visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>")
to_chat(user, "<span class='notice'>You successfully break out of [src]!</span>")
open_machine()
/obj/machinery/implantchair/relaymove(mob/user)
container_resist(user)
/obj/machinery/implantchair/MouseDrop_T(mob/target, mob/user)
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !user.IsAdvancedToolUser())
return
close_machine(target)
/obj/machinery/implantchair/close_machine(mob/living/user)
if((isnull(user) || istype(user)) && state_open)
..(user)
if(auto_inject && ready && ready_implants > 0)
implant(user,null)
/obj/machinery/implantchair/genepurge
name = "Genetic purifier"
desc = "Used to purge human genome of foreign influences"
special = TRUE
special_name = "Purge genome"
injection_cooldown = 0
replenish_cooldown = 300
/obj/machinery/implantchair/genepurge/implant_action(mob/living/carbon/human/H,mob/user)
if(!istype(H))
return 0
H.set_species(/datum/species/human, 1)//lizards go home
purrbation_remove(H)//remove cats
H.dna.remove_all_mutations()//hulks out
return 1
/obj/machinery/implantchair/brainwash
name = "Neural Imprinter"
desc = "Used to <s>indoctrinate</s> rehabilitate hardened recidivists."
special_name = "Imprint"
injection_cooldown = 3000
auto_inject = FALSE
auto_replenish = FALSE
special = TRUE
var/objective = "Obey the law. Praise Nanotrasen."
var/custom = FALSE
/obj/machinery/implantchair/brainwash/implant_action(mob/living/C,mob/user)
if(!istype(C) || !C.mind) // I don't know how this makes any sense for silicons but laws trump objectives anyway.
return 0
if(custom)
if(!user || !user.Adjacent(src))
return 0
objective = stripped_input(usr,"What order do you want to imprint on [C]?","Enter the order","",120)
message_admins("[key_name_admin(user)] set brainwash machine objective to '[objective]'.")
log_game("[key_name_admin(user)] set brainwash machine objective to '[objective]'.")
var/datum/objective/custom_objective = new/datum/objective(objective)
custom_objective.owner = C.mind
C.mind.objectives += custom_objective
C.mind.announce_objectives()
message_admins("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
log_game("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
return 1
/obj/machinery/implantchair
name = "mindshield implanter"
desc = "Used to implant occupants with mindshield implants."
icon = 'icons/obj/machines/implantchair.dmi'
icon_state = "implantchair"
density = TRUE
opacity = 0
anchored = TRUE
var/ready = TRUE
var/replenishing = FALSE
var/ready_implants = 5
var/max_implants = 5
var/injection_cooldown = 600
var/replenish_cooldown = 6000
var/implant_type = /obj/item/implant/mindshield
var/auto_inject = FALSE
var/auto_replenish = TRUE
var/special = FALSE
var/special_name = "special function"
var/message_cooldown
var/breakout_time = 1
/obj/machinery/implantchair/Initialize()
. = ..()
open_machine()
update_icon()
/obj/machinery/implantchair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "implantchair", name, 375, 280, master_ui, state)
ui.open()
/obj/machinery/implantchair/ui_data()
var/list/data = list()
data["occupied"] = occupant ? 1 : 0
data["open"] = state_open
data["occupant"] = list()
if(occupant)
var/mob/living/mob_occupant = occupant
data["occupant"]["name"] = mob_occupant.name
data["occupant"]["stat"] = mob_occupant.stat
data["special_name"] = special ? special_name : null
data["ready_implants"] = ready_implants
data["ready"] = ready
data["replenishing"] = replenishing
return data
/obj/machinery/implantchair/ui_act(action, params)
if(..())
return
switch(action)
if("door")
if(state_open)
close_machine()
else
open_machine()
. = TRUE
if("implant")
implant(occupant,usr)
. = TRUE
/obj/machinery/implantchair/proc/implant(mob/living/M,mob/user)
if (!istype(M))
return
if(!ready_implants || !ready)
return
if(implant_action(M,user))
ready_implants--
if(!replenishing && auto_replenish)
replenishing = TRUE
addtimer(CALLBACK(src,"replenish"),replenish_cooldown)
if(injection_cooldown > 0)
ready = FALSE
addtimer(CALLBACK(src,"set_ready"),injection_cooldown)
else
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, 1)
update_icon()
/obj/machinery/implantchair/proc/implant_action(mob/living/M)
var/obj/item/implant/I = new implant_type
if(I.implant(M))
visible_message("<span class='warning'>[M] has been implanted by the [name].</span>")
return 1
/obj/machinery/implantchair/update_icon()
icon_state = initial(icon_state)
if(state_open)
icon_state += "_open"
if(occupant)
icon_state += "_occupied"
if(ready)
add_overlay("ready")
else
cut_overlays()
/obj/machinery/implantchair/proc/replenish()
if(ready_implants < max_implants)
ready_implants++
if(ready_implants < max_implants)
addtimer(CALLBACK(src,"replenish"),replenish_cooldown)
else
replenishing = FALSE
/obj/machinery/implantchair/proc/set_ready()
ready = TRUE
update_icon()
/obj/machinery/implantchair/container_resist(mob/living/user)
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
"<span class='italics'>You hear a metallic creaking from [src].</span>")
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open)
return
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
"<span class='notice'>You successfully break out of [src]!</span>")
open_machine()
/obj/machinery/implantchair/relaymove(mob/user)
if(message_cooldown <= world.time)
message_cooldown = world.time + 50
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
/obj/machinery/implantchair/MouseDrop_T(mob/target, mob/user)
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !user.IsAdvancedToolUser())
return
close_machine(target)
/obj/machinery/implantchair/close_machine(mob/living/user)
if((isnull(user) || istype(user)) && state_open)
..(user)
if(auto_inject && ready && ready_implants > 0)
implant(user,null)
/obj/machinery/implantchair/genepurge
name = "Genetic purifier"
desc = "Used to purge human genome of foreign influences"
special = TRUE
special_name = "Purge genome"
injection_cooldown = 0
replenish_cooldown = 300
/obj/machinery/implantchair/genepurge/implant_action(mob/living/carbon/human/H,mob/user)
if(!istype(H))
return 0
H.set_species(/datum/species/human, 1)//lizards go home
purrbation_remove(H)//remove cats
H.dna.remove_all_mutations()//hulks out
return 1
/obj/machinery/implantchair/brainwash
name = "Neural Imprinter"
desc = "Used to <s>indoctrinate</s> rehabilitate hardened recidivists."
special_name = "Imprint"
injection_cooldown = 3000
auto_inject = FALSE
auto_replenish = FALSE
special = TRUE
var/objective = "Obey the law. Praise Nanotrasen."
var/custom = FALSE
/obj/machinery/implantchair/brainwash/implant_action(mob/living/C,mob/user)
if(!istype(C) || !C.mind) // I don't know how this makes any sense for silicons but laws trump objectives anyway.
return 0
if(custom)
if(!user || !user.Adjacent(src))
return 0
objective = stripped_input(usr,"What order do you want to imprint on [C]?","Enter the order","",120)
message_admins("[key_name_admin(user)] set brainwash machine objective to '[objective]'.")
log_game("[key_name_admin(user)] set brainwash machine objective to '[objective]'.")
var/datum/objective/custom_objective = new/datum/objective(objective)
custom_objective.owner = C.mind
C.mind.objectives += custom_objective
C.mind.announce_objectives()
message_admins("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
log_game("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
return 1
+150
View File
@@ -0,0 +1,150 @@
//Pinpointers are used to track atoms from a distance as long as they're on the same z-level. The captain and nuke ops have ones that track the nuclear authentication disk.
/obj/item/pinpointer
name = "pinpointer"
desc = "A handheld tracking device that locks onto certain signals."
icon = 'icons/obj/device.dmi'
icon_state = "pinpointer"
flags_1 = CONDUCT_1
slot_flags = SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL = 500, MAT_GLASS = 250)
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/active = FALSE
var/atom/movable/target //The thing we're searching for
var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination
var/alert = FALSE // TRUE to display things more seriously
/obj/item/pinpointer/Initialize()
. = ..()
GLOB.pinpointer_list += src
/obj/item/pinpointer/Destroy()
STOP_PROCESSING(SSfastprocess, src)
GLOB.pinpointer_list -= src
return ..()
/obj/item/pinpointer/attack_self(mob/living/user)
active = !active
user.visible_message("<span class='notice'>[user] [active ? "" : "de"]activates their pinpointer.</span>", "<span class='notice'>You [active ? "" : "de"]activate your pinpointer.</span>")
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
if(active)
START_PROCESSING(SSfastprocess, src)
else
target = null
STOP_PROCESSING(SSfastprocess, src)
update_icon()
/obj/item/pinpointer/process()
if(!active)
return PROCESS_KILL
scan_for_target()
update_icon()
/obj/item/pinpointer/proc/scan_for_target()
return
/obj/item/pinpointer/update_icon()
cut_overlays()
if(!active)
return
if(!target)
add_overlay("pinon[alert ? "alert" : ""]null")
var/turf/here = get_turf(src)
var/turf/there = get_turf(target)
if(here.z != there.z)
add_overlay("pinon[alert ? "alert" : ""]null")
return
if(get_dist_euclidian(here,there) <= minimum_range)
add_overlay("pinon[alert ? "alert" : ""]direct")
else
setDir(get_dir(here, there))
switch(get_dist(here, there))
if(1 to 8)
add_overlay("pinon[alert ? "alert" : "close"]")
if(9 to 16)
add_overlay("pinon[alert ? "alert" : "medium"]")
if(16 to INFINITY)
add_overlay("pinon[alert ? "alert" : "far"]")
/obj/item/pinpointer/crew // A replacement for the old crew monitoring consoles
name = "crew pinpointer"
desc = "A handheld tracking device that points to crew suit sensors."
icon_state = "pinpointer_crew"
/obj/item/pinpointer/crew/proc/trackable(mob/living/carbon/human/H)
var/turf/here = get_turf(src)
if((H.z == 0 || H.z == here.z) && istype(H.w_uniform, /obj/item/clothing/under))
var/obj/item/clothing/under/U = H.w_uniform
// Suit sensors must be on maximum.
if(!U.has_sensor || U.sensor_mode < SENSOR_COORDS)
return FALSE
var/turf/there = get_turf(H)
return (H.z != 0 || (there && there.z == H.z))
return FALSE
/obj/item/pinpointer/crew/attack_self(mob/living/user)
if(active)
active = FALSE
user.visible_message("<span class='notice'>[user] deactivates their pinpointer.</span>", "<span class='notice'>You deactivate your pinpointer.</span>")
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
target = null //Restarting the pinpointer forces a target reset
STOP_PROCESSING(SSfastprocess, src)
update_icon()
return
var/list/name_counts = list()
var/list/names = list()
for(var/mob/living/carbon/human/H in GLOB.mob_list)
if(!trackable(H))
continue
var/crewmember_name = "Unknown"
if(H.wear_id)
var/obj/item/card/id/I = H.wear_id.GetID()
crewmember_name = I.registered_name
while(crewmember_name in name_counts)
name_counts[crewmember_name]++
crewmember_name = text("[] ([])", crewmember_name, name_counts[crewmember_name])
names[crewmember_name] = H
name_counts[crewmember_name] = 1
if(!names.len)
user.visible_message("<span class='notice'>[user]'s pinpointer fails to detect a signal.</span>", "<span class='notice'>Your pinpointer fails to detect a signal.</span>")
return
var/A = input(user, "Person to track", "Pinpoint") in names
if(!A || QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated())
return
target = names[A]
active = TRUE
user.visible_message("<span class='notice'>[user] activates their pinpointer.</span>", "<span class='notice'>You activate your pinpointer.</span>")
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
START_PROCESSING(SSfastprocess, src)
update_icon()
/obj/item/pinpointer/crew/scan_for_target()
if(target)
if(ishuman(target))
var/mob/living/carbon/human/H = target
if(!trackable(H))
target = null
if(!target) //target can be set to null from above code, or elsewhere
active = FALSE
/obj/item/pinpointer/process()
if(!active)
return PROCESS_KILL
scan_for_target()
update_icon()
+187 -13
View File
@@ -1,27 +1,201 @@
/obj/item/banner
name = "banner"
desc = "A banner with Nanotrasen's logo on it."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "banner"
item_state = "banner"
force = 8
attack_verb = list("forcefully inspired", "violently encouraged", "relentlessly galvanized")
lefthand_file = 'icons/mob/inhands/equipment/banners_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/banners_righthand.dmi'
desc = "A banner with Nanotrasen's logo on it."
var/moralecooldown = 0
var/moralewait = 600
var/inspiration_available = TRUE //If this banner can be used to inspire crew
var/morale_time = 0
var/morale_cooldown = 600 //How many deciseconds between uses
var/list/job_loyalties //Mobs with any of these assigned roles will be inspired
var/list/role_loyalties //Mobs with any of these special roles will be inspired
var/warcry
/obj/item/banner/examine(mob/user)
..()
if(inspiration_available)
to_chat(user, "<span class='notice'>Activate it in your hand to inspire nearby allies of this banner's allegiance!</span>")
/obj/item/banner/attack_self(mob/living/carbon/human/user)
if(moralecooldown + moralewait > world.time)
if(!inspiration_available)
return
to_chat(user, "<span class='notice'>You increase the morale of your fellows!</span>")
moralecooldown = world.time
if(morale_time > world.time)
to_chat(user, "<span class='warning'>You aren't feeling inspired enough to flourish [src] again yet.</span>")
return
user.visible_message("<span class='big notice'>[user] flourishes [src]!</span>", \
"<span class='notice'>You raise [src] skywards, inspiring your allies!</span>")
playsound(src, "rustle", 100, FALSE)
if(warcry)
user.say("[warcry]")
var/old_transform = user.transform
user.transform *= 1.2
animate(user, transform = old_transform, time = 10)
morale_time = world.time + morale_cooldown
for(var/mob/living/carbon/human/H in range(4,get_turf(src)))
to_chat(H, "<span class='notice'>Your morale is increased by [user]'s banner!</span>")
H.adjustBruteLoss(-15)
H.adjustFireLoss(-15)
H.AdjustStun(-40)
H.AdjustKnockdown(-40)
H.AdjustUnconscious(-40)
var/list/inspired = list()
var/has_job_loyalties = LAZYLEN(job_loyalties)
var/has_role_loyalties = LAZYLEN(role_loyalties)
inspired += user //The user is always inspired, regardless of loyalties
for(var/mob/living/carbon/human/H in range(4, get_turf(src)))
if(H.stat == DEAD || H == user)
continue
if(H.mind && (has_job_loyalties || has_role_loyalties))
if(has_job_loyalties && H.mind.assigned_role in job_loyalties)
inspired += H
else if(has_role_loyalties && H.mind.special_role in role_loyalties)
inspired += H
else if(check_inspiration(H))
inspired += H
for(var/V in inspired)
var/mob/living/carbon/human/H = V
if(H != user)
to_chat(H, "<span class='notice'>Your confidence surges as [user] flourishes [user.p_their()] [name]!</span>")
inspiration(H)
special_inspiration(H)
/obj/item/banner/proc/check_inspiration(mob/living/carbon/human/H) //Banner-specific conditions for being eligible
return
/obj/item/banner/proc/inspiration(mob/living/carbon/human/H)
H.adjustBruteLoss(-15)
H.adjustFireLoss(-15)
H.AdjustStun(-40)
H.AdjustKnockdown(-40)
H.AdjustUnconscious(-40)
playsound(H, 'sound/magic/staff_healing.ogg', 25, FALSE)
/obj/item/banner/proc/special_inspiration(mob/living/carbon/human/H) //Any banner-specific inspiration effects go here
return
/obj/item/banner/security
name = "securistan banner"
desc = "The banner of Securistan, ruling the station with an iron fist."
icon_state = "banner_security"
job_loyalties = list("Security Officer", "Warden", "Detective", "Head of Security")
warcry = "EVERYONE DOWN ON THE GROUND!!"
/obj/item/banner/security/mundane
inspiration_available = FALSE
/datum/crafting_recipe/security_banner
name = "Securistan Banner"
result = /obj/item/banner/security/mundane
time = 40
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/security = 1)
category = CAT_MISC
/obj/item/banner/medical
name = "meditopia banner"
desc = "The banner of Meditopia, generous benefactors that cure wounds and shelter the weak."
icon_state = "banner_medical"
job_loyalties = list("Medical Doctor", "Chemist", "Geneticist", "Virologist", "Chief Medical Officer")
warcry = "No wounds cannot be healed!"
/obj/item/banner/medical/mundane
inspiration_available = FALSE
/obj/item/banner/medical/check_inspiration(mob/living/carbon/human/H)
return H.stat //Meditopia is moved to help those in need
/datum/crafting_recipe/medical_banner
name = "Meditopia Banner"
result = /obj/item/banner/medical/mundane
time = 40
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/medical = 1)
category = CAT_MISC
/obj/item/banner/medical/special_inspiration(mob/living/carbon/human/H)
H.adjustToxLoss(-15)
H.setOxyLoss(0)
H.reagents.add_reagent("inaprovaline", 5)
/obj/item/banner/science
name = "sciencia banner"
desc = "The banner of Sciencia, bold and daring thaumaturges and researchers that take the path less traveled."
icon_state = "banner_science"
job_loyalties = list("Scientist", "Roboticist", "Research Director")
warcry = "For Cuban Pete!"
/obj/item/banner/science/mundane
inspiration_available = FALSE
/obj/item/banner/science/check_inspiration(mob/living/carbon/human/H)
return H.on_fire //Sciencia is pleased by dedication to the art of Toxins
/datum/crafting_recipe/science_banner
name = "Sciencia Banner"
result = /obj/item/banner/science/mundane
time = 40
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/scientist = 1)
category = CAT_MISC
/obj/item/banner/cargo
name = "cargonia banner"
desc = "The banner of the eternal Cargonia, with the mystical power of conjuring any object into existence."
icon_state = "banner_cargo"
job_loyalties = list("Cargo Technician", "Shaft Miner", "Quartermaster")
warcry = "Hail Cargonia!"
/obj/item/banner/cargo/mundane
inspiration_available = FALSE
/datum/crafting_recipe/cargo_banner
name = "Cargonia Banner"
result = /obj/item/banner/cargo/mundane
time = 40
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/cargotech = 1)
category = CAT_MISC
/obj/item/banner/engineering
name = "engitopia banner"
desc = "The banner of Engitopia, wielders of limitless power."
icon_state = "banner_engineering"
job_loyalties = list("Station Engineer", "Atmospheric Technician", "Chief Engineer")
warcry = "All hail lord Singuloth!!"
/obj/item/banner/engineering/mundane
inspiration_available = FALSE
/obj/item/banner/engineering/special_inspiration(mob/living/carbon/human/H)
H.radiation = 0
/datum/crafting_recipe/engineering_banner
name = "Engitopia Banner"
result = /obj/item/banner/engineering/mundane
time = 40
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/rank/engineer = 1)
category = CAT_MISC
/obj/item/banner/command
name = "command banner"
desc = "The banner of Command, a staunch and ancient line of bueraucratic kings and queens."
//No icon state here since the default one is the NT banner
job_loyalties = list("Captain", "Head of Personnel", "Chief Engineer", "Head of Security", "Research Director", "Chief Medical Officer")
warcry = "Hail Nanotrasen!"
/obj/item/banner/command/mundane
inspiration_available = FALSE
/obj/item/banner/command/check_inspiration(mob/living/carbon/human/H)
return H.isloyal() //Command is stalwart but rewards their allies.
/datum/crafting_recipe/command_banner
name = "Command Banner"
result = /obj/item/banner/command/mundane
time = 40
reqs = list(/obj/item/stack/rods = 2,
/obj/item/clothing/under/captainparade = 1)
category = CAT_MISC
/obj/item/banner/red
name = "red banner"
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -487,7 +487,7 @@
righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi'
flags_1 = CONDUCT_1
force = 13
var/force_on = 21
var/force_on = 24
w_class = WEIGHT_CLASS_HUGE
throwforce = 13
throw_speed = 2
File diff suppressed because it is too large Load Diff
+1
View File
@@ -169,6 +169,7 @@
return
/obj/singularity_pull(S, current_size)
..()
if(!anchored || current_size >= STAGE_FIVE)
step_towards(src,S)
@@ -16,7 +16,7 @@
integrity_failure = 50
armor = list(melee = 20, bullet = 10, laser = 10, energy = 0, bomb = 10, bio = 0, rad = 0, fire = 70, acid = 60)
var/breakout_time = 2
var/lastbang
var/message_cooldown
var/can_weld_shut = TRUE
var/horizontal = FALSE
var/allow_objects = FALSE
@@ -300,14 +300,12 @@
/obj/structure/closet/relaymove(mob/user)
if(user.stat || !isturf(loc) || !isliving(user))
return
var/mob/living/L = user
if(!open())
if(L.last_special <= world.time)
container_resist(L)
if(world.time > lastbang+5)
lastbang = world.time
for(var/mob/M in get_hearers_in_view(src, null))
M.show_message("<FONT size=[max(0, 5 - get_dist(src, M))]>BANG, bang!</FONT>", 2)
if(locked)
if(message_cooldown <= world.time)
message_cooldown = world.time + 50
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
return
container_resist()
/obj/structure/closet/attack_hand(mob/user)
..()
@@ -367,9 +365,10 @@
//okay, so the closet is either welded or locked... resist!!!
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
to_chat(user, "<span class='notice'>You lean on the back of [src] and start pushing the door open.</span>")
visible_message("<span class='warning'>[src] begins to shake violently!</span>")
if(do_after(user,(breakout_time * 60 * 10), target = src)) //minutes * 60seconds * 10deciseconds
user.visible_message("<span class='warning'>[src] begins to shake violently!</span>", \
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
"<span class='italics'>You hear banging from [src].</span>")
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
if(!user || user.stat != CONSCIOUS || user.loc != src || opened || (!locked && !welded) )
return
//we check after a while whether there is a point of resisting anymore and whether the user is capable of resisting
@@ -83,7 +83,7 @@
new /obj/item/storage/belt/security/full(src)
new /obj/item/gun/energy/e_gun/hos(src)
new /obj/item/device/flashlight/seclite(src)
new /obj/item/pinpointer(src)
new /obj/item/pinpointer/nuke(src)
/obj/structure/closet/secure_closet/warden
name = "\proper warden's locker"
@@ -108,6 +108,7 @@
new /obj/item/clothing/gloves/krav_maga/sec(src)
new /obj/item/door_remote/head_of_security(src)
new /obj/item/gun/ballistic/shotgun/automatic/combat/compact(src)
new /obj/item/pinpointer/crew(src)
/obj/structure/closet/secure_closet/security
name = "security officer's locker"
@@ -183,6 +184,7 @@
new /obj/item/reagent_containers/spray/pepper(src)
new /obj/item/clothing/suit/armor/vest/det_suit(src)
new /obj/item/storage/belt/holster/full(src)
new /obj/item/pinpointer/crew(src)
new /obj/item/device/mass_spectrometer(src)
/obj/structure/closet/secure_closet/injection
+1
View File
@@ -45,6 +45,7 @@
qdel(src)
/obj/structure/lattice/singularity_pull(S, current_size)
..()
if(current_size >= STAGE_FOUR)
deconstruct()
+21 -5
View File
@@ -23,6 +23,8 @@
var/obj/structure/tray/connected = null
var/locked = FALSE
var/opendir = SOUTH
var/message_cooldown
var/breakout_time = 1
/obj/structure/bodycontainer/Destroy()
open()
@@ -41,6 +43,11 @@
/obj/structure/bodycontainer/relaymove(mob/user)
if(user.stat || !isturf(loc))
return
if(locked)
if(message_cooldown <= world.time)
message_cooldown = world.time + 50
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
return
open()
/obj/structure/bodycontainer/attack_paw(mob/user)
@@ -84,11 +91,20 @@
qdel(src)
/obj/structure/bodycontainer/container_resist(mob/living/user)
open()
/obj/structure/bodycontainer/relay_container_resist(mob/living/user, obj/O)
to_chat(user, "<span class='notice'>You slam yourself into the side of [O].</span>")
container_resist(user)
if(!locked)
open()
return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message(null, \
"<span class='notice'>You lean on the back of [src] and start pushing the tray open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
"<span class='italics'>You hear a metallic creaking from [src].</span>")
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
if(!user || user.stat != CONSCIOUS || user.loc != src )
return
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
"<span class='notice'>You successfully break out of [src]!</span>")
open()
/obj/structure/bodycontainer/proc/open()
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
@@ -30,6 +30,7 @@
return ..()
/obj/structure/transit_tube/singularity_pull(S, current_size)
..()
if(current_size >= STAGE_FIVE)
deconstruct(FALSE)
@@ -62,10 +62,14 @@
AM.ex_act(severity, target)
/obj/structure/transit_tube_pod/singularity_pull(S, current_size)
..()
if(current_size >= STAGE_FIVE)
deconstruct(FALSE)
/obj/structure/transit_tube_pod/container_resist(mob/living/user)
if(!user.incapacitated())
empty_pod()
return
if(!moving)
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
+1
View File
@@ -105,6 +105,7 @@
qdel(src)
/obj/structure/window/singularity_pull(S, current_size)
..()
if(current_size >= STAGE_FIVE)
deconstruct(FALSE)