Felinid/catpeople are now their own human subspecies (#39513)

* Catpeople are nyow a species

* Fixes a runtime

* Fixes the issues with being forced ears when you chose none

* Neko --> Felinid

* P2

* Update

* Working this time I promise
This commit is contained in:
kevinz000
2018-08-08 10:56:46 -07:00
committed by yogstation13-bot
parent 673eaa4085
commit 9e9995846d
16 changed files with 238 additions and 190 deletions

View File

@@ -58,9 +58,7 @@
#define iszombie(A) (is_species(A, /datum/species/zombie))
#define ismoth(A) (is_species(A, /datum/species/moth))
#define ishumanbasic(A) (is_species(A, /datum/species/human))
//why arent catpeople a subspecies
#define iscatperson(A) (ishumanbasic(A) && ( A.dna.features["ears"] == "Cat" || A.dna.features["tail_human"] == "Cat") )
#define iscatperson(A) (ishumanbasic(A) && istype(A.dna.species, /datum/species/human/felinid) )
//more carbon mobs
#define ismonkey(A) (istype(A, /mob/living/carbon/monkey))

View File

@@ -215,17 +215,21 @@
stored_dna.species = mrace //not calling any species update procs since we're a brain, not a monkey/human
/mob/living/carbon/set_species(datum/species/mrace, icon_update = 1)
/mob/living/carbon/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE)
if(mrace && has_dna())
dna.species.on_species_loss(src)
var/old_species = dna.species
var/datum/species/new_race
if(ispath(mrace))
dna.species = new mrace()
new_race = new mrace
else if(istype(mrace))
new_race = mrace
else
dna.species = mrace
dna.species.on_species_gain(src, old_species)
return
dna.species.on_species_loss(src, new_race, pref_load)
var/datum/species/old_species = dna.species
dna.species = new_race
dna.species.on_species_gain(src, old_species, pref_load)
/mob/living/carbon/human/set_species(datum/species/mrace, icon_update = 1)
/mob/living/carbon/human/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE)
..()
if(icon_update)
update_body()

View File

@@ -84,8 +84,8 @@
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
if(iscatperson(H))
H.startTailWag()
addtimer(CALLBACK(H, /mob/living/carbon/human.proc/endTailWag), 30)
H.dna.species.start_wagging_tail(H)
addtimer(CALLBACK(H.dna.species, /datum/species.proc/stop_wagging_tail, H), 30)
description = "<span class='nicegreen'>They want to play on the table!</span>\n"
mood_change = 2

View File

@@ -609,7 +609,8 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
/obj/item/slapper/attack(mob/M, mob/living/carbon/human/user)
if(ishuman(M))
var/mob/living/carbon/human/L = M
L.endTailWag()
if(L && L.dna && L.dna.species)
L.dna.species.stop_wagging_tail(M)
if(user.a_intent != INTENT_HARM && ((user.zone_selected == BODY_ZONE_PRECISE_MOUTH) || (user.zone_selected == BODY_ZONE_PRECISE_EYES) || (user.zone_selected == BODY_ZONE_HEAD)))
user.do_attack_animation(M)
playsound(M, 'sound/weapons/slap.ogg', 50, 1, -1)

View File

