From 3ee80a35867b00a5363b042ba2d617e40a98e9bd Mon Sep 17 00:00:00 2001 From: Tigercat2000 Date: Sat, 5 Sep 2015 17:20:28 -0700 Subject: [PATCH 1/7] Body accessory system This commit adds a modular system for selectable body accessories. These accessories are currently split into two primary groups, "/body_accessory/body" and "/body_accessory/tail", for "body" sprites and "tail" sprites respectively. (also known as a subtype just for vorestation taur sprites) Basically, this allows for selectable tails. This commit doesn't include any subtypes, which will cause the startup hook to fail. The only subtypes this actually includes is a snake 'body'. Admins can select any tail, regardless of species restriction. Admin-only subtypes are simply defined by not adding any species to the whitelist. Note, as this system uses the body color system, admins may also use the body colors at any time regardless of race. --- SQL/paradise_schema.sql | 1 + code/modules/client/preferences.dm | 43 ++++++++-- code/modules/client/preferences_mysql.dm | 10 ++- .../living/carbon/human/body_accessories.dm | 79 ++++++++++++++++++ .../mob/living/carbon/human/human_defines.dm | 4 +- .../mob/living/carbon/human/update_icons.dm | 40 ++++++--- .../modules/mob/living/carbon/update_icons.dm | 6 +- icons/mob/body_accessory_64.dmi | Bin 0 -> 863 bytes paradise.dme | 1 + 9 files changed, 157 insertions(+), 27 deletions(-) create mode 100644 code/modules/mob/living/carbon/human/body_accessories.dm create mode 100644 icons/mob/body_accessory_64.dmi diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index c6045cd835e..f36d62f7339 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -78,6 +78,7 @@ CREATE TABLE `characters` ( `rlimb_data` mediumtext NOT NULL, `nanotrasen_relation` varchar(45) NOT NULL, `speciesprefs` int(1) NOT NULL, + `body_accessory` mediumtext NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=18747 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 338d57dd616..785e4718617 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -127,6 +127,7 @@ datum/preferences var/species = "Human" var/language = "None" //Secondary language + var/body_accessory = null var/speciesprefs = 0//I hate having to do this, I really do (Using this for oldvox code, making names universal I guess @@ -185,17 +186,17 @@ datum/preferences // jukebox volume var/volume = 100 - + // BYOND membership var/unlock_content = 0 - + /datum/preferences/New(client/C) b_type = pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+") if(istype(C)) if(!IsGuestKey(C.key)) unlock_content = C.IsByondMember() if(unlock_content) - max_save_slots = MAX_SAVE_SLOTS_MEMBER + max_save_slots = MAX_SAVE_SLOTS_MEMBER var/loaded_preferences_successfully = load_preferences(C) if(loaded_preferences_successfully) if(load_character(C)) @@ -364,10 +365,14 @@ datum/preferences dat += "
Eyes
" dat += "Change Color
__

