From bbfc6db0a3d30100b4bfa5b2bd7ab500b4c6ae29 Mon Sep 17 00:00:00 2001 From: Zuhayr Date: Tue, 23 Dec 2014 17:37:33 +1030 Subject: [PATCH] Refactored gibbing and slipping for carbon mobs, entirely removed mutantrace var. This commit is only partial, following commits are contiguous to it (lol this is atomic right) --- baystation12.dme | 19 +- .../computer3/computers/scanconsole.dm | 7 - code/WorkInProgress/computer3/file.dm | 1 - code/__HELPERS/global_lists.dm | 9 +- code/datums/datumvars.dm | 24 +- code/game/dna/dna2.dm | 2 - code/game/gamemodes/heist/heist.dm | 1 - code/game/machinery/kitchen/gibber.dm | 226 +++---- code/game/machinery/machinery.dm | 2 +- code/game/objects/effects/effect_system.dm | 15 +- code/game/objects/effects/gibs.dm | 17 +- .../objects/effects/spawners/gibspawner.dm | 9 - code/game/objects/items/devices/PDA/PDA.dm | 16 +- code/game/objects/items/weapons/cards_ids.dm | 1 + .../game/objects/items/weapons/clown_items.dm | 27 +- code/game/turfs/simulated.dm | 79 +-- code/modules/admin/verbs/modifyvariables.dm | 2 +- code/modules/admin/verbs/one_click_antag.dm | 1 - code/modules/awaymissions/corpse.dm | 4 +- code/modules/client/preferences.dm | 22 +- code/modules/client/preferences_savefile.dm | 2 +- code/modules/food/recipes_microwave.dm | 31 - code/modules/mob/living/carbon/brain/MMI.dm | 2 +- code/modules/mob/living/carbon/carbon.dm | 12 +- code/modules/mob/living/carbon/human/death.dm | 38 +- code/modules/mob/living/carbon/human/human.dm | 10 +- .../living/carbon/human/human_attackhand.dm | 2 +- code/modules/mob/living/carbon/human/life.dm | 91 +-- .../mob/living/carbon/human/species.dm | 582 ------------------ .../carbon/human/species/outsider/shadow.dm | 8 + .../carbon/human/species/outsider/vox.dm | 97 +++ .../living/carbon/human/species/species.dm | 221 +++++++ .../carbon/human/species/species_attack.dm | 263 ++++++++ .../carbon/human/species/species_hud.dm | 53 ++ .../carbon/human/species/station/golem.dm | 17 + .../carbon/human/species/station/slime.dm | 10 + .../carbon/human/species/station/station.dm | 207 +++++++ .../xenomorphs}/alien_embryo.dm | 0 .../xenomorphs}/alien_facehugger.dm | 0 .../xenomorphs}/alien_powers.dm | 0 .../xenomorphs}/alien_species.dm | 2 +- .../xenomorphs/xenomorphs.dm} | 0 .../mob/living/carbon/human/unarmed_attack.dm | 254 -------- .../mob/living/carbon/human/update_icons.dm | 72 +-- .../modules/mob/living/carbon/metroid/life.dm | 8 +- .../mob/living/carbon/metroid/metroid.dm | 12 +- .../mob/living/carbon/monkey/monkey.dm | 12 - code/modules/mob/living/living.dm | 5 +- code/modules/mob/living/silicon/death.dm | 2 +- .../simple_animal/friendly/spiderbot.dm | 2 +- .../mob/living/simple_animal/simple_animal.dm | 72 +-- code/modules/mob/mob.dm | 2 +- code/modules/mob/new_player/new_player.dm | 6 +- code/modules/projectiles/gun.dm | 14 +- .../modules/projectiles/projectile/special.dm | 2 - code/modules/reagents/Chemistry-Reagents.dm | 7 +- .../reagent_containers/food/snacks/grown.dm | 13 +- .../reagent_containers/food/snacks/meat.dm | 8 +- code/modules/surgery/surgery.dm | 2 +- code/setup.dm | 31 +- 60 files changed, 1213 insertions(+), 1443 deletions(-) delete mode 100644 code/modules/mob/living/carbon/human/species.dm create mode 100644 code/modules/mob/living/carbon/human/species/outsider/shadow.dm create mode 100644 code/modules/mob/living/carbon/human/species/outsider/vox.dm create mode 100644 code/modules/mob/living/carbon/human/species/species.dm create mode 100644 code/modules/mob/living/carbon/human/species/species_attack.dm create mode 100644 code/modules/mob/living/carbon/human/species/species_hud.dm create mode 100644 code/modules/mob/living/carbon/human/species/station/golem.dm create mode 100644 code/modules/mob/living/carbon/human/species/station/slime.dm create mode 100644 code/modules/mob/living/carbon/human/species/station/station.dm rename code/modules/mob/living/carbon/human/{alien => species/xenomorphs}/alien_embryo.dm (100%) rename code/modules/mob/living/carbon/human/{alien => species/xenomorphs}/alien_facehugger.dm (100%) rename code/modules/mob/living/carbon/human/{alien => species/xenomorphs}/alien_powers.dm (100%) rename code/modules/mob/living/carbon/human/{alien => species/xenomorphs}/alien_species.dm (99%) rename code/modules/mob/living/carbon/human/{alien/alien.dm => species/xenomorphs/xenomorphs.dm} (100%) diff --git a/baystation12.dme b/baystation12.dme index 24731e803e..bc352f8f24 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1037,15 +1037,22 @@ #include "code\modules\mob\living\carbon\human\login.dm" #include "code\modules\mob\living\carbon\human\logout.dm" #include "code\modules\mob\living\carbon\human\say.dm" -#include "code\modules\mob\living\carbon\human\species.dm" #include "code\modules\mob\living\carbon\human\unarmed_attack.dm" #include "code\modules\mob\living\carbon\human\update_icons.dm" #include "code\modules\mob\living\carbon\human\whisper.dm" -#include "code\modules\mob\living\carbon\human\alien\alien.dm" -#include "code\modules\mob\living\carbon\human\alien\alien_embryo.dm" -#include "code\modules\mob\living\carbon\human\alien\alien_facehugger.dm" -#include "code\modules\mob\living\carbon\human\alien\alien_powers.dm" -#include "code\modules\mob\living\carbon\human\alien\alien_species.dm" +#include "code\modules\mob\living\carbon\human\species\species.dm" +#include "code\modules\mob\living\carbon\human\species\species_attack.dm" +#include "code\modules\mob\living\carbon\human\species\species_hud.dm" +#include "code\modules\mob\living\carbon\human\species\outsider\shadow.dm" +#include "code\modules\mob\living\carbon\human\species\outsider\vox.dm" +#include "code\modules\mob\living\carbon\human\species\station\golem.dm" +#include "code\modules\mob\living\carbon\human\species\station\slime.dm" +#include "code\modules\mob\living\carbon\human\species\station\station.dm" +#include "code\modules\mob\living\carbon\human\species\xenomorphs\alien_embryo.dm" +#include "code\modules\mob\living\carbon\human\species\xenomorphs\alien_facehugger.dm" +#include "code\modules\mob\living\carbon\human\species\xenomorphs\alien_powers.dm" +#include "code\modules\mob\living\carbon\human\species\xenomorphs\alien_species.dm" +#include "code\modules\mob\living\carbon\human\species\xenomorphs\xenomorphs.dm" #include "code\modules\mob\living\carbon\metroid\death.dm" #include "code\modules\mob\living\carbon\metroid\emote.dm" #include "code\modules\mob\living\carbon\metroid\examine.dm" diff --git a/code/WorkInProgress/computer3/computers/scanconsole.dm b/code/WorkInProgress/computer3/computers/scanconsole.dm index 3092f51fb8..446fb5c8ff 100644 --- a/code/WorkInProgress/computer3/computers/scanconsole.dm +++ b/code/WorkInProgress/computer3/computers/scanconsole.dm @@ -189,17 +189,10 @@ target.unique_enzymes = md5(target.real_name) updateappearance(scanner.occupant,target.uni_identity) domutcheck(scanner.occupant, scanner, 1) - - if(ishuman(scanner.occupant)) - target.mutantrace = buffer.mutantrace - scanner.occupant:update_mutantrace() if("se") if(buffer.struc_enzymes) target.struc_enzymes = buffer.struc_enzymes domutcheck(scanner.occupant, scanner, 1) - if(ishuman(scanner.occupant)) - target.mutantrace = buffer.mutantrace - scanner.occupant:update_mutantrace() if("ui") if(buffer.uni_identity) target.uni_identity = buffer.uni_identity diff --git a/code/WorkInProgress/computer3/file.dm b/code/WorkInProgress/computer3/file.dm index 849312ec50..1cbb363894 100644 --- a/code/WorkInProgress/computer3/file.dm +++ b/code/WorkInProgress/computer3/file.dm @@ -140,7 +140,6 @@ /datum/file/data/genome/SE name = "Structural Enzymes" - var/mutantrace = null /datum/file/data/genome/UE name = "Unique Enzymes" diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index c16aac30f7..67e7dd2948 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -22,8 +22,9 @@ var/global/list/joblist = list() //list of all jobstypes, minus borg and AI //Languages/species/whitelist. var/global/list/all_species[0] var/global/list/all_languages[0] -var/global/list/language_keys[0] //table of say codes for all languages -var/global/list/whitelisted_species = list("Human") +var/global/list/language_keys[0] // Table of say codes for all languages +var/global/list/whitelisted_species = list("Human") // Species that require a whitelist check. +var/global/list/playable_species = list("Human") // A list of ALL playable species, whitelisted, latejoin or otherwise. // Posters var/global/list/poster_designs = list() @@ -119,6 +120,8 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al S.race_key = rkey //Used in mob icon caching. all_species[S.name] = S + if(!(S.flags & IS_RESTRICTED)) + playable_species += S.name if(S.flags & IS_WHITELISTED) whitelisted_species += S.name @@ -127,7 +130,7 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al for(var/T in paths) var/datum/poster/P = new T poster_designs += P - + return 1 /* // Uncomment to debug chemical reaction list. diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index ceaca9c3ee..e666a03653 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -268,7 +268,6 @@ client body += "" if(ishuman(D)) body += "" - body += "" body += "" body += "" body += "" @@ -582,7 +581,7 @@ client usr << "This can only be used on instances of type /mob/living/carbon/human" return - H.makeSkeleton() + H.ChangeToSkeleton() href_list["datumrefresh"] = href_list["make_skeleton"] else if(href_list["delall"]) @@ -744,27 +743,6 @@ client return holder.Topic(href, list("makeai"=href_list["makeai"])) - else if(href_list["setmutantrace"]) - if(!check_rights(R_SPAWN)) return - - var/mob/living/carbon/human/H = locate(href_list["setmutantrace"]) - if(!istype(H)) - usr << "This can only be done to instances of type /mob/living/carbon/human" - return - - var/new_mutantrace = input("Please choose a new mutantrace","Mutantrace",null) as null|anything in list("NONE","golem","lizard","slime","plant","shadow","tajaran","skrell","vox") - switch(new_mutantrace) - if(null) - return - if("NONE") - new_mutantrace = "" - if(!H) - usr << "Mob doesn't exist anymore" - return - if(H.dna) - H.dna.mutantrace = new_mutantrace - H.update_mutantrace() - else if(href_list["setspecies"]) if(!check_rights(R_SPAWN)) return diff --git a/code/game/dna/dna2.dm b/code/game/dna/dna2.dm index 32c7ef1dd6..e30de18f4e 100644 --- a/code/game/dna/dna2.dm +++ b/code/game/dna/dna2.dm @@ -80,7 +80,6 @@ var/global/list/datum/dna/gene/dna_genes[0] // From old dna. var/b_type = "A+" // Should probably change to an integer => string map but I'm lazy. - var/mutantrace = null // The type of mutant race the player is, if applicable (i.e. potato-man) var/real_name // Stores the real name of the person who originally got this dna datum. Used primarily for changelings, // New stuff @@ -92,7 +91,6 @@ var/global/list/datum/dna/gene/dna_genes[0] var/datum/dna/new_dna = new() new_dna.unique_enzymes=unique_enzymes new_dna.b_type=b_type - new_dna.mutantrace=mutantrace new_dna.real_name=real_name new_dna.species=species for(var/b=1;b<=DNA_SE_LENGTH;b++) diff --git a/code/game/gamemodes/heist/heist.dm b/code/game/gamemodes/heist/heist.dm index 14e1b5a30e..8157acc1a0 100644 --- a/code/game/gamemodes/heist/heist.dm +++ b/code/game/gamemodes/heist/heist.dm @@ -102,7 +102,6 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind' vox.name = vox.real_name newraider.name = vox.name vox.age = rand(12,20) - vox.dna.mutantrace = "vox" vox.set_species("Vox") vox.languages = list() // Removing language from chargen. vox.flavor_text = "" diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index a005d0e9d4..cad72d9d96 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -8,8 +8,11 @@ anchored = 1 var/operating = 0 //Is it on? var/dirty = 0 // Does it need cleaning? - var/gibtime = 40 // Time from starting until meat appears var/mob/living/occupant // Mob who has been put inside + + var/gib_time = 40 // Time from starting until meat appears + var/gib_throw_dir // Direction to spit meat and gibs in. + use_power = 1 idle_power_usage = 2 active_power_usage = 500 @@ -18,31 +21,31 @@ /obj/machinery/gibber/autogibber var/turf/input_plate - New() - ..() - spawn(5) - for(var/i in cardinal) - var/obj/machinery/mineral/input/input_obj = locate( /obj/machinery/mineral/input, get_step(src.loc, i) ) - if(input_obj) - if(isturf(input_obj.loc)) - input_plate = input_obj.loc - del(input_obj) - break +/obj/machinery/gibber/autogibber/New() + ..() + spawn(5) + for(var/i in cardinal) + var/obj/machinery/mineral/input/input_obj = locate( /obj/machinery/mineral/input, get_step(src.loc, i) ) + if(input_obj) + if(isturf(input_obj.loc)) + input_plate = input_obj.loc + del(input_obj) + break - if(!input_plate) - log_misc("a [src] didn't find an input plate.") - return + if(!input_plate) + log_misc("a [src] didn't find an input plate.") + return - Bumped(var/atom/A) - if(!input_plate) return +/obj/machinery/gibber/autogibber/Bumped(var/atom/A) + if(!input_plate) return - if(ismob(A)) - var/mob/M = A + if(ismob(A)) + var/mob/M = A - if(M.loc == input_plate - ) - M.loc = src - M.gib() + if(M.loc == input_plate + ) + M.loc = src + M.gib() /obj/machinery/gibber/New() @@ -70,43 +73,70 @@ if(stat & (NOPOWER|BROKEN)) return if(operating) - user << "\red It's locked and running" + user << "The gibber is locked and running, wait for it to finish." return else src.startgibbing(user) -/obj/machinery/gibber/attackby(obj/item/weapon/grab/G as obj, mob/user as mob) - if(src.occupant) - user << "\red The gibber is full, empty it first!" +/obj/machinery/gibber/attackby(var/obj/item/W, var/mob/user) + + if(istype(W,/obj/item/weapon/card/emag)) + if(emagged) + user << "The gibber safety guard is already disabled." + return + user << "You disable the gibber safety guard." + emagged = 1 return - if( !(istype(G, /obj/item/weapon/grab)) ) - user << "\red This item is not suitable for the gibber!" - return + var/obj/item/weapon/grab/G = W - if( !(istype(G.affecting, /mob/living/carbon)) && !(istype(G.affecting, /mob/living/simple_animal)) ) - user << "\red This item is not suitable for the gibber!" - return + if(!istype(G)) + return ..() if(G.state < 2) - user << "\red You need a better grip to do that!" + user << "You need a better grip to do that!" return - if(G.affecting.abiotic(1)) - user << "\red Subject may not have abiotic items on." + move_into_gibber(user,G.affecting) + // Grab() process should clean up the grab item, no need to del it. + +/obj/machinery/gibber/MouseDrop_T(mob/target, mob/user) + if(user.stat || user.restrained()) + return + move_into_gibber(user,target) + +/obj/machinery/gibber/proc/move_into_gibber(var/mob/user,var/mob/living/victim) + + if(src.occupant) + user << "The gibber is full, empty it first!" return - user.visible_message("\red [user] starts to put [G.affecting] into the gibber!") + if(operating) + user << "The gibber is locked and running, wait for it to finish." + return + + if(!(istype(victim, /mob/living/carbon)) && !(istype(victim, /mob/living/simple_animal)) ) + user << "This is not suitable for the gibber!" + return + + if(istype(victim,/mob/living/carbon/human) && !emagged) + user << "The gibber safety guard is engaged!" + return + + + if(victim.abiotic(1)) + user << "Subject may not have abiotic items on." + return + + user.visible_message("\red [user] starts to put [victim] into the gibber!") src.add_fingerprint(user) - if(do_after(user, 30) && G && G.affecting && !occupant) - user.visible_message("\red [user] stuffs [G.affecting] into the gibber!") - var/mob/M = G.affecting - if(M.client) - M.client.perspective = EYE_PERSPECTIVE - M.client.eye = src - M.loc = src - src.occupant = M - del(G) + if(do_after(user, 30) && victim.Adjacent(src) && user.Adjacent(src) && victim.Adjacent(user) && !occupant) + user.visible_message("\red [user] stuffs [victim] into the gibber!") + if(victim.client) + victim.client.perspective = EYE_PERSPECTIVE + victim.client.eye = src + victim.loc = src + src.occupant = victim update_icon() /obj/machinery/gibber/verb/eject() @@ -121,7 +151,7 @@ return /obj/machinery/gibber/proc/go_out() - if (!src.occupant) + if(operating || !src.occupant) return for(var/obj/O in src) O.loc = src.loc @@ -138,86 +168,62 @@ if(src.operating) return if(!src.occupant) - visible_message("\red You hear a loud metallic grinding sound.") + visible_message("You hear a loud metallic grinding sound.") return use_power(1000) - visible_message("\red You hear a loud squelchy grinding sound.") + visible_message("You hear a loud squelchy grinding sound.") src.operating = 1 update_icon() - var/totalslabs = 3 - var/obj/item/weapon/reagent_containers/food/snacks/meat/allmeat[totalslabs] + var/slab_name = occupant.name + var/slab_count = 3 + var/slab_type = /obj/item/weapon/reagent_containers/food/snacks/meat + var/slab_nutrition = src.occupant.nutrition / 15 - if( istype(src.occupant, /mob/living/carbon/human/) ) - var/sourcename = src.occupant.real_name - var/sourcejob = src.occupant.job - var/sourcenutriment = src.occupant.nutrition / 15 - var/sourcetotalreagents = src.occupant.reagents.total_volume + // Some mobs have specific meat item types. + if(istype(src.occupant,/mob/living/simple_animal)) + var/mob/living/simple_animal/critter = src.occupant + if(critter.meat_amount) + slab_count = critter.meat_amount + if(critter.meat_type) + slab_type = critter.meat_type + else if(istype(src.occupant,/mob/living/carbon/human)) + slab_name = src.occupant.real_name + slab_type = /obj/item/weapon/reagent_containers/food/snacks/meat/human + else if(istype(src.occupant, /mob/living/carbon/monkey)) + slab_type = /obj/item/weapon/reagent_containers/food/snacks/meat/monkey - for(var/i=1 to totalslabs) - var/obj/item/weapon/reagent_containers/food/snacks/meat/human/newmeat = new - newmeat.name = sourcename + newmeat.name - newmeat.subjectname = sourcename - newmeat.subjectjob = sourcejob - newmeat.reagents.add_reagent("nutriment", sourcenutriment / totalslabs) // Thehehe. Fat guys go first - src.occupant.reagents.trans_to(newmeat, round (sourcetotalreagents / totalslabs, 1)) // Transfer all the reagents from the - allmeat[i] = newmeat + // Small mobs don't give as much nutrition. + if(src.occupant.small) + slab_nutrition *= 0.5 + slab_nutrition /= slab_count - src.occupant.attack_log += "\[[time_stamp()]\] Was gibbed by [user]/[user.ckey]" //One shall not simply gib a mob unnoticed! - user.attack_log += "\[[time_stamp()]\] Gibbed [src.occupant]/[src.occupant.ckey]" - msg_admin_attack("[user.name] ([user.ckey]) gibbed [src.occupant] ([src.occupant.ckey]) (JMP)") + for(var/i=1 to slab_count) + var/obj/item/weapon/reagent_containers/food/snacks/meat/new_meat = new slab_type(get_turf(src)) + new_meat.name = "[slab_name] [new_meat.name]" + new_meat.reagents.add_reagent("nutriment",slab_nutrition) - src.occupant.death(1) - src.occupant.ghostize() + if(src.occupant.reagents) + src.occupant.reagents.trans_to(new_meat, round(occupant.reagents.total_volume/slab_count,1)) - else if( istype(src.occupant, /mob/living/carbon/) || istype(src.occupant, /mob/living/simple_animal/ ) ) + src.occupant.attack_log += "\[[time_stamp()]\] Was gibbed by [user]/[user.ckey]" //One shall not simply gib a mob unnoticed! + user.attack_log += "\[[time_stamp()]\] Gibbed [src.occupant]/[src.occupant.ckey]" + msg_admin_attack("[user.name] ([user.ckey]) gibbed [src.occupant] ([src.occupant.ckey]) (JMP)") - var/sourcename = src.occupant.name - var/sourcenutriment = src.occupant.nutrition / 15 - var/sourcetotalreagents = 0 + src.occupant.ghostize() - if( istype(src.occupant, /mob/living/carbon/monkey/) || istype(src.occupant, /mob/living/carbon/alien/) ) // why are you gibbing aliens? oh well - totalslabs = 3 - sourcetotalreagents = src.occupant.reagents.total_volume - else if( istype(src.occupant, /mob/living/simple_animal/cow) || istype(src.occupant, /mob/living/simple_animal/hostile/bear) ) - totalslabs = 2 - else - totalslabs = 1 - sourcenutriment = src.occupant.nutrition / 30 // small animals don't have as much nutrition + spawn(gib_time) - for(var/i=1 to totalslabs) - var/obj/item/weapon/reagent_containers/food/snacks/meat/newmeat = new - newmeat.name = "[sourcename]-[newmeat.name]" + src.operating = 0 + src.occupant.gib() + del(src.occupant) - newmeat.reagents.add_reagent("nutriment", sourcenutriment / totalslabs) - - // Transfer reagents from the old mob to the meat - if( istype(src.occupant, /mob/living/carbon/) ) - src.occupant.reagents.trans_to(newmeat, round(sourcetotalreagents / totalslabs, 1)) - - allmeat[i] = newmeat - - if(src.occupant.client) // Gibbed a cow with a client in it? log that shit - src.occupant.attack_log += "\[[time_stamp()]\] Was gibbed by [user]/[user.ckey]" - user.attack_log += "\[[time_stamp()]\] Gibbed [src.occupant]/[src.occupant.ckey]" - msg_admin_attack("\[[time_stamp()]\] [key_name(user)] gibbed [key_name(src.occupant)]") - - src.occupant.death(1) - src.occupant.ghostize() - - del(src.occupant) - - spawn(src.gibtime) playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) operating = 0 - for (var/i=1 to totalslabs) - var/obj/item/meatslab = allmeat[i] - var/turf/Tx = locate(src.x - i, src.y, src.z) - meatslab.loc = src.loc - meatslab.throw_at(Tx,i,3,src) - if (!Tx.density) - new /obj/effect/decal/cleanable/blood/gibs(Tx,i) - src.operating = 0 + for (var/obj/item/thing in contents) + thing.loc = get_turf(thing) // Drop it onto the turf for throwing. + thing.throw_at(get_edge_target_turf(src,gib_throw_dir),rand(1,5),15) // Being pelted with bits of meat and bone would hurt. + update_icon() diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 62a24d714d..616ef4c6c9 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -378,7 +378,7 @@ Class Procs: if(istype(perp.belt, /obj/item/weapon/gun) || istype(perp.belt, /obj/item/weapon/melee)) threatcount += 2 - if(perp.dna && perp.dna.mutantrace && perp.dna.mutantrace != "none") + if(perp.species.name != "Human") //beepsky so racist. threatcount += 2 if(check_records || check_arrest) diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index db7abda850..03619c1350 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -557,18 +557,9 @@ steam.start() -- spawns the effect /obj/effect/effect/foam/Crossed(var/atom/movable/AM) if(metal) return - - if (istype(AM, /mob/living/carbon)) - var/mob/M = AM - if (istype(M, /mob/living/carbon/human) && (istype(M:shoes, /obj/item/clothing/shoes) && M:shoes.flags&NOSLIP) || M.buckled) - return - - M.stop_pulling() - M << "\blue You slipped on the foam!" - playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) - M.Stun(5) - M.Weaken(2) - + if(istype(AM, /mob/living)) + var/mob/living/M = AM + M.slip("the foam",6) /datum/effect/effect/system/foam_spread var/amount = 5 // the size of the foam spread. diff --git a/code/game/objects/effects/gibs.dm b/code/game/objects/effects/gibs.dm index 619935b8b2..c112e55fce 100644 --- a/code/game/objects/effects/gibs.dm +++ b/code/game/objects/effects/gibs.dm @@ -1,14 +1,7 @@ -/proc/gibs(atom/location, var/list/viruses, var/datum/dna/MobDNA) //CARN MARKER - new /obj/effect/gibspawner/generic(get_turf(location),viruses,MobDNA) - -/proc/hgibs(atom/location, var/list/viruses, var/datum/dna/MobDNA, var/fleshcolor, var/bloodcolor) - new /obj/effect/gibspawner/human(get_turf(location),viruses,MobDNA,fleshcolor,bloodcolor) - -/proc/xgibs(atom/location, var/list/viruses) - new /obj/effect/gibspawner/xeno(get_turf(location),viruses) - -/proc/robogibs(atom/location, var/list/viruses) - new /obj/effect/gibspawner/robot(get_turf(location),viruses) +/proc/gibs(atom/location, var/list/viruses, var/datum/dna/MobDNA, var/spawn_inside, gibber_type = /obj/effect/gibspawner/generic, var/fleshcolor, var/bloodcolor) + if(!spawn_inside) + location = get_turf(location) + new gibber_type(location,viruses,MobDNA,fleshcolor,bloodcolor) /obj/effect/gibspawner var/sparks = 0 //whether sparks spread on Gib() @@ -67,8 +60,6 @@ gib.blood_DNA = list() if(MobDNA) gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.b_type - else if(istype(src, /obj/effect/gibspawner/xeno)) - gib.blood_DNA["UNKNOWN DNA"] = "X*" else if(istype(src, /obj/effect/gibspawner/human)) // Probably a monkey gib.blood_DNA["Non-human DNA"] = "A+" var/list/directions = gibdirections[i] diff --git a/code/game/objects/effects/spawners/gibspawner.dm b/code/game/objects/effects/spawners/gibspawner.dm index 5446ba348e..b145b77ed2 100644 --- a/code/game/objects/effects/spawners/gibspawner.dm +++ b/code/game/objects/effects/spawners/gibspawner.dm @@ -16,15 +16,6 @@ gibamounts[6] = pick(0,1,2) ..() - xeno - gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno/up,/obj/effect/decal/cleanable/blood/gibs/xeno/down,/obj/effect/decal/cleanable/blood/gibs/xeno,/obj/effect/decal/cleanable/blood/gibs/xeno,/obj/effect/decal/cleanable/blood/gibs/xeno/body,/obj/effect/decal/cleanable/blood/gibs/xeno/limb,/obj/effect/decal/cleanable/blood/gibs/xeno/core) - gibamounts = list(1,1,1,1,1,1,1) - - New() - gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), alldirs, alldirs, list()) - gibamounts[6] = pick(0,1,2) - ..() - robot sparks = 1 gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/robot/up,/obj/effect/decal/cleanable/blood/gibs/robot/down,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot/limb) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index b69f85af38..fcdec82edf 100755 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -1343,21 +1343,13 @@ var/global/list/obj/item/device/pda/PDAs = list() ..() /obj/item/device/pda/clown/Crossed(AM as mob|obj) //Clown PDA is slippery. - if (istype(AM, /mob/living/carbon)) - var/mob/M = AM - if ((istype(M, /mob/living/carbon/human) && (istype(M:shoes, /obj/item/clothing/shoes) && M:shoes.flags&NOSLIP)) || M.m_intent == "walk") - return + if (istype(AM, /mob/living)) + var/mob/living/M = AM - if ((istype(M, /mob/living/carbon/human) && (M.real_name != src.owner) && (istype(src.cartridge, /obj/item/weapon/cartridge/clown)))) - if (src.cartridge.charges < 5) + if(M.slip("the PDA",8) && M.real_name != src.owner && istype(src.cartridge, /obj/item/weapon/cartridge/clown)) + if(src.cartridge.charges < 5) src.cartridge.charges++ - M.stop_pulling() - M << "\blue You slipped on the PDA!" - playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) - M.Stun(8) - M.Weaken(5) - /obj/item/device/pda/proc/available_pdas() var/list/names = list() var/list/plist = list() diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index afd33fdf08..0203bf0846 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -102,6 +102,7 @@ /obj/machinery/door, /obj/machinery/telecomms, /obj/machinery/mecha_part_fabricator, + /obj/machinery/gibber, /obj/vehicle ) diff --git a/code/game/objects/items/weapons/clown_items.dm b/code/game/objects/items/weapons/clown_items.dm index fe6e94ad07..656197fee0 100644 --- a/code/game/objects/items/weapons/clown_items.dm +++ b/code/game/objects/items/weapons/clown_items.dm @@ -9,31 +9,16 @@ * Banana Peals */ /obj/item/weapon/bananapeel/Crossed(AM as mob|obj) - if (istype(AM, /mob/living/carbon)) - var/mob/M = AM - if (istype(M, /mob/living/carbon/human) && (isobj(M:shoes) && M:shoes.flags&NOSLIP) || M.buckled) - return - - M.stop_pulling() - M << "\blue You slipped on the [name]!" - playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) - M.Stun(4) - M.Weaken(2) - + if (istype(AM, /mob/living)) + var/mob/living/M = AM + M.slip("the [src.name]",4) /* * Soap */ /obj/item/weapon/soap/Crossed(AM as mob|obj) //EXACTLY the same as bananapeel for now, so it makes sense to put it in the same dm -- Urist - if (istype(AM, /mob/living/carbon)) - var/mob/M = AM - if (istype(M, /mob/living/carbon/human) && (isobj(M:shoes) && M:shoes.flags&NOSLIP) || M.buckled) - return - - M.stop_pulling() - M << "\blue You slipped on the [name]!" - playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) - M.Stun(3) - M.Weaken(2) + if (istype(AM, /mob/living)) + var/mob/living/M = AM + M.slip("the [src.name]",3) /obj/item/weapon/soap/afterattack(atom/target, mob/user as mob, proximity) if(!proximity) return diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index 42a63f26e5..8f66524076 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -79,66 +79,29 @@ noslip = 1 if (noslip) return // no slipping while sitting in a chair, plz - switch (src.wet) - if(1) - if(istype(M, /mob/living/carbon/human)) // Added check since monkeys don't have shoes - if ((M.m_intent == "run") && !(istype(M:shoes, /obj/item/clothing/shoes) && M:shoes.flags&NOSLIP)) - M.stop_pulling() - step(M, M.dir) - M << "\blue You slipped on the wet floor!" - playsound(src, 'sound/misc/slip.ogg', 50, 1, -3) - M.Stun(5) - M.Weaken(3) - else - M.inertia_dir = 0 - return - else if(!istype(M, /mob/living/carbon/slime)) - if (M.m_intent == "run") - M.stop_pulling() - step(M, M.dir) - M << "\blue You slipped on the wet floor!" - playsound(src, 'sound/misc/slip.ogg', 50, 1, -3) - M.Stun(5) - M.Weaken(3) - else - M.inertia_dir = 0 - return - if(2) //lube //can cause infinite loops - needs work - if(!istype(M, /mob/living/carbon/slime) && !M.buckled) - M.stop_pulling() + if(src.wet) + var/slip_dist = 1 + var/slip_stun = 6 + var/floor_type = "wet" + + switch(src.wet) + if(2) // Lube + floor_type = "slippery" + slip_dist = 4 + slip_stun = 10 + if(3) // Ice + floor_type = "icy" + slip_stun = 4 + + if(M.slip("the [floor_type] floor",slip_stun)) + for(var/i = 0;iYou slipped on [slipped_on]!" + playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) + Stun(stun_duration) + Weaken(Floor(stun_duration/2)) + return 1 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index d71404e624..601705ecc2 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -8,12 +8,8 @@ // Override the current limb status and don't cause an explosion E.droplimb(1,1) - ..(species ? species.gibbed_anim : "gibbed-h") - - if(species) - hgibs(loc, viruses, dna, species.flesh_color, species.blood_color) - else - hgibs(loc, viruses, dna) + ..(species.gibbed_anim) + gibs(loc, viruses, dna, null, null, species.flesh_color, species.blood_color) /mob/living/carbon/human/dust() if(species) @@ -65,21 +61,6 @@ return ..(gibbed,species.death_message) -/mob/living/carbon/human/proc/makeSkeleton() - if(SKELETON in src.mutations) return - - if(f_style) - f_style = "Shaved" - if(h_style) - h_style = "Bald" - update_hair(0) - - mutations.Add(SKELETON) - status_flags |= DISFIGURED - update_body(0) - update_mutantrace() - return - /mob/living/carbon/human/proc/ChangeToHusk() if(HUSK in mutations) return @@ -92,10 +73,23 @@ mutations.Add(HUSK) status_flags |= DISFIGURED //makes them unknown without fucking up other stuff like admintools update_body(0) - update_mutantrace() return /mob/living/carbon/human/proc/Drain() ChangeToHusk() //mutations |= NOCLONE return + +/mob/living/carbon/human/proc/ChangeToSkeleton() + if(SKELETON in src.mutations) return + + if(f_style) + f_style = "Shaved" + if(h_style) + h_style = "Bald" + update_hair(0) + + mutations.Add(SKELETON) + status_flags |= DISFIGURED + update_body(0) + return diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index a3143e6b88..0b49434010 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -730,13 +730,8 @@ return /mob/living/carbon/human/get_species() - if(!species) set_species() - - if(dna && dna.mutantrace == "golem") - return "Animated Construct" - return species.name /mob/living/carbon/human/proc/play_xylophone() @@ -1286,3 +1281,8 @@ if(eyes && istype(eyes) && !eyes.status & ORGAN_CUT_AWAY) return 1 return 0 + +/mob/living/carbon/human/slip(var/slipped_on, stun_duration=8) + if((species.flags & NO_SLIP) || (shoes && (shoes.flags & NOSLIP))) + return 0 + ..(slipped_on,stun_duration) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 9e20c29d0e..070084a471 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -230,7 +230,7 @@ return W.afterattack(target,src) var/randn = rand(1, 100) - if (randn <= 25) + if(!(species.flags & NO_SLIP) && randn <= 25) apply_effect(3, WEAKEN, run_armor_check(affecting, "melee")) playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) visible_message("\red [M] has pushed [src]!") diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index b9e32968ea..64d599ecc5 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -929,64 +929,6 @@ return min(1,thermal_protection) - /* - proc/add_fire_protection(var/temp) - var/fire_prot = 0 - if(head) - if(head.protective_temperature > temp) - fire_prot += (head.protective_temperature/10) - if(wear_mask) - if(wear_mask.protective_temperature > temp) - fire_prot += (wear_mask.protective_temperature/10) - if(glasses) - if(glasses.protective_temperature > temp) - fire_prot += (glasses.protective_temperature/10) - if(ears) - if(ears.protective_temperature > temp) - fire_prot += (ears.protective_temperature/10) - if(wear_suit) - if(wear_suit.protective_temperature > temp) - fire_prot += (wear_suit.protective_temperature/10) - if(w_uniform) - if(w_uniform.protective_temperature > temp) - fire_prot += (w_uniform.protective_temperature/10) - if(gloves) - if(gloves.protective_temperature > temp) - fire_prot += (gloves.protective_temperature/10) - if(shoes) - if(shoes.protective_temperature > temp) - fire_prot += (shoes.protective_temperature/10) - - return fire_prot - - proc/handle_temperature_damage(body_part, exposed_temperature, exposed_intensity) - if(nodamage) - return - //world <<"body_part = [body_part], exposed_temperature = [exposed_temperature], exposed_intensity = [exposed_intensity]" - var/discomfort = min(abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0) - - if(exposed_temperature > bodytemperature) - discomfort *= 4 - - if(mutantrace == "plant") - discomfort *= TEMPERATURE_DAMAGE_COEFFICIENT * 2 //I don't like magic numbers. I'll make mutantraces a datum with vars sometime later. -- Urist - else - discomfort *= TEMPERATURE_DAMAGE_COEFFICIENT //Dangercon 2011 - now with less magic numbers! - //world <<"[discomfort]" - - switch(body_part) - if(HEAD) - apply_damage(2.5*discomfort, BURN, "head") - if(UPPER_TORSO) - apply_damage(2.5*discomfort, BURN, "chest") - if(LEGS) - apply_damage(0.6*discomfort, BURN, "l_leg") - apply_damage(0.6*discomfort, BURN, "r_leg") - if(ARMS) - apply_damage(0.4*discomfort, BURN, "l_arm") - apply_damage(0.4*discomfort, BURN, "r_arm") - */ - proc/handle_chemicals_in_body() if(reagents && !(species.flags & IS_SYNTHETIC)) //Synths don't process reagents. @@ -1024,7 +966,7 @@ adjustOxyLoss(-(light_amount)) //TODO: heal wounds, heal broken limbs. - if(dna && dna.mutantrace == "shadow") + if(species.light_dam) var/light_amount = 0 if(isturf(loc)) var/turf/T = loc @@ -1032,30 +974,11 @@ if(A) if(A.lighting_use_dynamic) light_amount = T.lighting_lumcount else light_amount = 10 - if(light_amount > 2) //if there's enough light, start dying + if(light_amount > species.light_dam) //if there's enough light, start dying take_overall_damage(1,1) - else if (light_amount < 2) //heal in the dark + else //heal in the dark heal_overall_damage(1,1) -/* //The fucking FAT mutation is the dumbest shit ever. It makes the code so difficult to work with - if(FAT in mutations) - if(overeatduration < 100) - src << "\blue You feel fit again!" - mutations.Remove(FAT) - update_mutantrace(0) - update_mutations(0) - update_inv_w_uniform(0) - update_inv_wear_suit() - else - if(overeatduration > 500) - src << "\red You suddenly feel blubbery!" - mutations.Add(FAT) - update_mutantrace(0) - update_mutations(0) - update_inv_w_uniform(0) - update_inv_wear_suit() -*/ - // nutrition decrease if (nutrition > 0 && stat != 2) nutrition = max (0, nutrition - HUNGER_FACTOR) @@ -1335,14 +1258,6 @@ sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS) see_in_dark = species.darksight see_invisible = see_in_dark>2 ? SEE_INVISIBLE_LEVEL_ONE : SEE_INVISIBLE_LIVING - if(dna) - switch(dna.mutantrace) - if("slime") - see_in_dark = 3 - see_invisible = SEE_INVISIBLE_LEVEL_ONE - if("shadow") - see_in_dark = 8 - see_invisible = SEE_INVISIBLE_LEVEL_ONE if(XRAY in mutations) sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm deleted file mode 100644 index 49266c02dc..0000000000 --- a/code/modules/mob/living/carbon/human/species.dm +++ /dev/null @@ -1,582 +0,0 @@ -/* - Datum-based species. Should make for much cleaner and easier to maintain mutantrace code. -*/ - -/datum/species - - var/name // Species name. - var/name_plural - - var/icobase = 'icons/mob/human_races/r_human.dmi' // Normal icon set. - var/deform = 'icons/mob/human_races/r_def_human.dmi' // Mutated icon set. - var/prone_icon // If set, draws this from icobase when mob is prone. - var/eyes = "eyes_s" // Icon for eyes. - var/blurb = "A completely nondescript species." // A brief lore summary for use in the chargen screen. - - var/primitive // Lesser form, if any (ie. monkey for humans) - var/tail // Name of tail image in species effects icon file. - var/list/unarmed_attacks = null // For empty hand harm-intent attack - var/datum/hud_data/hud - var/hud_type - var/slowdown = 0 - var/gluttonous // Can eat some mobs. 1 for monkeys, 2 for people. - var/rarity_value = 1 // Relative rarity/collector value for this species. Only used by ninja and cultists atm. - var/list/unarmed_types = list(/datum/unarmed_attack, /datum/unarmed_attack/bite) - - var/language = "Galactic Common" // Default racial language, if any. - // Default language is used when 'say' is used without modifiers. - var/default_language = "Galactic Common" - var/secondary_langs = list() // The names of secondary languages that are available to this species. - var/mutantrace // Safeguard due to old code. - var/list/speech_sounds // A list of sounds to potentially play when speaking. - var/list/speech_chance - var/has_fine_manipulation = 1 // Can use small items. - var/insulated // Immune to electrocution and glass shards to the feet. - - // Some species-specific gibbing data. - var/gibbed_anim = "gibbed-h" - var/dusted_anim = "dust-h" - var/remains_type = /obj/effect/decal/remains/xeno - var/death_sound - var/death_message = "seizes up and falls limp, their eyes dead and lifeless..." - - var/breath_type = "oxygen" // Non-oxygen gas breathed, if any. - var/poison_type = "phoron" // Poisonous air. - var/exhale_type = "carbon_dioxide" // Exhaled gas type. - - var/total_health = 100 //Point at which the mob will enter crit. - - var/cold_level_1 = 260 // Cold damage level 1 below this point. - var/cold_level_2 = 200 // Cold damage level 2 below this point. - var/cold_level_3 = 120 // Cold damage level 3 below this point. - - var/heat_level_1 = 360 // Heat damage level 1 above this point. - var/heat_level_2 = 400 // Heat damage level 2 above this point. - var/heat_level_3 = 1000 // Heat damage level 2 above this point. - - var/body_temperature = 310.15 //non-IS_SYNTHETIC species will try to stabilize at this temperature. (also affects temperature processing) - var/synth_temp_gain = 0 //IS_SYNTHETIC species will gain this much temperature every second - var/reagent_tag //Used for metabolizing reagents. - - var/darksight = 2 - var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure. - var/warning_high_pressure = WARNING_HIGH_PRESSURE // High pressure warning. - var/warning_low_pressure = WARNING_LOW_PRESSURE // Low pressure warning. - var/hazard_low_pressure = HAZARD_LOW_PRESSURE // Dangerously low pressure. - - var/brute_mod = null // Physical damage reduction/malus. - var/burn_mod = null // Burn damage reduction/malus. - - var/flags = 0 // Various specific features. - - var/list/abilities = list() // For species-derived or admin-given powers - - var/blood_color = "#A10808" //Red. - var/flesh_color = "#FFC896" //Pink. - var/base_color //Used when setting species. - - //Used in icon caching. - var/race_key = 0 - var/icon/icon_template - - // Species-specific abilities. - var/list/inherent_verbs - var/list/has_organ = list( - "heart" = /datum/organ/internal/heart, - "lungs" = /datum/organ/internal/lungs, - "liver" = /datum/organ/internal/liver, - "kidneys" = /datum/organ/internal/kidney, - "brain" = /datum/organ/internal/brain, - "appendix" = /datum/organ/internal/appendix, - "eyes" = /datum/organ/internal/eyes - ) - -/datum/species/New() - if(hud_type) - hud = new hud_type() - else - hud = new() - - unarmed_attacks = list() - for(var/u_type in unarmed_types) - unarmed_attacks += new u_type() - -/datum/species/proc/get_random_name(var/gender) - var/datum/language/species_language = all_languages[language] - return species_language.get_random_name(gender) - -/datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs. - - //Trying to work out why species changes aren't fixing organs properly. - if(H.organs) H.organs.Cut() - if(H.internal_organs) H.internal_organs.Cut() - if(H.organs_by_name) H.organs_by_name.Cut() - if(H.internal_organs_by_name) H.internal_organs_by_name.Cut() - - H.organs = list() - H.internal_organs = list() - H.organs_by_name = list() - H.internal_organs_by_name = list() - - //This is a basic humanoid limb setup. - H.organs_by_name["chest"] = new/datum/organ/external/chest() - H.organs_by_name["groin"] = new/datum/organ/external/groin(H.organs_by_name["chest"]) - H.organs_by_name["head"] = new/datum/organ/external/head(H.organs_by_name["chest"]) - H.organs_by_name["l_arm"] = new/datum/organ/external/l_arm(H.organs_by_name["chest"]) - H.organs_by_name["r_arm"] = new/datum/organ/external/r_arm(H.organs_by_name["chest"]) - H.organs_by_name["r_leg"] = new/datum/organ/external/r_leg(H.organs_by_name["groin"]) - H.organs_by_name["l_leg"] = new/datum/organ/external/l_leg(H.organs_by_name["groin"]) - H.organs_by_name["l_hand"] = new/datum/organ/external/l_hand(H.organs_by_name["l_arm"]) - H.organs_by_name["r_hand"] = new/datum/organ/external/r_hand(H.organs_by_name["r_arm"]) - H.organs_by_name["l_foot"] = new/datum/organ/external/l_foot(H.organs_by_name["l_leg"]) - H.organs_by_name["r_foot"] = new/datum/organ/external/r_foot(H.organs_by_name["r_leg"]) - - for(var/organ in has_organ) - var/organ_type = has_organ[organ] - H.internal_organs_by_name[organ] = new organ_type(H) - - for(var/name in H.organs_by_name) - H.organs += H.organs_by_name[name] - - for(var/datum/organ/external/O in H.organs) - O.owner = H - - if(flags & IS_SYNTHETIC) - for(var/datum/organ/external/E in H.organs) - if(E.status & ORGAN_CUT_AWAY || E.status & ORGAN_DESTROYED) continue - E.status |= ORGAN_ROBOT - for(var/datum/organ/internal/I in H.internal_organs) - I.mechanize() - -/datum/species/proc/hug(var/mob/living/carbon/human/H,var/mob/living/target) - - var/t_him = "them" - switch(target.gender) - if(MALE) - t_him = "him" - if(FEMALE) - t_him = "her" - - H.visible_message("[H] hugs [target] to make [t_him] feel better!", \ - "You hug [target] to make [t_him] feel better!") - -/datum/species/proc/remove_inherent_verbs(var/mob/living/carbon/human/H) - if(inherent_verbs) - for(var/verb_path in inherent_verbs) - H.verbs -= verb_path - return - -/datum/species/proc/add_inherent_verbs(var/mob/living/carbon/human/H) - if(inherent_verbs) - for(var/verb_path in inherent_verbs) - H.verbs |= verb_path - return - -/datum/species/proc/handle_post_spawn(var/mob/living/carbon/human/H) //Handles anything not already covered by basic species assignment. - add_inherent_verbs(H) - -/datum/species/proc/handle_death(var/mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns). - if(flags & IS_SYNTHETIC) - H.h_style = "" - spawn(100) - H.update_hair() - return - -// Only used for alien plasma weeds atm, but could be used for Dionaea later. -/datum/species/proc/handle_environment_special(var/mob/living/carbon/human/H) - return - -// Used to update alien icons for aliens. -/datum/species/proc/handle_login_special(var/mob/living/carbon/human/H) - return - -// As above. -/datum/species/proc/handle_logout_special(var/mob/living/carbon/human/H) - return - -// Builds the HUD using species-specific icons and usable slots. -/datum/species/proc/build_hud(var/mob/living/carbon/human/H) - return - -// Grabs the window recieved when you click-drag someone onto you. -/datum/species/proc/get_inventory_dialogue(var/mob/living/carbon/human/H) - return - -//Used by xenos understanding larvae and dionaea understanding nymphs. -/datum/species/proc/can_understand(var/mob/other) - return - -/datum/species/human - name = "Human" - name_plural = "Humans" - language = "Sol Common" - primitive = /mob/living/carbon/monkey - unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite) - blurb = "Humanity originated in the Sol system, and over the last five centuries has spread \ - colonies across a wide swathe of space. They hold a wide range of forms and creeds.