@@ -1201,82 +1201,6 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
log_admin("[key_name(usr)] sent \"[input]\" as the Tip of the Round.")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Tip")
/proc/mass_purrbation()
for(var/M in GLOB.mob_list)
if(ishumanbasic(M))
purrbation_apply(M)
CHECK_TICK
/proc/mass_remove_purrbation()
for(var/M in GLOB.mob_list)
if(ishumanbasic(M))
purrbation_remove(M)
CHECK_TICK
/proc/purrbation_toggle(mob/living/carbon/human/H, silent = FALSE)
if(!ishumanbasic(H))
return
if(!iscatperson(H))
purrbation_apply(H, silent)
. = TRUE
else
purrbation_remove(H, silent)
. = FALSE
/proc/purrbation_apply(mob/living/carbon/human/H, silent = FALSE)
if(!ishuman(H))
return
if(iscatperson(H))
return
var/obj/item/organ/ears/cat/ears = new
var/obj/item/organ/tail/cat/tail = new
ears.Insert(H, drop_if_replaced=FALSE)
tail.Insert(H, drop_if_replaced=FALSE)
if(!silent)
to_chat(H, "Something is nya~t right.")
playsound(get_turf(H), 'sound/effects/meow1.ogg', 50, 1, -1)
/proc/purrbation_remove(mob/living/carbon/human/H, silent = FALSE)
if(!ishuman(H))
return
if(!iscatperson(H))
return
var/obj/item/organ/ears/cat/ears = H.getorgan(/obj/item/organ/ears/cat)
var/obj/item/organ/tail/cat/tail = H.getorgan(/obj/item/organ/tail/cat)
if(ears)
var/obj/item/organ/ears/NE
if(H.dna.species && H.dna.species.mutantears)
// Roundstart cat ears override H.dna.species.mutantears, reset it here.
H.dna.species.mutantears = initial(H.dna.species.mutantears)
if(H.dna.species.mutantears)
NE = new H.dna.species.mutantears()
if(!NE)
// Go with default ears
NE = new /obj/item/organ/ears()
NE.Insert(H, drop_if_replaced = FALSE)
if(tail)
var/obj/item/organ/tail/NT
if(H.dna.species && H.dna.species.mutanttail)
// Roundstart cat tail overrides H.dna.species.mutanttail, reset it here.
H.dna.species.mutanttail = initial(H.dna.species.mutanttail)
if(H.dna.species.mutanttail)
NT = new H.dna.species.mutanttail()
if(NT)
NT.Insert(H, drop_if_replaced = FALSE)
else
tail.Remove(H)
if(!silent)
to_chat(H, "You are no longer a cat.")
/client/proc/modify_goals()
set category = "Debug"
set name = "Modify goals"

View File

@@ -405,8 +405,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "</td>"
mutant_category = 0
if(CONFIG_GET(flag/join_with_mutant_humans))
if("tail_human" in pref_species.default_features)
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -433,6 +431,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "</td>"
mutant_category = 0
if(CONFIG_GET(flag/join_with_mutant_humans))
if("wings" in pref_species.default_features && GLOB.r_wings_list.len >1)
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -1645,7 +1645,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
chosen_species = /datum/species/human
pref_species = new /datum/species/human
save_character()
character.set_species(chosen_species, icon_update=0)
character.set_species(chosen_species, icon_update = FALSE, pref_load = TRUE)
if(icon_updates)
character.update_body()

View File

@@ -226,7 +226,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["species"] >> species_id
if(species_id)
var/newtype = GLOB.species_list[species_id]
pref_species = new newtype()
if(newtype)
pref_species = new newtype
if(!S["features["mcolor"]"] || S["features["mcolor"]"] == "#000")
WRITE_FILE(S["features["mcolor"]"] , "#FFF")

View File

@@ -82,7 +82,6 @@
if(H.dna.species.id != "human")
H.set_species(/datum/species/human)
H.apply_pref_name("human", H.client)
purrbation_remove(H, silent=TRUE)
//Equip the rest of the gear
H.dna.species.before_equip_job(src, H, visualsOnly)

View File

