mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-29 06:57:42 +01:00
Merge branch 'master' into instrument-tgui-n-optimization
This commit is contained in:
@@ -2583,14 +2583,16 @@
|
||||
if("monkey")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","M")
|
||||
for(var/mob/living/carbon/human/H in GLOB.mob_list)
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
spawn(0)
|
||||
H.monkeyize()
|
||||
ok = 1
|
||||
if("corgi")
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","M")
|
||||
for(var/mob/living/carbon/human/H in GLOB.mob_list)
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
spawn(0)
|
||||
H.corgize()
|
||||
ok = 1
|
||||
@@ -2661,7 +2663,8 @@
|
||||
feedback_inc("admin_secrets_fun_used",1)
|
||||
feedback_add_details("admin_secrets_fun_used","PW")
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] teleported all players to the prison station.</span>", 1)
|
||||
for(var/mob/living/carbon/human/H in GLOB.mob_list)
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
var/turf/loc = find_loc(H)
|
||||
var/security = 0
|
||||
if(!is_station_level(loc.z) || GLOB.prisonwarped.Find(H))
|
||||
@@ -2994,7 +2997,8 @@
|
||||
if("manifest")
|
||||
var/dat = "<B>Showing Crew Manifest.</B><HR>"
|
||||
dat += "<table cellspacing=5><tr><th>Name</th><th>Position</th></tr>"
|
||||
for(var/mob/living/carbon/human/H in GLOB.mob_list)
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
if(H.ckey)
|
||||
dat += text("<tr><td>[]</td><td>[]</td></tr>", H.name, H.get_assignment())
|
||||
dat += "</table>"
|
||||
@@ -3004,7 +3008,8 @@
|
||||
if("DNA")
|
||||
var/dat = "<B>Showing DNA from blood.</B><HR>"
|
||||
dat += "<table cellspacing=5><tr><th>Name</th><th>DNA</th><th>Blood Type</th></tr>"
|
||||
for(var/mob/living/carbon/human/H in GLOB.mob_list)
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
if(H.dna && H.ckey)
|
||||
dat += "<tr><td>[H]</td><td>[H.dna.unique_enzymes]</td><td>[H.dna.blood_type]</td></tr>"
|
||||
dat += "</table>"
|
||||
@@ -3012,7 +3017,8 @@
|
||||
if("fingerprints")
|
||||
var/dat = "<B>Showing Fingerprints.</B><HR>"
|
||||
dat += "<table cellspacing=5><tr><th>Name</th><th>Fingerprints</th></tr>"
|
||||
for(var/mob/living/carbon/human/H in GLOB.mob_list)
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
if(H.ckey)
|
||||
if(H.dna && H.dna.uni_identity)
|
||||
dat += "<tr><td>[H]</td><td>[md5(H.dna.uni_identity)]</td></tr>"
|
||||
|
||||
@@ -643,7 +643,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
|
||||
for(var/areatype in areas_without_camera)
|
||||
to_chat(world, "* [areatype]")
|
||||
|
||||
/client/proc/cmd_admin_dress(var/mob/living/carbon/human/M in GLOB.mob_list)
|
||||
/client/proc/cmd_admin_dress(mob/living/carbon/human/M in GLOB.human_list)
|
||||
set category = "Event"
|
||||
set name = "Select equipment"
|
||||
|
||||
|
||||
@@ -979,7 +979,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
var/role_string
|
||||
var/obj_count = 0
|
||||
var/obj_string = ""
|
||||
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
if(!isLivingSSD(H))
|
||||
continue
|
||||
mins_ssd = round((world.time - H.last_logout) / 600)
|
||||
@@ -1016,7 +1017,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
msg += "AFK Players:<BR><TABLE border='1'>"
|
||||
msg += "<TR><TD><B>Key</B></TD><TD><B>Real Name</B></TD><TD><B>Job</B></TD><TD><B>Mins AFK</B></TD><TD><B>Special Role</B></TD><TD><B>Area</B></TD><TD><B>PPN</B></TD><TD><B>Cryo</B></TD></TR>"
|
||||
var/mins_afk
|
||||
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
if(H.client == null || H.stat == DEAD) // No clientless or dead
|
||||
continue
|
||||
mins_afk = round(H.client.inactivity / 600)
|
||||
|
||||
@@ -41,9 +41,8 @@
|
||||
A.common_radio.channels.Remove("Syndicate") // De-traitored AIs can still state laws over the syndicate channel without this
|
||||
A.laws.sorted_laws = A.laws.inherent_laws.Copy() // AI's 'notify laws' button will still state a law 0 because sorted_laws contains it
|
||||
A.show_laws()
|
||||
A.malf_picker.remove_malf_verbs(A)
|
||||
A.verbs -= /mob/living/silicon/ai/proc/choose_modules
|
||||
qdel(A.malf_picker)
|
||||
A.remove_malf_abilities()
|
||||
QDEL_NULL(A.malf_picker)
|
||||
|
||||
if(owner.som)
|
||||
var/datum/mindslaves/slaved = owner.som
|
||||
|
||||
@@ -154,6 +154,9 @@
|
||||
display_name = "corset, blue"
|
||||
path = /obj/item/clothing/accessory/corset/blue
|
||||
|
||||
/datum/gear/accessory/armband/job
|
||||
subtype_path = /datum/gear/accessory/armband/job
|
||||
subtype_cost_overlap = FALSE
|
||||
|
||||
/datum/gear/accessory/armband_red
|
||||
display_name = "armband"
|
||||
@@ -163,37 +166,37 @@
|
||||
display_name = "armband, blue-yellow"
|
||||
path = /obj/item/clothing/accessory/armband/yb
|
||||
|
||||
/datum/gear/accessory/armband_sec
|
||||
/datum/gear/accessory/armband/job/sec
|
||||
display_name = " armband, security"
|
||||
path = /obj/item/clothing/accessory/armband/sec
|
||||
allowed_roles = list("Head of Security", "Warden", "Detective", "Security Officer", "Brig Physician", "Security Pod Pilot")
|
||||
|
||||
/datum/gear/accessory/armband_cargo
|
||||
/datum/gear/accessory/armband/job/cargo
|
||||
display_name = "cargo armband"
|
||||
path = /obj/item/clothing/accessory/armband/cargo
|
||||
allowed_roles = list("Quartermaster","Cargo Technician", "Shaft Miner")
|
||||
|
||||
/datum/gear/accessory/armband_medical
|
||||
/datum/gear/accessory/armband/job/medical
|
||||
display_name = "armband, medical"
|
||||
path = /obj/item/clothing/accessory/armband/med
|
||||
allowed_roles = list("Chief Medical Officer", "Medical Doctor", "Coroner", "Paramedic", "Brig Physician")
|
||||
|
||||
/datum/gear/accessory/armband_emt
|
||||
/datum/gear/accessory/armband/job/emt
|
||||
display_name = "armband, EMT"
|
||||
path = /obj/item/clothing/accessory/armband/medgreen
|
||||
allowed_roles = list("Paramedic", "Brig Physician")
|
||||
|
||||
/datum/gear/accessory/armband_engineering
|
||||
/datum/gear/accessory/armband/job/engineering
|
||||
display_name = "armband, engineering"
|
||||
path = /obj/item/clothing/accessory/armband/engine
|
||||
allowed_roles = list("Chief Engineer","Station Engineer", "Life Support Specialist")
|
||||
|
||||
/datum/gear/accessory/armband_hydro
|
||||
/datum/gear/accessory/armband/job/hydro
|
||||
display_name = "armband, hydroponics"
|
||||
path = /obj/item/clothing/accessory/armband/hydro
|
||||
allowed_roles = list("Botanist")
|
||||
|
||||
/datum/gear/accessory/armband_sci
|
||||
/datum/gear/accessory/armband/job/sci
|
||||
display_name = "armband, science"
|
||||
path = /obj/item/clothing/accessory/armband/science
|
||||
allowed_roles = list("Research Director","Scientist", "Roboticist")
|
||||
|
||||
@@ -42,11 +42,6 @@
|
||||
display_name = "fedora, brown"
|
||||
path = /obj/item/clothing/head/fedora/brownfedora
|
||||
|
||||
/datum/gear/hat/beretsec
|
||||
display_name = "security beret"
|
||||
path = /obj/item/clothing/head/beret/sec
|
||||
allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot")
|
||||
|
||||
/datum/gear/hat/capcsec
|
||||
display_name = "security corporate cap"
|
||||
path = /obj/item/clothing/head/soft/sec/corp
|
||||
@@ -113,32 +108,54 @@
|
||||
display_name = "cowboy hat, pink"
|
||||
path = /obj/item/clothing/head/cowboyhat/pink
|
||||
|
||||
/datum/gear/hat/pr_beret
|
||||
//Berets Refactor
|
||||
//Defining all Job Berets as no-overlap
|
||||
//Somehow this doesn't break the DB.
|
||||
/datum/gear/hat/beret/job
|
||||
subtype_path = /datum/gear/hat/beret/job
|
||||
subtype_cost_overlap = FALSE
|
||||
|
||||
/datum/gear/hat/beret/purple
|
||||
display_name = "beret, purple"
|
||||
path = /obj/item/clothing/head/beret/purple_normal
|
||||
|
||||
/datum/gear/hat/bl_beret
|
||||
/datum/gear/hat/beret/black
|
||||
display_name = "beret, black"
|
||||
path = /obj/item/clothing/head/beret/black
|
||||
|
||||
/datum/gear/hat/blu_beret
|
||||
/datum/gear/hat/beret/blue
|
||||
display_name = "beret, blue"
|
||||
path = /obj/item/clothing/head/beret/blue
|
||||
|
||||
/datum/gear/hat/red_beret
|
||||
/datum/gear/hat/beret/red
|
||||
display_name = "beret, red"
|
||||
path = /obj/item/clothing/head/beret
|
||||
|
||||
/datum/gear/hat/sci_beret
|
||||
/datum/gear/hat/beret/job/sec
|
||||
display_name = "security beret"
|
||||
path = /obj/item/clothing/head/beret/sec
|
||||
allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot")
|
||||
|
||||
/datum/gear/hat/beret/job/sci
|
||||
display_name = "science beret"
|
||||
path = /obj/item/clothing/head/beret/sci
|
||||
allowed_roles = list("Research Director", "Scientist")
|
||||
|
||||
/datum/gear/hat/med_beret
|
||||
/datum/gear/hat/beret/job/med
|
||||
display_name = "medical beret"
|
||||
path = /obj/item/clothing/head/beret/med
|
||||
allowed_roles = list("Chief Medical Officer", "Medical Doctor" , "Virologist", "Brig Physician" , "Coroner")
|
||||
|
||||
/datum/gear/hat/beret/job/eng
|
||||
display_name = "engineering beret"
|
||||
path = /obj/item/clothing/head/beret/eng
|
||||
allowed_roles = list("Chief Engineer", "Station Engineer")
|
||||
|
||||
/datum/gear/hat/beret/job/atmos
|
||||
display_name = "atmospherics beret"
|
||||
path = /obj/item/clothing/head/beret/atmos
|
||||
allowed_roles = list("Chief Engineer", "Life Support Specialist")
|
||||
|
||||
/datum/gear/hat/surgicalcap_purple
|
||||
display_name = "surgical cap, purple"
|
||||
path = /obj/item/clothing/head/surgery/purple
|
||||
|
||||
@@ -175,32 +175,36 @@
|
||||
display_name = "regal shawl"
|
||||
path = /obj/item/clothing/suit/mantle/regal
|
||||
|
||||
/datum/gear/suit/captain_cloak
|
||||
/datum/gear/suit/mantle/job
|
||||
subtype_path = /datum/gear/suit/mantle/job
|
||||
subtype_cost_overlap = FALSE
|
||||
|
||||
/datum/gear/suit/mantle/job/captain
|
||||
display_name = "mantle, captain"
|
||||
path = /obj/item/clothing/suit/mantle/armor/captain
|
||||
allowed_roles = list("Captain")
|
||||
|
||||
/datum/gear/suit/ce_mantle
|
||||
/datum/gear/suit/mantle/job/ce
|
||||
display_name = "mantle, chief engineer"
|
||||
path = /obj/item/clothing/suit/mantle/chief_engineer
|
||||
allowed_roles = list("Chief Engineer")
|
||||
|
||||
/datum/gear/suit/cmo_mantle
|
||||
/datum/gear/suit/mantle/job/cmo
|
||||
display_name = "mantle, chief medical officer"
|
||||
path = /obj/item/clothing/suit/mantle/labcoat/chief_medical_officer
|
||||
allowed_roles = list("Chief Medical Officer")
|
||||
|
||||
/datum/gear/suit/armored_shawl
|
||||
/datum/gear/suit/mantle/job/hos
|
||||
display_name = "mantle, head of security"
|
||||
path = /obj/item/clothing/suit/mantle/armor
|
||||
allowed_roles = list("Head of Security")
|
||||
|
||||
/datum/gear/suit/hop_shawl
|
||||
/datum/gear/suit/mantle/job/hop
|
||||
display_name = "mantle, head of personnel"
|
||||
path = /obj/item/clothing/suit/mantle/armor/head_of_personnel
|
||||
allowed_roles = list("Head of Personnel")
|
||||
|
||||
/datum/gear/suit/rd_mantle
|
||||
/datum/gear/suit/mantle/job/rd
|
||||
display_name = "mantle, research director"
|
||||
path = /obj/item/clothing/suit/mantle/labcoat
|
||||
allowed_roles = list("Research Director")
|
||||
|
||||
@@ -59,7 +59,17 @@
|
||||
log_and_message_admins("APC Short event shorted out [affected_apc_count] APCs.")
|
||||
|
||||
/proc/power_restore(announce=TRUE)
|
||||
power_restore_quick(announce)
|
||||
if(announce)
|
||||
GLOB.event_announcement.Announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg')
|
||||
|
||||
// recharge the APCs
|
||||
for(var/thing in GLOB.apcs)
|
||||
var/obj/machinery/power/apc/A = thing
|
||||
if(!is_station_level(A.z))
|
||||
continue
|
||||
var/obj/item/stock_parts/cell/C = A.get_cell()
|
||||
if(C)
|
||||
C.give(C.maxcharge)
|
||||
|
||||
/proc/power_restore_quick(announce=TRUE)
|
||||
if(announce)
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
announceWhen = rand(0, 20)
|
||||
|
||||
/datum/event/mass_hallucination/start()
|
||||
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
if(H.stat == DEAD)
|
||||
continue
|
||||
var/armor = H.getarmor(type = "rad")
|
||||
if((RADIMMUNE in H.dna.species.species_traits) || armor >= 75) // Leave radiation-immune species/rad armored players completely unaffected
|
||||
continue
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
for(var/mob/living/simple_animal/L in GLOB.alive_mob_list)
|
||||
var/turf/T = get_turf(L)
|
||||
if (T.z != 1)
|
||||
if (!is_station_level(T.z))
|
||||
continue
|
||||
if(!(L in GLOB.player_list) && !L.mind && (L.sentience_type == sentience_type))
|
||||
potential += L
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#define TS_HIGHPOP_TRIGGER 80
|
||||
|
||||
/datum/event/spider_terror
|
||||
announceWhen = 240
|
||||
@@ -22,23 +23,32 @@
|
||||
if(temp_vent.parent.other_atmosmch.len > 50)
|
||||
vents += temp_vent
|
||||
var/spider_type
|
||||
var/infestation_type = pick(1, 2, 3, 4, 5)
|
||||
var/infestation_type
|
||||
if((length(GLOB.clients)) < TS_HIGHPOP_TRIGGER)
|
||||
infestation_type = pick(1, 2, 3, 4)
|
||||
else
|
||||
infestation_type = pick(2, 3, 4, 5)
|
||||
switch(infestation_type)
|
||||
if(1)
|
||||
// Weakest, only used during lowpop.
|
||||
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/green
|
||||
spawncount = 5
|
||||
if(2)
|
||||
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/white
|
||||
spawncount = 2
|
||||
if(3)
|
||||
// Fairly weak. Dangerous in single combat but has little staying power. Always gets whittled down.
|
||||
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/prince
|
||||
spawncount = 1
|
||||
if(3)
|
||||
// Variable. Depends how many they infect.
|
||||
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/white
|
||||
spawncount = 2
|
||||
if(4)
|
||||
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/queen
|
||||
spawncount = 1
|
||||
if(5)
|
||||
// Pretty strong.
|
||||
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/princess
|
||||
spawncount = 2
|
||||
if(5)
|
||||
// Strongest, only used during highpop.
|
||||
spider_type = /mob/living/simple_animal/hostile/poison/terror_spider/queen
|
||||
spawncount = 1
|
||||
while(spawncount >= 1 && vents.len)
|
||||
var/obj/machinery/atmospherics/unary/vent_pump/vent = pick(vents)
|
||||
|
||||
@@ -60,3 +70,6 @@
|
||||
new spider_type(vent.loc)
|
||||
spawncount--
|
||||
|
||||
|
||||
#undef TS_HIGHPOP_TRIGGER
|
||||
|
||||
|
||||
@@ -460,8 +460,9 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
target = T
|
||||
var/image/A = null
|
||||
var/kind = force_kind ? force_kind : pick("clown", "corgi", "carp", "skeleton", "demon","zombie")
|
||||
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
|
||||
if(H == target)
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
if(H.stat == DEAD || H == target)
|
||||
continue
|
||||
if(skip_nearby && (H in view(target)))
|
||||
continue
|
||||
@@ -539,7 +540,8 @@ Gunshots/explosions/opening doors/less rare audio (done)
|
||||
var/mob/living/carbon/human/clone = null
|
||||
var/clone_weapon = null
|
||||
|
||||
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
if(H.stat || H.lying)
|
||||
continue
|
||||
clone = H
|
||||
@@ -751,8 +753,10 @@ GLOBAL_LIST_INIT(non_fakeattack_weapons, list(/obj/item/gun/projectile, /obj/ite
|
||||
target.client.images.Remove(speech_overlay)
|
||||
else // Radio talk
|
||||
var/list/humans = list()
|
||||
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
|
||||
humans += H
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
if(H.stat != DEAD)
|
||||
humans += H
|
||||
person = pick(humans)
|
||||
target.hear_radio(message_to_multilingual(pick(radio_messages), pick(person.languages)), speaker = person, part_a = "<span class='[SSradio.frequency_span_class(PUB_FREQ)]'><b>\[[get_frequency_name(PUB_FREQ)]\]</b> <span class='name'>", part_b = "</span> <span class='message'>")
|
||||
qdel(src)
|
||||
|
||||
@@ -124,6 +124,13 @@
|
||||
reagents.reaction(M, REAGENT_TOUCH)
|
||||
reagents.clear_reagents()
|
||||
|
||||
/obj/item/reagent_containers/food/drinks/bottle/decompile_act(obj/item/matter_decompiler/C, mob/user)
|
||||
if(!reagents.total_volume)
|
||||
C.stored_comms["glass"] += 3
|
||||
qdel(src)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
//Keeping this here for now, I'll ask if I should keep it here.
|
||||
/obj/item/broken_bottle
|
||||
name = "Broken Bottle"
|
||||
@@ -141,6 +148,11 @@
|
||||
var/icon/broken_outline = icon('icons/obj/drinks.dmi', "broken")
|
||||
sharp = 1
|
||||
|
||||
/obj/item/broken_bottle/decompile_act(obj/item/matter_decompiler/C, mob/user)
|
||||
C.stored_comms["glass"] += 3
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
/obj/item/reagent_containers/food/drinks/bottle/gin
|
||||
name = "Griffeater Gin"
|
||||
desc = "A bottle of high quality gin, produced in the New London Space Station."
|
||||
|
||||
@@ -168,6 +168,11 @@
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/decompile_act(obj/item/matter_decompiler/C, mob/user)
|
||||
C.stored_comms["wood"] += 4
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
// For item-containing growns such as eggy or gatfruit
|
||||
/obj/item/reagent_containers/food/snacks/grown/shell/attack_self(mob/user)
|
||||
user.unEquip(src)
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
B.mineEffect(L)
|
||||
|
||||
for(var/mob/living/carbon/human/H in GLOB.player_list)
|
||||
if(H == L)
|
||||
if(H.stat == DEAD || H == L)
|
||||
continue
|
||||
to_chat(H, "<span class='userdanger'>You have an overwhelming desire to kill [L]. [L.p_they(TRUE)] [L.p_have()] been marked red! Go kill [L.p_them()]!</span>")
|
||||
H.put_in_hands(new /obj/item/kitchen/knife/butcher(H))
|
||||
|
||||
@@ -383,7 +383,10 @@
|
||||
var/mob/living/L = target
|
||||
if(!L.anchored)
|
||||
L.visible_message("<span class='danger'>[L] is snagged by [firer]'s hook!</span>")
|
||||
var/old_density = L.density
|
||||
L.density = FALSE // Ensures the hook does not hit the target multiple times
|
||||
L.forceMove(get_turf(firer))
|
||||
L.density = old_density
|
||||
|
||||
/obj/item/projectile/hook/Destroy()
|
||||
QDEL_NULL(chain)
|
||||
|
||||
@@ -273,7 +273,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
|
||||
icon_state = "Gibtonite active"
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/notify_admins = 0
|
||||
if(z != 5)//Only annoy the admins ingame if we're triggered off the mining zlevel
|
||||
if(!is_mining_level(z))//Only annoy the admins ingame if we're triggered off the mining zlevel
|
||||
notify_admins = 1
|
||||
|
||||
if(notify_admins)
|
||||
|
||||
@@ -63,6 +63,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
|
||||
|
||||
//MALFUNCTION
|
||||
var/datum/module_picker/malf_picker
|
||||
var/datum/action/innate/ai/choose_modules/modules_action
|
||||
var/list/datum/AI_Module/current_modules = list()
|
||||
var/can_dominate_mechs = 0
|
||||
var/shunted = 0 //1 if the AI is currently shunted. Used to differentiate between shunted and ghosted/braindead
|
||||
@@ -851,13 +852,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
|
||||
to_chat(src, "<span class='notice'>Switched to [network] camera network.</span>")
|
||||
//End of code by Mord_Sith
|
||||
|
||||
|
||||
/mob/living/silicon/ai/proc/choose_modules()
|
||||
set category = "Malfunction"
|
||||
set name = "Choose Module"
|
||||
|
||||
malf_picker.use(src)
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_statuschange()
|
||||
set category = "AI Commands"
|
||||
set name = "AI Status"
|
||||
@@ -1028,15 +1022,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
|
||||
|
||||
return
|
||||
|
||||
/mob/living/silicon/ai/proc/corereturn()
|
||||
set category = "Malfunction"
|
||||
set name = "Return to Main Core"
|
||||
|
||||
var/obj/machinery/power/apc/apc = loc
|
||||
if(!istype(apc))
|
||||
to_chat(src, "<span class='notice'>You are already in your Main Core.</span>")
|
||||
return
|
||||
apc.malfvacate()
|
||||
|
||||
//Toggles the luminosity and applies it by re-entereing the camera.
|
||||
/mob/living/silicon/ai/proc/toggle_camera_light()
|
||||
@@ -1244,8 +1229,17 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
|
||||
to_chat(src, "In the top right corner of the screen you will find the Malfunctions tab, where you can purchase various abilities, from upgraded surveillance to station ending doomsday devices.")
|
||||
to_chat(src, "You are also capable of hacking APCs, which grants you more points to spend on your Malfunction powers. The drawback is that a hacked APC will give you away if spotted by the crew. Hacking an APC takes 60 seconds.")
|
||||
view_core() //A BYOND bug requires you to be viewing your core before your verbs update
|
||||
verbs += /mob/living/silicon/ai/proc/choose_modules
|
||||
malf_picker = new /datum/module_picker
|
||||
modules_action = new(malf_picker)
|
||||
modules_action.Grant(src)
|
||||
|
||||
///Removes all malfunction-related /datum/action's from the target AI.
|
||||
/mob/living/silicon/ai/proc/remove_malf_abilities()
|
||||
QDEL_NULL(modules_action)
|
||||
for(var/datum/AI_Module/AM in current_modules)
|
||||
for(var/datum/action/A in actions)
|
||||
if(istype(A, initial(AM.power_type)))
|
||||
qdel(A)
|
||||
|
||||
/mob/living/silicon/ai/proc/open_nearest_door(mob/living/target)
|
||||
if(!istype(target))
|
||||
|
||||
@@ -354,3 +354,20 @@
|
||||
/mob/living/simple_animal/drone/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
|
||||
if(affect_silicon)
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/drone/decompile_act(obj/item/matter_decompiler/C, mob/user)
|
||||
if(!client && istype(user, /mob/living/silicon/robot/drone))
|
||||
to_chat(user, "<span class='warning'>You begin decompiling the other drone.</span>")
|
||||
if(!do_after(user, 5 SECONDS, target = loc))
|
||||
to_chat(user, "<span class='warning'>You need to remain still while decompiling such a large object.</span>")
|
||||
return
|
||||
if(QDELETED(src) || QDELETED(user))
|
||||
return ..()
|
||||
to_chat(user, "<span class='warning'>You carefully and thoroughly decompile your downed fellow, storing as much of its resources as you can within yourself.</span>")
|
||||
new/obj/effect/decal/cleanable/blood/oil(get_turf(src))
|
||||
C.stored_comms["metal"] += 15
|
||||
C.stored_comms["glass"] += 15
|
||||
C.stored_comms["wood"] += 5
|
||||
qdel(src)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
@@ -151,15 +151,13 @@
|
||||
var/list/stored_comms = list(
|
||||
"metal" = 0,
|
||||
"glass" = 0,
|
||||
"wood" = 0,
|
||||
"plastic" = 0
|
||||
"wood" = 0
|
||||
)
|
||||
|
||||
/obj/item/matter_decompiler/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
|
||||
return
|
||||
|
||||
/obj/item/matter_decompiler/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity, params)
|
||||
|
||||
/obj/item/matter_decompiler/afterattack(atom/target, mob/living/user, proximity, params)
|
||||
if(!proximity) return //Not adjacent.
|
||||
|
||||
//We only want to deal with using this on turfs. Specific items aren't important.
|
||||
@@ -168,101 +166,11 @@
|
||||
return
|
||||
|
||||
//Used to give the right message.
|
||||
var/grabbed_something = 0
|
||||
var/grabbed_something = FALSE
|
||||
|
||||
for(var/mob/M in T)
|
||||
if(istype(M,/mob/living/simple_animal/lizard) || istype(M,/mob/living/simple_animal/mouse))
|
||||
src.loc.visible_message("<span class='notice'>[src.loc] sucks [M] into its decompiler. There's a horrible crunching noise.</span>","<span class='warning'>It's a bit of a struggle, but you manage to suck [M] into your decompiler. It makes a series of visceral crunching noises.</span>")
|
||||
new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
|
||||
qdel(M)
|
||||
stored_comms["wood"]++
|
||||
stored_comms["wood"]++
|
||||
stored_comms["plastic"]++
|
||||
stored_comms["plastic"]++
|
||||
return
|
||||
|
||||
else if(istype(M,/mob/living/silicon/robot/drone) && !M.client)
|
||||
|
||||
var/mob/living/silicon/robot/drone/D = src.loc
|
||||
|
||||
if(!istype(D))
|
||||
return
|
||||
|
||||
to_chat(D, "<span class='warning'>You begin decompiling the other drone.</span>")
|
||||
|
||||
if(!do_after(D, 50, target = target))
|
||||
to_chat(D, "<span class='warning'>You need to remain still while decompiling such a large object.</span>")
|
||||
return
|
||||
|
||||
if(!M || !D) return
|
||||
|
||||
to_chat(D, "<span class='warning'>You carefully and thoroughly decompile your downed fellow, storing as much of its resources as you can within yourself.</span>")
|
||||
|
||||
qdel(M)
|
||||
new/obj/effect/decal/cleanable/blood/oil(get_turf(src))
|
||||
|
||||
stored_comms["metal"] += 15
|
||||
stored_comms["glass"] += 15
|
||||
stored_comms["wood"] += 5
|
||||
stored_comms["plastic"] += 5
|
||||
|
||||
return
|
||||
else
|
||||
continue
|
||||
|
||||
for(var/obj/W in T)
|
||||
//Different classes of items give different commodities.
|
||||
if(istype(W,/obj/item/cigbutt))
|
||||
stored_comms["plastic"]++
|
||||
else if(istype(W,/obj/structure/spider/spiderling))
|
||||
stored_comms["wood"]++
|
||||
stored_comms["wood"]++
|
||||
stored_comms["plastic"]++
|
||||
stored_comms["plastic"]++
|
||||
else if(istype(W,/obj/item/light))
|
||||
var/obj/item/light/L = W
|
||||
if(L.status >= 2) //In before someone changes the inexplicably local defines. ~ Z
|
||||
stored_comms["metal"]++
|
||||
stored_comms["glass"]++
|
||||
else
|
||||
continue
|
||||
else if(istype(W,/obj/effect/decal/remains/robot))
|
||||
stored_comms["metal"]++
|
||||
stored_comms["metal"]++
|
||||
stored_comms["plastic"]++
|
||||
stored_comms["plastic"]++
|
||||
stored_comms["glass"]++
|
||||
else if(istype(W,/obj/item/trash))
|
||||
stored_comms["metal"]++
|
||||
stored_comms["plastic"]++
|
||||
stored_comms["plastic"]++
|
||||
else if(istype(W,/obj/effect/decal/cleanable/blood/gibs/robot))
|
||||
stored_comms["metal"]++
|
||||
stored_comms["metal"]++
|
||||
stored_comms["glass"]++
|
||||
stored_comms["glass"]++
|
||||
else if(istype(W,/obj/item/ammo_casing))
|
||||
stored_comms["metal"]++
|
||||
else if(istype(W,/obj/item/shard))
|
||||
stored_comms["glass"]++
|
||||
stored_comms["glass"]++
|
||||
stored_comms["glass"]++
|
||||
else if(istype(W,/obj/item/reagent_containers/food/snacks/grown))
|
||||
stored_comms["wood"]++
|
||||
stored_comms["wood"]++
|
||||
stored_comms["wood"]++
|
||||
stored_comms["wood"]++
|
||||
else if(istype(W,/obj/item/broken_bottle))
|
||||
stored_comms["glass"]++
|
||||
stored_comms["glass"]++
|
||||
stored_comms["glass"]++
|
||||
else if(istype(W,/obj/item/light/tube) || istype(W,/obj/item/light/bulb))
|
||||
stored_comms["glass"]++
|
||||
else
|
||||
continue
|
||||
|
||||
qdel(W)
|
||||
grabbed_something = 1
|
||||
for(var/atom/movable/A in T)
|
||||
if(A.decompile_act(src, user)) // Each decompileable mob or obj needs to have this defined
|
||||
grabbed_something = TRUE
|
||||
|
||||
if(grabbed_something)
|
||||
to_chat(user, "<span class='notice'>You deploy your decompiler and clear out the contents of \the [T].</span>")
|
||||
@@ -353,11 +261,5 @@
|
||||
stack_wood = new /obj/item/stack/sheet/wood(src.module)
|
||||
stack_wood.amount = 1
|
||||
stack = stack_wood
|
||||
if("plastic")
|
||||
if(!stack_plastic)
|
||||
stack_plastic = new /obj/item/stack/sheet/plastic(src.module)
|
||||
stack_plastic.amount = 1
|
||||
stack = stack_plastic
|
||||
|
||||
stack.amount++
|
||||
decompiler.stored_comms[type]--
|
||||
|
||||
@@ -756,7 +756,7 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
|
||||
// send a radio signal with multiple data key/values
|
||||
/mob/living/simple_animal/bot/proc/post_signal_multiple(var/freq, var/list/keyval)
|
||||
if(z != 1) //Bot control will only work on station.
|
||||
if(!is_station_level(z)) //Bot control will only work on station.
|
||||
return
|
||||
var/datum/radio_frequency/frequency = SSradio.return_frequency(freq)
|
||||
if(!frequency)
|
||||
|
||||
@@ -23,3 +23,14 @@
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat = 1)
|
||||
can_collar = 1
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
|
||||
/mob/living/simple_animal/lizard/decompile_act(obj/item/matter_decompiler/C, mob/user)
|
||||
if(!istype(user, /mob/living/silicon/robot/drone))
|
||||
user.visible_message("<span class='notice'>[user] sucks [src] into its decompiler. There's a horrible crunching noise.</span>", \
|
||||
"<span class='warning'>It's a bit of a struggle, but you manage to suck [src] into your decompiler. It makes a series of visceral crunching noises.</span>")
|
||||
new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
|
||||
C.stored_comms["wood"] += 2
|
||||
C.stored_comms["glass"] += 2
|
||||
qdel(src)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
@@ -234,3 +234,14 @@
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
can_collar = 0
|
||||
butcher_results = list(/obj/item/stack/sheet/metal = 1)
|
||||
|
||||
/mob/living/simple_animal/mouse/decompile_act(obj/item/matter_decompiler/C, mob/user)
|
||||
if(!(istype(user, /mob/living/silicon/robot/drone)))
|
||||
user.visible_message("<span class='notice'>[user] sucks [src] into its decompiler. There's a horrible crunching noise.</span>", \
|
||||
"<span class='warning'>It's a bit of a struggle, but you manage to suck [src] into your decompiler. It makes a series of visceral crunching noises.</span>")
|
||||
new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
|
||||
C.stored_comms["wood"] += 2
|
||||
C.stored_comms["glass"] += 2
|
||||
qdel(src)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
@@ -615,3 +615,8 @@
|
||||
if(pcollar && collar_type)
|
||||
add_overlay("[collar_type]collar")
|
||||
add_overlay("[collar_type]tag")
|
||||
|
||||
/mob/living/simple_animal/Login()
|
||||
..()
|
||||
walk(src, 0) // if mob is moving under ai control, then stop AI movement
|
||||
|
||||
|
||||
@@ -82,14 +82,11 @@
|
||||
O.notify_ai(1)
|
||||
|
||||
if(O.mind && O.mind.assigned_role == "Cyborg")
|
||||
if(O.mind.role_alt_title == "Android")
|
||||
if(O.mind.role_alt_title == "Robot")
|
||||
O.mmi = new /obj/item/mmi/robotic_brain(O)
|
||||
else if(O.mind.role_alt_title == "Robot")
|
||||
O.mmi = null //Robots do not have removable brains.
|
||||
else
|
||||
O.mmi = new /obj/item/mmi(O)
|
||||
|
||||
if(O.mmi) O.mmi.transfer_identity(src) //Does not transfer key/client.
|
||||
O.mmi.transfer_identity(src) //Does not transfer key/client.
|
||||
|
||||
O.update_pipe_vision()
|
||||
|
||||
|
||||
@@ -1052,7 +1052,8 @@
|
||||
occupier.eyeobj.name = "[occupier.name] (AI Eye)"
|
||||
if(malf.parent)
|
||||
qdel(malf)
|
||||
occupier.verbs += /mob/living/silicon/ai/proc/corereturn
|
||||
var/datum/action/innate/ai/return_to_core/R = new
|
||||
R.Grant(occupier)
|
||||
occupier.cancel_camera()
|
||||
if((seclevel2num(get_security_level()) == SEC_LEVEL_DELTA) && malf.nuking)
|
||||
for(var/obj/item/pinpointer/point in GLOB.pinpointer_list)
|
||||
|
||||
@@ -634,6 +634,12 @@
|
||||
shatter()
|
||||
return ..()
|
||||
|
||||
/obj/item/light/decompile_act(obj/item/matter_decompiler/C, mob/user)
|
||||
C.stored_comms["glass"] += 1
|
||||
C.stored_comms["metal"] += 1
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
/obj/item/light/tube
|
||||
name = "light tube"
|
||||
desc = "A replacement light tube."
|
||||
|
||||
@@ -42,6 +42,13 @@
|
||||
var/image/lid = image(icon, src, "lid_bottle")
|
||||
overlays += lid
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/decompile_act(obj/item/matter_decompiler/C, mob/user)
|
||||
if(!reagents.total_volume)
|
||||
C.stored_comms["glass"] += 3
|
||||
qdel(src)
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/obj/item/reagent_containers/glass/bottle/toxin
|
||||
name = "toxin bottle"
|
||||
desc = "A small bottle containing toxic compounds."
|
||||
|
||||
@@ -265,7 +265,7 @@
|
||||
update()
|
||||
return
|
||||
|
||||
/obj/machinery/disposal/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
/obj/machinery/disposal/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "DisposalBin", name, 300, 250, master_ui, state)
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
/obj/machinery/computer/shuttle/ert/Topic(href, href_list)
|
||||
if(href_list["move"])
|
||||
var/authorized_roles = list(SPECIAL_ROLE_ERT, SPECIAL_ROLE_DEATHSQUAD)
|
||||
if(!((usr.mind.assigned_role in authorized_roles) || is_admin(usr)))
|
||||
if(!((usr.mind?.assigned_role in authorized_roles) || is_admin(usr)))
|
||||
message_admins("Potential ERT shuttle hijack, ERT shuttle moved by unauthorized user: [key_name_admin(usr)]")
|
||||
..()
|
||||
|
||||
|
||||
|
||||
/obj/machinery/computer/camera_advanced/shuttle_docker/ert
|
||||
name = "specops navigation computer"
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
if("track")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
var/mob/living/carbon/human/H = locate(params["track"]) in GLOB.mob_list
|
||||
var/mob/living/carbon/human/H = locate(params["track"]) in GLOB.human_list
|
||||
if(hassensorlevel(H, SUIT_SENSOR_TRACKING))
|
||||
AI.ai_actual_track(H)
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/tgui_module/crew_monitor/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
/datum/tgui_module/crew_monitor/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
// The 557 may seem random, but its the perfectsize for margins on the nanomap
|
||||
|
||||
Reference in New Issue
Block a user