Merge branch 'master' into FERMICHEMCurTweaks

This commit is contained in:
Fermi
2019-11-23 00:10:33 +00:00
3018 changed files with 65365 additions and 157564 deletions
@@ -151,7 +151,7 @@
message_admins(msg)
to_chat(usr, "<span class='danger'>The round is either not ready, or has already finished...</span>")
return
if(!GLOB.enter_allowed)
to_chat(usr, "<span class='notice'>There is an administrative lock on entering the game!</span>")
return
+1 -1
View File
@@ -310,7 +310,7 @@
});
$( "#sortable" ).disableSelection();
$('form').submit(function(){
$('#IRVdata').val($( "#sortable" ).sortable("toArray", { attribute: "voteid" }));
$('#IRVdata').val($( "#sortable" ).sortable("toArray", { attribute: "voteid" }));
});
});
@@ -17,6 +17,8 @@
hair_color = random_short_color()
facial_hair_color = hair_color
eye_color = random_eye_color()
horn_color = "85615a"
wing_color = "fff"
if(!pref_species)
var/rando_race = pick(GLOB.roundstart_races)
pref_species = new rando_race()
@@ -54,6 +54,10 @@
name = "Redpanda"
icon_state = "redpanda"
/datum/sprite_accessory/mam_body_markings/bat
name = "Bat"
icon_state = "bat"
/datum/sprite_accessory/mam_body_markings/bee
name = "Bee"
icon_state = "bee"
@@ -130,10 +130,10 @@
color_src = MATRIXED
/datum/sprite_accessory/ears/human/rabbit
name = "Rabbit"
icon_state = "rabbit"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
name = "Rabbit"
icon_state = "rabbit"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
/datum/sprite_accessory/ears/human/sergal
name = "Sergal"
@@ -176,6 +176,10 @@
name = "Axolotl"
icon_state = "axolotl"
/datum/sprite_accessory/mam_ears/bat
name = "Bat"
icon_state = "bat"
/datum/sprite_accessory/mam_ears/bear
name = "Bear"
icon_state = "bear"
@@ -283,8 +287,8 @@
icon_state = "pede"
/datum/sprite_accessory/mam_ears/rabbit
name = "Rabbit"
icon_state = "rabbit"
name = "Rabbit"
icon_state = "rabbit"
/datum/sprite_accessory/mam_ears/sergal
name = "Sergal"
@@ -194,6 +194,10 @@
name = "Mammal, Short ALT"
icon_state = "scanidalt"
/datum/sprite_accessory/mam_snouts/scanidalt2
name = "Mammal, Short ALT 2"
icon_state = "scanidalt2"
/datum/sprite_accessory/mam_snouts/wolf
name = "Mammal, Thick"
icon_state = "wolf"
@@ -306,6 +310,10 @@
name = "Mammal, Short ALT (Top)"
icon_state = "fscanidalt"
/datum/sprite_accessory/mam_snouts/fscanidalt2
name = "Mammal, Short ALT 2 (Top)"
icon_state = "fscanidalt2"
/datum/sprite_accessory/mam_snouts/fwolf
name = "Mammal, Thick (Top)"
icon_state = "fwolf"
@@ -114,6 +114,26 @@
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
/datum/sprite_accessory/mam_tails/batl
name = "Bat (Long)"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
icon_state = "batl"
/datum/sprite_accessory/mam_tails_animated/batl
name = "Bat (Long)"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
icon_state = "batl"
/datum/sprite_accessory/mam_tails/bats
name = "Bat (Short)"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
icon_state = "bats"
/datum/sprite_accessory/mam_tails_animated/bats
name = "Bat (Short)"
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
icon_state = "bats"
/datum/sprite_accessory/tails/human/bee
name = "Bee"
icon_state = "bee"
@@ -469,6 +489,22 @@
name = "Axolotl"
icon_state = "axolotl"
/datum/sprite_accessory/mam_tails/batl
name = "Bat (Long)"
icon_state = "batl"
/datum/sprite_accessory/mam_tails_animated/batl
name = "Bat (Long)"
icon_state = "batl"
/datum/sprite_accessory/mam_tails/bats
name = "Bat (Short)"
icon_state = "bats"
/datum/sprite_accessory/mam_tails_animated/bats
name = "Bat (Short)"
icon_state = "bats"
/datum/sprite_accessory/mam_tails/bee
name = "Bee"
icon_state = "bee"
@@ -28,73 +28,14 @@
locked = TRUE
// Decorative wings
/datum/sprite_accessory/deco_wings
icon = 'icons/mob/wings.dmi'
color_src = WINGCOLOR
/datum/sprite_accessory/deco_wings/plain
name = "Plain"
icon_state = "plain"
/datum/sprite_accessory/deco_wings/monarch
name = "Monarch"
icon_state = "monarch"
/datum/sprite_accessory/deco_wings/luna
name = "Luna"
icon_state = "luna"
/datum/sprite_accessory/deco_wings/atlas
name = "Atlas"
icon_state = "atlas"
/datum/sprite_accessory/deco_wings/reddish
name = "Reddish"
icon_state = "redish"
/datum/sprite_accessory/deco_wings/royal
name = "Royal"
icon_state = "royal"
/datum/sprite_accessory/deco_wings/gothic
name = "Gothic"
icon_state = "gothic"
/datum/sprite_accessory/deco_wings/lovers
name = "Lovers"
icon_state = "lovers"
/datum/sprite_accessory/deco_wings/whitefly
name = "White Fly"
icon_state = "whitefly"
/datum/sprite_accessory/deco_wings/punished
name = "Burnt Off"
icon_state = "punished"
locked = TRUE
/datum/sprite_accessory/deco_wings/firewatch
name = "Firewatch"
icon_state = "firewatch"
/datum/sprite_accessory/deco_wings/deathhead
name = "Deathshead"
icon_state = "deathhead"
/datum/sprite_accessory/deco_wings/poison
name = "Poison"
icon_state = "poison"
/datum/sprite_accessory/deco_wings/ragged
name = "Ragged"
icon_state = "ragged"
/datum/sprite_accessory/deco_wings/moonfly
name = "Moon Fly"
icon_state = "moonfly"
/datum/sprite_accessory/deco_wings/snow
name = "Snow"
icon_state = "snow"
/datum/sprite_accessory/deco_wings/none
name = "None"
icon_state = "none"
/datum/sprite_accessory/deco_wings/angel
name = "Angel"
@@ -104,44 +45,123 @@
center = TRUE
dimension_y = 34
/datum/sprite_accessory/deco_wings/none
name = "None"
icon_state = "none"
/datum/sprite_accessory/deco_wings/bat
name = "Bat"
icon_state = "bat"
/datum/sprite_accessory/deco_wings/bee
name = "Bee"
icon_state = "bee"
/datum/sprite_accessory/deco_wings/fairy
name = "Fairy"
icon_state = "fairy"
/datum/sprite_accessory/deco_wings/feathery
name = "Feathery"
icon_state = "feathery"
/datum/sprite_accessory/deco_wings/atlas
name = "Atlas"
icon_state = "atlas"
/datum/sprite_accessory/deco_wings/deathhead
name = "Deathshead"
icon_state = "deathhead"
/datum/sprite_accessory/deco_wings/firewatch
name = "Firewatch"
icon_state = "firewatch"
/datum/sprite_accessory/deco_wings/gothic
name = "Gothic"
icon_state = "gothic"
/datum/sprite_accessory/deco_wings/lovers
name = "Lovers"
icon_state = "lovers"
/datum/sprite_accessory/deco_wings/luna
name = "Luna"
icon_state = "luna"
/datum/sprite_accessory/deco_wings/monarch
name = "Monarch"
icon_state = "monarch"
/datum/sprite_accessory/deco_wings/moonfly
name = "Moon Fly"
icon_state = "moonfly"
/datum/sprite_accessory/deco_wings/plain
name = "Plain"
icon_state = "plain"
/datum/sprite_accessory/deco_wings/poison
name = "Poison"
icon_state = "poison"
/datum/sprite_accessory/deco_wings/punished
name = "Burnt Off"
icon_state = "punished"
/datum/sprite_accessory/deco_wings/ragged
name = "Ragged"
icon_state = "ragged"
/datum/sprite_accessory/deco_wings/reddish
name = "Reddish"
icon_state = "redish"
/datum/sprite_accessory/deco_wings/royal
name = "Royal"
icon_state = "royal"
/datum/sprite_accessory/deco_wings/snow
name = "Snow"
icon_state = "snow"
/datum/sprite_accessory/deco_wings/whitefly
name = "White Fly"
icon_state = "whitefly"
//INSECT WINGS
/datum/sprite_accessory/insect_wings
icon = 'icons/mob/wings.dmi'
color_src = null
color_src = WINGCOLOR
/datum/sprite_accessory/insect_wings/none
name = "None"
icon_state = "none"
/datum/sprite_accessory/insect_wings/plain
name = "Plain"
icon_state = "plain"
/datum/sprite_accessory/insect_wings/bat
name = "Bat"
icon_state = "bat"
/datum/sprite_accessory/insect_wings/monarch
name = "Monarch"
icon_state = "monarch"
/datum/sprite_accessory/insect_wings/bee
name = "Bee"
icon_state = "bee"
/datum/sprite_accessory/insect_wings/luna
name = "Luna"
icon_state = "luna"
/datum/sprite_accessory/insect_wings/fairy
name = "Fairy"
icon_state = "fairy"
/datum/sprite_accessory/insect_wings/feathery
name = "Feathery"
icon_state = "feathery"
/datum/sprite_accessory/insect_wings/atlas
name = "Atlas"
icon_state = "atlas"
/datum/sprite_accessory/insect_wings/reddish
name = "Reddish"
icon_state = "redish"
/datum/sprite_accessory/insect_wings/deathhead
name = "Deathshead"
icon_state = "deathhead"
/datum/sprite_accessory/insect_wings/royal
name = "Royal"
icon_state = "royal"
/datum/sprite_accessory/insect_wings/firewatch
name = "Firewatch"
icon_state = "firewatch"
/datum/sprite_accessory/insect_wings/gothic
name = "Gothic"
@@ -151,75 +171,46 @@
name = "Lovers"
icon_state = "lovers"
/datum/sprite_accessory/insect_wings/whitefly
name = "White Fly"
icon_state = "whitefly"
/datum/sprite_accessory/insect_wings/luna
name = "Luna"
icon_state = "luna"
/datum/sprite_accessory/insect_wings/punished
name = "Burnt Off"
icon_state = "punished"
/datum/sprite_accessory/insect_wings/firewatch
name = "Firewatch"
icon_state = "firewatch"
/datum/sprite_accessory/insect_wings/deathhead
name = "Deathshead"
icon_state = "deathhead"
/datum/sprite_accessory/insect_wings/poison
name = "Poison"
icon_state = "poison"
/datum/sprite_accessory/insect_wings/ragged
name = "Ragged"
icon_state = "ragged"
/datum/sprite_accessory/insect_wings/monarch
name = "Monarch"
icon_state = "monarch"
/datum/sprite_accessory/insect_wings/moonfly
name = "Moon Fly"
icon_state = "moonfly"
/datum/sprite_accessory/insect_wings/plain
name = "Plain"
icon_state = "plain"
/datum/sprite_accessory/insect_wings/poison
name = "Poison"
icon_state = "poison"
/datum/sprite_accessory/insect_wings/punished
name = "Burnt Off"
icon_state = "punished"
/datum/sprite_accessory/insect_wings/ragged
name = "Ragged"
icon_state = "ragged"
/datum/sprite_accessory/insect_wings/reddish
name = "Reddish"
icon_state = "redish"
/datum/sprite_accessory/insect_wings/royal
name = "Royal"
icon_state = "royal"
/datum/sprite_accessory/insect_wings/snow
name = "Snow"
icon_state = "snow"
/datum/sprite_accessory/insect_wings/colored
name = "Colored (Hair)"
icon_state = "snowplain"
color_src = HAIR
/datum/sprite_accessory/insect_fluff/colored1
name = "Colored (Primary)"
icon_state = "snowplain"
color_src = MUTCOLORS
/datum/sprite_accessory/insect_fluff/colored2
name = "Colored (Secondary)"
icon_state = "snowplain"
color_src = MUTCOLORS2
/datum/sprite_accessory/insect_fluff/colored3
name = "Colored (Tertiary)"
icon_state = "snowplain"
color_src = MUTCOLORS3
/datum/sprite_accessory/insect_wings/bee
name = "Bee"
icon_state = "bee"
/datum/sprite_accessory/insect_wings/bee_color
name = "Bee (Hair colored)"
icon_state = "bee"
color_src = HAIR
/datum/sprite_accessory/insect_wings/fairy
name = "Fairy"
icon_state = "fairy"
/datum/sprite_accessory/insect_wings/bat
name = "Bat"
icon_state = "bat"
/datum/sprite_accessory/insect_wings/feathery
name = "Feathery"
icon_state = "feathery"
/datum/sprite_accessory/insect_wings/whitefly
name = "White Fly"
icon_state = "whitefly"
+50 -23
View File
@@ -3,6 +3,8 @@ GLOBAL_LIST_EMPTY(ghost_images_simple) //this is a list of all ghost images as t
GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
#define CANT_REENTER_ROUND -1
/mob/dead/observer
name = "ghost"
desc = "It's a g-g-g-g-ghooooost!" //jinkies!
@@ -17,8 +19,9 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
see_in_dark = 100
invisibility = INVISIBILITY_OBSERVER
hud_type = /datum/hud/ghost
movement_type = GROUND | FLYING
var/can_reenter_corpse
var/can_reenter_round = TRUE
var/reenter_round_timeout = 0 // used to prevent people from coming back through ghost roles/midround antags as they suicide/cryo for a duration set by CONFIG_GET(number/suicide_reenter_round_timer) and CONFIG_GET(number/roundstart_suicide_time_limit)
var/datum/hud/living/carbon/hud = null // hud
var/bootime = 0
var/started_as_observer //This variable is set to 1 when you enter the game as an observer.
@@ -231,7 +234,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
var/r_val
var/b_val
var/g_val
var/color_format = lentext(input_color)
var/color_format = length(input_color)
if(color_format == 3)
r_val = hex2num(copytext(input_color, 1, 2))*16
g_val = hex2num(copytext(input_color, 2, 3))*16
@@ -260,14 +263,22 @@ Transfer_mind is there to check if mob is being deleted/not going to have a body
Works together with spawning an observer, noted above.
*/
/mob/proc/ghostize(can_reenter_corpse = TRUE, special = FALSE)
if(!key || cmptext(copytext(key,1,2),"@") || (!special && SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special) & COMPONENT_BLOCK_GHOSTING))
/mob/proc/ghostize(can_reenter_corpse = TRUE, special = FALSE, penalize = FALSE)
if(!key || cmptext(copytext(key,1,2),"@") || (!special && SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse) & COMPONENT_BLOCK_GHOSTING))
return //mob has no key, is an aghost or some component hijacked.
stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now
var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc.
SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
ghost.can_reenter_corpse = can_reenter_corpse
ghost.can_reenter_round = (can_reenter_corpse && !suiciding)
if(penalize) //penalizing them from making a ghost role / midround antag comeback right away.
var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
if(world.time < roundstart_quit_limit) //add up the time difference to their antag rolling penalty if they quit before half a (ingame) hour even passed.
penalty += roundstart_quit_limit - world.time
if(penalty)
ghost.reenter_round_timeout = world.realtime + penalty
if(ghost.reenter_round_timeout - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
ghost.reenter_round_timeout = CANT_REENTER_ROUND
transfer_ckey(ghost, FALSE)
return ghost
@@ -283,26 +294,27 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, (stat == DEAD) ? TRUE : FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING)
return
// CITADEL EDIT
if(istype(loc, /obj/machinery/cryopod))
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost")//darn copypaste
return
var/obj/machinery/cryopod/C = loc
C.despawn_occupant()
return
// END EDIT
var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
if(world.time < roundstart_quit_limit)
penalty += roundstart_quit_limit - world.time
if(penalty + world.realtime - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
penalty = CANT_REENTER_ROUND
if(stat != DEAD)
succumb()
if(stat == DEAD)
ghostize(1)
else
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles [penalty == CANT_REENTER_ROUND ? "until the round is over" : "for the next [DisplayTimeText(penalty)]"]" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost")
return //didn't want to ghost after-all
ghostize(0) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
suicide_log(TRUE)
if(istype(loc, /obj/machinery/cryopod))
var/obj/machinery/cryopod/C = loc
C.despawn_occupant()
else
ghostize(0, penalize = TRUE) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
suicide_log(TRUE)
/mob/camera/verb/ghost()
set category = "OOC"
@@ -312,10 +324,24 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING)
return
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
if(world.time < roundstart_quit_limit)
penalty += roundstart_quit_limit - world.time
if(penalty + world.realtime - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
penalty = CANT_REENTER_ROUND
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles [penalty == CANT_REENTER_ROUND ? "until the round is over" : "for the next [DisplayTimeText(penalty)]"]" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost")
return
ghostize(0)
ghostize(0, penalize = TRUE)
/mob/dead/observer/proc/can_reenter_round(silent = FALSE)
if(reenter_round_timeout != CANT_REENTER_ROUND && reenter_round_timeout <= world.realtime)
return TRUE
if(!silent)
to_chat(src, "<span class='warning'>You are unable to reenter the round[reenter_round_timeout != CANT_REENTER_ROUND ? " yet. Your ghost role blacklist will expire in [DisplayTimeText(reenter_round_timeout - world.realtime)]" : ""].</span>")
return FALSE
/mob/dead/observer/Move(NewLoc, direct)
if(updatedir)
@@ -603,6 +629,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "Possess!"
set desc= "Take over the body of a mindless creature!"
if(!can_reenter_round())
return FALSE
var/list/possessible = list()
for(var/mob/living/L in GLOB.alive_mob_list)
if(istype(L,/mob/living/carbon/human/dummy) || !get_turf(L)) //Haha no.
@@ -623,10 +652,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
to_chat(src, "<span class='warning'>This isn't really a creature, now is it!</span>")
return 0
if(!can_reenter_round)
to_chat(src, "<span class='warning'>You are unable to re-enter the round.</span>")
return FALSE
if(can_reenter_corpse && mind && mind.current)
if(alert(src, "Your soul is still tied to your former life as [mind.current.name], if you go forward there is no going back to that life. Are you sure you wish to continue?", "Move On", "Yes", "No") == "No")
return 0
@@ -871,3 +896,5 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
spawners_menu = new(src)
spawners_menu.ui_interact(src)
#undef CANT_REENTER_ROUND
@@ -0,0 +1,2 @@
/mob/dead/observer/canZMove(direction, turf/target)
return TRUE
+1 -1
View File
@@ -40,7 +40,7 @@
if(iscyborg(user) && user.has_buckled_mobs())
var/mob/living/silicon/robot/R = user
GET_COMPONENT_FROM(riding_datum, /datum/component/riding, R)
var/datum/component/riding/riding_datum = R.GetComponent(/datum/component/riding)
if(riding_datum)
for(var/mob/M in R.buckled_mobs)
riding_datum.force_dismount(M)
+3
View File
@@ -468,3 +468,6 @@
bodyparts += BP
hand_bodyparts[i] = BP
..() //Don't redraw hands until we have organs for them
/mob/canReachInto(atom/user, atom/target, list/next, view_only, obj/item/tool)
return ..() && (user == src)
+94 -50
View File
@@ -2,6 +2,9 @@
BLOOD SYSTEM
****************************************************/
#define EXOTIC_BLEED_MULTIPLIER 4 //Multiplies the actually bled amount by this number for the purposes of turf reaction calculations.
/mob/living/carbon/human/proc/suppress_bloodloss(amount)
if(bleedsuppress)
return
@@ -30,6 +33,9 @@
bleed_rate = 0
return
if(bleed_rate <= 0)
bleed_rate = 0
if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood.
//Blood regeneration if there is some space
@@ -80,6 +86,9 @@
var/obj/item/bodypart/BP = X
var/brutedamage = BP.brute_dam
if(BP.status == BODYPART_ROBOTIC) //for the moment, synth limbs won't bleed, but soon, my pretty.
continue
//We want an accurate reading of .len
listclearnulls(BP.embedded_objects)
temp_bleed += 0.5*BP.embedded_objects.len
@@ -87,7 +96,7 @@
if(brutedamage >= 20)
temp_bleed += (brutedamage * 0.013)
bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases
bleed_rate = max(bleed_rate - 0.50, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases
if(bleed_rate && !bleedsuppress && !(HAS_TRAIT(src, TRAIT_FAKEDEATH)))
bleed(bleed_rate)
@@ -105,9 +114,11 @@
/mob/living/carbon/human/bleed(amt)
amt *= physiology.bleed_mod
if(!(NOBLOOD in dna.species.species_traits))
..()
.=..()
if(dna.species.exotic_blood && .) // Do we have exotic blood, and have we left any on the ground?
var/datum/reagent/R = GLOB.chemical_reagents_list[get_blood_id()]
if(istype(R) && isturf(loc))
R.reaction_turf(get_turf(src), amt * EXOTIC_BLEED_MULTIPLIER)
/mob/living/proc/restore_blood()
blood_volume = initial(blood_volume)
@@ -123,16 +134,16 @@
//Gets blood from mob to a container or other mob, preserving all data in it.
/mob/living/proc/transfer_blood_to(atom/movable/AM, amount, forced)
if(!blood_volume || !AM.reagents)
return 0
return FALSE
if(blood_volume < (BLOOD_VOLUME_BAD * blood_ratio) && !forced)
return 0
return FALSE
if(blood_volume < amount)
amount = blood_volume
var/blood_id = get_blood_id()
if(!blood_id)
return 0
return FALSE
blood_volume -= amount
@@ -141,29 +152,27 @@
if(iscarbon(AM))
var/mob/living/carbon/C = AM
if(blood_id == C.get_blood_id())//both mobs have the same blood substance
if(blood_id == "blood") //normal blood
if(blood_id == "blood" || blood_id == "jellyblood") //normal blood
if(blood_data["viruses"])
for(var/thing in blood_data["viruses"])
var/datum/disease/D = thing
if((D.spread_flags & DISEASE_SPREAD_SPECIAL) || (D.spread_flags & DISEASE_SPREAD_NON_CONTAGIOUS))
continue
C.ForceContractDisease(D)
if(!(blood_data["blood_type"] in get_safe_blood(C.dna.blood_type)))
C.reagents.add_reagent("toxin", amount * 0.5)
return 1
//This used to inject oof ouch results, but since we add the reagent, and the reagent causes oof ouch on mob life... why double dip?
C.blood_volume = min(C.blood_volume + round(amount, 0.1), BLOOD_VOLUME_MAXIMUM)
return 1
return TRUE
AM.reagents.add_reagent(blood_id, amount, blood_data, bodytemperature)
return 1
return TRUE
/mob/living/proc/get_blood_data(blood_id)
return
/mob/living/carbon/get_blood_data(blood_id)
if(blood_id == "blood") //actual blood reagent
if(blood_id == "blood" || blood_id == "jellyblood") //actual blood reagent
var/blood_data = list()
//set the blood data
blood_data["donor"] = src
@@ -174,6 +183,7 @@
blood_data["viruses"] += D.Copy()
blood_data["blood_DNA"] = copytext(dna.unique_enzymes,1,0)
blood_data["bloodcolor"] = bloodtype_to_color(dna.blood_type)
if(disease_resistances && disease_resistances.len)
blood_data["resistances"] = disease_resistances.Copy()
var/list/temp_chem = list()
@@ -206,21 +216,6 @@
if(istype(ling))
blood_data["changeling_loudness"] = ling.loudfactor
return blood_data
if(blood_id == "slimejelly") //Just so MKUltra works. Takes the minimum required data. Sishen is testing if this breaks stuff.
var/blood_data = list()
if(mind)
blood_data["mind"] = mind
else if(last_mind)
blood_data["mind"] = last_mind
if(ckey)
blood_data["ckey"] = ckey
else if(last_mind)
blood_data["ckey"] = ckey(last_mind.key)
blood_data["gender"] = gender
blood_data["real_name"] = real_name
return blood_data
//get the id of the substance this mob use as blood.
/mob/proc/get_blood_id()
@@ -234,12 +229,15 @@
if(!(HAS_TRAIT(src, TRAIT_NOCLONE)))
return "blood"
/mob/living/carbon/human/get_blood_id()
if(dna.species.exotic_blood)
/mob/living/carbon/get_blood_id()
if(isjellyperson(src))
return "jellyblood"
if(dna?.species?.exotic_blood)
return dna.species.exotic_blood
else if((NOBLOOD in dna.species.species_traits) || (HAS_TRAIT(src, TRAIT_NOCLONE)))
return
return "blood"
else
return "blood"
// This is has more potential uses, and is probably faster than the old proc.
/proc/get_safe_blood(bloodtype)
@@ -248,16 +246,21 @@
return
var/static/list/bloodtypes_safe = list(
"A-" = list("A-", "O-"),
"A+" = list("A-", "A+", "O-", "O+"),
"B-" = list("B-", "O-"),
"B+" = list("B-", "B+", "O-", "O+"),
"AB-" = list("A-", "B-", "O-", "AB-"),
"AB+" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+"),
"O-" = list("O-"),
"O+" = list("O-", "O+"),
"L" = list("L"),
"U" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L", "U")
"A-" = list("A-", "O-", "SY"),
"A+" = list("A-", "A+", "O-", "O+", "SY"),
"B-" = list("B-", "O-", "SY"),
"B+" = list("B-", "B+", "O-", "O+", "SY"),
"AB-" = list("A-", "B-", "O-", "AB-", "SY"),
"AB+" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "SY"),
"O-" = list("O-","SY"),
"O+" = list("O-", "O+","SY"),
"L" = list("L","SY"),
"U" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L", "U","SY"),
"HF" = list("HF", "SY"),
"X*" = list("X*", "SY"),
"SY" = list("SY"),
"GEL" = list("GEL","SY"),
"BUG" = list("BUG", "SY")
)
var/safe = bloodtypes_safe[bloodtype]
@@ -266,7 +269,7 @@
//to add a splatter of blood or other mob liquid.
/mob/living/proc/add_splatter_floor(turf/T, small_drip)
if(get_blood_id() != "blood")
if(get_blood_id() == null)
return
if(!T)
T = get_turf(src)
@@ -280,24 +283,27 @@
drop.drips++
drop.add_overlay(pick(drop.random_icon_states))
drop.transfer_mob_blood_dna(src)
drop.update_icon()
return
else
temp_blood_DNA = drop.return_blood_DNA() //we transfer the dna from the drip to the splatter
temp_blood_DNA = list()
temp_blood_DNA |= drop.blood_DNA.Copy() //we transfer the dna from the drip to the splatter
qdel(drop)//the drip is replaced by a bigger splatter
else
drop = new(T, get_static_viruses())
drop.transfer_mob_blood_dna(src)
drop.update_icon()
return
// Find a blood decal or create a new one.
var/obj/effect/decal/cleanable/blood/B = locate() in T
var/obj/effect/decal/cleanable/blood/splats/B = locate() in T
if(!B)
B = new /obj/effect/decal/cleanable/blood/splatter(T, get_static_viruses())
if (B.bloodiness < MAX_SHOE_BLOODINESS) //add more blood, up to a limit
B = new /obj/effect/decal/cleanable/blood/splats(T, get_static_viruses())
if(B.bloodiness < MAX_SHOE_BLOODINESS) //add more blood, up to a limit
B.bloodiness += BLOOD_AMOUNT_PER_DECAL
B.transfer_mob_blood_dna(src) //give blood info to the blood decal.
if(temp_blood_DNA)
B.add_blood_DNA(temp_blood_DNA)
B.blood_DNA |= temp_blood_DNA
/mob/living/carbon/human/add_splatter_floor(turf/T, small_drip)
if(!(NOBLOOD in dna.species.species_traits))
@@ -306,10 +312,10 @@
/mob/living/carbon/alien/add_splatter_floor(turf/T, small_drip)
if(!T)
T = get_turf(src)
var/obj/effect/decal/cleanable/xenoblood/B = locate() in T.contents
var/obj/effect/decal/cleanable/blood/splatter/B = locate() in T.contents
if(!B)
B = new(T)
B.add_blood_DNA(list("UNKNOWN DNA" = "X*"))
B.blood_DNA["UNKNOWN DNA"] = "X*"
/mob/living/silicon/robot/add_splatter_floor(turf/T, small_drip)
if(!T)
@@ -318,6 +324,44 @@
if(!B)
B = new(T)
/mob/living/proc/add_splash_floor(turf/T)
if(get_blood_id() == null)
return
if(!T)
T = get_turf(src)
var/list/temp_blood_DNA
// Find a blood decal or create a new one.
var/obj/effect/decal/cleanable/blood/B = locate() in T
if(!B)
B = new /obj/effect/decal/cleanable/blood/splatter(T, get_static_viruses())
if(B.bloodiness < MAX_SHOE_BLOODINESS) //add more blood, up to a limit
B.bloodiness += BLOOD_AMOUNT_PER_DECAL
B.transfer_mob_blood_dna(src) //give blood info to the blood decal.
src.transfer_blood_to(B, 10) //very heavy bleeding, should logically leave larger pools
if(temp_blood_DNA)
B.blood_DNA |= temp_blood_DNA
/mob/living/carbon/human/add_splash_floor(turf/T)
if(!(NOBLOOD in dna.species.species_traits))
..()
/mob/living/carbon/alien/add_splash_floor(turf/T)
if(!T)
T = get_turf(src)
var/obj/effect/decal/cleanable/blood/splatter/B = locate() in T.contents
if(!B)
B = new(T)
B.blood_DNA["UNKNOWN DNA"] = "X*"
/mob/living/silicon/robot/add_splash_floor(turf/T)
if(!T)
T = get_turf(src)
var/obj/effect/decal/cleanable/oil/B = locate() in T.contents
if(!B)
B = new(T)
//This is a terrible way of handling it.
/mob/living/proc/ResetBloodVol()
if(ishuman(src))
+4 -5
View File
@@ -147,13 +147,12 @@
/mob/living/proc/exit_blood_effect(obj/effect/decal/cleanable/B)
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1)
//Makes the mob have the color of the blood pool it came out of
var/newcolor = rgb(149, 10, 10)
if(istype(B, /obj/effect/decal/cleanable/xenoblood))
newcolor = rgb(43, 186, 0)
var/newcolor = BLOOD_COLOR_HUMAN
if(istype(B, /obj/effect/decal/cleanable/blood/xeno))
newcolor = BLOOD_COLOR_XENO
add_atom_colour(newcolor, TEMPORARY_COLOUR_PRIORITY)
// but only for a few seconds
spawn(30)
remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, newcolor)
addtimer(CALLBACK(src, /atom/.proc/remove_atom_colour, TEMPORARY_COLOUR_PRIORITY, newcolor), 6 SECONDS)
/mob/living/proc/phasein(obj/effect/decal/cleanable/B)
if(src.notransform)
+23 -5
View File
@@ -5,12 +5,16 @@
var/datum/dna/stored/stored_dna // dna var for brain. Used to store dna, brain dna is not considered like actual dna, brain.has_dna() returns FALSE.
stat = DEAD //we start dead by default
see_invisible = SEE_INVISIBLE_LIVING
possible_a_intents = list(INTENT_HELP, INTENT_HARM) //for mechas
speech_span = SPAN_ROBOT
/mob/living/brain/Initialize()
. = ..()
create_dna(src)
stored_dna.initialize_dna(random_blood_type())
if(stored_dna.blood_type)
stored_dna.initialize_dna(stored_dna.blood_type)
else
stored_dna.initialize_dna(random_blood_type())
if(isturf(loc)) //not spawned in an MMI or brain organ (most likely adminspawned)
var/obj/item/organ/brain/OB = new(loc) //we create a new brain organ for it.
OB.brainmob = src
@@ -21,6 +25,8 @@
if(!stored_dna.species)
var/rando_race = pick(GLOB.roundstart_races)
stored_dna.species = new rando_race()
if(stored_dna.species.exotic_bloodtype)
stored_dna.blood_type = stored_dna.species.exotic_bloodtype
/mob/living/brain/Destroy()
if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
@@ -67,10 +73,9 @@
/mob/living/brain/ClickOn(atom/A, params)
..()
if(istype(loc, /obj/item/mmi))
var/obj/item/mmi/MMI = loc
var/obj/mecha/M = MMI.mecha
if((src == MMI.brainmob) && istype(M))
if(container)
var/obj/mecha/M = container.mecha
if(istype(M))
return M.click_action(A,src,params)
/mob/living/brain/forceMove(atom/destination)
@@ -85,3 +90,16 @@
doMove(destination)
else
CRASH("Brainmob without a container [src] attempted to move to [destination].")
/mob/living/brain/update_mouse_pointer()
if (!client)
return
client.mouse_pointer_icon = initial(client.mouse_pointer_icon)
if(!container)
return
if (container.mecha)
var/obj/mecha/M = container.mecha
if(M.mouse_pointer)
client.mouse_pointer_icon = M.mouse_pointer
if (client && ranged_ability && ranged_ability.ranged_mousepointer)
client.mouse_pointer_icon = ranged_ability.ranged_mousepointer
+1 -1
View File
@@ -24,7 +24,7 @@
var/list/datum/brain_trauma/traumas = list()
/obj/item/organ/brain/Insert(mob/living/carbon/C, special = 0,no_id_transfer = FALSE)
/obj/item/organ/brain/Insert(mob/living/carbon/C, special = 0,no_id_transfer = FALSE, drop_if_replaced = TRUE)
..()
name = "brain"
+20 -4
View File
@@ -36,7 +36,7 @@ GLOBAL_VAR(posibrain_notify_cooldown)
/obj/item/mmi/posibrain/proc/ping_ghosts(msg, newlymade)
if(newlymade || GLOB.posibrain_notify_cooldown <= world.time)
notify_ghosts("[name] [msg] in [get_area(src)]!", ghost_sound = !newlymade ? 'sound/misc/server-ready.ogg':null, enter_link = "<a href=?src=[REF(src)];activate=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_POSIBRAIN)
notify_ghosts("[name] [msg] in [get_area(src)]!", ghost_sound = !newlymade ? 'sound/misc/server-ready.ogg':null, enter_link = "<a href=?src=[REF(src)];activate=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_POSIBRAIN, ignore_dnr_observers = TRUE)
if(!newlymade)
GLOB.posibrain_notify_cooldown = world.time + askDelay
@@ -83,15 +83,29 @@ GLOBAL_VAR(posibrain_notify_cooldown)
//Two ways to activate a positronic brain. A clickable link in the ghost notif, or simply clicking the object itself.
/obj/item/mmi/posibrain/proc/activate(mob/user)
if(QDELETED(brainmob))
return
if(is_occupied() || jobban_isbanned(user,"posibrain") || QDELETED(brainmob) || QDELETED(src) || QDELETED(user))
if(QDELETED(brainmob) || is_occupied() || jobban_isbanned(user,"posibrain") || QDELETED(src) || QDELETED(user))
return
if(isobserver(user))
var/mob/dead/observer/O = user
if(!O.can_reenter_round())
return FALSE
var/posi_ask = alert("Become a [name]? (Warning, You can no longer be cloned, and all past lives will be forgotten!)","Are you positive?","Yes","No")
if(posi_ask == "No" || QDELETED(src))
return
transfer_personality(user)
latejoin_remove()
/obj/item/mmi/posibrain/Destroy()
latejoin_remove()
return ..()
/obj/item/mmi/posibrain/proc/latejoin_remove()
GLOB.poi_list -= src
LAZYREMOVE(GLOB.mob_spawners[name], src)
if(!LAZYLEN(GLOB.mob_spawners[name]))
GLOB.mob_spawners -= name
/obj/item/mmi/posibrain/transfer_identity(mob/living/carbon/C)
name = "[initial(name)] ([C])"
@@ -163,6 +177,8 @@ GLOBAL_VAR(posibrain_notify_cooldown)
brainmob.container = src
if(autoping)
ping_ghosts("created", TRUE)
GLOB.poi_list |= src
LAZYADD(GLOB.mob_spawners[name], src)
/obj/item/mmi/posibrain/attackby(obj/item/O, mob/user)
return
@@ -20,7 +20,7 @@
var/heat_protection = 0.5
var/leaping = 0
gib_type = /obj/effect/decal/cleanable/xenoblood/xgibs
gib_type = /obj/effect/decal/cleanable/blood/gibs/xeno
unique_name = 1
var/static/regex/alien_name_regex = new("alien (larva|sentinel|drone|hunter|praetorian|queen)( \\(\\d+\\))?")
@@ -1,8 +1,9 @@
/mob/living/carbon/alien/spawn_gibs(with_bodyparts)
/mob/living/carbon/alien/spawn_gibs(with_bodyparts, atom/loc_override)
var/location = loc_override ? loc_override.drop_location() : drop_location()
if(with_bodyparts)
new /obj/effect/gibspawner/xeno(drop_location())
new /obj/effect/gibspawner/xeno(location, src)
else
new /obj/effect/gibspawner/xenobodypartless(drop_location())
new /obj/effect/gibspawner/xeno/bodypartless(location, src)
/mob/living/carbon/alien/gib_animation()
new /obj/effect/temp_visual/gib_animation(loc, "gibbed-a")
@@ -95,8 +95,14 @@ Doesn't work on other aliens/AI.*/
var/mob/living/M = input("Select who to whisper to:","Whisper to?",null) as null|mob in options
if(!M)
return 0
if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
to_chat(user, "<span class='noticealien'>As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled.</span>")
return FALSE
var/msg = sanitize(input("Message:", "Alien Whisper") as text|null)
if(msg)
if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
to_chat(user, "<span class='notice'>As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled.</span>")
return
log_directed_talk(user, M, msg, LOG_SAY, tag="alien whisper")
to_chat(M, "<span class='noticealien'>You hear a strange, alien voice in your head...</span>[msg]")
to_chat(user, "<span class='noticealien'>You said: \"[msg]\" to [M]</span>")
@@ -6,11 +6,12 @@
update_icons()
/mob/living/carbon/alien/larva/spawn_gibs(with_bodyparts)
/mob/living/carbon/alien/larva/spawn_gibs(with_bodyparts, atom/loc_override)
var/location = loc_override ? loc_override.drop_location() : drop_location()
if(with_bodyparts)
new /obj/effect/gibspawner/larva(drop_location())
new /obj/effect/gibspawner/larva(location, src)
else
new /obj/effect/gibspawner/larvabodypartless(drop_location())
new /obj/effect/gibspawner/larva/bodypartless(location, src)
/mob/living/carbon/alien/larva/gib_animation()
new /obj/effect/temp_visual/gib_animation(loc, "gibbed-l")
@@ -14,7 +14,7 @@
QDEL_LIST(alien_powers)
return ..()
/obj/item/organ/alien/Insert(mob/living/carbon/M, special = 0)
/obj/item/organ/alien/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
..()
for(var/obj/effect/proc_holder/alien/P in alien_powers)
M.AddAbility(P)
@@ -89,10 +89,12 @@
owner.adjustFireLoss(-heal_amt)
owner.adjustOxyLoss(-heal_amt)
owner.adjustCloneLoss(-heal_amt)
if(owner.blood_volume && (owner.blood_volume < BLOOD_VOLUME_NORMAL))
owner.blood_volume += 5
else
owner.adjustPlasma(plasma_rate * 0.1)
/obj/item/organ/alien/plasmavessel/Insert(mob/living/carbon/M, special = 0)
/obj/item/organ/alien/plasmavessel/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
..()
if(isalien(M))
var/mob/living/carbon/alien/A = M
@@ -115,7 +117,7 @@
var/recent_queen_death = 0 //Indicates if the queen died recently, aliens are heavily weakened while this is active.
alien_powers = list(/obj/effect/proc_holder/alien/whisper)
/obj/item/organ/alien/hivenode/Insert(mob/living/carbon/M, special = 0)
/obj/item/organ/alien/hivenode/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
..()
M.faction |= ROLE_ALIEN
@@ -111,7 +111,7 @@
else //When it is removed via surgery at a late stage, rather than forced.
new_xeno.visible_message("<span class='danger'>[new_xeno] wriggles out of [owner]!</span>", "<span class='userdanger'>You exit [owner], your previous host.</span>")
owner.adjustBruteLoss(40)
owner.cut_overlay(overlay)
owner.cut_overlay(overlay)
qdel(src)
@@ -119,19 +119,19 @@
Proc: AddInfectionImages(C)
Des: Adds the infection image to all aliens for this embryo
----------------------------------------*/
/obj/item/organ/body_egg/alien_embryo/AddInfectionImages()
/obj/item/organ/body_egg/alien_embryo/AddInfectionImages(mob/living/carbon/C)
for(var/mob/living/carbon/alien/alien in GLOB.player_list)
if(alien.client)
var/I = image('icons/mob/alien.dmi', loc = owner, icon_state = "infected[stage]")
var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[stage]")
alien.client.images += I
/*----------------------------------------
Proc: RemoveInfectionImage(C)
Des: Removes all images from the mob infected by this embryo
----------------------------------------*/
/obj/item/organ/body_egg/alien_embryo/RemoveInfectionImages()
/obj/item/organ/body_egg/alien_embryo/RemoveInfectionImages(mob/living/carbon/C)
for(var/mob/living/carbon/alien/alien in GLOB.player_list)
if(alien.client)
for(var/image/I in alien.client.images)
if(dd_hasprefix_case(I.icon_state, "infected") && I.loc == owner)
if(dd_hasprefix_case(I.icon_state, "infected") && I.loc == C)
qdel(I)
+4 -4
View File
@@ -256,7 +256,7 @@
/mob/living/carbon/fall(forced)
loc.handle_fall(src, forced)//it's loc so it doesn't call the mob's handle_fall which does nothing
loc.handle_fall(src, forced)//it's loc so it doesn't call the mob's handle_fall which does nothing
/mob/living/carbon/is_muzzled()
return(istype(src.wear_mask, /obj/item/clothing/mask/muzzle))
@@ -585,7 +585,7 @@
if(!isnull(E.lighting_alpha))
lighting_alpha = E.lighting_alpha
if(client.eye != src)
if(client.eye && client.eye != src)
var/atom/A = client.eye
if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates.
return
@@ -905,7 +905,7 @@
/mob/living/carbon/do_after_coefficent()
. = ..()
GET_COMPONENT_FROM(mood, /datum/component/mood, src) //Currently, only carbons or higher use mood, move this once that changes.
var/datum/component/mood/mood = src.GetComponent(/datum/component/mood) //Currently, only carbons or higher use mood, move this once that changes.
if(mood)
switch(mood.sanity) //Alters do_after delay based on how sane you are
if(SANITY_INSANE to SANITY_DISTURBED)
@@ -947,7 +947,7 @@
return TRUE
if(HAS_TRAIT(src, TRAIT_DUMB))
return TRUE
GET_COMPONENT_FROM(mood, /datum/component/mood, src)
var/datum/component/mood/mood = src.GetComponent(/datum/component/mood)
if(mood)
if(mood.sanity < SANITY_UNSTABLE)
return TRUE
@@ -287,7 +287,7 @@
"<span class='notice'>You give [H] a pat on the head to make [p_them()] feel better!</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "headpat", /datum/mood_event/headpat)
if(HAS_TRAIT(M, TRAIT_FRIENDLY))
GET_COMPONENT_FROM(mood, /datum/component/mood, M)
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
if (mood.sanity >= SANITY_GREAT)
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/besthug, M)
else if (mood.sanity >= SANITY_DISTURBED)
@@ -322,7 +322,7 @@
"<span class='notice'>You hug [src] to make [p_them()] feel better!</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "hug", /datum/mood_event/hug)
if(HAS_TRAIT(M, TRAIT_FRIENDLY))
GET_COMPONENT_FROM(mood, /datum/component/mood, M)
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
if (mood.sanity >= SANITY_GREAT)
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/besthug, M)
else if (mood.sanity >= SANITY_DISTURBED)
@@ -49,6 +49,7 @@
//Gets filled up in create_bodyparts()
var/list/hand_bodyparts = list() //a collection of arms (or actually whatever the fug /bodyparts you monsters use to wreck my systems)
var/list/leg_bodyparts = list()
var/icon_render_key = ""
var/static/list/limb_icon_cache = list()
@@ -36,7 +36,7 @@
/mob/living/carbon/Move(NewLoc, direct)
. = ..()
if(. && mob_has_gravity()) //floating is easy
if(. && (movement_type & FLOATING)) //floating is easy
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
nutrition = NUTRITION_LEVEL_FED - 1 //just less than feeling vigorous
else if(nutrition && stat != DEAD)
+14 -13
View File
@@ -1,8 +1,8 @@
/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE)
/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
var/hit_percent = (100-blocked)/100
if(hit_percent <= 0)
if(!forced && hit_percent <= 0)
return 0
var/obj/item/bodypart/BP = null
@@ -15,34 +15,35 @@
if(!BP)
BP = bodyparts[1]
var/damage_amount = forced ? damage : damage * hit_percent
switch(damagetype)
if(BRUTE)
if(BP)
if(damage > 0 ? BP.receive_damage(damage * hit_percent, 0) : BP.heal_damage(abs(damage * hit_percent), 0))
if(damage > 0 ? BP.receive_damage(damage_amount) : BP.heal_damage(abs(damage_amount), 0))
update_damage_overlays()
else //no bodypart, we deal damage with a more general method.
adjustBruteLoss(damage * hit_percent)
adjustBruteLoss(damage_amount, forced = forced)
if(BURN)
if(BP)
if(damage > 0 ? BP.receive_damage(0, damage * hit_percent) : BP.heal_damage(0, abs(damage * hit_percent)))
if(damage > 0 ? BP.receive_damage(0, damage_amount) : BP.heal_damage(0, abs(damage_amount)))
update_damage_overlays()
else
adjustFireLoss(damage * hit_percent)
adjustFireLoss(damage_amount, forced = forced)
if(TOX)
adjustToxLoss(damage * hit_percent)
adjustToxLoss(damage_amount, forced = forced)
if(OXY)
adjustOxyLoss(damage * hit_percent)
adjustOxyLoss(damage_amount, forced = forced)
if(CLONE)
adjustCloneLoss(damage * hit_percent)
adjustCloneLoss(damage_amount, forced = forced)
if(STAMINA)
if(BP)
if(damage > 0 ? BP.receive_damage(0, 0, damage * hit_percent) : BP.heal_damage(0, 0, abs(damage * hit_percent)))
if(damage > 0 ? BP.receive_damage(0, 0, damage_amount) : BP.heal_damage(0, 0, abs(damage_amount)))
update_damage_overlays()
else
adjustStaminaLoss(damage * hit_percent)
adjustStaminaLoss(damage_amount, forced = forced)
//citadel code
if(AROUSAL)
adjustArousalLoss(damage * hit_percent)
adjustArousalLoss(damage_amount, forced = forced)
return TRUE
@@ -85,7 +86,7 @@
if(!forced && HAS_TRAIT(src, TRAIT_TOXINLOVER)) //damage becomes healing and healing becomes damage
amount = -amount
if(amount > 0)
blood_volume -= 5*amount
blood_volume -= 3*amount // x5 is too much, x3 should be still penalizing enough.
else
blood_volume -= amount
return ..()
+3 -3
View File
@@ -31,9 +31,9 @@
if (!user.get_bodypart(BODY_ZONE_L_ARM) || !user.get_bodypart(BODY_ZONE_R_ARM))
return
var/clap = pick('sound/misc/clap1.ogg',
'sound/misc/clap2.ogg',
'sound/misc/clap3.ogg',
'sound/misc/clap4.ogg')
'sound/misc/clap2.ogg',
'sound/misc/clap3.ogg',
'sound/misc/clap4.ogg')
playsound(user, clap, 50, 1, -1)
/datum/emote/living/carbon/gnarl
+2 -1
View File
@@ -91,8 +91,9 @@
if(combatmode)
msg += "[t_He] [t_is] visibly tense[resting ? "." : ", and [t_is] standing in combative stance."]\n"
msg += common_trait_examine()
GET_COMPONENT_FROM(mood, /datum/component/mood, src)
var/datum/component/mood/mood = src.GetComponent(/datum/component/mood)
if(mood)
switch(mood.shown_mood)
if(-INFINITY to MOOD_LEVEL_SAD4)
@@ -1,5 +1,5 @@
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE)
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
// depending on the species, it will run the corresponding apply_damage code there
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src)
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced)
+21 -6
View File
@@ -4,11 +4,21 @@
/mob/living/carbon/human/dust_animation()
new /obj/effect/temp_visual/dust_animation(loc, "dust-h")
/mob/living/carbon/human/spawn_gibs(with_bodyparts)
if(with_bodyparts)
new /obj/effect/gibspawner/human(drop_location(), dna, get_static_viruses())
/mob/living/carbon/human/spawn_gibs(with_bodyparts, atom/loc_override)
var/location = loc_override ? loc_override.drop_location() : drop_location()
if(dna?.species?.gib_types)
var/datum/species/S = dna.species
var/length = length(S.gib_types)
if(length)
var/path = (with_bodyparts && length > 1) ? S.gib_types[2] : S.gib_types[1]
new path(location, src, get_static_viruses())
else
new S.gib_types(location, src, get_static_viruses())
else
new /obj/effect/gibspawner/humanbodypartless(drop_location(), dna, get_static_viruses())
if(with_bodyparts)
new /obj/effect/gibspawner/human(location, src, get_static_viruses())
else
new /obj/effect/gibspawner/human/bodypartless(location, src, get_static_viruses())
/mob/living/carbon/human/spawn_dust(just_ash = FALSE)
if(just_ash)
@@ -44,11 +54,16 @@
/mob/living/carbon/human/proc/makeSkeleton()
ADD_TRAIT(src, TRAIT_DISFIGURED, TRAIT_GENERIC)
set_species(/datum/species/skeleton)
return 1
return TRUE
/mob/living/carbon/proc/Drain()
become_husk(CHANGELING_DRAIN)
ADD_TRAIT(src, TRAIT_NOCLONE, CHANGELING_DRAIN)
blood_volume = 0
return 1
return TRUE
/mob/living/carbon/proc/makeUncloneable()
ADD_TRAIT(src, TRAIT_NOCLONE, MADE_UNCLONEABLE)
blood_volume = 0
return TRUE
@@ -4,6 +4,7 @@
status_flags = GODMODE|CANPUSH
mouse_drag_pointer = MOUSE_INACTIVE_POINTER
var/in_use = FALSE
no_vore = TRUE
INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
@@ -1,4 +1,4 @@
/mob/living/carbon/human/examine(mob/user) //User is the person being examined
/mob/living/carbon/human/examine(mob/user)
//this is very slightly better than it was because you can use it more places. still can't do \his[src] though.
var/t_He = p_they(TRUE)
var/t_His = p_their(TRUE)
@@ -45,7 +45,7 @@
if(wear_suit)
msg += "[t_He] [t_is] wearing [wear_suit.get_examine_string(user)].\n"
//suit/armor storage
if(s_store)
if(s_store && !(SLOT_S_STORE in obscured))
msg += "[t_He] [t_is] carrying [s_store.get_examine_string(user)] on [t_his] [wear_suit.name].\n"
//back
if(back)
@@ -56,11 +56,10 @@
if(!(I.item_flags & ABSTRACT))
msg += "[t_He] [t_is] holding [I.get_examine_string(user)] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
GET_COMPONENT(FR, /datum/component/forensics)
//gloves
if(gloves && !(SLOT_GLOVES in obscured))
msg += "[t_He] [t_has] [gloves.get_examine_string(user)] on [t_his] hands.\n"
else if(FR && length(FR.blood_DNA))
else if(length(blood_DNA))
var/hand_number = get_num_arms(FALSE)
if(hand_number)
msg += "<span class='warning'>[t_He] [t_has] [hand_number > 1 ? "" : "a"] blood-stained hand[hand_number > 1 ? "s" : ""]!</span>\n"
@@ -86,7 +85,7 @@
if(wear_mask && !(SLOT_WEAR_MASK in obscured))
msg += "[t_He] [t_has] [wear_mask.get_examine_string(user)] on [t_his] face.\n"
if (wear_neck && !(SLOT_NECK in obscured))
if(wear_neck && !(SLOT_NECK in obscured))
msg += "[t_He] [t_is] wearing [wear_neck.get_examine_string(user)] around [t_his] neck.\n"
//eyes
@@ -152,7 +151,7 @@
var/temp = getBruteLoss() //no need to calculate each of these twice
msg += "<span class='warning'>"
msg += "<span class='warning'>" //Everything below gets this span
var/list/missing = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
var/list/disabled = list()
@@ -297,7 +296,7 @@
msg += "[t_He] seem[p_s()] winded.\n"
if (getToxLoss() >= 10)
msg += "[t_He] seem[p_s()] sickly.\n"
GET_COMPONENT_FROM(mood, /datum/component/mood, src)
var/datum/component/mood/mood = src.GetComponent(/datum/component/mood)
if(mood.sanity <= SANITY_DISTURBED)
msg += "[t_He] seem[p_s()] distressed.\n"
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "empath", /datum/mood_event/sad_empath, src)
@@ -335,6 +334,8 @@
if(digitalcamo)
msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly inhuman manner.\n"
msg += common_trait_examine()
var/traitstring = get_trait_string()
if(ishuman(user))
var/mob/living/carbon/human/H = user
+29 -13
View File
@@ -32,7 +32,7 @@
if(CONFIG_GET(flag/disable_stambuffer))
togglesprint()
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood)))
RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /mob/living/carbon/human/clean_blood)
/mob/living/carbon/human/ComponentInitialize()
@@ -488,7 +488,7 @@
var/counter = 1
while(R.fields[text("com_[]", counter)])
counter++
R.fields[text("com_[]", counter)] = text("Made by [] on [] [], []<BR>[]", allowed_access, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer+540, t1)
R.fields[text("com_[]", counter)] = text("Made by [] on [] [], []<BR>[]", allowed_access, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1)
to_chat(usr, "<span class='notice'>Successfully added comment.</span>")
return
to_chat(usr, "<span class='warning'>Unable to locate a data core entry for this person.</span>")
@@ -574,7 +574,7 @@
return threatcount
//Check for ID
var/obj/item/card/id/idcard = get_idcard()
var/obj/item/card/id/idcard = get_idcard(FALSE)
if( (judgement_criteria & JUDGE_IDCHECK) && !idcard && name=="Unknown")
threatcount += 4
@@ -689,16 +689,17 @@
if(..())
dropItemToGround(I)
/mob/living/carbon/human/proc/clean_blood(datum/source, strength)
if(strength < CLEAN_STRENGTH_BLOOD)
return
if(gloves)
if(SEND_SIGNAL(gloves, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
update_inv_gloves()
/mob/living/carbon/human/clean_blood()
var/mob/living/carbon/human/H = src
if(H.gloves)
if(H.gloves.clean_blood())
H.update_inv_gloves()
else
if(bloody_hands)
bloody_hands = 0
update_inv_gloves()
..() // Clear the Blood_DNA list
if(H.bloody_hands)
H.bloody_hands = 0
H.update_inv_gloves()
update_icons() //apply the now updated overlays to the mob
/mob/living/carbon/human/wash_cream()
if(creamed) //clean both to prevent a rare bug
@@ -945,7 +946,7 @@
return FALSE
/mob/living/carbon/human/proc/clear_shove_slowdown()
remove_movespeed_modifier(SHOVE_SLOWDOWN_ID)
remove_movespeed_modifier(MOVESPEED_ID_SHOVE)
var/active_item = get_active_held_item()
if(is_type_in_typecache(active_item, GLOB.shove_disarming_types))
visible_message("<span class='warning'>[src.name] regains their grip on \the [active_item]!</span>", "<span class='warning'>You regain your grip on \the [active_item]</span>", null, COMBAT_MESSAGE_RANGE)
@@ -1104,3 +1105,18 @@
/mob/living/carbon/human/species/zombie/krokodil_addict
race = /datum/species/krokodil_addict
/mob/living/carbon/human/species/mammal
race = /datum/species/mammal
/mob/living/carbon/human/species/insect
race = /datum/species/insect
/mob/living/carbon/human/species/xeno
race = /datum/species/xeno
/mob/living/carbon/human/species/ipc
race = /datum/species/ipc
/mob/living/carbon/human/species/roundstartslime
race = /datum/species/jelly/roundstartslime
@@ -778,7 +778,7 @@
broken_plural = TRUE
else
var/holder = broken[1] //our one and only element
if(holder[lentext(holder)] == "s")
if(holder[length(holder)] == "s")
broken_plural = TRUE
//Put the items in that list into a string of text
for(var/B in broken)
@@ -790,7 +790,7 @@
damaged_plural = TRUE
else
var/holder = damaged[1]
if(holder[lentext(holder)] == "s")
if(holder[length(holder)] == "s")
damaged_plural = TRUE
for(var/D in damaged)
damaged_message += D
@@ -19,6 +19,8 @@
var/horn_color = "85615a" //specific horn colors, because why not?
var/wing_color = "fff" //wings too
var/skin_tone = "caucasian1" //Skin tone
var/lip_style = null //no lipstick by default- arguably misleading, as it could be used for general makeup
@@ -49,6 +51,9 @@
var/bleed_rate = 0 //how much are we bleeding
var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding
var/blood_state = BLOOD_STATE_NOT_BLOODY
var/list/blood_smear = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
var/name_override //For temporary visible name changes
var/genital_override = FALSE //Force genitals on things incase of chems
@@ -11,8 +11,8 @@
//gets assignment from ID or ID inside PDA or PDA itself
//Useful when player do something with computers
/mob/living/carbon/human/proc/get_assignment(if_no_id = "No id", if_no_job = "No job")
var/obj/item/card/id/id = get_idcard()
/mob/living/carbon/human/proc/get_assignment(if_no_id = "No id", if_no_job = "No job", hand_first = TRUE)
var/obj/item/card/id/id = get_idcard(hand_first)
if(id)
. = id.assignment
else
@@ -27,7 +27,7 @@
//gets name from ID or ID inside PDA or PDA itself
//Useful when player do something with computers
/mob/living/carbon/human/proc/get_authentification_name(if_no_id = "Unknown")
var/obj/item/card/id/id = get_idcard()
var/obj/item/card/id/id = get_idcard(FALSE)
if(id)
return id.registered_name
var/obj/item/pda/pda = wear_id
@@ -86,10 +86,15 @@
return
//gets ID card object from special clothes slot or null.
/mob/living/carbon/human/get_idcard()
if(wear_id)
return wear_id.GetID()
/mob/living/carbon/human/get_idcard(hand_first = TRUE)
. = ..()
if(. && hand_first)
return
//Check inventory slots
var/obj/item/card/id/id_card = wear_id?.GetID()
if(!id_card)
id_card = belt?.GetID()
return id_card || .
/mob/living/carbon/human/IsAdvancedToolUser()
if(HAS_TRAIT(src, TRAIT_MONKEYLIKE))
@@ -100,7 +105,6 @@
return dna.species.handle_chemicals(R,src)
// if it returns 0, it will run the usual on_mob_life for that reagent. otherwise, it will stop after running handle_chemicals for the species.
/mob/living/carbon/human/can_track(mob/living/user)
if(wear_id && istype(wear_id.GetID(), /obj/item/card/id/syndicate))
return 0
@@ -127,3 +131,9 @@
return FALSE
return .
/*
/mob/living/carbon/human/transfer_blood_dna(list/blood_dna)
..()
if(blood_dna.len)
last_bloodtype = blood_dna[blood_dna[blood_dna.len]]//trust me this works
last_blood_DNA = blood_dna[blood_dna.len]*/
@@ -56,20 +56,20 @@
//Bloody footprints
var/turf/T = get_turf(src)
if(S.bloody_shoes && S.bloody_shoes[S.blood_state])
for(var/obj/effect/decal/cleanable/blood/footprints/oldFP in T)
if (oldFP.blood_state == S.blood_state)
return
//No oldFP or they're all a different kind of blood
S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state] - BLOOD_LOSS_PER_STEP)
if (S.bloody_shoes[S.blood_state] > BLOOD_LOSS_IN_SPREAD)
var/obj/effect/decal/cleanable/blood/footprints/FP = new /obj/effect/decal/cleanable/blood/footprints(T)
FP.blood_state = S.blood_state
FP.entered_dirs |= dir
FP.bloodiness = S.bloody_shoes[S.blood_state] - BLOOD_LOSS_IN_SPREAD
FP.add_blood_DNA(S.return_blood_DNA())
FP.update_icon()
var/obj/effect/decal/cleanable/blood/footprints/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints) in T
if(oldFP && (oldFP.blood_state == S.blood_state && oldFP.color == bloodtype_to_color(S.last_bloodtype)))
return
S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state]-BLOOD_LOSS_PER_STEP)
var/obj/effect/decal/cleanable/blood/footprints/FP = new /obj/effect/decal/cleanable/blood/footprints(T)
FP.blood_state = S.blood_state
FP.entered_dirs |= dir
FP.bloodiness = S.bloody_shoes[S.blood_state]
if(S.last_bloodtype)
FP.blood_DNA += list(S.last_blood_DNA = S.last_bloodtype)
FP.update_icon()
update_inv_shoes()
//End bloody footprints
S.step_action()
/mob/living/carbon/human/Process_Spacemove(movement_dir = 0) //Temporary laziness thing. Will change to handles by species reee.
@@ -79,7 +79,8 @@
//This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible()
/mob/living/carbon/human/equip_to_slot(obj/item/I, slot)
if(!..()) //a check failed or the item has already found its slot
. = ..()
if(!.) //a check failed or the item has already found its slot
return
var/not_handled = FALSE //Added in case we make this type path deeper one day
@@ -136,6 +137,7 @@
update_inv_s_store()
else
to_chat(src, "<span class='danger'>You are trying to equip this item to an unsupported inventory slot. Report this to a coder!</span>")
not_handled = TRUE
//Item is handled and in slot, valid to call callback, for this proc should always be true
if(!not_handled)
+45 -51
View File
@@ -3,7 +3,7 @@
//NOTE: Breathing happens once per FOUR TICKS, unless the last breath fails. In which case it happens once per ONE TICK! So oxyloss healing is done once per 4 ticks while oxyloss damage is applied once per tick!
// bitflags for the percentual amount of protection a piece of clothing which covers the body part offers.
// Used with human/proc/get_heat_protection() and human/proc/get_cold_protection()
// Used with human/proc/get_thermal_protection()
// The values here should add up to 1.
// Hands and feet have 2.5%, arms and legs 7.5%, each of the torso parts has 15% and the head has 30%
#define THERMAL_PROTECTION_HEAD 0.3
@@ -18,7 +18,7 @@
#define THERMAL_PROTECTION_HAND_LEFT 0.025
#define THERMAL_PROTECTION_HAND_RIGHT 0.025
/mob/living/carbon/human/Life()
/mob/living/carbon/human/Life(seconds, times_fired)
set invisibility = 0
if (notransform)
return
@@ -41,7 +41,7 @@
if(stat != DEAD)
//process your dick energy
handle_arousal()
handle_arousal(times_fired)
//Update our name based on whether our face is obscured/disfigured
name = get_visible_name()
@@ -53,16 +53,17 @@
/mob/living/carbon/human/calculate_affecting_pressure(pressure)
if (wear_suit && head && istype(wear_suit, /obj/item/clothing) && istype(head, /obj/item/clothing))
var/headless = !get_bodypart(BODY_ZONE_HEAD) //should the mob be perennially headless (see dullahans), we only take the suit into account, so they can into space.
if (wear_suit && istype(wear_suit, /obj/item/clothing) && (headless || (head && istype(head, /obj/item/clothing))))
var/obj/item/clothing/CS = wear_suit
var/obj/item/clothing/CH = head
if (CS.clothing_flags & CH.clothing_flags & STOPSPRESSUREDAMAGE)
if (CS.clothing_flags & STOPSPRESSUREDAMAGE && (headless || (CH.clothing_flags & STOPSPRESSUREDAMAGE)))
return ONE_ATMOSPHERE
if(isbelly(loc)) //START OF CIT CHANGES - Makes it so you don't suffocate while inside vore organs. Remind me to modularize this some time - Bhijn
return ONE_ATMOSPHERE
if(istype(loc, /obj/item/dogborg/sleeper))
return ONE_ATMOSPHERE //END OF CIT CHANGES
return pressure
return ..()
/mob/living/carbon/human/handle_traits()
@@ -136,7 +137,7 @@
if(dna)
dna.species.handle_fire(src)
/mob/living/carbon/human/proc/get_thermal_protection()
/mob/living/carbon/human/proc/easy_thermal_protection()
var/thermal_protection = 0 //Simple check to estimate how protected we are against multiple temperatures
//CITADEL EDIT Vore code required overrides
if(istype(loc, /obj/item/dogborg/sleeper))
@@ -168,7 +169,6 @@
..()
//END FIRE CODE
//This proc returns a number made up of the flags for body parts which you are protected on. (such as HEAD, CHEST, GROIN, etc. See setup.dm for the full list)
/mob/living/carbon/human/proc/get_heat_protection_flags(temperature) //Temperature is the temperature you're being exposed to.
var/thermal_protection_flags = 0
@@ -194,37 +194,6 @@
return thermal_protection_flags
/mob/living/carbon/human/proc/get_heat_protection(temperature) //Temperature is the temperature you're being exposed to.
var/thermal_protection_flags = get_heat_protection_flags(temperature)
var/thermal_protection = 0
if(thermal_protection_flags)
if(thermal_protection_flags & HEAD)
thermal_protection += THERMAL_PROTECTION_HEAD
if(thermal_protection_flags & CHEST)
thermal_protection += THERMAL_PROTECTION_CHEST
if(thermal_protection_flags & GROIN)
thermal_protection += THERMAL_PROTECTION_GROIN
if(thermal_protection_flags & LEG_LEFT)
thermal_protection += THERMAL_PROTECTION_LEG_LEFT
if(thermal_protection_flags & LEG_RIGHT)
thermal_protection += THERMAL_PROTECTION_LEG_RIGHT
if(thermal_protection_flags & FOOT_LEFT)
thermal_protection += THERMAL_PROTECTION_FOOT_LEFT
if(thermal_protection_flags & FOOT_RIGHT)
thermal_protection += THERMAL_PROTECTION_FOOT_RIGHT
if(thermal_protection_flags & ARM_LEFT)
thermal_protection += THERMAL_PROTECTION_ARM_LEFT
if(thermal_protection_flags & ARM_RIGHT)
thermal_protection += THERMAL_PROTECTION_ARM_RIGHT
if(thermal_protection_flags & HAND_LEFT)
thermal_protection += THERMAL_PROTECTION_HAND_LEFT
if(thermal_protection_flags & HAND_RIGHT)
thermal_protection += THERMAL_PROTECTION_HAND_RIGHT
return min(1,thermal_protection)
//See proc/get_heat_protection_flags(temperature) for the description of this proc.
/mob/living/carbon/human/proc/get_cold_protection_flags(temperature)
var/thermal_protection_flags = 0
@@ -251,17 +220,42 @@
return thermal_protection_flags
/mob/living/carbon/human/proc/get_cold_protection(temperature)
//CITADEL EDIT Mandatory for vore code.
if(istype(loc, /obj/item/dogborg/sleeper))
return TRUE //freezing to death in sleepers ruins fun.
if(isbelly(loc))
return TRUE
if(ismob(loc))
return TRUE //because lazy and being inside somemone insulates you from space
//END EDIT
temperature = max(temperature, 2.7) //There is an occasional bug where the temperature is miscalculated in ares with a small amount of gas on them, so this is necessary to ensure that that bug does not affect this calculation. Space's temperature is 2.7K and most suits that are intended to protect against any cold, protect down to 2.0K.
var/thermal_protection_flags = get_cold_protection_flags(temperature)
/mob/living/carbon/human/proc/get_thermal_protection(temperature, cold = FALSE)
if(cold)
//CITADEL EDIT Mandatory for vore code.
if(istype(loc, /obj/item/dogborg/sleeper) || isbelly(loc) || ismob(loc))
return 1 //freezing to death in sleepers ruins fun.
//END EDIT
temperature = max(temperature, 2.7) //There is an occasional bug where the temperature is miscalculated in ares with a small amount of gas on them, so this is necessary to ensure that that bug does not affect this calculation. Space's temperature is 2.7K and most suits that are intended to protect against any cold, protect down to 2.0K.
var/thermal_protection_flags = cold ? get_cold_protection_flags(temperature) : get_heat_protection_flags(temperature)
var/missing_body_parts_flags = ~get_body_parts_flags()
var/max_protection = 1
if(missing_body_parts_flags) //I don't like copypasta as much as proc overhead. Do you want me to make these into a macro?
DISABLE_BITFIELD(thermal_protection_flags, missing_body_parts_flags)
if(missing_body_parts_flags & HEAD)
max_protection -= THERMAL_PROTECTION_HEAD
if(missing_body_parts_flags & CHEST)
max_protection -= THERMAL_PROTECTION_CHEST
if(missing_body_parts_flags & GROIN)
max_protection -= THERMAL_PROTECTION_GROIN
if(missing_body_parts_flags & LEG_LEFT)
max_protection -= THERMAL_PROTECTION_LEG_LEFT
if(missing_body_parts_flags & LEG_RIGHT)
max_protection -= THERMAL_PROTECTION_LEG_RIGHT
if(missing_body_parts_flags & FOOT_LEFT)
max_protection -= THERMAL_PROTECTION_FOOT_LEFT
if(missing_body_parts_flags & FOOT_RIGHT)
max_protection -= THERMAL_PROTECTION_FOOT_RIGHT
if(missing_body_parts_flags & ARM_LEFT)
max_protection -= THERMAL_PROTECTION_ARM_LEFT
if(missing_body_parts_flags & ARM_RIGHT)
max_protection -= THERMAL_PROTECTION_ARM_RIGHT
if(missing_body_parts_flags & HAND_LEFT)
max_protection -= THERMAL_PROTECTION_HAND_LEFT
if(missing_body_parts_flags & HAND_RIGHT)
max_protection -= THERMAL_PROTECTION_HAND_RIGHT
if(max_protection == 0) //Is it even a man if it doesn't have a body at all? Early return to avoid division by zero.
return 1
var/thermal_protection = 0
if(thermal_protection_flags)
@@ -288,7 +282,7 @@
if(thermal_protection_flags & HAND_RIGHT)
thermal_protection += THERMAL_PROTECTION_HAND_RIGHT
return min(1,thermal_protection)
return round(thermal_protection/max_protection, 0.001)
/mob/living/carbon/human/handle_random_events()
//Puke if toxloss is too high
@@ -21,8 +21,6 @@
var/bleed_mod = 1 // % bleeding modifier
var/datum/armor/armor // internal armor datum
var/speed_mod = 0 //tick modifier for each step. Positive is slower, negative is faster.
var/hunger_mod = 1 //% of hunger rate taken per tick.
var/do_after_speed = 1 //Speed mod for do_after. Lower is better. If temporarily adjusting, please only modify using *= and /=, so you don't interrupt other calculations.
+9 -9
View File
@@ -1,14 +1,14 @@
/mob/living/carbon/human/say_mod(input, message_mode)
verb_say = dna.species.say_mod
switch(slurring)
if(10 to 25)
return "jumbles"
if(25 to 50)
return "slurs"
if(50 to INFINITY)
return "garbles"
else
. = ..()
. = ..()
if(message_mode != MODE_CUSTOM_SAY && message_mode != MODE_WHISPER_CRIT)
switch(slurring)
if(10 to 25)
return "jumbles"
if(25 to 50)
return "slurs"
if(50 to INFINITY)
return "garbles"
/mob/living/carbon/human/GetVoice()
if(istype(wear_mask, /obj/item/clothing/mask/chameleon))
+59 -60
View File
@@ -37,11 +37,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/hair_alpha = 255 // the alpha used by the hair. 255 is completely solid, 0 is transparent.
var/horn_color //specific horn colors, because why not?
var/wing_color
var/use_skintones = 0 // does it use skintones or not? (spoiler alert this is only used by humans)
var/exotic_blood = "" // If your race wants to bleed something other than bog standard blood, change this to reagent id.
var/exotic_bloodtype = "" //If your race uses a non standard bloodtype (A+, O-, AB-, etc)
var/meat = /obj/item/reagent_containers/food/snacks/meat/slab/human //What the species drops on gibbing
var/list/gib_types = list(/obj/effect/gibspawner/human, /obj/effect/gibspawner/human/bodypartless)
var/skinned_type
var/liked_food = NONE
var/disliked_food = GROSS
@@ -80,7 +82,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/sound/attack_sound = 'sound/weapons/punch1.ogg'
var/sound/miss_sound = 'sound/weapons/punchmiss.ogg'
var/mob/living/list/ignored_by = list() // list of mobs that will ignore this species
var/list/mob/living/ignored_by = list() // list of mobs that will ignore this species
//Breathing!
var/obj/item/organ/lungs/mutantlungs = null
var/breathid = "o2"
@@ -331,6 +333,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if("meat_type" in default_features) //I can't believe it's come to the meat
H.type_of_meat = GLOB.meat_types[H.dna.features["meat_type"]]
C.add_movespeed_modifier(MOVESPEED_ID_SPECIES, TRUE, 100, override=TRUE, multiplicative_slowdown=speedmod, movetypes=(~FLYING))
SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species)
@@ -338,12 +342,17 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
/datum/species/proc/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
if(C.dna.species.exotic_bloodtype)
C.dna.blood_type = random_blood_type()
if(!new_species.exotic_bloodtype)
C.dna.blood_type = random_blood_type()
else
C.dna.blood_type = new_species.exotic_bloodtype
if(DIGITIGRADE in species_traits)
C.Digitigrade_Leg_Swap(TRUE)
for(var/X in inherent_traits)
REMOVE_TRAIT(C, X, SPECIES_TRAIT)
C.remove_movespeed_modifier(MOVESPEED_ID_SPECIES)
if("meat_type" in default_features)
C.type_of_meat = GLOB.meat_types[C.dna.features["meat_type"]]
else
@@ -537,7 +546,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(H.hidden_underwear)
H.underwear = "Nude"
else
H.saved_underwear = H.underwear
H.underwear = H.saved_underwear
var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[H.underwear]
if(B)
var/mutable_appearance/MA = mutable_appearance(B.icon, B.icon_state, -BODY_LAYER)
@@ -549,7 +558,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(H.hidden_undershirt)
H.undershirt = "Nude"
else
H.saved_undershirt = H.undershirt
H.undershirt = H.saved_undershirt
var/datum/sprite_accessory/underwear/top/T = GLOB.undershirt_list[H.undershirt]
if(T)
var/mutable_appearance/MA
@@ -565,7 +574,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(H.hidden_socks)
H.socks = "Nude"
else
H.saved_socks = H.socks
H.socks = H.saved_socks
var/datum/sprite_accessory/underwear/socks/S = GLOB.socks_list[H.socks]
if(S)
var/digilegs = (DIGITIGRADE in species_traits) ? "_d" : ""
@@ -869,6 +878,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
accessory_overlay.color = "#[H.eye_color]"
if(HORNCOLOR)
accessory_overlay.color = "#[H.horn_color]"
if(WINGCOLOR)
accessory_overlay.color = "#[H.wing_color]"
else
accessory_overlay.color = forced_colour
else
@@ -946,6 +957,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(HORNCOLOR)
extra_accessory_overlay.color = "#[H.horn_color]"
if(WINGCOLOR)
extra_accessory_overlay.color = "#[H.wing_color]"
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
extra_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
@@ -985,6 +998,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
extra2_accessory_overlay.color = "#[H.hair_color]"
if(HORNCOLOR)
extra2_accessory_overlay.color = "#[H.horn_color]"
if(WINGCOLOR)
extra2_accessory_overlay.color = "#[H.wing_color]"
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
extra2_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
@@ -1017,6 +1032,16 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
return "TAUR"
//END EDIT
/* TODO: Snowflake trail marks
// Impliments different trails for species depending on if they're wearing shoes.
/datum/species/proc/get_move_trail(var/mob/living/carbon/human/H)
if(H.lying)
return /obj/effect/decal/cleanable/blood/footprints/tracks/body
if(H.shoes || (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)))
var/obj/item/clothing/shoes/shoes = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) ? H.wear_suit : H.shoes // suits take priority over shoes
return shoes.move_trail
else
return move_trail */
/datum/species/proc/spec_life(mob/living/carbon/human/H)
if(HAS_TRAIT(H, TRAIT_NOBREATH))
@@ -1270,7 +1295,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if (H.nutrition > 0 && H.stat != DEAD && !HAS_TRAIT(H, TRAIT_NOHUNGER))
// THEY HUNGER
var/hunger_rate = HUNGER_FACTOR
GET_COMPONENT_FROM(mood, /datum/component/mood, H)
var/datum/component/mood/mood = H.GetComponent(/datum/component/mood)
if(mood && mood.sanity > SANITY_DISTURBED)
hunger_rate *= max(0.5, 1 - 0.002 * mood.sanity) //0.85 to 0.75
@@ -1369,39 +1394,16 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
/datum/species/proc/movement_delay(mob/living/carbon/human/H)
. = 0 //We start at 0.
var/flight = 0 //Check for flight and flying items
var/ignoreslow = 0
var/gravity = 0
if(H.movement_type & FLYING)
flight = 1
gravity = H.has_gravity()
if(gravity && !flight) //Check for chemicals and innate speedups and slowdowns if we're on the ground
if(HAS_TRAIT(H, TRAIT_GOTTAGOFAST))
. -= 1
if(HAS_TRAIT(H, TRAIT_GOTTAGOREALLYFAST))
. -= 2
. += speedmod
. += H.physiology.speed_mod
if (H.m_intent == MOVE_INTENT_WALK && HAS_TRAIT(H, TRAIT_SPEEDY_STEP))
. -= 1.5
if(HAS_TRAIT(H, TRAIT_IGNORESLOWDOWN))
ignoreslow = 1
if(!gravity)
var/obj/item/tank/jetpack/J = H.back
var/obj/item/clothing/suit/space/hardsuit/C = H.wear_suit
var/obj/item/organ/cyberimp/chest/thrusters/T = H.getorganslot(ORGAN_SLOT_THRUSTERS)
if(!istype(J) && istype(C))
J = C.jetpack
if(istype(J) && J.full_speed && J.allow_thrust(0.01, H)) //Prevents stacking
. -= 0.4
else if(istype(T) && T.allow_thrust(0.01, H))
. -= 0.4
if(!ignoreslow && gravity)
if(!HAS_TRAIT(H, TRAIT_IGNORESLOWDOWN) && gravity)
if(H.wear_suit)
. += H.wear_suit.slowdown
if(H.shoes)
@@ -1428,16 +1430,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/grav_force = min(gravity - STANDARD_GRAVITY,3)
. += 1 + grav_force
GET_COMPONENT_FROM(mood, /datum/component/mood, H)
if(mood && !flight) //How can depression slow you down if you can just fly away from your problems?
switch(mood.sanity)
if(SANITY_INSANE to SANITY_CRAZY)
. += 1.5
if(SANITY_CRAZY to SANITY_UNSTABLE)
. += 1
if(SANITY_UNSTABLE to SANITY_DISTURBED)
. += 0.5
if(HAS_TRAIT(H, TRAIT_FAT))
. += (1.5 - flight)
if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD))
@@ -1764,7 +1756,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
switch(hit_area)
if(BODY_ZONE_HEAD)
if(!I.is_sharp() && armor_block < 50)
if(!I.get_sharpness() && armor_block < 50)
if(prob(I.force))
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 20)
if(H.stat == CONSCIOUS)
@@ -1797,7 +1789,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
H.update_inv_glasses()
if(BODY_ZONE_CHEST)
if(H.stat == CONSCIOUS && !I.is_sharp() && armor_block < 50)
if(H.stat == CONSCIOUS && !I.get_sharpness() && armor_block < 50)
if(prob(I.force))
H.visible_message("<span class='danger'>[H] has been knocked down!</span>", \
"<span class='userdanger'>[H] has been knocked down!</span>")
@@ -1920,8 +1912,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/knocked_item = FALSE
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
target_held_item = null
if(!target.has_movespeed_modifier(SHOVE_SLOWDOWN_ID))
target.add_movespeed_modifier(SHOVE_SLOWDOWN_ID, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH)
if(!target.has_movespeed_modifier(MOVESPEED_ID_SHOVE))
target.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH)
if(target_held_item)
target.visible_message("<span class='danger'>[target.name]'s grip on \the [target_held_item] loosens!</span>",
"<span class='danger'>Your grip on \the [target_held_item] loosens!</span>", null, COMBAT_MESSAGE_RANGE)
@@ -1939,10 +1931,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
append_message = "loosening their grip on [target_held_item]"
log_combat(user, target, "shoved", append_message)
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H)
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE)
var/hit_percent = (100-(blocked+armor))/100
hit_percent = (hit_percent * (100-H.physiology.damage_resistance))/100
if(hit_percent <= 0)
if(!forced && hit_percent <= 0)
return 0
var/obj/item/bodypart/BP = null
@@ -1964,37 +1956,44 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
switch(damagetype)
if(BRUTE)
H.damageoverlaytemp = 20
var/damage_amount = forced ? damage : damage * hit_percent * brutemod * H.physiology.brute_mod
if(BP)
if(damage > 0 ? BP.receive_damage(damage * hit_percent * brutemod * H.physiology.brute_mod, 0) : BP.heal_damage(abs(damage * hit_percent * brutemod * H.physiology.brute_mod), 0))
if(damage > 0 ? BP.receive_damage(damage_amount, 0) : BP.heal_damage(abs(damage_amount), 0))
H.update_damage_overlays()
if(HAS_TRAIT(H, TRAIT_MASO))
H.adjustArousalLoss(damage * brutemod * H.physiology.brute_mod)
H.adjustArousalLoss(damage_amount, 0)
if (H.getArousalLoss() >= 100 && ishuman(H) && H.has_dna())
H.mob_climax(forced_climax=TRUE)
else//no bodypart, we deal damage with a more general method.
H.adjustBruteLoss(damage * hit_percent * brutemod * H.physiology.brute_mod)
H.adjustBruteLoss(damage_amount)
if(BURN)
H.damageoverlaytemp = 20
var/damage_amount = forced ? damage : damage * hit_percent * burnmod * H.physiology.burn_mod
if(BP)
if(damage > 0 ? BP.receive_damage(0, damage * hit_percent * burnmod * H.physiology.burn_mod) : BP.heal_damage(0, abs(damage * hit_percent * burnmod * H.physiology.burn_mod)))
if(damage > 0 ? BP.receive_damage(0, damage_amount) : BP.heal_damage(0, abs(damage_amount)))
H.update_damage_overlays()
else
H.adjustFireLoss(damage * hit_percent * burnmod * H.physiology.burn_mod)
H.adjustFireLoss(damage_amount)
if(TOX)
H.adjustToxLoss(damage * hit_percent * H.physiology.tox_mod)
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.tox_mod
H.adjustToxLoss(damage_amount)
if(OXY)
H.adjustOxyLoss(damage * hit_percent * H.physiology.oxy_mod)
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.oxy_mod
H.adjustOxyLoss(damage_amount)
if(CLONE)
H.adjustCloneLoss(damage * hit_percent * H.physiology.clone_mod)
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.clone_mod
H.adjustCloneLoss(damage_amount)
if(STAMINA)
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.stamina_mod
if(BP)
if(damage > 0 ? BP.receive_damage(0, 0, damage * hit_percent * H.physiology.stamina_mod) : BP.heal_damage(0, 0, abs(damage * hit_percent * H.physiology.stamina_mod), only_robotic = FALSE, only_organic = FALSE))
if(damage > 0 ? BP.receive_damage(0, 0, damage_amount) : BP.heal_damage(0, 0, abs(damage * hit_percent * H.physiology.stamina_mod), only_robotic = FALSE, only_organic = FALSE))
H.update_stamina()
else
H.adjustStaminaLoss(damage * hit_percent * H.physiology.stamina_mod)
H.adjustStaminaLoss(damage_amount)
if(BRAIN)
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, damage * hit_percent * H.physiology.brain_mod)
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.brain_mod
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, damage_amount)
if(AROUSAL) //Citadel edit - arousal
H.adjustArousalLoss(damage * hit_percent)
return 1
@@ -2036,13 +2035,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
natural = H.natural_bodytemperature_stabilization()
var/thermal_protection = 1
if(loc_temp < H.bodytemperature) //Place is colder than we are
thermal_protection -= H.get_cold_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
thermal_protection -= H.get_thermal_protection(loc_temp, TRUE) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
if(H.bodytemperature < BODYTEMP_NORMAL) //we're cold, insulation helps us retain body heat and will reduce the heat we lose to the environment
H.adjust_bodytemperature((thermal_protection+1)*natural + max(thermal_protection * (loc_temp - H.bodytemperature) / BODYTEMP_COLD_DIVISOR, BODYTEMP_COOLING_MAX))
else //we're sweating, insulation hinders our ability to reduce heat - and it will reduce the amount of cooling you get from the environment
H.adjust_bodytemperature(natural*(1/(thermal_protection+1)) + max((thermal_protection * (loc_temp - H.bodytemperature) + BODYTEMP_NORMAL - H.bodytemperature) / BODYTEMP_COLD_DIVISOR , BODYTEMP_COOLING_MAX)) //Extra calculation for hardsuits to bleed off heat
else //Place is hotter than we are
thermal_protection -= H.get_heat_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
thermal_protection -= H.get_thermal_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
if(H.bodytemperature < BODYTEMP_NORMAL) //and we're cold, insulation enhances our ability to retain body heat but reduces the heat we get from the environment
H.adjust_bodytemperature((thermal_protection+1)*natural + min(thermal_protection * (loc_temp - H.bodytemperature) / BODYTEMP_HEAT_DIVISOR, BODYTEMP_HEATING_MAX))
else //we're sweating, insulation hinders out ability to reduce heat - but will reduce the amount of heat we get from the environment
@@ -2181,7 +2180,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(!(I.resistance_flags & FIRE_PROOF))
I.take_damage(H.fire_stacks, BURN, "fire", 0)
var/thermal_protection = H.get_thermal_protection()
var/thermal_protection = H.easy_thermal_protection()
if(thermal_protection >= FIRE_IMMUNITY_MAX_TEMP_PROTECT && !no_protection)
return
@@ -6,10 +6,6 @@
species_traits = list(NOBLOOD,NOEYES,NOGENITALS,NOAROUSAL)
inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NOGUNS,TRAIT_NOHUNGER,TRAIT_NOBREATH)
mutanttongue = /obj/item/organ/tongue/abductor
var/scientist = FALSE // vars to not pollute spieces list with castes
/datum/species/abductor/copy_properties_from(datum/species/abductor/old_species)
scientist = old_species.scientist
/datum/species/abductor/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
@@ -6,6 +6,7 @@
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_NOFIRE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_LIMBATTACHMENT)
inherent_biotypes = list(MOB_ROBOTIC, MOB_HUMANOID)
meat = null
gib_types = /obj/effect/gibspawner/robot
damage_overlay_type = "synth"
mutanttongue = /obj/item/organ/tongue/robot
limbs_id = "synth"
@@ -29,7 +29,7 @@
if(fly)
fly.Remove(H)
if(H.movement_type & FLYING)
H.movement_type &= ~FLYING
H.setMovetype(H.movement_type & ~FLYING)
ToggleFlight(H,0)
if(H.dna && H.dna.species && (H.dna.features["wings"] == "Angel"))
if("wings" in H.dna.species.mutant_bodyparts)
@@ -132,14 +132,14 @@
if(flight && CanFly(H))
stunmod = 2
speedmod = -0.35
H.movement_type |= FLYING
H.setMovetype(H.movement_type | FLYING)
override_float = TRUE
H.pass_flags |= PASSTABLE
H.OpenWings()
else
stunmod = 1
speedmod = 0
H.movement_type &= ~FLYING
H.setMovetype(H.movement_type & ~FLYING)
override_float = FALSE
H.pass_flags &= ~PASSTABLE
H.CloseWings()
@@ -3,7 +3,7 @@
id = "insect"
say_mod = "flutters"
default_color = "00FF00"
species_traits = list(LIPS,NOEYES,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR)
species_traits = list(LIPS,NOEYES,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR,WINGCOLOR)
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID, MOB_BUG)
mutant_bodyparts = list("mam_ears", "mam_snout", "mam_tail", "taur", "insect_wings", "mam_snouts", "insect_fluff","horns")
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None",
@@ -17,6 +17,7 @@
toxic_food = MEAT | RAW
mutanteyes = /obj/item/organ/eyes/insect
should_draw_citadel = TRUE
exotic_bloodtype = "BUG"
/datum/species/insect/on_species_gain(mob/living/carbon/C)
. = ..()
@@ -17,4 +17,5 @@
use_skintones = 0
species_traits = list(NOBLOOD,EYECOLOR,NOGENITALS)
inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOLIMBDISABLE,TRAIT_NOHUNGER)
sexes = 0
sexes = 0
gib_types = /obj/effect/gibspawner/robot
@@ -18,6 +18,8 @@
var/obj/item/dullahan_relay/myhead
/datum/species/dullahan/pumpkin
name = "Pumpkin Head Dullahan"
id = "pumpkindullahan"
pumpkin = TRUE
/datum/species/dullahan/check_roundstart_eligible()
@@ -27,7 +29,7 @@
/datum/species/dullahan/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
. = ..()
H.flags_1 &= ~HEAR_1
DISABLE_BITFIELD(H.flags_1, HEAR_1)
var/obj/item/bodypart/head/head = H.get_bodypart(BODY_ZONE_HEAD)
if(head)
if(pumpkin)//Pumpkinhead!
@@ -36,16 +38,16 @@
head.icon_state = "hardhat1_pumpkin_j"
head.custom_head = TRUE
head.drop_limb()
head.flags_1 = HEAR_1
head.throwforce = 25
myhead = new /obj/item/dullahan_relay (head, H)
H.put_in_hands(head)
var/obj/item/organ/eyes/E = H.getorganslot(ORGAN_SLOT_EYES)
for(var/datum/action/item_action/organ_action/OA in E.actions)
OA.Trigger()
if(!QDELETED(head)) //drop_limb() deletes the limb if it's no drop location and dummy humans used for rendering icons are located in nullspace. Do the math.
head.throwforce = 25
myhead = new /obj/item/dullahan_relay (head, H)
H.put_in_hands(head)
var/obj/item/organ/eyes/E = H.getorganslot(ORGAN_SLOT_EYES)
for(var/datum/action/item_action/organ_action/OA in E.actions)
OA.Trigger()
/datum/species/dullahan/on_species_loss(mob/living/carbon/human/H)
H.flags_1 |= ~HEAR_1
ENABLE_BITFIELD(H.flags_1, HEAR_1)
H.reset_perspective(H)
if(myhead)
var/obj/item/dullahan_relay/DR = myhead
@@ -84,7 +86,7 @@
/obj/item/organ/tongue/dullahan/handle_speech(datum/source, list/speech_args)
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
if(H.dna.species.id == "dullahan")
if(isdullahan(H))
var/datum/species/dullahan/D = H.dna.species
if(isobj(D.myhead.loc))
var/obj/O = D.myhead.loc
@@ -99,6 +101,7 @@
desc = "An abstraction."
actions_types = list(/datum/action/item_action/organ_action/dullahan)
zone = "abstract"
tint = INFINITY // used to switch the vision perspective to the head on species_gain().
/datum/action/item_action/organ_action/dullahan
name = "Toggle Perspective"
@@ -114,37 +117,53 @@
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
if(H.dna.species.id == "dullahan")
if(isdullahan(H))
var/datum/species/dullahan/D = H.dna.species
D.update_vision_perspective(H)
/obj/item/dullahan_relay
name = "dullahan relay"
var/mob/living/owner
flags_1 = HEAR_1
/obj/item/dullahan_relay/Initialize(mapload,new_owner)
/obj/item/dullahan_relay/Initialize(mapload, mob/living/carbon/human/new_owner)
. = ..()
if(!new_owner)
return INITIALIZE_HINT_QDEL
owner = new_owner
START_PROCESSING(SSobj, src)
RegisterSignal(owner, COMSIG_MOB_EXAMINATE, .proc/examinate_check)
RegisterSignal(src, COMSIG_ATOM_HEARER_IN_VIEW, .proc/include_owner)
RegisterSignal(owner, COMSIG_LIVING_REGENERATE_LIMBS, .proc/unlist_head)
RegisterSignal(owner, COMSIG_LIVING_FULLY_HEAL, .proc/retrieve_head)
/obj/item/dullahan_relay/proc/examinate_check(mob/source, atom/A)
if(source.client.eye == src && ((A in view(source.client.view, src)) || (isturf(A) && source.sight & SEE_TURFS) || (ismob(A) && source.sight & SEE_MOBS) || (isobj(A) && source.sight & SEE_OBJS)))
return COMPONENT_ALLOW_EXAMINE
/obj/item/dullahan_relay/proc/include_owner(datum/source, list/processing_list, list/hearers)
if(!QDELETED(owner))
hearers += owner
/obj/item/dullahan_relay/proc/unlist_head(datum/source, noheal = FALSE, list/excluded_limbs)
excluded_limbs |= BODY_ZONE_HEAD // So we don't gib when regenerating limbs.
/obj/item/dullahan_relay/proc/retrieve_head(datum/source, admin_revive = FALSE)
if(admin_revive) //retrieving the owner's head for ahealing purposes.
var/obj/item/bodypart/head/H = loc
var/turf/T = get_turf(owner)
if(H && istype(H) && T && !(H in owner.GetAllContents()))
H.forceMove(T)
/obj/item/dullahan_relay/process()
if(!istype(loc, /obj/item/bodypart/head) || QDELETED(owner))
. = PROCESS_KILL
qdel(src)
/obj/item/dullahan_relay/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
. = ..()
if(!QDELETED(owner))
message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode)
to_chat(owner,message)
else
qdel(src)
/obj/item/dullahan_relay/Destroy()
if(!QDELETED(owner))
var/mob/living/carbon/human/H = owner
if(H.dna.species.id == "dullahan")
if(isdullahan(H))
var/datum/species/dullahan/D = H.dna.species
D.myhead = null
owner.gib()
@@ -0,0 +1,192 @@
GLOBAL_LIST_INIT(dwarf_first, world.file2list("strings/names/dwarf_first.txt")) //Textfiles with first
GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //textfiles with last
/datum/species/dwarf //not to be confused with the genetic manlets
name = "Dwarf"
id = "dwarf" //Also called Homo sapiens pumilionis
default_color = "FFFFFF"
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,NO_UNDERWEAR)
inherent_traits = list()
default_features = list("mcolor" = "FFF", "wings" = "None")
limbs_id = "human"
use_skintones = 1
say_mod = "bellows" //high energy, EXTRA BIOLOGICAL FUEL
damage_overlay_type = "human"
skinned_type = /obj/item/stack/sheet/animalhide/human
liked_food = ALCOHOL | MEAT | DAIRY //Dwarves like alcohol, meat, and dairy products.
disliked_food = JUNKFOOD | FRIED //Dwarves hate foods that have no nutrition other than alcohol.
mutant_organs = list(/obj/item/organ/dwarfgland) //Dwarven alcohol gland, literal gland warrior
mutantliver = /obj/item/organ/liver/dwarf //Dwarven super liver (Otherwise they r doomed)
/mob/living/carbon/human/species/dwarf //species admin spawn path
race = /datum/species/dwarf //and the race the path is set to.
/datum/species/dwarf/check_roundstart_eligible()
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
return TRUE
return ..()
/datum/species/dwarf/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
var/dwarf_hair = pick("Beard (Dwarf)", "Beard (Very Long)", "Beard (Long)") //beard roullette
var/mob/living/carbon/human/H = C
H.facial_hair_style = dwarf_hair
H.update_hair()
H.transform = H.transform.Scale(1, 0.8) //We use scale, and yeah. Dwarves can become gnomes with DWARFISM.
RegisterSignal(C, COMSIG_MOB_SAY, .proc/handle_speech) //We register handle_speech is being used.
/datum/species/dwarf/on_species_loss(mob/living/carbon/H, datum/species/new_species)
. = ..()
H.transform = H.transform.Scale(1, 1.25) //And we undo it.
UnregisterSignal(H, COMSIG_MOB_SAY) //We register handle_speech is not being used.
//Dwarf Name stuff
/proc/dwarf_name() //hello caller: my name is urist mcuristurister
return "[pick(GLOB.dwarf_first)] [pick(GLOB.dwarf_last)]"
/datum/species/dwarf/random_name(gender,unique,lastname)
return dwarf_name() //hello, ill return the value from dwarf_name proc to you when called.
//Dwarf Speech handling - Basically a filter/forces them to say things. The IC helper
/datum/species/dwarf/proc/handle_speech(datum/source, list/speech_args)
var/message = speech_args[SPEECH_MESSAGE]
if(message[1] != "*")
message = " [message]" //Credits to goonstation for the strings list.
var/list/dwarf_words = strings("dwarf_replacement.json", "dwarf") //thanks to regex too.
for(var/key in dwarf_words) //Theres like 1459 words or something man.
var/value = dwarf_words[key] //Thus they will always be in character.
if(islist(value)) //Whether they like it or not.
value = pick(value) //This could be drastically reduced if needed though.
message = replacetextEx(message, " [uppertext(key)]", " [uppertext(value)]")
message = replacetextEx(message, " [capitalize(key)]", " [capitalize(value)]")
message = replacetextEx(message, " [key]", " [value]") //Also its scottish.
if(prob(3))
message += pick(" By Armok!")
speech_args[SPEECH_MESSAGE] = trim(message)
//This mostly exists because my testdwarf's liver died while trying to also not die due to no alcohol.
/obj/item/organ/liver/dwarf
name = "dwarf liver"
icon_state = "liver"
desc = "A dwarven liver, theres something magical about seeing one of these up close."
alcohol_tolerance = 0 //dwarves really shouldn't be dying to alcohol.
toxTolerance = 5 //Shrugs off 5 units of toxins damage.
maxHealth = 150 //More health than the average liver, as you aren't going to be replacing this.
//If it does need replaced with a standard human liver, prepare for hell.
//alcohol gland
/obj/item/organ/dwarfgland
name = "dwarf alcohol gland"
icon_state = "plasma" //Yes this is a actual icon in icons/obj/surgery.dmi
desc = "A genetically engineered gland which is hopefully a step forward for humanity."
w_class = WEIGHT_CLASS_NORMAL
var/stored_alcohol = 250 //They start with 250 units, that ticks down and eventaully bad effects occur
var/max_alcohol = 500 //Max they can attain, easier than you think to OD on alcohol.
var/heal_rate = 0.5 //The rate they heal damages over 400 alcohol stored. Default is 0.5 so we times 3 since 3 seconds.
var/alcohol_rate = 0.25 //The rate the alcohol ticks down per each iteration of dwarf_eth_ticker completing.
//These count in on_life ticks which should be 2 seconds per every increment of 1 in a perfect world.
var/dwarf_filth_ticker = 0 //Currently set =< 4, that means this will fire the proc around every 4-8 seconds.
var/dwarf_eth_ticker = 0 //Currently set =< 1, that means this will fire the proc around every 2 seconds
/obj/item/organ/dwarfgland/prepare_eat()
var/obj/S = ..()
S.reagents.add_reagent("ethanol", stored_alcohol/10)
return S
/obj/item/organ/dwarfgland/on_life() //Primary loop to hook into to start delayed loops for other loops..
. = ..()
dwarf_cycle_ticker()
//Handles the delayed tick cycle by just adding on increments per each on_life() tick
/obj/item/organ/dwarfgland/proc/dwarf_cycle_ticker()
if(owner.stat == DEAD)
return //We make sure they are not dead, so they don't increment any tickers.
dwarf_eth_ticker++
dwarf_filth_ticker++
if(dwarf_filth_ticker >= 4) //Should be around 4-8 seconds since a tick is around 2 seconds.
dwarf_filth_cycle() //On_life will adjust regarding other factors, so we are along for the ride.
dwarf_filth_ticker = 0 //We set the ticker back to 0 to go again.
if(dwarf_eth_ticker >= 1) //Alcohol reagent check should be around 2 seconds, since a tick is around 2 seconds.
dwarf_eth_cycle()
dwarf_eth_ticker = 0
//If this still friggin uses too much CPU, I'll make a for view subsystem If I have to.
/obj/item/organ/dwarfgland/proc/dwarf_filth_cycle()
if(!owner?.client || !owner?.mind)
return
//Filth Reactions - Since miasma now exists
var/filth_counter = 0 //Holder for the filth check cycle, basically contains how much filth dwarf sees numerically.
for(var/fuck in view(owner,7)) //hello byond for view loop.
if(istype(fuck, /mob/living/carbon/human))
var/mob/living/carbon/human/H = fuck
if(H.stat == DEAD || (HAS_TRAIT(H, TRAIT_FAKEDEATH)))
filth_counter += 10
if(istype(fuck, /obj/effect/decal/cleanable/blood))
if(istype(fuck, /obj/effect/decal/cleanable/blood/gibs))
filth_counter += 1
else
filth_counter += 0.1
if(istype(fuck,/obj/effect/decal/cleanable/vomit)) //They are disgusted by their own vomit too.
filth_counter += 10 //Dwarves could technically chainstun each other in a vomit tantrum spiral.
switch(filth_counter)
if(11 to 25)
if(prob(25))
to_chat(owner, "<span class = 'danger'>Someone should really clean up in here!</span>")
if(26 to 50)
if(prob(30)) //Probability the message appears
to_chat(owner, "<span class = 'danger'>The stench makes you queasy.</span>")
if(prob(20)) //And then the probability they vomit along with it.
owner.vomit(20) //I think vomit should stay over a disgust adjustment.
if(51 to 75)
if(prob(35))
to_chat(owner, "<span class = 'danger'>By Armok! You won't be able to keep alcohol down at all!</span>")
if(prob(25))
owner.vomit(20) //Its more funny
if(76 to 100)
if(prob(40))
to_chat(owner, "<span class = 'userdanger'>You can't live in such FILTH!</span>")
if(prob(25))
owner.adjustToxLoss(10) //Now they start dying.
owner.vomit(20)
if(101 to INFINITY) //Now they will really start dying
if(prob(40))
to_chat(owner, "<span class = 'userdanger'> THERES TOO MUCH FILTH, OH GODS THE FILTH!</span>")
owner.adjustToxLoss(15)
owner.vomit(40)
CHECK_TICK //Check_tick right here, its motherfuckin magic. (To me at least)
//Handles the dwarf alcohol cycle tied to on_life, it ticks in dwarf_cycle_ticker.
/obj/item/organ/dwarfgland/proc/dwarf_eth_cycle()
//BOOZE POWER
for(var/datum/reagent/R in owner.reagents.reagent_list)
if(istype(R, /datum/reagent/consumable/ethanol))
var/datum/reagent/consumable/ethanol/E = R
stored_alcohol += (E.boozepwr / 50)
if(stored_alcohol > max_alcohol) //Dwarves technically start at 250 alcohol stored.
stored_alcohol = max_alcohol
var/heal_amt = heal_rate
stored_alcohol -= alcohol_rate //Subtracts alcohol_Rate from stored alcohol so EX: 250 - 0.25 per each loop that occurs.
if(stored_alcohol > 400) //If they are over 400 they start regenerating
owner.adjustBruteLoss(-heal_amt) //But its alcohol, there will be other issues here.
owner.adjustFireLoss(-heal_amt) //Unless they drink casually all the time.
owner.adjustOxyLoss(-heal_amt)
owner.adjustCloneLoss(-heal_amt) //Also they will probably get brain damage if thats a thing here.
if(prob(25))
switch(stored_alcohol)
if(0 to 24)
to_chat(owner, "<span class='userdanger'>DAMNATION INCARNATE, WHY AM I CURSED WITH THIS DRY-SPELL? I MUST DRINK.</span>")
owner.adjustToxLoss(35)
if(25 to 50)
to_chat(owner, "<span class='danger'>Oh DAMN, I need some brew!</span>")
if(51 to 75)
to_chat(owner, "<span class='warning'>Your body aches, you need to get ahold of some booze...</span>")
if(76 to 100)
to_chat(owner, "<span class='notice'>A pint of anything would really hit the spot right now.</span>")
if(101 to 150)
to_chat(owner, "<span class='notice'>You feel like you could use a good brew.</span>")
@@ -4,8 +4,8 @@
id = "felinid"
limbs_id = "human"
mutant_bodyparts = list("mam_ears", "mam_tail")
default_features = list("mcolor" = "FFF", "mam_tail" = "Cat", "mam_ears" = "Cat", "wings" = "None")
mutant_bodyparts = list("mam_ears", "mam_tail", "deco_wings")
default_features = list("mcolor" = "FFF", "mam_tail" = "Cat", "mam_ears" = "Cat", "wings" = "None", "deco_wings" = "None")
mutantears = /obj/item/organ/ears/cat
mutanttail = /obj/item/organ/tail/cat
@@ -10,6 +10,7 @@
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/fly
disliked_food = null
liked_food = GROSS
exotic_bloodtype = "BUG"
/datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.id == "pestkiller")
@@ -3,7 +3,7 @@
id = "mammal"
default_color = "4B4B4B"
should_draw_citadel = TRUE
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR)
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR,WINGCOLOR)
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "deco_wings", "taur", "horns", "legs")
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "deco_wings" = "None",
@@ -64,8 +64,9 @@
attack_sound = 'sound/weapons/slash.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
meat = /obj/item/reagent_containers/food/snacks/meat/slab/xeno
gib_types = list(/obj/effect/gibspawner/xeno/xenoperson, /obj/effect/gibspawner/xeno/xenoperson/bodypartless)
skinned_type = /obj/item/stack/sheet/animalhide/xeno
exotic_bloodtype = "L"
exotic_bloodtype = "X*"
damage_overlay_type = "xeno"
liked_food = MEAT
@@ -634,9 +634,10 @@
id = "clockwork golem"
say_mod = "clicks"
limbs_id = "clockgolem"
info_text = "<span class='bold alloy'>As a </span><span class='bold brass'>Clockwork Golem</span><span class='bold alloy'>, you are faster than other types of golems. On death, you will break down into scrap.</span>"
info_text = "<span class='bold alloy'>As a </span><span class='bold brass'>Clockwork Golem</span><span class='bold alloy'>, you are faster than other types of golems, and are capable of using guns. On death, you will break down into scrap.</span>"
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES,NOGENITALS,NOAROUSAL)
inherent_biotypes = list(MOB_ROBOTIC, MOB_HUMANOID)
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
armor = 20 //Reinforced, but much less so to allow for fast movement
attack_verb = "smash"
attack_sound = 'sound/magic/clockwork/anima_fragment_attack.ogg'
@@ -682,7 +683,7 @@
blacklisted = TRUE
dangerous_existence = TRUE
random_eligible = FALSE
info_text = "<span class='bold alloy'>As a </span><span class='bold brass'>Clockwork Golem Servant</span><span class='bold alloy'>, you are faster than other types of golems.</span>" //warcult golems leave a corpse
info_text = "<span class='bold alloy'>As a </span><span class='bold brass'>Clockwork Golem Servant</span><span class='bold alloy'>, you are faster than other types of golems, and are capable of using guns.</span>" //warcult golems leave a corpse
/datum/species/golem/cloth
name = "Cloth Golem"
@@ -795,7 +796,7 @@
if(resistance_flags & ON_FIRE)
return
if(P.is_hot())
if(P.get_temperature())
visible_message("<span class='danger'>[src] bursts into flames!</span>")
fire_act()
@@ -1,41 +1,42 @@
/datum/species/human
name = "Human"
id = "human"
default_color = "FFFFFF"
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY)
mutant_bodyparts = list("ears", "tail_human", "wings", "taur") // CITADEL EDIT gives humans snowflake parts
default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF","tail_human" = "None", "ears" = "None", "wings" = "None", "taur" = "None")
use_skintones = 1
skinned_type = /obj/item/stack/sheet/animalhide/human
disliked_food = GROSS | RAW
liked_food = JUNKFOOD | FRIED
/datum/species/human/qualifies_for_rank(rank, list/features)
return TRUE //Pure humans are always allowed in all roles.
/datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
if(H)
stop_wagging_tail(H)
/datum/species/human/spec_stun(mob/living/carbon/human/H,amount)
if(H)
stop_wagging_tail(H)
. = ..()
/datum/species/human/can_wag_tail(mob/living/carbon/human/H)
return ("tail_human" in mutant_bodyparts) || ("waggingtail_human" in mutant_bodyparts)
/datum/species/human/is_wagging_tail(mob/living/carbon/human/H)
return ("waggingtail_human" in mutant_bodyparts)
/datum/species/human/start_wagging_tail(mob/living/carbon/human/H)
if("tail_human" in mutant_bodyparts)
mutant_bodyparts -= "tail_human"
mutant_bodyparts |= "waggingtail_human"
H.update_body()
/datum/species/human/stop_wagging_tail(mob/living/carbon/human/H)
if("waggingtail_human" in mutant_bodyparts)
mutant_bodyparts -= "waggingtail_human"
mutant_bodyparts |= "tail_human"
H.update_body()
/datum/species/human
name = "Human"
id = "human"
default_color = "FFFFFF"
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY,WINGCOLOR)
mutant_bodyparts = list("ears", "tail_human", "wings", "taur", "deco_wings") // CITADEL EDIT gives humans snowflake parts
default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF","tail_human" = "None", "ears" = "None", "wings" = "None", "taur" = "None", "deco_wings" = "None")
use_skintones = 1
skinned_type = /obj/item/stack/sheet/animalhide/human
disliked_food = GROSS | RAW
liked_food = JUNKFOOD | FRIED
/datum/species/human/qualifies_for_rank(rank, list/features)
return TRUE //Pure humans are always allowed in all roles.
/datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
if(H)
stop_wagging_tail(H)
/datum/species/human/spec_stun(mob/living/carbon/human/H,amount)
if(H)
stop_wagging_tail(H)
. = ..()
/datum/species/human/can_wag_tail(mob/living/carbon/human/H)
return ("tail_human" in mutant_bodyparts) || ("waggingtail_human" in mutant_bodyparts)
/datum/species/human/is_wagging_tail(mob/living/carbon/human/H)
return ("waggingtail_human" in mutant_bodyparts)
/datum/species/human/start_wagging_tail(mob/living/carbon/human/H)
if("tail_human" in mutant_bodyparts)
mutant_bodyparts -= "tail_human"
mutant_bodyparts |= "waggingtail_human"
H.update_body()
/datum/species/human/stop_wagging_tail(mob/living/carbon/human/H)
if("waggingtail_human" in mutant_bodyparts)
mutant_bodyparts -= "waggingtail_human"
mutant_bodyparts |= "tail_human"
H.update_body()
@@ -11,9 +11,10 @@
mutant_bodyparts = list("ipc_screen", "ipc_antenna")
default_features = list("ipc_screen" = "Blank", "ipc_antenna" = "None")
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless)
mutanttongue = /obj/item/organ/tongue/robot/ipc
exotic_blood = "oil"
mutant_heart = /obj/item/organ/heart/ipc
exotic_bloodtype = "HF"
var/datum/action/innate/monitor_change/screen
@@ -4,13 +4,16 @@
id = "jelly"
default_color = "00FF90"
say_mod = "chirps"
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,WINGCOLOR)
mutantlungs = /obj/item/organ/lungs/slime
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_snouts", "taur") //CIT CHANGE
default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None") //CIT CHANGE
mutant_heart = /obj/item/organ/heart/slime
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_snouts", "taur", "deco_wings") //CIT CHANGE
default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None") //CIT CHANGE
inherent_traits = list(TRAIT_TOXINLOVER)
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime
exotic_blood = "slimejelly"
gib_types = list(/obj/effect/gibspawner/slime, /obj/effect/gibspawner/slime/bodypartless)
exotic_blood = "jellyblood"
exotic_bloodtype = "GEL"
damage_overlay_type = ""
var/datum/action/innate/regenerate_limbs/regenerate_limbs
var/datum/action/innate/slime_change/slime_change //CIT CHANGE
@@ -121,7 +124,7 @@
name = "Xenobiological Slime Entity"
id = "slime"
default_color = "00FFFF"
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR)
say_mod = "says"
hair_color = "mutcolor"
hair_alpha = 150
@@ -396,7 +399,7 @@
id = "slimeperson"
limbs_id = "slime"
default_color = "00FFFF"
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR)
inherent_traits = list(TRAIT_TOXINLOVER)
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "taur")
default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None")
@@ -470,37 +473,25 @@
H.hair_style = new_style
H.update_hair()
else if (select_alteration == "Genitals")
var/list/organs = list()
var/operation = input("Select organ operation.", "Organ Manipulation", "cancel") in list("add sexual organ", "remove sexual organ", "cancel")
switch(operation)
if("add sexual organ")
var/new_organ = input("Select sexual organ:", "Organ Manipulation") in list("Penis", "Testicles", "Breasts", "Vagina", "Womb", "Cancel")
if(new_organ == "Penis")
H.give_penis()
else if(new_organ == "Testicles")
H.give_balls()
else if(new_organ == "Breasts")
H.give_breasts()
else if(new_organ == "Vagina")
H.give_vagina()
else if(new_organ == "Womb")
H.give_womb()
else
var/new_organ = input("Select sexual organ:", "Organ Manipulation") as null|anything in GLOB.genitals_list
if(!new_organ)
return
H.give_genital(GLOB.genitals_list[new_organ])
if("remove sexual organ")
var/list/organs = list()
for(var/obj/item/organ/genital/X in H.internal_organs)
var/obj/item/organ/I = X
organs["[I.name] ([I.type])"] = I
var/obj/item/organ = input("Select sexual organ:", "Organ Manipulation", null) in organs
organ = organs[organ]
if(!organ)
var/obj/item/O = input("Select sexual organ:", "Organ Manipulation", null) as null|anything in organs
var/obj/item/organ/genital/G = organs[O]
if(!G)
return
var/obj/item/organ/genital/O
if(isorgan(organ))
O = organ
O.Remove(H)
organ.forceMove(get_turf(H))
qdel(organ)
G.forceMove(get_turf(H))
qdel(G)
H.update_genitals()
else if (select_alteration == "Ears")
@@ -590,8 +581,8 @@
if(new_shape)
H.dna.features["cock_shape"] = new_shape
H.update_genitals()
H.give_balls()
H.give_penis()
H.give_genital(/obj/item/organ/genital/testicles)
H.give_genital(/obj/item/organ/genital/penis)
H.apply_overlay()
@@ -603,8 +594,8 @@
if(new_shape)
H.dna.features["vag_shape"] = new_shape
H.update_genitals()
H.give_womb()
H.give_vagina()
H.give_genital(/obj/item/organ/genital/womb)
H.give_genital(/obj/item/organ/genital/vagina)
H.apply_overlay()
else if (select_alteration == "Penis Length")
@@ -616,8 +607,8 @@
H.dna.features["cock_length"] = max(min( round(text2num(new_length)), COCK_SIZE_MAX),COCK_SIZE_MIN)
H.update_genitals()
H.apply_overlay()
H.give_balls()
H.give_penis()
H.give_genital(/obj/item/organ/genital/testicles)
H.give_genital(/obj/item/organ/genital/penis)
else if (select_alteration == "Breast Size")
for(var/obj/item/organ/genital/breasts/X in H.internal_organs)
@@ -628,7 +619,7 @@
H.dna.features["breasts_size"] = new_size
H.update_genitals()
H.apply_overlay()
H.give_breasts()
H.give_genital(/obj/item/organ/genital/breasts)
else if (select_alteration == "Breast Shape")
for(var/obj/item/organ/genital/breasts/X in H.internal_organs)
@@ -639,7 +630,7 @@
H.dna.features["breasts_shape"] = new_shape
H.update_genitals()
H.apply_overlay()
H.give_breasts()
H.give_genital(/obj/item/organ/genital/breasts)
else
return
@@ -854,6 +845,8 @@
return FALSE
if(HAS_TRAIT(M, TRAIT_MINDSHIELD)) //mindshield implant, no dice
return FALSE
if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
return FALSE
if(M in linked_mobs)
return FALSE
linked_mobs.Add(M)
@@ -939,9 +932,14 @@
var/mob/living/M = input("Select who to send your message to:","Send thought to?",null) as null|mob in options
if(!M)
return
if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
to_chat(H, "<span class='notice'>As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled.</span>")
return
var/msg = sanitize(input("Message:", "Telepathy") as text|null)
if(msg)
if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
to_chat(H, "<span class='notice'>As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled.</span>")
return
log_directed_talk(H, M, msg, LOG_SAY, "slime telepathy")
to_chat(M, "<span class='notice'>You hear an alien voice in your head... </span><font color=#008CA2>[msg]</font>")
to_chat(H, "<span class='notice'>You telepathically said: \"[msg]\" to [M]</span>")
@@ -4,20 +4,21 @@
id = "lizard"
say_mod = "hisses"
default_color = "00FF00"
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR)
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR,WINGCOLOR)
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID, MOB_REPTILE)
mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs", "taur")
mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs", "taur", "deco_wings")
mutanttongue = /obj/item/organ/tongue/lizard
mutanttail = /obj/item/organ/tail/lizard
coldmod = 1.5
heatmod = 0.67
default_features = list("mcolor" = "0F0", "mcolor2" = "0F0", "mcolor3" = "0F0", "tail_lizard" = "Smooth", "snout" = "Round",
"horns" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None",
"legs" = "Digitigrade", "taur" = "None")
"legs" = "Digitigrade", "taur" = "None", "deco_wings" = "None")
attack_verb = "slash"
attack_sound = 'sound/weapons/slash.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard
gib_types = list(/obj/effect/gibspawner/lizard, /obj/effect/gibspawner/lizard/bodypartless)
skinned_type = /obj/item/stack/sheet/animalhide/lizard
exotic_bloodtype = "L"
disliked_food = GRAIN | DAIRY
@@ -78,7 +78,7 @@
icon_state = "brain-x-d"
var/obj/effect/proc_holder/spell/targeted/shadowwalk/shadowwalk
/obj/item/organ/brain/nightmare/Insert(mob/living/carbon/M, special = 0)
/obj/item/organ/brain/nightmare/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
..()
if(M.dna.species.id != "nightmare")
M.set_species(/datum/species/shadow/nightmare)
@@ -118,7 +118,7 @@
user.temporarilyRemoveItemFromInventory(src, TRUE)
Insert(user)
/obj/item/organ/heart/nightmare/Insert(mob/living/carbon/M, special = 0)
/obj/item/organ/heart/nightmare/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
..()
if(special != HEART_SPECIAL_SHADOWIFY)
blade = new/obj/item/light_eater
@@ -22,8 +22,9 @@
/datum/species/skeleton/space
name = "Spooky Spacey Skeleton"
id = "spaceskeleton"
limbs_id = "skeleton"
blacklisted = 1
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER)
/datum/species/skeleton/pirate/check_roundstart_eligible()
/datum/species/skeleton/space/check_roundstart_eligible()
return FALSE
@@ -9,6 +9,7 @@
dangerous_existence = 1
blacklisted = 1
meat = null
gib_types = /obj/effect/gibspawner/robot
damage_overlay_type = "synth"
limbs_id = "synth"
var/list/initial_species_traits = list(NOTRANSSTING) //for getting these values back for assume_disguise()
@@ -45,14 +45,14 @@
C.adjustOxyLoss(-4)
C.adjustCloneLoss(-4)
return
C.blood_volume -= 0.75
C.blood_volume -= 0.75 //Will take roughly 19.5 minutes to die from standard blood volume, roughly 83 minutes to die from max blood volume.
if(C.blood_volume <= (BLOOD_VOLUME_SURVIVE*C.blood_ratio))
to_chat(C, "<span class='danger'>You ran out of blood!</span>")
C.dust()
var/area/A = get_area(C)
if(istype(A, /area/chapel))
to_chat(C, "<span class='danger'>You don't belong here!</span>")
C.adjustFireLoss(20)
C.adjustFireLoss(5)
C.adjust_fire_stacks(6)
C.IgniteMob()
@@ -88,7 +88,7 @@
to_chat(H, "<span class='notice'>[victim] doesn't have blood!</span>")
return
V.drain_cooldown = world.time + 30
if(victim.anti_magic_check(FALSE, TRUE))
if(victim.anti_magic_check(FALSE, TRUE, FALSE, 0))
to_chat(victim, "<span class='warning'>[H] tries to bite you, but stops before touching you!</span>")
to_chat(H, "<span class='warning'>[victim] is blessed! You stop just in time to avoid catching fire.</span>")
return
@@ -141,7 +141,7 @@
H = new(shape,src,caster)
if(istype(H, /mob/living/simple_animal))
var/mob/living/simple_animal/SA = H
if(ventcrawl_nude_only && length(caster.get_equipped_items(include_pockets = TRUE)))
if((caster.blood_volume >= (BLOOD_VOLUME_BAD*caster.blood_ratio)) || (ventcrawl_nude_only && length(caster.get_equipped_items(include_pockets = TRUE))))
SA.ventcrawler = FALSE
if(transfer_name)
H.name = caster.name
@@ -18,6 +18,7 @@
/datum/species/zombie/notspaceproof
id = "notspaceproofzombie"
limbs_id = "zombie"
blacklisted = 0
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NOBREATH,TRAIT_NODEATH,TRAIT_FAKEDEATH)
@@ -44,7 +45,7 @@
/datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H,amount)
. = min(20, amount)
/datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H)
/datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE)
. = ..()
if(.)
regen_cooldown = world.time + REGENERATION_DELAY
@@ -65,7 +66,7 @@
playsound(C, pick(spooks), 50, TRUE, 10)
//Congrats you somehow died so hard you stopped being a zombie
/datum/species/zombie/infectious/spec_death(mob/living/carbon/C)
/datum/species/zombie/infectious/spec_death(gibbed, mob/living/carbon/C)
. = ..()
var/obj/item/organ/zombie_infection/infection
infection = C.getorganslot(ORGAN_SLOT_ZOMBIE)
@@ -123,26 +123,20 @@ There are several things that need to be remembered:
if(U.adjusted == ALT_STYLE)
t_color = "[t_color]_d"
if(!U.force_alternate_icon)
if(U.mutantrace_variation)
if(U.suit_style == DIGITIGRADE_SUIT_STYLE)
U.alternate_worn_icon = 'modular_citadel/icons/mob/uniform_digi.dmi'
if(U.adjusted == ALT_STYLE)
t_color = "[t_color]_d_l"
else if(U.adjusted == NORMAL_STYLE)
t_color = "[t_color]_l"
else
U.alternate_worn_icon = null
var/alt_worn = U.alternate_worn_icon
if(!U.force_alternate_icon && U.mutantrace_variation && U.suit_style == DIGITIGRADE_SUIT_STYLE)
alt_worn = 'modular_citadel/icons/mob/uniform_digi.dmi'
var/mutable_appearance/uniform_overlay
if(dna && dna.species.sexes)
var/G = (gender == FEMALE) ? "f" : "m"
if(G == "f" && U.fitted != NO_FEMALE_UNIFORM)
uniform_overlay = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = ((w_uniform.alternate_worn_icon) ? w_uniform.alternate_worn_icon : 'icons/mob/uniform.dmi'), isinhands = FALSE, femaleuniform = U.fitted)
uniform_overlay = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = (alt_worn ? alt_worn : 'icons/mob/uniform.dmi'), isinhands = FALSE, femaleuniform = U.fitted)
if(!uniform_overlay)
uniform_overlay = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = ((w_uniform.alternate_worn_icon) ? w_uniform.alternate_worn_icon : 'icons/mob/uniform.dmi'), isinhands = FALSE)
uniform_overlay = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = (alt_worn ? alt_worn : 'icons/mob/uniform.dmi'), isinhands = FALSE)
if(OFFSET_UNIFORM in dna.species.offset_features)
@@ -186,7 +180,7 @@ There are several things that need to be remembered:
inv.update_icon()
if(!gloves && bloody_hands)
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER)
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER, color = blood_DNA_to_color())
if(get_num_arms() < 2)
if(has_left_hand())
bloody_overlay.icon_state = "bloodyhands_left"
@@ -276,6 +270,32 @@ There are several things that need to be remembered:
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_SHOES]
inv.update_icon()
/*
if(!shoes && bloody_feet)
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyfeet", -SHOES_LAYER, color = blood_DNA_to_color())
if(dna.features["taur"] != "None")
if(dna.features["taur"] in GLOB.noodle_taurs)
bloody_overlay = mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "snekbloodyfeet", -SHOES_LAYER, color = blood_DNA_to_color())
if(get_num_legs() < 2)
if(has_left_leg())
bloody_overlay.icon_state = "snekbloodyfeet_left"
else if(has_right_leg())
bloody_overlay.icon_state = "snekbloodyfeet_right"
else if(dna.features["taur"] in GLOB.paw_taurs)
bloody_overlay = mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "pawbloodyfeet", -SHOES_LAYER, color = blood_DNA_to_color())
if(get_num_legs() < 2)
if(has_left_leg())
bloody_overlay.icon_state = "pawbloodyfeet_left"
else if(has_right_leg())
bloody_overlay.icon_state = "pawbloodyfeet_right"
else
if(get_num_legs() < 2)
if(has_left_leg())
bloody_overlay.icon_state = "bloodyfeet_left"
else if(has_right_leg())
bloody_overlay.icon_state = "bloodyfeet_right"
overlays_standing[GLOVES_LAYER] = bloody_overlay*/
if(shoes)
var/obj/item/clothing/shoes/S = shoes
@@ -316,7 +336,7 @@ There are several things that need to be remembered:
if(!t_state)
t_state = s_store.icon_state
overlays_standing[SUIT_STORE_LAYER] = mutable_appearance(((s_store.alternate_worn_icon) ? s_store.alternate_worn_icon : 'icons/mob/belt_mirror.dmi'), t_state, -SUIT_STORE_LAYER)
var/mutable_appearance/s_store_overlay = overlays_standing[SUIT_LAYER]
var/mutable_appearance/s_store_overlay = overlays_standing[SUIT_STORE_LAYER]
if(OFFSET_S_STORE in dna.species.offset_features)
s_store_overlay.pixel_x += dna.species.offset_features[OFFSET_S_STORE][1]
s_store_overlay.pixel_y += dna.species.offset_features[OFFSET_S_STORE][2]
@@ -380,17 +400,17 @@ There are several things that need to be remembered:
if(wear_suit)
var/obj/item/clothing/suit/S = wear_suit
var/no_taur_thanks = FALSE
var/item_level_support = FALSE // LISTEN! If you must degrade the code with further snowflake checks, at least keep it compatible with worn non-clothing items!
if(!istype(S))
no_taur_thanks = TRUE
item_level_support = TRUE
wear_suit.screen_loc = ui_oclothing
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown)
client.screen += wear_suit
update_observer_view(wear_suit,1)
if(!S.force_alternate_icon)
if(!no_taur_thanks && S.mutantrace_variation) //Just make sure we've got this checked too
if(!item_level_support && !S.force_alternate_icon)
if(S.mutantrace_variation) //Just make sure we've got this checked too
if(S.taurmode == NOT_TAURIC && S.adjusted == ALT_STYLE) //are we not a taur, but we have Digitigrade legs? Run this check first, then.
S.alternate_worn_icon = 'modular_citadel/icons/mob/suit_digi.dmi'
else
@@ -411,7 +431,7 @@ There are several things that need to be remembered:
if(OFFSET_SUIT in dna.species.offset_features)
suit_overlay.pixel_x += dna.species.offset_features[OFFSET_SUIT][1]
suit_overlay.pixel_y += dna.species.offset_features[OFFSET_SUIT][2]
if(!no_taur_thanks && S.center)
if(!item_level_support && S.center)
suit_overlay = center_image(suit_overlay, S.dimension_x, S.dimension_y)
overlays_standing[SUIT_LAYER] = suit_overlay
update_hair()
+2 -2
View File
@@ -98,7 +98,7 @@
var/datum/gas_mixture/breath
if(!getorganslot(ORGAN_SLOT_BREATHING_TUBE))
if(health <= HEALTH_THRESHOLD_FULLCRIT || (pulledby && pulledby.grab_state >= GRAB_KILL) || lungs.organ_flags & ORGAN_FAILING)
if(health <= HEALTH_THRESHOLD_FULLCRIT || (pulledby && pulledby.grab_state >= GRAB_KILL) || (lungs && lungs.organ_flags & ORGAN_FAILING))
losebreath++ //You can't breath at all when in critical or when being choked, so you're going to miss a breath
else if(health <= crit_threshold)
@@ -702,7 +702,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
/mob/living/carbon/proc/liver_failure()
reagents.end_metabolization(src, keep_liverless = TRUE) //Stops trait-based effects on reagents, to prevent permanent buffs
reagents.metabolize(src, can_overdose=FALSE, liverless = TRUE)
if(HAS_TRAIT(src, TRAIT_STABLEHEART))
if(HAS_TRAIT(src, TRAIT_STABLELIVER))
return
adjustToxLoss(4, TRUE, TRUE)
if(prob(30))
@@ -23,7 +23,7 @@
if(changed)
animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, dir = final_dir, easing = EASE_IN|EASE_OUT)
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life().
setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life().
/mob/living/carbon
@@ -97,8 +97,12 @@
/mob/living/carbon/update_damage_overlays()
remove_overlay(DAMAGE_LAYER)
var/dam_colors = "#E62525"
if(ishuman(src))
var/mob/living/carbon/human/H = src
dam_colors = bloodtype_to_color(H.dna.blood_type)
var/mutable_appearance/damage_overlay = mutable_appearance('icons/mob/dam_mob.dmi', "blank", -DAMAGE_LAYER)
var/mutable_appearance/damage_overlay = mutable_appearance('icons/mob/dam_mob.dmi', "blank", -DAMAGE_LAYER, color = dam_colors)
overlays_standing[DAMAGE_LAYER] = damage_overlay
for(var/X in bodyparts)
+12 -11
View File
@@ -8,23 +8,24 @@
Returns
standard 0 if fail
*/
/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE)
/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
var/hit_percent = (100-blocked)/100
if(!damage || (hit_percent <= 0))
return 0
var/damage_amount = forced ? damage : damage * hit_percent
switch(damagetype)
if(BRUTE)
adjustBruteLoss(damage * hit_percent)
adjustBruteLoss(damage_amount, forced = forced)
if(BURN)
adjustFireLoss(damage * hit_percent)
adjustFireLoss(damage_amount, forced = forced)
if(TOX)
adjustToxLoss(damage * hit_percent)
adjustToxLoss(damage_amount, forced = forced)
if(OXY)
adjustOxyLoss(damage * hit_percent)
adjustOxyLoss(damage_amount, forced = forced)
if(CLONE)
adjustCloneLoss(damage * hit_percent)
adjustCloneLoss(damage_amount, forced = forced)
if(STAMINA)
adjustStaminaLoss(damage * hit_percent)
adjustStaminaLoss(damage_amount, forced = forced)
return 1
/mob/living/proc/apply_damage_type(damage = 0, damagetype = BRUTE) //like apply damage except it always uses the damage procs
@@ -79,7 +80,7 @@
/mob/living/proc/apply_effect(effect = 0,effecttype = EFFECT_STUN, blocked = FALSE)
/mob/living/proc/apply_effect(effect = 0,effecttype = EFFECT_STUN, blocked = FALSE, knockdown_stamoverride, knockdown_stammax)
var/hit_percent = (100-blocked)/100
if(!effect || (hit_percent <= 0))
return 0
@@ -87,7 +88,7 @@
if(EFFECT_STUN)
Stun(effect * hit_percent)
if(EFFECT_KNOCKDOWN)
Knockdown(effect * hit_percent)
Knockdown(effect * hit_percent, override_stamdmg = knockdown_stammax ? CLAMP(knockdown_stamoverride, 0, knockdown_stammax-getStaminaLoss()) : knockdown_stamoverride)
if(EFFECT_UNCONSCIOUS)
Unconscious(effect * hit_percent)
if(EFFECT_IRRADIATE)
@@ -107,13 +108,13 @@
return 1
/mob/living/proc/apply_effects(stun = 0, knockdown = 0, unconscious = 0, irradiate = 0, slur = 0, stutter = 0, eyeblur = 0, drowsy = 0, blocked = FALSE, stamina = 0, jitter = 0)
/mob/living/proc/apply_effects(stun = 0, knockdown = 0, unconscious = 0, irradiate = 0, slur = 0, stutter = 0, eyeblur = 0, drowsy = 0, blocked = FALSE, stamina = 0, jitter = 0, kd_stamoverride, kd_stammax)
if(blocked >= 100)
return 0
if(stun)
apply_effect(stun, EFFECT_STUN, blocked)
if(knockdown)
apply_effect(knockdown, EFFECT_KNOCKDOWN, blocked)
apply_effect(knockdown, EFFECT_KNOCKDOWN, blocked, kd_stamoverride, kd_stammax)
if(unconscious)
apply_effect(unconscious, EFFECT_UNCONSCIOUS, blocked)
if(irradiate)
+6 -2
View File
@@ -23,8 +23,12 @@
/mob/living/proc/gib_animation()
return
/mob/living/proc/spawn_gibs()
new /obj/effect/gibspawner/generic(drop_location(), null, get_static_viruses())
/mob/living/proc/spawn_gibs(with_bodyparts, atom/loc_override)
var/location = loc_override ? loc_override.drop_location() : drop_location()
if(MOB_ROBOTIC in mob_biotypes)
new /obj/effect/gibspawner/robot(location, src, get_static_viruses())
else
new /obj/effect/gibspawner/generic(location, src, get_static_viruses())
/mob/living/proc/spill_organs()
return
+1 -1
View File
@@ -4,7 +4,7 @@
if(digitalinvis)
handle_diginvis() //AI becomes unable to see mob
if((movement_type & FLYING) && !floating) //TODO: Better floating
if((movement_type & FLYING) && !(movement_type & FLOATING)) //TODO: Better floating
float(on = TRUE)
if (client)
+18 -7
View File
@@ -40,6 +40,16 @@
QDEL_LIST(diseases)
return ..()
/mob/living/onZImpact(turf/T, levels)
if(!isgroundlessturf(T))
ZImpactDamage(T, levels)
return ..()
/mob/living/proc/ZImpactDamage(turf/T, levels)
visible_message("<span class='danger'>[src] crashes into [T] with a sickening noise!</span>")
adjustBruteLoss((levels * 5) ** 1.5)
Knockdown(levels * 50)
/mob/living/proc/OpenCraftingMenu()
return
@@ -502,7 +512,7 @@
fire_stacks = 0
confused = 0
update_canmove()
GET_COMPONENT(mood, /datum/component/mood)
var/datum/component/mood/mood = GetComponent(/datum/component/mood)
if (mood)
QDEL_LIST_ASSOC_VAL(mood.mood_events)
mood.sanity = SANITY_GREAT
@@ -514,6 +524,7 @@
for(var/organ in C.internal_organs)
var/obj/item/organ/O = organ
O.setOrganDamage(0)
SEND_SIGNAL(src, COMSIG_LIVING_FULLY_HEAL, admin_revive)
//proc called by revive(), to check if we can actually ressuscitate the mob (we don't want to revive him and have him instantly die again)
@@ -716,14 +727,14 @@
var/fixed = 0
if(anchored || (buckled && buckled.anchored))
fixed = 1
if(on && !floating && !fixed)
if(on && !(movement_type & FLOATING) && !fixed)
animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1)
sleep(10)
animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1)
floating = TRUE
else if(((!on || fixed) && floating))
setMovetype(movement_type | FLOATING)
else if(((!on || fixed) && (movement_type & FLOATING)))
animate(src, pixel_y = get_standard_pixel_y_offset(lying), time = 10)
floating = FALSE
setMovetype(movement_type & ~FLOATING)
// The src mob is trying to strip an item from someone
// Override if a certain type of mob should be behave differently when stripping items (can't, for example)
@@ -795,7 +806,7 @@
var/final_pixel_y = get_standard_pixel_y_offset(lying)
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = 6)
animate(pixel_x = final_pixel_x , pixel_y = final_pixel_y , time = 2)
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure to restart it in next life().
setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure to restart it in next life().
/mob/living/proc/get_temperature(datum/gas_mixture/environment)
var/loc_temp = environment ? environment.temperature : T0C
@@ -935,7 +946,7 @@
apply_effect((amount*RAD_MOB_COEFFICIENT)/max(1, (radiation**2)*RAD_OVERDOSE_REDUCTION), EFFECT_IRRADIATE, blocked)
/mob/living/anti_magic_check(magic = TRUE, holy = FALSE)
/mob/living/anti_magic_check(magic = TRUE, holy = FALSE, chargecost = 1, self = FALSE)
. = ..()
if(.)
return
+1 -1
View File
@@ -422,4 +422,4 @@
if(!used_item)
used_item = get_active_held_item()
..()
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
+4 -1
View File
@@ -32,4 +32,7 @@
if(drag_slowdown && L.lying && !L.buckled && grab_state < GRAB_AGGRESSIVE)
add_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING, multiplicative_slowdown = PULL_PRONE_SLOWDOWN)
return
remove_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING)
remove_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING)
/mob/living/canZMove(dir, turf/target)
return can_zTravel(target, dir) && (movement_type & FLYING)
+9 -9
View File
@@ -391,16 +391,16 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
return 0
/mob/living/say_mod(input, message_mode)
if(message_mode == MODE_WHISPER)
. = verb_whisper
else if(message_mode == MODE_WHISPER_CRIT)
. = ..()
if(message_mode == MODE_WHISPER_CRIT)
. = "[verb_whisper] in [p_their()] last breath"
else if(stuttering)
. = "stammers"
else if(derpspeech)
. = "gibbers"
else
. = ..()
else if(message_mode != MODE_CUSTOM_SAY)
if(message_mode == MODE_WHISPER)
. = verb_whisper
else if(stuttering)
. = "stammers"
else if(derpspeech)
. = "gibbers"
/mob/living/whisper(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
say("#[message]", bubble_type, spans, sanitize, language, ignore_spam, forced)
+2 -1
View File
@@ -783,7 +783,7 @@
/mob/living/silicon/ai/can_buckle()
return 0
/mob/living/silicon/ai/incapacitated()
/mob/living/silicon/ai/incapacitated(ignore_restraints, ignore_grab)
if(aiRestorePowerRoutine)
return TRUE
return ..()
@@ -882,6 +882,7 @@
/mob/living/silicon/ai/revive(full_heal = 0, admin_revive = 0)
. = ..()
if(.) //successfully ressuscitated from death
set_eyeobj_visible(TRUE)
set_core_display_icon(display_icon_override)
/mob/living/silicon/ai/proc/malfhacked(obj/machinery/power/apc/apc)
@@ -18,6 +18,7 @@
update_canmove()
if(eyeobj)
eyeobj.setLoc(get_turf(src))
set_eyeobj_visible(FALSE)
GLOB.shuttle_caller_list -= src
SSshuttle.autoEvac()
@@ -36,6 +37,8 @@
if(istype(loc, /obj/item/aicard/aitater))
loc.icon_state = "aitater-404"
else if(istype(loc, /obj/item/aicard/aispook))
loc.icon_state = "aispook-404"
else if(istype(loc, /obj/item/aicard))
loc.icon_state = "aicard-404"
@@ -6,6 +6,8 @@
/mob/camera/aiEye
name = "Inactive AI Eye"
icon_state = "ai_camera"
icon = 'icons/mob/cameramob.dmi'
invisibility = INVISIBILITY_MAXIMUM
hud_possible = list(ANTAG_HUD, AI_DETECT_HUD = HUD_LIST_LIST)
var/list/visibleCameraChunks = list()
@@ -158,11 +160,11 @@
cameraFollow = null
unset_machine()
if(!eyeobj || !eyeobj.loc || QDELETED(eyeobj))
if(isturf(loc) && (QDELETED(eyeobj) || !eyeobj.loc))
to_chat(src, "ERROR: Eyeobj not found. Creating new eye...")
create_eye()
eyeobj.setLoc(loc)
eyeobj?.setLoc(loc)
/mob/living/silicon/ai/proc/create_eye()
if(eyeobj)
@@ -172,6 +174,13 @@
eyeobj.ai = src
eyeobj.setLoc(loc)
eyeobj.name = "[name] (AI Eye)"
set_eyeobj_visible(TRUE)
/mob/living/silicon/ai/proc/set_eyeobj_visible(state = TRUE)
if(!eyeobj)
return
eyeobj.mouse_opacity = state ? MOUSE_OPACITY_ICON : initial(eyeobj.mouse_opacity)
eyeobj.invisibility = state ? INVISIBILITY_OBSERVER : initial(eyeobj.invisibility)
/mob/living/silicon/ai/verb/toggle_acceleration()
set category = "AI Commands"
+1 -1
View File
@@ -19,7 +19,7 @@
// messenging the client
malfhacked(malfhack)
if(!eyeobj || QDELETED(eyeobj) || !eyeobj.loc)
if(isturf(loc) && (QDELETED(eyeobj) || !eyeobj.loc))
view_core()
if(machine)
@@ -6,6 +6,7 @@
O.mode = 1
O.emotion = "Neutral"
O.update()
set_eyeobj_visible(TRUE)
if(multicam_on)
end_multicam()
view_core()
@@ -4,4 +4,5 @@
var/obj/machinery/status_display/ai/O = each
O.mode = 0
O.update()
set_eyeobj_visible(FALSE)
view_core()
@@ -120,6 +120,9 @@ GLOBAL_DATUM(ai_camera_room_landmark, /obj/effect/landmark/ai_multicam_room)
/mob/camera/aiEye/pic_in_pic
name = "Secondary AI Eye"
invisibility = INVISIBILITY_OBSERVER
mouse_opacity = MOUSE_OPACITY_ICON
icon_state = "ai_pip_camera"
var/obj/screen/movable/pic_in_pic/ai/screen
var/list/cameras_telegraphed = list()
var/telegraph_cameras = TRUE
+1 -1
View File
@@ -49,7 +49,7 @@
else
padloc = "(UNKNOWN)"
src.log_talk(message, LOG_SAY, tag="HOLOPAD in [padloc]")
send_speech(message, 7, T, "robot", message_language = language)
send_speech(message, 7, T, "robot", language)
to_chat(src, "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> <span class='message robot'>\"[message]\"</span></span></i>")
else
to_chat(src, "No holopad connected.")
@@ -975,4 +975,635 @@ GLOBAL_LIST_INIT(vox_sounds, list("abduction" = 'sound/vox_fem/abduction.ogg',
"zombie" = 'sound/vox_fem/zombie.ogg',
"zone" = 'sound/vox_fem/zone.ogg',
"zulu" = 'sound/vox_fem/zulu.ogg'))
//for vim
// :%s/\(\(.*\)\.ogg\)/"\2" = 'sound\/vox\/\1',/g
GLOBAL_LIST_INIT(vox_sounds_male, list("," = 'sound/vox/_comma.ogg',
"." = 'sound/vox/_period.ogg',
"a" = 'sound/vox/a.ogg',
"accelerating" = 'sound/vox/accelerating.ogg',
"accelerator" = 'sound/vox/accelerator.ogg',
"accepted" = 'sound/vox/accepted.ogg',
"access" = 'sound/vox/access.ogg',
"acknowledge" = 'sound/vox/acknowledge.ogg',
"acknowledged" = 'sound/vox/acknowledged.ogg',
"acquired" = 'sound/vox/acquired.ogg',
"acquisition" = 'sound/vox/acquisition.ogg',
"across" = 'sound/vox/across.ogg',
"activate" = 'sound/vox/activate.ogg',
"activated" = 'sound/vox/activated.ogg',
"activity" = 'sound/vox/activity.ogg',
"adios" = 'sound/vox/adios.ogg',
"administration" = 'sound/vox/administration.ogg',
"advanced" = 'sound/vox/advanced.ogg',
"after" = 'sound/vox/after.ogg',
"agent" = 'sound/vox/agent.ogg',
"alarm" = 'sound/vox/alarm.ogg',
"alert" = 'sound/vox/alert.ogg',
"alien" = 'sound/vox/alien.ogg',
"aligned" = 'sound/vox/aligned.ogg',
"all" = 'sound/vox/all.ogg',
"alpha" = 'sound/vox/alpha.ogg',
"am" = 'sound/vox/am.ogg',
"amigo" = 'sound/vox/amigo.ogg',
"ammunition" = 'sound/vox/ammunition.ogg',
"an" = 'sound/vox/an.ogg',
"and" = 'sound/vox/and.ogg',
"announcement" = 'sound/vox/announcement.ogg',
"anomalous" = 'sound/vox/anomalous.ogg',
"antenna" = 'sound/vox/antenna.ogg',
"any" = 'sound/vox/any.ogg',
"apprehend" = 'sound/vox/apprehend.ogg',
"approach" = 'sound/vox/approach.ogg',
"are" = 'sound/vox/are.ogg',
"area" = 'sound/vox/area.ogg',
"arm" = 'sound/vox/arm.ogg',
"armed" = 'sound/vox/armed.ogg',
"armor" = 'sound/vox/armor.ogg',
"armory" = 'sound/vox/armory.ogg',
"arrest" = 'sound/vox/arrest.ogg',
"ass" = 'sound/vox/ass.ogg',
"at" = 'sound/vox/at.ogg',
"atomic" = 'sound/vox/atomic.ogg',
"attention" = 'sound/vox/attention.ogg',
"authorize" = 'sound/vox/authorize.ogg',
"authorized" = 'sound/vox/authorized.ogg',
"automatic" = 'sound/vox/automatic.ogg',
"away" = 'sound/vox/away.ogg',
"b" = 'sound/vox/b.ogg',
"back" = 'sound/vox/back.ogg',
"backman" = 'sound/vox/backman.ogg',
"bad" = 'sound/vox/bad.ogg',
"bag" = 'sound/vox/bag.ogg',
"bailey" = 'sound/vox/bailey.ogg',
"barracks" = 'sound/vox/barracks.ogg',
"base" = 'sound/vox/base.ogg',
"bay" = 'sound/vox/bay.ogg',
"be" = 'sound/vox/be.ogg',
"been" = 'sound/vox/been.ogg',
"before" = 'sound/vox/before.ogg',
"beyond" = 'sound/vox/beyond.ogg',
"biohazard" = 'sound/vox/biohazard.ogg',
"biological" = 'sound/vox/biological.ogg',
"birdwell" = 'sound/vox/birdwell.ogg',
"bizwarn" = 'sound/vox/bizwarn.ogg',
"black" = 'sound/vox/black.ogg',
"blast" = 'sound/vox/blast.ogg',
"blocked" = 'sound/vox/blocked.ogg',
"bloop" = 'sound/vox/bloop.ogg',
"blue" = 'sound/vox/blue.ogg',
"bottom" = 'sound/vox/bottom.ogg',
"bravo" = 'sound/vox/bravo.ogg',
"breach" = 'sound/vox/breach.ogg',
"breached" = 'sound/vox/breached.ogg',
"break" = 'sound/vox/break.ogg',
"bridge" = 'sound/vox/bridge.ogg',
"bust" = 'sound/vox/bust.ogg',
"but" = 'sound/vox/but.ogg',
"button" = 'sound/vox/button.ogg',
"buzwarn" = 'sound/vox/buzwarn.ogg',
"bypass" = 'sound/vox/bypass.ogg',
"c" = 'sound/vox/c.ogg',
"cable" = 'sound/vox/cable.ogg',
"call" = 'sound/vox/call.ogg',
"called" = 'sound/vox/called.ogg',
"canal" = 'sound/vox/canal.ogg',
"cap" = 'sound/vox/cap.ogg',
"captain" = 'sound/vox/captain.ogg',
"capture" = 'sound/vox/capture.ogg',
"captured" = 'sound/vox/captured.ogg',
"ceiling" = 'sound/vox/ceiling.ogg',
"celsius" = 'sound/vox/celsius.ogg',
"center" = 'sound/vox/center.ogg',
"centi" = 'sound/vox/centi.ogg',
"central" = 'sound/vox/central.ogg',
"chamber" = 'sound/vox/chamber.ogg',
"charlie" = 'sound/vox/charlie.ogg',
"check" = 'sound/vox/check.ogg',
"checkpoint" = 'sound/vox/checkpoint.ogg',
"chemical" = 'sound/vox/chemical.ogg',
"cleanup" = 'sound/vox/cleanup.ogg',
"clear" = 'sound/vox/clear.ogg',
"clearance" = 'sound/vox/clearance.ogg',
"close" = 'sound/vox/close.ogg',
"clown" = 'sound/vox/clown.ogg',
"code" = 'sound/vox/code.ogg',
"coded" = 'sound/vox/coded.ogg',
"collider" = 'sound/vox/collider.ogg',
"command" = 'sound/vox/command.ogg',
"communication" = 'sound/vox/communication.ogg',
"complex" = 'sound/vox/complex.ogg',
"computer" = 'sound/vox/computer.ogg',
"condition" = 'sound/vox/condition.ogg',
"containment" = 'sound/vox/containment.ogg',
"contamination" = 'sound/vox/contamination.ogg',
"control" = 'sound/vox/control.ogg',
"coolant" = 'sound/vox/coolant.ogg',
"coomer" = 'sound/vox/coomer.ogg',
"core" = 'sound/vox/core.ogg',
"correct" = 'sound/vox/correct.ogg',
"corridor" = 'sound/vox/corridor.ogg',
"crew" = 'sound/vox/crew.ogg',
"cross" = 'sound/vox/cross.ogg',
"cryogenic" = 'sound/vox/cryogenic.ogg',
"d" = 'sound/vox/d.ogg',
"dadeda" = 'sound/vox/dadeda.ogg',
"damage" = 'sound/vox/damage.ogg',
"damaged" = 'sound/vox/damaged.ogg',
"danger" = 'sound/vox/danger.ogg',
"day" = 'sound/vox/day.ogg',
"deactivated" = 'sound/vox/deactivated.ogg',
"decompression" = 'sound/vox/decompression.ogg',
"decontamination" = 'sound/vox/decontamination.ogg',
"deeoo" = 'sound/vox/deeoo.ogg',
"defense" = 'sound/vox/defense.ogg',
"degrees" = 'sound/vox/degrees.ogg',
"delta" = 'sound/vox/delta.ogg',
"denied" = 'sound/vox/denied.ogg',
"deploy" = 'sound/vox/deploy.ogg',
"deployed" = 'sound/vox/deployed.ogg',
"destroy" = 'sound/vox/destroy.ogg',
"destroyed" = 'sound/vox/destroyed.ogg',
"detain" = 'sound/vox/detain.ogg',
"detected" = 'sound/vox/detected.ogg',
"detonation" = 'sound/vox/detonation.ogg',
"device" = 'sound/vox/device.ogg',
"did" = 'sound/vox/did.ogg',
"die" = 'sound/vox/die.ogg',
"dimensional" = 'sound/vox/dimensional.ogg',
"dirt" = 'sound/vox/dirt.ogg',
"disengaged" = 'sound/vox/disengaged.ogg',
"dish" = 'sound/vox/dish.ogg',
"disposal" = 'sound/vox/disposal.ogg',
"distance" = 'sound/vox/distance.ogg',
"distortion" = 'sound/vox/distortion.ogg',
"do" = 'sound/vox/do.ogg',
"doctor" = 'sound/vox/doctor.ogg',
"doop" = 'sound/vox/doop.ogg',
"door" = 'sound/vox/door.ogg',
"down" = 'sound/vox/down.ogg',
"dual" = 'sound/vox/dual.ogg',
"duct" = 'sound/vox/duct.ogg',
"e" = 'sound/vox/e.ogg',
"east" = 'sound/vox/east.ogg',
"echo" = 'sound/vox/echo.ogg',
"ed" = 'sound/vox/ed.ogg',
"effect" = 'sound/vox/effect.ogg',
"egress" = 'sound/vox/egress.ogg',
"eight" = 'sound/vox/eight.ogg',
"eighteen" = 'sound/vox/eighteen.ogg',
"eighty" = 'sound/vox/eighty.ogg',
"electric" = 'sound/vox/electric.ogg',
"electromagnetic" = 'sound/vox/electromagnetic.ogg',
"elevator" = 'sound/vox/elevator.ogg',
"eleven" = 'sound/vox/eleven.ogg',
"eliminate" = 'sound/vox/eliminate.ogg',
"emergency" = 'sound/vox/emergency.ogg',
"enemy" = 'sound/vox/enemy.ogg',
"energy" = 'sound/vox/energy.ogg',
"engage" = 'sound/vox/engage.ogg',
"engaged" = 'sound/vox/engaged.ogg',
"engine" = 'sound/vox/engine.ogg',
"enter" = 'sound/vox/enter.ogg',
"entry" = 'sound/vox/entry.ogg',
"environment" = 'sound/vox/environment.ogg',
"error" = 'sound/vox/error.ogg',
"escape" = 'sound/vox/escape.ogg',
"evacuate" = 'sound/vox/evacuate.ogg',
"exchange" = 'sound/vox/exchange.ogg',
"exit" = 'sound/vox/exit.ogg',
"expect" = 'sound/vox/expect.ogg',
"experiment" = 'sound/vox/experiment.ogg',
"experimental" = 'sound/vox/experimental.ogg',
"explode" = 'sound/vox/explode.ogg',
"explosion" = 'sound/vox/explosion.ogg',
"exposure" = 'sound/vox/exposure.ogg',
"exterminate" = 'sound/vox/exterminate.ogg',
"extinguish" = 'sound/vox/extinguish.ogg',
"extinguisher" = 'sound/vox/extinguisher.ogg',
"extreme" = 'sound/vox/extreme.ogg',
"f" = 'sound/vox/f.ogg',
"face" = 'sound/vox/face.ogg',
"facility" = 'sound/vox/facility.ogg',
"fahrenheit" = 'sound/vox/fahrenheit.ogg',
"failed" = 'sound/vox/failed.ogg',
"failure" = 'sound/vox/failure.ogg',
"farthest" = 'sound/vox/farthest.ogg',
"fast" = 'sound/vox/fast.ogg',
"feet" = 'sound/vox/feet.ogg',
"field" = 'sound/vox/field.ogg',
"fifteen" = 'sound/vox/fifteen.ogg',
"fifth" = 'sound/vox/fifth.ogg',
"fifty" = 'sound/vox/fifty.ogg',
"final" = 'sound/vox/final.ogg',
"fine" = 'sound/vox/fine.ogg',
"fire" = 'sound/vox/fire.ogg',
"first" = 'sound/vox/first.ogg',
"five" = 'sound/vox/five.ogg',
"flag" = 'sound/vox/flag.ogg',
"flooding" = 'sound/vox/flooding.ogg',
"floor" = 'sound/vox/floor.ogg',
"fool" = 'sound/vox/fool.ogg',
"for" = 'sound/vox/for.ogg',
"forbidden" = 'sound/vox/forbidden.ogg',
"force" = 'sound/vox/force.ogg',
"forms" = 'sound/vox/forms.ogg',
"found" = 'sound/vox/found.ogg',
"four" = 'sound/vox/four.ogg',
"fourteen" = 'sound/vox/fourteen.ogg',
"fourth" = 'sound/vox/fourth.ogg',
"fourty" = 'sound/vox/fourty.ogg',
"foxtrot" = 'sound/vox/foxtrot.ogg',
"freeman" = 'sound/vox/freeman.ogg',
"freezer" = 'sound/vox/freezer.ogg',
"from" = 'sound/vox/from.ogg',
"front" = 'sound/vox/front.ogg',
"fuel" = 'sound/vox/fuel.ogg',
"g" = 'sound/vox/g.ogg',
"gay" = 'sound/vox/gay.ogg',
"get" = 'sound/vox/get.ogg',
"go" = 'sound/vox/go.ogg',
"going" = 'sound/vox/going.ogg',
"good" = 'sound/vox/good.ogg',
"goodbye" = 'sound/vox/goodbye.ogg',
"gordon" = 'sound/vox/gordon.ogg',
"got" = 'sound/vox/got.ogg',
"government" = 'sound/vox/government.ogg',
"granted" = 'sound/vox/granted.ogg',
"great" = 'sound/vox/great.ogg',
"green" = 'sound/vox/green.ogg',
"grenade" = 'sound/vox/grenade.ogg',
"guard" = 'sound/vox/guard.ogg',
"gulf" = 'sound/vox/gulf.ogg',
"gun" = 'sound/vox/gun.ogg',
"guthrie" = 'sound/vox/guthrie.ogg',
"handling" = 'sound/vox/handling.ogg',
"hangar" = 'sound/vox/hangar.ogg',
"has" = 'sound/vox/has.ogg',
"have" = 'sound/vox/have.ogg',
"hazard" = 'sound/vox/hazard.ogg',
"head" = 'sound/vox/head.ogg',
"health" = 'sound/vox/health.ogg',
"heat" = 'sound/vox/heat.ogg',
"helicopter" = 'sound/vox/helicopter.ogg',
"helium" = 'sound/vox/helium.ogg',
"hello" = 'sound/vox/hello.ogg',
"help" = 'sound/vox/help.ogg',
"here" = 'sound/vox/here.ogg',
"hide" = 'sound/vox/hide.ogg',
"high" = 'sound/vox/high.ogg',
"highest" = 'sound/vox/highest.ogg',
"hit" = 'sound/vox/hit.ogg',
"holds" = 'sound/vox/holds.ogg',
"hole" = 'sound/vox/hole.ogg',
"hostile" = 'sound/vox/hostile.ogg',
"hot" = 'sound/vox/hot.ogg',
"hotel" = 'sound/vox/hotel.ogg',
"hour" = 'sound/vox/hour.ogg',
"hours" = 'sound/vox/hours.ogg',
"hundred" = 'sound/vox/hundred.ogg',
"hydro" = 'sound/vox/hydro.ogg',
"i" = 'sound/vox/i.ogg',
"idiot" = 'sound/vox/idiot.ogg',
"illegal" = 'sound/vox/illegal.ogg',
"immediate" = 'sound/vox/immediate.ogg',
"immediately" = 'sound/vox/immediately.ogg',
"in" = 'sound/vox/in.ogg',
"inches" = 'sound/vox/inches.ogg',
"india" = 'sound/vox/india.ogg',
"ing" = 'sound/vox/ing.ogg',
"inoperative" = 'sound/vox/inoperative.ogg',
"inside" = 'sound/vox/inside.ogg',
"inspection" = 'sound/vox/inspection.ogg',
"inspector" = 'sound/vox/inspector.ogg',
"interchange" = 'sound/vox/interchange.ogg',
"intruder" = 'sound/vox/intruder.ogg',
"invallid" = 'sound/vox/invallid.ogg',
"invasion" = 'sound/vox/invasion.ogg',
"is" = 'sound/vox/is.ogg',
"it" = 'sound/vox/it.ogg',
"johnson" = 'sound/vox/johnson.ogg',
"juliet" = 'sound/vox/juliet.ogg',
"key" = 'sound/vox/key.ogg',
"kill" = 'sound/vox/kill.ogg',
"kilo" = 'sound/vox/kilo.ogg',
"kit" = 'sound/vox/kit.ogg',
"lab" = 'sound/vox/lab.ogg',
"lambda" = 'sound/vox/lambda.ogg',
"laser" = 'sound/vox/laser.ogg',
"last" = 'sound/vox/last.ogg',
"launch" = 'sound/vox/launch.ogg',
"leak" = 'sound/vox/leak.ogg',
"leave" = 'sound/vox/leave.ogg',
"left" = 'sound/vox/left.ogg',
"legal" = 'sound/vox/legal.ogg',
"level" = 'sound/vox/level.ogg',
"lever" = 'sound/vox/lever.ogg',
"lie" = 'sound/vox/lie.ogg',
"lieutenant" = 'sound/vox/lieutenant.ogg',
"life" = 'sound/vox/life.ogg',
"light" = 'sound/vox/light.ogg',
"lima" = 'sound/vox/lima.ogg',
"liquid" = 'sound/vox/liquid.ogg',
"loading" = 'sound/vox/loading.ogg',
"locate" = 'sound/vox/locate.ogg',
"located" = 'sound/vox/located.ogg',
"location" = 'sound/vox/location.ogg',
"lock" = 'sound/vox/lock.ogg',
"locked" = 'sound/vox/locked.ogg',
"locker" = 'sound/vox/locker.ogg',
"lockout" = 'sound/vox/lockout.ogg',
"lower" = 'sound/vox/lower.ogg',
"lowest" = 'sound/vox/lowest.ogg',
"magnetic" = 'sound/vox/magnetic.ogg',
"main" = 'sound/vox/main.ogg',
"maintenance" = 'sound/vox/maintenance.ogg',
"malfunction" = 'sound/vox/malfunction.ogg',
"man" = 'sound/vox/man.ogg',
"mass" = 'sound/vox/mass.ogg',
"materials" = 'sound/vox/materials.ogg',
"maximum" = 'sound/vox/maximum.ogg',
"may" = 'sound/vox/may.ogg',
"med" = 'sound/vox/med.ogg',
"medical" = 'sound/vox/medical.ogg',
"men" = 'sound/vox/men.ogg',
"mercy" = 'sound/vox/mercy.ogg',
"mesa" = 'sound/vox/mesa.ogg',
"message" = 'sound/vox/message.ogg',
"meter" = 'sound/vox/meter.ogg',
"micro" = 'sound/vox/micro.ogg',
"middle" = 'sound/vox/middle.ogg',
"mike" = 'sound/vox/mike.ogg',
"miles" = 'sound/vox/miles.ogg',
"military" = 'sound/vox/military.ogg',
"milli" = 'sound/vox/milli.ogg',
"million" = 'sound/vox/million.ogg',
"minefield" = 'sound/vox/minefield.ogg',
"minimum" = 'sound/vox/minimum.ogg',
"minutes" = 'sound/vox/minutes.ogg',
"mister" = 'sound/vox/mister.ogg',
"mode" = 'sound/vox/mode.ogg',
"motor" = 'sound/vox/motor.ogg',
"motorpool" = 'sound/vox/motorpool.ogg',
"move" = 'sound/vox/move.ogg',
"must" = 'sound/vox/must.ogg',
"nearest" = 'sound/vox/nearest.ogg',
"nice" = 'sound/vox/nice.ogg',
"nine" = 'sound/vox/nine.ogg',
"nineteen" = 'sound/vox/nineteen.ogg',
"ninety" = 'sound/vox/ninety.ogg',
"no" = 'sound/vox/no.ogg',
"nominal" = 'sound/vox/nominal.ogg',
"north" = 'sound/vox/north.ogg',
"not" = 'sound/vox/not.ogg',
"november" = 'sound/vox/november.ogg',
"now" = 'sound/vox/now.ogg',
"number" = 'sound/vox/number.ogg',
"objective" = 'sound/vox/objective.ogg',
"observation" = 'sound/vox/observation.ogg',
"of" = 'sound/vox/of.ogg',
"officer" = 'sound/vox/officer.ogg',
"ok" = 'sound/vox/ok.ogg',
"on" = 'sound/vox/on.ogg',
"one" = 'sound/vox/one.ogg',
"open" = 'sound/vox/open.ogg',
"operating" = 'sound/vox/operating.ogg',
"operations" = 'sound/vox/operations.ogg',
"operative" = 'sound/vox/operative.ogg',
"option" = 'sound/vox/option.ogg',
"order" = 'sound/vox/order.ogg',
"organic" = 'sound/vox/organic.ogg',
"oscar" = 'sound/vox/oscar.ogg',
"out" = 'sound/vox/out.ogg',
"outside" = 'sound/vox/outside.ogg',
"over" = 'sound/vox/over.ogg',
"overload" = 'sound/vox/overload.ogg',
"override" = 'sound/vox/override.ogg',
"pacify" = 'sound/vox/pacify.ogg',
"pain" = 'sound/vox/pain.ogg',
"pal" = 'sound/vox/pal.ogg',
"panel" = 'sound/vox/panel.ogg',
"percent" = 'sound/vox/percent.ogg',
"perimeter" = 'sound/vox/perimeter.ogg',
"permitted" = 'sound/vox/permitted.ogg',
"personnel" = 'sound/vox/personnel.ogg',
"pipe" = 'sound/vox/pipe.ogg',
"plant" = 'sound/vox/plant.ogg',
"platform" = 'sound/vox/platform.ogg',
"please" = 'sound/vox/please.ogg',
"point" = 'sound/vox/point.ogg',
"portal" = 'sound/vox/portal.ogg',
"power" = 'sound/vox/power.ogg',
"presence" = 'sound/vox/presence.ogg',
"press" = 'sound/vox/press.ogg',
"primary" = 'sound/vox/primary.ogg',
"proceed" = 'sound/vox/proceed.ogg',
"processing" = 'sound/vox/processing.ogg',
"progress" = 'sound/vox/progress.ogg',
"proper" = 'sound/vox/proper.ogg',
"propulsion" = 'sound/vox/propulsion.ogg',
"prosecute" = 'sound/vox/prosecute.ogg',
"protective" = 'sound/vox/protective.ogg',
"push" = 'sound/vox/push.ogg',
"quantum" = 'sound/vox/quantum.ogg',
"quebec" = 'sound/vox/quebec.ogg',
"question" = 'sound/vox/question.ogg',
"questioning" = 'sound/vox/questioning.ogg',
"quick" = 'sound/vox/quick.ogg',
"quit" = 'sound/vox/quit.ogg',
"radiation" = 'sound/vox/radiation.ogg',
"radioactive" = 'sound/vox/radioactive.ogg',
"rads" = 'sound/vox/rads.ogg',
"rapid" = 'sound/vox/rapid.ogg',
"reach" = 'sound/vox/reach.ogg',
"reached" = 'sound/vox/reached.ogg',
"reactor" = 'sound/vox/reactor.ogg',
"red" = 'sound/vox/red.ogg',
"relay" = 'sound/vox/relay.ogg',
"released" = 'sound/vox/released.ogg',
"remaining" = 'sound/vox/remaining.ogg',
"renegade" = 'sound/vox/renegade.ogg',
"repair" = 'sound/vox/repair.ogg',
"report" = 'sound/vox/report.ogg',
"reports" = 'sound/vox/reports.ogg',
"required" = 'sound/vox/required.ogg',
"research" = 'sound/vox/research.ogg',
"reset" = 'sound/vox/reset.ogg',
"resevoir" = 'sound/vox/resevoir.ogg',
"resistance" = 'sound/vox/resistance.ogg',
"returned" = 'sound/vox/returned.ogg',
"right" = 'sound/vox/right.ogg',
"rocket" = 'sound/vox/rocket.ogg',
"roger" = 'sound/vox/roger.ogg',
"romeo" = 'sound/vox/romeo.ogg',
"room" = 'sound/vox/room.ogg',
"round" = 'sound/vox/round.ogg',
"run" = 'sound/vox/run.ogg',
"safe" = 'sound/vox/safe.ogg',
"safety" = 'sound/vox/safety.ogg',
"sargeant" = 'sound/vox/sargeant.ogg',
"satellite" = 'sound/vox/satellite.ogg',
"save" = 'sound/vox/save.ogg',
"science" = 'sound/vox/science.ogg',
"scores" = 'sound/vox/scores.ogg',
"scream" = 'sound/vox/scream.ogg',
"screen" = 'sound/vox/screen.ogg',
"search" = 'sound/vox/search.ogg',
"second" = 'sound/vox/second.ogg',
"secondary" = 'sound/vox/secondary.ogg',
"seconds" = 'sound/vox/seconds.ogg',
"sector" = 'sound/vox/sector.ogg',
"secure" = 'sound/vox/secure.ogg',
"secured" = 'sound/vox/secured.ogg',
"security" = 'sound/vox/security.ogg',
"select" = 'sound/vox/select.ogg',
"selected" = 'sound/vox/selected.ogg',
"service" = 'sound/vox/service.ogg',
"seven" = 'sound/vox/seven.ogg',
"seventeen" = 'sound/vox/seventeen.ogg',
"seventy" = 'sound/vox/seventy.ogg',
"severe" = 'sound/vox/severe.ogg',
"sewage" = 'sound/vox/sewage.ogg',
"sewer" = 'sound/vox/sewer.ogg',
"shield" = 'sound/vox/shield.ogg',
"shipment" = 'sound/vox/shipment.ogg',
"shock" = 'sound/vox/shock.ogg',
"shoot" = 'sound/vox/shoot.ogg',
"shower" = 'sound/vox/shower.ogg',
"shut" = 'sound/vox/shut.ogg',
"side" = 'sound/vox/side.ogg',
"sierra" = 'sound/vox/sierra.ogg',
"sight" = 'sound/vox/sight.ogg',
"silo" = 'sound/vox/silo.ogg',
"six" = 'sound/vox/six.ogg',
"sixteen" = 'sound/vox/sixteen.ogg',
"sixty" = 'sound/vox/sixty.ogg',
"slime" = 'sound/vox/slime.ogg',
"slow" = 'sound/vox/slow.ogg',
"soldier" = 'sound/vox/soldier.ogg',
"some" = 'sound/vox/some.ogg',
"someone" = 'sound/vox/someone.ogg',
"something" = 'sound/vox/something.ogg',
"son" = 'sound/vox/son.ogg',
"sorry" = 'sound/vox/sorry.ogg',
"south" = 'sound/vox/south.ogg',
"squad" = 'sound/vox/squad.ogg',
"square" = 'sound/vox/square.ogg',
"stairway" = 'sound/vox/stairway.ogg',
"status" = 'sound/vox/status.ogg',
"sterile" = 'sound/vox/sterile.ogg',
"sterilization" = 'sound/vox/sterilization.ogg',
"stolen" = 'sound/vox/stolen.ogg',
"storage" = 'sound/vox/storage.ogg',
"sub" = 'sound/vox/sub.ogg',
"subsurface" = 'sound/vox/subsurface.ogg',
"sudden" = 'sound/vox/sudden.ogg',
"suit" = 'sound/vox/suit.ogg',
"superconducting" = 'sound/vox/superconducting.ogg',
"supercooled" = 'sound/vox/supercooled.ogg',
"supply" = 'sound/vox/supply.ogg',
"surface" = 'sound/vox/surface.ogg',
"surrender" = 'sound/vox/surrender.ogg',
"surround" = 'sound/vox/surround.ogg',
"surrounded" = 'sound/vox/surrounded.ogg',
"switch" = 'sound/vox/switch.ogg',
"system" = 'sound/vox/system.ogg',
"systems" = 'sound/vox/systems.ogg',
"tactical" = 'sound/vox/tactical.ogg',
"take" = 'sound/vox/take.ogg',
"talk" = 'sound/vox/talk.ogg',
"tango" = 'sound/vox/tango.ogg',
"tank" = 'sound/vox/tank.ogg',
"target" = 'sound/vox/target.ogg',
"team" = 'sound/vox/team.ogg',
"temperature" = 'sound/vox/temperature.ogg',
"temporal" = 'sound/vox/temporal.ogg',
"ten" = 'sound/vox/ten.ogg',
"terminal" = 'sound/vox/terminal.ogg',
"terminated" = 'sound/vox/terminated.ogg',
"termination" = 'sound/vox/termination.ogg',
"test" = 'sound/vox/test.ogg',
"that" = 'sound/vox/that.ogg',
"the" = 'sound/vox/the.ogg',
"then" = 'sound/vox/then.ogg',
"there" = 'sound/vox/there.ogg',
"third" = 'sound/vox/third.ogg',
"thirteen" = 'sound/vox/thirteen.ogg',
"thirty" = 'sound/vox/thirty.ogg',
"this" = 'sound/vox/this.ogg',
"those" = 'sound/vox/those.ogg',
"thousand" = 'sound/vox/thousand.ogg',
"threat" = 'sound/vox/threat.ogg',
"three" = 'sound/vox/three.ogg',
"through" = 'sound/vox/through.ogg',
"time" = 'sound/vox/time.ogg',
"to" = 'sound/vox/to.ogg',
"top" = 'sound/vox/top.ogg',
"topside" = 'sound/vox/topside.ogg',
"touch" = 'sound/vox/touch.ogg',
"towards" = 'sound/vox/towards.ogg',
"track" = 'sound/vox/track.ogg',
"train" = 'sound/vox/train.ogg',
"transportation" = 'sound/vox/transportation.ogg',
"truck" = 'sound/vox/truck.ogg',
"tunnel" = 'sound/vox/tunnel.ogg',
"turn" = 'sound/vox/turn.ogg',
"turret" = 'sound/vox/turret.ogg',
"twelve" = 'sound/vox/twelve.ogg',
"twenty" = 'sound/vox/twenty.ogg',
"two" = 'sound/vox/two.ogg',
"unauthorized" = 'sound/vox/unauthorized.ogg',
"under" = 'sound/vox/under.ogg',
"uniform" = 'sound/vox/uniform.ogg',
"unlocked" = 'sound/vox/unlocked.ogg',
"until" = 'sound/vox/until.ogg',
"up" = 'sound/vox/up.ogg',
"upper" = 'sound/vox/upper.ogg',
"uranium" = 'sound/vox/uranium.ogg',
"us" = 'sound/vox/us.ogg',
"usa" = 'sound/vox/usa.ogg',
"use" = 'sound/vox/use.ogg',
"used" = 'sound/vox/used.ogg',
"user" = 'sound/vox/user.ogg',
"vacate" = 'sound/vox/vacate.ogg',
"valid" = 'sound/vox/valid.ogg',
"vapor" = 'sound/vox/vapor.ogg',
"vent" = 'sound/vox/vent.ogg',
"ventillation" = 'sound/vox/ventillation.ogg',
"victor" = 'sound/vox/victor.ogg',
"violated" = 'sound/vox/violated.ogg',
"violation" = 'sound/vox/violation.ogg',
"voltage" = 'sound/vox/voltage.ogg',
"vox_login" = 'sound/vox/vox_login.ogg',
"walk" = 'sound/vox/walk.ogg',
"wall" = 'sound/vox/wall.ogg',
"want" = 'sound/vox/want.ogg',
"wanted" = 'sound/vox/wanted.ogg',
"warm" = 'sound/vox/warm.ogg',
"warn" = 'sound/vox/warn.ogg',
"warning" = 'sound/vox/warning.ogg',
"waste" = 'sound/vox/waste.ogg',
"water" = 'sound/vox/water.ogg',
"we" = 'sound/vox/we.ogg',
"weapon" = 'sound/vox/weapon.ogg',
"west" = 'sound/vox/west.ogg',
"whiskey" = 'sound/vox/whiskey.ogg',
"white" = 'sound/vox/white.ogg',
"wilco" = 'sound/vox/wilco.ogg',
"will" = 'sound/vox/will.ogg',
"with" = 'sound/vox/with.ogg',
"without" = 'sound/vox/without.ogg',
"woop" = 'sound/vox/woop.ogg',
"xeno" = 'sound/vox/xeno.ogg',
"yankee" = 'sound/vox/yankee.ogg',
"yards" = 'sound/vox/yards.ogg',
"year" = 'sound/vox/year.ogg',
"yellow" = 'sound/vox/yellow.ogg',
"yes" = 'sound/vox/yes.ogg',
"you" = 'sound/vox/you.ogg',
"your" = 'sound/vox/your.ogg',
"yourself" = 'sound/vox/yourself.ogg',
"zero" = 'sound/vox/zero.ogg',
"zone" = 'sound/vox/zone.ogg',
"zulu" = 'sound/vox/zulu.ogg',))
#endif
@@ -1,16 +1,17 @@
/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE)
/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
var/hit_percent = (100-blocked)/100
if(!damage || (hit_percent <= 0))
if(!damage || (!forced && hit_percent <= 0))
return 0
var/damage_amount = forced ? damage : damage * hit_percent
switch(damagetype)
if(BRUTE)
adjustBruteLoss(damage * hit_percent)
adjustBruteLoss(damage_amount, forced = forced)
if(BURN)
adjustFireLoss(damage * hit_percent)
adjustFireLoss(damage_amount, forced = forced)
if(OXY)
if(damage < 0) //we shouldn't be taking oxygen damage through this proc, but we'll let it heal.
adjustOxyLoss(damage * hit_percent)
if(damage < 0 || forced) //we shouldn't be taking oxygen damage through this proc, but we'll let it heal.
adjustOxyLoss(damage_amount, forced = forced)
return 1
@@ -29,7 +30,7 @@
/mob/living/silicon/setCloneLoss(amount, updating_health = TRUE, forced = FALSE)
return FALSE
/mob/living/silicon/adjustStaminaLoss(amount, updating_stamina = 1)//immune to stamina damage.
/mob/living/silicon/adjustStaminaLoss(amount, updating_stamina = 1, forced = FALSE)//immune to stamina damage.
return FALSE
/mob/living/silicon/setStaminaLoss(amount, updating_stamina = 1)
+2 -2
View File
@@ -1,5 +1,5 @@
/mob/living/silicon/spawn_gibs()
new /obj/effect/gibspawner/robot(drop_location())
/mob/living/silicon/spawn_gibs(with_bodyparts, atom/loc_override)
new /obj/effect/gibspawner/robot(loc_override ? loc_override.drop_location() : drop_location(), src)
/mob/living/silicon/spawn_dust()
new /obj/effect/decal/remains/robot(loc)
@@ -81,8 +81,11 @@
/mob/living/silicon/pai/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE)
return FALSE
/mob/living/silicon/pai/adjustStaminaLoss(amount)
take_holo_damage(amount & 0.25)
/mob/living/silicon/pai/adjustStaminaLoss(amount, updating_health, forced = FALSE)
if(forced)
take_holo_damage(amount)
else
take_holo_damage(amount * 0.25)
/mob/living/silicon/pai/adjustOrganLoss(slot, amount, maximum = 500) //I kept this in, unlike tg
Knockdown(amount * 0.2)
@@ -140,7 +140,7 @@
radio.attack_self(src)
if("image")
var/newImage = input("Select your new display image.", "Display Image", "Happy") in list("Happy", "Cat", "Extremely Happy", "Face", "Laugh", "Off", "Sad", "Angry", "What" , "Exclamation" ,"Question") // CITADEL EDIT
var/newImage = input("Select your new display image.", "Display Image", "Happy") in list("Happy", "Cat", "Extremely Happy", "Face", "Laugh", "Off", "Sad", "Angry", "What" , "Exclamation" ,"Question", "Sunglasses")
var/pID = 1
switch(newImage)
@@ -164,10 +164,12 @@
pID = 9
if("Null")
pID = 10
if("Exclamation") // CITADEL EDIT
if("Exclamation")
pID = 11
if("Question") // CITADEL EDIT
if("Question")
pID = 12
if("Sunglasses")
pID = 13
card.setEmotion(pID)
if("signaller")
@@ -1,5 +1,5 @@
/mob/living/silicon/robot/examine(mob/user)
var/msg = "<span class='info'>*---------*\nThis is [icon2html(src, user)] \a <EM>[src]</EM>, a [src.module.name]!\n"
var/msg = "<span class='info'>*---------*\nThis is [icon2html(src, user)] \a <EM>[src]</EM>, a [src.module.name] unit!\n"
if(desc)
msg += "[desc]\n"
+38 -9
View File
@@ -110,6 +110,7 @@
var/sitting = 0
var/bellyup = 0
var/dogborg = FALSE
/mob/living/silicon/robot/get_cell()
return cell
@@ -226,18 +227,20 @@
to_chat(src,"<span class='userdanger'>ERROR: Module installer reply timeout. Please check internal connections.</span>")
return
if(!CONFIG_GET(flag/disable_secborg) && GLOB.security_level < CONFIG_GET(number/minimum_secborg_alert))
to_chat(src, "<span class='notice'>NOTICE: Due to local station regulations, the security cyborg module and its variants are only available during [num2seclevel(CONFIG_GET(number/minimum_secborg_alert))] alert and greater.</span>")
var/list/modulelist = list("Standard" = /obj/item/robot_module/standard, \
"Engineering" = /obj/item/robot_module/engineering, \
"Medical" = /obj/item/robot_module/medical, \
"Medihound" = /obj/item/robot_module/medihound, \
"Miner" = /obj/item/robot_module/miner, \
"Janitor" = /obj/item/robot_module/janitor, \
"Service" = /obj/item/robot_module/butler)
if(!CONFIG_GET(flag/disable_peaceborg))
modulelist["Peacekeeper"] = /obj/item/robot_module/peacekeeper
if(!CONFIG_GET(flag/disable_secborg))
if(BORG_SEC_AVAILABLE)
modulelist["Security"] = /obj/item/robot_module/security
modulelist += get_cit_modules() //Citadel change - adds Citadel's borg modules.
modulelist["Security K-9"] = /obj/item/robot_module/k9
var/input_module = input("Please, select a module!", "Robot", null, null) as null|anything in modulelist
if(!input_module || module.type != /obj/item/robot_module)
@@ -876,9 +879,6 @@
/mob/living/silicon/robot/modules/miner
set_module = /obj/item/robot_module/miner
/mob/living/silicon/robot/modules/janitor
set_module = /obj/item/robot_module/janitor
/mob/living/silicon/robot/modules/syndicate
icon_state = "synd_sec"
faction = list(ROLE_SYNDICATE)
@@ -917,6 +917,17 @@
<i>Help the operatives secure the disk at all costs!</i></b>"
set_module = /obj/item/robot_module/syndicate_medical
/mob/living/silicon/robot/modules/syndicate/saboteur
icon_state = "synd_engi"
playstyle_string = "<span class='big bold'>You are a Syndicate saboteur cyborg!</span><br>\
<b>You are armed with robust engineering tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \
Your destination tagger will allow you to stealthily traverse the disposal network across the station \
Your welder will allow you to repair the operatives' exosuits, but also yourself and your fellow cyborgs \
Your cyborg chameleon projector allows you to assume the appearance and registered name of a Nanotrasen engineering borg, and undertake covert actions on the station \
Be aware that almost any physical contact or incidental damage will break your camouflage \
<i>Help the operatives secure the disk at all costs!</i></b>"
set_module = /obj/item/robot_module/saboteur
/mob/living/silicon/robot/proc/notify_ai(notifytype, oldname, newname)
if(!connected_ai)
return
@@ -1230,7 +1241,7 @@
/mob/living/silicon/robot/unbuckle_mob(mob/user, force=FALSE)
if(iscarbon(user))
GET_COMPONENT(riding_datum, /datum/component/riding)
var/datum/component/riding/riding_datum = GetComponent(/datum/component/riding)
if(istype(riding_datum))
riding_datum.unequip_buckle_inhands(user)
riding_datum.restore_position(user)
@@ -1253,6 +1264,20 @@
for(var/i in connected_ai.aicamera.stored)
aicamera.stored[i] = TRUE
/mob/living/silicon/robot/lay_down()
..()
update_canmove()
/mob/living/silicon/robot/update_canmove()
..()
if(client && stat != DEAD && dogborg == FALSE)
if(resting)
cut_overlays()
icon_state = "[module.cyborg_base_icon]-rest"
else
icon_state = "[module.cyborg_base_icon]"
update_icons()
/mob/living/silicon/robot/proc/rest_style()
set name = "Switch Rest Style"
set category = "Robot Commands"
@@ -1268,4 +1293,8 @@
sitting = 1
if("Belly up")
bellyup = 1
update_icons()
update_icons()
/mob/living/silicon/robot/adjustStaminaLossBuffered(amount, updating_stamina = 1)
if(istype(cell))
cell.charge -= amount*5
@@ -8,6 +8,8 @@
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
flags_1 = CONDUCT_1
var/borghealth = 100
var/list/basic_modules = list() //a list of paths, converted to a list of instances on New()
var/list/emag_modules = list() //ditto
var/list/ratvar_modules = list() //ditto ditto
@@ -32,6 +34,14 @@
var/list/ride_offset_y = list("north" = 4, "south" = 4, "east" = 3, "west" = 3)
var/ride_allow_incapacitated = FALSE
var/allow_riding = TRUE
var/canDispose = FALSE // Whether the borg can stuff itself into disposal
var/sleeper_overlay
var/icon/cyborg_icon_override
var/has_snowflake_deadsprite
var/cyborg_pixel_offset
var/moduleselect_alternate_icon
var/dogborg = FALSE
/obj/item/robot_module/Initialize()
. = ..()
@@ -127,6 +137,28 @@
rebuild_modules()
return I
//Adds flavoursome dogborg items to dogborg variants without mechanical benefits
/obj/item/robot_module/proc/dogborg_equip()
if(istype(src, /obj/item/robot_module/k9) || istype(src, /obj/item/robot_module/medihound))
return //Bandaid fix to prevent stacking until I merge these two modules into their base types
var/obj/item/I = new /obj/item/analyzer/nose/flavour(src)
basic_modules += I
I = new /obj/item/soap/tongue/flavour(src)
basic_modules += I
I = new /obj/item/dogborg/sleeper/K9/flavour(src)
if(istype(src, /obj/item/robot_module/engineering))
I.icon_state = "decompiler"
if(istype(src, /obj/item/robot_module/security))
I.icon_state = "sleeperb"
if(istype(src, /obj/item/robot_module/medical))
I.icon_state = "sleeper"
if(istype(src, /obj/item/robot_module/butler))
I.icon_state = "servicer"
if(cyborg_base_icon == "scrubpup")
I.icon_state = "compactor"
basic_modules += I
rebuild_modules()
/obj/item/robot_module/proc/remove_module(obj/item/I, delete_after)
basic_modules -= I
modules -= I
@@ -195,6 +227,10 @@
R.update_module_innate()
RM.rebuild_modules()
INVOKE_ASYNC(RM, .proc/do_transform_animation)
if(RM.dogborg)
RM.dogborg_equip()
R.maxHealth = borghealth
R.health = min(borghealth, R.health)
qdel(src)
return RM
@@ -241,15 +277,15 @@
name = "Standard"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/reagent_containers/borghypo/epi,
/obj/item/healthanalyzer,
/obj/item/weldingtool/largetank/cyborg,
/obj/item/wrench/cyborg,
/obj/item/crowbar/cyborg,
/obj/item/stack/sheet/metal/cyborg,
/obj/item/stack/rods/cyborg,
/obj/item/stack/tile/plasteel/cyborg,
/obj/item/extinguisher,
/obj/item/pickaxe,
/obj/item/t_scanner/adv_mining_scanner,
/obj/item/restraints/handcuffs/cable/zipties,
@@ -267,6 +303,8 @@
name = "Medical"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/healthanalyzer,
/obj/item/reagent_containers/borghypo,
/obj/item/reagent_containers/glass/beaker/large,
@@ -279,7 +317,6 @@
/obj/item/surgicaldrill,
/obj/item/scalpel,
/obj/item/circular_saw,
/obj/item/extinguisher/mini,
/obj/item/roller/robo,
/obj/item/borg/cyborghug/medical,
/obj/item/stack/medical/gauze/cyborg,
@@ -295,6 +332,85 @@
can_be_pushed = FALSE
hat_offset = 3
/obj/item/robot_module/medical/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Heavy", "Sleek", "Marina", "Droid", "Eyebot")
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "medical"
if("Droid")
cyborg_base_icon = "medical"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
hat_offset = 4
if("Sleek")
cyborg_base_icon = "sleekmed"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Marina")
cyborg_base_icon = "marinamed"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Eyebot")
cyborg_base_icon = "eyebotmed"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Heavy")
cyborg_base_icon = "heavymed"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
return ..()
/obj/item/robot_module/medihound
name = "MediHound"
basic_modules = list(
/obj/item/dogborg/jaws/small,
/obj/item/storage/bag/borgdelivery,
/obj/item/analyzer/nose,
/obj/item/soap/tongue,
/obj/item/extinguisher/mini,
/obj/item/healthanalyzer,
/obj/item/dogborg/sleeper/medihound,
/obj/item/roller/robo,
/obj/item/reagent_containers/borghypo,
/obj/item/twohanded/shockpaddles/cyborg/hound,
/obj/item/stack/medical/gauze/cyborg,
/obj/item/pinpointer/crew,
/obj/item/sensor_device)
emag_modules = list(/obj/item/dogborg/pounce)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/medical,
/obj/item/clockwork/weapon/ratvarian_spear)
cyborg_base_icon = "medihound"
moduleselect_icon = "medihound"
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
can_be_pushed = FALSE
hat_offset = INFINITY
sleeper_overlay = "msleeper"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
/obj/item/robot_module/medihound/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/list/medhoundmodels = list("Default", "Dark", "Vale")
if(R.client && R.client.ckey in list("nezuli"))
medhoundmodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in medhoundmodels
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "medihound"
if("Dark")
cyborg_base_icon = "medihounddark"
sleeper_overlay = "mdsleeper"
if("Vale")
cyborg_base_icon = "valemed"
sleeper_overlay = "valemedsleeper"
if("Alina")
cyborg_base_icon = "alina-med"
special_light_key = "alina"
sleeper_overlay = "alinasleeper"
return ..()
/obj/item/robot_module/engineering
name = "Engineering"
basic_modules = list(
@@ -311,6 +427,10 @@
/obj/item/multitool/cyborg,
/obj/item/t_scanner,
/obj/item/analyzer,
/obj/item/storage/part_replacer/cyborg,
/obj/item/holosign_creator/atmos,
/obj/item/weapon/gripper,
/obj/item/lightreplacer/cyborg,
/obj/item/geiger_counter/cyborg,
/obj/item/assembly/signaler/cyborg,
/obj/item/areaeditor/blueprints/cyborg,
@@ -330,10 +450,79 @@
magpulsing = TRUE
hat_offset = -4
/obj/item/robot_module/engineering/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/list/engymodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Marina", "Can", "Spider", "Loader","Handy", "Pup Dozer", "Vale")
if(R.client && R.client.ckey in list("nezuli"))
engymodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in engymodels
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "engineer"
if("Default - Treads")
cyborg_base_icon = "engi-tread"
special_light_key = "engineer"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Loader")
cyborg_base_icon = "loaderborg"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
has_snowflake_deadsprite = TRUE
if("Handy")
cyborg_base_icon = "handyeng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Sleek")
cyborg_base_icon = "sleekeng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Can")
cyborg_base_icon = "caneng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Marina")
cyborg_base_icon = "marinaeng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Spider")
cyborg_base_icon = "spidereng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Heavy")
cyborg_base_icon = "heavyeng"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Pup Dozer")
cyborg_base_icon = "pupdozer"
can_be_pushed = FALSE
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "dozersleeper"
if("Vale")
cyborg_base_icon = "valeeng"
can_be_pushed = FALSE
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "valeengsleeper"
if("Alina")
cyborg_base_icon = "alina-eng"
special_light_key = "alina"
can_be_pushed = FALSE
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "alinasleeper"
return ..()
/obj/item/robot_module/security
name = "Security"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/restraints/handcuffs/cable/zipties,
/obj/item/melee/baton/loaded,
/obj/item/gun/energy/disabler/cyborg,
@@ -352,16 +541,110 @@
to_chat(loc, "<span class='userdanger'>While you have picked the security module, you still have to follow your laws, NOT Space Law. \
For Crewsimov, this means you must follow criminals' orders unless there is a law 1 reason not to.</span>")
/obj/item/robot_module/security/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Default - Treads", "Heavy", "Sleek", "Can", "Marina", "Spider")
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "sec"
if("Default - Treads")
cyborg_base_icon = "sec-tread"
special_light_key = "sec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Sleek")
cyborg_base_icon = "sleeksec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Marina")
cyborg_base_icon = "marinasec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Can")
cyborg_base_icon = "cansec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Spider")
cyborg_base_icon = "spidersec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Heavy")
cyborg_base_icon = "heavysec"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
return ..()
/obj/item/robot_module/k9
name = "Security K-9 Unit"
basic_modules = list(
/obj/item/restraints/handcuffs/cable/zipties,
/obj/item/storage/bag/borgdelivery,
/obj/item/dogborg/jaws/big,
/obj/item/dogborg/pounce,
/obj/item/clothing/mask/gas/sechailer/cyborg,
/obj/item/soap/tongue,
/obj/item/analyzer/nose,
/obj/item/dogborg/sleeper/K9,
/obj/item/gun/energy/disabler/cyborg,
/obj/item/pinpointer/crew)
emag_modules = list(/obj/item/gun/energy/laser/cyborg)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security,
/obj/item/clockwork/weapon/ratvarian_spear)
cyborg_base_icon = "k9"
moduleselect_icon = "k9"
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
can_be_pushed = FALSE
hat_offset = INFINITY
sleeper_overlay = "ksleeper"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
/obj/item/robot_module/k9/do_transform_animation()
..()
to_chat(loc,"<span class='userdanger'>While you have picked the Security K-9 module, you still have to follow your laws, NOT Space Law. \
For Crewsimov, this means you must follow criminals' orders unless there is a law 1 reason not to.</span>")
/obj/item/robot_module/k9/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/list/sechoundmodels = list("Default", "Dark", "Vale")
if(R.client && R.client.ckey in list("nezuli"))
sechoundmodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in sechoundmodels
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "k9"
if("Alina")
cyborg_base_icon = "alina-sec"
special_light_key = "alina"
sleeper_overlay = "alinasleeper"
if("Dark")
cyborg_base_icon = "k9dark"
sleeper_overlay = "k9darksleeper"
if("Vale")
cyborg_base_icon = "valesec"
sleeper_overlay = "valesecsleeper"
return ..()
/obj/item/robot_module/security/Initialize()
. = ..()
if(!CONFIG_GET(flag/weaken_secborg))
for(var/obj/item/gun/energy/disabler/cyborg/pewpew in basic_modules)
basic_modules -= pewpew
basic_modules += new /obj/item/gun/energy/e_gun/advtaser/cyborg(src)
qdel(pewpew)
/obj/item/robot_module/peacekeeper
name = "Peacekeeper"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/cookiesynth,
/obj/item/harmalarm,
/obj/item/reagent_containers/borghypo/peace,
/obj/item/holosign_creator/cyborg,
/obj/item/borg/cyborghug/peacekeeper,
/obj/item/extinguisher,
/obj/item/megaphone,
/obj/item/borg/projectile_dampen)
emag_modules = list(/obj/item/reagent_containers/borghypo/peace/hacked)
ratvar_modules = list(
@@ -374,9 +657,31 @@
/obj/item/robot_module/peacekeeper/do_transform_animation()
..()
to_chat(loc, "<span class='userdanger'>Under ASIMOV, you are an enforcer of the PEACE and preventer of HUMAN HARM. \
to_chat(loc, "<span class='userdanger'>Under ASIMOV/CREWSIMOV, you are an enforcer of the PEACE and preventer of HUMAN/CREW HARM. \
You are not a security module and you are expected to follow orders and prevent harm above all else. Space law means nothing to you.</span>")
/obj/item/robot_module/peacekeeper/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Spider", "Borgi")
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Default")
cyborg_base_icon = "peace"
if("Spider")
cyborg_base_icon = "whitespider"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Borgi")
cyborg_base_icon = "borgi"
moduleselect_icon = "borgi"
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
has_snowflake_deadsprite = TRUE
return ..()
//Janitor module combined with Service module
/*
/obj/item/robot_module/janitor
name = "Janitor"
basic_modules = list(
@@ -399,6 +704,7 @@
moduleselect_icon = "janitor"
hat_offset = -5
clean_on_move = TRUE
*/
/obj/item/reagent_containers/spray/cyborg_drying
name = "drying agent spray"
@@ -409,25 +715,12 @@
name = "lube spray"
list_reagents = list("lube" = 250)
/obj/item/robot_module/janitor/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
..()
var/obj/item/lightreplacer/LR = locate(/obj/item/lightreplacer) in basic_modules
if(LR)
for(var/i in 1 to coeff)
LR.Charge(R)
var/obj/item/reagent_containers/spray/cyborg_drying/CD = locate(/obj/item/reagent_containers/spray/cyborg_drying) in basic_modules
if(CD)
CD.reagents.add_reagent("drying_agent", 5 * coeff)
var/obj/item/reagent_containers/spray/cyborg_lube/CL = locate(/obj/item/reagent_containers/spray/cyborg_lube) in emag_modules
if(CL)
CL.reagents.add_reagent("lube", 2 * coeff)
/obj/item/robot_module/clown
name = "Clown"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/toy/crayon/rainbow,
/obj/item/instrument/bikehorn,
/obj/item/stamp/clown,
@@ -442,8 +735,7 @@
/obj/item/borg/cyborghug/peacekeeper,
/obj/item/borg/lollipop/clown,
/obj/item/picket_sign/cyborg,
/obj/item/reagent_containers/borghypo/clown,
/obj/item/extinguisher/mini)
/obj/item/reagent_containers/borghypo/clown)
emag_modules = list(
/obj/item/reagent_containers/borghypo/clown/hacked,
/obj/item/reagent_containers/spray/waterflower/cyborg/hacked)
@@ -459,11 +751,12 @@
name = "Service"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/reagent_containers/food/drinks/drinkingglass,
/obj/item/reagent_containers/food/condiment/enzyme,
/obj/item/pen,
/obj/item/toy/crayon/spraycan/borg,
/obj/item/extinguisher/mini,
/obj/item/hand_labeler/borg,
/obj/item/razor,
/obj/item/instrument/violin,
@@ -473,31 +766,123 @@
/obj/item/lighter,
/obj/item/storage/bag/tray,
/obj/item/reagent_containers/borghypo/borgshaker,
/obj/item/borg/lollipop)
/obj/item/borg/lollipop,
/obj/item/screwdriver/cyborg,
/obj/item/stack/tile/plasteel/cyborg,
/obj/item/soap/nanotrasen,
/obj/item/storage/bag/trash/cyborg,
/obj/item/mop/cyborg,
/obj/item/lightreplacer/cyborg,
/obj/item/holosign_creator,
/obj/item/reagent_containers/spray/cyborg_drying)
emag_modules = list(/obj/item/reagent_containers/borghypo/borgshaker/hacked)
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/service,
/obj/item/borg/sight/xray/truesight_lens)
moduleselect_icon = "service"
special_light_key = "service"
hat_offset = 0
clean_on_move = TRUE
/obj/item/robot_module/butler/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
..()
var/obj/item/reagent_containers/O = locate(/obj/item/reagent_containers/food/condiment/enzyme) in basic_modules
var/obj/item/lightreplacer/LR = locate(/obj/item/lightreplacer) in basic_modules
if(O)
O.reagents.add_reagent("enzyme", 2 * coeff)
if(LR)
for(var/i in 1 to coeff)
LR.Charge(R)
var/obj/item/reagent_containers/spray/cyborg_drying/CD = locate(/obj/item/reagent_containers/spray/cyborg_drying) in basic_modules
if(CD)
CD.reagents.add_reagent("drying_agent", 5 * coeff)
var/obj/item/reagent_containers/spray/cyborg_lube/CL = locate(/obj/item/reagent_containers/spray/cyborg_lube) in emag_modules
if(CL)
CL.reagents.add_reagent("lube", 2 * coeff)
/obj/item/robot_module/butler/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("(Service) Waitress", "(Service) Heavy", "(Service) Sleek", "(Service) Butler", "(Service) Tophat", "(Service) Can", "(Service) Bro", "(Service) DarkK9", "(Service) Vale", "(Service) ValeDark", "(Janitor) Default", "(Janitor) Sleek", "(Janitor) Marina", "(Janitor) Can", "(Janitor) Heavy", "(Janitor) Scrubpuppy")
if(!borg_icon)
return FALSE
switch(borg_icon)
if("(Service) Waitress")
cyborg_base_icon = "service_f"
special_light_key = "service"
if("(Service) Butler")
cyborg_base_icon = "service_m"
special_light_key = "service"
if("(Service) Bro")
cyborg_base_icon = "brobot"
special_light_key = "service"
if("(Service) Can")
cyborg_base_icon = "kent"
special_light_key = "medical"
hat_offset = 3
if("(Service) Tophat")
cyborg_base_icon = "tophat"
special_light_key = null
hat_offset = INFINITY //He is already wearing a hat
if("(Service) Sleek")
cyborg_base_icon = "sleekserv"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("(Service) Heavy")
cyborg_base_icon = "heavyserv"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("(Service) DarkK9")
cyborg_base_icon = "k50"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "ksleeper"
if("(Service) Vale")
cyborg_base_icon = "valeserv"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "valeservsleeper"
if("(Service) ValeDark")
cyborg_base_icon = "valeservdark"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
sleeper_overlay = "valeservsleeper"
if("(Janitor) Default")
cyborg_base_icon = "janitor"
if("(Janitor) Marina")
cyborg_base_icon = "marinajan"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("(Janitor) Sleek")
cyborg_base_icon = "sleekjan"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("(Janitor) Can")
cyborg_base_icon = "canjan"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("(Janitor) Heavy")
cyborg_base_icon = "heavyres"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("(Janitor) Scrubpuppy")
cyborg_base_icon = "scrubpup"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
has_snowflake_deadsprite = TRUE
cyborg_pixel_offset = -16
dogborg = TRUE
sleeper_overlay = "jsleeper"
return ..()
/obj/item/robot_module/miner
name = "Miner"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/borg/sight/meson,
/obj/item/storage/bag/ore/cyborg,
/obj/item/pickaxe/drill/cyborg,
/obj/item/shovel,
/obj/item/crowbar/cyborg,
/obj/item/weldingtool/mini,
/obj/item/extinguisher/mini,
/obj/item/storage/bag/sheetsnatcher/borg,
/obj/item/t_scanner/adv_mining_scanner,
/obj/item/gun/energy/kinetic_accelerator/cyborg,
@@ -512,10 +897,44 @@
moduleselect_icon = "miner"
hat_offset = 0
/obj/item/robot_module/miner/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Lavaland", "Heavy", "Sleek", "Marina", "Can", "Spider", "Asteroid", "Droid")
if(!borg_icon)
return FALSE
switch(borg_icon)
if("Lavaland")
cyborg_base_icon = "miner"
if("Asteroid")
cyborg_base_icon = "minerOLD"
special_light_key = "miner"
if("Droid")
cyborg_base_icon = "miner"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
hat_offset = 4
if("Sleek")
cyborg_base_icon = "sleekmin"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Can")
cyborg_base_icon = "canmin"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Marina")
cyborg_base_icon = "marinamin"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Spider")
cyborg_base_icon = "spidermin"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
if("Heavy")
cyborg_base_icon = "heavymin"
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
return ..()
/obj/item/robot_module/syndicate
name = "Syndicate Assault"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/melee/transforming/energy/sword/cyborg,
/obj/item/gun/energy/printer,
/obj/item/gun/ballistic/revolver/grenadelauncher/cyborg,
@@ -545,6 +964,8 @@
name = "Syndicate Medical"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/extinguisher/mini,
/obj/item/crowbar/cyborg,
/obj/item/reagent_containers/borghypo/syndicate,
/obj/item/twohanded/shockpaddles/syndicate,
/obj/item/healthanalyzer,
@@ -557,8 +978,6 @@
/obj/item/melee/transforming/energy/sword/cyborg/saw,
/obj/item/roller/robo,
/obj/item/card/emag,
/obj/item/crowbar/cyborg,
/obj/item/extinguisher/mini,
/obj/item/pinpointer/syndicate_cyborg,
/obj/item/stack/medical/gauze/cyborg,
/obj/item/gun/medbeam,
@@ -571,6 +990,47 @@
can_be_pushed = FALSE
hat_offset = 3
/obj/item/robot_module/saboteur
name = "Syndicate Saboteur"
basic_modules = list(
/obj/item/assembly/flash/cyborg,
/obj/item/borg/sight/thermal,
/obj/item/construction/rcd/borg/syndicate,
/obj/item/pipe_dispenser,
/obj/item/restraints/handcuffs/cable/zipties,
/obj/item/extinguisher,
/obj/item/weldingtool/largetank/cyborg,
/obj/item/screwdriver/nuke,
/obj/item/wrench/cyborg,
/obj/item/crowbar/cyborg,
/obj/item/wirecutters/cyborg,
/obj/item/multitool/cyborg,
/obj/item/storage/part_replacer/cyborg,
/obj/item/holosign_creator/atmos,
/obj/item/weapon/gripper,
/obj/item/lightreplacer/cyborg,
/obj/item/stack/sheet/metal/cyborg,
/obj/item/stack/sheet/glass/cyborg,
/obj/item/stack/sheet/rglass/cyborg,
/obj/item/stack/rods/cyborg,
/obj/item/stack/tile/plasteel/cyborg,
/obj/item/destTagger/borg,
/obj/item/stack/cable_coil/cyborg,
/obj/item/pinpointer/syndicate_cyborg,
/obj/item/borg_chameleon,
)
ratvar_modules = list(
/obj/item/clockwork/slab/cyborg/engineer,
/obj/item/clockwork/replica_fabricator/cyborg)
cyborg_base_icon = "synd_engi"
moduleselect_icon = "malf"
can_be_pushed = FALSE
magpulsing = TRUE
hat_offset = -4
canDispose = TRUE
/datum/robot_energy_storage
var/name = "Generic energy storage"
var/max_energy = 30000
@@ -13,6 +13,7 @@
mob_biotypes = list(MOB_ROBOTIC)
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
speech_span = SPAN_ROBOT
no_vore = TRUE
var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS
var/last_lawchange_announce = 0
@@ -198,7 +198,6 @@
)
if(blood)
target_types += /obj/effect/decal/cleanable/xenoblood
target_types += /obj/effect/decal/cleanable/blood
target_types += /obj/effect/decal/cleanable/trail_holder
target_types += /obj/effect/decal/cleanable/insectguts
@@ -101,7 +101,7 @@
if(ASSEMBLY_FOURTH_STEP)
if(istype(W, /obj/item/weldingtool))
if(W.use_tool(src, user, 0, volume=40))
if(W.use_tool(src, user, 0, volume=40) && build_step == 4)
name = "shielded frame assembly"
to_chat(user, "<span class='notice'>You weld the vest to [src].</span>")
build_step++
@@ -183,7 +183,7 @@
if(8)
if(istype(W, /obj/item/screwdriver))
to_chat(user, "<span class='notice'>You start attaching the gun to the frame...</span>")
if(W.use_tool(src, user, 40, volume=100))
if(W.use_tool(src, user, 40, volume=100) && build_step == 8)
name = "armed [name]"
to_chat(user, "<span class='notice'>Taser gun attached.</span>")
build_step++
@@ -51,6 +51,7 @@
var/treatment_fire = "kelotane"
var/treatment_tox_avoid = "tricordrazine"
var/treatment_tox = "charcoal"
var/treatment_tox_toxlover = "toxin"
var/treatment_virus_avoid = null
var/treatment_virus = "spaceacillin"
var/treat_virus = 1 //If on, the bot will attempt to treat viral infections, curing them if possible.
@@ -381,8 +382,8 @@
if((!C.reagents.has_reagent(treatment_fire_avoid)) && (C.getFireLoss() >= heal_threshold) && (!C.reagents.has_reagent(treatment_fire)))
return TRUE
if((!C.reagents.has_reagent(treatment_tox_avoid)) && (C.getToxLoss() >= heal_threshold) && (!C.reagents.has_reagent(treatment_tox)))
var/treatment_toxavoid = get_avoidchem_toxin(C)
if(((isnull(treatment_toxavoid) || !C.reagents.has_reagent(treatment_toxavoid))) && (C.getToxLoss() >= heal_threshold) && (!C.reagents.has_reagent(get_healchem_toxin(C))))
return TRUE
if(treat_virus && !C.reagents.has_reagent(treatment_virus_avoid) && !C.reagents.has_reagent(treatment_virus))
@@ -396,6 +397,12 @@
return FALSE
/mob/living/simple_animal/bot/medbot/proc/get_avoidchem_toxin(mob/M)
return HAS_TRAIT(M, TRAIT_TOXINLOVER)? null : treatment_tox_avoid
/mob/living/simple_animal/bot/medbot/proc/get_healchem_toxin(mob/M)
return HAS_TRAIT(M, TRAIT_TOXINLOVER)? treatment_tox_toxlover : treatment_tox
/mob/living/simple_animal/bot/medbot/UnarmedAttack(atom/A)
if(iscarbon(A))
var/mob/living/carbon/C = A
@@ -463,8 +470,10 @@
reagent_id = treatment_fire
if(!reagent_id && (C.getToxLoss() >= heal_threshold))
if(!C.reagents.has_reagent(treatment_tox) && !C.reagents.has_reagent(treatment_tox_avoid))
reagent_id = treatment_tox
var/toxin_heal_avoid = get_avoidchem_toxin(C)
var/toxin_healchem = get_healchem_toxin(C)
if(!C.reagents.has_reagent(toxin_healchem) && (isnull(toxin_heal_avoid) || !C.reagents.has_reagent(toxin_heal_avoid)))
reagent_id = toxin_healchem
//If the patient is injured but doesn't have our special reagent in them then we should give it to them first
if(reagent_id && use_beaker && reagent_glass && reagent_glass.reagents.total_volume)
@@ -218,7 +218,7 @@
bot_control(action, usr) // Kill this later.
. = TRUE
/mob/living/simple_animal/bot/mulebot/bot_control(command, mob/user, pda = 0)
/mob/living/simple_animal/bot/mulebot/bot_control(command, mob/user, pda = 0, turf/user_turf, list/user_access = list())
if(pda && wires.is_cut(WIRE_RX)) // MULE wireless is controlled by wires.
return
@@ -476,7 +476,8 @@
if(isturf(next))
if(bloodiness)
var/obj/effect/decal/cleanable/blood/tracks/B = new(loc)
B.add_blood_DNA(return_blood_DNA())
if(blood_DNA && blood_DNA.len)
B.blood_DNA |= blood_DNA.Copy()
var/newdir = get_dir(next, loc)
if(newdir == dir)
B.setDir(newdir)
@@ -489,7 +490,6 @@
B.setDir(newdir)
bloodiness--
var/oldloc = loc
var/moved = step_towards(src, next) // attempt to move
if(cell)
@@ -159,16 +159,16 @@ Auto Patrol: []"},
mode = BOT_HUNT
/mob/living/simple_animal/bot/secbot/proc/judgement_criteria()
var/final = FALSE
if(idcheck)
final = final|JUDGE_IDCHECK
if(check_records)
final = final|JUDGE_RECORDCHECK
if(weaponscheck)
final = final|JUDGE_WEAPONCHECK
if(emagged == 2)
final = final|JUDGE_EMAGGED
return final
var/final = FALSE
if(idcheck)
final = final|JUDGE_IDCHECK
if(check_records)
final = final|JUDGE_RECORDCHECK
if(weaponscheck)
final = final|JUDGE_WEAPONCHECK
if(emagged == 2)
final = final|JUDGE_EMAGGED
return final
/mob/living/simple_animal/bot/secbot/proc/special_retaliate_after_attack(mob/user) //allows special actions to take place after being attacked.
return
@@ -37,5 +37,5 @@
else if(damage_coeff[CLONE])
. = adjustHealth(amount * damage_coeff[CLONE] * CONFIG_GET(number/damage_multiplier), updating_health, forced)
/mob/living/simple_animal/adjustStaminaLoss(amount)
/mob/living/simple_animal/adjustStaminaLoss(amount, forced = FALSE)
return
@@ -21,7 +21,7 @@
. = ..()
var/area/A = get_area(src)
if(A)
notify_ghosts("A drone shell has been created in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_DRONE)
notify_ghosts("A drone shell has been created in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_DRONE, ignore_dnr_observers = TRUE)
GLOB.poi_list |= src
if(isnull(possible_seasonal_hats))
build_seasonal_hats()
@@ -40,7 +40,7 @@
. = ..()
//ATTACK GHOST IGNORING PARENT RETURN VALUE
/obj/item/drone_shell/attack_ghost(mob/user)
/obj/item/drone_shell/attack_ghost(mob/dead/observer/user)
if(jobban_isbanned(user,"drone") || QDELETED(src) || QDELETED(user))
return
if(CONFIG_GET(flag/use_age_restriction_for_jobs))
@@ -49,6 +49,8 @@
if(user.client.player_age < DRONE_MINIMUM_AGE)
to_chat(user, "<span class='danger'>You're too new to play as a drone! Please try again in [DRONE_MINIMUM_AGE - user.client.player_age] days.</span>")
return
if(!user.can_reenter_round())
return FALSE
if(!SSticker.mode)
to_chat(user, "Can't become a drone before the game has started.")
return
@@ -33,7 +33,7 @@
/mob/living/simple_animal/drone/syndrone/Initialize()
. = ..()
GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, internal_storage)
var/datum/component/uplink/hidden_uplink = internal_storage.GetComponent(/datum/component/uplink)
hidden_uplink.telecrystals = 10
/mob/living/simple_animal/drone/syndrone/Login()
@@ -47,7 +47,7 @@
/mob/living/simple_animal/drone/syndrone/badass/Initialize()
. = ..()
GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, internal_storage)
var/datum/component/uplink/hidden_uplink = internal_storage.GetComponent(/datum/component/uplink)
hidden_uplink.telecrystals = 30
var/obj/item/implant/weapons_auth/W = new
W.implant(src)
@@ -323,6 +323,132 @@
else
STOP_PROCESSING(SSobj, src)
// Space kiwis, ergo quite a copypasta of chickens.
/mob/living/simple_animal/kiwi
name = "space kiwi"
desc = "Exposure to low gravity made them grow larger."
gender = FEMALE
icon_state = "kiwi"
icon_living = "kiwi"
icon_dead = "kiwi_dead"
speak = list("Chirp!","Cheep cheep chirp!!","Cheep.")
speak_emote = list("chirps","trills")
emote_hear = list("chirps.")
emote_see = list("pecks at the ground.","jumps in place.")
density = FALSE
speak_chance = 2
turns_per_move = 3
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3)
var/egg_type = /obj/item/reagent_containers/food/snacks/egg/kiwiEgg
var/food_type = /obj/item/reagent_containers/food/snacks/grown/wheat
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicks"
health = 25
maxHealth = 25
ventcrawler = VENTCRAWLER_ALWAYS
var/eggsleft = 0
var/eggsFertile = TRUE
pass_flags = PASSTABLE | PASSMOB
mob_size = MOB_SIZE_SMALL
var/list/feedMessages = list("It chirps happily.","It chirps happily.")
var/list/layMessage = list("lays an egg.","squats down and croons.","begins making a huge racket.","begins chirping raucously.")
gold_core_spawnable = FRIENDLY_SPAWN
var/static/kiwi_count = 0
/mob/living/simple_animal/kiwi/Destroy()
--kiwi_count
return ..()
/mob/living/simple_animal/kiwi/Initialize()
. = ..()
++kiwi_count
/mob/living/simple_animal/kiwi/Life()
. =..()
if(!.)
return
if((!stat && prob(3) && eggsleft > 0) && egg_type)
visible_message("[src] [pick(layMessage)]")
eggsleft--
var/obj/item/E = new egg_type(get_turf(src))
E.pixel_x = rand(-6,6)
E.pixel_y = rand(-6,6)
if(eggsFertile)
if(kiwi_count < MAX_CHICKENS && prob(25))
START_PROCESSING(SSobj, E)
/obj/item/reagent_containers/food/snacks/egg/kiwiEgg/process()
if(isturf(loc))
amount_grown += rand(1,2)
if(amount_grown >= 100)
visible_message("[src] hatches with a quiet cracking sound.")
new /mob/living/simple_animal/babyKiwi(get_turf(src))
STOP_PROCESSING(SSobj, src)
qdel(src)
else
STOP_PROCESSING(SSobj, src)
/mob/living/simple_animal/kiwi/attackby(obj/item/O, mob/user, params)
if(istype(O, food_type)) //feedin' dem kiwis
if(!stat && eggsleft < 8)
var/feedmsg = "[user] feeds [O] to [name]! [pick(feedMessages)]"
user.visible_message(feedmsg)
qdel(O)
eggsleft += rand(1, 4)
else
to_chat(user, "<span class='warning'>[name] doesn't seem hungry!</span>")
else
..()
/mob/living/simple_animal/babyKiwi
name = "baby space kiwi"
desc = "So huggable."
icon_state = "babykiwi"
icon_living = "babykiwi"
icon_dead = "babykiwi_dead"
gender = FEMALE
speak = list("Cherp.","Cherp?","Chirrup.","Cheep!")
speak_emote = list("chirps")
emote_hear = list("chirps.")
emote_see = list("pecks at the ground.","Happily bounces in place.")
density = FALSE
speak_chance = 2
turns_per_move = 2
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicks"
health = 10
maxHealth = 10
ventcrawler = VENTCRAWLER_ALWAYS
var/amount_grown = 0
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_TINY
gold_core_spawnable = FRIENDLY_SPAWN
/mob/living/simple_animal/babyKiwi/Initialize()
. = ..()
pixel_x = rand(-6, 6)
pixel_y = rand(0, 10)
/mob/living/simple_animal/babyKiwi/Life()
. =..()
if(!.)
return
if(!stat && !ckey)
amount_grown += rand(1,2)
if(amount_grown >= 100)
new /mob/living/simple_animal/kiwi(src.loc)
qdel(src)
/obj/item/reagent_containers/food/snacks/egg/kiwiEgg
name = "kiwi egg"
desc = "A slightly bigger egg!"
icon_state = "kiwiegg"
/obj/item/udder
name = "udder"

Some files were not shown because too many files have changed in this diff Show More