initial commit - cross reference with 5th port - obviously has compile errors

This commit is contained in:
LetterJay
2016-07-03 02:17:19 -05:00
commit 35a1723e98
4355 changed files with 2221257 additions and 0 deletions
+348
View File
@@ -0,0 +1,348 @@
/datum/game_mode
var/list/datum/mind/syndicates = list()
var/nukeops_lastname = ""
/datum/game_mode/nuclear
name = "nuclear emergency"
config_tag = "nuclear"
required_players = 30 // 30 players - 3 players to be the nuke ops = 27 players remaining
required_enemies = 2
recommended_enemies = 5
antag_flag = ROLE_OPERATIVE
enemy_minimum_age = 14
var/const/agents_possible = 5 //If we ever need more syndicate agents.
var/nukes_left = 1 // Call 3714-PRAY right now and order more nukes! Limited offer!
var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station
var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level
/datum/game_mode/nuclear/announce()
world << "<B>The current game mode is - Nuclear Emergency!</B>"
world << "<B>A [syndicate_name()] Strike Force is approaching [station_name()]!</B>"
world << "A nuclear explosive was being transported by Nanotrasen to a military base. The transport ship mysteriously lost contact with Space Traffic Control (STC). About that time a strange disk was discovered around [station_name()]. It was identified by Nanotrasen as a nuclear auth. disk and now Syndicate Operatives have arrived to retake the disk and detonate SS13! Also, most likely Syndicate star ships are in the vicinity so take care not to lose the disk!\n<B>Syndicate</B>: Reclaim the disk and detonate the nuclear bomb anywhere on SS13.\n<B>Personnel</B>: Hold the disk and <B>escape with the disk</B> on the shuttle!"
/datum/game_mode/nuclear/pre_setup()
var/n_players = num_players()
var/n_agents = min(round(n_players / 10, 1), agents_possible)
if(antag_candidates.len < n_agents) //In the case of having less candidates than the selected number of agents
n_agents = antag_candidates.len
while(n_agents > 0)
var/datum/mind/new_syndicate = pick(antag_candidates)
syndicates += new_syndicate
antag_candidates -= new_syndicate //So it doesn't pick the same guy each time.
n_agents--
for(var/datum/mind/synd_mind in syndicates)
synd_mind.assigned_role = "Syndicate"
synd_mind.special_role = "Syndicate"//So they actually have a special role/N
log_game("[synd_mind.key] (ckey) has been selected as a nuclear operative")
return 1
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
/datum/game_mode/proc/update_synd_icons_added(datum/mind/synd_mind)
var/datum/atom_hud/antag/opshud = huds[ANTAG_HUD_OPS]
opshud.join_hud(synd_mind.current)
set_antag_hud(synd_mind.current, "synd")
/datum/game_mode/proc/update_synd_icons_removed(datum/mind/synd_mind)
var/datum/atom_hud/antag/opshud = huds[ANTAG_HUD_OPS]
opshud.leave_hud(synd_mind.current)
set_antag_hud(synd_mind.current, null)
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
/datum/game_mode/nuclear/post_setup()
var/list/turf/synd_spawn = list()
for(var/obj/effect/landmark/A in landmarks_list)
if(A.name == "Syndicate-Spawn")
synd_spawn += get_turf(A)
continue
var/nuke_code = "[rand(10000, 99999)]"
var/leader_selected = 0
var/agent_number = 1
var/spawnpos = 1
for(var/datum/mind/synd_mind in syndicates)
if(spawnpos > synd_spawn.len)
spawnpos = 2
synd_mind.current.loc = synd_spawn[spawnpos]
forge_syndicate_objectives(synd_mind)
greet_syndicate(synd_mind)
equip_syndicate(synd_mind.current)
if(nuke_code)
synd_mind.store_memory("<B>Syndicate Nuclear Bomb Code</B>: [nuke_code]", 0, 0)
synd_mind.current << "The nuclear authorization code is: <B>[nuke_code]</B>"
if(!leader_selected)
prepare_syndicate_leader(synd_mind, nuke_code)
leader_selected = 1
else
synd_mind.current.real_name = "[syndicate_name()] Operative #[agent_number]"
agent_number++
spawnpos++
update_synd_icons_added(synd_mind)
var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in nuke_list
if(nuke)
nuke.r_code = nuke_code
return ..()
/datum/game_mode/proc/prepare_syndicate_leader(datum/mind/synd_mind, nuke_code)
var/leader_title = pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")
spawn(1)
nukeops_lastname = nukelastname(synd_mind.current)
NukeNameAssign(nukeops_lastname,syndicates) //allows time for the rest of the syndies to be chosen
synd_mind.current.real_name = "[syndicate_name()] [leader_title]"
synd_mind.current << "<B>You are the Syndicate [leader_title] for this mission. You are responsible for the distribution of telecrystals and your ID is the only one who can open the launch bay doors.</B>"
synd_mind.current << "<B>If you feel you are not up to this task, give your ID to another operative.</B>"
synd_mind.current << "<B>In your hand you will find a special item capable of triggering a greater challenge for your team. Examine it carefully and consult with your fellow operatives before activating it.</B>"
var/obj/item/device/nuclear_challenge/challenge = new /obj/item/device/nuclear_challenge
synd_mind.current.equip_to_slot_or_del(challenge, slot_r_hand)
var/list/foundIDs = synd_mind.current.search_contents_for(/obj/item/weapon/card/id)
if(foundIDs.len)
for(var/obj/item/weapon/card/id/ID in foundIDs)
ID.name = "lead agent card"
ID.access += access_syndicate_leader
else
message_admins("Warning: Nuke Ops spawned without access to leave their spawn area!")
var/obj/item/device/radio/headset/syndicate/alt/A = locate() in synd_mind.current
if(A)
A.command = TRUE
if(nuke_code)
var/obj/item/weapon/paper/P = new
P.info = "The nuclear authorization code is: <b>[nuke_code]</b>"
P.name = "nuclear bomb code"
var/mob/living/carbon/human/H = synd_mind.current
P.loc = H.loc
H.equip_to_slot_or_del(P, slot_r_hand, 0)
H.update_icons()
else
nuke_code = "code will be provided later"
return
/datum/game_mode/proc/forge_syndicate_objectives(datum/mind/syndicate)
var/datum/objective/nuclear/syndobj = new
syndobj.owner = syndicate
syndicate.objectives += syndobj
/datum/game_mode/proc/greet_syndicate(datum/mind/syndicate, you_are=1)
if(you_are)
syndicate.current << "<span class='notice'>You are a [syndicate_name()] agent!</span>"
var/obj_count = 1
for(var/datum/objective/objective in syndicate.objectives)
syndicate.current << "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
obj_count++
return
/datum/game_mode/proc/equip_syndicate(mob/living/carbon/human/synd_mob, telecrystals = TRUE)
synd_mob.set_species(/datum/species/human) //Plasamen burn up otherwise, and lizards are vulnerable to asimov AIs
if(telecrystals)
synd_mob.equipOutfit(/datum/outfit/syndicate)
else
synd_mob.equipOutfit(/datum/outfit/syndicate/no_crystals)
return 1
/datum/game_mode/nuclear/check_win()
if (nukes_left == 0)
return 1
return ..()
/datum/game_mode/proc/are_operatives_dead()
for(var/datum/mind/operative_mind in syndicates)
if (istype(operative_mind.current,/mob/living/carbon/human) && (operative_mind.current.stat!=2))
return 0
return 1
/datum/game_mode/nuclear/check_finished() //to be called by ticker
if(replacementmode && round_converted == 2)
return replacementmode.check_finished()
if((SSshuttle.emergency.mode == SHUTTLE_ENDGAME) || station_was_nuked)
return 1
if(are_operatives_dead())
if(bomb_set) //snaaaaaaaaaake! It's not over yet!
return 0
..()
/datum/game_mode/nuclear/declare_completion()
var/disk_rescued = 1
for(var/obj/item/weapon/disk/nuclear/D in poi_list)
if(!D.onCentcom())
disk_rescued = 0
break
var/crew_evacuated = (SSshuttle.emergency.mode == SHUTTLE_ENDGAME)
//var/operatives_are_dead = is_operatives_are_dead()
//nukes_left
//station_was_nuked
//derp //Used for tracking if the syndies actually haul the nuke to the station //no
//herp //Used for tracking if the syndies got the shuttle off of the z-level //NO, DON'T FUCKING NAME VARS LIKE THIS
if (!disk_rescued && station_was_nuked && !syndies_didnt_escape)
feedback_set_details("round_end_result","win - syndicate nuke")
world << "<FONT size = 3><B>Syndicate Major Victory!</B></FONT>"
world << "<B>[syndicate_name()] operatives have destroyed [station_name()]!</B>"
else if (!disk_rescued && station_was_nuked && syndies_didnt_escape)
feedback_set_details("round_end_result","halfwin - syndicate nuke - did not evacuate in time")
world << "<FONT size = 3><B>Total Annihilation</B></FONT>"
world << "<B>[syndicate_name()] operatives destroyed [station_name()] but did not leave the area in time and got caught in the explosion.</B> Next time, don't lose the disk!"
else if (!disk_rescued && !station_was_nuked && nuke_off_station && !syndies_didnt_escape)
feedback_set_details("round_end_result","halfwin - blew wrong station")
world << "<FONT size = 3><B>Crew Minor Victory</B></FONT>"
world << "<B>[syndicate_name()] operatives secured the authentication disk but blew up something that wasn't [station_name()].</B> Next time, don't lose the disk!"
else if (!disk_rescued && !station_was_nuked && nuke_off_station && syndies_didnt_escape)
feedback_set_details("round_end_result","halfwin - blew wrong station - did not evacuate in time")
world << "<FONT size = 3><B>[syndicate_name()] operatives have earned Darwin Award!</B></FONT>"
world << "<B>[syndicate_name()] operatives blew up something that wasn't [station_name()] and got caught in the explosion.</B> Next time, don't lose the disk!"
else if ((disk_rescued || SSshuttle.emergency.mode != SHUTTLE_ENDGAME) && are_operatives_dead())
feedback_set_details("round_end_result","loss - evacuation - disk secured - syndi team dead")
world << "<FONT size = 3><B>Crew Major Victory!</B></FONT>"
world << "<B>The Research Staff has saved the disc and killed the [syndicate_name()] Operatives</B>"
else if (disk_rescued)
feedback_set_details("round_end_result","loss - evacuation - disk secured")
world << "<FONT size = 3><B>Crew Major Victory</B></FONT>"
world << "<B>The Research Staff has saved the disc and stopped the [syndicate_name()] Operatives!</B>"
else if (!disk_rescued && are_operatives_dead())
feedback_set_details("round_end_result","halfwin - evacuation - disk not secured")
world << "<FONT size = 3><B>Neutral Victory!</B></FONT>"
world << "<B>The Research Staff failed to secure the authentication disk but did manage to kill most of the [syndicate_name()] Operatives!</B>"
else if (!disk_rescued && crew_evacuated)
feedback_set_details("round_end_result","halfwin - detonation averted")
world << "<FONT size = 3><B>Syndicate Minor Victory!</B></FONT>"
world << "<B>[syndicate_name()] operatives recovered the abandoned authentication disk but detonation of [station_name()] was averted.</B> Next time, don't lose the disk!"
else if (!disk_rescued && !crew_evacuated)
feedback_set_details("round_end_result","halfwin - interrupted")
world << "<FONT size = 3><B>Neutral Victory</B></FONT>"
world << "<B>Round was mysteriously interrupted!</B>"
..()
return
/datum/game_mode/proc/auto_declare_completion_nuclear()
if( syndicates.len || (ticker && istype(ticker.mode,/datum/game_mode/nuclear)) )
var/text = "<br><FONT size=3><B>The syndicate operatives were:</B></FONT>"
var/purchases = ""
var/TC_uses = 0
for(var/datum/mind/syndicate in syndicates)
text += printplayer(syndicate)
for(var/obj/item/device/uplink/H in uplinks)
if(H && H.owner && H.owner == syndicate.key)
TC_uses += H.spent_telecrystals
purchases += H.purchase_log
text += "<br>"
text += "(Syndicates used [TC_uses] TC) [purchases]"
if(TC_uses == 0 && station_was_nuked && !are_operatives_dead())
text += "<BIG><IMG CLASS=icon SRC=\ref['icons/BadAss.dmi'] ICONSTATE='badass'></BIG>"
world << text
return 1
/proc/nukelastname(mob/M) //--All praise goes to NEO|Phyte, all blame goes to DH, and it was Cindi-Kate's idea. Also praise Urist for copypasta ho.
var/randomname = pick(last_names)
var/newname = copytext(sanitize(input(M,"You are the nuke operative [pick("Czar", "Boss", "Commander", "Chief", "Kingpin", "Director", "Overlord")]. Please choose a last name for your family.", "Name change",randomname)),1,MAX_NAME_LEN)
if (!newname)
newname = randomname
else
if (newname == "Unknown" || newname == "floor" || newname == "wall" || newname == "rwall" || newname == "_")
M << "That name is reserved."
return nukelastname(M)
return capitalize(newname)
/proc/NukeNameAssign(lastname,list/syndicates)
for(var/datum/mind/synd_mind in syndicates)
var/mob/living/carbon/human/H = synd_mind.current
synd_mind.name = H.dna.species.random_name(H.gender,0,lastname)
synd_mind.current.real_name = synd_mind.name
return
/datum/outfit/syndicate
name = "Syndicate Operative - Basic"
uniform = /obj/item/clothing/under/syndicate
shoes = /obj/item/clothing/shoes/combat
gloves = /obj/item/clothing/gloves/combat
back = /obj/item/weapon/storage/backpack
ears = /obj/item/device/radio/headset/syndicate/alt
l_pocket = /obj/item/weapon/pinpointer/nukeop
id = /obj/item/weapon/card/id/syndicate
belt = /obj/item/weapon/gun/projectile/automatic/pistol
backpack_contents = list(/obj/item/weapon/storage/box/syndie=1)
var/tc = 25
/datum/outfit/syndicate/no_crystals
tc = 0
/datum/outfit/syndicate/post_equip(mob/living/carbon/human/H)
var/obj/item/device/radio/R = H.ears
R.set_frequency(SYND_FREQ)
R.freqlock = 1
if(tc)
var/obj/item/device/radio/uplink/nuclear/U = new(H)
U.hidden_uplink.owner = "[H.key]"
U.hidden_uplink.telecrystals = tc
H.equip_to_slot_or_del(U, slot_in_backpack)
var/obj/item/weapon/implant/weapons_auth/W = new/obj/item/weapon/implant/weapons_auth(H)
W.implant(H)
var/obj/item/weapon/implant/explosive/E = new/obj/item/weapon/implant/explosive(H)
E.implant(H)
H.faction |= "syndicate"
H.update_icons()
/datum/outfit/syndicate/full
name = "Syndicate Operative - Full Kit"
glasses = /obj/item/clothing/glasses/night
mask = /obj/item/clothing/mask/gas/syndicate
suit = /obj/item/clothing/suit/space/hardsuit/syndi
r_pocket = /obj/item/weapon/tank/internals/emergency_oxygen/engi
belt = /obj/item/weapon/storage/belt/military
r_hand = /obj/item/weapon/gun/projectile/automatic/shotgun/bulldog
backpack_contents = list(/obj/item/weapon/storage/box/syndie=1,\
/obj/item/weapon/tank/jetpack/oxygen/harness=1,\
/obj/item/weapon/gun/projectile/automatic/pistol=1)
/datum/outfit/syndicate/full/post_equip(mob/living/carbon/human/H)
..()
var/obj/item/clothing/suit/space/hardsuit/syndi/suit = H.wear_suit
suit.ToggleHelmet()
H.internal = H.r_store
@@ -0,0 +1,65 @@
#define CHALLENGE_TELECRYSTALS 280
#define CHALLENGE_TIME_LIMIT 3000
#define CHALLENGE_MIN_PLAYERS 50
#define CHALLENGE_SHUTTLE_DELAY 15000 // 25 minutes, so the ops have at least 5 minutes before the shuttle is callable.
/obj/item/device/nuclear_challenge
name = "Declaration of War (Challenge Mode)"
icon_state = "gangtool-red"
item_state = "walkietalkie"
desc = "Use to send a declaration of hostilities to the target, delaying your shuttle departure for 20 minutes while they prepare for your assault. \
Such a brazen move will attract the attention of powerful benefactors within the Syndicate, who will supply your team with a massive amount of bonus telecrystals. \
Must be used within five minutes, or your benefactors will lose interest."
var/declaring_war = 0
/obj/item/device/nuclear_challenge/attack_self(mob/living/user)
if(!check_allowed(user))
return
declaring_war = 1
var/are_you_sure = alert(user, "Consult your team carefully before you declare war on [station_name()]]. Are you sure you want to alert the enemy crew?", "Declare war?", "Yes", "No")
declaring_war = 0
if(are_you_sure == "No")
user << "On second thought, the element of surprise isn't so bad after all."
return
if(!check_allowed(user))
return
declaring_war = 1
var/war_declaration = "[user.real_name] has declared his intent to utterly destroy [station_name()] with a nuclear device, and dares the crew to try and stop them."
priority_announce(war_declaration, title = "Declaration of War", sound = 'sound/machines/Alarm.ogg')
user << "You've attracted the attention of powerful forces within the syndicate. A bonus bundle of telecrystals has been granted to your team. Great things await you if you complete the mission."
for(var/V in syndicate_shuttle_boards)
var/obj/item/weapon/circuitboard/computer/syndicate_shuttle/board = V
board.challenge = TRUE
var/obj/item/device/radio/uplink/nuclear/U = new(get_turf(user))
U.hidden_uplink.owner = "[user.key]"
U.hidden_uplink.telecrystals = CHALLENGE_TELECRYSTALS
U.hidden_uplink.gamemode = /datum/game_mode/nuclear
config.shuttle_refuel_delay = max(config.shuttle_refuel_delay, CHALLENGE_SHUTTLE_DELAY)
qdel(src)
/obj/item/device/nuclear_challenge/proc/check_allowed(mob/living/user)
if(declaring_war)
return 0
if(player_list.len < CHALLENGE_MIN_PLAYERS)
user << "The enemy crew is too small to be worth declaring war on."
return 0
if(user.z != ZLEVEL_CENTCOM)
user << "You have to be at your base to use this."
return 0
if(world.time-round_start_time > CHALLENGE_TIME_LIMIT)
user << "It's too late to declare hostilities. Your benefactors are already busy with other schemes. You'll have to make do with what you have on hand."
return 0
for(var/V in syndicate_shuttle_boards)
var/obj/item/weapon/circuitboard/computer/syndicate_shuttle/board = V
if(board.moved)
user << "The shuttle has already been moved! You have forfeit the right to declare war."
return 0
return 1
#undef CHALLENGE_TELECRYSTALS
#undef CHALLENGE_MIN_PLAYERS
#undef CHALLENGE_SHUTTLE_DELAY
+495
View File
@@ -0,0 +1,495 @@
#define NUKESTATE_INTACT 5
#define NUKESTATE_UNSCREWED 4
#define NUKESTATE_PANEL_REMOVED 3
#define NUKESTATE_WELDED 2
#define NUKESTATE_CORE_EXPOSED 1
#define NUKESTATE_CORE_REMOVED 0
#define NUKE_OFF_LOCKED 0
#define NUKE_OFF_UNLOCKED 1
#define NUKE_ON_TIMING 2
#define NUKE_ON_EXPLODING 3
var/bomb_set
/obj/machinery/nuclearbomb
name = "nuclear fission explosive"
desc = "You probably shouldn't stick around to see if this is armed."
icon = 'icons/obj/machines/nuke.dmi'
icon_state = "nuclearbomb_base"
density = 1
var/timeleft = 60
var/timing = 0
var/r_code = "ADMIN"
var/code = ""
var/yes_code = 0
var/safety = 1
var/obj/item/weapon/disk/nuclear/auth = null
use_power = 0
var/previous_level = ""
var/lastentered = ""
var/obj/item/nuke_core/core = null
var/deconstruction_state = NUKESTATE_INTACT
var/image/lights = null
var/image/interior = null
var/obj/effect/countdown/nuclearbomb/countdown
/obj/machinery/nuclearbomb/New()
..()
countdown = new(src)
nuke_list += src
core = new /obj/item/nuke_core(src)
STOP_PROCESSING(SSobj, core)
update_icon()
poi_list |= src
previous_level = get_security_level()
/obj/machinery/nuclearbomb/Destroy()
poi_list -= src
nuke_list -= src
qdel(countdown)
countdown = null
. = ..()
/obj/machinery/nuclearbomb/selfdestruct
name = "station self-destruct terminal"
desc = "For when it all gets too much to bear. Do not taunt."
icon = 'icons/obj/machines/nuke_terminal.dmi'
icon_state = "nuclearbomb_base"
anchored = 1 //stops it being moved
layer = MOB_LAYER
/obj/machinery/nuclearbomb/syndicate
/obj/machinery/nuclearbomb/syndicate/New()
var/obj/machinery/nuclearbomb/existing = locate("syndienuke")
if(existing)
qdel(src)
throw EXCEPTION("Attempted to spawn a syndicate nuke while one already exists at [existing.loc.x],[existing.loc.y],[existing.loc.z]")
return 0
tag = "syndienuke"
return ..()
/obj/machinery/nuclearbomb/attackby(obj/item/I, mob/user, params)
if (istype(I, /obj/item/weapon/disk/nuclear))
if(!user.drop_item())
return
I.loc = src
auth = I
add_fingerprint(user)
return
switch(deconstruction_state)
if(NUKESTATE_INTACT)
if(istype(I, /obj/item/weapon/screwdriver/nuke))
playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1)
user << "<span class='notice'>You start removing [src]'s front panel's screws...</span>"
if(do_after(user, 60/I.toolspeed,target=src))
deconstruction_state = NUKESTATE_UNSCREWED
user << "<span class='notice'>You remove the screws from [src]'s front panel.</span>"
update_icon()
return
if(NUKESTATE_UNSCREWED)
if(istype(I, /obj/item/weapon/crowbar))
user << "<span class='notice'>You start removing [src]'s front panel...</span>"
playsound(loc, 'sound/items/Crowbar.ogg', 100, 1)
if(do_after(user,30/I.toolspeed,target=src))
user << "<span class='notice'>You remove [src]'s front panel.</span>"
deconstruction_state = NUKESTATE_PANEL_REMOVED
update_icon()
return
if(NUKESTATE_PANEL_REMOVED)
if(istype(I, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/welder = I
playsound(loc, 'sound/items/Welder.ogg', 100, 1)
user << "<span class='notice'>You start cutting [src]'s inner plate...</span>"
if(welder.remove_fuel(1,user))
if(do_after(user,80/I.toolspeed,target=src))
user << "<span class='notice'>You cut [src]'s inner plate.</span>"
deconstruction_state = NUKESTATE_WELDED
update_icon()
return
if(NUKESTATE_WELDED)
if(istype(I, /obj/item/weapon/crowbar))
user << "<span class='notice'>You start prying off [src]'s inner plate...</span>"
playsound(loc, 'sound/items/Crowbar.ogg', 100, 1)
if(do_after(user,50/I.toolspeed,target=src))
user << "<span class='notice'>You pry off [src]'s inner plate. You can see the core's green glow!</span>"
deconstruction_state = NUKESTATE_CORE_EXPOSED
update_icon()
START_PROCESSING(SSobj, core)
return
if(NUKESTATE_CORE_EXPOSED)
if(istype(I, /obj/item/nuke_core_container))
var/obj/item/nuke_core_container/core_box = I
user << "<span class='notice'>You start loading the plutonium core into [core_box]...</span>"
if(do_after(user,50,target=src))
if(core_box.load(core, user))
user << "<span class='notice'>You load the plutonium core into [core_box].</span>"
deconstruction_state = NUKESTATE_CORE_REMOVED
update_icon()
core = null
else
user << "<span class='warning'>You fail to load the plutonium core into [core_box]. [core_box] has already been used!</span>"
return
if(istype(I, /obj/item/stack/sheet/metal))
var/obj/item/stack/sheet/metal/M = I
if(M.amount >= 20)
user << "<span class='notice'>You begin repairing [src]'s inner metal plate...</span>"
if(do_after(user, 100, target=src))
if(M.use(20))
user << "<span class='notice'>You repair [src]'s inner metal plate. The radiation is contained.</span>"
deconstruction_state = NUKESTATE_PANEL_REMOVED
STOP_PROCESSING(SSobj, core)
update_icon()
else
user << "<span class='warning'>You need more metal to do that!</span>"
else
user << "<span class='warning'>You need more metal to do that!</span>"
return
return ..()
/obj/machinery/nuclearbomb/proc/get_nuke_state()
if(timing < 0)
return NUKE_ON_EXPLODING
if(timing > 0)
return NUKE_ON_TIMING
if(safety)
return NUKE_OFF_LOCKED
else
return NUKE_OFF_UNLOCKED
/obj/machinery/nuclearbomb/update_icon()
if(deconstruction_state == NUKESTATE_INTACT)
switch(get_nuke_state())
if(NUKE_OFF_LOCKED, NUKE_OFF_UNLOCKED)
icon_state = "nuclearbomb_base"
update_icon_interior()
update_icon_lights()
if(NUKE_ON_TIMING)
cut_overlays()
icon_state = "nuclearbomb_timing"
if(NUKE_ON_EXPLODING)
cut_overlays()
icon_state = "nuclearbomb_exploding"
else
icon_state = "nuclearbomb_base"
update_icon_interior()
update_icon_lights()
/obj/machinery/nuclearbomb/proc/update_icon_interior()
overlays -= interior
switch(deconstruction_state)
if(NUKESTATE_UNSCREWED)
interior = image(icon,"panel-unscrewed")
if(NUKESTATE_PANEL_REMOVED)
interior = image(icon,"panel-removed")
if(NUKESTATE_WELDED)
interior = image(icon,"plate-welded")
if(NUKESTATE_CORE_EXPOSED)
interior = image(icon,"plate-removed")
if(NUKESTATE_CORE_REMOVED)
interior = image(icon,"core-removed")
if(NUKESTATE_INTACT)
interior = null
add_overlay(interior)
/obj/machinery/nuclearbomb/proc/update_icon_lights()
overlays -= lights
switch(get_nuke_state())
if(NUKE_OFF_LOCKED)
lights = null
if(NUKE_OFF_UNLOCKED)
lights = image(icon,"lights-safety")
if(NUKE_ON_TIMING)
lights = image(icon,"lights-timing")
if(NUKE_ON_EXPLODING)
lights = image(icon,"lights-exploding")
add_overlay(lights)
/obj/machinery/nuclearbomb/process()
if (timing > 0)
countdown.start()
bomb_set = 1 //So long as there is one nuke timing, it means one nuke is armed.
timeleft--
if (timeleft <= 0)
explode()
else
var/volume = (timeleft <= 20 ? 30 : 5)
playsound(loc, 'sound/items/timer.ogg', volume, 0)
for(var/mob/M in viewers(1, src))
if ((M.client && M.machine == src))
attack_hand(M)
else
countdown.stop()
/obj/machinery/nuclearbomb/attack_paw(mob/user)
return attack_hand(user)
/obj/machinery/nuclearbomb/attack_ai(mob/user)
return
/obj/machinery/nuclearbomb/attack_hand(mob/user)
user.set_machine(src)
var/dat = text("<TT>\nAuth. Disk: <A href='?src=\ref[];auth=1'>[]</A><HR>", src, (auth ? "++++++++++" : "----------"))
if (auth)
if (yes_code)
dat += text("\n<B>Status</B>: []-[]<BR>\n<B>Timer</B>: []<BR>\n<BR>\nTimer: [] <A href='?src=\ref[];timer=1'>Toggle</A><BR>\nTime: <A href='?src=\ref[];time=-10'>-</A> <A href='?src=\ref[];time=-1'>-</A> [] <A href='?src=\ref[];time=1'>+</A> <A href='?src=\ref[];time=10'>+</A><BR>\n<BR>\nSafety: [] <A href='?src=\ref[];safety=1'>Toggle</A><BR>\nAnchor: [] <A href='?src=\ref[];anchor=1'>Toggle</A><BR>\n", (timing ? "Func/Set" : "Functional"), (safety ? "Safe" : "Engaged"), timeleft, (timing ? "On" : "Off"), src, src, src, timeleft, src, src, (safety ? "On" : "Off"), src, (anchored ? "Engaged" : "Off"), src)
else
dat += text("\n<B>Status</B>: Auth. S2-[]<BR>\n<B>Timer</B>: []<BR>\n<BR>\nTimer: [] Toggle<BR>\nTime: - - [] + +<BR>\n<BR>\n[] Safety: Toggle<BR>\nAnchor: [] Toggle<BR>\n", (safety ? "Safe" : "Engaged"), timeleft, (timing ? "On" : "Off"), timeleft, (safety ? "On" : "Off"), (anchored ? "Engaged" : "Off"))
else
if (timing)
dat += text("\n<B>Status</B>: Set-[]<BR>\n<B>Timer</B>: []<BR>\n<BR>\nTimer: [] Toggle<BR>\nTime: - - [] + +<BR>\n<BR>\nSafety: [] Toggle<BR>\nAnchor: [] Toggle<BR>\n", (safety ? "Safe" : "Engaged"), timeleft, (timing ? "On" : "Off"), timeleft, (safety ? "On" : "Off"), (anchored ? "Engaged" : "Off"))
else
dat += text("\n<B>Status</B>: Auth. S1-[]<BR>\n<B>Timer</B>: []<BR>\n<BR>\nTimer: [] Toggle<BR>\nTime: - - [] + +<BR>\n<BR>\nSafety: [] Toggle<BR>\nAnchor: [] Toggle<BR>\n", (safety ? "Safe" : "Engaged"), timeleft, (timing ? "On" : "Off"), timeleft, (safety ? "On" : "Off"), (anchored ? "Engaged" : "Off"))
var/message = "AUTH"
if (auth)
message = text("[]", code)
if (yes_code)
message = "*****"
dat += text("<HR>\n>[]<BR>\n<A href='?src=\ref[];type=1'>1</A><A href='?src=\ref[];type=2'>2</A><A href='?src=\ref[];type=3'>3</A><BR>\n<A href='?src=\ref[];type=4'>4</A><A href='?src=\ref[];type=5'>5</A><A href='?src=\ref[];type=6'>6</A><BR>\n<A href='?src=\ref[];type=7'>7</A><A href='?src=\ref[];type=8'>8</A><A href='?src=\ref[];type=9'>9</A><BR>\n<A href='?src=\ref[];type=R'>R</A><A href='?src=\ref[];type=0'>0</A><A href='?src=\ref[];type=E'>E</A><BR>\n</TT>", message, src, src, src, src, src, src, src, src, src, src, src, src)
var/datum/browser/popup = new(user, "nuclearbomb", name, 300, 400)
popup.set_content(dat)
popup.open()
/obj/machinery/nuclearbomb/Topic(href, href_list)
if(..())
return
usr.set_machine(src)
if (href_list["auth"])
if (auth)
auth.loc = loc
yes_code = 0
auth = null
else
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/disk/nuclear))
usr.drop_item()
I.loc = src
auth = I
if (auth)
if (href_list["type"])
if (href_list["type"] == "E")
if (code == r_code)
yes_code = 1
code = null
else
code = "ERROR"
else
if (href_list["type"] == "R")
yes_code = 0
code = null
else
lastentered = text("[]", href_list["type"])
if (text2num(lastentered) == null)
var/turf/LOC = get_turf(usr)
message_admins("[key_name_admin(usr)] (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[usr]'>FLW</A>) tried to exploit a nuclear bomb by entering non-numerical codes: <a href='?_src_=vars;Vars=\ref[src]'>[lastentered]</a> ! ([LOC ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[LOC.x];Y=[LOC.y];Z=[LOC.z]'>JMP</a>" : "null"])", 0)
log_admin("EXPLOIT : [key_name(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered] !")
else
code += lastentered
if (length(code) > 5)
code = "ERROR"
if (yes_code)
if (href_list["time"])
var/time = text2num(href_list["time"])
timeleft += time
timeleft = min(max(round(timeleft), 60), 600)
if (href_list["timer"])
set_active()
if (href_list["safety"])
set_safety()
if (href_list["anchor"])
set_anchor()
add_fingerprint(usr)
for(var/mob/M in viewers(1, src))
if ((M.client && M.machine == src))
attack_hand(M)
/obj/machinery/nuclearbomb/proc/set_anchor()
if(!isinspace())
anchored = !anchored
else
usr << "<span class='warning'>There is nothing to anchor to!</span>"
/obj/machinery/nuclearbomb/proc/set_safety()
safety = !safety
if(safety)
if(timing)
set_security_level(previous_level)
timing = 0
bomb_set = 0
update_icon()
/obj/machinery/nuclearbomb/proc/set_active()
if(safety && !bomb_set)
usr << "<span class='danger'>The safety is still on.</span>"
return
timing = !timing
if(timing)
previous_level = get_security_level()
bomb_set = 1
set_security_level("delta")
else
bomb_set = 0
set_security_level(previous_level)
update_icon()
/obj/machinery/nuclearbomb/ex_act(severity, target)
return
/obj/machinery/nuclearbomb/blob_act(obj/effect/blob/B)
if (timing == -1)
return
else
return ..()
#define NUKERANGE 127
/obj/machinery/nuclearbomb/proc/explode()
if (safety)
timing = 0
return
timing = -1
yes_code = 0
safety = 1
update_icon()
for(var/mob/M in player_list)
M << 'sound/machines/Alarm.ogg'
if (ticker && ticker.mode)
ticker.mode.explosion_in_progress = 1
sleep(100)
if(!core)
ticker.station_explosion_cinematic(3,"no_core")
ticker.mode.explosion_in_progress = 0
return
enter_allowed = 0
var/off_station = 0
var/turf/bomb_location = get_turf(src)
if(bomb_location && (bomb_location.z == ZLEVEL_STATION))
var/area/A = get_area(bomb_location)
if(istype(A, /area/space))
off_station = 1
if((bomb_location.x < (128-NUKERANGE)) || (bomb_location.x > (128+NUKERANGE)) || (bomb_location.y < (128-NUKERANGE)) || (bomb_location.y > (128+NUKERANGE)))
off_station = 1
else
off_station = 2
if(ticker.mode && ticker.mode.name == "nuclear emergency")
var/obj/docking_port/mobile/Shuttle = SSshuttle.getShuttle("syndicate")
ticker.mode:syndies_didnt_escape = (Shuttle && Shuttle.z == ZLEVEL_CENTCOM) ? 0 : 1
ticker.mode:nuke_off_station = off_station
ticker.station_explosion_cinematic(off_station,null)
if(ticker.mode)
ticker.mode.explosion_in_progress = 0
if(ticker.mode.name == "nuclear emergency")
ticker.mode:nukes_left --
else
world << "<B>The station was destoyed by the nuclear blast!</B>"
ticker.mode.station_was_nuked = (off_station<2) //offstation==1 is a draw. the station becomes irradiated and needs to be evacuated.
//kinda shit but I couldn't get permission to do what I wanted to do.
if(!ticker.mode.check_finished())//If the mode does not deal with the nuke going off so just reboot because everyone is stuck as is
spawn()
world.Reboot("Station destroyed by Nuclear Device.", "end_error", "nuke - unhandled ending")
/*
This is here to make the tiles around the station mininuke change when it's armed.
*/
/obj/machinery/nuclearbomb/selfdestruct/proc/SetTurfs()
if(loc == initial(loc))
for(var/N in nuke_tiles)
var/turf/open/floor/T = N
T.icon_state = (timing ? "rcircuitanim" : T.icon_regular_floor)
/obj/machinery/nuclearbomb/selfdestruct/set_anchor()
return
/obj/machinery/nuclearbomb/selfdestruct/set_active()
..()
SetTurfs()
/obj/machinery/nuclearbomb/selfdestruct/set_safety()
..()
SetTurfs()
//==========DAT FUKKEN DISK===============
/obj/item/weapon/disk
icon = 'icons/obj/module.dmi'
w_class = 1
item_state = "card-id"
icon_state = "datadisk0"
/obj/item/weapon/disk/nuclear
name = "nuclear authentication disk"
desc = "Better keep this safe."
icon_state = "nucleardisk"
/obj/item/weapon/disk/nuclear/New()
..()
poi_list |= src
START_PROCESSING(SSobj, src)
/obj/item/weapon/disk/nuclear/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is \
going delta! It looks like they're comitting suicide.</span>")
playsound(user.loc, 'sound/machines/Alarm.ogg', 50, -1, 1)
var/end_time = world.time + 100
var/orig_color = user.color
while(world.time < end_time)
if(!user)
return
user.color = RANDOM_COLOUR
sleep(1)
user.color = orig_color
user.visible_message("<span class='suicide'>[user] was destroyed \
by the nuclear blast!</span>")
return OXYLOSS
/obj/item/weapon/disk/nuclear/process()
var/turf/diskturf = get_turf(src)
if(diskturf && (diskturf.z == ZLEVEL_CENTCOM || diskturf.z == ZLEVEL_STATION))
return
else
get(src, /mob) << "<span class='danger'>You can't help but feel that you just lost something back there...</span>"
var/turf/targetturf = relocate()
message_admins("[src] has been moved out of bounds in ([diskturf ? "[diskturf.x], [diskturf.y] ,[diskturf.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[diskturf.x];Y=[diskturf.y];Z=[diskturf.z]'>JMP</a>":"nonexistent location"]). Moving it to ([targetturf.x], [targetturf.y], [targetturf.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[targetturf.x];Y=[targetturf.y];Z=[targetturf.z]'>JMP</a>).")
log_game("[src] has been moved out of bounds in ([diskturf ? "[diskturf.x], [diskturf.y] ,[diskturf.z]":"nonexistent location"]). Moving it to ([targetturf.x], [targetturf.y], [targetturf.z]).")
/obj/item/weapon/disk/nuclear/proc/relocate()
var/targetturf = find_safe_turf(ZLEVEL_STATION)
if(!targetturf)
if(blobstart.len > 0)
targetturf = get_turf(pick(blobstart))
else
throw EXCEPTION("Unable to find a blobstart landmark")
if(ismob(loc))
var/mob/M = loc
M.remove_from_mob(src)
if(istype(loc, /obj/item/weapon/storage))
var/obj/item/weapon/storage/S = loc
S.remove_from_storage(src, targetturf)
// move the disc, so ghosts remain orbiting it even if it's "destroyed"
forceMove(targetturf)
return targetturf
/obj/item/weapon/disk/nuclear/Destroy(force)
var/turf/diskturf = get_turf(src)
if(force)
message_admins("[src] has been !!force deleted!! in ([diskturf ? "[diskturf.x], [diskturf.y] ,[diskturf.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[diskturf.x];Y=[diskturf.y];Z=[diskturf.z]'>JMP</a>":"nonexistent location"]).")
log_game("[src] has been !!force deleted!! in ([diskturf ? "[diskturf.x], [diskturf.y] ,[diskturf.z]":"nonexistent location"]).")
poi_list -= src
STOP_PROCESSING(SSobj, src)
return ..()
var/turf/targetturf = relocate()
message_admins("[src] has been destroyed in ([diskturf ? "[diskturf.x], [diskturf.y] ,[diskturf.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[diskturf.x];Y=[diskturf.y];Z=[diskturf.z]'>JMP</a>":"nonexistent location"]). Moving it to ([targetturf.x], [targetturf.y], [targetturf.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[targetturf.x];Y=[targetturf.y];Z=[targetturf.z]'>JMP</a>).")
log_game("[src] has been destroyed in ([diskturf ? "[diskturf.x], [diskturf.y] ,[diskturf.z]":"nonexistent location"]). Moving it to ([targetturf.x], [targetturf.y], [targetturf.z]).")
return QDEL_HINT_LETMELIVE //Cancel destruction unless forced
+297
View File
@@ -0,0 +1,297 @@
/obj/item/weapon/pinpointer
name = "pinpointer"
icon = 'icons/obj/device.dmi'
icon_state = "pinoff"
flags = CONDUCT
slot_flags = SLOT_BELT
w_class = 2
item_state = "electronic"
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=500)
var/obj/item/weapon/disk/nuclear/the_disk = null
var/active = 0
/obj/item/weapon/pinpointer/New()
..()
pinpointer_list += src
/obj/item/weapon/pinpointer/Destroy()
active = 0
pinpointer_list -= src
return ..()
/obj/item/weapon/pinpointer/attack_self()
if(!active)
active = 1
workdisk()
usr << "<span class='notice'>You activate the pinpointer.</span>"
else
active = 0
icon_state = "pinoff"
usr << "<span class='notice'>You deactivate the pinpointer.</span>"
/obj/item/weapon/pinpointer/proc/scandisk()
if(!the_disk)
the_disk = locate()
/obj/item/weapon/pinpointer/proc/point_at(atom/target, spawnself = 1)
if(!active)
return
if(!target)
icon_state = "pinonnull"
return
var/turf/T = get_turf(target)
var/turf/L = get_turf(src)
if(T.z != L.z)
icon_state = "pinonnull"
else
setDir(get_dir(L, T))
switch(get_dist(L, T))
if(-1)
icon_state = "pinondirect"
if(1 to 8)
icon_state = "pinonclose"
if(9 to 16)
icon_state = "pinonmedium"
if(16 to INFINITY)
icon_state = "pinonfar"
if(spawnself)
spawn(5)
.()
/obj/item/weapon/pinpointer/proc/workdisk()
scandisk()
point_at(the_disk, 0)
spawn(5)
.()
/obj/item/weapon/pinpointer/examine(mob/user)
..()
for(var/obj/machinery/nuclearbomb/bomb in machines)
if(bomb.timing)
user << "Extreme danger. Arming signal detected. Time remaining: [bomb.timeleft]"
/obj/item/weapon/pinpointer/advpinpointer
name = "advanced pinpointer"
icon = 'icons/obj/device.dmi'
desc = "A larger version of the normal pinpointer, this unit features a helpful quantum entanglement detection system to locate various objects that do not broadcast a locator signal."
var/mode = 0 // Mode 0 locates disk, mode 1 locates coordinates.
var/turf/location = null
var/obj/target = null
/obj/item/weapon/pinpointer/advpinpointer/attack_self()
if(!active)
active = 1
if(mode == 0)
workdisk()
if(mode == 1)
point_at(location)
if(mode == 2)
point_at(target)
usr << "<span class='notice'>You activate the pinpointer.</span>"
else
active = 0
icon_state = "pinoff"
usr << "<span class='notice'>You deactivate the pinpointer.</span>"
/obj/item/weapon/pinpointer/advpinpointer/verb/toggle_mode()
set category = "Object"
set name = "Toggle Pinpointer Mode"
set src in view(1)
if(usr.stat || usr.restrained() || !usr.canmove)
return
active = 0
icon_state = "pinoff"
target=null
location = null
switch(alert("Please select the mode you want to put the pinpointer in.", "Pinpointer Mode Select", "Location", "Disk Recovery", "Other Signature"))
if("Location")
mode = 1
var/locationx = input(usr, "Please input the x coordinate to search for.", "Location?" , "") as num
if(!locationx || !(usr in view(1,src)))
return
var/locationy = input(usr, "Please input the y coordinate to search for.", "Location?" , "") as num
if(!locationy || !(usr in view(1,src)))
return
var/turf/Z = get_turf(src)
location = locate(locationx,locationy,Z.z)
usr << "<span class='notice'>You set the pinpointer to locate [locationx],[locationy]</span>"
return attack_self()
if("Disk Recovery")
mode = 0
return attack_self()
if("Other Signature")
mode = 2
switch(alert("Search for item signature or DNA fragment?" , "Signature Mode Select" , "" , "Item" , "DNA"))
if("Item")
var/targetitem = input("Select item to search for.", "Item Mode Select","") as null|anything in possible_items
if(!targetitem)
return
target=locate(possible_items[targetitem])
if(!target)
usr << "<span class='warning'>Failed to locate [targetitem]!</span>"
return
usr << "<span class='notice'>You set the pinpointer to locate [targetitem].</span>"
if("DNA")
var/DNAstring = input("Input DNA string to search for." , "Please Enter String." , "")
if(!DNAstring)
return
for(var/mob/living/carbon/C in mob_list)
if(!C.dna)
continue
if(C.dna.unique_enzymes == DNAstring)
target = C
break
return attack_self()
///////////////////////
//nuke op pinpointers//
///////////////////////
/obj/item/weapon/pinpointer/nukeop
var/mode = 0 //Mode 0 locates disk, mode 1 locates the shuttle
var/obj/docking_port/mobile/home
/obj/item/weapon/pinpointer/nukeop/attack_self(mob/user)
if(!active)
active = 1
var/mode_text = "Authentication Disk Locator mode"
if(!mode)
workdisk()
else
mode_text = "Shuttle Locator mode"
worklocation()
user << "<span class='notice'>You activate the pinpointer([mode_text]).</span>"
else
active = 0
icon_state = "pinoff"
user << "<span class='notice'>You deactivate the pinpointer.</span>"
/obj/item/weapon/pinpointer/nukeop/workdisk()
if(!active) return
if(mode) //Check in case the mode changes while operating
worklocation()
return
if(bomb_set) //If the bomb is set, lead to the shuttle
mode = 1 //Ensures worklocation() continues to work
worklocation()
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1) //Plays a beep
visible_message("Shuttle Locator mode actived.") //Lets the mob holding it know that the mode has changed
return //Get outta here
scandisk()
if(!the_disk)
icon_state = "pinonnull"
return
setDir(get_dir(src, the_disk))
switch(get_dist(src, the_disk))
if(0)
icon_state = "pinondirect"
if(1 to 8)
icon_state = "pinonclose"
if(9 to 16)
icon_state = "pinonmedium"
if(16 to INFINITY)
icon_state = "pinonfar"
spawn(5) .()
/obj/item/weapon/pinpointer/nukeop/proc/worklocation()
if(!active)
return
if(!mode)
workdisk()
return
if(!bomb_set)
mode = 0
workdisk()
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
visible_message("<span class='notice'>Authentication Disk Locator mode actived.</span>")
return
if(!home)
home = SSshuttle.getShuttle("syndicate")
if(!home)
icon_state = "pinonnull"
return
if(loc.z != home.z) //If you are on a different z-level from the shuttle
icon_state = "pinonnull"
else
setDir(get_dir(src, home))
switch(get_dist(src, home))
if(0)
icon_state = "pinondirect"
if(1 to 8)
icon_state = "pinonclose"
if(9 to 16)
icon_state = "pinonmedium"
if(16 to INFINITY)
icon_state = "pinonfar"
spawn(5)
.()
/obj/item/weapon/pinpointer/operative
name = "operative pinpointer"
icon = 'icons/obj/device.dmi'
desc = "A pinpointer that leads to the first Syndicate operative detected."
var/mob/living/carbon/nearest_op = null
/obj/item/weapon/pinpointer/operative/attack_self()
if(!usr.mind || !(usr.mind in ticker.mode.syndicates))
usr << "<span class='danger'>AUTHENTICATION FAILURE. ACCESS DENIED.</span>"
return 0
if(!active)
active = 1
workop()
usr << "<span class='notice'>You activate the pinpointer.</span>"
else
active = 0
icon_state = "pinoff"
usr << "<span class='notice'>You deactivate the pinpointer.</span>"
/obj/item/weapon/pinpointer/operative/proc/scan_for_ops()
if(active)
nearest_op = null //Resets nearest_op every time it scans
var/closest_distance = 1000
for(var/mob/living/carbon/M in mob_list)
if(M.mind && (M.mind in ticker.mode.syndicates))
if(get_dist(M, get_turf(src)) < closest_distance) //Actually points toward the nearest op, instead of a random one like it used to
nearest_op = M
/obj/item/weapon/pinpointer/operative/proc/workop()
if(active)
scan_for_ops()
point_at(nearest_op, 0)
spawn(5)
.()
else
return 0
/obj/item/weapon/pinpointer/operative/examine(mob/user)
..()
if(active)
if(nearest_op)
user << "Nearest operative detected is <i>[nearest_op.real_name].</i>"
else
user << "No operatives detected within scanning range."