\ - While the central Sol government maintains control of its far-flung people, powerful corporate \ - interests, rampant cyber and bio-augmentation and secretive factions make life on most human \ - worlds tumultous at best." - - flags = HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR - -/datum/species/unathi - name = "Unathi" - name_plural = "Unathi" - icobase = 'icons/mob/human_races/r_lizard.dmi' - deform = 'icons/mob/human_races/r_def_lizard.dmi' - language = "Sinta'unathi" - tail = "sogtail" - unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp) - primitive = /mob/living/carbon/monkey/unathi - darksight = 3 - gluttonous = 1 - - blurb = "A heavily reptillian species, Unathi (or 'Sinta as they call themselves) hail from the \ - Uuosa-Eso system, which roughly translates to 'burning mother'.

Coming from a harsh, radioactive \ - desert planet, they mostly hold ideals of honesty, virtue, martial combat and bravery above all \ - else, frequently even their own lives. They prefer warmer temperatures than most species and \ - their native tongue is a heavy hissing laungage called Sinta'Unathi." - - cold_level_1 = 280 //Default 260 - Lower is better - cold_level_2 = 220 //Default 200 - cold_level_3 = 130 //Default 120 - - heat_level_1 = 420 //Default 360 - Higher is better - heat_level_2 = 480 //Default 400 - heat_level_3 = 1100 //Default 1000 - - flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR - - flesh_color = "#34AF10" - - reagent_tag = IS_UNATHI - base_color = "#066000" - -/datum/species/tajaran - name = "Tajara" - name_plural = "Tajaran" - icobase = 'icons/mob/human_races/r_tajaran.dmi' - deform = 'icons/mob/human_races/r_def_tajaran.dmi' - language = "Siik'tajr" - tail = "tajtail" - unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp) - darksight = 8 - blurb = "The Tajaran race is a species of feline-like bipeds hailing from the planet of Ahdomai in the \ - S'randarr system. They have been brought up into the space age by the Humans and Skrell, and have been \ - influenced heavily by their long history of Slavemaster rule. They have a structured, clan-influenced way \ - of family and politics. They prefer colder environments, and speak a variety of languages, mostly Siik'Maas, \ - using unique inflections their mouths form." - - cold_level_1 = 200 //Default 260 - cold_level_2 = 140 //Default 200 - cold_level_3 = 80 //Default 120 - - heat_level_1 = 330 //Default 360 - heat_level_2 = 380 //Default 400 - heat_level_3 = 800 //Default 1000 - - primitive = /mob/living/carbon/monkey/tajara - - flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR - - flesh_color = "#AFA59E" - base_color = "#333333" - -/datum/species/skrell - name = "Skrell" - name_plural = "Skrell" - icobase = 'icons/mob/human_races/r_skrell.dmi' - deform = 'icons/mob/human_races/r_def_skrell.dmi' - eyes = "skrell_eyes_s" - language = "Skrellian" - primitive = /mob/living/carbon/monkey/skrell - unarmed_types = list(/datum/unarmed_attack/punch) - blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \ - the royals' or 'Light of the Crown'.

