Files
2020-02-19 19:48:29 -08:00

1402 lines
40 KiB
Plaintext

#define OVERRIDE_ARM_L 1
#define OVERRIDE_ARM_R 2
#define OVERRIDE_LEG_R 4
#define OVERRIDE_LEG_L 8
// mutant races: cheap way to add new "types" of mobs
// without copy/pasting the human code a million times.
// Now a robust object-oriented version!!!!
/datum/mutantrace
var/name = null // used for identification in diseases, clothing, etc
var/override_eyes = 1
var/override_hair = 1
var/override_beard = 1
var/override_detail = 1
var/override_skintone = 1
var/override_attack = 1 // set to 1 to override the limb attack actions. Mutantraces may use the limb action within custom_attack(),
// but they must explicitly specify if they're overriding via this var
var/override_language = null // set to a language ID to replace the language of the human
var/understood_languages = list() // additional understood languages (in addition to override_language if set, or english if not)
var/allow_fat = 0 // whether fat icons/disabilities are used
var/uses_special_head = 0 // unused
var/human_compatible = 1 // if 1, allows human diseases and dna injectors to affect this mutantrace
var/uses_human_clothes = 1 // if 0, can only wear clothes listed in an item's compatible_species var
var/clothing_icon_override = null // set to an icon to have human.update_clothing() look through its icon_states for matching things
var/exclusive_language = 0 // if 1, only understood by others of this mutantrace
var/voice_message = null // overrides normal voice message if defined (and others don't understand us, ofc)
var/voice_name = "human"
var/jerk = 0 // Should robots arrest these by default?
var/icon = 'icons/effects/genetics.dmi'
var/icon_state = "epileptic"
var/icon_head = null
var/icon_beard = null
var/icon_override_static = 0 // does this look different enough from a default human to warrant a static icon of its own?
var/head_offset = 0 // affects pixel_y of clothes
var/hand_offset = 0
var/body_offset = 0
var/r_limb_arm_type_mutantrace = null // Should we get custom arms? Dispose() replaces them with normal human arms.
var/l_limb_arm_type_mutantrace = null
var/r_limb_leg_type_mutantrace = null
var/l_limb_leg_type_mutantrace = null
var/ignore_missing_limbs = 0 // Replace both arms regardless of mob status (new and dispose).
var/firevuln = 1 //Scales damage, just like critters.
var/brutevuln = 1
var/toxvuln = 1
var/aquatic = 0 //ignores suffocation from being underwater + moves at full speed underwater
var/needs_oxy = 1
var/voice_override = 0
var/mob/living/carbon/human/mob = null
var/anchor_to_floor = 0
var/image/detail_1
var/image/detail_2
var/image/detail_3
proc/say_filter(var/message)
return message
proc/say_verb()
return "says"
proc/emote(var/act)
return null
// custom attacks, should return attack_hand by default or bad things will happen!!
// ^--- Outdated, please use limb datums instead if possible.
proc/custom_attack(atom/target)
return target.attack_hand(mob)
// movement delay modifier
proc/movement_delay()
return 0
// vision modifier (see_mobs, etc i guess)
proc/sight_modifier()
return
proc/onLife(var/mult = 1) //Called every Life cycle of our mob
return
proc/onDeath() //Called when our mob dies. Returning a true value will short circuit the normal death proc right before deathgasp/headspider/etc
return
New(var/mob/living/carbon/human/M)
..()
if(ishuman(M))
src.mob = M
var/list/obj/item/clothing/restricted = list(mob.w_uniform, mob.shoes, mob.wear_suit)
for(var/obj/item/clothing/W in restricted)
if (istype(W,/obj/item/clothing))
if(W.compatible_species.Find(src.name) || (src.human_compatible && W.compatible_species.Find("human")))
continue
mob.u_equip(W)
boutput(mob, "<span style=\"color:red\"><B>You can no longer wear the [W.name] in your current state!</B></span>")
if (W)
W.set_loc(mob.loc)
W.dropped(mob)
W.layer = initial(W.layer)
M.image_eyes.pixel_y = src.head_offset
M.image_cust_one.pixel_y = src.head_offset
M.image_cust_two.pixel_y = src.head_offset
M.image_cust_three.pixel_y = src.head_offset
// Replacement for custom_attack() of several mutantraces, which used an entire copy of
// pre-stamina melee code. They do the same stuff with more flexible limb datums (Convair880).
if (src.r_limb_arm_type_mutantrace)
if (M.limbs.r_arm || src.ignore_missing_limbs == 1)
var/obj/item/parts/human_parts/arm/limb = new src.r_limb_arm_type_mutantrace(M)
if (istype(limb))
qdel(M.limbs.r_arm)
limb.quality = 0.5
M.limbs.r_arm = limb
limb.holder = M
limb.remove_stage = 0
if (src.l_limb_arm_type_mutantrace)
if (M.limbs.l_arm || src.ignore_missing_limbs == 1)
var/obj/item/parts/human_parts/arm/limb = new src.l_limb_arm_type_mutantrace(M)
if (istype(limb))
qdel(M.limbs.l_arm)
limb.quality = 0.5
M.limbs.l_arm = limb
limb.holder = M
limb.remove_stage = 0
//////////////LEGS//////////////////
if (src.r_limb_leg_type_mutantrace)
if (M.limbs.r_leg || src.ignore_missing_limbs == 1)
var/obj/item/parts/human_parts/leg/limb = new src.r_limb_leg_type_mutantrace(M)
if (istype(limb))
qdel(M.limbs.r_leg)
limb.quality = 0.5
M.limbs.r_leg = limb
limb.holder = M
limb.remove_stage = 0
if (src.l_limb_leg_type_mutantrace)
if (M.limbs.l_leg || src.ignore_missing_limbs == 1)
var/obj/item/parts/human_parts/leg/limb = new src.l_limb_leg_type_mutantrace(M)
if (istype(limb))
qdel(M.limbs.l_leg)
limb.quality = 0.5
M.limbs.l_leg = limb
limb.holder = M
limb.remove_stage = 0
M.update_face()
M.update_body()
if (M.bioHolder && M.bioHolder.mobAppearance)
M.bioHolder.mobAppearance.UpdateMob()
SPAWN_DBG (25) // Don't remove.
if (M && M.organHolder && M.organHolder.skull)
M.assign_gimmick_skull() // For hunters (Convair880).
else
src.dispose()
return
disposing()
if(mob)
mob.mutantrace = null
mob.set_face_icon_dirty()
mob.set_body_icon_dirty()
var/list/obj/item/clothing/restricted = list(mob.w_uniform, mob.shoes, mob.wear_suit)
for (var/obj/item/clothing/W in restricted)
if (istype(W,/obj/item/clothing))
if (W.compatible_species.Find("human"))
continue
mob.u_equip(W)
boutput(mob, "<span style=\"color:red\"><B>You can no longer wear the [W.name] in your current state!</B></span>")
if (W)
W.set_loc(mob.loc)
W.dropped(mob)
W.layer = initial(W.layer)
if (ishuman(mob))
var/mob/living/carbon/human/H = mob
H.image_eyes.pixel_y = initial(H.image_eyes.pixel_y)
H.image_cust_one.pixel_y = initial(H.image_cust_one.pixel_y)
H.image_cust_two.pixel_y = initial(H.image_cust_two.pixel_y)
H.image_cust_three.pixel_y = initial(H.image_cust_three.pixel_y)
// And the other way around (Convair880).
if (src.r_limb_arm_type_mutantrace)
if (H.limbs.r_arm || src.ignore_missing_limbs == 1)
var/obj/item/parts/human_parts/arm/limb = new /obj/item/parts/human_parts/arm/right(H)
if (istype(limb))
qdel(H.limbs.r_arm)
limb.quality = 0.5
H.limbs.r_arm = limb
limb.holder = H
limb.remove_stage = 0
if (src.l_limb_arm_type_mutantrace)
if (H.limbs.l_arm || src.ignore_missing_limbs == 1)
var/obj/item/parts/human_parts/arm/limb = new /obj/item/parts/human_parts/arm/left(H)
if (istype(limb))
qdel(H.limbs.l_arm)
limb.quality = 0.5
H.limbs.l_arm = limb
limb.holder = H
limb.remove_stage = 0
//////////////LEGS//////////////////
if (src.r_limb_leg_type_mutantrace)
if (H.limbs.r_leg || src.ignore_missing_limbs == 1)
var/obj/item/parts/human_parts/leg/limb = new /obj/item/parts/human_parts/leg/right(H)
if (istype(limb))
qdel(H.limbs.r_leg)
limb.quality = 0.5
H.limbs.r_leg = limb
limb.holder = H
limb.remove_stage = 0
if (src.l_limb_leg_type_mutantrace)
if (H.limbs.l_leg || src.ignore_missing_limbs == 1)
var/obj/item/parts/human_parts/leg/limb = new /obj/item/parts/human_parts/leg/left(H)
if (istype(limb))
qdel(H.limbs.l_leg)
limb.quality = 0.5
H.limbs.l_leg = limb
limb.holder = H
limb.remove_stage = 0
detail_1 = null
detail_2 = null
detail_3 = null
H.set_face_icon_dirty()
H.set_body_icon_dirty()
SPAWN_DBG (25) // Don't remove.
if (H && H.organHolder && H.organHolder.skull) // check for H.organHolder as well so we don't get null.skull runtimes
H.assign_gimmick_skull() // We might have to update the skull (Convair880).
mob.set_clothing_icon_dirty()
src.mob = null
..()
return
/datum/mutantrace/blob // podrick's july assjam submission, it's pretty cute
name = "blob"
icon = 'icons/mob/blob_ambassador.dmi'
icon_state = "blob"
human_compatible = 0
uses_human_clothes = 0
hand_offset = -1
body_offset = -8
voice_override = "bloop"
say_verb()
return pick("burbles", "gurgles", "blurbs", "gloops")
/datum/mutantrace/flubber
name = "flubber"
icon = 'icons/mob/flubber.dmi'
icon_state = "flubber"
uses_human_clothes = 0
head_offset = -7
override_hair = 1
override_beard = 1
override_detail = 1
voice_override = "bloop"
//override_static = 1
jerk = 0 //flubber is a good goo person
sight_modifier()
mob.see_in_dark = SEE_DARK_FULL
movement_delay()
playsound(get_turf(mob), "sound/misc/boing/[rand(1,6)].ogg", 20, 1 )
animate(mob, time = 1, pixel_y = 16, easing = ELASTIC_EASING)
animate(time = 1, pixel_y = 0, easing = ELASTIC_EASING)
return -2
say_filter(var/message)
return pick("Wooo!!", "Whopeee!!", "Boing!!", "Čapaš!!")
onLife(var/mult = 1)
if (!isdead(mob))
mob.reagents.add_reagent("flubber", 10) //change "flubber" to whatever flubber is in code obviously
if (mob.health < mob.max_health && mob.health>0) //you can kill flubber with extreme measures
mob.full_heal()
onDeath()
var/turf/T = get_turf(mob)
T.fluid_react_single("flubber", 500)
mob.gib()
say_verb()
return "flubbers"
/datum/mutantrace/flashy
name = "flashy"
override_eyes = 0
override_hair = 0
override_beard = 0
override_detail = 0
override_attack = 0
/datum/mutantrace/virtual
name = "virtual"
icon_state = "virtual"
override_attack = 0
override_hair = 0
override_beard = 0
override_detail = 0
New(var/mob/living/carbon/human/H)
..()
if(ishuman(mob))
mob.blood_color = pick("#FF0000","#FFFF00","#00FF00","#00FFFF","#0000FF","#FF00FF")
H.abilityHolder = new /datum/abilityHolder/virtual(H)
H.abilityHolder.owner = H
H.abilityHolder.addAbility(/datum/targetable/virtual/logout)
/datum/mutantrace/blank
name = "blank"
icon_state = "blank"
override_eyes = 0
override_hair = 0
override_beard = 0
override_detail = 0
override_attack = 0
/datum/mutantrace/grey
name = "grey"
icon_state = "grey"
voice_name = "grey"
voice_message = "hums"
override_eyes = 1
override_hair = 1
override_beard = 1
override_detail = 1
exclusive_language = 1
jerk = 1
var/original_blood_color = null
New(var/mob/living/carbon/human/M)
..()
if(ishuman(mob))
original_blood_color = mob.blood_color
mob.blood_color = "#000000"
disposing()
if(ishuman(mob))
if(!isnull(original_blood_color))
mob.blood_color = original_blood_color
original_blood_color = null
..()
sight_modifier()
mob.sight |= SEE_MOBS
mob.see_in_dark = SEE_DARK_FULL
mob.see_invisible = 3
emote(var/act)
var/message = null
if(act == "scream")
if(mob.emote_allowed)
mob.emote_allowed = 0
message = "<B>[mob]</B> screams with \his mind! Guh, that's creepy!"
playsound(get_turf(mob), "sound/voice/screams/Psychic_Scream_1.ogg", 80, 0, 0, max(0.7, min(1.2, 1.0 + (30 - mob.bioHolder.age)/60)))
SPAWN_DBG(3 SECONDS)
mob.emote_allowed = 1
return message
else
..()
/datum/mutantrace/lizard
name = "lizard"
// icon_state = "lizard"
icon_state = "lizard"
icon_override_static = 1
allow_fat = 1
override_attack = 0
voice_override = "lizard"
New(var/mob/living/carbon/human/H)
..()
if(ishuman(mob))
var/datum/appearanceHolder/aH = mob.bioHolder.mobAppearance
detail_1 = image('icons/effects/genetics.dmi', icon_state="lizard_detail-1", layer = MOB_LIMB_LAYER+0.1)
detail_2 = image('icons/effects/genetics.dmi', icon_state="lizard_detail-2", layer = MOB_LIMB_LAYER+0.2)
detail_3 = image('icons/effects/genetics.dmi', icon_state="lizard_detail-3", layer = MOB_LIMB_LAYER+0.3)
hex_to_rgb_list(aH.customization_first_color)
detail_1.color = fix_colors(aH.customization_first_color)
detail_2.color = fix_colors(aH.customization_second_color)
detail_3.color = fix_colors(aH.customization_third_color)
// detail_1.color = aH.customization_first_color
// detail_2.color = aH.customization_second_color
// detail_3.color = aH.customization_third_color
mob.update_face()
mob.update_body()
mob.update_clothing()
proc/fix_colors(var/hex)
var/list/L = hex_to_rgb_list(hex)
for (var/i in L)
L[i] = min(L[i], 190)
L[i] = max(L[i], 50)
if (L.len == 3)
return rgb(L["r"], L["g"], L["b"])
return rgb(22, 210, 22)
disposing()
..()
sight_modifier()
mob.see_in_dark = SEE_DARK_HUMAN + 1
mob.see_invisible = 1
say_filter(var/message)
return replacetext(message, "s", stutter("ss"))
/datum/mutantrace/zombie
name = "zombie"
icon_state = "zombie"
override_hair = 0
override_beard = 0
override_detail = 0
jerk = 1
New(var/mob/living/carbon/human/M)
..()
if(ishuman(mob))
src.add_ability(mob)
M.add_stam_mod_max("zombie", -100)
M.add_stam_mod_regen("zombie", 15)
disposing()
if (ishuman(mob))
mob.remove_stam_mod_max("zombie")
mob.remove_stam_mod_regen("zombie")
proc/add_ability(var/mob/living/carbon/human/H)
return
sight_modifier()
mob.sight |= SEE_MOBS
mob.see_in_dark = SEE_DARK_FULL
mob.see_invisible = 0
movement_delay()
return 4
say_filter(var/message)
return pick("Urgh...", "Brains...", "Hungry...", "Kill...")
emote(var/act)
var/message = null
if(act == "scream")
if(mob.emote_allowed)
mob.emote_allowed = 0
message = "<B>[mob]</B> moans!"
playsound(get_turf(mob), "sound/voice/Zgroan[pick("1","2","3","4")].ogg", 80, 0, 0, max(0.7, min(1.2, 1.0 + (30 - mob.bioHolder.age)/60)))
SPAWN_DBG(3 SECONDS)
mob.emote_allowed = 1
return message
else
..()
onDeath()
mob.show_message("<span style=\"color:blue\">You can feel your flesh re-assembling. You will rise once more. (This will take about one minute.)</span>")
SPAWN_DBG(45 SECONDS)
if (mob)
if (!mob.organHolder.brain || !mob.organHolder.skull || !mob.organHolder.head)
mob.show_message("<span style=\"color:blue\">You fail to rise, your brain has been destroyed.</span>")
else
// ha ha nope. Instead we copy paste a bunch of shit from full_heal but leave out select bits such as : limb regeneration, reagent clearing
//mob.full_heal()
mob.HealDamage("All", 100000, 100000)
mob.drowsyness = 0
mob.stuttering = 0
mob.losebreath = 0
mob.delStatus("paralysis")
mob.delStatus("stunned")
mob.delStatus("weakened")
mob.delStatus("slowed")
mob.delStatus("radiation")
mob.change_eye_blurry(-INFINITY)
mob.take_eye_damage(-INFINITY)
mob.take_eye_damage(-INFINITY, 1)
mob.take_ear_damage(-INFINITY)
mob.take_ear_damage(-INFINITY, 1)
mob.take_brain_damage(-120)
mob.health = mob.max_health
if (mob.stat > 1)
setalive(mob)
mob.remove_ailments()
mob.take_toxin_damage(-INFINITY)
mob.take_oxygen_deprivation(-INFINITY)
mob.change_misstep_chance(-INFINITY)
mob.blinded = 0
mob.bleeding = 0
mob.blood_volume = 500
if (!mob.organHolder)
mob.organHolder = new(src)
mob.organHolder.create_organs()
if (mob.get_stamina() != (STAMINA_MAX + mob.get_stam_mod_max()))
mob.set_stamina(STAMINA_MAX + mob.get_stam_mod_max())
mob.update_body()
mob.update_face()
mob.updatehealth()
mob.emote("scream")
mob.visible_message("<span style=\"color:red\"><B>[mob]</B> rises from the dead!</span>")
return 1
/datum/mutantrace/zombie/can_infect
add_ability(var/mob/living/carbon/human/H)
H.abilityHolder = new /datum/abilityHolder/critter(src) //lol
H.abilityHolder.owner = H
H.abilityHolder.addAbility(/datum/targetable/critter/zombify)
disposing()
if (ishuman(mob))
var/mob/living/carbon/human/H = mob
H.abilityHolder.removeAbility(/datum/targetable/critter/zombify)
/datum/mutantrace/vamp_zombie
name = "vampiric zombie"
icon_state = "vamp_zombie"
override_hair = 0
override_beard = 0
override_detail = 0
jerk = 1
var/blood_points = 0
var/const/blood_decay = 0.5
var/cleanable_tally = 0
var/const/blood_to_health_scalar = 0.5 //200 blood = 100 health
New(var/mob/living/carbon/human/M)
..()
if(ishuman(mob))
src.add_ability(mob)
M.add_stam_mod_max("vamp_zombie", 100)
//M.add_stam_mod_regen("vamp_zombie", 15)
disposing()
if (ishuman(mob))
mob.remove_stam_mod_max("vamp_zombie")
//mob.remove_stam_mod_regen("vamp_zombie")
proc/add_ability(var/mob/living/carbon/human/H)
H.make_vampiric_zombie()
onLife(var/mult = 1)
..()
if (mob.bleeding)
blood_points -= blood_decay * mob.bleeding
var/prev_blood = blood_points
blood_points -= blood_decay * mult
blood_points = max(0,blood_points)
cleanable_tally += (prev_blood - blood_points)
if (cleanable_tally > 20)
make_cleanable(/obj/decal/cleanable/blood,get_turf(mob))
cleanable_tally = 0
mob.max_health = blood_points * blood_to_health_scalar
mob.max_health = (max(20,mob.max_health))
movement_delay()
.= 1
if (blood_points <= 150)
.= 2
else if (blood_points <= 100)
.= 3
else if (blood_points <= 50)
.= 4
//say_filter(var/message)
//play sound
// ..()
//return pick("Urgh...", "Brains...", "Hungry...", "Kill...")
emote(var/act)
var/message = null
if(act == "scream")
if(mob.emote_allowed)
mob.emote_allowed = 0
message = "<B>[mob]</B> moans!"
playsound(get_turf(mob), "sound/voice/Zgroan[pick("1","2","3","4")].ogg", 80, 0, 0, max(0.7, min(1.2, 1.0 + (30 - mob.bioHolder.age)/60)))
SPAWN_DBG(3 SECONDS)
mob.emote_allowed = 1
return message
else
..()
onDeath()
var/datum/abilityHolder/vampiric_zombie/abil = mob.get_ability_holder(/datum/abilityHolder/vampiric_zombie)
if (abil)
if (abil.master)
abil.master.remove_thrall(mob)
else
remove_mindslave_status(mob)
..()
/datum/mutantrace/skeleton
name = "skeleton"
icon = 'icons/mob/human.dmi'
icon_state = "skeleton"
icon_override_static = 1
voice_override = "skelly"
New(var/mob/living/carbon/human/M)
..()
if(ishuman(M))
M.mob_flags |= IS_BONER
disposing()
if (ishuman(mob) && (mob.mob_flags & IS_BONER))
mob.mob_flags &= ~IS_BONER
/*
/datum/mutantrace/ape
name = "ape"
icon_state = "ape"
*/
/datum/mutantrace/nostalgic
name = "Homo nostalgius"
icon_state = "oldhuman"
icon_override_static = 1
override_skintone = 0
override_attack = 0
/datum/mutantrace/abomination
name = "abomination"
icon_state = "abomination"
icon_override_static = 1
human_compatible = 0
uses_human_clothes = 0
jerk = 1
brutevuln = 0.2
override_attack = 0
r_limb_arm_type_mutantrace = /obj/item/parts/human_parts/arm/right/abomination
l_limb_arm_type_mutantrace = /obj/item/parts/human_parts/arm/left/abomination
ignore_missing_limbs = 1 //OVERRIDE_ARM_L | OVERRIDE_ARM_R
anchor_to_floor = 1
var/last_drain = 0
var/drains_dna_on_life = 1
var/ruff_tuff_and_ultrabuff = 1
New(var/mob/living/carbon/human/M)
if(ruff_tuff_and_ultrabuff && M)
M.add_stam_mod_max("abomination", 1000)
M.add_stam_mod_regen("abomination", 1000)
M.add_stun_resist_mod("abomination", 1000)
last_drain = world.time
return ..(M)
disposing()
if(mob)
mob.remove_stam_mod_max("abomination")
mob.remove_stam_mod_regen("abomination")
mob.remove_stun_resist_mod("abomination")
return ..()
movement_delay()
return 1
onLife(var/mult = 1)
//Bringing it more in line with how it was before it got broken (in a hilarious fashion)
if (ruff_tuff_and_ultrabuff && !(mob.getStatusDuration("burning") && prob(90))) //Are you a macho abomination or not?
mob.delStatus("disorient")
mob.drowsyness = 0
mob.change_misstep_chance(-INFINITY)
mob.delStatus("slowed")
mob.stuttering = 0
changeling_super_heal_step(mob, mult = mult)
if (drains_dna_on_life) //Do you continuously lose DNA points when in this form?
var/datum/abilityHolder/changeling/C = mob.get_ability_holder(/datum/abilityHolder/changeling)
if (C && C.points)
if (last_drain + 30 <= world.time)
C.points = max(0, C.points - 1)
switch (C.points)
if (-INFINITY to 0)
mob.show_text("<I><B>We cannot hold this form!</B></I>", "red")
mob.revert_from_horror_form()
if (5)
mob.show_text("<I><B>Our DNA stockpile is almost depleted!</B></I>", "red")
if (10)
mob.show_text("<I><B>We cannot maintain this form much longer!</B></I>", "red")
return
say_filter(var/message)
return pick("We are one...", "Join with us...", "Sssssss...")
say_verb()
return "screeches"
emote(var/act)
var/message = null
switch (act)
if ("scream")
if (mob.emote_allowed)
mob.emote_allowed = 0
message = "<span style=\"color:red\"><B>[mob] screeches!</B></span>"
playsound(get_turf(mob), "sound/voice/creepyshriek.ogg", 60, 1)
SPAWN_DBG (30)
if (mob) mob.emote_allowed = 1
return message
/datum/mutantrace/abomination/admin //This will not revert to human form
drains_dna_on_life = 0
/datum/mutantrace/abomination/admin/weak //This also does not get any of the OnLife effects
ruff_tuff_and_ultrabuff = 0
/datum/mutantrace/werewolf
name = "werewolf"
icon_state = "werewolf"
icon_override_static = 1
human_compatible = 0
uses_human_clothes = 0
head_offset = -1
var/original_name
jerk = 1
override_attack = 0
r_limb_arm_type_mutantrace = /obj/item/parts/human_parts/arm/right/werewolf
l_limb_arm_type_mutantrace = /obj/item/parts/human_parts/arm/left/werewolf
ignore_missing_limbs = 0
New()
..()
if (mob)
mob.add_stam_mod_max("werewolf", 40) // Gave them a significant stamina boost, as they're melee-orientated (Convair880).
mob.add_stam_mod_regen("werewolf", 9) //mbc : these increase as they feast now. reduced!
mob.add_stun_resist_mod("werewolf", 40)
mob.max_health += 50
src.original_name = mob.real_name
mob.real_name = "werewolf"
var/duration = 3000
var/datum/ailment_data/disease/D = mob.find_ailment_by_type(/datum/ailment/disease/lycanthropy/)
if(D)
D.cycles++
duration = rand(2000, 4000) * D.cycles
SPAWN_DBG(duration)
if(src)
if (mob) mob.show_text("<b>You suddenly transform back into a human!</b>", "red")
qdel(src)
disposing()
if (mob)
mob.remove_stam_mod_max("werewolf")
mob.remove_stam_mod_regen("werewolf")
mob.remove_stun_resist_mod("werewolf")
mob.max_health -= 30
if (!isnull(src.original_name))
mob.real_name = src.original_name
return ..()
sight_modifier()
if (mob && ismob(mob))
mob.sight |= SEE_MOBS
mob.see_in_dark = SEE_DARK_FULL
mob.see_invisible = 2
return
// Werewolves (being a melee-focused role) are quite buff.
onLife(var/mult = 1)
if (mob && ismob(mob))
if (mob.drowsyness)
mob.drowsyness = max(0, mob.drowsyness - 2)
if (mob.misstep_chance)
mob.change_misstep_chance(-10 * mult)
if (mob.getStatusDuration("slowed"))
mob.changeStatus("slowed", -20 * mult)
return
say_verb()
return "snarls"
say_filter(var/message)
return message
emote(var/act)
var/message = null
switch(act)
if("howl", "scream")
if(mob.emote_allowed)
mob.emote_allowed = 0
message = "<span style=\"color:red\"><B>[mob] howls [pick("ominously", "eerily", "hauntingly", "proudly", "loudly")]!</B></span>"
playsound(get_turf(mob), "sound/voice/animal/werewolf_howl.ogg", 80, 0, 0, max(0.7, min(1.2, 1.0 + (30 - mob.bioHolder.age)/60)))
SPAWN_DBG(3 SECONDS)
mob.emote_allowed = 1
if("burp")
if(mob.emote_allowed)
mob.emote_allowed = 0
message = "<B>[mob]</B> belches."
playsound(get_turf(mob), "sound/voice/burp_alien.ogg", 60, 1)
SPAWN_DBG(1 SECOND)
mob.emote_allowed = 1
return message
/datum/mutantrace/hunter
name = "hunter"
icon_state = "hunter"
human_compatible = 0
jerk = 1
override_attack = 0
r_limb_arm_type_mutantrace = /obj/item/parts/human_parts/arm/right/hunter
l_limb_arm_type_mutantrace = /obj/item/parts/human_parts/arm/left/hunter
ignore_missing_limbs = 0
// Gave them a minor stamina boost (Convair880).
New(var/mob/living/carbon/human/M)
M.add_stam_mod_max("hunter", 50)
M.add_stam_mod_regen("hunter", 10)
return ..(M)
disposing()
if(mob)
mob.remove_stam_mod_max("hunter")
mob.remove_stam_mod_regen("hunter")
return ..()
sight_modifier()
mob.see_in_dark = SEE_DARK_FULL
return
say_verb()
return "snarls"
/datum/mutantrace/ithillid
name = "ithillid"
icon_state = "squid"
icon_override_static = 1
allow_fat = 1
jerk = 1
override_attack = 0
aquatic = 1
voice_override = "blub"
say_verb()
return "glubs"
/datum/mutantrace/dwarf
name = "dwarf"
icon_state = "dwarf"
icon_override_static = 1
head_offset = -3
hand_offset = -2
body_offset = -3
override_eyes = 0
override_hair = 0
override_beard = 0
override_skintone = 0
override_attack = 0
/datum/mutantrace/monkey
name = "monkey"
icon = 'icons/mob/monkey.dmi'
icon_state = "monkey"
icon_override_static = 1
head_offset = -9
hand_offset = -5
body_offset = -7
// uses_human_clothes = 0 // Guess they can keep that ability for now (Convair880).
human_compatible = 0
exclusive_language = 1
voice_message = "chimpers"
voice_name = "monkey"
override_language = "monkey"
understood_languages = list("english")
clothing_icon_override = 'icons/mob/monkey.dmi'
var/sound_monkeyscream = 'sound/voice/screams/monkey_scream.ogg'
var/had_tablepass = 0
var/table_hide = 0
New(var/mob/living/carbon/human/M)
if (M)
if (M.flags & TABLEPASS)
had_tablepass = 1
else
M.flags ^= TABLEPASS
M.add_stam_mod_max("monkey", -50)
..()
disposing()
if(mob && !had_tablepass)
mob.flags ^= TABLEPASS
if (ishuman(mob))
mob:remove_stam_mod_max("monkey")
..()
say_verb()
return "chimpers"
custom_attack(atom/target) // Fixed: monkeys can click-hide under every table now, not just the parent type. Also added beds (Convair880).
if(istype(target, /obj/machinery/optable/))
do_table_hide(target)
if(istype(target, /obj/table/))
do_table_hide(target)
if(istype(target, /obj/stool/bed/))
do_table_hide(target)
return target.attack_hand(mob)
proc
do_table_hide(obj/target)
step(mob, get_dir(mob, target))
if (mob.loc == target.loc)
if (table_hide)
table_hide = 0
mob.layer = MOB_LAYER
mob.visible_message("[mob] crawls on top of [target]!")
else
table_hide = 1
mob.layer = target.layer - 0.01
mob.visible_message("[mob] hides under [target]!")
emote(var/act)
. = null
var/muzzled = istype(mob.wear_mask, /obj/item/clothing/mask/muzzle)
switch(act)
if("scratch")
if (!mob.restrained())
. = "<B>[mob.name]</B> scratches."
if("whimper")
if (!muzzled)
. = "<B>[mob.name]</B> whimpers."
if("yawn")
if (!muzzled)
. = "<b>[mob.name]</B> yawns."
if("roar")
if (!muzzled)
. = "<B>[mob.name]</B> roars."
if("tail")
. = "<B>[mob.name]</B> waves \his tail."
if("paw")
if (!mob.restrained())
. = "<B>[mob.name]</B> flails \his paw."
if("scretch")
if (!muzzled)
. = "<B>[mob.name]</B> scretches."
if("sulk")
. = "<B>[mob.name]</B> sulks down sadly."
/*if("dance")
if (!mob.restrained())
. = "<B>[mob.name]</B> dances around happily."
SPAWN_DBG(0)
for (var/i = 0, i < 4, i++)
src.mob.pixel_x+= 1
sleep(1)
for (var/i = 0, i < 4, i++)
src.mob.dir = turn(src.mob.dir, -90)
sleep(2)
for (var/i = 0, i < 4, i++)
src.mob.pixel_x-= 1
sleep(1)
SPAWN_DBG(5 DECI SECONDS)
var/beeMax = 15
for (var/obj/critter/domestic_bee/responseBee in range(7, src.mob))
if (!responseBee.alive)
continue
if (beeMax-- < 0)
break
responseBee.dance_response()
var/parrotMax = 15
for (var/obj/critter/parrot/responseParrot in range(7, src.mob))
if (!responseParrot.alive)
continue
if (parrotMax-- < 0)
break
responseParrot.dance_response()
if (src.mob.traitHolder && src.mob.traitHolder.hasTrait("happyfeet"))
if (prob(33))
SPAWN_DBG(5 DECI SECONDS)
for (var/mob/living/carbon/human/responseMonkey in range(1, src.mob)) // they don't have to be monkeys, but it's signifying monkey code
if (responseMonkey.stat || responseMonkey.getStatusDuration("paralysis") || responseMonkey.sleeping || responseMonkey.getStatusDuration("stunned") || (responseMonkey == src.mob))
continue
responseMonkey.emote("dance")
if (src.mob.reagents)
if (src.mob.reagents.has_reagent("ants") && src.mob.reagents.has_reagent("mutagen"))
var/ant_amt = src.mob.reagents.get_reagent_amount("ants")
var/mut_amt = src.mob.reagents.get_reagent_amount("mutagen")
src.mob.reagents.del_reagent("ants")
src.mob.reagents.del_reagent("mutagen")
src.mob.reagents.add_reagent("spiders", ant_amt + mut_amt)
boutput(src.mob, "<span style=\"color:blue\">The ants arachnify.</span>")
playsound(get_turf(src.mob), "sound/effects/bubbles.ogg", 80, 1)*/
if("roll")
if (!mob.restrained())
. = "<B>[src.name]</B> rolls."
if("gnarl")
if (!muzzled)
. = "<B>[mob]</B> gnarls and shows \his teeth.."
if("jump")
. = "<B>[mob.name]</B> jumps!"
if ("scream")
if(mob.emote_allowed)
if(!(mob.client && mob.client.holder))
mob.emote_allowed = 0
. = "<B>[mob]</B> screams!"
playsound(get_turf(mob), src.sound_monkeyscream, 80, 0, 0, mob.get_age_pitch())
SPAWN_DBG(5 SECONDS)
if (mob)
mob.emote_allowed = 1
if ("fart")
if(farting_allowed && mob.emote_allowed && (!mob.reagents || !mob.reagents.has_reagent("anti_fart")))
mob.emote_allowed = 0
var/fart_on_other = 0
for(var/mob/living/M in mob.loc)
if(M == src || !M.lying)
continue
. = "<span style=\"color:red\"><B>[mob]</B> farts in [M]'s face!</span>"
fart_on_other = 1
break
if(!fart_on_other)
switch(rand(1, 27))
if(1) . = "<B>[mob]</B> farts. It smells like... bananas. Huh."
if(2) . = "<B>[mob]</B> goes apeshit! Or at least smells like it."
if(3) . = "<B>[mob]</B> releases an unbelievably foul fart."
if(4) . = "<B>[mob]</B> chimpers out of its ass."
if(5) . = "<B>[mob]</B> farts and looks incredibly amused about it."
if(6) . = "<B>[mob]</B> unleashes the king kong of farts!"
if(7) . = "<B>[mob]</B> farts and does a silly little dance."
if(8) . = "<B>[mob]</B> farts gloriously."
if(9) . = "<B>[mob]</B> plays the song of its people. With farts."
if(10) . = "<B>[mob]</B> screeches loudly and wildly flails its arms in a poor attempt to conceal a fart."
if(11) . = "<B>[mob]</B> clenches and bares its teeth, but only manages a sad squeaky little fart."
if(12) . = "<B>[mob]</B> unleashes a chain of farts by beating its chest."
if(13) . = "<B>[mob]</B> farts so hard a bunch of fur flies off its ass."
if(14) . = "<B>[mob]</B> does an impression of a baboon by farting until its ass turns red."
if(15) . = "<B>[mob]</B> farts out a choking, hideous stench!"
if(16) . = "<B>[mob]</B> reflects on its captive life aboard a space station, before farting and bursting into hysterial laughter."
if(17) . = "<B>[mob]</B> farts megalomaniacally."
if(18) . = "<B>[mob]</B> rips a floor-rattling fart. Damn."
if(19) . = "<B>[mob]</B> farts. What a damn dirty ape!"
if(20) . = "<B>[mob]</B> farts. It smells like a nuclear engine. Not that you know what that smells like."
if(21) . = "<B>[mob]</B> performs a complex monkey divining ritual. By farting."
if(22) . = "<B>[mob]</B> farts out the smell of the jungle. The jungle smells gross as hell apparently."
if(23) . = "<B>[mob]</B> farts up a methane monsoon!"
if(24) . = "<B>[mob]</B> unleashes an utterly rancid stink from its ass."
if(25) . = "<B>[mob]</B> makes a big goofy grin and farts loudly."
if(26) . = "<B>[mob]</B> hovers off the ground for a moment using a powerful fart."
if(27) . = "<B>[mob]</B> plays drums on its ass while farting."
playsound(mob.loc, "sound/voice/farts/poo2.ogg", 80, 0, 0, mob.get_age_pitch())
mob.remove_stamina(STAMINA_DEFAULT_FART_COST)
mob.stamina_stun()
#ifdef DATALOGGER
game_stats.Increment("farts")
#endif
SPAWN_DBG(1 SECOND)
mob.emote_allowed = 1
/datum/mutantrace/monkey/seamonkey
name = "sea monkey"
icon = 'icons/mob/monkey.dmi'
icon_state = "seamonkey"
aquatic = 1
/datum/mutantrace/martian
name = "martian"
icon_state = "martian"
icon_override_static = 1
human_compatible = 0
uses_human_clothes = 0
override_language = "martian"
/datum/mutantrace/stupidbaby
name = "stupid alien baby"
icon_state = "stupidbaby"
icon_override_static = 1
human_compatible = 0
uses_human_clothes = 0
jerk = 1
New()
..()
if(mob)
mob.real_name = pick("a", "ay", "ey", "eh", "e") + pick("li", "lee", "lhi", "ley", "ll") + pick("n", "m", "nn", "en")
if(prob(50))
mob.real_name = uppertext(mob.real_name)
mob.bioHolder.AddEffect("clumsy")
mob.take_brain_damage(80)
mob.stuttering = 120
mob.contract_disease(/datum/ailment/disability/clumsy,null,null,1)
/datum/mutantrace/premature_clone
name = "premature clone"
icon = 'icons/mob/human.dmi'
icon_state = "mutant3"
icon_override_static = 1
human_compatible = 1
uses_human_clothes = 1
override_hair = 0
override_beard = 0
override_skintone = 0
New()
..()
if(mob)
if (isitem(mob.l_hand))
var/obj/item/toDrop = mob.l_hand
mob.u_equip(toDrop)
if (toDrop)
toDrop.layer = initial(toDrop.layer)
toDrop.set_loc(mob.loc)
if (mob.limbs && mob.limbs.l_arm)
mob.limbs.l_arm.delete()
say_verb()
return "gurgles"
onDeath()
SPAWN_DBG(2 SECONDS)
if (mob)
mob.visible_message("<span style=\"color:red\"><B>[mob]</B> starts convulsing violently!</span>", "You feel as if your body is tearing itself apart!")
mob.changeStatus("weakened", 150)
mob.make_jittery(1000)
sleep(rand(40, 120))
mob.gib()
return
// some new simple gimmick junk
/datum/mutantrace/gross
name = "mutilated"
icon_state = "gross"
override_attack = 0
say_verb()
return "shrieks"
/datum/mutantrace/faceless
name = "humanoid"
icon_state = "faceless"
override_attack = 0
say_verb()
return "murmurs"
/datum/mutantrace/cyclops
name = "cyclops"
icon_state = "cyclops"
override_hair = 0
override_beard = 0
override_attack = 0
/datum/mutantrace/roach
name = "roach"
icon_state = "roach"
icon_override_static = 1
override_attack = 0
say_verb()
return "clicks"
sight_modifier()
mob.see_in_dark = SEE_DARK_HUMAN + 1
mob.see_invisible = 1
/datum/mutantrace/cat // we have the sprites so ~why not add them~? (I fully expect to get shit for this)
name = "cat"
icon_state = "cat"
icon_override_static = 1
jerk = 1
override_attack = 0
firevuln = 1.5 // very flammable catthings
say_verb()
return "meows"
sight_modifier()
mob.see_in_dark = SEE_DARK_HUMAN + 1
mob.see_invisible = 1
/datum/mutantrace/amphibian
name = "amphibian"
icon_state = "amphibian"
icon_override_static = 1
firevuln = 1.3
brutevuln = 0.7
human_compatible = 0
uses_human_clothes = 1
aquatic = 1
voice_name = "amphibian"
jerk = 1
head_offset = 0
hand_offset = -3
body_offset = -3
allow_fat = 1
var/original_blood_color = null
say_verb()
return "croaks"
say_filter(var/message)
return replacetext(message, "r", stutter("rrr"))
New(var/mob/living/carbon/human/M)
..()
if(ishuman(mob))
original_blood_color = mob.blood_color
mob.blood_color = "#22EE99"
M.bioHolder.AddEffect("mattereater")
M.bioHolder.AddEffect("jumpy")
M.bioHolder.AddEffect("vowelitis")
M.bioHolder.AddEffect("accent_chav")
M.bioHolder.AddEffect("fat")
disposing()
if(ishuman(mob))
if(!isnull(original_blood_color))
mob.blood_color = original_blood_color
original_blood_color = null
..()
movement_delay()
return(1.5)
emote(var/act)
var/message = null
switch (act)
if ("scream","howl","laugh")
if (mob.emote_allowed)
mob.emote_allowed = 0
message = "<span style=\"color:red\"><B>[mob] makes an awful noise!</B></span>"
playsound(get_turf(mob), pick("sound/voice/screams/frogscream1.ogg","sound/voice/screams/frogscream3.ogg","sound/voice/screams/frogscream4.ogg"), 60, 1)
SPAWN_DBG (30)
if (mob) mob.emote_allowed = 1
return message
if("burp","fart","gasp")
if(mob.emote_allowed)
mob.emote_allowed = 0
message = "<B>[mob]</B> croaks."
playsound(get_turf(mob), "sound/voice/farts/frogfart.ogg", 60, 1)
SPAWN_DBG(1 SECOND)
if (mob) mob.emote_allowed = 1
return message
else ..()
/datum/mutantrace/kudzu
name = "kudzu"
icon_state = "kudzu-w"
// icon_override_static = 1 //Level 2 and 3
// anchor_to_floor = 1 //Level 3
human_compatible = 0
uses_human_clothes = 0
var/original_name
jerk = 1 //Not really, but NT doesn't really like treehuggers
aquatic = 1
needs_oxy = 0 //get their nutrients from the kudzu
understood_languages = list("english", "kudzu")
override_eyes = 0
override_hair = 0
override_beard = 0
override_detail = 0
override_skintone = 0
override_attack = 1
// r_limb_arm_type_mutantrace = /obj/item/parts/human_parts/arm/right/
// l_limb_arm_type_mutantrace = /obj/item/parts/human_parts/arm/left/ //kudzu
// ignore_missing_limbs = OVERRIDE_ARM_L | OVERRIDE_ARM_R
custom_attack(atom/target) // Fixed: monkeys can click-hide under every table now, not just the parent type. Also added beds (Convair880).
if(ishuman(target))
mob.visible_message("<span style=\"color:red\"><B>[mob]</B> waves its limbs at [target] threateningly!</span>")
else
return target.attack_hand(mob)
var/nutrients = 0
say_verb()
return "rasps"
New(var/mob/living/carbon/human/H)
..()
H.max_health -= 50
H.add_stam_mod_max("kudzu", -100)
H.add_stam_mod_regen("kudzu", -5)
if(ishuman(mob))
H.abilityHolder = new /datum/abilityHolder/kudzu(H)
H.abilityHolder.owner = H
H.abilityHolder.addAbility(/datum/targetable/kudzu/guide)
H.abilityHolder.addAbility(/datum/targetable/kudzu/heal_other)
H.abilityHolder.addAbility(/datum/targetable/kudzu/stealth)
H.abilityHolder.addAbility(/datum/targetable/kudzu/kudzusay)
disposing()
if(ishuman(mob))
var/mob/living/carbon/human/H = mob
H.abilityHolder.removeAbility(/datum/targetable/kudzu/guide)
H.abilityHolder.removeAbility(/datum/targetable/kudzu/heal_other)
H.abilityHolder.removeAbility(/datum/targetable/kudzu/stealth)
H.abilityHolder.addAbility(/datum/targetable/kudzu/kudzusay)
H.remove_stam_mod_max("kudzu")
H.remove_stam_mod_regen("kudzu")
return ..()
// movement delay modifier
movement_delay()
return 5
// vision modifier (see_mobs, etc i guess)
sight_modifier()
mob.sight |= SEE_TURFS
mob.sight |= SEE_MOBS
mob.sight |= SEE_OBJS
mob.see_in_dark = SEE_DARK_FULL
return
onLife(var/mult = 1) //Called every Life cycle of our mob
if (!mob.abilityHolder)
mob.abilityHolder = new /datum/abilityHolder/kudzu(mob)
var/datum/abilityHolder/kudzu/KAH = mob.abilityHolder
var/round_mult = max(1, round((mult)))
var/turf/T = get_turf(mob)
//if on kudzu, get nutrients for later use. If at max nutrients. Then heal self.
if (T && T.temp_flags & HAS_KUDZU)
if (KAH.points < KAH:MAX_POINTS)
KAH.points += round_mult
else
//at max points, so heal
mob.take_toxin_damage(-round_mult)
mob.HealDamage("All", round_mult, round_mult)
else
//nutrients for a bit of grace period
if (KAH.points > 0)
KAH.points -= 10
else
//do effects from not being on kudzu here.
mob.take_toxin_damage(2 * round_mult)
mob.changeStatus("slowed", 3 SECONDS)
// random_brute_damage(mob, 2 * mult)
if (prob(30))
mob.changeStatus("weakened", 3 SECONDS)
return
#undef OVERRIDE_ARM_L
#undef OVERRIDE_ARM_R
#undef OVERRIDE_LEG_R
#undef OVERRIDE_LEG_L