diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index 7692b31e3e4..12af8c24d65 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -2,236 +2,130 @@ /obj/machinery/computer/robotics - name = "Robotics Control" + name = "robotics control console" desc = "Used to remotely lockdown or detonate linked Cyborgs." icon = 'icons/obj/computer.dmi' icon_state = "robot" req_access = list(access_robotics) - circuit = "/obj/item/weapon/circuitboard/robotics" - - var/id = 0.0 + circuit = /obj/item/weapon/circuitboard/robotics var/temp = null - var/status = 0 - var/timeleft = 60 - var/stop = 0.0 - var/screen = 0 // 0 - Main Menu, 1 - Cyborg Status, 2 - Kill 'em All! -- In text l_color = "#CD00CD" - -/obj/machinery/computer/robotics/attack_ai(var/mob/user as mob) - return src.attack_hand(user) - -/obj/machinery/computer/robotics/attack_paw(var/mob/user as mob) - - return src.attack_hand(user) - return +/obj/machinery/computer/robotics/proc/can_control(var/mob/user, var/mob/living/silicon/robot/R) + if(!istype(R)) + return 0 + if(istype(user, /mob/living/silicon/ai)) + if (R.connected_ai != user) + return 0 + if(istype(user, /mob/living/silicon/robot)) + if (R != user) + return 0 + if(R.scrambledcodes) + return 0 + return 1 /obj/machinery/computer/robotics/attack_hand(var/mob/user as mob) if(..()) return + interact(user) + +/obj/machinery/computer/robotics/interact(var/mob/user as mob) if (src.z > 6) - user << "\red Unable to establish a connection: \black You're too far away from the station!" + user << "Unable to establish a connection: \black You're too far away from the station!" return user.set_machine(src) var/dat - if (src.temp) - dat = "[src.temp]

Clear Screen" - else - if(screen == 0) - dat += "

Cyborg Control Console


" - dat += "1. Cyborg Status
" - dat += "2. Emergency Full Destruct
" - if(screen == 1) - for(var/mob/living/silicon/robot/R in mob_list) - if(istype(R, /mob/living/silicon/robot/drone)) - continue //There's a specific console for drones. - if(istype(user, /mob/living/silicon/ai)) - if (R.connected_ai != user) - continue - if(istype(user, /mob/living/silicon/robot)) - if (R != user) - continue - if(R.scrambledcodes) - continue + var/robots = 0 + for(var/mob/living/silicon/robot/R in mob_list) + if(!can_control(user, R)) + continue + robots++ + dat += "[R.name] |" + if(R.stat) + dat += " Not Responding |" + else if (!R.canmove) + dat += " Locked Down |" + else + dat += " Operating Normally |" + if (!R.canmove) + else if(R.cell) + dat += " Battery Installed ([R.cell.charge]/[R.cell.maxcharge]) |" + else + dat += " No Cell Installed |" + if(R.module) + dat += " Module Installed ([R.module.name]) |" + else + dat += " No Module Installed |" + if(R.connected_ai) + dat += " Slaved to [R.connected_ai.name] |" + else + dat += " Independent from AI |" + if (istype(user, /mob/living/silicon)) + if(issilicon(user) && is_special_character(user) && !R.emagged) + dat += "(Hack) " + dat += "([R.canmove ? "Lockdown" : "Release"]) " + dat += "(Destroy)" + dat += "
" - dat += "[R.name] |" - if(R.stat) - dat += " Not Responding |" - else if (!R.canmove) - dat += " Locked Down |" - else - dat += " Operating Normally |" - if (!R.canmove) - else if(R.cell) - dat += " Battery Installed ([R.cell.charge]/[R.cell.maxcharge]) |" - else - dat += " No Cell Installed |" - if(R.module) - dat += " Module Installed ([R.module.name]) |" - else - dat += " No Module Installed |" - if(R.connected_ai) - dat += " Slaved to [R.connected_ai.name] |" - else - dat += " Independent from AI |" - if (istype(user, /mob/living/silicon)) - if((user.mind.special_role && user.mind.original == user) && !R.emagged) - dat += "(Hack) " - dat += "([R.canmove ? "Lockdown" : "Release"]) " - dat += "(Destroy)" - dat += "
" - dat += "(Return to Main Menu)
" - if(screen == 2) - if(!src.status) - dat += {"
Emergency Robot Self-Destruct
\nStatus: Off
- \n
- \nCountdown: [src.timeleft]/60 \[Reset\]
- \n
- \nStart Sequence
- \n
- \nClose"} - else - dat = {"Emergency Robot Self-Destruct
\nStatus: Activated
- \n
- \nCountdown: [src.timeleft]/60 \[Reset\]
- \n
\nStop Sequence
- \n
- \nClose"} - dat += "(Return to Main Menu)
" + if(!robots) + dat += "No Cyborg Units detected within access parameters." - user << browse(dat, "window=computer;size=400x500") - onclose(user, "computer") + var/datum/browser/popup = new(user, "computer", "Cyborg Control Console", 400, 500) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() return /obj/machinery/computer/robotics/Topic(href, href_list) if(..()) - return 1 - if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) - usr.set_machine(src) + return - if (href_list["eject"]) - src.temp = {"Destroy Robots?
-
\[Swipe ID to initiate destruction sequence\]
- Cancel"} + if (href_list["temp"]) + src.temp = null - else if (href_list["eject2"]) - var/obj/item/weapon/card/id/I = usr.get_active_hand() - if (istype(I, /obj/item/device/pda)) - var/obj/item/device/pda/pda = I - I = pda.id - if (istype(I)) - if(src.check_access(I)) - if (!status) - msg_admin_attack("\blue [key_name_admin(usr)] has initiated the global cyborg killswitch!") - log_game("\blue [key_name(usr)] has initiated the global cyborg killswitch!") - use_log += text("\[[time_stamp()]\] [usr.name] ([usr.ckey]) has initiated the global cyborg killswitch!") - src.status = 1 - src.start_sequence() - src.temp = null + else if (href_list["killbot"]) + if(src.allowed(usr)) + var/mob/living/silicon/robot/R = locate(href_list["killbot"]) + if(can_control(usr, R)) + var/choice = input("Are you certain you wish to detonate [R.name]?") in list("Confirm", "Abort") + if(choice == "Confirm" && can_control(usr, R) && !..()) + if(R.mind && R.mind.special_role && R.emagged) + R << "Extreme danger. Termination codes detected. Scrambling security codes and automatic AI unlink triggered." + R.ResetSecurityCodes() + else + message_admins("[key_name(usr, usr.client)](JMP) detonated [key_name(R, R.client)](JMP)!") + log_game("\[key_name(usr)] detonated [key_name(R)]!") + if(R.connected_ai) + R.connected_ai << "