Skrell are a highly advanced and logical race who live under the rule \ - of the Qerr'Katish, a caste within their society which keeps the empire of the Skrell running smoothly. Skrell are \ - herbivores on the whole and tend to be co-operative with the other species of the galaxy, although they rarely reveal \ - the secrets of their empire to their allies." - - flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR - - flesh_color = "#8CD7A3" - blood_color = "#1D2CBF" - - reagent_tag = IS_SKRELL - -/datum/species/vox - name = "Vox" - name_plural = "Vox" - icobase = 'icons/mob/human_races/r_vox.dmi' - deform = 'icons/mob/human_races/r_def_vox.dmi' - default_language = "Vox-pidgin" - language = "Galactic Common" - unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong) - rarity_value = 2 - blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \ - scavenging vermin who prey on isolated stations, ships or planets to keep their own ancient arkships \ - alive. They are four to five feet tall, reptillian, beaked, tailed and quilled; human crews often \ - refer to them as 'shitbirds' for their violent and offensive nature, as well as their horrible \ - smell.

Most humans will never meet a Vox raider, instead learning of this insular species through \ - dealing with their traders and merchants; those that do rarely enjoy the experience." - - speech_sounds = list('sound/voice/shriek1.ogg') - speech_chance = 20 - - warning_low_pressure = 50 - hazard_low_pressure = 0 - - cold_level_1 = 80 - cold_level_2 = 50 - cold_level_3 = 0 - - eyes = "vox_eyes_s" - - breath_type = "nitrogen" - poison_type = "oxygen" - insulated = 1 - - flags = NO_SCAN | HAS_EYE_COLOR - - blood_color = "#2299FC" - flesh_color = "#808D11" - - reagent_tag = IS_VOX - - inherent_verbs = list( - /mob/living/carbon/human/proc/leap - ) - - has_organ = list( - "heart" = /datum/organ/internal/heart, - "lungs" = /datum/organ/internal/lungs, - "liver" = /datum/organ/internal/liver, - "kidneys" = /datum/organ/internal/kidney, - "brain" = /datum/organ/internal/brain, - "eyes" = /datum/organ/internal/eyes, - "stack" = /datum/organ/internal/stack/vox - ) - -/datum/species/vox/get_random_name(var/gender) - var/datum/language/species_language = all_languages[default_language] - return species_language.get_random_name(gender) - -/datum/species/vox/armalis - name = "Vox Armalis" - name_plural = "Vox" - icobase = 'icons/mob/human_races/r_armalis.dmi' - deform = 'icons/mob/human_races/r_armalis.dmi' - rarity_value = 10 - - warning_low_pressure = 50 - hazard_low_pressure = 0 - - cold_level_1 = 80 - cold_level_2 = 50 - cold_level_3 = 0 - - heat_level_1 = 2000 - heat_level_2 = 3000 - heat_level_3 = 4000 - - brute_mod = 0.2 - burn_mod = 0.2 - - eyes = "blank_eyes" - breath_type = "nitrogen" - poison_type = "oxygen" - - flags = NO_SCAN | NO_BLOOD | NO_PAIN | HAS_EYE_COLOR - - blood_color = "#2299FC" - flesh_color = "#808D11" - - tail = "armalis_tail" - icon_template = 'icons/mob/human_races/r_armalis.dmi' - - reagent_tag = IS_VOX - - inherent_verbs = list( - /mob/living/carbon/human/proc/leap, - /mob/living/carbon/human/proc/gut, - /mob/living/carbon/human/proc/commune - ) - -/datum/species/diona - name = "Diona" - name_plural = "Dionaea" - icobase = 'icons/mob/human_races/r_diona.dmi' - deform = 'icons/mob/human_races/r_def_plant.dmi' - language = "Rootspeak" - unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/diona) - primitive = /mob/living/carbon/alien/diona - slowdown = 7 - rarity_value = 3 - blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \ - species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \ - there is no effective upper limit to the number that can fuse in gestalt, and reports exist of the Epsilon Ursae \ - Minoris primary being ringed with a cloud of singing space-station-sized entities.