@@ -77,54 +77,27 @@
if(!.)
return
var/mob/living/carbon/human/H = user
if(!H.is_wagging_tail())
H.startTailWag()
if(!istype(H) || !H.dna || !H.dna.species || !H.dna.species.can_wag_tail(H))
return
if(!H.dna.species.is_wagging_tail())
H.dna.species.start_wagging_tail(H)
else
H.endTailWag()
/mob/living/carbon/human/proc/is_wagging_tail()
return (dna && dna.species && (("waggingtail_lizard" in dna.species.mutant_bodyparts) || ("waggingtail_human" in dna.species.mutant_bodyparts)))
H.dna.species.stop_wagging_tail(H)
/datum/emote/living/carbon/human/wag/can_run_emote(mob/user, status_check = TRUE)
if(!..())
return FALSE
var/mob/living/carbon/human/H = user
if(H.dna && H.dna.species && (("tail_lizard" in H.dna.species.mutant_bodyparts) || ("waggingtail_lizard" in H.dna.species.mutant_bodyparts) || ("tail_human" in H.dna.species.mutant_bodyparts) || ("waggingtail_human" in H.dna.species.mutant_bodyparts)))
return TRUE
return H.dna && H.dna.species && H.dna.species.can_wag_tail(user)
/datum/emote/living/carbon/human/wag/select_message_type(mob/user)
. = ..()
var/mob/living/carbon/human/H = user
if(H.is_wagging_tail())
if(!H.dna || !H.dna.species)
return
if(H.dna.species.is_wagging_tail())
. = null
//Don't know where else to put this, it's basically an emote
/mob/living/carbon/human/proc/startTailWag()
if(!dna || !dna.species)
return
if("tail_lizard" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "tail_lizard"
dna.species.mutant_bodyparts -= "spines"
dna.species.mutant_bodyparts |= "waggingtail_lizard"
dna.species.mutant_bodyparts |= "waggingspines"
if("tail_human" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "tail_human"
dna.species.mutant_bodyparts |= "waggingtail_human"
update_body()
/mob/living/carbon/human/proc/endTailWag()
if(!dna || !dna.species)
return
if("waggingtail_lizard" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "waggingtail_lizard"
dna.species.mutant_bodyparts -= "waggingspines"
dna.species.mutant_bodyparts |= "tail_lizard"
dna.species.mutant_bodyparts |= "spines"
if("waggingtail_human" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "waggingtail_human"
dna.species.mutant_bodyparts |= "tail_human"
update_body()
/datum/emote/living/carbon/human/wing
key = "wing"
key_third_person = "wings"

View File

@@ -242,7 +242,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/obj/item/organ/I = new path()
I.Insert(C)
/datum/species/proc/on_species_gain(mob/living/carbon/C, datum/species/old_species)
/datum/species/proc/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load)
// Drop the items the new species can't wear
for(var/slot_id in no_equip)
var/obj/item/thing = C.get_item_by_slot(slot_id)
@@ -287,7 +287,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
A.cure(FALSE)
/datum/species/proc/on_species_loss(mob/living/carbon/C)
/datum/species/proc/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
if(C.dna.species.exotic_bloodtype)
C.dna.blood_type = random_blood_type()
if(DIGITIGRADE in species_traits)
@@ -1665,3 +1665,17 @@ GLOBAL_LIST_EMPTY(roundstart_races)
/datum/species/proc/negates_gravity(mob/living/carbon/human/H)
return 0
////////////////
//Tail Wagging//
////////////////
/datum/species/proc/can_wag_tail(mob/living/carbon/human/H)
return FALSE
/datum/species/proc/is_wagging_tail(mob/living/carbon/human/H)
return FALSE
/datum/species/proc/start_wagging_tail(mob/living/carbon/human/H)
/datum/species/proc/stop_wagging_tail(mob/living/carbon/human/H)

View File

@@ -0,0 +1,130 @@
//Subtype of human
/datum/species/human/felinid
name = "Felinid"
id = "felinid"
limbs_id = "human"
mutant_bodyparts = list("ears", "tail_human")
default_features = list("mcolor" = "FFF", "tail_human" = "Cat", "ears" = "Cat", "wings" = "None")
mutantears = /obj/item/organ/ears/cat
mutanttail = /obj/item/organ/tail/cat
/datum/species/human/felinid/qualifies_for_rank(rank, list/features)
return TRUE
//Curiosity killed the cat's wagging tail.
/datum/species/human/felinid/spec_death(gibbed, mob/living/carbon/human/H)
if(H)
stop_wagging_tail(H)
/datum/species/human/felinid/spec_stun(mob/living/carbon/human/H,amount)
if(H)
stop_wagging_tail(H)
. = ..()
/datum/species/human/felinid/can_wag_tail(mob/living/carbon/human/H)
return ("tail_human" in mutant_bodyparts) || ("waggingtail_human" in mutant_bodyparts)
/datum/species/human/felinid/is_wagging_tail(mob/living/carbon/human/H)
return ("waggingtail_human" in mutant_bodyparts)
/datum/species/human/felinid/start_wagging_tail(mob/living/carbon/human/H)
if("tail_human" in mutant_bodyparts)
mutant_bodyparts -= "tail_human"
mutant_bodyparts |= "waggingtail_human"
H.update_body()
/datum/species/human/felinid/stop_wagging_tail(mob/living/carbon/human/H)
if("waggingtail_human" in mutant_bodyparts)
mutant_bodyparts -= "waggingtail_human"
mutant_bodyparts |= "tail_human"
H.update_body()
/datum/species/human/felinid/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load)
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(!pref_load) //Hah! They got forcefully purrbation'd. Force default felinid parts on them if they have no mutant parts in those areas!
if(H.dna.features["tail_human"] == "None")
H.dna.features["tail_human"] = "Cat"
if(H.dna.features["ears"] == "None")
H.dna.features["ears"] = "Cat"
if(H.dna.features["ears"] == "Cat")
var/obj/item/organ/ears/cat/ears = new
ears.Insert(H, drop_if_replaced = FALSE)
else
mutantears = /obj/item/organ/ears
if(H.dna.features["tail_human"] == "Cat")
var/obj/item/organ/tail/cat/tail = new
tail.Insert(H, drop_if_replaced = FALSE)
else
mutanttail = null
return ..()
/datum/species/human/felinid/on_species_loss(mob/living/carbon/H, datum/species/new_species, pref_load)
var/obj/item/organ/ears/cat/ears = H.getorgan(/obj/item/organ/ears/cat)
var/obj/item/organ/tail/cat/tail = H.getorgan(/obj/item/organ/tail/cat)
if(ears)
var/obj/item/organ/ears/NE
if(new_species && new_species.mutantears)
// Roundstart cat ears override new_species.mutantears, reset it here.
new_species.mutantears = initial(new_species.mutantears)
if(new_species.mutantears)
NE = new new_species.mutantears
if(!NE)
// Go with default ears
NE = new /obj/item/organ/ears
NE.Insert(H, drop_if_replaced = FALSE)
if(tail)
var/obj/item/organ/tail/NT
if(new_species && new_species.mutanttail)
// Roundstart cat tail overrides new_species.mutanttail, reset it here.
new_species.mutanttail = initial(new_species.mutanttail)
if(new_species.mutanttail)
NT = new new_species.mutanttail
if(NT)
NT.Insert(H, drop_if_replaced = FALSE)
else
tail.Remove(H)
/proc/mass_purrbation()
for(var/M in GLOB.mob_list)
if(ishumanbasic(M))
purrbation_apply(M)
CHECK_TICK
/proc/mass_remove_purrbation()
for(var/M in GLOB.mob_list)
if(ishumanbasic(M))
purrbation_remove(M)
CHECK_TICK
/proc/purrbation_toggle(mob/living/carbon/human/H, silent = FALSE)
if(!ishumanbasic(H))
return
if(!iscatperson(H))
purrbation_apply(H, silent)
. = TRUE
else
purrbation_remove(H, silent)
. = FALSE
/proc/purrbation_apply(mob/living/carbon/human/H, silent = FALSE)
if(!ishuman(H) || iscatperson(H))
return
H.set_species(/datum/species/human/felinid)
if(!silent)
to_chat(H, "Something is nya~t right.")
playsound(get_turf(H), 'sound/effects/meow1.ogg', 50, 1, -1)
/proc/purrbation_remove(mob/living/carbon/human/H, silent = FALSE)
if(!ishuman(H) || !iscatperson(H))
return
H.set_species(/datum/species/human)
if(!silent)
to_chat(H, "You are no longer a cat.")

View File

@@ -3,29 +3,11 @@
id = "human"
default_color = "FFFFFF"
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS)
default_features = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "wings" = "None")
default_features = list("mcolor" = "FFF", "wings" = "None")
use_skintones = 1
skinned_type = /obj/item/stack/sheet/animalhide/human
disliked_food = GROSS | RAW
liked_food = JUNKFOOD | FRIED
/datum/species/human/qualifies_for_rank(rank, list/features)
return TRUE //Pure humans are always allowed in all roles.
//Curiosity killed the cat's wagging tail.
/datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
if(H)
H.endTailWag()
/datum/species/human/spec_stun(mob/living/carbon/human/H,amount)
if(H)
H.endTailWag()
. = ..()
/datum/species/human/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
if(H.dna.features["ears"] == "Cat")
mutantears = /obj/item/organ/ears/cat
if(H.dna.features["tail_human"] == "Cat")
mutanttail = /obj/item/organ/tail/cat
..()

