From f3726aba32344ec17d32a0ad2cb261ff9a381d19 Mon Sep 17 00:00:00 2001 From: James Date: Thu, 2 Dec 2021 17:01:23 +0000 Subject: [PATCH] Added slave collars, slave console and modified comms console --- _maps/map_files/generic/CentCom.dmm | 792 +++++++++--------- code/__DEFINES/access.dm | 1 + code/__DEFINES/atom_hud.dm | 3 +- code/__DEFINES/role_preferences.dm | 2 + code/__DEFINES/traits.dm | 1 + code/_globalvars/lists/mapping.dm | 2 + code/_globalvars/lists/objects.dm | 1 + code/datums/hud.dm | 3 +- code/datums/mind.dm | 14 + .../game/gamemodes/bloodsucker/bloodsucker.dm | 2 +- code/game/gamemodes/objective.dm | 9 + .../game/machinery/computer/communications.dm | 1 + code/game/machinery/computer/slavery.dm | 117 +++ code/game/objects/effects/landmarks.dm | 24 + .../items/devices/radio/electropack.dm | 18 + code/modules/admin/topic.dm | 8 + code/modules/admin/verbs/one_click_antag.dm | 45 + code/modules/admin/verbs/randomverbs.dm | 4 + .../slaver/equipment/slaver_outfits.dm | 41 + code/modules/antagonists/slaver/slaver.dm | 177 ++++ code/modules/mob/mob_helpers.dm | 3 + icons/mob/hud.dmi | Bin 18163 -> 18088 bytes tgstation.dme | 3 + .../tgui/interfaces/CommunicationsConsole.js | 53 +- tgui/packages/tgui/interfaces/SlaveConsole.js | 196 +++++ 25 files changed, 1138 insertions(+), 382 deletions(-) create mode 100644 code/game/machinery/computer/slavery.dm create mode 100644 code/modules/antagonists/slaver/equipment/slaver_outfits.dm create mode 100644 code/modules/antagonists/slaver/slaver.dm create mode 100644 tgui/packages/tgui/interfaces/SlaveConsole.js diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index c267f9fb7d..a8f9178a83 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -16794,6 +16794,10 @@ }, /turf/open/indestructible/boss/air, /area/centcom/holding) +"Mu" = ( +/obj/machinery/computer/robotics, +/turf/open/indestructible/hotelwood, +/area/syndicate_mothership) "Mv" = ( /obj/structure/table/reinforced, /obj/item/storage/fancy/donut_box, @@ -17309,6 +17313,9 @@ }, /turf/open/floor/mineral/titanium/blue, /area/centcom/holding) +"OQ" = ( +/turf/open/indestructible/hotelwood, +/area/syndicate_mothership) "OS" = ( /obj/structure/mecha_wreckage/mauler, /turf/open/floor/plasteel/dark, @@ -17327,10 +17334,23 @@ }, /turf/open/floor/wood, /area/syndicate_mothership) +"OY" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/indestructible/hotelwood, +/area/syndicate_mothership) "OZ" = ( /obj/effect/turf_decal/delivery, /turf/open/floor/plating, /area/syndicate_mothership) +"Pc" = ( +/turf/closed/indestructible{ + icon = 'icons/turf/walls/wood_wall.dmi'; + icon_state = "wood"; + smooth = 1 + }, +/area/syndicate_mothership) "Pg" = ( /obj/machinery/light{ dir = 1 @@ -18557,6 +18577,10 @@ }, /turf/open/indestructible/hotelwood, /area/centcom/holding) +"WB" = ( +/obj/effect/landmark/start/slaver, +/turf/open/floor/carpet, +/area/syndicate_mothership) "WC" = ( /obj/structure/table/reinforced, /obj/item/pen, @@ -18654,6 +18678,10 @@ /obj/item/vending_refill/snack, /turf/open/indestructible/hotelwood, /area/centcom/holding) +"Xc" = ( +/obj/effect/landmark/start/slaver_leader, +/turf/open/floor/carpet, +/area/syndicate_mothership) "Xd" = ( /obj/structure/flora/ausbushes/fernybush, /obj/structure/flora/ausbushes/fullgrass, @@ -18771,6 +18799,10 @@ "XN" = ( /turf/open/floor/carpet/red, /area/centcom/holding) +"XP" = ( +/obj/machinery/computer/telecrystals, +/turf/open/indestructible/hotelwood, +/area/syndicate_mothership) "XT" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/snacks/sashimi, @@ -18837,6 +18869,10 @@ /obj/structure/dresser, /turf/open/floor/plasteel/dark, /area/syndicate_mothership) +"Yj" = ( +/obj/machinery/computer/slavery, +/turf/open/indestructible/hotelwood, +/area/syndicate_mothership) "Ym" = ( /obj/machinery/computer/arcade/orion_trail, /turf/open/indestructible/hotelwood, @@ -53000,24 +53036,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc aa aa aa @@ -53257,24 +53293,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +Pc aa aa aa @@ -53514,24 +53550,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +Pc aa aa aa @@ -53771,24 +53807,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OY +OQ +Pc aa aa aa @@ -54028,24 +54064,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OQ +OY +OQ +OQ +OQ +OQ +OQ +OQ +OY +OQ +OQ +OQ +OY +OQ +Pc aa aa aa @@ -54285,24 +54321,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +Pc aa aa aa @@ -54542,24 +54578,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +Pc aa aa aa @@ -54799,24 +54835,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OY +OQ +Mu +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +Pc aa aa aa @@ -55056,24 +55092,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OQ +OQ +OQ +OQ +OY +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +Pc aa aa aa @@ -55313,24 +55349,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +WB +OQ +OQ +OQ +OQ +OQ +OQ +OQ +Pc aa aa aa @@ -55570,24 +55606,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OQ +OQ +Yj +OQ +Xc +OQ +WB +OQ +OQ +OQ +OQ +OQ +OQ +OQ +Pc aa aa aa @@ -55827,24 +55863,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +WB +OQ +OY +OQ +OQ +OQ +OQ +OQ +Pc aa aa aa @@ -56084,24 +56120,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OY +OQ +OQ +OQ +OQ +OQ +WB +OQ +OQ +OQ +OQ +OY +OQ +OQ +Pc aa aa aa @@ -56341,24 +56377,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +WB +OQ +OQ +OQ +OQ +OQ +OQ +OQ +Pc aa aa aa @@ -56598,24 +56634,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OQ +OQ +OQ +XP +OY +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +Pc aa aa aa @@ -56855,24 +56891,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +Pc aa aa aa @@ -57112,24 +57148,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +Pc aa aa aa @@ -57369,24 +57405,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OY +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OY +OQ +OQ +OQ +Pc aa aa aa @@ -57626,24 +57662,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +Pc aa aa aa @@ -57883,24 +57919,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +OQ +Pc aa aa aa @@ -58140,24 +58176,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc +Pc aa aa aa diff --git a/code/__DEFINES/access.dm b/code/__DEFINES/access.dm index c2021a86f2..a7b690e210 100644 --- a/code/__DEFINES/access.dm +++ b/code/__DEFINES/access.dm @@ -83,6 +83,7 @@ //The Syndicate #define ACCESS_SYNDICATE 150//General Syndicate Access. Includes Syndicate mechs and ruins. #define ACCESS_SYNDICATE_LEADER 151//Nuke Op Leader Access +#define ACCESS_SLAVER 152 //Slaver traders //Away Missions or Ruins /*For generic away-mission/ruin access. Why would normal crew have access to a long-abandoned derelict diff --git a/code/__DEFINES/atom_hud.dm b/code/__DEFINES/atom_hud.dm index 386473a3ae..d060944d70 100644 --- a/code/__DEFINES/atom_hud.dm +++ b/code/__DEFINES/atom_hud.dm @@ -60,7 +60,8 @@ #define ANTAG_HUD_BROTHER 23 #define ANTAG_HUD_BLOODSUCKER 24 #define ANTAG_HUD_FUGITIVE 25 -#define ANTAG_HUD_HERETIC 26 +#define ANTAG_HUD_HERETIC 26 +#define ANTAG_HUD_SLAVER 27 // Notification action types #define NOTIFY_JUMP "jump" diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 19ccf5fdc1..7fd88c5fe1 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -9,6 +9,7 @@ #define ROLE_SYNDICATE "Syndicate" #define ROLE_TRAITOR "traitor" #define ROLE_OPERATIVE "operative" +#define ROLE_SLAVER "slaver" #define ROLE_CHANGELING "changeling" #define ROLE_WIZARD "wizard" #define ROLE_MALF "malf AI" @@ -55,6 +56,7 @@ GLOBAL_LIST_INIT(special_roles, list( ROLE_TRAITOR = /datum/game_mode/traitor, ROLE_BROTHER = /datum/game_mode/traitor/bros, ROLE_OPERATIVE = /datum/game_mode/nuclear, + ROLE_SLAVER, ROLE_CHANGELING = /datum/game_mode/changeling, ROLE_WIZARD = /datum/game_mode/wizard, ROLE_MALF, diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 811ad111c4..40abb10ff7 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -335,6 +335,7 @@ #define DOMAIN_TRAIT "domain" #define NUKEOP_TRAIT "nuke-op" #define CLOWNOP_TRAIT "clown-op" +#define SLAVER_TRAIT "slaver" #define MEGAFAUNA_TRAIT "megafauna" #define DEATHSQUAD_TRAIT "deathsquad" #define SLIMEPUDDLE_TRAIT "slimepuddle" diff --git a/code/_globalvars/lists/mapping.dm b/code/_globalvars/lists/mapping.dm index 1e3f8d25eb..c831edba85 100644 --- a/code/_globalvars/lists/mapping.dm +++ b/code/_globalvars/lists/mapping.dm @@ -21,6 +21,8 @@ GLOBAL_LIST_EMPTY(jobspawn_overrides) //These will take precedence over norm GLOBAL_LIST_EMPTY(wizardstart) GLOBAL_LIST_EMPTY(nukeop_start) GLOBAL_LIST_EMPTY(nukeop_leader_start) +GLOBAL_LIST_EMPTY(slaver_start) +GLOBAL_LIST_EMPTY(slaver_leader_start) GLOBAL_LIST_EMPTY(newplayer_start) GLOBAL_LIST_EMPTY(prisonwarp) //prisoners go to these GLOBAL_LIST_EMPTY(holdingfacility) //captured people go here diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index 9abc37c7e4..662e122419 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -26,6 +26,7 @@ GLOBAL_LIST_EMPTY(rcd_list) //list of Rapid Construction Devices. GLOBAL_LIST_EMPTY(apcs_list) //list of all Area Power Controller machines, separate from machines for powernet speeeeeeed. GLOBAL_LIST_EMPTY(tracked_implants) //list of all current implants that are tracked to work out what sort of trek everyone is on. Sadly not on lavaworld not implemented... GLOBAL_LIST_EMPTY(tracked_chem_implants) //list of implants the prisoner console can track and send inject commands too +GLOBAL_LIST_EMPTY(tracked_slaves) //list of mobs with slaver collars equipped. GLOBAL_LIST_EMPTY(poi_list) //list of points of interest for observe/follow GLOBAL_LIST_EMPTY(pinpointer_list) //list of all pinpointers. Used to change stuff they are pointing to all at once. GLOBAL_LIST_EMPTY(zombie_infection_list) // A list of all zombie_infection organs, for any mass "animation" diff --git a/code/datums/hud.dm b/code/datums/hud.dm index 1c23d5f2a0..fcf13cac4c 100644 --- a/code/datums/hud.dm +++ b/code/datums/hud.dm @@ -29,7 +29,8 @@ GLOBAL_LIST_INIT(huds, list( ANTAG_HUD_BROTHER = new/datum/atom_hud/antag/hidden(), ANTAG_HUD_BLOODSUCKER = new/datum/atom_hud/antag/bloodsucker(), ANTAG_HUD_FUGITIVE = new/datum/atom_hud/antag(), - ANTAG_HUD_HERETIC = new/datum/atom_hud/antag/hidden() + ANTAG_HUD_HERETIC = new/datum/atom_hud/antag/hidden(), + ANTAG_HUD_SLAVER = new/datum/atom_hud/antag(), )) /datum/atom_hud diff --git a/code/datums/mind.dm b/code/datums/mind.dm index fe8a7db23d..33d640c4dd 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -234,6 +234,12 @@ remove_antag_datum(nuke.type) special_role = null +/datum/mind/proc/remove_slaver() + var/datum/antagonist/slaver/slaver = has_antag_datum(/datum/antagonist/slaver,TRUE) + if(slaver) + remove_antag_datum(slaver.type) + special_role = null + /datum/mind/proc/remove_wizard() remove_antag_datum(/datum/antagonist/wizard) special_role = null @@ -263,6 +269,7 @@ remove_changeling() remove_traitor() remove_nukeop() + remove_slaver() remove_wizard() remove_cultist() remove_rev() @@ -367,6 +374,13 @@ N.nukeop_outfit = null add_antag_datum(N,converter.nuke_team) + else if(is_slaver(creator)) + var/datum/antagonist/slaver/converter = creator.mind.has_antag_datum(/datum/antagonist/slaver,TRUE) + var/datum/antagonist/slaver/S = new() + S.send_to_spawnpoint = FALSE + S.slaver_outfit = null + add_antag_datum(S,converter.slaver_team) + enslaved_to = creator diff --git a/code/game/gamemodes/bloodsucker/bloodsucker.dm b/code/game/gamemodes/bloodsucker/bloodsucker.dm index aa8edeaa72..6acedb0d52 100644 --- a/code/game/gamemodes/bloodsucker/bloodsucker.dm +++ b/code/game/gamemodes/bloodsucker/bloodsucker.dm @@ -7,7 +7,7 @@ // LISTS // var/list/vassal_allowed_antags = list(/datum/antagonist/brother, /datum/antagonist/traitor, /datum/antagonist/traitor/internal_affairs, /datum/antagonist/survivalist, \ - /datum/antagonist/rev, /datum/antagonist/nukeop, /datum/antagonist/pirate, /datum/antagonist/cult, /datum/antagonist/abductee, /datum/antagonist/valentine, /datum/antagonist/heartbreaker,) + /datum/antagonist/rev, /datum/antagonist/nukeop, /datum/antagonist/slaver, /datum/antagonist/pirate, /datum/antagonist/cult, /datum/antagonist/abductee, /datum/antagonist/valentine, /datum/antagonist/heartbreaker,) // The antags you're allowed to be if turning Vassal. /proc/AmBloodsucker(mob/living/M, falseIfInDisguise = FALSE) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 1c6c444fb4..193ab47ad1 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -557,6 +557,15 @@ If not set, defaults to check_completion instead. Set it. It's used by cryo. return TRUE return FALSE +/datum/objective/slaver + name = "slaver" + explanation_text = "Capture some of the station crew. Bring them back to the hideout." + +/datum/objective/slaver/check_completion() + // if(SSticker && SSticker.mode && SSticker.mode.station_was_nuked) + // return TRUE + return FALSE + GLOBAL_LIST_EMPTY(possible_items) /datum/objective/steal name = "steal" diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 822302789f..df3fb00f61 100755 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -376,6 +376,7 @@ data["authorizeName"] = authorize_name data["canLogOut"] = !issilicon(user) data["shuttleCanEvacOrFailReason"] = SSshuttle.canEvac(user, TRUE) + data["availableSlaves"] = TRUE // GLOB.tracked_slaves if (authenticated_as_non_silicon_captain(user)) data["canRequestNuke"] = TRUE diff --git a/code/game/machinery/computer/slavery.dm b/code/game/machinery/computer/slavery.dm new file mode 100644 index 0000000000..c452063621 --- /dev/null +++ b/code/game/machinery/computer/slavery.dm @@ -0,0 +1,117 @@ +/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." + icon_screen = "explosive" + icon_keyboard = "security_key" + clockwork = TRUE + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + req_access = list(ACCESS_SLAVER) + light_color = LIGHT_COLOR_RED + +// /obj/machinery/computer/slavery/ui_interact(mob/user) +// . = ..() +// var/dat = "" +// dat += "Refresh.
" +// dat += "[storedcrystals] telecrystals are available for distribution.
" +// dat += "

" + +// dat += "
Slaves
" +// for(var/obj/item/electropack/shockcollar/slave/S in GLOB.tracked_slaves) +// if(!isliving(loc)) +// continue +// Tr = get_turf(T.imp_in) +// if((Tr) && (Tr.z != src.z)) +// continue//Out of range + +// var/loc_display = "Unknown" +// var/mob/living/M = T.imp_in +// if(is_station_level(Tr.z) && !isspaceturf(M.loc)) +// var/turf/mob_loc = get_turf(M) +// loc_display = mob_loc.loc + +// dat += "ID: [T.imp_in.name] | Location: [loc_display]
" +// dat += "(Message Holder) |
" +// dat += "********************************
" +// dat += "
{Log Out}" + +/obj/machinery/computer/slavery/ui_interact(mob/user, datum/tgui/ui) + // priority_announce("Message test 123 123 Message test 123 123 Message test 123 123 Message test 123 123 Message test 123 123.", sender_override = "Hail from the [slaver_team.slaver_crew_name]") + // if(!GLOB.bounties_list.len) + // setup_bounties() + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "SlaveConsole", name) + ui.open() + +/obj/machinery/computer/slavery/ui_data(mob/user) + var/list/data = list() + + var/turf/curr = get_turf(src) + data["currentCoords"] = "[curr.x], [curr.y], [curr.z]" + + var/list/slaves = list() + data["slaves"] = list() + + for(var/tracked_slave in GLOB.tracked_slaves) + var/obj/item/electropack/shockcollar/slave/C = tracked_slave + if (!isliving(C.loc)) + continue; + + var/mob/living/L = C.loc + var/turf/pos = get_turf(L) + if(!pos || pos.z != curr.z || C == L.get_item_by_slot(SLOT_NECK)) + continue + + var/list/slave = list() + slave["id"] = C.collarID + priority_announce("Getting collar ID first: [C.GetID()] end.", sender_override = "toggleBought") + slave["name"] = L.real_name + slave["bought"] = C.bought + + slave["coords"] = "[pos.x], [pos.y], [pos.z]" + 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. + slaves += list(slave) //Add this slave to the list of slaves + data["slaves"] = slaves + return data + +/obj/machinery/computer/slavery/ui_act(action, params) + if(..()) + return + + switch(action) + if ("makePriorityAnnouncement") + priority_announce("Announcement.", sender_override = "Beep Beep upgate") + // var/is_ai = issilicon(user) + // if(!SScommunications.can_announce(user, is_ai)) + // to_chat(user, "Intercomms recharging. Please stand by.") + // return + // var/input = stripped_input(user, "Please choose a message to announce to the station crew.", "What?") + // if(!input || !user.canUseTopic(src, !issilicon(usr))) + // return + // if(!(user.can_speak())) //No more cheating, mime/random mute guy! + // input = "..." + // to_chat(user, "You find yourself unable to speak.") + // else + // input = user.treat_message(input) //Adds slurs and so on. Someone should make this use languages too. + // SScommunications.make_announcement(user, is_ai, input) + // deadchat_broadcast(" made a priority announcement from [get_area_name(usr, TRUE)].", "[user.real_name]", user) + + if("purchaseSupplies") + priority_announce("Purchase Supplies.", sender_override = "Beep Beep upgate") + + if("toggleBought") + var/boughtID = text2num(params["id"]) + priority_announce("Collar ID is: [boughtID] end.", sender_override = "toggleBought") + + for(var/tracked_slave in GLOB.tracked_slaves) + var/obj/item/electropack/shockcollar/slave/C = tracked_slave + if (C.collarID == boughtID) + if (!isliving(C.loc)) + priority_announce("Not living location", sender_override = "toggleBought") + continue; + + var/mob/living/L = C.loc + priority_announce("Slave ckey is: [L.ckey] end.", sender_override = "toggleBought") + + diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 8ff4017b8c..c87b1f1133 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -270,6 +270,30 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) GLOB.nukeop_leader_start += loc return INITIALIZE_HINT_QDEL + + +/obj/effect/landmark/start/slaver + name = "slaver" + icon = 'icons/effects/landmarks_static.dmi' + icon_state = "sslaver_spawn" + +/obj/effect/landmark/start/slaver/Initialize() + ..() + GLOB.slaver_start += loc + return INITIALIZE_HINT_QDEL + +/obj/effect/landmark/start/slaver_leader + name = "slaver leader" + icon = 'icons/effects/landmarks_static.dmi' + icon_state = "sslaver_leader_spawn" + +/obj/effect/landmark/start/slaver_leader/Initialize() + ..() + GLOB.slaver_leader_start += loc + return INITIALIZE_HINT_QDEL + + + // Must be immediate because players will // join before SSatom initializes everything. INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index c51edc8106..852316b02b 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -202,3 +202,21 @@ if(action == "power") // DO. NOT. return FALSE return ..() + +/obj/item/electropack/shockcollar/slave + name = "slave collar" + desc = "A reinforced metal collar. This one has a shock element and tracker installed." + var/static/lastID = 0; + var/collarID + var/bought = FALSE + +/obj/item/electropack/shockcollar/slave/Initialize() + . = ..() + collarID = ++lastID + GLOB.tracked_slaves += src + priority_announce("New pack", sender_override = "Beep Beep upgate") + +/obj/item/electropack/shockcollar/slave/Destroy() + . = ..() + GLOB.tracked_slaves -= src + priority_announce("pack deleted", sender_override = "Beep Beep upgate") diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index a8a7e51611..fd48d5015e 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -113,6 +113,14 @@ else message_admins("[key_name_admin(usr)] tried to create a nuke team. Unfortunately, there were not enough candidates available.") log_admin("[key_name(usr)] failed to create a nuke team.") + if("slaver") + message_admins("[key_name(usr)] is creating a slaver trader crew...") + if(src.makeSlaverTeam()) + message_admins("[key_name(usr)] created a slave trader crew.") + log_admin("[key_name(usr)] created a slave trader crew.") + else + message_admins("[key_name_admin(usr)] tried to create a slave trader crew. Unfortunately, there were not enough candidates available.") + log_admin("[key_name(usr)] failed to create a slave trader crew.") if("ninja") message_admins("[key_name(usr)] spawned a ninja.") log_admin("[key_name(usr)] spawned a ninja.") diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 6c43d61cce..26c56fbeeb 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -19,6 +19,7 @@ Make Blob
Make Wizard (Requires Ghosts)
Make Nuke Team (Requires Ghosts)
+ Make Slave Trader Crew (Requires Ghosts)
Make CentCom Response Team (Requires Ghosts)
Make Abductor Team (Requires Ghosts)
Make Revenant (Requires Ghost)
@@ -254,6 +255,50 @@ return 0 +//Abductors +///datum/admins/proc/makeAbductorTeam() +// new /datum/round_event/ghost_role/abductor +// return 1 + +/datum/admins/proc/makeSlaverTeam() + var/list/mob/candidates = pollGhostCandidates("Do you wish to be considered for the slave trader crew entering the sector?", ROLE_SLAVER) + var/list/mob/chosen = list() + var/mob/theghost = null + + if(candidates.len) + var/numslavers = 5 + var/slavercount = 0 + + for(var/i = 0, iYou are a slave trader!") + owner.announce_objectives() + +/datum/antagonist/slaver/on_gain() + forge_objectives() + . = ..() + equip_slaver() + if(send_to_spawnpoint) + move_to_spawnpoint() + +/datum/antagonist/slaver/get_team() + return slaver_team + +/datum/antagonist/slaver/proc/forge_objectives() + objectives |= slaver_team.objectives + +/datum/antagonist/slaver/proc/move_to_spawnpoint() + owner.current.forceMove(GLOB.slaver_start[(0 % GLOB.slaver_start.len) + 1]) + +/datum/antagonist/slaver/leader/move_to_spawnpoint() + owner.current.forceMove(pick(GLOB.slaver_leader_start)) + +/datum/antagonist/slaver/admin_add(datum/mind/new_owner,mob/admin) + new_owner.assigned_role = ROLE_SLAVER + new_owner.add_antag_datum(src) + message_admins("[key_name_admin(admin)] has slaver'd [new_owner.current].") + log_admin("[key_name(admin)] has slaver'd [new_owner.current].") + +/datum/antagonist/slaver/get_admin_commands() + . = ..() + .["Send to base"] = CALLBACK(src,.proc/admin_send_to_base) + +/datum/antagonist/slaver/proc/admin_send_to_base(mob/admin) + owner.current.forceMove(pick(GLOB.slaver_start)) + +/datum/antagonist/slaver/leader + name = "Slave Master" + slaver_outfit = /datum/outfit/slaver/leader + +/datum/antagonist/slaver/leader/greet() + owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/ops.ogg',100,0) + to_chat(owner, "You are the Slave Master for this collection job. You are responsible for organising your team and your ID is the only one who can open the launch bay doors.") + to_chat(owner, "If you feel you are not up to this task, give your ID to another slaver.") + owner.announce_objectives() + addtimer(CALLBACK(src, .proc/slavers_name_assign), 1) + + +/datum/antagonist/slaver/leader/proc/slavers_name_assign() + slaver_team.slaver_crew_name = ask_name() + // priority_announce("Message test 123 123 Message test 123 123 Message test 123 123 Message test 123 123 Message test 123 123.", sender_override = "Hail from the [slaver_team.slaver_crew_name]") + +/datum/antagonist/slaver/leader/proc/ask_name() + var/defaultname = slaver_team.slaver_crew_name + var/newname = stripped_input(owner.current, "You are the slave master. Please choose a name for your crew.", "Crew name", defaultname) + if (!newname) + newname = defaultname + else + newname = reject_bad_name(newname) + if(!newname) + newname = defaultname + + return capitalize(newname) + +/datum/team/slavers + var/slaver_crew_name = "Slave Traders" + var/core_objective = /datum/objective/slaver + +/datum/team/slavers/proc/update_objectives() + if(core_objective) + var/datum/objective/O = new core_objective + O.team = src + objectives += O + +/datum/team/pirate/roundend_report() + var/list/parts = list() + + parts += "Space Pirates were:" + + var/all_dead = TRUE + for(var/datum/mind/M in members) + if(considered_alive(M)) + all_dead = FALSE + parts += printplayerlist(members) + + parts += "Loot stolen: " + var/datum/objective/loot/L = locate() in objectives + parts += L.loot_listing() + parts += "Total loot value : [L.get_loot_value()]/[L.target_value] credits" + + if(L.check_completion() && !all_dead) + parts += "The pirate crew was successful!" + else + parts += "The pirate crew has failed." + + return "
[parts.Join("
")]
" + +/datum/team/slavers/roundend_report() + var/list/parts = list() + parts += "[slaver_crew_name] Crew:" + + var/text = "
The syndicate operatives were:" + var/purchases = "" + var/TC_uses = 0 + LAZYINITLIST(GLOB.uplink_purchase_logs_by_key) + for(var/I in members) + var/datum/mind/syndicate = I + var/datum/uplink_purchase_log/H = GLOB.uplink_purchase_logs_by_key[syndicate.key] + if(H) + TC_uses += H.total_spent + purchases += H.generate_render(show_key = FALSE) + text += printplayerlist(members) + text += "
" + text += "(Syndicates used [TC_uses] TC) [purchases]" + + parts += text + + return "
[parts.Join("
")]
" + +/datum/team/slavers/antag_listing_name() + if(slaver_crew_name) + return "[slaver_crew_name] Syndico" + else + return "Syndicaa" + +/datum/team/slavers/is_gamemode_hero() + return SSticker.mode.name == "slave hunters" + +/proc/is_slaver(mob/M) + return M && istype(M) && M.mind && M.mind.has_antag_datum(/datum/antagonist/slaver) + +// /datum/round_event_control/operative +// name = "Slave Traders" +// typepath = /datum/round_event/ghost_role/slavers +// weight = 0 //Admin only +// max_occurrences = 1 diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 5bfc6fe652..757d8847f1 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -327,6 +327,9 @@ It's fairly easy to fix if dealing with single letters but not so much with comp if("nuclear") if(M.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE)) return 2 + if("slaver") + if(M.mind.has_antag_datum(/datum/antagonist/slaver,TRUE)) + return 2 if("changeling") if(M.mind.has_antag_datum(/datum/antagonist/changeling,TRUE)) return 2 diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 1d2007fd63ca1f1dfad4568067d1b31f3dae954f..db5371f95d2219873457d541f06b79f148a79fbc 100644 GIT binary patch literal 18088 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 delta 16957 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 Lnoo)!S-k&W^2qTx diff --git a/tgstation.dme b/tgstation.dme index 0be30ab1ed..b0a25d6f09 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -946,6 +946,7 @@ #include "code\game\machinery\computer\pod.dm" #include "code\game\machinery\computer\robot.dm" #include "code\game\machinery\computer\security.dm" +#include "code\game\machinery\computer\slavery.dm" #include "code\game\machinery\computer\station_alert.dm" #include "code\game\machinery\computer\telecrystalconsoles.dm" #include "code\game\machinery\computer\teleporter.dm" @@ -1777,6 +1778,8 @@ #include "code\modules\antagonists\slaughter\slaughter.dm" #include "code\modules\antagonists\slaughter\slaughter_antag.dm" #include "code\modules\antagonists\slaughter\slaughterevent.dm" +#include "code\modules\antagonists\slaver\slaver.dm" +#include "code\modules\antagonists\slaver\equipment\slaver_outfits.dm" #include "code\modules\antagonists\space_dragon\space_dragon.dm" #include "code\modules\antagonists\space_ninja\space_ninja.dm" #include "code\modules\antagonists\survivalist\survivalist.dm" diff --git a/tgui/packages/tgui/interfaces/CommunicationsConsole.js b/tgui/packages/tgui/interfaces/CommunicationsConsole.js index a9b07a8f36..6350c43d55 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 } from "../components"; +import { Blink, Box, Button, Dimmer, Flex, Stack, Icon, Input, Modal, Section, TextArea, LabeledList } from "../components"; import { Window } from "../layouts"; import { sanitizeText } from "../sanitize"; @@ -317,6 +317,7 @@ export const PageMain = (props, context) => { shuttleCanEvacOrFailReason, shuttleLastCalled, shuttleRecallable, + availableSlaves, } = data; const [callingShuttle, setCallingShuttle] = useLocalState( @@ -472,6 +473,56 @@ export const PageMain = (props, context) => { + {availableSlaves && ( +
+ + + John Smith + + +
+ )} + {!!canMessageAssociates && messagingAssociates && map(parseFloat)(coords.split(', ')); + +export const SlaveConsole = (props, context) => { + const { act, data } = useBackend(context); + const { + currentCoords, + } = data; + const slaves = flow([ + map((slave, index) => { + // Calculate distance to the target. BYOND distance is capped to 127, + // that's why we roll our own calculations here. + const dist = slave.dist && ( + Math.round(vecLength(vecSubtract( + coordsToVec(currentCoords), + coordsToVec(slave.coords)))) + ); + return { ...slave, dist, index }; + }), + sortBy( + slave => slave.name), // Sort alphabetically + ])(data.slaves || []); + return ( + + +
+ + 12345 + +
+ +
+ + 12345 + +
+ +
+ 12345 +
+ +
+ +
+ +
+ + {slaves.map(slave => ( + + + + {slave.name} + + + + {slave.degrees !== undefined && ( + + )} + {slave.dist !== undefined && ( + slave.dist + 'm' + )} +
+ +
+ + {slaves.map(slave => ( + + + + {slave.name} + + + + {slave.degrees !== undefined && ( + + )} + {slave.dist !== undefined && ( + slave.dist + 'm' + )} + + + +
+
+ +
+ + {slaves.map(slave => ( + + + + {slave.name} + + + + {slave.degrees !== undefined && ( + + )} + {slave.dist !== undefined && ( + slave.dist + 'm' + )} + + + +
+
+
+
+ ); +};