The Dionaea coexist peacefully with \ - all known species, especially the Skrell. Their communal mind makes them slow to react, and they have difficulty understanding \ - even the simplest concepts of other minds. Their alien physiology allows them survive happily off a diet of nothing but light, \ - water and other radiation." - - has_organ = list( - "nutrient channel" = /datum/organ/internal/diona/nutrients, - "neural strata" = /datum/organ/internal/diona/strata, - "response node" = /datum/organ/internal/diona/node, - "gas bladder" = /datum/organ/internal/diona/bladder, - "polyp segment" = /datum/organ/internal/diona/polyp, - "anchoring ligament" = /datum/organ/internal/diona/ligament - ) - - warning_low_pressure = 50 - hazard_low_pressure = -1 - - cold_level_1 = 50 - cold_level_2 = -1 - cold_level_3 = -1 - - heat_level_1 = 2000 - heat_level_2 = 3000 - heat_level_3 = 4000 - - body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not - - flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | IS_PLANT | NO_BLOOD | NO_PAIN | NO_SLIP | HAS_EYE_COLOR - - blood_color = "#004400" - flesh_color = "#907E4A" - - reagent_tag = IS_DIONA - -/datum/species/diona/can_understand(var/mob/other) - var/mob/living/carbon/alien/diona/D = other - if(istype(D)) - return 1 - return 0 - -/datum/species/diona/handle_post_spawn(var/mob/living/carbon/human/H) - H.gender = NEUTER - return ..() - -/datum/species/diona/handle_death(var/mob/living/carbon/human/H) - - var/mob/living/carbon/alien/diona/S = new(get_turf(H)) - - if(H.mind) - H.mind.transfer_to(S) - - for(var/mob/living/carbon/alien/diona/D in H.contents) - if(D.client) - D.loc = H.loc - else - del(D) - - H.visible_message("\red[H] splits apart with a wet slithering noise!") - -/datum/species/machine - name = "Machine" - name_plural = "machines" - - icobase = 'icons/mob/human_races/r_machine.dmi' - deform = 'icons/mob/human_races/r_machine.dmi' - language = "Tradeband" - unarmed_types = list(/datum/unarmed_attack/punch) - rarity_value = 2 - - eyes = "blank_eyes" - brute_mod = 0.5 - burn_mod = 1 - - warning_low_pressure = 50 - hazard_low_pressure = 0 - - cold_level_1 = 50 - cold_level_2 = -1 - cold_level_3 = -1 - - heat_level_1 = 500 //gives them about 25 seconds in space before taking damage - heat_level_2 = 1000 - heat_level_3 = 2000 - - synth_temp_gain = 10 //this should cause IPCs to stabilize at ~80 C in a 20 C environment. - - flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | IS_SYNTHETIC - - blood_color = "#1F181F" - flesh_color = "#575757" - - has_organ = list( - "heart" = /datum/organ/internal/heart, - "brain" = /datum/organ/internal/brain, - ) - -// Called when using the shredding behavior. -/datum/species/proc/can_shred(var/mob/living/carbon/human/H) - - if(H.a_intent != "hurt") - return 0 - - for(var/datum/unarmed_attack/attack in unarmed_attacks) - if(!attack.is_usable(H)) - continue - if(attack.shredding) - return 1 - - return 0 - - -/datum/hud_data - var/icon // If set, overrides ui_style. - var/has_a_intent = 1 // Set to draw intent box. - var/has_m_intent = 1 // Set to draw move intent box. - var/has_warnings = 1 // Set to draw environment warnings. - var/has_pressure = 1 // Draw the pressure indicator. - var/has_nutrition = 1 // Draw the nutrition indicator. - var/has_bodytemp = 1 // Draw the bodytemp indicator. - var/has_hands = 1 // Set to draw shand. - var/has_drop = 1 // Set to draw drop button. - var/has_throw = 1 // Set to draw throw button. - var/has_resist = 1 // Set to draw resist button. - var/has_internals = 1 // Set to draw the internals toggle button. - var/list/equip_slots = list() // Checked by mob_can_equip(). - - // Contains information on the position and tag for all inventory slots - // to be drawn for the mob. This is fairly delicate, try to avoid messing with it - // unless you know exactly what it does. - var/list/gear = list( - "i_clothing" = list("loc" = ui_iclothing, "slot" = slot_w_uniform, "state" = "center", "toggle" = 1, "dir" = SOUTH), - "o_clothing" = list("loc" = ui_oclothing, "slot" = slot_wear_suit, "state" = "equip", "toggle" = 1, "dir" = SOUTH), - "mask" = list("loc" = ui_mask, "slot" = slot_wear_mask, "state" = "equip", "toggle" = 1, "dir" = NORTH), - "gloves" = list("loc" = ui_gloves, "slot" = slot_gloves, "state" = "gloves", "toggle" = 1), - "eyes" = list("loc" = ui_glasses, "slot" = slot_glasses, "state" = "glasses","toggle" = 1), - "l_ear" = list("loc" = ui_l_ear, "slot" = slot_l_ear, "state" = "ears", "toggle" = 1), - "r_ear" = list("loc" = ui_r_ear, "slot" = slot_r_ear, "state" = "ears", "toggle" = 1), - "head" = list("loc" = ui_head, "slot" = slot_head, "state" = "hair", "toggle" = 1), - "shoes" = list("loc" = ui_shoes, "slot" = slot_shoes, "state" = "shoes", "toggle" = 1), - "suit storage" = list("loc" = ui_sstore1, "slot" = slot_s_store, "state" = "belt", "dir" = 8), - "back" = list("loc" = ui_back, "slot" = slot_back, "state" = "back", "dir" = NORTH), - "id" = list("loc" = ui_id, "slot" = slot_wear_id, "state" = "id", "dir" = NORTH), - "storage1" = list("loc" = ui_storage1, "slot" = slot_l_store, "state" = "pocket"), - "storage2" = list("loc" = ui_storage2, "slot" = slot_r_store, "state" = "pocket"), - "belt" = list("loc" = ui_belt, "slot" = slot_belt, "state" = "belt") - ) - -/datum/hud_data/New() - ..() - for(var/slot in gear) - equip_slots |= gear[slot]["slot"] - - if(has_hands) - equip_slots |= slot_l_hand - equip_slots |= slot_r_hand - equip_slots |= slot_handcuffed - - if(slot_back in equip_slots) - equip_slots |= slot_in_backpack - - if(slot_w_uniform in equip_slots) - equip_slots |= slot_tie - - equip_slots |= slot_legcuffed diff --git a/code/modules/mob/living/carbon/human/species/outsider/shadow.dm b/code/modules/mob/living/carbon/human/species/outsider/shadow.dm new file mode 100644 index 0000000000..3e7612b211 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/outsider/shadow.dm @@ -0,0 +1,8 @@ +/datum/species/shadow + name = "Shadow" + name_plural = "shadows" + language = "Sol Common" //todo? + unarmed_types = list(/datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/sharp) + light_dam = 2 + darksight = 8 + flags = IS_RESTRICTED | NO_SCAN | NO_SLIP | NO_POISON \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/outsider/vox.dm b/code/modules/mob/living/carbon/human/species/outsider/vox.dm new file mode 100644 index 0000000000..3c44fbd5c6 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/outsider/vox.dm @@ -0,0 +1,97 @@ +/datum/species/vox + name = "Vox" + name_plural = "Vox" + icobase = 'icons/mob/human_races/r_vox.dmi' + deform = 'icons/mob/human_races/r_def_vox.dmi' + default_language = "Vox-pidgin" + language = "Galactic Common" + unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong) + rarity_value = 2 + blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \ + scavenging vermin who prey on isolated stations, ships or planets to keep their own ancient arkships \ + alive. They are four to five feet tall, reptillian, beaked, tailed and quilled; human crews often \ + refer to them as 'shitbirds' for their violent and offensive nature, as well as their horrible \ + smell.

