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)

This commit is contained in:
Zuhayr
2014-12-23 17:37:33 +10:30
parent 2483f6fecc
commit bbfc6db0a3
60 changed files with 1213 additions and 1443 deletions

View File

@@ -1037,15 +1037,22 @@
#include "code\modules\mob\living\carbon\human\login.dm" #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\logout.dm"
#include "code\modules\mob\living\carbon\human\say.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\unarmed_attack.dm"
#include "code\modules\mob\living\carbon\human\update_icons.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\whisper.dm"
#include "code\modules\mob\living\carbon\human\alien\alien.dm" #include "code\modules\mob\living\carbon\human\species\species.dm"
#include "code\modules\mob\living\carbon\human\alien\alien_embryo.dm" #include "code\modules\mob\living\carbon\human\species\species_attack.dm"
#include "code\modules\mob\living\carbon\human\alien\alien_facehugger.dm" #include "code\modules\mob\living\carbon\human\species\species_hud.dm"
#include "code\modules\mob\living\carbon\human\alien\alien_powers.dm" #include "code\modules\mob\living\carbon\human\species\outsider\shadow.dm"
#include "code\modules\mob\living\carbon\human\alien\alien_species.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\death.dm"
#include "code\modules\mob\living\carbon\metroid\emote.dm" #include "code\modules\mob\living\carbon\metroid\emote.dm"
#include "code\modules\mob\living\carbon\metroid\examine.dm" #include "code\modules\mob\living\carbon\metroid\examine.dm"

View File

@@ -189,17 +189,10 @@
target.unique_enzymes = md5(target.real_name) target.unique_enzymes = md5(target.real_name)
updateappearance(scanner.occupant,target.uni_identity) updateappearance(scanner.occupant,target.uni_identity)
domutcheck(scanner.occupant, scanner, 1) domutcheck(scanner.occupant, scanner, 1)
if(ishuman(scanner.occupant))
target.mutantrace = buffer.mutantrace
scanner.occupant:update_mutantrace()
if("se") if("se")
if(buffer.struc_enzymes) if(buffer.struc_enzymes)
target.struc_enzymes = buffer.struc_enzymes target.struc_enzymes = buffer.struc_enzymes
domutcheck(scanner.occupant, scanner, 1) domutcheck(scanner.occupant, scanner, 1)
if(ishuman(scanner.occupant))
target.mutantrace = buffer.mutantrace
scanner.occupant:update_mutantrace()
if("ui") if("ui")
if(buffer.uni_identity) if(buffer.uni_identity)
target.uni_identity = buffer.uni_identity target.uni_identity = buffer.uni_identity

View File

@@ -140,7 +140,6 @@
/datum/file/data/genome/SE /datum/file/data/genome/SE
name = "Structural Enzymes" name = "Structural Enzymes"
var/mutantrace = null
/datum/file/data/genome/UE /datum/file/data/genome/UE
name = "Unique Enzymes" name = "Unique Enzymes"

View File

@@ -22,8 +22,9 @@ var/global/list/joblist = list() //list of all jobstypes, minus borg and AI
//Languages/species/whitelist. //Languages/species/whitelist.
var/global/list/all_species[0] var/global/list/all_species[0]
var/global/list/all_languages[0] var/global/list/all_languages[0]
var/global/list/language_keys[0] //table of say codes for all languages var/global/list/language_keys[0] // Table of say codes for all languages
var/global/list/whitelisted_species = list("Human") 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 // Posters
var/global/list/poster_designs = list() 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. S.race_key = rkey //Used in mob icon caching.
all_species[S.name] = S all_species[S.name] = S
if(!(S.flags & IS_RESTRICTED))
playable_species += S.name
if(S.flags & IS_WHITELISTED) if(S.flags & IS_WHITELISTED)
whitelisted_species += S.name whitelisted_species += S.name

View File

@@ -268,7 +268,6 @@ client
body += "<option value='?_src_=vars;remverb=\ref[D]'>Remove Verb</option>" body += "<option value='?_src_=vars;remverb=\ref[D]'>Remove Verb</option>"
if(ishuman(D)) if(ishuman(D))
body += "<option value>---</option>" body += "<option value>---</option>"
body += "<option value='?_src_=vars;setmutantrace=\ref[D]'>Set Mutantrace</option>"
body += "<option value='?_src_=vars;setspecies=\ref[D]'>Set Species</option>" body += "<option value='?_src_=vars;setspecies=\ref[D]'>Set Species</option>"
body += "<option value='?_src_=vars;makeai=\ref[D]'>Make AI</option>" body += "<option value='?_src_=vars;makeai=\ref[D]'>Make AI</option>"
body += "<option value='?_src_=vars;makerobot=\ref[D]'>Make cyborg</option>" body += "<option value='?_src_=vars;makerobot=\ref[D]'>Make cyborg</option>"
@@ -582,7 +581,7 @@ client
usr << "This can only be used on instances of type /mob/living/carbon/human" usr << "This can only be used on instances of type /mob/living/carbon/human"
return return
H.makeSkeleton() H.ChangeToSkeleton()
href_list["datumrefresh"] = href_list["make_skeleton"] href_list["datumrefresh"] = href_list["make_skeleton"]
else if(href_list["delall"]) else if(href_list["delall"])
@@ -744,27 +743,6 @@ client
return return
holder.Topic(href, list("makeai"=href_list["makeai"])) 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"]) else if(href_list["setspecies"])
if(!check_rights(R_SPAWN)) return if(!check_rights(R_SPAWN)) return

View File

@@ -80,7 +80,6 @@ var/global/list/datum/dna/gene/dna_genes[0]
// From old dna. // From old dna.
var/b_type = "A+" // Should probably change to an integer => string map but I'm lazy. 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, var/real_name // Stores the real name of the person who originally got this dna datum. Used primarily for changelings,
// New stuff // New stuff
@@ -92,7 +91,6 @@ var/global/list/datum/dna/gene/dna_genes[0]
var/datum/dna/new_dna = new() var/datum/dna/new_dna = new()
new_dna.unique_enzymes=unique_enzymes new_dna.unique_enzymes=unique_enzymes
new_dna.b_type=b_type new_dna.b_type=b_type
new_dna.mutantrace=mutantrace
new_dna.real_name=real_name new_dna.real_name=real_name
new_dna.species=species new_dna.species=species
for(var/b=1;b<=DNA_SE_LENGTH;b++) for(var/b=1;b<=DNA_SE_LENGTH;b++)

View File

@@ -102,7 +102,6 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind'
vox.name = vox.real_name vox.name = vox.real_name
newraider.name = vox.name newraider.name = vox.name
vox.age = rand(12,20) vox.age = rand(12,20)
vox.dna.mutantrace = "vox"
vox.set_species("Vox") vox.set_species("Vox")
vox.languages = list() // Removing language from chargen. vox.languages = list() // Removing language from chargen.
vox.flavor_text = "" vox.flavor_text = ""

View File

