Merge pull request #7489 from Citadel-Station-13/nanites

Nanites port
This commit is contained in:
deathride58
2018-09-03 13:47:28 -04:00
committed by GitHub
109 changed files with 5816 additions and 3795 deletions
+13
View File
@@ -589,6 +589,10 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "Engineering Storage"
icon_state = "engi_storage"
/area/engine/storage_shared
name = "Shared Engineering Storage"
icon_state = "engi_storage"
/area/engine/transit_tube
name = "Transit Tube"
icon_state = "transit_tube"
@@ -1035,6 +1039,11 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "Toxins Mixing Lab"
icon_state = "toxmix"
/area/science/mixing/chamber
name = "Toxins Mixing Chamber"
icon_state = "toxmix"
valid_territory = FALSE
/area/science/misc_lab
name = "Testing Lab"
icon_state = "toxmisc"
@@ -1087,6 +1096,10 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
name = "Abandoned Research Lab"
icon_state = "medresearch"
/area/science/nanite
name = "Nanite Lab"
icon_state = "toxmisc"
//Storage
/area/storage/tools
+2 -1
View File
@@ -482,11 +482,12 @@
if(spin)
SpinAnimation(5, 1)
SEND_SIGNAL(src, COMSIG_MOVABLE_THROW, TT, spin)
SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_THROW, TT, spin) //CITADEL - THIS IS BORKED. PENDING SYNC.
SSthrowing.processing[src] = TT
if (SSthrowing.state == SS_PAUSED && length(SSthrowing.currentrun))
SSthrowing.currentrun[src] = TT
TT.tick()
SEND_SIGNAL(src, COMSIG_MOVABLE_POST_THROW, TT, spin)
/atom/movable/proc/handle_buckled_mob_movement(newloc,direct)
for(var/m in buckled_mobs)
+28 -10
View File
@@ -18,7 +18,7 @@
/datum/atom_hud/data
/datum/atom_hud/data/human/medical
hud_icons = list(STATUS_HUD, HEALTH_HUD)
hud_icons = list(STATUS_HUD, HEALTH_HUD, NANITE_HUD)
/datum/atom_hud/data/human/medical/basic
@@ -47,15 +47,15 @@
hud_icons = list(ID_HUD)
/datum/atom_hud/data/human/security/advanced
hud_icons = list(ID_HUD, IMPTRACK_HUD, IMPLOYAL_HUD, IMPCHEM_HUD, WANTED_HUD)
hud_icons = list(ID_HUD, IMPTRACK_HUD, IMPLOYAL_HUD, IMPCHEM_HUD, WANTED_HUD, NANITE_HUD)
/datum/atom_hud/data/diagnostic
/datum/atom_hud/data/diagnostic/basic
hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_CIRCUIT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD)
hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_CIRCUIT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_NANITE_FULL_HUD)
/datum/atom_hud/data/diagnostic/advanced
hud_icons = list (DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_CIRCUIT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_PATH_HUD)
hud_icons = list(DIAG_HUD, DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_BOT_HUD, DIAG_CIRCUIT_HUD, DIAG_TRACK_HUD, DIAG_AIRLOCK_HUD, DIAG_NANITE_FULL_HUD, DIAG_PATH_HUD)
/datum/atom_hud/data/bot_path
hud_icons = list(DIAG_PATH_HUD)
@@ -65,6 +65,16 @@
/datum/atom_hud/sentient_disease
hud_icons = list(SENTIENT_DISEASE_HUD)
/*
/datum/atom_hud/ai_detector
hud_icons = list(AI_DETECT_HUD)
/datum/atom_hud/ai_detector/add_hud_to(mob/M)
..()
if(M && (hudusers.len == 1))
for(var/V in GLOB.aiEyes)
var/mob/camera/aiEye/E = V
E.update_ai_detect_hud()*/
/* MED/SEC/DIAG HUD HOOKS */
@@ -216,7 +226,7 @@
holder.icon_state = "hud[ckey(wear_id.GetJobName())]"
sec_hud_set_security_status()
/mob/living/carbon/human/proc/sec_hud_set_implants()
/mob/living/proc/sec_hud_set_implants()
var/image/holder
for(var/i in list(IMPTRACK_HUD, IMPLOYAL_HUD, IMPCHEM_HUD))
holder = hud_list[i]
@@ -227,16 +237,16 @@
var/icon/IC = icon(icon, icon_state, dir)
holder.pixel_y = IC.Height() - world.icon_size
holder.icon_state = "hud_imp_tracking"
else if(istype(I, /obj/item/implant/mindshield))
holder = hud_list[IMPLOYAL_HUD]
var/icon/IC = icon(icon, icon_state, dir)
holder.pixel_y = IC.Height() - world.icon_size
holder.icon_state = "hud_imp_loyal"
else if(istype(I, /obj/item/implant/chem))
holder = hud_list[IMPCHEM_HUD]
var/icon/IC = icon(icon, icon_state, dir)
holder.pixel_y = IC.Height() - world.icon_size
holder.icon_state = "hud_imp_chem"
if(has_trait(TRAIT_MINDSHIELD))
holder = hud_list[IMPLOYAL_HUD]
var/icon/IC = icon(icon, icon_state, dir)
holder.pixel_y = IC.Height() - world.icon_size
holder.icon_state = "hud_imp_loyal"
/mob/living/carbon/human/proc/sec_hud_set_security_status()
var/image/holder = hud_list[WANTED_HUD]
@@ -265,6 +275,14 @@
Diagnostic HUDs!
************************************************/
/mob/living/proc/hud_set_nanite_indicator()
var/image/holder = hud_list[NANITE_HUD]
var/icon/I = icon(icon, icon_state, dir)
holder.pixel_y = I.Height() - world.icon_size
holder.icon_state = null
if(src in SSnanites.nanite_monitored_mobs)
holder.icon_state = "nanite_ping"
//For Diag health and cell bars!
/proc/RoundDiagBar(value)
switch(value * 100)
+5 -1
View File
@@ -59,8 +59,12 @@ Credit where due:
return FALSE
else
return FALSE
if(iscultist(M) || isconstruct(M) || M.isloyal() || ispAI(M))
if(iscultist(M) || isconstruct(M) || ispAI(M))
return FALSE
if(isliving(M))
var/mob/living/L = M
if(L.has_trait(TRAIT_MINDSHIELD))
return FALSE
if(ishuman(M) || isbrain(M) || isguardian(M) || issilicon(M) || isclockmob(M) || istype(M, /mob/living/simple_animal/drone/cogscarab) || istype(M, /mob/camera/eminence))
return TRUE
return FALSE
+1 -1
View File
@@ -26,7 +26,7 @@
return FALSE
else
return FALSE
if(M.isloyal() || issilicon(M) || isbot(M) || isdrone(M) || is_servant_of_ratvar(M) || !M.client)
if(M.has_trait(TRAIT_MINDSHIELD) || issilicon(M) || isbot(M) || isdrone(M) || is_servant_of_ratvar(M) || !M.client)
return FALSE //can't convert machines, shielded, braindead, or ratvar's dogs
return TRUE
+9 -6
View File
@@ -120,14 +120,17 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
var/life_status
for(var/mob/living/carbon/human/H in GLOB.carbon_list)
var/nanite_sensors = FALSE
if(H in SSnanites.nanite_monitored_mobs)
nanite_sensors = TRUE
// Check if their z-level is correct and if they are wearing a uniform.
// Accept H.z==0 as well in case the mob is inside an object.
if ((H.z == 0 || H.z == z) && istype(H.w_uniform, /obj/item/clothing/under))
if ((H.z == 0 || H.z == z) && istype(H.w_uniform, /obj/item/clothing/under) || nanite_sensors)
U = H.w_uniform
// Are the suit sensors on?
if ((U.has_sensor > 0) && U.sensor_mode)
pos = H.z == 0 || U.sensor_mode == SENSOR_COORDS ? get_turf(H) : null
if (nanite_sensors || ((U.has_sensor > 0) && U.sensor_mode))
pos = H.z == 0 || (nanite_sensors || U.sensor_mode == SENSOR_COORDS) ? get_turf(H) : null
// Special case: If the mob is inside an object confirm the z-level on turf level.
if (H.z == 0 && (!pos || pos.z != z))
@@ -144,12 +147,12 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
assignment = ""
ijob = 80
if (U.sensor_mode >= SENSOR_LIVING)
if (nanite_sensors || U.sensor_mode >= SENSOR_LIVING)
life_status = (!H.stat ? TRUE : FALSE)
else
life_status = null
if (U.sensor_mode >= SENSOR_VITALS)
if (nanite_sensors || U.sensor_mode >= SENSOR_VITALS)
oxydam = round(H.getOxyLoss(),1)
toxdam = round(H.getToxLoss(),1)
burndam = round(H.getFireLoss(),1)
@@ -160,7 +163,7 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
burndam = null
brutedam = null
if (U.sensor_mode >= SENSOR_COORDS)
if (nanite_sensors || U.sensor_mode >= SENSOR_COORDS)
if (!pos)
pos = get_turf(H)
area = get_area_name(H, TRUE)
+4 -1
View File
@@ -180,7 +180,7 @@
break
if(component_check)
P.play_tool_sound(src)
var/obj/machinery/new_machine = new circuit.build_path(loc, 1)
var/obj/machinery/new_machine = new circuit.build_path(loc)
new_machine.setAnchored(anchored)
new_machine.on_construction()
for(var/obj/O in new_machine.component_parts)
@@ -189,6 +189,9 @@
for(var/obj/O in src)
O.moveToNullspace()
new_machine.component_parts += O
if(new_machine.circuit)
QDEL_NULL(new_machine.circuit)
new_machine.circuit = circuit
circuit.moveToNullspace()
new_machine.RefreshParts()
qdel(src)
@@ -23,6 +23,7 @@
flags_1 |= HEAR_1
/obj/machinery/door/password/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
. = ..()
if(!density || !voice_activated || radio_freq)
return
if(findtext(raw_message,password))
+1
View File
@@ -408,6 +408,7 @@ Possible to do for anyone motivated enough:
/*This is the proc for special two-way communication between AI and holopad/people talking near holopad.
For the other part of the code, check silicon say.dm. Particularly robot talk.*/
/obj/machinery/holopad/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
. = ..()
if(speaker && LAZYLEN(masters) && !radio_freq)//Master is mostly a safety in case lag hits or something. Radio_freq so AIs dont hear holopad stuff through radios.
for(var/mob/living/silicon/ai/master in masters)
if(masters[master] && speaker != master)
@@ -485,7 +485,7 @@
threatcount += 4
if(shoot_unloyal)
if (!perp.isloyal())
if (!perp.has_trait(TRAIT_MINDSHIELD))
threatcount += 4
return threatcount
+1
View File
@@ -402,6 +402,7 @@
return
/obj/mecha/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
. = ..()
if(speaker == occupant)
if(radio.broadcasting)
radio.talk_into(speaker, text, , spans, message_language)
@@ -342,3 +342,11 @@
/obj/item/circuitboard/computer/sat_control
name = "Satellite Network Control (Computer Board)"
build_path = /obj/machinery/computer/sat_control
/obj/item/circuitboard/computer/nanite_chamber_control
name = "Nanite Chamber Control (Computer Board)"
build_path = /obj/machinery/computer/nanite_chamber_control
/obj/item/circuitboard/computer/nanite_cloud_controller
name = "Nanite Cloud Control (Computer Board)"
build_path = /obj/machinery/computer/nanite_cloud_controller
@@ -741,6 +741,47 @@
/obj/item/stock_parts/manipulator = 2,
/obj/item/stock_parts/micro_laser = 2)
/obj/item/circuitboard/machine/nanite_chamber
name = "Nanite Chamber (Machine Board)"
build_path = /obj/machinery/nanite_chamber
req_components = list(
/obj/item/stock_parts/scanning_module = 2,
/obj/item/stock_parts/micro_laser = 2,
/obj/item/stock_parts/manipulator = 1)
/obj/item/circuitboard/machine/public_nanite_chamber
name = "Public Nanite Chamber (Machine Board)"
build_path = /obj/machinery/public_nanite_chamber
var/cloud_id = 1
req_components = list(
/obj/item/stock_parts/micro_laser = 2,
/obj/item/stock_parts/manipulator = 1)
/obj/item/circuitboard/machine/public_nanite_chamber/multitool_act(mob/living/user)
var/new_cloud = input("Set the public nanite chamber's Cloud ID (1-100).", "Cloud ID", cloud_id) as num|null
if(new_cloud == null)
return
cloud_id = CLAMP(round(new_cloud, 1), 1, 100)
/obj/item/circuitboard/machine/public_nanite_chamber/examine(mob/user)
. = ..()
to_chat(user, "Cloud ID is currently set to [cloud_id].")
/obj/item/circuitboard/machine/nanite_program_hub
name = "Nanite Program Hub (Machine Board)"
build_path = /obj/machinery/nanite_program_hub
req_components = list(
/obj/item/stock_parts/matter_bin = 1,
/obj/item/stock_parts/manipulator = 1)
/obj/item/circuitboard/machine/nanite_programmer
name = "Nanite Programmer (Machine Board)"
build_path = /obj/machinery/nanite_programmer
req_components = list(
/obj/item/stock_parts/manipulator = 2,
/obj/item/stock_parts/micro_laser = 2,
/obj/item/stock_parts/scanning_module = 1)
/obj/item/circuitboard/machine/protolathe
name = "Protolathe (Machine Board)"
build_path = /obj/machinery/rnd/production/protolathe
+2
View File
@@ -520,6 +520,7 @@
add_logs(user, H, "overloaded the heart of", defib)
H.Knockdown(100)
H.Jitter(100)
SEND_SIGNAL(H, COMSIG_LIVING_MINOR_SHOCK)
if(req_defib)
defib.deductcharge(revivecost)
cooldown = TRUE
@@ -602,6 +603,7 @@
H.set_heartattack(FALSE)
H.revive()
H.emote("gasp")
SEND_SIGNAL(H, COMSIG_LIVING_MINOR_SHOCK)
H.Jitter(100)
if(tplus > tloss)
H.adjustBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100))), 150)
@@ -114,11 +114,11 @@
/obj/item/radio/intercom/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans, message_mode)
. = ..()
if (message_mode == MODE_INTERCOM)
return // Avoid hearing the same thing twice
if(!anyai && !(speaker in ai))
return
..()
/obj/item/radio/intercom/process()
if(((world.timeofday - last_tick) > 30) || ((world.timeofday - last_tick) < 0))
@@ -276,6 +276,7 @@
signal.broadcast()
/obj/item/radio/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
. = ..()
if(radio_freq || !broadcasting || get_dist(src, speaker) > canhear_range)
return
@@ -328,6 +328,7 @@ SLIME SCANNER
if(cyberimp_detect)
to_chat(user, "<span class='notice'>Detected cybernetic modifications:</span>")
to_chat(user, "<span class='notice'>[cyberimp_detect]</span>")
SEND_SIGNAL(M, COMSIG_NANITE_SCAN, user, FALSE)
/proc/chemscan(mob/living/user, mob/living/M)
if(istype(M))
@@ -603,3 +604,29 @@ SLIME SCANNER
to_chat(user, "<span class='notice'>Core mutation in progress: [T.effectmod]</span>")
to_chat(user, "<span_class = 'notice'>Progress in core mutation: [T.applied] / [SLIME_EXTRACT_CROSSING_REQUIRED]</span>")
to_chat(user, "========================")
/obj/item/nanite_scanner
name = "nanite scanner"
icon = 'icons/obj/device.dmi'
icon_state = "nanite_scanner"
item_state = "nanite_remote"
lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
desc = "A hand-held body scanner able to detect nanites and their programming."
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
slot_flags = ITEM_SLOT_BELT
throwforce = 3
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=200)
/obj/item/nanite_scanner/attack(mob/living/M, mob/living/carbon/human/user)
user.visible_message("<span class='notice'>[user] has analyzed [M]'s nanites.</span>")
add_fingerprint(user)
var/response = SEND_SIGNAL(M, COMSIG_NANITE_SCAN, user, TRUE)
if(!response)
to_chat(user, "<span class='info'>No nanites detected in the subject.</span>")
@@ -95,6 +95,7 @@
/obj/item/taperecorder/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode)
. = ..()
if(mytape && recording)
mytape.timestamp += mytape.used_capacity
mytape.storedinfo += "\[[time2text(mytape.used_capacity * 10,"mm:ss")]\] [message]"
+1
View File
@@ -123,6 +123,7 @@
return ..()
/obj/item/toy/eightball/haunted/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode)
. = ..()
last_message = raw_message
/obj/item/toy/eightball/haunted/start_shaking(mob/user)
@@ -19,6 +19,8 @@
/obj/item/implant/mindshield/implant(mob/living/target, mob/user, silent = FALSE)
if(..())
if(!target.mind)
target.add_trait(TRAIT_MINDSHIELD, "implant")
target.sec_hud_set_implants()
return TRUE
if(target.mind.has_antag_datum(/datum/antagonist/brainwashed))
@@ -39,6 +41,8 @@
to_chat(target, "<span class='warning'>You feel something interfering with your mental conditioning, but you resist it!</span>")
else
to_chat(target, "<span class='notice'>You feel a sense of peace and security. You are now protected from brainwashing.</span>")
target.add_trait(TRAIT_MINDSHIELD, "implant")
target.sec_hud_set_implants()
return TRUE
return FALSE
@@ -46,8 +50,12 @@
if(..())
if(target.stat != DEAD && !silent)
to_chat(target, "<span class='boldnotice'>Your mind suddenly feels terribly vulnerable. You are no longer safe from brainwashing.</span>")
return 1
return 0
if(isliving(target))
var/mob/living/L = target
L.remove_trait(TRAIT_MINDSHIELD, "implant")
L.sec_hud_set_implants()
return TRUE
return FALSE
/obj/item/implanter/mindshield
name = "implanter (mindshield)"
@@ -185,7 +185,7 @@
objective = stripped_input(usr,"What order do you want to imprint on [C]?","Enter the order","",120)
message_admins("[ADMIN_LOOKUPFLW(user)] set brainwash machine objective to '[objective]'.")
log_game("[key_name(user)] set brainwash machine objective to '[objective]'.")
if(C.isloyal())
if(C.has_trait(TRAIT_MINDSHIELD))
return FALSE
brainwash(C, objective)
message_admins("[ADMIN_LOOKUPFLW(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
+1 -1
View File
@@ -187,7 +187,7 @@
inspiration_available = FALSE
/obj/item/banner/command/check_inspiration(mob/living/carbon/human/H)
return H.isloyal() //Command is stalwart but rewards their allies.
return H.has_trait(TRAIT_MINDSHIELD) //Command is stalwart but rewards their allies.
/datum/crafting_recipe/command_banner
name = "Command Banner"
+8
View File
@@ -1008,3 +1008,11 @@
new /obj/item/stock_parts/matter_bin/bluespace(src)
new /obj/item/stock_parts/matter_bin/bluespace(src)
new /obj/item/stock_parts/matter_bin/bluespace(src)
/obj/item/storage/box/disks_nanite
name = "nanite program disks box"
illustration = "disk_kit"
/obj/item/storage/box/disks_nanite/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/disk/nanite_program(src)
+1
View File
@@ -165,6 +165,7 @@
L.Knockdown(stunforce)
L.adjustStaminaLoss(stunforce*0.1)//CIT CHANGE - makes stunbatons deal extra staminaloss. Todo: make this also deal pain when pain gets implemented.
L.apply_effect(EFFECT_STUTTER, stunforce)
SEND_SIGNAL(L, COMSIG_LIVING_MINOR_SHOCK)
if(user)
L.lastattacker = user.real_name
L.lastattackerckey = user.ckey
+3
View File
@@ -12,9 +12,11 @@
user.visible_message("<span class='danger'>[user] accidentally hits [user.p_them()]self with [src]!</span>", \
"<span class='userdanger'>You accidentally hit yourself with [src]!</span>")
if(do_teleport(user, get_turf(user), 50))//honk honk
SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK)
user.Knockdown(stunforce*3)
deductcharge(hitcost)
else
SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK)
user.Knockdown(stunforce*3)
deductcharge(hitcost/4)
return
@@ -23,6 +25,7 @@
if(!istype(M) && M.anchored)
return .
else
SEND_SIGNAL(M, COMSIG_LIVING_MINOR_SHOCK)
do_teleport(M, get_turf(M), 15)
/obj/item/melee/baton/cattleprod/attackby(obj/item/I, mob/user, params)//handles sticking a crystal onto a stunprod to make a teleprod
+1 -1
View File
@@ -29,7 +29,7 @@ GLOBAL_LIST_INIT(freqtospan, list(
send_speech(message, 7, src, , spans, message_language=language)
/atom/movable/proc/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
return
SEND_SIGNAL(src, COMSIG_MOVABLE_HEAR, message, speaker, message_language, raw_message, radio_freq, spans, message_mode)
/atom/movable/proc/can_speak()
return 1