Most humans will never meet a Vox raider, instead learning of this insular species through \ + dealing with their traders and merchants; those that do rarely enjoy the experience." + + speech_sounds = list('sound/voice/shriek1.ogg') + speech_chance = 20 + + warning_low_pressure = 50 + hazard_low_pressure = 0 + + cold_level_1 = 80 + cold_level_2 = 50 + cold_level_3 = 0 + + eyes = "vox_eyes_s" + + breath_type = "nitrogen" + poison_type = "oxygen" + insulated = 1 + + flags = IS_WHITELISTED | NO_SCAN | HAS_EYE_COLOR + + blood_color = "#2299FC" + flesh_color = "#808D11" + + reagent_tag = IS_VOX + + inherent_verbs = list( + /mob/living/carbon/human/proc/leap + ) + + has_organ = list( + "heart" = /datum/organ/internal/heart, + "lungs" = /datum/organ/internal/lungs, + "liver" = /datum/organ/internal/liver, + "kidneys" = /datum/organ/internal/kidney, + "brain" = /datum/organ/internal/brain, + "eyes" = /datum/organ/internal/eyes, + "stack" = /datum/organ/internal/stack/vox + ) + +/datum/species/vox/get_random_name(var/gender) + var/datum/language/species_language = all_languages[default_language] + return species_language.get_random_name(gender) + +/datum/species/vox/armalis + name = "Vox Armalis" + name_plural = "Vox" + icobase = 'icons/mob/human_races/r_armalis.dmi' + deform = 'icons/mob/human_races/r_armalis.dmi' + rarity_value = 10 + + warning_low_pressure = 50 + hazard_low_pressure = 0 + + cold_level_1 = 80 + cold_level_2 = 50 + cold_level_3 = 0 + + heat_level_1 = 2000 + heat_level_2 = 3000 + heat_level_3 = 4000 + + brute_mod = 0.2 + burn_mod = 0.2 + + eyes = "blank_eyes" + breath_type = "nitrogen" + poison_type = "oxygen" + + flags = IS_RESTRICTED | NO_SCAN | NO_BLOOD | NO_PAIN | HAS_EYE_COLOR + + blood_color = "#2299FC" + flesh_color = "#808D11" + + tail = "armalis_tail" + icon_template = 'icons/mob/human_races/r_armalis.dmi' + + reagent_tag = IS_VOX + + inherent_verbs = list( + /mob/living/carbon/human/proc/leap, + /mob/living/carbon/human/proc/gut, + /mob/living/carbon/human/proc/commune + ) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm new file mode 100644 index 0000000000..9f668117b8 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -0,0 +1,221 @@ +/* + Datum-based species. Should make for much cleaner and easier to maintain race code. +*/ + +/datum/species + + // Descriptors and strings. + var/name // Species name. + var/name_plural // Pluralized name (since "[name]s" is not always valid) + var/blurb = "A completely nondescript species." // A brief lore summary for use in the chargen screen. + + // Icon/appearance vars. + var/icobase = 'icons/mob/human_races/r_human.dmi' // Normal icon set. + var/deform = 'icons/mob/human_races/r_def_human.dmi' // Mutated icon set. + var/prone_icon // If set, draws this from icobase when mob is prone. + var/eyes = "eyes_s" // Icon for eyes. + var/blood_color = "#A10808" // Red. + var/flesh_color = "#FFC896" // Pink. + var/base_color // Used by changelings. Should also be used for icon previes.. + var/tail // Name of tail image in species effects icon file. + var/race_key = 0 // Used for mob icon cache string. + var/icon/icon_template // Used for mob icon generation for non-32x32 species. + + // Language/culture vars. + var/default_language = "Galactic Common" // Default language is used when 'say' is used without modifiers. + var/language = "Galactic Common" // Default racial language, if any. + var/secondary_langs = list() // The names of secondary languages that are available to this species. + var/list/speech_sounds // A list of sounds to potentially play when speaking. + var/list/speech_chance // The likelihood of a speech sound playing. + + // Combat vars. + var/total_health = 100 // Point at which the mob will enter crit. + var/list/unarmed_types = list( // Possible unarmed attacks that the mob will use in combat. + /datum/unarmed_attack, + /datum/unarmed_attack/bite + ) + var/list/unarmed_attacks = null // For empty hand harm-intent attack + var/brute_mod = null // Physical damage reduction/malus. + var/burn_mod = null // Burn damage reduction/malus. + + // Death vars. + var/gibber_type = /obj/effect/gibspawner/human + var/remains_type = /obj/effect/decal/remains/xeno + var/gibbed_anim = "gibbed-h" + var/dusted_anim = "dust-h" + var/death_sound + var/death_message = "seizes up and falls limp, their eyes dead and lifeless..." + + // Environment tolerance/life processes vars. + var/reagent_tag //Used for metabolizing reagents. + var/breath_type = "oxygen" // Non-oxygen gas breathed, if any. + var/poison_type = "phoron" // Poisonous air. + var/exhale_type = "carbon_dioxide" // Exhaled gas type. + var/cold_level_1 = 260 // Cold damage level 1 below this point. + var/cold_level_2 = 200 // Cold damage level 2 below this point. + var/cold_level_3 = 120 // Cold damage level 3 below this point. + var/heat_level_1 = 360 // Heat damage level 1 above this point. + var/heat_level_2 = 400 // Heat damage level 2 above this point. + var/heat_level_3 = 1000 // Heat damage level 2 above this point. + var/synth_temp_gain = 0 // IS_SYNTHETIC species will gain this much temperature every second + var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure. + var/warning_high_pressure = WARNING_HIGH_PRESSURE // High pressure warning. + var/warning_low_pressure = WARNING_LOW_PRESSURE // Low pressure warning. + var/hazard_low_pressure = HAZARD_LOW_PRESSURE // Dangerously low pressure. + var/light_dam // If set, mob will be damaged in light over this value and heal in light below its negative. + var/body_temperature = 310.15 // Non-IS_SYNTHETIC species will try to stabilize at this temperature. + // (also affects temperature processing) + // HUD data vars. + var/datum/hud_data/hud + var/hud_type + + // Body/form vars. + var/list/inherent_verbs // Species-specific verbs. + var/has_fine_manipulation = 1 // Can use small items. + var/insulated // Immune to electrocution and glass shards to the feet. + var/darksight = 2 // Native darksight distance. + var/flags = 0 // Various specific features. + var/slowdown = 0 // Passive movement speed malus (or boost, if negative) + var/primitive // Lesser form, if any (ie. monkey for humans) + var/gluttonous // Can eat some mobs. 1 for monkeys, 2 for people. + var/rarity_value = 1 // Relative rarity/collector value for this species. + // Determines the organs that the species spawns with and + var/list/has_organ = list( // which required-organ checks are conducted. + "heart" = /datum/organ/internal/heart, + "lungs" = /datum/organ/internal/lungs, + "liver" = /datum/organ/internal/liver, + "kidneys" = /datum/organ/internal/kidney, + "brain" = /datum/organ/internal/brain, + "appendix" = /datum/organ/internal/appendix, + "eyes" = /datum/organ/internal/eyes + ) + +/datum/species/New() + if(hud_type) + hud = new hud_type() + else + hud = new() + + unarmed_attacks = list() + for(var/u_type in unarmed_types) + unarmed_attacks += new u_type() + +/datum/species/proc/get_random_name(var/gender) + var/datum/language/species_language = all_languages[language] + return species_language.get_random_name(gender) + +/datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs. + + //Trying to work out why species changes aren't fixing organs properly. + if(H.organs) H.organs.Cut() + if(H.internal_organs) H.internal_organs.Cut() + if(H.organs_by_name) H.organs_by_name.Cut() + if(H.internal_organs_by_name) H.internal_organs_by_name.Cut() + + H.organs = list() + H.internal_organs = list() + H.organs_by_name = list() + H.internal_organs_by_name = list() + + //This is a basic humanoid limb setup. + H.organs_by_name["chest"] = new/datum/organ/external/chest() + H.organs_by_name["groin"] = new/datum/organ/external/groin(H.organs_by_name["chest"]) + H.organs_by_name["head"] = new/datum/organ/external/head(H.organs_by_name["chest"]) + H.organs_by_name["l_arm"] = new/datum/organ/external/l_arm(H.organs_by_name["chest"]) + H.organs_by_name["r_arm"] = new/datum/organ/external/r_arm(H.organs_by_name["chest"]) + H.organs_by_name["r_leg"] = new/datum/organ/external/r_leg(H.organs_by_name["groin"]) + H.organs_by_name["l_leg"] = new/datum/organ/external/l_leg(H.organs_by_name["groin"]) + H.organs_by_name["l_hand"] = new/datum/organ/external/l_hand(H.organs_by_name["l_arm"]) + H.organs_by_name["r_hand"] = new/datum/organ/external/r_hand(H.organs_by_name["r_arm"]) + H.organs_by_name["l_foot"] = new/datum/organ/external/l_foot(H.organs_by_name["l_leg"]) + H.organs_by_name["r_foot"] = new/datum/organ/external/r_foot(H.organs_by_name["r_leg"]) + + for(var/organ in has_organ) + var/organ_type = has_organ[organ] + H.internal_organs_by_name[organ] = new organ_type(H) + + for(var/name in H.organs_by_name) + H.organs += H.organs_by_name[name] + + for(var/datum/organ/external/O in H.organs) + O.owner = H + + if(flags & IS_SYNTHETIC) + for(var/datum/organ/external/E in H.organs) + if(E.status & ORGAN_CUT_AWAY || E.status & ORGAN_DESTROYED) continue + E.status |= ORGAN_ROBOT + for(var/datum/organ/internal/I in H.internal_organs) + I.mechanize() + +/datum/species/proc/hug(var/mob/living/carbon/human/H,var/mob/living/target) + + var/t_him = "them" + switch(target.gender) + if(MALE) + t_him = "him" + if(FEMALE) + t_him = "her" + + H.visible_message("[H] hugs [target] to make [t_him] feel better!", \ + "You hug [target] to make [t_him] feel better!") + +/datum/species/proc/remove_inherent_verbs(var/mob/living/carbon/human/H) + if(inherent_verbs) + for(var/verb_path in inherent_verbs) + H.verbs -= verb_path + return + +/datum/species/proc/add_inherent_verbs(var/mob/living/carbon/human/H) + if(inherent_verbs) + for(var/verb_path in inherent_verbs) + H.verbs |= verb_path + return + +/datum/species/proc/handle_post_spawn(var/mob/living/carbon/human/H) //Handles anything not already covered by basic species assignment. + add_inherent_verbs(H) + +/datum/species/proc/handle_death(var/mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns). + if(flags & IS_SYNTHETIC) + H.h_style = "" + spawn(100) + H.update_hair() + return + +// Only used for alien plasma weeds atm, but could be used for Dionaea later. +/datum/species/proc/handle_environment_special(var/mob/living/carbon/human/H) + return + +// Used to update alien icons for aliens. +/datum/species/proc/handle_login_special(var/mob/living/carbon/human/H) + return + +// As above. +/datum/species/proc/handle_logout_special(var/mob/living/carbon/human/H) + return + +// Builds the HUD using species-specific icons and usable slots. +/datum/species/proc/build_hud(var/mob/living/carbon/human/H) + return + +// Grabs the window recieved when you click-drag someone onto you. +/datum/species/proc/get_inventory_dialogue(var/mob/living/carbon/human/H) + return + +//Used by xenos understanding larvae and dionaea understanding nymphs. +/datum/species/proc/can_understand(var/mob/other) + return + +// Called when using the shredding behavior. +/datum/species/proc/can_shred(var/mob/living/carbon/human/H) + + if(H.a_intent != "hurt") + return 0 + + for(var/datum/unarmed_attack/attack in unarmed_attacks) + if(!attack.is_usable(H)) + continue + if(attack.shredding) + return 1 + + return 0 + diff --git a/code/modules/mob/living/carbon/human/species/species_attack.dm b/code/modules/mob/living/carbon/human/species/species_attack.dm new file mode 100644 index 0000000000..4ebfb91092 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/species_attack.dm @@ -0,0 +1,263 @@ +//Species unarmed attacks +/datum/unarmed_attack + var/attack_verb = list("attack") // Empty hand hurt intent verb. + var/attack_noun = list("fist") + var/damage = 0 // Extra empty hand attack damage. + var/attack_sound = "punch" + var/miss_sound = 'sound/weapons/punchmiss.ogg' + var/shredding = 0 // Calls the old attack_alien() behavior on objects/mobs when on harm intent. + var/sharp = 0 + var/edge = 0 + +/datum/unarmed_attack/proc/is_usable(var/mob/living/carbon/human/user) + if(user.restrained()) + return 0 + + // Check if they have a functioning hand. + var/datum/organ/external/E = user.organs_by_name["l_hand"] + if(E && !(E.status & ORGAN_DESTROYED)) + return 1 + + E = user.organs_by_name["r_hand"] + if(E && !(E.status & ORGAN_DESTROYED)) + return 1 + + return 0 + +/datum/unarmed_attack/proc/apply_effects(var/mob/living/carbon/human/user,var/mob/living/carbon/human/target,var/armour,var/attack_damage,var/zone) + + var/stun_chance = rand(0, 100) + + if(attack_damage >= 5 && armour < 2 && !(target == user) && stun_chance <= attack_damage * 5) // 25% standard chance + switch(zone) // strong punches can have effects depending on where they hit + if("head", "mouth", "eyes") + // Induce blurriness + target.visible_message("[target] looks dazed.", "You see stars.") + target.apply_effect(attack_damage*2, EYE_BLUR, armour) + if("l_arm", "l_hand") + if (target.l_hand) + // Disarm left hand + target.visible_message("[src] [pick("dropped", "let go off")] \the [target.l_hand][pick("", " with a scream")]!") + target.drop_l_hand() + if("r_arm", "r_hand") + if (target.r_hand) + // Disarm right hand + target.visible_message("[src] [pick("dropped", "let go off")] \the [target.r_hand][pick("", " with a scream")]!") + target.drop_r_hand() + if("chest") + if(!target.lying) + var/turf/T = get_step(get_turf(target), get_dir(get_turf(user), get_turf(target))) + if(!T.density) + step(target, get_dir(get_turf(user), get_turf(target))) + target.visible_message("[pick("[target] was sent flying backward!", "[target] staggers back from the impact!")]") + else + target.visible_message("[target] slams into [T]!") + if(prob(50)) + target.set_dir(reverse_dir[target.dir]) + target.apply_effect(attack_damage * 0.4, WEAKEN, armour) + if("groin") + target.visible_message("[target] looks like \he is in pain!", "[(target.gender=="female") ? "Oh god that hurt!" : "Oh no, not your[pick("testicles", "crown jewels", "clockweights", "family jewels", "marbles", "bean bags", "teabags", "sweetmeats", "goolies")]!"]") + target.apply_effects(stutter = attack_damage * 2, agony = attack_damage* 3, blocked = armour) + if("l_leg", "l_foot", "r_leg", "r_foot") + if(!target.lying) + target.visible_message("[src] gives way slightly.") + target.apply_effect(attack_damage*3, AGONY, armour) + else if(attack_damage >= 5 && !(target == user) && (stun_chance + attack_damage * 5 >= 100) && armour < 2) // Chance to get the usual throwdown as well (25% standard chance) + if(!target.lying) + target.visible_message("[target] [pick("slumps", "falls", "drops")] down to the ground!") + else + target.visible_message("[target] has been weakened!") + target.apply_effect(3, WEAKEN, armour) + +/datum/unarmed_attack/proc/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) + var/datum/organ/external/affecting = target.get_organ(zone) + user.visible_message("[user] [pick(attack_verb)] [target] in the [affecting.display_name]!") + playsound(user.loc, attack_sound, 25, 1, -1) + +/datum/unarmed_attack/bite + attack_verb = list("bit") + attack_sound = 'sound/weapons/bite.ogg' + shredding = 0 + damage = 0 + sharp = 0 + edge = 0 + +/datum/unarmed_attack/bite/sharp //eye teeth + attack_verb = list("bit", "chomped on") + attack_sound = 'sound/weapons/bite.ogg' + shredding = 0 + damage = 5 + sharp = 1 + edge = 1 + +/datum/unarmed_attack/bite/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone) + if (user.wear_mask && istype(user.wear_mask, /obj/item/clothing/mask/muzzle)) + return 0 + if (user == target && (zone == "head" || zone == "eyes" || zone == "mouth")) + return 0 + return 1 + +/datum/unarmed_attack/punch + attack_verb = list("punched") + attack_noun = list("fist") + damage = 0 + +/datum/unarmed_attack/punch/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) + var/datum/organ/external/affecting = target.get_organ(zone) + var/organ = affecting.display_name + + attack_damage = Clamp(attack_damage, 1, 5) // We expect damage input of 1 to 5 for this proc. But we leave this check juuust in case. + + if(target == user) + user.visible_message("[user] [pick(attack_verb)] \himself in the [organ]!") + return 0 + + if(!target.lying) + switch(zone) + if("head", "mouth", "eyes") + // ----- HEAD ----- // + switch(attack_damage) + if(1 to 2) user.visible_message("[user] slapped [target] across \his cheek!") + if(3 to 4) user.visible_message("[user] struck [target] in the head[pick("", " with a closed fist")]!") + if(5) user.visible_message("[user] gave [target] a resounding slap to the face!") + if("chest", "l_arm", "r_arm", "l_hand", "r_hand", "groin", "l_leg", "r_let", "l_foot", "r_foot") + // ----- BODY ----- // + switch(attack_damage) + if(1 to 2) user.visible_message("[user] slapped [target]'s [organ]!") + if(3 to 4) user.visible_message("[user] [pick(attack_verb)] [target] in \his [organ]!") + if(5) user.visible_message("[user] slammed \his [pick(attack_noun)] into [target]'s [organ]!") + else + user.visible_message("[user] [pick("punched", "threw a punch", "struck", "slapped", "rammed their [pick(attack_noun)] into")] [target]'s [organ]!") + +/datum/unarmed_attack/kick + attack_verb = list("kicked", "kneed") + attack_noun = list("kick") + attack_sound = "swing_hit" + damage = 1 + +/datum/unarmed_attack/kick/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone) + if (target.legcuffed) + return 0 + + if(!(zone in list("l_leg", "r_leg", "l_foot", "r_foot", "groin"))) + return 0 + + var/datum/organ/external/E = user.organs_by_name["l_foot"] + if(E && !(E.status & ORGAN_DESTROYED)) + return 1 + + E = user.organs_by_name["r_foot"] + if(E && !(E.status & ORGAN_DESTROYED)) + return 1 + + return 0 + +/datum/unarmed_attack/kick/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) + var/datum/organ/external/affecting = target.get_organ(zone) + var/organ = affecting.display_name + + attack_damage = Clamp(attack_damage, 1, 5) + + switch(zone) + if("groin", "l_leg", "r_leg") + // -- LOWER BODY -- // + switch(attack_damage) + if(1 to 2) user.visible_message("[user] gave [target] a light [pick(attack_noun)] to the [organ]!") + if(3 to 4) user.visible_message("[user] [pick(attack_verb)] [target] in \his [organ]!") + if(5) user.visible_message("[user] landed a strong [pick(attack_noun)] against [target]'s [organ]!") + if("l_foot", "r_foot") + // ----- FEET ----- // + switch(attack_damage) + if(1 to 4) user.visible_message("[user] kicked [target] in \his [organ]!") + if(5) user.visible_message("[user] stomped down hard on [target]'s [organ]!") + +/datum/unarmed_attack/stomp + attack_verb = null + attack_noun = list("kick") + attack_sound = "swing_hit" + damage = 3 + +/datum/unarmed_attack/stomp/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone) + if (target.legcuffed) + return 0 + + if (target.lying && !user.lying) + var/datum/organ/external/E = user.organs_by_name["l_foot"] + if(E && !(E.status & ORGAN_DESTROYED)) + return 1 + + E = user.organs_by_name["r_foot"] + if(E && !(E.status & ORGAN_DESTROYED)) + return 1 + + return 0 + +/datum/unarmed_attack/stomp/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) + var/datum/organ/external/affecting = target.get_organ(zone) + var/organ = affecting.display_name + + attack_damage = Clamp(attack_damage, 1, 5) + + switch(attack_damage) + if(1 to 3) + user.visible_message("[user] [pick("gave a kick against", "kicked against", "stomped down on", "slammed their foot into")] [target]'s [organ]!") + if(4 to 5) + user.visible_message("[user] [pick("landed a strong kick against", "kicked against", "stomped down hard on", "rammed their foot into")] [target]'s [organ]!") + +/datum/unarmed_attack/diona + attack_verb = list("lashed", "bludgeoned") + attack_noun = list("tendril") + damage = 5 + +/datum/unarmed_attack/claws + attack_verb = list("scratched", "clawed", "slashed") + attack_noun = list("claws") + attack_sound = 'sound/weapons/slice.ogg' + miss_sound = 'sound/weapons/slashmiss.ogg' + damage = 5 + sharp = 1 + edge = 1 + +/datum/unarmed_attack/claws/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) + var/skill = user.skills["combat"] + var/datum/organ/external/affecting = target.get_organ(zone) + + if(!skill) skill = 1 + attack_damage = Clamp(attack_damage, 1, 5) + + if(target == user) + user.visible_message("[user] [pick(attack_verb)] \himself in the [affecting.display_name]!") + return 0 + + switch(zone) + if("head", "mouth", "eyes") + // ----- HEAD ----- // + switch(attack_damage) + if(1 to 2) user.visible_message("[user] scratched [target] across \his cheek!") + if(3 to 4) user.visible_message("[user] [pick(attack_verb)] [target]'s [pick("head", "neck")] [pick("", "", "", "with spread [pick(attack_noun)]")]!") + if(5) user.visible_message("[pick("[user] [pick(attack_verb)] [target] across \his face!", "[user] rakes \his [pick(attack_noun)] across [target]'s face!")]") + if("chest", "l_arm", "r_arm", "l_hand", "r_hand", "groin", "l_leg", "r_leg", "l_foot", "r_foot") + // ----- BODY ----- // + switch(attack_damage) + if(1 to 2) user.visible_message("[user] scratched [target]'s [affecting.display_name]!") + if(3 to 4) user.visible_message("[user] [pick(attack_verb)] [pick("", "", "the side of")] [target]'s [affecting.display_name]!") + if(5) user.visible_message("[user] tears \his [pick(attack_noun)] deep into [target]'s [affecting.display_name]!") + +/datum/unarmed_attack/claws/strong + attack_verb = list("slash") + damage = 10 + shredding = 1 + +/datum/unarmed_attack/bite/strong + attack_verb = list("maul") + damage = 15 + shredding = 1 + +/datum/unarmed_attack/slime_glomp + attack_verb = list("glomped") + attack_noun = list("body") + damage = 0 + +/datum/unarmed_attack/slime_glomp/apply_effects() + //Todo, maybe have a chance of causing an electrical shock? + return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/species_hud.dm b/code/modules/mob/living/carbon/human/species/species_hud.dm new file mode 100644 index 0000000000..7a041691b1 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/species_hud.dm @@ -0,0 +1,53 @@ +/datum/hud_data + var/icon // If set, overrides ui_style. + var/has_a_intent = 1 // Set to draw intent box. + var/has_m_intent = 1 // Set to draw move intent box. + var/has_warnings = 1 // Set to draw environment warnings. + var/has_pressure = 1 // Draw the pressure indicator. + var/has_nutrition = 1 // Draw the nutrition indicator. + var/has_bodytemp = 1 // Draw the bodytemp indicator. + var/has_hands = 1 // Set to draw shand. + var/has_drop = 1 // Set to draw drop button. + var/has_throw = 1 // Set to draw throw button. + var/has_resist = 1 // Set to draw resist button. + var/has_internals = 1 // Set to draw the internals toggle button. + var/list/equip_slots = list() // Checked by mob_can_equip(). + + // Contains information on the position and tag for all inventory slots + // to be drawn for the mob. This is fairly delicate, try to avoid messing with it + // unless you know exactly what it does. + var/list/gear = list( + "i_clothing" = list("loc" = ui_iclothing, "slot" = slot_w_uniform, "state" = "center", "toggle" = 1, "dir" = SOUTH), + "o_clothing" = list("loc" = ui_oclothing, "slot" = slot_wear_suit, "state" = "equip", "toggle" = 1, "dir" = SOUTH), + "mask" = list("loc" = ui_mask, "slot" = slot_wear_mask, "state" = "equip", "toggle" = 1, "dir" = NORTH), + "gloves" = list("loc" = ui_gloves, "slot" = slot_gloves, "state" = "gloves", "toggle" = 1), + "eyes" = list("loc" = ui_glasses, "slot" = slot_glasses, "state" = "glasses","toggle" = 1), + "l_ear" = list("loc" = ui_l_ear, "slot" = slot_l_ear, "state" = "ears", "toggle" = 1), + "r_ear" = list("loc" = ui_r_ear, "slot" = slot_r_ear, "state" = "ears", "toggle" = 1), + "head" = list("loc" = ui_head, "slot" = slot_head, "state" = "hair", "toggle" = 1), + "shoes" = list("loc" = ui_shoes, "slot" = slot_shoes, "state" = "shoes", "toggle" = 1), + "suit storage" = list("loc" = ui_sstore1, "slot" = slot_s_store, "state" = "belt", "dir" = 8), + "back" = list("loc" = ui_back, "slot" = slot_back, "state" = "back", "dir" = NORTH), + "id" = list("loc" = ui_id, "slot" = slot_wear_id, "state" = "id", "dir" = NORTH), + "storage1" = list("loc" = ui_storage1, "slot" = slot_l_store, "state" = "pocket"), + "storage2" = list("loc" = ui_storage2, "slot" = slot_r_store, "state" = "pocket"), + "belt" = list("loc" = ui_belt, "slot" = slot_belt, "state" = "belt") + ) + +/datum/hud_data/New() + ..() + for(var/slot in gear) + equip_slots |= gear[slot]["slot"] + + if(has_hands) + equip_slots |= slot_l_hand + equip_slots |= slot_r_hand + equip_slots |= slot_handcuffed + + if(slot_back in equip_slots) + equip_slots |= slot_in_backpack + + if(slot_w_uniform in equip_slots) + equip_slots |= slot_tie + + equip_slots |= slot_legcuffed diff --git a/code/modules/mob/living/carbon/human/species/station/golem.dm b/code/modules/mob/living/carbon/human/species/station/golem.dm new file mode 100644 index 0000000000..b115b75b29 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/station/golem.dm @@ -0,0 +1,17 @@ +/datum/species/golem + name = "Golem" + name_plural = "golems" + language = "Sol Common" //todo? + unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch) + flags = IS_RESTRICTED | NO_BREATHE | NO_PAIN | NO_BLOOD | IS_SYNTHETIC | NO_SCAN | NO_POISON + + breath_type = null + poison_type = null + +/datum/species/golem/handle_post_spawn(var/mob/living/carbon/human/H) + if(H.mind) + H.mind.assigned_role = "Golem" + H.mind.special_role = "Golem" + H.real_name = "adamantine golem ([rand(1, 1000)])" + H.name = H.real_name + ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/station/slime.dm b/code/modules/mob/living/carbon/human/species/station/slime.dm new file mode 100644 index 0000000000..63a7061926 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/station/slime.dm @@ -0,0 +1,10 @@ +/datum/species/slime + name = "Slime" + name_plural = "slimes" + language = "Sol Common" //todo? + unarmed_types = list(/datum/unarmed_attack/slime_glomp) + flags = IS_RESTRICTED | NO_SCAN | NO_SLIP | NO_BREATHE + darksight = 3 + + breath_type = null + poison_type = null \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm new file mode 100644 index 0000000000..6b2a01b468 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species/station/station.dm @@ -0,0 +1,207 @@ +/datum/species/human + name = "Human" + name_plural = "Humans" + language = "Sol Common" + primitive = /mob/living/carbon/monkey + unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite) + blurb = "Humanity originated in the Sol system, and over the last five centuries has spread \ + colonies across a wide swathe of space. They hold a wide range of forms and creeds.