@@ -8,8 +8,11 @@
anchored = 1 anchored = 1
var/operating = 0 //Is it on? var/operating = 0 //Is it on?
var/dirty = 0 // Does it need cleaning? 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/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 use_power = 1
idle_power_usage = 2 idle_power_usage = 2
active_power_usage = 500 active_power_usage = 500
@@ -18,7 +21,7 @@
/obj/machinery/gibber/autogibber /obj/machinery/gibber/autogibber
var/turf/input_plate var/turf/input_plate
New() /obj/machinery/gibber/autogibber/New()
..() ..()
spawn(5) spawn(5)
for(var/i in cardinal) for(var/i in cardinal)
@@ -33,7 +36,7 @@
log_misc("a [src] didn't find an input plate.") log_misc("a [src] didn't find an input plate.")
return return
Bumped(var/atom/A) /obj/machinery/gibber/autogibber/Bumped(var/atom/A)
if(!input_plate) return if(!input_plate) return
if(ismob(A)) if(ismob(A))
@@ -70,43 +73,70 @@
if(stat & (NOPOWER|BROKEN)) if(stat & (NOPOWER|BROKEN))
return return
if(operating) if(operating)
user << "\red It's locked and running" user << "<span class='danger'>The gibber is locked and running, wait for it to finish.</span>"
return return
else else
src.startgibbing(user) src.startgibbing(user)
/obj/machinery/gibber/attackby(obj/item/weapon/grab/G as obj, mob/user as mob) /obj/machinery/gibber/attackby(var/obj/item/W, var/mob/user)
if(src.occupant)
user << "\red The gibber is full, empty it first!" if(istype(W,/obj/item/weapon/card/emag))
if(emagged)
user << "The gibber safety guard is already disabled."
return
user << "<span class='danger'>You disable the gibber safety guard.</span>"
emagged = 1
return return
if( !(istype(G, /obj/item/weapon/grab)) ) var/obj/item/weapon/grab/G = W
user << "\red This item is not suitable for the gibber!"
return
if( !(istype(G.affecting, /mob/living/carbon)) && !(istype(G.affecting, /mob/living/simple_animal)) ) if(!istype(G))
user << "\red This item is not suitable for the gibber!" return ..()
return
if(G.state < 2) if(G.state < 2)
user << "\red You need a better grip to do that!" user << "<span class='danger'>You need a better grip to do that!</span>"
return return
if(G.affecting.abiotic(1)) move_into_gibber(user,G.affecting)
user << "\red Subject may not have abiotic items on." // 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 << "<span class='danger'>The gibber is full, empty it first!</span>"
return return
user.visible_message("\red [user] starts to put [G.affecting] into the gibber!") if(operating)
user << "<span class='danger'>The gibber is locked and running, wait for it to finish.</span>"
return
if(!(istype(victim, /mob/living/carbon)) && !(istype(victim, /mob/living/simple_animal)) )
user << "<span class='danger'>This is not suitable for the gibber!</span>"
return
if(istype(victim,/mob/living/carbon/human) && !emagged)
user << "<span class='danger'>The gibber safety guard is engaged!</span>"
return
if(victim.abiotic(1))
user << "<span class='danger'>Subject may not have abiotic items on.</span>"
return
user.visible_message("\red [user] starts to put [victim] into the gibber!")
src.add_fingerprint(user) src.add_fingerprint(user)
if(do_after(user, 30) && G && G.affecting && !occupant) if(do_after(user, 30) && victim.Adjacent(src) && user.Adjacent(src) && victim.Adjacent(user) && !occupant)
user.visible_message("\red [user] stuffs [G.affecting] into the gibber!") user.visible_message("\red [user] stuffs [victim] into the gibber!")
var/mob/M = G.affecting if(victim.client)
if(M.client) victim.client.perspective = EYE_PERSPECTIVE
M.client.perspective = EYE_PERSPECTIVE victim.client.eye = src
M.client.eye = src victim.loc = src
M.loc = src src.occupant = victim
src.occupant = M
del(G)
update_icon() update_icon()
/obj/machinery/gibber/verb/eject() /obj/machinery/gibber/verb/eject()
@@ -121,7 +151,7 @@
return return
/obj/machinery/gibber/proc/go_out() /obj/machinery/gibber/proc/go_out()
if (!src.occupant) if(operating || !src.occupant)
return return
for(var/obj/O in src) for(var/obj/O in src)
O.loc = src.loc O.loc = src.loc
@@ -138,86 +168,62 @@
if(src.operating) if(src.operating)
return return
if(!src.occupant) if(!src.occupant)
visible_message("\red You hear a loud metallic grinding sound.") visible_message("<span class='danger'>You hear a loud metallic grinding sound.</span>")
return return
use_power(1000) use_power(1000)
visible_message("\red You hear a loud squelchy grinding sound.") visible_message("<span class='danger'>You hear a loud squelchy grinding sound.</span>")
src.operating = 1 src.operating = 1
update_icon() update_icon()
var/totalslabs = 3 var/slab_name = occupant.name
var/obj/item/weapon/reagent_containers/food/snacks/meat/allmeat[totalslabs] 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/) ) // Some mobs have specific meat item types.
var/sourcename = src.occupant.real_name if(istype(src.occupant,/mob/living/simple_animal))
var/sourcejob = src.occupant.job var/mob/living/simple_animal/critter = src.occupant
var/sourcenutriment = src.occupant.nutrition / 15 if(critter.meat_amount)
var/sourcetotalreagents = src.occupant.reagents.total_volume 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) // Small mobs don't give as much nutrition.
var/obj/item/weapon/reagent_containers/food/snacks/meat/human/newmeat = new if(src.occupant.small)
newmeat.name = sourcename + newmeat.name slab_nutrition *= 0.5
newmeat.subjectname = sourcename slab_nutrition /= slab_count
newmeat.subjectjob = sourcejob
newmeat.reagents.add_reagent("nutriment", sourcenutriment / totalslabs) // Thehehe. Fat guys go first for(var/i=1 to slab_count)
src.occupant.reagents.trans_to(newmeat, round (sourcetotalreagents / totalslabs, 1)) // Transfer all the reagents from the var/obj/item/weapon/reagent_containers/food/snacks/meat/new_meat = new slab_type(get_turf(src))
allmeat[i] = newmeat new_meat.name = "[slab_name] [new_meat.name]"
new_meat.reagents.add_reagent("nutriment",slab_nutrition)
if(src.occupant.reagents)
src.occupant.reagents.trans_to(new_meat, round(occupant.reagents.total_volume/slab_count,1))
src.occupant.attack_log += "\[[time_stamp()]\] Was gibbed by <b>[user]/[user.ckey]</b>" //One shall not simply gib a mob unnoticed! src.occupant.attack_log += "\[[time_stamp()]\] Was gibbed by <b>[user]/[user.ckey]</b>" //One shall not simply gib a mob unnoticed!
user.attack_log += "\[[time_stamp()]\] Gibbed <b>[src.occupant]/[src.occupant.ckey]</b>" user.attack_log += "\[[time_stamp()]\] Gibbed <b>[src.occupant]/[src.occupant.ckey]</b>"
msg_admin_attack("[user.name] ([user.ckey]) gibbed [src.occupant] ([src.occupant.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)") msg_admin_attack("[user.name] ([user.ckey]) gibbed [src.occupant] ([src.occupant.ckey]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
src.occupant.death(1)
src.occupant.ghostize() src.occupant.ghostize()
else if( istype(src.occupant, /mob/living/carbon/) || istype(src.occupant, /mob/living/simple_animal/ ) ) spawn(gib_time)
var/sourcename = src.occupant.name
var/sourcenutriment = src.occupant.nutrition / 15
var/sourcetotalreagents = 0
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
for(var/i=1 to totalslabs)
var/obj/item/weapon/reagent_containers/food/snacks/meat/newmeat = new
newmeat.name = "[sourcename]-[newmeat.name]"
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 <b>[user]/[user.ckey]</b>"
user.attack_log += "\[[time_stamp()]\] Gibbed <b>[src.occupant]/[src.occupant.ckey]</b>"
msg_admin_attack("\[[time_stamp()]\] <b>[key_name(user)]</b> gibbed <b>[key_name(src.occupant)]</b>")
src.occupant.death(1)
src.occupant.ghostize()
src.operating = 0
src.occupant.gib()
del(src.occupant) del(src.occupant)
spawn(src.gibtime)
playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) playsound(src.loc, 'sound/effects/splat.ogg', 50, 1)
operating = 0 operating = 0
for (var/i=1 to totalslabs) for (var/obj/item/thing in contents)
var/obj/item/meatslab = allmeat[i] thing.loc = get_turf(thing) // Drop it onto the turf for throwing.
var/turf/Tx = locate(src.x - i, src.y, src.z) 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.
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
update_icon() update_icon()

