Tail Overhaul 2 (#15577)

* Tail Styles

* sql migration

* finishing touches

* cl

* accidentally left this in

* credit spriter

* animated cloth

* cl fix

* update migration

* updated SQL & changelog, merge conflicts resolved

* adds checks for species type in standard.dm

* the above but better

* Applies Suggestions

---------

Co-authored-by: Geeves <ggrobler447@gmail.com>
Co-authored-by: Werner <1331699+Arrow768@users.noreply.github.com>
Co-authored-by: SleepyGemmy <99297919+SleepyGemmy@users.noreply.github.com>
This commit is contained in:
Ramke
2023-02-05 20:22:33 +01:00
committed by GitHub
co-authored by Geeves Werner SleepyGemmy
parent 87beb2d6eb
commit ac20badaa0
27 changed files with 275 additions and 59 deletions
@@ -16,6 +16,7 @@
if(current_species.appearance_flags & HAS_SKIN_COLOR)
randomize_skin_color(current_species)
tail_style = length(current_species.selectable_tails) ? pick(current_species.selectable_tails) : null
h_style = random_hair_style(gender, species)
f_style = random_facial_hair_style(gender, species)
randomize_hair_color("hair")
@@ -1,4 +1,7 @@
/mob/living/carbon/human
// Tail Style
var/tail_style = null
//Hair colour and style
var/r_hair = 0
var/g_hair = 0
@@ -408,3 +408,21 @@
/mob/living/carbon/human/get_stutter_verbs()
return species.stutter_verbs
/mob/living/carbon/human/proc/set_tail_style(var/new_style)
tail_style = new_style
if(tail_style)
verbs |= /mob/living/carbon/human/proc/open_tail_storage
else
verbs -= /mob/living/carbon/human/proc/open_tail_storage
/mob/living/carbon/human/proc/get_tail_accessory()
var/obj/item/organ/external/groin/G = organs_by_name[BP_GROIN]
if(!G)
return
if(!G.tail_storage)
return
if(length(G.tail_storage.contents))
return G.tail_storage.contents[1]
return null
@@ -116,7 +116,7 @@
/mob/living/carbon/human/set_dir(var/new_dir, ignore_facing_dir = FALSE)
. = ..()
if(. && species.tail)
if(. && tail_style)
update_tail_showing(1)
/mob/living/carbon/human/Move()
@@ -835,7 +835,7 @@ mob/living/carbon/human/proc/change_monitor()
earpain(3, TRUE, 1)
else if (T in range(src, 2))
earpain(2, TRUE, 2)
for (var/mob/living/carbon/human/T in hearers(2, src) - src)
if(T.get_hearing_protection() >= EAR_PROTECTION_MAJOR)
continue
@@ -1320,3 +1320,18 @@ mob/living/carbon/human/proc/change_monitor()
if (is_listening())
visible_message("<b>[src]</b> stops listening intently.")
intent_listener -= src
/mob/living/carbon/human/proc/open_tail_storage()
set name = "Tail Accessories"
set desc = "Opens the tail accessory slot."
set category = "Abilities"
var/obj/item/organ/external/groin/G = organs_by_name[BP_GROIN]
if(!G)
to_chat(usr, SPAN_WARNING("You have no tail!"))
return
if(!G.tail_storage)
to_chat(usr, SPAN_WARNING("Your tail storage is missing!"))
return
G.tail_storage.open(usr)
@@ -50,6 +50,7 @@
var/tail // Name of tail state in species effects icon file.
var/tail_animation // If set, the icon to obtain tail animation states from.
var/tail_hair
var/list/selectable_tails
var/race_key = 0 // Used for mob icon cache string.
var/icon/icon_template // Used for mob icon generation for non-32x32 species.
var/mob_size = MOB_MEDIUM
@@ -12,7 +12,9 @@
brute_mod = 0.9
oxy_mod = 0.9
hydration_loss_factor = 1.1
tail = "axiori_tail"
tail = "Tail"
tail_animation = 'icons/mob/species/skrell/tail.dmi'
selectable_tails = list("Tail")
eyes = "skrell_axiori_eyes_s"
sprint_speed_factor = 0.7 // Species default 0.8
@@ -8,8 +8,9 @@
deform = 'icons/mob/human_races/tajara/r_def_tajaran.dmi'
preview_icon = 'icons/mob/human_races/tajara/tajaran_preview.dmi'
bandages_icon = 'icons/mob/bandage.dmi'
tail = "tajtail"
tail = "Tail"
tail_animation = 'icons/mob/species/tajaran/tail.dmi'
selectable_tails = list("Tail", "Hakh'jar Tail")
unarmed_types = list(
/datum/unarmed_attack/stomp,
/datum/unarmed_attack/kick,
@@ -8,8 +8,9 @@
deform = 'icons/mob/human_races/unathi/r_def_unathi.dmi'
preview_icon = 'icons/mob/human_races/unathi/unathi_preview.dmi'
bandages_icon = 'icons/mob/bandage.dmi'
tail = "unathtail"
tail = "Tail"
tail_animation = 'icons/mob/species/unathi/tail.dmi'
selectable_tails = list("Tail")
unarmed_types = list(
/datum/unarmed_attack/stomp,
/datum/unarmed_attack/kick,
@@ -86,45 +86,48 @@ There are several things that need to be remembered:
// Human Overlays Indexes //
// Layer 1 intentionally left empty.
#define FIRE_LAYER_LOWER 2
#define MUTATIONS_LAYER 3
#define DAMAGE_LAYER 4
#define SURGERY_LAYER 5
#define UNDERWEAR_LAYER 6
#define TAIL_SOUTH_LAYER 7
#define SHOES_LAYER_ALT 8
#define UNIFORM_LAYER 9
#define ID_LAYER 10
#define SHOES_LAYER 11
#define GLOVES_LAYER 12
#define BELT_LAYER 13
#define WRISTS_LAYER_ALT 14
#define SUIT_LAYER 15
#define ID_LAYER_ALT 16
#define TAIL_NORTH_LAYER 17
#define HAIR_LAYER_ALT 18
#define GLASSES_LAYER 19
#define BELT_LAYER_ALT 20
#define SUIT_STORE_LAYER 21
#define BACK_LAYER 22
#define HAIR_LAYER 23
#define GLASSES_LAYER_ALT 24
#define L_EAR_LAYER 25
#define R_EAR_LAYER 26
#define FACEMASK_LAYER 27
#define HEAD_LAYER 28
#define COLLAR_LAYER 29
#define HANDCUFF_LAYER 30
#define LEGCUFF_LAYER 31
#define L_HAND_LAYER 32
#define R_HAND_LAYER 33
#define WRISTS_LAYER 34
#define FIRE_LAYER_UPPER 35
#define TOTAL_LAYERS 35
#define FIRE_LAYER_LOWER 2
#define MUTATIONS_LAYER 3
#define DAMAGE_LAYER 4
#define SURGERY_LAYER 5
#define UNDERWEAR_LAYER 6
#define TAIL_SOUTH_LAYER 7
#define TAIL_SOUTH_ACC_LAYER 8
#define SHOES_LAYER_ALT 9
#define UNIFORM_LAYER 10
#define ID_LAYER 11
#define SHOES_LAYER 12
#define GLOVES_LAYER 13
#define BELT_LAYER 14
#define WRISTS_LAYER_ALT 15
#define SUIT_LAYER 16
#define ID_LAYER_ALT 17
#define TAIL_NORTH_LAYER 18
#define TAIL_NORTH_ACC_LAYER 19
#define HAIR_LAYER_ALT 20
#define GLASSES_LAYER 21
#define BELT_LAYER_ALT 22
#define SUIT_STORE_LAYER 23
#define BACK_LAYER 24
#define HAIR_LAYER 25
#define GLASSES_LAYER_ALT 26
#define L_EAR_LAYER 27
#define R_EAR_LAYER 28
#define FACEMASK_LAYER 29
#define HEAD_LAYER 30
#define COLLAR_LAYER 31
#define HANDCUFF_LAYER 32
#define LEGCUFF_LAYER 33
#define L_HAND_LAYER 34
#define R_HAND_LAYER 35
#define WRISTS_LAYER 36
#define FIRE_LAYER_UPPER 37
#define TOTAL_LAYERS 37
////////////////////////////
#define GET_BODY_TYPE (cached_bodytype || (cached_bodytype = species.get_bodytype()))
#define GET_TAIL_LAYER (dir == NORTH ? TAIL_NORTH_LAYER : TAIL_SOUTH_LAYER)
#define GET_TAIL_ACC_LAYER (dir == NORTH ? TAIL_NORTH_ACC_LAYER : TAIL_SOUTH_ACC_LAYER)
/proc/overlay_image(icon,icon_state,color,flags)
var/image/ret = image(icon,icon_state)
@@ -1287,8 +1290,9 @@ There are several things that need to be remembered:
if(species.tail && NOT_FLAG(mutations, HUSK) && NOT_FLAG(mutations, SKELETON) && !(wear_suit && wear_suit.flags_inv & HIDETAIL))
var/icon/tail_s = get_tail_icon()
overlays_raw[tail_layer] = image(tail_s, icon_state = "[species.tail]_s")
animate_tail_reset(0)
overlays_raw[tail_layer] = image(tail_s, icon_state = "[tail_style]_s")
animate_tail_reset()
update_tail_accessory(FALSE)
if(update_icons)
update_icon()
@@ -1305,7 +1309,7 @@ There are several things that need to be remembered:
tail_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
// The following will not work with animated tails.
if(species.tail_hair)
var/icon/hair_icon = icon('icons/effects/species.dmi', "[species.tail]_[species.tail_hair]")
var/icon/hair_icon = icon('icons/effects/species.dmi', "[tail_style]_[species.tail_hair]")
hair_icon.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
tail_icon.Blend(hair_icon, ICON_OVERLAY)
SSicon_cache.tail_icon_cache[icon_key] = tail_icon
@@ -1313,16 +1317,20 @@ There are several things that need to be remembered:
return tail_icon
/mob/living/carbon/human/proc/set_tail_state(var/mob_state)
if (!species.tail)
if(!tail_style)
return
var/tail_layer = GET_TAIL_LAYER
var/image/tail_overlay = overlays_raw[tail_layer]
var/obj/item/clothing/tail_accessory/TA = get_tail_accessory()
if(TA && !(tail_style in TA.compatible_animated_tail))
mob_state = "[tail_style]_static"
if(tail_overlay && species.tail_animation)
if (tail_overlay.icon_state != mob_state)
if(tail_overlay.icon_state != mob_state)
tail_overlay.icon_state = mob_state
update_tail_accessory()
update_icon()
return tail_overlay
return null
@@ -1330,7 +1338,7 @@ There are several things that need to be remembered:
//Not really once, since BYOND can't do that.
//Update this if the ability to flick() images or make looping animation start at the first frame is ever added.
/mob/living/carbon/human/proc/animate_tail_once()
var/mob_state = "[species.tail]_once"
var/mob_state = "[tail_style]_once"
var/tail_layer = GET_TAIL_LAYER
@@ -1345,23 +1353,42 @@ There are several things that need to be remembered:
/mob/living/carbon/human/proc/end_animate_tail_once(image/tail_overlay)
//check that the animation hasn't changed in the meantime
var/tail_layer = GET_TAIL_LAYER
if(overlays_raw[tail_layer] == tail_overlay && tail_overlay.icon_state == "[species.tail]_once")
if(overlays_raw[tail_layer] == tail_overlay && tail_overlay.icon_state == "[tail_style]_once")
animate_tail_stop()
update_tail_accessory()
/mob/living/carbon/human/proc/animate_tail_start()
set_tail_state("[species.tail]_slow[rand(0,9)]")
set_tail_state("[tail_style]_slow")
/mob/living/carbon/human/proc/animate_tail_fast()
set_tail_state("[species.tail]_loop[rand(0,9)]")
set_tail_state("[tail_style]_loop")
/mob/living/carbon/human/proc/animate_tail_reset()
if(stat != DEAD && !lying)
set_tail_state("[species.tail]_idle[rand(0,9)]")
set_tail_state("[tail_style]_idle")
else
set_tail_state("[species.tail]_static")
set_tail_state("[tail_style]_static")
/mob/living/carbon/human/proc/animate_tail_stop(var/update_icons=1)
set_tail_state("[species.tail]_static")
set_tail_state("[tail_style]_static")
/mob/living/carbon/human/proc/update_tail_accessory(var/update_icons=1)
overlays_raw[TAIL_NORTH_ACC_LAYER] = null
overlays_raw[TAIL_SOUTH_ACC_LAYER] = null
var/obj/item/clothing/tail_accessory/TA = get_tail_accessory()
if(!TA)
return
var/image/tail_overlay = overlays_raw[GET_TAIL_LAYER]
if(!tail_overlay)
return
overlays_raw[GET_TAIL_ACC_LAYER] = TA.get_mob_overlay(src, TA.icon, "[tail_overlay.icon_state]_to", slot_tail_str)
if(update_icons)
update_icon()
//Adds a collar overlay above the helmet layer if the suit has one
// Suit needs an identically named sprite in icons/mob/collar.dmi