\ + While the central Sol government maintains control of its far-flung people, powerful corporate \ + interests, rampant cyber and bio-augmentation and secretive factions make life on most human \ + worlds tumultous at best." + + flags = CAN_JOIN | HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR + +/datum/species/unathi + name = "Unathi" + name_plural = "Unathi" + icobase = 'icons/mob/human_races/r_lizard.dmi' + deform = 'icons/mob/human_races/r_def_lizard.dmi' + language = "Sinta'unathi" + tail = "sogtail" + unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp) + primitive = /mob/living/carbon/monkey/unathi + darksight = 3 + gluttonous = 1 + + blurb = "A heavily reptillian species, Unathi (or 'Sinta as they call themselves) hail from the \ + Uuosa-Eso system, which roughly translates to 'burning mother'.

Coming from a harsh, radioactive \ + desert planet, they mostly hold ideals of honesty, virtue, martial combat and bravery above all \ + else, frequently even their own lives. They prefer warmer temperatures than most species and \ + their native tongue is a heavy hissing laungage called Sinta'Unathi." + + cold_level_1 = 280 //Default 260 - Lower is better + cold_level_2 = 220 //Default 200 + cold_level_3 = 130 //Default 120 + + heat_level_1 = 420 //Default 360 - Higher is better + heat_level_2 = 480 //Default 400 + heat_level_3 = 1100 //Default 1000 + + flags = CAN_JOIN | IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR + + flesh_color = "#34AF10" + + reagent_tag = IS_UNATHI + base_color = "#066000" + +/datum/species/tajaran + name = "Tajara" + name_plural = "Tajaran" + icobase = 'icons/mob/human_races/r_tajaran.dmi' + deform = 'icons/mob/human_races/r_def_tajaran.dmi' + language = "Siik'tajr" + tail = "tajtail" + unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/claws, /datum/unarmed_attack/bite/sharp) + darksight = 8 + blurb = "The Tajaran race is a species of feline-like bipeds hailing from the planet of Ahdomai in the \ + S'randarr system. They have been brought up into the space age by the Humans and Skrell, and have been \ + influenced heavily by their long history of Slavemaster rule. They have a structured, clan-influenced way \ + of family and politics. They prefer colder environments, and speak a variety of languages, mostly Siik'Maas, \ + using unique inflections their mouths form." + + cold_level_1 = 200 //Default 260 + cold_level_2 = 140 //Default 200 + cold_level_3 = 80 //Default 120 + + heat_level_1 = 330 //Default 360 + heat_level_2 = 380 //Default 400 + heat_level_3 = 800 //Default 1000 + + primitive = /mob/living/carbon/monkey/tajara + + flags = CAN_JOIN | IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR + + flesh_color = "#AFA59E" + base_color = "#333333" + +/datum/species/skrell + name = "Skrell" + name_plural = "Skrell" + icobase = 'icons/mob/human_races/r_skrell.dmi' + deform = 'icons/mob/human_races/r_def_skrell.dmi' + eyes = "skrell_eyes_s" + language = "Skrellian" + primitive = /mob/living/carbon/monkey/skrell + unarmed_types = list(/datum/unarmed_attack/punch) + blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \ + the royals' or 'Light of the Crown'.

Skrell are a highly advanced and logical race who live under the rule \ + of the Qerr'Katish, a caste within their society which keeps the empire of the Skrell running smoothly. Skrell are \ + herbivores on the whole and tend to be co-operative with the other species of the galaxy, although they rarely reveal \ + the secrets of their empire to their allies." + + flags = CAN_JOIN | IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR + + flesh_color = "#8CD7A3" + blood_color = "#1D2CBF" + + reagent_tag = IS_SKRELL + +/datum/species/diona + name = "Diona" + name_plural = "Dionaea" + icobase = 'icons/mob/human_races/r_diona.dmi' + deform = 'icons/mob/human_races/r_def_plant.dmi' + language = "Rootspeak" + unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/diona) + primitive = /mob/living/carbon/alien/diona + slowdown = 7 + rarity_value = 3 + blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \ + species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \ + there is no effective upper limit to the number that can fuse in gestalt, and reports exist of the Epsilon Ursae \ + Minoris primary being ringed with a cloud of singing space-station-sized entities.