View File

@@ -378,7 +378,7 @@ Class Procs:
if(istype(perp.belt, /obj/item/weapon/gun) || istype(perp.belt, /obj/item/weapon/melee)) if(istype(perp.belt, /obj/item/weapon/gun) || istype(perp.belt, /obj/item/weapon/melee))
threatcount += 2 threatcount += 2
if(perp.dna && perp.dna.mutantrace && perp.dna.mutantrace != "none") if(perp.species.name != "Human") //beepsky so racist.
threatcount += 2 threatcount += 2
if(check_records || check_arrest) if(check_records || check_arrest)

View File

@@ -557,18 +557,9 @@ steam.start() -- spawns the effect
/obj/effect/effect/foam/Crossed(var/atom/movable/AM) /obj/effect/effect/foam/Crossed(var/atom/movable/AM)
if(metal) if(metal)
return return
if(istype(AM, /mob/living))
if (istype(AM, /mob/living/carbon)) var/mob/living/M = AM
var/mob/M = AM M.slip("the foam",6)
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)
/datum/effect/effect/system/foam_spread /datum/effect/effect/system/foam_spread
var/amount = 5 // the size of the foam spread. var/amount = 5 // the size of the foam spread.

View File

@@ -1,14 +1,7 @@
/proc/gibs(atom/location, var/list/viruses, var/datum/dna/MobDNA) //CARN MARKER /proc/gibs(atom/location, var/list/viruses, var/datum/dna/MobDNA, var/spawn_inside, gibber_type = /obj/effect/gibspawner/generic, var/fleshcolor, var/bloodcolor)
new /obj/effect/gibspawner/generic(get_turf(location),viruses,MobDNA) if(!spawn_inside)
location = get_turf(location)
/proc/hgibs(atom/location, var/list/viruses, var/datum/dna/MobDNA, var/fleshcolor, var/bloodcolor) new gibber_type(location,viruses,MobDNA,fleshcolor,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)
/obj/effect/gibspawner /obj/effect/gibspawner
var/sparks = 0 //whether sparks spread on Gib() var/sparks = 0 //whether sparks spread on Gib()
@@ -67,8 +60,6 @@
gib.blood_DNA = list() gib.blood_DNA = list()
if(MobDNA) if(MobDNA)
gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.b_type 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 else if(istype(src, /obj/effect/gibspawner/human)) // Probably a monkey
gib.blood_DNA["Non-human DNA"] = "A+" gib.blood_DNA["Non-human DNA"] = "A+"
var/list/directions = gibdirections[i] var/list/directions = gibdirections[i]

View File

@@ -16,15 +16,6 @@
gibamounts[6] = pick(0,1,2) 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 robot
sparks = 1 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) 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)

View File

@@ -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. /obj/item/device/pda/clown/Crossed(AM as mob|obj) //Clown PDA is slippery.
if (istype(AM, /mob/living/carbon)) if (istype(AM, /mob/living))
var/mob/M = AM var/mob/living/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(M, /mob/living/carbon/human) && (M.real_name != src.owner) && (istype(src.cartridge, /obj/item/weapon/cartridge/clown)))) if(M.slip("the PDA",8) && M.real_name != src.owner && istype(src.cartridge, /obj/item/weapon/cartridge/clown))
if(src.cartridge.charges < 5) if(src.cartridge.charges < 5)
src.cartridge.charges++ 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() /obj/item/device/pda/proc/available_pdas()
var/list/names = list() var/list/names = list()
var/list/plist = list() var/list/plist = list()

View File

@@ -102,6 +102,7 @@
/obj/machinery/door, /obj/machinery/door,
/obj/machinery/telecomms, /obj/machinery/telecomms,
/obj/machinery/mecha_part_fabricator, /obj/machinery/mecha_part_fabricator,
/obj/machinery/gibber,
/obj/vehicle /obj/vehicle
) )

View File

