diff --git a/aurora.dme b/aurora.dme index 3b5bcedb..c7d1c3fa 100644 --- a/aurora.dme +++ b/aurora.dme @@ -125,6 +125,7 @@ #include "code\_onclick\other_mobs.dm" #include "code\_onclick\telekinesis.dm" #include "code\_onclick\hud\_defines.dm" +#include "code\_onclick\hud\ai.dm" #include "code\_onclick\hud\alien.dm" #include "code\_onclick\hud\alien_larva.dm" #include "code\_onclick\hud\hud.dm" @@ -1155,6 +1156,7 @@ #include "code\modules\mob\living\silicon\ai\life.dm" #include "code\modules\mob\living\silicon\ai\login.dm" #include "code\modules\mob\living\silicon\ai\logout.dm" +#include "code\modules\mob\living\silicon\ai\nano.dm" #include "code\modules\mob\living\silicon\ai\say.dm" #include "code\modules\mob\living\silicon\ai\freelook\cameranet.dm" #include "code\modules\mob\living\silicon\ai\freelook\chunk.dm" diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index c4fd7564..debc67a1 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -57,7 +57,10 @@ RestrainedClickOn(A) return */ - + // handle equipping modules + if (A.equip_robot(src)) + return + var/obj/item/W = get_active_hand() // Cyborgs have no range-checking unless there is item use @@ -118,6 +121,9 @@ /atom/proc/attack_robot(mob/user as mob) attack_ai(user) return + +/atom/proc/equip_robot(mob/user as mob) + return /mob/living/silicon/robot/MiddleClickOn(var/atom/A) cycle_modules() @@ -137,7 +143,7 @@ var/locked_door=A.AICtrlClick(src) if (!locked_door) ..(A) - + /mob/living/silicon/robot/AltClickOn(var/atom/A) A.AIAltClick(src) diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index fc822a38..57d2cac3 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -39,6 +39,7 @@ #define ui_alien_head "4:12,1:5" //aliens #define ui_alien_oclothing "5:14,1:5" //aliens +#define ui_borg_sensor "5:16,1:5" //borgs #define ui_inv1 "6:16,1:5" //borgs #define ui_inv2 "7:16,1:5" //borgs #define ui_inv3 "8:16,1:5" //borgs @@ -57,6 +58,8 @@ #define ui_acti_alt "14:28,1:5" //alternative intent switcher for when the interface is hidden (F12) #define ui_borg_pull "12:24,2:7" +#define ui_borg_radio "EAST-1:28,SOUTH+1:7" +#define ui_borg_intents "EAST-2:26,SOUTH:5" #define ui_borg_module "13:26,2:7" #define ui_borg_panel "14:28,2:7" @@ -117,3 +120,22 @@ #define ui_iarrowleft "SOUTH-1,11" #define ui_iarrowright "SOUTH-1,13" + +// AI + +#define ui_ai_camera_list "SOUTH:6+1,WEST+1:16" +#define ui_ai_track_with_camera "SOUTH:6+1,WEST+2:16" +#define ui_ai_camera_light "SOUTH:6+1,WEST+3:16" +#define ui_ai_sensor "SOUTH:6+1,WEST+4:16" + +#define ui_ai_core "SOUTH:6,WEST+1:16" +#define ui_ai_crew_monitor "SOUTH:6,WEST+2:16" +#define ui_ai_crew_manifest "SOUTH:6,WEST+3:16" +#define ui_ai_alerts "SOUTH:6,WEST+4:16" +#define ui_ai_announcement "SOUTH:6,WEST+5:16" +#define ui_ai_shuttle "SOUTH:6,WEST+6:16" +#define ui_ai_state_laws "SOUTH:6,WEST+7:16" +#define ui_ai_pda_send "SOUTH:6,WEST+8:16" +#define ui_ai_pda_log "SOUTH:6,WEST+9:16" +#define ui_ai_take_picture "SOUTH:6,WEST+10:16" +#define ui_ai_view_images "SOUTH:6,WEST+11:16" \ No newline at end of file diff --git a/code/_onclick/hud/ai.dm b/code/_onclick/hud/ai.dm new file mode 100644 index 00000000..b528832c --- /dev/null +++ b/code/_onclick/hud/ai.dm @@ -0,0 +1,143 @@ +/datum/hud/proc/ai_hud() + adding = list() + other = list() + + var/obj/screen/using + +//AI core + using = new /obj/screen() + using.name = "AI Core" + using.icon = 'icons/mob/screen_ai.dmi' + using.icon_state = "ai_core" + using.screen_loc = ui_ai_core + using.layer = 20 + adding += using + +//Camera list + using = new /obj/screen() + using.name = "Show Camera List" + using.icon = 'icons/mob/screen_ai.dmi' + using.icon_state = "camera" + using.screen_loc = ui_ai_camera_list + using.layer = 20 + adding += using + +//Track + using = new /obj/screen() + using.name = "Track With Camera" + using.icon = 'icons/mob/screen_ai.dmi' + using.icon_state = "track" + using.screen_loc = ui_ai_track_with_camera + using.layer = 20 + adding += using + +//Camera light + using = new /obj/screen() + using.name = "Toggle Camera Light" + using.icon = 'icons/mob/screen_ai.dmi' + using.icon_state = "camera_light" + using.screen_loc = ui_ai_camera_light + using.layer = 20 + adding += using + +//Crew Monitorting + using = new /obj/screen() + using.name = "Crew Monitoring" + using.icon = 'icons/mob/screen_ai.dmi' + using.icon_state = "crew_monitor" + using.screen_loc = ui_ai_crew_monitor + using.layer = 20 + adding += using + +//Crew Manifest + using = new /obj/screen() + using.name = "Show Crew Manifest" + using.icon = 'icons/mob/screen_ai.dmi' + using.icon_state = "manifest" + using.screen_loc = ui_ai_crew_manifest + using.layer = 20 + adding += using + +//Alerts + using = new /obj/screen() + using.name = "Show Alerts" + using.icon = 'icons/mob/screen_ai.dmi' + using.icon_state = "alerts" + using.screen_loc = ui_ai_alerts + using.layer = 20 + adding += using + +//Announcement + using = new /obj/screen() + using.name = "Announcement" + using.icon = 'icons/mob/screen_ai.dmi' + using.icon_state = "announcement" + using.screen_loc = ui_ai_announcement + using.layer = 20 + adding += using + +//Shuttle + using = new /obj/screen() + using.name = "Call Emergency Shuttle" + using.icon = 'icons/mob/screen_ai.dmi' + using.icon_state = "call_shuttle" + using.screen_loc = ui_ai_shuttle + using.layer = 20 + adding += using + +//Laws + using = new /obj/screen() + using.name = "State Laws" + using.icon = 'icons/mob/screen_ai.dmi' + using.icon_state = "state_laws" + using.screen_loc = ui_ai_state_laws + using.layer = 20 + adding += using + +//PDA message + using = new /obj/screen() + using.name = "PDA - Send Message" + using.icon = 'icons/mob/screen_ai.dmi' + using.icon_state = "pda_send" + using.screen_loc = ui_ai_pda_send + using.layer = 20 + adding += using + +//PDA log + using = new /obj/screen() + using.name = "PDA - Show Message Log" + using.icon = 'icons/mob/screen_ai.dmi' + using.icon_state = "pda_receive" + using.screen_loc = ui_ai_pda_log + using.layer = 20 + adding += using + +//Take image + using = new /obj/screen() + using.name = "Take Image" + using.icon = 'icons/mob/screen_ai.dmi' + using.icon_state = "take_picture" + using.screen_loc = ui_ai_take_picture + using.layer = 20 + adding += using + +//View images + using = new /obj/screen() + using.name = "View Images" + using.icon = 'icons/mob/screen_ai.dmi' + using.icon_state = "view_images" + using.screen_loc = ui_ai_view_images + using.layer = 20 + adding += using + +//Medical/Security sensors + using = new /obj/screen() + using.name = "Set Sensor Augmentation" + using.icon = 'icons/mob/screen_ai.dmi' + using.icon_state = "ai_sensor" + using.screen_loc = ui_ai_sensor + using.layer = 20 + adding += using + + mymob.client.screen += adding + other + return \ No newline at end of file diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm index cd19e78d..10cf0d03 100644 --- a/code/_onclick/hud/other_mobs.dm +++ b/code/_onclick/hud/other_mobs.dm @@ -13,9 +13,6 @@ mymob.blind.screen_loc = "1,1" mymob.blind.layer = 0 -/datum/hud/proc/ai_hud() - return - /datum/hud/proc/blob_hud(ui_style = 'icons/mob/screen1_Midnight.dmi') blobpwrdisplay = new /obj/screen() diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 62cf2247..913440e7 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -12,7 +12,7 @@ using.dir = SOUTHWEST using.icon = 'icons/mob/screen1_robot.dmi' using.icon_state = "radio" - using.screen_loc = ui_movi + using.screen_loc = ui_borg_radio using.layer = 20 src.adding += using @@ -55,8 +55,8 @@ using.name = "act_intent" using.dir = SOUTHWEST using.icon = 'icons/mob/screen1_robot.dmi' - using.icon_state = (mymob.a_intent == "hurt" ? "harm" : mymob.a_intent) - using.screen_loc = ui_acti + using.icon_state = (mymob.a_intent == "harm" ? "harm" : mymob.a_intent) + using.screen_loc = ui_borg_intents using.layer = 20 src.adding += using action_intent = using @@ -82,14 +82,6 @@ mymob.hands.name = "module" mymob.hands.screen_loc = ui_borg_module -//Module Panel - using = new /obj/screen() - using.name = "panel" - using.icon = 'icons/mob/screen1_robot.dmi' - using.icon_state = "panel" - using.screen_loc = ui_borg_panel - using.layer = 19 - src.adding += using //Store mymob.throw_icon = new /obj/screen() @@ -153,18 +145,91 @@ if (mymob.client.target_can_click) mymob.item_use_icon.dir = 1 src.adding += mymob.item_use_icon - mymob.gun_move_icon = new /obj/screen/gun/move(null) + /*mymob.gun_move_icon = new /obj/screen/gun/move(null) if (mymob.client.target_can_move) mymob.gun_move_icon.dir = 1 mymob.gun_run_icon = new /obj/screen/gun/run(null) if (mymob.client.target_can_run) mymob.gun_run_icon.dir = 1 src.adding += mymob.gun_run_icon - src.adding += mymob.gun_move_icon + src.adding += mymob.gun_move_icon*/ mymob.client.screen = null - mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.fire, mymob.hands, mymob.healths, mymob:cells, mymob.pullin, mymob.blind, mymob.flash, mymob.gun_setting_icon) //, mymob.rest, mymob.sleep, mymob.mach ) + mymob.client.screen += list(mymob.zone_sel, mymob.oxygen, mymob.fire, mymob.hands, mymob.healths, mymob:cells, mymob.pullin, mymob.blind, mymob.flash, mymob.gun_setting_icon) //, mymob.rest, mymob.sleep, mymob.mach ) mymob.client.screen += src.adding + src.other return + + +/datum/hud/proc/toggle_show_robot_modules() + if(!isrobot(mymob)) return + + var/mob/living/silicon/robot/r = mymob + + r.shown_robot_modules = !r.shown_robot_modules + update_robot_modules_display() + +/datum/hud/proc/update_robot_modules_display() + if(!isrobot(mymob)) + return + var/mob/living/silicon/robot/r = mymob + if (!r.client) // no client? No problem! + return + if(r.shown_robot_modules) + //Modules display is shown + r.client.screen += r.throw_icon //"store" icon + + if(!r.module) + usr << "\red No module selected" + return + + if(!r.module.modules) + usr << "\red Selected module has no modules to select" + return + + if(!r.robot_modules_background) + return + + var/display_rows = round((r.module.modules.len) / 8) +1 //+1 because round() returns floor of number + r.robot_modules_background.screen_loc = "CENTER-4:16,SOUTH+1:7 to CENTER+3:16,SOUTH+[display_rows]:7" + r.client.screen += r.robot_modules_background + + var/x = -4 //Start at CENTER-4,SOUTH+1 + var/y = 1 + + //Unfortunately adding the emag module to the list of modules has to be here. This is because a borg can + //be emagged before they actually select a module. - or some situation can cause them to get a new module + // - or some situation might cause them to get de-emagged or something. + if(r.emagged) + if(!(r.module.emag in r.module.modules)) + r.module.modules.Add(r.module.emag) + else + if(r.module.emag in r.module.modules) + r.module.modules.Remove(r.module.emag) + + for(var/atom/movable/A in r.module.modules) + if( (A != r.module_state_1) && (A != r.module_state_2) && (A != r.module_state_3) ) + //Module is not currently active + r.client.screen += A + if(x < 0) + A.screen_loc = "CENTER[x]:16,SOUTH+[y]:7" + else + A.screen_loc = "CENTER+[x]:16,SOUTH+[y]:7" + A.layer = 20 + + x++ + if(x == 4) + x = -4 + y++ + + else + //Modules display is hidden + r.client.screen -= r.throw_icon //"store" icon + + for(var/atom/A in r.module.modules) + if( (A != r.module_state_1) && (A != r.module_state_2) && (A != r.module_state_3) ) + //Module is not currently active + r.client.screen -= A + r.shown_robot_modules = 0 + r.client.screen -= r.robot_modules_background diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 56443936..5ef8be1d 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -370,10 +370,12 @@ usr.drop_item_v() if("module") - if(issilicon(usr)) - if(usr:module) + if(isrobot(usr)) + var/mob/living/silicon/robot/R = usr + if(R.module) + R.hud_used.toggle_show_robot_modules() return 1 - usr:pick_module() + R.pick_module() if("radio") if(issilicon(usr)) @@ -383,9 +385,15 @@ usr:installed_modules() if("store") - if(issilicon(usr)) - usr:uneq_active() + if(isrobot(usr)) + var/mob/living/silicon/robot/R = usr + R.uneq_active() + if("Toggle Sensor Augmentation") + if(isrobot(usr)) + var/mob/living/silicon/robot/R = usr + R.sensor_mode() + if("module1") if(istype(usr, /mob/living/silicon/robot)) usr:toggle_module(1) @@ -455,7 +463,85 @@ if("Toggle Gun Mode") usr.client.ToggleGunMode() + + if("AI Core") + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + AI.view_core() + + if("Show Camera List") + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + var/camera = input(AI) in AI.get_camera_list() + AI.ai_camera_list(camera) + + if("Track With Camera") + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + var/target_name = input(AI) in AI.trackable_mobs() + AI.ai_camera_track(target_name) + + if("Toggle Camera Light") + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + AI.toggle_camera_light() + + if("Crew Monitoring") + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + AI.nano_crew_monitor() + + if("Show Crew Manifest") + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + AI.ai_roster() + + if("Show Alerts") + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + AI.ai_alerts() + + if("Announcement") + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + AI.ai_announcement() + + if("Call Emergency Shuttle") + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + AI.ai_call_shuttle() + + if("State Laws") + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + AI.checklaws() + + if("PDA - Send Message") + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + AI.aiPDA.cmd_send_pdamesg(usr) + + if("PDA - Show Message Log") + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + AI.aiPDA.cmd_show_message_log(usr) + + if("Take Image") + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + AI.aiCamera.toggle_camera_mode() + + if("View Images") + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + AI.aiCamera.viewpictures() + + if("Set Sensor Augmentation") + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + AI.sensor_mode() + else return 0 return 1 diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 99635762..c6565915 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -179,6 +179,16 @@ user.put_in_active_hand(src) return + +/obj/item/equip_robot(mob/user as mob) + if (istype(src.loc, /obj/item/weapon/robot_module)) + //If the item is part of a cyborg module, equip it + if(!isrobot(user)) return + var/mob/living/silicon/robot/R = user + R.activate_module(src) + R.hud_used.update_robot_modules_display() + return TRUE + // Due to storage type consolidation this should get used more now. // I have cleaned it up a little, but it could probably use more. -Sayu /obj/item/attackby(obj/item/weapon/W as obj, mob/user as mob) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 98964af5..d0fddc9a 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -282,6 +282,12 @@ if(src.throw_icon) src.throw_icon.icon_state = "act_throw_on" +/mob/living/carbon/key_pressed_q() + if(!get_active_hand()) + usr << "\red You have nothing to drop in your hand." + return + return drop_item() + /mob/proc/throw_item(atom/target) return diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index c31aebbb..c0c6208e 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -502,13 +502,15 @@ return istype(H.glasses, /obj/item/clothing/glasses/hud/health) else return 0 - else if(istype(M, /mob/living/silicon/robot)) - var/mob/living/silicon/robot/R = M + else if(istype(M, /mob/living/silicon)) + var/mob/living/silicon/R = M switch(hudtype) if("security") - return istype(R.module_state_1, /obj/item/borg/sight/hud/sec) || istype(R.module_state_2, /obj/item/borg/sight/hud/sec) || istype(R.module_state_3, /obj/item/borg/sight/hud/sec) + if(R.sensor_mode == 1) + return 1 if("medical") - return istype(R.module_state_1, /obj/item/borg/sight/hud/med) || istype(R.module_state_2, /obj/item/borg/sight/hud/med) || istype(R.module_state_3, /obj/item/borg/sight/hud/med) + if(R.sensor_mode == 2) + return 1 else return 0 else diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index b4495d47..7ea6ca75 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -724,7 +724,11 @@ var/list/ai_verbs_default = list( else lightNearbyCamera() - +/mob/living/silicon/ai/proc/sensor_mode() + set name = "Set Sensor Augmentation" + set desc = "Augment visual feed with internal sensor overlays." + set category = "AI Commands" + toggle_sensor_mode() // Handled camera lighting, when toggled. // It will get the nearest camera from the eyeobj, lighting it. diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 5fe31ac3..11457dee 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -172,6 +172,12 @@ src.show_laws() sleep(50) theAPC = null + regular_hud_updates() + switch(src.sensor_mode) + if (SEC_HUD) + process_sec_hud(src,1,src.eyeobj) + if (MED_HUD) + process_med_hud(src,1,src.eyeobj) /mob/living/silicon/ai/updatehealth() if(status_flags & GODMODE) diff --git a/code/modules/mob/living/silicon/ai/nano.dm b/code/modules/mob/living/silicon/ai/nano.dm new file mode 100644 index 00000000..9fab4365 --- /dev/null +++ b/code/modules/mob/living/silicon/ai/nano.dm @@ -0,0 +1,11 @@ +var/obj/nano_module/crew_monitor/crew_monitor + +/mob/living/silicon/ai/proc/init_subsystems() + crew_monitor = new(src) + +/mob/living/silicon/ai/proc/nano_crew_monitor() + set category = "AI Commands" + set name = "Crew Monitor" + if (!crew_monitor) + init_subsystems() + crew_monitor.ui_interact(usr) \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm index 39851507..b9ca25b5 100644 --- a/code/modules/mob/living/silicon/robot/examine.dm +++ b/code/modules/mob/living/silicon/robot/examine.dm @@ -7,6 +7,10 @@ return var/msg = "*---------*\nThis is \icon[src] \a [src][custom_name ? ", [modtype] [braintype]" : ""]!\n" + + msg += "\n" + msg += describe_all_modules() // describe modules + msg += "\n" msg += "" if (src.getBruteLoss()) if (src.getBruteLoss() < 75) diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index 35ce156b..d1b10ccd 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -5,67 +5,110 @@ /mob/living/silicon/robot/get_active_hand() return module_active + + /*-------TODOOOOOOOOOO--------*/ -/mob/living/silicon/robot/proc/uneq_active() - if(isnull(module_active)) - return - if(module_state_1 == module_active) - if(istype(module_state_1,/obj/item/borg/sight)) - sight_mode &= ~module_state_1:sight_mode - if (client) - client.screen -= module_state_1 - contents -= module_state_1 +/mob/living/silicon/robot/proc/uneq_module(obj/item/O,var/display_tool_transfer=TRUE) + if(!O) + return 0 + + if(istype(O,/obj/item/borg/sight)) + var/obj/item/borg/sight/S = O + sight_mode &= ~S.sight_mode + else if(istype(O, /obj/item/device/flashlight)) + var/obj/item/device/flashlight/F = O + if(F.on) + F.on = 0 + F.update_brightness(src) + if(client) + client.screen -= O + contents -= O + if(module) + O.loc = module //Return item to module so it appears in its contents, so it can be taken out again. + + if (!display_tool_transfer) + for(var/mob/M in viewers(src, null)) // show when cyborgs change their modules + if (M == src) + usr << "You retract \icon[O] [O] into your internal tool storage." + else if (M in range(1)) //If someone is standing close enough, they can tell what it is... + M.show_message("[src] retracts \icon[O] [O] into their internal tool storage.") + else //Otherwise they can only see that you've put something back. + M.show_message("[src] retracts a tool into their internal tool storage.") + + if(module_active == O) module_active = null - module_state_1 = null + if(module_state_1 == O) inv1.icon_state = "inv1" - else if(module_state_2 == module_active) - if(istype(module_state_2,/obj/item/borg/sight)) - sight_mode &= ~module_state_2:sight_mode - if (client) - client.screen -= module_state_2 - contents -= module_state_2 - module_active = null - module_state_2 = null + module_state_1 = null + else if(module_state_2 == O) inv2.icon_state = "inv2" - else if(module_state_3 == module_active) - if(istype(module_state_3,/obj/item/borg/sight)) - sight_mode &= ~module_state_3:sight_mode - if (client) - client.screen -= module_state_3 - contents -= module_state_3 - module_active = null + module_state_2 = null + else if(module_state_3 == O) module_state_3 = null inv3.icon_state = "inv3" - updateicon() + + hud_used.update_robot_modules_display() // update the display + + return 1 + + + +/mob/living/silicon/robot/proc/activate_module(var/obj/item/O) + if(!(locate(O) in src.module.modules) && O != src.module.emag) + return + if(activated(O)) + src << "Already activated" + return + var/selected=get_selected_module() // this makes you swap your selected module if you've got one selected + if (selected) + for(var/mob/M in viewers(src, null)) // show when cyborgs change their modules + if (M == src) + usr << "You swap \icon[module_active] [module_active] for \icon[O] [O]." + else if (M in range(1)) //If someone is standing close enough, they can tell what it is... + M.show_message("[src] swaps \icon[module_active] [module_active] for \icon[O] [O].") + else //Otherwise they can only see that you've swapped something. + M.show_message("[src] swaps some of their tools.") + uneq_active(TRUE) + + var/target=(selected) ? selected : first_free_module() // find where we're putting this + if (!target) // if there's nowhere to put it just warn them and kick out + src << "You need to disable a module first!" + return + + switch (target) + if(1) + module_state_1=O + O.screen_loc = inv1.screen_loc + if(2) + module_state_2=O + O.screen_loc = inv2.screen_loc + if(3) + module_state_3=O + O.screen_loc = inv3.screen_loc + + O.layer = 20 // this bit moves the target object into the robot, and moves it's location on screen + contents += O + if(istype(O,/obj/item/borg/sight)) + sight_mode |= module_state_1:sight_mode + + if (selected) // replaces your selection if you're swapping + select_module(selected) + else // only do this if we activated a module but weren't swapping + for(var/mob/M in viewers(src, null)) // show when cyborgs change their modules + if (M == src) + usr << "You retrieve \icon[O] [O] from your internal tool storage." + else if (M in range(1)) //If someone is standing close enough, they can tell what it is... + M.show_message("[src] extends \icon[O] [O] from their internal tool storage.") + else //Otherwise they can only see that you've swapped something. + M.show_message("[src] extends a tool.") + +/mob/living/silicon/robot/proc/uneq_active(var/display_tool_transfer=FALSE) + uneq_module(module_active,display_tool_transfer) /mob/living/silicon/robot/proc/uneq_all() - module_active = null - - if(module_state_1) - if(istype(module_state_1,/obj/item/borg/sight)) - sight_mode &= ~module_state_1:sight_mode - if (client) - client.screen -= module_state_1 - contents -= module_state_1 - module_state_1 = null - inv1.icon_state = "inv1" - if(module_state_2) - if(istype(module_state_2,/obj/item/borg/sight)) - sight_mode &= ~module_state_2:sight_mode - if (client) - client.screen -= module_state_2 - contents -= module_state_2 - module_state_2 = null - inv2.icon_state = "inv2" - if(module_state_3) - if(istype(module_state_3,/obj/item/borg/sight)) - sight_mode &= ~module_state_3:sight_mode - if (client) - client.screen -= module_state_3 - contents -= module_state_3 - module_state_3 = null - inv3.icon_state = "inv3" - updateicon() + uneq_module(module_state_1) + uneq_module(module_state_2) + uneq_module(module_state_3) /mob/living/silicon/robot/proc/activated(obj/item/O) if(module_state_1 == O) @@ -164,6 +207,11 @@ return return + +/mob/living/silicon/robot/proc/deselect_current_module() //deselect current module + deselect_module(get_selected_module()) + + //toggle_module(module) - Toggles the selection of the module slot specified by "module". /mob/living/silicon/robot/proc/toggle_module(var/module) //Module is 1-3 if(module < 1 || module > 3) return @@ -177,23 +225,75 @@ deselect_module(get_selected_module()) //If we can't do select anything, at least deselect the current module. return +/mob/living/silicon/robot/proc/first_active_module() + for (var/slot=0,slot<=3,slot++) + if (module_active(slot)) + return slot + return 0 + +/mob/living/silicon/robot/proc/first_free_module() + for (var/slot=1,slot<=3,slot++) + if (!module_active(slot)) + return slot + return 0 + +/mob/living/silicon/robot/proc/next_slot(var/slot) + if (slot >= 3) + return 1 + return slot+1 + //cycle_modules() - Cycles through the list of selected modules. /mob/living/silicon/robot/proc/cycle_modules() var/slot_start = get_selected_module() - if(slot_start) deselect_module(slot_start) //Only deselect if we have a selected slot. - - var/slot_num - if(slot_start == 0) - slot_num = 1 - slot_start = 2 + if(slot_start) + deselect_module(slot_start) //Only deselect if we have a selected slot. + if(!slot_start) // we did not find a module + select_module(first_active_module()) // try to select the first active module else - slot_num = slot_start + 1 - - while(slot_start != slot_num) //If we wrap around without finding any free slots, just give up. - if(module_active(slot_num)) - select_module(slot_num) - return - slot_num++ - if(slot_num > 3) slot_num = 1 //Wrap around. - + var/slot_num = next_slot(slot_start) + while(slot_start != slot_num) //If we wrap around without finding any free slots, just give up. + if(module_active(slot_num)) + select_module(slot_num) + return + slot_num=next_slot(slot_num) return + + +/mob/living/silicon/robot/key_pressed_v() + uneq_active() + +/mob/living/silicon/robot/key_pressed_c() + deselect_current_module() + +/mob/living/silicon/robot/key_pressed_q() + hud_used.toggle_show_robot_modules() + +/mob/living/silicon/robot/key_pressed_1() + return select_module(1) + +/mob/living/silicon/robot/key_pressed_2() + return select_module(2) + +/mob/living/silicon/robot/key_pressed_3() + return select_module(3) + +/mob/living/silicon/robot/key_pressed_4() + return + + +/mob/living/silicon/robot/proc/describe_module(var/slot) + var/list/index_module=list(module_state_1,module_state_2,module_state_3) + var/result = " Hardpoint [slot] holds " + result += (index_module[slot]) ? "\icon[index_module[slot]] [index_module[slot]]." : "nothing." + result += "\n" + return result + + +/mob/living/silicon/robot/proc/describe_all_modules() + var/result="It has three tool hardpoints.\n" + for (var/x = 1; x <=3; x++) + result+=describe_module(x) + var/selected=get_selected_module() + if (selected) + result+="\nThe activity light on hardpoint [selected] is on.\n" + return result diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index 3913577e..2445aa9a 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -167,8 +167,11 @@ if(copytext(hud.icon_state,1,4) == "hud") //ugly, but icon comparison is worse, I believe client.images.Remove(hud) - var/obj/item/borg/sight/hud/hud = (locate(/obj/item/borg/sight/hud) in src) - if(hud && hud.hud) hud.hud.process_hud(src) + switch(src.sensor_mode) + if (SEC_HUD) + process_sec_hud(src,1) + if (MED_HUD) + process_med_hud(src,1) if (src.healths) if (src.stat != 2) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index bf1532c0..5d70a9c8 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -18,6 +18,9 @@ var/obj/screen/inv1 = null var/obj/screen/inv2 = null var/obj/screen/inv3 = null + + var/shown_robot_modules = 0 //Used to determine whether they have the module menu shown or not + var/obj/screen/robot_modules_background //3 Modules can be activated at any one time. var/obj/item/weapon/robot_module/module = null @@ -73,6 +76,10 @@ add_language("Robot Talk", 1) + robot_modules_background = new() + robot_modules_background.icon_state = "block" + robot_modules_background.layer = 19 //Objects that appear on screen are on layer 20, UI should be just below it. + ident = rand(1, 999) updatename("Default") updateicon() @@ -168,103 +175,44 @@ modules+="Combat" modtype = input("Please, select a module!", "Robot", null, null) in modules - var/module_sprites[0] //Used to store the associations between sprite names and sprite index. - if(module) return switch(modtype) if("Standard") module = new /obj/item/weapon/robot_module/standard(src) - module_sprites["Basic"] = "robot_old" - module_sprites["Android"] = "droid" - module_sprites["Default"] = "robot" - if("Service") module = new /obj/item/weapon/robot_module/butler(src) - module_sprites["Waitress"] = "Service" - module_sprites["Kent"] = "toiletbot" - module_sprites["Bro"] = "Brobot" - module_sprites["Rich"] = "maximillion" - module_sprites["Default"] = "Service2" - if("Clerical") module = new /obj/item/weapon/robot_module/clerical(src) - module_sprites["Waitress"] = "Service" - module_sprites["Kent"] = "toiletbot" - module_sprites["Bro"] = "Brobot" - module_sprites["Rich"] = "maximillion" - module_sprites["Default"] = "Service2" - if("Miner") module = new /obj/item/weapon/robot_module/miner(src) - module.channels = list("Supply" = 1) - if(camera && "Robots" in camera.network) - camera.network.Add("MINE") - module_sprites["Basic"] = "Miner_old" - module_sprites["Advanced Droid"] = "droid-miner" - module_sprites["Treadhead"] = "Miner" - if("Crisis") module = new /obj/item/weapon/robot_module/crisis(src) - module.channels = list("Medical" = 1) - if(camera && "Robots" in camera.network) - camera.network.Add("Medical") - module_sprites["Basic"] = "Medbot" - module_sprites["Standard"] = "surgeon" - module_sprites["Advanced Droid"] = "droid-medical" - module_sprites["Needles"] = "medicalrobot" - if("Surgeon") module = new /obj/item/weapon/robot_module/surgeon(src) - module.channels = list("Medical" = 1) - if(camera && "Robots" in camera.network) - camera.network.Add("Medical") - - module_sprites["Basic"] = "Medbot" - module_sprites["Standard"] = "surgeon" - module_sprites["Advanced Droid"] = "droid-medical" - module_sprites["Needles"] = "medicalrobot" - if("Security") module = new /obj/item/weapon/robot_module/security(src) - module.channels = list("Security" = 1) - module_sprites["Basic"] = "secborg" - module_sprites["Red Knight"] = "Security" - module_sprites["Black Knight"] = "securityrobot" - module_sprites["Bloodhound"] = "bloodhound" - if("Engineering") module = new /obj/item/weapon/robot_module/engineering(src) - module.channels = list("Engineering" = 1) - if(camera && "Robots" in camera.network) - camera.network.Add("Engineering") - module_sprites["Basic"] = "Engineering" - module_sprites["Antique"] = "engineerrobot" - module_sprites["Landmate"] = "landmate" - if("Construction") module = new /obj/item/weapon/robot_module/construction(src) - module.channels = list("Engineering" = 1) - if(camera && "Robots" in camera.network) - camera.network.Add("Engineering") - module_sprites["Basic"] = "Engineering" - module_sprites["Antique"] = "engineerrobot" - module_sprites["Landmate"] = "landmate" - if("Janitor") module = new /obj/item/weapon/robot_module/janitor(src) - module_sprites["Basic"] = "JanBot2" - module_sprites["Mopbot"] = "janitorrobot" - module_sprites["Mop Gear Rex"] = "mopgearrex" - if("Combat") module = new /obj/item/weapon/robot_module/combat(src) - module_sprites["Combat Android"] = "droid-combat" - module.channels = list("Security" = 1) - //languages + // languages module.add_languages(src) + + // cameras + module.add_to_camera_network(src) + + // sensors + module.add_sensor_modification(src) + + // create sprite list + var/list/module_sprites = module.sprites.Copy() //Custom_sprite check and entry if (custom_sprite == 1) @@ -425,6 +373,12 @@ updatehealth() return 1 return 0 + +/mob/living/silicon/robot/proc/sensor_mode() + set name = "Set Sensor Augmentation" + set desc = "Augment visual feed with internal sensor overlays." + set category = "Robot Commands" + toggle_sensor_mode() // this function shows information about the malf_ai gameplay type in the status screen /mob/living/silicon/robot/show_malf_ai() diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 9f4cdb23..e5e529ce 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -6,6 +6,9 @@ item_state = "electronic" flags = FPRINT|TABLEPASS | CONDUCT var/channels = list() + var/camera_network = null + var/sensor_mode = 0 + var/list/sprites = list("Basic"="robot_old") var/list/modules = list() var/obj/item/emag = null var/obj/item/borg/upgrade/jetpack = null @@ -26,11 +29,9 @@ src.modules += new /obj/item/device/flash(src) src.emag = new /obj/item/toy/sword(src) src.emag.name = "Placeholder Emag Item" -// src.jetpack = new /obj/item/toy/sword(src) -// src.jetpack.name = "Placeholder Upgrade Item" return - - + + /obj/item/weapon/robot_module/proc/respawn_consumable(var/mob/living/silicon/robot/R) if(!stacktypes || !stacktypes.len) return @@ -66,9 +67,19 @@ R.add_language("Rootspeak", 0) +/obj/item/weapon/robot_module/proc/add_to_camera_network(var/mob/living/silicon/robot/R) + if (camera_network) + if(R.camera && "Robots" in R.camera.network) + R.camera.network.Add(camera_network) + + +/obj/item/weapon/robot_module/proc/add_sensor_modification(var/mob/living/silicon/robot/R) + R.sensor_mode=sensor_mode + + /obj/item/weapon/robot_module/standard name = "standard robot module" - + sprites=list("Basic" = "robot_old","Android" = "droid", "Default" = "robot") New() src.modules += new /obj/item/device/flashlight(src) src.modules += new /obj/item/device/flash(src) @@ -82,6 +93,13 @@ /obj/item/weapon/robot_module/surgeon name = "surgeon robot module" + sensor_mode=MED_HUD + channels=list("Medical" = 1) + camera_network="Medical" + sprites=list( "Basic" = "Medbot", + "Standard "= "surgeon", + "Advanced Droid" = "droid-medical", + "Needles" = "medicalrobot") stacktypes = list( /obj/item/stack/medical/advanced/bruise_pack = 5, /obj/item/stack/nanopaste = 5 @@ -119,6 +137,13 @@ /obj/item/weapon/robot_module/crisis name = "crisis robot module" + sensor_mode=MED_HUD + channels=list("Medical" = 1) + camera_network="Medical" + sprites=list( "Basic" = "Medbot", + "Standard "= "surgeon", + "Advanced Droid" = "droid-medical", + "Needles" = "medicalrobot") stacktypes = list( /obj/item/stack/medical/ointment = 5, /obj/item/stack/medical/bruise_pack = 5, @@ -128,7 +153,6 @@ New() src.modules += new /obj/item/device/flashlight(src) src.modules += new /obj/item/device/flash(src) - src.modules += new /obj/item/borg/sight/hud/med(src) src.modules += new /obj/item/device/healthanalyzer(src) src.modules += new /obj/item/device/reagent_scanner/adv(src) src.modules += new /obj/item/roller_holder(src) @@ -164,7 +188,11 @@ /obj/item/weapon/robot_module/construction name = "construction robot module" - + channels = list("Engineering" = 1) + camera_network="Engineering" + sprites=list( "Basic" = "Engineering", + "Antique" = "engineerrobot", + "Landmate" = "landmate") stacktypes = list( /obj/item/stack/sheet/metal = 50, /obj/item/stack/sheet/plasteel = 10, @@ -185,7 +213,11 @@ /obj/item/weapon/robot_module/engineering name = "engineering robot module" - + channels = list("Engineering" = 1) + camera_network="Engineering" + sprites=list( "Basic" = "Engineering", + "Antique" = "engineerrobot", + "Landmate" = "landmate") stacktypes = list( /obj/item/stack/sheet/metal = 50, /obj/item/stack/sheet/glass = 50, @@ -233,11 +265,15 @@ /obj/item/weapon/robot_module/security name = "security robot module" - + sensor_mode=SEC_HUD + channels=list("Security" = 1) + sprites = list( "Basic" = "secborg", + "Red Knight" = "Security", + "Black Knight" = "securityrobot", + "Bloodhound" = "bloodhound") New() src.modules += new /obj/item/device/flashlight(src) src.modules += new /obj/item/device/flash(src) - src.modules += new /obj/item/borg/sight/hud/sec(src) src.modules += new /obj/item/weapon/handcuffs/cyborg(src) src.modules += new /obj/item/weapon/melee/baton/loaded(src) src.modules += new /obj/item/weapon/gun/energy/taser/cyborg(src) @@ -262,7 +298,9 @@ /obj/item/weapon/robot_module/janitor name = "janitorial robot module" - + sprites=list( "Basic" = "JanBot2", + "Mopbot" = "janitorrobot", + "Mop Gear Rex" = "mopgearrex" ) New() src.modules += new /obj/item/device/flashlight(src) src.modules += new /obj/item/device/flash(src) @@ -285,7 +323,11 @@ /obj/item/weapon/robot_module/butler name = "service robot module" - + sprites = list( "Waitress" = "Service", + "Kent" = "toiletbot", + "Bro" = "Brobot", + "Rich" = "maximillion", + "Default" = "Service2") New() src.modules += new /obj/item/device/flashlight(src) src.modules += new /obj/item/device/flash(src) @@ -326,7 +368,11 @@ /obj/item/weapon/robot_module/clerical name = "clerical robot module" - + sprites = list( "Waitress" = "Service", + "Kent" = "toiletbot", + "Bro" = "Brobot", + "Rich" = "maximillion", + "Default" = "Service2") New() src.modules += new /obj/item/device/flashlight(src) src.modules += new /obj/item/device/flash(src) @@ -354,7 +400,10 @@ /obj/item/weapon/robot_module/miner name = "miner robot module" - + channels=list("Supply" = 1) + sprites = list( "Basic" = "Miner_old", + "Advanced Droid" = "droid-miner", + "Treadhead" = "Miner") New() src.modules += new /obj/item/device/flashlight(src) src.modules += new /obj/item/device/flash(src) @@ -380,7 +429,8 @@ /obj/item/weapon/robot_module/combat name = "combat robot module" - + channels=list("Security" = 1) + sprites = list("Combat Android" = "droid-combat") New() src.modules += new /obj/item/device/flashlight(src) src.modules += new /obj/item/device/flash(src) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index ca4fadba..dd7bb964 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -1,3 +1,6 @@ +#define SEC_HUD 1 //Security HUD mode +#define MED_HUD 2 //Medical HUD mode + /mob/living/silicon gender = NEUTER voice_name = "synthesized voice" @@ -11,6 +14,7 @@ var/speak_statement = "states" var/speak_exclamation = "declares" var/speak_query = "queries" + var/sensor_mode = 0 //Determines the current HUD. var/pose //Yes, now AIs can pose too. var/obj/item/device/camera/siliconcam/aiCamera = null //photography var/local_transmit //If set, can only speak to others of the same type within a short range. @@ -204,4 +208,17 @@ flavor_text = copytext(sanitize(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text), 1) /mob/living/silicon/binarycheck() - return 1 \ No newline at end of file + return 1 + +/mob/living/silicon/proc/toggle_sensor_mode() + var/sensor_type = input("Please select sensor type.", "Sensor Integration", null) in list("Security", "Medical","Disable") + switch(sensor_type) + if ("Security") + sensor_mode = SEC_HUD + src << "Security records overlay enabled." + if ("Medical") + sensor_mode = MED_HUD + src << "Life signs monitor overlay enabled." + if ("Disable") + sensor_mode = 0 + src << "Sensor augmentations disabled." diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 5e183dcc..27ac10e4 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -394,6 +394,65 @@ var/list/intents = list("help","disarm","grab","hurt") if(2) return "grab" else return "hurt" +/mob/proc/key_pressed_c() + return +/mob/proc/key_pressed_q() + return +/mob/proc/key_pressed_v() + return + +/client/verb/key_pressed_c() + set hidden = 1 + set name = "key-pressed-c" + if (mob) + mob:key_pressed_c() + +/client/verb/key_pressed_q() + set hidden = 1 + set name = "key-pressed-q" + if (mob) + mob:key_pressed_q() + +/client/verb/key_pressed_v() + set hidden = 1 + set name = "key-pressed-v" + if (mob) + mob:key_pressed_v() + +/mob/proc/key_pressed_1() + return a_intent_change("help") +/mob/proc/key_pressed_2() + return a_intent_change("disarm") +/mob/proc/key_pressed_3() + return a_intent_change("grab") +/mob/proc/key_pressed_4() + return a_intent_change("hurt") + +/client/verb/key_pressed_1() + set hidden = 1 + set name = "key-pressed-1" + if (mob) + mob:key_pressed_1() + +/client/verb/key_pressed_2() + set hidden = 1 + set name = "key-pressed-2" + if (mob) + mob:key_pressed_2() + +/client/verb/key_pressed_3() + set hidden = 1 + set name = "key-pressed-3" + if (mob) + mob:key_pressed_3() + +/client/verb/key_pressed_4() + set hidden = 1 + set name = "key-pressed-4" + if (mob) + mob:key_pressed_4() + + //change a mob's act-intent. Input the intent as a string such as "help" or use "right"/"left /mob/verb/a_intent_change(input as text) set name = "a-intent" diff --git a/icons/mob/screen_ai.dmi b/icons/mob/screen_ai.dmi new file mode 100644 index 00000000..ddc08ed4 Binary files /dev/null and b/icons/mob/screen_ai.dmi differ diff --git a/interface/skin.dmf b/interface/skin.dmf index d0a59f86..b71f4dc6 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -243,31 +243,43 @@ macro "hotkeymode" is-disabled = false elem name = "1" - command = "a-intent help" + command = "key-pressed-1" is-disabled = false elem name = "CTRL+1" command = "a-intent help" is-disabled = false + elem + name = "SHIFT+1" + command = "shift-1-key-pressed" + is-disabled = false elem name = "2" - command = "a-intent disarm" + command = "key-pressed-2" is-disabled = false elem name = "CTRL+2" command = "a-intent disarm" is-disabled = false + elem + name = "SHIFT+2" + command = "shift-2-key-pressed" + is-disabled = false elem name = "3" - command = "a-intent grab" + command = "key-pressed-3" is-disabled = false elem name = "CTRL+3" command = "a-intent grab" is-disabled = false + elem + name = "SHIFT+3" + command = "shift-3-key-pressed" + is-disabled = false elem name = "4" - command = "a-intent hurt" + command = "key-pressed-4" is-disabled = false elem name = "CTRL+4" @@ -281,6 +293,10 @@ macro "hotkeymode" name = "CTRL+A+REP" command = ".west" is-disabled = false + elem + name = "C" + command = "key-pressed-c" + is-disabled = false elem name = "D+REP" command = ".east" @@ -323,11 +339,11 @@ macro "hotkeymode" is-disabled = false elem name = "Q" - command = ".northwest" + command = "key-pressed-q" is-disabled = false elem name = "CTRL+Q" - command = ".northwest" + command = "key-pressed-q" is-disabled = false elem name = "R" @@ -349,6 +365,10 @@ macro "hotkeymode" name = "T" command = "say" is-disabled = false + elem "Toggle Module" + name = "V" + command = "key-pressed-v" + is-disabled = false elem "w_key" name = "W+REP" command = ".north"