" - if(species == "Unathi" || species == "Tajaran" || species == "Skrell" || species == "Slime People" || species == "Vulpkanin") + if(species == "Unathi" || species == "Tajaran" || species == "Skrell" || species == "Slime People" || species == "Vulpkanin" || body_accessory_by_species[species] || check_rights(R_ADMIN, 1, user)) //admins can always fuck with this, because they are admins dat += "
Body Color
" dat += "Change Color
__
" + if(body_accessory_by_species[species] || check_rights(R_ADMIN, 1, user)) + dat += "
Body Accessory
" + dat += "Accessory: [body_accessory ? "[body_accessory]" : "None"]
" + dat += "
" if (1) // General Preferences @@ -385,7 +390,7 @@ datum/preferences dat += "Ghost radio: [(toggles & CHAT_GHOSTRADIO) ? "Nearest Speakers" : "All Chatter"]
" if(config.allow_Metadata) dat += "OOC notes: Edit
" - + if(user.client) if(user.client.holder) dat += "Adminhelp sound: " @@ -393,7 +398,7 @@ datum/preferences if(check_rights(R_ADMIN,0)) dat += "OOC:     Change
" - + if(unlock_content) dat += "BYOND Membership Publicity: [(toggles & MEMBER_PUBLIC) ? "Public" : "Hidden"]
" @@ -1160,10 +1165,27 @@ datum/preferences valid_hairstyles[hairstyle] = hair_styles_list[hairstyle] - var/new_h_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in valid_hairstyles + var/new_h_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in valid_hairstyles if(new_h_style) h_style = new_h_style + if("body_accessory") + var/list/possible_body_accessories = list() + if(check_rights(R_ADMIN, 1, user)) + possible_body_accessories = body_accessory_by_name.Copy() + else + for(var/B in body_accessory_by_name) + var/datum/body_accessory/accessory = body_accessory_by_name[B] + if(!istype(accessory)) + possible_body_accessories += "None" //the only null entry should be the "None" option + continue + if(species in accessory.allowed_species) + possible_body_accessories += B + + var/new_body_accessory = input(user, "Choose your body accessory:", "Character Preference") as null|anything in possible_body_accessories + if(new_body_accessory) + body_accessory = new_body_accessory + if("facial") var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference") as color|null if(new_facial) @@ -1225,7 +1247,7 @@ datum/preferences s_tone = 35 - max(min( round(new_s_tone), 220),1) if("skin") - if(species == "Unathi" || species == "Tajaran" || species == "Skrell" || species == "Slime People"|| species == "Vulpkanin") + if(species == "Unathi" || species == "Tajaran" || species == "Skrell" || species == "Slime People"|| species == "Vulpkanin" || body_accessory_by_species[species] || check_rights(R_ADMIN, 1, user)) var/new_skin = input(user, "Choose your character's skin colour: ", "Character Preference") as color|null if(new_skin) r_skin = hex2num(copytext(new_skin, 2, 4)) @@ -1360,7 +1382,7 @@ datum/preferences if("publicity") if(unlock_content) toggles ^= MEMBER_PUBLIC - + if("gender") if(gender == MALE) gender = FEMALE @@ -1549,6 +1571,9 @@ datum/preferences character.underwear = underwear character.undershirt = undershirt + if(body_accessory) + character.body_accessory = body_accessory_by_name["[body_accessory]"] + if(backbag > 4 || backbag < 1) backbag = 1 //Same as above character.backbag = backbag diff --git a/code/modules/client/preferences_mysql.dm b/code/modules/client/preferences_mysql.dm index 96e51448c6d..f89a76d7689 100644 --- a/code/modules/client/preferences_mysql.dm +++ b/code/modules/client/preferences_mysql.dm @@ -148,6 +148,7 @@ rlimb_data = params2list(query.item[51]) nanotrasen_relation = query.item[52] speciesprefs = text2num(query.item[53]) + body_accessory = query.item[54] //Sanitize metadata = sanitize_text(metadata, initial(metadata)) @@ -267,7 +268,8 @@ organ_data='[organlist]', rlimb_data='[rlimblist]', nanotrasen_relation='[nanotrasen_relation]', - speciesprefs='[speciesprefs]' + speciesprefs='[speciesprefs]', + body_accessory='[body_accessory]' WHERE ckey='[C.ckey]' AND slot='[default_slot]'"} ) @@ -295,7 +297,8 @@ job_karma_high, job_karma_med, job_karma_low, flavor_text, med_record, sec_record, gen_record, player_alt_titles, be_special, - disabilities, organ_data, rlimb_data, nanotrasen_relation, speciesprefs) + disabilities, organ_data, rlimb_data, nanotrasen_relation, speciesprefs, + body_accessory) VALUES ('[C.ckey]', '[default_slot]', '[sql_sanitize_text(metadata)]', '[sql_sanitize_text(real_name)]', '[be_random_name]','[gender]', '[age]', '[sql_sanitize_text(species)]', '[sql_sanitize_text(language)]', @@ -312,7 +315,8 @@ '[job_karma_high]', '[job_karma_med]', '[job_karma_low]', '[sql_sanitize_text(flavor_text)]', '[sql_sanitize_text(med_record)]', '[sql_sanitize_text(sec_record)]', '[sql_sanitize_text(gen_record)]', '[playertitlelist]', '[be_special]', - '[disabilities]', '[organlist]', '[rlimblist]', '[nanotrasen_relation]', '[speciesprefs]') + '[disabilities]', '[organlist]', '[rlimblist]', '[nanotrasen_relation]', '[speciesprefs]', + '[body_accessory]') "} ) diff --git a/code/modules/mob/living/carbon/human/body_accessories.dm b/code/modules/mob/living/carbon/human/body_accessories.dm new file mode 100644 index 00000000000..4ad65f05ffb --- /dev/null +++ b/code/modules/mob/living/carbon/human/body_accessories.dm @@ -0,0 +1,79 @@ +var/global/list/body_accessory_by_name = list("None" = null) + +/hook/startup/proc/initalize_body_accessories() + //each accessory subtype needs it's own loop + for(var/type in subtypesof(/datum/body_accessory/body)) + var/datum/body_accessory/ac1 = new type + if(istype(ac1)) + body_accessory_by_name["[ac1.name]"] = ac1 + + for(var/type in subtypesof(/datum/body_accessory/tail)) + var/datum/body_accessory/ac2 = new type + if(istype(ac2)) + body_accessory_by_name["[ac2.name]"] = ac2 + + if(body_accessory_by_name.len) + if(initialize_body_accessory_by_species()) + return 1 + + return 0 //fail if no bodies are found + +var/global/list/body_accessory_by_species = list("None" = null) + +/proc/initialize_body_accessory_by_species() + for(var/B in body_accessory_by_name) + var/datum/body_accessory/accessory = body_accessory_by_name[B] + if(!istype(accessory)) continue + for(var/A in accessory.allowed_species) + body_accessory_by_species[A] += accessory + + if(body_accessory_by_species.len) + return 1 + return 0 + + +/datum/body_accessory + var/name = "default" + + var/icon = null + var/icon_state = "" + + var/animated_icon = null + var/animated_icon_state = "" + + var/blend_mode = null + + var/list/pixel_offsets = list("x" = 0, "y" = 0) + + var/list/allowed_species = list() + +/datum/body_accessory/proc/try_restrictions(var/mob/living/carbon/human/H) + return 1 + +/datum/body_accessory/proc/get_pixel_x(var/mob/living/carbon/human/H) + return pixel_offsets["x"] + +/datum/body_accessory/proc/get_pixel_y(var/mob/living/carbon/human/H) + return pixel_offsets["y"] + + +//Bodies +/datum/body_accessory/body + blend_mode = ICON_MULTIPLY + +/datum/body_accessory/body/snake + name = "Snake" + + icon = 'icons/mob/body_accessory_64.dmi' + icon_state = "naga" + + pixel_offsets = list("x" = -16, "y" = 0) + +//Tails +/datum/body_accessory/tail + blend_mode = ICON_ADD + +/datum/body_accessory/tail/try_restrictions(var/mob/living/carbon/human/H) + if(!H.wear_suit || !(H.wear_suit.flags_inv & HIDETAIL) && !istype(H.wear_suit, /obj/item/clothing/suit/space)) + return 1 + return 0 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index bc10d54b1c8..38523536807 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -81,4 +81,6 @@ var/lastFart = 0 // Toxic fart cooldown. var/fire_dmi = 'icons/mob/OnFire.dmi' - var/fire_sprite = "Standing" \ No newline at end of file + var/fire_sprite = "Standing" + + var/datum/body_accessory/body_accessory = null \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 2e7a5e2be23..1fb591ba8a3 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -337,7 +337,7 @@ var/global/list/damage_icon_parts = list() stand_icon.Blend(lips, ICON_OVERLAY) //tail - update_tail_showing(0) + update_tail_layer(0) //HAIR OVERLAY @@ -756,12 +756,12 @@ var/global/list/damage_icon_parts = list() overlays_standing[SUIT_LAYER] = standing - update_tail_showing(0) + update_tail_layer(0) else overlays_standing[SUIT_LAYER] = null - update_tail_showing(0) + update_tail_layer(0) update_collar(0) @@ -896,10 +896,20 @@ var/global/list/damage_icon_parts = list() overlays_standing[L_HAND_LAYER] = null if(update_icons) update_icons() -/mob/living/carbon/human/proc/update_tail_showing(var/update_icons=1) + + +/mob/living/carbon/human/proc/update_tail_layer(var/update_icons=1) overlays_standing[TAIL_LAYER] = null - if(species.tail && species.bodyflags & HAS_TAIL) + if(body_accessory) + if(body_accessory.try_restrictions(src)) + var/icon/accessory_s = new/icon("icon" = body_accessory.icon, "icon_state" = body_accessory.icon_state) + accessory_s.Blend(rgb(r_skin, g_skin, b_skin), body_accessory.blend_mode) + + overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.get_pixel_x(src), "pixel_y" = body_accessory.get_pixel_y(src)) + + + else if(species.tail && species.bodyflags & HAS_TAIL) //no tailless tajaran if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space)) var/icon/tail_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_s") tail_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) @@ -913,7 +923,14 @@ var/global/list/damage_icon_parts = list() /mob/living/carbon/human/proc/start_tail_wagging(var/update_icons=1) overlays_standing[TAIL_LAYER] = null - if(species.tail && species.bodyflags & HAS_TAIL) + if(body_accessory) + if(body_accessory.animated_icon && body_accessory.animated_icon_state) + var/icon/accessory_s = new/icon("icon" = body_accessory.animated_icon, "icon_state" = body_accessory.animated_icon_state) + accessory_s.Blend(rgb(r_skin, g_skin, b_skin), body_accessory.blend_mode) + + overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.get_pixel_x(src), "pixel_y" = body_accessory.get_pixel_y(src)) + + else if(species.tail && species.bodyflags & HAS_TAIL) var/icon/tailw_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]w_s") tailw_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) @@ -925,14 +942,11 @@ var/global/list/damage_icon_parts = list() /mob/living/carbon/human/proc/stop_tail_wagging(var/update_icons=1) overlays_standing[TAIL_LAYER] = null - if(species.tail && species.bodyflags & HAS_TAIL) - var/icon/tail_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_s") - tail_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) + update_tail_layer(update_icons) //just trigger a full update for normal stationary sprites - overlays_standing[TAIL_LAYER] = image(tail_s) - - if(update_icons) - update_icons() +/mob/living/carbon/human/handle_transform_change() + ..() + update_tail_layer() //Adds a collar overlay above the helmet layer if the suit has one // Suit needs an identically named sprite in icons/mob/collar.dmi diff --git a/code/modules/mob/living/carbon/update_icons.dm b/code/modules/mob/living/carbon/update_icons.dm index 02fe01c39a1..e22ad5e66dc 100644 --- a/code/modules/mob/living/carbon/update_icons.dm +++ b/code/modules/mob/living/carbon/update_icons.dm @@ -28,4 +28,8 @@ if(changed) animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, dir = final_dir, easing = EASE_IN|EASE_OUT) - floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life(). \ No newline at end of file + handle_transform_change() + floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life(). + +/mob/living/carbon/proc/handle_transform_change() + return \ No newline at end of file diff --git a/icons/mob/body_accessory_64.dmi b/icons/mob/body_accessory_64.dmi new file mode 100644 index 0000000000000000000000000000000000000000..4dfe1fc23a9d540660ec0bea90c5812786874dc7 GIT binary patch literal 863 zcmV-l1EBngP)5H4+R@R`r>Ca4xVVRhhJt{Aj*g9bdU~#|u8@z9a&mHngoL!S zv!tY?tgNj5l+kAZ0004WQchCV=-0C=2JR&a84 z_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6#a?DJ)I5Sc+(=$qd9AhJ{;*!LYR3K9+ zFEKq)iHkEOv#1!Phl?|<00073Nkl+MhCLNGnsr>d3C6RCC~%zT*u!akk4y1Kf$y1Kf$ezDGn zu~x%jtOo!ca03{IGN*LjfI84W066~Zc7W61ORV0;ln*5N&ETK9d2m+)A_#XvuB@N7yuLK&-vl*z8 zK=KJ7H2_916*dq^3FcWxKB@^Od)-|FYA}^HFz(5p1eE~U1}5^;-vO>P2Ye)`zX#d? za=tVG*1+up$Q1yL<8?mhN;FmiAj@;UG{6Ng&IPC>UkT{S$HOfci@rkc2{c_Bz_Uy) zGB3$z0!BEhHlGR3Nf*)WcKayHSA?UQzm2=Py1Kf$y8bf_rXPzK97aA0etNg(e-$yf zs4E#WZtAy>hIY4MT(NC&sJ z2Cq(sjB%#r1>^CG13)~*=-UB&WCM6w7lxPva0xW6=mSxVi0uG~F_QW|>=FcW&j3uj zJs)g26>Q1`t@mJck`Hz%YPu)nT4jLkQ?Re+g3a42kOJ&V!oEn{60!h{yX|PCvyCNU z+q+=(nxA~^s`PsxTk49OrP~6k^qLo^7XZj5eMTo+4#{@Pz!ob@bF_0Uzr6t?uz0hz zjgPz`6Z7Xz3SW7Ok>?R@qoA Date: Sun, 6 Sep 2015 21:49:58 -0700 Subject: [PATCH 2/7] Fix tail-wagging invisible tails --- .../mob/living/carbon/human/body_accessories.dm | 12 ++++++++++++ code/modules/mob/living/carbon/human/update_icons.dm | 7 +++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/living/carbon/human/body_accessories.dm b/code/modules/mob/living/carbon/human/body_accessories.dm index 4ad65f05ffb..e4cac481f21 100644 --- a/code/modules/mob/living/carbon/human/body_accessories.dm +++ b/code/modules/mob/living/carbon/human/body_accessories.dm @@ -56,6 +56,18 @@ var/global/list/body_accessory_by_species = list("None" = null) /datum/body_accessory/proc/get_pixel_y(var/mob/living/carbon/human/H) return pixel_offsets["y"] +/datum/body_accessory/proc/get_animated_icon() //return animated if it has it, return static if it does not. + if(animated_icon) + return animated_icon + + else return icon + +/datum/body_accessory/proc/get_animated_icon_state() + if(animated_icon_state) + return animated_icon_state + + else return icon_state + //Bodies /datum/body_accessory/body diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 1fb591ba8a3..b62ac1a786b 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -924,11 +924,10 @@ var/global/list/damage_icon_parts = list() overlays_standing[TAIL_LAYER] = null if(body_accessory) - if(body_accessory.animated_icon && body_accessory.animated_icon_state) - var/icon/accessory_s = new/icon("icon" = body_accessory.animated_icon, "icon_state" = body_accessory.animated_icon_state) - accessory_s.Blend(rgb(r_skin, g_skin, b_skin), body_accessory.blend_mode) + var/icon/accessory_s = new/icon("icon" = body_accessory.get_animated_icon(), "icon_state" = body_accessory.get_animated_icon_state()) + accessory_s.Blend(rgb(r_skin, g_skin, b_skin), body_accessory.blend_mode) - overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.get_pixel_x(src), "pixel_y" = body_accessory.get_pixel_y(src)) + overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.get_pixel_x(src), "pixel_y" = body_accessory.get_pixel_y(src)) else if(species.tail && species.bodyflags & HAS_TAIL) var/icon/tailw_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]w_s") From 7ce1d0595ee036752a7ea2b169e76bae90a8e6cd Mon Sep 17 00:00:00 2001 From: Tigercat2000 Date: Tue, 8 Sep 2015 18:10:51 -0700 Subject: [PATCH 3/7] Add FullofSkittle's alt. vulp tails, fixes --- .../living/carbon/human/body_accessories.dm | 65 ++++++++++++++---- icons/mob/body_accessory.dmi | Bin 0 -> 2486 bytes 2 files changed, 53 insertions(+), 12 deletions(-) create mode 100644 icons/mob/body_accessory.dmi diff --git a/code/modules/mob/living/carbon/human/body_accessories.dm b/code/modules/mob/living/carbon/human/body_accessories.dm index e4cac481f21..4ceff41ed11 100644 --- a/code/modules/mob/living/carbon/human/body_accessories.dm +++ b/code/modules/mob/living/carbon/human/body_accessories.dm @@ -1,16 +1,9 @@ var/global/list/body_accessory_by_name = list("None" = null) /hook/startup/proc/initalize_body_accessories() - //each accessory subtype needs it's own loop - for(var/type in subtypesof(/datum/body_accessory/body)) - var/datum/body_accessory/ac1 = new type - if(istype(ac1)) - body_accessory_by_name["[ac1.name]"] = ac1 - for(var/type in subtypesof(/datum/body_accessory/tail)) - var/datum/body_accessory/ac2 = new type - if(istype(ac2)) - body_accessory_by_name["[ac2.name]"] = ac2 + __init_body_accessory(/datum/body_accessory/body) + __init_body_accessory(/datum/body_accessory/tail) if(body_accessory_by_name.len) if(initialize_body_accessory_by_species()) @@ -24,13 +17,29 @@ var/global/list/body_accessory_by_species = list("None" = null) for(var/B in body_accessory_by_name) var/datum/body_accessory/accessory = body_accessory_by_name[B] if(!istype(accessory)) continue - for(var/A in accessory.allowed_species) - body_accessory_by_species[A] += accessory + + for(var/species in accessory.allowed_species) + if(!body_accessory_by_species["[species]"]) body_accessory_by_species["[species]"] = list() + body_accessory_by_species["[species]"] += accessory if(body_accessory_by_species.len) return 1 return 0 +/proc/__init_body_accessory(var/ba_path) + if(ispath(ba_path)) + var/_added_counter = 0 + + for(var/A in subtypesof(ba_path)) + var/datum/body_accessory/B = new A + if(istype(B)) + body_accessory_by_name[B.name] += B + ++_added_counter + + if(_added_counter) + return 1 + return 0 + /datum/body_accessory var/name = "default" @@ -83,9 +92,41 @@ var/global/list/body_accessory_by_species = list("None" = null) //Tails /datum/body_accessory/tail + icon = 'icons/mob/body_accessory.dmi' + animated_icon = 'icons/mob/body_accessory.dmi' blend_mode = ICON_ADD /datum/body_accessory/tail/try_restrictions(var/mob/living/carbon/human/H) if(!H.wear_suit || !(H.wear_suit.flags_inv & HIDETAIL) && !istype(H.wear_suit, /obj/item/clothing/suit/space)) return 1 - return 0 \ No newline at end of file + return 0 + + +//vulpakin +/datum/body_accessory/tail/vulpkanin_2 + name = "Vulpkanin Alt 1 (Bushy)" + + icon_state = "vulptail2" + animated_icon_state = "vulptail2_a" + allowed_species = list("Vulpkanin") + +/datum/body_accessory/tail/vulpkanin_3 + name = "Vulpkanin Alt 2 (Straight)" + + icon_state = "vulptail3" + animated_icon_state = "vulptail3_a" + allowed_species = list("Vulpkanin") + +/datum/body_accessory/tail/vulpkanin_4 + name = "Vulpkanin Alt 3 (Tiny)" + + icon_state = "vulptail4" + animated_icon_state = "vulptail4_a" + allowed_species = list("Vulpkanin") + +/datum/body_accessory/tail/vulpkanin_5 + name = "Vulpkanin Alt 4 (Short)" + + icon_state = "vulptail5" + animated_icon_state = "vulptail5_a" + allowed_species = list("Vulpkanin") \ No newline at end of file diff --git a/icons/mob/body_accessory.dmi b/icons/mob/body_accessory.dmi new file mode 100644 index 0000000000000000000000000000000000000000..fac217e71fa1e1a566e651bc4c7586d3249f520b GIT binary patch literal 2486 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 HYRrEC_{78n literal 0 HcmV?d00001 From aa508b42a6640c92ea2fff0b42a63183e9a52a37 Mon Sep 17 00:00:00 2001 From: Tigercat2000 Date: Sat, 12 Sep 2015 07:58:24 -0700 Subject: [PATCH 4/7] Change pixel_offsets list into two variables for efficiency --- code/modules/mob/living/carbon/human/body_accessories.dm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/living/carbon/human/body_accessories.dm b/code/modules/mob/living/carbon/human/body_accessories.dm index 4ceff41ed11..8abe9d92331 100644 --- a/code/modules/mob/living/carbon/human/body_accessories.dm +++ b/code/modules/mob/living/carbon/human/body_accessories.dm @@ -52,7 +52,8 @@ var/global/list/body_accessory_by_species = list("None" = null) var/blend_mode = null - var/list/pixel_offsets = list("x" = 0, "y" = 0) + var/pixel_x_offset = 0 + var/pixel_y_offset = 0 var/list/allowed_species = list() @@ -60,10 +61,10 @@ var/global/list/body_accessory_by_species = list("None" = null) return 1 /datum/body_accessory/proc/get_pixel_x(var/mob/living/carbon/human/H) - return pixel_offsets["x"] + return pixel_x_offset /datum/body_accessory/proc/get_pixel_y(var/mob/living/carbon/human/H) - return pixel_offsets["y"] + return pixel_y_offset /datum/body_accessory/proc/get_animated_icon() //return animated if it has it, return static if it does not. if(animated_icon) @@ -88,7 +89,7 @@ var/global/list/body_accessory_by_species = list("None" = null) icon = 'icons/mob/body_accessory_64.dmi' icon_state = "naga" - pixel_offsets = list("x" = -16, "y" = 0) + pixel_x_offset = -16 //Tails /datum/body_accessory/tail From 49b54508cdbee3cde7d5658cf80758a600adae2d Mon Sep 17 00:00:00 2001 From: Tigercat2000 Date: Sat, 12 Sep 2015 08:02:58 -0700 Subject: [PATCH 5/7] Allow anyone with a body_accessory to use the tail-wag verbs. --- code/modules/mob/living/carbon/human/emote.dm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 1054a639819..abbe2d2cf3d 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -116,7 +116,12 @@ m_type = 1 if("wag") - if(species.bodyflags & TAIL_WAGGING) + if(body_accessory) + if(body_accessory.try_restrictions(src)) + message = "[src] starts wagging \his tail." + start_tail_wagging(1) + + else if(species.bodyflags & TAIL_WAGGING) if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space)) message = "[src] starts wagging \his tail." src.start_tail_wagging(1) @@ -126,7 +131,7 @@ return if("swag") - if(species.bodyflags & TAIL_WAGGING) + if(species.bodyflags & TAIL_WAGGING || body_accessory) message = "[src] stops wagging \his tail." src.stop_tail_wagging(1) else From 82002c1c46fd521a421fa7c7b5f7f2cbf4eaaa74 Mon Sep 17 00:00:00 2001 From: Tigercat2000 Date: Sat, 12 Sep 2015 15:33:59 -0700 Subject: [PATCH 6/7] Get rid of pointless get_ procs --- code/modules/mob/living/carbon/human/body_accessories.dm | 7 +------ code/modules/mob/living/carbon/human/update_icons.dm | 4 ++-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/code/modules/mob/living/carbon/human/body_accessories.dm b/code/modules/mob/living/carbon/human/body_accessories.dm index 8abe9d92331..a242e02e241 100644 --- a/code/modules/mob/living/carbon/human/body_accessories.dm +++ b/code/modules/mob/living/carbon/human/body_accessories.dm @@ -1,3 +1,4 @@ + var/global/list/body_accessory_by_name = list("None" = null) /hook/startup/proc/initalize_body_accessories() @@ -60,12 +61,6 @@ var/global/list/body_accessory_by_species = list("None" = null) /datum/body_accessory/proc/try_restrictions(var/mob/living/carbon/human/H) return 1 -/datum/body_accessory/proc/get_pixel_x(var/mob/living/carbon/human/H) - return pixel_x_offset - -/datum/body_accessory/proc/get_pixel_y(var/mob/living/carbon/human/H) - return pixel_y_offset - /datum/body_accessory/proc/get_animated_icon() //return animated if it has it, return static if it does not. if(animated_icon) return animated_icon diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 771a2a79e85..ea0e4197314 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -913,7 +913,7 @@ var/global/list/damage_icon_parts = list() var/icon/accessory_s = new/icon("icon" = body_accessory.icon, "icon_state" = body_accessory.icon_state) accessory_s.Blend(rgb(r_skin, g_skin, b_skin), body_accessory.blend_mode) - overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.get_pixel_x(src), "pixel_y" = body_accessory.get_pixel_y(src)) + overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) else if(species.tail && species.bodyflags & HAS_TAIL) //no tailless tajaran @@ -934,7 +934,7 @@ var/global/list/damage_icon_parts = list() var/icon/accessory_s = new/icon("icon" = body_accessory.get_animated_icon(), "icon_state" = body_accessory.get_animated_icon_state()) accessory_s.Blend(rgb(r_skin, g_skin, b_skin), body_accessory.blend_mode) - overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.get_pixel_x(src), "pixel_y" = body_accessory.get_pixel_y(src)) + overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset) else if(species.tail && species.bodyflags & HAS_TAIL) var/icon/tailw_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]w_s") From f01b8f122cc1b7202dd2c59cc509199b350e9087 Mon Sep 17 00:00:00 2001 From: Tigercat2000 Date: Mon, 14 Sep 2015 15:44:34 -0700 Subject: [PATCH 7/7] Remove snake body until better sprite can be found --- .../mob/living/carbon/human/body_accessories.dm | 6 +++--- icons/mob/body_accessory_64.dmi | Bin 863 -> 0 bytes 2 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 icons/mob/body_accessory_64.dmi diff --git a/code/modules/mob/living/carbon/human/body_accessories.dm b/code/modules/mob/living/carbon/human/body_accessories.dm index a242e02e241..2a8dfa4e458 100644 --- a/code/modules/mob/living/carbon/human/body_accessories.dm +++ b/code/modules/mob/living/carbon/human/body_accessories.dm @@ -3,7 +3,7 @@ var/global/list/body_accessory_by_name = list("None" = null) /hook/startup/proc/initalize_body_accessories() - __init_body_accessory(/datum/body_accessory/body) +// __init_body_accessory(/datum/body_accessory/body) __init_body_accessory(/datum/body_accessory/tail) if(body_accessory_by_name.len) @@ -73,7 +73,7 @@ var/global/list/body_accessory_by_species = list("None" = null) else return icon_state - +/* //Bodies /datum/body_accessory/body blend_mode = ICON_MULTIPLY @@ -84,7 +84,7 @@ var/global/list/body_accessory_by_species = list("None" = null) icon = 'icons/mob/body_accessory_64.dmi' icon_state = "naga" - pixel_x_offset = -16 + pixel_x_offset = -16*/ //Tails /datum/body_accessory/tail diff --git a/icons/mob/body_accessory_64.dmi b/icons/mob/body_accessory_64.dmi deleted file mode 100644 index 4dfe1fc23a9d540660ec0bea90c5812786874dc7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 863 zcmV-l1EBngP)5H4+R@R`r>Ca4xVVRhhJt{Aj*g9bdU~#|u8@z9a&mHngoL!S zv!tY?tgNj5l+kAZ0004WQchCV=-0C=2JR&a84 z_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6#a?DJ)I5Sc+(=$qd9AhJ{;*!LYR3K9+ zFEKq)iHkEOv#1!Phl?|<00073Nkl+MhCLNGnsr>d3C6RCC~%zT*u!akk4y1Kf$y1Kf$ezDGn zu~x%jtOo!ca03{IGN*LjfI84W066~Zc7W61ORV0;ln*5N&ETK9d2m+)A_#XvuB@N7yuLK&-vl*z8 zK=KJ7H2_916*dq^3FcWxKB@^Od)-|FYA}^HFz(5p1eE~U1}5^;-vO>P2Ye)`zX#d? za=tVG*1+up$Q1yL<8?mhN;FmiAj@;UG{6Ng&IPC>UkT{S$HOfci@rkc2{c_Bz_Uy) zGB3$z0!BEhHlGR3Nf*)WcKayHSA?UQzm2=Py1Kf$y8bf_rXPzK97aA0etNg(e-$yf zs4E#WZtAy>hIY4MT(NC&sJ z2Cq(sjB%#r1>^CG13)~*=-UB&WCM6w7lxPva0xW6=mSxVi0uG~F_QW|>=FcW&j3uj zJs)g26>Q1`t@mJck`Hz%YPu)nT4jLkQ?Re+g3a42kOJ&V!oEn{60!h{yX|PCvyCNU z+q+=(nxA~^s`PsxTk49OrP~6k^qLo^7XZj5eMTo+4#{@Pz!ob@bF_0Uzr6t?uz0hz zjgPz`6Z7Xz3SW7Ok>?R@qoA