@@ -9,31 +9,16 @@
* Banana Peals * Banana Peals
*/ */
/obj/item/weapon/bananapeel/Crossed(AM as mob|obj) /obj/item/weapon/bananapeel/Crossed(AM as mob|obj)
if (istype(AM, /mob/living/carbon)) if (istype(AM, /mob/living))
var/mob/M = AM var/mob/living/M = AM
if (istype(M, /mob/living/carbon/human) && (isobj(M:shoes) && M:shoes.flags&NOSLIP) || M.buckled) M.slip("the [src.name]",4)
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)
/* /*
* Soap * 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 /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)) if (istype(AM, /mob/living))
var/mob/M = AM var/mob/living/M = AM
if (istype(M, /mob/living/carbon/human) && (isobj(M:shoes) && M:shoes.flags&NOSLIP) || M.buckled) M.slip("the [src.name]",3)
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)
/obj/item/weapon/soap/afterattack(atom/target, mob/user as mob, proximity) /obj/item/weapon/soap/afterattack(atom/target, mob/user as mob, proximity)
if(!proximity) return if(!proximity) return

View File

@@ -79,66 +79,29 @@
noslip = 1 noslip = 1
if (noslip) if (noslip)
return // no slipping while sitting in a chair, plz 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(src.wet)
if(!istype(M, /mob/living/carbon/slime) && !M.buckled) var/slip_dist = 1
M.stop_pulling() var/slip_stun = 6
step(M, M.dir) var/floor_type = "wet"
spawn(1) step(M, M.dir)
spawn(2) step(M, M.dir) switch(src.wet)
spawn(3) step(M, M.dir) if(2) // Lube
spawn(4) step(M, M.dir) floor_type = "slippery"
M.take_organ_damage(2) // Was 5 -- TLE slip_dist = 4
M << "\blue You slipped on the floor!" slip_stun = 10
playsound(src, 'sound/misc/slip.ogg', 50, 1, -3)
M.Weaken(10)
if(3) // Ice if(3) // Ice
if(istype(M, /mob/living/carbon/human)) // Added check since monkeys don't have shoes floor_type = "icy"
if ((M.m_intent == "run") && !(istype(M:shoes, /obj/item/clothing/shoes) && M:shoes.flags&NOSLIP) && prob(30)) slip_stun = 4
M.stop_pulling()
if(M.slip("the [floor_type] floor",slip_stun))
for(var/i = 0;i<slip_dist;i++)
step(M, M.dir) step(M, M.dir)
M << "\blue You slipped on the icy floor!" sleep(1)
playsound(src, 'sound/misc/slip.ogg', 50, 1, -3)
M.Stun(4)
M.Weaken(3)
else else
M.inertia_dir = 0 M.inertia_dir = 0
return
else if(!istype(M, /mob/living/carbon/slime))
if (M.m_intent == "run" && prob(30))
M.stop_pulling()
step(M, M.dir)
M << "\blue You slipped on the icy floor!"
playsound(src, 'sound/misc/slip.ogg', 50, 1, -3)
M.Stun(4)
M.Weaken(3)
else else
M.inertia_dir = 0 M.inertia_dir = 0
return
..() ..()

View File

@@ -275,7 +275,7 @@ var/list/forbidden_varedit_object_types = list(
/client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0) /client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0)
if(!check_rights(R_VAREDIT)) return if(!check_rights(R_VAREDIT)) return
var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "cuffed", "ka", "last_eaten", "icon", "icon_state", "mutantrace") var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "cuffed", "ka", "last_eaten", "icon", "icon_state")
for(var/p in forbidden_varedit_object_types) for(var/p in forbidden_varedit_object_types)
if( istype(O,p) ) if( istype(O,p) )

View File

@@ -511,7 +511,6 @@ client/proc/one_click_antag()
new_vox.age = rand(12,20) new_vox.age = rand(12,20)
new_vox.dna.ready_dna(new_vox) // Creates DNA. new_vox.dna.ready_dna(new_vox) // Creates DNA.
new_vox.dna.mutantrace = "vox"
new_vox.mind_initialize() new_vox.mind_initialize()
new_vox.mind.assigned_role = "MODE" new_vox.mind.assigned_role = "MODE"
new_vox.mind.special_role = "Vox Raider" new_vox.mind.special_role = "Vox Raider"

View File

@@ -23,14 +23,14 @@
var/corpseidjob = null // Needs to be in quotes, such as "Clown" or "Chef." This just determines what the ID reads as, not their access var/corpseidjob = null // Needs to be in quotes, such as "Clown" or "Chef." This just determines what the ID reads as, not their access
var/corpseidaccess = null //This is for access. See access.dm for which jobs give what access. Again, put in quotes. Use "Captain" if you want it to be all access. var/corpseidaccess = null //This is for access. See access.dm for which jobs give what access. Again, put in quotes. Use "Captain" if you want it to be all access.
var/corpseidicon = null //For setting it to be a gold, silver, centcomm etc ID var/corpseidicon = null //For setting it to be a gold, silver, centcomm etc ID
var/mutantrace = "human" var/species = "Human"
/obj/effect/landmark/corpse/initialize() /obj/effect/landmark/corpse/initialize()
createCorpse() createCorpse()
/obj/effect/landmark/corpse/proc/createCorpse() //Creates a mob and checks for gear in each slot before attempting to equip it. /obj/effect/landmark/corpse/proc/createCorpse() //Creates a mob and checks for gear in each slot before attempting to equip it.
var/mob/living/carbon/human/M = new /mob/living/carbon/human (src.loc) var/mob/living/carbon/human/M = new /mob/living/carbon/human (src.loc)
M.dna.mutantrace = mutantrace M.set_species(species)
M.real_name = src.name M.real_name = src.name
M.death(1) //Kills the new mob M.death(1) //Kills the new mob
if(src.corpseuniform) if(src.corpseuniform)

View File

@@ -604,6 +604,8 @@ datum/preferences
dat += "<img src='species_preview_[current_species.name].png' width='64px' height='64px'><br/><br/>" dat += "<img src='species_preview_[current_species.name].png' width='64px' height='64px'><br/><br/>"
dat += "<b>Language:</b> [current_species.language]<br/>" dat += "<b>Language:</b> [current_species.language]<br/>"
dat += "<small>" dat += "<small>"
if(current_species.flags & CAN_JOIN)
dat += "</br><b>Often present on human stations.</b>"
if(current_species.flags & IS_WHITELISTED) if(current_species.flags & IS_WHITELISTED)
dat += "</br><b>Whitelist restricted.</b>" dat += "</br><b>Whitelist restricted.</b>"
if(current_species.flags & NO_BLOOD) if(current_species.flags & NO_BLOOD)
@@ -632,12 +634,18 @@ datum/preferences
dat += "</tr>" dat += "</tr>"
dat += "</table><center><hr/>" dat += "</table><center><hr/>"
var/restricted var/restricted = 0
if(config.usealienwhitelist) //If we're using the whitelist, make sure to check it! if(config.usealienwhitelist) //If we're using the whitelist, make sure to check it!
if((current_species.flags & IS_WHITELISTED) && !is_alien_whitelisted(user,current_species)) if(!(current_species.flags & CAN_JOIN))
restricted = 2
else if((current_species.flags & IS_WHITELISTED) && !is_alien_whitelisted(user,current_species))
restricted = 1 restricted = 1
if(restricted)
if(restricted && !check_rights(R_ADMIN, 0))
if(restricted == 1)
dat += "<font color='red'><b>You cannot play as this species.</br><small>If you wish to be whitelisted, you can make an application post on <a href='http://baystation12.net/forums/viewtopic.php?f=46&t=5319'>the forums</a>.</small></b></font>" dat += "<font color='red'><b>You cannot play as this species.</br><small>If you wish to be whitelisted, you can make an application post on <a href='http://baystation12.net/forums/viewtopic.php?f=46&t=5319'>the forums</a>.</small></b></font>"
else if(restricted == 2)
dat += "<font color='red'><b>You cannot play as this species.</br><small>This species is not available for play as a station race..</small></b></font>"
else else
dat += "\[<a href='?src=\ref[user];preference=species;task=input;newspecies=[species_preview]'>select</a>\]" dat += "\[<a href='?src=\ref[user];preference=species;task=input;newspecies=[species_preview]'>select</a>\]"
dat += "</center></body>" dat += "</center></body>"
@@ -1138,7 +1146,7 @@ datum/preferences
if("change") if("change")
if(href_list["preference"] == "species") if(href_list["preference"] == "species")
// Actual whitelist checks are handled elsewhere, this is just for accessing the preview window. // Actual whitelist checks are handled elsewhere, this is just for accessing the preview window.
var/choice = input("Which species would you like to look at?") as null|anything in whitelisted_species var/choice = input("Which species would you like to look at?") as null|anything in playable_species
if(!choice) return if(!choice) return
species_preview = choice species_preview = choice
SetSpecies(user) SetSpecies(user)

View File

@@ -189,7 +189,7 @@
metadata = sanitize_text(metadata, initial(metadata)) metadata = sanitize_text(metadata, initial(metadata))
real_name = reject_bad_name(real_name) real_name = reject_bad_name(real_name)
if(isnull(species) || !(species in whitelisted_species)) if(isnull(species) || !(species in playable_species))
species = "Human" species = "Human"
if(isnull(language)) language = "None" if(isnull(language)) language = "None"

View File

@@ -80,28 +80,6 @@ I said no!
) )
result = /obj/item/weapon/reagent_containers/food/snacks/donut/normal result = /obj/item/weapon/reagent_containers/food/snacks/donut/normal
/* what is this
/datum/recipe/human
//invalid recipe
make_food(var/obj/container as obj)
var/human_name
var/human_job
for (var/obj/item/weapon/reagent_containers/food/snacks/meat/human/HM in container)
if (!HM.subjectname)
continue
human_name = HM.subjectname
human_job = HM.subjectjob
break
var/lastname_index = findtext(human_name, " ")
if (lastname_index)
human_name = copytext(human_name,lastname_index+1)
var/obj/item/weapon/reagent_containers/food/snacks/human/HB = ..(container)
HB.name = human_name+HB.name
HB.job = human_job
return HB
*/
/datum/recipe/human/burger /datum/recipe/human/burger
items = list( items = list(
/obj/item/weapon/reagent_containers/food/snacks/meat/human, /obj/item/weapon/reagent_containers/food/snacks/meat/human,
@@ -109,15 +87,6 @@ I said no!
) )
result = /obj/item/weapon/reagent_containers/food/snacks/human/burger result = /obj/item/weapon/reagent_containers/food/snacks/human/burger
/* Duplicated by plainburger
/datum/recipe/monkeyburger
items = list(
/obj/item/weapon/reagent_containers/food/snacks/bun,
/obj/item/weapon/reagent_containers/food/snacks/meat/monkey
)
result = /obj/item/weapon/reagent_containers/food/snacks/monkeyburger
*/
/datum/recipe/plainburger /datum/recipe/plainburger
items = list( items = list(
/obj/item/weapon/reagent_containers/food/snacks/bun, /obj/item/weapon/reagent_containers/food/snacks/bun,

View File

@@ -2,7 +2,7 @@
/obj/item/device/mmi/digital/New() /obj/item/device/mmi/digital/New()
src.brainmob = new(src) src.brainmob = new(src)
src.brainmob.add_language("Binary") src.brainmob.add_language("Robot Talk")
src.brainmob.loc = src src.brainmob.loc = src
src.brainmob.container = src src.brainmob.container = src
src.brainmob.stat = 0 src.brainmob.stat = 0

View File

@@ -511,3 +511,13 @@
/mob/living/carbon/can_use_vents() /mob/living/carbon/can_use_vents()
return return
/mob/living/carbon/slip(var/slipped_on,stun_duration=8)
if(buckled)
return 0
stop_pulling()
src << "<span class='warning'>You slipped on [slipped_on]!</span>"
playsound(src.loc, 'sound/misc/slip.ogg', 50, 1, -3)
Stun(stun_duration)
Weaken(Floor(stun_duration/2))
return 1

View File

@@ -8,12 +8,8 @@
// Override the current limb status and don't cause an explosion // Override the current limb status and don't cause an explosion
E.droplimb(1,1) E.droplimb(1,1)
..(species ? species.gibbed_anim : "gibbed-h") ..(species.gibbed_anim)
gibs(loc, viruses, dna, null, null, species.flesh_color, species.blood_color)
if(species)
hgibs(loc, viruses, dna, species.flesh_color, species.blood_color)
else
hgibs(loc, viruses, dna)
/mob/living/carbon/human/dust() /mob/living/carbon/human/dust()
if(species) if(species)
@@ -65,21 +61,6 @@
return ..(gibbed,species.death_message) 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() /mob/living/carbon/human/proc/ChangeToHusk()
if(HUSK in mutations) return if(HUSK in mutations) return
@@ -92,10 +73,23 @@
mutations.Add(HUSK) mutations.Add(HUSK)
status_flags |= DISFIGURED //makes them unknown without fucking up other stuff like admintools status_flags |= DISFIGURED //makes them unknown without fucking up other stuff like admintools
update_body(0) update_body(0)
update_mutantrace()
return return
/mob/living/carbon/human/proc/Drain() /mob/living/carbon/human/proc/Drain()
ChangeToHusk() ChangeToHusk()
//mutations |= NOCLONE //mutations |= NOCLONE
return 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

View File

@@ -730,13 +730,8 @@
return return
/mob/living/carbon/human/get_species() /mob/living/carbon/human/get_species()
if(!species) if(!species)
set_species() set_species()
if(dna && dna.mutantrace == "golem")
return "Animated Construct"
return species.name return species.name
/mob/living/carbon/human/proc/play_xylophone() /mob/living/carbon/human/proc/play_xylophone()
@@ -1286,3 +1281,8 @@
if(eyes && istype(eyes) && !eyes.status & ORGAN_CUT_AWAY) if(eyes && istype(eyes) && !eyes.status & ORGAN_CUT_AWAY)
return 1 return 1
return 0 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)

View File

@@ -230,7 +230,7 @@
return W.afterattack(target,src) return W.afterattack(target,src)
var/randn = rand(1, 100) var/randn = rand(1, 100)
if (randn <= 25) if(!(species.flags & NO_SLIP) && randn <= 25)
apply_effect(3, WEAKEN, run_armor_check(affecting, "melee")) apply_effect(3, WEAKEN, run_armor_check(affecting, "melee"))
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message("\red <B>[M] has pushed [src]!</B>") visible_message("\red <B>[M] has pushed [src]!</B>")

View File

@@ -929,64 +929,6 @@
return min(1,thermal_protection) 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() proc/handle_chemicals_in_body()
if(reagents && !(species.flags & IS_SYNTHETIC)) //Synths don't process reagents. if(reagents && !(species.flags & IS_SYNTHETIC)) //Synths don't process reagents.
@@ -1024,7 +966,7 @@
adjustOxyLoss(-(light_amount)) adjustOxyLoss(-(light_amount))
//TODO: heal wounds, heal broken limbs. //TODO: heal wounds, heal broken limbs.
if(dna && dna.mutantrace == "shadow") if(species.light_dam)
var/light_amount = 0 var/light_amount = 0
if(isturf(loc)) if(isturf(loc))
var/turf/T = loc var/turf/T = loc
@@ -1032,30 +974,11 @@
if(A) if(A)
if(A.lighting_use_dynamic) light_amount = T.lighting_lumcount if(A.lighting_use_dynamic) light_amount = T.lighting_lumcount
else light_amount = 10 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) take_overall_damage(1,1)
else if (light_amount < 2) //heal in the dark else //heal in the dark
heal_overall_damage(1,1) 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 // nutrition decrease
if (nutrition > 0 && stat != 2) if (nutrition > 0 && stat != 2)
nutrition = max (0, nutrition - HUNGER_FACTOR) nutrition = max (0, nutrition - HUNGER_FACTOR)
@@ -1335,14 +1258,6 @@
sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS) sight &= ~(SEE_TURFS|SEE_MOBS|SEE_OBJS)
see_in_dark = species.darksight see_in_dark = species.darksight
see_invisible = see_in_dark>2 ? SEE_INVISIBLE_LEVEL_ONE : SEE_INVISIBLE_LIVING 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) if(XRAY in mutations)
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS

View File

@@ -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("<span class='notice'>[H] hugs [target] to make [t_him] feel better!</span>", \
"<span class='notice'>You hug [target] to make [t_him] feel better!</span>")
/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.<br/><br/> \
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'.<br/><br/>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'.<br/><br/>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.<br/><br/>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.<br/><br/>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

View File

@@ -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

View File

@@ -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.<br/><br/>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
)

View File

@@ -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("<span class='notice'>[H] hugs [target] to make [t_him] feel better!</span>", \
"<span class='notice'>You hug [target] to make [t_him] feel better!</span>")
/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

View File

@@ -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("<span class='danger'>[target] looks dazed.</span>", "<span class='danger'>You see stars.</span>")
target.apply_effect(attack_damage*2, EYE_BLUR, armour)
if("l_arm", "l_hand")
if (target.l_hand)
// Disarm left hand
target.visible_message("<span class='danger'>[src] [pick("dropped", "let go off")] \the [target.l_hand][pick("", " with a scream")]!</span>")
target.drop_l_hand()
if("r_arm", "r_hand")
if (target.r_hand)
// Disarm right hand
target.visible_message("<span class='danger'>[src] [pick("dropped", "let go off")] \the [target.r_hand][pick("", " with a scream")]!</span>")
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("<span class='danger'>[pick("[target] was sent flying backward!", "[target] staggers back from the impact!")]</span>")
else
target.visible_message("<span class='danger'>[target] slams into [T]!</span>")
if(prob(50))
target.set_dir(reverse_dir[target.dir])
target.apply_effect(attack_damage * 0.4, WEAKEN, armour)
if("groin")
target.visible_message("<span class='warning'>[target] looks like \he is in pain!</span>", "<span class='warning'>[(target.gender=="female") ? "Oh god that hurt!" : "Oh no, not your[pick("testicles", "crown jewels", "clockweights", "family jewels", "marbles", "bean bags", "teabags", "sweetmeats", "goolies")]!"]</span>")
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("<span class='warning'>[src] gives way slightly.</span>")
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("<span class='danger'>[target] [pick("slumps", "falls", "drops")] down to the ground!</span>")
else
target.visible_message("<span class='danger'>[target] has been weakened!</span>")
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("<span class='warning'>[user] [pick(attack_verb)] [target] in the [affecting.display_name]!</span>")
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("<span class='danger'>[user] [pick(attack_verb)] \himself in the [organ]!</span>")
return 0
if(!target.lying)
switch(zone)
if("head", "mouth", "eyes")
// ----- HEAD ----- //
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] slapped [target] across \his cheek!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] struck [target] in the head[pick("", " with a closed fist")]!</span>")
if(5) user.visible_message("<span class='danger'>[user] gave [target] a resounding slap to the face!</span>")
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("<span class='danger'>[user] slapped [target]'s [organ]!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target] in \his [organ]!</span>")
if(5) user.visible_message("<span class='danger'>[user] slammed \his [pick(attack_noun)] into [target]'s [organ]!</span>")
else
user.visible_message("<span class='danger'>[user] [pick("punched", "threw a punch", "struck", "slapped", "rammed their [pick(attack_noun)] into")] [target]'s [organ]!</span>")
/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("<span class='danger'>[user] gave [target] a light [pick(attack_noun)] to the [organ]!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target] in \his [organ]!</span>")
if(5) user.visible_message("<span class='danger'>[user] landed a strong [pick(attack_noun)] against [target]'s [organ]!</span>")
if("l_foot", "r_foot")
// ----- FEET ----- //
switch(attack_damage)
if(1 to 4) user.visible_message("<span class='danger'>[user] kicked [target] in \his [organ]!</span>")
if(5) user.visible_message("<span class='danger'>[user] stomped down hard on [target]'s [organ]!</span>")
/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("<span class='danger'>[user] [pick("gave a kick against", "kicked against", "stomped down on", "slammed their foot into")] [target]'s [organ]!</span>")
if(4 to 5)
user.visible_message("<span class='danger'>[user] [pick("landed a strong kick against", "kicked against", "stomped down hard on", "rammed their foot into")] [target]'s [organ]!</span>")
/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("<span class='danger'>[user] [pick(attack_verb)] \himself in the [affecting.display_name]!</span>")
return 0
switch(zone)
if("head", "mouth", "eyes")
// ----- HEAD ----- //
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] scratched [target] across \his cheek!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target]'s [pick("head", "neck")] [pick("", "", "", "with spread [pick(attack_noun)]")]!</span>")
if(5) user.visible_message("<span class='danger'>[pick("[user] [pick(attack_verb)] [target] across \his face!", "[user] rakes \his [pick(attack_noun)] across [target]'s face!")]</span>")
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("<span class='danger'>[user] scratched [target]'s [affecting.display_name]!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [pick("", "", "the side of")] [target]'s [affecting.display_name]!</span>")
if(5) user.visible_message("<span class='danger'>[user] tears \his [pick(attack_noun)] deep into [target]'s [affecting.display_name]!</span>")
/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

View File

@@ -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

View File

@@ -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
..()

View File

@@ -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

View File

@@ -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.<br/><br/> \
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'.<br/><br/>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'.<br/><br/>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.<br/><br/>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,
)

