diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 908102b8a06..275b0b26951 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -299,22 +299,59 @@ var/list/ai_verbs_default = list(
for(var/i = 1 to Entry.len)
Entry[i] = trim(Entry[i])
- if(Entry.len < 2)
+ if(Entry.len < 2 || Entry[1] != "ai") //ignore incorrectly formatted entries or entries that aren't marked for AI
continue
- if(Entry.len < 3 && Entry[1] == ckey && Entry[2] == real_name)
- custom_sprite = 1 //They're in the list? Custom sprite time
- icon = 'icons/mob/custom-synthetic.dmi'
+ if(Entry[2] == ckey) //They're in the list? Custom sprite time, var and icon change required
+ custom_sprite = 1
+ var/display_choices = list(
+ "Monochrome",
+ "Blue",
+ "Clown",
+ "Inverted",
+ "Text",
+ "Smiley",
+ "Angry",
+ "Dorf",
+ "Matrix",
+ "Bliss",
+ "Firewall",
+ "Green",
+ "Red",
+ "Static",
+ "Triumvirate",
+ "Triumvirate Static",
+ "Red October",
+ "Sparkles",
+ "ANIMA",
+ "President",
+ "NT",
+ "NT2",
+ "Rainbow",
+ "Angel",
+ "Heartline",
+ "Hades",
+ "Helios",
+ "Syndicat Meow",
+ "Too Deep",
+ "Goon",
+ "Murica",
+ "Fuzzy",
+ "Glitchman",
+ "House",
+ "Database"
+ )
+ if(custom_sprite)
+ display_choices += "Custom"
//if(icon_state == initial(icon_state))
var/icontype = ""
- if(custom_sprite == 1)
- icontype = ("Custom")//automagically selects custom sprite if one is available
- else
- icontype = input("Select an icon!", "AI", null, null) in list("Monochrome", "Blue", "Clown", "Inverted", "Text", "Smiley", "Angry", "Dorf", "Matrix", "Bliss", "Firewall", "Green", "Red", "Static", "Triumvirate", "Triumvirate Static", "Red October", "Sparkles", "ANIMA", "President", "NT", "NT2", "Rainbow", "Angel", "Heartline", "Hades", "Helios", "Syndicat Meow", "Too Deep", "Goon", "Murica", "Fuzzy", "Glitchman", "House", "Database")
+ icontype = input("Select an icon!", "AI", null, null) in display_choices
+ icon = 'icons/mob/AI.dmi' //reset this in case we were on a custom sprite and want to change to a standard one
switch(icontype)
if("Custom")
+ icon = 'icons/mob/custom_synthetic/custom-synthetic.dmi' //set this here so we can use the custom_sprite
icon_state = "[ckey]-ai"
if("Clown")
icon_state = "ai-clown"
@@ -859,10 +896,10 @@ var/list/ai_verbs_default = list(
for(var/i = 1 to Entry.len)
Entry[i] = trim(Entry[i])
- if(Entry.len < 3)
+ if(Entry.len < 2 || Entry[1] != "hologram")
continue
- if (Entry[1] == ckey && Entry[2] == real_name && Entry[3] == "Hologram") //Custom holograms
+ if (Entry[2] == ckey) //Custom holograms
custom_hologram = 1 // option is given in hologram menu
var/input
@@ -971,10 +1008,10 @@ var/list/ai_verbs_default = list(
if("ancient machine")
holo_icon = getHologramIcon(icon('icons/mob/ancient_machine.dmi', "ancient_machine"))
if("custom")
- if("[ckey]-ai-holo" in icon_states('icons/mob/custom-synthetic.dmi'))
- holo_icon = getHologramIcon(icon('icons/mob/custom-synthetic.dmi', "[ckey]-ai-holo"))
- else if("[ckey]-ai-holo" in icon_states('icons/mob/custom-synthetic64.dmi'))
- holo_icon = getHologramIcon(icon('icons/mob/custom-synthetic64.dmi', "[ckey]-ai-holo"))
+ if("[ckey]-ai-holo" in icon_states('icons/mob/custom_synthetic/custom-synthetic.dmi'))
+ holo_icon = getHologramIcon(icon('icons/mob/custom_synthetic/custom-synthetic.dmi', "[ckey]-ai-holo"))
+ else if("[ckey]-ai-holo" in icon_states('icons/mob/custom_synthetic/custom-synthetic64.dmi'))
+ holo_icon = getHologramIcon(icon('icons/mob/custom_synthetic/custom-synthetic64.dmi', "[ckey]-ai-holo"))
else
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo1"))
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 125eb110c66..ecd30b18c9a 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -81,6 +81,7 @@
var/translator_on = 0 // keeps track of the translator module
var/current_pda_messaging = null
+ var/custom_sprite = 0
/mob/living/silicon/pai/New(var/obj/item/device/paicard)
loc = paicard
@@ -394,17 +395,47 @@
set category = "pAI Commands"
set name = "Choose Chassis"
+ var/list/my_choices = list()
var/choice
var/finalized = "No"
+
+ //check for custom_sprite
+ if(!custom_sprite)
+ var/file = file2text("config/custom_sprites.txt")
+ var/lines = splittext(file, "\n")
+
+ for(var/line in lines)
+ // split & clean up
+ var/list/Entry = splittext(line, ":")
+ for(var/i = 1 to Entry.len)
+ Entry[i] = trim(Entry[i])
+
+ if(Entry.len < 2 || Entry[1] != "pai") //ignore incorrectly formatted entries or entries that aren't marked for pAI
+ continue
+
+ if(Entry[2] == ckey) //They're in the list? Custom sprite time, var and icon change required
+ custom_sprite = 1
+ my_choices["Custom"] = "[ckey]-pai"
+
+ my_choices = possible_chassis.Copy()
+ if(custom_sprite)
+ my_choices["Custom"] = "[ckey]-pai"
+
+ if(loc == card) //don't let them continue in card form, since they won't be able to actually see their new mobile form sprite.
+ to_chat(src, "You must be in your mobile form to reconfigure your chassis.")
+ return
+
while(finalized == "No" && client)
-
- choice = input(usr,"What would you like to use for your mobile chassis icon? This decision can only be made once.") as null|anything in possible_chassis
+ choice = input(usr,"What would you like to use for your mobile chassis icon? This decision can only be made once.") as null|anything in my_choices
if(!choice) return
-
- icon_state = possible_chassis[choice]
+ if(choice == "Custom")
+ icon = 'icons/mob/custom_synthetic/custom-synthetic.dmi'
+ else
+ icon = 'icons/mob/pai.dmi'
+ icon_state = my_choices[choice]
finalized = alert("Look at your sprite. Is this what you wish to use?",,"No","Yes")
- chassis = possible_chassis[choice]
+ chassis = my_choices[choice]
verbs -= /mob/living/silicon/pai/proc/choose_chassis
/mob/living/silicon/pai/proc/choose_verbs()
@@ -562,15 +593,23 @@
// Handle being picked up.
-/mob/living/silicon/pai/get_scooped(var/mob/living/carbon/grabber)
+/mob/living/silicon/pai/get_scooped(mob/living/carbon/grabber)
var/obj/item/weapon/holder/H = ..()
if(!istype(H))
return
if(resting)
icon_state = "[chassis]"
resting = 0
- H.icon_state = "pai-[icon_state]"
- H.item_state = "pai-[icon_state]"
+ if(custom_sprite)
+ H.icon = 'icons/mob/custom_synthetic/custom-synthetic.dmi'
+ H.icon_override = 'icons/mob/custom_synthetic/custom_head.dmi'
+ H.lefthand_file = 'icons/mob/custom_synthetic/custom_lefthand.dmi'
+ H.righthand_file = 'icons/mob/custom_synthetic/custom_righthand.dmi'
+ H.icon_state = "[icon_state]"
+ H.item_state = "[icon_state]_hand"
+ else
+ H.icon_state = "pai-[icon_state]"
+ H.item_state = "pai-[icon_state]"
grabber.put_in_active_hand(H)//for some reason unless i call this it dosen't work
grabber.update_inv_l_hand()
grabber.update_inv_r_hand()
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index 14e05f0c7be..2838dbcf850 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -281,7 +281,7 @@
if(!player) return
- src.ckey = player.ckey
+ ckey = player.ckey
if(player.mob && player.mob.mind)
player.mob.mind.transfer_to(src)
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm
index d450d508bd3..2ee6eeb9f53 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_abilities.dm
@@ -47,4 +47,55 @@
if(M.a_intent == I_HELP)
get_scooped(M)
- ..()
\ No newline at end of file
+ ..()
+
+/mob/living/silicon/robot/drone/verb/customize()
+ set name = "Customize Chassis"
+ set desc = "Reconfigure your chassis into a customized version."
+ set category = "Drone"
+
+ if(!custom_sprite) //Check to see if custom sprite time, checking the appopriate file to change a var
+ var/file = file2text("config/custom_sprites.txt")
+ var/lines = splittext(file, "\n")
+
+ for(var/line in lines)
+ // split & clean up
+ var/list/Entry = splittext(line, ":")
+ for(var/i = 1 to Entry.len)
+ Entry[i] = trim(Entry[i])
+
+ if(Entry.len < 2 || Entry[1] != "drone")
+ continue
+
+ if (Entry[2] == ckey) //Custom holograms
+ custom_sprite = 1 // option is given in hologram menu
+
+ if(!custom_sprite)
+ to_chat(src, "Error 404: Custom chassis not found. Revoking customization option.")
+ else
+ icon = 'icons/mob/custom_synthetic/custom-synthetic.dmi'
+ icon_state = "[ckey]-drone"
+ to_chat(src, "You reconfigure your chassis and improve the station through your new aesthetics.")
+ verbs -= /mob/living/silicon/robot/drone/verb/customize
+
+/mob/living/silicon/robot/drone/get_scooped(mob/living/carbon/grabber)
+ var/obj/item/weapon/holder/H = ..()
+ if(!istype(H))
+ return
+ if(resting)
+ resting = 0
+ if(custom_sprite)
+ H.icon = 'icons/mob/custom_synthetic/custom-synthetic.dmi'
+ H.icon_override = 'icons/mob/custom_synthetic/custom_head.dmi'
+ H.lefthand_file = 'icons/mob/custom_synthetic/custom_lefthand.dmi'
+ H.righthand_file = 'icons/mob/custom_synthetic/custom_righthand.dmi'
+ H.icon_state = "[icon_state]"
+ H.item_state = "[icon_state]_hand"
+ else
+ H.icon_state = "drone"
+ H.item_state = "drone"
+ grabber.put_in_active_hand(H)//for some reason unless i call this it dosen't work
+ grabber.update_inv_l_hand()
+ grabber.update_inv_r_hand()
+
+ return H
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 8ca615ae9b0..3cc383e523e 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -180,16 +180,15 @@ var/list/robot_verbs_default = list(
for(var/line in lines)
// split & clean up
- var/list/Entry = splittext(line, ";")
+ var/list/Entry = splittext(line, ":")
for(var/i = 1 to Entry.len)
Entry[i] = trim(Entry[i])
- if(Entry.len < 2)
- continue;
+ if(Entry.len < 2 || Entry[1] != "cyborg") //ignore incorrectly formatted entries or entries that aren't marked for cyborg
+ continue
- if(Entry[1] == src.ckey && Entry[2] == src.real_name) //They're in the list? Custom sprite time, var and icon change required
+ if(Entry[2] == ckey) //They're in the list? Custom sprite time, var and icon change required
custom_sprite = 1
- icon = 'icons/mob/custom-synthetic.dmi'
return 1
@@ -1252,15 +1251,14 @@ var/list/robot_verbs_default = list(
triesleft--
var/icontype
-
- if(custom_sprite == 1)
- icontype = "Custom"
- triesleft = 0
- else
- 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
+ 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"
diff --git a/config/example/custom_sprites.txt b/config/example/custom_sprites.txt
index db3930a4ae2..471764270d4 100644
--- a/config/example/custom_sprites.txt
+++ b/config/example/custom_sprites.txt
@@ -1 +1,5 @@
-ckey-state
\ No newline at end of file
+Each entry should be composed of 2 parts, divided by a colon (:) with no spaces, in order to work. Failure to do so will result in that entry being disregarded by the code.
+- The first part should be either "cyborg", "ai", "hologram", "pai", or "drone". This tells the code what type of custom sprite this entry is for. The "ai" option is for AI core displays, while "hologram" is for AI hologram projections.
+- The second part should be the ckey of the player this entry is for. This tells the code who it works for and also is used to retrieve the proper sprite for them to use.
+
+example:example
\ No newline at end of file
diff --git a/icons/mob/custom-synthetic.dmi b/icons/mob/custom-synthetic.dmi
deleted file mode 100644
index 0434efd900f..00000000000
Binary files a/icons/mob/custom-synthetic.dmi and /dev/null differ
diff --git a/icons/mob/custom_synthetic/custom-synthetic.dmi b/icons/mob/custom_synthetic/custom-synthetic.dmi
new file mode 100644
index 00000000000..29917049c85
Binary files /dev/null and b/icons/mob/custom_synthetic/custom-synthetic.dmi differ
diff --git a/icons/mob/custom-synthetic64.dmi b/icons/mob/custom_synthetic/custom-synthetic64.dmi
similarity index 100%
rename from icons/mob/custom-synthetic64.dmi
rename to icons/mob/custom_synthetic/custom-synthetic64.dmi
diff --git a/icons/mob/custom_synthetic/custom_head.dmi b/icons/mob/custom_synthetic/custom_head.dmi
new file mode 100644
index 00000000000..76ffcedcc82
Binary files /dev/null and b/icons/mob/custom_synthetic/custom_head.dmi differ
diff --git a/icons/mob/custom_synthetic/custom_lefthand.dmi b/icons/mob/custom_synthetic/custom_lefthand.dmi
new file mode 100644
index 00000000000..8d469195434
Binary files /dev/null and b/icons/mob/custom_synthetic/custom_lefthand.dmi differ
diff --git a/icons/mob/custom_synthetic/custom_righthand.dmi b/icons/mob/custom_synthetic/custom_righthand.dmi
new file mode 100644
index 00000000000..8d469195434
Binary files /dev/null and b/icons/mob/custom_synthetic/custom_righthand.dmi differ