Merge branch 'master' of https://github.com/ParadiseSS13/Paradise into TasteOfVictory

This commit is contained in:
variableundefined
2019-08-27 15:20:23 -04:00
717 changed files with 29367 additions and 9847 deletions
+26 -5
View File
@@ -29,6 +29,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
var/seedarkness = TRUE
var/data_hud_seen = FALSE //this should one of the defines in __DEFINES/hud.dm
var/ghost_orbit = GHOST_ORBIT_CIRCLE
var/health_scan = FALSE //does the ghost have health scanner mode on? by default it should be off
/mob/dead/observer/New(var/mob/body=null, var/flags=1)
set_invisibility(GLOB.observer_default_invisibility)
@@ -236,6 +237,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return 1
/mob/dead/observer/Move(NewLoc, direct)
update_parallax_contents()
following = null
setDir(direct)
ghostimage.setDir(dir)
@@ -405,7 +407,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
A.on_close(CALLBACK(src, .proc/teleport))
/mob/dead/observer/proc/teleport(area/thearea)
if(!thearea)
if(!thearea || !isobserver(usr))
return
var/list/L = list()
@@ -416,7 +418,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
to_chat(usr, "<span class='warning'>No area available.</span>")
return
usr.forceMove(pick(L))
forceMove(pick(L))
update_parallax_contents()
following = null
/mob/dead/observer/verb/follow()
@@ -430,7 +433,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
// This is the ghost's follow verb with an argument
/mob/dead/observer/proc/ManualFollow(var/atom/movable/target)
if(!target)
if(!target || !isobserver(usr))
return
if(!get_turf(target))
@@ -504,13 +507,15 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
A.on_close(CALLBACK(src, .proc/jump_to_mob))
/mob/dead/observer/proc/jump_to_mob(mob/M)
if(!M)
if(!M || !isobserver(usr))
return
var/mob/A = src //Source mob
var/turf/T = get_turf(M) //Turf of the destination mob
if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination.
A.forceMove(T)
M.update_parallax_contents()
following = null
return
to_chat(A, "This mob is not located in the game world.")
@@ -537,6 +542,19 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set hidden = 1
to_chat(src, "<span class='warning'>You are dead! You have no mind to store memory!</span>")
/mob/dead/observer/verb/toggle_health_scan()
set name = "Toggle Health Scan"
set desc = "Toggles whether you health-scan living beings on click"
set category = "Ghost"
if(health_scan) //remove old huds
to_chat(src, "<span class='notice'>Health scan disabled.</span>")
health_scan = FALSE
else
to_chat(src, "<span class='notice'>Health scan enabled.</span>")
health_scan = TRUE
/mob/dead/observer/verb/analyze_air()
set name = "Analyze Air"
set category = "Ghost"
@@ -761,14 +779,17 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/proc/incarnate_ghost()
if(!client)
return
var/mob/living/carbon/human/new_char = new(get_turf(src))
client.prefs.copy_to(new_char)
if(mind)
mind.active = 1
mind.active = TRUE
mind.transfer_to(new_char)
else
new_char.key = key
return new_char
/mob/dead/observer/is_literate()
return TRUE
+10 -9
View File
@@ -58,19 +58,20 @@
if(message)
log_emote(message, src)
//Hearing gasp and such every five seconds is not good emotes were not global for a reason.
// Maybe some people are okay with that.
// Hearing gasp and such every five seconds is not good emotes were not global for a reason.
// Maybe some people are okay with that.
for(var/mob/M in GLOB.player_list)
if(!M.client)
continue //skip monkeys and leavers
if(istype(M, /mob/new_player))
continue
if(findtext(message," snores.")) //Because we have so many sleeping people.
break
if(M.stat == DEAD && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
M.show_message(message)
if(isnewplayer(M))
continue
if(findtext(message, " snores.")) //Because we have so many sleeping people.
break
if(isobserver(M) && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src, null)) && client) // The client check makes sure people with ghost sight don't get spammed by simple mobs emoting.
M.show_message(message)
// Type 1 (Visual) emotes are sent to anyone in view of the item
if(m_type & EMOTE_VISUAL)
+2 -4
View File
@@ -63,10 +63,10 @@
var/datum/gas_mixture/environment = T.return_air()
var/pressure = environment ? environment.return_pressure() : 0
if(pressure < SOUND_MINIMUM_PRESSURE && get_dist(speaker, src) > 1)
return 0
return FALSE
if(pressure < ONE_ATMOSPHERE * 0.4) //sound distortion pressure, to help clue people in that the air is thin, even if it isn't a vacuum yet
italics = 1
italics = TRUE
sound_vol *= 0.5
if(sleeping || stat == UNCONSCIOUS)
@@ -87,8 +87,6 @@
var/track = null
if(isobserver(src))
if(italics && client.prefs.toggles & CHAT_GHOSTRADIO)
return
if(speaker_name != speaker.real_name && speaker.real_name)
speaker_name = "[speaker.real_name] ([speaker_name])"
track = "([ghost_follow_link(speaker, ghost=src)]) "
+13 -8
View File
@@ -455,6 +455,7 @@
colour = "alien"
key = "y"
flags = RESTRICTED | HIVEMIND
follow = TRUE
/datum/language/wryn/check_special_condition(mob/other)
var/mob/living/carbon/M = other
@@ -485,7 +486,7 @@
colour = "alien"
key = "a"
flags = RESTRICTED | HIVEMIND
follow = 1
follow = TRUE
/datum/language/terrorspider
name = "Spider Hivemind"
@@ -496,7 +497,7 @@
colour = "terrorspider"
key = "ts"
flags = RESTRICTED | HIVEMIND
follow = 1
follow = TRUE
/datum/language/ling
name = "Changeling"
@@ -505,10 +506,11 @@
colour = "changeling"
key = "g"
flags = RESTRICTED | HIVEMIND
follow = TRUE
/datum/language/ling/broadcast(mob/living/speaker, message, speaker_mask)
if(speaker.mind && speaker.mind.changeling)
..(speaker,message,speaker.mind.changeling.changelingID)
..(speaker, message, speaker.mind.changeling.changelingID)
else if(speaker.mind && speaker.mind.linglink)
..()
else
@@ -521,6 +523,7 @@
colour = "shadowling"
key = "8"
flags = RESTRICTED | HIVEMIND
follow = TRUE
/datum/language/shadowling/broadcast(mob/living/speaker, message, speaker_mask)
if(speaker.mind && speaker.mind.special_role == SPECIAL_ROLE_SHADOWLING)
@@ -539,6 +542,7 @@
colour = "abductor"
key = "zw" //doesn't matter, this is their default and only language
flags = RESTRICTED | HIVEMIND
follow = TRUE
/datum/language/abductor/broadcast(mob/living/speaker, message, speaker_mask)
..(speaker,message,speaker.real_name)
@@ -567,6 +571,7 @@
colour = "alien"
key = "bo"
flags = RESTRICTED | HIVEMIND
follow = TRUE
/datum/language/corticalborer/broadcast(mob/living/speaker, message, speaker_mask)
var/mob/living/simple_animal/borer/B
@@ -590,7 +595,7 @@
exclaim_verb = "declares"
key = "b"
flags = RESTRICTED | HIVEMIND
follow = 1
follow = TRUE
var/drone_only
/datum/language/binary/broadcast(mob/living/speaker, message, speaker_mask)
@@ -636,8 +641,8 @@
colour = "say_quote"
key = "d"
flags = RESTRICTED | HIVEMIND
drone_only = 1
follow = 1
drone_only = TRUE
follow = TRUE
/datum/language/drone
name = "Drone"
@@ -647,7 +652,7 @@
exclaim_verb = "declares"
key = "]"
flags = RESTRICTED
follow = 1
follow = TRUE
syllables = list ("beep", "boop")
/datum/language/swarmer
@@ -659,7 +664,7 @@
colour = "say_quote"
key = "z"//Zwarmer...Or Zerg!
flags = RESTRICTED | HIVEMIND
follow = 1
follow = TRUE
// Language handling.
/mob/proc/add_language(language)
@@ -73,7 +73,11 @@
stat = CONSCIOUS
return
health = maxHealth - getOxyLoss() - getFireLoss() - getBruteLoss() - getCloneLoss()
update_stat("updatehealth([reason])")
med_hud_set_health()
med_hud_set_status()
handle_hud_icons_health()
/mob/living/carbon/alien/handle_environment(var/datum/gas_mixture/environment)
@@ -17,7 +17,7 @@
. = -1 //hunters are sanic
. += ..() //but they still need to slow down on stun
/mob/living/carbon/alien/humanoid/hunter/handle_regular_hud_updates()
/mob/living/carbon/alien/humanoid/hunter/handle_hud_icons_health()
..() //-Yvarov
if(healths)
@@ -42,7 +42,7 @@
alien_organs += new /obj/item/organ/internal/xenos/neurotoxin
..()
/mob/living/carbon/alien/humanoid/sentinel/handle_regular_hud_updates()
/mob/living/carbon/alien/humanoid/sentinel/handle_hud_icons_health()
..() //-Yvarov
if(healths)
@@ -48,29 +48,26 @@
alien_organs += new /obj/item/organ/internal/xenos/neurotoxin
..()
/mob/living/carbon/alien/humanoid/empress
/mob/living/carbon/alien/humanoid/empress/handle_hud_icons_health()
..() //-Yvarov
handle_regular_hud_updates()
..() //-Yvarov
if(src.healths)
if(src.stat != 2)
switch(health)
if(250 to INFINITY)
src.healths.icon_state = "health0"
if(175 to 250)
src.healths.icon_state = "health1"
if(100 to 175)
src.healths.icon_state = "health2"
if(50 to 100)
src.healths.icon_state = "health3"
if(0 to 50)
src.healths.icon_state = "health4"
else
src.healths.icon_state = "health5"
else
src.healths.icon_state = "health6"
if(healths)
if(stat != 2)
switch(health)
if(250 to INFINITY)
healths.icon_state = "health0"
if(175 to 250)
healths.icon_state = "health1"
if(100 to 175)
healths.icon_state = "health2"
if(50 to 100)
healths.icon_state = "health3"
if(0 to 50)
healths.icon_state = "health4"
else
healths.icon_state = "health5"
else
healths.icon_state = "health6"
/mob/living/carbon/alien/humanoid/empress/verb/lay_egg()
set name = "Lay Egg (250)"
@@ -32,7 +32,7 @@
. = ..()
. += 3
/mob/living/carbon/alien/humanoid/queen/handle_regular_hud_updates()
/mob/living/carbon/alien/humanoid/queen/handle_hud_icons_health()
..() //-Yvarov
if(healths)
@@ -72,7 +72,7 @@ var/const/MAX_ACTIVE_TIME = 400
/obj/item/clothing/mask/facehugger/equipped(mob/M)
Attach(M)
/obj/item/clothing/mask/facehugger/Crossed(atom/target)
/obj/item/clothing/mask/facehugger/Crossed(atom/target, oldloc)
HasProximity(target)
return
+1
View File
@@ -1128,6 +1128,7 @@ so that different stomachs can handle things in different ways VB*/
var/obj/item/clothing/C = I
if(C.tint || initial(C.tint))
update_tint()
update_sight()
if(I.flags_inv & HIDEMASK || forced)
update_inv_wear_mask()
update_inv_head()
@@ -671,9 +671,9 @@
if(!restrained())
var/t1 = round(text2num(param))
if(isnum(t1))
if(t1 <= 5 && (!r_hand || !l_hand))
if(t1 <= 5 && t1 >= 1 && (!r_hand || !l_hand))
message = "<B>[src]</B> raises [t1] finger\s."
else if(t1 <= 10 && (!r_hand && !l_hand))
else if(t1 <= 10 && t1 >= 1 && (!r_hand && !l_hand))
message = "<B>[src]</B> raises [t1] finger\s."
m_type = 1
@@ -946,9 +946,13 @@
// Maybe some people are okay with that.
for(var/mob/M in GLOB.dead_mob_list)
if(!M.client || istype(M, /mob/new_player))
continue //skip monkeys, leavers and new players
if(M.stat == DEAD && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
if(!M.client)
continue
if(isnewplayer(M))
continue
if(isobserver(M) && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src, null)) && client) // The client check makes sure people with ghost sight don't get spammed by simple mobs emoting.
M.show_message(message)
switch(m_type)
@@ -338,18 +338,9 @@
msg += "[p_they(TRUE)] [p_are()] mostly dessicated now, with only bones remaining of what used to be a person.\n"
if(hasHUD(user,"security"))
var/perpname = "wot"
var/perpname = get_visible_name(TRUE)
var/criminal = "None"
if(wear_id)
var/obj/item/card/id/I = wear_id.GetID()
if(I)
perpname = I.registered_name
else
perpname = name
else
perpname = name
if(perpname)
for(var/datum/data/record/E in data_core.general)
if(E.fields["name"] == perpname)
@@ -361,18 +352,9 @@
msg += "<span class = 'deptradio'>Security records:</span> <a href='?src=[UID()];secrecord=`'>\[View\]</a> <a href='?src=[UID()];secrecordadd=`'>\[Add comment\]</a>\n"
if(hasHUD(user,"medical"))
var/perpname = "wot"
var/perpname = get_visible_name(TRUE)
var/medical = "None"
if(wear_id)
if(istype(wear_id,/obj/item/card/id))
perpname = wear_id:registered_name
else if(istype(wear_id,/obj/item/pda))
var/obj/item/pda/tempPda = wear_id
perpname = tempPda.owner
else
perpname = src.name
for(var/datum/data/record/E in data_core.general)
if(E.fields["name"] == perpname)
for(var/datum/data/record/R in data_core.general)
+19 -79
View File
@@ -453,7 +453,7 @@
popup.open()
/mob/living/carbon/human/Crossed(atom/movable/AM)
/mob/living/carbon/human/Crossed(atom/movable/AM, oldloc)
var/mob/living/simple_animal/bot/mulebot/MB = AM
if(istype(MB))
MB.RunOver(src)
@@ -711,17 +711,9 @@
if(usr.incapacitated())
return
var/found_record = 0
var/perpname = "wot"
if(wear_id)
var/obj/item/card/id/I = wear_id.GetID()
if(I)
perpname = I.registered_name
else
perpname = name
else
perpname = name
var/perpname = get_visible_name(TRUE)
if(perpname)
if(perpname != "Unknown")
for(var/datum/data/record/E in data_core.general)
if(E.fields["name"] == perpname)
for(var/datum/data/record/R in data_core.security)
@@ -758,17 +750,9 @@
if(hasHUD(usr,"security"))
if(usr.incapacitated())
return
var/perpname = "wot"
var/perpname = get_visible_name(TRUE)
var/read = 0
if(wear_id)
if(istype(wear_id,/obj/item/card/id))
perpname = wear_id:registered_name
else if(istype(wear_id,/obj/item/pda))
var/obj/item/pda/tempPda = wear_id
perpname = tempPda.owner
else
perpname = src.name
for(var/datum/data/record/E in data_core.general)
if(E.fields["name"] == perpname)
for(var/datum/data/record/R in data_core.security)
@@ -790,24 +774,16 @@
if(hasHUD(usr,"security"))
if(usr.incapacitated())
return
var/perpname = "wot"
var/perpname = get_visible_name(TRUE)
var/read = 0
if(wear_id)
if(istype(wear_id,/obj/item/card/id))
perpname = wear_id:registered_name
else if(istype(wear_id,/obj/item/pda))
var/obj/item/pda/tempPda = wear_id
perpname = tempPda.owner
else
perpname = src.name
for(var/datum/data/record/E in data_core.general)
if(E.fields["name"] == perpname)
for(var/datum/data/record/R in data_core.security)
if(R.fields["id"] == E.fields["id"])
if(hasHUD(usr,"security"))
read = 1
if(length(R.fields["comments"]))
if(LAZYLEN(R.fields["comments"]))
for(var/c in R.fields["comments"])
to_chat(usr, c)
else
@@ -821,15 +797,8 @@
if(hasHUD(usr,"security"))
if(usr.incapacitated())
return
var/perpname = "wot"
if(wear_id)
if(istype(wear_id,/obj/item/card/id))
perpname = wear_id:registered_name
else if(istype(wear_id,/obj/item/pda))
var/obj/item/pda/tempPda = wear_id
perpname = tempPda.owner
else
perpname = src.name
var/perpname = get_visible_name(TRUE)
for(var/datum/data/record/E in data_core.general)
if(E.fields["name"] == perpname)
for(var/datum/data/record/R in data_core.security)
@@ -852,17 +821,8 @@
if(hasHUD(usr,"medical"))
if(usr.incapacitated())
return
var/perpname = "wot"
var/modified = 0
if(wear_id)
if(istype(wear_id,/obj/item/card/id))
perpname = wear_id:registered_name
else if(istype(wear_id,/obj/item/pda))
var/obj/item/pda/tempPda = wear_id
perpname = tempPda.owner
else
perpname = src.name
var/perpname = get_visible_name(TRUE)
for(var/datum/data/record/E in data_core.general)
if(E.fields["name"] == perpname)
@@ -887,17 +847,9 @@
if(hasHUD(usr,"medical"))
if(usr.incapacitated())
return
var/perpname = "wot"
var/read = 0
if(wear_id)
if(istype(wear_id,/obj/item/card/id))
perpname = wear_id:registered_name
else if(istype(wear_id,/obj/item/pda))
var/obj/item/pda/tempPda = wear_id
perpname = tempPda.owner
else
perpname = src.name
var/perpname = get_visible_name(TRUE)
for(var/datum/data/record/E in data_core.general)
if(E.fields["name"] == perpname)
for(var/datum/data/record/R in data_core.medical)
@@ -920,24 +872,16 @@
if(hasHUD(usr,"medical"))
if(usr.incapacitated())
return
var/perpname = "wot"
var/perpname = get_visible_name(TRUE)
var/read = 0
if(wear_id)
if(istype(wear_id,/obj/item/card/id))
perpname = wear_id:registered_name
else if(istype(wear_id,/obj/item/pda))
var/obj/item/pda/tempPda = wear_id
perpname = tempPda.owner
else
perpname = src.name
for(var/datum/data/record/E in data_core.general)
if(E.fields["name"] == perpname)
for(var/datum/data/record/R in data_core.medical)
if(R.fields["id"] == E.fields["id"])
if(hasHUD(usr,"medical"))
read = 1
if(length(R.fields["comments"]))
if(LAZYLEN(R.fields["comments"]))
for(var/c in R.fields["comments"])
to_chat(usr, c)
else
@@ -951,15 +895,7 @@
if(hasHUD(usr,"medical"))
if(usr.incapacitated())
return
var/perpname = "wot"
if(wear_id)
if(istype(wear_id,/obj/item/card/id))
perpname = wear_id:registered_name
else if(istype(wear_id,/obj/item/pda))
var/obj/item/pda/tempPda = wear_id
perpname = tempPda.owner
else
perpname = src.name
var/perpname = get_visible_name(TRUE)
for(var/datum/data/record/E in data_core.general)
if(E.fields["name"] == perpname)
for(var/datum/data/record/R in data_core.medical)
@@ -974,6 +910,9 @@
if(isrobot(usr))
var/mob/living/silicon/robot/U = usr
R.fields["comments"] += "Made by [U.name] ([U.modtype] [U.braintype]) on [current_date_string] [station_time_timestamp()]<BR>[t1]"
if(isAI(usr))
var/mob/living/silicon/ai/U = usr
R.fields["comments"] += "Made by [U.name] (artificial intelligence) on [current_date_string] [station_time_timestamp()]<BR>[t1]"
if(href_list["lookitem"])
var/obj/item/I = locate(href_list["lookitem"])
@@ -1606,7 +1545,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
//Check for arrest warrant
if(judgebot.check_records)
var/perpname = get_face_name(get_id_name())
var/perpname = get_visible_name(TRUE)
var/datum/data/record/R = find_record("name", perpname, data_core.security)
if(R && R.fields["criminal"])
switch(R.fields["criminal"])
@@ -1938,6 +1877,7 @@ Eyes need to have significantly high darksight to shine unless the mob has the X
. = ..()
. += "---"
.["Set Species"] = "?_src_=vars;setspecies=[UID()]"
.["Copy Outfit"] = "?_src_=vars;copyoutfit=[UID()]"
.["Make AI"] = "?_src_=vars;makeai=[UID()]"
.["Make cyborg"] = "?_src_=vars;makerobot=[UID()]"
.["Make monkey"] = "?_src_=vars;makemonkey=[UID()]"
@@ -141,19 +141,19 @@ emp_act
if(l_hand && !istype(l_hand, /obj/item/clothing))
var/final_block_chance = l_hand.block_chance - (Clamp((armour_penetration-l_hand.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
if(l_hand.hit_reaction(src, attack_text, final_block_chance, damage, attack_type))
if(l_hand.hit_reaction(src, attack_text, final_block_chance, damage, attack_type, AM))
return 1
if(r_hand && !istype(r_hand, /obj/item/clothing))
var/final_block_chance = r_hand.block_chance - (Clamp((armour_penetration-r_hand.armour_penetration)/2,0,100)) + block_chance_modifier //Need to reset the var so it doesn't carry over modifications between attempts
if(r_hand.hit_reaction(src, attack_text, final_block_chance, damage, attack_type))
if(r_hand.hit_reaction(src, attack_text, final_block_chance, damage, attack_type, AM))
return 1
if(wear_suit)
var/final_block_chance = wear_suit.block_chance - (Clamp((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier
if(wear_suit.hit_reaction(src, attack_text, final_block_chance, damage, attack_type))
if(wear_suit.hit_reaction(src, attack_text, final_block_chance, damage, attack_type, AM))
return 1
if(w_uniform)
var/final_block_chance = w_uniform.block_chance - (Clamp((armour_penetration-w_uniform.armour_penetration)/2,0,100)) + block_chance_modifier
if(w_uniform.hit_reaction(src, attack_text, final_block_chance, damage, attack_type))
if(w_uniform.hit_reaction(src, attack_text, final_block_chance, damage, attack_type, AM))
return 1
return 0
@@ -525,4 +525,4 @@ emp_act
if(head)
to_chat(src, "<span class='danger'>Your [head.name] protects you from the [hot ? "hot" : "cold"] liquid!</span>")
return FALSE
return TRUE
return TRUE
@@ -63,7 +63,8 @@
else
//No oldFP or it's a different kind of blood
S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state] - BLOOD_LOSS_PER_STEP)
createFootprintsFrom(shoes, dir, T)
if(S.bloody_shoes[S.blood_state] > BLOOD_LOSS_IN_SPREAD)
createFootprintsFrom(shoes, dir, T)
update_inv_shoes()
else if(hasfeet)
if(bloody_feet && bloody_feet[blood_state])
@@ -72,7 +73,8 @@
return
else
bloody_feet[blood_state] = max(0, bloody_feet[blood_state] - BLOOD_LOSS_PER_STEP)
createFootprintsFrom(src, dir, T)
if(bloody_feet[blood_state] > BLOOD_LOSS_IN_SPREAD)
createFootprintsFrom(src, dir, T)
update_inv_shoes()
//End bloody footprints
if(S)
@@ -567,3 +567,10 @@
return 0
return O.equip(src, visualsOnly)
//delete all equipment without dropping anything
/mob/living/carbon/human/proc/delete_equipment()
for(var/slot in get_all_slots())//order matters, dependant slots go first
qdel(slot)
for(var/obj/item/I in l_hand, r_hand)
qdel(I)
@@ -6,21 +6,19 @@
dangerous_existence = TRUE //So so much
//language = "Clatter"
species_traits = list(IS_WHITELISTED, NO_BLOOD, NOTRANSSTING)
species_traits = list(IS_WHITELISTED, RADIMMUNE, NO_BLOOD, NOTRANSSTING)
forced_heartattack = TRUE // Plasmamen have no blood, but they should still get heart-attacks
skinned_type = /obj/item/stack/sheet/mineral/plasma // We're low on plasma, R&D! *eyes plasmaman co-worker intently*
dietflags = DIET_OMNI
reagent_tag = PROCESS_ORG
//default_mutations=list(SKELETON) // This screws things up
butt_sprite = "plasma"
breathid = "tox"
heat_level_1 = 350 // Heat damage level 1 above this point.
heat_level_2 = 400 // Heat damage level 2 above this point.
heat_level_3 = 500 // Heat damage level 3 above this point.
burn_mod = 1.5
heatmod = 1.5
brute_mod = 1.5
//Has default darksight of 2.
@@ -48,136 +46,118 @@
message = replacetext(message, "s", stutter("ss"))
return message
/datum/species/plasmaman/after_equip_job(datum/job/J, mob/living/carbon/human/H)
var/assigned_role = H.mind && H.mind.assigned_role ? H.mind.assigned_role : "Civilian"
// Unequip existing suits and hats.
H.unEquip(H.wear_suit)
H.unEquip(H.head)
if(assigned_role != "Clown")
H.unEquip(H.wear_mask)
H.equip_or_collect(new /obj/item/clothing/mask/breath(H), slot_wear_mask)
var/suit=/obj/item/clothing/suit/space/eva/plasmaman/assistant
var/helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/assistant
var/tank_slot = slot_s_store
var/tank_slot_name = "suit storage"
switch(assigned_role)
if("Scientist","Roboticist")
suit=/obj/item/clothing/suit/space/eva/plasmaman/science
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/science
if("Geneticist")
suit=/obj/item/clothing/suit/space/eva/plasmaman/science/geneticist
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/science/geneticist
if("Research Director")
suit=/obj/item/clothing/suit/space/eva/plasmaman/science/rd
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/science/rd
if("Station Engineer", "Mechanic")
suit=/obj/item/clothing/suit/space/eva/plasmaman/engineer
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/engineer
if("Chief Engineer")
suit=/obj/item/clothing/suit/space/eva/plasmaman/engineer/ce
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/engineer/ce
if("Life Support Specialist")
suit=/obj/item/clothing/suit/space/eva/plasmaman/atmostech
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/atmostech
if("Detective")
suit=/obj/item/clothing/suit/space/eva/plasmaman/security
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security
if("Warden","Security Officer","Security Pod Pilot")
suit=/obj/item/clothing/suit/space/eva/plasmaman/security
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security
if("Internal Affairs Agent")
suit=/obj/item/clothing/suit/space/eva/plasmaman/lawyer
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/lawyer
if("Magistrate")
suit=/obj/item/clothing/suit/space/eva/plasmaman/magistrate
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/magistrate
if("Head of Security", "Special Operations Officer")
suit=/obj/item/clothing/suit/space/eva/plasmaman/security/hos
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security/hos
if("Captain", "Blueshield")
suit=/obj/item/clothing/suit/space/eva/plasmaman/security/captain
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security/captain
if("Head of Personnel")
suit=/obj/item/clothing/suit/space/eva/plasmaman/security/hop
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security/hop
if("Nanotrasen Representative", "Nanotrasen Navy Officer")
suit = /obj/item/clothing/suit/space/eva/plasmaman/nt_rep
helm = /obj/item/clothing/head/helmet/space/eva/plasmaman/nt_rep
if("Medical Doctor","Brig Physician","Virologist")
suit=/obj/item/clothing/suit/space/eva/plasmaman/medical
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical
if("Paramedic")
suit=/obj/item/clothing/suit/space/eva/plasmaman/medical/paramedic
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/paramedic
if("Chemist")
suit=/obj/item/clothing/suit/space/eva/plasmaman/medical/chemist
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/chemist
if("Chief Medical Officer")
suit=/obj/item/clothing/suit/space/eva/plasmaman/medical/cmo
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/cmo
if("Coroner")
suit=/obj/item/clothing/suit/space/eva/plasmaman/medical/coroner
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/coroner
if("Virologist")
suit=/obj/item/clothing/suit/space/eva/plasmaman/medical/virologist
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/virologist
if("Bartender", "Chef")
suit=/obj/item/clothing/suit/space/eva/plasmaman/service
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/service
if("Cargo Technician", "Quartermaster")
suit=/obj/item/clothing/suit/space/eva/plasmaman/cargo
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/cargo
if("Shaft Miner")
suit=/obj/item/clothing/suit/space/eva/plasmaman/explorer
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/explorer
if("Botanist")
suit=/obj/item/clothing/suit/space/eva/plasmaman/botanist
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/botanist
/datum/species/plasmaman/before_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE)
var/current_job = J.title
var/datum/outfit/plasmaman/O = new /datum/outfit/plasmaman
switch(current_job)
if("Chaplain")
suit=/obj/item/clothing/suit/space/eva/plasmaman/chaplain
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/chaplain
if("Janitor")
suit=/obj/item/clothing/suit/space/eva/plasmaman/janitor
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/janitor
if("Civilian", "Barber")
suit=/obj/item/clothing/suit/space/eva/plasmaman/assistant
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/assistant
if("Clown")
suit=/obj/item/clothing/suit/space/eva/plasmaman/clown
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/clown
if("Mime")
suit=/obj/item/clothing/suit/space/eva/plasmaman/mime
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/mime
if("Syndicate Officer")
suit=/obj/item/clothing/suit/space/eva/plasmaman/nuclear
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/nuclear
O = new /datum/outfit/plasmaman/chaplain
if((H.mind.special_role == SPECIAL_ROLE_WIZARD) || (H.mind.special_role == SPECIAL_ROLE_WIZARD_APPRENTICE))
H.equip_to_slot(new /obj/item/clothing/suit/space/eva/plasmaman/wizard(H), slot_wear_suit)
H.equip_to_slot(new /obj/item/clothing/head/helmet/space/eva/plasmaman/wizard(H), slot_head)
else
H.equip_or_collect(new suit(H), slot_wear_suit)
H.equip_or_collect(new helm(H), slot_head)
H.equip_or_collect(new /obj/item/tank/plasma/plasmaman(H), tank_slot) // Bigger plasma tank from Raggy.
H.equip_or_collect(new /obj/item/plasmensuit_cartridge(H), slot_in_backpack)
H.equip_or_collect(new /obj/item/plasmensuit_cartridge(H), slot_in_backpack) //Two refill cartridges for their suit. Can fit in boxes.
to_chat(H, "<span class='notice'>You are now running on plasma internals from the [H.s_store] in your [tank_slot_name]. You must breathe plasma in order to survive, and are extremely flammable.</span>")
H.internal = H.get_item_by_slot(tank_slot)
if("Librarian")
O = new /datum/outfit/plasmaman/librarian
if("Janitor")
O = new /datum/outfit/plasmaman/janitor
if("Botanist")
O = new /datum/outfit/plasmaman/botany
if("Bartender", "Internal Affairs Agent", "Magistrate", "Nanotrasen Representative", "Nanotrasen Navy Officer")
O = new /datum/outfit/plasmaman/bar
if("Chef")
O = new /datum/outfit/plasmaman/chef
if("Security Officer", "Security Pod Pilot", "Special Operations Officer")
O = new /datum/outfit/plasmaman/security
if("Detective")
O = new /datum/outfit/plasmaman/detective
if("Warden")
O = new /datum/outfit/plasmaman/warden
if("Head of Security")
O = new /datum/outfit/plasmaman/hos
if("Cargo Technician", "Quartermaster")
O = new /datum/outfit/plasmaman/cargo
if("Shaft Miner")
O = new /datum/outfit/plasmaman/mining
if("Medical Doctor", "Brig Physician", "Paramedic", "Coroner")
O = new /datum/outfit/plasmaman/medical
if("Chief Medical Officer")
O = new /datum/outfit/plasmaman/cmo
if("Chemist")
O = new /datum/outfit/plasmaman/chemist
if("Geneticist")
O = new /datum/outfit/plasmaman/genetics
if("Roboticist")
O = new /datum/outfit/plasmaman/robotics
if("Virologist")
O = new /datum/outfit/plasmaman/viro
if("Scientist")
O = new /datum/outfit/plasmaman/science
if("Research Director")
O = new /datum/outfit/plasmaman/rd
if("Station Engineer", "Mechanic")
O = new /datum/outfit/plasmaman/engineering
if("Chief Engineer")
O = new /datum/outfit/plasmaman/ce
if("Life Support Specialist")
O = new /datum/outfit/plasmaman/atmospherics
if("Mime")
O = new /datum/outfit/plasmaman/mime
if("Clown")
O = new /datum/outfit/plasmaman/clown
if("Head of Personnel")
O = new /datum/outfit/plasmaman/hop
if("Captain")
O = new /datum/outfit/plasmaman/captain
if("Blueshield")
O = new /datum/outfit/plasmaman/blueshield
H.equipOutfit(O, visualsOnly)
H.internal = H.r_hand
H.update_action_buttons_icon()
return FALSE
/datum/species/plasmaman/handle_life(mob/living/carbon/human/H)
if(!istype(H.wear_suit, /obj/item/clothing/suit/space/eva/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/eva/plasmaman))
var/datum/gas_mixture/environment = H.loc.return_air()
if(environment && environment.oxygen && environment.oxygen >= OXYCONCEN_PLASMEN_IGNITION) //Plasmamen so long as there's enough oxygen (0.5 moles, same as it takes to burn gaseous plasma).
H.adjust_fire_stacks(0.5)
if(!H.on_fire && H.fire_stacks > 0)
H.visible_message("<span class='danger'>[H]'s body reacts with the atmosphere and bursts into flames!</span>","<span class='userdanger'>Your body reacts with the atmosphere and bursts into flame!</span>")
H.IgniteMob()
var/datum/gas_mixture/environment = H.loc.return_air()
var/atmos_sealed = FALSE
if (H.wear_suit && H.head && istype(H.wear_suit, /obj/item/clothing) && istype(H.head, /obj/item/clothing))
var/obj/item/clothing/CS = H.wear_suit
var/obj/item/clothing/CH = H.head
if (CS.flags & CH.flags & STOPSPRESSUREDMAGE)
atmos_sealed = TRUE
if((!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman)) && !atmos_sealed)
if(environment)
if(environment.total_moles())
if(environment.oxygen && environment.oxygen >= OXYCONCEN_PLASMEN_IGNITION) //Same threshhold that extinguishes fire
H.adjust_fire_stacks(0.5)
if(!H.on_fire && H.fire_stacks > 0)
H.visible_message("<span class='danger'>[H]'s body reacts with the atmosphere and bursts into flames!</span>","<span class='userdanger'>Your body reacts with the atmosphere and bursts into flame!</span>")
H.IgniteMob()
else
if(H.on_fire && H.fire_stacks > 0)
var/obj/item/clothing/suit/space/eva/plasmaman/P = H.wear_suit
if(H.fire_stacks)
var/obj/item/clothing/under/plasmaman/P = H.w_uniform
if(istype(P))
P.Extinguish(H)
H.update_fire()
@@ -7,19 +7,19 @@
/mob/living/carbon/human/SetStunned(amount, updating = 1, force = 0)
if(dna.species)
amount = amount * dna.species.stun_mod
..()
return ..()
/mob/living/carbon/human/SetWeakened(amount, updating = 1, force = 0)
if(dna.species)
amount = amount * dna.species.stun_mod
..()
return ..()
/mob/living/carbon/human/SetParalysis(amount, updating = 1, force = 0)
if(dna.species)
amount = amount * dna.species.stun_mod
..()
return ..()
/mob/living/carbon/human/SetSleeping(amount, updating = 1, no_alert = FALSE)
if(dna.species)
amount = amount * dna.species.stun_mod
..()
return ..()
@@ -586,7 +586,8 @@ var/global/list/damage_icon_parts = list()
standing.overlays += image("icon" = A.sprite_sheets[dna.species.name], "icon_state" = "[A.icon_state]")
else
standing.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]")
standing.alpha = w_uniform.alpha
standing.color = w_uniform.color
overlays_standing[UNIFORM_LAYER] = standing
else
// Automatically drop anything in store / id / belt if you're not wearing a uniform. //CHECK IF NECESARRY
@@ -716,12 +717,13 @@ var/global/list/damage_icon_parts = list()
l_ear.screen_loc = ui_l_ear //...draw the item in the inventory screen
client.screen += l_ear //Either way, add the item to the HUD
var/t_type = l_ear.icon_state
var/t_type = l_ear.item_state
if(!t_type)
t_type = l_ear.icon_state
if(l_ear.icon_override)
t_type = "[t_type]_l"
overlays_standing[EARS_LAYER] = mutable_appearance(l_ear.icon_override, "[t_type]", layer = -EARS_LAYER)
else if(l_ear.sprite_sheets && l_ear.sprite_sheets[dna.species.name])
t_type = "[t_type]_l"
overlays_standing[EARS_LAYER] = mutable_appearance(l_ear.sprite_sheets[dna.species.name], "[t_type]", layer = -EARS_LAYER)
else
overlays_standing[EARS_LAYER] = mutable_appearance('icons/mob/ears.dmi', "[t_type]", layer = -EARS_LAYER)
@@ -732,12 +734,13 @@ var/global/list/damage_icon_parts = list()
r_ear.screen_loc = ui_r_ear //...draw the item in the inventory screen
client.screen += r_ear //Either way, add the item to the HUD
var/t_type = r_ear.icon_state
var/t_type = r_ear.item_state
if(!t_type)
t_type = r_ear.icon_state
if(r_ear.icon_override)
t_type = "[t_type]_r"
overlays_standing[EARS_LAYER] = mutable_appearance(r_ear.icon_override, "[t_type]", layer = -EARS_LAYER)
else if(r_ear.sprite_sheets && r_ear.sprite_sheets[dna.species.name])
t_type = "[t_type]_r"
overlays_standing[EARS_LAYER] = mutable_appearance(r_ear.sprite_sheets[dna.species.name], "[t_type]", layer = -EARS_LAYER)
else
overlays_standing[EARS_LAYER] = mutable_appearance('icons/mob/ears.dmi', "[t_type]", layer = -EARS_LAYER)
@@ -769,6 +772,8 @@ var/global/list/damage_icon_parts = list()
var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "shoeblood")
bloodsies.color = shoes.blood_color
standing.overlays += bloodsies
standing.alpha = shoes.alpha
standing.color = shoes.color
overlays_standing[SHOES_LAYER] = standing
else
if(feet_blood_DNA)
@@ -819,6 +824,8 @@ var/global/list/damage_icon_parts = list()
var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "helmetblood")
bloodsies.color = head.blood_color
standing.overlays += bloodsies
standing.alpha = head.alpha
standing.color = head.color
overlays_standing[HEAD_LAYER] = standing
apply_overlay(HEAD_LAYER)
@@ -886,6 +893,8 @@ var/global/list/damage_icon_parts = list()
bloodsies.color = wear_suit.blood_color
standing.overlays += bloodsies
standing.alpha = wear_suit.alpha
standing.color = wear_suit.color
overlays_standing[SUIT_LAYER] = standing
apply_overlay(SUIT_LAYER)
@@ -931,27 +940,31 @@ var/global/list/damage_icon_parts = list()
if(inv)
inv.update_icon()
if(wear_mask && (istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/accessory)))
var/obj/item/organ/external/head/head_organ = get_organ("head")
var/datum/sprite_accessory/alt_heads/alternate_head
if(head_organ.alt_head && head_organ.alt_head != "None")
alternate_head = GLOB.alt_heads_list[head_organ.alt_head]
if(!(slot_wear_mask in check_obscured_slots()))
var/obj/item/organ/external/head/head_organ = get_organ("head")
var/datum/sprite_accessory/alt_heads/alternate_head
if(head_organ.alt_head && head_organ.alt_head != "None")
alternate_head = GLOB.alt_heads_list[head_organ.alt_head]
var/mutable_appearance/standing
var/icon/mask_icon = new(wear_mask.icon)
if(wear_mask.icon_override)
mask_icon = new(wear_mask.icon_override)
standing = mutable_appearance(wear_mask.icon_override, "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]", layer = -FACEMASK_LAYER)
else if(wear_mask.sprite_sheets && wear_mask.sprite_sheets[dna.species.name])
mask_icon = new(wear_mask.sprite_sheets[dna.species.name])
standing = mutable_appearance(wear_mask.sprite_sheets[dna.species.name], "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]", layer = -FACEMASK_LAYER)
else
standing = mutable_appearance('icons/mob/mask.dmi', "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]", layer = -FACEMASK_LAYER)
var/mutable_appearance/standing
var/icon/mask_icon = new(wear_mask.icon)
if(wear_mask.icon_override)
mask_icon = new(wear_mask.icon_override)
standing = mutable_appearance(wear_mask.icon_override, "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]", layer = -FACEMASK_LAYER)
else if(wear_mask.sprite_sheets && wear_mask.sprite_sheets[dna.species.name])
mask_icon = new(wear_mask.sprite_sheets[dna.species.name])
standing = mutable_appearance(wear_mask.sprite_sheets[dna.species.name], "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]", layer = -FACEMASK_LAYER)
else
standing = mutable_appearance('icons/mob/mask.dmi', "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]", layer = -FACEMASK_LAYER)
if(!istype(wear_mask, /obj/item/clothing/mask/cigarette) && wear_mask.blood_DNA)
var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "maskblood")
bloodsies.color = wear_mask.blood_color
standing.overlays += bloodsies
overlays_standing[FACEMASK_LAYER] = standing
if(!istype(wear_mask, /obj/item/clothing/mask/cigarette) && wear_mask.blood_DNA)
var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "maskblood")
bloodsies.color = wear_mask.blood_color
standing.overlays += bloodsies
standing.alpha = wear_mask.alpha
standing.color = wear_mask.color
overlays_standing[FACEMASK_LAYER] = standing
apply_overlay(FACEMASK_LAYER)
@@ -973,6 +986,8 @@ var/global/list/damage_icon_parts = list()
standing = mutable_appearance('icons/mob/back.dmi', "[back.icon_state]", layer = -BACK_LAYER)
//create the image
standing.alpha = back.alpha
standing.color = back.color
overlays_standing[BACK_LAYER] = standing
apply_overlay(BACK_LAYER)
@@ -1006,9 +1021,14 @@ var/global/list/damage_icon_parts = list()
if(!t_state)
t_state = r_hand.icon_state
var/mutable_appearance/I = mutable_appearance(r_hand.righthand_file, "[t_state]", layer = -R_HAND_LAYER)
I = center_image(I, r_hand.inhand_x_dimension, r_hand.inhand_y_dimension)
overlays_standing[R_HAND_LAYER] = I
var/mutable_appearance/standing
if(r_hand.sprite_sheets_inhand && r_hand.sprite_sheets_inhand[dna.species.name])
t_state = "[t_state]_r"
standing = mutable_appearance(r_hand.sprite_sheets_inhand[dna.species.name], "[t_state]", layer = -R_HAND_LAYER)
else
standing = mutable_appearance(r_hand.righthand_file, "[t_state]", layer = -R_HAND_LAYER)
standing = center_image(standing, r_hand.inhand_x_dimension, r_hand.inhand_y_dimension)
overlays_standing[R_HAND_LAYER] = standing
apply_overlay(R_HAND_LAYER)
@@ -1020,9 +1040,14 @@ var/global/list/damage_icon_parts = list()
if(!t_state)
t_state = l_hand.icon_state
var/mutable_appearance/I = mutable_appearance(l_hand.lefthand_file, "[t_state]", layer = -L_HAND_LAYER)
I = center_image(I, l_hand.inhand_x_dimension, l_hand.inhand_y_dimension)
overlays_standing[L_HAND_LAYER] = I
var/mutable_appearance/standing
if(l_hand.sprite_sheets_inhand && l_hand.sprite_sheets_inhand[dna.species.name])
t_state = "[t_state]_l"
standing = mutable_appearance(l_hand.sprite_sheets_inhand[dna.species.name], "[t_state]", layer = -L_HAND_LAYER)
else
standing = mutable_appearance(l_hand.lefthand_file, "[t_state]", layer = -L_HAND_LAYER)
standing = center_image(standing, l_hand.inhand_x_dimension, l_hand.inhand_y_dimension)
overlays_standing[L_HAND_LAYER] = standing
apply_overlay(L_HAND_LAYER)
//human HUD updates for items in our inventory
+1 -1
View File
@@ -332,7 +332,7 @@
break //Only count the first bedsheet
if(drunk)
comfort += 1 //Aren't naps SO much better when drunk?
AdjustDrunk(1-0.0015*comfort) //reduce drunkenness ~6% per two seconds, when on floor.
AdjustDrunk(-0.2*comfort) //reduce drunkenness while sleeping.
if(comfort > 1 && prob(3))//You don't heal if you're just sleeping on the floor without a blanket.
adjustBruteLoss(-1*comfort)
adjustFireLoss(-1*comfort)
@@ -146,6 +146,44 @@
stat(null,"Power Level: [powerlevel]")
/mob/living/carbon/slime/updatehealth(reason)
. = ..()
update_health_hud()
/mob/living/carbon/slime/proc/update_health_hud()
if(hud_used)
var/severity = 0
var/healthpercent = (health/maxHealth) * 100
if(stat != DEAD)
switch(healthpercent)
if(100 to INFINITY)
healths.icon_state = "slime_health0"
if(80 to 100)
healths.icon_state = "slime_health1"
severity = 1
if(60 to 80)
healths.icon_state = "slime_health2"
severity = 2
if(40 to 60)
healths.icon_state = "slime_health3"
severity = 3
if(20 to 40)
healths.icon_state = "slime_health4"
severity = 4
if(0 to 20)
healths.icon_state = "slime_health5"
severity = 5
if(-199 to 0)
healths.icon_state = "slime_health6"
severity = 6
else
healths.icon_state = "slime_health7"
severity = 6
if(severity > 0)
overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
else
clear_fullscreen("brute")
/mob/living/carbon/slime/adjustFireLoss(amount)
..(-abs(amount)) // Heals them
return
+29 -1
View File
@@ -44,6 +44,22 @@
if(BRAIN)
return adjustBrainLoss(damage)
/mob/living/proc/get_damage_amount(damagetype = BRUTE)
switch(damagetype)
if(BRUTE)
return getBruteLoss()
if(BURN)
return getFireLoss()
if(TOX)
return getToxLoss()
if(OXY)
return getOxyLoss()
if(CLONE)
return getCloneLoss()
if(STAMINA)
return getStaminaLoss()
/mob/living/proc/apply_damages(var/brute = 0, var/burn = 0, var/tox = 0, var/oxy = 0, var/clone = 0, var/def_zone = null, var/blocked = 0, var/stamina = 0)
if(blocked >= 100) return 0
if(brute) apply_damage(brute, BRUTE, def_zone, blocked)
@@ -309,4 +325,16 @@
updatehealth("take overall damage")
/mob/living/proc/has_organic_damage()
return (maxHealth - health)
return (maxHealth - health)
//heal up to amount damage, in a given order
/mob/living/proc/heal_ordered_damage(amount, list/damage_types)
. = amount //we'll return the amount of damage healed
for(var/i in damage_types)
var/amount_to_heal = min(amount, get_damage_amount(i)) //heal only up to the amount of damage we have
if(amount_to_heal)
apply_damage_type(-amount_to_heal, i)
amount -= amount_to_heal //remove what we healed from our current amount
if(!amount)
break
. -= amount //if there's leftover healing, remove it from what we return
+1 -2
View File
@@ -59,8 +59,7 @@
handle_status_effects() //all special effects, stunned, weakened, jitteryness, hallucination, sleeping, etc
if(client)
//regular_hud_updates() //THIS DOESN'T FUCKING UPDATE SHIT
handle_regular_hud_updates() //IT JUST REMOVES FUCKING HUD IMAGES
handle_regular_hud_updates()
..()
+2
View File
@@ -256,8 +256,10 @@
death()
to_chat(src, "<span class='notice'>You have given up life and succumbed to death.</span>")
/mob/living/proc/InCritical()
return (health < HEALTH_THRESHOLD_CRIT && health > HEALTH_THRESHOLD_DEAD && stat == UNCONSCIOUS)
/mob/living/ex_act(severity)
..()
+34 -19
View File
@@ -216,7 +216,7 @@ proc/get_radio_key_from_channel(var/channel)
message_range = 1
if(pressure < ONE_ATMOSPHERE * 0.4) //sound distortion pressure, to help clue people in that the air is thin, even if it isn't a vacuum yet
italics = 1
italics = TRUE
sound_vol *= 0.5 //muffle the sound a bit, so it's like we're actually talking through contact
var/list/hear = hear(message_range, T)
@@ -236,12 +236,20 @@ proc/get_radio_key_from_channel(var/channel)
for(var/mob/M in GLOB.player_list)
if(!M.client)
continue //skip monkeys and leavers
continue
if(isnewplayer(M))
continue
if(M.stat == DEAD && M.client && M.get_preference(CHAT_GHOSTEARS) && client) // client is so that ghosts don't have to listen to mice
listening |= M
continue
if(isobserver(M))
if(M.get_preference(CHAT_GHOSTEARS) && client) // The client check is so that ghosts don't have to listen to mice.
listening |= M
continue
if(message_range < world.view && (get_dist(T, M) <= world.view))
listening |= M
continue
if(get_turf(M) in hearturfs)
listening |= M
@@ -291,10 +299,13 @@ proc/get_radio_key_from_channel(var/channel)
log_emote(message, src)
for(var/mob/M in GLOB.dead_mob_list)
if(!M.client || istype(M, /mob/new_player))
continue //skip monkeys, leavers and new players //who the hell knows why new players are in the dead mob list
if(!M.client)
continue //skip monkeys and leavers
if(M.stat == DEAD && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
if(isnewplayer(M))
continue
if(isobserver(M) && M.get_preference(CHAT_GHOSTSIGHT) && !(M in viewers(src, null)) && client) // The client check makes sure people with ghost sight don't get spammed by simple mobs emoting.
M.show_message(message)
switch(type)
@@ -380,7 +391,7 @@ proc/get_radio_key_from_channel(var/channel)
var/list/hearturfs = list()
//Pass whispers on to anything inside the immediate listeners.
// Pass whispers on to anything inside the immediate listeners.
// This comes before the ghosts do so that ghosts don't act as whisper relays
for(var/atom/L in listening)
if(ismob(L))
@@ -391,22 +402,26 @@ proc/get_radio_key_from_channel(var/channel)
if(isobj(L))
hearturfs += get_turf(L)
//ghosts
for(var/mob/M in GLOB.dead_mob_list) //does this include players who joined as observers as well?
// Loop through all players to see if they need to hear it.
for(var/mob/M in GLOB.player_list)
if(!M.client)
continue
if(M.stat == DEAD && M.client && M.get_preference(CHAT_GHOSTEARS))
listening |= M
// This, in tandem with "hearturfs", lets nested mobs hear whispers that are in range
// Grifted from saycode above.
for(var/mob/M in GLOB.player_list)
if(!M.client || isnewplayer(M))
continue //skip monkeys and leavers
if(isnewplayer(M))
continue
if(isobserver(M))
if(M.get_preference(CHAT_GHOSTEARS)) // The client check is so that ghosts don't have to listen to mice.
listening |= M
continue
if(message_range < world.view && (get_dist(whisper_loc, M) <= world.view))
listening |= M
continue
if(get_turf(M) in hearturfs)
listening |= M
//pass on the message to objects that can hear us.
for(var/obj/O in view(message_range, whisper_loc))
spawn(0)
+6 -6
View File
@@ -498,7 +498,7 @@ var/list/ai_verbs_default = list(
if(check_unable(AI_CHECK_WIRELESS))
return
var/input = input(usr, "Please enter the reason for calling the shuttle.", "Shuttle Call Reason.","") as text|null
var/input = clean_input("Please enter the reason for calling the shuttle.", "Shuttle Call Reason.","")
if(!input || stat)
return
@@ -634,7 +634,7 @@ var/list/ai_verbs_default = list(
return
if(href_list["trackbot"])
var/mob/living/simple_animal/bot/target = locate(href_list["trackbot"]) in GLOB.simple_animals
var/mob/living/simple_animal/bot/target = locate(href_list["trackbot"]) in GLOB.bots_list
if(target)
ai_actual_track(target)
else
@@ -642,7 +642,7 @@ var/list/ai_verbs_default = list(
return
if(href_list["callbot"]) //Command a bot to move to a selected location.
Bot = locate(href_list["callbot"]) in GLOB.simple_animals
Bot = locate(href_list["callbot"]) in GLOB.bots_list
if(!Bot || Bot.remote_disabled || control_disabled)
return //True if there is no bot found, the bot is manually emagged, or the AI is carded with wireless off.
waypoint_mode = 1
@@ -650,7 +650,7 @@ var/list/ai_verbs_default = list(
return
if(href_list["interface"]) //Remotely connect to a bot!
Bot = locate(href_list["interface"]) in GLOB.simple_animals
Bot = locate(href_list["interface"]) in GLOB.bots_list
if(!Bot || Bot.remote_disabled || control_disabled)
return
Bot.attack_ai(src)
@@ -746,7 +746,7 @@ var/list/ai_verbs_default = list(
d += "<A HREF=?src=[UID()];botrefresh=\ref[Bot]>Query network status</A><br>"
d += "<table width='100%'><tr><td width='40%'><h3>Name</h3></td><td width='20%'><h3>Status</h3></td><td width='30%'><h3>Location</h3></td><td width='10%'><h3>Control</h3></td></tr>"
for(var/mob/living/simple_animal/bot/Bot in GLOB.simple_animals)
for(var/mob/living/simple_animal/bot/Bot in GLOB.bots_list)
if(is_ai_allowed(Bot.z) && !Bot.remote_disabled) //Only non-emagged bots on the allowed Z-level are detected!
bot_area = get_area(Bot)
d += "<tr><td width='30%'>[Bot.hacked ? "<span class='bad'>(!) </span>[Bot.name]" : Bot.name] ([Bot.model])</td>"
@@ -1074,7 +1074,7 @@ var/list/ai_verbs_default = list(
set desc = "Change the message that's transmitted when a new crew member arrives on station."
set category = "AI Commands"
var/newmsg = input("What would you like the arrival message to be? List of options: $name, $rank, $species, $gender, $age", "Change Arrival Message", arrivalmsg) as text
var/newmsg = clean_input("What would you like the arrival message to be? List of options: $name, $rank, $species, $gender, $age", "Change Arrival Message", arrivalmsg)
if(newmsg != arrivalmsg)
arrivalmsg = newmsg
to_chat(usr, "The arrival message has been successfully changed.")
@@ -31,6 +31,7 @@
ai.camera_visibility(src)
if(ai.client && !ai.multicam_on)
ai.client.eye = src
update_parallax_contents()
//Holopad
if(ai.master_multicam)
ai.master_multicam.refresh_view()
+2 -2
View File
@@ -107,6 +107,8 @@
aiRestorePowerRoutine = 0
update_blind_effects()
update_sight()
to_chat(src, "Here are your current laws:")
show_laws()
return
switch(PRP)
@@ -126,8 +128,6 @@
theAPC.attack_ai(src)
apc_override = 0
aiRestorePowerRoutine = 3
to_chat(src, "Here are your current laws:")
src.show_laws() //WHY THE FUCK IS THIS HERE
sleep(50)
theAPC = null
+1 -1
View File
@@ -99,7 +99,7 @@ var/const/VOX_PATH = "sound/vox_fem/"
to_chat(src, "<span class='warning'>Please wait [round((announcing_vox - world.time) / 10)] seconds.</span>")
return
var/message = input(src, "WARNING: Misuse of this verb can result in you being job banned. More help is available in 'Announcement Help'", "Announcement", last_announcement) as text|null
var/message = clean_input("WARNING: Misuse of this verb can result in you being job banned. More help is available in 'Announcement Help'", "Announcement", last_announcement, src)
last_announcement = message
@@ -235,6 +235,12 @@
to_chat(user, "<span class='notice'>Body Temperature: ???</span>")
return
user.visible_message("<span class='notice'>[user] has analyzed [M]'s components.</span>","<span class='notice'>You have analyzed [M]'s components.</span>")
robot_healthscan(user, M)
add_fingerprint(user)
proc/robot_healthscan(mob/user, mob/living/M)
var/scan_type
if(istype(M, /mob/living/silicon/robot))
scan_type = "robot"
@@ -244,7 +250,7 @@
to_chat(user, "<span class='warning'>You can't analyze non-robotic things!</span>")
return
user.visible_message("<span class='notice'>[user] has analyzed [M]'s components.</span>","<span class='notice'>You have analyzed [M]'s components.</span>")
switch(scan_type)
if("robot")
var/BU = M.getFireLoss() > 50 ? "<b>[M.getFireLoss()]</b>" : M.getFireLoss()
@@ -308,5 +314,3 @@
to_chat(user, "<span class='notice'>Internal Fluid Level:[H.blood_volume]/[H.max_blood]</span>")
if(H.bleed_rate)
to_chat(user, "<span class='warning'>Warning:External component leak detected!</span>")
src.add_fingerprint(user)
@@ -576,6 +576,8 @@ var/list/robot_verbs_default = list(
/mob/living/silicon/robot/restrained()
return 0
/mob/living/silicon/robot/InCritical()
return low_power_mode
/mob/living/silicon/robot/ex_act(severity)
switch(severity)
@@ -883,6 +885,8 @@ var/list/robot_verbs_default = list(
/mob/living/silicon/robot/attack_ghost(mob/user)
if(wiresexposed)
wires.Interact(user)
else
..() //this calls the /mob/living/attack_ghost proc for the ghost health/cyborg analyzer
/mob/living/silicon/robot/proc/allowed(obj/item/I)
var/obj/dummy = new /obj(null) // Create a dummy object to check access on as to avoid having to snowflake check_access on every mob
@@ -1456,4 +1460,4 @@ var/list/robot_verbs_default = list(
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT)
sync_lighting_plane_alpha()
+2 -1
View File
@@ -337,4 +337,5 @@
/////////////////////////////////// EAR DAMAGE ////////////////////////////////////
/mob/living/silicon/can_hear()
. = TRUE
. = TRUE
@@ -48,7 +48,7 @@
..()
light_color = LIGHT_COLOR_PURE_RED //if you see a red one. RUN!!
/mob/living/simple_animal/bot/secbot/griefsky/Crossed(atom/movable/AM)
/mob/living/simple_animal/bot/secbot/griefsky/Crossed(atom/movable/AM, oldloc)
..()
if(ismob(AM) && AM == target)
var/mob/living/carbon/C = AM
@@ -298,7 +298,7 @@
target = user
mode = BOT_HUNT
/mob/living/simple_animal/bot/honkbot/Crossed(atom/movable/AM)
/mob/living/simple_animal/bot/honkbot/Crossed(atom/movable/AM, oldloc)
if(ismob(AM) && on) //only if its online
if(prob(30)) //you're far more likely to trip on a honkbot
var/mob/living/carbon/C = AM
@@ -439,7 +439,7 @@ Auto Patrol: []"},
target = user
mode = BOT_HUNT
/mob/living/simple_animal/bot/secbot/Crossed(atom/movable/AM)
/mob/living/simple_animal/bot/secbot/Crossed(atom/movable/AM, oldloc)
if(ismob(AM) && target)
var/mob/living/carbon/C = AM
if(!istype(C) || !C || in_range(src, target))
@@ -24,7 +24,7 @@
/mob/living/simple_animal/cockroach/can_die()
return ..() && !SSticker.cinematic //If the nuke is going off, then cockroaches are invincible. Keeps the nuke from killing them, cause cockroaches are immune to nukes.
/mob/living/simple_animal/cockroach/Crossed(var/atom/movable/AM)
/mob/living/simple_animal/cockroach/Crossed(var/atom/movable/AM, oldloc)
if(isliving(AM))
var/mob/living/A = AM
if(A.mob_size > MOB_SIZE_SMALL)
@@ -165,7 +165,7 @@
/obj/item/clothing/suit/armor/vest,
/obj/item/clothing/suit/armor/vest/blueshield,
/obj/item/clothing/suit/space/deathsquad,
/obj/item/clothing/suit/space/hardsuit/engineering,
/obj/item/clothing/suit/space/hardsuit/engine,
/obj/item/radio,
/obj/item/radio/off,
/obj/item/clothing/suit/cardborg,
@@ -356,7 +356,7 @@
desc = "That's not red paint. That's real corgi blood."
valid = 1
if(/obj/item/clothing/head/helmet/space/hardsuit/engineering)
if(/obj/item/clothing/suit/space/hardsuit/engine)
name = "Space Explorer [real_name]"
desc = "That's one small step for a corgi. One giant yap for corgikind."
valid = 1
@@ -34,13 +34,29 @@
holder_type = /obj/item/holder/mouse
can_collar = 1
gold_core_spawnable = CHEM_MOB_SPAWN_FRIENDLY
var/chew_probability = 1
/mob/living/simple_animal/mouse/Initialize(mapload)
. = ..()
AddComponent(/datum/component/squeak, list('sound/creatures/mousesqueak.ogg' = 1), 100)
/mob/living/simple_animal/mouse/handle_automated_action()
if(prob(chew_probability))
var/turf/simulated/floor/F = get_turf(src)
if(istype(F) && !F.intact)
var/obj/structure/cable/C = locate() in F
if(C && prob(15))
if(C.avail())
visible_message("<span class='warning'>[src] chews through [C]. It's toast!</span>")
playsound(src, 'sound/effects/sparks2.ogg', 100, 1)
C.deconstruct()
toast() // mmmm toasty.
else
C.deconstruct()
visible_message("<span class='warning'>[src] chews through [C].</span>")
/mob/living/simple_animal/mouse/handle_automated_speech()
..()
..()
if(prob(speak_chance))
for(var/mob/M in view())
M << squeak_sound
@@ -91,14 +107,19 @@
to_chat(src, "<span class='warning'>You are too small to pull anything.</span>")
return
/mob/living/simple_animal/mouse/Crossed(AM as mob|obj)
/mob/living/simple_animal/mouse/Crossed(AM as mob|obj, oldloc)
if(ishuman(AM))
if(!stat)
var/mob/M = AM
to_chat(M, "<span class='notice'>[bicon(src)] Squeek!</span>")
..()
/mob/living/simple_animal/mouse/death(gibbed)
/mob/living/simple_animal/mouse/proc/toast()
add_atom_colour("#3A3A3A", FIXED_COLOUR_PRIORITY)
desc = "It's toast."
death()
/mob/living/simple_animal/mouse/death(gibbed)
// Only execute the below if we successfully died
playsound(src, squeak_sound, 40, 1)
. = ..(gibbed)
@@ -16,6 +16,10 @@
turns_per_move = 10
icon = 'icons/mob/penguins.dmi'
/mob/living/simple_animal/pet/penguin/Initialize(mapload)
. = ..()
AddComponent(/datum/component/waddling)
/mob/living/simple_animal/pet/penguin/emperor
name = "Emperor penguin"
real_name = "penguin"
@@ -12,8 +12,8 @@
response_disarm = "shoos"
response_harm = "stomps on"
emote_see = list("jiggles", "bounces in place")
var/colour = "grey"
pass_flags = PASSTABLE
var/colour = "grey"
/mob/living/simple_animal/slime/adult
health = 200
@@ -24,3 +24,37 @@
/mob/living/simple_animal/slime/New()
..()
overlays += "aslime-:33"
/mob/living/simple_animal/slime/updatehealth(reason)
. = ..()
update_health_hud()
/mob/living/simple_animal/slime/proc/update_health_hud()
if(hud_used)
var/severity = 0
var/healthpercent = (health/maxHealth) * 100
switch(healthpercent)
if(100 to INFINITY)
healths.icon_state = "slime_health0"
if(80 to 100)
healths.icon_state = "slime_health1"
severity = 1
if(60 to 80)
healths.icon_state = "slime_health2"
severity = 2
if(40 to 60)
healths.icon_state = "slime_health3"
severity = 3
if(20 to 40)
healths.icon_state = "slime_health4"
severity = 4
if(1 to 20)
healths.icon_state = "slime_health5"
severity = 5
else
healths.icon_state = "slime_health7"
severity = 6
if(severity > 0)
overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
else
clear_fullscreen("brute")
@@ -4,7 +4,7 @@
icon = 'icons/mob/alien.dmi'
icon_state = "alienh_running"
icon_living = "alienh_running"
icon_dead = "alien_l"
icon_dead = "alienh_dead"
icon_gib = "syndicate_gib"
response_help = "pokes the"
response_disarm = "shoves the"
@@ -40,7 +40,7 @@
name = "alien drone"
icon_state = "aliend_running"
icon_living = "aliend_running"
icon_dead = "aliend_l"
icon_dead = "aliend_dead"
health = 60
maxHealth = 60
melee_damage_lower = 15
@@ -61,7 +61,7 @@
name = "alien sentinel"
icon_state = "aliens_running"
icon_living = "aliens_running"
icon_dead = "aliens_l"
icon_dead = "aliens_dead"
health = 120
maxHealth = 120
melee_damage_lower = 15
@@ -77,7 +77,7 @@
name = "alien queen"
icon_state = "alienq_running"
icon_living = "alienq_running"
icon_dead = "alienq_l"
icon_dead = "alienq_d"
health = 250
maxHealth = 250
melee_damage_lower = 15
@@ -142,7 +142,7 @@
return //no don't attack the goddamm box
else
..()
if(isliving(target))
if(isliving(target) && (!client || a_intent == INTENT_HARM))
var/mob/living/L = target
if(L.reagents)
if(beegent)
@@ -1,7 +1,6 @@
/mob/living/simple_animal/hostile/creature
name = "creature"
desc = "A sanity-destroying otherthing."
icon = 'icons/mob/critter.dmi'
speak_emote = list("gibbers")
icon_state = "otherthing"
icon_living = "otherthing"
@@ -1,100 +1,106 @@
#define EGG_INCUBATION_TIME 120
/mob/living/simple_animal/hostile/headcrab
name = "headslug"
desc = "Absolutely not de-beaked or harmless. Keep away from corpses."
name = "headcrab"
desc = "A small parasitic creature that would like to connect with your brain stem."
icon = 'icons/mob/headcrab.dmi'
icon_state = "headcrab"
icon_living = "headcrab"
icon_dead = "headcrab_dead"
icon = 'icons/mob/mob.dmi'
health = 50
maxHealth = 50
health = 40
maxHealth = 40
melee_damage_lower = 5
melee_damage_upper = 5
attacktext = "chomps"
attack_sound = 'sound/weapons/bite.ogg'
faction = list("creature")
robust_searching = 1
stat_attack = 2
obj_damage = 0
environment_smash = 0
speak_emote = list("squeaks")
ventcrawler = 2
var/datum/mind/origin
var/egg_lain = 0
melee_damage_upper = 10
ranged = 1
ranged_message = "leaps"
ranged_cooldown_time = 40
var/jumpdistance = 4
var/jumpspeed = 1
attacktext = "bites"
attack_sound = 'sound/creatures/headcrab_attack.ogg'
speak_emote = list("hisses")
var/is_zombie = 0
stat_attack = 1 //so they continue to attack when they are on the ground.
var/host_species = ""
var/list/human_overlays = list()
/mob/living/simple_animal/hostile/headcrab/examine(mob/user)
/mob/living/simple_animal/hostile/headcrab/Life(seconds, times_fired)
if(!is_zombie && isturf(src.loc) && stat != DEAD)
for(var/mob/living/carbon/human/H in oview(src, 1)) //Only for corpse right next to/on same tile
if(H.stat == DEAD || (!H.check_death_method() && H.health <= HEALTH_THRESHOLD_DEAD))
Zombify(H)
break
..()
if(stat == DEAD)
to_chat(desc = "It appears to be dead.")
/mob/living/simple_animal/hostile/headcrab/proc/Infect(mob/living/carbon/victim)
var/obj/item/organ/internal/body_egg/changeling_egg/egg = new(victim)
egg.insert(victim)
if(origin)
egg.origin = origin
else if(mind) // Let's make this a feature
egg.origin = mind
for(var/obj/item/organ/internal/I in src)
I.loc = egg
visible_message("<span class='warning'>[src] plants something in [victim]'s flesh!</span>", \
"<span class='danger'>We inject our egg into [victim]'s body!</span>")
egg_lain = 1
/mob/living/simple_animal/hostile/headcrab/OpenFire(atom/A)
if(check_friendly_fire)
for(var/turf/T in getline(src,A)) // Not 100% reliable but this is faster than simulating actual trajectory
for(var/mob/living/L in T)
if(L == src || L == A)
continue
if(faction_check(L) && !attack_same)
return
visible_message("<span class='danger'><b>[src]</b> [ranged_message] at [A]!</span>")
throw_at(A, jumpdistance, jumpspeed, spin = FALSE, diagonals_first = TRUE)
ranged_cooldown = world.time + ranged_cooldown_time
/mob/living/simple_animal/hostile/headcrab/AttackingTarget()
if(egg_lain)
target.attack_animal(src)
return
if(iscarbon(target) && !issmall(target))
// Changeling egg can survive in aliens!
var/mob/living/carbon/C = target
if(C.stat == DEAD)
if(C.status_flags & XENO_HOST)
to_chat(src, "<span class='userdanger'>A foreign presence repels us from this body. Perhaps we should try to infest another?</span>")
return
Infect(target)
to_chat(src, "<span class='userdanger'>With our egg laid, our death approaches rapidly...</span>")
spawn(100)
death()
return
target.attack_animal(src)
/mob/living/simple_animal/hostile/headcrab/proc/Zombify(mob/living/carbon/human/H)
if(!H.check_death_method())
H.death()
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
is_zombie = TRUE
if(H.wear_suit)
var/obj/item/clothing/suit/armor/A = H.wear_suit
if(A.armor && A.armor["melee"])
maxHealth += A.armor["melee"] //That zombie's got armor, I want armor!
maxHealth += 50
health = maxHealth
name = "zombie"
desc = "A corpse animated by the alien being on its head."
melee_damage_lower = 10
melee_damage_upper = 15
ranged = 0
icon = H.icon
speak = list('sound/creatures/zombie_idle1.ogg','sound/creatures/zombie_idle2.ogg','sound/creatures/zombie_idle3.ogg')
speak_chance = 50
speak_emote = list("groans")
attacktext = "bites"
attack_sound = 'sound/creatures/zombie_attack.ogg'
icon_state = "zombie2_s"
if(head_organ)
head_organ.h_style = null
H.update_hair()
host_species = H.dna.species.name
human_overlays = H.overlays
update_icons()
H.forceMove(src)
visible_message("<span class='warning'>The corpse of [H.name] suddenly rises!</span>")
/obj/item/organ/internal/body_egg/changeling_egg
name = "changeling egg"
desc = "Twitching and disgusting."
origin_tech = "biotech=7" // You need to be really lucky to obtain it.
var/datum/mind/origin
var/time
/obj/item/organ/internal/body_egg/changeling_egg/egg_process()
// Changeling eggs grow in dead people
time++
if(time >= EGG_INCUBATION_TIME)
Pop()
remove(owner)
/mob/living/simple_animal/hostile/headcrab/death()
..()
if(is_zombie)
qdel(src)
/obj/item/organ/internal/body_egg/changeling_egg/proc/Pop()
var/mob/living/carbon/human/monkey/M = new(owner)
owner.stomach_contents += M
for(var/obj/item/organ/internal/I in src)
I.insert(M, 1)
/mob/living/simple_animal/hostile/headcrab/handle_automated_speech() // This way they have different screams when attacking, sometimes. Might be seen as sphagetthi code though.
if(speak_chance)
if(rand(0,200) < speak_chance)
if(speak && speak.len)
playsound(get_turf(src), pick(speak), 200, 1)
if(origin && origin.current && (origin.current.stat == DEAD))
origin.transfer_to(M)
if(!origin.changeling)
M.make_changeling()
if(origin.changeling.can_absorb_dna(M, owner))
origin.changeling.absorb_dna(owner, M)
/mob/living/simple_animal/hostile/headcrab/Destroy()
if(contents)
for(var/mob/M in contents)
M.loc = get_turf(src)
return ..()
var/datum/action/changeling/humanform/HF = new
HF.Grant(M)
for(var/power in origin.changeling.purchasedpowers)
var/datum/action/changeling/S = power
if(istype(S) && S.needs_button)
S.Grant(M)
M.key = origin.key
owner.gib()
#undef EGG_INCUBATION_TIME
/mob/living/simple_animal/hostile/headcrab/update_icons()
..()
if(is_zombie)
overlays.Cut()
overlays = human_overlays
var/image/I = image('icons/mob/headcrab.dmi', icon_state = "headcrabpod")
if(host_species == "Vox")
I = image('icons/mob/headcrab.dmi', icon_state = "headcrabpod_vox")
else if(host_species == "Gray")
I = image('icons/mob/headcrab.dmi', icon_state = "headcrabpod_gray")
overlays += I
@@ -0,0 +1,100 @@
#define EGG_INCUBATION_TIME 120
/mob/living/simple_animal/hostile/headslug
name = "headslug"
desc = "Absolutely not de-beaked or harmless. Keep away from corpses."
icon_state = "headslug"
icon_living = "headslug"
icon_dead = "headslug_dead"
icon = 'icons/mob/mob.dmi'
health = 50
maxHealth = 50
melee_damage_lower = 5
melee_damage_upper = 5
attacktext = "chomps"
attack_sound = 'sound/weapons/bite.ogg'
faction = list("creature")
robust_searching = 1
stat_attack = 2
obj_damage = 0
environment_smash = 0
speak_emote = list("squeaks")
ventcrawler = 2
var/datum/mind/origin
var/egg_lain = 0
/mob/living/simple_animal/hostile/headslug/examine(mob/user)
..()
if(stat == DEAD)
to_chat(desc = "It appears to be dead.")
/mob/living/simple_animal/hostile/headslug/proc/Infect(mob/living/carbon/victim)
var/obj/item/organ/internal/body_egg/changeling_egg/egg = new(victim)
egg.insert(victim)
if(origin)
egg.origin = origin
else if(mind) // Let's make this a feature
egg.origin = mind
for(var/obj/item/organ/internal/I in src)
I.loc = egg
visible_message("<span class='warning'>[src] plants something in [victim]'s flesh!</span>", \
"<span class='danger'>We inject our egg into [victim]'s body!</span>")
egg_lain = 1
/mob/living/simple_animal/hostile/headslug/AttackingTarget()
if(egg_lain)
target.attack_animal(src)
return
if(iscarbon(target) && !issmall(target))
// Changeling egg can survive in aliens!
var/mob/living/carbon/C = target
if(C.stat == DEAD)
if(C.status_flags & XENO_HOST)
to_chat(src, "<span class='userdanger'>A foreign presence repels us from this body. Perhaps we should try to infest another?</span>")
return
Infect(target)
to_chat(src, "<span class='userdanger'>With our egg laid, our death approaches rapidly...</span>")
spawn(100)
death()
return
target.attack_animal(src)
/obj/item/organ/internal/body_egg/changeling_egg
name = "changeling egg"
desc = "Twitching and disgusting."
origin_tech = "biotech=7" // You need to be really lucky to obtain it.
var/datum/mind/origin
var/time
/obj/item/organ/internal/body_egg/changeling_egg/egg_process()
// Changeling eggs grow in dead people
time++
if(time >= EGG_INCUBATION_TIME)
Pop()
remove(owner)
qdel(src)
/obj/item/organ/internal/body_egg/changeling_egg/proc/Pop()
var/mob/living/carbon/human/monkey/M = new(owner)
owner.stomach_contents += M
for(var/obj/item/organ/internal/I in src)
I.insert(M, 1)
if(origin && origin.current && (origin.current.stat == DEAD))
origin.transfer_to(M)
if(!origin.changeling)
M.make_changeling()
if(origin.changeling.can_absorb_dna(M, owner))
origin.changeling.absorb_dna(owner, M)
var/datum/action/changeling/humanform/HF = new
HF.Grant(M)
for(var/power in origin.changeling.purchasedpowers)
var/datum/action/changeling/S = power
if(istype(S) && S.needs_button)
S.Grant(M)
M.key = origin.key
owner.gib()
#undef EGG_INCUBATION_TIME
@@ -309,14 +309,18 @@
else
M.Goto(src,M.move_to_delay,M.minimum_distance)
/mob/living/simple_animal/hostile/proc/OpenFire(atom/A)
/mob/living/simple_animal/hostile/proc/CheckFriendlyFire(atom/A)
if(check_friendly_fire)
for(var/turf/T in getline(src,A)) // Not 100% reliable but this is faster than simulating actual trajectory
for(var/mob/living/L in T)
if(L == src || L == A)
continue
if(faction_check(L) && !attack_same)
return
if(faction_check_mob(L) && !attack_same)
return TRUE
/mob/living/simple_animal/hostile/proc/OpenFire(atom/A)
if(CheckFriendlyFire(A))
return
visible_message("<span class='danger'><b>[src]</b> [ranged_message] at [A]!</span>")
if(rapid)
@@ -21,6 +21,7 @@
maxHealth = 50
health = 50
pixel_x = -16
see_in_dark = 8
harm_intent_damage = 8
melee_damage_lower = 15
@@ -37,6 +37,7 @@ Difficulty: Medium
ranged = 1
ranged_cooldown_time = 16
pixel_x = -16
crusher_loot = list(/obj/item/melee/energy/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator, /obj/item/crusher_trophy/miner_eye)
loot = list(/obj/item/melee/energy/cleaving_saw, /obj/item/gun/energy/kinetic_accelerator)
wander = FALSE
del_on_death = TRUE
@@ -48,7 +49,7 @@ Difficulty: Medium
var/guidance = FALSE
deathmessage = "falls to the ground, decaying into glowing particles."
death_sound = "bodyfall"
/obj/item/gps/internal/miner
icon_state = null
gpstag = "Resonant Signal"
@@ -42,6 +42,7 @@ Difficulty: Hard
ranged = 1
pixel_x = -32
del_on_death = 1
crusher_loot = list(/obj/structure/closet/crate/necropolis/bubblegum/crusher)
loot = list(/obj/structure/closet/crate/necropolis/bubblegum)
var/charging = 0
medal_type = BOSS_MEDAL_BUBBLEGUM
@@ -45,7 +45,8 @@ Difficulty: Very Hard
del_on_death = 1
medal_type = BOSS_MEDAL_COLOSSUS
score_type = COLOSSUS_SCORE
loot = list(/obj/machinery/anomalous_crystal/random, /obj/item/organ/internal/vocal_cords/colossus)
crusher_loot = list(/obj/structure/closet/crate/necropolis/colossus/crusher)
loot = list(/obj/structure/closet/crate/necropolis/colossus)
butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30)
deathmessage = "disintegrates, leaving a glowing core in its wake."
death_sound = 'sound/misc/demon_dies.ogg'
@@ -43,6 +43,7 @@ Difficulty: Medium
move_to_delay = 10
ranged = 1
pixel_x = -16
crusher_loot = list(/obj/structure/closet/crate/necropolis/dragon/crusher)
loot = list(/obj/structure/closet/crate/necropolis/dragon)
butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30)
var/swooping = 0
@@ -271,6 +272,7 @@ Difficulty: Medium
melee_damage_lower = 30
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
loot = list()
crusher_loot = list()
/mob/living/simple_animal/hostile/megafauna/dragon/lesser/grant_achievement(medaltype,scoretype)
return
@@ -53,6 +53,7 @@ Difficulty: Hard
ranged_cooldown_time = 40
aggro_vision_range = 23
loot = list(/obj/item/hierophant_staff)
crusher_loot = list(/obj/item/hierophant_staff, /obj/item/crusher_trophy/vortex_talisman)
wander = FALSE
var/burst_range = 3 //range on burst aoe
var/beam_range = 5 //range on cross blast beams
@@ -496,6 +497,7 @@ Difficulty: Hard
icon = 'icons/effects/effects.dmi'
icon_state = "hierophant_blast"
name = "vortex blast"
layer = 3.9 // between LYING_MOB_LAYER and ABOVE_MOB_LAYER
luminosity = 1
desc = "Get out of the way!"
duration = 9
@@ -526,7 +528,7 @@ Difficulty: Hard
sleep(1.3) //slightly forgiving; the burst animation is 1.5 deciseconds
bursting = FALSE //we no longer damage crossers
/obj/effect/temp_visual/hierophant/blast/Crossed(atom/movable/AM)
/obj/effect/temp_visual/hierophant/blast/Crossed(atom/movable/AM, oldloc)
..()
if(bursting)
do_damage(get_turf(src))
@@ -555,6 +557,37 @@ Difficulty: Hard
playsound(M,'sound/weapons/sear.ogg', 50, 1, -4)
M.take_damage(damage, BURN, 0, 0)
/obj/effect/temp_visual/hierophant/wall //smoothing and pooling were not friends, but pooling is dead.
name = "vortex wall"
icon = 'icons/turf/walls/hierophant_wall_temp.dmi'
icon_state = "wall"
light_range = MINIMUM_USEFUL_LIGHT_RANGE
duration = 100
smooth = SMOOTH_TRUE
/obj/effect/temp_visual/hierophant/wall/New(loc, new_caster)
..()
queue_smooth_neighbors(src)
queue_smooth(src)
/obj/effect/temp_visual/hierophant/wall/Destroy()
queue_smooth_neighbors(src)
return ..()
/obj/effect/temp_visual/hierophant/wall/CanPass(atom/movable/mover, turf/target)
if(QDELETED(caster))
return FALSE
if(mover == caster.pulledby)
return TRUE
if(istype(mover, /obj/item/projectile))
var/obj/item/projectile/P = mover
if(P.firer == caster)
return TRUE
if(mover == caster)
return TRUE
return FALSE
/obj/effect/hierophant
name = "hierophant rune"
desc = "A powerful magic mark allowing whomever attunes themself to it to return to it at will."
@@ -31,6 +31,7 @@
/obj/structure/barricade,
/obj/machinery/field,
/obj/machinery/power/emitter)
var/list/crusher_loot
var/medal_type
var/score_type = BOSS_SCORE
var/elimination = 0
@@ -43,6 +44,10 @@
layer = LARGE_MOB_LAYER //Looks weird with them slipping under mineral walls and cameras and shit otherwise
mouse_opacity = MOUSE_OPACITY_OPAQUE // Easier to click on in melee, they're giant targets anyway
/mob/living/simple_animal/hostile/megafauna/New()
..()
apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
/mob/living/simple_animal/hostile/megafauna/Destroy()
QDEL_NULL(internal_gps)
. = ..()
@@ -53,11 +58,17 @@
/mob/living/simple_animal/hostile/megafauna/death(gibbed)
// this happens before the parent call because `del_on_death` may be set
if(can_die() && !admin_spawned)
feedback_set_details("megafauna_kills","[initial(name)]")
var/datum/status_effect/crusher_damage/C = has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
if(C && crusher_loot && C.total_damage >= maxHealth * 0.6)
spawn_crusher_loot()
if(!elimination) //used so the achievment only occurs for the last legion to die.
grant_achievement(medal_type,score_type)
feedback_set_details("megafauna_kills","[initial(name)]")
return ..()
/mob/living/simple_animal/hostile/megafauna/proc/spawn_crusher_loot()
loot = crusher_loot
/mob/living/simple_animal/hostile/megafauna/AttackingTarget()
..()
if(isliving(target))
@@ -77,6 +77,7 @@
stat_attack = 1
flying = TRUE
robust_searching = 1
crusher_loot = /obj/item/crusher_trophy/watcher_wing
loot = list()
butcher_results = list(/obj/item/stack/ore/diamond = 2, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 1)
@@ -102,6 +103,8 @@
light_power = 2.5
light_color = LIGHT_COLOR_ORANGE
projectiletype = /obj/item/projectile/temp/basilisk/magmawing
crusher_loot = /obj/item/crusher_trophy/blaster_tubes/magma_wing
crusher_drop_mod = 60
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/icewing
name = "icewing watcher"
@@ -114,6 +117,8 @@
health = 170
projectiletype = /obj/item/projectile/temp/basilisk/icewing
butcher_results = list(/obj/item/stack/ore/diamond = 5, /obj/item/stack/sheet/bone = 1) //No sinew; the wings are too fragile to be usable
crusher_loot = /obj/item/crusher_trophy/watcher_wing/ice_wing
crusher_drop_mod = 30
/obj/item/projectile/temp/basilisk/magmawing
name = "scorching blast"
@@ -83,6 +83,7 @@
icon_dead = "goliath_dead"
throw_message = "does nothing to the tough hide of the"
pre_attack_icon = "goliath2"
crusher_loot = /obj/item/crusher_trophy/goliath_tentacle
butcher_results = list(/obj/item/reagent_containers/food/snacks/goliath = 2, /obj/item/stack/sheet/animalhide/goliath_hide = 1, /obj/item/stack/sheet/bone = 2)
loot = list()
stat_attack = TRUE
@@ -45,6 +45,9 @@
/mob/living/simple_animal/hostile/asteroid/hivelord/AttackingTarget()
OpenFire()
/mob/living/simple_animal/hostile/asteroid/hivelord/spawn_crusher_loot()
loot += crusher_loot //we don't butcher
/mob/living/simple_animal/hostile/asteroid/hivelord/death(gibbed)
// Only execute the below if we successfully died
. = ..(gibbed)
@@ -52,80 +55,6 @@
return FALSE
mouse_opacity = MOUSE_OPACITY_ICON
/obj/item/organ/internal/hivelord_core
name = "hivelord remains"
desc = "All that remains of a hivelord, it seems to be what allows it to break pieces of itself off without being hurt... its healing properties will soon become inert if not used quickly."
icon_state = "roro core 2"
flags = NOBLUDGEON
slot = "hivecore"
force = 0
actions_types = list(/datum/action/item_action/organ_action/use)
var/inert = 0
var/preserved = 0
/obj/item/organ/internal/hivelord_core/New()
..()
addtimer(CALLBACK(src, .proc/inert_check), 2400)
/obj/item/organ/internal/hivelord_core/proc/inert_check()
if(owner)
preserved(implanted = 1)
else if(preserved)
preserved()
else
go_inert()
/obj/item/organ/internal/hivelord_core/proc/preserved(implanted = 0)
inert = FALSE
preserved = TRUE
update_icon()
if(implanted)
feedback_add_details("hivelord_core", "[type]|implanted")
else
feedback_add_details("hivelord_core", "[type]|stabilizer")
/obj/item/organ/internal/hivelord_core/proc/go_inert()
inert = TRUE
desc = "The remains of a hivelord that have become useless, having been left alone too long after being harvested."
feedback_add_details("hivelord_core", "[src.type]|inert")
update_icon()
/obj/item/organ/internal/hivelord_core/ui_action_click()
owner.revive()
qdel(src)
/obj/item/organ/internal/hivelord_core/on_life()
..()
if(owner.health < HEALTH_THRESHOLD_CRIT)
ui_action_click()
/obj/item/organ/internal/hivelord_core/afterattack(atom/target, mob/user, proximity_flag)
if(proximity_flag && ishuman(target))
var/mob/living/carbon/human/H = target
if(inert)
to_chat(user, "<span class='notice'>[src] has become inert, its healing properties are no more.</span>")
return
else
if(H.stat == DEAD)
to_chat(user, "<span class='notice'>[src] are useless on the dead.</span>")
return
if(H != user)
H.visible_message("[user] forces [H] to apply [src]... They quickly regenerate all injuries!")
feedback_add_details("hivelord_core","[src.type]|used|other")
else
to_chat(user, "<span class='notice'>You start to smear [src] on yourself. It feels and smells disgusting, but you feel amazingly refreshed in mere moments.</span>")
feedback_add_details("hivelord_core","[src.type]|used|self")
playsound(src.loc,'sound/items/eatfood.ogg', rand(10,50), 1)
H.revive()
user.drop_item()
qdel(src)
..()
/obj/item/organ/internal/hivelord_core/prepare_eat()
return null
/mob/living/simple_animal/hostile/asteroid/hivelordbrood
name = "hivelord brood"
desc = "A fragment of the original Hivelord, rallying behind its original. One isn't much of a threat, but..."
@@ -231,6 +160,7 @@
speak_emote = list("echoes")
attack_sound = 'sound/weapons/pierce.ogg'
throw_message = "bounces harmlessly off of"
crusher_loot = /obj/item/crusher_trophy/legion_skull
loot = list(/obj/item/organ/internal/hivelord_core/legion)
brood_type = /mob/living/simple_animal/hostile/asteroid/hivelordbrood/legion
del_on_death = 1
@@ -322,34 +252,6 @@
H.forceMove(L)
qdel(src)
/obj/item/organ/internal/hivelord_core/legion
name = "legion's soul"
desc = "A strange rock that still crackles with power... its \
healing properties will soon become inert if not used quickly."
icon_state = "legion_soul"
/obj/item/organ/internal/hivelord_core/legion/New()
..()
update_icon()
/obj/item/organ/internal/hivelord_core/legion/update_icon()
icon_state = inert ? "legion_soul_inert" : "legion_soul"
overlays.Cut()
if(!inert && !preserved)
overlays += image(icon, "legion_soul_crackle")
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/organ/internal/hivelord_core/legion/go_inert()
. = ..()
desc = "[src] has become inert, it crackles no more and is useless for \
healing injuries."
/obj/item/organ/internal/hivelord_core/legion/preserved(implanted = 0)
..()
desc = "[src] has been stabilized. It no longer crackles with power, but it's healing properties are preserved indefinitely."
/obj/item/legion_skull
name = "legion's head"
desc = "The once living, now empty eyes of the former human's skull cut deep into your soul."
@@ -403,7 +305,7 @@
if(prob(95))
head = /obj/item/clothing/head/helmet/gladiator
else
head = /obj/item/clothing/head/skullhelmet
head = /obj/item/clothing/head/helmet/skull
suit = /obj/item/clothing/suit/armor/bone
if(prob(5))
back = pickweight(list(/obj/item/twohanded/spear/bonespear = 3, /obj/item/twohanded/fireaxe/boneaxe = 2))
@@ -1,4 +1,4 @@
/mob/living/simple_animal/hostile/asteroid/
/mob/living/simple_animal/hostile/asteroid
vision_range = 2
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
unsuitable_atmos_damage = 15
@@ -13,12 +13,18 @@
response_harm = "strikes"
status_flags = 0
a_intent = INTENT_HARM
var/crusher_loot
var/throw_message = "bounces off of"
var/icon_aggro = null // for swapping to when we get aggressive
var/fromtendril = FALSE
see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
mob_size = MOB_SIZE_LARGE
var/crusher_drop_mod = 25
/mob/living/simple_animal/hostile/asteroid/New()
..()
apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
/mob/living/simple_animal/hostile/asteroid/Aggro()
..()
@@ -46,3 +52,12 @@
visible_message("<span class='notice'>The [T.name] [src.throw_message] [src.name]!</span>")
return
..()
/mob/living/simple_animal/hostile/asteroid/death(gibbed)
var/datum/status_effect/crusher_damage/C = has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
if(C && crusher_loot && prob((C.total_damage/maxHealth) * crusher_drop_mod)) //on average, you'll need to kill 4 creatures before getting the item
spawn_crusher_loot()
..(gibbed)
/mob/living/simple_animal/hostile/asteroid/proc/spawn_crusher_loot()
butcher_results[crusher_loot] = 1
@@ -12,7 +12,7 @@
maxHealth = 250
max_mobs = 3
spawn_time = 300 //30 seconds default
mob_type = /mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril
mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/tendril)
spawn_text = "emerges from"
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
@@ -73,7 +73,7 @@
qdel(src)
/mob/living/simple_animal/hostile/spawner/lavaland/goliath
mob_type = /mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril
mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril)
/mob/living/simple_animal/hostile/spawner/lavaland/legion
mob_type = /mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril
mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord/legion/tendril)
@@ -0,0 +1,113 @@
/mob/living/simple_animal/hostile/netherworld
name = "creature"
desc = "A sanity-destroying otherthing from the netherworld."
icon_state = "otherthing"
icon_living = "otherthing"
icon_dead = "otherthing-dead"
health = 80
maxHealth = 80
obj_damage = 100
melee_damage_lower = 25
melee_damage_upper = 50
attacktext = "slashes"
attack_sound = 'sound/weapons/bladeslice.ogg'
faction = list("creature")
speak_emote = list("screams")
gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
faction = list("nether")
/mob/living/simple_animal/hostile/netherworld/migo
name = "mi-go"
desc = "A pinkish, fungoid crustacean-like creature with numerous pairs of clawed appendages and a head covered with waving antennae."
speak_emote = list("screams", "clicks", "chitters", "barks", "moans", "growls", "meows", "reverberates", "roars", "squeaks", "rattles", "exclaims", "yells", "remarks", "mumbles", "jabbers", "stutters", "seethes")
icon_state = "mi-go"
icon_living = "mi-go"
icon_dead = "mi-go-dead"
attacktext = "lacerates"
speed = -0.5
var/static/list/migo_sounds
deathmessage = "wails as its form turns into a pulpy mush."
death_sound = 'sound/voice/hiss6.ogg'
/mob/living/simple_animal/hostile/netherworld/migo/Initialize()
. = ..()
migo_sounds = list('sound/items/bubblewrap.ogg', 'sound/items/change_jaws.ogg', 'sound/items/crowbar.ogg', 'sound/items/drink.ogg', 'sound/items/deconstruct.ogg', 'sound/items/change_drill.ogg', 'sound/items/dodgeball.ogg', 'sound/items/eatfood.ogg', 'sound/items/screwdriver.ogg', 'sound/items/weeoo1.ogg', 'sound/items/wirecutter.ogg', 'sound/items/welder.ogg', 'sound/items/zip.ogg', 'sound/items/rped.ogg', 'sound/items/ratchet.ogg', 'sound/items/polaroid1.ogg', 'sound/items/pshoom.ogg', 'sound/items/airhorn.ogg', 'sound/voice/bcreep.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/ed209_20sec.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss6.ogg', 'sound/voice/mpatchedup.ogg', 'sound/voice/mfeelbetter.ogg', 'sound/weapons/sear.ogg', 'sound/ambience/antag/tatoralert.ogg', 'sound/mecha/nominal.ogg', 'sound/mecha/weapdestr.ogg', 'sound/mecha/critdestr.ogg', 'sound/mecha/imag_enh.ogg', 'sound/effects/adminhelp.ogg', 'sound/effects/alert.ogg', 'sound/effects/attackblob.ogg', 'sound/effects/bamf.ogg', 'sound/effects/blobattack.ogg', 'sound/effects/break_stone.ogg', 'sound/effects/bubbles.ogg', 'sound/effects/bubbles2.ogg', 'sound/effects/clang.ogg', 'sound/effects/clownstep2.ogg', 'sound/effects/dimensional_rend.ogg', 'sound/effects/doorcreaky.ogg', 'sound/effects/empulse.ogg', 'sound/effects/explosionfar.ogg', 'sound/effects/explosion1.ogg', 'sound/effects/grillehit.ogg', 'sound/effects/genetics.ogg', 'sound/effects/heartbeat.ogg', 'sound/effects/hyperspace_begin.ogg', 'sound/effects/hyperspace_end.ogg', 'sound/goonstation/effects/screech.ogg', 'sound/effects/phasein.ogg', 'sound/effects/picaxe1.ogg', 'sound/effects/sparks1.ogg', 'sound/effects/smoke.ogg', 'sound/effects/splat.ogg', 'sound/effects/snap.ogg', 'sound/effects/tendril_destroyed.ogg', 'sound/effects/supermatter.ogg', 'sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg', 'sound/misc/bloblarm.ogg', 'sound/goonstation/misc/airraid_loop.ogg', 'sound/misc/interference.ogg', 'sound/misc/notice1.ogg', 'sound/misc/notice2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/misc/slip.ogg', 'sound/weapons/armbomb.ogg', 'sound/weapons/chainsaw.ogg', 'sound/weapons/emitter.ogg', 'sound/weapons/emitter2.ogg', 'sound/weapons/blade1.ogg', 'sound/weapons/bladeslice.ogg', 'sound/weapons/blastcannon.ogg', 'sound/weapons/blaster.ogg', 'sound/weapons/bulletflyby3.ogg', 'sound/weapons/circsawhit.ogg', 'sound/weapons/cqchit2.ogg', 'sound/weapons/drill.ogg', 'sound/weapons/genhit1.ogg', 'sound/weapons/gunshots/gunshot_silenced.ogg', 'sound/weapons/gunshots/gunshot.ogg', 'sound/weapons/handcuffs.ogg', 'sound/weapons/homerun.ogg', 'sound/weapons/kenetic_accel.ogg', 'sound/machines/fryer/deep_fryer_emerge.ogg', 'sound/machines/airlock_alien_prying.ogg', 'sound/machines/airlock_close.ogg', 'sound/machines/airlockforced.ogg', 'sound/machines/airlock_open.ogg', 'sound/machines/alarm.ogg', 'sound/machines/blender.ogg', 'sound/machines/boltsdown.ogg', 'sound/machines/boltsup.ogg', 'sound/machines/buzz-sigh.ogg', 'sound/machines/buzz-two.ogg', 'sound/machines/chime.ogg', 'sound/machines/defib_charge.ogg', 'sound/machines/defib_failed.ogg', 'sound/machines/defib_ready.ogg', 'sound/machines/defib_zap.ogg', 'sound/machines/deniedbeep.ogg', 'sound/machines/ding.ogg', 'sound/machines/disposalflush.ogg', 'sound/machines/door_close.ogg', 'sound/machines/door_open.ogg', 'sound/machines/engine_alert1.ogg', 'sound/machines/engine_alert2.ogg', 'sound/machines/hiss.ogg', 'sound/machines/honkbot_evil_laugh.ogg', 'sound/machines/juicer.ogg', 'sound/machines/ping.ogg', 'sound/ambience/signal.ogg', 'sound/machines/synth_no.ogg', 'sound/machines/synth_yes.ogg', 'sound/machines/terminal_alert.ogg', 'sound/machines/twobeep.ogg', 'sound/machines/ventcrawl.ogg', 'sound/machines/warning-buzzer.ogg', 'sound/ai/outbreak5.ogg', 'sound/ai/outbreak7.ogg', 'sound/ai/poweroff.ogg', 'sound/ai/radiation.ogg', 'sound/ai/shuttlecalled.ogg', 'sound/ai/shuttledock.ogg', 'sound/ai/shuttlerecalled.ogg', 'sound/ai/aimalf.ogg') //hahahaha fuck you code divers
/mob/living/simple_animal/hostile/netherworld/migo/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
..()
if(stat)
return
var/chosen_sound = pick(migo_sounds)
playsound(src, chosen_sound, 50, TRUE)
/mob/living/simple_animal/hostile/netherworld/migo/Life()
..()
if(stat)
return
if(prob(10))
var/chosen_sound = pick(migo_sounds)
playsound(src, chosen_sound, 50, TRUE)
/mob/living/simple_animal/hostile/netherworld/blankbody
name = "blank body"
desc = "This looks human enough, but its flesh has an ashy texture, and it's face is featureless save an eerie smile."
icon_state = "blank-body"
icon_living = "blank-body"
icon_dead = "blank-dead"
gold_core_spawnable = CHEM_MOB_SPAWN_INVALID
health = 100
maxHealth = 100
melee_damage_lower = 5
melee_damage_upper = 10
attacktext = "punches"
deathmessage = "falls apart into a fine dust."
/mob/living/simple_animal/hostile/spawner/nether
name = "netherworld link"
desc = null //see examine()
icon_state = "nether"
health = 50
maxHealth = 50
spawn_time = 600 //1 minute
max_mobs = 15
icon = 'icons/mob/nest.dmi'
spawn_text = "crawls through"
mob_types = list(/mob/living/simple_animal/hostile/netherworld/migo, /mob/living/simple_animal/hostile/netherworld, /mob/living/simple_animal/hostile/netherworld/blankbody)
faction = list("nether")
/mob/living/simple_animal/hostile/spawner/nether/death()
. = ..()
qdel(src)
/mob/living/simple_animal/hostile/spawner/nether/examine(mob/user)
..()
if(isskeleton(user))
to_chat(user, "A direct link to another dimension full of creatures very happy to see you. <span class='nicegreen'>You can see your house from here!</span>")
else
to_chat(user, "A direct link to another dimension full of creatures not very happy to see you. <span class='warning'>Entering the link would be a very bad idea.</span>")
/mob/living/simple_animal/hostile/spawner/nether/attack_hand(mob/user)
. = ..()
if(isskeleton(user))
to_chat(user, "<span class='notice'>You don't feel like going home yet...</span>")
else
user.visible_message("<span class='warning'>[user] is violently pulled into the link!</span>", \
"<span class='userdanger'>Touching the portal, you are quickly pulled through into a world of unimaginable horror!</span>")
contents.Add(user)
/mob/living/simple_animal/hostile/spawner/nether/Life()
. = ..()
for(var/mob/living/M in contents)
if(M)
playsound(src, 'sound/magic/demon_consume.ogg', 50, 1)
M.adjustBruteLoss(60)
new /obj/effect/gibspawner/generic(get_turf(M), M)
if(M.stat == DEAD)
var/mob/living/simple_animal/hostile/netherworld/blankbody/blank
blank = new(loc)
blank.name = "[M]"
blank.desc = "It's [M], but [M.p_their()] flesh has an ashy texture, and [M.p_their()] face is featureless save an eerie smile."
visible_message("<span class='warning'>[M] reemerges from the link!</span>")
qdel(M)
@@ -54,7 +54,7 @@
melee_damage_lower = 2
melee_damage_upper = 2
speak_emote = list("blurps")
butcher_results = null
butcher_results = list(/obj/item/reagent_containers/food/snacks/salmonmeat = 1)
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
@@ -0,0 +1,49 @@
/mob/living/simple_animal/hostile/skeleton
name = "reanimated skeleton"
desc = "A real bonefied skeleton, doesn't seem like it wants to socialize."
icon = 'icons/mob/animal.dmi'
icon_state = "skeleton"
icon_living = "skeleton"
turns_per_move = 5
speak_emote = list("rattles")
emote_see = list("rattles")
a_intent = INTENT_HARM
maxHealth = 40
health = 40
speed = 1
harm_intent_damage = 5
melee_damage_lower = 15
melee_damage_upper = 15
minbodytemp = 0
maxbodytemp = 1500
healable = FALSE //they're skeletons how would bruise packs help them??
attacktext = "slashes"
attack_sound = 'sound/hallucinations/growl1.ogg'
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
unsuitable_atmos_damage = 10
robust_searching = 1
stat_attack = UNCONSCIOUS
gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE
faction = list("skeleton")
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
deathmessage = "collapses into a pile of bones!"
del_on_death = TRUE
loot = list(/obj/effect/decal/remains/human)
/mob/living/simple_animal/hostile/skeleton/eskimo
name = "undead eskimo"
desc = "The reanimated remains of some poor traveler."
icon_state = "eskimo"
icon_living = "eskimo"
maxHealth = 55
health = 55
weather_immunities = list("snow")
gold_core_spawnable = CHEM_MOB_SPAWN_INVALID
melee_damage_lower = 17
melee_damage_upper = 20
deathmessage = "collapses into a pile of bones, its gear falling to the floor!"
loot = list(/obj/effect/decal/remains/human,
/obj/item/twohanded/spear,
/obj/item/clothing/shoes/winterboots,
/obj/item/clothing/suit/hooded/wintercoat)
@@ -36,7 +36,7 @@
desc = "A thick vine, painful to the touch."
/obj/effect/ebeam/vine/Crossed(atom/movable/AM)
/obj/effect/ebeam/vine/Crossed(atom/movable/AM, oldloc)
if(isliving(AM))
var/mob/living/L = AM
if(!("vines" in L.faction))
@@ -7,7 +7,7 @@
var/max_mobs = 5
var/spawn_delay = 0
var/spawn_time = 300 //30 seconds default
var/mob_type = /mob/living/simple_animal/hostile/carp
var/mob_types = list(/mob/living/simple_animal/hostile/carp)
var/spawn_text = "emerges from"
status_flags = 0
move_resist = MOVE_FORCE_VERY_STRONG
@@ -39,7 +39,8 @@
if(spawn_delay > world.time)
return 0
spawn_delay = world.time + spawn_time
var/mob/living/simple_animal/L = new mob_type(src.loc)
var/chosen_type = pick(mob_types)
var/mob/living/simple_animal/L = new chosen_type(loc)
L.admin_spawned = admin_spawned //If we were admin spawned, lets have our children count as that as well.
spawned_mobs += L
L.nest = src
@@ -51,7 +52,7 @@
icon = 'icons/obj/device.dmi'
icon_state = "syndbeacon"
spawn_text = "warps in from"
mob_type = /mob/living/simple_animal/hostile/syndicate/ranged
mob_types = list(/mob/living/simple_animal/hostile/syndicate/ranged)
faction = list("syndicate")
/mob/living/simple_animal/hostile/spawner/mining
@@ -64,21 +65,21 @@
max_mobs = 3
icon = 'icons/mob/nest.dmi'
spawn_text = "crawls out of"
mob_type = /mob/living/simple_animal/hostile/asteroid/goldgrub
mob_types = list(/mob/living/simple_animal/hostile/asteroid/goldgrub)
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
faction = list("mining")
/mob/living/simple_animal/hostile/spawner/mining/goliath
name = "goliath den"
desc = "A den housing a nest of goliaths, oh god why?"
mob_type = /mob/living/simple_animal/hostile/asteroid/goliath
mob_types = list(/mob/living/simple_animal/hostile/asteroid/goliath)
/mob/living/simple_animal/hostile/spawner/mining/hivelord
name = "hivelord den"
desc = "A den housing a nest of hivelords."
mob_type = /mob/living/simple_animal/hostile/asteroid/hivelord
mob_types = list(/mob/living/simple_animal/hostile/asteroid/hivelord)
/mob/living/simple_animal/hostile/spawner/mining/basilisk
name = "basilisk den"
desc = "A den housing a nest of basilisks, bring a coat."
mob_type = /mob/living/simple_animal/hostile/asteroid/basilisk
mob_types = list(/mob/living/simple_animal/hostile/asteroid/basilisk)
+6
View File
@@ -397,6 +397,9 @@
// STUN
/mob/living/Stun(amount, updating = 1, force = 0)
if(status_flags & CANSTUN || force)
if(absorb_stun(amount, force))
return FALSE
return SetStunned(max(stunned, amount), updating, force)
/mob/living/SetStunned(amount, updating = 1, force = 0) //if you REALLY need to set stun to a set amount without the whole "can't go below current stunned"
@@ -434,6 +437,9 @@
// WEAKEN
/mob/living/Weaken(amount, updating = 1, force = 0)
if(status_flags & CANWEAKEN || force)
if(absorb_stun(amount, force))
return FALSE
return SetWeakened(max(weakened, amount), updating, force)
/mob/living/SetWeakened(amount, updating = 1, force = 0)
+21 -10
View File
@@ -193,14 +193,7 @@
var/obj/item/W = get_active_hand()
if(istype(W))
if(istype(W, /obj/item/clothing))
var/obj/item/clothing/C = W
if(C.hardsuit_restrict_helmet)
to_chat(src, "<span class='warning'>You must fasten the helmet to a hardsuit first. (Target the head and use on a hardsuit)</span>")// Stop eva helms equipping.
else
equip_to_slot_if_possible(C, slot)
else
equip_to_slot_if_possible(W, slot)
equip_to_slot_if_possible(W, slot)
else if(!restrained())
W = get_item_by_slot(slot)
if(W)
@@ -694,8 +687,12 @@ var/list/slot_equipment_priority = list( \
msg = copytext(msg, 1, MAX_MESSAGE_LEN)
msg = sanitize_simple(html_encode(msg), list("\n" = "<BR>"))
if(mind)
var/combined = length(memory + msg)
if(mind && (combined < MAX_PAPER_MESSAGE_LEN))
mind.store_memory(msg)
else if(combined >= MAX_PAPER_MESSAGE_LEN)
to_chat(src, "Your brain can't hold that much information!")
return
else
to_chat(src, "The game appears to have misplaced your mind datum, so we can't show you your notes.")
@@ -1366,5 +1363,19 @@ var/list/slot_equipment_priority = list( \
/mob/proc/sync_lighting_plane_alpha()
if(hud_used)
var/obj/screen/plane_master/lighting/L = hud_used.plane_masters["[LIGHTING_PLANE]"]
if (L)
if(L)
L.alpha = lighting_alpha
sync_nightvision_screen() //Sync up the overlay used for nightvision to the amount of see_in_dark a mob has. This needs to be called everywhere sync_lighting_plane_alpha() is.
/mob/proc/sync_nightvision_screen()
var/obj/screen/fullscreen/see_through_darkness/S = screens["see_through_darkness"]
if(S)
var/suffix = ""
switch(see_in_dark)
if(3 to 8)
suffix = "_[see_in_dark]"
if(8 to INFINITY)
suffix = "_8"
S.icon_state = "[initial(S.icon_state)][suffix]"
+5 -3
View File
@@ -369,7 +369,7 @@ var/list/intents = list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM)
if(hud_used && hud_used.action_intent)
hud_used.action_intent.icon_state = "[a_intent]"
else if(isrobot(src) || islarva(src) || isanimal(src))
else if(isrobot(src) || islarva(src) || isanimal(src) || isAI(src))
switch(input)
if(INTENT_HELP)
a_intent = INTENT_HELP
@@ -482,6 +482,8 @@ var/list/intents = list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM)
if(A)
if(O.client.prefs && O.client.prefs.UI_style)
A.icon = ui_style2icon(O.client.prefs.UI_style)
if(title)
A.name = title
A.desc = message
A.action = action
A.target = source
@@ -565,9 +567,9 @@ var/list/intents = list(INTENT_HELP,INTENT_DISARM,INTENT_GRAB,INTENT_HARM)
for(var/i=1,i<=3,i++) //we get 3 attempts to pick a suitable name.
if(force)
newname = input(src, "Pick a new name.", "Name Change", oldname) as text
newname = clean_input("Pick a new name.", "Name Change", oldname, src)
else
newname = input(src, "You are a [role]. Would you like to change your name to something else? (You have 3 minutes to select a new name.)", "Name Change", oldname) as text
newname = clean_input("You are a [role]. Would you like to change your name to something else? (You have 3 minutes to select a new name.)", "Name Change", oldname, src)
if(((world.time - time_passed) > 1800) && !force)
alert(src, "Unfortunately, more than 3 minutes have passed for selecting your name. If you are a robot, use the Namepick verb; otherwise, adminhelp.", "Name Change")
return //took too long
@@ -9,7 +9,7 @@
return
if(!new_type)
new_type = input("Mob type path:", "Mob type") as text|null
new_type = clean_input("Mob type path:", "Mob type")
if(istext(new_type))
new_type = text2path(new_type)
@@ -169,7 +169,10 @@
/datum/sprite_accessory/underwear
icon = 'icons/mob/underwear.dmi'
species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask", "Vox")
sprite_sheets = list("Vox" = 'icons/mob/species/vox/underwear.dmi')
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/underwear.dmi',
"Grey" = 'icons/mob/species/grey/underwear.dmi'
)
gender = NEUTER
/datum/sprite_accessory/underwear/nude
@@ -296,7 +299,9 @@
/datum/sprite_accessory/undershirt
icon = 'icons/mob/underwear.dmi'
species_allowed = list("Human", "Unathi", "Diona", "Vulpkanin", "Tajaran", "Kidan", "Grey", "Plasmaman", "Machine", "Skrell", "Slime People", "Skeleton", "Drask", "Vox")
sprite_sheets = list("Vox" = 'icons/mob/species/vox/underwear.dmi')
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/underwear.dmi',
"Grey" = 'icons/mob/species/grey/underwear.dmi')
gender = NEUTER
/datum/sprite_accessory/undershirt/nude