View File

@@ -38,13 +38,35 @@
//I wag in death
/datum/species/lizard/spec_death(gibbed, mob/living/carbon/human/H)
if(H)
H.endTailWag()
stop_wagging_tail(H)
/datum/species/lizard/spec_stun(mob/living/carbon/human/H,amount)
if(H)
H.endTailWag()
stop_wagging_tail(H)
. = ..()
/datum/species/lizard/can_wag_tail(mob/living/carbon/human/H)
return ("tail_lizard" in mutant_bodyparts) || ("waggingtail_lizard" in mutant_bodyparts)
/datum/species/lizard/is_wagging_tail(mob/living/carbon/human/H)
return ("waggingtail_lizard" in mutant_bodyparts)
/datum/species/lizard/start_wagging_tail(mob/living/carbon/human/H)
if("tail_lizard" in mutant_bodyparts)
mutant_bodyparts -= "tail_lizard"
mutant_bodyparts -= "spines"
mutant_bodyparts |= "waggingtail_lizard"
mutant_bodyparts |= "waggingspines"
H.update_body()
/datum/species/lizard/stop_wagging_tail(mob/living/carbon/human/H)
if("waggingtail_lizard" in mutant_bodyparts)
mutant_bodyparts -= "waggingtail_lizard"
mutant_bodyparts -= "waggingspines"
mutant_bodyparts |= "tail_lizard"
mutant_bodyparts |= "spines"
H.update_body()
/*
Lizard subspecies: ASHWALKERS
*/

View File

@@ -10,9 +10,8 @@
/obj/item/organ/tail/Remove(mob/living/carbon/human/H, special = 0)
..()
if(istype(H))
H.endTailWag()
if(H && H.dna && H.dna.species)
H.dna.species.stop_wagging_tail(H)
/obj/item/organ/tail/cat
name = "cat tail"

View File

@@ -1901,6 +1901,7 @@
#include "code\modules\mob\living\carbon\human\species_types\angel.dm"
#include "code\modules\mob\living\carbon\human\species_types\corporate.dm"
#include "code\modules\mob\living\carbon\human\species_types\dullahan.dm"
#include "code\modules\mob\living\carbon\human\species_types\felinid.dm"
#include "code\modules\mob\living\carbon\human\species_types\flypeople.dm"
#include "code\modules\mob\living\carbon\human\species_types\golems.dm"
#include "code\modules\mob\living\carbon\human\species_types\humans.dm"