diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 7d8b6c2279b..c62380e6d66 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -122,9 +122,6 @@ else overlays -= "eyes" -/mob/living/silicon/robot/drone/choose_icon() - return - /mob/living/silicon/robot/drone/pick_module() return diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 238c53a2d52..05f21e4c5ed 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -66,7 +66,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( /// Value incoming burn damage to borgs is multiplied by. var/burn_mod = 1 - var/list/force_modules = list() + var/list/force_modules var/allow_rename = TRUE var/weapons_unlock = FALSE var/static_radio_channels = FALSE @@ -215,15 +215,17 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( camera.c_tag = newname //Check for custom sprite - if(!custom_sprite) - if(ckey in GLOB.configuration.custom_sprites.cyborg_ckeys) - custom_sprite = TRUE + check_custom_sprite() if(mmi && mmi.brainmob) mmi.brainmob.name = newname return 1 +/mob/living/silicon/robot/proc/check_custom_sprite() + if(!custom_sprite && (ckey in GLOB.configuration.custom_sprites.cyborg_ckeys)) + custom_sprite = TRUE + /mob/living/silicon/robot/proc/get_default_name(prefix as text) if(prefix) @@ -306,132 +308,202 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( /mob/living/silicon/robot/proc/pick_module() if(module) return - var/list/modules = list("Engineering", "Medical", "Miner", "Janitor", "Service") - if(islist(force_modules) && force_modules.len) - modules = force_modules.Copy() - if(mmi != null && mmi.alien) - modules = list("Hunter") - modtype = input("Please, select a module!", "Robot", null, null) as null|anything in modules - if(!modtype) + // Pick a module type + var/selected_module = show_radial_menu(src, src, get_module_types(), radius = 42) + if(!selected_module || module) return - designation = modtype - var/module_sprites[0] //Used to store the associations between sprite names and sprite index. - - if(module) + // Pick a sprite + var/module_sprites = get_module_sprites(selected_module) + var/selected_sprite = show_radial_menu(src, src, module_sprites, radius = 42) + if(!selected_sprite) return - switch(modtype) - if("Service") - module = new /obj/item/robot_module/butler(src) - module.channels = list("Service" = 1) - module_sprites["Waitress"] = "Service" - module_sprites["Kent"] = "toiletbot" - module_sprites["Bro"] = "Brobot" - module_sprites["Rich"] = "maximillion" - module_sprites["Default"] = "Service2" - module_sprites["Standard"] = "Standard-Serv" - module_sprites["Noble-SRV"] = "Noble-SRV" - module_sprites["Cricket"] = "Cricket-SERV" - see_reagents = TRUE +// Now actually set the module and sprites + initialize_module(selected_module, selected_sprite, module_sprites) - if("Miner") - module = new /obj/item/robot_module/miner(src) - module.channels = list("Supply" = 1) - if(camera && ("Robots" in camera.network)) - camera.network.Add("Mining Outpost") - module_sprites["Basic"] = "Miner_old" - module_sprites["Advanced Droid"] = "droid-miner" - module_sprites["Treadhead"] = "Miner" - module_sprites["Standard"] = "Standard-Mine" - module_sprites["Noble-DIG"] = "Noble-DIG" - module_sprites["Cricket"] = "Cricket-MINE" - module_sprites["Lavaland"] = "lavaland" +/** + * Returns a list of choosable module types, associated with the module icon for the radial menu. + * + * Key: Module name | Value: Module 'icon' + * + * By default this returns the Engineering, Janitor, Medical, Mining, and Service modules. + * If there are any [/mob/living/silicon/robot/var/force_modules] set, then they are returned instead. + * If the MMI has a xenomorph brain in it ([/obj/item/mmi/var/alien]), then only the "Hunter" module is returned. + */ +/mob/living/silicon/robot/proc/get_module_types() + var/static/list/standard_modules = list( + "Engineering" = image('icons/mob/robots.dmi', "engi-radial"), + "Janitor" = image('icons/mob/robots.dmi', "jan-radial"), + "Medical" = image('icons/mob/robots.dmi', "med-radial"), + "Mining" = image('icons/mob/robots.dmi', "mining-radial"), + "Service" = image('icons/mob/robots.dmi', "serv-radial")) + var/static/list/special_modules = list( + "Combat" = image('icons/mob/robots.dmi', "security-radial"), + "Security" = image('icons/mob/robots.dmi', "security-radial"), + "Destroyer" = image('icons/mob/robots.dmi', "droidcombat")) + if(mmi?.alien) + return list("Hunter" = image('icons/mob/robots.dmi', "xeno-radial")) + + // Return a list of `force_modules`, with the associated images from the other lists. + if(length(force_modules)) + return (standard_modules + special_modules) & force_modules + + return standard_modules + +/** + * Returns an associative list of possible borg sprites based on the `selected_module`. + * + * Key: Sprite name | Value: Sprite icon + * + * Arguments: + * * selected_module - The chosen cyborg module to get the sprites for. + */ +/mob/living/silicon/robot/proc/get_module_sprites(selected_module) + var/list/module_sprites + switch(selected_module) + if("Engineering") + module_sprites = list( + "Basic" = image('icons/mob/robots.dmi', "Engineering"), + "Antique" = image('icons/mob/robots.dmi', "engineerrobot"), + "Landmate" = image('icons/mob/robots.dmi', "landmate"), + "Standard" = image('icons/mob/robots.dmi', "Standard-Engi"), + "Noble-ENG" = image('icons/mob/robots.dmi', "Noble-ENG"), + "Cricket" = image('icons/mob/robots.dmi', "Cricket-ENGI") + ) + if("Janitor") + module_sprites = list( + "Basic" = image('icons/mob/robots.dmi', "JanBot2"), + "Mopbot" = image('icons/mob/robots.dmi', "janitorrobot"), + "Mop Gear Rex" = image('icons/mob/robots.dmi', "mopgearrex"), + "Standard" = image('icons/mob/robots.dmi', "Standard-Jani"), + "Noble-CLN" = image('icons/mob/robots.dmi', "Noble-CLN"), + "Cricket" = image('icons/mob/robots.dmi', "Cricket-JANI") + ) if("Medical") - module = new /obj/item/robot_module/medical(src) - module.channels = list("Medical" = 1) - if(camera && ("Robots" in camera.network)) - camera.network.Add("Medical") - module_sprites["Basic"] = "Medbot" - module_sprites["Surgeon"] = "surgeon" - module_sprites["Advanced Droid"] = "droid-medical" - module_sprites["Needles"] = "medicalrobot" - module_sprites["Standard"] = "Standard-Medi" - module_sprites["Noble-MED"] = "Noble-MED" - module_sprites["Cricket"] = "Cricket-MEDI" - status_flags &= ~CANPUSH - see_reagents = TRUE - + module_sprites = list( + "Basic" = image('icons/mob/robots.dmi', "Medbot"), + "Surgeon" = image('icons/mob/robots.dmi', "surgeon"), + "Advanced Droid" = image('icons/mob/robots.dmi', "droid-medical"), + "Needles" = image('icons/mob/robots.dmi', "medicalrobot"), + "Standard" = image('icons/mob/robots.dmi', "Standard-Medi"), + "Noble-MED" = image('icons/mob/robots.dmi', "Noble-MED"), + "Cricket" = image('icons/mob/robots.dmi', "Cricket-MEDI") + ) + if("Mining") + module_sprites = list( + "Basic" = image('icons/mob/robots.dmi', "Miner_old"), + "Advanced Droid" = image('icons/mob/robots.dmi', "droid-miner"), + "Treadhead" = image('icons/mob/robots.dmi', "Miner"), + "Standard" = image('icons/mob/robots.dmi', "Standard-Mine"), + "Noble-DIG" = image('icons/mob/robots.dmi', "Noble-DIG"), + "Cricket" = image('icons/mob/robots.dmi', "Cricket-MINE"), + "Lavaland" = image('icons/mob/robots.dmi', "lavaland") + ) + if("Service") + module_sprites = list( + "Waitress" = image('icons/mob/robots.dmi', "Service"), + "Kent" = image('icons/mob/robots.dmi', "toiletbot"), + "Bro" = image('icons/mob/robots.dmi', "Brobot"), + "Rich" = image('icons/mob/robots.dmi', "maximillion"), + "Default" = image('icons/mob/robots.dmi', "Service2"), + "Standard" = image('icons/mob/robots.dmi', "Standard-Serv"), + "Noble-SRV" = image('icons/mob/robots.dmi', "Noble-SRV"), + "Cricket" = image('icons/mob/robots.dmi', "Cricket-SERV") + ) + if("Combat") + module_sprites = list( + "Combat" = image('icons/mob/robots.dmi', "ertgamma") + ) if("Security") - module = new /obj/item/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" - module_sprites["Standard"] = "Standard-Secy" - module_sprites["Noble-SEC"] = "Noble-SEC" - module_sprites["Cricket"] = "Cricket-SEC" - status_flags &= ~CANPUSH + module_sprites = list( + "Basic" = image('icons/mob/robots.dmi', "secborg"), + "Red Knight" = image('icons/mob/robots.dmi', "Security"), + "Black Knight" = image('icons/mob/robots.dmi', "securityrobot"), + "Bloodhound" = image('icons/mob/robots.dmi', "bloodhound"), + "Standard" = image('icons/mob/robots.dmi', "Standard-Secy"), + "Noble-SEC" = image('icons/mob/robots.dmi', "Noble-SEC"), + "Cricket" = image('icons/mob/robots.dmi', "Cricket-SEC") + ) + if("Destroyer") //for Adminbus presumably + module_sprites = list( + "Destroyer" = image('icons/mob/robots.dmi', "droidcombat") + ) + if("Hunter") + module_sprites = list( + "Xeno-Hu" = image('icons/mob/robots.dmi', "xenoborg-state-a") + ) + if(custom_sprite && check_sprite("[ckey]-[selected_module]")) + module_sprites["Custom"] = image('icons/mob/custom_synthetic/custom-synthetic.dmi', "[ckey]-[selected_module]") + + return module_sprites + +/** + * Sets up the module items and sprites for the cyborg module chosen in `pick_module()`. + * + * Arguments: + * * selected_module - The name of the module chosen by the player in the previous procs. + * * selected_sprite - The name of the sprite chosen by the player in the previous procs. + * * module_sprites - The list of sprites possible for the given module. Used to transfer the `icon` and `icon_state` variables to the player. + */ +/mob/living/silicon/robot/proc/initialize_module(selected_module, selected_sprite, list/module_sprites) + switch(selected_module) if("Engineering") module = new /obj/item/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" - module_sprites["Standard"] = "Standard-Engi" - module_sprites["Noble-ENG"] = "Noble-ENG" - module_sprites["Cricket"] = "Cricket-ENGI" + camera.network += "Engineering" magpulse = TRUE - if("Janitor") module = new /obj/item/robot_module/janitor(src) module.channels = list("Service" = 1) - module_sprites["Basic"] = "JanBot2" - module_sprites["Mopbot"] = "janitorrobot" - module_sprites["Mop Gear Rex"] = "mopgearrex" - module_sprites["Standard"] = "Standard-Jani" - module_sprites["Noble-CLN"] = "Noble-CLN" - module_sprites["Cricket"] = "Cricket-JANI" - - if("Destroyer") // Rolling Borg - module = new /obj/item/robot_module/destroyer(src) - module.channels = list("Security" = 1) - icon_state = "droidcombat" + if("Medical") + module = new /obj/item/robot_module/medical(src) + module.channels = list("Medical" = 1) + if(camera && ("Robots" in camera.network)) + camera.network += "Medical" status_flags &= ~CANPUSH - - if("Combat") // Gamma ERT + see_reagents = TRUE + if("Mining") + module = new /obj/item/robot_module/miner(src) + module.channels = list("Supply" = 1) + if(camera && ("Robots" in camera.network)) + camera.network += "Mining Outpost" + if("Service") + module = new /obj/item/robot_module/butler(src) + module.channels = list("Service" = 1) + see_reagents = TRUE + if(selected_sprite == "Bro") + module.module_type = "Brobot" + if("Combat") module = new /obj/item/robot_module/combat(src) - icon_state = "ertgamma" status_flags &= ~CANPUSH - + if("Security") + module = new /obj/item/robot_module/security(src) + status_flags &= ~CANPUSH if("Hunter") module = new /obj/item/robot_module/alien/hunter(src) - icon_state = "xenoborg-state-a" - modtype = "Xeno-Hu" - //languages + if(!module) + return FALSE + modtype = selected_module + designation = selected_module module.add_languages(src) - //subsystems module.add_subsystems_and_actions(src) - - //Custom_sprite check and entry - if(custom_sprite && check_sprite("[ckey]-[modtype]")) - module_sprites["Custom"] = "[src.ckey]-[modtype]" - - hands.icon_state = lowertext(module.module_type) - SSblackbox.record_feedback("tally", "cyborg_modtype", 1, "[lowertext(modtype)]") - rename_character(real_name, get_default_name()) - - if(modtype == "Medical" || modtype == "Security" || modtype == "Combat") - status_flags &= ~CANPUSH - - choose_icon(6,module_sprites) if(!static_radio_channels) radio.config(module.channels) + rename_character(real_name, get_default_name()) + + var/image/sprite_image = module_sprites[selected_sprite] + var/list/names = splittext(selected_sprite, "-") + icon = sprite_image.icon + icon_state = sprite_image.icon_state + custom_panel = trim(names[1]) + + update_module_icon() + update_icons() + SSblackbox.record_feedback("tally", "cyborg_modtype", 1, "[lowertext(selected_module)]") notify_ai(2) /mob/living/silicon/robot/proc/reset_module() @@ -454,6 +526,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( languages = list() speech_synthesizer_langs = list() radio.recalculateChannels() + custom_panel = null update_icons() update_headlamp() @@ -1216,48 +1289,6 @@ GLOBAL_LIST_INIT(robot_verbs_default, list( else REMOVE_TRAITS_IN(src, LOCKDOWN_TRAIT) -/mob/living/silicon/robot/proc/choose_icon(triesleft, list/module_sprites) - - if(triesleft<1 || !module_sprites.len) - return - else - triesleft-- - - var/icontype - lockcharge = 1 //Locks borg until it select an icon to avoid secborgs running around with a standard sprite - icontype = input("Select an icon! [triesleft ? "You have [triesleft] more chances." : "This is your last try."]", "Robot", null, null) in module_sprites - - if(icontype) - if(icontype == "Custom") - icon = 'icons/mob/custom_synthetic/custom-synthetic.dmi' - else - icon = 'icons/mob/robots.dmi' - icon_state = module_sprites[icontype] - if(icontype == "Bro") - module.module_type = "Brobot" - update_module_icon() - lockcharge = null - var/list/names = splittext(icontype, "-") - custom_panel = trim(names[1]) - else - to_chat(src, "Something is badly wrong with the sprite selection. Harass a coder.") - icon_state = module_sprites[1] - lockcharge = null - return - - update_icons() - - if(triesleft >= 1) - var/choice = input("Look at your icon - is this what you want?") in list("Yes","No") - if(choice=="No") - choose_icon(triesleft, module_sprites) - return - else - triesleft = 0 - return - else - to_chat(src, "Your icon has been set. You now require a module reset to change it.") - /mob/living/silicon/robot/proc/notify_ai(notifytype, oldname, newname) if(!connected_ai) return diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 10abc60bbcf..11fc6bde535 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -107,6 +107,7 @@ O.update_pipe_vision() + O.check_custom_sprite() O.Namepick() INVOKE_ASYNC(GLOBAL_PROC, .proc/qdel, src) // To prevent the proc from returning null. diff --git a/icons/mob/custom_synthetic/custom-synthetic.dmi b/icons/mob/custom_synthetic/custom-synthetic.dmi index c937b8882e7..6b9f356f20a 100644 Binary files a/icons/mob/custom_synthetic/custom-synthetic.dmi and b/icons/mob/custom_synthetic/custom-synthetic.dmi differ diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi index 977703020c8..f822eef096b 100644 Binary files a/icons/mob/robots.dmi and b/icons/mob/robots.dmi differ