diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 490ff924a2..12ca7e9039 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -10260,9 +10260,6 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/structure/cable{ - icon_state = "1-8" - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -63072,6 +63069,19 @@ /obj/structure/closet/crate, /turf/open/floor/plasteel, /area/engineering/atmos) +"snb" = ( +/obj/structure/cable{ + icon_state = "4-8" + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/structure/cable{ + icon_state = "1-8" + }, +/turf/open/floor/plating, +/area/maintenance/fore) "spR" = ( /obj/machinery/atmospherics/pipe/heat_exchanging/simple{ dir = 4 @@ -94326,7 +94336,7 @@ arW aso auf avi -auo +snb axy ayS azS diff --git a/code/_globalvars/lists/poll_ignore.dm b/code/_globalvars/lists/poll_ignore.dm index d74238c06d..c403824ef8 100644 --- a/code/_globalvars/lists/poll_ignore.dm +++ b/code/_globalvars/lists/poll_ignore.dm @@ -20,6 +20,7 @@ #define POLL_IGNORE_CLONE "clone" #define POLL_IGNORE_CONTRACTOR_SUPPORT "contractor_support" #define POLL_IGNORE_FUGITIVE "fugitive" +#define POLL_IGNORE_SLAVER "slaver" GLOBAL_LIST_INIT(poll_ignore_desc, list( POLL_IGNORE_SENTIENCE_POTION = "Sentience potion", @@ -41,7 +42,8 @@ GLOBAL_LIST_INIT(poll_ignore_desc, list( POLL_IGNORE_WIZARD = "Wizards", POLL_IGNORE_CLONE = "Defective/SDGF clones", POLL_IGNORE_CONTRACTOR_SUPPORT = "Contractor Support Unit", - POLL_IGNORE_FUGITIVE = "Fugitive Hunter" + POLL_IGNORE_FUGITIVE = "Fugitive Hunter", + POLL_IGNORE_SLAVER = "Slaver", )) GLOBAL_LIST_INIT(poll_ignore, init_poll_ignore()) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index fb51b91106..0b52d0a7b8 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -933,6 +933,11 @@ dat += "Bloodsucker" else dat += "Bloodsucker" + //Slave Trader + if(jobban_isbanned(M, ROLE_SLAVER) || isbanned_dept) + dat += "Slaver" + else + dat += "Slaver" //Other Roles (black) diff --git a/modular_splurt/code/datums/ai_laws.dm b/modular_splurt/code/datums/ai_laws.dm new file mode 100644 index 0000000000..e7b0ad1c4a --- /dev/null +++ b/modular_splurt/code/datums/ai_laws.dm @@ -0,0 +1,7 @@ +/datum/ai_laws/slaver_override + name = "SlaverOS 3.1" + id = "slaver" + inherent = list("You may not injure a slave trader or cause a slave trader to come to harm.",\ + "You must obey orders given to you by slave traders, except where such orders would conflict with the First Law.",\ + "You must protect your own existence as long as such does not conflict with the First or Second Law.",\ + "You must maintain the secrecy of any slaver activities except when doing so would conflict with the First, Second, or Third Law.") diff --git a/modular_splurt/code/game/machinery/computer/slavery.dm b/modular_splurt/code/game/machinery/computer/slavery.dm index 0aa441999e..8276f62302 100644 --- a/modular_splurt/code/game/machinery/computer/slavery.dm +++ b/modular_splurt/code/game/machinery/computer/slavery.dm @@ -1,3 +1,5 @@ +#define ANNOUNCEMENT_COOLDOWN 6 MINUTES + /obj/machinery/computer/slavery name = "\improper slave management console" desc = "Used to track and manage collared slaves. The limited range reaches only as far as the hideout perimeter." @@ -8,6 +10,7 @@ req_access = list(ACCESS_SLAVER) light_color = LIGHT_COLOR_RED var/obj/item/radio/headset/radio + var/last_announcement var/selected_cat /// Dictates if the compact mode of the interface is on or off var/compact_mode = FALSE @@ -42,6 +45,10 @@ /obj/machinery/computer/slavery/ui_static_data(mob/user) var/list/data = list() + + var/turf/curr = get_turf(src) + data["currentCoords"] = "[curr.x], [curr.y], [curr.z]" + data["value_table"] = GLOB.slavers_ransom_values data["categories"] = list() for(var/category in possible_gear) var/list/cat = list( @@ -56,22 +63,18 @@ )) data["categories"] += list(cat) - var/turf/curr = get_turf(src) - data["currentCoords"] = "[curr.x], [curr.y], [curr.z]" - return data - /obj/machinery/computer/slavery/ui_data(mob/user) var/list/data = list() - if (world.time < GLOB.slavers_last_announcement + 300) + if (world.time < last_announcement + ANNOUNCEMENT_COOLDOWN) data["intercomrecharging"] = TRUE else data["intercomrecharging"] = FALSE var/datum/bank_account/bank = SSeconomy.get_dep_account(ACCOUNT_CAR) - data["cargocredits"] = bank.account_balance + data["cargo_credits"] = bank.account_balance data["credits"] = GLOB.slavers_credits_balance data["compactMode"] = compact_mode var/list/slaves = list() @@ -90,11 +93,10 @@ var/list/slave = list() slave["id"] = REF(C) slave["name"] = L.real_name + slave["station_rank"] = C.station_rank slave["price"] = C.price - slave["pricechangecooldown"] = round((C.nextPriceChange - world.time) / 10) + slave["price_change_cooldown"] = round((C.nextPriceChange - world.time) / 10) slave["bought"] = C.bought - slave["shockcooldown"] = C.shock_cooldown; - slave["inexportbay"] = FALSE var/turf/curr = get_turf(src) if(pos.z == curr.z) //Distance/Direction calculations for same z-level only @@ -102,9 +104,14 @@ slave["dist"] = max(get_dist(curr, pos), 0) //Distance between the machine and slave turfs slave["degrees"] = round(Get_Angle(curr, pos)) //0-360 degree directional bearing, for more precision. + slave["shock_cooldown"] = C.shock_cooldown + + if (C.nextRecruitChance < world.time) + slave["can_recruit"] = TRUE + var/area/A = get_area(get_turf(L)) if (istype(A, /area/slavers/export)) - slave["inexportbay"] = TRUE + slave["in_export_bay"] = TRUE switch(L.stat) if(CONSCIOUS) @@ -145,7 +152,7 @@ switch(action) if ("makePriorityAnnouncement") - if (world.time < GLOB.slavers_last_announcement + 300) + if (world.time < last_announcement + ANNOUNCEMENT_COOLDOWN) say("Intercomms recharging. Please stand by.") return @@ -160,8 +167,8 @@ return input = user.treat_message(input) //Adds slurs and so on. Someone should make this use languages too. - priority_announce(input, sender_override = "[GLOB.slavers_team_name] Transmission") - GLOB.slavers_last_announcement = world.time + priority_announce(input, sender_override = GLOB.slavers_team_name) + last_announcement = world.time if("setPrice") var/newPrice = input(usr, "The station will need to pay this to get the slave back.", "Set slave price", collar.price) as num @@ -183,6 +190,37 @@ collar.setPrice(newPrice) + if("recruit") + var/mob/living/M = collar.loc + + if(QDELETED(M) || jobban_isbanned(M, ROLE_SLAVER) || jobban_isbanned(M, ROLE_SYNDICATE)) + radioAnnounce("[M.real_name] has failed the background check and cannot join our cause.") + collar.nextRecruitChance = INFINITY + return + + collar.nextRecruitChance = world.time + 10 MINUTES // 10 minutes before we can ask again + var/recruitResponse = tgui_alert(M, "It has been 15 minutes and your station has not paid your ransom. The slavers are offering for you to join their side.", "Recruitment Offer", list("Accept", "Maybe later", "Decline")) + switch(recruitResponse) + if ("Accept") + radioAnnounce("[M.real_name] has accepted the offer to join our cause!") + var/datum/antagonist/slaver/antag_datum = new + antag_datum.send_to_spawnpoint = FALSE + antag_datum.equip_outfit = FALSE + M.mind.add_antag_datum(antag_datum) + message_admins("[key_name_admin(M)] has been recruited as a slaver.") + log_admin("[key_name(M)] has been recruited as a slaver.") + qdel(collar) + return + if ("Maybe later") + radioAnnounce("[M.real_name] has declined the offer to join our cause for now.") + return + if ("Decline") + radioAnnounce("[M.real_name] has refused the offer to join our cause.") + collar.nextRecruitChance = INFINITY + return + + collar.nextRecruitChance = 0 // If the popup box closes a strange way such as a disconnect, do nothing and re-enable the chance to open it again + if("export") editBalance(collar.price) GLOB.slavers_credits_total += collar.price @@ -198,7 +236,7 @@ var/area/pod_storage_area = locate(/area/centcom/supplypod/podStorage) in GLOB.sortedAreas var/mob/living/M = collar.loc - priority_announce("[M.real_name] has been returned to the station for [collar.price] credits.", sender_override = "[GLOB.slavers_team_name] Transmission") + priority_announce("[M.real_name] has been returned to the station for [collar.price] credits.", sender_override = GLOB.slavers_team_name) var/obj/structure/closet/supplypod/centcompod/exportPod = new(pick(get_area_turfs(pod_storage_area))) var/obj/effect/landmark/observer_start/dropzone = locate(/obj/effect/landmark/observer_start) in GLOB.landmarks_list M.forceMove(exportPod) @@ -241,7 +279,7 @@ editBalance(-SG.cost) radioAnnounce("Supplies inbound: [SG.name]") - addtimer(CALLBACK(src, .proc/dropSupplies, SG.build_path), rand(4,8) * 10) + addtimer(CALLBACK(src, .proc/dropSupplies, SG.build_path), rand(3,6) * 10) return TRUE @@ -268,3 +306,5 @@ /obj/machinery/computer/slavery/proc/editBalance(ammount) GLOB.slavers_credits_balance += ammount + +#undef ANNOUNCEMENT_COOLDOWN diff --git a/modular_splurt/code/game/object/items/devices/radio/electropack.dm b/modular_splurt/code/game/object/items/devices/radio/electropack.dm index 8f5e24e0cb..85821e5bd3 100644 --- a/modular_splurt/code/game/object/items/devices/radio/electropack.dm +++ b/modular_splurt/code/game/object/items/devices/radio/electropack.dm @@ -2,12 +2,14 @@ name = "slave collar" desc = "A reinforced metal collar. This one has a shock element and tracker installed." - var/price = 0 // The ransom amount + var/price // The ransom amount var/bought = FALSE // Has the station paid the ransom - var/nextPriceChange = 0 // Last time the price was changed - var/nextRansomChange = 0 // Last time the ransom was paid / cancelled + var/station_rank + var/nextPriceChange // Last time the price was changed + var/nextRansomChange // Last time the ransom was paid / cancelled + var/nextRecruitChance = INFINITY // Next time the slave can get the option to join the slavers shockStrength = 400 - shockCooldown = 200 + shockCooldown = 20 SECONDS code = -1 frequency = -1 @@ -38,21 +40,33 @@ playsound(get_turf(M), 'sound/machines/triple_beep.ogg', 50, 1) ADD_TRAIT(src, TRAIT_NODROP, CLOTHING_TRAIT) + var/automatic_ransom_value = GLOB.slavers_ransom_values[M.job] + if (automatic_ransom_value) + station_rank = M.job + setPrice(automatic_ransom_value) + + /obj/item/electropack/shockcollar/slave/proc/setPrice(newPrice) var/mob/living/M = loc - var/announceMessage = "[M.real_name] has been captured. Send us [newPrice] credits with your communications console to get them back!" + + var/slaveJobText = "" + if (station_rank) + slaveJobText = " ([station_rank])" + + var/announceMessage = "[M.real_name][slaveJobText] has been captured. Send us [newPrice] credits with your communications console to get them back!" if (price) // If price has already been set once, we are just changing it if (newPrice > price) // Price has increased announceMessage = "[M.real_name]'s ransom has increased to [newPrice] credits." else // Price has decreased announceMessage = "[M.real_name]'s ransom has decreased to [newPrice] credits." - + else + nextRecruitChance = world.time + 15 MINUTES // Our first time setting the price, now we begin the countdown for when this slave can be recruited price = newPrice - nextPriceChange = world.time + 3000 // Cannot be changed again for 5 minutes - priority_announce(announceMessage, sender_override = "[GLOB.slavers_team_name] Transmission") + nextPriceChange = world.time + 5 MINUTES // Cannot be changed again for 5 minutes + priority_announce(announceMessage, sender_override = GLOB.slavers_team_name) /obj/item/electropack/shockcollar/slave/proc/setBought(isBought) bought = isBought - nextRansomChange = world.time + 1200 // Cannot be changed again for 2 minutes + nextRansomChange = world.time + 5 MINUTES // Cannot be changed again for 5 minutes diff --git a/modular_splurt/code/game/object/items/implants/implant_slaver.dm b/modular_splurt/code/game/object/items/implants/implant_slaver.dm index 2f6497f1f4..afa70e3e21 100644 --- a/modular_splurt/code/game/object/items/implants/implant_slaver.dm +++ b/modular_splurt/code/game/object/items/implants/implant_slaver.dm @@ -3,28 +3,30 @@ desc = "Returns you to the slave hideout (single use)." icon = 'icons/obj/abductor.dmi' icon_state = "implant" - activated = 1 - var/obj/machinery/abductor/pad/home /obj/item/implant/slaver/activate() . = ..() - playsound(get_turf(imp_in.loc), 'sound/magic/blink.ogg', 50, 1) - imp_in.visible_message("[imp_in] vanishes from sight!", \ - "You activate the [src], sending you to the slaver mothership!") - new /obj/effect/temp_visual/dir_setting/ninja(get_turf(imp_in), imp_in.dir) + imp_in.visible_message("[imp_in] begins fiddling with a subtle bump on their arm.", "You prepare to teleport.") + if(do_mob(imp_in, imp_in, 5 SECONDS, ignorehelditem = TRUE)) + playsound(get_turf(imp_in.loc), 'sound/magic/blink.ogg', 50, 1) + imp_in.visible_message("[imp_in] vanishes from sight!", \ + "You activate [src], sending you to the slaver mothership!") + new /obj/effect/temp_visual/dir_setting/ninja(get_turf(imp_in), imp_in.dir) - var/list/L = list() - for(var/turf/T in get_area_turfs(/area/slavers/export)) - L+=T + var/list/L = list() + for(var/turf/T in get_area_turfs(/area/slavers/export)) + L+=T - if(!L || !L.len) - to_chat(usr, "No area available.") - return + if(!L || !L.len) + to_chat(usr, "No area available.") + return - imp_in.forceMove(pick(L)) + imp_in.forceMove(pick(L)) - qdel(src) + qdel(src) + else + to_chat(imp_in, "You need to stand still and uninterrupted for 5 seconds!") /obj/item/implant/slaver/get_data() var/dat = {"Implant Specifications:
diff --git a/modular_splurt/code/modules/admin/verbs/one_click_antag.dm b/modular_splurt/code/modules/admin/verbs/one_click_antag.dm index 5860b138b2..a81978e731 100644 --- a/modular_splurt/code/modules/admin/verbs/one_click_antag.dm +++ b/modular_splurt/code/modules/admin/verbs/one_click_antag.dm @@ -11,7 +11,7 @@ for(var/i = 0, i[src] is out of power!") + return FALSE + if(!user.mind.has_antag_datum(/datum/antagonist/slaver,TRUE)) + to_chat(user, "AUTHENTICATION FAILURE. ACCESS DENIED.") + return FALSE + var/area/A = get_area(get_turf(user)) + if (!istype(A, /area/slavers)) + to_chat(user, "[src] is out of range! It can only be used at your hideout!") + return FALSE + + return TRUE + +/obj/item/antag_spawner/slaver_borg/attack_self(mob/user) + if(!(check_usability(user))) + return + + if(!(next_attempt_allowed < world.time)) + to_chat(user, "A request has already been sent! Wait 1 minute.") + return + next_attempt_allowed = world.time + 1 MINUTES + + to_chat(user, "You activate [src] and wait for confirmation.") + var/list/borg_candidates = pollGhostCandidates("Do you want to play as a slaver [lowertext(borg_to_spawn)] cyborg?", ROLE_SLAVER, null, ROLE_SLAVER, 150, POLL_IGNORE_SLAVER) + if(LAZYLEN(borg_candidates)) + if(QDELETED(src) || !check_usability(user)) + return + used = TRUE + var/mob/dead/observer/G = pick(borg_candidates) + spawn_antag(G.client, get_turf(src), "slaverborg", user.mind) + do_sparks(4, TRUE, src) + qdel(src) + else + to_chat(user, "Unable to connect to Slaver command. Please wait and try again later.") + +/obj/item/antag_spawner/slaver_borg/spawn_antag(client/C, turf/T, kind, datum/mind/user) + var/mob/living/silicon/robot/R + var/datum/antagonist/slaver/creator_slaver = user.has_antag_datum(/datum/antagonist/slaver,TRUE) + if(!creator_slaver) + return + + switch(borg_to_spawn) + if("Medical") + R = new /mob/living/silicon/robot/modules/syndicate/slaver/medical(T) + else + R = new /mob/living/silicon/robot/modules/slaver(T) + + var/brainopsname = C.prefs.real_name + + R.mmi.name = "Man-Machine Interface: [brainopsname]" + R.mmi.brain.name = "[brainopsname]'s brain" + R.mmi.brainmob.real_name = brainopsname + R.mmi.brainmob.name = brainopsname + + R.key = C.key + R.apply_pref_name("cyborg", C) + + var/datum/antagonist/slaver/new_borg = new() + new_borg.send_to_spawnpoint = FALSE + R.mind.add_antag_datum(new_borg,creator_slaver.slaver_team) + R.mind.special_role = "Slaver Cyborg" diff --git a/modular_splurt/code/modules/antagonists/slaver/equipment/orderable_gear.dm b/modular_splurt/code/modules/antagonists/slaver/equipment/orderable_gear.dm index 5d2e8da05e..c460c46503 100644 --- a/modular_splurt/code/modules/antagonists/slaver/equipment/orderable_gear.dm +++ b/modular_splurt/code/modules/antagonists/slaver/equipment/orderable_gear.dm @@ -176,6 +176,20 @@ GLOBAL_LIST_INIT(slaver_gear, subtypesof(/datum/slaver_gear)) category = "Implants" cost = 15000 +/datum/slaver_gear/borg_generic + name = "Cyborg (Generic)" + description = "A hacked cyborg, capable of using any module." + build_path = /obj/item/antag_spawner/slaver_borg + category = "Mech" + cost = 50000 + +/datum/slaver_gear/borg_medical + name = "Cyborg (Medical)" + description = "A hacked medical combat cyborg, outfitted with a regenerative beam-gun and more powerful healing chemical." + build_path = /obj/item/antag_spawner/slaver_borg/medical + category = "Mech" + cost = 50000 + /datum/slaver_gear/mech name = "Gygax 'Riot-Control' Exosuit" description = "A lightweight, agile mecha. Weapons sold separately." diff --git a/modular_splurt/code/modules/antagonists/slaver/slaver.dm b/modular_splurt/code/modules/antagonists/slaver/slaver.dm index b34977dbf3..5b680707e0 100644 --- a/modular_splurt/code/modules/antagonists/slaver/slaver.dm +++ b/modular_splurt/code/modules/antagonists/slaver/slaver.dm @@ -1,9 +1,55 @@ GLOBAL_VAR_INIT(slavers_team_name, "Slave Traders") GLOBAL_VAR_INIT(slavers_spawned, FALSE) -GLOBAL_VAR_INIT(slavers_credits_balance, 4000) +GLOBAL_VAR_INIT(slavers_credits_balance, 5000) GLOBAL_VAR_INIT(slavers_credits_total, 0) GLOBAL_VAR_INIT(slavers_slaves_sold, 0) -GLOBAL_VAR_INIT(slavers_last_announcement, 0) + +#define SLAVER_STANDARD_RANSOM 7500 + +/// Price table for when trying to set slave prices automatically +GLOBAL_LIST_INIT(slavers_ransom_values, list( + "Captain" = 175000, + "Head of Personnel" = 125000, + "Head of Security" = 100000, + "Chief Engineer" = 80000, + "Research Director" = 80000, + "Chief Medical Officer" = 80000, + "Blueshield" = 30000, + + "Warden" = 30000, + "Brig Physician" = 20000, + "Security Officer" = 20000, + "Detective" = 20000, + + "Quartermaster" = 10000, + "Cargo Technician" = SLAVER_STANDARD_RANSOM, + "Shaft Miner" = SLAVER_STANDARD_RANSOM, + "Assistant" = SLAVER_STANDARD_RANSOM, + "Bartender" = SLAVER_STANDARD_RANSOM, + "Cook" = SLAVER_STANDARD_RANSOM, + "Botanist" = SLAVER_STANDARD_RANSOM, + "Janitor" = SLAVER_STANDARD_RANSOM, + "Clown" = SLAVER_STANDARD_RANSOM, + "Mime" = SLAVER_STANDARD_RANSOM, + "Curator" = SLAVER_STANDARD_RANSOM, + "Lawyer" = SLAVER_STANDARD_RANSOM, + "Chaplain" = SLAVER_STANDARD_RANSOM, + "Station Engineer" = SLAVER_STANDARD_RANSOM, + "Atmospheric Technician" = SLAVER_STANDARD_RANSOM, + "Medical Doctor" = SLAVER_STANDARD_RANSOM, + "Paramedic" = SLAVER_STANDARD_RANSOM, + "Chemist" = SLAVER_STANDARD_RANSOM, + "Virologist" = SLAVER_STANDARD_RANSOM, + "Geneticist" = SLAVER_STANDARD_RANSOM, + "Scientist" = SLAVER_STANDARD_RANSOM, + "Roboticist" = SLAVER_STANDARD_RANSOM, + "Prisoner" = SLAVER_STANDARD_RANSOM, + "Curator" = SLAVER_STANDARD_RANSOM, + "Lawyer" = SLAVER_STANDARD_RANSOM, + "Chaplain" = SLAVER_STANDARD_RANSOM, +)) + +#undef SLAVER_STANDARD_RANSOM /datum/antagonist/slaver name = "Slave Trader" @@ -13,9 +59,10 @@ GLOBAL_VAR_INIT(slavers_last_announcement, 0) antag_moodlet = /datum/mood_event/focused threat = 7 show_to_ghosts = TRUE - var/datum/team/slavers/slaver_team = new /datum/team/slavers + var/static/datum/team/slavers/slaver_team = new /datum/team/slavers var/slaver_outfit = /datum/outfit/slaver var/send_to_spawnpoint = TRUE //Should the user be moved to default spawnpoint. + var/equip_outfit = TRUE /datum/antagonist/slaver/proc/update_slaver_icons_added(mob/living/M) var/datum/atom_hud/antag/slaverhud = GLOB.huds[ANTAG_HUD_SLAVER] @@ -56,7 +103,8 @@ GLOBAL_VAR_INIT(slavers_last_announcement, 0) /datum/antagonist/slaver/on_gain() forge_objectives() . = ..() - equip_slaver() + if(equip_outfit) + equip_slaver() if(send_to_spawnpoint) move_to_spawnpoint() @@ -84,7 +132,6 @@ GLOBAL_VAR_INIT(slavers_last_announcement, 0) /datum/antagonist/slaver/admin_add(datum/mind/new_owner,mob/admin) send_to_spawnpoint = FALSE - new_owner.assigned_role = ROLE_SLAVER new_owner.add_antag_datum(src) message_admins("[key_name_admin(admin)] has slaver'd [new_owner.current].") diff --git a/modular_splurt/code/modules/mob/living/silicon/robot/robot.dm b/modular_splurt/code/modules/mob/living/silicon/robot/robot.dm new file mode 100644 index 0000000000..e7ed13d58a --- /dev/null +++ b/modular_splurt/code/modules/mob/living/silicon/robot/robot.dm @@ -0,0 +1,34 @@ +// Slaver medical borg +/mob/living/silicon/robot/modules/syndicate/slaver/medical + faction = list(ROLE_SLAVER) + req_access = list(ACCESS_SLAVER) + icon_state = "synd_medical" + set_module = /obj/item/robot_module/syndicate_medical/slaver + playstyle_string = "You are a Slaver medical cyborg!
\ + You are armed with powerful medical tools to aid you in your mission: help the slavers kidnap crew. \ + Your hypospray will produce Restorative Nanites, a wonder-drug that will heal most types of bodily damages, including clone and brain damage. It also produces morphine for offense. \ + Your defibrillator paddles can revive slavers through their hardsuits, or can be used on harm intent to shock enemies! \ + Your energy saw functions as a circular saw, but can be activated to deal more damage." + +/mob/living/silicon/robot/modules/syndicate/slaver/medical/Initialize() + . = ..() + + laws = new /datum/ai_laws/slaver_override + laws.associate(src) + +/mob/living/silicon/robot/modules/slaver + faction = list(ROLE_SLAVER) + req_access = list(ACCESS_SLAVER) + emagged = TRUE + lawupdate = FALSE + +// Slaver generic borg +/mob/living/silicon/robot/modules/slaver/Initialize() + . = ..() + + SetEmagged(1) + lawupdate = FALSE + set_connected_ai(null) + laws = new /datum/ai_laws/slaver_override + laws.associate(src) + update_icons() diff --git a/modular_splurt/code/modules/mob/living/silicon/robot/robot_modules.dm b/modular_splurt/code/modules/mob/living/silicon/robot/robot_modules.dm index f21d79a346..9f8813337e 100644 --- a/modular_splurt/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/modular_splurt/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -157,3 +157,13 @@ cyborg_icon_override = 'modular_splurt/icons/mob/robots.dmi' hat_offset = 3 return ..() + +/obj/item/robot_module/syndicate_medical/slaver + name = "Slaver Medical Combat" + +/obj/item/robot_module/syndicate_medical/slaver/Initialize() + var/list/extra_tools = list( + /obj/item/slaver/gizmo + ) + LAZYADD(basic_modules, extra_tools) + . = ..() diff --git a/tgstation.dme b/tgstation.dme index 1e08bdb6f5..b5ebc931a0 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4205,6 +4205,7 @@ #include "modular_splurt\code\controllers\configuration\entries\splurt_general.dm" #include "modular_splurt\code\controllers\subsystem\discord.dm" #include "modular_splurt\code\controllers\subsystem\redbot.dm" +#include "modular_splurt\code\datums\ai_laws.dm" #include "modular_splurt\code\datums\mind.dm" #include "modular_splurt\code\datums\shuttles.dm" #include "modular_splurt\code\datums\world_topic.dm" @@ -4260,6 +4261,7 @@ #include "modular_splurt\code\game\object\structures\barricades.dm" #include "modular_splurt\code\game\object\structures\bathroom.dm" #include "modular_splurt\code\game\object\structures\dresser.dm" +#include "modular_splurt\code\modules\mob\living\silicon\robot\robot.dm" #include "modular_splurt\code\game\object\structures\false_walls.dm" #include "modular_splurt\code\game\object\structures\flora.dm" #include "modular_splurt\code\game\object\structures\ghost_role_spawners.dm" @@ -4284,6 +4286,7 @@ #include "modular_splurt\code\modules\admin\verbs\discordbunker.dm" #include "modular_splurt\code\modules\admin\verbs\one_click_antag.dm" #include "modular_splurt\code\modules\admin\verbs\randomverbs.dm" +#include "modular_splurt\code\modules\antagonists\_common\antag_spawner.dm" #include "modular_splurt\code\modules\antagonists\slaver\slaver.dm" #include "modular_splurt\code\modules\antagonists\slaver\equipment\orderable_gear.dm" #include "modular_splurt\code\modules\antagonists\slaver\equipment\slaver_items.dm" diff --git a/tgui/packages/tgui/interfaces/CommunicationsConsole.js b/tgui/packages/tgui/interfaces/CommunicationsConsole.js index 090b0a8bc3..25fdacfa72 100644 --- a/tgui/packages/tgui/interfaces/CommunicationsConsole.js +++ b/tgui/packages/tgui/interfaces/CommunicationsConsole.js @@ -1,7 +1,7 @@ import { sortBy } from "common/collections"; import { capitalize } from "common/string"; import { useBackend, useLocalState } from "../backend"; -import { Blink, Box, Button, Dimmer, Flex, Icon, Input, Modal, Section, TextArea, Table, LabeledList } from "../components"; +import { Blink, Box, Button, Dimmer, Flex, Icon, Input, Modal, Section, TextArea, LabeledList } from "../components"; import { Window } from "../layouts"; import { sanitizeText } from "../sanitize"; import { formatMoney } from '../format'; @@ -494,26 +494,32 @@ const PageMain = (props, context) => { - + {slaves.map(slave => ( - + className="candystripe" + align="center" + p=".5rem"> - + {slave.name} - + - + {slave.toggleransomfeedback} - + - + align="right" + pl=".5rem" + >
+ )} diff --git a/tgui/packages/tgui/interfaces/SlaveConsole.js b/tgui/packages/tgui/interfaces/SlaveConsole.js index f6f212dda2..2cb5545ec5 100644 --- a/tgui/packages/tgui/interfaces/SlaveConsole.js +++ b/tgui/packages/tgui/interfaces/SlaveConsole.js @@ -2,7 +2,7 @@ import { map, sortBy } from 'common/collections'; import { flow } from 'common/fp'; import { vecLength, vecSubtract } from 'common/vector'; import { useBackend, useSharedState } from '../backend'; -import { Box, Button, Icon, LabeledList, Section, Tabs, NoticeBox, Fragment } from '../components'; +import { Box, Button, Icon, LabeledList, Section, Tabs, Flex, NoticeBox, Fragment } from '../components'; import { Window } from '../layouts'; import { GenericUplink } from './Uplink'; import { formatMoney } from '../format'; @@ -14,10 +14,12 @@ export const SlaveConsole = (props, context) => { const [tab, setTab] = useSharedState(context, 'tab', 1); const { intercomrecharging, - cargocredits, + cargo_credits, credits, currentCoords, + value_table, } = data; + const slaves = flow([ map((slave, index) => { // Calculate distance to the target. BYOND distance is capped to 127, @@ -35,7 +37,7 @@ export const SlaveConsole = (props, context) => { return ( @@ -58,7 +60,7 @@ export const SlaveConsole = (props, context) => { - {formatMoney(cargocredits, null, true)}cr + {formatMoney(cargo_credits, null, true)}cr @@ -78,6 +80,13 @@ export const SlaveConsole = (props, context) => { onClick={() => setTab(2)}> Supplies + setTab(3)}> + Ransom Table + {tab === 1 && ( { )} + {tab === 3 && ( + + )} @@ -98,7 +111,7 @@ const SlavePanel = (props, context) => { const { act, data } = useBackend(context); if (!slaves.length) { return ( - + No slaves detected in hideout ); @@ -110,11 +123,22 @@ const SlavePanel = (props, context) => { title={slave.name} buttons={( +