ALERT - Cyborg detonation detected: [R.name]
" + R.self_destruct() + else + usr << "Access Denied." - else - usr << "\red Access Denied." + else if (href_list["stopbot"]) + if(src.allowed(usr)) + var/mob/living/silicon/robot/R = locate(href_list["stopbot"]) + if(can_control(usr, R)) + var/choice = input("Are you certain you wish to [R.canmove ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort") + if(choice == "Confirm" && can_control(usr, R) && !..()) + message_admins("[key_name(usr, usr.client)](JMP) [R.canmove ? "locked down" : "released"] [key_name(R, R.client)](JMP)!") + log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [key_name(R)]!") + R.SetLockdown(!R.lockcharge) + R << "[!R.lockcharge ? "Your lockdown has been lifted!" : "You have been locked down!"]" + if(R.connected_ai) + R.connected_ai << "[!R.lockcharge ? "NOTICE - Cyborg lockdown lifted" : "ALERT - Cyborg lockdown detected"]: [R.name]
" - else if (href_list["stop"]) - src.temp = {" - Stop Robot Destruction Sequence?
-
Yes
- No"} + else + usr << "Access Denied." - else if (href_list["stop2"]) - src.stop = 1 - src.temp = null - src.status = 0 + else if (href_list["magbot"]) + if(issilicon(usr) && is_special_character(usr)) + var/mob/living/silicon/robot/R = locate(href_list["magbot"]) + if(istype(R) && !R.emagged && R.connected_ai == usr && !R.scrambledcodes && can_control(usr, R)) + log_game("[key_name(usr)] emagged [R.name] using robotic console!") + R.emagged = 1 + if(R.mind.special_role) + R.verbs += /mob/living/silicon/robot/proc/ResetSecurityCodes - else if (href_list["reset"]) - src.timeleft = 60 - - else if (href_list["temp"]) - src.temp = null - else if (href_list["screen"]) - switch(href_list["screen"]) - if("0") - screen = 0 - if("1") - screen = 1 - if("2") - screen = 2 - else if (href_list["killbot"]) - if(src.allowed(usr)) - var/mob/living/silicon/robot/R = locate(href_list["killbot"]) - if(R) - var/choice = input("Are you certain you wish to detonate [R.name]?") in list("Confirm", "Abort") - if(choice == "Confirm") - if(R && istype(R)) - if(R.mind && R.mind.special_role && R.emagged) - R << "Extreme danger. Termination codes detected. Scrambling security codes and automatic AI unlink triggered." - R.ResetSecurityCodes() - - else - msg_admin_attack("\blue [key_name_admin(usr)] detonated [R.name]!") - log_game("\blue [key_name_admin(usr)] detonated [R.name]!") - use_log += text("\[[time_stamp()]\] [usr.name] ([usr.ckey]) detonated [R.name] ([R.ckey])!") - R.self_destruct() - else - usr << "\red Access Denied." - - else if (href_list["stopbot"]) - if(src.allowed(usr)) - var/mob/living/silicon/robot/R = locate(href_list["stopbot"]) - if(R && istype(R)) // Extra sancheck because of input var references - var/choice = input("Are you certain you wish to [R.canmove ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort") - if(choice == "Confirm") - if(R && istype(R)) - msg_admin_attack("\blue [key_name_admin(usr)] [R.canmove ? "locked down" : "released"] [R.name]!") - log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [R.name]!") - R.canmove = !R.canmove - if (R.lockcharge) - // R.cell.charge = R.lockcharge - R.lockcharge = !R.lockcharge - R << "Your lockdown has been lifted!" - else - R.lockcharge = !R.lockcharge - // R.cell.charge = 0 - R << "You have been locked down!" - - else - usr << "\red Access Denied." - - else if (href_list["magbot"]) - if(src.allowed(usr)) - var/mob/living/silicon/robot/R = locate(href_list["magbot"]) - - // whatever weirdness this is supposed to be, but that is how the href gets added, so here it is again - if(istype(R) && istype(usr, /mob/living/silicon) && usr.mind.special_role && (usr.mind.original == usr) && !R.emagged) - - var/choice = input("Are you certain you wish to hack [R.name]?") in list("Confirm", "Abort") - if(choice == "Confirm") - if(R && istype(R)) - msg_admin_attack("\blue [key_name_admin(usr)] emagged [R.name] using robotic console!") - log_game("[key_name(usr)] emagged [R.name] using robotic console!") - R.emagged = 1 - if(R.hud_used) - R.hud_used.update_robot_modules_display() //Shows/hides the emag item if the inventory screen is already open. - if(R.mind.special_role) - R.verbs += /mob/living/silicon/robot/proc/ResetSecurityCodes - - src.add_fingerprint(usr) src.updateUsrDialog() return - -/obj/machinery/computer/robotics/proc/start_sequence() - - do - if(src.stop) - src.stop = 0 - return - src.timeleft-- - sleep(10) - while(src.timeleft) - - for(var/mob/living/silicon/robot/R in mob_list) - if(!R.scrambledcodes && !istype(R, /mob/living/silicon/robot/drone)) - R.self_destruct() - - return diff --git a/code/modules/computer3/lapvend.dm b/code/modules/computer3/lapvend.dm index 4188e3a55e8..20839d6394a 100644 --- a/code/modules/computer3/lapvend.dm +++ b/code/modules/computer3/lapvend.dm @@ -320,8 +320,8 @@ newlap.spawn_files += (/datum/file/camnet_key/anomalyisolation) newlap.spawn_files += (/datum/file/camnet_key/toxins) newlap.spawn_files += (/datum/file/camnet_key/telepad) - if(access_rd in C.access) - newlap.spawn_files += (/datum/file/program/borg_control) +/* if(access_rd in C.access) + newlap.spawn_files += (/datum/file/program/borg_control) */ if(access_cent_specops in C.access) newlap.spawn_files += (/datum/file/camnet_key/ert) newlap.spawn_files += (/datum/file/camnet_key/centcom) diff --git a/code/modules/computer3/program.dm b/code/modules/computer3/program.dm index e7c1afd082f..ebead299e1e 100644 --- a/code/modules/computer3/program.dm +++ b/code/modules/computer3/program.dm @@ -361,12 +361,12 @@ Programs are a file that can be executed drm = 1 active_state = "power" volume = 5000 - +/* /datum/file/program/borg_control name = "Cyborg Maint" image = 'icons/ntos/borgcontrol.png' active_state = "robot" - volume = 9050 + volume = 9050 */ /datum/file/program/AIupload name = "AI Upload" diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm index 73ec259f7f7..fb5aeada842 100644 --- a/code/modules/mob/living/silicon/robot/component.dm +++ b/code/modules/mob/living/silicon/robot/component.dm @@ -67,11 +67,11 @@ name = "armour plating" energy_consumption = 0 external_type = /obj/item/robot_parts/robot_component/armour - max_damage = 60 + max_damage = 100 /datum/robot_component/actuator name = "actuator" - energy_consumption = 2 + energy_consumption = 1 external_type = /obj/item/robot_parts/robot_component/actuator max_damage = 50 @@ -121,7 +121,7 @@ /mob/living/silicon/robot/proc/is_component_functioning(module_name) var/datum/robot_component/C = components[module_name] return C && C.installed == 1 && C.toggled && C.is_powered() - + // Returns component by it's string name /mob/living/silicon/robot/proc/get_component(var/component_name) var/datum/robot_component/C = components[component_name] diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index 8171b891977..3810dba4e34 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -16,16 +16,19 @@ update_items() if (src.stat != DEAD) //still using power use_power() - process_killswitch() process_locks() + update_canmove() + + update_gravity(mob_has_gravity()) + handle_fire() /mob/living/silicon/robot/proc/clamp_values() -// SetStunned(min(stunned, 30)) + SetStunned(min(stunned, 30)) SetParalysis(min(paralysis, 30)) -// SetWeakened(min(weakened, 20)) + SetWeakened(min(weakened, 20)) sleeping = 0 adjustBruteLoss(0) adjustToxLoss(0) @@ -36,20 +39,23 @@ if (is_component_functioning("power cell") && cell) if(src.cell.charge <= 0) uneq_all() - src.stat = 1 + src.stat = 1 has_power = 0 for(var/V in components) var/datum/robot_component/C = components[V] if(C.name == "actuator") // Let drained robots move, disable the rest continue C.consume_power() + else if (src.cell.charge <= 100) + uneq_all() + src.cell.use(1) else if(src.module_state_1) - src.cell.use(3) + src.cell.use(4) if(src.module_state_2) - src.cell.use(3) + src.cell.use(4) if(src.module_state_3) - src.cell.use(3) + src.cell.use(4) for(var/V in components) var/datum/robot_component/C = components[V] @@ -57,15 +63,14 @@ if(!is_component_functioning("actuator")) Paralyse(3) - + src.eye_blind = 0 src.stat = 0 has_power = 1 else uneq_all() - src.stat = 1 + src.stat = 1 Paralyse(3) - /mob/living/silicon/robot/proc/handle_regular_status_updates() if(src.camera && !scrambledcodes) @@ -74,7 +79,9 @@ else src.camera.status = 1 - updatehealth() + health = maxHealth - (getOxyLoss() + getFireLoss() + getBruteLoss()) + + if(getOxyLoss() > 50) Paralyse(3) if(src.sleeping) Paralyse(3) @@ -83,10 +90,21 @@ if(src.resting) Weaken(5) - if(health < config.health_threshold_dead && src.stat != 2) //die only once + if(health <= config.health_threshold_dead && src.stat != 2) //die only once death() if (src.stat != 2) //Alive. + if(!istype(src,/mob/living/silicon/robot/drone)) + if(health < 50) //Gradual break down of modules as more damage is sustained + if(uneq_module(module_state_3)) + src << "SYSTEM ERROR: Module 3 OFFLINE." + if(health < 0) + if(uneq_module(module_state_2)) + src << "SYSTEM ERROR: Module 2 OFFLINE." + if(health < -50) + if(uneq_module(module_state_1)) + src << "CRITICAL ERROR: All modules OFFLINE." + if (src.paralysis || src.stunned || src.weakened) //Stunned etc. src.stat = 1 if (src.stunned > 0) @@ -95,34 +113,25 @@ AdjustWeakened(-1) if (src.paralysis > 0) AdjustParalysis(-1) - src.blinded = 1 + src.eye_blind = max(eye_blind, 1) else - src.blinded = 0 + src.eye_blind = 0 else //Not stunned. src.stat = 0 else //Dead. - src.blinded = 1 - src.stat = 2 + src.eye_blind = 1 if (src.stuttering) src.stuttering-- if (src.eye_blind) src.eye_blind-- - src.blinded = 1 - - if (src.ear_deaf > 0) src.ear_deaf-- - if (src.ear_damage < 25) - src.ear_damage -= 0.05 - src.ear_damage = max(src.ear_damage, 0) src.density = !( src.lying ) - if ((src.sdisabilities & BLIND)) - src.blinded = 1 - if ((src.sdisabilities & DEAF)) - src.ear_deaf = 1 + if (src.disabilities & BLIND) + src.eye_blind = max(1, eye_blind) if (src.eye_blurry > 0) src.eye_blurry-- @@ -154,31 +163,32 @@ /mob/living/silicon/robot/proc/handle_regular_hud_updates() - if (src.stat == 2 || XRAY in mutations || src.sight_mode & BORGXRAY) + if (src.stat == 2 || src.sight_mode & BORGXRAY) src.sight |= SEE_TURFS src.sight |= SEE_MOBS src.sight |= SEE_OBJS src.see_in_dark = 8 - src.see_invisible = SEE_INVISIBLE_MINIMUM - else if (src.sight_mode & BORGMESON && src.sight_mode & BORGTHERM) - src.sight |= SEE_TURFS - src.sight |= SEE_MOBS - src.see_in_dark = 8 - see_invisible = SEE_INVISIBLE_MINIMUM - else if (src.sight_mode & BORGMESON) - src.sight |= SEE_TURFS - src.see_in_dark = 8 - see_invisible = SEE_INVISIBLE_MINIMUM - else if (src.sight_mode & BORGTHERM) - src.sight |= SEE_MOBS - src.see_in_dark = 8 src.see_invisible = SEE_INVISIBLE_LEVEL_TWO - else if (src.stat != 2) - src.sight &= ~SEE_MOBS - src.sight &= ~SEE_TURFS - src.sight &= ~SEE_OBJS + else src.see_in_dark = 8 - src.see_invisible = SEE_INVISIBLE_LEVEL_TWO + if (src.sight_mode & BORGMESON && src.sight_mode & BORGTHERM) + src.sight |= SEE_TURFS + src.sight |= SEE_MOBS + src.see_invisible = SEE_INVISIBLE_MINIMUM + else if (src.sight_mode & BORGMESON) + src.sight |= SEE_TURFS + src.see_invisible = SEE_INVISIBLE_MINIMUM + src.see_in_dark = 1 + else if (src.sight_mode & BORGTHERM) + src.sight |= SEE_MOBS + src.see_invisible = SEE_INVISIBLE_LEVEL_TWO + else if (src.stat != 2) + src.sight &= ~SEE_MOBS + src.sight &= ~SEE_TURFS + src.sight &= ~SEE_OBJS + src.see_invisible = SEE_INVISIBLE_LEVEL_TWO + if(see_override) + see_invisible = see_override regular_hud_updates() @@ -212,17 +222,15 @@ src.healths.icon_state = "health6" else switch(health) - if(200 to INFINITY) + if(100 to INFINITY) src.healths.icon_state = "health0" - if(150 to 200) - src.healths.icon_state = "health1" - if(100 to 150) - src.healths.icon_state = "health2" if(50 to 100) - src.healths.icon_state = "health3" + src.healths.icon_state = "health2" if(0 to 50) + src.healths.icon_state = "health3" + if(-50 to 0) src.healths.icon_state = "health4" - if(config.health_threshold_dead to 0) + if(config.health_threshold_dead to -50) src.healths.icon_state = "health5" else src.healths.icon_state = "health6" @@ -319,16 +327,6 @@ src.module_state_3:screen_loc = ui_inv3 updateicon() -/mob/living/silicon/robot/proc/process_killswitch() - if(killswitch) - killswitch_time -- - if(killswitch_time <= 0) - if(src.client) - src << "\red Killswitch Activated" - killswitch = 0 - spawn(5) - gib() - /mob/living/silicon/robot/proc/process_locks() if(weapon_lock) uneq_all() @@ -348,7 +346,13 @@ /mob/living/silicon/robot/handle_fire() if(..()) return - adjustFireLoss(3) + if(fire_stacks > 0) + fire_stacks-- + fire_stacks = max(0, fire_stacks) + else + ExtinguishMob() + + //adjustFireLoss(3) return /mob/living/silicon/robot/update_fire() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 9bb0eee9203..79c5fc8b469 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -8,8 +8,8 @@ var/list/robot_verbs_default = list( real_name = "Cyborg" icon = 'icons/mob/robots.dmi' icon_state = "robot" - maxHealth = 200 - health = 200 + maxHealth = 100 + health = 100 universal_speak = 1 var/sight_mode = 0 @@ -63,8 +63,6 @@ var/list/robot_verbs_default = list( var/datum/effect/effect/system/spark_spread/spark_system//So they can initialize sparks whenever/N var/jeton = 0 var/has_power = 1 - var/killswitch = 0 - var/killswitch_time = 60 var/weapon_lock = 0 var/weaponlock_time = 120 var/lawupdate = 1 //Cyborgs will sync their laws with their AI by default @@ -76,7 +74,7 @@ var/list/robot_verbs_default = list( var/braintype = "Cyborg" var/base_icon = "" var/crisis = 0 - + var/obj/item/borg/sight/hud/sec/sechud = null var/obj/item/borg/sight/hud/med/healthhud = null @@ -84,9 +82,9 @@ var/list/robot_verbs_default = list( spark_system = new /datum/effect/effect/system/spark_spread() spark_system.set_up(5, 0, src) spark_system.attach(src) - + add_language("Robot Talk", 1) - + wires = new(src) robot_modules_background = new() @@ -98,9 +96,9 @@ var/list/robot_verbs_default = list( radio = new /obj/item/device/radio/borg(src) common_radio = radio - + init() - + if(!scrambledcodes && !camera) camera = new /obj/machinery/camera(src) camera.c_tag = real_name @@ -126,7 +124,7 @@ var/list/robot_verbs_default = list( cell.charge = 7500 ..() - + add_robot_verbs() if(cell) @@ -165,7 +163,7 @@ var/list/robot_verbs_default = list( rbPDA.set_name_and_job(custom_name,braintype) if(scrambledcodes) rbPDA.hidden = 1 - + /mob/living/silicon/robot/binarycheck() if(is_component_functioning("comms")) var/datum/robot_component/RC = get_component("comms") @@ -243,6 +241,7 @@ var/list/robot_verbs_default = list( module_sprites["Standard"] = "surgeon" module_sprites["Advanced Droid"] = "droid-medical" module_sprites["Needles"] = "medicalrobot" + status_flags &= ~CANPUSH if("Security") module = new /obj/item/weapon/robot_module/security(src) @@ -251,6 +250,7 @@ var/list/robot_verbs_default = list( module_sprites["Red Knight"] = "Security" module_sprites["Black Knight"] = "securityrobot" module_sprites["Bloodhound"] = "bloodhound" + status_flags &= ~CANPUSH if("Engineering") module = new /obj/item/weapon/robot_module/engineering(src) @@ -281,7 +281,7 @@ var/list/robot_verbs_default = list( icon_state = "xenoborg-state-a" modtype = "Xeno-Hu" feedback_inc("xeborg_hunter",1) - + //languages module.add_languages(src) @@ -445,7 +445,7 @@ var/list/robot_verbs_default = list( set desc = "Augment visual feed with internal sensor overlays." set category = "Robot Commands" toggle_sensor_mode() - + /mob/living/silicon/robot/proc/add_robot_verbs() src.verbs |= robot_verbs_default @@ -824,7 +824,7 @@ var/list/robot_verbs_default = list( else spark_system.start() return ..() - + /mob/living/silicon/robot/emag_act(user as mob) if(!ishuman(user)) return @@ -904,128 +904,44 @@ var/list/robot_verbs_default = list( usr << "You unlock your cover." /mob/living/silicon/robot/attack_alien(mob/living/carbon/alien/humanoid/M as mob) - if (!ticker) - M << "You cannot attack people before the game has started." - return - - if (istype(loc, /turf) && istype(loc.loc, /area/start)) - M << "No attacking people at spawn, you jackass." - return - - switch(M.a_intent) - - if ("help") - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("[M] caresses [src]'s plating with its scythe like arm."), 1) - - if ("grab") - if (M == src || anchored) - return - var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(M, src ) - - M.put_in_active_hand(G) - - G.synch() - playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) - visible_message("[M] has grabbed [src] passively!") - - if ("harm") + if (M.a_intent =="disarm") + if(!(lying)) M.do_attack_animation(src) - var/damage = rand(10, 20) - if (prob(90)) - /* - if (M.class == "combat") - damage += 15 - if(prob(20)) - weakened = max(weakened,4) - stunned = max(stunned,4) - What is this?*/ - - playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1) - visible_message("[M] has slashed at [src]!",\ - "[M] has slashed at [src]!") - if(prob(8)) - flick("noise", flash) - adjustBruteLoss(damage) - updatehealth() + if (prob(85)) + Stun(7) + step(src,get_dir(M,src)) + spawn(5) + step(src,get_dir(M,src)) + add_logs(M, src, "pushed", admin=0) + playsound(loc, 'sound/weapons/pierce.ogg', 50, 1, -1) + visible_message("[M] has forced back [src]!", \ + "[M] has forced back [src]!") else playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1) visible_message("[M] took a swipe at [src]!", \ "[M] took a swipe at [src]!") - - if ("disarm") - if(!(lying)) - M.do_attack_animation(src) - if (rand(1,100) <= 85) - Stun(7) - step(src,get_dir(M,src)) - spawn(5) step(src,get_dir(M,src)) - playsound(loc, 'sound/weapons/pierce.ogg', 50, 1, -1) - visible_message("[M] has forced back [src]!",\ - "[M] has forced back [src]!") - else - playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1) - visible_message("[M] attempted to force back [src]!",\ - "[M] attempted to force back [src]!") + else + ..() return /mob/living/silicon/robot/attack_slime(mob/living/carbon/slime/M as mob) - if (!ticker) - M << "You cannot attack people before the game has started." - return + if(..()) //successful slime shock + flick("noise", flash) + var/stunprob = M.powerlevel * 7 + 10 + if(prob(stunprob) && M.powerlevel >= 8) + adjustBruteLoss(M.powerlevel * rand(6,10)) - if(M.Victim) return // can't attack while eating! + var/damage = rand(1, 3) - if (health > -100) - M.do_attack_animation(src) - visible_message("The [M.name] glomps [src]!",\ - "The [M.name] glomps [src]!") - - var/damage = rand(1, 3) - - if(M.is_adult) - damage = rand(20, 40) - else - damage = rand(5, 35) - - damage = round(damage / 2) // borgs recieve half damage - adjustBruteLoss(damage) - - - if(M.powerlevel > 0) - var/stunprob = 10 - - switch(M.powerlevel) - if(1 to 2) stunprob = 20 - if(3 to 4) stunprob = 30 - if(5 to 6) stunprob = 40 - if(7 to 8) stunprob = 60 - if(9) stunprob = 70 - if(10) stunprob = 95 - - if(prob(stunprob)) - M.powerlevel -= 3 - if(M.powerlevel < 0) - M.powerlevel = 0 - - for(var/mob/O in viewers(src, null)) - if ((O.client && !( O.blinded ))) - O.show_message(text("The [M.name] has electrified []!", src), 1) - - flick("noise", flash) - - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(5, 1, src) - s.start() - - if (prob(stunprob) && M.powerlevel >= 8) - adjustBruteLoss(M.powerlevel * rand(6,10)) - - - updatehealth() + if(M.is_adult) + damage = rand(20, 40) + else + damage = rand(5, 35) + damage = round(damage / 2) // borgs recieve half damage + adjustBruteLoss(damage) + updatehealth() return @@ -1301,6 +1217,12 @@ var/list/robot_verbs_default = list( return /mob/living/silicon/robot/proc/self_destruct() + if(emagged) + if(mmi) + qdel(mmi) + explosion(src.loc,1,2,4) + else + explosion(src.loc,-1,0,2) gib() return @@ -1313,9 +1235,12 @@ var/list/robot_verbs_default = list( scrambledcodes = 1 //Disconnect it's camera so it's not so easily tracked. if(src.camera) - src.camera.network = list() - cameranet.removeCamera(src.camera) - + qdel(src.camera) + src.camera = null + // I'm trying to get the Cyborg to not be listed in the camera list + // Instead of being listed as "deactivated". The downside is that I'm going + // to have to check if every camera is null or not before doing anything, to prevent runtime errors. + // I could change the network to null but I don't know what would happen, and it seems too hacky for me. /mob/living/silicon/robot/proc/ResetSecurityCodes() set category = "Robot Commands" @@ -1394,7 +1319,7 @@ var/list/robot_verbs_default = list( faction = list("nanotrasen") designation = "NT Combat Cyborg" req_access = list(access_cent_specops) - + /mob/living/silicon/robot/deathsquad/New(loc) if(!cell) cell = new /obj/item/weapon/stock_parts/cell(src) @@ -1402,7 +1327,7 @@ var/list/robot_verbs_default = list( cell.charge = 25000 ..() - + /mob/living/silicon/robot/deathsquad/init() aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src) @@ -1473,7 +1398,7 @@ var/list/robot_verbs_default = list( cell.charge = 25000 ..() - + /mob/living/silicon/robot/syndicate/init() aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src) diff --git a/code/modules/paperwork/stamps.dm b/code/modules/paperwork/stamps.dm index 243762eefb6..925abb3e84f 100644 --- a/code/modules/paperwork/stamps.dm +++ b/code/modules/paperwork/stamps.dm @@ -6,17 +6,21 @@ item_state = "stamp" throwforce = 0 w_class = 1.0 - throw_speed = 7 - throw_range = 15 + throw_speed = 3 + throw_range = 7 m_amt = 60 - _color = "qm" + _color = "cargo" pressure_resistance = 2 attack_verb = list("stamped") +/obj/item/weapon/stamp/suicide_act(mob/user) + user.visible_message("[user] stamps 'VOID' on \his forehead, then promptly falls over, dead.") + return (OXYLOSS) + /obj/item/weapon/stamp/qm name = "Quartermaster's rubber stamp" icon_state = "stamp-qm" - _color = "cargo" + _color = "qm" /obj/item/weapon/stamp/law name = "Law office's rubber stamp" @@ -56,8 +60,8 @@ /obj/item/weapon/stamp/granted name = "\improper GRANTED rubber stamp" icon_state = "stamp-ok" - _color = "qm" - + _color = "qm" + /obj/item/weapon/stamp/denied name = "\improper DENIED rubber stamp" icon_state = "stamp-deny" diff --git a/code/modules/projectiles/guns/energy/special.dm b/code/modules/projectiles/guns/energy/special.dm index 5e8a3a501f2..84db4fa444f 100644 --- a/code/modules/projectiles/guns/energy/special.dm +++ b/code/modules/projectiles/guns/energy/special.dm @@ -4,19 +4,24 @@ icon_state = "ionrifle" item_state = null //so the human update icon uses the icon_state instead. icon_override = 'icons/mob/in-hand/guns.dmi' - fire_sound = 'sound/weapons/Laser.ogg' + fire_sound = 'sound/weapons/IonRifle.ogg' origin_tech = "combat=2;magnets=4" - w_class = 4.0 + w_class = 5.0 flags = CONDUCT slot_flags = SLOT_BACK projectile_type = "/obj/item/projectile/ion" /obj/item/weapon/gun/energy/ionrifle/emp_act(severity) - if(severity <= 2) - power_supply.use(round(power_supply.maxcharge / severity)) - update_icon() - else - return + return + +/obj/item/weapon/gun/energy/ionrifle/carbine + name = "ion carbine" + desc = "The MK.II Prototype Ion Projector is a lightweight carbine version of the larger ion rifle, built to be ergonomic and efficient." + icon_state = "ioncarbine" + item_state = "ioncarbine" + origin_tech = "combat=4;magnets=4;materials=4" + w_class = 3 + slot_flags = SLOT_BELT /obj/item/weapon/gun/energy/decloner name = "biological demolecularisor" @@ -288,7 +293,8 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out. desc = "A self-defense weapon that exhausts organic targets, weakening them until they collapse." icon_state = "disabler" item_state = null - projectile_type = "/obj/item/projectile/beam/disabler" + projectile_type = /obj/item/projectile/beam/disabler + fire_sound = 'sound/weapons/taser2.ogg' cell_type = "/obj/item/weapon/stock_parts/cell" charge_cost = 500 diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 2a892e2d057..f27eb81f01e 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -46,14 +46,14 @@ build_path = /obj/item/weapon/gun/energy/floragun category = list("Weapons") -/datum/design/ionrifle - name = "Ion Rifle" +/datum/design/ioncarbine + name = "Ion Carbine" desc = "How to dismantle a cyborg : The gun." - id = "ionrifle" + id = "ioncarbine" req_tech = list("combat" = 5, "materials" = 4, "magnets" = 4) build_type = PROTOLATHE materials = list("$silver" = 4000, "$metal" = 6000, "$uranium" = 1000) - build_path = /obj/item/weapon/gun/energy/ionrifle + build_path = /obj/item/weapon/gun/energy/ionrifle/carbine locked = 1 category = list("Weapons") diff --git a/icons/mob/in-hand/guns.dmi b/icons/mob/in-hand/guns.dmi index ff8adfd7c5a..619a7e534ef 100644 Binary files a/icons/mob/in-hand/guns.dmi and b/icons/mob/in-hand/guns.dmi differ diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi index cbc9742a6c5..d87a61fc5cd 100644 Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ diff --git a/sound/weapons/IonRifle.ogg b/sound/weapons/IonRifle.ogg new file mode 100644 index 00000000000..b808068e55f Binary files /dev/null and b/sound/weapons/IonRifle.ogg differ