View File

@@ -25,7 +25,7 @@
cold_level_2 = -1 cold_level_2 = -1
cold_level_3 = -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 reagent_tag = IS_XENOS

View File

@@ -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("<span class='danger'>[target] looks dazed.</span>", "<span class='danger'>You see stars.</span>")
target.apply_effect(attack_damage*2, EYE_BLUR, armour)
if("l_arm", "l_hand")
if (target.l_hand)
// Disarm left hand
target.visible_message("<span class='danger'>[src] [pick("dropped", "let go off")] \the [target.l_hand][pick("", " with a scream")]!</span>")
target.drop_l_hand()
if("r_arm", "r_hand")
if (target.r_hand)
// Disarm right hand
target.visible_message("<span class='danger'>[src] [pick("dropped", "let go off")] \the [target.r_hand][pick("", " with a scream")]!</span>")
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("<span class='danger'>[pick("[target] was sent flying backward!", "[target] staggers back from the impact!")]</span>")
else
target.visible_message("<span class='danger'>[target] slams into [T]!</span>")
if(prob(50))
target.set_dir(reverse_dir[target.dir])
target.apply_effect(attack_damage * 0.4, WEAKEN, armour)
if("groin")
target.visible_message("<span class='warning'>[target] looks like \he is in pain!</span>", "<span class='warning'>[(target.gender=="female") ? "Oh god that hurt!" : "Oh no, not your[pick("testicles", "crown jewels", "clockweights", "family jewels", "marbles", "bean bags", "teabags", "sweetmeats", "goolies")]!"]</span>")
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("<span class='warning'>[src] gives way slightly.</span>")
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("<span class='danger'>[target] [pick("slumps", "falls", "drops")] down to the ground!</span>")
else
target.visible_message("<span class='danger'>[target] has been weakened!</span>")
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("<span class='warning'>[user] [pick(attack_verb)] [target] in the [affecting.display_name]!</span>")
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("<span class='danger'>[user] [pick(attack_verb)] \himself in the [organ]!</span>")
return 0
if(!target.lying)
switch(zone)
if("head", "mouth", "eyes")
// ----- HEAD ----- //
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] slapped [target] across \his cheek!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] struck [target] in the head[pick("", " with a closed fist")]!</span>")
if(5) user.visible_message("<span class='danger'>[user] gave [target] a resounding slap to the face!</span>")
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("<span class='danger'>[user] slapped [target]'s [organ]!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target] in \his [organ]!</span>")
if(5) user.visible_message("<span class='danger'>[user] slammed \his [pick(attack_noun)] into [target]'s [organ]!</span>")
else
user.visible_message("<span class='danger'>[user] [pick("punched", "threw a punch", "struck", "slapped", "rammed their [pick(attack_noun)] into")] [target]'s [organ]!</span>")
/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("<span class='danger'>[user] gave [target] a light [pick(attack_noun)] to the [organ]!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target] in \his [organ]!</span>")
if(5) user.visible_message("<span class='danger'>[user] landed a strong [pick(attack_noun)] against [target]'s [organ]!</span>")
if("l_foot", "r_foot")
// ----- FEET ----- //
switch(attack_damage)
if(1 to 4) user.visible_message("<span class='danger'>[user] kicked [target] in \his [organ]!</span>")
if(5) user.visible_message("<span class='danger'>[user] stomped down hard on [target]'s [organ]!</span>")
/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("<span class='danger'>[user] [pick("gave a kick against", "kicked against", "stomped down on", "slammed their foot into")] [target]'s [organ]!</span>")
if(4 to 5)
user.visible_message("<span class='danger'>[user] [pick("landed a strong kick against", "kicked against", "stomped down hard on", "rammed their foot into")] [target]'s [organ]!</span>")
/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("<span class='danger'>[user] [pick(attack_verb)] \himself in the [affecting.display_name]!</span>")
return 0
switch(zone)
if("head", "mouth", "eyes")
// ----- HEAD ----- //
switch(attack_damage)
if(1 to 2) user.visible_message("<span class='danger'>[user] scratched [target] across \his cheek!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [target]'s [pick("head", "neck")] [pick("", "", "", "with spread [pick(attack_noun)]")]!</span>")
if(5) user.visible_message("<span class='danger'>[pick("[user] [pick(attack_verb)] [target] across \his face!", "[user] rakes \his [pick(attack_noun)] across [target]'s face!")]</span>")
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("<span class='danger'>[user] scratched [target]'s [affecting.display_name]!</span>")
if(3 to 4) user.visible_message("<span class='danger'>[user] [pick(attack_verb)] [pick("", "", "the side of")] [target]'s [affecting.display_name]!</span>")
if(5) user.visible_message("<span class='danger'>[user] tears \his [pick(attack_noun)] deep into [target]'s [affecting.display_name]!</span>")
/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

View File

@@ -68,7 +68,6 @@ There are several things that need to be remembered:
> There are also these special cases: > There are also these special cases:
update_mutations() //handles updating your appearance for certain mutations. e.g TK head-glows 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) 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_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 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///////// //Human Overlays Indexes/////////
#define MUTANTRACE_LAYER 1 #define MUTATIONS_LAYER 1
#define MUTATIONS_LAYER 2 #define DAMAGE_LAYER 2
#define DAMAGE_LAYER 3 #define UNIFORM_LAYER 3
#define UNIFORM_LAYER 4 #define TAIL_LAYER 4 //bs12 specific. this hack is probably gonna come back to haunt me
#define TAIL_LAYER 5 //bs12 specific. this hack is probably gonna come back to haunt me #define ID_LAYER 5
#define ID_LAYER 6 #define SHOES_LAYER 6
#define SHOES_LAYER 7 #define GLOVES_LAYER 7
#define GLOVES_LAYER 8 #define SUIT_LAYER 8
#define SUIT_LAYER 9 #define GLASSES_LAYER 9
#define GLASSES_LAYER 10 #define BELT_LAYER 10 //Possible make this an overlay of somethign required to wear a belt?
#define BELT_LAYER 11 //Possible make this an overlay of somethign required to wear a belt? #define SUIT_STORE_LAYER 11
#define SUIT_STORE_LAYER 12 #define BACK_LAYER 12
#define BACK_LAYER 13 #define HAIR_LAYER 13 //TODO: make part of head layer?
#define HAIR_LAYER 14 //TODO: make part of head layer? #define EARS_LAYER 14
#define EARS_LAYER 15 #define FACEMASK_LAYER 15
#define FACEMASK_LAYER 16 #define HEAD_LAYER 16
#define HEAD_LAYER 17 #define COLLAR_LAYER 17
#define COLLAR_LAYER 18 #define HANDCUFF_LAYER 18
#define HANDCUFF_LAYER 19 #define LEGCUFF_LAYER 19
#define LEGCUFF_LAYER 20 #define L_HAND_LAYER 20
#define L_HAND_LAYER 21 #define R_HAND_LAYER 21
#define R_HAND_LAYER 22 #define TARGETED_LAYER 22 //BS12: Layer for the target overlay from weapon targeting system
#define TARGETED_LAYER 23 //BS12: Layer for the target overlay from weapon targeting system #define TOTAL_LAYERS 22
#define TOTAL_LAYERS 23
////////////////////////////////// //////////////////////////////////
/mob/living/carbon/human /mob/living/carbon/human
@@ -271,8 +269,6 @@ proc/get_damage_icon_part(damage_state, body_part)
else else
//BEGIN CACHED ICON GENERATION. //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/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) 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 overlays_standing[MUTATIONS_LAYER] = null
if(update_icons) update_icons() 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 //Call when target overlay should be added/removed
/mob/living/carbon/human/update_targeted(var/update_icons=1) /mob/living/carbon/human/update_targeted(var/update_icons=1)
if (targeted_by && target_locked) if (targeted_by && target_locked)
@@ -515,7 +491,6 @@ proc/get_damage_icon_part(damage_state, body_part)
..() ..()
if(monkeyizing) return if(monkeyizing) return
update_mutations(0) update_mutations(0)
update_mutantrace(0)
update_inv_w_uniform(0) update_inv_w_uniform(0)
update_inv_wear_id(0) update_inv_wear_id(0)
update_inv_gloves(0) update_inv_gloves(0)
@@ -972,7 +947,6 @@ proc/get_damage_icon_part(damage_state, body_part)
return face_lying_image return face_lying_image
//Human Overlays Indexes///////// //Human Overlays Indexes/////////
#undef MUTANTRACE_LAYER
#undef MUTATIONS_LAYER #undef MUTATIONS_LAYER
#undef DAMAGE_LAYER #undef DAMAGE_LAYER
#undef UNIFORM_LAYER #undef UNIFORM_LAYER

View File

@@ -342,8 +342,7 @@
if(istype(L, /mob/living/carbon/human) && dna) //Ignore slime(wo)men if(istype(L, /mob/living/carbon/human) && dna) //Ignore slime(wo)men
var/mob/living/carbon/human/H = L var/mob/living/carbon/human/H = L
if(H.dna) if(H.species.name == "Slime")
if(H.dna.mutantrace == "slime")
continue continue
if(!L.canmove) // Only one slime can latch on at a time. if(!L.canmove) // Only one slime can latch on at a time.
@@ -575,3 +574,6 @@
if (Leader) return 0 if (Leader) return 0
if (holding_still) return 0 if (holding_still) return 0
return 1 return 1
/mob/living/carbon/slime/slip() //Can't slip something without legs.
return 0

View File

@@ -797,16 +797,8 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
if(!ghost) if(!ghost)
user << "The rune fizzles uselessly. There is no spirit nearby." user << "The rune fizzles uselessly. There is no spirit nearby."
return return
var/mob/living/carbon/human/G = new /mob/living/carbon/human var/mob/living/carbon/human/G = new(src.loc)
G.dna.mutantrace = "adamantine" G.set_species("Golem")
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
G.key = ghost.key 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." 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) del (src)

View File

@@ -82,18 +82,6 @@
update_icons() update_icons()
return 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() /mob/living/carbon/monkey/movement_delay()
var/tally = 0 var/tally = 0
if(reagents) if(reagents)

View File

@@ -839,3 +839,6 @@
/mob/living/proc/has_eyes() /mob/living/proc/has_eyes()
return 1 return 1
/mob/living/proc/slip(var/slipped_on,stun_duration=8)
return 0

View File

@@ -1,6 +1,6 @@
/mob/living/silicon/gib() /mob/living/silicon/gib()
..("gibbed-r") ..("gibbed-r")
robogibs(loc, viruses) gibs(loc, viruses, null, null, /obj/effect/gibspawner/robot)
/mob/living/silicon/dust() /mob/living/silicon/dust()
..("dust-r", /obj/effect/decal/remains/robot) ..("dust-r", /obj/effect/decal/remains/robot)

View File

@@ -208,7 +208,7 @@
held_item.loc = src.loc held_item.loc = src.loc
held_item = null 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() src.Del()
return return

View File

@@ -197,12 +197,6 @@
else 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) /mob/living/simple_animal/emote(var/act, var/type, var/desc)
if(act) if(act)
..(act, type, desc) ..(act, type, desc)
@@ -255,43 +249,43 @@
return 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(istype(O, /obj/item/stack/medical))
if(stat != DEAD) if(stat != DEAD && health < maxHealth)
var/obj/item/stack/medical/MED = O var/obj/item/stack/medical/medical_pack = O
if(health < maxHealth) if(medical_pack.use(1))
if(MED.get_amount() >= 1) adjustBruteLoss(-medical_pack.heal_brute)
adjustBruteLoss(-MED.heal_brute) visible_message("<span class='warning'>\The [user] applies the [medical_pack] to \the [src].</span>")
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]")
else else
user << "\blue this [src] is dead, medical items won't bring it back to life." user << "<span class='warning'>\The [src] cannot benefit from medical items in its current state.</span>"
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))
del(src)
return return
gib()
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("<span class='danger'>[user] chops up \the [src]!</span>")
del(src)
else else
user.visible_message("<span class='danger'>[user] butchers \the [src] messily!</span>")
gib()
return
if(O.force) if(O.force)
var/damage = O.force var/damage = O.force
if (O.damtype == HALLOSS) if (O.damtype == HALLOSS)
damage = 0 damage = 0
adjustBruteLoss(damage) adjustBruteLoss(damage)
for(var/mob/M in viewers(src, null)) visible_message("<span class='danger'>\The [src] has been attacked with \the [O] by [user].</span>")
if ((M.client && !( M.blinded )))
M.show_message("\red \b [src] has been attacked with the [O] by [user]. ")
else else
usr << "\red This weapon is ineffective, it does no damage." user << "<span class='danger'>This weapon is ineffective; it does no damage.</span>"
for(var/mob/M in viewers(src, null)) visible_message("<span class='danger'>\The [user] gently taps [src] with the [O].</span>")
if ((M.client && !( M.blinded )))
M.show_message("\red [user] gently taps [src] with the [O]. ")
/mob/living/simple_animal/movement_delay() /mob/living/simple_animal/movement_delay()
var/tally = 0 //Incase I need to add stuff other than "speed" later var/tally = 0 //Incase I need to add stuff other than "speed" later