The Dionaea coexist peacefully with \ + all known species, especially the Skrell. Their communal mind makes them slow to react, and they have difficulty understanding \ + even the simplest concepts of other minds. Their alien physiology allows them survive happily off a diet of nothing but light, \ + water and other radiation." + + has_organ = list( + "nutrient channel" = /datum/organ/internal/diona/nutrients, + "neural strata" = /datum/organ/internal/diona/strata, + "response node" = /datum/organ/internal/diona/node, + "gas bladder" = /datum/organ/internal/diona/bladder, + "polyp segment" = /datum/organ/internal/diona/polyp, + "anchoring ligament" = /datum/organ/internal/diona/ligament + ) + + warning_low_pressure = 50 + hazard_low_pressure = -1 + + cold_level_1 = 50 + cold_level_2 = -1 + cold_level_3 = -1 + + heat_level_1 = 2000 + heat_level_2 = 3000 + heat_level_3 = 4000 + + body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not + + flags = CAN_JOIN | IS_WHITELISTED | NO_BREATHE | NO_SCAN | IS_PLANT | NO_BLOOD | NO_PAIN | NO_SLIP | HAS_EYE_COLOR + + blood_color = "#004400" + flesh_color = "#907E4A" + + reagent_tag = IS_DIONA + +/datum/species/diona/can_understand(var/mob/other) + var/mob/living/carbon/alien/diona/D = other + if(istype(D)) + return 1 + return 0 + +/datum/species/diona/handle_post_spawn(var/mob/living/carbon/human/H) + H.gender = NEUTER + return ..() + +/datum/species/diona/handle_death(var/mob/living/carbon/human/H) + + var/mob/living/carbon/alien/diona/S = new(get_turf(H)) + + if(H.mind) + H.mind.transfer_to(S) + + for(var/mob/living/carbon/alien/diona/D in H.contents) + if(D.client) + D.loc = H.loc + else + del(D) + + H.visible_message("\red[H] splits apart with a wet slithering noise!") + +/datum/species/machine + name = "Machine" + name_plural = "machines" + + icobase = 'icons/mob/human_races/r_machine.dmi' + deform = 'icons/mob/human_races/r_machine.dmi' + language = "Tradeband" + unarmed_types = list(/datum/unarmed_attack/punch) + rarity_value = 2 + + eyes = "blank_eyes" + brute_mod = 0.5 + burn_mod = 1 + + warning_low_pressure = 50 + hazard_low_pressure = 0 + + cold_level_1 = 50 + cold_level_2 = -1 + cold_level_3 = -1 + + heat_level_1 = 500 //gives them about 25 seconds in space before taking damage + heat_level_2 = 1000 + heat_level_3 = 2000 + + synth_temp_gain = 10 //this should cause IPCs to stabilize at ~80 C in a 20 C environment. + + flags = CAN_JOIN | IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | IS_SYNTHETIC + + blood_color = "#1F181F" + flesh_color = "#575757" + + has_organ = list( + "heart" = /datum/organ/internal/heart, + "brain" = /datum/organ/internal/brain, + ) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/alien/alien_embryo.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm similarity index 100% rename from code/modules/mob/living/carbon/human/alien/alien_embryo.dm rename to code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm diff --git a/code/modules/mob/living/carbon/human/alien/alien_facehugger.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm similarity index 100% rename from code/modules/mob/living/carbon/human/alien/alien_facehugger.dm rename to code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm diff --git a/code/modules/mob/living/carbon/human/alien/alien_powers.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm similarity index 100% rename from code/modules/mob/living/carbon/human/alien/alien_powers.dm rename to code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm diff --git a/code/modules/mob/living/carbon/human/alien/alien_species.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm similarity index 99% rename from code/modules/mob/living/carbon/human/alien/alien_species.dm rename to code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm index 3e6fada92c..64d5974f25 100644 --- a/code/modules/mob/living/carbon/human/alien/alien_species.dm +++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm @@ -25,7 +25,7 @@ cold_level_2 = -1 cold_level_3 = -1 - flags = NO_BREATHE | NO_SCAN | NO_PAIN | NO_SLIP | NO_POISON + flags = IS_RESTRICTED | NO_BREATHE | NO_SCAN | NO_PAIN | NO_SLIP | NO_POISON reagent_tag = IS_XENOS diff --git a/code/modules/mob/living/carbon/human/alien/alien.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/xenomorphs.dm similarity index 100% rename from code/modules/mob/living/carbon/human/alien/alien.dm rename to code/modules/mob/living/carbon/human/species/xenomorphs/xenomorphs.dm diff --git a/code/modules/mob/living/carbon/human/unarmed_attack.dm b/code/modules/mob/living/carbon/human/unarmed_attack.dm index 3986c39a44..e69de29bb2 100644 --- a/code/modules/mob/living/carbon/human/unarmed_attack.dm +++ b/code/modules/mob/living/carbon/human/unarmed_attack.dm @@ -1,254 +0,0 @@ -//Species unarmed attacks -/datum/unarmed_attack - var/attack_verb = list("attack") // Empty hand hurt intent verb. - var/attack_noun = list("fist") - var/damage = 0 // Extra empty hand attack damage. - var/attack_sound = "punch" - var/miss_sound = 'sound/weapons/punchmiss.ogg' - var/shredding = 0 // Calls the old attack_alien() behavior on objects/mobs when on harm intent. - var/sharp = 0 - var/edge = 0 - -/datum/unarmed_attack/proc/is_usable(var/mob/living/carbon/human/user) - if(user.restrained()) - return 0 - - // Check if they have a functioning hand. - var/datum/organ/external/E = user.organs_by_name["l_hand"] - if(E && !(E.status & ORGAN_DESTROYED)) - return 1 - - E = user.organs_by_name["r_hand"] - if(E && !(E.status & ORGAN_DESTROYED)) - return 1 - - return 0 - -/datum/unarmed_attack/proc/apply_effects(var/mob/living/carbon/human/user,var/mob/living/carbon/human/target,var/armour,var/attack_damage,var/zone) - - var/stun_chance = rand(0, 100) - - if(attack_damage >= 5 && armour < 2 && !(target == user) && stun_chance <= attack_damage * 5) // 25% standard chance - switch(zone) // strong punches can have effects depending on where they hit - if("head", "mouth", "eyes") - // Induce blurriness - target.visible_message("[target] looks dazed.", "You see stars.") - target.apply_effect(attack_damage*2, EYE_BLUR, armour) - if("l_arm", "l_hand") - if (target.l_hand) - // Disarm left hand - target.visible_message("[src] [pick("dropped", "let go off")] \the [target.l_hand][pick("", " with a scream")]!") - target.drop_l_hand() - if("r_arm", "r_hand") - if (target.r_hand) - // Disarm right hand - target.visible_message("[src] [pick("dropped", "let go off")] \the [target.r_hand][pick("", " with a scream")]!") - target.drop_r_hand() - if("chest") - if(!target.lying) - var/turf/T = get_step(get_turf(target), get_dir(get_turf(user), get_turf(target))) - if(!T.density) - step(target, get_dir(get_turf(user), get_turf(target))) - target.visible_message("[pick("[target] was sent flying backward!", "[target] staggers back from the impact!")]") - else - target.visible_message("[target] slams into [T]!") - if(prob(50)) - target.set_dir(reverse_dir[target.dir]) - target.apply_effect(attack_damage * 0.4, WEAKEN, armour) - if("groin") - target.visible_message("[target] looks like \he is in pain!", "[(target.gender=="female") ? "Oh god that hurt!" : "Oh no, not your[pick("testicles", "crown jewels", "clockweights", "family jewels", "marbles", "bean bags", "teabags", "sweetmeats", "goolies")]!"]") - target.apply_effects(stutter = attack_damage * 2, agony = attack_damage* 3, blocked = armour) - if("l_leg", "l_foot", "r_leg", "r_foot") - if(!target.lying) - target.visible_message("[src] gives way slightly.") - target.apply_effect(attack_damage*3, AGONY, armour) - else if(attack_damage >= 5 && !(target == user) && (stun_chance + attack_damage * 5 >= 100) && armour < 2) // Chance to get the usual throwdown as well (25% standard chance) - if(!target.lying) - target.visible_message("[target] [pick("slumps", "falls", "drops")] down to the ground!") - else - target.visible_message("[target] has been weakened!") - target.apply_effect(3, WEAKEN, armour) - -/datum/unarmed_attack/proc/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) - var/datum/organ/external/affecting = target.get_organ(zone) - user.visible_message("[user] [pick(attack_verb)] [target] in the [affecting.display_name]!") - playsound(user.loc, attack_sound, 25, 1, -1) - -/datum/unarmed_attack/bite - attack_verb = list("bit") - attack_sound = 'sound/weapons/bite.ogg' - shredding = 0 - damage = 0 - sharp = 0 - edge = 0 - -/datum/unarmed_attack/bite/sharp //eye teeth - attack_verb = list("bit", "chomped on") - attack_sound = 'sound/weapons/bite.ogg' - shredding = 0 - damage = 5 - sharp = 1 - edge = 1 - -/datum/unarmed_attack/bite/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone) - if (user.wear_mask && istype(user.wear_mask, /obj/item/clothing/mask/muzzle)) - return 0 - if (user == target && (zone == "head" || zone == "eyes" || zone == "mouth")) - return 0 - return 1 - -/datum/unarmed_attack/punch - attack_verb = list("punched") - attack_noun = list("fist") - damage = 0 - -/datum/unarmed_attack/punch/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) - var/datum/organ/external/affecting = target.get_organ(zone) - var/organ = affecting.display_name - - attack_damage = Clamp(attack_damage, 1, 5) // We expect damage input of 1 to 5 for this proc. But we leave this check juuust in case. - - if(target == user) - user.visible_message("[user] [pick(attack_verb)] \himself in the [organ]!") - return 0 - - if(!target.lying) - switch(zone) - if("head", "mouth", "eyes") - // ----- HEAD ----- // - switch(attack_damage) - if(1 to 2) user.visible_message("[user] slapped [target] across \his cheek!") - if(3 to 4) user.visible_message("[user] struck [target] in the head[pick("", " with a closed fist")]!") - if(5) user.visible_message("[user] gave [target] a resounding slap to the face!") - if("chest", "l_arm", "r_arm", "l_hand", "r_hand", "groin", "l_leg", "r_let", "l_foot", "r_foot") - // ----- BODY ----- // - switch(attack_damage) - if(1 to 2) user.visible_message("[user] slapped [target]'s [organ]!") - if(3 to 4) user.visible_message("[user] [pick(attack_verb)] [target] in \his [organ]!") - if(5) user.visible_message("[user] slammed \his [pick(attack_noun)] into [target]'s [organ]!") - else - user.visible_message("[user] [pick("punched", "threw a punch", "struck", "slapped", "rammed their [pick(attack_noun)] into")] [target]'s [organ]!") - -/datum/unarmed_attack/kick - attack_verb = list("kicked", "kneed") - attack_noun = list("kick") - attack_sound = "swing_hit" - damage = 1 - -/datum/unarmed_attack/kick/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone) - if (target.legcuffed) - return 0 - - if(!(zone in list("l_leg", "r_leg", "l_foot", "r_foot", "groin"))) - return 0 - - var/datum/organ/external/E = user.organs_by_name["l_foot"] - if(E && !(E.status & ORGAN_DESTROYED)) - return 1 - - E = user.organs_by_name["r_foot"] - if(E && !(E.status & ORGAN_DESTROYED)) - return 1 - - return 0 - -/datum/unarmed_attack/kick/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) - var/datum/organ/external/affecting = target.get_organ(zone) - var/organ = affecting.display_name - - attack_damage = Clamp(attack_damage, 1, 5) - - switch(zone) - if("groin", "l_leg", "r_leg") - // -- LOWER BODY -- // - switch(attack_damage) - if(1 to 2) user.visible_message("[user] gave [target] a light [pick(attack_noun)] to the [organ]!") - if(3 to 4) user.visible_message("[user] [pick(attack_verb)] [target] in \his [organ]!") - if(5) user.visible_message("[user] landed a strong [pick(attack_noun)] against [target]'s [organ]!") - if("l_foot", "r_foot") - // ----- FEET ----- // - switch(attack_damage) - if(1 to 4) user.visible_message("[user] kicked [target] in \his [organ]!") - if(5) user.visible_message("[user] stomped down hard on [target]'s [organ]!") - -/datum/unarmed_attack/stomp - attack_verb = null - attack_noun = list("kick") - attack_sound = "swing_hit" - damage = 3 - -/datum/unarmed_attack/stomp/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone) - if (target.legcuffed) - return 0 - - if (target.lying && !user.lying) - var/datum/organ/external/E = user.organs_by_name["l_foot"] - if(E && !(E.status & ORGAN_DESTROYED)) - return 1 - - E = user.organs_by_name["r_foot"] - if(E && !(E.status & ORGAN_DESTROYED)) - return 1 - - return 0 - -/datum/unarmed_attack/stomp/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) - var/datum/organ/external/affecting = target.get_organ(zone) - var/organ = affecting.display_name - - attack_damage = Clamp(attack_damage, 1, 5) - - switch(attack_damage) - if(1 to 3) - user.visible_message("[user] [pick("gave a kick against", "kicked against", "stomped down on", "slammed their foot into")] [target]'s [organ]!") - if(4 to 5) - user.visible_message("[user] [pick("landed a strong kick against", "kicked against", "stomped down hard on", "rammed their foot into")] [target]'s [organ]!") - -/datum/unarmed_attack/diona - attack_verb = list("lashed", "bludgeoned") - attack_noun = list("tendril") - damage = 5 - -/datum/unarmed_attack/claws - attack_verb = list("scratched", "clawed", "slashed") - attack_noun = list("claws") - attack_sound = 'sound/weapons/slice.ogg' - miss_sound = 'sound/weapons/slashmiss.ogg' - damage = 5 - sharp = 1 - edge = 1 - -/datum/unarmed_attack/claws/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage) - var/skill = user.skills["combat"] - var/datum/organ/external/affecting = target.get_organ(zone) - - if(!skill) skill = 1 - attack_damage = Clamp(attack_damage, 1, 5) - - if(target == user) - user.visible_message("[user] [pick(attack_verb)] \himself in the [affecting.display_name]!") - return 0 - - switch(zone) - if("head", "mouth", "eyes") - // ----- HEAD ----- // - switch(attack_damage) - if(1 to 2) user.visible_message("[user] scratched [target] across \his cheek!") - if(3 to 4) user.visible_message("[user] [pick(attack_verb)] [target]'s [pick("head", "neck")] [pick("", "", "", "with spread [pick(attack_noun)]")]!") - if(5) user.visible_message("[pick("[user] [pick(attack_verb)] [target] across \his face!", "[user] rakes \his [pick(attack_noun)] across [target]'s face!")]") - if("chest", "l_arm", "r_arm", "l_hand", "r_hand", "groin", "l_leg", "r_leg", "l_foot", "r_foot") - // ----- BODY ----- // - switch(attack_damage) - if(1 to 2) user.visible_message("[user] scratched [target]'s [affecting.display_name]!") - if(3 to 4) user.visible_message("[user] [pick(attack_verb)] [pick("", "", "the side of")] [target]'s [affecting.display_name]!") - if(5) user.visible_message("[user] tears \his [pick(attack_noun)] deep into [target]'s [affecting.display_name]!") - -/datum/unarmed_attack/claws/strong - attack_verb = list("slash") - damage = 10 - shredding = 1 - -/datum/unarmed_attack/bite/strong - attack_verb = list("maul") - damage = 15 - shredding = 1 diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 860f5a9a25..ae9a733fec 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -68,7 +68,6 @@ There are several things that need to be remembered: > There are also these special cases: update_mutations() //handles updating your appearance for certain mutations. e.g TK head-glows - update_mutantrace() //handles updating your appearance after setting the mutantrace var UpdateDamageIcon() //handles damage overlays for brute/burn damage //(will rename this when I geta round to it) update_body() //Handles updating your mob's icon to reflect their gender/race/complexion etc update_hair() //Handles updating your hair overlay (used to be update_face, but mouth and @@ -106,30 +105,29 @@ Please contact me on #coderbus IRC. ~Carn x */ //Human Overlays Indexes///////// -#define MUTANTRACE_LAYER 1 -#define MUTATIONS_LAYER 2 -#define DAMAGE_LAYER 3 -#define UNIFORM_LAYER 4 -#define TAIL_LAYER 5 //bs12 specific. this hack is probably gonna come back to haunt me -#define ID_LAYER 6 -#define SHOES_LAYER 7 -#define GLOVES_LAYER 8 -#define SUIT_LAYER 9 -#define GLASSES_LAYER 10 -#define BELT_LAYER 11 //Possible make this an overlay of somethign required to wear a belt? -#define SUIT_STORE_LAYER 12 -#define BACK_LAYER 13 -#define HAIR_LAYER 14 //TODO: make part of head layer? -#define EARS_LAYER 15 -#define FACEMASK_LAYER 16 -#define HEAD_LAYER 17 -#define COLLAR_LAYER 18 -#define HANDCUFF_LAYER 19 -#define LEGCUFF_LAYER 20 -#define L_HAND_LAYER 21 -#define R_HAND_LAYER 22 -#define TARGETED_LAYER 23 //BS12: Layer for the target overlay from weapon targeting system -#define TOTAL_LAYERS 23 +#define MUTATIONS_LAYER 1 +#define DAMAGE_LAYER 2 +#define UNIFORM_LAYER 3 +#define TAIL_LAYER 4 //bs12 specific. this hack is probably gonna come back to haunt me +#define ID_LAYER 5 +#define SHOES_LAYER 6 +#define GLOVES_LAYER 7 +#define SUIT_LAYER 8 +#define GLASSES_LAYER 9 +#define BELT_LAYER 10 //Possible make this an overlay of somethign required to wear a belt? +#define SUIT_STORE_LAYER 11 +#define BACK_LAYER 12 +#define HAIR_LAYER 13 //TODO: make part of head layer? +#define EARS_LAYER 14 +#define FACEMASK_LAYER 15 +#define HEAD_LAYER 16 +#define COLLAR_LAYER 17 +#define HANDCUFF_LAYER 18 +#define LEGCUFF_LAYER 19 +#define L_HAND_LAYER 20 +#define R_HAND_LAYER 21 +#define TARGETED_LAYER 22 //BS12: Layer for the target overlay from weapon targeting system +#define TOTAL_LAYERS 22 ////////////////////////////////// /mob/living/carbon/human @@ -271,8 +269,6 @@ proc/get_damage_icon_part(damage_state, body_part) else //BEGIN CACHED ICON GENERATION. - - // Why don't we just make skeletons/shadows/golems a species? ~Z var/race_icon = (skeleton ? 'icons/mob/human_races/r_skeleton.dmi' : species.icobase) var/deform_icon = (skeleton ? 'icons/mob/human_races/r_skeleton.dmi' : species.icobase) @@ -478,26 +474,6 @@ proc/get_damage_icon_part(damage_state, body_part) overlays_standing[MUTATIONS_LAYER] = null if(update_icons) update_icons() - -/mob/living/carbon/human/proc/update_mutantrace(var/update_icons=1) - var/fat - - if( FAT in mutations ) - fat = "fat" - - if(dna) - switch(dna.mutantrace) - if("golem","slime","shadow","adamantine") - overlays_standing[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/genetics.dmi', "icon_state" = "[dna.mutantrace][fat]_[gender]_s") - else - overlays_standing[MUTANTRACE_LAYER] = null - - if(!dna || !(dna.mutantrace in list("golem","metroid"))) - update_body(0) - - update_hair(0) - if(update_icons) update_icons() - //Call when target overlay should be added/removed /mob/living/carbon/human/update_targeted(var/update_icons=1) if (targeted_by && target_locked) @@ -515,7 +491,6 @@ proc/get_damage_icon_part(damage_state, body_part) ..() if(monkeyizing) return update_mutations(0) - update_mutantrace(0) update_inv_w_uniform(0) update_inv_wear_id(0) update_inv_gloves(0) @@ -972,7 +947,6 @@ proc/get_damage_icon_part(damage_state, body_part) return face_lying_image //Human Overlays Indexes///////// -#undef MUTANTRACE_LAYER #undef MUTATIONS_LAYER #undef DAMAGE_LAYER #undef UNIFORM_LAYER diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm index 0552892025..de34d74afa 100644 --- a/code/modules/mob/living/carbon/metroid/life.dm +++ b/code/modules/mob/living/carbon/metroid/life.dm @@ -342,9 +342,8 @@ if(istype(L, /mob/living/carbon/human) && dna) //Ignore slime(wo)men var/mob/living/carbon/human/H = L - if(H.dna) - if(H.dna.mutantrace == "slime") - continue + if(H.species.name == "Slime") + continue if(!L.canmove) // Only one slime can latch on at a time. var/notarget = 0 @@ -575,3 +574,6 @@ if (Leader) return 0 if (holding_still) return 0 return 1 + +/mob/living/carbon/slime/slip() //Can't slip something without legs. + return 0 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm index 47c35b488f..42a9c858f5 100644 --- a/code/modules/mob/living/carbon/metroid/metroid.dm +++ b/code/modules/mob/living/carbon/metroid/metroid.dm @@ -797,16 +797,8 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75 if(!ghost) user << "The rune fizzles uselessly. There is no spirit nearby." return - var/mob/living/carbon/human/G = new /mob/living/carbon/human - G.dna.mutantrace = "adamantine" - G.real_name = text("Adamantine Golem ([rand(1, 1000)])") - G.equip_to_slot_or_del(new /obj/item/clothing/under/golem(G), slot_w_uniform) - G.equip_to_slot_or_del(new /obj/item/clothing/suit/golem(G), slot_wear_suit) - G.equip_to_slot_or_del(new /obj/item/clothing/shoes/golem(G), slot_shoes) - G.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/golem(G), slot_wear_mask) - G.equip_to_slot_or_del(new /obj/item/clothing/gloves/golem(G), slot_gloves) - //G.equip_to_slot_or_del(new /obj/item/clothing/head/space/golem(G), slot_head) - G.loc = src.loc + var/mob/living/carbon/human/G = new(src.loc) + G.set_species("Golem") G.key = ghost.key G << "You are an adamantine golem. You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. Serve [user], and assist them in completing their goals at any cost." del (src) diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index a45106b7e0..f9b12bc02e 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -82,18 +82,6 @@ update_icons() return -/mob/living/carbon/monkey/unathi/New() - ..() - dna.mutantrace = "lizard" - -/mob/living/carbon/monkey/skrell/New() - ..() - dna.mutantrace = "skrell" - -/mob/living/carbon/monkey/tajara/New() - ..() - dna.mutantrace = "tajaran" - /mob/living/carbon/monkey/movement_delay() var/tally = 0 if(reagents) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 5ca7d569dd..b243dcb159 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -838,4 +838,7 @@ return 1 /mob/living/proc/has_eyes() - return 1 \ No newline at end of file + return 1 + +/mob/living/proc/slip(var/slipped_on,stun_duration=8) + return 0 \ No newline at end of file diff --git a/code/modules/mob/living/silicon/death.dm b/code/modules/mob/living/silicon/death.dm index 2b56af7537..ccc9f5f536 100644 --- a/code/modules/mob/living/silicon/death.dm +++ b/code/modules/mob/living/silicon/death.dm @@ -1,6 +1,6 @@ /mob/living/silicon/gib() ..("gibbed-r") - robogibs(loc, viruses) + gibs(loc, viruses, null, null, /obj/effect/gibspawner/robot) /mob/living/silicon/dust() ..("dust-r", /obj/effect/decal/remains/robot) diff --git a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm index 4122e3a210..1aff173aa7 100644 --- a/code/modules/mob/living/simple_animal/friendly/spiderbot.dm +++ b/code/modules/mob/living/simple_animal/friendly/spiderbot.dm @@ -208,7 +208,7 @@ held_item.loc = src.loc held_item = null - robogibs(src.loc, viruses) + gibs(loc, viruses, null, null, /obj/effect/gibspawner/robot) //TODO: use gib() or refactor spiderbots into synthetics. src.Del() return diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 831f3aa83a..92052b84e1 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -197,12 +197,6 @@ else ..() -/mob/living/simple_animal/gib() - if(meat_amount && meat_type) - for(var/i = 0; i < meat_amount; i++) - new meat_type(src.loc) - ..(icon_gib,1) - /mob/living/simple_animal/emote(var/act, var/type, var/desc) if(act) ..(act, type, desc) @@ -228,7 +222,7 @@ if("help") if (health > 0) M.visible_message("\blue [M] [response_help] \the [src]") - + if("disarm") M.visible_message("\blue [M] [response_disarm] \the [src]") //TODO: Push the mob away or something @@ -255,43 +249,43 @@ return -/mob/living/simple_animal/attackby(var/obj/item/O as obj, var/mob/user as mob) //Marker -Agouri +/mob/living/simple_animal/attackby(var/obj/item/O, var/mob/user) //Marker -Agouri + if(istype(O, /obj/item/stack/medical)) - if(stat != DEAD) - var/obj/item/stack/medical/MED = O - if(health < maxHealth) - if(MED.get_amount() >= 1) - adjustBruteLoss(-MED.heal_brute) - MED.use(1) - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\blue [user] applies the [MED] on [src]") + if(stat != DEAD && health < maxHealth) + var/obj/item/stack/medical/medical_pack = O + if(medical_pack.use(1)) + adjustBruteLoss(-medical_pack.heal_brute) + visible_message("\The [user] applies the [medical_pack] to \the [src].") else - user << "\blue this [src] is dead, medical items won't bring it back to life." - if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead. - if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch)) - new meat_type (get_turf(src)) - if(prob(95)) + user << "\The [src] cannot benefit from medical items in its current state." + return + + else if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch)) + + if(meat_type && (stat == DEAD)) + if(meat_amount && (meat_amount/2) >= 1) + for(var/i = 0; i < meat_amount/2; i++) + var/obj/item/meat = new meat_type(get_turf(src)) + meat.name = "[src.name] [meat.name]" + if(small) + user.visible_message("[user] chops up \the [src]!") del(src) - return - gib() + else + user.visible_message("[user] butchers \the [src] messily!") + gib() + return + + if(O.force) + var/damage = O.force + if (O.damtype == HALLOSS) + damage = 0 + adjustBruteLoss(damage) + visible_message("\The [src] has been attacked with \the [O] by [user].") else - if(O.force) - var/damage = O.force - if (O.damtype == HALLOSS) - damage = 0 - adjustBruteLoss(damage) - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red \b [src] has been attacked with the [O] by [user]. ") - else - usr << "\red This weapon is ineffective, it does no damage." - for(var/mob/M in viewers(src, null)) - if ((M.client && !( M.blinded ))) - M.show_message("\red [user] gently taps [src] with the [O]. ") - - + user << "This weapon is ineffective; it does no damage." + visible_message("\The [user] gently taps [src] with the [O].") /mob/living/simple_animal/movement_delay() var/tally = 0 //Incase I need to add stuff other than "speed" later diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index aee673df09..356036e1de 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1159,4 +1159,4 @@ mob/proc/yank_out_object() return 0 /mob/proc/updateicon() - return + return diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index a4382c16e5..c72639a5b0 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -145,7 +145,7 @@ usr << "\red The round is either not ready, or has already finished..." return - if(client.prefs.species != "Human") + if(client.prefs.species != "Human" && !check_rights(R_ADMIN, 0)) if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist) src << alert("You are currently not whitelisted to play [client.prefs.species].") return 0 @@ -172,8 +172,8 @@ return 0 var/datum/species/S = all_species[client.prefs.species] - if(!(S.flags & IS_WHITELISTED)) - src << alert("Your current species,[client.prefs.species], is not available for play on the station.") + if(!(S.flags & CAN_JOIN)) + src << alert("Your current species, [client.prefs.species], is not available for play on the station.") return 0 AttemptLateSpawn(href_list["SelectedJob"],client.prefs.spawnpoint) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index d2811fdfcc..b36359ccf6 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -53,8 +53,8 @@ /obj/item/weapon/gun/afterattack(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, flag, params) if(flag) return //It's adjacent, is the user, or is on the user's person if(istype(target, /obj/machinery/recharger) && istype(src, /obj/item/weapon/gun/energy)) return//Shouldnt flag take care of this? - - + + //decide whether to aim or shoot normally var/aiming = 0 if(user && user.client && !(A in target)) @@ -62,10 +62,10 @@ //If help intent is on and we have clicked on an eligible target, switch to aim mode automatically if(user.a_intent == "help" && isliving(A) && !C.gun_mode) C.ToggleGunMode() - + if(C.gun_mode) aiming = PreFire(A,user,params) //They're using the new gun system, locate what they're aiming at. - + if (!aiming) if(user && user.a_intent == "help") //regardless of what happens, refuse to shoot if help intent is on user << "\red You refrain from firing your [src] as your intent is set to help." @@ -92,11 +92,7 @@ if(istype(user, /mob/living)) var/mob/living/M = user if (HULK in M.mutations) - M << "\red Your meaty finger is much too large for the trigger guard!" - return - if(ishuman(user)) - if(user.dna && user.dna.mutantrace == "adamantine") - user << "\red Your metal fingers don't fit in the trigger guard!" + M << "\red Your fingers are much too large for the trigger guard!" return add_fingerprint(user) diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index f426eefb2f..49cd420994 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -80,7 +80,6 @@ on_hit(var/atom/target, var/blocked = 0) var/mob/living/M = target -// if(ishuman(target) && M.dna && M.dna.mutantrace == "plant") //Plantmen possibly get mutated and damaged by the rays. if(ishuman(target)) var/mob/living/carbon/human/H = M if((H.species.flags & IS_PLANT) && (M.nutrition < 500)) @@ -120,7 +119,6 @@ on_hit(var/atom/target, var/blocked = 0) var/mob/M = target -// if(ishuman(target) && M.dna && M.dna.mutantrace == "plant") //These rays make plantmen fat. if(ishuman(target)) //These rays make plantmen fat. var/mob/living/carbon/human/H = M if((H.species.flags & IS_PLANT) && (M.nutrition < 500)) diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 7393a255ab..7e11d25f9a 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -332,10 +332,9 @@ datum if(!M) M = holder.my_atom if(ishuman(M)) var/mob/living/carbon/human/human = M - if(human.dna.mutantrace == null) - M << "\red Your flesh rapidly mutates!" - human.dna.mutantrace = "slime" - human.update_mutantrace() + if(human.species.name != "Slime") + M << "Your flesh rapidly mutates!" + human.set_species("Slime") ..() return diff --git a/code/modules/reagents/reagent_containers/food/snacks/grown.dm b/code/modules/reagents/reagent_containers/food/snacks/grown.dm index 238d0ae84b..d570f13861 100644 --- a/code/modules/reagents/reagent_containers/food/snacks/grown.dm +++ b/code/modules/reagents/reagent_containers/food/snacks/grown.dm @@ -428,16 +428,9 @@ return /obj/item/weapon/reagent_containers/food/snacks/grown/bluetomato/Crossed(AM as mob|obj) - if (istype(AM, /mob/living/carbon)) - var/mob/M = AM - if (istype(M, /mob/living/carbon/human) && (isobj(M:shoes) && M:shoes.flags&NOSLIP) || M.buckled) - return - - M.stop_pulling() - M << "\blue You slipped on the [name]!" - playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3) - M.Stun(8) - M.Weaken(5) + if (istype(AM, /mob/living)) + var/mob/living/M = AM + M.slip("the [src]!") /obj/item/weapon/reagent_containers/food/snacks/grown/wheat name = "wheat" diff --git a/code/modules/reagents/reagent_containers/food/snacks/meat.dm b/code/modules/reagents/reagent_containers/food/snacks/meat.dm index e5d3c38bc6..ac888c00a6 100644 --- a/code/modules/reagents/reagent_containers/food/snacks/meat.dm +++ b/code/modules/reagents/reagent_containers/food/snacks/meat.dm @@ -23,12 +23,10 @@ name = "synthetic meat" desc = "A synthetic slab of flesh." +// Seperate definitions because some food likes to know if it's human. +// TODO: rewrite kitchen code to check a var on the meat item so we can remove +// all these sybtypes. /obj/item/weapon/reagent_containers/food/snacks/meat/human - name = "-meat" - var/subjectname = "" - var/subjectjob = null - - /obj/item/weapon/reagent_containers/food/snacks/meat/monkey //same as plain meat diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm index c5e883e79a..3f5cc5800f 100644 --- a/code/modules/surgery/surgery.dm +++ b/code/modules/surgery/surgery.dm @@ -5,7 +5,7 @@ // type path referencing tools that can be used for this step, and how well are they suited for it var/list/allowed_tools = null - // type paths referencing mutantraces that this step applies to. + // type paths referencing races that this step applies to. var/list/allowed_species = null var/list/disallowed_species = null diff --git a/code/setup.dm b/code/setup.dm index 5ebde2b9a3..7d85a7d0b7 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -742,21 +742,22 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse ) //Species flags. -#define NO_BLOOD 1 -#define NO_BREATHE 2 -#define NO_SCAN 4 -#define NO_PAIN 8 -#define NO_SLIP 16 -#define NO_POISON 32 - -#define HAS_SKIN_TONE 64 -#define HAS_SKIN_COLOR 128 -#define HAS_LIPS 256 -#define HAS_UNDERWEAR 512 -#define IS_PLANT 1024 -#define IS_WHITELISTED 2048 -#define IS_SYNTHETIC 4096 -#define HAS_EYE_COLOR 8192 +#define NO_BLOOD 1 // Vessel var is not filled with blood, cannot bleed out. +#define NO_BREATHE 2 // Cannot suffocate or take oxygen loss. +#define NO_SCAN 4 // Cannot be scanned in a DNA machine/genome-stolen. +#define NO_PAIN 8 // Cannot suffer halloss/recieves deceptive health indicator +#define NO_SLIP 16 // Cannot fall over +#define NO_POISON 32 // Cannot not suffer toxloss +#define HAS_SKIN_TONE 64 // Skin tone selectable in chargen (0-255) +#define HAS_SKIN_COLOR 128 // Skin colour selectable in chargen (RGB) +#define HAS_LIPS 256 // Lips are drawn onto the mob icon (lipstick) +#define HAS_UNDERWEAR 512 // Underwear is drawn onto the mob icon +#define IS_PLANT 1024 // Is a treeperson +#define IS_WHITELISTED 2048 // Must be whitelisted to play +#define IS_SYNTHETIC 4096 // Is a machine race +#define HAS_EYE_COLOR 8192 // Eye colour selectable in chargen (RGB) +#define CAN_JOIN 16384 // Species is selectable in chargen +#define IS_RESTRICTED 32768 // Is not a core/normally playable species (castes, mutantraces) //Language flags. #define WHITELISTED 1 // Language is available if the speaker is whitelisted.