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={(
+