View File

@@ -145,7 +145,7 @@
usr << "\red The round is either not ready, or has already finished..." usr << "\red The round is either not ready, or has already finished..."
return 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) if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist)
src << alert("You are currently not whitelisted to play [client.prefs.species].") src << alert("You are currently not whitelisted to play [client.prefs.species].")
return 0 return 0
@@ -172,7 +172,7 @@
return 0 return 0
var/datum/species/S = all_species[client.prefs.species] var/datum/species/S = all_species[client.prefs.species]
if(!(S.flags & IS_WHITELISTED)) if(!(S.flags & CAN_JOIN))
src << alert("Your current species, [client.prefs.species], is not available for play on the station.") src << alert("Your current species, [client.prefs.species], is not available for play on the station.")
return 0 return 0

View File

@@ -92,11 +92,7 @@
if(istype(user, /mob/living)) if(istype(user, /mob/living))
var/mob/living/M = user var/mob/living/M = user
if (HULK in M.mutations) if (HULK in M.mutations)
M << "\red Your meaty finger is much too large for the trigger guard!" M << "\red Your fingers are 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!"
return return
add_fingerprint(user) add_fingerprint(user)

View File

@@ -80,7 +80,6 @@
on_hit(var/atom/target, var/blocked = 0) on_hit(var/atom/target, var/blocked = 0)
var/mob/living/M = target 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)) if(ishuman(target))
var/mob/living/carbon/human/H = M var/mob/living/carbon/human/H = M
if((H.species.flags & IS_PLANT) && (M.nutrition < 500)) if((H.species.flags & IS_PLANT) && (M.nutrition < 500))
@@ -120,7 +119,6 @@
on_hit(var/atom/target, var/blocked = 0) on_hit(var/atom/target, var/blocked = 0)
var/mob/M = target 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. if(ishuman(target)) //These rays make plantmen fat.
var/mob/living/carbon/human/H = M var/mob/living/carbon/human/H = M
if((H.species.flags & IS_PLANT) && (M.nutrition < 500)) if((H.species.flags & IS_PLANT) && (M.nutrition < 500))

