diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm index a0deb25b20d..b01949e3fca 100644 --- a/_maps/map_files/cyberiad/cyberiad.dmm +++ b/_maps/map_files/cyberiad/cyberiad.dmm @@ -1299,7 +1299,7 @@ /turf/simulated/shuttle/plating/vox, /area/shuttle/vox) "ade" = ( -/obj/structure/closet/syndicate/suits, +/obj/machinery/suit_storage_unit/syndicate/secure, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, @@ -1757,12 +1757,12 @@ /turf/simulated/floor/plasteel, /area/security/range) "adS" = ( -/obj/structure/closet/syndicate/suits, /obj/machinery/light/spot{ tag = "icon-tube1 (WEST)"; icon_state = "tube1"; dir = 8 }, +/obj/machinery/suit_storage_unit/syndicate/secure, /turf/simulated/shuttle/floor{ icon_state = "floor4" }, diff --git a/_maps/map_files/cyberiad/z2.dmm b/_maps/map_files/cyberiad/z2.dmm index 62f6c7c5181..65cdf6e0f1e 100644 --- a/_maps/map_files/cyberiad/z2.dmm +++ b/_maps/map_files/cyberiad/z2.dmm @@ -12005,8 +12005,8 @@ /area/syndicate_mothership) "BE" = ( /obj/structure/rack, -/obj/item/storage/backpack/duffel/syndie/ammo/loaded, -/obj/item/storage/backpack/duffel/syndie/ammo/loaded, +/obj/item/storage/backpack/duffel/syndie/ammo/shotgun, +/obj/item/storage/backpack/duffel/syndie/ammo/shotgun, /obj/item/gun/projectile/automatic/shotgun/bulldog, /obj/item/gun/projectile/automatic/shotgun/bulldog, /turf/unsimulated/floor{ diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index c7c3bbf5256..27b69284a3d 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -442,7 +442,7 @@ /proc/SecondsToTicks(var/seconds) return seconds * 10 -proc/pollCandidates(Question, be_special_type, antag_age_check = 0, poll_time = 300, ignore_respawnability = 0, min_hours = 0, flashwindow = TRUE, check_antaghud = TRUE) +proc/pollCandidates(Question, be_special_type, antag_age_check = FALSE, poll_time = 300, ignore_respawnability = FALSE, min_hours = 0, flashwindow = TRUE, check_antaghud = TRUE) var/roletext = be_special_type ? get_roletext(be_special_type) : null var/list/mob/dead/observer/candidates = list() var/time_passed = world.time diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 556e74179da..0306c39c36c 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1025,6 +1025,7 @@ if(!ticker.mode.equip_syndicate(current)) to_chat(usr, "Equipping a syndicate failed!") return + ticker.mode.update_syndicate_id(current.mind, ticker.mode.syndicates.len == 1) log_admin("[key_name(usr)] has equipped [key_name(current)] as a nuclear operative") message_admins("[key_name_admin(usr)] has equipped [key_name_admin(current)] as a nuclear operative") diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 9278d0d5f80..297dc4ff323 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -12,10 +12,10 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) var/datum/uplink_item/I = new path if(!I.item) continue - if(I.gamemodes.len && ticker && !(ticker.mode.type in I.gamemodes)) - continue - if(I.excludefrom.len && ticker && (ticker.mode.type in I.excludefrom)) - continue + // if(I.gamemodes.len && ticker && !(ticker.mode.type in I.gamemodes)) + // continue + // if(I.excludefrom.len && ticker && (ticker.mode.type in I.excludefrom)) + // continue if(I.last) last += I continue @@ -441,7 +441,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) /datum/uplink_item/dangerous category = "Highly Visible and Dangerous Weapons" - /datum/uplink_item/dangerous/pistol name = "FK-69 Pistol" reference = "SPI" @@ -559,37 +558,66 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/batterer cost = 5 -/datum/uplink_item/dangerous/gygax +// SUPPORT AND MECHAS + +/datum/uplink_item/support + category = "Support and Mechanized Exosuits" + surplus = 0 + gamemodes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/support/gygax name = "Gygax Exosuit" desc = "A lightweight exosuit, painted in a dark scheme. Its speed and equipment selection make it excellent for hit-and-run style attacks. \ This model lacks a method of space propulsion, and therefore it is advised to repair the mothership's teleporter if you wish to make use of it." reference = "GE" item = /obj/mecha/combat/gygax/dark/loaded cost = 90 - gamemodes = list(/datum/game_mode/nuclear) - surplus = 0 -/datum/uplink_item/dangerous/mauler +/datum/uplink_item/support/mauler name = "Mauler Exosuit" desc = "A massive and incredibly deadly Syndicate exosuit. Features long-range targeting, thrust vectoring, and deployable smoke." reference = "ME" item = /obj/mecha/combat/marauder/mauler/loaded cost = 140 - gamemodes = list(/datum/game_mode/nuclear) - surplus = 0 -/datum/uplink_item/dangerous/syndieborg - name = "Syndicate Cyborg" - desc = "A cyborg designed and programmed for systematic extermination of non-Syndicate personnel. Comes in Assault, Medical, or Saboteur variants." - reference = "SC" - item = /obj/item/antag_spawner/borg_tele - refund_path = /obj/item/antag_spawner/borg_tele - cost = 50 - gamemodes = list(/datum/game_mode/nuclear) - surplus = 0 +/datum/uplink_item/support/reinforcement + name = "Reinforcement" + desc = "Call in an additional team member. They won't come with any gear, so you'll have to save some telecrystals \ + to arm them as well." + reference = "REINF" + item = /obj/item/antag_spawner/nuke_ops + refund_path = /obj/item/antag_spawner/nuke_ops + cost = 25 refundable = TRUE cant_discount = TRUE +/datum/uplink_item/support/reinforcement/assault_borg + name = "Syndicate Assault Cyborg" + desc = "A cyborg designed and programmed for systematic extermination of non-Syndicate personnel. \ + Comes equipped with a self-resupplying LMG, a grenade launcher, energy sword, emag, pinpointer, flash and crowbar." + reference = "SAC" + item = /obj/item/antag_spawner/nuke_ops/borg_tele/assault + refund_path = /obj/item/antag_spawner/nuke_ops/borg_tele/assault + cost = 65 + +/datum/uplink_item/support/reinforcement/medical_borg + name = "Syndicate Medical Cyborg" + desc = "A combat medical cyborg. Has limited offensive potential, but makes more than up for it with its support capabilities. \ + It comes equipped with a nanite hypospray, a medical beamgun, combat defibrillator, full surgical kit including an energy saw, an emag, pinpointer and flash. \ + Thanks to its organ storage bag, it can perform surgery as well as any humanoid." + reference = "SMC" + item = /obj/item/antag_spawner/nuke_ops/borg_tele/medical + refund_path = /obj/item/antag_spawner/nuke_ops/borg_tele/medical + cost = 35 + +/datum/uplink_item/support/reinforcement/saboteur_borg + name = "Syndicate Saboteur Cyborg" + desc = "A streamlined engineering cyborg, equipped with covert modules and engineering equipment. Also incapable of leaving the welder in the shuttle. \ + Its chameleon projector lets it disguise itself as a Nanotrasen cyborg, on top it has thermal vision and a pinpointer." + reference = "SSC" + item = /obj/item/antag_spawner/nuke_ops/borg_tele/saboteur + refund_path = /obj/item/antag_spawner/nuke_ops/borg_tele/saboteur + /datum/uplink_item/dangerous/foamsmg name = "Toy Submachine Gun" desc = "A fully-loaded Donksoft bullpup submachine gun that fires riot grade rounds with a 20-round magazine." @@ -653,15 +681,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/ammo_box/magazine/m10mm/hp cost = 3 -/datum/uplink_item/ammo/ammobag - name = "Bulldog - Shotgun Ammo Grab Bag" - desc = "A duffelbag filled with Bulldog ammo to kit out an entire team, at a discounted price." - reference = "SAGL" - item = /obj/item/storage/backpack/duffel/syndie/ammo/loaded - cost = 10 //bulk buyer's discount. Very useful if you're buying a mech and dont have TC left to buy people non-shotgun guns - gamemodes = list(/datum/game_mode/nuclear) - cant_discount = TRUE - /datum/uplink_item/ammo/bullslug name = "Bulldog - 12g Slug Magazine" desc = "An additional 8-round slug magazine for use in the Bulldog shotgun. Now 8 times less likely to shoot your pals." @@ -694,6 +713,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 2 gamemodes = list(/datum/game_mode/nuclear) +/datum/uplink_item/ammo/bulldog_ammobag + name = "Bulldog - 12g Ammo Duffel Bag" + desc = "A duffel bag filled with enough 12g ammo to supply an entire team, at a discounted price." + reference = "12ADB" + item = /obj/item/storage/backpack/duffel/syndie/ammo/shotgun + cost = 12 // normally 18 + gamemodes = list(/datum/game_mode/nuclear) + /datum/uplink_item/ammo/smg name = "C-20r - .45 Magazine" desc = "An additional 20-round .45 magazine for use in the C-20r submachine gun. These bullets pack a lot of punch that can knock most targets down, but do limited overall damage." @@ -702,6 +729,14 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 2 gamemodes = list(/datum/game_mode/nuclear) +/datum/uplink_item/ammo/smg_ammobag + name = "C-20r - .45 Ammo Duffel Bag" + desc = "A duffel bag filled with enough .45 ammo to supply an entire team, at a discounted price." + reference = "45ADB" + item = /obj/item/storage/backpack/duffel/syndie/ammo/smg + cost = 14 // normally 20 + gamemodes = list(/datum/game_mode/nuclear) + /datum/uplink_item/ammo/carbine name = "Carbine - 5.56 Toploader Magazine" desc = "An additional 30-round 5.56 magazine for use in the M-90gl carbine. These bullets don't have the punch to knock most targets down, but dish out higher overall damage." @@ -907,12 +942,13 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/grenade/plastic/c4 cost = 1 -/datum/uplink_item/explosives/plastic_explosives_pack - name = "Pack of 5 C-4 Explosives" - desc = "A package containing 5 C-4 Explosives at a discounted price. For when you need that little bit extra for your sabotaging needs." - reference = "C4P" - item = /obj/item/storage/box/syndie_kit/c4 - cost = 4 +/datum/uplink_item/explosives/c4bag + name = "Bag of C-4 explosives" + desc = "Because sometimes quantity is quality. Contains 10 C-4 plastic explosives." + item = /obj/item/storage/backpack/duffel/syndie/c4 + cost = 8 //20% discount! + cant_discount = TRUE + gamemodes = list(/datum/game_mode/nuclear) /datum/uplink_item/explosives/breaching_charge name = "Composition X-4" @@ -922,6 +958,16 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 2 gamemodes = list(/datum/game_mode/nuclear) +/datum/uplink_item/explosives/x4bag + name = "Bag of X-4 explosives" + desc = "Contains 3 X-4 shaped plastic explosives. Similar to C4, but with a stronger blast that is directional instead of circular. \ + X-4 can be placed on a solid surface, such as a wall or window, and it will blast through the wall, injuring anything on the opposite side, while being safer to the user. \ + For when you want a controlled explosion that leaves a wider, deeper, hole." + item = /obj/item/storage/backpack/duffel/syndie/x4 + cost = 4 + cant_discount = TRUE + gamemodes = list(/datum/game_mode/nuclear) + /datum/uplink_item/explosives/syndicate_bomb name = "Syndicate Bomb" desc = "The Syndicate Bomb has an adjustable timer with a minimum setting of 60 seconds. Ordering the bomb sends you a small beacon, which will teleport the explosive to your location when you activate it. \ @@ -1361,37 +1407,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/multitool/ai_detect cost = 1 -/datum/uplink_item/device_tools/telecrystal - name = "Raw Telecrystal" - desc = "Telecrystal in its rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - reference = "RTC" - item = /obj/item/stack/telecrystal - cost = 1 - surplus = 0 - cant_discount = TRUE - -/datum/uplink_item/device_tools/telecrystal/five - name = "5 Raw Telecrystals" - desc = "Five telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - reference = "RTCF" - item = /obj/item/stack/telecrystal/five - cost = 5 - -/datum/uplink_item/device_tools/telecrystal/twenty - name = "20 Raw Telecrystals" - desc = "Twenty telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - reference = "RTCT" - item = /obj/item/stack/telecrystal/twenty - cost = 20 - -/datum/uplink_item/device_tools/telecrystal/fifty - name = "50 Raw Telecrystals" - desc = "Fifty telecrystals in their rawest and purest form. You know you want that Mauler." - reference = "RTCB" - item = /obj/item/stack/telecrystal/fifty - cost = 50 - gamemodes = list(/datum/game_mode/nuclear) - /datum/uplink_item/device_tools/jammer name = "Radio Jammer" desc = "This device will disrupt any nearby outgoing radio communication when activated." @@ -1491,11 +1506,10 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) category = "Cybernetic Implants" surplus = 0 gamemodes = list(/datum/game_mode/nuclear) - var/cyber_bundle = FALSE /datum/uplink_item/cyber_implants/spawn_item(turf/loc, obj/item/uplink/U) if(item) - if(findtext(item, /obj/item/organ/internal/cyberimp) && !cyber_bundle) + if(findtext(item, /obj/item/organ/internal/cyberimp)) U.uses -= max(cost, 0) U.used_TC += cost feedback_add_details("traitor_uplink_items_bought", name) //this one and the line before copypasted because snowflaek code @@ -1532,16 +1546,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/organ/internal/cyberimp/chest/reviver cost = 8 -/datum/uplink_item/cyber_implants/bundle - name = "Cybernetic Implants Bundle" - desc = "A random selection of cybernetic implants. Guaranteed 5 high quality implants. \ - Comes with an automated implanting tool." - reference = "CIB" - item = /obj/item/storage/box/cyber_implants/bundle - cost = 40 - cyber_bundle = TRUE - cant_discount = TRUE - // POINTLESS BADASSERY /datum/uplink_item/badass @@ -1555,15 +1559,6 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) item = /obj/item/storage/fancy/cigarettes/cigpack_syndicate cost = 2 -/datum/uplink_item/badass/bundle - name = "Syndicate Bundle" - desc = "Syndicate Bundles are specialised groups of items that arrive in a plain box. These items are collectively worth more than 20 telecrystals, but you do not know which specialisation you will receive." - reference = "SYB" - item = /obj/item/storage/box/syndicate - cost = 20 - excludefrom = list(/datum/game_mode/nuclear) - cant_discount = TRUE - /datum/uplink_item/badass/syndiecards name = "Syndicate Playing Cards" desc = "A special deck of space-grade playing cards with a mono-molecular edge and metal reinforcement, making them lethal weapons both when wielded as a blade and when thrown. \ @@ -1606,50 +1601,80 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) cost = 20 gamemodes = list(/datum/game_mode/nuclear) -/*/datum/uplink_item/badass/random - name = "Random Item" - desc = "Picking this choice will send you a random item from the list. Useful for when you cannot think of a strategy to finish your objectives with." - reference = "RAIT" +/datum/uplink_item/bundles_TC + category = "Bundles and Telecrystals" + surplus = 0 + cant_discount = TRUE + +/datum/uplink_item/bundles_TC/bulldog + name = "Bulldog Bundle" + desc = "Lean and mean: Optimized for people that want to get up close and personal. Contains the popular \ + Bulldog shotgun, two 12g buckshot drums, and a pair of Thermal imaging goggles." + reference = "BULB" + item = /obj/item/storage/backpack/duffel/syndie/bulldogbundle + cost = 9 // normally 12 + gamemodes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/c20r + name = "C-20r Bundle" + desc = "Old Faithful: The classic C-20r, bundled with two magazines and a (surplus) suppressor at discount price." + reference = "C20B" + item = /obj/item/storage/backpack/duffel/syndie/c20rbundle + cost = 14 // normally 17 + gamemodes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/cyber_implants + name = "Cybernetic Implants Bundle" + desc = "A random selection of cybernetic implants. Guaranteed 5 high quality implants. \ + Comes with an automated implanting tool." + reference = "CIB" + item = /obj/item/storage/box/cyber_implants/bundle + cost = 40 + +/datum/uplink_item/bundles_TC/medical + name = "Medical Bundle" + desc = "The support specialist: Aid your fellow operatives with this medical bundle. Contains a tactical medkit, \ + a Donksoft LMG and a box of riot darts." + reference = "MEDB" + item = /obj/item/storage/backpack/duffel/syndie/med/medicalbundle + cost = 15 // normally 20 + gamemodes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/sniper + name = "Sniper bundle" + desc = "Elegant and refined: Contains a collapsed sniper rifle in an expensive carrying case, \ + two soporific knockout magazines, a free surplus suppressor, and a sharp-looking tactical turtleneck suit. \ + We'll throw in a free red tie if you order NOW." + reference = "SNPB" + item = /obj/item/storage/briefcase/sniperbundle + cost = 18 // normally 23 + gamemodes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/badass + name = "Syndicate Bundle" + desc = "Syndicate Bundles are specialised groups of items that arrive in a plain box. These items are collectively worth more than 20 telecrystals, but you do not know which specialisation you will receive." + reference = "SYB" item = /obj/item/storage/box/syndicate - cost = 0 + cost = 20 + excludefrom = list(/datum/game_mode/nuclear) -/datum/uplink_item/badass/random/spawn_item(var/turf/loc, var/obj/item/uplink/U) - - var/list/buyable_items = get_uplink_items() - var/list/possible_items = list() - - for(var/category in buyable_items) - for(var/datum/uplink_item/I in buyable_items[category]) - if(I == src) - continue - if(I.cost > U.uses) - continue - possible_items += I - - if(possible_items.len) - var/datum/uplink_item/I = pick(possible_items) - U.uses -= max(0, I.cost) - feedback_add_details("traitor_uplink_items_bought","RN") - return new I.item(loc) */ - -/datum/uplink_item/badass/surplus_crate +/datum/uplink_item/bundles_TC/surplus_crate name = "Syndicate Surplus Crate" desc = "A crate containing 50 telecrystals worth of random syndicate leftovers." reference = "SYSC" cost = 20 item = /obj/item/storage/box/syndicate excludefrom = list(/datum/game_mode/nuclear) - cant_discount = TRUE // You fucking wish var/crate_value = 50 -/datum/uplink_item/badass/surplus_crate/super +/datum/uplink_item/bundles_TC/surplus_crate/super name = "Syndicate Super Surplus Crate" desc = "A crate containing 125 telecrystals worth of random syndicate leftovers." reference = "SYSS" cost = 40 crate_value = 125 -/datum/uplink_item/badass/surplus_crate/spawn_item(turf/loc, obj/item/uplink/U) +/datum/uplink_item/bundles_TC/surplus_crate/spawn_item(turf/loc, obj/item/uplink/U) var/obj/structure/closet/crate/C = new(loc) var/list/temp_uplink_list = get_uplink_items() var/list/buyable_items = list() @@ -1679,3 +1704,32 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) new item(C) U.purchase_log += "[bicon(item)]" log_game("[key_name(usr)] purchased a surplus crate with [jointext(itemlog, ", ")]") + +/datum/uplink_item/bundles_TC/telecrystal + name = "Raw Telecrystal" + desc = "Telecrystal in its rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." + reference = "RTC" + item = /obj/item/stack/telecrystal + cost = 1 + +/datum/uplink_item/bundles_TC/telecrystal/five + name = "5 Raw Telecrystals" + desc = "Five telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." + reference = "RTCF" + item = /obj/item/stack/telecrystal/five + cost = 5 + +/datum/uplink_item/bundles_TC/telecrystal/twenty + name = "20 Raw Telecrystals" + desc = "Twenty telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." + reference = "RTCT" + item = /obj/item/stack/telecrystal/twenty + cost = 20 + +/datum/uplink_item/bundles_TC/telecrystal/fifty + name = "50 Raw Telecrystals" + desc = "Fifty telecrystals in their rawest and purest form. You know you want that Mauler." + reference = "RTCB" + item = /obj/item/stack/telecrystal/fifty + cost = 50 + gamemodes = list(/datum/game_mode/nuclear) \ No newline at end of file diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index 2a7504a7ef8..6e89c78508a 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -1,4 +1,4 @@ -#define NUKESCALINGMODIFIER 1 +#define NUKESCALINGMODIFIER 1.2 /datum/game_mode var/list/datum/mind/syndicates = list() @@ -38,10 +38,7 @@ proc/issyndicate(mob/living/M as mob) if(possible_syndicates.len < 1) return 0 - var/enough_candidates = LAZYLEN(possible_syndicates) > agents_possible - if(enough_candidates && LAZYLEN(GLOB.clients) >= highpop_trigger) - agent_number = agents_possible_highpop - else if(enough_candidates) + if(LAZYLEN(possible_syndicates) > agents_possible) agent_number = agents_possible else agent_number = possible_syndicates.len @@ -128,12 +125,7 @@ proc/issyndicate(mob/living/M as mob) leader_selected = 1 else synd_mind.current.real_name = "[syndicate_name()] Operative #[agent_number]" - - var/list/foundIDs = synd_mind.current.search_contents_for(/obj/item/card/id) - if(foundIDs.len) - for(var/obj/item/card/id/ID in foundIDs) - ID.name = "[syndicate_name()] Operative ID card" - ID.registered_name = synd_mind.current.real_name + update_syndicate_id(synd_mind, FALSE) agent_number++ spawnpos++ @@ -206,15 +198,7 @@ proc/issyndicate(mob/living/M as mob) var/obj/item/nuclear_challenge/challenge = new /obj/item/nuclear_challenge synd_mind.current.equip_to_slot_or_del(challenge, slot_r_hand) - var/list/foundIDs = synd_mind.current.search_contents_for(/obj/item/card/id) - - if(foundIDs.len) - for(var/obj/item/card/id/ID in foundIDs) - ID.name = "[syndicate_name()] [leader_title] ID card" - ID.registered_name = synd_mind.current.real_name - ID.access += access_syndicate_leader - else - message_admins("Warning: Nuke Ops spawned without access to leave their spawn area!") + update_syndicate_id(synd_mind, leader_title, TRUE) if(nuke_code) synd_mind.store_memory("Syndicate Nuclear Bomb Code: [nuke_code]", 0, 0) @@ -236,8 +220,18 @@ proc/issyndicate(mob/living/M as mob) else nuke_code = "code will be provided later" - return +/datum/game_mode/proc/update_syndicate_id(var/datum/mind/synd_mind, is_leader = FALSE) + var/list/found_ids = synd_mind.current.search_contents_for(/obj/item/card/id) + + if(LAZYLEN(found_ids)) + for(var/obj/item/card/id/ID in found_ids) + ID.name = "[synd_mind.current.real_name] ID card" + ID.registered_name = synd_mind.current.real_name + if(is_leader) + ID.access += access_syndicate_leader + else + message_admins("Warning: Operative [key_name_admin(synd_mind.current)] spawned without an ID card!") /datum/game_mode/proc/forge_syndicate_objectives(var/datum/mind/syndicate) var/datum/objective/nuclear/syndobj = new diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index b09d80bd804..b55d298c9a4 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -11,11 +11,13 @@ var/obj/item/clothing/suit/space/suit = null var/obj/item/clothing/head/helmet/space/helmet = null var/obj/item/clothing/mask/mask = null + var/obj/item/clothing/shoes/magboots/magboots = null var/obj/item/storage = null var/helmet_type = null var/suit_type = null var/mask_type = null + var/magboots_type = null var/storage_type = null var/locked = FALSE @@ -63,7 +65,7 @@ suit_type = /obj/item/clothing/suit/space/hardsuit/engineering helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/engineering mask_type = /obj/item/clothing/mask/breath - storage_type = /obj/item/clothing/shoes/magboots + magboots_type = /obj/item/clothing/shoes/magboots req_access = list(access_engine_equip) /obj/machinery/suit_storage_unit/engine/secure @@ -74,7 +76,7 @@ suit_type = /obj/item/clothing/suit/space/hardsuit/elite helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/elite mask_type = /obj/item/clothing/mask/gas - storage_type = /obj/item/clothing/shoes/magboots/advance + magboots_type = /obj/item/clothing/shoes/magboots/advance req_access = list(access_ce) /obj/machinery/suit_storage_unit/ce/secure @@ -85,7 +87,7 @@ suit_type = /obj/item/clothing/suit/space/hardsuit/security helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/security mask_type = /obj/item/clothing/mask/gas/sechailer - storage_type = /obj/item/clothing/shoes/magboots + magboots_type = /obj/item/clothing/shoes/magboots req_access = list(access_security) /obj/machinery/suit_storage_unit/security/secure @@ -99,7 +101,7 @@ suit_type = /obj/item/clothing/suit/space/hardsuit/atmos helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/atmos mask_type = /obj/item/clothing/mask/gas - storage_type = /obj/item/clothing/shoes/magboots + magboots_type = /obj/item/clothing/shoes/magboots req_access = list(access_atmospherics) /obj/machinery/suit_storage_unit/atmos/secure @@ -128,7 +130,7 @@ /obj/machinery/suit_storage_unit/cmo/secure/sec_storage name = "medical suit storage unit" mask_type = /obj/item/clothing/mask/gas - storage_type = /obj/item/clothing/shoes/magboots + magboots_type = /obj/item/clothing/shoes/magboots /obj/machinery/suit_storage_unit/clown name = "clown suit storage unit" @@ -150,13 +152,13 @@ /obj/machinery/suit_storage_unit/syndicate name = "syndicate suit storage unit" - suit_type = /obj/item/clothing/suit/space/hardsuit/syndi - helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/syndi - mask_type = /obj/item/clothing/mask/gas/syndicate - storage_type = /obj/item/tank/jetpack/oxygen/harness + suit_type = /obj/item/clothing/suit/space/hardsuit/syndi + helmet_type = /obj/item/clothing/head/helmet/space/hardsuit/syndi + mask_type = /obj/item/clothing/mask/gas/syndicate + magboots_type = /obj/item/clothing/shoes/magboots/syndie + storage_type = /obj/item/tank/jetpack/oxygen/harness req_access = list(access_syndicate) safeties = FALSE //in a syndicate base, everything can be used as a murder weapon at a moment's notice. - uv_super = TRUE //so efficient /obj/machinery/suit_storage_unit/syndicate/secure secure = TRUE @@ -245,6 +247,8 @@ helmet = new helmet_type(src) if(mask_type) mask = new mask_type(src) + if(magboots_type) + magboots = new magboots_type(src) if(storage_type) storage = new storage_type(src) update_icon() @@ -257,6 +261,7 @@ QDEL_NULL(suit) QDEL_NULL(helmet) QDEL_NULL(mask) + QDEL_NULL(magboots) QDEL_NULL(storage) QDEL_NULL(wires) return ..() @@ -324,7 +329,10 @@ if(istype(I, /obj/item/clothing/mask) && !mask) mask = I . = TRUE - if((istype(I, /obj/item/tank) || istype(I, /obj/item/clothing/shoes/magboots)) && !storage) + if(istype(I, /obj/item/clothing/shoes/magboots) && !magboots) + magboots = I + . = TRUE + if((istype(I, /obj/item/tank)) && !storage) storage = I . = TRUE if(.) @@ -410,6 +418,8 @@ qdel(suit) // Delete everything but the occupant. mask = null qdel(mask) + magboots = null + qdel(magboots) storage = null qdel(storage) else @@ -544,7 +554,10 @@ dat+= text("Breathmask storage compartment: []
",(mask ? mask.name : "No breathmask detected.") ) if(mask && state_open) dat+="Dispense mask
" - dat+= text("Tank, Magboots storage compartment: []
",(storage ? storage.name : "
No storage item detected.") ) + dat+= text("Magboots storage compartment: []
",(magboots ? magboots.name : "
No magboots detected.") ) + if(magboots && state_open) + dat+="Dispense magboots
" + dat+= text("Tank storage compartment: []
",(storage ? storage.name : "
No storage item detected.") ) if(storage && state_open) dat+="Dispense storage item
" if(occupant) @@ -604,6 +617,10 @@ dispense_mask(usr) updateUsrDialog() update_icon() + if(href_list["dispense_magboots"]) + dispense_magboots(usr) + updateUsrDialog() + update_icon() if(href_list["dispense_storage"]) dispense_storage(usr) updateUsrDialog() @@ -671,6 +688,13 @@ else mask.forceMove(loc) mask = null + +/obj/machinery/suit_storage_unit/proc/dispense_magboots(mob/user as mob) + if(!magboots) + return + else + magboots.forceMove(loc) + magboots = null /obj/machinery/suit_storage_unit/proc/dispense_storage(mob/user as mob) if(!storage) diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 8df4b17251d..e5ee3562228 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -315,7 +315,7 @@ /obj/item/storage/backpack/duffel/syndie name = "suspicious looking duffelbag" desc = "A large duffelbag for holding extra tactical supplies." - icon_state = "duffel-syndi" + icon_state = "duffel-syndie" item_state = "duffel-syndimed" origin_tech = "syndicate=1" silent = 1 @@ -333,21 +333,64 @@ icon_state = "duffel-syndiammo" item_state = "duffel-syndiammo" -/obj/item/storage/backpack/duffel/syndie/ammo/loaded +/obj/item/storage/backpack/duffel/syndie/ammo/shotgun desc = "A large duffelbag, packed to the brim with Bulldog shotgun ammo." -/obj/item/storage/backpack/duffel/syndie/ammo/loaded/New() +/obj/item/storage/backpack/duffel/syndie/ammo/shotgun/New() ..() - new /obj/item/ammo_box/magazine/m12g(src) - new /obj/item/ammo_box/magazine/m12g(src) - new /obj/item/ammo_box/magazine/m12g(src) - new /obj/item/ammo_box/magazine/m12g(src) - new /obj/item/ammo_box/magazine/m12g(src) - new /obj/item/ammo_box/magazine/m12g(src) + for(var/i in 1 to 6) + new /obj/item/ammo_box/magazine/m12g(src) + new /obj/item/ammo_box/magazine/m12g/buckshot(src) new /obj/item/ammo_box/magazine/m12g/buckshot(src) - new /obj/item/ammo_box/magazine/m12g/stun(src) new /obj/item/ammo_box/magazine/m12g/dragon(src) +/obj/item/storage/backpack/duffel/syndie/ammo/smg + desc = "A large duffel bag, packed to the brim with C-20r magazines." + +/obj/item/storage/backpack/duffel/syndie/ammo/smg/New() + ..() + for(var/i in 1 to 10) + new /obj/item/ammo_box/magazine/smgm45(src) + +/obj/item/storage/backpack/duffel/syndie/c20rbundle + desc = "A large duffel bag containing a C-20r, some magazines, and a cheap looking suppressor." + +/obj/item/storage/backpack/duffel/syndie/c20rbundle/New() + ..() + new /obj/item/ammo_box/magazine/smgm45(src) + new /obj/item/ammo_box/magazine/smgm45(src) + new /obj/item/gun/projectile/automatic/c20r(src) + new /obj/item/suppressor/specialoffer(src) + +/obj/item/storage/backpack/duffel/syndie/bulldogbundle + desc = "A large duffel bag containing a Bulldog, some drums, and a pair of thermal imaging glasses." + +/obj/item/storage/backpack/duffel/syndie/bulldogbundle/New() + ..() + new /obj/item/gun/projectile/automatic/shotgun/bulldog(src) + new /obj/item/ammo_box/magazine/m12g(src) + new /obj/item/ammo_box/magazine/m12g(src) + new /obj/item/clothing/glasses/thermal/syndi(src) + +/obj/item/storage/backpack/duffel/syndie/med/medicalbundle + desc = "A large duffel bag containing a tactical medkit, a Donksoft machine gun and a big jumbo box of riot darts." + +/obj/item/storage/backpack/duffel/syndie/med/medicalbundle/New() + ..() + new /obj/item/storage/firstaid/tactical(src) + new /obj/item/gun/projectile/automatic/l6_saw/toy(src) + new /obj/item/ammo_box/foambox/riot(src) + +/obj/item/storage/backpack/duffel/syndie/c4/New() + ..() + for(var/i in 1 to 10) + new /obj/item/grenade/plastic/c4(src) + +/obj/item/storage/backpack/duffel/syndie/x4/New() + ..() + for(var/i in 1 to 3) + new /obj/item/grenade/plastic/x4(src) + /obj/item/storage/backpack/duffel/syndie/surgery name = "surgery duffelbag" desc = "A suspicious looking duffelbag for holding surgery tools." diff --git a/code/game/objects/items/weapons/storage/briefcase.dm b/code/game/objects/items/weapons/storage/briefcase.dm index b2637a9688e..2450648cded 100644 --- a/code/game/objects/items/weapons/storage/briefcase.dm +++ b/code/game/objects/items/weapons/storage/briefcase.dm @@ -15,5 +15,15 @@ burn_state = FLAMMABLE burntime = 20 -/obj/item/storage/briefcase/New() - ..() +/obj/item/storage/briefcase/sniperbundle + desc = "Its label reads \"genuine hardened Captain leather\", but suspiciously has no other tags or branding. Smells like L'Air du Temps." + force = 10 + +/obj/item/storage/briefcase/sniperbundle/New() + ..() + new /obj/item/gun/projectile/automatic/sniper_rifle/syndicate(src) + new /obj/item/clothing/accessory/red(src) + new /obj/item/clothing/under/syndicate/sniper(src) + new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) + new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) + new /obj/item/suppressor/specialoffer(src) \ No newline at end of file diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm index 2b78de43f82..a72f8f10433 100644 --- a/code/modules/antagonists/_common/antag_spawner.dm +++ b/code/modules/antagonists/_common/antag_spawner.dm @@ -10,72 +10,91 @@ /obj/item/antag_spawner/proc/equip_antag(mob/target) return -/obj/item/antag_spawner/borg_tele - name = "syndicate cyborg teleporter" - desc = "A single-use teleporter used to deploy a Syndicate Cyborg on the field." +///////////BORGS AND OPERATIVES +/obj/item/antag_spawner/nuke_ops + name = "syndicate operative teleporter" + desc = "A single-use teleporter designed to quickly reinforce operatives in the field." icon = 'icons/obj/device.dmi' icon_state = "locator" - var/checking = FALSE - var/TC_cost = 0 var/borg_to_spawn - var/upload_mind - var/list/possible_types = list("Assault", "Medical", "Saboteur") + var/checking = FALSE -/obj/item/antag_spawner/borg_tele/attack_self(mob/user) +/obj/item/antag_spawner/nuke_ops/proc/check_usability(mob/user) if(used) to_chat(user, "[src] is out of power!") - return + return FALSE if(!(user.mind in ticker.mode.syndicates)) to_chat(user, "AUTHENTICATION FAILURE. ACCESS DENIED.") return FALSE if(checking) - to_chat(user, "[src] is already checking for possible borgs.") - return - borg_to_spawn = input("What type of borg would you like to teleport?", "Cyborg Type", type) as null|anything in possible_types - if(!borg_to_spawn || checking || used) - return - upload_mind = input("Would you like to continue playing as an operative or take over the cyborg? (Another player will control your old self)", "Play as") as null|anything in list("Nuclear Operative", "Syndicate Cyborg") - if(!upload_mind || checking || used) - return - if(upload_mind == "Nuclear Operative") - checking = TRUE - to_chat(user, "The device is now checking for possible borgs.") - var/list/borg_candidates = pollCandidates("Do you want to play as a Syndicate [borg_to_spawn] borg?", ROLE_OPERATIVE, 1) - if(borg_candidates.len > 0 && !used) - checking = FALSE - used = TRUE - var/mob/M = pick(borg_candidates) - var/client/C = M.client - spawn_antag(C, get_turf(loc), "syndieborg") - qdel(src) - else - checking = FALSE - to_chat(user, "Unable to connect to Syndicate command. Please wait and try again later or refund your teleporter through your uplink.") - return - else if(upload_mind == "Syndicate Cyborg") - checking = TRUE - to_chat(user, "You attempt to upload your consciousness into a new syndicate cyborg.") - var/list/nuclear_candidates = pollCandidates("Do you want to play as the Syndicate Nuclear Operative [user.real_name]?", ROLE_OPERATIVE, 1) - if(nuclear_candidates.len > 0 && !used) - checking = FALSE - used = TRUE - var/mob/M = pick(nuclear_candidates) - var/client/nukeop_client = M.client - var/client/borg_client = user.client - spawn_antag(borg_client, get_turf(loc), "syndieborg") - user.key = nukeop_client.key - ticker.mode.greet_syndicate(user.mind) - qdel(src) - else - checking = FALSE - to_chat(user, "Unable to connect to Syndicate command. Please wait and try again later or refund your teleporter through your uplink.") - return + to_chat(user, "The device is already connecting to Syndicate command. Please wait.") + return FALSE + return TRUE -/obj/item/antag_spawner/borg_tele/spawn_antag(client/C, turf/T, type = "") - if(!borg_to_spawn) //If there's no type at all, let it still be used but don't do anything +/obj/item/antag_spawner/nuke_ops/attack_self(mob/user) + if(!(check_usability(user))) + return + + checking = TRUE + to_chat(user, "You activate [src] and wait for confirmation.") + var/list/nuke_candidates = pollCandidates("Do you want to play as a syndicate [borg_to_spawn ? "[lowertext(borg_to_spawn)] cyborg" : "operative"]?", ROLE_OPERATIVE, TRUE, 150) + if(LAZYLEN(nuke_candidates)) + checking = FALSE + if(QDELETED(src) || !check_usability(user)) + return + used = TRUE + var/mob/dead/observer/G = pick(nuke_candidates) + spawn_antag(G.client, get_turf(src), user.mind) + do_sparks(4, TRUE, src) + qdel(src) + else + checking = FALSE + to_chat(user, "Unable to connect to Syndicate command. Please wait and try again later or use the teleporter on your uplink to get your points refunded.") + +/obj/item/antag_spawner/nuke_ops/spawn_antag(client/C, turf/T, kind, datum/mind/user) + var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) + C.prefs.copy_to(M) + + var/agent_number = LAZYLEN(ticker.mode.syndicates) + M.real_name = "[syndicate_name()] Operative #[agent_number]" + + set_syndicate_values(C, M) + +/obj/item/antag_spawner/nuke_ops/proc/set_syndicate_values(client/C, mob/living/M) + M.key = C.key + + ticker.mode.syndicates += M.mind + ticker.mode.update_synd_icons_added(M.mind) + + M.mind.assigned_role = SPECIAL_ROLE_NUKEOPS + M.mind.special_role = SPECIAL_ROLE_NUKEOPS + M.mind.offstation_role = TRUE + + M.faction = list("syndicate") + ticker.mode.greet_syndicate(M.mind) + +//////SYNDICATE BORG +/obj/item/antag_spawner/nuke_ops/borg_tele + name = "syndicate cyborg teleporter" + desc = "A single-use teleporter designed to quickly reinforce operatives in the field." + +/obj/item/antag_spawner/nuke_ops/borg_tele/assault + name = "syndicate assault cyborg teleporter" + borg_to_spawn = "Assault" + +/obj/item/antag_spawner/nuke_ops/borg_tele/medical + name = "syndicate medical teleporter" + borg_to_spawn = "Medical" + +/obj/item/antag_spawner/nuke_ops/borg_tele/saboteur + name = "syndicate saboteur teleporter" + borg_to_spawn = "Saboteur" + +/obj/item/antag_spawner/nuke_ops/borg_tele/spawn_antag(client/C, turf/T, datum/mind/user) + if(!(user in ticker.mode.syndicates)) used = FALSE return - do_sparks(4, 1, src) + var/mob/living/silicon/robot/R switch(borg_to_spawn) if("Medical") @@ -84,11 +103,22 @@ R = new /mob/living/silicon/robot/syndicate/saboteur(T) else R = new /mob/living/silicon/robot/syndicate(T) //Assault borg by default - R.key = C.key - ticker.mode.syndicates += R.mind - ticker.mode.update_synd_icons_added(R.mind) - R.mind.special_role = SPECIAL_ROLE_NUKEOPS - R.faction = list("syndicate") + + var/brainfirstname = pick(GLOB.first_names_male) + if(prob(50)) + brainfirstname = pick(GLOB.first_names_female) + var/brainopslastname = pick(GLOB.last_names) + if(syndicate_name()) //the brain inside the syndiborg has the same last name as the other ops. + brainopslastname = syndicate_name() + var/brainopsname = "[brainfirstname] [brainopslastname]" + + R.mmi.name = "[initial(R.mmi.name)]: [brainopsname]" + R.mmi.brainmob.real_name = brainopsname + R.mmi.brainmob.name = brainopsname + + set_syndicate_values(C, R) + +///////////SLAUGHTER DEMON /obj/item/antag_spawner/slaughter_demon //Warning edgiest item in the game name = "vial of blood" @@ -159,6 +189,8 @@ objective_verb = "Hug and Tickle" demon_type = /mob/living/simple_animal/slaughter/laughter +///////////MORPH + /obj/item/antag_spawner/morph name = "vial of ooze" desc = "A magically infused bottle of ooze, distilled by methods rather not be spoken of. Used to awaken an all-consuming monstrosity." diff --git a/code/modules/clothing/under/syndicate.dm b/code/modules/clothing/under/syndicate.dm index 198a3e46de9..a6da9d4391e 100644 --- a/code/modules/clothing/under/syndicate.dm +++ b/code/modules/clothing/under/syndicate.dm @@ -16,4 +16,11 @@ icon_state = "tactifool" item_state = "bl_suit" item_color = "tactifool" - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) \ No newline at end of file + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) + +/obj/item/clothing/under/syndicate/sniper + name = "Tactical turtleneck suit" + desc = "A double seamed tactical turtleneck disguised as a civilian grade silk suit. Intended for the most formal operator. The collar is really sharp." + icon_state = "really_black_suit" + item_state = "bl_suit" + item_color = "black_suit" \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index a84af2c8254..44f21fcaace 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -441,6 +441,9 @@ /obj/item/robot_module/syndicate_saboteur name = "engineering robot module" //to disguise in examine module_type = "Malf" + module_actions = list( + /datum/action/innate/robot_sight/thermal, + ) stacktypes = list( /obj/item/stack/sheet/metal/cyborg = 50,