From 144a973693c535dbdfd4b79f84f02a7d71a5541a Mon Sep 17 00:00:00 2001 From: Heroman Date: Sat, 30 Jul 2022 05:20:53 +1000 Subject: [PATCH] Altevian base code implementation --- code/__defines/mobs_vr.dm | 1 + code/game/area/areas.dm | 2 + code/modules/catalogue/catalogue_data_vr.dm | 8 +++ .../mob/living/carbon/human/human_movement.dm | 21 ++++--- .../living/carbon/human/species/species.dm | 3 +- .../carbon/human/species/species_getters.dm | 4 +- .../human/species/station/station_vr.dm | 57 ++++++++++++++++++ .../mob/living/carbon/human/update_icons.dm | 57 ++++++++++-------- .../new_player/sprite_accessories_tail_vr.dm | 12 +++- icons/mob/vore/tails_vr.dmi | Bin 155456 -> 155942 bytes 10 files changed, 130 insertions(+), 35 deletions(-) diff --git a/code/__defines/mobs_vr.dm b/code/__defines/mobs_vr.dm index be17f09c39..51c65f532b 100644 --- a/code/__defines/mobs_vr.dm +++ b/code/__defines/mobs_vr.dm @@ -25,6 +25,7 @@ #define SPECIES_PROTEAN "Protean" #define SPECIES_RAPALA "Rapala" #define SPECIES_SERGAL "Sergal" +#define SPECIES_ALTEVIAN "Altevian" #define SPECIES_SHADEKIN_CREW "Black-Eyed Shadekin" #define SPECIES_VASILISSAN "Vasilissan" #define SPECIES_VULPKANIN "Vulpkanin" diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index dc13aa2365..d0cdeb0187 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -451,6 +451,8 @@ var/list/mob/living/forced_ambiance_list = new return if(H.incorporeal_move) // VOREstation edit - Phaseshifted beings should not be affected by gravity return + if(H.species.can_zero_g_move || H.species.can_space_freemove) + return if(H.m_intent == "run") H.AdjustStunned(6) diff --git a/code/modules/catalogue/catalogue_data_vr.dm b/code/modules/catalogue/catalogue_data_vr.dm index 52d00f4a74..350ffe088b 100644 --- a/code/modules/catalogue/catalogue_data_vr.dm +++ b/code/modules/catalogue/catalogue_data_vr.dm @@ -93,6 +93,14 @@ comparable conditions as wealthy members of the Diaspora." value = CATALOGUER_REWARD_TRIVIAL +/datum/category_item/catalogue/fauna/altevian + name = "Sapients - Altevian" + desc = "The Altevian are a species of tall, rodent humanoids that are akin to rats for their features. \ + The Altevian, unlike most species, do not have a home planet, nor system, adopting a fully nomadic lifestyle \ + for their survival across the stars. Instead, they have opted to live in massive super capital-class colony-ships \ + with a flagship as their place they would call home." + value = CATALOGUER_REWARD_TRIVIAL + /datum/category_item/catalogue/fauna/shadekin name = "Sapients - Shadekin" desc = "ERROR : No DNA found. ERROR : Ambient energy signature detected. Likely origin from attempt of scanning \ diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index c3eedab5ec..2e880f5e4a 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -202,7 +202,13 @@ if(restrained()) return 0 if(..()) //Can move due to other reasons, don't use jetpack fuel - return 1 + return TRUE + + if(species.can_space_freemove || (species.can_zero_g_move && !istype(get_turf(src), /turf/space))) //VOREStation Edit. + return TRUE //VOREStation Edit. + + if(flying) //VOREStation Edit. If you're flying, you glide around! + return TRUE //VOREStation Edit. //Do we have a working jetpack? var/obj/item/weapon/tank/jetpack/thrust = get_jetpack() @@ -210,22 +216,23 @@ if(thrust) if(((!check_drift) || (check_drift && thrust.stabilization_on)) && (!lying) && (thrust.do_thrust(0.01, src))) inertia_dir = 0 - return 1 - if(flying) //VOREStation Edit. If you're flying, you glide around! - return 0 //VOREStation Edit. + return TRUE - return 0 + return FALSE /mob/living/carbon/human/Process_Spaceslipping(var/prob_slip = 5) //If knocked out we might just hit it and stop. This makes it possible to get dead bodies and such. if(species.flags & NO_SLIP) - return 0 + return FALSE + + if(species.can_space_freemove || species.can_zero_g_move) + return FALSE var/obj/item/weapon/tank/jetpack/thrust = get_jetpack() if(thrust?.can_thrust(0.01)) - return 0 + return FALSE if(stat) prob_slip = 0 // Changing this to zero to make it line up with the comment, and also, make more sense. diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index ff775a5063..5f6a24920e 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -201,7 +201,8 @@ var/has_glowing_eyes = 0 // Whether the eyes are shown above all lighting var/water_movement = 0 // How much faster or slower the species is in water var/snow_movement = 0 // How much faster or slower the species is on snow - + var/can_space_freemove = FALSE // Can we freely move in space? + var/can_zero_g_move = FALSE // What about just in zero-g non-space? var/item_slowdown_mod = 1 // How affected by item slowdown the species is. var/primitive_form // Lesser form, if any (ie. monkey for humans) diff --git a/code/modules/mob/living/carbon/human/species/species_getters.dm b/code/modules/mob/living/carbon/human/species/species_getters.dm index bcb9de1f29..27bb09baa6 100644 --- a/code/modules/mob/living/carbon/human/species/species_getters.dm +++ b/code/modules/mob/living/carbon/human/species/species_getters.dm @@ -103,8 +103,10 @@ if(!name_language) if(gender == FEMALE) return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names)) - else + else if(gender == MALE) return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) + else + return capitalize(prob(50) ? pick(first_names_male) : pick(first_names_female)) + " " + capitalize(pick(last_names)) var/datum/language/species_language = GLOB.all_languages[name_language] if(!species_language) diff --git a/code/modules/mob/living/carbon/human/species/station/station_vr.dm b/code/modules/mob/living/carbon/human/species/station/station_vr.dm index 0e402ab5c6..dbfab1414f 100644 --- a/code/modules/mob/living/carbon/human/species/station/station_vr.dm +++ b/code/modules/mob/living/carbon/human/species/station/station_vr.dm @@ -562,3 +562,60 @@ "You feel uncomfortably warm.", "Your chitin feels hot." ) + +/datum/species/altevian + name = SPECIES_ALTEVIAN + name_plural = "Altevians" + icobase = 'icons/mob/human_races/r_sergal.dmi' + deform = 'icons/mob/human_races/r_def_sergal.dmi' + unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp) + language = LANGUAGE_TAVAN + num_alternate_languages = 3 + secondary_langs = list(LANGUAGE_TAVAN) + name_language = null + color_mult = 1 + inherent_verbs = list(/mob/living/carbon/human/proc/tie_hair) + + min_age = 18 + max_age = 80 + + blurb = "The Altevian are a species of tall, rodent humanoids that are akin to rats for their features. \ + The Altevian, unlike most species, do not have a home planet, nor system, adopting a fully nomadic lifestyle \ + for their survival across the stars. Instead, they have opted to live in massive super capital-class colony-ships \ + with a flagship as their place they would call home." + + wikilink="https://wiki.vore-station.net/Altevian" + + catalogue_data = list(/datum/category_item/catalogue/fauna/altevian) + + spawn_flags = SPECIES_CAN_JOIN + appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR + + flesh_color = "#AFA59E" + base_color = "#777777" + + genders = list(MALE, FEMALE, PLURAL, NEUTER) + + burn_mod = 1.15 + hunger_factor = 0.04 + can_zero_g_move = TRUE + + heat_discomfort_strings = list( + "Your fur prickles in the heat.", + "You feel uncomfortably warm.", + "Your overheated skin itches." + ) + + has_limbs = list( + BP_TORSO = list("path" = /obj/item/organ/external/chest), + BP_GROIN = list("path" = /obj/item/organ/external/groin), + BP_HEAD = list("path" = /obj/item/organ/external/head), + BP_L_ARM = list("path" = /obj/item/organ/external/arm), + BP_R_ARM = list("path" = /obj/item/organ/external/arm/right), + BP_L_LEG = list("path" = /obj/item/organ/external/leg), + BP_R_LEG = list("path" = /obj/item/organ/external/leg/right), + BP_L_HAND = list("path" = /obj/item/organ/external/hand), + BP_R_HAND = list("path" = /obj/item/organ/external/hand/right), + BP_L_FOOT = list("path" = /obj/item/organ/external/foot), + BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right) + ) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 3c513052cf..6da73bc471 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -66,7 +66,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() #define MOB_DAM_LAYER 4 //Injury overlay sprites like open wounds #define SURGERY_LAYER 5 //Overlays for open surgical sites #define UNDERWEAR_LAYER 6 //Underwear/bras/etc -#define TAIL_SOUTH_LAYER 7 //Tail as viewed from the south +#define TAIL_LOWER_LAYER 7 //Tail as viewed from the south #define SHOES_LAYER_ALT 8 //Shoe-slot item (when set to be under uniform via verb) #define UNIFORM_LAYER 9 //Uniform-slot item #define ID_LAYER 10 //ID-slot item @@ -74,7 +74,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() #define GLOVES_LAYER 12 //Glove-slot item #define BELT_LAYER 13 //Belt-slot item #define SUIT_LAYER 14 //Suit-slot item -#define TAIL_NORTH_LAYER 15 //Some species have tails to render (As viewed from the N, E, or W) +#define TAIL_UPPER_LAYER 15 //Some species have tails to render (As viewed from the N, E, or W) #define GLASSES_LAYER 16 //Eye-slot item #define BELT_LAYER_ALT 17 //Belt-slot item (when set to be above suit via verb) #define SUIT_STORE_LAYER 18 //Suit storage-slot item @@ -90,7 +90,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() #define L_HAND_LAYER 28 //Left-hand item #define R_HAND_LAYER 29 //Right-hand item #define WING_LAYER 30 //Wings or protrusions over the suit. -#define TAIL_NORTH_LAYER_ALT 31 //Modified tail-sprite layer. Tend to be larger. +#define TAIL_UPPER_LAYER_ALT 31 //Modified tail-sprite layer. Tend to be larger. #define MODIFIER_EFFECTS_LAYER 32 //Effects drawn by modifiers #define FIRE_LAYER 33 //'Mob on fire' overlay layer #define MOB_WATER_LAYER 34 //'Mob submerged' overlay layer @@ -98,8 +98,6 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() #define TOTAL_LAYERS 35 //VOREStation edit. <---- KEEP THIS UPDATED, should always equal the highest number here, used to initialize a list. ////////////////////////////////// -#define GET_TAIL_LAYER (dir == SOUTH ? TAIL_SOUTH_LAYER : TAIL_NORTH_LAYER) - /mob/living/carbon/human var/list/overlays_standing[TOTAL_LAYERS] var/previous_damage_appearance // store what the body last looked like, so we only have to update it if something changed @@ -839,7 +837,7 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() suit_sprite = INV_SUIT_DEF_ICON var/icon/c_mask = null - var/tail_is_rendered = (overlays_standing[TAIL_NORTH_LAYER] || overlays_standing[TAIL_NORTH_LAYER_ALT] || overlays_standing[TAIL_SOUTH_LAYER]) + var/tail_is_rendered = (overlays_standing[TAIL_UPPER_LAYER] || overlays_standing[TAIL_UPPER_LAYER_ALT] || overlays_standing[TAIL_LOWER_LAYER]) var/valid_clip_mask = tail_style?.clip_mask if(tail_is_rendered && valid_clip_mask && !(istype(suit) && suit.taurized)) //Clip the lower half of the suit off using the tail's clip mask for taurs since taur bodies aren't hidden. @@ -952,19 +950,29 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() apply_layer(L_HAND_LAYER) +/mob/living/carbon/human/proc/get_tail_layer() + var/list/lower_layer_dirs = list(SOUTH) + if(tail_style) + lower_layer_dirs = tail_style.lower_layer_dirs.Copy() + + if(dir in lower_layer_dirs) + return TAIL_LOWER_LAYER + else + return TAIL_UPPER_LAYER + /mob/living/carbon/human/proc/update_tail_showing() if(QDESTROYING(src)) return - remove_layer(TAIL_NORTH_LAYER) - remove_layer(TAIL_NORTH_LAYER_ALT) - remove_layer(TAIL_SOUTH_LAYER) + remove_layer(TAIL_UPPER_LAYER) + remove_layer(TAIL_UPPER_LAYER_ALT) + remove_layer(TAIL_LOWER_LAYER) - var/tail_layer = GET_TAIL_LAYER + var/tail_layer = get_tail_layer() if(src.tail_style && src.tail_style.clip_mask_state) - tail_layer = TAIL_NORTH_LAYER // Use default, let clip mask handle everything - if(tail_alt && tail_layer == TAIL_NORTH_LAYER) - tail_layer = TAIL_NORTH_LAYER_ALT + tail_layer = TAIL_UPPER_LAYER // Use default, let clip mask handle everything + if(tail_alt && tail_layer == TAIL_UPPER_LAYER) + tail_layer = TAIL_UPPER_LAYER_ALT var/image/tail_image = get_tail_image() if(tail_image) @@ -1003,16 +1011,16 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() return tail_icon /mob/living/carbon/human/proc/set_tail_state(var/t_state) - var/tail_layer = GET_TAIL_LAYER + var/tail_layer = get_tail_layer() if(src.tail_style && src.tail_style.clip_mask_state) - tail_layer = TAIL_NORTH_LAYER // Use default, let clip mask handle everything - if(tail_alt && tail_layer == TAIL_NORTH_LAYER) - tail_layer = TAIL_NORTH_LAYER_ALT + tail_layer = TAIL_UPPER_LAYER // Use default, let clip mask handle everything + if(tail_alt && tail_layer == TAIL_UPPER_LAYER) + tail_layer = TAIL_UPPER_LAYER_ALT var/image/tail_overlay = overlays_standing[tail_layer] - remove_layer(TAIL_NORTH_LAYER) - remove_layer(TAIL_NORTH_LAYER_ALT) - remove_layer(TAIL_SOUTH_LAYER) + remove_layer(TAIL_UPPER_LAYER) + remove_layer(TAIL_UPPER_LAYER_ALT) + remove_layer(TAIL_LOWER_LAYER) if(tail_overlay) overlays_standing[tail_layer] = tail_overlay @@ -1030,9 +1038,9 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() return var/t_state = "[species.get_tail(src)]_once" - var/tail_layer = GET_TAIL_LAYER + var/tail_layer = get_tail_layer() if(src.tail_style && src.tail_style.clip_mask_state) - tail_layer = TAIL_NORTH_LAYER // Use default, let clip mask handle everything + tail_layer = TAIL_UPPER_LAYER // Use default, let clip mask handle everything var/image/tail_overlay = overlays_standing[tail_layer] if(tail_overlay && tail_overlay.icon_state == t_state) @@ -1292,9 +1300,8 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() #undef GLOVES_LAYER #undef BELT_LAYER #undef SUIT_LAYER -#undef TAIL_NORTH_LAYER -#undef TAIL_SOUTH_LAYER -#undef GET_TAIL_LAYER +#undef TAIL_UPPER_LAYER +#undef TAIL_LOWER_LAYER #undef GLASSES_LAYER #undef BELT_LAYER_ALT #undef SUIT_STORE_LAYER diff --git a/code/modules/mob/new_player/sprite_accessories_tail_vr.dm b/code/modules/mob/new_player/sprite_accessories_tail_vr.dm index a1c1034be5..cf9632ccda 100644 --- a/code/modules/mob/new_player/sprite_accessories_tail_vr.dm +++ b/code/modules/mob/new_player/sprite_accessories_tail_vr.dm @@ -11,6 +11,8 @@ do_colouration = 0 //Set to 1 to enable coloration using the tail color. species_allowed = list(SPECIES_HUMAN, SPECIES_SKRELL, SPECIES_UNATHI, SPECIES_TAJ, SPECIES_TESHARI, SPECIES_NEVREAN, SPECIES_AKULA, SPECIES_SERGAL, SPECIES_FENNEC, SPECIES_ZORREN_HIGH, SPECIES_VULPKANIN, SPECIES_XENOCHIMERA, SPECIES_XENOHYBRID, SPECIES_VASILISSAN, SPECIES_RAPALA, SPECIES_PROTEAN, SPECIES_ALRAUNE, SPECIES_WEREBEAST, SPECIES_SHADEKIN, SPECIES_SHADEKIN_CREW) //This lets all races use + var/list/lower_layer_dirs = list(SOUTH) + /datum/sprite_accessory/tail/New() . = ..() if(clip_mask_icon && clip_mask_state) @@ -1175,6 +1177,14 @@ color_blend_mode = ICON_MULTIPLY ckeys_allowed = list("prettiebyrd") +/datum/sprite_accessory/tail/altevian + name = "Altevian Tail" + icon = 'icons/mob/vore/tails_vr.dmi' + icon_state = "altevian" + do_colouration = 1 + color_blend_mode = ICON_MULTIPLY + lower_layer_dirs = list(SOUTH, WEST) + /datum/sprite_accessory/tail/tentacle name = "Tentacle, colorable (vwag)" desc = "" @@ -1201,4 +1211,4 @@ /datum/sprite_accessory/tail/longtail/shadekin_tail/shadekin_tail_long name = "Shadekin Long Tail" - icon_state = "shadekin_long_s" + icon_state = "shadekin_long_s" \ No newline at end of file diff --git a/icons/mob/vore/tails_vr.dmi b/icons/mob/vore/tails_vr.dmi index d5a4d7ad574bd7247c49884a319d2a13f922a3d2..1b2e94607983177b77d3f67fda081653df392ecb 100644 GIT binary patch delta 5332 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 z

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