View File

@@ -332,10 +332,9 @@ datum
if(!M) M = holder.my_atom if(!M) M = holder.my_atom
if(ishuman(M)) if(ishuman(M))
var/mob/living/carbon/human/human = M var/mob/living/carbon/human/human = M
if(human.dna.mutantrace == null) if(human.species.name != "Slime")
M << "\red Your flesh rapidly mutates!" M << "<span class='danger'>Your flesh rapidly mutates!</span>"
human.dna.mutantrace = "slime" human.set_species("Slime")
human.update_mutantrace()
..() ..()
return return

View File

@@ -428,16 +428,9 @@
return return
/obj/item/weapon/reagent_containers/food/snacks/grown/bluetomato/Crossed(AM as mob|obj) /obj/item/weapon/reagent_containers/food/snacks/grown/bluetomato/Crossed(AM as mob|obj)
if (istype(AM, /mob/living/carbon)) if (istype(AM, /mob/living))
var/mob/M = AM var/mob/living/M = AM
if (istype(M, /mob/living/carbon/human) && (isobj(M:shoes) && M:shoes.flags&NOSLIP) || M.buckled) M.slip("the [src]!")
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)
/obj/item/weapon/reagent_containers/food/snacks/grown/wheat /obj/item/weapon/reagent_containers/food/snacks/grown/wheat
name = "wheat" name = "wheat"

View File

@@ -23,12 +23,10 @@
name = "synthetic meat" name = "synthetic meat"
desc = "A synthetic slab of flesh." 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 /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 /obj/item/weapon/reagent_containers/food/snacks/meat/monkey
//same as plain meat //same as plain meat

View File

@@ -5,7 +5,7 @@
// type path referencing tools that can be used for this step, and how well are they suited for it // type path referencing tools that can be used for this step, and how well are they suited for it
var/list/allowed_tools = null 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/allowed_species = null
var/list/disallowed_species = null var/list/disallowed_species = null

View File

@@ -742,21 +742,22 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse
) )
//Species flags. //Species flags.
#define NO_BLOOD 1 #define NO_BLOOD 1 // Vessel var is not filled with blood, cannot bleed out.
#define NO_BREATHE 2 #define NO_BREATHE 2 // Cannot suffocate or take oxygen loss.
#define NO_SCAN 4 #define NO_SCAN 4 // Cannot be scanned in a DNA machine/genome-stolen.
#define NO_PAIN 8 #define NO_PAIN 8 // Cannot suffer halloss/recieves deceptive health indicator
#define NO_SLIP 16 #define NO_SLIP 16 // Cannot fall over
#define NO_POISON 32 #define NO_POISON 32 // Cannot not suffer toxloss
#define HAS_SKIN_TONE 64 // Skin tone selectable in chargen (0-255)
#define HAS_SKIN_TONE 64 #define HAS_SKIN_COLOR 128 // Skin colour selectable in chargen (RGB)
#define HAS_SKIN_COLOR 128 #define HAS_LIPS 256 // Lips are drawn onto the mob icon (lipstick)
#define HAS_LIPS 256 #define HAS_UNDERWEAR 512 // Underwear is drawn onto the mob icon
#define HAS_UNDERWEAR 512 #define IS_PLANT 1024 // Is a treeperson
#define IS_PLANT 1024 #define IS_WHITELISTED 2048 // Must be whitelisted to play
#define IS_WHITELISTED 2048 #define IS_SYNTHETIC 4096 // Is a machine race
#define IS_SYNTHETIC 4096 #define HAS_EYE_COLOR 8192 // Eye colour selectable in chargen (RGB)
#define HAS_EYE_COLOR 8192 #define CAN_JOIN 16384 // Species is selectable in chargen
#define IS_RESTRICTED 32768 // Is not a core/normally playable species (castes, mutantraces)
//Language flags. //Language flags.
#define WHITELISTED 1 // Language is available if the speaker is whitelisted. #define WHITELISTED 1 // Language is available if the speaker is whitelisted.