mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-22 19:47:22 +01:00
Merge remote-tracking branch 'upstream/master' into updateicons
This commit is contained in:
@@ -30,7 +30,9 @@ var/list/image/ghost_darkness_images = list() //this is a list of images for thi
|
||||
sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER_AI_EYE
|
||||
see_in_dark = 100
|
||||
verbs += /mob/dead/observer/proc/dead_tele
|
||||
verbs += list(
|
||||
/mob/dead/observer/proc/dead_tele,
|
||||
/mob/dead/observer/proc/open_spawners_menu)
|
||||
|
||||
// Our new boo spell.
|
||||
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/boo(null))
|
||||
@@ -677,3 +679,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
mind.transfer_to(new_char)
|
||||
else
|
||||
new_char.key = key
|
||||
|
||||
/mob/dead/observer/proc/open_spawners_menu()
|
||||
set name = "Mob spawners menu"
|
||||
set desc = "See all currently available ghost spawners"
|
||||
set category = "Ghost"
|
||||
|
||||
var/datum/spawners_menu/menu = new /datum/spawners_menu(src)
|
||||
menu.ui_interact(src)
|
||||
|
||||
@@ -281,6 +281,15 @@
|
||||
flags = RESTRICTED | WHITELISTED
|
||||
syllables = list("click","clack")
|
||||
|
||||
/datum/language/kidan/get_random_name()
|
||||
var/new_name = "[pick(list("Vrax", "Krek", "Vriz", "Zrik", "Zarak", "Click", "Zerk", "Drax", "Zven", "Drexx"))]"
|
||||
new_name += ", "
|
||||
new_name += "[pick(list("Noble", "Worker", "Scout", "Builder", "Farmer", "Gatherer", "Soldier", "Guard", "Prospector"))]"
|
||||
new_name += " of Clan "
|
||||
new_name += "[pick(list("Tristan", "Zarlan", "Clack", "Kkraz", "Zramn", "Orlan", "Zrax"))]" //I ran out of ideas after the first two tbh -_-
|
||||
return new_name
|
||||
|
||||
|
||||
/datum/language/slime
|
||||
name = "Bubblish"
|
||||
desc = "The language of slimes. It's a mixture of bubbling noises and pops. Very difficult to speak without mechanical aid for humans."
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
/mob/living/carbon/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked = 0)
|
||||
if(!skipcatch)
|
||||
if(in_throw_mode && !get_active_hand()) //empty active hand and we're in throw mode
|
||||
if(canmove && !restrained())
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/I = AM
|
||||
if(isturf(I.loc))
|
||||
put_in_active_hand(I)
|
||||
visible_message("<span class='warning'>[src] catches [I]!</span>")
|
||||
throw_mode_off()
|
||||
return 1
|
||||
if(in_throw_mode && canmove && !restrained()) //Makes sure player is in throw mode
|
||||
if(!istype(AM,/obj/item) || !isturf(AM.loc))
|
||||
return FALSE
|
||||
if(get_active_hand())
|
||||
return FALSE
|
||||
if(istype(AM, /obj/item/twohanded))
|
||||
if(get_inactive_hand())
|
||||
return FALSE
|
||||
put_in_active_hand(AM)
|
||||
visible_message("<span class='warning'>[src] catches [AM]!</span>")
|
||||
throw_mode_off()
|
||||
return TRUE
|
||||
..()
|
||||
|
||||
/mob/living/carbon/water_act(volume, temperature, source)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
if("Yes")
|
||||
if(!I)
|
||||
return
|
||||
if(!Adjacent(usr))
|
||||
if(!Adjacent(target))
|
||||
to_chat(usr, "<span class='warning'> You need to stay in reaching distance while giving an object.</span>")
|
||||
to_chat(target, "<span class='warning'> [usr.name] moved too far away.</span>")
|
||||
return
|
||||
|
||||
@@ -58,9 +58,9 @@
|
||||
add_to_all_human_data_huds()
|
||||
|
||||
/mob/living/carbon/human/Destroy()
|
||||
. = ..()
|
||||
QDEL_LIST(bodyparts)
|
||||
splinted_limbs.Cut()
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/dummy
|
||||
real_name = "Test Dummy"
|
||||
@@ -730,25 +730,22 @@
|
||||
|
||||
if(hasHUD(usr, "security") && setcriminal != "Cancel")
|
||||
found_record = 1
|
||||
var/their_name = R.fields["name"]
|
||||
var/their_rank = R.fields["rank"]
|
||||
if(R.fields["criminal"] == "*Execute*")
|
||||
to_chat(usr, "<span class='warning'>Unable to modify the sec status of a person with an active Execution order. Use a security computer instead.</span>")
|
||||
else
|
||||
else
|
||||
var/rank
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/U = usr
|
||||
R.fields["comments"] += "Set to [setcriminal] by [U.get_authentification_name()] ([U.get_assignment()]) on [current_date_string] [station_time_timestamp()] with comment: [t1]<BR>"
|
||||
if(isrobot(usr))
|
||||
rank = U.get_assignment()
|
||||
else if(isrobot(usr))
|
||||
var/mob/living/silicon/robot/U = usr
|
||||
R.fields["comments"] += "Set to [setcriminal] by [U.name] ([U.modtype] [U.braintype]) on [current_date_string] [station_time_timestamp()] with comment: [t1]<BR>"
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/U = usr
|
||||
R.fields["comments"] += "Set to [setcriminal] by [U.name] (artificial intelligence) on [current_date_string] [station_time_timestamp()] with comment: [t1]<BR>"
|
||||
|
||||
R.fields["criminal"] = setcriminal
|
||||
log_admin("[key_name_admin(usr)] set secstatus of [their_rank] [their_name] to [setcriminal], comment: [t1]")
|
||||
spawn()
|
||||
sec_hud_set_security_status()
|
||||
rank = "[U.modtype] [U.braintype]"
|
||||
else if(isAI(usr))
|
||||
rank = "AI"
|
||||
set_criminal_status(usr, R, setcriminal, t1, rank)
|
||||
break // Git out of the securiy records loop!
|
||||
if(found_record)
|
||||
break // Git out of the general records
|
||||
|
||||
if(!found_record)
|
||||
to_chat(usr, "<span class='warning'>Unable to locate a data core entry for this person.</span>")
|
||||
|
||||
@@ -538,7 +538,7 @@
|
||||
|
||||
/datum/species/proc/handle_hud_icons_health_side(mob/living/carbon/human/H)
|
||||
if(H.healths)
|
||||
if(H.stat == DEAD)
|
||||
if(H.stat == DEAD || (H.status_flags & FAKEDEATH))
|
||||
H.healths.icon_state = "health7"
|
||||
else
|
||||
switch(H.hal_screwyhud)
|
||||
@@ -557,7 +557,7 @@
|
||||
|
||||
/datum/species/proc/handle_hud_icons_health_doll(mob/living/carbon/human/H)
|
||||
if(H.healthdoll)
|
||||
if(H.stat == DEAD)
|
||||
if(H.stat == DEAD || (H.status_flags & FAKEDEATH))
|
||||
H.healthdoll.icon_state = "healthdoll_DEAD"
|
||||
if(H.healthdoll.overlays.len)
|
||||
H.healthdoll.overlays.Cut()
|
||||
@@ -628,7 +628,7 @@ It'll return null if the organ doesn't correspond, so include null checks when u
|
||||
else
|
||||
H.see_invisible = SEE_INVISIBLE_LIVING
|
||||
|
||||
if(H.client.eye != H)
|
||||
if(H.client && H.client.eye != H)
|
||||
var/atom/A = H.client.eye
|
||||
if(A.update_remote_sight(H)) //returns 1 if we override all other sight updates.
|
||||
return
|
||||
|
||||
@@ -292,8 +292,8 @@
|
||||
return
|
||||
|
||||
/mob/living/attack_animal(mob/living/simple_animal/M)
|
||||
if(M.melee_damage_upper == 0)
|
||||
M.custom_emote(1, "[M.friendly] [src]")
|
||||
if((M.a_intent == INTENT_HELP && M.ckey) || M.melee_damage_upper == 0)
|
||||
M.custom_emote(1, "[M.friendly] [src].")
|
||||
return 0
|
||||
else
|
||||
if(M.attack_sound)
|
||||
|
||||
@@ -274,7 +274,7 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
spawn(0)
|
||||
if(loc && !isturf(loc))
|
||||
var/atom/A = loc //Non-turf, let it handle the speech bubble
|
||||
A.speech_bubble("hR[speech_bubble_test]", A.loc, speech_bubble_recipients)
|
||||
A.speech_bubble("hR[speech_bubble_test]", A, speech_bubble_recipients)
|
||||
else //Turf, leave speech bubbles to the mob
|
||||
speech_bubble("h[speech_bubble_test]", src, speech_bubble_recipients)
|
||||
|
||||
|
||||
@@ -1119,15 +1119,15 @@ var/list/ai_verbs_default = list(
|
||||
|
||||
/mob/living/silicon/ai/proc/check_unable(flags = 0)
|
||||
if(stat == DEAD)
|
||||
to_chat(usr, "<span class='warning'>You are dead!</span>")
|
||||
to_chat(src, "<span class='warning'>You are dead!</span>")
|
||||
return TRUE
|
||||
|
||||
if(lacks_power())
|
||||
to_chat(usr, "<span class='warning'>Power systems failure!</span>")
|
||||
to_chat(src, "<span class='warning'>Power systems failure!</span>")
|
||||
return TRUE
|
||||
|
||||
if((flags & AI_CHECK_WIRELESS) && control_disabled)
|
||||
to_chat(usr, "<span class='warning'>Wireless control is disabled!</span>")
|
||||
to_chat(src, "<span class='warning'>Wireless control is disabled!</span>")
|
||||
return TRUE
|
||||
if((flags & AI_CHECK_RADIO) && aiRadio.disabledAi)
|
||||
to_chat(src, "<span class='warning'>System Error - Transceiver Disabled!</span>")
|
||||
|
||||
@@ -225,9 +225,9 @@
|
||||
|
||||
// See software.dm for Topic()
|
||||
|
||||
/mob/living/silicon/pai/attack_animal(mob/living/simple_animal/M as mob)
|
||||
if(M.melee_damage_upper == 0)
|
||||
M.custom_emote(1, "[M.friendly] [src]")
|
||||
/mob/living/silicon/pai/attack_animal(mob/living/simple_animal/M)
|
||||
if((M.a_intent == INTENT_HELP && M.ckey) || M.melee_damage_upper == 0)
|
||||
M.custom_emote(1, "[M.friendly] [src].")
|
||||
else
|
||||
M.do_attack_animation(src)
|
||||
if(M.attack_sound)
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
to_chat(user, "<span class='warning'>The interface is fried, and a distressing burned smell wafts from the robot's interior. You're not rebooting this one.</span>")
|
||||
return
|
||||
|
||||
if(!allowed(usr))
|
||||
if(!allowed(W))
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
return
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
if(emagged)
|
||||
return
|
||||
|
||||
if(allowed(usr))
|
||||
if(allowed(W))
|
||||
shut_down()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
@@ -223,6 +223,10 @@
|
||||
health = 35 - (getBruteLoss() + getFireLoss())
|
||||
update_stat("updatehealth([reason])")
|
||||
|
||||
/mob/living/silicon/robot/drone/death(gibbed)
|
||||
. = ..(gibbed)
|
||||
ghostize(can_reenter_corpse = 0)
|
||||
|
||||
|
||||
//CONSOLE PROCS
|
||||
/mob/living/silicon/robot/drone/proc/law_resync()
|
||||
|
||||
@@ -42,7 +42,10 @@
|
||||
if(UNCONSCIOUS)
|
||||
msg += "<span class='warning'>It doesn't seem to be responding.</span>\n"
|
||||
if(DEAD)
|
||||
msg += "<span class='deadsay'>It looks like its system is corrupted and requires a reset.</span>\n"
|
||||
if(!suiciding)
|
||||
msg += "<span class='deadsay'>It looks like its system is corrupted and requires a reset.</span>\n"
|
||||
else
|
||||
msg += "<span class='warning'>It looks like its system is corrupted beyond repair. There is no hope of recovery.</span>\n"
|
||||
msg += "*---------*</span>"
|
||||
|
||||
if(print_flavor_text()) msg += "\n[print_flavor_text()]\n"
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/syndicate/New()
|
||||
..()
|
||||
Radio.syndie = 1
|
||||
Radio.syndiekey = new /obj/item/encryptionkey/syndicate
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/syndicate/emagged
|
||||
emagged = 2
|
||||
|
||||
@@ -32,24 +32,72 @@
|
||||
melee_damage_upper = 8
|
||||
attacktext = "bites"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
var/chirp_sound = 'sound/misc/nymphchirp.ogg' //used in emote
|
||||
|
||||
speed = 0
|
||||
stop_automated_movement = 0
|
||||
turns_per_move = 4
|
||||
|
||||
var/list/donors = list()
|
||||
var/ready_evolve = 0
|
||||
holder_type = /obj/item/holder/diona
|
||||
can_collar = 1
|
||||
can_collar = TRUE
|
||||
|
||||
a_intent = INTENT_HELP
|
||||
var/gestalt_alert = "merged with gestalt" //used in adding and clearing alert
|
||||
var/evolve_donors = 5 //amount of blood donors needed before evolving
|
||||
var/awareness_donors = 3 //amount of blood donors needed for understand language
|
||||
var/nutrition_need = 500 //amount of nutrition needed before evolving
|
||||
|
||||
var/datum/action/innate/diona/merge/merge_action = new()
|
||||
var/datum/action/innate/diona/evolve/evolve_action = new()
|
||||
var/datum/action/innate/diona/steal_blood/steal_blood_action = new()
|
||||
|
||||
/datum/action/innate/diona/merge
|
||||
name = "Merge with gestalt"
|
||||
icon_icon = 'icons/mob/human_races/r_diona.dmi'
|
||||
button_icon_state = "preview"
|
||||
|
||||
/datum/action/innate/diona/merge/Activate()
|
||||
var/mob/living/simple_animal/diona/user = owner
|
||||
user.merge()
|
||||
|
||||
/datum/action/innate/diona/evolve
|
||||
name = "Evolve"
|
||||
icon_icon = 'icons/obj/cloning.dmi'
|
||||
button_icon_state = "pod_1"
|
||||
|
||||
/datum/action/innate/diona/evolve/Activate()
|
||||
var/mob/living/simple_animal/diona/user = owner
|
||||
user.evolve()
|
||||
|
||||
/datum/action/innate/diona/steal_blood
|
||||
name = "Steal blood"
|
||||
icon_icon = 'icons/obj/bloodpack.dmi'
|
||||
button_icon_state = "full"
|
||||
|
||||
/datum/action/innate/diona/steal_blood/Activate()
|
||||
var/mob/living/simple_animal/diona/user = owner
|
||||
user.steal_blood()
|
||||
|
||||
/mob/living/simple_animal/diona/New()
|
||||
..()
|
||||
if(name == initial(name)) //To stop Pun-Pun becoming generic.
|
||||
name = "[name] ([rand(1, 1000)])"
|
||||
real_name = name
|
||||
|
||||
add_language("Rootspeak")
|
||||
verbs += /mob/living/simple_animal/diona/proc/merge
|
||||
merge_action.Grant(src)
|
||||
evolve_action.Grant(src)
|
||||
steal_blood_action.Grant(src)
|
||||
|
||||
/mob/living/simple_animal/diona/UnarmedAttack(var/atom/A)
|
||||
if(isdiona(A) && (src in A.contents)) //can't attack your gestalt
|
||||
visible_message("[src] wiggles around a bit.")
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/diona/resist()
|
||||
..()
|
||||
split()
|
||||
|
||||
/mob/living/simple_animal/diona/attack_hand(mob/living/carbon/human/M)
|
||||
//Let people pick the little buggers up.
|
||||
@@ -57,88 +105,76 @@
|
||||
if(isdiona(M))
|
||||
to_chat(M, "You feel your being twine with that of [src] as it merges with your biomass.")
|
||||
to_chat(src, "You feel your being twine with that of [M] as you merge with its biomass.")
|
||||
verbs += /mob/living/simple_animal/diona/proc/split
|
||||
verbs -= /mob/living/simple_animal/diona/proc/merge
|
||||
throw_alert(gestalt_alert, /obj/screen/alert/nymph, new_master = src) //adds a screen alert that can call resist
|
||||
forceMove(M)
|
||||
else
|
||||
get_scooped(M)
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/diona/proc/merge()
|
||||
set category = "Diona"
|
||||
set name = "Merge with gestalt"
|
||||
set desc = "Merge with another diona."
|
||||
|
||||
if(iscarbon(loc))
|
||||
verbs -= /mob/living/simple_animal/diona/proc/merge
|
||||
return
|
||||
if(stat != CONSCIOUS)
|
||||
return FALSE
|
||||
|
||||
var/list/choices = list()
|
||||
for(var/mob/living/carbon/C in view(1,src))
|
||||
|
||||
if(!(Adjacent(C)) || !(C.client))
|
||||
for(var/mob/living/carbon/human/H in view(1,src))
|
||||
if(!(Adjacent(H)) || !isdiona(H))
|
||||
continue
|
||||
choices += H
|
||||
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/D = C
|
||||
if(isdiona(D))
|
||||
choices += C
|
||||
if(!choices.len)
|
||||
to_chat(src, "<span class='warning'>No suitable diona nearby.</span>")
|
||||
return FALSE
|
||||
|
||||
var/mob/living/M = input(src,"Who do you wish to merge with?") in null|choices
|
||||
|
||||
if(!M || !src || !(Adjacent(M)))
|
||||
return
|
||||
if(!M || !src || !(Adjacent(M)) || stat != CONSCIOUS) //input can take a while, so re-validate
|
||||
return FALSE
|
||||
|
||||
if(ishuman(M))
|
||||
if(isdiona(M))
|
||||
to_chat(M, "You feel your being twine with that of [src] as it merges with your biomass.")
|
||||
M.status_flags |= PASSEMOTES
|
||||
|
||||
to_chat(src, "You feel your being twine with that of [M] as you merge with its biomass.")
|
||||
forceMove(M)
|
||||
verbs += /mob/living/simple_animal/diona/proc/split
|
||||
verbs -= /mob/living/simple_animal/diona/proc/merge
|
||||
throw_alert(gestalt_alert, /obj/screen/alert/nymph, new_master = src) //adds a screen alert that can call resist
|
||||
return TRUE
|
||||
else
|
||||
return
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/diona/proc/split()
|
||||
set category = "Diona"
|
||||
set name = "Split from gestalt"
|
||||
set desc = "Split away from your gestalt as a lone nymph."
|
||||
|
||||
if(!(iscarbon(loc)))
|
||||
verbs -= /mob/living/simple_animal/diona/proc/split
|
||||
return
|
||||
|
||||
if((stat != CONSCIOUS) || !isdiona(loc))
|
||||
return FALSE
|
||||
var/mob/living/carbon/human/D = loc
|
||||
T = get_turf(src)
|
||||
if(!T)
|
||||
return FALSE
|
||||
to_chat(loc, "You feel a pang of loss as [src] splits away from your biomass.")
|
||||
to_chat(src, "You wiggle out of the depths of [loc]'s biomass and plop to the ground.")
|
||||
forceMove(T)
|
||||
|
||||
var/hasMobs = FALSE
|
||||
for(var/atom/A in D.contents)
|
||||
if(istype(A, /mob/) || istype(A, /obj/item/holder))
|
||||
hasMobs = TRUE
|
||||
if(!hasMobs)
|
||||
D.status_flags &= ~PASSEMOTES
|
||||
|
||||
var/mob/living/M = loc
|
||||
clear_alert(gestalt_alert)
|
||||
return TRUE
|
||||
|
||||
forceMove(get_turf(src))
|
||||
verbs -= /mob/living/simple_animal/diona/proc/split
|
||||
verbs += /mob/living/simple_animal/diona/proc/merge
|
||||
|
||||
if(istype(M))
|
||||
for(var/atom/A in M.contents)
|
||||
if(istype(A, /mob/living/simple_animal/borer) || istype(A, /obj/item/holder))
|
||||
return
|
||||
M.status_flags &= ~PASSEMOTES
|
||||
|
||||
/mob/living/simple_animal/diona/verb/evolve()
|
||||
set category = "Diona"
|
||||
set name = "Evolve"
|
||||
set desc = "Grow to a more complex form."
|
||||
|
||||
if(donors.len < 5)
|
||||
/mob/living/simple_animal/diona/proc/evolve()
|
||||
if(stat != CONSCIOUS)
|
||||
return FALSE
|
||||
|
||||
if(donors.len < evolve_donors)
|
||||
to_chat(src, "<span class='warning'>You need more blood in order to ascend to a new state of consciousness...</span>")
|
||||
return
|
||||
return FALSE
|
||||
|
||||
if(nutrition < 500)
|
||||
if(nutrition < nutrition_need)
|
||||
to_chat(src, "<span class='warning'>You need to binge on weeds in order to have the energy to grow...</span>")
|
||||
return
|
||||
return FALSE
|
||||
|
||||
split()
|
||||
if(isdiona(loc) && !split()) //if it's merged with diona, needs to able to split before evolving
|
||||
return FALSE
|
||||
|
||||
visible_message("<span class='danger'>[src] begins to shift and quiver, and erupts in a shower of shed bark as it splits into a tangle of nearly a dozen new dionaea.</span>","<span class='danger'>You begin to shift and quiver, feeling your awareness splinter. All at once, we consume our stored nutrients to surge with growth, splitting into a tangle of at least a dozen new dionaea. We have attained our gestalt form.</span>")
|
||||
|
||||
var/mob/living/carbon/human/diona/adult = new(get_turf(loc))
|
||||
@@ -162,28 +198,33 @@
|
||||
unEquip(W)
|
||||
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
/mob/living/simple_animal/diona/verb/steal_blood()
|
||||
set category = "Diona"
|
||||
set name = "Steal Blood"
|
||||
set desc = "Take a blood sample from a suitable donor."
|
||||
|
||||
/mob/living/simple_animal/diona/proc/steal_blood()
|
||||
if(stat != CONSCIOUS)
|
||||
return FALSE
|
||||
|
||||
var/list/choices = list()
|
||||
for(var/mob/living/carbon/human/H in oview(1,src))
|
||||
choices += H
|
||||
if(Adjacent(H) && H.dna && !(NO_BLOOD in H.dna.species.species_traits))
|
||||
choices += H
|
||||
|
||||
if(!choices.len)
|
||||
to_chat(src, "<span class='warning'>No suitable blood donors nearby.</span>")
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/human/M = input(src,"Who do you wish to take a sample from?") in null|choices
|
||||
|
||||
if(!M || !src)
|
||||
return
|
||||
if(!M || !src || !(Adjacent(M)) || stat != CONSCIOUS) //input can take a while, so re-validate
|
||||
return FALSE
|
||||
|
||||
if(NO_BLOOD in M.dna.species.species_traits)
|
||||
if(!M.dna || (NO_BLOOD in M.dna.species.species_traits))
|
||||
to_chat(src, "<span class='warning'>That donor has no blood to take.</span>")
|
||||
return
|
||||
return FALSE
|
||||
|
||||
if(donors.Find(M.real_name))
|
||||
to_chat(src, "<span class='warning'>That donor offers you nothing new.</span>")
|
||||
return
|
||||
return FALSE
|
||||
|
||||
visible_message("<span class='danger'>[src] flicks out a feeler and neatly steals a sample of [M]'s blood.</span>","<span class='danger'>You flick out a feeler and neatly steal a sample of [M]'s blood.</span>")
|
||||
donors += M.real_name
|
||||
@@ -195,13 +236,12 @@
|
||||
update_progression()
|
||||
|
||||
/mob/living/simple_animal/diona/proc/update_progression()
|
||||
if(!donors.len)
|
||||
return
|
||||
if(stat != CONSCIOUS || !donors.len)
|
||||
return FALSE
|
||||
|
||||
if(donors.len == 5)
|
||||
ready_evolve = 1
|
||||
if(donors.len == evolve_donors)
|
||||
to_chat(src, "<span class='noticealien'>You feel ready to move on to your next stage of growth.</span>")
|
||||
else if(donors.len == 3)
|
||||
else if(donors.len == awareness_donors)
|
||||
universal_understand = 1
|
||||
to_chat(src, "<span class='noticealien'>You feel your awareness expand, and realize you know how to understand the creatures around you.</span>")
|
||||
else
|
||||
@@ -219,7 +259,7 @@
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/diona/emote(act, m_type=1, message = null)
|
||||
if(stat)
|
||||
if(stat != CONSCIOUS)
|
||||
return
|
||||
|
||||
var/on_CD = 0
|
||||
@@ -237,6 +277,6 @@
|
||||
if("chirp")
|
||||
message = "<B>\The [src]</B> chirps!"
|
||||
m_type = 2 //audible
|
||||
playsound(src, 'sound/misc/nymphchirp.ogg', 40, 1, 1)
|
||||
playsound(src, chirp_sound, 40, 1, 1)
|
||||
|
||||
..(act, m_type, message)
|
||||
@@ -23,6 +23,11 @@
|
||||
var/datum/mind/origin
|
||||
var/egg_lain = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/headcrab/examine(mob/user)
|
||||
..()
|
||||
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)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
var/check_friendly_fire = 0 // Should the ranged mob check for friendlies when shooting
|
||||
var/retreat_distance = null //If our mob runs from players when they're too close, set in tile distance. By default, mobs do not retreat.
|
||||
var/minimum_distance = 1 //Minimum approach distance, so ranged mobs chase targets down, but still keep their distance set in tiles to the target, set higher to make mobs keep distance
|
||||
|
||||
|
||||
//These vars are related to how mobs locate and target
|
||||
var/robust_searching = 0 //By default, mobs have a simple searching method, set this to 1 for the more scrutinous searching (stat_attack, stat_exclusive, etc), should be disabled on most mobs
|
||||
var/vision_range = 9 //How big of an area to search for targets in, a vision of 9 attempts to find targets as soon as they walk into screen view
|
||||
|
||||
@@ -101,7 +101,7 @@ Difficulty: Medium
|
||||
animate(src, pixel_z = 0, time = 12)
|
||||
|
||||
/obj/effect/temp_visual/target
|
||||
icon = 'icons/mob/actions.dmi'
|
||||
icon = 'icons/mob/actions/actions.dmi'
|
||||
icon_state = "sniper_zoom"
|
||||
layer = MOB_LAYER - 0.1
|
||||
luminosity = 2
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
/datum/action/innate/terrorspider/queen/queensense
|
||||
name = "Hive Sense"
|
||||
icon_icon = 'icons/mob/actions.dmi'
|
||||
icon_icon = 'icons/mob/actions/actions.dmi'
|
||||
button_icon_state = "mindswap"
|
||||
|
||||
/datum/action/innate/terrorspider/queen/queensense/Activate()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/mob/new_player
|
||||
var/ready = 0
|
||||
var/skip_antag = 0 //For declining an antag roll this round.
|
||||
var/spawning = 0 //Referenced when you want to delete the new_player later on in the code.
|
||||
var/totalPlayers = 0 //Player counts for the Lobby tab
|
||||
var/totalPlayersReady = 0
|
||||
@@ -65,16 +64,16 @@
|
||||
if(!ticker || ticker.current_state <= GAME_STATE_PREGAME)
|
||||
if(!ready) output += "<p><a href='byond://?src=[UID()];ready=1'>Declare Ready</A></p>"
|
||||
else output += "<p><b>You are ready</b> (<a href='byond://?src=[UID()];ready=2'>Cancel</A>)</p>"
|
||||
|
||||
var/list/antags = client.prefs.be_special
|
||||
if(antags && antags.len)
|
||||
if(!skip_antag) output += "<p><a href='byond://?src=[UID()];skip_antag=1'>Global Antag Candidacy</A>"
|
||||
else output += "<p><a href='byond://?src=[UID()];skip_antag=2'>Global Antag Candidacy</A>"
|
||||
output += "<br /><small>You are <b>[skip_antag ? "ineligible" : "eligible"]</b> for all antag roles.</small></p>"
|
||||
else
|
||||
output += "<p><a href='byond://?src=[UID()];manifest=1'>View the Crew Manifest</A></p>"
|
||||
output += "<p><a href='byond://?src=[UID()];late_join=1'>Join Game!</A></p>"
|
||||
|
||||
var/list/antags = client.prefs.be_special
|
||||
if(antags && antags.len)
|
||||
if(!client.skip_antag) output += "<p><a href='byond://?src=[UID()];skip_antag=1'>Global Antag Candidacy</A>"
|
||||
else output += "<p><a href='byond://?src=[UID()];skip_antag=2'>Global Antag Candidacy</A>"
|
||||
output += "<br /><small>You are <b>[client.skip_antag ? "ineligible" : "eligible"]</b> for all antag roles.</small></p>"
|
||||
|
||||
output += "<p><a href='byond://?src=[UID()];observe=1'>Observe</A></p>"
|
||||
|
||||
if(GLOB.join_tos)
|
||||
@@ -172,7 +171,7 @@
|
||||
new_player_panel_proc()
|
||||
|
||||
if(href_list["skip_antag"])
|
||||
skip_antag = !skip_antag
|
||||
client.skip_antag = !client.skip_antag
|
||||
new_player_panel_proc()
|
||||
|
||||
if(href_list["refresh"])
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
return
|
||||
if(!AM || !isturf(AM.loc)) //if there's no object or the object being pulled is inside something: abort!
|
||||
return
|
||||
if(incapacitated())
|
||||
return
|
||||
if(!(AM.anchored))
|
||||
AM.add_fingerprint(src)
|
||||
|
||||
@@ -14,7 +16,6 @@
|
||||
if(AM == pulling)
|
||||
return
|
||||
stop_pulling()
|
||||
|
||||
if(AM.pulledby)
|
||||
visible_message("<span class='danger'>[src] has pulled [AM] from [AM.pulledby]'s grip.</span>")
|
||||
AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
|
||||
|
||||
Reference in New Issue
Block a user