diff --git a/code/datums/ghost_query.dm b/code/datums/ghost_query.dm index 25fcbd6c7bd..c06013105a2 100644 --- a/code/datums/ghost_query.dm +++ b/code/datums/ghost_query.dm @@ -92,6 +92,13 @@ question = "An Alien has just been created on the facility. Would you like to play as them?" be_special_flag = BE_ALIEN +/datum/ghost_query/syndicate_drone + role_name = "Mercenary Drone" + question = "A team of dubious mercenaries have purchased a powerful drone, and they are attempting to activate it. Would you like to play as the drone?" + be_special_flag = BE_AI + check_bans = list("AI", "Cyborg", "Syndicate") + cutoff_number = 1 + // Surface stuff. /datum/ghost_query/lost_drone role_name = "Lost Drone" diff --git a/code/datums/uplink/backup.dm b/code/datums/uplink/backup.dm new file mode 100644 index 00000000000..40f2a468f67 --- /dev/null +++ b/code/datums/uplink/backup.dm @@ -0,0 +1,35 @@ +/********* +* Back up * +**********/ +/datum/uplink_item/item/backup + category = /datum/uplink_category/backup + blacklisted = 1 + +/datum/uplink_item/item/backup/syndicate_drone_protector + name = "Drone (Protector)" + desc = "A miniature teleport which will bring a powerful and loyal drone to you. \ + This type comes with a directional shield projector, a supressive fire energy weapon, \ + a stunbaton, handcuffs, an agent ID, energy sword, pinpointer, and a jetpack." + item_cost = DEFAULT_TELECRYSTAL_AMOUNT * 1.5 + antag_roles = list("mercenary") + path = /obj/item/weapon/antag_spawner/syndicate_drone/protector + +/datum/uplink_item/item/backup/syndicate_drone_combat_medic + name = "Drone (Combat Medic)" + desc = "A miniature teleport which will bring a powerful and loyal drone to you. \ + This type comes with standard medical equipment, full set of surgery tools, \ + a powerful hypospray that can create many potent chemicals, an agent ID, energy \ + sword, pinpointer, and a jetpack." + item_cost = DEFAULT_TELECRYSTAL_AMOUNT * 1.5 + antag_roles = list("mercenary") + path = /obj/item/weapon/antag_spawner/syndicate_drone/combat_medic + +/datum/uplink_item/item/backup/syndicate_drone_mechanist + name = "Drone (Mechanist)" + desc = "A miniature teleport which will bring a powerful and loyal drone to you. \ + This type comes with a full set of tools, an RCD, the ability to unlock other bound synthetics, \ + a cryptographic sequencer, an AI detector, the ability to analyze and repair full-body prosthetics, \ + a set of construction materials, an ionic rapier, an agent ID, energy sword, pinpointer, and a jetpack." + item_cost = DEFAULT_TELECRYSTAL_AMOUNT * 1.5 + antag_roles = list("mercenary") + path = /obj/item/weapon/antag_spawner/syndicate_drone/mechanist \ No newline at end of file diff --git a/code/datums/uplink/uplink_categories.dm b/code/datums/uplink/uplink_categories.dm index 7c65747f0b6..27760855947 100644 --- a/code/datums/uplink/uplink_categories.dm +++ b/code/datums/uplink/uplink_categories.dm @@ -49,4 +49,7 @@ datum/uplink_category/ammunition name = "Highly Visible and Dangerous Weapons" /datum/uplink_category/telecrystals - name = "Telecrystals" \ No newline at end of file + name = "Telecrystals" + +/datum/uplink_category/backup + name = "Backup" \ No newline at end of file diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm index 5d67b6eece4..f47e04bbb06 100644 --- a/code/game/gamemodes/nuclear/pinpointer.dm +++ b/code/game/gamemodes/nuclear/pinpointer.dm @@ -263,3 +263,57 @@ icon_state = "pinonfar" spawn(5) .() + + +// This one only points to the ship. Useful if there is no nuking to occur today. +/obj/item/weapon/pinpointer/shuttle + var/shuttle_comp_id = null + var/obj/machinery/computer/shuttle_control/our_shuttle = null + +/obj/item/weapon/pinpointer/shuttle/attack_self(mob/user as mob) + if(!active) + active = TRUE + find_shuttle() + to_chat(user, "Shuttle Locator active.") + else + active = FALSE + icon_state = "pinoff" + to_chat(user, "You deactivate the pinpointer.") + +/obj/item/weapon/pinpointer/shuttle/proc/find_shuttle() + if(!active) + return + + if(!our_shuttle) + for(var/obj/machinery/computer/shuttle_control/S in machines) + if(S.shuttle_tag == shuttle_comp_id) // Shuttle tags are used so that it will work if the computer path changes, as it does on the southern cross map. + our_shuttle = S + break + + if(!our_shuttle) + icon_state = "pinonnull" + return + + if(loc.z != our_shuttle.z) //If you are on a different z-level from the shuttle + icon_state = "pinonnull" + else + set_dir(get_dir(src, our_shuttle)) + switch(get_dist(src, our_shuttle)) + if(0) + icon_state = "pinondirect" + if(1 to 8) + icon_state = "pinonclose" + if(9 to 16) + icon_state = "pinonmedium" + if(16 to INFINITY) + icon_state = "pinonfar" + + spawn(5) + .() + + +/obj/item/weapon/pinpointer/shuttle/merc + shuttle_comp_id = "Mercenary" + +/obj/item/weapon/pinpointer/shuttle/heist + shuttle_comp_id = "Skipjack" \ No newline at end of file diff --git a/code/game/gamemodes/technomancer/assistance/assistance.dm b/code/game/gamemodes/technomancer/assistance/assistance.dm index db9e98a2661..0e550a08b20 100644 --- a/code/game/gamemodes/technomancer/assistance/assistance.dm +++ b/code/game/gamemodes/technomancer/assistance/assistance.dm @@ -10,90 +10,6 @@ cost = 300 obj_path = /obj/item/weapon/antag_spawner/technomancer_apprentice -/obj/item/weapon/antag_spawner - w_class = ITEMSIZE_TINY - var/used = 0 - var/ghost_query_type = null - -/obj/item/weapon/antag_spawner/proc/spawn_antag(client/C, turf/T) - return - -/obj/item/weapon/antag_spawner/proc/equip_antag(mob/target) - return - -/obj/item/weapon/antag_spawner/proc/request_player() - if(!ghost_query_type) - return - - var/datum/ghost_query/Q = new ghost_query_type() - var/list/winner = Q.query() - if(winner.len) - var/mob/observer/dead/D = winner[1] - spawn_antag(D.client, get_turf(src)) - else - reset_search() - return - -/obj/item/weapon/antag_spawner/proc/reset_search() - return - -/obj/item/weapon/antag_spawner/technomancer_apprentice - name = "apprentice teleporter" - desc = "A teleportation device, which will bring a less potent manipulator of space to you." - icon = 'icons/obj/objects.dmi' - icon_state = "oldshieldoff" - ghost_query_type = /datum/ghost_query/apprentice - var/searching = 0 - var/datum/effect/effect/system/spark_spread/sparks - -/obj/item/weapon/antag_spawner/technomancer_apprentice/New() - ..() - sparks = new /datum/effect/effect/system/spark_spread() - sparks.set_up(5, 0, src) - sparks.attach(loc) - -/obj/item/weapon/antag_spawner/technomancer_apprentice/Destroy() - qdel(sparks) - return ..() - -/obj/item/weapon/antag_spawner/technomancer_apprentice/attack_self(mob/user) - user << "Teleporter attempting to lock on to your apprentice." - request_player() - -/obj/item/weapon/antag_spawner/technomancer_apprentice/request_player() - searching = 1 - icon_state = "oldshieldon" - ..() - -/obj/item/weapon/antag_spawner/technomancer_apprentice/reset_search() - searching = 0 - if(!used) - icon_state = "oldshieldoff" - visible_message("The teleporter failed to find the apprentice. Perhaps another attempt could be made later?") - -/obj/item/weapon/antag_spawner/technomancer_apprentice/spawn_antag(client/C, turf/T) - sparks.start() - var/mob/living/carbon/human/H = new/mob/living/carbon/human(T) - C.prefs.copy_to(H) - H.key = C.key - - H << "You are the Technomancer's apprentice! Your goal is to assist them in their mission at the [station_name()]." - H << "Your service has not gone unrewarded, however. Studying under them, you have learned how to use a Manipulation Core \ - of your own. You also have a catalog, to purchase your own functions and equipment as you see fit." - H << "It would be wise to speak to your master, and learn what their plans are for today." - - spawn(1) - technomancers.add_antagonist(H.mind, 0, 1, 0, 0, 0) - equip_antag(H) - used = 1 - qdel(src) - - -/obj/item/weapon/antag_spawner/technomancer_apprentice/equip_antag(mob/technomancer_mob) - var/datum/antagonist/technomancer/antag_datum = all_antag_types[MODE_TECHNOMANCER] - antag_datum.equip_apprentice(technomancer_mob) - - /* // For when no one wants to play support. /datum/technomancer/assistance/golem diff --git a/code/game/objects/items/antag_spawners.dm b/code/game/objects/items/antag_spawners.dm new file mode 100644 index 00000000000..ce358bc1ee2 --- /dev/null +++ b/code/game/objects/items/antag_spawners.dm @@ -0,0 +1,135 @@ +/obj/item/weapon/antag_spawner + w_class = ITEMSIZE_TINY + var/used = 0 + var/ghost_query_type = null + var/searching = FALSE + var/datum/effect/effect/system/spark_spread/sparks + +/obj/item/weapon/antag_spawner/New() + ..() + sparks = new /datum/effect/effect/system/spark_spread() + sparks.set_up(5, 0, src) + sparks.attach(loc) + +/obj/item/weapon/antag_spawner/Destroy() + qdel(sparks) + return ..() + +/obj/item/weapon/antag_spawner/proc/spawn_antag(client/C, turf/T) + return + +/obj/item/weapon/antag_spawner/proc/equip_antag(mob/target) + return + +/obj/item/weapon/antag_spawner/proc/request_player() + if(!ghost_query_type) + return + if(searching) + return // Already searching. + searching = TRUE + + var/datum/ghost_query/Q = new ghost_query_type() + var/list/winner = Q.query() + if(winner.len) + var/mob/observer/dead/D = winner[1] + spawn_antag(D.client, get_turf(src)) + else + reset_search() + return + +/obj/item/weapon/antag_spawner/proc/reset_search() + searching = FALSE + return + +/obj/item/weapon/antag_spawner/technomancer_apprentice + name = "apprentice teleporter" + desc = "A teleportation device, which will bring a less potent manipulator of space to you." + icon = 'icons/obj/objects.dmi' + icon_state = "oldshieldoff" + ghost_query_type = /datum/ghost_query/apprentice + +/obj/item/weapon/antag_spawner/technomancer_apprentice/attack_self(mob/user) + user << "Teleporter attempting to lock on to your apprentice." + request_player() + +/obj/item/weapon/antag_spawner/technomancer_apprentice/request_player() + icon_state = "oldshieldon" + ..() + +/obj/item/weapon/antag_spawner/technomancer_apprentice/reset_search() + ..() + if(!used) + icon_state = "oldshieldoff" + visible_message("The teleporter failed to find the apprentice. Perhaps another attempt could be made later?") + +/obj/item/weapon/antag_spawner/technomancer_apprentice/spawn_antag(client/C, turf/T) + sparks.start() + var/mob/living/carbon/human/H = new/mob/living/carbon/human(T) + C.prefs.copy_to(H) + H.key = C.key + + H << "You are the Technomancer's apprentice! Your goal is to assist them in their mission at the [station_name()]." + H << "Your service has not gone unrewarded, however. Studying under them, you have learned how to use a Manipulation Core \ + of your own. You also have a catalog, to purchase your own functions and equipment as you see fit." + H << "It would be wise to speak to your master, and learn what their plans are for today." + + spawn(1) + technomancers.add_antagonist(H.mind, 0, 1, 0, 0, 0) + equip_antag(H) + used = 1 + qdel(src) + +/obj/item/weapon/antag_spawner/technomancer_apprentice/equip_antag(mob/technomancer_mob) + var/datum/antagonist/technomancer/antag_datum = all_antag_types[MODE_TECHNOMANCER] + antag_datum.equip_apprentice(technomancer_mob) + + + + +/obj/item/weapon/antag_spawner/syndicate_drone + name = "drone teleporter" + desc = "A teleportation device, which will bring a powerful and loyal drone to you." + icon = 'icons/obj/objects.dmi' + icon_state = "oldshieldoff" + ghost_query_type = /datum/ghost_query/syndicate_drone + var/drone_type = null + +/obj/item/weapon/antag_spawner/syndicate_drone/attack_self(mob/user) + to_chat(user, "Teleporter attempting to lock on to an available unit.") + request_player() + +/obj/item/weapon/antag_spawner/syndicate_drone/request_player() + icon_state = "oldshieldon" + ..() + +/obj/item/weapon/antag_spawner/syndicate_drone/reset_search() + ..() + if(!used) + icon_state = "oldshieldoff" + visible_message("The teleporter failed to find any available. Perhaps another attempt could be made later?") + +/obj/item/weapon/antag_spawner/syndicate_drone/spawn_antag(client/C, turf/T) + sparks.start() + var/mob/living/silicon/robot/R = new drone_type(T) + + // Put this text here before ckey change so that their laws are shown below it, since borg login() shows it. + to_chat(C, "You are a Mercenary Drone, activated to serve your team.") + to_chat(C, "Be sure to examine your currently loaded lawset closely. It would be wise \ + to speak with your team, and learn what their plan is for today.") + + R.key = C.key +// R.Namepick() // Apparnetly making someone a merc lets them pick a name, so this isn't needed. + + spawn(1) + mercs.add_antagonist(R.mind, FALSE, TRUE, FALSE, FALSE, FALSE) + //add_antagonist(var/datum/mind/player, var/ignore_role, var/do_not_equip, var/move_to_spawn, var/do_not_announce, var/preserve_appearance) + qdel(src) + +/obj/item/weapon/antag_spawner/syndicate_drone/protector + drone_type = /mob/living/silicon/robot/syndicate/protector + +/obj/item/weapon/antag_spawner/syndicate_drone/combat_medic + drone_type = /mob/living/silicon/robot/syndicate/combat_medic + +/obj/item/weapon/antag_spawner/syndicate_drone/mechanist + drone_type = /mob/living/silicon/robot/syndicate/mechanist \ No newline at end of file diff --git a/code/game/objects/items/devices/defib.dm b/code/game/objects/items/devices/defib.dm index b9b8af0c0df..e58f363bc15 100644 --- a/code/game/objects/items/devices/defib.dm +++ b/code/game/objects/items/devices/defib.dm @@ -542,6 +542,13 @@ var/mob/living/silicon/robot/R = src.loc return (R.cell && R.cell.checked_use(charge_amt)) +/obj/item/weapon/shockpaddles/robot/combat + name = "combat defibrillator paddles" + desc = "A pair of advanced shockpaddles powered by a robot's internal power cell, able to penetrate thick clothing. This version \ + appears to be optimized for combat situations, foregoing the safety inhabitors in favor of a faster charging time." + safety = 0 + chargetime = (1 SECONDS) + /* Shockpaddles that are linked to a base unit */ diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index d79f584e2f2..733afcfbcab 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -178,6 +178,9 @@ /obj/item/weapon/rcd/borg canRwall = 1 +/obj/item/weapon/rcd/borg/lesser + canRwall = FALSE + /obj/item/weapon/rcd/borg/useResource(var/amount, var/mob/user) if(isrobot(user)) var/mob/living/silicon/robot/R = user diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 3cd3d0c96e1..1ea7c154644 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1241,7 +1241,7 @@ W.message = message W.add_fingerprint(src) -/mob/living/carbon/human/can_inject(var/mob/user, var/error_msg, var/target_zone) +/mob/living/carbon/human/can_inject(var/mob/user, var/error_msg, var/target_zone, var/ignore_thickness = FALSE) . = 1 if(!target_zone) @@ -1261,10 +1261,10 @@ else switch(target_zone) if(BP_HEAD) - if(head && head.item_flags & THICKMATERIAL) + if(head && (head.item_flags & THICKMATERIAL) && !ignore_thickness) . = 0 else - if(wear_suit && wear_suit.item_flags & THICKMATERIAL) + if(wear_suit && (wear_suit.item_flags & THICKMATERIAL) && !ignore_thickness) . = 0 if(!. && error_msg && user) if(!fail_msg) diff --git a/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm b/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm index 2def8149ffd..f769cb29ab2 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules/syndicate.dm @@ -26,12 +26,13 @@ ) var/id +// All syndie modules get these, and the base borg items (flash, crowbar, etc). /obj/item/weapon/robot_module/robot/syndicate/New(var/mob/living/silicon/robot/R) ..() loc = R + src.modules += new /obj/item/weapon/pinpointer/shuttle/merc(src) src.modules += new /obj/item/weapon/melee/energy/sword(src) - src.modules += new /obj/item/weapon/gun/energy/pulse_rifle/destroyer(src) - src.modules += new /obj/item/weapon/card/emag(src) + var/jetpack = new/obj/item/weapon/tank/jetpack/carbondioxide(src) src.modules += jetpack R.internals = jetpack @@ -43,3 +44,141 @@ src.modules -= id id = null return ..() + +// Gets a big shield and a gun that shoots really fast to scare the opposing force. +/obj/item/weapon/robot_module/robot/syndicate/protector + name = "protector robot module" + sprites = list( + "Cerberus - Treaded" = "syndie_treadhound", + "Cerberus" = "syndie_bloodhound", + "Ares" = "squats", + "XI-ALP" = "syndi-heavy" + ) + +/obj/item/weapon/robot_module/robot/syndicate/protector/New(var/mob/living/silicon/robot/R) + ..() + src.modules += new /obj/item/shield_projector/rectangle/weak(src) + src.modules += new /obj/item/weapon/gun/energy/dakkalaser(src) + src.modules += new /obj/item/weapon/handcuffs/cyborg(src) + src.modules += new /obj/item/weapon/melee/baton/robot(src) + +// 95% engi-borg and 15% roboticist. +/obj/item/weapon/robot_module/robot/syndicate/mechanist + name = "mechanist robot module" + sprites = list( + "XI-GUS" = "spidersyndi", + "WTOperator" = "sleekhos" + ) + +/obj/item/weapon/robot_module/robot/syndicate/mechanist/New(var/mob/living/silicon/robot/R) + ..() + // General engineering/hacking. + src.modules += new /obj/item/borg/sight/meson(src) + src.modules += new /obj/item/weapon/weldingtool/electric/mounted/cyborg(src) + src.modules += new /obj/item/weapon/screwdriver/cyborg(src) + src.modules += new /obj/item/weapon/wrench/cyborg(src) + src.modules += new /obj/item/weapon/wirecutters/cyborg(src) + src.modules += new /obj/item/device/multitool/ai_detector(src) + src.modules += new /obj/item/weapon/pickaxe/plasmacutter(src) + src.modules += new /obj/item/weapon/rcd/borg/lesser(src) // Can't eat rwalls to prevent AI core cheese. + src.modules += new /obj/item/weapon/melee/energy/sword/ionic_rapier(src) + + // FBP repair. + src.modules += new /obj/item/device/robotanalyzer(src) + src.modules += new /obj/item/weapon/shockpaddles/robot/jumper(src) + src.modules += new /obj/item/weapon/gripper/no_use/organ/robotics(src) + + // Hacking other things. + src.modules += new /obj/item/weapon/card/robot(src) + src.modules += new /obj/item/weapon/card/emag(src) + + // Materials. + var/datum/matter_synth/nanite = new /datum/matter_synth/nanite(10000) + synths += nanite + var/datum/matter_synth/wire = new /datum/matter_synth/wire() + synths += wire + var/datum/matter_synth/metal = new /datum/matter_synth/metal(40000) + synths += metal + var/datum/matter_synth/glass = new /datum/matter_synth/glass(40000) + synths += glass + + var/obj/item/stack/nanopaste/N = new /obj/item/stack/nanopaste(src) + N.uses_charge = 1 + N.charge_costs = list(1000) + N.synths = list(nanite) + src.modules += N + + var/obj/item/stack/material/cyborg/steel/M = new (src) + M.synths = list(metal) + src.modules += M + + var/obj/item/stack/material/cyborg/glass/G = new (src) + G.synths = list(glass) + src.modules += G + + var/obj/item/stack/rods/cyborg/rods = new /obj/item/stack/rods/cyborg(src) + rods.synths = list(metal) + src.modules += rods + + var/obj/item/stack/cable_coil/cyborg/C = new /obj/item/stack/cable_coil/cyborg(src) + C.synths = list(wire) + src.modules += C + + var/obj/item/stack/material/cyborg/glass/reinforced/RG = new (src) + RG.synths = list(metal, glass) + src.modules += RG + + + + +// Mediborg optimized for on-the-field healing, but can also do surgery if needed. +/obj/item/weapon/robot_module/robot/syndicate/combat_medic + name = "combat medic robot module" + sprites = list( + "Telemachus" = "toiletbotantag" + ) + +/obj/item/weapon/robot_module/robot/syndicate/combat_medic/New(var/mob/living/silicon/robot/R) + ..() + src.modules += new /obj/item/borg/sight/hud/med(src) + src.modules += new /obj/item/device/healthanalyzer(src) + src.modules += new /obj/item/weapon/reagent_containers/borghypo/merc(src) + + // Surgery things. + src.modules += new /obj/item/weapon/surgical/scalpel/cyborg(src) + src.modules += new /obj/item/weapon/surgical/hemostat/cyborg(src) + src.modules += new /obj/item/weapon/surgical/retractor/cyborg(src) + src.modules += new /obj/item/weapon/surgical/cautery/cyborg(src) + src.modules += new /obj/item/weapon/surgical/bonegel/cyborg(src) + src.modules += new /obj/item/weapon/surgical/FixOVein/cyborg(src) + src.modules += new /obj/item/weapon/surgical/bonesetter/cyborg(src) + src.modules += new /obj/item/weapon/surgical/circular_saw/cyborg(src) + src.modules += new /obj/item/weapon/surgical/surgicaldrill/cyborg(src) + src.modules += new /obj/item/weapon/gripper/no_use/organ(src) + + // General healing. + src.modules += new /obj/item/weapon/gripper/medical(src) + src.modules += new /obj/item/weapon/shockpaddles/robot/combat(src) + src.modules += new /obj/item/weapon/reagent_containers/dropper(src) // Allows borg to fix necrosis apparently + src.modules += new /obj/item/weapon/reagent_containers/syringe(src) + src.modules += new /obj/item/roller_holder(src) + + // Materials. + var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(15000) + synths += medicine + + var/obj/item/stack/medical/advanced/ointment/O = new /obj/item/stack/medical/advanced/ointment(src) + var/obj/item/stack/medical/advanced/bruise_pack/B = new /obj/item/stack/medical/advanced/bruise_pack(src) + var/obj/item/stack/medical/splint/S = new /obj/item/stack/medical/splint(src) + O.uses_charge = 1 + O.charge_costs = list(1000) + O.synths = list(medicine) + B.uses_charge = 1 + B.charge_costs = list(1000) + B.synths = list(medicine) + S.uses_charge = 1 + S.charge_costs = list(1000) + S.synths = list(medicine) + src.modules += O + src.modules += B + src.modules += S diff --git a/code/modules/mob/living/silicon/robot/subtypes/gravekeeper.dm b/code/modules/mob/living/silicon/robot/subtypes/gravekeeper.dm index 9cc09b286a9..d722027ad3e 100644 --- a/code/modules/mob/living/silicon/robot/subtypes/gravekeeper.dm +++ b/code/modules/mob/living/silicon/robot/subtypes/gravekeeper.dm @@ -6,6 +6,7 @@ lawchannel = "State" braintype = "Drone" idcard_type = /obj/item/weapon/card/id + icon_selected = FALSE /mob/living/silicon/robot/gravekeeper/init() aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src) diff --git a/code/modules/mob/living/silicon/robot/subtypes/lost_drone.dm b/code/modules/mob/living/silicon/robot/subtypes/lost_drone.dm index ba6890e835f..281e158a92c 100644 --- a/code/modules/mob/living/silicon/robot/subtypes/lost_drone.dm +++ b/code/modules/mob/living/silicon/robot/subtypes/lost_drone.dm @@ -6,6 +6,7 @@ lawchannel = "State" braintype = "Drone" idcard_type = /obj/item/weapon/card/id + icon_selected = FALSE /mob/living/silicon/robot/lost/init() aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src) diff --git a/code/modules/mob/living/silicon/robot/subtypes/syndicate.dm b/code/modules/mob/living/silicon/robot/subtypes/syndicate.dm new file mode 100644 index 00000000000..76496f4d4c5 --- /dev/null +++ b/code/modules/mob/living/silicon/robot/subtypes/syndicate.dm @@ -0,0 +1,46 @@ +/mob/living/silicon/robot/syndicate + lawupdate = 0 + scrambledcodes = 1 + icon_state = "syndie_bloodhound" + modtype = "Syndicate" + lawchannel = "State" + braintype = "Drone" + idcard_type = /obj/item/weapon/card/id/syndicate + icon_selected = FALSE + +/mob/living/silicon/robot/syndicate/init() + aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src) + + mmi = new /obj/item/device/mmi/digital/robot(src) // Explicitly a drone. + overlays.Cut() + init_id() + + updatename("Syndicate") + + if(!cell) + cell = new /obj/item/weapon/cell/high(src) // 15k cell, because Antag. + + laws = new /datum/ai_laws/syndicate_override() + + radio.keyslot = new /obj/item/device/encryptionkey/syndicate(radio) + radio.recalculateChannels() + + playsound(loc, 'sound/mecha/nominalsyndi.ogg', 75, 0) + +/mob/living/silicon/robot/syndicate/protector/init() + ..() + module = new /obj/item/weapon/robot_module/robot/syndicate/protector(src) + updatename("Protector") + +/mob/living/silicon/robot/syndicate/mechanist/init() + ..() + module = new /obj/item/weapon/robot_module/robot/syndicate/mechanist(src) + updatename("Mechanist") + +/mob/living/silicon/robot/syndicate/combat_medic/init() + ..() + module = new /obj/item/weapon/robot_module/robot/syndicate/combat_medic(src) + updatename("Combat Medic") + +/mob/living/silicon/robot/syndicate/speech_bubble_appearance() + return "synthetic_evil" \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 46988c99340..d613f1f2062 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -177,4 +177,24 @@ obj/item/weapon/gun/energy/staff/focus charge_cost = 200 user << "The [src.name] will now strike only a single person." projectile_type = "/obj/item/projectile/forcebolt" - */ \ No newline at end of file + */ + +/obj/item/weapon/gun/energy/dakkalaser + name = "suppression gun" + desc = "A massive weapon, designed to pressure the opposition by raining down a torrent of energy pellets." + icon_state = "dakkalaser" + item_state = "dakkalaser" + fire_sound = 'sound/weapons/Laser.ogg' + w_class = ITEMSIZE_HUGE + charge_cost = 24 // 100 shots, it's a spray and pray (to RNGesus) weapon. + projectile_type = /obj/item/projectile/energy/blue_pellet + self_recharge = 1 + accuracy = 5 // Suppressive weapons don't work too well if there's no risk of being hit. + burst_delay = 1 // Burst faster than average. + origin_tech = list(TECH_COMBAT = 6, TECH_MAGNET = 6, TECH_ILLEGAL = 6) + + firemodes = list( + list(mode_name="single shot", burst = 1, burst_accuracy = list(5), dispersion = list(0), charge_cost = 24), + list(mode_name="five shot burst", burst = 5, burst_accuracy = list(5,5,5,5,5), dispersion = list(1,1,1,1,1)), + list(mode_name="ten shot burst", burst = 10, burst_accuracy = list(5,5,5,5,5,5,5,5,5,5), dispersion = list(2,2,2,2,2,2,2,2,2,2)), + ) \ No newline at end of file diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index 42be84f2ac0..dbc54fc4325 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -182,4 +182,17 @@ /obj/item/projectile/energy/plasmastun/on_hit(var/atom/target) bang(target) - . = ..() \ No newline at end of file + . = ..() + +/obj/item/projectile/energy/blue_pellet + name = "suppressive pellet" + icon_state = "blue_pellet" + damage = 5 + armor_penetration = 75 + pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE + damage_type = BURN + check_armour = "energy" + light_color = "#0000FF" + + embed_chance = 0 + muzzle_type = /obj/effect/projectile/pulse/muzzle \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm index 8cfb75e20cb..8d09b903b6b 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm @@ -691,4 +691,21 @@ else if(world.time > data + ANTIDEPRESSANT_MESSAGE_DELAY) data = world.time - to_chat(M, "You feel invigorated and calm.") \ No newline at end of file + to_chat(M, "You feel invigorated and calm.") + +// This exists to cut the number of chemicals a merc borg has to juggle on their hypo. +/datum/reagent/healing_nanites + name = "Restorative Nanites" + id = "healing_nanites" + description = "Miniature medical robots that swiftly restore bodily damage." + taste_description = "metal" + reagent_state = SOLID + color = "#555555" + metabolism = REM * 4 // Nanomachines gotta go fast. + scannable = 1 + +/datum/reagent/healing_nanites/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + M.heal_organ_damage(2 * removed, 2 * removed) + M.adjustOxyLoss(-4 * removed) + M.adjustToxLoss(-2 * removed) + M.adjustCloneLoss(-2 * removed) \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index 5c4a6bdce60..d0cd3cf9e60 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -12,6 +12,7 @@ var/charge_cost = 50 var/charge_tick = 0 var/recharge_time = 5 //Time it takes for shots to recharge (in seconds) + var/bypass_protection = FALSE // If true, can inject through things like spacesuits and armor. var/list/reagent_ids = list("tricordrazine", "inaprovaline", "anti_toxin", "tramadol", "dexalin" ,"spaceacillin") var/list/reagent_volumes = list() @@ -26,6 +27,13 @@ /obj/item/weapon/reagent_containers/borghypo/lost reagent_ids = list("tricordrazine", "bicaridine", "dexalin", "anti_toxin", "tramadol", "spaceacillin") +/obj/item/weapon/reagent_containers/borghypo/merc + name = "advanced cyborg hypospray" + desc = "An advanced nanite and chemical synthesizer and injection system, designed for heavy-duty medical equipment. This type is capable of safely bypassing \ + thick materials that other hyposprays would struggle with." + bypass_protection = TRUE // Because mercs tend to be in spacesuits. + reagent_ids = list("healing_nanites", "hyperzine", "tramadol", "oxycodone", "spaceacillin", "peridaxon", "osteodaxon", "myelamine") + /obj/item/weapon/reagent_containers/borghypo/New() ..() @@ -72,7 +80,7 @@ user << "You cannot inject a robotic limb." return - if (M.can_inject(user, 1)) + if(M.can_inject(user, 1, ignore_thickness = bypass_protection)) user << "You inject [M] with the injector." M << "You feel a tiny prick!" diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi index d32d479e3fb..35e6df449f8 100644 Binary files a/icons/mob/robots.dmi and b/icons/mob/robots.dmi differ diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi index 1550d6bf4b7..e037ce6f9b8 100644 Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index 8af7372321f..90d6dcd1ea9 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ diff --git a/polaris.dme b/polaris.dme index 737a2910cbb..1856f771ff8 100644 --- a/polaris.dme +++ b/polaris.dme @@ -279,6 +279,7 @@ #include "code\datums\uplink\ammunition.dm" #include "code\datums\uplink\announcements.dm" #include "code\datums\uplink\armor.dm" +#include "code\datums\uplink\backup.dm" #include "code\datums\uplink\badassery.dm" #include "code\datums\uplink\grenades.dm" #include "code\datums\uplink\hardsuit_modules.dm" @@ -795,6 +796,7 @@ #include "code\game\objects\effects\decals\posters\polarisposters.dm" #include "code\game\objects\effects\spawners\bombspawner.dm" #include "code\game\objects\effects\spawners\gibspawner.dm" +#include "code\game\objects\items\antag_spawners.dm" #include "code\game\objects\items\apc_frame.dm" #include "code\game\objects\items\blueprints.dm" #include "code\game\objects\items\bodybag.dm" @@ -1774,7 +1776,6 @@ #include "code\modules\mob\living\silicon\robot\robot_damage.dm" #include "code\modules\mob\living\silicon\robot\robot_items.dm" #include "code\modules\mob\living\silicon\robot\robot_movement.dm" -#include "code\modules\mob\living\silicon\robot\syndicate.dm" #include "code\modules\mob\living\silicon\robot\drone\drone.dm" #include "code\modules\mob\living\silicon\robot\drone\drone_abilities.dm" #include "code\modules\mob\living\silicon\robot\drone\drone_console.dm" @@ -1787,6 +1788,7 @@ #include "code\modules\mob\living\silicon\robot\robot_modules\syndicate.dm" #include "code\modules\mob\living\silicon\robot\subtypes\gravekeeper.dm" #include "code\modules\mob\living\silicon\robot\subtypes\lost_drone.dm" +#include "code\modules\mob\living\silicon\robot\subtypes\syndicate.dm" #include "code\modules\mob\living\simple_animal\corpse.dm" #include "code\modules\mob\living\simple_animal\simple_animal.dm" #include "code\modules\mob\living\simple_animal\aliens\alien.dm"