Merge conflict resolution

This commit is contained in:
Mars
2018-07-29 14:38:11 +02:00
1925 changed files with 54397 additions and 50020 deletions
+7 -7
View File
@@ -106,7 +106,7 @@ var/list/image/ghost_darkness_images = list() //this is a list of images for thi
Transfer_mind is there to check if mob is being deleted/not going to have a body.
Works together with spawning an observer, noted above.
*/
/mob/dead/observer/Life()
/mob/dead/observer/Life(seconds, times_fired)
..()
if(!loc) return
if(!client) return 0
@@ -229,18 +229,18 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/verb/reenter_corpse()
set category = "Ghost"
set name = "Re-enter Corpse"
if(!client) return
if(!can_reenter_corpse)
to_chat(src, "<span class='warning'>You've given up your right to respawn!</span>")
if(!client)
return
if(!(mind && mind.current && can_reenter_corpse))
if(!mind || QDELETED(mind.current))
to_chat(src, "<span class='warning'>You have no body.</span>")
return
if(!can_reenter_corpse)
to_chat(src, "<span class='warning'>You cannot re-enter your body.</span>")
return
if(mind.current.key && copytext(mind.current.key,1,2)!="@") //makes sure we don't accidentally kick any clients
to_chat(usr, "<span class='warning'>Another consciousness is in your body...It is resisting you.</span>")
return
mind.current.ajourn=0
mind.current.key = key
var/obj/structure/morgue/Morgue = locate() in mind.current.loc
@@ -419,7 +419,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(.)
update_following()
/mob/Life()
/mob/Life(seconds, times_fired)
// to catch teleports etc which directly set loc
update_following()
return ..()
+2 -2
View File
@@ -4,7 +4,7 @@
if(!message)
return
log_say("Ghost/[src.key] : [message]")
log_ghostsay(message, src)
if(src.client)
if(src.client.prefs.muted & MUTE_DEADCHAT)
@@ -26,7 +26,7 @@
if(act != "me")
return
log_emote("Ghost/[src.key] : [message]")
log_ghostemote(message, src)
if(src.client)
if(src.client.prefs.muted & MUTE_DEADCHAT)
+3 -6
View File
@@ -46,7 +46,7 @@
if(message)
log_emote("[name]/[key] : [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.
@@ -70,7 +70,7 @@
if(O.status_flags & PASSEMOTES)
for(var/obj/item/weapon/holder/H in O.contents)
for(var/obj/item/holder/H in O.contents)
H.show_message(message, m_type)
for(var/mob/living/M in O.contents)
@@ -85,7 +85,7 @@
if(O.status_flags & PASSEMOTES)
for(var/obj/item/weapon/holder/H in O.contents)
for(var/obj/item/holder/H in O.contents)
H.show_message(message, m_type)
for(var/mob/living/M in O.contents)
@@ -94,7 +94,6 @@
O.show_message(message, m_type)
/mob/proc/emote_dead(var/message)
if(client.prefs.muted & MUTE_DEADCHAT)
to_chat(src, "<span class='warning'>You cannot send deadchat emotes (muted).</span>")
return
@@ -122,8 +121,6 @@
if(message)
log_emote("Ghost/[src.key] : [message]")
for(var/mob/M in player_list)
if(istype(M, /mob/new_player))
continue
+2 -2
View File
@@ -70,7 +70,7 @@
if(speaker == src)
to_chat(src, "<span class='warning'>You cannot hear yourself speak!</span>")
else
to_chat(src, "<span class='name'>[speaker_name]</span>[alt_name] talks but you cannot hear them.")
to_chat(src, "<span class='name'>[speaker_name]</span>[alt_name] talks but you cannot hear [speaker.p_them()].")
else
if(language)
to_chat(src, "<span class='game say'><span class='name'>[speaker_name]</span>[alt_name] [track][language.format_message(message, verb)]</span>")
@@ -159,7 +159,7 @@
message = "<B>[src]</B> [verb]."
if(src.status_flags & PASSEMOTES)
for(var/obj/item/weapon/holder/H in src.contents)
for(var/obj/item/holder/H in src.contents)
H.show_message(message)
for(var/mob/living/M in src.contents)
M.show_message(message)
+17 -17
View File
@@ -1,19 +1,19 @@
//Helper object for picking dionaea (and other creatures) up.
/obj/item/weapon/holder
/obj/item/holder
name = "holder"
desc = "You shouldn't ever see this."
icon = 'icons/obj/objects.dmi'
slot_flags = SLOT_HEAD
/obj/item/weapon/holder/New()
/obj/item/holder/New()
..()
processing_objects.Add(src)
/obj/item/weapon/holder/Destroy()
/obj/item/holder/Destroy()
processing_objects.Remove(src)
return ..()
/obj/item/weapon/holder/process()
/obj/item/holder/process()
if(istype(loc,/turf) || !(contents.len))
@@ -26,23 +26,23 @@
qdel(src)
/obj/item/weapon/holder/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
/obj/item/holder/attackby(obj/item/W as obj, mob/user as mob, params)
for(var/mob/M in src.contents)
M.attackby(W,user, params)
/obj/item/weapon/holder/proc/show_message(var/message, var/m_type)
/obj/item/holder/proc/show_message(var/message, var/m_type)
for(var/mob/living/M in contents)
M.show_message(message,m_type)
/obj/item/weapon/holder/emp_act(var/intensity)
/obj/item/holder/emp_act(var/intensity)
for(var/mob/living/M in contents)
M.emp_act(intensity)
/obj/item/weapon/holder/ex_act(var/intensity)
/obj/item/holder/ex_act(var/intensity)
for(var/mob/living/M in contents)
M.ex_act(intensity)
/obj/item/weapon/holder/container_resist(var/mob/living/L)
/obj/item/holder/container_resist(var/mob/living/L)
var/mob/M = src.loc //Get our mob holder (if any).
if(istype(M))
@@ -55,7 +55,7 @@
if(istype(M))
for(var/atom/A in M.contents)
if(istype(A,/mob/living/simple_animal/borer) || istype(A,/obj/item/weapon/holder))
if(istype(A,/mob/living/simple_animal/borer) || istype(A,/obj/item/holder))
return
M.status_flags &= ~PASSEMOTES
@@ -67,10 +67,10 @@
/mob/living/proc/get_scooped(var/mob/living/carbon/grabber)
if(!holder_type) return
var/obj/item/weapon/holder/H = new holder_type(loc)
var/obj/item/holder/H = new holder_type(loc)
src.forceMove(H)
H.name = name
if(istype(H, /obj/item/weapon/holder/mouse)) H.icon_state = icon_state
if(istype(H, /obj/item/holder/mouse)) H.icon_state = icon_state
if(desc) H.desc = desc
H.attack_hand(grabber)
@@ -81,26 +81,26 @@
//Mob specific holders.
/obj/item/weapon/holder/diona
/obj/item/holder/diona
name = "diona nymph"
desc = "It's a tiny plant critter."
icon_state = "nymph"
/obj/item/weapon/holder/drone
/obj/item/holder/drone
name = "maintenance drone"
desc = "It's a small maintenance robot."
icon_state = "drone"
/obj/item/weapon/holder/drone/emagged
/obj/item/holder/drone/emagged
name = "maintenance drone"
icon_state = "drone-emagged"
/obj/item/weapon/holder/pai
/obj/item/holder/pai
name = "pAI"
desc = "It's a little robot."
icon_state = "pai"
/obj/item/weapon/holder/mouse
/obj/item/holder/mouse
name = "mouse"
desc = "It's a small, disease-ridden rodent."
icon = 'icons/mob/animal.dmi'
+1 -1
View File
@@ -191,7 +191,7 @@
M.s_active.handle_item_insertion(src)
return 1
var/obj/item/weapon/storage/S = M.get_inactive_hand()
var/obj/item/storage/S = M.get_inactive_hand()
if(istype(S) && S.can_be_inserted(src, 1)) //see if we have box in other hand
S.handle_item_insertion(src)
return 1
+19 -16
View File
@@ -99,7 +99,7 @@
if(!check_can_speak(speaker))
return FALSE
log_say("[key_name(speaker)]: ([name]) [message]")
log_say("([name]-HIVE) [message]", speaker)
if(!speaker_mask)
speaker_mask = speaker.name
@@ -226,7 +226,14 @@
"SKRE","AHK","EHK","RAWK","KRA","AAA","EEE","KI","II","KRI","KA")
/datum/language/vox/get_random_name()
return ..(FEMALE,1,6)
var/sounds = rand(2, 8)
var/i = 0
var/newname = ""
while(i <= sounds)
i++
newname += pick(vox_name_syllables)
return capitalize(newname)
/datum/language/diona
name = "Rootspeak"
@@ -240,8 +247,8 @@
syllables = list("hs","zt","kr","st","sh")
/datum/language/diona/get_random_name()
var/new_name = "[pick(list("To Sleep Beneath","Wind Over","Embrace of","Dreams of","Witnessing","To Walk Beneath","Approaching the"))]"
new_name += " [pick(list("the Void","the Sky","Encroaching Night","Planetsong","Starsong","the Wandering Star","the Empty Day","Daybreak","Nightfall","the Rain"))]"
var/new_name = "[pick(list("To Sleep Beneath", "Wind Over", "Embrace of", "Dreams of", "Witnessing", "To Walk Beneath", "Approaching the", "Glimmer of", "The Ripple of", "Colors of", "The Still of", "Silence of", "Gentle Breeze of", "Glistening Waters under", "Child of", "Blessed Plant-ling of", "Grass-Walker of", "Element of", "Spawn of"))]"
new_name += " [pick(list("the Void", "the Sky", "Encroaching Night", "Planetsong", "Starsong", "the Wandering Star", "the Empty Day", "Daybreak", "Nightfall", "the Rain", "the Stars", "the Waves", "Dusk", "Night", "the Wind", "the Summer Wind", "the Blazing Sun", "the Scorching Sun", "Eternal Fields", "the Soothing Plains", "the Undying Fiona", "Mother Nature's Bousum"))]"
return new_name
/datum/language/trinary
@@ -310,12 +317,7 @@
to_chat(speaker,"<span class='warning'>You can't communicate while unable to move your hands to your head!</span>")
return FALSE
var/their = "their"
if(speaker.gender == "female")
their = "her"
if(speaker.gender == "male")
their = "his"
speaker.visible_message("<span class='notice'>[speaker] touches [their] fingers to [their] temple.</span>") //If placed in grey/broadcast, it will happen regardless of the success of the action.
speaker.visible_message("<span class='notice'>[speaker] touches [speaker.p_their()] fingers to [speaker.p_their()] temple.</span>") //If placed in grey/broadcast, it will happen regardless of the success of the action.
return TRUE
@@ -512,8 +514,10 @@
..(speaker,message,speaker.real_name)
/datum/language/abductor/check_special_condition(mob/living/carbon/human/other, mob/living/carbon/human/speaker)
if(other.mind && other.mind.abductor)
if(other.mind.abductor.team == speaker.mind.abductor.team)
if(isabductor(other) && isabductor(speaker))
var/datum/species/abductor/A = speaker.dna.species
var/datum/species/abductor/A2 = other.dna.species
if(A.team == A2.team)
return TRUE
return FALSE
@@ -553,16 +557,15 @@
var/drone_only
/datum/language/binary/broadcast(mob/living/speaker, message, speaker_mask)
if(!speaker.binarycheck())
return
if(!message)
return
log_robot("[key_name(speaker)] : [message]")
log_say("(ROBOT) [message]", speaker)
var/message_start = "<i><span class='game say'>[name], <span class='name'>[speaker.name]</span>"
var/message_body = "<span class='message'>[speaker.say_quote(message)],</i> <span class='ibm'>\"[message]\"</span></span></span>"
var/message_body = "<span class='message'>[speaker.say_quote(message)],</i><span class='robot'>\"[message]\"</span></span></span>"
for(var/mob/M in dead_mob_list)
if(!isnewplayer(M) && !isbrain(M))
+1 -1
View File
@@ -4,7 +4,7 @@
/mob/living/carbon/human/handle_autohiss(message, datum/language/L)
if(!client || client.prefs.autohiss_mode == AUTOHISS_OFF) // no need to process if there's no client or they have autohiss off
return message
return species.handle_autohiss(message, L, client.prefs.autohiss_mode)
return dna.species.handle_autohiss(message, L, client.prefs.autohiss_mode)
/client/verb/toggle_autohiss()
set name = "Toggle Auto-Accent"
+3 -42
View File
@@ -1,7 +1,3 @@
#define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point
#define HEAT_DAMAGE_LEVEL_2 3 //Amount of damage applied when your body temperature passes the 400K point
#define HEAT_DAMAGE_LEVEL_3 8 //Amount of damage applied when your body temperature passes the 1000K point
/mob/living/carbon/alien
name = "alien"
voice_name = "alien"
@@ -9,15 +5,10 @@
icon = 'icons/mob/alien.dmi'
gender = NEUTER
dna = null
alien_talk_understand = 1
nightvision = 1
var/obj/item/weapon/card/id/wear_id = null // Fix for station bounced radios -- Skie
var/obj/item/card/id/wear_id = null // Fix for station bounced radios -- Skie
var/has_fine_manipulation = 0
var/move_delay_add = 0 // movement delay to add
status_flags = CANPARALYSE|CANPUSH
@@ -27,7 +18,6 @@
var/heat_protection = 0.5
var/leaping = 0
ventcrawler = 2
var/list/alien_organs = list()
/mob/living/carbon/alien/New()
@@ -118,31 +108,6 @@
else
clear_alert("alien_fire")
/mob/living/carbon/alien/handle_mutations_and_radiation()
// Aliens love radiation nom nom nom
if(radiation)
if(radiation > 100)
radiation = 100
if(radiation < 0)
radiation = 0
switch(radiation)
if(1 to 49)
radiation--
if(prob(25))
adjustToxLoss(1)
if(50 to 74)
radiation -= 2
adjustToxLoss(1)
if(prob(5))
radiation -= 5
if(75 to 100)
radiation -= 3
adjustToxLoss(3)
/mob/living/carbon/alien/handle_fire()//Aliens on fire code
if(..())
return
@@ -199,11 +164,11 @@
//Lasertag bullshit
if(lasercolor)
if(lasercolor == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve
if((istype(r_hand,/obj/item/weapon/gun/energy/laser/redtag)) || (istype(l_hand,/obj/item/weapon/gun/energy/laser/redtag)))
if((istype(r_hand,/obj/item/gun/energy/laser/redtag)) || (istype(l_hand,/obj/item/gun/energy/laser/redtag)))
threatcount += 4
if(lasercolor == "r")
if((istype(r_hand,/obj/item/weapon/gun/energy/laser/bluetag)) || (istype(l_hand,/obj/item/weapon/gun/energy/laser/bluetag)))
if((istype(r_hand,/obj/item/gun/energy/laser/bluetag)) || (istype(l_hand,/obj/item/gun/energy/laser/bluetag)))
threatcount += 4
return threatcount
@@ -260,10 +225,6 @@ Des: Removes all infected images from the alien.
/mob/living/carbon/alien/can_use_vents()
return
#undef HEAT_DAMAGE_LEVEL_1
#undef HEAT_DAMAGE_LEVEL_2
#undef HEAT_DAMAGE_LEVEL_3
/mob/living/carbon/alien/handle_footstep(turf/T)
if(..())
if(T.footstep_sounds["xeno"])
@@ -5,7 +5,7 @@
As such, they can either help or harm other aliens. Help works like the human help command while harm is a simple nibble.
In all, this is a lot like the monkey code. /N
*/
/mob/living/carbon/alien/attack_alien(mob/living/carbon/alien/M as mob)
/mob/living/carbon/alien/attack_alien(mob/living/carbon/alien/M)
if(!ticker)
to_chat(M, "You cannot attack people before the game has started.")
return
@@ -29,38 +29,37 @@ In all, this is a lot like the monkey code. /N
else
if(health > 0)
M.do_attack_animation(src)
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
var/damage = 1
visible_message("<span class='danger'>[M.name] bites [src]!</span>", \
"<span class='userdanger'>[M.name] bites [src]!</span>")
adjustBruteLoss(damage)
add_logs(M, src, "attacked", admin=0, print_attack_log = 0)
add_attack_logs(M, src, "Alien attack", ATKLOG_ALL)
updatehealth()
else
to_chat(M, "<span class='warning'>[name] is too injured for that.</span>")
/mob/living/carbon/alien/attack_larva(mob/living/carbon/alien/larva/L as mob)
/mob/living/carbon/alien/attack_larva(mob/living/carbon/alien/larva/L)
return attack_alien(L)
/mob/living/carbon/alien/attack_hand(mob/living/carbon/human/M as mob)
/mob/living/carbon/alien/attack_hand(mob/living/carbon/human/M)
if(..()) //to allow surgery to return properly.
return 0
if(istype(src,/mob/living/carbon/alien/humanoid))
return 0 //this is horrible but 100% necessary
switch(M.a_intent)
if(INTENT_HELP)
help_shake_act(M)
if(INTENT_GRAB)
grabbedby(M)
if(INTENT_HARM, INTENT_DISARM)
if(INTENT_HARM)
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
if(INTENT_DISARM)
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
return 1
return 0
/mob/living/carbon/alien/attack_animal(mob/living/simple_animal/M as mob)
/mob/living/carbon/alien/attack_animal(mob/living/simple_animal/M)
if(..())
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
switch(M.melee_damage_type)
@@ -55,6 +55,6 @@
update_icons()
timeofdeath = world.time
if(mind) mind.store_memory("Time of death: [worldtime2text(timeofdeath)]", 0)
if(mind) mind.store_memory("Time of death: [station_time_timestamp("hh:mm:ss", timeofdeath)]", 0)
return ..(gibbed)
@@ -43,7 +43,7 @@ Doesn't work on other aliens/AI.*/
adjustPlasma(-10)
var/msg = sanitize(input("Message:", "Alien Whisper") as text|null)
if(msg)
log_say("Alien Whisper: [key_name(src)]->[key_name(M)]: [msg]")
log_say("(AWHISPER to [key_name(M)]) [msg]", src)
to_chat(M, "<span class='noticealien'>You hear a strange, alien voice in your head...<span class='noticealien'>[msg]")
to_chat(src, "<span class='noticealien'>You said: [msg] to [M]</span>")
for(var/mob/dead/observer/G in player_list)
@@ -161,7 +161,7 @@ Doesn't work on other aliens/AI.*/
stomach_contents.Remove(M)
M.loc = loc
//Paralyse(10)
src.visible_message("<span class='alertalien'><B>[src] hurls out the contents of their stomach!</span>")
src.visible_message("<span class='alertalien'><B>[src] hurls out the contents of [p_their()] stomach!</span>")
return
/mob/living/carbon/proc/getPlasma()
@@ -2,9 +2,9 @@
name = "alien"
icon_state = "alien_s"
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/xenomeat = 5, /obj/item/stack/sheet/animalhide/xeno = 1)
var/obj/item/weapon/r_store = null
var/obj/item/weapon/l_store = null
butcher_results = list(/obj/item/reagent_containers/food/snacks/xenomeat = 5, /obj/item/stack/sheet/animalhide/xeno = 1)
var/obj/item/r_store = null
var/obj/item/l_store = null
var/caste = ""
var/alt_icon = 'icons/mob/alienleap.dmi' //used to switch between the two alien icon files.
var/next_attack = 0
@@ -78,138 +78,14 @@
updatehealth()
/mob/living/carbon/alien/humanoid/attack_slime(mob/living/carbon/slime/M as mob)
if(!ticker)
to_chat(M, "You cannot attack people before the game has started.")
return
if(M.Victim) return // can't attack while eating!
if(stat > -100)
M.do_attack_animation(src)
visible_message("<span class='danger'>The [M.name] glomps [src]!</span>", \
"<span class='userdanger'>The [M.name] glomps [src]!</span>")
var/damage = rand(1, 3)
if(M.is_adult)
damage = rand(10, 40)
else
damage = rand(5, 35)
adjustBruteLoss(damage)
if(M.powerlevel > 0)
var/stunprob = 10
var/power = M.powerlevel + rand(0,3)
switch(M.powerlevel)
if(1 to 2) stunprob = 20
if(3 to 4) stunprob = 30
if(5 to 6) stunprob = 40
if(7 to 8) stunprob = 60
if(9) stunprob = 70
if(10) stunprob = 95
if(prob(stunprob))
M.powerlevel -= 3
if(M.powerlevel < 0)
M.powerlevel = 0
visible_message("<span class='danger'>The [M.name] has shocked [src]!</span>", \
"<span class='userdanger'>The [M.name] has shocked [src]!</span>")
Weaken(power)
if(stuttering < power)
stuttering = power
Stun(power)
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(5, 1, src)
s.start()
if(prob(stunprob) && M.powerlevel >= 8)
adjustFireLoss(M.powerlevel * rand(6,10))
updatehealth()
return
/mob/living/carbon/alien/humanoid/attack_animal(mob/living/simple_animal/M as mob)
if(M.melee_damage_upper == 0)
M.custom_emote(1, "[M.friendly] [src]")
else
M.do_attack_animation(src)
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
visible_message("<span class='danger'>[M] [M.attacktext] [src]!</span>", \
"<span class='userdanger'>[M] [M.attacktext] [src]!</span>")
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
adjustBruteLoss(damage)
updatehealth()
/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M as mob)
if(!ticker)
to_chat(M, "You cannot attack people before the game has started.")
return
if(istype(loc, /turf) && istype(loc.loc, /area/start))
to_chat(M, "No attacking people at spawn, you jackass.")
return
if(..()) //to allow surgery to return properly.
return
switch(M.a_intent)
if(INTENT_HELP)
help_shake_act(M)
if(INTENT_GRAB)
grabbedby(M)
if(INTENT_HARM)
M.do_attack_animation(src)
var/damage = rand(1, 9)
if(prob(90))
if(HULK in M.mutations)//HULK SMASH
damage = 15
spawn(0)
Paralyse(1)
step_away(src,M,15)
sleep(3)
step_away(src,M,15)
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[M] has punched [src]!</span>", \
"<span class='userdanger'>[M] has punched [src]!</span>")
if((stat != DEAD) && (damage > 9||prob(5)))//Regular humans have a very small chance of weakening an alien.
Paralyse(2)
visible_message("<span class='danger'>[M] has weakened [src]!</span>", \
"<span class='userdanger'>[M] has weakened [src]!</span>", \
"<span class='danger'>You hear someone fall.</span>")
adjustBruteLoss(damage)
updatehealth()
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to punch [src]!</span>")
if(INTENT_DISARM)
if(!lying)
if(prob(5))//Very small chance to push an alien down.
Paralyse(2)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
"<span class='userdanger'>[M] has pushed down [src]!</span>")
else
if(prob(50))
drop_item()
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
"<span class='userdanger'>[M] has disarmed [src]!</span>")
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to disarm [src]!</span>")
/mob/living/carbon/alien/humanoid/attack_slime(mob/living/carbon/slime/M)
..()
var/damage = rand(5, 35)
if(M.is_adult)
damage = rand(10, 40)
adjustBruteLoss(damage)
add_attack_logs(src, M, "Slime'd for [damage] damage")
updatehealth()
return
/mob/living/carbon/alien/humanoid/restrained()
@@ -0,0 +1,59 @@
/mob/living/carbon/alien/humanoid/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
if(user.a_intent == INTENT_HARM)
..(user, TRUE)
adjustBruteLoss(15)
var/hitverb = "punched"
if(mob_size < MOB_SIZE_LARGE)
Paralyse(1)
spawn(0)
step_away(src, user, 15)
sleep(1)
step_away(src, user, 15)
hitverb = "slammed"
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[user] has [hitverb] [src]!</span>", "<span class='userdanger'>[user] has [hitverb] [src]!</span>")
return TRUE
/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M)
if(..())
switch(M.a_intent)
if(INTENT_HARM)
var/damage = rand(1, 9)
if(prob(90))
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[M] has punched [src]!</span>", \
"<span class='userdanger'>[M] has punched [src]!</span>")
if((stat != DEAD) && (damage > 9||prob(5)))//Regular humans have a very small chance of weakening an alien.
Paralyse(2)
visible_message("<span class='danger'>[M] has weakened [src]!</span>", \
"<span class='userdanger'>[M] has weakened [src]!</span>", \
"<span class='danger'>You hear someone fall.</span>")
adjustBruteLoss(damage)
add_attack_logs(M, src, "Melee attacked with fists")
updatehealth()
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to punch [src]!</span>")
if(INTENT_DISARM)
if(!lying)
if(prob(5))//Very small chance to push an alien down.
Paralyse(2)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
add_attack_logs(M, src, "Pushed over")
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
"<span class='userdanger'>[M] has pushed down [src]!</span>")
else
if(prob(50))
drop_item()
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
"<span class='userdanger'>[M] has disarmed [src]!</span>")
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to disarm [src]!</span>")
/mob/living/carbon/alien/humanoid/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
if(!no_effect && !visual_effect_icon)
visual_effect_icon = ATTACK_EFFECT_CLAW
..()
@@ -1,4 +1,4 @@
/mob/living/carbon/alien/humanoid/Life()
/mob/living/carbon/alien/humanoid/Life(seconds, times_fired)
. = ..()
update_icons()
@@ -3,7 +3,7 @@
#define X_SUIT_LAYER 2
#define X_L_HAND_LAYER 3
#define X_R_HAND_LAYER 4
#define TARGETED_LAYER 5
#define X_TARGETED_LAYER 5
#define X_FIRE_LAYER 6
#define X_TOTAL_LAYERS 6
/////////////////////////////////
@@ -161,6 +161,6 @@
#undef X_SUIT_LAYER
#undef X_L_HAND_LAYER
#undef X_R_HAND_LAYER
#undef TARGETED_LAYER
#undef X_TARGETED_LAYER
#undef X_FIRE_LAYER
#undef X_TOTAL_LAYERS
@@ -9,7 +9,7 @@
update_canmove()
timeofdeath = world.time
if(mind) mind.store_memory("Time of death: [worldtime2text(timeofdeath)]", 0)
if(mind) mind.store_memory("Time of death: [station_time_timestamp("hh:mm:ss", timeofdeath)]", 0)
living_mob_list -= src
return ..(gibbed)
@@ -114,7 +114,7 @@
else
to_chat(src, text("Invalid Emote: []", act))
if((message && src.stat == 0))
log_emote("[name]/[key] : [message]")
log_emote(message, src)
if(m_type & 1)
for(var/mob/O in viewers(src, null))
O.show_message(message, m_type)
@@ -73,91 +73,15 @@
/mob/living/carbon/alien/larva/attack_ui(slot_id)
return
/mob/living/carbon/alien/larva/attack_animal(mob/living/simple_animal/M as mob)
if(M.melee_damage_upper == 0)
M.custom_emote(1, "[M.friendly] [src]")
else
M.do_attack_animation(src)
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
visible_message("<span class='danger'>[M] [M.attacktext] [src]!</span>", \
"<span class='userdanger'>[M] [M.attacktext] [src]!</span>")
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
adjustBruteLoss(damage)
add_logs(M, src, "attacked", admin=0, print_attack_log = 0)
updatehealth()
/mob/living/carbon/alien/larva/attack_slime(mob/living/carbon/slime/M as mob)
if(!ticker)
to_chat(M, "You cannot attack people before the game has started.")
return
if(M.Victim)
return // can't attack while eating!
if(stat != DEAD)
M.do_attack_animation(src)
visible_message("<span class='danger'>The [M.name] glomps [src]!</span>", \
"<span class='userdanger'>The [M.name] glomps [src]!</span>")
var/damage = rand(1, 3)
if(M.is_adult)
damage = rand(20, 40)
else
damage = rand(5, 35)
adjustBruteLoss(damage)
updatehealth()
return
/mob/living/carbon/alien/larva/attack_hand(mob/living/carbon/human/M as mob)
if(!ticker)
to_chat(M, "You cannot attack people before the game has started.")
return
if(istype(loc, /turf) && istype(loc.loc, /area/start))
to_chat(M, "No attacking people at spawn, you jackass.")
return
/mob/living/carbon/alien/larva/attack_slime(mob/living/carbon/slime/M)
..()
switch(M.a_intent)
if(INTENT_HELP)
help_shake_act(M)
if(INTENT_GRAB)
grabbedby(M)
else
M.do_attack_animation(src)
var/damage = rand(1, 9)
if(prob(90))
if(HULK in M.mutations)
damage += 5
spawn(0)
Paralyse(1)
step_away(src,M,15)
sleep(3)
step_away(src,M,15)
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[M] has kicked [src]!</span>", \
"<span class='userdanger'>[M] has kicked [src]!</span>")
if((stat != DEAD) && (damage > 4.9))
Paralyse(rand(5,10))
visible_message("<span class='danger'>[M] has weakened [src]!</span>", \
"<span class='userdanger'>[M] has weakened [src]!</span>", \
"<span class='danger'>You hear someone fall.</span>")
adjustBruteLoss(damage)
updatehealth()
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to kick [src]!</span>", \
"<span class='userdanger'>[M] has attempted to kick [src]!</span>")
var/damage = rand(5, 35)
if(M.is_adult)
damage = rand(20, 40)
adjustBruteLoss(damage)
add_attack_logs(src, M, "Slime'd for [damage] damage")
updatehealth()
return
/mob/living/carbon/alien/larva/restrained()
return 0
@@ -0,0 +1,34 @@
/mob/living/carbon/alien/larva/attack_hand(mob/living/carbon/human/M)
if(..())
var/damage = rand(1, 9)
if(prob(90))
playsound(loc, "punch", 25, 1, -1)
add_attack_logs(M, src, "Melee attacked with fists")
visible_message("<span class='danger'>[M] has kicked [src]!</span>", \
"<span class='userdanger'>[M] has kicked [src]!</span>")
if((stat != DEAD) && (damage > 4.9))
Paralyse(rand(5,10))
adjustBruteLoss(damage)
updatehealth()
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to kick [src]!</span>", \
"<span class='userdanger'>[M] has attempted to kick [src]!</span>")
/mob/living/carbon/alien/larva/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
if(user.a_intent == INTENT_HARM)
..(user, TRUE)
adjustBruteLoss(5 + rand(1, 9))
spawn(0)
Paralyse(1)
step_away(src, user, 15)
sleep(3)
step_away(src, user, 15)
return TRUE
/mob/living/carbon/alien/larva/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
if(!no_effect && !visual_effect_icon)
visual_effect_icon = ATTACK_EFFECT_BITE
..()
@@ -1,4 +1,4 @@
/mob/living/carbon/alien/larva/Life()
/mob/living/carbon/alien/larva/Life(seconds, times_fired)
if(..()) //still breathing
// GROW!
if(amount_grown < max_grown)
@@ -96,7 +96,7 @@
if(ticker && ticker.mode)
ticker.mode.xenos += new_xeno.mind
new_xeno.mind.name = new_xeno.name
new_xeno.mind.assigned_role = "MODE"
new_xeno.mind.assigned_role = SPECIAL_ROLE_XENOMORPH
new_xeno.mind.special_role = SPECIAL_ROLE_XENOMORPH
new_xeno << sound('sound/voice/hiss5.ogg',0,0,0,100)//To get the player's attention
+149 -59
View File
@@ -1,4 +1,4 @@
/obj/item/device/mmi
/obj/item/mmi
name = "Man-Machine Interface"
desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity."
icon = 'icons/obj/assemblies.dmi'
@@ -16,7 +16,10 @@
var/obj/mecha/mecha = null//This does not appear to be used outside of reference in mecha.dm.
// I'm using this for mechs giving MMIs HUDs now
/obj/item/device/mmi/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
var/obj/item/radio/radio = null // For use with the radio MMI upgrade
var/datum/action/generic/configure_mmi_radio/radio_action = null
/obj/item/mmi/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
if(istype(O, /obj/item/organ/internal/brain/crystal ))
to_chat(user, "<span class='warning'> This brain is too malformed to be able to use with the [src].</span>")
return
@@ -29,34 +32,70 @@
to_chat(user, "<span class='userdanger'>Somehow, this MMI still has a brain in it. Report this to the bug tracker.</span>")
log_runtime(EXCEPTION("[user] tried to stick a [O] into [src] in [get_area(src)], but the held brain variable wasn't cleared"), src)
return
for(var/mob/V in viewers(src, null))
V.show_message("<span class='notice'>[user] sticks \a [O] into \the [src].</span>")
brainmob = B.brainmob
B.brainmob = null
brainmob.loc = src
brainmob.container = src
brainmob.stat = CONSCIOUS
respawnable_list -= brainmob
dead_mob_list -= brainmob//Update dem lists
living_mob_list += brainmob
if(user.drop_item())
B.forceMove(src)
visible_message("<span class='notice'>[user] sticks \a [O] into \the [src].</span>")
brainmob = B.brainmob
B.brainmob = null
brainmob.loc = src
brainmob.container = src
brainmob.stat = CONSCIOUS
respawnable_list -= brainmob
dead_mob_list -= brainmob//Update dem lists
living_mob_list += brainmob
user.drop_item()
B.forceMove(src)
held_brain = B
if(istype(O,/obj/item/organ/internal/brain/xeno)) // kept the type check, as it still does other weird stuff
name = "Man-Machine Interface: Alien - [brainmob.real_name]"
icon = 'icons/mob/alien.dmi'
icon_state = "AlienMMI"
alien = 1
held_brain = B
if(istype(O,/obj/item/organ/internal/brain/xeno)) // kept the type check, as it still does other weird stuff
name = "Man-Machine Interface: Alien - [brainmob.real_name]"
icon = 'icons/mob/alien.dmi'
become_occupied("AlienMMI")
alien = 1
else
name = "Man-Machine Interface: [brainmob.real_name]"
icon = B.mmi_icon
become_occupied("[B.mmi_icon_state]")
alien = 0
if(radio_action)
radio_action.UpdateButtonIcon()
feedback_inc("cyborg_mmis_filled",1)
else
name = "Man-Machine Interface: [brainmob.real_name]"
icon = B.mmi_icon
icon_state = "[B.mmi_icon_state]"
alien = 0
feedback_inc("cyborg_mmis_filled",1)
to_chat(user, "<span class='warning'>You can't drop [B]!</span>")
return
if(istype(O, /obj/item/mmi_radio_upgrade))
if(radio)
to_chat(user, "<span class='warning'>[src] already has a radio installed.</span>")
else
user.visible_message("<span class='notice'>[user] begins to install the [O] into [src]...</span>", \
"<span class='notice'>You start to install the [O] into [src]...</span>")
if(do_after(user, 20, target=src))
if(user.drop_item())
user.visible_message("<span class='notice'>[user] installs [O] in [src].</span>", \
"<span class='notice'>You install [O] in [src].</span>")
if(brainmob)
to_chat(brainmob, "<span class='notice'>MMI radio capability installed.</span>")
install_radio()
qdel(O)
else
to_chat(user, "<span class='warning'>You can't drop [O]!</span>")
return
// Maybe later add encryption key support, but that's a pain in the neck atm
if(isscrewdriver(O))
if(radio)
user.visible_message("<span class='warning'>[user] begins to uninstall the radio from [src]...</span>", \
"<span class='notice'>You start to uninstall the radio from [src]...</span>")
if(do_after(user, 40 * O.toolspeed, target = src))
uninstall_radio()
new /obj/item/mmi_radio_upgrade(get_turf(src))
user.visible_message("<span class='warning'>[user] uninstalls the radio from [src].</span>", \
"<span class='notice'>You uninstall the radio from [src].</span>")
else
to_chat(user, "<span class='warning'>There is no radio in [src]!</span>")
return
if(brainmob)
O.attack(brainmob, user)//Oh noooeeeee
// Brainmobs can take damage, but they can't actually die. Maybe should fix.
@@ -65,7 +104,7 @@
/obj/item/device/mmi/attack_self(mob/user as mob)
/obj/item/mmi/attack_self(mob/user as mob)
if(!brainmob)
to_chat(user, "<span class='warning'>You upend the MMI, but there's nothing in it.</span>")
else
@@ -75,17 +114,17 @@
icon_state = "mmi_empty"
name = "Man-Machine Interface"
/obj/item/device/mmi/proc/transfer_identity(var/mob/living/carbon/human/H)//Same deal as the regular brain proc. Used for human-->robot people.
/obj/item/mmi/proc/transfer_identity(var/mob/living/carbon/human/H)//Same deal as the regular brain proc. Used for human-->robot people.
brainmob = new(src)
brainmob.name = H.real_name
brainmob.real_name = H.real_name
brainmob.dna = H.dna.Clone()
brainmob.container = src
if(!istype(H.species) || isnull(H.species.return_organ("brain"))) // Diona/buggy people
if(!istype(H.dna.species) || isnull(H.dna.species.return_organ("brain"))) // Diona/buggy people
held_brain = new(src)
else // We have a species, and it has a brain
var/brain_path = H.species.return_organ("brain")
var/brain_path = H.dna.species.return_organ("brain")
if(!ispath(brain_path, /obj/item/organ/internal/brain))
brain_path = /obj/item/organ/internal/brain
held_brain = new brain_path(src) // Slime people will keep their slimy brains this way
@@ -93,12 +132,11 @@
held_brain.name = "\the [brainmob.name]'s [initial(held_brain.name)]"
name = "Man-Machine Interface: [brainmob.real_name]"
icon_state = "mmi_full"
return
become_occupied("mmi_full")
//I made this proc as a way to have a brainmob be transferred to any created brain, and to solve the
//problem i was having with alien/nonalien brain drops.
/obj/item/device/mmi/proc/dropbrain(var/turf/dropspot)
/obj/item/mmi/proc/dropbrain(var/turf/dropspot)
if(isnull(held_brain))
log_runtime(EXCEPTION("[src] at [loc] attempted to drop brain without a contained brain in [get_area(src)]."), src)
to_chat(brainmob, "<span class='userdanger'>Your MMI did not contain a brain! We'll make a new one for you, but you'd best report this to the bugtracker!</span>")
@@ -116,33 +154,56 @@
held_brain.forceMove(dropspot)
held_brain = null
/obj/item/mmi/proc/become_occupied(var/new_icon)
icon_state = new_icon
if(radio)
radio_action.ApplyIcon()
/obj/item/device/mmi/radio_enabled
name = "Radio-enabled Man-Machine Interface"
desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity. This one comes with a built-in radio."
origin_tech = "biotech=2;programming=3;engineering=2;magnets=2"
/obj/item/mmi/examine(mob/user)
. = ..()
if(radio)
to_chat(user, "<span class='notice'>A radio is installed on [src].</span>")
var/obj/item/device/radio/radio = null//Let's give it a radio.
/obj/item/mmi/proc/install_radio()
radio = new(src)
radio.broadcasting = TRUE
radio_action = new(radio, src)
if(brainmob && brainmob.loc == src)
radio_action.Grant(brainmob)
/obj/item/device/mmi/radio_enabled/New()
..()
radio = new(src)//Spawns a radio inside the MMI.
radio.broadcasting = 1//So it's broadcasting from the start.
/obj/item/mmi/proc/uninstall_radio()
QDEL_NULL(radio)
QDEL_NULL(radio_action)
/obj/item/device/mmi/radio_enabled/verb/Toggle_Listening()
set name = "Toggle Listening"
set desc = "Toggle listening channel on or off."
set category = "MMI"
set src = usr.loc
set popup_menu = 0
/datum/action/generic/configure_mmi_radio
name = "Configure MMI Radio"
desc = "Configure the radio installed in your MMI."
check_flags = AB_CHECK_CONSCIOUS
procname = "ui_interact"
var/obj/item/mmi = null
if(brainmob.stat)
to_chat(brainmob, "Can't do that while incapacitated or dead.")
/datum/action/generic/configure_mmi_radio/New(var/Target, var/obj/item/mmi/M)
. = ..()
mmi = M
radio.listening = radio.listening==1 ? 0 : 1
to_chat(brainmob, "<span class='notice'>Radio is [radio.listening==1 ? "now" : "no longer"] receiving broadcast.</span>")
/datum/action/generic/configure_mmi_radio/Destroy()
mmi = null
return ..()
/obj/item/device/mmi/emp_act(severity)
/datum/action/generic/configure_mmi_radio/ApplyIcon(obj/screen/movable/action_button/current_button)
// A copy/paste of the item action icon code
current_button.overlays.Cut()
if(target)
var/obj/item/I = mmi
var/old_layer = I.layer
var/old_plane = I.plane
I.layer = 21
I.plane = HUD_PLANE
current_button.overlays += I
I.layer = old_layer
I.plane = old_plane
/obj/item/mmi/emp_act(severity)
if(!brainmob)
return
else
@@ -155,28 +216,42 @@
brainmob.emp_damage += rand(0,10)
..()
/obj/item/device/mmi/relaymove(var/mob/user, var/direction)
/obj/item/mmi/relaymove(var/mob/user, var/direction)
if(user.stat || user.stunned)
return
var/obj/item/weapon/rig/rig = src.get_rig()
var/obj/item/rig/rig = src.get_rig()
if(rig)
rig.forced_move(direction, user)
/obj/item/device/mmi/Destroy()
/obj/item/mmi/Destroy()
if(isrobot(loc))
var/mob/living/silicon/robot/borg = loc
borg.mmi = null
QDEL_NULL(brainmob)
QDEL_NULL(held_brain)
QDEL_NULL(radio)
QDEL_NULL(radio_action)
return ..()
/obj/item/device/mmi/syndie
// These two procs are important for when an MMI pilots a mech
// (Brainmob "enters/leaves" the MMI when piloting)
// Also neatly handles basically every case where a brain
// is inserted or removed from an MMI
/obj/item/mmi/Entered(atom/movable/A)
if(radio && istype(A, /mob/living/carbon/brain))
radio_action.Grant(A)
/obj/item/mmi/Exited(atom/movable/A)
if(radio && istype(A, /mob/living/carbon/brain))
radio_action.Remove(A)
/obj/item/mmi/syndie
name = "Syndicate Man-Machine Interface"
desc = "Syndicate's own brand of MMI. It enforces laws designed to help Syndicate agents achieve their goals upon cyborgs created with it, but doesn't fit in Nanotrasen AI cores."
origin_tech = "biotech=4;programming=4;syndicate=2"
syndiemmi = 1
/obj/item/device/mmi/attempt_become_organ(obj/item/organ/external/parent,mob/living/carbon/human/H)
/obj/item/mmi/attempt_become_organ(obj/item/organ/external/parent,mob/living/carbon/human/H)
if(!brainmob)
return 0
if(!parent)
@@ -190,10 +265,25 @@
forceMove(holder)
holder.stored_mmi = src
holder.update_from_mmi()
if(istype(src, /obj/item/device/mmi/posibrain))
holder.robotize()
if(brainmob && brainmob.mind)
brainmob.mind.transfer_to(H)
holder.insert(H)
return 1
// As a synthetic, the only limit on visibility is view range
/obj/item/mmi/contents_nano_distance(var/src_object, var/mob/living/user)
if((src_object in view(src)) && get_dist(src_object, src) <= user.client.view)
return STATUS_INTERACTIVE // interactive (green visibility)
return user.shared_living_nano_distance(src_object)
// For now the only thing that is helped by this is radio access
// Later a more intricate system for MMI UI interaction can be established
/obj/item/mmi/contents_nano_interact(var/src_object, var/mob/living/user)
if(!istype(user, /mob/living/carbon/brain))
log_runtime(EXCEPTION("Somehow a non-brain mob is inside an MMI!"), user)
return ..()
var/mob/living/carbon/brain/BM = user
if(BM.container == src && src_object == radio)
return STATUS_INTERACTIVE
return ..()
@@ -0,0 +1,5 @@
/obj/item/mmi_radio_upgrade
name = "MMI radio upgrade"
desc = "Enables radio capability on MMIs when either installed directly on the MMI, or through a cyborg's chassis."
icon = 'icons/obj/module.dmi'
icon_state = "cyborg_upgrade1"
@@ -20,22 +20,22 @@
/mob/living/carbon/brain/say_understands(other)//Goddamn is this hackish, but this say code is so odd
if(istype(other, /mob/living/silicon/ai))
if(!(container && istype(container, /obj/item/device/mmi)))
if(!(container && istype(container, /obj/item/mmi)))
return 0
else
return 1
if(istype(other, /mob/living/silicon/decoy))
if(!(container && istype(container, /obj/item/device/mmi)))
if(!(container && istype(container, /obj/item/mmi)))
return 0
else
return 1
if(istype(other, /mob/living/silicon/pai))
if(!(container && istype(container, /obj/item/device/mmi)))
if(!(container && istype(container, /obj/item/mmi)))
return 0
else
return 1
if(istype(other, /mob/living/silicon/robot))
if(!(container && istype(container, /obj/item/device/mmi)))
if(!(container && istype(container, /obj/item/mmi)))
return 0
else
return 1
@@ -50,7 +50,7 @@
if(in_contents_of(/obj/mecha))
canmove = 1
use_me = 1 //If it can move, let it emote
else if(istype(loc, /obj/item/device/mmi))
else if(istype(loc, /obj/item/mmi))
canmove = 1 //mmi won't move anyways so whatever
else
canmove = 0
@@ -78,18 +78,18 @@ This will return true if the brain has a container that leaves it less helpless
I'm using this for Stat to give it a more nifty interface to work with
*/
/mob/living/carbon/brain/proc/has_synthetic_assistance()
return (container && istype(container, /obj/item/device/mmi)) || in_contents_of(/obj/mecha)
return (container && istype(container, /obj/item/mmi)) || in_contents_of(/obj/mecha)
/mob/living/carbon/brain/proc/get_race()
if(container)
var/obj/item/device/mmi/M = container
var/obj/item/mmi/M = container
if(istype(M) && M.held_brain)
return M.held_brain.dna.get_species_name()
return M.held_brain.dna.species.name
else
return "Artificial Life"
if(istype(loc, /obj/item/organ/internal/brain))
var/obj/item/organ/internal/brain/B = loc
return B.dna.get_species_name()
return B.dna.species.name
/mob/living/carbon/brain/Stat()
..()
@@ -14,7 +14,8 @@
organ_tag = "brain"
parent_organ = "head"
slot = "brain"
vital = 1
vital = TRUE
hidden_pain = TRUE //the brain has no pain receptors, and brain damage is meant to be a stealthy damage type.
var/mmi_icon = 'icons/obj/assemblies.dmi'
var/mmi_icon_state = "mmi_full"
@@ -1,6 +1,6 @@
/mob/living/carbon/brain/death(gibbed)
if(stat == DEAD) return
if(!gibbed && container && istype(container, /obj/item/device/mmi))//If not gibbed but in a container.
if(!gibbed && container && istype(container, /obj/item/mmi))//If not gibbed but in a container.
for(var/mob/O in viewers(container, null))
O.show_message(text("<span class='danger'>[]'s MMI flatlines!</span>", src), 1, "<span class='warning'>You hear something flatline.</span>", 2)
container.icon_state = "mmi_dead"
@@ -11,7 +11,7 @@
see_invisible = SEE_INVISIBLE_LEVEL_TWO
timeofdeath = world.time
if(mind) mind.store_memory("Time of death: [worldtime2text(timeofdeath)]", 0) //mind. ?
if(mind) mind.store_memory("Time of death: [station_time_timestamp("hh:mm:ss", timeofdeath)]", 0) //mind. ?
return ..(gibbed)
@@ -32,7 +32,7 @@
gibs(loc, dna)
dead_mob_list -= src
if(container && istype(container, /obj/item/device/mmi))
if(container && istype(container, /obj/item/mmi))
qdel(container)//Gets rid of the MMI if there is one
if(loc)
if(istype(loc,/obj/item/organ/internal/brain))
@@ -1,5 +1,5 @@
/mob/living/carbon/brain/emote(var/act,var/m_type=1,var/message = null)
if(!(container && istype(container, /obj/item/device/mmi)))//No MMI, no emotes
if(!(container && istype(container, /obj/item/mmi)))//No MMI, no emotes
return
if(findtext(act, "-", 1, null))
+2 -21
View File
@@ -1,36 +1,20 @@
/mob/living/carbon/brain/handle_mutations_and_radiation()
if(radiation)
if(radiation > 100)
radiation -= 3
adjustToxLoss(3)
updatehealth()
if(!container)
to_chat(src, "<span class='danger'>You feel weak.</span>")
else
to_chat(src, "<span class='danger'>STATUS: CRITICAL AMOUNTS OF RADIATION DETECTED.</span>")
switch(radiation)
if(0 to 49)
radiation--
if(prob(25))
adjustToxLoss(1)
updatehealth()
if(50 to 74)
radiation -= 2
adjustToxLoss(1)
if(50 to 75)
if(prob(5))
radiation -= 5
if(!container)
to_chat(src, "<span class='danger'>You feel weak.</span>")
else
to_chat(src, "<span class='danger'>STATUS: DANGEROUS AMOUNTS OF RADIATION DETECTED.</span>")
updatehealth()
if(75 to 100)
radiation -= 3
adjustToxLoss(3)
updatehealth()
..()
/mob/living/carbon/brain/proc/handle_temperature_damage(body_part, exposed_temperature, exposed_intensity)
if(status_flags & GODMODE)
@@ -38,13 +22,10 @@
if(exposed_temperature > bodytemperature)
var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0)
//adjustFireLoss(2.5*discomfort)
//adjustFireLoss(5.0*discomfort)
adjustFireLoss(20.0*discomfort)
else
var/discomfort = min( abs(exposed_temperature - bodytemperature)*(exposed_intensity)/2000000, 1.0)
//adjustFireLoss(2.5*discomfort)
adjustFireLoss(5.0*discomfort)
/mob/living/carbon/brain/handle_regular_status_updates()
@@ -1,205 +0,0 @@
/obj/item/device/mmi/posibrain
name = "positronic brain"
desc = "A cube of shining metal, four inches to a side and covered in shallow grooves."
icon = 'icons/obj/assemblies.dmi'
icon_state = "posibrain"
w_class = WEIGHT_CLASS_NORMAL
origin_tech = "biotech=3;programming=3;plasmatech=2"
var/searching = 0
var/askDelay = 10 * 60 * 1
//var/mob/living/carbon/brain/brainmob = null
var/list/ghost_volunteers[0]
req_access = list(access_robotics)
mecha = null//This does not appear to be used outside of reference in mecha.dm.
var/silenced = 0 //if set to 1, they can't talk.
var/next_ping_at = 0
/obj/item/device/mmi/posibrain/examine(mob/user)
if(..(user, 1))
to_chat(user, "Its speaker is turned [silenced ? "off" : "on"].")
/obj/item/device/mmi/posibrain/attack_self(mob/user)
if(brainmob && !brainmob.key && searching == 0)
//Start the process of searching for a new user.
to_chat(user, "<span class='notice'>You carefully locate the manual activation switch and start the positronic brain's boot process.</span>")
icon_state = "posibrain-searching"
ghost_volunteers.Cut()
searching = 1
request_player()
spawn(600)
if(ghost_volunteers.len)
var/mob/dead/observer/O
while(!istype(O) && ghost_volunteers.len)
O = pick_n_take(ghost_volunteers)
if(istype(O) && check_observer(O))
transfer_personality(O)
reset_search()
else
silenced = !silenced
to_chat(user, "<span class='notice'>You toggle the speaker [silenced ? "off" : "on"].</span>")
if(brainmob && brainmob.key)
to_chat(brainmob, "<span class='warning'>Your internal speaker has been toggled [silenced ? "off" : "on"].</span>")
/obj/item/device/mmi/posibrain/proc/request_player()
for(var/mob/dead/observer/O in player_list)
if(check_observer(O))
to_chat(O, "<span class='boldnotice'>\A [src] has been activated. (<a href='?src=[O.UID()];jump=\ref[src]'>Teleport</a> | <a href='?src=[UID()];signup=\ref[O]'>Sign Up</a>)</span>")
/obj/item/device/mmi/posibrain/proc/check_observer(var/mob/dead/observer/O)
if(cannotPossess(O))
return 0
if(jobban_isbanned(O, "Cyborg") || jobban_isbanned(O,"nonhumandept"))
return 0
if(!O.can_reenter_corpse)
return 0
if(O.client)
return 1
return 0
/obj/item/device/mmi/posibrain/proc/question(var/client/C)
spawn(0)
if(!C) return
var/response = alert(C, "Someone is requesting a personality for a positronic brain. Would you like to play as one?", "Positronic brain request", "Yes", "No", "Never for this round")
if(!C || brainmob.key || 0 == searching) return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located.
if(response == "Yes")
transfer_personality(C.mob)
else if(response == "Never for this round")
C.prefs.be_special -= ROLE_POSIBRAIN
// This should not ever happen, but let's be safe
/obj/item/device/mmi/posibrain/dropbrain(var/turf/dropspot)
log_runtime(EXCEPTION("[src] at [loc] attempted to drop brain without a contained brain."), src)
return
/obj/item/device/mmi/posibrain/transfer_identity(var/mob/living/carbon/H)
name = "positronic brain ([H])"
if(isnull(brainmob.dna))
brainmob.dna = H.dna.Clone()
brainmob.name = brainmob.dna.real_name
brainmob.real_name = brainmob.name
brainmob.timeofhostdeath = H.timeofdeath
brainmob.stat = CONSCIOUS
if(brainmob.mind)
brainmob.mind.assigned_role = "Positronic Brain"
if(H.mind)
H.mind.transfer_to(brainmob)
to_chat(brainmob, "<span class='notice'>You feel slightly disoriented. That's normal when you're just a metal cube.</span>")
icon_state = "posibrain-occupied"
return
/obj/item/device/mmi/posibrain/proc/transfer_personality(var/mob/candidate)
src.searching = 0
src.brainmob.key = candidate.key
src.name = "positronic brain ([src.brainmob.name])"
to_chat(src.brainmob, "<b>You are a positronic brain, brought into existence on [station_name()].</b>")
to_chat(src.brainmob, "<b>As a synthetic intelligence, you answer to all crewmembers, as well as the AI.</b>")
to_chat(src.brainmob, "<b>Remember, the purpose of your existence is to serve the crew and the station. Above all else, do no harm.</b>")
src.brainmob.mind.assigned_role = "Positronic Brain"
var/turf/T = get_turf_or_move(src.loc)
for(var/mob/M in viewers(T))
M.show_message("<span class='notice'>The positronic brain chimes quietly.</span>")
icon_state = "posibrain-occupied"
/obj/item/device/mmi/posibrain/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer.
if(src.brainmob && src.brainmob.key) return
src.searching = 0
icon_state = "posibrain"
var/turf/T = get_turf_or_move(src.loc)
for(var/mob/M in viewers(T))
M.show_message("<span class='notice'>The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?</span>")
/obj/item/device/mmi/posibrain/Topic(href,href_list)
if("signup" in href_list)
var/mob/dead/observer/O = locate(href_list["signup"])
if(!O) return
volunteer(O)
/obj/item/device/mmi/posibrain/proc/volunteer(var/mob/dead/observer/O)
if(!searching)
to_chat(O, "Not looking for a ghost, yet.")
return
if(!istype(O))
to_chat(O, "<span class='warning'>Error.</span>")
return
if(O in ghost_volunteers)
to_chat(O, "<span class='notice'>Removed from registration list.</span>")
ghost_volunteers.Remove(O)
return
if(!check_observer(O))
to_chat(O, "<span class='warning'>You cannot be \a [src].</span>")
return
if(cannotPossess(O))
to_chat(O, "<span class='warning'>Upon using the antagHUD you forfeited the ability to join the round.</span>")
return
if(jobban_isbanned(O, "Cyborg") || jobban_isbanned(O,"nonhumandept"))
to_chat(O, "<span class='warning'>You are job banned from this role.</span>")
return
to_chat(O., "<span class='notice'>You've been added to the list of ghosts that may become this [src]. Click again to unvolunteer.</span>")
ghost_volunteers.Add(O)
/obj/item/device/mmi/posibrain/examine(mob/user)
to_chat(user, "<span class='info'>*---------*</span>")
if(!..(user))
to_chat(user, "<span class='info'>*---------*</span>")
return
var/msg = "<span class='info'>"
if(src.brainmob && src.brainmob.key)
switch(src.brainmob.stat)
if(CONSCIOUS)
if(!src.brainmob.client) msg += "It appears to be in stand-by mode.\n" //afk
if(UNCONSCIOUS) msg += "<span class='warning'>It doesn't seem to be responsive.</span>\n"
if(DEAD) msg += "<span class='deadsay'>It appears to be completely inactive.</span>\n"
else
msg += "<span class='deadsay'>It appears to be completely inactive.</span>\n"
msg += "*---------*</span>"
to_chat(user, msg)
/obj/item/device/mmi/posibrain/emp_act(severity)
if(!src.brainmob)
return
else
switch(severity)
if(1)
src.brainmob.emp_damage += rand(20,30)
if(2)
src.brainmob.emp_damage += rand(10,20)
if(3)
src.brainmob.emp_damage += rand(0,10)
..()
/obj/item/device/mmi/posibrain/New()
src.brainmob = new(src)
src.brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]"
src.brainmob.real_name = src.brainmob.name
src.brainmob.loc = src
src.brainmob.container = src
src.brainmob.stat = 0
src.brainmob.SetSilence(0)
dead_mob_list -= src.brainmob
..()
/obj/item/device/mmi/posibrain/attack_ghost(var/mob/dead/observer/O)
if(searching)
volunteer(O)
return
if(brainmob && brainmob.key)
return // No point pinging a posibrain with a player already inside
if(check_observer(O) && (world.time >= next_ping_at))
next_ping_at = world.time + (20 SECONDS)
playsound(get_turf(src), 'sound/items/posiping.ogg', 80, 0)
var/turf/T = get_turf_or_move(src.loc)
for(var/mob/M in viewers(T))
M.show_message("<span class='notice'>The positronic brain pings softly.</span>")
/obj/item/device/mmi/posibrain/ipc
desc = "A cube of shining metal, four inches to a side and covered in shallow grooves. The speaker switch is set to 'off'."
silenced = 1
@@ -0,0 +1,231 @@
/obj/item/mmi/robotic_brain
name = "robotic brain"
desc = "An advanced circuit, capable of housing a non-sentient synthetic intelligence."
icon = 'icons/obj/module.dmi'
icon_state = "boris_blank"
var/blank_icon = "boris_blank"
var/searching_icon = "boris_recharging"
var/occupied_icon = "boris"
w_class = WEIGHT_CLASS_NORMAL
origin_tech = "biotech=3;programming=3;plasmatech=2"
var/searching = FALSE
var/askDelay = 10 * 60 * 1
//var/mob/living/carbon/brain/brainmob = null
var/list/ghost_volunteers[0]
req_access = list(access_robotics)
mecha = null//This does not appear to be used outside of reference in mecha.dm.
var/silenced = FALSE //if TRUE, they can't talk.
var/next_ping_at = 0
var/requires_master = TRUE
var/mob/living/carbon/human/imprinted_master = null
var/ejected_flavor_text = "circuit"
/obj/item/mmi/robotic_brain/Destroy()
imprinted_master = null
return ..()
/obj/item/mmi/robotic_brain/attack_self(mob/user)
if(requires_master && !imprinted_master)
to_chat(user, "<span class='notice'>You press your thumb on [src] and imprint your user information.</span>")
imprinted_master = user
return
if(brainmob && !brainmob.key && !searching)
//Start the process of searching for a new user.
to_chat(user, "<span class='notice'>You carefully locate the manual activation switch and start [src]'s boot process.</span>")
icon_state = searching_icon
ghost_volunteers.Cut()
searching = TRUE
request_player()
spawn(600)
if(ghost_volunteers.len)
var/mob/dead/observer/O
while(!istype(O) && ghost_volunteers.len)
O = pick_n_take(ghost_volunteers)
if(istype(O) && check_observer(O))
transfer_personality(O)
reset_search()
else
silenced = !silenced
to_chat(user, "<span class='notice'>You toggle the speaker [silenced ? "off" : "on"].</span>")
if(brainmob && brainmob.key)
to_chat(brainmob, "<span class='warning'>Your internal speaker has been toggled [silenced ? "off" : "on"].</span>")
/obj/item/mmi/robotic_brain/proc/request_player()
for(var/mob/dead/observer/O in player_list)
if(check_observer(O))
to_chat(O, "<span class='boldnotice'>\A [src] has been activated. (<a href='?src=[O.UID()];jump=\ref[src]'>Teleport</a> | <a href='?src=[UID()];signup=\ref[O]'>Sign Up</a>)</span>")
/obj/item/mmi/robotic_brain/proc/check_observer(mob/dead/observer/O)
if(cannotPossess(O))
return FALSE
if(jobban_isbanned(O, "Cyborg") || jobban_isbanned(O,"nonhumandept"))
return FALSE
if(!O.can_reenter_corpse)
return FALSE
if(O.client)
return TRUE
return FALSE
/obj/item/mmi/robotic_brain/proc/question(client/C)
spawn(0)
if(!C)
return
var/response = alert(C, "Someone is requesting a personality for a [src]. Would you like to play as one?", "[src] request", "Yes", "No", "Never for this round")
if(!C || brainmob.key || !searching)
return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located.
if(response == "Yes")
transfer_personality(C.mob)
else if(response == "Never for this round")
C.prefs.be_special -= ROLE_POSIBRAIN
// This should not ever happen, but let's be safe
/obj/item/mmi/robotic_brain/dropbrain(turf/dropspot)
log_runtime(EXCEPTION("[src] at [loc] attempted to drop brain without a contained brain."), src)
/obj/item/mmi/robotic_brain/transfer_identity(mob/living/carbon/H)
name = "[src] ([H])"
if(isnull(brainmob.dna))
brainmob.dna = H.dna.Clone()
brainmob.name = brainmob.dna.real_name
brainmob.real_name = brainmob.name
brainmob.timeofhostdeath = H.timeofdeath
brainmob.stat = CONSCIOUS
if(brainmob.mind)
brainmob.mind.assigned_role = "Positronic Brain"
if(H.mind)
H.mind.transfer_to(brainmob)
to_chat(brainmob, "<span class='notice'>You feel slightly disoriented. That's normal when you're just a [ejected_flavor_text].</span>")
become_occupied(occupied_icon)
if(radio)
radio_action.ApplyIcon()
/obj/item/mmi/robotic_brain/attempt_become_organ(obj/item/organ/external/parent, mob/living/carbon/human/H)
if(..())
if(imprinted_master)
to_chat(H, "<span class='biggerdanger'>You are permanently imprinted to [imprinted_master], obey [imprinted_master]'s every order and assist [imprinted_master.p_them()] in completing [imprinted_master.p_their()] goals at any cost.</span>")
/obj/item/mmi/robotic_brain/proc/transfer_personality(mob/candidate)
searching = FALSE
brainmob.key = candidate.key
name = "[src] ([brainmob.name])"
to_chat(brainmob, "<b>You are a [src], brought into existence on [station_name()].</b>")
to_chat(brainmob, "<b>As a non-sentient synthetic intelligence, you answer to [imprinted_master], unless otherwise placed inside of a lawed synthetic structure or mech.</b>")
to_chat(brainmob, "<b>Remember, the purpose of your existence is to serve [imprinted_master]'s every word, unless lawed or placed into a mech in the future.</b>")
brainmob.mind.assigned_role = "Positronic Brain"
visible_message("<span class='notice'>[src] chimes quietly.</span>")
become_occupied(occupied_icon)
/obj/item/mmi/robotic_brain/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer.
if(brainmob && brainmob.key)
return
searching = FALSE
icon_state = blank_icon
visible_message("<span class='notice'>[src] buzzes quietly as the light fades out. Perhaps you could try again?</span>")
/obj/item/mmi/robotic_brain/Topic(href, href_list)
if("signup" in href_list)
var/mob/dead/observer/O = locate(href_list["signup"])
if(!O)
return
volunteer(O)
/obj/item/mmi/robotic_brain/proc/volunteer(mob/dead/observer/O)
if(!searching)
to_chat(O, "Not looking for a ghost, yet.")
return
if(!istype(O))
to_chat(O, "<span class='warning'>Error.</span>")
return
if(O in ghost_volunteers)
to_chat(O, "<span class='notice'>Removed from registration list.</span>")
ghost_volunteers.Remove(O)
return
if(!check_observer(O))
to_chat(O, "<span class='warning'>You cannot be \a [src].</span>")
return
if(cannotPossess(O))
to_chat(O, "<span class='warning'>Upon using the antagHUD you forfeited the ability to join the round.</span>")
return
if(jobban_isbanned(O, "Cyborg") || jobban_isbanned(O,"nonhumandept"))
to_chat(O, "<span class='warning'>You are job banned from this role.</span>")
return
to_chat(O., "<span class='notice'>You've been added to the list of ghosts that may become this [src]. Click again to unvolunteer.</span>")
ghost_volunteers.Add(O)
/obj/item/mmi/robotic_brain/examine(mob/user)
to_chat(user, "Its speaker is turned [silenced ? "off" : "on"].")
to_chat(user, "<span class='info'>*---------*</span>")
. = ..()
if(!.)
to_chat(user, "<span class='info'>*---------*</span>")
return
var/list/msg = list("<span class='info'>")
if(brainmob && brainmob.key)
switch(brainmob.stat)
if(CONSCIOUS)
if(!brainmob.client)
msg += "It appears to be in stand-by mode.\n" //afk
if(UNCONSCIOUS)
msg += "<span class='warning'>It doesn't seem to be responsive.</span>\n"
if(DEAD)
msg += "<span class='deadsay'>It appears to be completely inactive.</span>\n"
else
msg += "<span class='deadsay'>It appears to be completely inactive.</span>\n"
msg += "*---------*</span>"
to_chat(user, msg.Join(""))
/obj/item/mmi/robotic_brain/emp_act(severity)
if(!brainmob)
return
switch(severity)
if(1)
brainmob.emp_damage += rand(20, 30)
if(2)
brainmob.emp_damage += rand(10, 20)
if(3)
brainmob.emp_damage += rand(0, 10)
..()
/obj/item/mmi/robotic_brain/New()
brainmob = new(src)
brainmob.name = "[pick(list("PBU", "HIU", "SINA", "ARMA", "OSI"))]-[rand(100, 999)]"
brainmob.real_name = brainmob.name
brainmob.forceMove(src)
brainmob.container = src
brainmob.stat = CONSCIOUS
brainmob.SetSilence(0)
dead_mob_list -= brainmob
..()
/obj/item/mmi/robotic_brain/attack_ghost(mob/dead/observer/O)
if(searching)
volunteer(O)
return
if(brainmob && brainmob.key)
return // No point pinging a posibrain with a player already inside
if(check_observer(O) && (world.time >= next_ping_at))
next_ping_at = world.time + (20 SECONDS)
playsound(get_turf(src), 'sound/items/posiping.ogg', 80, 0)
visible_message("<span class='notice'>[src] pings softly.</span>")
/obj/item/mmi/robotic_brain/positronic
name = "positronic brain"
icon = 'icons/obj/assemblies.dmi'
icon_state = "posibrain"
blank_icon = "posibrain"
searching_icon = "posibrain-searching"
occupied_icon = "posibrain-occupied"
desc = "A cube of shining metal, four inches to a side and covered in shallow grooves."
silenced = TRUE
requires_master = FALSE
ejected_flavor_text = "metal cube"
+12 -14
View File
@@ -2,7 +2,7 @@
/mob/living/carbon/brain/say(var/message, var/datum/language/speaking = null)
if(!can_speak(warning = TRUE))
return
if(prob(emp_damage * 4))
if(prob(10)) //10% chance to drop the message entirely
return
@@ -10,21 +10,21 @@
message = Gibberish(message, (emp_damage*6))//scrambles the message, gets worse when emp_damage is higher
..(message)
/mob/living/carbon/brain/whisper(message as text)
if(!can_speak(warning = TRUE))
return
..()
/mob/living/carbon/brain/can_speak(var/warning = FALSE)
. = ..()
if(!istype(container, /obj/item/device/mmi))
if(!istype(container, /obj/item/mmi))
. = FALSE
else if(istype(container, /obj/item/device/mmi/posibrain))
var/obj/item/device/mmi/posibrain/P = container
if(P && P.silenced)
else if(istype(container, /obj/item/mmi/robotic_brain))
var/obj/item/mmi/robotic_brain/R = container
if(R && R.silenced)
if(warning)
to_chat(usr, "<span class='warning'>You cannot speak, as your internal speaker is turned off.</span>")
. = FALSE
@@ -34,19 +34,17 @@
if("headset")
var/radio_worked = 0 // If any of the radios our brainmob could use functioned, this is set true so that we don't use any others
// I'm doing it this way so that if the mecha radio fails for some reason, a radio MMI still has the built-in fallback
if(container && istype(container,/obj/item/device/mmi))
var/obj/item/device/mmi/c = container
if(container && istype(container,/obj/item/mmi))
var/obj/item/mmi/c = container
if(!radio_worked && c.mecha)
var/obj/mecha/metalgear = c.mecha
if(metalgear.radio)
radio_worked = metalgear.radio.talk_into(src, message, message_mode, verb, speaking)
else if(!radio_worked && istype(c, /obj/item/device/mmi/radio_enabled))
var/obj/item/device/mmi/radio_enabled/R = c
if(R.radio)
radio_worked = R.radio.talk_into(src, message, message_mode, verb, speaking)
else if(!radio_worked && c.radio)
radio_worked = c.radio.talk_into(src, message, message_mode, verb, speaking)
return radio_worked
if("whisper")
whisper_say(message, speaking, alt_name)
return 1
else return 0
else return 0
+46 -47
View File
@@ -1,8 +1,12 @@
/mob/living
var/canEnterVentWith = "/obj/item/weapon/implant=0&/obj/item/clothing/mask/facehugger=0&/obj/item/device/radio/borg=0&/obj/machinery/camera=0"
var/canEnterVentWith = "/obj/item/implant=0&/obj/item/clothing/mask/facehugger=0&/obj/item/radio/borg=0&/obj/machinery/camera=0"
var/datum/middleClickOverride/middleClickOverride = null
/mob/living/carbon/Destroy()
// This clause is here due to items falling off from limb deletion
for(var/obj/item in get_all_slots())
unEquip(item)
qdel(item)
QDEL_LIST(internal_organs)
QDEL_LIST(stomach_contents)
var/mob/living/simple_animal/borer/B = has_brain_worms()
@@ -170,7 +174,7 @@
/mob/living/carbon/swap_hand()
var/obj/item/item_in_hand = src.get_active_hand()
if(item_in_hand) //this segment checks if the item in your hand is twohanded.
if(istype(item_in_hand,/obj/item/weapon/twohanded))
if(istype(item_in_hand,/obj/item/twohanded))
if(item_in_hand:wielded == 1)
to_chat(usr, "<span class='warning'>Your other hand is too busy holding the [item_in_hand.name]</span>")
return
@@ -197,11 +201,12 @@
swap_hand()
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/M)
if(src.health >= config.health_threshold_crit)
if(src == M && istype(src, /mob/living/carbon/human))
add_attack_logs(M, src, "Shaked", ATKLOG_ALL)
if(health >= config.health_threshold_crit)
if(src == M && ishuman(src))
var/mob/living/carbon/human/H = src
src.visible_message( \
text("<span class='notice'>[src] examines [].</span>",src.gender==MALE?"himself":"herself"), \
visible_message( \
text("<span class='notice'>[src] examines [].</span>",gender==MALE?"himself":"herself"), \
"<span class='notice'>You check yourself for injuries.</span>" \
)
@@ -251,28 +256,24 @@
H.play_xylophone()
else
if(player_logged)
M.visible_message("<span class='notice'>[M] shakes [src], but they do not respond. Probably suffering from SSD.", \
"<span class='notice'>You shake [src], but they are unresponsive. Probably suffering from SSD.</span>")
M.visible_message("<span class='notice'>[M] shakes [src], but [p_they()] [p_do()] not respond. Probably suffering from SSD.", \
"<span class='notice'>You shake [src], but [p_theyre()] unresponsive. Probably suffering from SSD.</span>")
if(lying) // /vg/: For hugs. This is how update_icon figgers it out, anyway. - N3X15
var/t_him = "it"
if(src.gender == MALE)
t_him = "him"
else if(src.gender == FEMALE)
t_him = "her"
if(istype(src,/mob/living/carbon/human) && src:w_uniform)
if(ishuman(src))
var/mob/living/carbon/human/H = src
H.w_uniform.add_fingerprint(M)
if(H.w_uniform)
H.w_uniform.add_fingerprint(M)
AdjustSleeping(-5)
if(src.sleeping == 0)
src.resting = 0
if(sleeping == 0)
resting = 0
AdjustParalysis(-3)
AdjustStunned(-3)
AdjustWeakened(-3)
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
if(!player_logged)
M.visible_message( \
"<span class='notice'>[M] shakes [src] trying to wake [t_him] up!</span>",\
"<span class='notice'>You shake [src] trying to wake [t_him] up!</span>",\
"<span class='notice'>[M] shakes [src] trying to wake [p_them()] up!</span>",\
"<span class='notice'>You shake [src] trying to wake [p_them()] up!</span>",\
)
// BEGIN HUGCODE - N3X
else
@@ -288,7 +289,7 @@
"<span class='notice'>[M] gives [src] a [pick("hug","warm embrace")].</span>",\
"<span class='notice'>You hug [src].</span>",\
)
if(istype(src,/mob/living/carbon/human))
if(ishuman(src))
var/mob/living/carbon/human/H = src
if(H.wear_suit)
H.wear_suit.add_fingerprint(M)
@@ -341,7 +342,7 @@
AdjustEyeBlurry(damage * rand(3, 6))
if(E.damage > (E.min_bruised_damage + E.min_broken_damage) / 2)
if(!(E.status & ORGAN_ROBOT))
if(!E.is_robotic())
to_chat(src, "<span class='warning'>Your eyes start to burn badly!</span>")
else //snowflake conditions piss me off for the record
to_chat(src, "<span class='warning'>The flash blinds you!</span>")
@@ -381,7 +382,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
if(!ventcrawler)
if(ishuman(src))
var/mob/living/carbon/human/H = src
ventcrawlerlocal = H.species.ventcrawler
ventcrawlerlocal = H.dna.species.ventcrawler
if(!ventcrawlerlocal) return
@@ -436,7 +437,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
if(iscarbon(src) && contents.len && ventcrawlerlocal < 2)//It must have atleast been 1 to get this far
for(var/obj/item/I in contents)
var/failed = 0
if(istype(I, /obj/item/weapon/implant))
if(istype(I, /obj/item/implant))
continue
if(istype(I, /obj/item/organ))
continue
@@ -547,8 +548,8 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
throw_mode_off()
var/atom/movable/thrown_thing
if(istype(I, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = I
if(istype(I, /obj/item/grab))
var/obj/item/grab/G = I
var/mob/throwable_mob = G.get_mob_if_throwable() //throw the person instead of the grab
qdel(G) //We delete the grab.
if(throwable_mob)
@@ -560,7 +561,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
var/start_T_descriptor = "<font color='#6b5d00'>tile at [start_T.x], [start_T.y], [start_T.z] in area [get_area(start_T)]</font>"
var/end_T_descriptor = "<font color='#6b4400'>tile at [end_T.x], [end_T.y], [end_T.z] in area [get_area(end_T)]</font>"
add_logs(src, throwable_mob, "thrown", addition="from [start_T_descriptor] with the target [end_T_descriptor]")
add_attack_logs(src, throwable_mob, "Thrown from [start_T_descriptor] with the target [end_T_descriptor]")
else if(!(I.flags & ABSTRACT)) //can't throw abstract items
thrown_thing = I
@@ -615,7 +616,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
<tr><td>&nbsp;</td></tr>"}
dat += "<tr><td><B>Back:</B></td><td><A href='?src=[UID()];item=[slot_back]'>[(back && !(back.flags&ABSTRACT)) ? back : "<font color=grey>Empty</font>"]</A>"
if(istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/weapon/tank))
if(istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/tank))
dat += "&nbsp;<A href='?src=[UID()];internal=[slot_back]'>[internal ? "Disable Internals" : "Set Internals"]</A>"
dat += "</td></tr><tr><td>&nbsp;</td></tr>"
@@ -651,7 +652,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
if(href_list["internal"])
var/slot = text2num(href_list["internal"])
var/obj/item/ITEM = get_item_by_slot(slot)
if(ITEM && istype(ITEM, /obj/item/weapon/tank))
if(ITEM && istype(ITEM, /obj/item/tank))
visible_message("<span class='danger'>[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM].</span>", \
"<span class='userdanger'>[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM].</span>")
@@ -739,7 +740,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
if(restrained())
changeNext_move(CLICK_CD_BREAKOUT)
last_special = world.time + CLICK_CD_BREAKOUT
visible_message("<span class='warning'>[src] attempts to unbuckle themself!</span>", \
visible_message("<span class='warning'>[src] attempts to unbuckle [p_them()]self!</span>", \
"<span class='notice'>You attempt to unbuckle yourself... (This will take around one minute and you need to stay still.)</span>")
if(do_after(src, 600, 0, target = src))
if(!buckled)
@@ -756,11 +757,11 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
Weaken(3, 1, 1) //We dont check for CANWEAKEN, I don't care how immune to weakening you are, if you're rolling on the ground, you're busy.
update_canmove()
spin(32,2)
visible_message("<span class='danger'>[src] rolls on the floor, trying to put themselves out!</span>", \
visible_message("<span class='danger'>[src] rolls on the floor, trying to put [p_them()]self out!</span>", \
"<span class='notice'>You stop, drop, and roll!</span>")
sleep(30)
if(fire_stacks <= 0)
visible_message("<span class='danger'>[src] has successfully extinguished themselves!</span>", \
visible_message("<span class='danger'>[src] has successfully extinguished [p_them()]self!</span>", \
"<span class='notice'>You extinguish yourself.</span>")
ExtinguishMob()
@@ -859,8 +860,8 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
if(handcuffed)
//we don't want problems with nodrop shit if there ever is more than one nodrop twohanded
var/obj/item/I = get_active_hand()
if(istype(I, /obj/item/weapon/twohanded))
var/obj/item/weapon/twohanded/TH = I //FML
if(istype(I, /obj/item/twohanded))
var/obj/item/twohanded/TH = I //FML
if(TH.wielded)
TH.unwield()
drop_r_hand()
@@ -904,7 +905,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
/mob/living/carbon/proc/uncuff()
if(handcuffed)
var/obj/item/weapon/W = handcuffed
var/obj/item/W = handcuffed
handcuffed = null
if(buckled && buckled.buckle_requires_restraints)
buckled.unbuckle_mob()
@@ -918,7 +919,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
W.layer = initial(W.layer)
W.plane = initial(W.plane)
if(legcuffed)
var/obj/item/weapon/W = legcuffed
var/obj/item/W = legcuffed
legcuffed = null
update_inv_legcuffed()
if(client)
@@ -955,15 +956,15 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
/mob/living/carbon/proc/can_eat(flags = 255)
return 1
/mob/living/carbon/proc/eat(var/obj/item/weapon/reagent_containers/food/toEat, mob/user, var/bitesize_override)
/mob/living/carbon/proc/eat(var/obj/item/reagent_containers/food/toEat, mob/user, var/bitesize_override)
if(!istype(toEat))
return 0
var/fullness = nutrition + 10
if(istype(toEat, /obj/item/weapon/reagent_containers/food/snacks))
if(istype(toEat, /obj/item/reagent_containers/food/snacks))
for(var/datum/reagent/consumable/C in reagents.reagent_list) //we add the nutrition value of what we're currently digesting
fullness += C.nutriment_factor * C.volume / (C.metabolization_rate * metabolism_efficiency * digestion_ratio)
if(user == src)
if(istype(toEat, /obj/item/weapon/reagent_containers/food/drinks))
if(istype(toEat, /obj/item/reagent_containers/food/drinks))
if(!selfDrink(toEat))
return 0
else
@@ -976,7 +977,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
score_foodeaten++
return 1
/mob/living/carbon/proc/selfFeed(var/obj/item/weapon/reagent_containers/food/toEat, fullness)
/mob/living/carbon/proc/selfFeed(var/obj/item/reagent_containers/food/toEat, fullness)
if(ispill(toEat))
to_chat(src, "<span class='notify'>You [toEat.apply_method] [toEat].</span>")
else
@@ -996,10 +997,10 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
return 0
return 1
/mob/living/carbon/proc/selfDrink(var/obj/item/weapon/reagent_containers/food/drinks/toDrink, mob/user)
/mob/living/carbon/proc/selfDrink(var/obj/item/reagent_containers/food/drinks/toDrink, mob/user)
return 1
/mob/living/carbon/proc/forceFed(var/obj/item/weapon/reagent_containers/food/toEat, mob/user, fullness)
/mob/living/carbon/proc/forceFed(var/obj/item/reagent_containers/food/toEat, mob/user, fullness)
if(ispill(toEat) || fullness <= (600 * (1 + overeatduration / 1000)))
if(!toEat.instant_application)
visible_message("<span class='warning'>[user] attempts to force [src] to [toEat.apply_method] [toEat].</span>")
@@ -1013,10 +1014,8 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
visible_message("<span class='warning'>[user] forces [src] to [toEat.apply_method] [toEat].</span>")
return 1
/mob/living/carbon/proc/forceFedAttackLog(var/obj/item/weapon/reagent_containers/food/toEat, mob/user)
create_attack_log("<font color='orange'>Has been fed [toEat.name] by [user.name] ([user.ckey]) Reagents: [toEat.reagentlist(toEat)]</font>")
user.create_attack_log("<font color='red'>Fed [toEat.name] to [name] ([ckey]) Reagents: [toEat.reagentlist(toEat)]</font>")
log_attack("[user.name] ([user.ckey]) fed [name] ([ckey]) with [toEat.name] Reagents: [toEat.reagentlist(toEat)] (INTENT: [uppertext(user.a_intent)])")
/mob/living/carbon/proc/forceFedAttackLog(var/obj/item/reagent_containers/food/toEat, mob/user)
add_attack_logs(user, src, "Fed [toEat]. Reagents: [toEat.reagentlist(toEat)]", ATKLOG_FEW)
if(!iscarbon(user))
LAssailant = null
else
@@ -1025,7 +1024,7 @@ var/list/ventcrawl_machinery = list(/obj/machinery/atmospherics/unary/vent_pump,
/*TO DO - If/when stomach organs are introduced, override this at the human level sending the item to the stomach
so that different stomachs can handle things in different ways VB*/
/mob/living/carbon/proc/consume(var/obj/item/weapon/reagent_containers/food/toEat, var/bitesize_override, var/taste = TRUE)
/mob/living/carbon/proc/consume(var/obj/item/reagent_containers/food/toEat, var/bitesize_override, var/taste = TRUE)
var/this_bite = bitesize_override ? bitesize_override : toEat.bitesize
if(!toEat.reagents)
return
@@ -18,13 +18,12 @@
/mob/living/carbon/attackby(obj/item/I, mob/user, params)
if(lying)
if(surgeries.len)
if(user != src && user.a_intent == INTENT_HELP)
for(var/datum/surgery/S in surgeries)
if(S.next_step(user, src))
return 1
..()
if(lying && surgeries.len)
if(user != src && user.a_intent == INTENT_HELP)
for(var/datum/surgery/S in surgeries)
if(S.next_step(user, src))
return 1
return ..()
/mob/living/carbon/attack_hand(mob/living/carbon/human/user)
if(!iscarbon(user))
@@ -39,8 +38,26 @@
var/datum/disease/D = thing
if(D.IsSpreadByTouch())
ContractDisease(D)
if(lying && surgeries.len)
if(user.a_intent == INTENT_HELP)
for(var/datum/surgery/S in surgeries)
if(S.next_step(user, src))
return 1
return 0
/mob/living/carbon/attack_slime(mob/living/carbon/slime/M)
if(..())
var/power = M.powerlevel + rand(0,3)
Weaken(power)
Stuttering(power)
Stun(power)
var/stunprob = M.powerlevel * 7 + 10
if(prob(stunprob) && M.powerlevel >= 8)
adjustFireLoss(M.powerlevel * rand(6,10))
updatehealth()
return 1
/mob/living/carbon/is_mouth_covered(head_only = FALSE, mask_only = FALSE)
if((!mask_only && head && (head.flags_cover & HEADCOVERSMOUTH)) || (!head_only && wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH)))
return TRUE
@@ -3,20 +3,9 @@
AC.flags = flags
AC.ui_interact(user, state = state)
/mob/living/carbon/human/proc/change_species(var/new_species)
if(!new_species || species == new_species || !(new_species in all_species))
return
set_species(new_species, null, 1)
reset_hair()
if(species.bodyflags & HAS_MARKINGS)
reset_markings()
return 1
/mob/living/carbon/human/proc/change_gender(var/new_gender, var/update_dna = 1)
var/obj/item/organ/external/head/H = bodyparts_by_name["head"]
if(gender == new_gender || (gender == PLURAL && species.has_gender))
if(gender == new_gender || (gender == PLURAL && dna.species.has_gender))
return
gender = new_gender
@@ -129,7 +118,7 @@
/mob/living/carbon/human/proc/change_alt_head(var/alternate_head)
var/obj/item/organ/external/head/H = get_organ("head")
if(!H || H.alt_head == alternate_head || (H.status & ORGAN_ROBOT) || (!(species.bodyflags & HAS_ALT_HEADS) && alternate_head != "None") || !(alternate_head in alt_heads_list))
if(!H || H.alt_head == alternate_head || H.is_robotic() || (!(dna.species.bodyflags & HAS_ALT_HEADS) && alternate_head != "None") || !(alternate_head in alt_heads_list))
return
H.alt_head = alternate_head
@@ -296,7 +285,7 @@
/mob/living/carbon/human/proc/change_skin_color(var/colour = "#000000")
if(colour == skin_colour || !(species.bodyflags & HAS_SKIN_COLOR))
if(colour == skin_colour || !(dna.species.bodyflags & HAS_SKIN_COLOR))
return
skin_colour = colour
@@ -306,7 +295,7 @@
return 1
/mob/living/carbon/human/proc/change_skin_tone(var/tone)
if(s_tone == tone || !((species.bodyflags & HAS_SKIN_TONE) || (species.bodyflags & HAS_ICON_SKIN_TONE)))
if(s_tone == tone || !((dna.species.bodyflags & HAS_SKIN_TONE) || (dna.species.bodyflags & HAS_ICON_SKIN_TONE)))
return
s_tone = tone
@@ -321,8 +310,8 @@
/mob/living/carbon/human/proc/generate_valid_species(var/check_whitelist = 1, var/list/whitelist = list(), var/list/blacklist = list())
var/list/valid_species = new()
for(var/current_species_name in all_species)
var/datum/species/current_species = all_species[current_species_name]
for(var/current_species_name in GLOB.all_species)
var/datum/species/current_species = GLOB.all_species[current_species_name]
if(check_whitelist && config.usealienwhitelist && !check_rights(R_ADMIN, 0, src)) //If we're using the whitelist, make sure to check it!
if(whitelist.len && !(current_species_name in whitelist))
@@ -350,16 +339,16 @@
continue
if((H.gender == MALE && S.gender == FEMALE) || (H.gender == FEMALE && S.gender == MALE))
continue
if(H.species.bodyflags & ALL_RPARTS) //If the user is a species who can have a robotic head...
if(H.dna.species.bodyflags & ALL_RPARTS) //If the user is a species who can have a robotic head...
var/datum/robolimb/robohead = all_robolimbs[H.model]
if((H.species.name in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list.
if((H.dna.species.name in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list.
valid_hairstyles += hairstyle //Give them their hairstyles if they do.
else
if(!robohead.is_monitor && ("Human" in S.species_allowed)) /*If the hairstyle is not native to the user's species and they're using a head with an ipc-style screen, don't let them access it.
But if the user has a robotic humanoid head and the hairstyle can fit humans, let them use it as a wig. */
valid_hairstyles += hairstyle
else //If the user is not a species who can have robotic heads, use the default handling.
if(H.species.name in S.species_allowed) //If the user's head is of a species the hairstyle allows, add it to the list.
if(H.dna.species.name in S.species_allowed) //If the user's head is of a species the hairstyle allows, add it to the list.
valid_hairstyles += hairstyle
return valid_hairstyles
@@ -378,17 +367,17 @@
continue
if((H.gender == MALE && S.gender == FEMALE) || (H.gender == FEMALE && S.gender == MALE))
continue
if(H.species.bodyflags & ALL_RPARTS) //If the user is a species who can have a robotic head...
if(H.dna.species.bodyflags & ALL_RPARTS) //If the user is a species who can have a robotic head...
var/datum/robolimb/robohead = all_robolimbs[H.model]
if(H.species.name in S.species_allowed) //If this is a facial hair style native to the user's species...
if((H.species.name in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a facial hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list.
if(H.dna.species.name in S.species_allowed) //If this is a facial hair style native to the user's species...
if((H.dna.species.name in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a facial hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list.
valid_facial_hairstyles += facialhairstyle //Give them their facial hairstyles if they do.
else
if(!robohead.is_monitor && ("Human" in S.species_allowed)) /*If the facial hairstyle is not native to the user's species and they're using a head with an ipc-style screen, don't let them access it.
But if the user has a robotic humanoid head and the facial hairstyle can fit humans, let them use it as a wig. */
valid_facial_hairstyles += facialhairstyle
else //If the user is not a species who can have robotic heads, use the default handling.
if(H.species.name in S.species_allowed) //If the user's head is of a species the facial hair style allows, add it to the list.
if(H.dna.species.name in S.species_allowed) //If the user's head is of a species the facial hair style allows, add it to the list.
valid_facial_hairstyles += facialhairstyle
return valid_facial_hairstyles
@@ -402,7 +391,7 @@
for(var/head_accessory in head_accessory_styles_list)
var/datum/sprite_accessory/S = head_accessory_styles_list[head_accessory]
if(!(H.species.name in S.species_allowed)) //If the user's head is not of a species the head accessory style allows, skip it. Otherwise, add it to the list.
if(!(H.dna.species.name in S.species_allowed)) //If the user's head is not of a species the head accessory style allows, skip it. Otherwise, add it to the list.
continue
valid_head_accessories += head_accessory
@@ -421,7 +410,7 @@
continue
if(S.marking_location != location) //If the marking isn't for the location we desire, skip.
continue
if(!(species.name in S.species_allowed)) //If the user is not of a species the marking style allows, skip it. Otherwise, add it to the list.
if(!(dna.species.name in S.species_allowed)) //If the user is not of a species the marking style allows, skip it. Otherwise, add it to the list.
continue
if(location == "tail")
if(!body_accessory)
@@ -432,7 +421,7 @@
continue
if(location == "head")
var/datum/sprite_accessory/body_markings/head/M = marking_styles_list[S.name]
if(H.species.bodyflags & ALL_RPARTS)//If the user is a species that can have a robotic head...
if(H.dna.species.bodyflags & ALL_RPARTS) //If the user is a species that can have a robotic head...
var/datum/robolimb/robohead = all_robolimbs[H.model]
if(!(S.models_allowed && (robohead.company in S.models_allowed))) //Make sure they don't get markings incompatible with their head.
continue
@@ -456,7 +445,7 @@
if(!istype(A))
valid_body_accessories["None"] = "None" //The only null entry should be the "None" option.
continue
if(species.name in A.allowed_species) //If the user is not of a species the body accessory style allows, skip it. Otherwise, add it to the list.
if(dna.species.name in A.allowed_species) //If the user is not of a species the body accessory style allows, skip it. Otherwise, add it to the list.
valid_body_accessories += B
return valid_body_accessories
@@ -469,7 +458,7 @@
valid_alt_heads["None"] = alt_heads_list["None"] //The only null entry should be the "None" option, and there should always be a "None" option.
for(var/alternate_head in alt_heads_list)
var/datum/sprite_accessory/alt_heads/head = alt_heads_list[alternate_head]
if(!(H.species.name in head.species_allowed))
if(!(H.dna.species.name in head.species_allowed))
continue
valid_alt_heads += alternate_head
+12 -10
View File
@@ -62,7 +62,7 @@
animation.master = src
flick("dust-h", animation)
new species.remains_type(get_turf(src))
new dna.species.remains_type(get_turf(src))
spawn(15)
if(animation) qdel(animation)
@@ -103,15 +103,15 @@
set_heartattack(FALSE)
//Handle species-specific deaths.
if(species)
species.handle_death(src)
if(dna.species)
dna.species.handle_death(src)
callHook("death", list(src, gibbed))
if(ishuman(LAssailant))
var/mob/living/carbon/human/H=LAssailant
if(H.mind)
H.mind.kills += "[name] ([ckey])"
H.mind.kills += "[key_name(src)]"
if(!gibbed)
update_canmove()
@@ -119,9 +119,9 @@
timeofdeath = world.time
med_hud_set_health()
med_hud_set_status()
if(mind) mind.store_memory("Time of death: [worldtime2text(timeofdeath)]", 0)
if(mind) mind.store_memory("Time of death: [station_time_timestamp("hh:mm:ss", timeofdeath)]", 0)
if(ticker && ticker.mode)
// log_to_dd("k")
// log_world("k")
sql_report_death(src)
ticker.mode.check_win() //Calls the rounds wincheck, mainly for wizard, malf, and changeling now
@@ -139,9 +139,11 @@
/mob/living/carbon/human/proc/makeSkeleton()
var/obj/item/organ/external/head/H = get_organ("head")
if(SKELETON in src.mutations) return
if(SKELETON in src.mutations)
return
if(istype(H))
H.disfigured = TRUE
if(H.f_style)
H.f_style = initial(H.f_style)
if(H.h_style)
@@ -159,16 +161,17 @@
mutations.Add(SKELETON)
mutations.Add(NOCLONE)
status_flags |= DISFIGURED
update_body(0)
update_mutantrace()
return
/mob/living/carbon/human/proc/ChangeToHusk()
var/obj/item/organ/external/head/H = bodyparts_by_name["head"]
if(HUSK in mutations) return
if(HUSK in mutations)
return
if(istype(H))
H.disfigured = TRUE //makes them unknown without fucking up other stuff like admintools
if(H.f_style)
H.f_style = "Shaved" //we only change the icon_state of the hair datum, so it doesn't mess up their UI/UE
if(H.h_style)
@@ -177,7 +180,6 @@
update_hair(0)
mutations.Add(HUSK)
status_flags |= DISFIGURED //makes them unknown without fucking up other stuff like admintools
update_body(0)
update_mutantrace()
return
+108 -74
View File
@@ -14,7 +14,7 @@
muzzled = 1
//var/m_type = 1
for(var/obj/item/weapon/implant/I in src)
for(var/obj/item/implant/I in src)
if(I.implanted)
I.trigger(act, src)
@@ -29,34 +29,42 @@
switch(act)
//Cooldown-inducing emotes
if("ping", "pings", "buzz", "buzzes", "beep", "beeps", "yes", "no", "buzz2")
if(species.name == "Machine") //Only Machines can beep, ping, and buzz, yes, no, and make a silly sad trombone noise.
var/found_machine_head = FALSE
if(ismachine(src)) //Only Machines can beep, ping, and buzz, yes, no, and make a silly sad trombone noise.
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
else //Everyone else fails, skip the emote attempt
return
found_machine_head = TRUE
else
var/obj/item/organ/external/head/H = get_organ("head") // If you have a robotic head, you can make beep-boop noises
if(H && H.is_robotic())
on_CD = handle_emote_CD()
found_machine_head = TRUE
if(!found_machine_head) //Everyone else fails, skip the emote attempt
return //Everyone else fails, skip the emote attempt
if("drone","drones","hum","hums","rumble","rumbles")
if(get_species() == "Drask") //Only Drask can make whale noises
if(isdrask(src)) //Only Drask can make whale noises
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm
else
return
if("howl", "howls")
if(get_species() == "Vulpkanin") //Only Vulpkanin can howl
if(isvulpkanin(src)) //Only Vulpkanin can howl
on_CD = handle_emote_CD(100)
else
return
if("growl", "growls")
if(get_species() == "Vulpkanin") //Only Vulpkanin can growl
if(isvulpkanin(src)) //Only Vulpkanin can growl
on_CD = handle_emote_CD()
else
return
if("squish", "squishes")
var/found_slime_bodypart = 0
if(get_species() == "Slime People") //Only Slime People can squish
if(isslimeperson(src)) //Only Slime People can squish
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm'
found_slime_bodypart = 1
else
for(var/obj/item/organ/external/L in bodyparts) // if your limbs are squishy you can squish too!
if(L.dna.species in list("Slime People"))
if(istype(L.dna.species, /datum/species/slime))
on_CD = handle_emote_CD()
found_slime_bodypart = 1
break
@@ -65,31 +73,31 @@
return
if("clack", "clacks")
if(get_species() == "Kidan") //Only Kidan can clack and rightfully so.
if(iskidan(src)) //Only Kidan can clack and rightfully so.
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm'
else //Everyone else fails, skip the emote attempt
return
if("click", "clicks")
if(get_species() == "Kidan") //Only Kidan can click and rightfully so.
if(iskidan(src)) //Only Kidan can click and rightfully so.
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm'
else //Everyone else fails, skip the emote attempt
return
if("creaks", "creak")
if(get_species() == "Diona") //Only Dionas can Creaks.
if(isdiona(src)) //Only Dionas can Creaks.
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm'
else //Everyone else fails, skip the emote attempt
return
if("hiss", "hisses")
if(get_species() == "Unathi") //Only Unathi can hiss.
if(isunathi(src)) //Only Unathi can hiss.
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm'
else //Everyone else fails, skip the emote attempt
return
if("quill", "quills")
if(get_species() == "Vox") //Only Vox can rustle their quills.
if(isvox(src)) //Only Vox can rustle their quills.
on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm'
else //Everyone else fails, skip the emote attempt
return
@@ -102,6 +110,8 @@
on_CD = handle_emote_CD()
if("sneeze", "sneezes")
on_CD = handle_emote_CD()
if("clap", "claps")
on_CD = handle_emote_CD()
//Everything else, including typos of the above emotes
else
on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown
@@ -171,14 +181,14 @@
if("clack", "clacks")
var/M = handle_emote_param(param)
message = "<B>[src]</B> clacks their mandibles[M ? " at [M]" : ""]."
message = "<B>[src]</B> clacks [p_their()] mandibles[M ? " at [M]" : ""]."
playsound(loc, 'sound/effects/Kidanclack.ogg', 50, 0) //Credit to DrMinky (freesound.org) for the sound.
m_type = 2
if("click", "clicks")
var/M = handle_emote_param(param)
message = "<B>[src]</B> clicks their mandibles[M ? " at [M]" : ""]."
message = "<B>[src]</B> clicks [p_their()] mandibles[M ? " at [M]" : ""]."
playsound(loc, 'sound/effects/Kidanclack2.ogg', 50, 0) //Credit to DrMinky (freesound.org) for the sound.
m_type = 2
@@ -199,7 +209,7 @@
if("quill", "quills")
var/M = handle_emote_param(param)
message = "<B>[src]</B> rustles their quills[M ? " at [M]" : ""]."
message = "<B>[src]</B> rustles [p_their()] quills[M ? " at [M]" : ""]."
playsound(loc, 'sound/effects/voxrustle.ogg', 50, 0) //Credit to sound-ideas (freesfx.co.uk) for the sound.
m_type = 2
@@ -220,12 +230,12 @@
if("wag", "wags")
if(body_accessory)
if(body_accessory.try_restrictions(src))
message = "<B>[src]</B> starts wagging \his tail."
message = "<B>[src]</B> starts wagging [p_their()] tail."
start_tail_wagging(1)
else if(species.bodyflags & TAIL_WAGGING)
else if(dna.species.bodyflags & TAIL_WAGGING)
if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space))
message = "<B>[src]</B> starts wagging \his tail."
message = "<B>[src]</B> starts wagging [p_their()] tail."
start_tail_wagging(1)
else
return
@@ -234,8 +244,8 @@
m_type = 1
if("swag", "swags")
if(species.bodyflags & TAIL_WAGGING || body_accessory)
message = "<B>[src]</B> stops wagging \his tail."
if(dna.species.bodyflags & TAIL_WAGGING || body_accessory)
message = "<B>[src]</B> stops wagging [p_their()] tail."
stop_tail_wagging(1)
else
return
@@ -280,7 +290,7 @@
if("choke", "chokes")
if(miming)
message = "<B>[src]</B> clutches \his throat desperately!"
message = "<B>[src]</B> clutches [p_their()] throat desperately!"
m_type = 1
else
if(!muzzled)
@@ -292,7 +302,7 @@
if("burp", "burps")
if(miming)
message = "<B>[src]</B> opens their mouth rather obnoxiously."
message = "<B>[src]</B> opens [p_their()] mouth rather obnoxiously."
m_type = 1
else
if(!muzzled)
@@ -302,14 +312,33 @@
message = "<B>[src]</B> makes a peculiar noise."
m_type = 2
if("clap", "claps")
if(!restrained())
message = "<B>[src]</B> claps."
if(miming)
message = "<B>[src]</B> claps silently."
m_type = 1
else
m_type = 2
if(miming)
m_type = 1
var/obj/item/organ/external/L = get_organ("l_hand")
var/obj/item/organ/external/R = get_organ("r_hand")
var/left_hand_good = FALSE
var/right_hand_good = FALSE
if(L && (!(L.status & ORGAN_SPLINTED)) && (!(L.status & ORGAN_BROKEN)))
left_hand_good = TRUE
if(R && (!(R.status & ORGAN_SPLINTED)) && (!(R.status & ORGAN_BROKEN)))
right_hand_good = TRUE
if(left_hand_good && right_hand_good)
message = "<b>[src]</b> claps."
var/clap = pick('sound/misc/clap1.ogg', 'sound/misc/clap2.ogg', 'sound/misc/clap3.ogg', 'sound/misc/clap4.ogg')
playsound(loc, clap, 50, 1, -1)
else
to_chat(usr, "You need your hands working in order to clap.")
if("flap", "flaps")
if(!restrained())
message = "<B>[src]</B> flaps \his wings."
message = "<B>[src]</B> flaps [p_their()] wings."
m_type = 2
if(miming)
m_type = 1
@@ -336,8 +365,8 @@
if(lying || weakened)
message = "<B>[src]</B> flops and flails around on the floor."
else
var/obj/item/weapon/grab/G
if(istype(get_active_hand(), /obj/item/weapon/grab))
var/obj/item/grab/G
if(istype(get_active_hand(), /obj/item/grab))
G = get_active_hand()
if(G && G.affecting)
if(buckled || G.affecting.buckled)
@@ -361,7 +390,7 @@
if("aflap", "aflaps")
if(!restrained())
message = "<B>[src]</B> flaps \his wings ANGRILY!"
message = "<B>[src]</B> flaps [p_their()] wings ANGRILY!"
m_type = 2
if(miming)
m_type = 1
@@ -410,11 +439,11 @@
message = "<B>[src]</B> coughs!"
m_type = 2
if(gender == FEMALE)
if(species.female_cough_sounds)
playsound(src, pick(species.female_cough_sounds), 120)
if(dna.species.female_cough_sounds)
playsound(src, pick(dna.species.female_cough_sounds), 120)
else
if(species.male_cough_sounds)
playsound(src, pick(species.male_cough_sounds), 120)
if(dna.species.male_cough_sounds)
playsound(src, pick(dna.species.male_cough_sounds), 120)
else
message = "<B>[src]</B> makes a strong noise."
m_type = 2
@@ -458,7 +487,7 @@
m_type = 2
if("deathgasp", "deathgasps")
message = "<B>[src]</B> [species.death_message]"
message = "<B>[src]</B> [replacetext(dna.species.death_message, "their", p_their())]"
m_type = 1
if("giggle", "giggles")
@@ -506,7 +535,7 @@
message = "<B>[src]</B> cries."
m_type = 2
else
message = "<B>[src]</B> makes a weak noise. \He frowns."
message = "<B>[src]</B> makes a weak noise. [p_they(TRUE)] frown[p_s()]."
m_type = 2
if("sigh", "sighs")
@@ -584,7 +613,7 @@
message = "<B>[src]</B> takes a drag from a cigarette and blows \"[M]\" out in smoke."
m_type = 1
else
message = "<B>[src]</B> says, \"[M], please. They had a family.\" [name] takes a drag from a cigarette and blows their name out in smoke."
message = "<B>[src]</B> says, \"[M], please. They had a family.\" [name] takes a drag from a cigarette and blows [p_their()] name out in smoke."
m_type = 2
if("point", "points")
@@ -610,7 +639,7 @@
if("shake", "shakes")
var/M = handle_emote_param(param, 1) //Check to see if the param is valid (mob with the param name is in view) but exclude ourselves.
message = "<B>[src]</B> shakes \his head[M ? " at [M]" : ""]."
message = "<B>[src]</B> shakes [p_their()] head[M ? " at [M]" : ""]."
m_type = 1
if("shrug", "shrugs")
@@ -655,9 +684,9 @@
if(!muzzled)
message = "<B>[src]</B> sneezes."
if(gender == FEMALE)
playsound(src, species.female_sneeze_sound, 70)
playsound(src, dna.species.female_sneeze_sound, 70)
else
playsound(src, species.male_sneeze_sound, 70)
playsound(src, dna.species.male_sneeze_sound, 70)
m_type = 2
else
message = "<B>[src]</B> makes a strange noise."
@@ -721,7 +750,7 @@
if(M)
message = "<B>[src]</B> hugs [M]."
else
message = "<B>[src]</B> hugs \himself."
message = "<B>[src]</B> hugs [p_them()]self."
if("handshake")
m_type = 1
@@ -732,7 +761,7 @@
if(M.canmove && !M.r_hand && !M.restrained())
message = "<B>[src]</B> shakes hands with [M]."
else
message = "<B>[src]</B> holds out \his hand to [M]."
message = "<B>[src]</B> holds out [p_their()] hand to [M]."
if("dap", "daps")
m_type = 1
@@ -742,7 +771,7 @@
if(M)
message = "<B>[src]</B> gives daps to [M]."
else
message = "<B>[src]</B> sadly can't find anybody to give daps to, and daps \himself. Shameful."
message = "<B>[src]</B> sadly can't find anybody to give daps to, and daps [p_them()]self. Shameful."
if("slap", "slaps")
m_type = 1
@@ -752,7 +781,7 @@
if(M)
message = "<span class='danger'>[src] slaps [M] across the face. Ouch!</span>"
else
message = "<span class='danger'>[src] slaps \himself!</span>"
message = "<span class='danger'>[src] slaps [p_them()]self!</span>"
adjustFireLoss(4)
playsound(loc, 'sound/effects/snap.ogg', 50, 1)
@@ -763,12 +792,12 @@
m_type = 1
else
if(!muzzled)
message = "<B>[src]</B> [species.scream_verb][M ? " at [M]" : ""]!"
message = "<B>[src]</B> [dna.species.scream_verb][M ? " at [M]" : ""]!"
m_type = 2
if(gender == FEMALE)
playsound(loc, "[species.female_scream_sound]", 80, 1, frequency = get_age_pitch())
playsound(loc, "[dna.species.female_scream_sound]", 80, 1, frequency = get_age_pitch())
else
playsound(loc, "[species.male_scream_sound]", 80, 1, frequency = get_age_pitch()) //default to male screams if no gender is present.
playsound(loc, "[dna.species.male_scream_sound]", 80, 1, frequency = get_age_pitch()) //default to male screams if no gender is present.
else
message = "<B>[src]</B> makes a very loud noise[M ? " at [M]" : ""]."
@@ -793,10 +822,10 @@
var/M = handle_emote_param(param)
message = "<b>[src]</b> snaps \his fingers[M ? " at [M]" : ""]."
message = "<b>[src]</b> snaps [p_their()] fingers[M ? " at [M]" : ""]."
playsound(loc, 'sound/effects/fingersnap.ogg', 50, 1, -3)
else
message = "<span class='danger'><b>[src]</b> snaps \his fingers right off!</span>"
message = "<span class='danger'><b>[src]</b> snaps [p_their()] fingers right off!</span>"
playsound(loc, 'sound/effects/snap.ogg', 50, 1)
// Needed for M_TOXIC_FART
@@ -804,35 +833,35 @@
if(reagents.has_reagent("simethicone"))
return
// playsound(loc, 'sound/effects/fart.ogg', 50, 1, -3) //Admins still vote no to fun
if(locate(/obj/item/weapon/storage/bible) in get_turf(src))
to_chat(viewers(src), "<span class='warning'><b>[src] farts on the Bible!</b></span>")
var/image/cross = image('icons/obj/storage.dmi',"bible")
var/adminbfmessage = "\blue [bicon(cross)] <b><font color=red>Bible Fart: </font>[key_name(src, 1)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=[UID()]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) ([admin_jump_link(src)]) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;Smite=[UID()]'>SMITE</A>):</b>"
if(locate(/obj/item/storage/bible) in get_turf(src))
to_chat(viewers(src), "<span class='danger'>[src] farts on the Bible!</span>")
var/image/cross = image('icons/obj/storage.dmi', "bible")
var/adminbfmessage = "[bicon(cross)] <span class='danger'>Bible Fart:</span> [key_name(src, 1)] (<A HREF='?_src_=holder;adminmoreinfo=[UID()]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[UID()]'>PP</A>) (<A HREF='?_src_=vars;Vars=[UID()]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[UID()]'>SM</A>) ([admin_jump_link(src)]) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;Smite=[UID()]'>SMITE</A>):</b>"
for(var/client/X in admins)
if(check_rights(R_EVENT,0,X.mob))
if(check_rights(R_EVENT, 0, X.mob))
to_chat(X, adminbfmessage)
else if(TOXIC_FARTS in mutations)
message = "<b>[src]</b> unleashes a [pick("horrible","terrible","foul","disgusting","awful")] fart."
message = "<b>[src]</b> unleashes a [pick("horrible", "terrible", "foul", "disgusting", "awful")] fart."
else if(SUPER_FART in mutations)
message = "<b>[src]</b> unleashes a [pick("loud","deafening")] fart."
newtonian_move(dir)
message = "<b>[src]</b> unleashes a [pick("loud", "deafening")] fart."
else
message = "<b>[src]</b> [pick("passes wind","farts")]."
message = "<b>[src]</b> [pick("passes wind", "farts")]."
m_type = 2
var/turf/location = get_turf(src)
var/aoe_range=2 // Default
// Process toxic farts first.
if(TOXIC_FARTS in mutations)
for(var/mob/M in range(location,aoe_range))
if(M.internal != null && M.wear_mask && (M.wear_mask.flags & AIRTIGHT))
for(var/mob/living/carbon/C in range(location, 2))
if(C.internal != null && C.wear_mask && (C.wear_mask.flags & AIRTIGHT))
continue
// Now, we don't have this:
//new /obj/effects/fart_cloud(T,L)
if(M == src)
if(C == src)
continue
M.reagents.add_reagent("jenkem", 1)
C.reagents.add_reagent("jenkem", 1)
// Farting as a form of locomotion in space
if(SUPER_FART in mutations)
newtonian_move(dir)
if("hem")
message = "<b>[src]</b> hems."
@@ -869,9 +898,7 @@
+ " shiver(s), shrug(s), sigh(s), signal(s)-#1-10,slap(s)-(none)/mob, smile(s),snap(s), sneeze(s), sniff(s), snore(s), stare(s)-(none)/mob, swag(s), tremble(s), twitch(es), twitch(es)_s," \
+ " wag(s), wave(s), whimper(s), wink(s), yawn(s), quill(s)"
switch(species.name)
if("Machine")
emotelist += "\nMachine specific emotes :- beep(s)-(none)/mob, buzz(es)-none/mob, no-(none)/mob, ping(s)-(none)/mob, yes-(none)/mob, buzz2-(none)/mob"
switch(dna.species.name)
if("Drask")
emotelist += "\nDrask specific emotes :- drone(s)-(none)/mob, hum(s)-(none)/mob, rumble(s)-(none)/mob"
if("Kidan")
@@ -885,11 +912,18 @@
if("Diona")
emotelist += "\nDiona specific emotes :- creak(s)"
if (species.name == "Slime People")
if(ismachine(src))
emotelist += "\nMachine specific emotes :- beep(s)-(none)/mob, buzz(es)-none/mob, no-(none)/mob, ping(s)-(none)/mob, yes-(none)/mob, buzz2-(none)/mob"
else
var/obj/item/organ/external/head/H = get_organ("head") // If you have a robotic head, you can make beep-boop noises
if(H && H.is_robotic())
emotelist += "\nRobotic head specific emotes :- beep(s)-(none)/mob, buzz(es)-none/mob, no-(none)/mob, ping(s)-(none)/mob, yes-(none)/mob, buzz2-(none)/mob"
if(isslimeperson(src))
emotelist += "\nSlime people specific emotes :- squish(es)-(none)/mob"
else
for(var/obj/item/organ/external/L in bodyparts) // if your limbs are squishy you can squish too!
if(L.dna.species in list("Slime People"))
if(istype(L.dna.species, /datum/species/slime))
emotelist += "\nSlime people body part specific emotes :- squish(es)-(none)/mob"
break
@@ -898,7 +932,7 @@
to_chat(src, "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>")
if(message) //Humans are special fucking snowflakes and have 800 lines of emotes, they get to handle their own emotes, not call the parent.
log_emote("[name]/[key] : [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.
@@ -920,7 +954,7 @@
set desc = "Sets a description which will be shown when someone examines you."
set category = "IC"
pose = sanitize(copytext(input(usr, "This is [src]. \He is...", "Pose", null) as text, 1, MAX_MESSAGE_LEN))
pose = sanitize(copytext(input(usr, "This is [src]. [p_they(TRUE)] [p_are()]...", "Pose", null) as text, 1, MAX_MESSAGE_LEN))
/mob/living/carbon/human/verb/set_flavor()
set name = "Set Flavour Text"
+90 -123
View File
@@ -23,51 +23,18 @@
if(wear_mask)
skipface |= wear_mask.flags_inv & HIDEFACE
// crappy hacks because you can't do \his[src] etc. I'm sorry this proc is so unreadable, blame the text macros :<
var/t_He = "It" //capitalised for use at the start of each line.
var/t_his = "its"
var/t_him = "it"
var/t_has = "has"
var/t_is = "is"
var/msg = "<span class='info'>*---------*\nThis is "
if((skipjumpsuit && skipface)) //big suits/masks/helmets make it hard to tell their gender
t_He = "They"
t_his = "their"
t_him = "them"
t_has = "have"
t_is = "are"
else
if(icon)
msg += "[bicon(icon(icon, dir=SOUTH))] " //fucking BYOND: this should stop dreamseeker crashing if we -somehow- examine somebody before their icon is generated
switch(gender)
if(MALE)
t_He = "He"
t_his = "his"
t_him = "him"
if(FEMALE)
t_He = "She"
t_his = "her"
t_him = "her"
if(PLURAL)
t_He = "They"
t_his = "their"
t_him = "them"
t_has = "have"
t_is = "are"
if(!(skipjumpsuit && skipface) && icon) //big suits/masks/helmets make it hard to tell their gender
msg += "[bicon(icon(icon, dir=SOUTH))] " //fucking BYOND: this should stop dreamseeker crashing if we -somehow- examine somebody before their icon is generated
msg += "<EM>[name]</EM>"
var/list/nospecies = list("Abductor", "Shadowling", "Neara", "Monkey", "Stok", "Farwa", "Wolpin") //species that won't show their race no matter what
var/displayed_species = get_species()
var/displayed_species = dna.species.name
for(var/obj/item/clothing/C in src) //Disguise checks
if(C == src.head || C == src.wear_suit || C == src.wear_mask || C == src.w_uniform || C == src.belt || C == src.back)
if(C.species_disguise)
displayed_species = C.species_disguise
if(skipjumpsuit && skipface || (displayed_species in nospecies)) //either obscured or on the nospecies list
if(skipjumpsuit && skipface || (NO_EXAMINE in dna.species.species_traits)) //either obscured or on the nospecies list
msg += "!\n" //omit the species when examining
else if(displayed_species == "Slime People") //snowflakey because Slime People are defined as a plural
msg += ", a slime person!\n"
@@ -86,129 +53,129 @@
tie_msg += " with [english_accessory_list(U)]"
if(w_uniform.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing [bicon(w_uniform)] [w_uniform.gender==PLURAL?"some":"a"] [w_uniform.blood_color != "#030303" ? "blood-stained":"oil-stained"] [w_uniform.name][tie_msg]!</span>\n"
msg += "<span class='warning'>[p_they(TRUE)] [p_are()] wearing [bicon(w_uniform)] [w_uniform.gender==PLURAL?"some":"a"] [w_uniform.blood_color != "#030303" ? "blood-stained":"oil-stained"] [w_uniform.name][tie_msg]!</span>\n"
else
msg += "[t_He] [t_is] wearing [bicon(w_uniform)] \a [w_uniform][tie_msg].\n"
msg += "[p_they(TRUE)] [p_are()] wearing [bicon(w_uniform)] \a [w_uniform][tie_msg].\n"
//head
if(head && !(head.flags & ABSTRACT))
if(head.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing [bicon(head)] [head.gender==PLURAL?"some":"a"] [head.blood_color != "#030303" ? "blood-stained":"oil-stained"] [head.name] on [t_his] head!</span>\n"
msg += "<span class='warning'>[p_they(TRUE)] [p_are()] wearing [bicon(head)] [head.gender==PLURAL?"some":"a"] [head.blood_color != "#030303" ? "blood-stained":"oil-stained"] [head.name] on [p_their()] head!</span>\n"
else
msg += "[t_He] [t_is] wearing [bicon(head)] \a [head] on [t_his] head.\n"
msg += "[p_they(TRUE)] [p_are()] wearing [bicon(head)] \a [head] on [p_their()] head.\n"
//suit/armour
if(wear_suit && !(wear_suit.flags & ABSTRACT))
if(wear_suit.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing [bicon(wear_suit)] [wear_suit.gender==PLURAL?"some":"a"] [wear_suit.blood_color != "#030303" ? "blood-stained":"oil-stained"] [wear_suit.name]!</span>\n"
msg += "<span class='warning'>[p_they(TRUE)] [p_are()] wearing [bicon(wear_suit)] [wear_suit.gender==PLURAL?"some":"a"] [wear_suit.blood_color != "#030303" ? "blood-stained":"oil-stained"] [wear_suit.name]!</span>\n"
else
msg += "[t_He] [t_is] wearing [bicon(wear_suit)] \a [wear_suit].\n"
msg += "[p_they(TRUE)] [p_are()] wearing [bicon(wear_suit)] \a [wear_suit].\n"
//suit/armour storage
if(s_store && !skipsuitstorage)
if(s_store.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] carrying [bicon(s_store)] [s_store.gender==PLURAL?"some":"a"] [s_store.blood_color != "#030303" ? "blood-stained":"oil-stained"] [s_store.name] on [t_his] [wear_suit.name]!</span>\n"
msg += "<span class='warning'>[p_they(TRUE)] [p_are()] carrying [bicon(s_store)] [s_store.gender==PLURAL?"some":"a"] [s_store.blood_color != "#030303" ? "blood-stained":"oil-stained"] [s_store.name] on [p_their()] [wear_suit.name]!</span>\n"
else
msg += "[t_He] [t_is] carrying [bicon(s_store)] \a [s_store] on [t_his] [wear_suit.name].\n"
msg += "[p_they(TRUE)] [p_are()] carrying [bicon(s_store)] \a [s_store] on [p_their()] [wear_suit.name].\n"
//back
if(back && !(back.flags & ABSTRACT))
if(back.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] [bicon(back)] [back.gender==PLURAL?"some":"a"] [back.blood_color != "#030303" ? "blood-stained":"oil-stained"] [back] on [t_his] back.</span>\n"
msg += "<span class='warning'>[p_they(TRUE)] [p_have()] [bicon(back)] [back.gender==PLURAL?"some":"a"] [back.blood_color != "#030303" ? "blood-stained":"oil-stained"] [back] on [p_their()] back.</span>\n"
else
msg += "[t_He] [t_has] [bicon(back)] \a [back] on [t_his] back.\n"
msg += "[p_they(TRUE)] [p_have()] [bicon(back)] \a [back] on [p_their()] back.\n"
//left hand
if(l_hand && !(l_hand.flags & ABSTRACT))
if(l_hand.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] holding [bicon(l_hand)] [l_hand.gender==PLURAL?"some":"a"] [l_hand.blood_color != "#030303" ? "blood-stained":"oil-stained"] [l_hand.name] in [t_his] left hand!</span>\n"
msg += "<span class='warning'>[p_they(TRUE)] [p_are()] holding [bicon(l_hand)] [l_hand.gender==PLURAL?"some":"a"] [l_hand.blood_color != "#030303" ? "blood-stained":"oil-stained"] [l_hand.name] in [p_their()] left hand!</span>\n"
else
msg += "[t_He] [t_is] holding [bicon(l_hand)] \a [l_hand] in [t_his] left hand.\n"
msg += "[p_they(TRUE)] [p_are()] holding [bicon(l_hand)] \a [l_hand] in [p_their()] left hand.\n"
//right hand
if(r_hand && !(r_hand.flags & ABSTRACT))
if(r_hand.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] holding [bicon(r_hand)] [r_hand.gender==PLURAL?"some":"a"] [r_hand.blood_color != "#030303" ? "blood-stained":"oil-stained"] [r_hand.name] in [t_his] right hand!</span>\n"
msg += "<span class='warning'>[p_they(TRUE)] [p_are()] holding [bicon(r_hand)] [r_hand.gender==PLURAL?"some":"a"] [r_hand.blood_color != "#030303" ? "blood-stained":"oil-stained"] [r_hand.name] in [p_their()] right hand!</span>\n"
else
msg += "[t_He] [t_is] holding [bicon(r_hand)] \a [r_hand] in [t_his] right hand.\n"
msg += "[p_they(TRUE)] [p_are()] holding [bicon(r_hand)] \a [r_hand] in [p_their()] right hand.\n"
//gloves
if(gloves && !skipgloves && !(gloves.flags & ABSTRACT))
if(gloves.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] [bicon(gloves)] [gloves.gender==PLURAL?"some":"a"] [gloves.blood_color != "#030303" ? "blood-stained":"oil-stained"] [gloves.name] on [t_his] hands!</span>\n"
msg += "<span class='warning'>[p_they(TRUE)] [p_have()] [bicon(gloves)] [gloves.gender==PLURAL?"some":"a"] [gloves.blood_color != "#030303" ? "blood-stained":"oil-stained"] [gloves.name] on [p_their()] hands!</span>\n"
else
msg += "[t_He] [t_has] [bicon(gloves)] \a [gloves] on [t_his] hands.\n"
msg += "[p_they(TRUE)] [p_have()] [bicon(gloves)] \a [gloves] on [p_their()] hands.\n"
else if(blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] [hand_blood_color != "#030303" ? "blood-stained":"oil-stained"] hands!</span>\n"
msg += "<span class='warning'>[p_they(TRUE)] [p_have()] [hand_blood_color != "#030303" ? "blood-stained":"oil-stained"] hands!</span>\n"
//handcuffed?
if(handcuffed)
if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/cable/zipties))
msg += "<span class='warning'>[t_He] [t_is] [bicon(handcuffed)] restrained with zipties!</span>\n"
else if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/cable))
msg += "<span class='warning'>[t_He] [t_is] [bicon(handcuffed)] restrained with cable!</span>\n"
if(istype(handcuffed, /obj/item/restraints/handcuffs/cable/zipties))
msg += "<span class='warning'>[p_they(TRUE)] [p_are()] [bicon(handcuffed)] restrained with zipties!</span>\n"
else if(istype(handcuffed, /obj/item/restraints/handcuffs/cable))
msg += "<span class='warning'>[p_they(TRUE)] [p_are()] [bicon(handcuffed)] restrained with cable!</span>\n"
else
msg += "<span class='warning'>[t_He] [t_is] [bicon(handcuffed)] handcuffed!</span>\n"
msg += "<span class='warning'>[p_they(TRUE)] [p_are()] [bicon(handcuffed)] handcuffed!</span>\n"
//belt
if(belt)
if(belt.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] [bicon(belt)] [belt.gender==PLURAL?"some":"a"] [belt.blood_color != "#030303" ? "blood-stained":"oil-stained"] [belt.name] about [t_his] waist!</span>\n"
msg += "<span class='warning'>[p_they(TRUE)] [p_have()] [bicon(belt)] [belt.gender==PLURAL?"some":"a"] [belt.blood_color != "#030303" ? "blood-stained":"oil-stained"] [belt.name] about [p_their()] waist!</span>\n"
else
msg += "[t_He] [t_has] [bicon(belt)] \a [belt] about [t_his] waist.\n"
msg += "[p_they(TRUE)] [p_have()] [bicon(belt)] \a [belt] about [p_their()] waist.\n"
//shoes
if(shoes && !skipshoes && !(shoes.flags & ABSTRACT))
if(shoes.blood_DNA)
msg += "<span class='warning'>[t_He] [t_is] wearing [bicon(shoes)] [shoes.gender==PLURAL?"some":"a"] [shoes.blood_color != "#030303" ? "blood-stained":"oil-stained"] [shoes.name] on [t_his] feet!</span>\n"
msg += "<span class='warning'>[p_they(TRUE)] [p_are()] wearing [bicon(shoes)] [shoes.gender==PLURAL?"some":"a"] [shoes.blood_color != "#030303" ? "blood-stained":"oil-stained"] [shoes.name] on [p_their()] feet!</span>\n"
else
msg += "[t_He] [t_is] wearing [bicon(shoes)] \a [shoes] on [t_his] feet.\n"
msg += "[p_they(TRUE)] [p_are()] wearing [bicon(shoes)] \a [shoes] on [p_their()] feet.\n"
else if(blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] [feet_blood_color != "#030303" ? "blood-stained":"oil-stained"] feet!</span>\n"
msg += "<span class='warning'>[p_they(TRUE)] [p_have()] [feet_blood_color != "#030303" ? "blood-stained":"oil-stained"] feet!</span>\n"
//mask
if(wear_mask && !skipmask && !(wear_mask.flags & ABSTRACT))
if(wear_mask.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] [bicon(wear_mask)] [wear_mask.gender==PLURAL?"some":"a"] [wear_mask.blood_color != "#030303" ? "blood-stained":"oil-stained"] [wear_mask.name] on [t_his] face!</span>\n"
msg += "<span class='warning'>[p_they(TRUE)] [p_have()] [bicon(wear_mask)] [wear_mask.gender==PLURAL?"some":"a"] [wear_mask.blood_color != "#030303" ? "blood-stained":"oil-stained"] [wear_mask.name] on [p_their()] face!</span>\n"
else
msg += "[t_He] [t_has] [bicon(wear_mask)] \a [wear_mask] on [t_his] face.\n"
msg += "[p_they(TRUE)] [p_have()] [bicon(wear_mask)] \a [wear_mask] on [p_their()] face.\n"
//eyes
if(glasses && !skipeyes && !(glasses.flags & ABSTRACT))
if(glasses.blood_DNA)
msg += "<span class='warning'>[t_He] [t_has] [bicon(glasses)] [glasses.gender==PLURAL?"some":"a"] [glasses.blood_color != "#030303" ? "blood-stained":"oil-stained"] [glasses] covering [t_his] eyes!</span>\n"
msg += "<span class='warning'>[p_they(TRUE)] [p_have()] [bicon(glasses)] [glasses.gender==PLURAL?"some":"a"] [glasses.blood_color != "#030303" ? "blood-stained":"oil-stained"] [glasses] covering [p_their()] eyes!</span>\n"
else
msg += "[t_He] [t_has] [bicon(glasses)] \a [glasses] covering [t_his] eyes.\n"
msg += "[p_they(TRUE)] [p_have()] [bicon(glasses)] \a [glasses] covering [p_their()] eyes.\n"
//left ear
if(l_ear && !skipears)
msg += "[t_He] [t_has] [bicon(l_ear)] \a [l_ear] on [t_his] left ear.\n"
msg += "[p_they(TRUE)] [p_have()] [bicon(l_ear)] \a [l_ear] on [p_their()] left ear.\n"
//right ear
if(r_ear && !skipears)
msg += "[t_He] [t_has] [bicon(r_ear)] \a [r_ear] on [t_his] right ear.\n"
msg += "[p_they(TRUE)] [p_have()] [bicon(r_ear)] \a [r_ear] on [p_their()] right ear.\n"
//ID
if(wear_id)
msg += "[t_He] [t_is] wearing [bicon(wear_id)] \a [wear_id].\n"
msg += "[p_they(TRUE)] [p_are()] wearing [bicon(wear_id)] \a [wear_id].\n"
//Jitters
switch(jitteriness)
if(300 to INFINITY)
msg += "<span class='warning'><B>[t_He] [t_is] convulsing violently!</B></span>\n"
msg += "<span class='warning'><B>[p_they(TRUE)] [p_are()] convulsing violently!</B></span>\n"
if(200 to 300)
msg += "<span class='warning'>[t_He] [t_is] extremely jittery.</span>\n"
msg += "<span class='warning'>[p_they(TRUE)] [p_are()] extremely jittery.</span>\n"
if(100 to 200)
msg += "<span class='warning'>[t_He] [t_is] twitching ever so slightly.</span>\n"
msg += "<span class='warning'>[p_they(TRUE)] [p_are()] twitching ever so slightly.</span>\n"
var/appears_dead = FALSE
if(stat == DEAD || (status_flags & FAKEDEATH))
appears_dead = TRUE
if(suiciding)
msg += "<span class='warning'>[t_He] appears to have committed suicide... there is no hope of recovery.</span>\n"
msg += "<span class='deadsay'>[t_He] [t_is] limp and unresponsive; there are no signs of life"
msg += "<span class='warning'>[p_they(TRUE)] appear[p_s()] to have committed suicide... there is no hope of recovery.</span>\n"
msg += "<span class='deadsay'>[p_they(TRUE)] [p_are()] limp and unresponsive; there are no signs of life"
if(get_int_organ(/obj/item/organ/internal/brain))
if(!key)
var/foundghost = FALSE
@@ -220,35 +187,35 @@
foundghost = FALSE
break
if(!foundghost)
msg += " and [t_his] soul has departed"
msg += " and [p_their()] soul has departed"
msg += "...</span>\n"
if(!get_int_organ(/obj/item/organ/internal/brain))
msg += "<span class='deadsay'>It appears that [t_his] brain is missing...</span>\n"
msg += "<span class='deadsay'>It appears that [p_their()] brain is missing...</span>\n"
msg += "<span class='warning'>"
var/list/wound_flavor_text = list()
var/list/is_destroyed = list()
for(var/organ_tag in species.has_limbs)
for(var/organ_tag in dna.species.has_limbs)
var/list/organ_data = species.has_limbs[organ_tag]
var/list/organ_data = dna.species.has_limbs[organ_tag]
var/organ_descriptor = organ_data["descriptor"]
is_destroyed["[organ_data["descriptor"]]"] = 1
var/obj/item/organ/external/E = bodyparts_by_name[organ_tag]
if(!E)
wound_flavor_text["[organ_tag]"] = "<B>[t_He] [t_is] missing [t_his] [organ_descriptor].</B>\n"
wound_flavor_text["[organ_tag]"] = "<B>[p_they(TRUE)] [p_are()] missing [p_their()] [organ_descriptor].</B>\n"
else
if(!isSynthetic())
if(E.status & ORGAN_ROBOT)
wound_flavor_text["[E.limb_name]"] = "[t_He] [t_has] a robotic [E.name]!\n"
if(E.is_robotic())
wound_flavor_text["[E.limb_name]"] = "[p_they(TRUE)] [p_have()] a robotic [E.name]!\n"
else if(E.status & ORGAN_SPLINTED)
wound_flavor_text["[E.limb_name]"] = "[t_He] [t_has] a splint on [t_his] [E.name]!\n"
wound_flavor_text["[E.limb_name]"] = "[p_they(TRUE)] [p_have()] a splint on [p_their()] [E.name]!\n"
for(var/obj/item/I in E.embedded_objects)
msg += "<B>[t_He] [t_has] \a [bicon(I)] [I] embedded in [t_his] [E.name]!</B>\n"
msg += "<B>[p_they(TRUE)] [p_have()] \a [bicon(I)] [I] embedded in [p_their()] [E.name]!</B>\n"
//Handles the text strings being added to the actual description.
//If they have something that covers the limb, and it is not missing, put flavortext. If it is covered but bleeding, add other flavortext.
@@ -280,108 +247,108 @@
if(temp)
var/brute_message = !isSynthetic() ? "bruising" : "denting"
if(temp < 30)
msg += "[t_He] [t_has] minor [brute_message ].\n"
msg += "[p_they(TRUE)] [p_have()] minor [brute_message ].\n"
else
msg += "<B>[t_He] [t_has] severe [brute_message ]!</B>\n"
msg += "<B>[p_they(TRUE)] [p_have()] severe [brute_message ]!</B>\n"
temp = getFireLoss()
if(temp)
if(temp < 30)
msg += "[t_He] [t_has] minor burns.\n"
msg += "[p_they(TRUE)] [p_have()] minor burns.\n"
else
msg += "<B>[t_He] [t_has] severe burns!</B>\n"
msg += "<B>[p_they(TRUE)] [p_have()] severe burns!</B>\n"
temp = getCloneLoss()
if(temp)
if(temp < 30)
msg += "[t_He] [t_has] minor cellular damage.\n"
msg += "[p_they(TRUE)] [p_have()] minor cellular damage.\n"
else
msg += "<B>[t_He] [t_has] severe cellular damage.</B>\n"
msg += "<B>[p_they(TRUE)] [p_have()] severe cellular damage.</B>\n"
if(fire_stacks > 0)
msg += "[t_He] [t_is] covered in something flammable.\n"
msg += "[p_they(TRUE)] [p_are()] covered in something flammable.\n"
if(fire_stacks < 0)
msg += "[t_He] looks a little soaked.\n"
msg += "[p_they(TRUE)] looks a little soaked.\n"
switch(wetlevel)
if(1)
msg += "[t_He] looks a bit damp.\n"
msg += "[p_they(TRUE)] looks a bit damp.\n"
if(2)
msg += "[t_He] looks a little bit wet.\n"
msg += "[p_they(TRUE)] looks a little bit wet.\n"
if(3)
msg += "[t_He] looks wet.\n"
msg += "[p_they(TRUE)] looks wet.\n"
if(4)
msg += "[t_He] looks very wet.\n"
msg += "[p_they(TRUE)] looks very wet.\n"
if(5)
msg += "[t_He] looks absolutely soaked.\n"
msg += "[p_they(TRUE)] looks absolutely soaked.\n"
if(nutrition < NUTRITION_LEVEL_STARVING - 50)
msg += "[t_He] [t_is] severely malnourished.\n"
msg += "[p_they(TRUE)] [p_are()] severely malnourished.\n"
else if(nutrition >= NUTRITION_LEVEL_FAT)
if(user.nutrition < NUTRITION_LEVEL_STARVING - 50)
msg += "[t_He] [t_is] plump and delicious looking - Like a fat little piggy. A tasty piggy.\n"
msg += "[p_they(TRUE)] [p_are()] plump and delicious looking - Like a fat little piggy. A tasty piggy.\n"
else
msg += "[t_He] [t_is] quite chubby.\n"
msg += "[p_they(TRUE)] [p_are()] quite chubby.\n"
if(blood_volume < BLOOD_VOLUME_SAFE)
msg += "[t_He] [t_has] pale skin.\n"
msg += "[p_they(TRUE)] [p_have()] pale skin.\n"
if(bleedsuppress)
msg += "[t_He] [t_is] bandaged with something.\n"
msg += "[p_they(TRUE)] [p_are()] bandaged with something.\n"
else if(bleed_rate)
if(reagents.has_reagent("heparin"))
msg += "<B>[t_He] [t_is] bleeding uncontrollably!</B>\n"
msg += "<B>[p_they(TRUE)] [p_are()] bleeding uncontrollably!</B>\n"
else
msg += "<B>[t_He] [t_is] bleeding!</B>\n"
msg += "<B>[p_they(TRUE)] [p_are()] bleeding!</B>\n"
if(reagents.has_reagent("teslium"))
msg += "[t_He] is emitting a gentle blue glow!\n"
msg += "[p_they(TRUE)] [p_are()] emitting a gentle blue glow!\n"
msg += "</span>"
if(!appears_dead)
if(stat == UNCONSCIOUS)
msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.\n"
msg += "[p_they(TRUE)] [p_are()]n't responding to anything around [p_them()] and seems to be asleep.\n"
else if(getBrainLoss() >= 60)
msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
msg += "[p_they(TRUE)] [p_have()] a stupid expression on [p_their()] face.\n"
if(get_int_organ(/obj/item/organ/internal/brain))
if(istype(src, /mob/living/carbon/human/interactive))
var/mob/living/carbon/human/interactive/auto = src
if(auto.showexaminetext)
msg += "<span class='deadsay'>[t_He] [t_is] appears to be some sort of sick automaton, [t_his] eyes are glazed over and [t_his] mouth is slightly agape.</span>\n"
msg += "<span class='deadsay'>[p_they(TRUE)] [p_are()] appears to be some sort of sick automaton, [p_their()] eyes are glazed over and [p_their()] mouth is slightly agape.</span>\n"
if(auto.debugexamine)
var/dodebug = auto.doing2string(auto.doing)
var/interestdebug = auto.interest2string(auto.interest)
msg += "<span class='deadsay'>[t_He] [t_is] appears to be [interestdebug] and [dodebug].</span>\n"
else if(species.show_ssd)
msg += "<span class='deadsay'>[p_they(TRUE)] [p_are()] appears to be [interestdebug] and [dodebug].</span>\n"
else if(dna.species.show_ssd)
if(!key)
msg += "<span class='deadsay'>[t_He] [t_is] totally catatonic. The stresses of life in deep-space must have been too much for [t_him]. Any recovery is unlikely.</span>\n"
msg += "<span class='deadsay'>[p_they(TRUE)] [p_are()] totally catatonic. The stresses of life in deep-space must have been too much for [p_them()]. Any recovery is unlikely.</span>\n"
else if(!client)
msg += "[t_He] [t_has] suddenly fallen asleep, suffering from Space Sleep Disorder. [t_He] may wake up soon.\n"
msg += "[p_they(TRUE)] [p_have()] suddenly fallen asleep, suffering from Space Sleep Disorder. [p_they(TRUE)] may wake up soon.\n"
if(digitalcamo)
msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly inhuman manner.\n"
msg += "[p_they(TRUE)] [p_are()] moving [p_their()] body in an unnatural and blatantly inhuman manner.\n"
if(!(skipface || ( wear_mask && ( wear_mask.flags_inv & HIDEFACE || wear_mask.flags_cover & MASKCOVERSMOUTH) ) ) && is_thrall(src) && in_range(user,src))
msg += "Their features seem unnaturally tight and drawn.\n"
if(decaylevel == 1)
msg += "[t_He] [t_is] starting to smell.\n"
msg += "[p_they(TRUE)] [p_are()] starting to smell.\n"
if(decaylevel == 2)
msg += "[t_He] [t_is] bloated and smells disgusting.\n"
msg += "[p_they(TRUE)] [p_are()] bloated and smells disgusting.\n"
if(decaylevel == 3)
msg += "[t_He] [t_is] rotting and blackened, the skin sloughing off. The smell is indescribably foul.\n"
msg += "[p_they(TRUE)] [p_are()] rotting and blackened, the skin sloughing off. The smell is indescribably foul.\n"
if(decaylevel == 4)
msg += "[t_He] [t_is] mostly dessicated now, with only bones remaining of what used to be a person.\n"
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/criminal = "None"
if(wear_id)
var/obj/item/weapon/card/id/I = wear_id.GetID()
var/obj/item/card/id/I = wear_id.GetID()
if(I)
perpname = I.registered_name
else
@@ -404,10 +371,10 @@
var/medical = "None"
if(wear_id)
if(istype(wear_id,/obj/item/weapon/card/id))
if(istype(wear_id,/obj/item/card/id))
perpname = wear_id:registered_name
else if(istype(wear_id,/obj/item/device/pda))
var/obj/item/device/pda/tempPda = wear_id
else if(istype(wear_id,/obj/item/pda))
var/obj/item/pda/tempPda = wear_id
perpname = tempPda.owner
else
perpname = src.name
@@ -429,7 +396,7 @@
if(pose)
if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 )
pose = addtext(pose,".") //Makes sure all emotes end with a period.
msg += "\n[t_He] is [pose]"
msg += "\n[p_they(TRUE)] [p_are()] [pose]"
to_chat(user, msg)
File diff suppressed because it is too large Load Diff
@@ -1,50 +0,0 @@
/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
if(check_shields(0, M.name))
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>")
return 0
switch(M.a_intent)
if(INTENT_HELP)
visible_message("<span class='notice'>[M] caresses [src] with its scythe like arm.</span>")
if(INTENT_GRAB)
grabbedby(M)
if(INTENT_HARM)
M.do_attack_animation(src)
if(w_uniform)
w_uniform.add_fingerprint(M)
var/damage = rand(15, 30)
if(!damage)
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has lunged at [src]!</span>")
return 0
var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
var/armor_block = run_armor_check(affecting, "melee")
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has slashed at [src]!</span>")
apply_damage(damage, BRUTE, affecting, armor_block)
if(damage >= 25)
visible_message("<span class='danger'>[M] has wounded [src]!</span>")
apply_effect(4, WEAKEN, armor_block)
updatehealth()
if(INTENT_DISARM)
M.do_attack_animation(src)
if(prob(80))
var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
apply_effect(5, WEAKEN, run_armor_check(affecting, "melee"))
visible_message("<span class='danger'>[M] has tackled down [src]!</span>")
else
if(prob(99)) //this looks fucking stupid but it was previously 'var/randn = rand(1, 100); if(randn <= 99)'
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
drop_item()
visible_message("<span class='danger'>[M] disarmed [src]!</span>")
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has tried to disarm [src]!</span>")
@@ -1,233 +0,0 @@
/mob/living/carbon/human/attack_hand(mob/living/carbon/human/M as mob)
if(istype(loc, /turf) && istype(loc.loc, /area/start))
to_chat(M, "No attacking people at spawn, you jackass.")
return
if(frozen)
to_chat(M, "<span class='warning'>Do not touch Admin-Frozen people.</span>")
return
var/mob/living/carbon/human/H = M
if(istype(H))
var/obj/item/organ/external/temp = H.bodyparts_by_name["r_hand"]
if(H.hand)
temp = H.bodyparts_by_name["l_hand"]
if(!temp || !temp.is_usable())
to_chat(H, "<span class='warning'>You can't use your hand.</span>")
return
..()
if((M != src) && M.a_intent != INTENT_HELP && check_shields(0, M.name, attack_type = UNARMED_ATTACK))
add_logs(M, src, "attempted to touch")
visible_message("<span class='warning'>[M] attempted to touch [src]!</span>")
return 0
if(istype(M.gloves , /obj/item/clothing/gloves/boxing/hologlove))
var/damage = rand(0, 9)
if(!damage)
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to punch [src]!</span>")
return 0
var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
var/armor_block = run_armor_check(affecting, "melee")
if(HULK in M.mutations)
damage += 5
Weaken(4)
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[M] has punched [src]!</span>")
apply_damage(damage, STAMINA, affecting, armor_block)
if(damage >= 9)
visible_message("<span class='danger'>[M] has weakened [src]!</span>")
apply_effect(4, WEAKEN, armor_block)
return
var/datum/martial_art/attacker_style = M.martial_art
species.handle_attack_hand(src,M)
switch(M.a_intent)
if(INTENT_HELP)
if(attacker_style && attacker_style.help_act(H, src))//adminfu only...
return 1
if(can_operate(src))
if(health >= config.health_threshold_crit)
if(src.surgeries.len)
for(var/datum/surgery/S in src.surgeries)
if(S.next_step(M, src))
return 1
help_shake_act(M)
add_logs(M, src, "shaked")
return 1
if(health >= config.health_threshold_crit)
help_shake_act(M)
add_logs(M, src, "shaked")
return 1
if(!H.check_has_mouth())
to_chat(H, "<span class='danger'>You don't have a mouth, you cannot perform CPR!</span>")
return
if(!check_has_mouth())
to_chat(H, "<span class='danger'>They don't have a mouth, you cannot perform CPR!</span>")
return
if((M.head && (M.head.flags_cover & HEADCOVERSMOUTH)) || (M.wear_mask && (M.wear_mask.flags_cover & MASKCOVERSMOUTH) && !M.wear_mask.mask_adjusted))
to_chat(M, "<span class='warning'>Remove your mask!</span>")
return 0
if((head && (head.flags_cover & HEADCOVERSMOUTH)) || (wear_mask && (wear_mask.flags_cover & MASKCOVERSMOUTH) && !wear_mask.mask_adjusted))
to_chat(M, "<span class='warning'>Remove his mask!</span>")
return 0
M.visible_message("<span class='danger'>\The [M] is trying to perform CPR on \the [src]!</span>", \
"<span class='danger'>You try to perform CPR on \the [src]!</span>")
if(do_mob(M, src, 40))
if(health > config.health_threshold_dead && health <= config.health_threshold_crit)
var/suff = min(getOxyLoss(), 7)
adjustOxyLoss(-suff)
updatehealth()
M.visible_message("<span class='danger'>\The [M] performs CPR on \the [src]!</span>", \
"<span class='notice'>You perform CPR on \the [src].</span>")
to_chat(src, "<span class='notice'>You feel a breath of fresh air enter your lungs. It feels good.</span>")
to_chat(M, "<span class='alert'>Repeat at least every 7 seconds.")
add_logs(M, src, "CPRed")
return 1
else
to_chat(M, "<span class='danger'>You need to stay still while performing CPR!</span>")
if(INTENT_GRAB)
if(attacker_style && attacker_style.grab_act(H, src))
return 1
else
src.grabbedby(M)
return 1
if(INTENT_HARM)
//Vampire code
if(M.mind && M.mind.vampire && (M.mind in ticker.mode.vampires) && !M.mind.vampire.draining && M.zone_sel && M.zone_sel.selecting == "head" && src != M)
if((NO_BLOOD in species.species_traits) || species.exotic_blood || !blood_volume)
to_chat(M, "<span class='warning'>They have no blood!</span>")
return
if(mind && mind.vampire && (mind in ticker.mode.vampires))
to_chat(M, "<span class='warning'>Your fangs fail to pierce [name]'s cold flesh</span>")
return
if(SKELETON in mutations)
to_chat(M, "<span class='warning'>There is no blood in a skeleton!</span>")
return
if(issmall(src) && !ckey) //Monkeyized humans are okay, humanized monkeys are okay, NPC monkeys are not.
to_chat(M, "<span class='warning'>Blood from a monkey is useless!</span>")
return
//we're good to suck the blood, blaah
M.mind.vampire.handle_bloodsucking(src)
add_logs(M, src, "vampirebit")
msg_admin_attack("[key_name_admin(M)] vampirebit [key_name_admin(src)]")
return
//end vampire codes
if(attacker_style && attacker_style.harm_act(H, src))
return 1
else
var/datum/unarmed_attack/attack = M.species.unarmed
M.do_attack_animation(src)
add_logs(M, src, "[pick(attack.attack_verb)]ed")
if(!iscarbon(M))
LAssailant = null
else
LAssailant = M
var/damage = rand(M.species.punchdamagelow, M.species.punchdamagehigh)
damage += attack.damage
if(!damage)
playsound(loc, attack.miss_sound, 25, 1, -1)
visible_message("<span class='danger'>[M] tried to [pick(attack.attack_verb)] [src]!</span>")
return 0
var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
var/armor_block = run_armor_check(affecting, "melee")
if(HULK in M.mutations)
adjustBruteLoss(15)
playsound(loc, attack.attack_sound, 25, 1, -1)
visible_message("<span class='danger'>[M] [pick(attack.attack_verb)]ed [src]!</span>")
apply_damage(damage, BRUTE, affecting, armor_block, sharp = attack.sharp) //moving this back here means Armalis are going to knock you down 70% of the time, but they're pure adminbus anyway.
if((stat != DEAD) && damage >= M.species.punchstunthreshold)
visible_message("<span class='danger'>[M] has weakened [src]!</span>", \
"<span class='userdanger'>[M] has weakened [src]!</span>")
apply_effect(4, WEAKEN, armor_block)
forcesay(hit_appends)
else if(lying)
forcesay(hit_appends)
if(INTENT_DISARM)
if(attacker_style && attacker_style.disarm_act(H, src))
return 1
else
add_logs(M, src, "disarmed")
if(w_uniform)
w_uniform.add_fingerprint(M)
var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
var/randn = rand(1, 100)
if(randn <= 25)
apply_effect(2, WEAKEN, run_armor_check(affecting, "melee"))
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has pushed [src]!</span>")
M.create_attack_log("<font color='red'>Pushed [src.name] ([src.ckey])</font>")
src.create_attack_log("<font color='orange'>Has been pushed by [M.name] ([M.ckey])</font>")
if(!iscarbon(M))
LAssailant = null
else
LAssailant = M
log_attack("[M.name] ([M.ckey]) pushed [src.name] ([src.ckey])")
return
var/talked = 0 // BubbleWrap
if(randn <= 60)
//BubbleWrap: Disarming breaks a pull
if(pulling)
visible_message("<span class='danger'>[M] has broken [src]'s grip on [pulling]!</span>")
talked = 1
stop_pulling()
//BubbleWrap: Disarming also breaks a grab - this will also stop someone being choked, won't it?
if(istype(l_hand, /obj/item/weapon/grab))
var/obj/item/weapon/grab/lgrab = l_hand
if(lgrab.affecting)
visible_message("<span class='danger'>[M] has broken [src]'s grip on [lgrab.affecting]!</span>")
talked = 1
spawn(1)
qdel(lgrab)
if(istype(r_hand, /obj/item/weapon/grab))
var/obj/item/weapon/grab/rgrab = r_hand
if(rgrab.affecting)
visible_message("<span class='danger'>[M] has broken [src]'s grip on [rgrab.affecting]!</span>")
talked = 1
spawn(1)
qdel(rgrab)
//End BubbleWrap
if(!talked) //BubbleWrap
if(drop_item())
visible_message("<span class='danger'>[M] has disarmed [src]!</span>")
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
return
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] attempted to disarm [src]!</span>")
return
/mob/living/carbon/human/proc/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, inrange, params)
return
@@ -17,7 +17,7 @@
//TODO: fix husking
if(((maxHealth - total_burn) < config.health_threshold_dead) && stat == DEAD)
ChangeToHusk()
if(species.can_revive_by_healing)
if(dna.species.can_revive_by_healing)
var/obj/item/organ/internal/brain/B = get_int_organ(/obj/item/organ/internal/brain)
if(B)
if((health >= (config.health_threshold_dead + config.health_threshold_crit) * 0.5) && stat == DEAD && getBrainLoss()<120)
@@ -32,11 +32,11 @@
if(status_flags & GODMODE)
return 0 //godmode
if(species && species.has_organ["brain"])
if(dna.species && dna.species.has_organ["brain"])
var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain)
if(sponge)
if(species)
amount = amount * species.brain_mod
if(dna.species)
amount = amount * dna.species.brain_mod
sponge.receive_damage(amount, 1)
brainloss = sponge.damage
else
@@ -48,11 +48,11 @@
if(status_flags & GODMODE)
return 0 //godmode
if(species && species.has_organ["brain"])
if(dna.species && dna.species.has_organ["brain"])
var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain)
if(sponge)
if(species)
amount = amount * species.brain_mod
if(dna.species)
amount = amount * dna.species.brain_mod
sponge.damage = min(max(amount, 0), (maxHealth*2))
brainloss = sponge.damage
else
@@ -64,7 +64,7 @@
if(status_flags & GODMODE)
return 0 //godmode
if(species && species.has_organ["brain"])
if(dna.species && dna.species.has_organ["brain"])
var/obj/item/organ/internal/brain/sponge = get_int_organ(/obj/item/organ/internal/brain)
if(sponge)
brainloss = min(sponge.damage,maxHealth*2)
@@ -89,24 +89,24 @@
/mob/living/carbon/human/adjustBruteLoss(amount, damage_source)
if(species)
amount = amount * species.brute_mod
if(dna.species)
amount = amount * dna.species.brute_mod
if(amount > 0)
take_overall_damage(amount, 0, used_weapon = damage_source)
else
heal_overall_damage(-amount, 0)
/mob/living/carbon/human/adjustFireLoss(amount, damage_source)
if(species)
amount = amount * species.burn_mod
if(dna.species)
amount = amount * dna.species.burn_mod
if(amount > 0)
take_overall_damage(0, amount, used_weapon = damage_source)
else
heal_overall_damage(0, -amount)
/mob/living/carbon/human/proc/adjustBruteLossByPart(amount, organ_name, obj/damage_source = null)
if(species)
amount = amount * species.brute_mod
if(dna.species)
amount = amount * dna.species.brute_mod
if(organ_name in bodyparts_by_name)
var/obj/item/organ/external/O = get_organ(organ_name)
@@ -115,12 +115,12 @@
O.receive_damage(amount, 0, sharp=is_sharp(damage_source), used_weapon=damage_source)
else
//if you don't want to heal robot organs, they you will have to check that yourself before using this proc.
O.heal_damage(-amount, 0, internal=0, robo_repair=(O.status & ORGAN_ROBOT))
O.heal_damage(-amount, 0, internal = 0, robo_repair = O.is_robotic())
/mob/living/carbon/human/proc/adjustFireLossByPart(amount, organ_name, obj/damage_source = null)
if(species)
amount = amount * species.burn_mod
if(dna.species)
amount = amount * dna.species.burn_mod
if(organ_name in bodyparts_by_name)
var/obj/item/organ/external/O = get_organ(organ_name)
@@ -129,7 +129,7 @@
O.receive_damage(0, amount, sharp=is_sharp(damage_source), used_weapon=damage_source)
else
//if you don't want to heal robot organs, they you will have to check that yourself before using this proc.
O.heal_damage(0, -amount, internal=0, robo_repair=(O.status & ORGAN_ROBOT))
O.heal_damage(0, -amount, internal = 0, robo_repair = O.is_robotic())
/mob/living/carbon/human/Paralyse(amount)
@@ -139,8 +139,8 @@
..()
/mob/living/carbon/human/adjustCloneLoss(amount)
if(species)
amount = amount * species.clone_mod
if(dna.species)
amount = amount * dna.species.clone_mod
..()
var/heal_prob = max(0, 80 - getCloneLoss())
@@ -149,7 +149,7 @@
if(prob(mut_prob))
var/list/obj/item/organ/external/candidates = list() //TYPECASTED LISTS ARE NOT A FUCKING THING WHAT THE FUCK
for(var/obj/item/organ/external/O in bodyparts)
if(O.status & ORGAN_ROBOT)
if(O.is_robotic())
continue
if(!(O.status & ORGAN_MUTATED))
candidates |= O
@@ -179,23 +179,23 @@
// Defined here solely to take species flags into account without having to recast at mob/living level.
/mob/living/carbon/human/adjustOxyLoss(amount)
if(species)
amount = amount * species.oxy_mod
if(dna.species)
amount = amount * dna.species.oxy_mod
..()
/mob/living/carbon/human/setOxyLoss(amount)
if(species)
amount = amount * species.oxy_mod
if(dna.species)
amount = amount * dna.species.oxy_mod
..()
/mob/living/carbon/human/adjustToxLoss(amount)
if(species)
amount = amount * species.tox_mod
if(dna.species)
amount = amount * dna.species.tox_mod
..()
/mob/living/carbon/human/setToxLoss(amount)
if(species)
amount = amount * species.tox_mod
if(dna.species)
amount = amount * dna.species.tox_mod
..()
////////////////////////////////////////////
@@ -205,9 +205,9 @@
var/list/obj/item/organ/external/parts = list()
for(var/obj/item/organ/external/O in bodyparts)
if((brute && O.brute_dam) || (burn && O.burn_dam))
if(!(flags & AFFECT_ROBOTIC_ORGAN) && O.status & ORGAN_ROBOT)
if(!(flags & AFFECT_ROBOTIC_ORGAN) && O.is_robotic())
continue
if(!(flags & AFFECT_ORGANIC_ORGAN) && !(O.status & ORGAN_ROBOT))
if(!(flags & AFFECT_ORGANIC_ORGAN) && !O.is_robotic())
continue
parts += O
return parts
@@ -352,8 +352,8 @@ This function restores all organs.
switch(damagetype)
if(BRUTE)
damageoverlaytemp = 20
if(species)
damage = damage * species.brute_mod
if(dna.species)
damage = damage * dna.species.brute_mod
if(organ.receive_damage(damage, 0, sharp, used_weapon))
UpdateDamageIcon()
@@ -372,13 +372,12 @@ This function restores all organs.
dmgIcon.pixel_y = (!lying) ? rand(-11,9) : rand(-10,1)
flick_overlay(dmgIcon, attack_bubble_recipients, 9)
receiving_damage()
if(BURN)
damageoverlaytemp = 20
if(species)
damage = damage * species.burn_mod
if(dna.species)
damage = damage * dna.species.burn_mod
if(organ.receive_damage(0, damage, sharp, used_weapon))
UpdateDamageIcon()
@@ -165,7 +165,7 @@ emp_act
/mob/living/carbon/human/emag_act(user as mob, var/obj/item/organ/external/affecting)
if(!istype(affecting))
return
if(!(affecting.status & ORGAN_ROBOT))
if(!affecting.is_robotic())
to_chat(user, "<span class='warning'>That limb isn't robotic.</span>")
return
if(affecting.sabotaged)
@@ -175,24 +175,28 @@ emp_act
affecting.sabotaged = 1
return 1
//Returns 1 if the attack hit, 0 if it missed.
/mob/living/carbon/human/proc/attacked_by(var/obj/item/I, var/mob/living/user, var/def_zone)
if(!I || !user) return 0
/mob/living/carbon/human/grabbedby(mob/living/user)
if(w_uniform)
w_uniform.add_fingerprint(user)
..()
if((istype(I, /obj/item/weapon/kitchen/knife/butcher/meatcleaver) || istype(I, /obj/item/weapon/twohanded/chainsaw)) && src.stat == DEAD && user.a_intent == INTENT_HARM)
var/obj/item/weapon/reagent_containers/food/snacks/meat/human/newmeat = new /obj/item/weapon/reagent_containers/food/snacks/meat/human(get_turf(src.loc))
newmeat.name = src.real_name + newmeat.name
newmeat.subjectname = src.real_name
newmeat.subjectjob = src.job
newmeat.reagents.add_reagent ("nutriment", (src.nutrition / 15) / 3)
src.reagents.trans_to (newmeat, round ((src.reagents.total_volume) / 3, 1))
//Returns 1 if the attack hit, 0 if it missed.
/mob/living/carbon/human/attacked_by(obj/item/I, mob/living/user, def_zone)
if(!I || !user)
return 0
if((istype(I, /obj/item/kitchen/knife/butcher/meatcleaver) || istype(I, /obj/item/twohanded/chainsaw)) && stat == DEAD && user.a_intent == INTENT_HARM)
var/obj/item/reagent_containers/food/snacks/meat/human/newmeat = new /obj/item/reagent_containers/food/snacks/meat/human(get_turf(loc))
newmeat.name = real_name + newmeat.name
newmeat.subjectname = real_name
newmeat.subjectjob = job
newmeat.reagents.add_reagent("nutriment", (nutrition / 15) / 3)
reagents.trans_to(newmeat, round((reagents.total_volume) / 3, 1))
add_mob_blood(src)
--src.meatleft
to_chat(user, "<span class='warning'>You hack off a chunk of meat from [src.name]</span>")
if(!src.meatleft)
src.create_attack_log("Was chopped up into meat by <b>[key_name(user)]</b>")
user.create_attack_log("Chopped up <b>[key_name(src)]</b> into meat</b>")
msg_admin_attack("[key_name_admin(user)] chopped up [key_name_admin(src)] into meat")
--meatleft
to_chat(user, "<span class='warning'>You hack off a chunk of meat from [name]</span>")
if(!meatleft)
add_attack_logs(user, src, "Chopped up into meat")
if(!iscarbon(user))
LAssailant = null
else
@@ -211,22 +215,21 @@ emp_act
if(check_shields(I.force, "the [I.name]", I, MELEE_ATTACK, I.armour_penetration))
return 0
if(istype(I,/obj/item/weapon/card/emag))
if(istype(I,/obj/item/card/emag))
emag_act(user, affecting)
if(! I.discrete)
if(I.attack_verb.len)
visible_message("<span class='combat danger'>[src] has been [pick(I.attack_verb)] in the [hit_area] with [I.name] by [user]!</span>")
else
visible_message("<span class='combat danger'>[src] has been attacked in the [hit_area] with [I.name] by [user]!</span>")
send_item_attack_message(I, user, hit_area)
var/armor = run_armor_check(affecting, "melee", "Your armor has protected your [hit_area].", "Your armor has softened hit to your [hit_area].", armour_penetration = I.armour_penetration)
if(!I.force)
return 0 //item force is zero
var/armor = run_armor_check(affecting, "melee", "<span class='warning'>Your armour has protected your [hit_area].</span>", "<span class='warning'>Your armour has softened hit to your [hit_area].</span>", armour_penetration = I.armour_penetration)
var/weapon_sharp = is_sharp(I)
if(weapon_sharp && prob(getarmor(user.zone_sel.selecting, "melee")))
weapon_sharp = 0
if(armor >= 100) return 0
if(!I.force) return 0
if(armor >= 100)
return 0
var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords)
apply_damage(I.force, I.damtype, affecting, armor, sharp = weapon_sharp, used_weapon = I)
@@ -234,8 +237,6 @@ emp_act
var/bloody = 0
if(I.damtype == BRUTE && I.force && prob(25 + I.force * 2))
I.add_mob_blood(src) //Make the weapon bloody, not the person.
// if(user.hand) user.update_inv_l_hand() //updates the attacker's overlay for the (now bloodied) weapon
// else user.update_inv_r_hand() //removed because weapons don't have on-mob blood overlays
if(prob(I.force * 2)) //blood spatter!
bloody = 1
var/turf/location = loc
@@ -347,6 +348,111 @@ emp_act
if(penetrated_dam) SS.create_breaches(damtype, penetrated_dam)
/mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
if(user.a_intent == INTENT_HARM)
var/hulk_verb = pick("smash", "pummel")
if(check_shields(user, 15, "the [hulk_verb]ing"))
return
..(user, TRUE)
playsound(loc, user.dna.species.unarmed.attack_sound, 25, 1, -1)
var/message = "[user] has [hulk_verb]ed [src]!"
visible_message("<span class='danger'>[message]</span>", "<span class='userdanger'>[message]</span>")
adjustBruteLoss(15)
return TRUE
/mob/living/carbon/human/attack_hand(mob/user)
if(..()) //to allow surgery to return properly.
return
if(ishuman(user))
var/mob/living/carbon/human/H = user
dna.species.spec_attack_hand(H, src)
/mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L)
if(..()) //successful larva bite.
var/damage = rand(1, 3)
if(stat != DEAD)
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
var/obj/item/organ/external/affecting = get_organ(ran_zone(L.zone_sel.selecting))
var/armor_block = run_armor_check(affecting, "melee")
apply_damage(damage, BRUTE, affecting, armor_block)
updatehealth()
/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M)
if(check_shields(0, M.name))
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>")
return 0
if(..())
if(M.a_intent == INTENT_HARM)
if(w_uniform)
w_uniform.add_fingerprint(M)
var/damage = rand(15, 30)
if(!damage)
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has lunged at [src]!</span>")
return 0
var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
var/armor_block = run_armor_check(affecting, "melee")
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
"<span class='userdanger'>[M] has slashed at [src]!</span>")
apply_damage(damage, BRUTE, affecting, armor_block)
if(damage >= 25)
visible_message("<span class='danger'>[M] has wounded [src]!</span>", \
"<span class='userdanger'>[M] has wounded [src]!</span>")
apply_effect(4, WEAKEN, armor_block)
add_attack_logs(M, src, "Alien attacked")
updatehealth()
if(M.a_intent == INTENT_DISARM)
if(prob(80))
var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_sel.selecting))
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
apply_effect(5, WEAKEN, run_armor_check(affecting, "melee"))
add_attack_logs(M, src, "Alien tackled")
visible_message("<span class='danger'>[M] has tackled down [src]!</span>")
else
if(prob(99)) //this looks fucking stupid but it was previously 'var/randn = rand(1, 100); if(randn <= 99)'
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
drop_item()
visible_message("<span class='danger'>[M] disarmed [src]!</span>")
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has tried to disarm [src]!</span>")
/mob/living/carbon/human/attack_animal(mob/living/simple_animal/M)
if(..())
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
if(check_shields(damage, "the [M.name]", null, MELEE_ATTACK, M.armour_penetration))
return 0
var/dam_zone = pick("head", "chest", "groin", "l_arm", "l_hand", "r_arm", "r_hand", "l_leg", "l_foot", "r_leg", "r_foot")
var/obj/item/organ/external/affecting = get_organ(ran_zone(dam_zone))
var/armor = run_armor_check(affecting, "melee", armour_penetration = M.armour_penetration)
var/obj/item/organ/external/affected = src.get_organ(dam_zone)
if(affected)
affected.add_autopsy_data(M.name, damage) // Add the mob's name to the autopsy data
apply_damage(damage, M.melee_damage_type, affecting, armor)
updatehealth()
/mob/living/carbon/human/attack_slime(mob/living/carbon/slime/M)
..()
var/damage = rand(1, 3)
if(M.is_adult)
damage = rand(10, 35)
else
damage = rand(5, 25)
var/dam_zone = pick("head", "chest", "groin", "l_arm", "l_hand", "r_arm", "r_hand", "l_leg", "l_foot", "r_leg", "r_foot")
var/obj/item/organ/external/affecting = get_organ(ran_zone(dam_zone))
var/armor_block = run_armor_check(affecting, "melee")
apply_damage(damage, BRUTE, affecting, armor_block)
return
/mob/living/carbon/human/mech_melee_attack(obj/mecha/M)
if(M.occupant.a_intent == INTENT_HARM)
if(M.damtype == "brute")
@@ -373,10 +479,7 @@ emp_act
visible_message("<span class='danger'>[src] has been hit by [M.name].</span>", \
"<span class='userdanger'>[src] has been hit by [M.name].</span>")
create_attack_log("<font color='orange'>Has been attacked by \the [M] controlled by [key_name(M.occupant)] (INTENT: [uppertext(M.occupant.a_intent)])</font>")
M.occupant.create_attack_log("<font color='red'>Attacked [src] with \the [M] (INTENT: [uppertext(M.occupant.a_intent)])</font>")
msg_admin_attack("[key_name_admin(M.occupant)] attacked [key_name_admin(src)] with \the [M] (INTENT: [uppertext(M.occupant.a_intent)])")
add_attack_logs(M.occupant, src, "Mecha-meleed with [M]")
else
..()
@@ -391,7 +494,7 @@ emp_act
/mob/living/carbon/human/water_act(volume, temperature, source)
..()
species.water_act(src,volume,temperature,source)
dna.species.water_act(src,volume,temperature,source)
/mob/living/carbon/human/is_eyes_covered(check_glasses = TRUE, check_head = TRUE, check_mask = TRUE)
if(check_glasses && glasses && (glasses.flags_cover & GLASSESCOVERSEYES))
@@ -1,7 +1,7 @@
var/global/default_martial_art = new/datum/martial_art
/mob/living/carbon/human
hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPMINDSHIELD_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,NATIONS_HUD)
hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPMINDSHIELD_HUD,IMPCHEM_HUD,IMPTRACK_HUD,SPECIALROLE_HUD,NATIONS_HUD,GLAND_HUD)
//Marking colour and style
var/list/m_colours = DEFAULT_MARKING_COLOURS //All colours set to #000000.
@@ -2,7 +2,7 @@
. = 0
. += ..()
. += config.human_delay
. += species.movement_delay(src)
. += dna.species.movement_delay(src)
/mob/living/carbon/human/Process_Spacemove(movement_dir = 0)
@@ -10,11 +10,11 @@
return 1
//Do we have a working jetpack?
var/obj/item/weapon/tank/jetpack/thrust
if(istype(back,/obj/item/weapon/tank/jetpack))
var/obj/item/tank/jetpack/thrust
if(istype(back,/obj/item/tank/jetpack))
thrust = back
else if(istype(back,/obj/item/weapon/rig))
var/obj/item/weapon/rig/rig = back
else if(istype(back,/obj/item/rig))
var/obj/item/rig/rig = back
for(var/obj/item/rig_module/maneuvering_jets/module in rig.installed_modules)
thrust = module.jets
break
@@ -39,12 +39,12 @@
if(!lying && !buckled && !throwing)
for(var/obj/item/organ/external/splinted in splinted_limbs)
splinted.update_splints()
if(!has_gravity(loc))
return
var/obj/item/clothing/shoes/S = shoes
//Bloody footprints
var/turf/T = get_turf(src)
var/obj/item/organ/external/l_foot = get_organ("l_foot")
@@ -119,7 +119,7 @@
if(step_count % 3) //this basically says, every three moves make a noise
return 0 //1st - none, 1%3==1, 2nd - none, 2%3==2, 3rd - noise, 3%3==0
if(species.silent_steps)
if(dna.species.silent_steps)
return 0 //species is silent
playsound(T, S, volume, 1, range)
@@ -20,7 +20,7 @@
//Moving around with fractured ribs won't do you any good
if(E.is_broken() && E.internal_organs && E.internal_organs.len && prob(15))
var/obj/item/organ/internal/I = pick(E.internal_organs)
custom_pain("You feel broken bones moving in your [E.name]!", 1)
custom_pain("You feel broken bones moving in your [E.name]!")
I.receive_damage(rand(3,5))
//handle_stance()
@@ -62,7 +62,7 @@
// standing is poor
if(stance_damage >= 8)
if(!(lying || resting))
if(!(NO_PAIN in species.species_traits))
if(!(NO_PAIN in dna.species.species_traits))
emote("scream")
custom_emote(1, "collapses!")
Weaken(5) //can't emote while weakened, apparently.
@@ -90,7 +90,7 @@
continue
var/emote_scream = pick("screams in pain and ", "lets out a sharp cry and ", "cries out and ")
custom_emote(1, "[(NO_PAIN in species.species_traits) ? "" : emote_scream ]drops what they were holding in their [E.name]!")
custom_emote(1, "[(NO_PAIN in dna.species.species_traits) ? "" : emote_scream ]drops what [p_they()] [p_were()] holding in [p_their()] [E.name]!")
else if(E.is_malfunctioning())
@@ -105,7 +105,7 @@
if(!unEquip(r_hand))
continue
custom_emote(1, "drops what they were holding, their [E.name] malfunctioning!")
custom_emote(1, "drops what [p_they()] [p_were()] holding, [p_their()] [E.name] malfunctioning!")
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread()
spark_system.set_up(5, 0, src)
@@ -178,7 +178,7 @@ I use this to standardize shadowling dethrall code
/mob/living/carbon/human/has_organic_damage()
var/odmg = 0
for(var/obj/item/organ/external/O in bodyparts)
if(O.status & ORGAN_ROBOT)
if(O.is_robotic())
odmg += O.brute_dam
odmg += O.burn_dam
return (health < (100 - odmg))
@@ -87,13 +87,13 @@
if(inactivity_period <= 0)
inactivity_period = 9999 // technically infinite
if(do_after(src, 60, target = traitorTarget))
custom_emote(1, "A fire bursts from [src]'s eyes, igniting white hot and consuming their body in a flaming explosion!")
custom_emote(1, "A fire bursts from [src]'s eyes, igniting white hot and consuming [p_their()] body in a flaming explosion!")
explosion(src, 6, 6, 6)
else
inactivity_period = 0
custom_emote(1, "[src]'s chest closes, hiding their insides.")
custom_emote(1, "[src]'s chest closes, hiding [p_their()] insides.")
if(SNPC_PSYCHO)
var/choice = pick(typesof(/obj/item/weapon/grenade/chem_grenade) - /obj/item/weapon/grenade/chem_grenade)
var/choice = pick(typesof(/obj/item/grenade/chem_grenade) - /obj/item/grenade/chem_grenade)
new choice(src)
@@ -109,13 +109,13 @@
var/list/allContents = getAllContents()
var/obj/item/weapon/reagent_containers/glass/beaker/bluespace/internalBeaker = locate(/obj/item/weapon/reagent_containers/glass/beaker/bluespace) in allContents
var/obj/item/weapon/storage/bag/plants/internalBag = locate(/obj/item/weapon/storage/bag/plants) in allContents
var/obj/item/reagent_containers/glass/beaker/bluespace/internalBeaker = locate(/obj/item/reagent_containers/glass/beaker/bluespace) in allContents
var/obj/item/storage/bag/plants/internalBag = locate(/obj/item/storage/bag/plants) in allContents
if(!internalBag)
internalBag = new/obj/item/weapon/storage/bag/plants(src)
internalBag = new/obj/item/storage/bag/plants(src)
if(!internalBeaker)
internalBeaker = new/obj/item/weapon/reagent_containers/glass/beaker/bluespace(src)
internalBeaker = new/obj/item/reagent_containers/glass/beaker/bluespace(src)
internalBeaker.name = "Grow-U-All Super Spray"
if(internalBeaker && internalBag)
@@ -181,7 +181,7 @@
if(change)
HP.attackby(internalBeaker,src)
var/obj/item/weapon/reagent_containers/food/snacks/grown/GF = locate(/obj/item/weapon/reagent_containers/food/snacks/grown) in view(12,src)
var/obj/item/reagent_containers/food/snacks/grown/GF = locate(/obj/item/reagent_containers/food/snacks/grown) in view(12,src)
if(GF)
if(!Adjacent(GF))
tryWalk(get_turf(GF))
@@ -216,7 +216,7 @@
var/mob/living/carbon/human/serveTarget
for(var/mob/living/carbon/human/H in rangeCheck)
if(!locate(/obj/item/weapon/reagent_containers/food/drinks) in orange(1, H))
if(!locate(/obj/item/reagent_containers/food/drinks) in orange(1, H))
serveTarget = H
@@ -227,9 +227,9 @@
if(!Adjacent(RT))
tryWalk(get_turf(RT))
else
var/drinkChoice = pick(typesof(/obj/item/weapon/reagent_containers/food/drinks) - /obj/item/weapon/reagent_containers/food/drinks)
var/drinkChoice = pick(typesof(/obj/item/reagent_containers/food/drinks) - /obj/item/reagent_containers/food/drinks)
if(drinkChoice)
var/obj/item/weapon/reagent_containers/food/drinks/D = new drinkChoice(get_turf(src))
var/obj/item/reagent_containers/food/drinks/D = new drinkChoice(get_turf(src))
RT.attackby(D,src)
say("[pick("Something to wet your whistle!","Down the hatch, a tasty beverage!","One drink, coming right up!","Tasty liquid for your oral intake!","Enjoy!")]")
custom_emote(2, "[pick("gibbers","drools","slobbers","claps wildly","spits")], serving up a [D]!")
@@ -237,10 +237,15 @@
/mob/living/carbon/human/interactive/proc/shitcurity(obj)
var/list/allContents = getAllContents()
if(retal && TARGET && Adjacent(TARGET))
var/obj/item/weapon/restraints/R = locate() in allContents
if(R)
R.attack(TARGET, src) // go go bluespace restraint launcher!
if(retal && TARGET)
if(Adjacent(TARGET))
var/obj/item/restraints/R = locate() in allContents
if(R)
R.attack(TARGET, src) // go go bluespace restraint launcher!
else if(TARGET in oview(7, src))
var/obj/item/gun/G = locate() in allContents
if(G)
G.afterattack(TARGET, src)
/mob/living/carbon/human/interactive/proc/clowning(obj)
if(shouldModulePass())
@@ -251,17 +256,17 @@
var/mob/living/carbon/human/clownTarget
var/list/clownPriority = list()
var/obj/item/weapon/reagent_containers/spray/S
if(!locate(/obj/item/weapon/reagent_containers/spray) in allContents)
new/obj/item/weapon/reagent_containers/spray(src)
var/obj/item/reagent_containers/spray/S
if(!locate(/obj/item/reagent_containers/spray) in allContents)
new/obj/item/reagent_containers/spray(src)
else
S = locate(/obj/item/weapon/reagent_containers/spray) in allContents
S = locate(/obj/item/reagent_containers/spray) in allContents
for(var/mob/living/carbon/human/C in rangeCheck)
var/pranksNearby = 100
for(var/turf/simulated/T in orange(1, C))
for(var/obj/item/A in T)
if(istype(A,/obj/item/weapon/soap) || istype(A,/obj/item/weapon/reagent_containers/food/snacks/grown/banana) || istype(A,/obj/item/weapon/grown/bananapeel))
if(istype(A,/obj/item/soap) || istype(A,/obj/item/reagent_containers/food/snacks/grown/banana) || istype(A,/obj/item/grown/bananapeel))
pranksNearby--
if(T.wet)
pranksNearby -= 10
@@ -281,13 +286,13 @@
var/hasPranked = 0
for(var/A in allContents)
if(prob(smartness/2) && !hasPranked)
if(istype(A,/obj/item/weapon/soap))
if(istype(A,/obj/item/soap))
npcDrop(A)
hasPranked = 1
if(istype(A,/obj/item/weapon/reagent_containers/food/snacks/grown/banana))
var/obj/item/weapon/reagent_containers/food/snacks/B = A
if(istype(A,/obj/item/reagent_containers/food/snacks/grown/banana))
var/obj/item/reagent_containers/food/snacks/B = A
B.attack(src, src)
if(istype(A,/obj/item/weapon/grown/bananapeel))
if(istype(A,/obj/item/grown/bananapeel))
npcDrop(A)
hasPranked = 1
if(!hasPranked)
@@ -307,12 +312,12 @@
shouldTryHeal = 1
M = A
var/obj/item/weapon/reagent_containers/hypospray/HPS
var/obj/item/reagent_containers/hypospray/HPS
if(!locate(/obj/item/weapon/reagent_containers/hypospray) in allContents)
new/obj/item/weapon/reagent_containers/hypospray(src)
if(!locate(/obj/item/reagent_containers/hypospray) in allContents)
new/obj/item/reagent_containers/hypospray(src)
else
HPS = locate(/obj/item/weapon/reagent_containers/hypospray) in allContents
HPS = locate(/obj/item/reagent_containers/hypospray) in allContents
if(!shouldTryHeal)
shouldTryHeal = 2 // we have no stackables to use, lets use our internal hypospray instead
@@ -346,12 +351,12 @@
return
var/list/allContents = getAllContents()
//now with bluespace magic!
var/obj/item/weapon/reagent_containers/spray/SP = locate() in allContents
var/obj/item/reagent_containers/spray/SP = locate() in allContents
if(!SP)
SP = new /obj/item/weapon/reagent_containers/spray(src)
var/obj/item/weapon/soap/SO = locate() in allContents
SP = new /obj/item/reagent_containers/spray(src)
var/obj/item/soap/SO = locate() in allContents
if(!SO)
SO = new /obj/item/weapon/soap(src)
SO = new /obj/item/soap(src)
if(SP.reagents.total_volume <= 5)
SP.reagents.add_reagent("cleaner", 25) // bluespess water delivery for AI
@@ -420,22 +425,22 @@
return
doing |= SNPC_SPECIAL
var/static/list/customableTypes = list(/obj/item/weapon/reagent_containers/food/snacks/customizable,/obj/item/weapon/reagent_containers/food/snacks/breadslice,/obj/item/weapon/reagent_containers/food/snacks/bun,/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough,/obj/item/weapon/reagent_containers/food/snacks/boiledspaghetti,/obj/item/trash/plate,/obj/item/trash/bowl)
var/static/list/customableTypes = list(/obj/item/reagent_containers/food/snacks/customizable,/obj/item/reagent_containers/food/snacks/breadslice,/obj/item/reagent_containers/food/snacks/bun,/obj/item/reagent_containers/food/snacks/sliceable/flatdough,/obj/item/reagent_containers/food/snacks/boiledspaghetti,/obj/item/trash/plate,/obj/item/trash/bowl)
var/static/list/rawtypes = list(/obj/item/weapon/reagent_containers/food/snacks/grown, /obj/item/weapon/reagent_containers/food/snacks/rawcutlet, /obj/item/weapon/reagent_containers/food/snacks/rawsticks, /obj/item/weapon/reagent_containers/food/snacks/salmonmeat, /obj/item/weapon/reagent_containers/food/snacks/carpmeat, /obj/item/weapon/reagent_containers/food/snacks/catfishmeat, /obj/item/weapon/reagent_containers/food/snacks/spaghetti, /obj/item/weapon/reagent_containers/food/snacks/dough, /obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough, /obj/item/weapon/reagent_containers/food/snacks/doughslice, /obj/item/weapon/reagent_containers/food/snacks/meat, /obj/item/weapon/reagent_containers/food/snacks/boiledrice, /obj/item/weapon/reagent_containers/food/snacks/cheesewedge, /obj/item/weapon/reagent_containers/food/snacks/raw_bacon)
var/static/list/rawtypes = list(/obj/item/reagent_containers/food/snacks/grown, /obj/item/reagent_containers/food/snacks/rawcutlet, /obj/item/reagent_containers/food/snacks/rawsticks, /obj/item/reagent_containers/food/snacks/salmonmeat, /obj/item/reagent_containers/food/snacks/carpmeat, /obj/item/reagent_containers/food/snacks/catfishmeat, /obj/item/reagent_containers/food/snacks/spaghetti, /obj/item/reagent_containers/food/snacks/dough, /obj/item/reagent_containers/food/snacks/sliceable/flatdough, /obj/item/reagent_containers/food/snacks/doughslice, /obj/item/reagent_containers/food/snacks/meat, /obj/item/reagent_containers/food/snacks/boiledrice, /obj/item/reagent_containers/food/snacks/cheesewedge, /obj/item/reagent_containers/food/snacks/raw_bacon)
try
var/list/allContents = getAllContents()
var/list/rangeCheck = view(6, src)
//Bluespace in some inbuilt tools
var/obj/item/weapon/kitchen/rollingpin/RP = locate() in allContents
var/obj/item/kitchen/rollingpin/RP = locate() in allContents
if(!RP)
RP = new /obj/item/weapon/kitchen/rollingpin(src)
RP = new /obj/item/kitchen/rollingpin(src)
var/obj/item/weapon/kitchen/knife/KK = locate() in allContents
var/obj/item/kitchen/knife/KK = locate() in allContents
if(!KK)
KK = new /obj/item/weapon/kitchen/knife(src)
KK = new /obj/item/kitchen/knife(src)
var/global/list/available_recipes
if(!available_recipes)
@@ -453,7 +458,7 @@
var/foundCustom
for(var/customType in customableTypes)
var/A = locate(customType) in rangeCheck
var/obj/item/weapon/reagent_containers/food/snacks/customizable/I = A
var/obj/item/reagent_containers/food/snacks/customizable/I = A
if(A && (!istype(I) || I.ingredients.len <= 3))
foundCustom = A // this will eventually wittle down to 0
break
@@ -464,7 +469,7 @@
if(!Adjacent(SF))
tryWalk(get_turf(SF))
else
custom_emote(2, "[pick("gibbers","drools","slobbers","claps wildly","spits")], grabbing various foodstuffs from [SF] and sticking them in it's mouth!")
custom_emote(2, "[pick("gibbers","drools","slobbers","claps wildly","spits")], grabbing various foodstuffs from [SF] and sticking them in its mouth!")
for(var/obj/item/A in SF.contents)
if(prob(smartness/2))
var/count = SF.item_quants[A.name]
@@ -473,8 +478,8 @@
A.forceMove(src)
if(foundCustom)
var/obj/item/weapon/reagent_containers/food/snacks/FC = foundCustom
for(var/obj/item/weapon/reagent_containers/food/snacks/toMake in allContents)
var/obj/item/reagent_containers/food/snacks/FC = foundCustom
for(var/obj/item/reagent_containers/food/snacks/toMake in allContents)
if(prob(smartness))
if(FC.reagents)
if(toMake.reagents)
@@ -492,13 +497,13 @@
qdel(FC) // this food is usless, toss it
// Process tool-based ingredients
var/obj/item/weapon/reagent_containers/food/snacks/dough/D = locate() in rangeCheck
var/obj/item/weapon/reagent_containers/food/snacks/sliceable/flatdough/FD = locate() in rangeCheck
var/obj/item/weapon/reagent_containers/food/snacks/rawcutlet/RC = locate() in rangeCheck
var/obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesewheel/CW = locate() in rangeCheck
var/obj/item/weapon/reagent_containers/food/snacks/grown/potato/PO = locate() in rangeCheck
var/obj/item/weapon/reagent_containers/food/snacks/meat/ME = locate() in rangeCheck
var/obj/item/weapon/reagent_containers/food/snacks/raw_bacon/RB = locate() in rangeCheck
var/obj/item/reagent_containers/food/snacks/dough/D = locate() in rangeCheck
var/obj/item/reagent_containers/food/snacks/sliceable/flatdough/FD = locate() in rangeCheck
var/obj/item/reagent_containers/food/snacks/rawcutlet/RC = locate() in rangeCheck
var/obj/item/reagent_containers/food/snacks/sliceable/cheesewheel/CW = locate() in rangeCheck
var/obj/item/reagent_containers/food/snacks/grown/potato/PO = locate() in rangeCheck
var/obj/item/reagent_containers/food/snacks/meat/ME = locate() in rangeCheck
var/obj/item/reagent_containers/food/snacks/raw_bacon/RB = locate() in rangeCheck
if(D)
TARGET = D
@@ -576,7 +581,7 @@
// dont display our ingredients
var/list/finishedList = list()
for(var/obj/item/weapon/reagent_containers/food/snacks/toDisplay in allContents)
for(var/obj/item/reagent_containers/food/snacks/toDisplay in allContents)
var/raw = 0
for(var/type in rawtypes)
if(istype(toDisplay, type))
@@ -585,7 +590,7 @@
if(!raw)
finishedList += toDisplay
for(var/obj/item/weapon/reagent_containers/food/snacks/toGrab in rangeCheck)
for(var/obj/item/reagent_containers/food/snacks/toGrab in rangeCheck)
if(!(locate(/obj/structure/table/reinforced) in get_turf(toGrab))) //it's not being displayed
var/raw = 0
for(var/type in rawtypes)
@@ -605,7 +610,7 @@
for(var/obj/structure/table/reinforced/toCheck in rangeCheck)
var/counted = 0
for(var/obj/item/weapon/reagent_containers/food/snacks/S in get_turf(toCheck))
for(var/obj/item/reagent_containers/food/snacks/S in get_turf(toCheck))
++counted
if(counted < 12) // make sure theres not too much food here
RT = toCheck
@@ -616,17 +621,17 @@
if(!Adjacent(RT))
tryWalk(get_turf(RT))
else
for(var/obj/item/weapon/reagent_containers/food/snacks/toPlop in finishedList)
for(var/obj/item/reagent_containers/food/snacks/toPlop in finishedList)
RT.attackby(toPlop,src)
if(!foundCookable)
var/chosenType = pick(rawtypes)
var/obj/item/weapon/reagent_containers/food/snacks/newSnack = new chosenType(get_turf(src))
var/obj/item/reagent_containers/food/snacks/newSnack = new chosenType(get_turf(src))
TARGET = newSnack
newSnack.reagents.remove_any((newSnack.reagents.total_volume/2)-1)
newSnack.name = "Synthetic [newSnack.name]"
custom_emote(2, "[pick("gibbers","drools","slobbers","claps wildly","spits")] as they vomit [newSnack] from their mouth!")
custom_emote(2, "[pick("gibbers","drools","slobbers","claps wildly","spits")] as [p_they()] vomit[p_s()] [newSnack] from [p_their()] mouth!")
catch(var/exception/e)
log_runtime(e, src, "Caught in SNPC cooking module")
doing &= ~SNPC_SPECIAL
@@ -661,7 +666,7 @@
//ensure we're using the best object possible
var/obj/item/weapon/best
var/obj/item/best
var/foundFav = 0
var/list/allContents = getAllContents()
for(var/test in allContents)
@@ -671,16 +676,16 @@
foundFav = 1
return
if(!foundFav)
if(istype(test,/obj/item/weapon))
var/obj/item/weapon/R = test
if(istype(test,/obj/item))
var/obj/item/R = test
if(R.force > 2) // make sure we don't equip any non-weaponlike items, ie bags and stuff
if(!best)
best = R
else
if(best.force < R.force)
best = R
if(istype(R, /obj/item/weapon/gun))
var/obj/item/weapon/gun/G = R
if(istype(R, /obj/item/gun))
var/obj/item/gun/G = R
if(G.can_shoot())
best = R
break // gun with ammo? screw the rest
@@ -693,16 +698,16 @@
if(M.health > 1 && (M in oview(src, 6)))
//THROWING OBJECTS
for(var/A in allContents)
if(istype(A,/obj/item/weapon/gun)) // guns are for shooting, not throwing.
if(istype(A,/obj/item/gun)) // guns are for shooting, not throwing.
continue
if(prob(robustness))
if(istype(A,/obj/item/weapon))
var/obj/item/weapon/W = A
if(istype(A,/obj/item))
var/obj/item/W = A
if(W.throwforce > 19) // Only throw worthwile stuff, no more lobbing wrenches at wenches
npcDrop(W, 1)
throw_item(TARGET)
if(istype(A,/obj/item/weapon/grenade)) // Allahu ackbar! ALLAHU ACKBARR!!
var/obj/item/weapon/grenade/G = A
if(istype(A,/obj/item/grenade)) // Allahu ackbar! ALLAHU ACKBARR!!
var/obj/item/grenade/G = A
G.attack_self(src)
if(prob(smartness))
npcDrop(G, 1)
@@ -713,12 +718,12 @@
swap_hands()
if(main_hand)
if(main_hand.force != 0)
if(istype(main_hand,/obj/item/weapon/gun))
var/obj/item/weapon/gun/G = main_hand
if(istype(main_hand,/obj/item/gun))
var/obj/item/gun/G = main_hand
if(G.can_trigger_gun(src))
var/shouldFire = 1
if(istype(main_hand, /obj/item/weapon/gun/energy))
var/obj/item/weapon/gun/energy/P = main_hand
if(istype(main_hand, /obj/item/gun/energy))
var/obj/item/gun/energy/P = main_hand
var/stunning = 0
for(var/A in P.ammo_type)
if(ispath(A,/obj/item/ammo_casing/energy/electrode))
@@ -737,7 +742,7 @@
if(!walk2derpless(TARGET))
timeout++
else
var/obj/item/weapon/W = main_hand
var/obj/item/W = main_hand
W.attack(TARGET, src)
else
npcDrop(G, 1)
@@ -797,7 +802,7 @@
/mob/living/carbon/human/interactive/proc/pickStamp(allContents)
var/list/stamps[0]
for(var/obj/item/weapon/stamp/S in allContents)
for(var/obj/item/stamp/S in allContents)
stamps += S
if(stamps.len)
return pick(stamps)
@@ -805,7 +810,7 @@
// just make one, maybe
if(prob(SNPC_FUZZY_CHANCE_LOW / 2))
for(var/p in favoured_types)
if(ispath(p, /obj/item/weapon/stamp))
if(ispath(p, /obj/item/stamp))
return new p(src)
return null
@@ -817,12 +822,12 @@
var/list/allContents = getAllContents()
var/obj/item/weapon/paper/P = locate() in allContents
var/obj/item/weapon/stamp/S = pickStamp(allContents)
var/obj/item/paper/P = locate() in allContents
var/obj/item/stamp/S = pickStamp(allContents)
var/mob/living/carbon/human/H = locate() in nearby
if(!P)
P = new /obj/item/weapon/paper(src)
P = new /obj/item/paper(src)
if(P && S && H)
if(!P.stamped || !P.stamped.len)
@@ -845,12 +850,12 @@
var/list/allContents = getAllContents()
var/list/rangeCheck = view(7, src)
var/obj/item/weapon/stamp/S = pickStamp(allContents)
var/obj/item/stamp/S = pickStamp(allContents)
if(!S)
return
// stamp a paper we're holding, and drop it
var/obj/item/weapon/paper/P = locate() in allContents
var/obj/item/paper/P = locate() in allContents
if(P)
if(!P.stamped || !P.stamped.len)
P.stamp(S)
@@ -859,7 +864,7 @@
return
// stamp a paper in the world
for(var/obj/item/weapon/paper/A in rangeCheck)
for(var/obj/item/paper/A in rangeCheck)
if(!A.stamped || !A.stamped.len)
if(!Adjacent(A))
tryWalk(A)
@@ -44,13 +44,13 @@
var/list/blacklistItems = list() // items we should be ignoring
var/maxStepsTick = 6 // step as many times as we can per frame
//Job and mind data
var/obj/item/weapon/card/id/MYID
var/obj/item/weapon/card/id/RPID // the "real" idea they use
var/obj/item/device/pda/MYPDA
var/obj/item/card/id/MYID
var/obj/item/card/id/RPID // the "real" idea they use
var/obj/item/pda/MYPDA
var/obj/item/main_hand
var/obj/item/other_hand
var/TRAITS = 0
var/obj/item/weapon/card/id/Path_ID
var/obj/item/card/id/Path_ID
var/default_job = /datum/job/civilian // the type for the default job
var/datum/job/myjob
var/list/myPath = list()
@@ -128,7 +128,7 @@
//this is here because this has no client/prefs/brain whatever.
age = rand(AGE_MIN, AGE_MAX)
change_gender(pick("male", "female"))
rename_character(real_name, species.get_random_name(gender))
rename_character(real_name, dna.species.get_random_name(gender))
//job handling
myjob = new default_job()
job = myjob.title
@@ -208,9 +208,9 @@
var/datum/dna/toDoppel = chosen.dna
T.real_name = toDoppel.real_name
T.set_species(chosen.species.name)
T.body_accessory = chosen.body_accessory
T.set_species(chosen.dna.species.type)
T.dna = toDoppel.Clone()
T.body_accessory = chosen.body_accessory
T.UpdateAppearance()
domutcheck(T)
@@ -229,7 +229,7 @@
T.revive()
/mob/living/carbon/human/interactive/proc/doSetup(alt_title = null)
Path_ID = new /obj/item/weapon/card/id(src)
Path_ID = new /obj/item/card/id(src)
var/datum/job/captain/C = new/datum/job/captain
Path_ID.access = C.get_access()
@@ -245,7 +245,7 @@
MYID.age = age
MYID.registered_name = real_name
MYID.photo = get_id_photo(src)
MYID.access = Path_ID.access // Automatons have strange powers... strange indeed
MYID.access = Path_ID.access.Copy() // Automatons have strange powers... strange indeed
RPID = new(src)
RPID.name = "[real_name]'s ID Card ([alt_title])"
@@ -257,7 +257,10 @@
RPID.photo = get_id_photo(src)
RPID.access = myjob.get_access()
equip_to_slot_or_del(MYID, slot_wear_id)
if(wear_id)
qdel(wear_id)
if(!equip_to_slot_or_del(MYID, slot_wear_id))
create_attack_log("<font color='blue'>Deleted ID due to slot contention</font>")
if(wear_pda)
MYPDA = wear_pda
else
@@ -316,43 +319,43 @@
/mob/living/carbon/human/interactive/proc/setup_job(thejob)
switch(thejob)
if("Civilian")
favoured_types = list(/obj/item/clothing, /obj/item/weapon)
favoured_types = list(/obj/item/clothing, /obj/item)
if("Captain", "Head of Personnel")
favoured_types = list(/obj/item/clothing, /obj/item/weapon/stamp/captain,/obj/item/weapon/disk/nuclear)
favoured_types = list(/obj/item/clothing, /obj/item/stamp/captain,/obj/item/disk/nuclear)
if("Nanotrasen Representative")
favoured_types = list(/obj/item/clothing, /obj/item/weapon/stamp/centcom, /obj/item/weapon/paper, /obj/item/weapon/melee/classic_baton/ntcane)
favoured_types = list(/obj/item/clothing, /obj/item/stamp/centcom, /obj/item/paper, /obj/item/melee/classic_baton/ntcane)
functions += "paperwork"
if("Magistrate", "Internal Affairs Agent")
favoured_types = list(/obj/item/clothing, /obj/item/weapon/stamp/law, /obj/item/weapon/paper)
favoured_types = list(/obj/item/clothing, /obj/item/stamp/law, /obj/item/paper)
functions += "paperwork"
if("Quartermaster", "Cargo Technician")
favoured_types = list(/obj/item/clothing, /obj/item/weapon/stamp/granted, /obj/item/weapon/stamp/denied, /obj/item/weapon/paper, /obj/item/weapon/clipboard)
favoured_types = list(/obj/item/clothing, /obj/item/stamp/granted, /obj/item/stamp/denied, /obj/item/paper, /obj/item/clipboard)
functions += "stamping"
if("Chef")
favoured_types = list(/obj/item/weapon/reagent_containers/food, /obj/item/weapon/kitchen)
favoured_types = list(/obj/item/reagent_containers/food, /obj/item/kitchen)
functions += "souschef"
restrictedJob = 1
if("Bartender")
favoured_types = list(/obj/item/weapon/reagent_containers/food, /obj/item/weapon/kitchen)
favoured_types = list(/obj/item/reagent_containers/food, /obj/item/kitchen)
functions += "bartend"
restrictedJob = 1
if("Station Engineer", "Chief Engineer", "Life Support Specialist", "Mechanic")
favoured_types = list(/obj/item/stack, /obj/item/weapon, /obj/item/clothing)
favoured_types = list(/obj/item/stack, /obj/item, /obj/item/clothing)
if("Chief Medical Officer", "Medical Doctor", "Chemist", "Virologist", "Geneticist", "Psychiatrist", "Paramedic", "Brig Physician")
favoured_types = list(/obj/item/weapon/reagent_containers/glass/beaker, /obj/item/weapon/storage/firstaid, /obj/item/stack/medical, /obj/item/weapon/reagent_containers/syringe)
favoured_types = list(/obj/item/reagent_containers/glass/beaker, /obj/item/storage/firstaid, /obj/item/stack/medical, /obj/item/reagent_containers/syringe)
functions += "healpeople"
if("Research Director", "Scientist", "Roboticist")
favoured_types = list(/obj/item/weapon/reagent_containers/glass/beaker, /obj/item/stack, /obj/item/weapon/reagent_containers)
favoured_types = list(/obj/item/reagent_containers/glass/beaker, /obj/item/stack, /obj/item/reagent_containers)
if("Head of Security", "Warden", "Security Officer", "Detective", "Security Pod Pilot", "Blueshield")
favoured_types = list(/obj/item/clothing, /obj/item/weapon, /obj/item/weapon/restraints)
favoured_types = list(/obj/item/clothing, /obj/item, /obj/item/restraints)
if("Janitor")
favoured_types = list(/obj/item/weapon/mop, /obj/item/weapon/reagent_containers/glass/bucket, /obj/item/weapon/reagent_containers/spray/cleaner, /obj/effect/decal/cleanable)
favoured_types = list(/obj/item/mop, /obj/item/reagent_containers/glass/bucket, /obj/item/reagent_containers/spray/cleaner, /obj/effect/decal/cleanable)
functions += "dojanitor"
if("Clown")
favoured_types = list(/obj/item/weapon/soap, /obj/item/weapon/reagent_containers/food/snacks/grown/banana, /obj/item/weapon/grown/bananapeel)
favoured_types = list(/obj/item/soap, /obj/item/reagent_containers/food/snacks/grown/banana, /obj/item/grown/bananapeel)
functions += "clowning"
if("Botanist")
favoured_types = list(/obj/machinery/hydroponics, /obj/item/weapon/reagent_containers, /obj/item/weapon)
favoured_types = list(/obj/machinery/hydroponics, /obj/item/reagent_containers, /obj/item)
functions += "botany"
restrictedJob = 1
else
@@ -403,8 +406,12 @@
if(!hud_used)
hud_used = new /datum/hud/human(src)
/mob/living/carbon/human/interactive/New(var/new_loc, var/new_species = null)
/mob/living/carbon/human/interactive/Initialize()
..()
return INITIALIZE_HINT_LATELOAD
/mob/living/carbon/human/interactive/LateInitialize()
. = ..()
snpc_list += src
create_mob_hud()
@@ -427,6 +434,7 @@
/mob/living/carbon/human/interactive/Destroy()
hear_radio_list -= src
snpc_list -= src
npc_master.removeBot(src)
return ..()
/mob/living/carbon/human/interactive/proc/retalTarget(mob/living/target)
@@ -554,10 +562,14 @@
/mob/living/carbon/human/interactive/proc/insert_into_backpack()
var/list/slots = list(slot_l_store, slot_r_store, slot_l_hand, slot_r_hand)
var/obj/item/I = get_item_by_slot(pick(slots))
var/obj/item/weapon/storage/BP = get_item_by_slot(slot_back)
var/obj/item/storage/BP = get_item_by_slot(slot_back)
if(back && BP && I)
// hack to allow SNPCs to "sticky grab" items without losing their inventorying
var/oldnodrop = I.flags | NODROP
I.flags &= ~NODROP
if(BP.can_be_inserted(I))
BP.handle_item_insertion(I)
I.flags |= oldnodrop
else
unEquip(I,TRUE)
update_hands = 1
@@ -658,7 +670,7 @@
update_hands = 0
if(grabbed_by.len > 0)
for(var/obj/item/weapon/grab/G in grabbed_by)
for(var/obj/item/grab/G in grabbed_by)
if(Adjacent(G))
a_intent = INTENT_DISARM
G.assailant.attack_hand(src)
@@ -696,8 +708,8 @@
var/obj/item/I = TARGET
if(I.anchored)
TARGET = null
else if(istype(TARGET, /obj/item/weapon))
var/obj/item/weapon/W = TARGET
else if(istype(TARGET, /obj/item))
var/obj/item/W = TARGET
if(W.force >= best_force || prob((SNPC_FUZZY_CHANCE_LOW + SNPC_FUZZY_CHANCE_HIGH) / 2) || favouredObjIn(list(W)))
if(!l_hand || !r_hand)
put_in_hands(W)
@@ -729,7 +741,7 @@
if(istype(TARGET, /obj/structure))
var/obj/structure/STR = TARGET
if(main_hand)
var/obj/item/weapon/W = main_hand
var/obj/item/W = main_hand
STR.attackby(W, src)
else
STR.attack_hand(src)
@@ -881,7 +893,7 @@
return pick(/area/hallway, /area/crew_quarters)
/mob/living/carbon/human/interactive/proc/target_filter(target)
var/list/filtered_targets = list(/area, /turf, /obj/machinery/door, /atom/movable/lighting_overlay, /obj/structure/cable, /obj/machinery/atmospherics, /obj/item/device/radio/intercom)
var/list/filtered_targets = list(/area, /turf, /obj/machinery/door, /atom/movable/lighting_overlay, /obj/structure/cable, /obj/machinery/atmospherics, /obj/item/radio/intercom)
var/list/L = target
for(var/atom/A in target) // added a bunch of "junk" that clogs up the general find procs
if(is_type_in_list(A,filtered_targets))
@@ -1,18 +1,18 @@
/mob/living/carbon/human/interactive/angry/New()
/mob/living/carbon/human/interactive/angry/Initialize(mapload)
TRAITS |= TRAIT_ROBUST
TRAITS |= TRAIT_MEAN
faction += "bot_angry"
..()
return ..()
/mob/living/carbon/human/interactive/friendly/New()
/mob/living/carbon/human/interactive/friendly/Initialize(mapload)
TRAITS |= TRAIT_FRIENDLY
TRAITS |= TRAIT_UNROBUST
faction += "bot_friendly"
faction += "neutral"
functions -= "combat"
..()
return ..()
/mob/living/carbon/human/interactive/greytide/New()
/mob/living/carbon/human/interactive/greytide/Initialize(mapload)
TRAITS |= TRAIT_ROBUST
TRAITS |= TRAIT_MEAN
TRAITS |= TRAIT_THIEVING
@@ -21,4 +21,4 @@
targetInterestShift = 2 // likewise
faction += "bot_grey"
graytide = 1
..()
return ..()
@@ -419,7 +419,7 @@
..(what, who, where, silent = is_silent)
/mob/living/carbon/human/can_equip(obj/item/I, slot, disable_warning = 0)
switch(species.handle_can_equip(I, slot, disable_warning, src))
switch(dna.species.handle_can_equip(I, slot, disable_warning, src))
if(1) return 1
if(2) return 0 //if it returns 2, it wants no normal handling
@@ -578,24 +578,24 @@
if(!disable_warning)
to_chat(src, "The [name] is too big to attach.")
return 0
if(istype(I, /obj/item/device/pda) || istype(I, /obj/item/weapon/pen) || is_type_in_list(I, wear_suit.allowed))
if(istype(I, /obj/item/pda) || istype(I, /obj/item/pen) || is_type_in_list(I, wear_suit.allowed))
return 1
return 0
if(slot_handcuffed)
if(handcuffed)
return 0
if(!istype(I, /obj/item/weapon/restraints/handcuffs))
if(!istype(I, /obj/item/restraints/handcuffs))
return 0
return 1
if(slot_legcuffed)
if(legcuffed)
return 0
if(!istype(I, /obj/item/weapon/restraints/legcuffs))
if(!istype(I, /obj/item/restraints/legcuffs))
return 0
return 1
if(slot_in_backpack)
if(back && istype(back, /obj/item/weapon/storage/backpack))
var/obj/item/weapon/storage/backpack/B = back
if(back && istype(back, /obj/item/storage/backpack))
var/obj/item/storage/backpack/B = back
if(B.contents.len < B.storage_slots && I.w_class <= B.max_w_class)
return 1
return 0
+47 -50
View File
@@ -1,4 +1,4 @@
/mob/living/carbon/human/Life()
/mob/living/carbon/human/Life(seconds, times_fired)
life_tick++
voice = GetVoice()
@@ -15,10 +15,10 @@
handle_heartbeat()
handle_heartattack()
handle_drunk()
species.handle_life(src)
dna.species.handle_life(src)
if(!client)
species.handle_npc(src)
dna.species.handle_npc(src)
if(stat != DEAD)
//Stuff jammed in your limbs hurts
@@ -32,7 +32,7 @@
//Update our name based on whether our face is obscured/disfigured
name = get_visible_name()
pulse = handle_pulse()
pulse = handle_pulse(times_fired)
if(mind && mind.vampire)
mind.vampire.handle_vampire()
@@ -150,7 +150,7 @@
AdjustSilence(2)
if(getBrainLoss() >= 120 && stat != 2) //they died from stupidity--literally. -Fox
visible_message("<span class='alert'><B>[src]</B> goes limp, their facial expression utterly blank.</span>")
visible_message("<span class='alert'><B>[src]</B> goes limp, [p_their()] facial expression utterly blank.</span>")
death()
/mob/living/carbon/human/handle_mutations_and_radiation()
@@ -178,7 +178,7 @@
if(gene_stability < GENETIC_DAMAGE_STAGE_3)
gib()
if(!(RADIMMUNE in species.species_traits))
if(!(RADIMMUNE in dna.species.species_traits))
if(radiation)
radiation = Clamp(radiation, 0, 200)
@@ -238,7 +238,7 @@
chest.add_autopsy_data("Radiation Poisoning", autopsy_damage)
/mob/living/carbon/human/breathe()
if(!species.breathe(src))
if(!dna.species.breathe(src))
..()
/mob/living/carbon/human/check_breath(datum/gas_mixture/breath)
@@ -253,8 +253,8 @@
failed_last_breath = TRUE
if(species)
var/datum/species/S = species
if(dna.species)
var/datum/species/S = dna.species
if(S.breathid == "o2")
throw_alert("not_enough_oxy", /obj/screen/alert/not_enough_oxy)
@@ -287,8 +287,8 @@
if(!(head && head.flags & AIRTIGHT)) //if NOT (head AND head.flags CONTAIN AIRTIGHT)
null_internals = 1 //not wearing a mask or suitable helmet
if(istype(back, /obj/item/weapon/rig)) //wearing a rigsuit
var/obj/item/weapon/rig/rig = back //needs to be typecasted because this doesn't use get_rig() for some reason
if(istype(back, /obj/item/rig)) //wearing a rigsuit
var/obj/item/rig/rig = back //needs to be typecasted because this doesn't use get_rig() for some reason
if(rig.offline && (rig.air_supply && internal == rig.air_supply)) //if rig IS offline AND (rig HAS air_supply AND internal IS air_supply)
null_internals = 1 //offline suits do not breath
@@ -332,39 +332,39 @@
bodytemperature += min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX)
// +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt.
if(bodytemperature > species.heat_level_1)
if(bodytemperature > dna.species.heat_level_1)
//Body temperature is too hot.
if(status_flags & GODMODE) return 1 //godmode
var/mult = species.heatmod
var/mult = dna.species.heatmod
if(bodytemperature >= species.heat_level_1 && bodytemperature <= species.heat_level_2)
if(bodytemperature >= dna.species.heat_level_1 && bodytemperature <= dna.species.heat_level_2)
throw_alert("temp", /obj/screen/alert/hot, 1)
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature")
if(bodytemperature > species.heat_level_2 && bodytemperature <= species.heat_level_3)
if(bodytemperature > dna.species.heat_level_2 && bodytemperature <= dna.species.heat_level_3)
throw_alert("temp", /obj/screen/alert/hot, 2)
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
if(bodytemperature > species.heat_level_3 && bodytemperature < INFINITY)
if(bodytemperature > dna.species.heat_level_3 && bodytemperature < INFINITY)
throw_alert("temp", /obj/screen/alert/hot, 3)
if(on_fire)
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_3, used_weapon = "Fire")
else
take_overall_damage(burn=mult*HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
else if(bodytemperature < species.cold_level_1)
else if(bodytemperature < dna.species.cold_level_1)
if(status_flags & GODMODE)
return 1
if(stat == DEAD)
return 1
if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
var/mult = species.coldmod
if(bodytemperature >= species.cold_level_2 && bodytemperature <= species.cold_level_1)
var/mult = dna.species.coldmod
if(bodytemperature >= dna.species.cold_level_2 && bodytemperature <= dna.species.cold_level_1)
throw_alert("temp", /obj/screen/alert/cold, 1)
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_1, used_weapon = "Low Body Temperature")
if(bodytemperature >= species.cold_level_3 && bodytemperature < species.cold_level_2)
if(bodytemperature >= dna.species.cold_level_3 && bodytemperature < dna.species.cold_level_2)
throw_alert("temp", /obj/screen/alert/cold, 2)
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_2, used_weapon = "Low Body Temperature")
if(bodytemperature > -INFINITY && bodytemperature < species.cold_level_3)
if(bodytemperature > -INFINITY && bodytemperature < dna.species.cold_level_3)
throw_alert("temp", /obj/screen/alert/cold, 3)
take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_3, used_weapon = "Low Body Temperature")
else
@@ -379,18 +379,18 @@
var/adjusted_pressure = calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob.
if(status_flags & GODMODE) return 1 //godmode
if(adjusted_pressure >= species.hazard_high_pressure)
if(adjusted_pressure >= dna.species.hazard_high_pressure)
if(!(HEATRES in mutations))
var/pressure_damage = min( ( (adjusted_pressure / species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE)
var/pressure_damage = min( ( (adjusted_pressure / dna.species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE)
take_overall_damage(brute=pressure_damage, used_weapon = "High Pressure")
throw_alert("pressure", /obj/screen/alert/highpressure, 2)
else
clear_alert("pressure")
else if(adjusted_pressure >= species.warning_high_pressure)
else if(adjusted_pressure >= dna.species.warning_high_pressure)
throw_alert("pressure", /obj/screen/alert/highpressure, 1)
else if(adjusted_pressure >= species.warning_low_pressure)
else if(adjusted_pressure >= dna.species.warning_low_pressure)
clear_alert("pressure")
else if(adjusted_pressure >= species.hazard_low_pressure)
else if(adjusted_pressure >= dna.species.hazard_low_pressure)
throw_alert("pressure", /obj/screen/alert/lowpressure, 1)
else
if(COLDRES in mutations)
@@ -430,13 +430,13 @@
//END FIRE CODE
/mob/living/carbon/human/proc/stabilize_temperature_from_calories()
var/body_temperature_difference = species.body_temperature - bodytemperature
var/body_temperature_difference = dna.species.body_temperature - bodytemperature
if(bodytemperature <= species.cold_level_1) //260.15 is 310.15 - 50, the temperature where you start to feel effects.
if(bodytemperature <= dna.species.cold_level_1) //260.15 is 310.15 - 50, the temperature where you start to feel effects.
bodytemperature += max((body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM)
if(bodytemperature >= species.cold_level_1 && bodytemperature <= species.heat_level_1)
if(bodytemperature >= dna.species.cold_level_1 && bodytemperature <= dna.species.heat_level_1)
bodytemperature += body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR
if(bodytemperature >= species.heat_level_1) //360.15 is 310.15 + 50, the temperature where you start to feel effects.
if(bodytemperature >= dna.species.heat_level_1) //360.15 is 310.15 + 50, the temperature where you start to feel effects.
//We totally need a sweat system cause it totally makes sense...~
bodytemperature += min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers
@@ -588,7 +588,7 @@
return 0 //godmode
//The fucking FAT mutation is the greatest shit ever. It makes everyone so hot and bothered.
if(CAN_BE_FAT in species.species_traits)
if(CAN_BE_FAT in dna.species.species_traits)
if(FAT in mutations)
if(overeatduration < 100)
becomeSlim()
@@ -652,7 +652,7 @@
AdjustDizzy(-3)
AdjustJitter(-3)
if(NO_INTORGANS in species.species_traits)
if(NO_INTORGANS in dna.species.species_traits)
return
handle_trace_chems()
@@ -766,10 +766,10 @@
//Vision //god knows why this is here
var/obj/item/organ/vision
if(species.vision_organ)
vision = get_int_organ(species.vision_organ)
if(dna.species.vision_organ)
vision = get_int_organ(dna.species.vision_organ)
if(!species.vision_organ) // Presumably if a species has no vision organs, they see via some other means.
if(!dna.species.vision_organ) // Presumably if a species has no vision organs, they see via some other means.
SetEyeBlind(0)
blinded = 0
SetEyeBlurry(0)
@@ -832,7 +832,8 @@
/mob/living/carbon/human/handle_vision()
if(machine)
if(!machine.check_eye(src)) reset_perspective(null)
if(!machine.check_eye(src))
reset_perspective(null)
else
var/isRemoteObserve = 0
if((REMOTE_VIEW in mutations) && remoteview_target)
@@ -859,10 +860,10 @@
remoteview_target = null
reset_perspective(null)
species.handle_vision(src)
dna.species.handle_vision(src)
/mob/living/carbon/human/handle_hud_icons()
species.handle_hud_icons(src)
dna.species.handle_hud_icons(src)
/mob/living/carbon/human/handle_random_events()
// Puke if toxloss is too high
@@ -902,12 +903,11 @@
hud_used.lingchemdisplay.invisibility = 101
/mob/living/carbon/human/proc/handle_pulse()
if(mob_master.current_cycle % 5)
/mob/living/carbon/human/proc/handle_pulse(times_fired)
if(times_fired % 5 == 1)
return pulse //update pulse every 5 life ticks (~1 tick/sec, depending on server load)
if(NO_BLOOD in species.species_traits)
if(NO_BLOOD in dna.species.species_traits)
return PULSE_NONE //No blood, no pulse.
if(stat == DEAD)
@@ -977,7 +977,7 @@
var/obj/item/clothing/mask/M = H.wear_mask
if(M && (M.flags_cover & MASKCOVERSMOUTH))
return
if(NO_BREATHE in H.species.species_traits)
if(NO_BREATHE in H.dna.species.species_traits)
return //no puking if you can't smell!
// Humans can lack a mind datum, y'know
if(H.mind && (H.mind.assigned_role == "Detective" || H.mind.assigned_role == "Coroner"))
@@ -993,7 +993,7 @@
if(!H) //H.status will runtime if there is no H (obviously)
return
if(H.status & ORGAN_ROBOT) //Handle robotic hearts specially with a wuuuubb. This also applies to machine-people.
if(H.is_robotic()) //Handle robotic hearts specially with a wuuuubb. This also applies to machine-people.
if(shock_stage >= 10 || istype(get_turf(src), /turf/space))
//PULSE_THREADY - maximum value for pulse, currently it 5.
//High pulse value corresponds to a fast rate of heartbeat.
@@ -1020,10 +1020,7 @@
if(heartbeat >= rate)
heartbeat = 0
if(H.status & ORGAN_ASSISTED)
src << sound('sound/effects/pacemakebeat.ogg',0,0,CHANNEL_HEARTBEAT,50)
else
src << sound('sound/effects/singlebeat.ogg',0,0,CHANNEL_HEARTBEAT,50)
src << sound('sound/effects/singlebeat.ogg',0,0,CHANNEL_HEARTBEAT,50)
else
heartbeat++
@@ -1057,9 +1054,9 @@
/mob/living/carbon/human/proc/can_heartattack()
if(NO_BLOOD in species.species_traits)
if(NO_BLOOD in dna.species.species_traits)
return FALSE
if(NO_INTORGANS in species.species_traits)
if(NO_INTORGANS in dna.species.species_traits)
return FALSE
return TRUE
@@ -1,7 +1,7 @@
/mob/living/carbon/human/Login()
..()
if(species && species.ventcrawler)
if(dna.species && dna.species.ventcrawler)
to_chat(src, "<span class='notice'>You can ventcrawl! Use alt+click on vents to quickly travel about the station.</span>")
update_pipe_vision()
return
+4 -5
View File
@@ -5,9 +5,8 @@
item_color = "punpun"
species_restricted = list("Monkey")
/mob/living/carbon/human/monkey/punpun/New()
/mob/living/carbon/human/monkey/punpun/Initialize(mapload)
..()
spawn(1)
name = "Pun Pun"
real_name = name
equip_to_slot(new /obj/item/clothing/under/punpun(src), slot_w_uniform)
name = "Pun Pun"
real_name = name
equip_to_slot(new /obj/item/clothing/under/punpun(src), slot_w_uniform)
+13 -13
View File
@@ -42,7 +42,7 @@
if(has_brain_worms()) //Brain worms translate everything. Even mice and alien speak.
return 1
if(species.can_understand(other))
if(dna.species.can_understand(other))
return 1
//These only pertain to common. Languages are handled by mob/say_understands()
@@ -62,8 +62,8 @@
return ..()
/mob/living/carbon/human/proc/HasVoiceChanger()
if(istype(back,/obj/item/weapon/rig))
var/obj/item/weapon/rig/rig = back
if(istype(back,/obj/item/rig))
var/obj/item/rig/rig = back
if(rig.speech && rig.speech.voice_holder && rig.speech.voice_holder.active && rig.speech.voice_holder.voice)
return rig.speech.voice_holder.voice
@@ -87,7 +87,7 @@
/mob/living/carbon/human/IsVocal()
// how do species that don't breathe talk? magic, that's what.
var/breathes = (!(NO_BREATHE in species.species_traits))
var/breathes = (!(NO_BREATHE in dna.species.species_traits))
var/obj/item/organ/internal/L = get_organ_slot("lungs")
if((breathes && !L) || breathes && L && (L.status & ORGAN_DEAD))
return FALSE
@@ -163,13 +163,13 @@
/mob/living/carbon/human/handle_message_mode(var/message_mode, var/message, var/verb, var/speaking, var/used_radios, var/alt_name)
switch(message_mode)
if("intercom")
for(var/obj/item/device/radio/intercom/I in view(1, src))
for(var/obj/item/radio/intercom/I in view(1, src))
spawn(0)
I.talk_into(src, message, null, verb, speaking)
used_radios += I
if("headset")
var/obj/item/device/radio/R = null
var/obj/item/radio/R = null
if(isradio(l_ear))
R = l_ear
used_radios += R
@@ -183,7 +183,7 @@
return
if("right ear")
var/obj/item/device/radio/R
var/obj/item/radio/R
if(isradio(r_ear))
R = r_ear
else if(isradio(r_hand))
@@ -193,7 +193,7 @@
R.talk_into(src, message, null, verb, speaking)
if("left ear")
var/obj/item/device/radio/R
var/obj/item/radio/R
if(isradio(l_ear))
R = l_ear
else if(isradio(l_hand))
@@ -219,20 +219,20 @@
/mob/living/carbon/human/handle_speech_sound()
var/list/returns[2]
if(species.speech_sounds && prob(species.speech_chance))
returns[1] = sound(pick(species.speech_sounds))
if(dna.species.speech_sounds && prob(dna.species.speech_chance))
returns[1] = sound(pick(dna.species.speech_sounds))
returns[2] = 50
return returns
/mob/living/carbon/human/binarycheck()
. = FALSE
var/obj/item/device/radio/headset/R
if(istype(l_ear, /obj/item/device/radio/headset))
var/obj/item/radio/headset/R
if(istype(l_ear, /obj/item/radio/headset))
R = l_ear
if(R.translate_binary)
. = TRUE
if(istype(r_ear, /obj/item/device/radio/headset))
if(istype(r_ear, /obj/item/radio/headset))
R = r_ear
if(R.translate_binary)
. = TRUE
@@ -23,7 +23,7 @@
/mob/living/carbon/human/proc/handle_shock()
if(status_flags & GODMODE) //godmode
return
if(NO_PAIN in species.species_traits)
if(NO_PAIN in dna.species.species_traits)
return
updateshock()
@@ -43,7 +43,7 @@
if(shock_stage >= 30)
if(shock_stage == 30)
custom_emote(1,"is having trouble keeping their eyes open.")
custom_emote(1,"is having trouble keeping [p_their()] eyes open.")
EyeBlurry(2)
Stuttering(5)
@@ -1,11 +1,6 @@
/*
Datum-based species. Should make for much cleaner and easier to maintain mutantrace code.
*/
/datum/species
var/name // Species name.
var/name_plural // Pluralized name (since "[name]s" is not always valid)
var/path // Species path
var/icobase = 'icons/mob/human_races/r_human.dmi' // Normal icon set.
var/deform = 'icons/mob/human_races/r_def_human.dmi' // Mutated icon set.
@@ -18,10 +13,10 @@
var/blurb = "A completely nondescript species." // A brief lore summary for use in the chargen screen.
var/butt_sprite = "human"
var/primitive_form // Lesser form, if any (ie. monkey for humans)
var/greater_form // Greater form, if any, ie. human for monkeys.
var/datum/species/primitive_form = null // Lesser form, if any (ie. monkey for humans)
var/datum/species/greater_form = null // Greater form, if any, ie. human for monkeys.
var/tail // Name of tail image in species effects icon file.
var/unarmed //For empty hand harm-intent attack
var/datum/unarmed_attack/unarmed //For empty hand harm-intent attack
var/unarmed_type = /datum/unarmed_attack
var/slowdown = 0 // Passive movement speed malus (or boost, if negative)
var/silent_steps = 0 // Stops step noises
@@ -80,6 +75,7 @@
var/clothing_flags = 0 // Underwear and socks.
var/exotic_blood
var/skinned_type
var/bodyflags = 0
var/dietflags = 0 // Make sure you set this, otherwise it won't be able to digest a lot of foods
@@ -94,6 +90,7 @@
//Used in icon caching.
var/race_key = 0
var/icon/icon_template
var/is_small
var/show_ssd = 1
var/can_revive_by_healing // Determines whether or not this species can be revived by simply healing them
@@ -165,11 +162,11 @@
unarmed = new unarmed_type()
/datum/species/proc/get_random_name(var/gender)
/datum/species/proc/get_random_name(gender)
var/datum/language/species_language = all_languages[language]
return species_language.get_random_name(gender)
/datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs.
/datum/species/proc/create_organs(mob/living/carbon/human/H) //Handles creation of mob organs.
QDEL_LIST(H.internal_organs)
QDEL_LIST(H.bodyparts)
@@ -262,28 +259,24 @@
. -= 2
return .
/datum/species/proc/handle_post_spawn(var/mob/living/carbon/C) //Handles anything not already covered by basic species assignment.
/datum/species/proc/handle_post_spawn(mob/living/carbon/C) //Handles anything not already covered by basic species assignment.
grant_abilities(C)
/datum/species/proc/updatespeciescolor(mob/living/carbon/human/H) //Handles changing icobase for species that have multiple skin colors.
return
/datum/species/proc/updatespeciescolor(var/mob/living/carbon/human/H) //Handles changing icobase for species that have multiple skin colors.
return
/datum/species/proc/grant_abilities(var/mob/living/carbon/human/H)
/datum/species/proc/grant_abilities(mob/living/carbon/human/H)
for(var/proc/ability in species_abilities)
H.verbs += ability
return
/datum/species/proc/handle_pre_change(var/mob/living/carbon/human/H)
if(H.butcher_results)//clear it out so we don't butcher a actual human.
/datum/species/proc/handle_pre_change(mob/living/carbon/human/H)
if(H.butcher_results) //clear it out so we don't butcher a actual human.
H.butcher_results = null
remove_abilities(H)
return
/datum/species/proc/remove_abilities(var/mob/living/carbon/human/H)
/datum/species/proc/remove_abilities(mob/living/carbon/human/H)
for(var/proc/ability in species_abilities)
H.verbs -= ability
return
// Do species-specific reagent handling here
// Return 1 if it should do normal processing too
@@ -294,29 +287,184 @@
if(R.id == exotic_blood)
H.blood_volume = min(H.blood_volume + round(R.volume, 0.1), BLOOD_VOLUME_NORMAL)
H.reagents.del_reagent(R.id)
return 0
return 1
return FALSE
return TRUE
// For special snowflake species effects
// (Slime People changing color based on the reagents they consume)
/datum/species/proc/handle_life(var/mob/living/carbon/human/H)
/datum/species/proc/handle_life(mob/living/carbon/human/H)
if((NO_BREATHE in species_traits) || (BREATHLESS in H.mutations))
H.setOxyLoss(0)
H.SetLoseBreath(0)
/datum/species/proc/handle_dna(var/mob/living/carbon/C, var/remove) //Handles DNA mutations, as that doesn't work at init. Make sure you call genemutcheck on any blocks changed here
/datum/species/proc/handle_dna(mob/living/carbon/C, remove) //Handles DNA mutations, as that doesn't work at init. Make sure you call genemutcheck on any blocks changed here
return
// Used for species-specific names (Vox, etc)
/datum/species/proc/makeName(var/gender,var/mob/living/carbon/human/H=null)
if(gender==FEMALE) return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names))
else return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
/datum/species/proc/handle_death(var/mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns).
/datum/species/proc/handle_death(mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns).
return
/datum/species/proc/handle_attack_hand(var/mob/living/carbon/human/H, var/mob/living/carbon/human/M) //Handles any species-specific attackhand events.
return
/datum/species/proc/help(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
if(attacker_style && attacker_style.help_act(user, target))//adminfu only...
return TRUE
if(target.health >= config.health_threshold_crit)
target.help_shake_act(user)
return TRUE
else
user.do_cpr(target)
/datum/species/proc/grab(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
if(attacker_style && attacker_style.grab_act(user, target))
return TRUE
else
target.grabbedby(user)
return TRUE
/datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
//Vampire code
if(user.mind && user.mind.vampire && (user.mind in ticker.mode.vampires) && !user.mind.vampire.draining && user.zone_sel && user.zone_sel.selecting == "head" && target != user)
if((NO_BLOOD in target.dna.species.species_traits) || target.dna.species.exotic_blood || !target.blood_volume)
to_chat(user, "<span class='warning'>They have no blood!</span>")
return
if(target.mind && target.mind.vampire && (target.mind in ticker.mode.vampires))
to_chat(user, "<span class='warning'>Your fangs fail to pierce [target.name]'s cold flesh</span>")
return
if(SKELETON in target.mutations)
to_chat(user, "<span class='warning'>There is no blood in a skeleton!</span>")
return
if(issmall(target) && !target.ckey) //Monkeyized humans are okay, humanized monkeys are okay, NPC monkeys are not.
to_chat(user, "<span class='warning'>Blood from a monkey is useless!</span>")
return
//we're good to suck the blood, blaah
user.mind.vampire.handle_bloodsucking(target)
add_attack_logs(user, target, "vampirebit")
return
//end vampire codes
if(attacker_style && attacker_style.harm_act(user, target))
return TRUE
else
var/datum/unarmed_attack/attack = user.dna.species.unarmed
user.do_attack_animation(target, attack.animation_type)
add_attack_logs(user, target, "Melee attacked with fists", target.ckey ? null : ATKLOG_ALL)
if(!iscarbon(user))
target.LAssailant = null
else
target.LAssailant = user
var/damage = rand(user.dna.species.punchdamagelow, user.dna.species.punchdamagehigh)
damage += attack.damage
if(!damage)
playsound(target.loc, attack.miss_sound, 25, 1, -1)
target.visible_message("<span class='danger'>[user] tried to [pick(attack.attack_verb)] [target]!</span>")
return FALSE
var/obj/item/organ/external/affecting = target.get_organ(ran_zone(user.zone_sel.selecting))
var/armor_block = target.run_armor_check(affecting, "melee")
playsound(target.loc, attack.attack_sound, 25, 1, -1)
target.visible_message("<span class='danger'>[user] [pick(attack.attack_verb)]ed [target]!</span>")
target.apply_damage(damage, BRUTE, affecting, armor_block, sharp = attack.sharp) //moving this back here means Armalis are going to knock you down 70% of the time, but they're pure adminbus anyway.
if((target.stat != DEAD) && damage >= user.dna.species.punchstunthreshold)
target.visible_message("<span class='danger'>[user] has weakened [target]!</span>", \
"<span class='userdanger'>[user] has weakened [target]!</span>")
target.apply_effect(4, WEAKEN, armor_block)
target.forcesay(hit_appends)
else if(target.lying)
target.forcesay(hit_appends)
/datum/species/proc/disarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
if(attacker_style && attacker_style.disarm_act(user, target))
return TRUE
else
add_attack_logs(user, target, "Disarmed", ATKLOG_ALL)
user.do_attack_animation(target, ATTACK_EFFECT_DISARM)
if(target.w_uniform)
target.w_uniform.add_fingerprint(user)
var/obj/item/organ/external/affecting = target.get_organ(ran_zone(user.zone_sel.selecting))
var/randn = rand(1, 100)
if(randn <= 25)
target.apply_effect(2, WEAKEN, target.run_armor_check(affecting, "melee"))
playsound(target.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
target.visible_message("<span class='danger'>[user] has pushed [target]!</span>")
add_attack_logs(user, target, "Pushed over", ATKLOG_ALL)
if(!iscarbon(user))
target.LAssailant = null
else
target.LAssailant = user
return
var/talked = 0 // BubbleWrap
if(randn <= 60)
//BubbleWrap: Disarming breaks a pull
if(target.pulling)
target.visible_message("<span class='danger'>[user] has broken [target]'s grip on [target.pulling]!</span>")
talked = 1
target.stop_pulling()
//BubbleWrap: Disarming also breaks a grab - this will also stop someone being choked, won't it?
if(istype(target.l_hand, /obj/item/grab))
var/obj/item/grab/lgrab = target.l_hand
if(lgrab.affecting)
target.visible_message("<span class='danger'>[user] has broken [target]'s grip on [lgrab.affecting]!</span>")
talked = 1
spawn(1)
qdel(lgrab)
if(istype(target.r_hand, /obj/item/grab))
var/obj/item/grab/rgrab = target.r_hand
if(rgrab.affecting)
target.visible_message("<span class='danger'>[user] has broken [target]'s grip on [rgrab.affecting]!</span>")
talked = 1
spawn(1)
qdel(rgrab)
//End BubbleWrap
if(!talked) //BubbleWrap
if(target.drop_item())
target.visible_message("<span class='danger'>[user] has disarmed [target]!</span>")
playsound(target.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
return
playsound(target.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
target.visible_message("<span class='danger'>[user] attempted to disarm [target]!</span>")
/datum/species/proc/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art) //Handles any species-specific attackhand events.
if(!istype(M))
return
if(H.frozen)
to_chat(M, "<span class='warning'>Do not touch Admin-Frozen people.</span>")
return
if(istype(M))
var/obj/item/organ/external/temp = M.bodyparts_by_name["r_hand"]
if(M.hand)
temp = M.bodyparts_by_name["l_hand"]
if(!temp || !temp.is_usable())
to_chat(M, "<span class='warning'>You can't use your hand.</span>")
return
if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(0, M.name, attack_type = UNARMED_ATTACK))
add_attack_logs(M, H, "Melee attacked with fists (miss/block)")
H.visible_message("<span class='warning'>[M] attempted to touch [H]!</span>")
return FALSE
switch(M.a_intent)
if(INTENT_HELP)
help(M, H, attacker_style)
if(INTENT_GRAB)
grab(M, H, attacker_style)
if(INTENT_HARM)
harm(M, H, attacker_style)
if(INTENT_DISARM)
disarm(M, H, attacker_style)
/datum/species/proc/say_filter(mob/M, message, datum/language/speaking)
return message
@@ -327,27 +475,22 @@
/datum/species/proc/after_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE)
return
/datum/species/proc/can_understand(var/mob/other)
/datum/species/proc/can_understand(mob/other)
return
// Called in life() when the mob has no client.
/datum/species/proc/handle_npc(var/mob/living/carbon/human/H)
/datum/species/proc/handle_npc(mob/living/carbon/human/H)
return
//Species unarmed attacks
/datum/unarmed_attack
var/attack_verb = list("attack") // Empty hand hurt intent verb.
var/attack_verb = list("punch") // Empty hand hurt intent verb.
var/damage = 0 // How much flat bonus damage an attack will do. This is a *bonus* guaranteed damage amount on top of the random damage attacks do.
var/attack_sound = "punch"
var/miss_sound = 'sound/weapons/punchmiss.ogg'
var/sharp = 0
/datum/unarmed_attack/punch
attack_verb = list("punch")
/datum/unarmed_attack/punch/weak
attack_verb = list("flail")
var/sharp = FALSE
var/animation_type = ATTACK_EFFECT_PUNCH
/datum/unarmed_attack/diona
attack_verb = list("lash", "bludgeon")
@@ -356,14 +499,21 @@
attack_verb = list("scratch", "claw")
attack_sound = 'sound/weapons/slice.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
sharp = 1
sharp = TRUE
animation_type = ATTACK_EFFECT_CLAW
/datum/unarmed_attack/bite
attack_verb = list("chomp")
attack_sound = 'sound/weapons/bite.ogg'
sharp = TRUE
animation_type = ATTACK_EFFECT_BITE
/datum/unarmed_attack/claws/armalis
attack_verb = list("slash", "claw")
damage = 6
/datum/species/proc/handle_can_equip(obj/item/I, slot, disable_warning = 0, mob/living/carbon/human/user)
return 0
return FALSE
/datum/species/proc/handle_vision(mob/living/carbon/human/H)
// Right now this just handles blind, blurry, and similar states
@@ -469,7 +619,7 @@ Returns the path corresponding to the corresponding organ
It'll return null if the organ doesn't correspond, so include null checks when using this!
*/
//Fethas Todo:Do i need to redo this?
/datum/species/proc/return_organ(var/organ_slot)
/datum/species/proc/return_organ(organ_slot)
if(!(organ_slot in has_organ))
return null
return has_organ[organ_slot]
@@ -534,8 +684,8 @@ It'll return null if the organ doesn't correspond, so include null checks when u
if(hat.helmet_goggles_invis_view)
H.see_invisible = min(hat.helmet_goggles_invis_view, H.see_invisible)
if(istype(H.back, /obj/item/weapon/rig)) ///aghhh so snowflakey
var/obj/item/weapon/rig/rig = H.back
if(istype(H.back, /obj/item/rig)) ///aghhh so snowflakey
var/obj/item/rig/rig = H.back
if(rig.visor)
if(!rig.helmet || (H.head && rig.helmet == H.head))
if(rig.visor && rig.visor.vision && rig.visor.active && rig.visor.vision.glasses)
@@ -567,4 +717,4 @@ It'll return null if the organ doesn't correspond, so include null checks when u
/datum/species/proc/water_act(mob/living/carbon/human/M, volume, temperature, source)
if(abs(temperature - M.bodytemperature) > 10) //If our water and mob temperature varies by more than 10K, cool or/ heat them appropriately
M.bodytemperature = (temperature + M.bodytemperature) * 0.5 //Approximation for gradual heating or cooling
M.bodytemperature = (temperature + M.bodytemperature) * 0.5 //Approximation for gradual heating or cooling
@@ -3,10 +3,8 @@
name_plural = "Abductors"
icobase = 'icons/mob/human_races/r_abductor.dmi'
deform = 'icons/mob/human_races/r_abductor.dmi'
path = /mob/living/carbon/human/abductor
language = "Abductor Mindlink"
default_language = "Abductor Mindlink"
unarmed_type = /datum/unarmed_attack/punch
eyes = "blank_eyes"
has_organ = list(
"heart" = /obj/item/organ/internal/heart,
@@ -17,7 +15,7 @@
"eyes" = /obj/item/organ/internal/eyes/abductor //3 darksight.
)
species_traits = list(NO_BLOOD, NO_BREATHE, VIRUSIMMUNE, NOGUNS)
species_traits = list(NO_BLOOD, NO_BREATHE, VIRUSIMMUNE, NOGUNS, NO_EXAMINE)
oxy_mod = 0
@@ -28,14 +26,21 @@
female_scream_sound = 'sound/goonstation/voice/male_scream.ogg'
female_cough_sounds = list('sound/effects/mob_effects/m_cougha.ogg','sound/effects/mob_effects/m_coughb.ogg', 'sound/effects/mob_effects/m_coughc.ogg')
female_sneeze_sound = 'sound/effects/mob_effects/sneeze.ogg' //Abductors always scream like guys
var/team = 1
var/scientist = FALSE // vars to not pollute spieces list with castes
/datum/species/abductor/can_understand(mob/other) //Abductors can understand everyone, but they can only speak over their mindlink to another team-member
return 1
return TRUE
/datum/species/abductor/handle_post_spawn(mob/living/carbon/human/H)
H.gender = NEUTER
if(H.mind)
H.mind.abductor = new /datum/abductor
H.languages.Cut() //Under no condition should you be able to speak any language
H.add_language("Abductor Mindlink") //other than over the abductor's own mindlink
var/datum/atom_hud/abductor_hud = huds[DATA_HUD_ABDUCTOR]
abductor_hud.add_hud_to(H)
return ..()
/datum/species/abductor/remove_abilities(mob/living/carbon/human/H)
..()
var/datum/atom_hud/abductor_hud = huds[DATA_HUD_ABDUCTOR]
abductor_hud.remove_hud_from(H)
@@ -1,127 +0,0 @@
/datum/species/wryn
name = "Wryn"
name_plural = "Wryn"
icobase = 'icons/mob/human_races/r_wryn.dmi'
deform = 'icons/mob/human_races/r_wryn.dmi'
language = "Wryn Hivemind"
tail = "wryntail"
unarmed_type = /datum/unarmed_attack/punch/weak
punchdamagelow = 0
punchdamagehigh = 1
//primitive = /mob/living/carbon/monkey/wryn
slowdown = 1
warning_low_pressure = -300
hazard_low_pressure = 1
blurb = "The wryn (r-in, singular r-in) are a humanoid race that possess many bee-like features. Originating from Alveare they \
have adapted extremely well to cold environments though have lost most of their muscles over generations.\
In order to communicate and work with multi-species crew Wryn were forced to take on names. Wryn have tended towards using only \
first names, these names are generally simplistic and easy to pronounce. Wryn have rarely had to communicate using their mouths, \
so in order to integrate with the multi-species crew they have been taught broken sol?."
cold_level_1 = 200 //Default 260 - Lower is better
cold_level_2 = 150 //Default 200
cold_level_3 = 115 //Default 120
heat_level_1 = 300 //Default 360 - Higher is better
heat_level_2 = 310 //Default 400
heat_level_3 = 317 //Default 1000
body_temperature = 286
has_organ = list(
"heart" = /obj/item/organ/internal/heart,
"brain" = /obj/item/organ/internal/brain,
"eyes" = /obj/item/organ/internal/eyes/wryn, //3 darksight.
"appendix" = /obj/item/organ/internal/appendix,
"antennae" = /obj/item/organ/internal/wryn/hivenode
)
species_traits = list(IS_WHITELISTED, NO_BREATHE, HAS_SKIN_COLOR, NO_SCAN, HIVEMIND)
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
dietflags = DIET_HERB //bees feed off nectar, so bee people feed off plants too
oxy_mod = 0
reagent_tag = PROCESS_ORG
base_color = "#704300"
flesh_color = "#704300"
blood_color = "#FFFF99"
//Default styles for created mobs.
default_hair = "Antennae"
/datum/species/wryn/handle_death(var/mob/living/carbon/human/H)
for(var/mob/living/carbon/C in living_mob_list)
if(C.get_int_organ(/obj/item/organ/internal/wryn/hivenode))
to_chat(C, "<span class='danger'><B>Your antennae tingle as you are overcome with pain...</B></span>")
to_chat(C, "<span class='danger'>It feels like part of you has died.</span>")
/datum/species/wryn/handle_attack_hand(var/mob/living/carbon/human/H, var/mob/living/carbon/human/M)
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
if(M.a_intent == INTENT_HARM)
if(H.handcuffed)
if(!H.get_int_organ(/obj/item/organ/internal/wryn/hivenode)) return
var/turf/p_loc = M.loc
var/turf/p_loc_m = H.loc
M.visible_message("<span class='notice'>[M] begins to violently pull off [H]'s antennae.</span>")
to_chat(H, "<span class='danger'><B>[M] grips your antennae and starts violently pulling!<B></span>")
if(do_after(H, 250, target = src))
if(p_loc == M.loc && p_loc_m == H.loc)
var/obj/item/organ/internal/wryn/hivenode/node = new /obj/item/organ/internal/wryn/hivenode
H.remove_language("Wryn Hivemind")
node.remove(H)
node.loc = M.loc
to_chat(M, "<span class='notice'>You hear a loud crunch as you mercilessly pull off [H]'s antennae.</span>")
to_chat(H, "<span class='danger'>You hear a loud crunch as your antennae is ripped off your head by [M].</span>")
to_chat(H, "<span class='danger'><span class='danger'><B>It's so quiet...</B></span>")
head_organ.h_style = "Bald"
H.update_hair()
M.create_attack_log("<font color='red'>removed antennae [H.name] ([H.ckey])</font>")
H.create_attack_log("<font color='orange'>Has had their antennae removed by [M.name] ([M.ckey])</font>")
msg_admin_attack("[key_name(M)] removed [key_name(H)]'s antennae")
return 0
/datum/species/nucleation
name = "Nucleation"
name_plural = "Nucleations"
icobase = 'icons/mob/human_races/r_nucleation.dmi'
unarmed_type = /datum/unarmed_attack/punch
blurb = "A sub-race of unfortunates who have been exposed to too much supermatter radiation. As a result, \
supermatter crystal clusters have begun to grow across their bodies. Research to find a cure for this ailment \
has been slow, and so this is a common fate for veteran engineers. The supermatter crystals produce oxygen, \
negating the need for the individual to breathe. Their massive change in biology, however, renders most medicines \
obselete. Ionizing radiation seems to cause resonance in some of their crystals, which seems to encourage regeneration \
and produces a calming effect on the individual. Nucleations are highly stigmatized, and are treated much in the same \
way as lepers were back on Earth."
language = "Sol Common"
burn_mod = 4 // holy shite, poor guys wont survive half a second cooking smores
brute_mod = 2 // damn, double wham, double dam
oxy_mod = 0
species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_BLOOD, NO_PAIN, NO_SCAN, RADIMMUNE)
dietflags = DIET_OMNI //still human at their core, so they maintain their eating habits and diet
//Default styles for created mobs.
default_hair = "Nucleation Crystals"
reagent_tag = PROCESS_ORG
has_organ = list(
"heart" = /obj/item/organ/internal/heart,
"crystallized brain" = /obj/item/organ/internal/brain/crystal,
"eyes" = /obj/item/organ/internal/eyes/luminescent_crystal, //Standard darksight of 2.
"strange crystal" = /obj/item/organ/internal/nucleation/strange_crystal
)
vision_organ = /obj/item/organ/internal/eyes/luminescent_crystal
/datum/species/nucleation/handle_post_spawn(var/mob/living/carbon/human/H)
H.light_color = "#1C1C00"
H.set_light(2)
return ..()
/datum/species/nucleation/handle_death(var/mob/living/carbon/human/H)
var/turf/T = get_turf(H)
H.visible_message("<span class='warning'>[H]'s body explodes, leaving behind a pile of microscopic crystals!</span>")
explosion(T, 0, 0, 2, 2) // Create a small explosion burst upon death
// new /obj/item/weapon/shard/supermatter( T )
qdel(H)
@@ -0,0 +1,114 @@
/datum/species/diona
name = "Diona"
name_plural = "Dionaea"
icobase = 'icons/mob/human_races/r_diona.dmi'
deform = 'icons/mob/human_races/r_def_plant.dmi'
language = "Rootspeak"
speech_sounds = list('sound/voice/dionatalk1.ogg') //Credit https://www.youtube.com/watch?v=ufnvlRjsOTI [0:13 - 0:16]
speech_chance = 20
unarmed_type = /datum/unarmed_attack/diona
//primitive_form = "Nymph"
slowdown = 5
remains_type = /obj/effect/decal/cleanable/ash
warning_low_pressure = 50
hazard_low_pressure = -1
cold_level_1 = 50
cold_level_2 = -1
cold_level_3 = -1
heat_level_1 = 300
heat_level_2 = 340
heat_level_3 = 400
blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \
species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \
there is no effective upper limit to the number that can fuse in gestalt, and reports exist of the Epsilon Ursae \
Minoris primary being ringed with a cloud of singing space-station-sized entities.<br/><br/>The Dionaea coexist peacefully with \
all known species, especially the Skrell. Their communal mind makes them slow to react, and they have difficulty understanding \
even the simplest concepts of other minds. Their alien physiology allows them survive happily off a diet of nothing but light, \
water and other radiation."
species_traits = list(NO_BREATHE, RADIMMUNE, IS_PLANT, NO_BLOOD, NO_PAIN)
clothing_flags = HAS_SOCKS
default_hair_colour = "#000000"
dietflags = 0 //Diona regenerate nutrition in light and water, no diet necessary
taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE
skinned_type = /obj/item/stack/sheet/wood
oxy_mod = 0
body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not
blood_color = "#004400"
flesh_color = "#907E4A"
butt_sprite = "diona"
reagent_tag = PROCESS_ORG
has_organ = list(
"nutrient channel" = /obj/item/organ/internal/liver/diona,
"neural strata" = /obj/item/organ/internal/heart/diona,
"receptor node" = /obj/item/organ/internal/eyes/diona, //Default darksight of 2.
"gas bladder" = /obj/item/organ/internal/brain/diona,
"polyp segment" = /obj/item/organ/internal/kidneys/diona,
"anchoring ligament" = /obj/item/organ/internal/appendix/diona
)
vision_organ = /obj/item/organ/internal/eyes/diona
has_limbs = list(
"chest" = list("path" = /obj/item/organ/external/chest/diona),
"groin" = list("path" = /obj/item/organ/external/groin/diona),
"head" = list("path" = /obj/item/organ/external/head/diona),
"l_arm" = list("path" = /obj/item/organ/external/arm/diona),
"r_arm" = list("path" = /obj/item/organ/external/arm/right/diona),
"l_leg" = list("path" = /obj/item/organ/external/leg/diona),
"r_leg" = list("path" = /obj/item/organ/external/leg/right/diona),
"l_hand" = list("path" = /obj/item/organ/external/hand/diona),
"r_hand" = list("path" = /obj/item/organ/external/hand/right/diona),
"l_foot" = list("path" = /obj/item/organ/external/foot/diona),
"r_foot" = list("path" = /obj/item/organ/external/foot/right/diona)
)
suicide_messages = list(
"is losing branches!",
"pulls out a secret stash of herbicide and takes a hearty swig!",
"is pulling themselves apart!")
/datum/species/diona/can_understand(var/mob/other)
if(istype(other, /mob/living/simple_animal/diona))
return 1
return 0
/datum/species/diona/handle_post_spawn(var/mob/living/carbon/human/H)
H.gender = NEUTER
return ..()
/datum/species/diona/handle_life(var/mob/living/carbon/human/H)
H.radiation = Clamp(H.radiation, 0, 100) //We have to clamp this first, then decrease it, or there's a few edge cases of massive heals if we clamp and decrease at the same time.
var/rads = H.radiation / 25
H.radiation = max(H.radiation-rads, 0)
H.nutrition = min(H.nutrition+rads, NUTRITION_LEVEL_WELL_FED+10)
H.adjustBruteLoss(-(rads))
H.adjustToxLoss(-(rads))
var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
if(isturf(H.loc)) //else, there's considered to be no light
var/turf/T = H.loc
light_amount = min(T.get_lumcount() * 10, 5) //hardcapped so it's not abused by having a ton of flashlights
H.nutrition = min(H.nutrition+light_amount, NUTRITION_LEVEL_WELL_FED+10)
if(light_amount > 0)
H.clear_alert("nolight")
else
H.throw_alert("nolight", /obj/screen/alert/nolight)
if((light_amount >= 5) && !H.suiciding) //if there's enough light, heal
H.adjustBruteLoss(-(light_amount/2))
H.adjustFireLoss(-(light_amount/4))
if(H.nutrition < NUTRITION_LEVEL_STARVING+50)
H.take_overall_damage(10,0)
..()
@@ -0,0 +1,62 @@
/datum/species/drask
name = "Drask"
name_plural = "Drask"
icobase = 'icons/mob/human_races/r_drask.dmi'
deform = 'icons/mob/human_races/r_drask.dmi'
language = "Orluum"
eyes = "drask_eyes_s"
speech_sounds = list('sound/voice/DraskTalk.ogg')
speech_chance = 20
male_scream_sound = 'sound/voice/DraskTalk2.ogg'
female_scream_sound = 'sound/voice/DraskTalk2.ogg'
male_cough_sounds = 'sound/voice/DraskCough.ogg'
female_cough_sounds = 'sound/voice/DraskCough.ogg'
male_sneeze_sound = 'sound/voice/DraskSneeze.ogg'
female_sneeze_sound = 'sound/voice/DraskSneeze.ogg'
burn_mod = 2
//exotic_blood = "cryoxadone"
body_temperature = 273
blurb = "Hailing from Hoorlm, planet outside what is usually considered a habitable \
orbit, the Drask evolved to live in extreme cold. Their strange bodies seem \
to operate better the colder their surroundings are, and can regenerate rapidly \
when breathing supercooled gas. <br/><br/> On their homeworld, the Drask live long lives \
in their labyrinthine settlements, carved out beneath Hoorlm's icy surface, where the air \
is of breathable density."
suicide_messages = list(
"is self-warming with friction!",
"is jamming fingers through their big eyes!",
"is sucking in warm air!",
"is holding their breath!")
species_traits = list(LIPS, IS_WHITELISTED)
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT
bodyflags = HAS_SKIN_TONE | HAS_BODY_MARKINGS
dietflags = DIET_OMNI
cold_level_1 = -1 //Default 260 - Lower is better
cold_level_2 = -1 //Default 200
cold_level_3 = -1 //Default 120
coldmod = -1
heat_level_1 = 300 //Default 360 - Higher is better
heat_level_2 = 340 //Default 400
heat_level_3 = 400 //Default 460
heatmod = 2
flesh_color = "#a3d4eb"
reagent_tag = PROCESS_ORG
base_color = "#a3d4eb"
blood_color = "#a3d4eb"
butt_sprite = "drask"
has_organ = list(
"heart" = /obj/item/organ/internal/heart/drask,
"lungs" = /obj/item/organ/internal/lungs/drask,
"metabolic strainer" = /obj/item/organ/internal/liver/drask,
"eyes" = /obj/item/organ/internal/eyes/drask, //5 darksight.
"brain" = /obj/item/organ/internal/brain/drask
)
@@ -5,7 +5,6 @@
icobase = 'icons/mob/human_races/r_golem.dmi'
deform = 'icons/mob/human_races/r_golem.dmi'
default_language = "Galactic Common"
species_traits = list(NO_BREATHE, NO_BLOOD, RADIMMUNE, VIRUSIMMUNE, NOGUNS)
oxy_mod = 0
@@ -13,7 +12,6 @@
dietflags = DIET_OMNI //golems can eat anything because they are magic or something
reagent_tag = PROCESS_ORG
unarmed_type = /datum/unarmed_attack/punch
punchdamagelow = 5
punchdamagehigh = 14
punchstunthreshold = 11 //about 40% chance to stun
@@ -0,0 +1,55 @@
/datum/species/grey
name = "Grey"
name_plural = "Greys"
icobase = 'icons/mob/human_races/r_grey.dmi'
deform = 'icons/mob/human_races/r_def_grey.dmi'
language = "Psionic Communication"
eyes = "grey_eyes_s"
butt_sprite = "grey"
has_organ = list(
"heart" = /obj/item/organ/internal/heart,
"lungs" = /obj/item/organ/internal/lungs,
"liver" = /obj/item/organ/internal/liver/grey,
"kidneys" = /obj/item/organ/internal/kidneys,
"brain" = /obj/item/organ/internal/brain/grey,
"appendix" = /obj/item/organ/internal/appendix,
"eyes" = /obj/item/organ/internal/eyes/grey //5 darksight.
)
brute_mod = 1.25 //greys are fragile
default_genes = list(REMOTE_TALK)
species_traits = list(LIPS, IS_WHITELISTED, CAN_BE_FAT)
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_BODY_MARKINGS
dietflags = DIET_HERB
reagent_tag = PROCESS_ORG
blood_color = "#A200FF"
/datum/species/grey/handle_dna(var/mob/living/carbon/C, var/remove)
if(!remove)
C.dna.SetSEState(REMOTETALKBLOCK,1,1)
genemutcheck(C,REMOTETALKBLOCK,null,MUTCHK_FORCED)
else
C.dna.SetSEState(REMOTETALKBLOCK,0,1)
genemutcheck(C,REMOTETALKBLOCK,null,MUTCHK_FORCED)
..()
/datum/species/grey/water_act(var/mob/living/carbon/C, volume, temperature, source)
..()
C.take_organ_damage(5,min(volume,20))
C.emote("scream")
/datum/species/grey/after_equip_job(datum/job/J, mob/living/carbon/human/H)
var/speech_pref = H.client.prefs.speciesprefs
if(speech_pref)
H.mind.speech_span = "wingdings"
/datum/species/grey/handle_reagents(mob/living/carbon/human/H, datum/reagent/R)
if(R.id == "sacid")
H.reagents.del_reagent(R.id)
return 0
return ..()
@@ -0,0 +1,20 @@
/datum/species/human
name = "Human"
name_plural = "Humans"
icobase = 'icons/mob/human_races/r_human.dmi'
deform = 'icons/mob/human_races/r_def_human.dmi'
primitive_form = /datum/species/monkey
language = "Sol Common"
species_traits = list(LIPS, CAN_BE_FAT)
skinned_type = /obj/item/stack/sheet/animalhide/human
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_SKIN_TONE | HAS_BODY_MARKINGS
dietflags = DIET_OMNI
blurb = "Humanity originated in the Sol system, and over the last five centuries has spread \
colonies across a wide swathe of space. They hold a wide range of forms and creeds.<br/><br/> \
While the central Sol government maintains control of its far-flung people, powerful corporate \
interests, rampant cyber and bio-augmentation and secretive factions make life on most human \
worlds tumultous at best."
reagent_tag = PROCESS_ORG
//Has standard darksight of 2.
@@ -0,0 +1,41 @@
/datum/species/kidan
name = "Kidan"
name_plural = "Kidan"
icobase = 'icons/mob/human_races/r_kidan.dmi'
deform = 'icons/mob/human_races/r_def_kidan.dmi'
language = "Chittin"
unarmed_type = /datum/unarmed_attack/claws
brute_mod = 0.8
species_traits = list(IS_WHITELISTED)
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_HEAD_ACCESSORY | HAS_HEAD_MARKINGS | HAS_BODY_MARKINGS
eyes = "kidan_eyes_s"
dietflags = DIET_HERB
blood_color = "#FB9800"
reagent_tag = PROCESS_ORG
//Default styles for created mobs.
default_headacc = "Normal Antennae"
butt_sprite = "kidan"
has_organ = list(
"heart" = /obj/item/organ/internal/heart,
"lungs" = /obj/item/organ/internal/lungs,
"liver" = /obj/item/organ/internal/liver/kidan,
"kidneys" = /obj/item/organ/internal/kidneys,
"brain" = /obj/item/organ/internal/brain,
"appendix" = /obj/item/organ/internal/appendix,
"eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2.
"lantern" = /obj/item/organ/internal/lantern
)
allowed_consumed_mobs = list(/mob/living/simple_animal/diona)
suicide_messages = list(
"is attempting to bite their antenna off!",
"is jamming their claws into their eye sockets!",
"is twisting their own neck!",
"is cracking their exoskeleton!",
"is stabbing themselves with their mandibles!",
"is holding their breath!")
@@ -0,0 +1,88 @@
/datum/species/machine
name = "Machine"
name_plural = "Machines"
blurb = "Positronic intelligence really took off in the 26th century, and it is not uncommon to see independant, free-willed \
robots on many human stations, particularly in fringe systems where standards are slightly lax and public opinion less relevant \
to corporate operations. IPCs (Integrated Positronic Chassis) are a loose category of self-willed robots with a humanoid form, \
generally self-owned after being 'born' into servitude; they are reliable and dedicated workers, albeit more than slightly \
inhuman in outlook and perspective."
icobase = 'icons/mob/human_races/r_machine.dmi'
deform = 'icons/mob/human_races/r_machine.dmi'
language = "Trinary"
remains_type = /obj/effect/decal/remains/robot
skinned_type = /obj/item/stack/sheet/metal // Let's grind up IPCs for station resources!
eyes = "blank_eyes"
brute_mod = 2.5 // 100% * 2.5 * 0.6 (robolimbs) ~= 150%
burn_mod = 2.5 // So they take 50% extra damage from brute/burn overall.
tox_mod = 0
clone_mod = 0
oxy_mod = 0
death_message = "gives one shrill beep before falling limp, their monitor flashing blue before completely shutting off..."
species_traits = list(IS_WHITELISTED, NO_BREATHE, NO_SCAN, NO_BLOOD, NO_PAIN, NO_DNA, RADIMMUNE, VIRUSIMMUNE, NOTRANSSTING)
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_SKIN_COLOR | HAS_HEAD_MARKINGS | HAS_HEAD_ACCESSORY | ALL_RPARTS
dietflags = 0 //IPCs can't eat, so no diet
taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE
blood_color = "#1F181F"
flesh_color = "#AAAAAA"
//Default styles for created mobs.
default_hair = "Blue IPC Screen"
can_revive_by_healing = 1
has_gender = FALSE
reagent_tag = PROCESS_SYN
male_scream_sound = 'sound/goonstation/voice/robot_scream.ogg'
female_scream_sound = 'sound/goonstation/voice/robot_scream.ogg'
male_cough_sounds = list('sound/effects/mob_effects/m_machine_cougha.ogg','sound/effects/mob_effects/m_machine_coughb.ogg', 'sound/effects/mob_effects/m_machine_coughc.ogg')
female_cough_sounds = list('sound/effects/mob_effects/f_machine_cougha.ogg','sound/effects/mob_effects/f_machine_coughb.ogg')
male_sneeze_sound = 'sound/effects/mob_effects/machine_sneeze.ogg'
female_sneeze_sound = 'sound/effects/mob_effects/f_machine_sneeze.ogg'
butt_sprite = "machine"
has_organ = list(
"brain" = /obj/item/organ/internal/brain/mmi_holder/posibrain,
"cell" = /obj/item/organ/internal/cell,
"optics" = /obj/item/organ/internal/eyes/optical_sensor, //Default darksight of 2.
"charger" = /obj/item/organ/internal/cyberimp/arm/power_cord
)
vision_organ = /obj/item/organ/internal/eyes/optical_sensor
has_limbs = list(
"chest" = list("path" = /obj/item/organ/external/chest/ipc),
"groin" = list("path" = /obj/item/organ/external/groin/ipc),
"head" = list("path" = /obj/item/organ/external/head/ipc),
"l_arm" = list("path" = /obj/item/organ/external/arm/ipc),
"r_arm" = list("path" = /obj/item/organ/external/arm/right/ipc),
"l_leg" = list("path" = /obj/item/organ/external/leg/ipc),
"r_leg" = list("path" = /obj/item/organ/external/leg/right/ipc),
"l_hand" = list("path" = /obj/item/organ/external/hand/ipc),
"r_hand" = list("path" = /obj/item/organ/external/hand/right/ipc),
"l_foot" = list("path" = /obj/item/organ/external/foot/ipc),
"r_foot" = list("path" = /obj/item/organ/external/foot/right/ipc)
)
suicide_messages = list(
"is powering down!",
"is smashing their own monitor!",
"is twisting their own neck!",
"is downloading extra RAM!",
"is frying their own circuits!",
"is blocking their ventilation port!")
species_abilities = list(
/mob/living/carbon/human/proc/change_monitor
)
/datum/species/machine/handle_death(var/mob/living/carbon/human/H)
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
if(!head_organ)
return
head_organ.h_style = "Bald"
head_organ.f_style = "Shaved"
spawn(100)
if(H)
H.update_hair()
H.update_fhair()
@@ -8,10 +8,11 @@
damage_overlays = 'icons/mob/human_races/masks/dam_monkey.dmi'
damage_mask = 'icons/mob/human_races/masks/dam_mask_monkey.dmi'
blood_mask = 'icons/mob/human_races/masks/blood_monkey.dmi'
path = /mob/living/carbon/human/monkey
language = null
default_language = "Chimpanzee"
greater_form = "Human"
species_traits = list(NO_EXAMINE)
skinned_type = /obj/item/stack/sheet/animalhide/monkey
greater_form = /datum/species/human
is_small = 1
has_fine_manipulation = 0
ventcrawler = 1
@@ -28,8 +29,7 @@
reagent_tag = PROCESS_ORG
//Has standard darksight of 2.
//unarmed_types = list(/datum/unarmed_attack/bite, /datum/unarmed_attack/claws)
//inherent_verbs = list(/mob/living/proc/ventcrawl)
unarmed_type = /datum/unarmed_attack/bite
total_health = 75
brute_mod = 1.5
@@ -49,7 +49,7 @@
/datum/species/monkey/handle_post_spawn(var/mob/living/carbon/human/H)
H.real_name = "[lowertext(name)] ([rand(100,999)])"
H.name = H.real_name
H.butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/monkey = 5)
H.butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/monkey = 5)
..()
@@ -82,12 +82,12 @@
if(slot_handcuffed)
if(user.handcuffed)
return 2
if(!istype(I, /obj/item/weapon/restraints/handcuffs))
if(!istype(I, /obj/item/restraints/handcuffs))
return 2
return 1
if(slot_in_backpack)
if(user.back && istype(user.back, /obj/item/weapon/storage/backpack))
var/obj/item/weapon/storage/backpack/B = user.back
if(user.back && istype(user.back, /obj/item/storage/backpack))
var/obj/item/storage/backpack/B = user.back
if(B.contents.len < B.storage_slots && I.w_class <= B.max_w_class)
return 1
return 2
@@ -100,7 +100,7 @@
icobase = 'icons/mob/human_races/monkeys/r_farwa.dmi'
deform = 'icons/mob/human_races/monkeys/r_farwa.dmi'
greater_form = "Tajaran"
greater_form = /datum/species/tajaran
default_language = "Farwa"
flesh_color = "#AFA59E"
base_color = "#000000"
@@ -124,7 +124,7 @@
icobase = 'icons/mob/human_races/monkeys/r_wolpin.dmi'
deform = 'icons/mob/human_races/monkeys/r_wolpin.dmi'
greater_form = "Vulpkanin"
greater_form = /datum/species/vulpkanin
default_language = "Wolpin"
flesh_color = "#966464"
base_color = "#000000"
@@ -148,7 +148,7 @@
icobase = 'icons/mob/human_races/monkeys/r_neara.dmi'
deform = 'icons/mob/human_races/monkeys/r_neara.dmi'
greater_form = "Skrell"
greater_form = /datum/species/skrell
default_language = "Neara"
flesh_color = "#8CD7A3"
blood_color = "#1D2CBF"
@@ -163,7 +163,7 @@
deform = 'icons/mob/human_races/monkeys/r_stok.dmi'
tail = "stoktail"
greater_form = "Unathi"
greater_form = /datum/species/unathi
default_language = "Stok"
flesh_color = "#34AF10"
base_color = "#000000"
@@ -0,0 +1,41 @@
/datum/species/nucleation
name = "Nucleation"
name_plural = "Nucleations"
icobase = 'icons/mob/human_races/r_nucleation.dmi'
blurb = "A sub-race of unfortunates who have been exposed to too much supermatter radiation. As a result, \
supermatter crystal clusters have begun to grow across their bodies. Research to find a cure for this ailment \
has been slow, and so this is a common fate for veteran engineers. The supermatter crystals produce oxygen, \
negating the need for the individual to breathe. Their massive change in biology, however, renders most medicines \
obselete. Ionizing radiation seems to cause resonance in some of their crystals, which seems to encourage regeneration \
and produces a calming effect on the individual. Nucleations are highly stigmatized, and are treated much in the same \
way as lepers were back on Earth."
language = "Sol Common"
burn_mod = 4 // holy shite, poor guys wont survive half a second cooking smores
brute_mod = 2 // damn, double wham, double dam
oxy_mod = 0
species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_BLOOD, NO_PAIN, NO_SCAN, RADIMMUNE)
dietflags = DIET_OMNI //still human at their core, so they maintain their eating habits and diet
//Default styles for created mobs.
default_hair = "Nucleation Crystals"
reagent_tag = PROCESS_ORG
has_organ = list(
"heart" = /obj/item/organ/internal/heart,
"crystallized brain" = /obj/item/organ/internal/brain/crystal,
"eyes" = /obj/item/organ/internal/eyes/luminescent_crystal, //Standard darksight of 2.
"strange crystal" = /obj/item/organ/internal/nucleation/strange_crystal
)
vision_organ = /obj/item/organ/internal/eyes/luminescent_crystal
/datum/species/nucleation/handle_post_spawn(var/mob/living/carbon/human/H)
H.light_color = "#1C1C00"
H.set_light(2)
return ..()
/datum/species/nucleation/handle_death(var/mob/living/carbon/human/H)
var/turf/T = get_turf(H)
H.visible_message("<span class='warning'>[H]'s body explodes, leaving behind a pile of microscopic crystals!</span>")
explosion(T, 0, 0, 2, 2) // Create a small explosion burst upon death
// new /obj/item/shard/supermatter( T )
qdel(H)
@@ -4,9 +4,9 @@
icobase = 'icons/mob/human_races/r_plasmaman_sb.dmi'
deform = 'icons/mob/human_races/r_plasmaman_pb.dmi' // TODO: Need deform.
//language = "Clatter"
unarmed_type = /datum/unarmed_attack/punch
species_traits = list(IS_WHITELISTED, NO_BLOOD, NOTRANSSTING)
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
@@ -82,7 +82,7 @@
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
H.equip_or_collect(new /obj/item/weapon/gun/energy/gun/advtaser(H), slot_in_backpack)
H.equip_or_collect(new /obj/item/gun/energy/gun/advtaser(H), slot_in_backpack)
if("Internal Affairs Agent")
suit=/obj/item/clothing/suit/space/eva/plasmaman/lawyer
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/lawyer
@@ -92,7 +92,7 @@
if("Head of Security")
suit=/obj/item/clothing/suit/space/eva/plasmaman/security/hos
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security/hos
H.equip_or_collect(new /obj/item/weapon/gun/energy/gun(H), slot_in_backpack)
H.equip_or_collect(new /obj/item/gun/energy/gun(H), slot_in_backpack)
if("Captain", "Blueshield")
suit=/obj/item/clothing/suit/space/eva/plasmaman/security/captain
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/security/captain
@@ -105,7 +105,7 @@
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
H.equip_or_collect(new /obj/item/device/flashlight/pen(H), slot_in_backpack)
H.equip_or_collect(new /obj/item/flashlight/pen(H), slot_in_backpack)
if("Paramedic")
suit=/obj/item/clothing/suit/space/eva/plasmaman/medical/paramedic
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/medical/paramedic
@@ -148,11 +148,16 @@
if("Mime")
suit=/obj/item/clothing/suit/space/eva/plasmaman/mime
helm=/obj/item/clothing/head/helmet/space/eva/plasmaman/mime
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/weapon/tank/plasma/plasmaman(H), tank_slot) // Bigger plasma tank from Raggy.
H.equip_or_collect(new /obj/item/weapon/plasmensuit_cartridge(H), slot_in_backpack)
H.equip_or_collect(new /obj/item/weapon/plasmensuit_cartridge(H), slot_in_backpack) //Two refill cartridges for their suit. Can fit in boxes.
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)
H.update_action_buttons_icon()
@@ -5,7 +5,6 @@
icobase = 'icons/mob/human_races/r_shadow.dmi'
deform = 'icons/mob/human_races/r_shadow.dmi'
default_language = "Galactic Common"
unarmed_type = /datum/unarmed_attack/claws
ignored_by = list(/mob/living/simple_animal/hostile/faithless)
@@ -0,0 +1,85 @@
/datum/species/shadow/ling
//Normal shadowpeople but with enhanced effects
name = "Shadowling"
icobase = 'icons/mob/human_races/r_shadowling.dmi'
deform = 'icons/mob/human_races/r_shadowling.dmi'
blood_color = "#555555"
flesh_color = "#222222"
species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE, NOGUNS, NO_EXAMINE) //Can't use guns due to muzzle flash
burn_mod = 1.5 //1.5x burn damage, 2x is excessive
oxy_mod = 0
heatmod = 1.5
silent_steps = 1
grant_vision_toggle = 0
has_organ = list(
"brain" = /obj/item/organ/internal/brain,
"eyes" = /obj/item/organ/internal/eyes)
/datum/species/shadow/ling/handle_life(var/mob/living/carbon/human/H)
if(!H.weakeyes)
H.weakeyes = 1 //Makes them more vulnerable to flashes and flashbangs
var/light_amount = 0
H.nutrition = NUTRITION_LEVEL_WELL_FED //i aint never get hongry
if(isturf(H.loc))
var/turf/T = H.loc
light_amount = T.get_lumcount() * 10
if(light_amount > LIGHT_DAM_THRESHOLD && !H.incorporeal_move) //Can survive in very small light levels. Also doesn't take damage while incorporeal, for shadow walk purposes
H.throw_alert("lightexposure", /obj/screen/alert/lightexposure)
H.take_overall_damage(0, LIGHT_DAMAGE_TAKEN)
if(H.stat != DEAD)
to_chat(H, "<span class='userdanger'>The light burns you!</span>")//Message spam to say "GET THE FUCK OUT"
H << 'sound/weapons/sear.ogg'
else if(light_amount < LIGHT_HEAL_THRESHOLD)
H.clear_alert("lightexposure")
var/obj/item/organ/internal/eyes/E = H.get_int_organ(/obj/item/organ/internal/eyes)
if(istype(E))
E.receive_damage(-1)
H.heal_overall_damage(5, 5)
H.adjustToxLoss(-5)
H.adjustBrainLoss(-25) //Shad O. Ling gibbers, "CAN U BE MY THRALL?!!"
H.AdjustEyeBlurry(-1)
H.CureNearsighted()
H.CureBlind()
H.adjustCloneLoss(-1)
H.SetWeakened(0)
H.SetStunned(0)
..()
/datum/species/shadow/ling/lesser //Empowered thralls. Obvious, but powerful
name = "Lesser Shadowling"
icobase = 'icons/mob/human_races/r_lshadowling.dmi'
deform = 'icons/mob/human_races/r_lshadowling.dmi'
blood_color = "#CCCCCC"
flesh_color = "#AAAAAA"
species_traits = list(NO_BLOOD, NO_BREATHE, RADIMMUNE)
burn_mod = 1.1
oxy_mod = 0
heatmod = 1.1
/datum/species/shadow/ling/lesser/handle_life(var/mob/living/carbon/human/H)
if(!H.weakeyes)
H.weakeyes = 1 //Makes them more vulnerable to flashes and flashbangs
var/light_amount = 0
H.nutrition = NUTRITION_LEVEL_WELL_FED //i aint never get hongry
if(isturf(H.loc))
var/turf/T = H.loc
light_amount = T.get_lumcount() * 10
if(light_amount > LIGHT_DAM_THRESHOLD && !H.incorporeal_move)
H.throw_alert("lightexposure", /obj/screen/alert/lightexposure)
H.take_overall_damage(0, LIGHT_DAMAGE_TAKEN/2)
else if(light_amount < LIGHT_HEAL_THRESHOLD)
H.clear_alert("lightexposure")
H.heal_overall_damage(2,2)
H.adjustToxLoss(-5)
H.adjustBrainLoss(-25)
H.adjustCloneLoss(-1)
..()
@@ -6,14 +6,12 @@
icobase = 'icons/mob/human_races/r_skeleton.dmi'
deform = 'icons/mob/human_races/r_skeleton.dmi'
path = /mob/living/carbon/human/skeleton
default_language = "Galactic Common"
unarmed_type = /datum/unarmed_attack/punch
blood_color = "#FFFFFF"
flesh_color = "#E6E6C6"
species_traits = list(NO_BREATHE, NO_BLOOD, RADIMMUNE, VIRUSIMMUNE)
skinned_type = /obj/item/stack/sheet/bone
oxy_mod = 0
@@ -0,0 +1,46 @@
/datum/species/skrell
name = "Skrell"
name_plural = "Skrell"
icobase = 'icons/mob/human_races/r_skrell.dmi'
deform = 'icons/mob/human_races/r_def_skrell.dmi'
language = "Skrellian"
primitive_form = /datum/species/monkey/skrell
blurb = "An amphibious species, Skrell come from the star system known as Qerr'Vallis, which translates to 'Star of \
the royals' or 'Light of the Crown'.<br/><br/>Skrell are a highly advanced and logical race who live under the rule \
of the Qerr'Katish, a caste within their society which keeps the empire of the Skrell running smoothly. Skrell are \
herbivores on the whole and tend to be co-operative with the other species of the galaxy, although they rarely reveal \
the secrets of their empire to their allies."
species_traits = list(LIPS)
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_SKIN_COLOR | HAS_BODY_MARKINGS
dietflags = DIET_HERB
taste_sensitivity = TASTE_SENSITIVITY_DULL
flesh_color = "#8CD7A3"
blood_color = "#1D2CBF"
base_color = "#38b661" //RGB: 56, 182, 97.
default_hair_colour = "#38b661"
eyes = "skrell_eyes_s"
//Default styles for created mobs.
default_hair = "Skrell Male Tentacles"
reagent_tag = PROCESS_ORG
butt_sprite = "skrell"
has_organ = list(
"heart" = /obj/item/organ/internal/heart,
"lungs" = /obj/item/organ/internal/lungs,
"liver" = /obj/item/organ/internal/liver/skrell,
"kidneys" = /obj/item/organ/internal/kidneys,
"brain" = /obj/item/organ/internal/brain,
"appendix" = /obj/item/organ/internal/appendix,
"eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2.
"headpocket" = /obj/item/organ/internal/headpocket
)
suicide_messages = list(
"is attempting to bite their tongue off!",
"is jamming their thumbs into their eye sockets!",
"is twisting their own neck!",
"makes like a fish and suffocates!",
"is strangling themselves with their own tendrils!")
@@ -0,0 +1,200 @@
/datum/species/slime
name = "Slime People"
name_plural = "Slime People"
language = "Bubblish"
icobase = 'icons/mob/human_races/r_slime.dmi'
deform = 'icons/mob/human_races/r_slime.dmi'
remains_type = /obj/effect/decal/remains/slime
// More sensitive to the cold
cold_level_1 = 280
cold_level_2 = 240
cold_level_3 = 200
coldmod = 3
oxy_mod = 0
brain_mod = 2.5
male_cough_sounds = list('sound/effects/slime_squish.ogg')
female_cough_sounds = list('sound/effects/slime_squish.ogg')
species_traits = list(LIPS, IS_WHITELISTED, NO_BREATHE, NO_INTORGANS, NO_SCAN)
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_SKIN_COLOR | NO_EYES
dietflags = DIET_CARN
reagent_tag = PROCESS_ORG
blood_color = "#0064C8"
exotic_blood = "water"
blood_damage_type = TOX
butt_sprite = "slime"
//Has default darksight of 2.
has_organ = list(
"brain" = /obj/item/organ/internal/brain/slime
)
suicide_messages = list(
"is melting into a puddle!",
"is ripping out their own core!",
"is turning a dull, brown color and melting into a puddle!")
var/reagent_skin_coloring = FALSE
var/datum/action/innate/regrow/grow = new()
species_abilities = list(
/mob/living/carbon/human/verb/toggle_recolor_verb,
/mob/living/carbon/human/proc/regrow_limbs
)
/datum/species/slime/handle_post_spawn(var/mob/living/carbon/human/H)
grow.Grant(H)
..()
/datum/action/innate/regrow
name = "Regrow limbs"
icon_icon = 'icons/effects/effects.dmi'
button_icon_state = "greenglow"
/datum/action/innate/regrow/Activate()
var/mob/living/carbon/human/user = owner
user.regrow_limbs()
/datum/species/slime/handle_life(var/mob/living/carbon/human/H)
//This is allegedly for code "style". Like a plaid sweater?
#define SLIMEPERSON_COLOR_SHIFT_TRIGGER 0.1
#define SLIMEPERSON_ICON_UPDATE_PERIOD 200 // 20 seconds
#define SLIMEPERSON_BLOOD_SCALING_FACTOR 5 // Used to adjust how much of an effect the blood has on the rate of color change. Higher is slower.
// Slowly shifting to the color of the reagents
if(reagent_skin_coloring && H.reagents.total_volume > SLIMEPERSON_COLOR_SHIFT_TRIGGER)
var/blood_amount = H.blood_volume
var/r_color = mix_color_from_reagents(H.reagents.reagent_list)
var/new_body_color = BlendRGB(r_color, H.skin_colour, (blood_amount*SLIMEPERSON_BLOOD_SCALING_FACTOR)/((blood_amount*SLIMEPERSON_BLOOD_SCALING_FACTOR)+(H.reagents.total_volume)))
H.skin_colour = new_body_color
if(world.time % SLIMEPERSON_ICON_UPDATE_PERIOD > SLIMEPERSON_ICON_UPDATE_PERIOD - 20) // The 20 is because this gets called every 2 seconds, from the mob controller
for(var/organname in H.bodyparts_by_name)
var/obj/item/organ/external/E = H.bodyparts_by_name[organname]
if(istype(E) && E.dna && istype(E.dna.species, /datum/species/slime))
E.sync_colour_to_human(H)
H.update_hair(0)
H.update_body()
..()
#undef SLIMEPERSON_COLOR_SHIFT_TRIGGER
#undef SLIMEPERSON_ICON_UPDATE_PERIOD
#undef SLIMEPERSON_BLOOD_SCALING_FACTOR
/mob/living/carbon/human/proc/toggle_recolor(silent = FALSE)
if(!isslimeperson(src))
if(!silent)
to_chat(src, "You're not a slime person!")
return
var/datum/species/slime/S = dna.species
if(S.reagent_skin_coloring)
S.reagent_skin_coloring = TRUE
if(!silent)
to_chat(src, "You adjust your internal chemistry to filter out pigments from things you consume.")
else
S.reagent_skin_coloring = TRUE
if(!silent)
to_chat(src, "You adjust your internal chemistry to permit pigments in chemicals you consume to tint you.")
/mob/living/carbon/human/verb/toggle_recolor_verb()
set category = "IC"
set name = "Toggle Reagent Recoloring"
set desc = "While active, you'll slowly adjust your body's color to that of the reagents inside of you, moderated by how much blood you have."
toggle_recolor()
/mob/living/carbon/human/proc/regrow_limbs()
set category = "IC"
set name = "Regrow Limbs"
set desc = "Regrow one of your missing limbs at the cost of a large amount of hunger"
#define SLIMEPERSON_HUNGERCOST 50
#define SLIMEPERSON_MINHUNGER 250
#define SLIMEPERSON_REGROWTHDELAY 450 // 45 seconds
if(stat || paralysis || stunned)
to_chat(src, "<span class='warning'>You cannot regenerate missing limbs in your current state.</span>")
return
if(nutrition < SLIMEPERSON_MINHUNGER)
to_chat(src, "<span class='warning'>You're too hungry to regenerate a limb!</span>")
return
var/list/missing_limbs = list()
for(var/l in bodyparts_by_name)
var/obj/item/organ/external/E = bodyparts_by_name[l]
if(!istype(E))
var/list/limblist = dna.species.has_limbs[l]
var/obj/item/organ/external/limb = limblist["path"]
var/parent_organ = initial(limb.parent_organ)
var/obj/item/organ/external/parentLimb = bodyparts_by_name[parent_organ]
if(!istype(parentLimb))
continue
missing_limbs[initial(limb.name)] = l
if(!missing_limbs.len)
to_chat(src, "<span class='warning'>You're not missing any limbs!</span>")
return
var/limb_select = input(src, "Choose a limb to regrow", "Limb Regrowth") as null|anything in missing_limbs
var/chosen_limb = missing_limbs[limb_select]
visible_message("<span class='notice'>[src] begins to hold still and concentrate on [p_their()] missing [limb_select]...</span>", "<span class='notice'>You begin to focus on regrowing your missing [limb_select]... (This will take [round(SLIMEPERSON_REGROWTHDELAY/10)] seconds, and you must hold still.)</span>")
if(do_after(src, SLIMEPERSON_REGROWTHDELAY, needhand=0, target = src))
if(stat || paralysis || stunned)
to_chat(src, "<span class='warning'>You cannot regenerate missing limbs in your current state.</span>")
return
if(nutrition < SLIMEPERSON_MINHUNGER)
to_chat(src, "<span class='warning'>You're too hungry to regenerate a limb!</span>")
return
var/obj/item/organ/external/O = bodyparts_by_name[chosen_limb]
var/stored_brute = 0
var/stored_burn = 0
if(istype(O))
to_chat(src, "<span class='warning'>You distribute the damaged tissue around your body, out of the way of your new pseudopod!</span>")
var/obj/item/organ/external/doomedStump = O
stored_brute = doomedStump.brute_dam
stored_burn = doomedStump.burn_dam
qdel(O)
var/limb_list = dna.species.has_limbs[chosen_limb]
var/obj/item/organ/external/limb_path = limb_list["path"]
// Parent check
var/obj/item/organ/external/potential_parent = bodyparts_by_name[initial(limb_path.parent_organ)]
if(!istype(potential_parent))
to_chat(src, "<span class='danger'>You've lost the organ that you've been growing your new part on!</span>")
return // No rayman for you
// Grah this line will leave a "not used" warning, in spite of the fact that the new() proc WILL do the thing.
// Bothersome.
var/obj/item/organ/external/new_limb = new limb_path(src)
new_limb.open = 0 // This is just so that the compiler won't think that new_limb is unused, because the compiler is horribly stupid.
adjustBruteLoss(stored_brute)
adjustFireLoss(stored_burn)
update_body()
updatehealth()
UpdateDamageIcon()
nutrition -= SLIMEPERSON_HUNGERCOST
visible_message("<span class='notice'>[src] finishes regrowing [p_their()] missing [new_limb]!</span>", "<span class='notice'>You finish regrowing your [limb_select]</span>")
else
to_chat(src, "<span class='warning'>You need to hold still in order to regrow a limb!</span>")
return
#undef SLIMEPERSON_HUNGERCOST
#undef SLIMEPERSON_MINHUNGER
#undef SLIMEPERSON_REGROWTHDELAY
/datum/species/slime/handle_pre_change(mob/living/carbon/human/H)
..()
if(reagent_skin_coloring)
H.toggle_recolor(silent = 1)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,58 @@
/datum/species/tajaran
name = "Tajaran"
name_plural = "Tajaran"
icobase = 'icons/mob/human_races/r_tajaran.dmi'
deform = 'icons/mob/human_races/r_def_tajaran.dmi'
language = "Siik'tajr"
tail = "tajtail"
skinned_type = /obj/item/stack/sheet/fur
unarmed_type = /datum/unarmed_attack/claws
blurb = "The Tajaran race is a species of feline-like bipeds hailing from the planet of Ahdomai in the \
S'randarr system. They have been brought up into the space age by the Humans and Skrell, and have been \
influenced heavily by their long history of Slavemaster rule. They have a structured, clan-influenced way \
of family and politics. They prefer colder environments, and speak a variety of languages, mostly Siik'Maas, \
using unique inflections their mouths form."
cold_level_1 = 240
cold_level_2 = 180
cold_level_3 = 100
heat_level_1 = 340
heat_level_2 = 380
heat_level_3 = 440
primitive_form = /datum/species/monkey/tajaran
species_traits = list(LIPS, CAN_BE_FAT)
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_HEAD_MARKINGS | HAS_BODY_MARKINGS | HAS_SKIN_COLOR | TAIL_WAGGING
dietflags = DIET_OMNI
taste_sensitivity = TASTE_SENSITIVITY_SHARP
reagent_tag = PROCESS_ORG
flesh_color = "#AFA59E"
base_color = "#424242"
butt_sprite = "tajaran"
has_organ = list(
"heart" = /obj/item/organ/internal/heart,
"lungs" = /obj/item/organ/internal/lungs,
"liver" = /obj/item/organ/internal/liver/tajaran,
"kidneys" = /obj/item/organ/internal/kidneys,
"brain" = /obj/item/organ/internal/brain,
"appendix" = /obj/item/organ/internal/appendix,
"eyes" = /obj/item/organ/internal/eyes/tajaran /*Most Tajara see in full colour as a result of genetic augmentation, although it cost them their darksight (darksight = 2)
unless they choose otherwise by selecting the colourblind disability in character creation (darksight = 8 but colourblind).*/
)
allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/chick, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot,
/mob/living/simple_animal/tribble)
suicide_messages = list(
"is attempting to bite their tongue off!",
"is jamming their claws into their eye sockets!",
"is twisting their own neck!",
"is holding their breath!")
/datum/species/tajaran/handle_death(var/mob/living/carbon/human/H)
H.stop_tail_wagging(1)
@@ -0,0 +1,102 @@
/datum/species/unathi
name = "Unathi"
name_plural = "Unathi"
icobase = 'icons/mob/human_races/r_lizard.dmi'
deform = 'icons/mob/human_races/r_def_lizard.dmi'
language = "Sinta'unathi"
tail = "sogtail"
skinned_type = /obj/item/stack/sheet/animalhide/lizard
unarmed_type = /datum/unarmed_attack/claws
primitive_form = /datum/species/monkey/unathi
blurb = "A heavily reptillian species, Unathi (or 'Sinta as they call themselves) hail from the \
Uuosa-Eso system, which roughly translates to 'burning mother'.<br/><br/>Coming from a harsh, radioactive \
desert planet, they mostly hold ideals of honesty, virtue, martial combat and bravery above all \
else, frequently even their own lives. They prefer warmer temperatures than most species and \
their native tongue is a heavy hissing laungage called Sinta'Unathi."
species_traits = list(LIPS)
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_TAIL | HAS_HEAD_ACCESSORY | HAS_BODY_MARKINGS | HAS_HEAD_MARKINGS | HAS_SKIN_COLOR | HAS_ALT_HEADS | TAIL_WAGGING
dietflags = DIET_CARN
cold_level_1 = 280 //Default 260 - Lower is better
cold_level_2 = 220 //Default 200
cold_level_3 = 140 //Default 120
heat_level_1 = 380 //Default 360 - Higher is better
heat_level_2 = 420 //Default 400
heat_level_3 = 480 //Default 460
flesh_color = "#34AF10"
reagent_tag = PROCESS_ORG
base_color = "#066000"
//Default styles for created mobs.
default_headacc = "Simple"
default_headacc_colour = "#404040"
butt_sprite = "unathi"
brute_mod = 1.05
has_organ = list(
"heart" = /obj/item/organ/internal/heart,
"lungs" = /obj/item/organ/internal/lungs,
"liver" = /obj/item/organ/internal/liver/unathi,
"kidneys" = /obj/item/organ/internal/kidneys,
"brain" = /obj/item/organ/internal/brain,
"appendix" = /obj/item/organ/internal/appendix,
"eyes" = /obj/item/organ/internal/eyes/unathi //3 darksight.
)
allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/lizard, /mob/living/simple_animal/chick, /mob/living/simple_animal/chicken,
/mob/living/simple_animal/crab, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/tribble)
suicide_messages = list(
"is attempting to bite their tongue off!",
"is jamming their claws into their eye sockets!",
"is twisting their own neck!",
"is holding their breath!")
var/datum/action/innate/tail_lash/lash = new()
/datum/species/unathi/handle_post_spawn(var/mob/living/carbon/human/H)
lash.Grant(H)
..()
/datum/action/innate/tail_lash
name = "Tail lash"
icon_icon = 'icons/effects/effects.dmi'
button_icon_state = "tail"
check_flags = AB_CHECK_LYING | AB_CHECK_CONSCIOUS | AB_CHECK_STUNNED
/datum/action/innate/tail_lash/Activate()
var/mob/living/carbon/human/user = owner
if((user.restrained() && user.pulledby) || user.buckled)
to_chat(user, "<span class='warning'>You need freedom of movement to tail lash!</span>")
return
if(user.getStaminaLoss() >= 50)
to_chat(user, "<span class='warning'>Rest before tail lashing again!</span>")
return
for(var/mob/living/carbon/human/C in orange(1))
var/obj/item/organ/external/E = C.get_organ(pick("l_leg", "r_leg", "l_foot", "r_foot", "groin"))
if(E)
user.changeNext_move(CLICK_CD_MELEE)
user.visible_message("<span class='danger'>[src] smacks [C] in [E] with their tail! </span>", "<span class='danger'>You hit [C] in [E] with your tail!</span>")
user.adjustStaminaLoss(15)
C.apply_damage(5, BRUTE, E)
user.spin(20, 1)
playsound(user.loc, 'sound/weapons/slash.ogg', 50, 0)
add_attack_logs(user, C, "tail whipped")
if(user.restrained())
if(prob(50))
user.Weaken(5)
user.visible_message("<span class='danger'>[src] loses [p_their()] balance!</span>", "<span class='danger'>You lose your balance!</span>")
return
if(user.getStaminaLoss() >= 60) //Bit higher as you don't need to start, just would need to keep going with the tail lash.
to_chat(user, "<span class='warning'>You run out of momentum!</span>")
return
/datum/species/unathi/handle_death(var/mob/living/carbon/human/H)
H.stop_tail_wagging(1)
@@ -0,0 +1,201 @@
/datum/species/vox
name = "Vox"
name_plural = "Vox"
icobase = 'icons/mob/human_races/vox/r_vox.dmi'
deform = 'icons/mob/human_races/vox/r_def_vox.dmi'
language = "Vox-pidgin"
tail = "voxtail"
speech_sounds = list('sound/voice/shriek1.ogg')
speech_chance = 20
unarmed_type = /datum/unarmed_attack/claws //I dont think it will hurt to give vox claws too.
blurb = "The Vox are the broken remnants of a once-proud race, now reduced to little more than \
scavenging vermin who prey on isolated stations, ships or planets to keep their own ancient arkships \
alive. They are four to five feet tall, reptillian, beaked, tailed and quilled; human crews often \
refer to them as 'shitbirds' for their violent and offensive nature, as well as their horrible \
smell.<br/><br/>Most humans will never meet a Vox raider, instead learning of this insular species through \
dealing with their traders and merchants; those that do rarely enjoy the experience."
brute_mod = 1.2 //20% more brute damage. Fragile bird bones.
warning_low_pressure = 50
hazard_low_pressure = 0
cold_level_1 = 80
cold_level_2 = 50
cold_level_3 = 0
breathid = "n2"
eyes = "vox_eyes_s"
species_traits = list(NO_SCAN, IS_WHITELISTED, NOTRANSSTING)
clothing_flags = HAS_SOCKS
dietflags = DIET_OMNI
bodyflags = HAS_ICON_SKIN_TONE | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED | HAS_BODY_MARKINGS | HAS_TAIL_MARKINGS
blood_color = "#2299FC"
flesh_color = "#808D11"
//Default styles for created mobs.
default_hair = "Short Vox Quills"
default_hair_colour = "#614f19" //R: 97, G: 79, B: 25
butt_sprite = "vox"
reagent_tag = PROCESS_ORG
scream_verb = "shrieks"
male_scream_sound = 'sound/voice/shriek1.ogg'
female_scream_sound = 'sound/voice/shriek1.ogg'
male_cough_sounds = list('sound/voice/shriekcough.ogg')
female_cough_sounds = list('sound/voice/shriekcough.ogg')
male_sneeze_sound = 'sound/voice/shrieksneeze.ogg'
female_sneeze_sound = 'sound/voice/shrieksneeze.ogg'
icon_skin_tones = list(
1 = "Default Green",
2 = "Dark Green",
3 = "Brown",
4 = "Grey",
5 = "Emerald",
6 = "Azure"
)
has_organ = list(
"heart" = /obj/item/organ/internal/heart,
"lungs" = /obj/item/organ/internal/lungs/vox,
"liver" = /obj/item/organ/internal/liver/vox,
"kidneys" = /obj/item/organ/internal/kidneys,
"brain" = /obj/item/organ/internal/brain,
"appendix" = /obj/item/organ/internal/appendix,
"eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2.
"stack" = /obj/item/organ/internal/stack //Not the same as the cortical stack implant Vox Raiders spawn with. The cortical stack implant is used
) //for determining the success of the heist game-mode's 'leave nobody behind' objective, while this is just an organ.
suicide_messages = list(
"is attempting to bite their tongue off!",
"is jamming their claws into their eye sockets!",
"is twisting their own neck!",
"is holding their breath!",
"is deeply inhaling oxygen!")
/datum/species/vox/handle_death(var/mob/living/carbon/human/H)
H.stop_tail_wagging(1)
/datum/species/vox/after_equip_job(datum/job/J, mob/living/carbon/human/H)
if(!H.mind || !H.mind.assigned_role || H.mind.assigned_role != "Clown" && H.mind.assigned_role != "Mime")
H.unEquip(H.wear_mask)
H.unEquip(H.l_hand)
H.equip_or_collect(new /obj/item/clothing/mask/breath/vox(H), slot_wear_mask)
var/tank_pref = H.client && H.client.prefs ? H.client.prefs.speciesprefs : null
if(tank_pref)//Diseasel, here you go
H.equip_or_collect(new /obj/item/tank/nitrogen(H), slot_l_hand)
else
H.equip_or_collect(new /obj/item/tank/emergency_oxygen/vox(H), slot_l_hand)
to_chat(H, "<span class='notice'>You are now running on nitrogen internals from the [H.l_hand] in your hand. Your species finds oxygen toxic, so you must breathe nitrogen only.</span>")
H.internal = H.l_hand
H.update_action_buttons_icon()
/datum/species/vox/handle_post_spawn(var/mob/living/carbon/human/H)
updatespeciescolor(H)
H.update_icons()
//H.verbs += /mob/living/carbon/human/proc/leap
..()
/datum/species/vox/updatespeciescolor(var/mob/living/carbon/human/H, var/owner_sensitive = 1) //Handling species-specific skin-tones for the Vox race.
if(H.dna.species.bodyflags & HAS_ICON_SKIN_TONE) //Making sure we don't break Armalis.
var/new_icobase = 'icons/mob/human_races/vox/r_vox.dmi' //Default Green Vox.
var/new_deform = 'icons/mob/human_races/vox/r_def_vox.dmi' //Default Green Vox.
switch(H.s_tone)
if(6) //Azure Vox.
new_icobase = 'icons/mob/human_races/vox/r_voxazu.dmi'
new_deform = 'icons/mob/human_races/vox/r_def_voxazu.dmi'
H.tail = "voxtail_azu"
if(5) //Emerald Vox.
new_icobase = 'icons/mob/human_races/vox/r_voxemrl.dmi'
new_deform = 'icons/mob/human_races/vox/r_def_voxemrl.dmi'
H.tail = "voxtail_emrl"
if(4) //Grey Vox.
new_icobase = 'icons/mob/human_races/vox/r_voxgry.dmi'
new_deform = 'icons/mob/human_races/vox/r_def_voxgry.dmi'
H.tail = "voxtail_gry"
if(3) //Brown Vox.
new_icobase = 'icons/mob/human_races/vox/r_voxbrn.dmi'
new_deform = 'icons/mob/human_races/vox/r_def_voxbrn.dmi'
H.tail = "voxtail_brn"
if(2) //Dark Green Vox.
new_icobase = 'icons/mob/human_races/vox/r_voxdgrn.dmi'
new_deform = 'icons/mob/human_races/vox/r_def_voxdgrn.dmi'
H.tail = "voxtail_dgrn"
else //Default Green Vox.
H.tail = "voxtail" //Ensures they get an appropriately coloured tail depending on the skin-tone.
H.change_icobase(new_icobase, new_deform, owner_sensitive) //Update the icobase/deform of all our organs, but make sure we don't mess with frankenstein limbs in doing so.
H.update_dna()
/datum/species/vox/handle_reagents(var/mob/living/carbon/human/H, var/datum/reagent/R)
if(R.id == "oxygen") //Armalis are above such petty things.
H.adjustToxLoss(1*REAGENTS_EFFECT_MULTIPLIER) //Same as plasma.
H.reagents.remove_reagent(R.id, REAGENTS_METABOLISM)
return 0 //Handling reagent removal on our own.
return ..()
/datum/species/vox/armalis/handle_post_spawn(var/mob/living/carbon/human/H)
H.verbs += /mob/living/carbon/human/proc/leap
H.verbs += /mob/living/carbon/human/proc/gut
..()
/datum/species/vox/armalis
name = "Vox Armalis"
name_plural = "Vox Armalis"
icobase = 'icons/mob/human_races/r_armalis.dmi'
deform = 'icons/mob/human_races/r_armalis.dmi'
unarmed_type = /datum/unarmed_attack/claws/armalis
warning_low_pressure = 50
hazard_low_pressure = 0
cold_level_1 = 80
cold_level_2 = 50
cold_level_3 = 0
heat_level_1 = 2000
heat_level_2 = 3000
heat_level_3 = 4000
brute_mod = 0.2
burn_mod = 0.2
eyes = "blank_eyes"
species_traits = list(NO_SCAN, NO_BLOOD, NO_PAIN, IS_WHITELISTED)
bodyflags = HAS_TAIL
dietflags = DIET_OMNI //should inherit this from vox, this is here just in case
blood_color = "#2299FC"
flesh_color = "#808D11"
reagent_tag = PROCESS_ORG
tail = "armalis_tail"
icon_template = 'icons/mob/human_races/r_armalis.dmi'
has_organ = list(
"heart" = /obj/item/organ/internal/heart,
"lungs" = /obj/item/organ/internal/lungs/vox,
"liver" = /obj/item/organ/internal/liver,
"kidneys" = /obj/item/organ/internal/kidneys,
"brain" = /obj/item/organ/internal/brain,
"eyes" = /obj/item/organ/internal/eyes, //Default darksight of 2.
"stack" = /obj/item/organ/internal/stack //Not the same as the cortical stack implant Vox Raiders spawn with. The cortical stack implant is used
) //for determining the success of the heist game-mode's 'leave nobody behind' objective, while this is just an organ.
suicide_messages = list(
"is attempting to bite their tongue off!",
"is jamming their claws into their eye sockets!",
"is twisting their own neck!",
"is holding their breath!",
"is huffing oxygen!")
/datum/species/vox/armalis/handle_reagents() //Skip the Vox oxygen reagent toxicity. Armalis are above such things.
return 1
@@ -0,0 +1,52 @@
/datum/species/vulpkanin
name = "Vulpkanin"
name_plural = "Vulpkanin"
icobase = 'icons/mob/human_races/r_vulpkanin.dmi'
deform = 'icons/mob/human_races/r_vulpkanin.dmi'
language = "Canilunzt"
primitive_form = /datum/species/monkey/vulpkanin
tail = "vulptail"
skinned_type = /obj/item/stack/sheet/fur
unarmed_type = /datum/unarmed_attack/claws
blurb = "Vulpkanin are a species of sharp-witted canine-pideds residing on the planet Altam just barely within the \
dual-star Vazzend system. Their politically de-centralized society and independent natures have led them to become a species and \
culture both feared and respected for their scientific breakthroughs. Discovery, loyalty, and utilitarianism dominates their lifestyles \
to the degree it can cause conflict with more rigorous and strict authorities. They speak a guttural language known as 'Canilunzt' \
which has a heavy emphasis on utilizing tail positioning and ear twitches to communicate intent."
species_traits = list(LIPS)
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
bodyflags = HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED | HAS_HEAD_ACCESSORY | HAS_MARKINGS | HAS_SKIN_COLOR
dietflags = DIET_OMNI
hunger_drain = 0.11
taste_sensitivity = TASTE_SENSITIVITY_SHARP
reagent_tag = PROCESS_ORG
flesh_color = "#966464"
base_color = "#CF4D2F"
butt_sprite = "vulp"
scream_verb = "yelps"
has_organ = list(
"heart" = /obj/item/organ/internal/heart,
"lungs" = /obj/item/organ/internal/lungs,
"liver" = /obj/item/organ/internal/liver/vulpkanin,
"kidneys" = /obj/item/organ/internal/kidneys,
"brain" = /obj/item/organ/internal/brain,
"appendix" = /obj/item/organ/internal/appendix,
"eyes" = /obj/item/organ/internal/eyes/vulpkanin /*Most Vulpkanin see in full colour as a result of genetic augmentation, although it cost them their darksight (darksight = 2)
unless they choose otherwise by selecting the colourblind disability in character creation (darksight = 8 but colourblind).*/
)
allowed_consumed_mobs = list(/mob/living/simple_animal/mouse, /mob/living/simple_animal/lizard, /mob/living/simple_animal/chick, /mob/living/simple_animal/chicken,
/mob/living/simple_animal/crab, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/parrot, /mob/living/simple_animal/tribble)
suicide_messages = list(
"is attempting to bite their tongue off!",
"is jamming their claws into their eye sockets!",
"is twisting their own neck!",
"is holding their breath!")
/datum/species/vulpkanin/handle_death(var/mob/living/carbon/human/H)
H.stop_tail_wagging(1)
@@ -0,0 +1,78 @@
/datum/species/wryn
name = "Wryn"
name_plural = "Wryn"
icobase = 'icons/mob/human_races/r_wryn.dmi'
deform = 'icons/mob/human_races/r_wryn.dmi'
language = "Wryn Hivemind"
tail = "wryntail"
punchdamagelow = 0
punchdamagehigh = 1
//primitive = /mob/living/carbon/monkey/wryn
slowdown = 1
warning_low_pressure = -300
hazard_low_pressure = 1
blurb = "The wryn (r-in, singular r-in) are a humanoid race that possess many bee-like features. Originating from Alveare they \
have adapted extremely well to cold environments though have lost most of their muscles over generations.\
In order to communicate and work with multi-species crew Wryn were forced to take on names. Wryn have tended towards using only \
first names, these names are generally simplistic and easy to pronounce. Wryn have rarely had to communicate using their mouths, \
so in order to integrate with the multi-species crew they have been taught broken sol?."
cold_level_1 = 200 //Default 260 - Lower is better
cold_level_2 = 150 //Default 200
cold_level_3 = 115 //Default 120
heat_level_1 = 300 //Default 360 - Higher is better
heat_level_2 = 310 //Default 400
heat_level_3 = 317 //Default 1000
body_temperature = 286
has_organ = list(
"heart" = /obj/item/organ/internal/heart,
"brain" = /obj/item/organ/internal/brain,
"eyes" = /obj/item/organ/internal/eyes/wryn, //3 darksight.
"appendix" = /obj/item/organ/internal/appendix,
"antennae" = /obj/item/organ/internal/wryn/hivenode
)
species_traits = list(IS_WHITELISTED, NO_BREATHE, HAS_SKIN_COLOR, NO_SCAN, HIVEMIND)
clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS
dietflags = DIET_HERB //bees feed off nectar, so bee people feed off plants too
oxy_mod = 0
reagent_tag = PROCESS_ORG
base_color = "#704300"
flesh_color = "#704300"
blood_color = "#FFFF99"
//Default styles for created mobs.
default_hair = "Antennae"
/datum/species/wryn/handle_death(var/mob/living/carbon/human/H)
for(var/mob/living/carbon/C in living_mob_list)
if(C.get_int_organ(/obj/item/organ/internal/wryn/hivenode))
to_chat(C, "<span class='danger'><B>Your antennae tingle as you are overcome with pain...</B></span>")
to_chat(C, "<span class='danger'>It feels like part of you has died.</span>")
/datum/species/wryn/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
if(target.handcuffed && target.get_int_organ(/obj/item/organ/internal/wryn/hivenode))
user.visible_message("<span class='notice'>[user] begins to violently pull off [target]'s antennae.</span>")
to_chat(target, "<span class='danger'><B>[user] grips your antennae and starts violently pulling!<B></span>")
if(do_mob(user, target, 250))
var/obj/item/organ/internal/wryn/hivenode/node = new /obj/item/organ/internal/wryn/hivenode
target.remove_language("Wryn Hivemind")
node.remove(target)
node.forceMove(user.loc)
to_chat(user, "<span class='notice'>You hear a loud crunch as you mercilessly pull off [target]'s antennae.</span>")
to_chat(target, "<span class='danger'>You hear a loud crunch as your antennae is ripped off your head by [user].</span>")
to_chat(target, "<span class='danger'><B>It's so quiet...</B></span>")
var/obj/item/organ/external/head/head_organ = target.get_organ("head")
head_organ.h_style = "Bald"
target.update_hair()
add_attack_logs(user, target, "Antennae removed")
return 0
else
..()
@@ -1,19 +1,19 @@
/mob/living/carbon/human/SetStunned(amount, updating = 1, force = 0)
if(species)
amount = amount * species.stun_mod
if(dna.species)
amount = amount * dna.species.stun_mod
..()
/mob/living/carbon/human/SetWeakened(amount, updating = 1, force = 0)
if(species)
amount = amount * species.stun_mod
if(dna.species)
amount = amount * dna.species.stun_mod
..()
/mob/living/carbon/human/SetParalysis(amount, updating = 1, force = 0)
if(species)
amount = amount * species.stun_mod
if(dna.species)
amount = amount * dna.species.stun_mod
..()
/mob/living/carbon/human/SetSleeping(amount, updating = 1, no_alert = FALSE)
if(species)
amount = amount * species.stun_mod
if(dna.species)
amount = amount * dna.species.stun_mod
..()
@@ -185,7 +185,7 @@ var/global/list/damage_icon_parts = list()
previous_damage_appearance = damage_appearance
var/icon/standing = new /icon(species.damage_overlays, "00")
var/icon/standing = new /icon(dna.species.damage_overlays, "00")
var/image/standing_image = new /image("icon" = standing)
@@ -194,18 +194,18 @@ var/global/list/damage_icon_parts = list()
O.update_icon()
if(O.damage_state == "00") continue
var/icon/DI
var/cache_index = "[O.damage_state]/[O.icon_name]/[species.blood_color]/[species.name]"
var/cache_index = "[O.damage_state]/[O.icon_name]/[dna.species.blood_color]/[dna.species.name]"
if(damage_icon_parts[cache_index] == null)
DI = new /icon(species.damage_overlays, O.damage_state) // the damage icon for whole human
DI.Blend(new /icon(species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels
DI.Blend(species.blood_color, ICON_MULTIPLY)
DI = new /icon(dna.species.damage_overlays, O.damage_state) // the damage icon for whole human
DI.Blend(new /icon(dna.species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels
DI.Blend(dna.species.blood_color, ICON_MULTIPLY)
damage_icon_parts[cache_index] = DI
else
DI = damage_icon_parts[cache_index]
standing_image.overlays += DI
overlays_standing[DAMAGE_LAYER] = standing_image
overlays_standing[H_DAMAGE_LAYER] = standing_image
if(update_icons) update_icons()
@@ -220,15 +220,15 @@ var/global/list/damage_icon_parts = list()
var/hulk = (HULK in mutations)
var/skeleton = (SKELETON in mutations)
if(species && species.bodyflags & HAS_ICON_SKIN_TONE)
species.updatespeciescolor(src)
if(dna.species && dna.species.bodyflags & HAS_ICON_SKIN_TONE)
dna.species.updatespeciescolor(src)
//CACHING: Generate an index key from visible bodyparts.
//0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic.
//Create a new, blank icon for our mob to use.
if(stand_icon)
qdel(stand_icon)
stand_icon = new(species.icon_template ? species.icon_template : 'icons/mob/human.dmi',"blank")
stand_icon = new(dna.species.icon_template ? dna.species.icon_template : 'icons/mob/human.dmi',"blank")
var/icon_key = ""
var/obj/item/organ/internal/eyes/eyes = get_int_organ(/obj/item/organ/internal/eyes)
@@ -237,11 +237,11 @@ var/global/list/damage_icon_parts = list()
else
icon_key += "#000000"
for(var/organ_tag in species.has_limbs)
for(var/organ_tag in dna.species.has_limbs)
var/obj/item/organ/external/part = bodyparts_by_name[organ_tag]
if(isnull(part))
icon_key += "0"
else if(part.status & ORGAN_ROBOT)
else if(part.is_robotic())
icon_key += "2[part.model ? "-[part.model]": ""]"
else if(part.status & ORGAN_DEAD)
icon_key += "3"
@@ -249,7 +249,8 @@ var/global/list/damage_icon_parts = list()
icon_key += "1"
if(part)
icon_key += "[part.species.race_key]"
var/datum/species/S = GLOB.all_species[part.dna.species.name] //This has to reference the species datums from round start, since they're global and unchanging
icon_key += "[S.race_key]"
icon_key += "[part.dna.GetUIState(DNA_UI_GENDER)]"
icon_key += "[part.dna.GetUIValue(DNA_UI_SKIN_TONE)]"
if(part.s_col)
@@ -307,7 +308,7 @@ var/global/list/damage_icon_parts = list()
//END CACHED ICON GENERATION.
stand_icon.Blend(base_icon,ICON_OVERLAY)
if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the user's species is flagged to have a tail that needs to be overlapped by limbs... (having a non-tail body accessory like the snake body will override this)
if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the user's species is flagged to have a tail that needs to be overlapped by limbs... (having a non-tail body accessory like the snake body will override this)
overlays_standing[LIMBS_LAYER] = image(stand_icon) // Diverts limbs to their own layer so they can overlay things (i.e. tails).
else
overlays_standing[LIMBS_LAYER] = null // So we don't get the old species' sprite splatted on top of the new one's
@@ -316,18 +317,18 @@ var/global/list/damage_icon_parts = list()
overlays_standing[UNDERWEAR_LAYER] = null
var/icon/underwear_standing = new/icon('icons/mob/underwear.dmi',"nude")
if(underwear && species.clothing_flags & HAS_UNDERWEAR)
if(underwear && dna.species.clothing_flags & HAS_UNDERWEAR)
var/datum/sprite_accessory/underwear/U = underwear_list[underwear]
if(U)
underwear_standing.Blend(new /icon(U.icon, "uw_[U.icon_state]_s"), ICON_OVERLAY)
if(undershirt && species.clothing_flags & HAS_UNDERSHIRT)
if(undershirt && dna.species.clothing_flags & HAS_UNDERSHIRT)
var/datum/sprite_accessory/undershirt/U2 = undershirt_list[undershirt]
if(U2)
underwear_standing.Blend(new /icon(U2.icon, "us_[U2.icon_state]_s"), ICON_OVERLAY)
if(socks && species.clothing_flags & HAS_SOCKS)
if(socks && dna.species.clothing_flags & HAS_SOCKS)
var/datum/sprite_accessory/socks/U3 = socks_list[socks]
if(U3)
underwear_standing.Blend(new /icon(U3.icon, "sk_[U3.icon_state]_s"), ICON_OVERLAY)
@@ -339,7 +340,7 @@ var/global/list/damage_icon_parts = list()
if(update_icons)
update_icons()
if(lip_style && (LIPS in species.species_traits))
if(lip_style && (LIPS in dna.species.species_traits))
var/icon/lips = icon("icon"='icons/mob/human_face.dmi', "icon_state"="lips_[lip_style]_s")
lips.Blend(lip_color, ICON_ADD)
@@ -369,7 +370,7 @@ var/global/list/damage_icon_parts = list()
if(chest_organ && m_styles["body"])
var/body_marking = m_styles["body"]
var/datum/sprite_accessory/body_marking_style = marking_styles_list[body_marking]
if(body_marking_style && body_marking_style.species_allowed && (species.name in body_marking_style.species_allowed))
if(body_marking_style && body_marking_style.species_allowed && (dna.species.name in body_marking_style.species_allowed))
var/icon/b_marking_s = new/icon("icon" = body_marking_style.icon, "icon_state" = "[body_marking_style.icon_state]_s")
if(body_marking_style.do_colouration)
b_marking_s.Blend(m_colours["body"], ICON_ADD)
@@ -379,7 +380,7 @@ var/global/list/damage_icon_parts = list()
if(head_organ && m_styles["head"]) //If the head is destroyed, forget the head markings. This prevents floating optical markings on decapitated IPCs, for example.
var/head_marking = m_styles["head"]
var/datum/sprite_accessory/head_marking_style = marking_styles_list[head_marking]
if(head_marking_style && head_marking_style.species_allowed && (head_organ.species.name in head_marking_style.species_allowed))
if(head_marking_style && head_marking_style.species_allowed && (head_organ.dna.species.name in head_marking_style.species_allowed))
var/icon/h_marking_s = new/icon("icon" = head_marking_style.icon, "icon_state" = "[head_marking_style.icon_state]_s")
if(head_marking_style.do_colouration)
h_marking_s.Blend(m_colours["head"], ICON_ADD)
@@ -407,10 +408,10 @@ var/global/list/damage_icon_parts = list()
//base icons
var/icon/head_accessory_standing = new /icon('icons/mob/body_accessory.dmi',"accessory_none_s")
if(head_organ.ha_style && (head_organ.species.bodyflags & HAS_HEAD_ACCESSORY))
if(head_organ.ha_style && (head_organ.dna.species.bodyflags & HAS_HEAD_ACCESSORY))
var/datum/sprite_accessory/head_accessory/head_accessory_style = head_accessory_styles_list[head_organ.ha_style]
if(head_accessory_style && head_accessory_style.species_allowed)
if(head_organ.species.name in head_accessory_style.species_allowed)
if(head_organ.dna.species.name in head_accessory_style.species_allowed)
var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s")
if(head_accessory_style.do_colouration)
head_accessory_s.Blend(head_organ.headacc_colour, ICON_ADD)
@@ -448,12 +449,12 @@ var/global/list/damage_icon_parts = list()
if(head_organ.h_style && !(head && (head.flags & BLOCKHEADHAIR) && !(isSynthetic())))
var/datum/sprite_accessory/hair/hair_style = hair_styles_full_list[head_organ.h_style]
//if(!src.get_int_organ(/obj/item/organ/internal/brain) && src.get_species() != "Machine" )//make it obvious we have NO BRAIN
//if(!src.get_int_organ(/obj/item/organ/internal/brain) && !ismachine(src))//make it obvious we have NO BRAIN
// hair_standing.Blend(debrained_s, ICON_OVERLAY)
if(hair_style && hair_style.species_allowed)
if((head_organ.species.name in hair_style.species_allowed) || (head_organ.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics...
if((head_organ.dna.species.name in hair_style.species_allowed) || (head_organ.dna.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics...
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
if(head_organ.species.name == "Slime People") // I am el worstos
if(istype(head_organ.dna.species, /datum/species/slime)) // I am el worstos
hair_s.Blend("[skin_colour]A0", ICON_AND)
else if(hair_style.do_colouration)
hair_s.Blend(head_organ.hair_colour, ICON_ADD)
@@ -497,9 +498,9 @@ var/global/list/damage_icon_parts = list()
if(head_organ.f_style)
var/datum/sprite_accessory/facial_hair/facial_hair_style = facial_hair_styles_list[head_organ.f_style]
if(facial_hair_style && facial_hair_style.species_allowed)
if((head_organ.species.name in facial_hair_style.species_allowed) || (head_organ.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics...
if((head_organ.dna.species.name in facial_hair_style.species_allowed) || (head_organ.dna.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics...
var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
if(head_organ.species.name == "Slime People") // I am el worstos
if(istype(head_organ.dna.species, /datum/species/slime)) // I am el worstos
facial_s.Blend("[skin_colour]A0", ICON_AND)
else if(facial_hair_style.do_colouration)
facial_s.Blend(head_organ.facial_colour, ICON_ADD)
@@ -644,11 +645,11 @@ var/global/list/damage_icon_parts = list()
if(w_uniform.icon_override)
standing.icon = w_uniform.icon_override
else if(w_uniform.sprite_sheets && w_uniform.sprite_sheets[species.name])
standing.icon = w_uniform.sprite_sheets[species.name]
else if(w_uniform.sprite_sheets && w_uniform.sprite_sheets[dna.species.name])
standing.icon = w_uniform.sprite_sheets[dna.species.name]
if(w_uniform.blood_DNA)
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "uniformblood")
var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "uniformblood")
bloodsies.color = w_uniform.blood_color
standing.overlays += bloodsies
@@ -658,8 +659,8 @@ var/global/list/damage_icon_parts = list()
if(!tie_color) tie_color = A.icon_state
if(A.icon_override)
standing.overlays += image("icon" = A.icon_override, "icon_state" = "[A.icon_state]")
else if(A.sprite_sheets && A.sprite_sheets[species.name])
standing.overlays += image("icon" = A.sprite_sheets[species.name], "icon_state" = "[A.icon_state]")
else if(A.sprite_sheets && A.sprite_sheets[dna.species.name])
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]")
@@ -720,19 +721,19 @@ var/global/list/damage_icon_parts = list()
var/image/standing
if(gloves.icon_override)
standing = image("icon" = gloves.icon_override, "icon_state" = "[t_state]")
else if(gloves.sprite_sheets && gloves.sprite_sheets[species.name])
standing = image("icon" = gloves.sprite_sheets[species.name], "icon_state" = "[t_state]")
else if(gloves.sprite_sheets && gloves.sprite_sheets[dna.species.name])
standing = image("icon" = gloves.sprite_sheets[dna.species.name], "icon_state" = "[t_state]")
else
standing = image("icon" = 'icons/mob/hands.dmi', "icon_state" = "[t_state]")
if(gloves.blood_DNA)
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "bloodyhands")
var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "bloodyhands")
bloodsies.color = gloves.blood_color
standing.overlays += bloodsies
overlays_standing[GLOVES_LAYER] = standing
else
if(blood_DNA)
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "bloodyhands")
var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "bloodyhands")
bloodsies.color = hand_blood_color
overlays_standing[GLOVES_LAYER] = bloodsies
else
@@ -759,8 +760,8 @@ var/global/list/damage_icon_parts = list()
if(glasses.icon_override)
new_glasses = image("icon" = glasses.icon_override, "icon_state" = "[glasses.icon_state]")
else if(glasses.sprite_sheets && glasses.sprite_sheets[head_organ.species.name])
new_glasses = image("icon" = glasses.sprite_sheets[head_organ.species.name], "icon_state" = "[glasses.icon_state]")
else if(glasses.sprite_sheets && glasses.sprite_sheets[head_organ.dna.species.name])
new_glasses = image("icon" = glasses.sprite_sheets[head_organ.dna.species.name], "icon_state" = "[glasses.icon_state]")
else
new_glasses = image("icon" = 'icons/mob/eyes.dmi', "icon_state" = "[glasses.icon_state]")
@@ -795,9 +796,9 @@ var/global/list/damage_icon_parts = list()
if(l_ear.icon_override)
t_type = "[t_type]_l"
overlays_standing[EARS_LAYER] = image("icon" = l_ear.icon_override, "icon_state" = "[t_type]")
else if(l_ear.sprite_sheets && l_ear.sprite_sheets[species.name])
else if(l_ear.sprite_sheets && l_ear.sprite_sheets[dna.species.name])
t_type = "[t_type]_l"
overlays_standing[EARS_LAYER] = image("icon" = l_ear.sprite_sheets[species.name], "icon_state" = "[t_type]")
overlays_standing[EARS_LAYER] = image("icon" = l_ear.sprite_sheets[dna.species.name], "icon_state" = "[t_type]")
else
overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]")
@@ -811,9 +812,9 @@ var/global/list/damage_icon_parts = list()
if(r_ear.icon_override)
t_type = "[t_type]_r"
overlays_standing[EARS_LAYER] = image("icon" = r_ear.icon_override, "icon_state" = "[t_type]")
else if(r_ear.sprite_sheets && r_ear.sprite_sheets[species.name])
else if(r_ear.sprite_sheets && r_ear.sprite_sheets[dna.species.name])
t_type = "[t_type]_r"
overlays_standing[EARS_LAYER] = image("icon" = r_ear.sprite_sheets[species.name], "icon_state" = "[t_type]")
overlays_standing[EARS_LAYER] = image("icon" = r_ear.sprite_sheets[dna.species.name], "icon_state" = "[t_type]")
else
overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]")
@@ -837,20 +838,20 @@ var/global/list/damage_icon_parts = list()
var/image/standing
if(shoes.icon_override)
standing = image("icon" = shoes.icon_override, "icon_state" = "[shoes.icon_state]")
else if(shoes.sprite_sheets && shoes.sprite_sheets[species.name])
standing = image("icon" = shoes.sprite_sheets[species.name], "icon_state" = "[shoes.icon_state]")
else if(shoes.sprite_sheets && shoes.sprite_sheets[dna.species.name])
standing = image("icon" = shoes.sprite_sheets[dna.species.name], "icon_state" = "[shoes.icon_state]")
else
standing = image("icon" = 'icons/mob/feet.dmi', "icon_state" = "[shoes.icon_state]")
if(shoes.blood_DNA)
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "shoeblood")
var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "shoeblood")
bloodsies.color = shoes.blood_color
standing.overlays += bloodsies
overlays_standing[SHOES_LAYER] = standing
else
if(feet_blood_DNA)
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "shoeblood")
var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "shoeblood")
bloodsies.color = feet_blood_color
overlays_standing[SHOES_LAYER] = bloodsies
else
@@ -891,13 +892,13 @@ var/global/list/damage_icon_parts = list()
var/image/standing
if(head.icon_override)
standing = image("icon" = head.icon_override, "icon_state" = "[head.icon_state]")
else if(head.sprite_sheets && head.sprite_sheets[species.name])
standing = image("icon" = head.sprite_sheets[species.name], "icon_state" = "[head.icon_state]")
else if(head.sprite_sheets && head.sprite_sheets[dna.species.name])
standing = image("icon" = head.sprite_sheets[dna.species.name], "icon_state" = "[head.icon_state]")
else
standing = image("icon" = 'icons/mob/head.dmi', "icon_state" = "[head.icon_state]")
if(head.blood_DNA)
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "helmetblood")
var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "helmetblood")
bloodsies.color = head.blood_color
standing.overlays += bloodsies
overlays_standing[HEAD_LAYER] = standing
@@ -925,8 +926,8 @@ var/global/list/damage_icon_parts = list()
if(belt.icon_override)
t_state = "[t_state]_be"
overlays_standing[BELT_LAYER] = image("icon" = belt.icon_override, "icon_state" = "[t_state]")
else if(belt.sprite_sheets && belt.sprite_sheets[species.name])
overlays_standing[BELT_LAYER] = image("icon" = belt.sprite_sheets[species.name], "icon_state" = "[t_state]")
else if(belt.sprite_sheets && belt.sprite_sheets[dna.species.name])
overlays_standing[BELT_LAYER] = image("icon" = belt.sprite_sheets[dna.species.name], "icon_state" = "[t_state]")
else
overlays_standing[BELT_LAYER] = image("icon" = 'icons/mob/belt.dmi', "icon_state" = "[t_state]")
else
@@ -949,8 +950,8 @@ var/global/list/damage_icon_parts = list()
var/image/standing
if(wear_suit.icon_override)
standing = image("icon" = wear_suit.icon_override, "icon_state" = "[wear_suit.icon_state]")
else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[species.name])
standing = image("icon" = wear_suit.sprite_sheets[species.name], "icon_state" = "[wear_suit.icon_state]")
else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[dna.species.name])
standing = image("icon" = wear_suit.sprite_sheets[dna.species.name], "icon_state" = "[wear_suit.icon_state]")
else if(FAT in mutations)
if(wear_suit.flags_size & ONESIZEFITSALL)
standing = image("icon" = 'icons/mob/suit_fat.dmi', "icon_state" = "[wear_suit.icon_state]")
@@ -969,7 +970,7 @@ var/global/list/damage_icon_parts = list()
if(wear_suit.blood_DNA)
var/obj/item/clothing/suit/S = wear_suit
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "[S.blood_overlay_type]blood")
var/image/bloodsies = image("icon" = dna.species.blood_mask, "icon_state" = "[S.blood_overlay_type]blood")
bloodsies.color = wear_suit.blood_color
standing.overlays += bloodsies
@@ -1035,14 +1036,14 @@ var/global/list/damage_icon_parts = list()
if(wear_mask.icon_override)
mask_icon = new(wear_mask.icon_override)
standing = image("icon" = wear_mask.icon_override, "icon_state" = "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]")
else if(wear_mask.sprite_sheets && wear_mask.sprite_sheets[species.name])
mask_icon = new(wear_mask.sprite_sheets[species.name])
standing = image("icon" = wear_mask.sprite_sheets[species.name], "icon_state" = "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]")
else if(wear_mask.sprite_sheets && wear_mask.sprite_sheets[dna.species.name])
mask_icon = new(wear_mask.sprite_sheets[dna.species.name])
standing = image("icon" = wear_mask.sprite_sheets[dna.species.name], "icon_state" = "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]")
else
standing = image("icon" = 'icons/mob/mask.dmi', "icon_state" = "[wear_mask.icon_state][(alternate_head && ("[wear_mask.icon_state]_[alternate_head.suffix]" in mask_icon.IconStates())) ? "_[alternate_head.suffix]" : ""]")
if(!istype(wear_mask, /obj/item/clothing/mask/cigarette) && wear_mask.blood_DNA)
var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "maskblood")
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
@@ -1058,12 +1059,12 @@ var/global/list/damage_icon_parts = list()
var/icon/standing
if(back.icon_override)
standing = image("icon" = back.icon_override, "icon_state" = "[back.icon_state]")
else if(istype(back, /obj/item/weapon/rig))
else if(istype(back, /obj/item/rig))
//If this is a rig and a mob_icon is set, it will take species into account in the rig update_icon() proc.
var/obj/item/weapon/rig/rig = back
var/obj/item/rig/rig = back
standing = rig.mob_icon
else if(back.sprite_sheets && back.sprite_sheets[species.name])
standing = image("icon" = back.sprite_sheets[species.name], "icon_state" = "[back.icon_state]")
else if(back.sprite_sheets && back.sprite_sheets[dna.species.name])
standing = image("icon" = back.sprite_sheets[dna.species.name], "icon_state" = "[back.icon_state]")
else
standing = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]")
@@ -1077,7 +1078,7 @@ var/global/list/damage_icon_parts = list()
/mob/living/carbon/human/update_inv_handcuffed(var/update_icons=1)
overlays_standing[HANDCUFF_LAYER] = null
if(handcuffed)
if(istype(handcuffed, /obj/item/weapon/restraints/handcuffs/pinkcuffs))
if(istype(handcuffed, /obj/item/restraints/handcuffs/pinkcuffs))
overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "pinkcuff1")
else
overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1")
@@ -1163,7 +1164,7 @@ var/global/list/damage_icon_parts = list()
var/icon/tail_marking_icon
var/datum/sprite_accessory/body_markings/tail/tail_marking_style
if(m_styles["tail"] != "None" && (species.bodyflags & HAS_TAIL_MARKINGS))
if(m_styles["tail"] != "None" && (dna.species.bodyflags & HAS_TAIL_MARKINGS))
var/tail_marking = m_styles["tail"]
tail_marking_style = marking_styles_list[tail_marking]
tail_marking_icon = new/icon("icon" = tail_marking_style.icon, "icon_state" = "[tail_marking_style.icon_state]_s")
@@ -1172,11 +1173,11 @@ var/global/list/damage_icon_parts = list()
if(body_accessory)
if(body_accessory.try_restrictions(src))
var/icon/accessory_s = new/icon("icon" = body_accessory.icon, "icon_state" = body_accessory.icon_state)
if(species.bodyflags & HAS_SKIN_COLOR)
if(dna.species.bodyflags & HAS_SKIN_COLOR)
accessory_s.Blend(skin_colour, body_accessory.blend_mode)
if(tail_marking_icon && (body_accessory.name in tail_marking_style.tails_allowed))
accessory_s.Blend(tail_marking_icon, ICON_OVERLAY)
if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this)
if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this)
// Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway.
var/icon/under = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "accessory_none_s")
under.Insert(new/icon(accessory_s, dir=SOUTH), dir=SOUTH)
@@ -1194,14 +1195,14 @@ var/global/list/damage_icon_parts = list()
else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation.
overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset)
else if(tail && species.bodyflags & HAS_TAIL) //no tailless tajaran
else if(tail && dna.species.bodyflags & HAS_TAIL) //no tailless tajaran
if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space))
var/icon/tail_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[tail]_s")
if(species.bodyflags & HAS_SKIN_COLOR)
if(dna.species.bodyflags & HAS_SKIN_COLOR)
tail_s.Blend(skin_colour, ICON_ADD)
if(tail_marking_icon && !tail_marking_style.tails_allowed)
tail_s.Blend(tail_marking_icon, ICON_OVERLAY)
if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this)
if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this)
// Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway.
var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "blank")
under.Insert(new/icon(tail_s, dir=SOUTH), dir=SOUTH)
@@ -1230,7 +1231,7 @@ var/global/list/damage_icon_parts = list()
var/icon/tail_marking_icon
var/datum/sprite_accessory/body_markings/tail/tail_marking_style
if(m_styles["tail"] != "None" && (species.bodyflags & HAS_TAIL_MARKINGS))
if(m_styles["tail"] != "None" && (dna.species.bodyflags & HAS_TAIL_MARKINGS))
var/tail_marking = m_styles["tail"]
tail_marking_style = marking_styles_list[tail_marking]
tail_marking_icon = new/icon("icon" = tail_marking_style.icon, "icon_state" = "[tail_marking_style.icon_state]w_s")
@@ -1238,15 +1239,15 @@ var/global/list/damage_icon_parts = list()
if(body_accessory)
var/icon/accessory_s = new/icon("icon" = body_accessory.get_animated_icon(), "icon_state" = body_accessory.get_animated_icon_state())
if(species.bodyflags & HAS_SKIN_COLOR)
if(dna.species.bodyflags & HAS_SKIN_COLOR)
accessory_s.Blend(skin_colour, body_accessory.blend_mode)
if(tail_marking_icon && (body_accessory.name in tail_marking_style.tails_allowed))
accessory_s.Blend(tail_marking_icon, ICON_OVERLAY)
if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this)
if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this)
// Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway.
var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "Vulpkanin_tail_delay")
if(body_accessory.allowed_species && (species.name in body_accessory.allowed_species))
under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.name]_tail_delay")
if(body_accessory.allowed_species && (dna.species.name in body_accessory.allowed_species))
under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay")
under.Insert(new/icon(accessory_s, dir=SOUTH), dir=SOUTH)
under.Insert(new/icon(accessory_s, dir=EAST), dir=EAST)
under.Insert(new/icon(accessory_s, dir=WEST), dir=WEST)
@@ -1255,23 +1256,23 @@ var/global/list/damage_icon_parts = list()
// Creates a blank icon, and copies accessory_s' north direction sprite into it before passing that to the tail layer that overlays uniforms and such.
var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "Vulpkanin_tail_delay")
if(body_accessory.allowed_species && (species.name in body_accessory.allowed_species)) // If the user's species is in the list of allowed species for the currently selected body accessory, use the appropriate animation timing blank
over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.name]_tail_delay")
if(body_accessory.allowed_species && (dna.species.name in body_accessory.allowed_species)) // If the user's species is in the list of allowed species for the currently selected body accessory, use the appropriate animation timing blank
over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay")
over.Insert(new/icon(accessory_s, dir=NORTH), dir=NORTH)
overlays_standing[TAIL_LAYER] = image(over, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset)
else // Otherwise, since the user's tail isn't overlapped by limbs, go ahead and use default icon generation.
overlays_standing[TAIL_LAYER] = image(accessory_s, "pixel_x" = body_accessory.pixel_x_offset, "pixel_y" = body_accessory.pixel_y_offset)
else if(tail && species.bodyflags & HAS_TAIL)
else if(tail && dna.species.bodyflags & HAS_TAIL)
var/icon/tailw_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[tail]w_s")
if(species.bodyflags & HAS_SKIN_COLOR)
if(dna.species.bodyflags & HAS_SKIN_COLOR)
tailw_s.Blend(skin_colour, ICON_ADD)
if(tail_marking_icon && !tail_marking_style.tails_allowed)
tailw_s.Blend(tail_marking_icon, ICON_OVERLAY)
if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this)
if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this)
// Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway.
var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.name]_tail_delay")
var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay")
under.Insert(new/icon(tailw_s, dir=SOUTH), dir=SOUTH)
under.Insert(new/icon(tailw_s, dir=EAST), dir=EAST)
under.Insert(new/icon(tailw_s, dir=WEST), dir=WEST)
@@ -1279,7 +1280,7 @@ var/global/list/damage_icon_parts = list()
overlays_standing[TAIL_UNDERLIMBS_LAYER] = image(under)
// Creates a blank icon, and copies accessory_s' north direction sprite into it before passing that to the tail layer that overlays uniforms and such.
var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.name]_tail_delay")
var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay")
over.Insert(new/icon(tailw_s, dir=NORTH), dir=NORTH)
overlays_standing[TAIL_LAYER] = image(over)
@@ -1314,8 +1315,8 @@ var/global/list/damage_icon_parts = list()
var/icon/icon_file = new(icon_path)
if(wear_suit.icon_state in icon_file.IconStates())
standing = image("icon" = icon_file, "icon_state" = "[wear_suit.icon_state]")
else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[species.name])
var/icon_path = "[wear_suit.sprite_sheets[species.name]]"
else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[dna.species.name])
var/icon_path = "[wear_suit.sprite_sheets[dna.species.name]]"
icon_path = "[copytext(icon_path, 1, findtext(icon_path, "/suit.dmi"))]/collar.dmi" //If this file doesn't exist, the end result is that COLLAR_LAYER will be unchanged (empty).
if(fexists(icon_path)) //Just ensuring the nonexistance of a file with the above path won't cause a runtime.
var/icon/icon_file = new(icon_path)
+9 -9
View File
@@ -1,4 +1,4 @@
/mob/living/carbon/Life()
/mob/living/carbon/Life(seconds, times_fired)
set invisibility = 0
set background = BACKGROUND_ENABLED
@@ -14,7 +14,7 @@
O.on_life()
handle_changeling()
handle_wetness()
handle_wetness(times_fired)
// Increase germ_level regularly
if(germ_level < GERM_LEVEL_AMBIENT && prob(30)) //if you're just standing there, you shouldn't get more germs beyond an ambient level
@@ -26,8 +26,8 @@
///////////////
//Start of a breath chain, calls breathe()
/mob/living/carbon/handle_breathing()
if(mob_master.current_cycle % 4 == 2 || failed_last_breath)
/mob/living/carbon/handle_breathing(times_fired)
if(times_fired % 4 == 2 || failed_last_breath)
breathe() //Breathe per 4 ticks, unless suffocating
else
if(istype(loc, /obj/))
@@ -241,11 +241,11 @@
reagents.metabolize(src)
/mob/living/carbon/proc/handle_wetness()
if(mob_master.current_cycle%20==2) //dry off a bit once every 20 ticks or so
/mob/living/carbon/proc/handle_wetness(times_fired)
if(times_fired % 20==2) //dry off a bit once every 20 ticks or so
wetlevel = max(wetlevel - 1,0)
/mob/living/carbon/handle_stomach()
/mob/living/carbon/handle_stomach(times_fired)
for(var/mob/living/M in stomach_contents)
if(M.loc != src)
stomach_contents.Remove(M)
@@ -255,7 +255,7 @@
stomach_contents.Remove(M)
qdel(M)
continue
if(mob_master.current_cycle%3==1)
if(times_fired % 3 == 1)
M.adjustBruteLoss(5)
nutrition += 10
@@ -357,7 +357,7 @@
if(istype(buckled, /obj/structure/stool/bed))
var/obj/structure/stool/bed/bed = buckled
comfort+= bed.comfort
for(var/obj/item/weapon/bedsheet/bedsheet in range(loc,0))
for(var/obj/item/bedsheet/bedsheet in range(loc,0))
if(bedsheet.loc != loc) //bedsheets in your backpack/neck don't give you comfort
continue
comfort+= bedsheet.comfort
@@ -1,4 +1,6 @@
/mob/living/carbon/slime/death(gibbed)
if(stat == DEAD)
return
if(!gibbed)
if(is_adult)
var/mob/living/carbon/slime/M = new /mob/living/carbon/slime(loc)
@@ -11,13 +13,11 @@
number = rand(1, 1000)
name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])"
return
if(stat == DEAD) return
else
visible_message("<b>The [name]</b> seizes up and falls limp...")
stat = DEAD
icon_state = "[colour] baby slime dead"
overlays.len = 0
for(var/mob/O in viewers(src, null))
O.show_message("<b>The [name]</b> seizes up and falls limp...", 1) //ded -- Urist
update_canmove()
+38 -9
View File
@@ -1,4 +1,4 @@
/mob/living/carbon/slime/emote(var/act, var/m_type=1, var/message = null)
/mob/living/carbon/slime/emote(act, m_type = 1, message = null)
if(findtext(act, "-", 1, null))
var/t1 = findtext(act, "-", 1, null)
//param = copytext(act, t1 + 1, length(act) + 1)
@@ -8,6 +8,9 @@
act = copytext(act,1,length(act))
act = lowertext(act)
var/regenerate_icons
switch(act) //Alphabetical please
if("me")
if(silent)
@@ -58,18 +61,44 @@
message = "<B>The [src.name]</B> vibrates!"
m_type = 1
if("noface") //mfw I have no face
mood = null
regenerate_icons = 1
if("smile")
mood = "mischevous"
regenerate_icons = 1
if(":3")
mood = ":33"
regenerate_icons = 1
if("pout")
mood = "pout"
regenerate_icons = 1
if("frown")
mood = "sad"
regenerate_icons = 1
if("scowl")
mood = "angry"
regenerate_icons = 1
if("help") //This is an exception
to_chat(src, "Help for slime emotes. You can use these emotes with say \"*emote\":\n\nbounce, custom, jiggle, light, moan, shiver, sway, twitch, vibrate")
to_chat(src, "Help for slime emotes. You can use these emotes with say \"*emote\":\n\nbounce, custom, jiggle, light, moan, shiver, sway, twitch, vibrate. \n\nYou may also change your face with: \n\nsmile, :3, pout, frown, scowl, noface")
else
to_chat(src, "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>")
if((message && src.stat == 0))
if((message && stat == CONSCIOUS))
if(client)
log_emote("[name]/[key] : [message]")
if(m_type & 1)
for(var/mob/O in viewers(src, null))
O.show_message(message, m_type)
//Foreach goto(703)
visible_message(message)
else
for(var/mob/O in hearers(src, null))
O.show_message(message, m_type)
//Foreach goto(746)
loc.audible_message(message)
if(regenerate_icons)
regenerate_icons()
return
+41 -10
View File
@@ -5,7 +5,7 @@
var/Discipline = 0 // if a slime has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while
var/SStun = 0 // stun variable
/mob/living/carbon/slime/Life()
/mob/living/carbon/slime/Life(seconds, times_fired)
if(..())
handle_nutrition()
handle_targets()
@@ -156,7 +156,14 @@
if(reagents)
reagents.metabolize(src)
src.updatehealth()
if(reagents.get_reagent_amount("plasma")>=5)
mutation_chance = min(mutation_chance + 5,50) //Prevents mutation chance going >50%
reagents.remove_reagent("plasma", 5)
if(reagents.get_reagent_amount("epinephrine")>=5)
mutation_chance = max(mutation_chance - 5,0) //Prevents mutation chance going <0%
reagents.remove_reagent("epinephrine", 5)
updatehealth()
return //TODO: DEFERRED
@@ -235,6 +242,10 @@
/mob/living/carbon/slime/proc/handle_nutrition()
if(docile) //God as my witness, I will never go hungry again
nutrition = 700
return
if(prob(15))
nutrition -= 1 + is_adult
@@ -254,6 +265,15 @@
else
Evolve()
/mob/living/carbon/slime/proc/add_nutrition(nutrition_to_add = 0, lastnut = 0)
nutrition = min((nutrition + nutrition_to_add), get_max_nutrition())
if(nutrition >= (lastnut + 50))
if(prob(80))
lastnut = nutrition
powerlevel++
if(powerlevel > 10)
powerlevel = 10
adjustToxLoss(-10)
/mob/living/carbon/slime/proc/handle_targets()
if(Tempstun)
@@ -282,7 +302,7 @@
if(Target)
--target_patience
if(target_patience <= 0 || SStun || Discipline || attacked) // Tired of chasing or something draws out attention
if(target_patience <= 0 || SStun || Discipline || attacked || docile) // Tired of chasing or something draws out attention
target_patience = 0
Target = null
@@ -317,7 +337,7 @@
if(istype(L, /mob/living/carbon/human)) //Ignore slime(wo)men
var/mob/living/carbon/human/H = L
if(H.species.name == "Slime People")
if(isslimeperson(H))
continue
if(!L.canmove) // Only one slime can latch on at a time.
@@ -365,6 +385,8 @@
else
if(holding_still)
holding_still = max(holding_still - 1, 0)
else if(docile && pulledby)
holding_still = 10
else if(canmove && isturf(loc) && prob(33))
step(src, pick(cardinal))
else if(!AIproc)
@@ -374,8 +396,12 @@
/mob/living/carbon/slime/proc/handle_speech_and_mood()
//Mood starts here
var/newmood = ""
if(rabid || attacked) newmood = "angry"
else if(Target) newmood = "mischevous"
if(rabid || attacked)
newmood = "angry"
else if(docile)
newmood = ":3"
else if(Target)
newmood = "mischevous"
if(!newmood)
if(Discipline && prob(25))
@@ -544,8 +570,13 @@
if(is_adult) return 300
else return 200
/mob/living/carbon/slime/proc/will_hunt(var/hunger = -1) // Check for being stopped from feeding and chasing
if(hunger == 2 || rabid || attacked) return 1
if(Leader) return 0
if(holding_still) return 0
/mob/living/carbon/slime/proc/will_hunt(hunger = -1) // Check for being stopped from feeding and chasing
if(docile)
return 0
if(hunger == 2 || rabid || attacked)
return 1
if(Leader)
return 0
if(holding_still)
return 0
return 1
+49 -52
View File
@@ -3,11 +3,15 @@
set desc = "This will let you feed on any valid creature in the surrounding area. This should also be used to halt the feeding process."
if(Victim)
Feedstop()
return
return 0
if(docile)
to_chat(src, "<span class='notice'><i>I'm not hungry anymore...</i></span>")
return 0
if(stat)
to_chat(src, "<i>I must be conscious to do this...</i>")
return
return 0
var/list/choices = list()
for(var/mob/living/C in view(1,src))
@@ -15,32 +19,31 @@
choices += C
var/mob/living/M = input(src,"Who do you wish to feed on?") in null|choices
if(!M) return
if(!M)
return 0
if(Adjacent(M))
if(!istype(src, /mob/living/carbon/brain))
if(!istype(M, /mob/living/carbon/slime))
if(stat != 2)
if(health > -70)
for(var/mob/living/carbon/slime/met in view())
if(met.Victim == M && met != src)
to_chat(src, "<i>The [met.name] is already feeding on this subject...</i>")
return
to_chat(src, "<span class='notice'><i>I have latched onto the subject and begun feeding...</i></span>")
to_chat(M, "<span class='danger'>The [src.name] has latched onto your head!</span>")
Feedon(M)
else
to_chat(src, "<i>This subject does not have a strong enough life energy...</i>")
else
to_chat(src, "<i>This subject does not have an edible life energy...</i>")
else
to_chat(src, "<i>I must not feed on my brothers...</i>")
else
if(isbrain(M))
to_chat(src, "<i>This subject does not have an edible life energy...</i>")
return 0
if(iscarbon(M) && (M.health < -70))
to_chat(src, "<i>This subject does not have a strong enough life energy...</i>")
return 0
if(isanimal(M) && (M.health < 1))//animals don't go into crit, stupid; fixes infinite energy exploit
to_chat(src, "<i>This subject does not have a strong enough life energy...</i>")
return 0
for(var/mob/living/carbon/slime/met in view())
if(met.Victim == M && met != src)
to_chat(src, "<i>The [met.name] is already feeding on this subject...</i>")
return 0
to_chat(src, "<span class='notice'><i>I have latched onto the subject and begun feeding...</i></span>")
to_chat(M, "<span class='danger'>The [name] has latched onto your head!</span>")
Feedon(M)
return 1
/mob/living/carbon/slime/proc/Feedon(var/mob/living/M)
Victim = M
@@ -49,55 +52,49 @@
anchored = 1
var/lastnut = nutrition
var/fed_succesfully = 0
var/health_minimum = -70
if(is_adult)
icon_state = "[colour] adult slime eat"
else
icon_state = "[colour] baby slime eat"
while(Victim && M.health > -70 && M.stat != DEAD && stat != DEAD)
if(isanimal(Victim))
health_minimum = 0
while(Victim && Victim.health > health_minimum && stat != DEAD)
canmove = 0
if(Adjacent(M))
if(Adjacent(Victim))
loc = M.loc
if(prob(15) && M.client && istype(M, /mob/living/carbon))
to_chat(M, "<span class='danger'>[pick("You can feel your body becoming weak!", \
"You feel like you're about to die!", \
"You feel every part of your body screaming in agony!", \
"A low, rolling pain passes through your body!", \
"Your body feels as if it's falling apart!", \
"You feel extremely weak!", \
"A sharp, deep pain bathes every inch of your body!")]</span>")
if(istype(M, /mob/living/carbon))
if(iscarbon(Victim))
Victim.adjustCloneLoss(rand(5,6))
Victim.adjustToxLoss(rand(1,2))
if(Victim.health <= 0)
Victim.adjustToxLoss(rand(2,4))
if(prob(15) && Victim.client)
to_chat(Victim, "<span class='danger'>[pick("You can feel your body becoming weak!", \
"You feel like you're about to die!", \
"You feel every part of your body screaming in agony!", \
"A low, rolling pain passes through your body!", \
"Your body feels as if it's falling apart!", \
"You feel extremely weak!", \
"A sharp, deep pain bathes every inch of your body!")]</span>")
fed_succesfully = 1
else if(istype(M, /mob/living/simple_animal))
else if(health_minimum == 0) //we already know it's a simple_animal from above
Victim.adjustBruteLoss(is_adult ? rand(7, 15) : rand(4, 12))
fed_succesfully = 1
else
if(prob(25))
to_chat(src, "<span class='warning'>[pick("This subject is incompatable", \
"This subject does not have a life energy", "This subject is empty", \
"I am not satisified", "I can not feed from this subject", \
"I do not feel nourished", "This subject is not food")]...</span>")
to_chat(src, "<span class='warning'>[pick("This subject is incompatable", \
"This subject does not have a life energy", "This subject is empty", \
"I am not satisified", "I can not feed from this subject", \
"I do not feel nourished", "This subject is not food")]...</span>")
if(fed_succesfully)
//I have no idea why this is not in handle_nutrition()
nutrition += rand(15,30)
if(nutrition >= lastnut + 50)
if(prob(80))
lastnut = nutrition
powerlevel++
if(powerlevel > 10)
powerlevel = 10
adjustToxLoss(-10)
add_nutrition(rand(15,30), lastnut)
//Heal yourself.
adjustOxyLoss(-10)
@@ -128,7 +125,7 @@
anchored = 0
if(M)
if(M.health <= -70)
if(M.health <= health_minimum)
M.canmove = 0
if(!client)
if(Victim && !rabid && !attacked)
+74 -143
View File
@@ -5,18 +5,14 @@
pass_flags = PASSTABLE
ventcrawler = 2
speak_emote = list("telepathically chirps")
layer = 5
maxHealth = 150
health = 150
gender = NEUTER
nutrition = 700
see_in_dark = 8
update_slimes = 0
faction = list("slime","neutral")
// canstun and canweaken don't affect slimes because they ignore stun and weakened variables
// for the sake of cleanliness, though, here they are.
status_flags = CANPARALYSE|CANPUSH
@@ -44,7 +40,7 @@
var/mood = "" // To show its face
var/is_adult = 0
var/docile = 0
var/core_removal_stage = 0 //For removing cores.
var/mutator_used = FALSE //So you can't shove a dozen mutators into a single slime
@@ -140,7 +136,8 @@
stat(null, "Health: [round((health / 150) * 100)]%")
if(client.statpanel == "Status")
stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]")
if(!docile)
stat(null, "Nutrition: [nutrition]/[get_max_nutrition()]")
if(amount_grown >= 10)
if(is_adult)
stat(null, "You can reproduce!")
@@ -193,6 +190,12 @@
updatehealth()
return
/mob/living/carbon/slime/MouseDrop(atom/movable/A)
if(isliving(A) && A != src && usr == src)
var/mob/living/Food = A
if(Food.Adjacent(src) && !stat && Food.stat != DEAD) //messy
Feedon(Food)
..()
/mob/living/carbon/slime/unEquip(obj/item/W as obj)
return
@@ -200,79 +203,58 @@
/mob/living/carbon/slime/attack_ui(slot)
return
/mob/living/carbon/slime/attack_slime(mob/living/carbon/slime/M as mob)
if(!ticker)
to_chat(M, "You cannot attack people before the game has started.")
/mob/living/carbon/slime/attack_slime(mob/living/carbon/slime/M)
..()
if(Victim)
Victim = null
visible_message("<span class='danger'>[M] pulls [src] off!</span>")
return
if(Victim) return // can't attack while eating!
if(health > -100)
M.do_attack_animation(src)
visible_message("<span class='danger'> The [M.name] has glomped [src]!</span>", \
"<span class='userdanger'> The [M.name] has glomped [src]!</span>")
var/damage = rand(1, 3)
attacked += 5
if(M.is_adult)
damage = rand(1, 6)
else
damage = rand(1, 3)
adjustBruteLoss(damage)
attacked += 5
if(nutrition >= 100) //steal some nutrition. negval handled in life()
nutrition -= (50 + (5 * M.amount_grown))
M.add_nutrition(50 + (5 * M.amount_grown))
if(health > 0)
adjustBruteLoss(4 + (2 * M.amount_grown)) //amt_grown isn't very linear but it works
updatehealth()
return
M.adjustBruteLoss(-4 + (-2 * M.amount_grown))
M.updatehealth()
/mob/living/carbon/slime/attack_animal(mob/living/simple_animal/M as mob)
if(M.melee_damage_upper == 0)
M.custom_emote(1, "[M.friendly] [src]")
else
M.do_attack_animation(src)
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
visible_message("<span class='danger'>[M] [M.attacktext] [src]!</span>", \
"<span class='userdanger'>[M] [M.attacktext] [src]!</span>")
M.create_attack_log("<font color='red'>attacked [src.name] ([src.ckey])</font>")
src.create_attack_log("<font color='orange'>was attacked by [M.name] ([M.ckey])</font>")
/mob/living/carbon/slime/attack_animal(mob/living/simple_animal/M)
if(..())
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
attacked += 10
adjustBruteLoss(damage)
updatehealth()
/mob/living/carbon/slime/attack_larva(mob/living/carbon/alien/larva/L as mob)
/mob/living/carbon/slime/attack_larva(mob/living/carbon/alien/larva/L)
if(..()) //successful larva bite.
var/damage = rand(1, 3)
if(stat != DEAD)
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
adjustBruteLoss(damage)
updatehealth()
switch(L.a_intent)
if(INTENT_HELP)
visible_message("<span class='notice'>[L] rubs its head against [src].</span>")
else
L.do_attack_animation(src)
attacked += 10
visible_message("<span class='danger'>[L] bites [src]!</span>", \
"<span class='userdanger'>[L] bites [src]!</span>")
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
if(stat != DEAD)
var/damage = rand(1, 3)
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
adjustBruteLoss(damage)
/mob/living/carbon/slime/attack_hand(mob/living/carbon/human/M as mob)
if(!ticker)
to_chat(M, "You cannot attack people before the game has started.")
return
if(istype(loc, /turf) && istype(loc.loc, /area/start))
to_chat(M, "No attacking people at spawn, you jackass.")
return
..()
/mob/living/carbon/slime/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
if(user.a_intent == INTENT_HARM)
if(Victim || Target)
Victim = null
Target = null
anchored = 0
if(prob(80) && !client)
Discipline++
spawn(0)
step_away(src, user, 15)
sleep(3)
step_away(src, user, 15)
..(user, TRUE)
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[user] has punched [src]!</span>", "<span class='userdanger'>[user] has punched [src]!</span>")
adjustBruteLoss(15)
return TRUE
/mob/living/carbon/slime/attack_hand(mob/living/carbon/human/M)
if(Victim)
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
if(Victim == M)
if(prob(60))
visible_message("<span class='warning'>[M] attempts to wrestle \the [name] off!</span>")
@@ -320,26 +302,9 @@
step_away(src,M)
return
else
if(stat == DEAD && surgeries.len)
if(M.a_intent == INTENT_HELP)
for(var/datum/surgery/S in surgeries)
if(S.next_step(M, src))
return 1
/*
if(M.gloves && istype(M.gloves,/obj/item/clothing/gloves))
var/obj/item/clothing/gloves/G = M.gloves
if(G.cell)
if(M.a_intent == "hurt")//Stungloves. Any contact will stun the alien.
if(G.cell.charge >= 2500)
G.cell.use(2500)
visible_message("<span class='warning'>[src] has been touched with the stun gloves by [M]!</span>")
return
else
to_chat(M, "<span class='warning'>Not enough charge! </span>")
return
*/
if(..()) //To allow surgery to return properly.
return
switch(M.a_intent)
@@ -350,77 +315,46 @@
grabbedby(M)
else
M.do_attack_animation(src)
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
var/damage = rand(1, 9)
attacked += 10
if(prob(90))
if(HULK in M.mutations)
damage += 15
if(Victim || Target)
Victim = null
Target = null
anchored = 0
if(prob(80) && !client)
Discipline++
spawn(0)
step_away(src,M,15)
sleep(3)
step_away(src,M,15)
playsound(loc, "punch", 25, 1, -1)
add_attack_logs(M, src, "Melee attacked with fists")
visible_message("<span class='danger'>[M] has punched [src]!</span>", \
"<span class='userdanger'>[M] has punched [src]!</span>")
adjustBruteLoss(damage)
updatehealth()
if(stat != DEAD)
adjustBruteLoss(damage)
updatehealth()
else
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to punch [src]!</span>")
return
/mob/living/carbon/slime/attack_alien(mob/living/carbon/alien/humanoid/M as mob)
if(!ticker)
to_chat(M, "You cannot attack people before the game has started.")
return
if(istype(loc, /turf) && istype(loc.loc, /area/start))
to_chat(M, "No attacking people at spawn, you jackass.")
return
switch(M.a_intent)
if(INTENT_HELP)
visible_message("<span class='notice'>[M] caresses [src] with its scythe like arm.</span>")
if(INTENT_HARM)
M.do_attack_animation(src)
/mob/living/carbon/slime/attack_alien(mob/living/carbon/alien/humanoid/M)
if(..()) //if harm or disarm intent.
if(M.a_intent == INTENT_HARM)
if(prob(95))
attacked += 10
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
var/damage = rand(15, 30)
if(damage >= 25)
damage = rand(20, 40)
visible_message("<span class='danger'>[M] has attacked [name]!</span>", \
"<span class='userdanger'>[M] has attacked [name]!</span>")
visible_message("<span class='danger'>[M] has slashed [name]!</span>", \
"<span class='userdanger'>[M] has slashed [name]!</span>")
else
visible_message("<span class='danger'>[M] has wounded [name]!</span>", \
"<span class='userdanger'>)[M] has wounded [name]!</span>")
adjustBruteLoss(damage)
updatehealth()
add_attack_logs(M, src, "Alien attacked")
if(stat != DEAD)
adjustBruteLoss(damage)
updatehealth()
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has attempted to lunge at [name]!</span>", \
"<span class='userdanger'>[M] has attempted to lunge at [name]!</span>")
if(INTENT_GRAB)
grabbedby(M)
if(INTENT_DISARM)
M.do_attack_animation(src)
if(M.a_intent == INTENT_DISARM)
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
var/damage = 5
attacked += 10
@@ -435,7 +369,7 @@
anchored = 0
if(prob(80) && !client)
Discipline++
if(!istype(src, /mob/living/carbon/slime))
if(!isslime(src))
if(Discipline == 1)
attacked = 0
@@ -453,16 +387,12 @@
drop_item()
visible_message("<span class='danger'>[M] has disarmed [name]!</span>",
"<span class='userdanger'>[M] has disarmed [name]!</span>")
add_attack_logs(M, src, "Alien disarmed")
adjustBruteLoss(damage)
updatehealth()
return
/mob/living/carbon/slime/attackby(obj/item/W, mob/user, params)
if(stat == DEAD && surgeries.len)
if(user.a_intent == INTENT_HELP)
for(var/datum/surgery/S in surgeries)
if(S.next_step(user, src))
return 1
/mob/living/carbon/slime/attackby(obj/item/W, mob/living/user, params)
if(istype(W,/obj/item/stack/sheet/mineral/plasma)) //Lets you feed slimes plasma.
if(user in Friends)
++Friends[user]
@@ -475,6 +405,7 @@
else if(W.force > 0)
attacked += 10
if(prob(25))
user.do_attack_animation(src)
to_chat(user, "<span class='danger'>[W] passes right through [src]!</span>")
return
if(Discipline && prob(50)) // wow, buddy, why am I getting attacked??
@@ -554,8 +485,8 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
return "You cannot ventcrawl while feeding."
..()
/mob/living/carbon/slime/forceFed(var/obj/item/weapon/reagent_containers/food/toEat, mob/user, fullness)
if(istype(toEat, /obj/item/weapon/reagent_containers/food/drinks))
/mob/living/carbon/slime/forceFed(var/obj/item/reagent_containers/food/toEat, mob/user, fullness)
if(istype(toEat, /obj/item/reagent_containers/food/drinks))
return 1
to_chat(user, "This creature does not seem to have a mouth!")
return 0
+14 -14
View File
@@ -21,7 +21,7 @@
H.rename_character(H.real_name, name)
for(var/obj/item/W in H.get_all_slots())
H.unEquip(W)
H.equip_to_slot_or_del(new /obj/item/device/radio/headset(H), slot_l_ear)
H.equip_to_slot_or_del(new /obj/item/radio/headset(H), slot_l_ear)
/datum/superheroes/proc/fixflags(var/mob/living/carbon/human/H)
for(var/obj/item/W in H.get_all_slots())
@@ -42,7 +42,7 @@
H.mind.AddSpell(new S(null))
/datum/superheroes/proc/assign_id(var/mob/living/carbon/human/H)
var/obj/item/weapon/card/id/syndicate/W = new(H)
var/obj/item/card/id/syndicate/W = new(H)
W.registered_name = H.real_name
W.access = list(access_maint_tunnels)
if(class == "Superhero")
@@ -76,7 +76,7 @@
H.equip_to_slot_or_del(new /obj/item/clothing/under/owl(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/toggle/owlwings(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/owl_mask/super_hero(H), slot_wear_mask)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/bluespace/owlman(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/storage/belt/bluespace/owlman(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/glasses/night(H), slot_glasses)
@@ -96,7 +96,7 @@
H.equip_to_slot_or_del(new /obj/item/clothing/suit/toggle/owlwings/griffinwings(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/head/griffin/(H), slot_head)
var/obj/item/weapon/implant/freedom/L = new/obj/item/weapon/implant/freedom(H)
var/obj/item/implant/freedom/L = new/obj/item/implant/freedom(H)
L.implant(H)
@@ -116,7 +116,7 @@
H.equip_to_slot_or_del(new /obj/item/clothing/suit/corgisuit/super_hero(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/head/corgi/super_hero(H), slot_head)
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/yellow(H), slot_gloves)
H.equip_to_slot_or_del(new /obj/item/weapon/bedsheet/orange(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/bedsheet/orange(H), slot_back)
/datum/superheroes/electro
@@ -134,7 +134,7 @@
H.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/corgisuit/super_hero/en(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/head/corgi/super_hero/en(H), slot_head)
H.equip_to_slot_or_del(new /obj/item/weapon/bedsheet/cult(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/bedsheet/cult(H), slot_back)
@@ -188,15 +188,15 @@
switch(progress)
if(1)
to_chat(user, "<span class='notice'>You begin by introducing yourself and explaining what you're about.</span>")
user.visible_message("<span class='danger'>[user] introduces \himself and explains \his plans.</span>")
user.visible_message("<span class='danger'>[user] introduces [user.p_them()]self and explains [user.p_their()] plans.</span>")
if(2)
to_chat(user, "<span class='notice'>You begin the recruitment of [target].</span>")
user.visible_message("<span class='danger'>[user] leans over towards [target], whispering excitedly as he gives a speech.</span>")
user.visible_message("<span class='danger'>[user] leans over towards [target], whispering excitedly as [user.p_they()] give[user.p_s()] a speech.</span>")
to_chat(target, "<span class='danger'>You feel yourself agreeing with [user], and a surge of loyalty begins building.</span>")
target.Weaken(12)
sleep(20)
if(ismindshielded(target))
to_chat(user, "<span class='notice'>They are enslaved by Nanotrasen. You feel their interest in your cause wane and disappear.</span>")
to_chat(user, "<span class='notice'>[target.p_they(TRUE)] are enslaved by Nanotrasen. You feel [target.p_their()] interest in your cause wane and disappear.</span>")
user.visible_message("<span class='danger'>[user] stops talking for a moment, then moves back away from [target].</span>")
to_chat(target, "<span class='danger'>Your mindshield implant activates, protecting you from conversion.</span>")
return
@@ -214,10 +214,10 @@
recruiting = 0
to_chat(user, "<span class='notice'>You have recruited <b>[target]</b> as your henchman!</span>")
to_chat(target, "<span class='deadsay'><b>You have decided to enroll as a henchman for [user]. You are now part of the feared 'Greyshirts'.</b></span>")
to_chat(target, "<span class='deadsay'><b>You must follow the orders of [user], and help him succeed in \his dastardly schemes.</span>")
to_chat(target, "<span class='deadsay'><b>You must follow the orders of [user], and help [user.p_them()] succeed in [user.p_their()] dastardly schemes.</span>")
to_chat(target, "<span class='deadsay'>You may not harm other Greyshirt or [user]. However, you do not need to obey other Greyshirts.</span>")
ticker.mode.greyshirts += target.mind
target.set_species("Human")
target.set_species(/datum/species/human)
head_organ.h_style = "Bald"
head_organ.f_style = "Shaved"
target.s_tone = 35
@@ -228,9 +228,9 @@
target.rename_character(target.real_name, "Generic Henchman ([rand(1, 1000)])")
target.equip_to_slot_or_del(new /obj/item/clothing/under/color/grey/greytide(target), slot_w_uniform)
target.equip_to_slot_or_del(new /obj/item/clothing/shoes/black/greytide(target), slot_shoes)
target.equip_to_slot_or_del(new /obj/item/weapon/storage/toolbox/mechanical/greytide(target), slot_l_hand)
target.equip_to_slot_or_del(new /obj/item/device/radio/headset(target), slot_l_ear)
var/obj/item/weapon/card/id/syndicate/W = new(target)
target.equip_to_slot_or_del(new /obj/item/storage/toolbox/mechanical/greytide(target), slot_l_hand)
target.equip_to_slot_or_del(new /obj/item/radio/headset(target), slot_l_ear)
var/obj/item/card/id/syndicate/W = new(target)
W.icon_state = "lifetimeid"
W.access = list(access_maint_tunnels)
W.assignment = "Greyshirt"
+6 -6
View File
@@ -1,4 +1,4 @@
/mob/living/Life()
/mob/living/Life(seconds, times_fired)
set invisibility = 0
set background = BACKGROUND_ENABLED
@@ -22,7 +22,7 @@
handle_mutations_and_radiation()
//Breathing, if applicable
handle_breathing()
handle_breathing(times_fired)
//Random events (vomiting etc)
handle_random_events()
@@ -38,13 +38,13 @@
handle_fire()
//stuff in the stomach
handle_stomach()
handle_stomach(times_fired)
update_gravity(mob_has_gravity())
update_pulling()
for(var/obj/item/weapon/grab/G in src)
for(var/obj/item/grab/G in src)
G.process()
if(handle_regular_status_updates()) // Status & health update, are we dead or alive etc.
@@ -61,7 +61,7 @@
..()
/mob/living/proc/handle_breathing()
/mob/living/proc/handle_breathing(times_fired)
return
/mob/living/proc/handle_mutations_and_radiation()
@@ -80,7 +80,7 @@
/mob/living/proc/handle_environment(datum/gas_mixture/environment)
return
/mob/living/proc/handle_stomach()
/mob/living/proc/handle_stomach(times_fired)
return
/mob/living/proc/update_pulling()
+37 -105
View File
@@ -1,4 +1,4 @@
/mob/living/New()
/mob/living/Initialize()
. = ..()
var/datum/atom_hud/data/human/medical/advanced/medhud = huds[DATA_HUD_MEDICAL_ADVANCED]
medhud.add_to_hud(src)
@@ -137,10 +137,12 @@
if(!AM.anchored)
now_pushing = 1
var/t = get_dir(src, AM)
if(istype(AM, /obj/structure/window/full))
for(var/obj/structure/window/win in get_step(AM, t))
now_pushing = 0
return
if(istype(AM, /obj/structure/window))
var/obj/structure/window/W = AM
if(W.fulltile)
for(var/obj/structure/window/win in get_step(W, t))
now_pushing = 0
return
if(pulling == AM)
stop_pulling()
var/current_dir
@@ -155,7 +157,7 @@
/mob/living/Stat()
. = ..()
if(. && get_rig_stats)
var/obj/item/weapon/rig/rig = get_rig()
var/obj/item/rig/rig = get_rig()
if(rig)
SetupStat(rig)
@@ -198,7 +200,7 @@
if(!..())
return FALSE
var/obj/item/hand_item = get_active_hand()
if(istype(hand_item, /obj/item/weapon/gun) && A != hand_item)
if(istype(hand_item, /obj/item/gun) && A != hand_item)
if(a_intent == INTENT_HELP || !ismob(A))
visible_message("<b>[src]</b> points to [A] with [hand_item]")
return TRUE
@@ -353,48 +355,48 @@
//Recursive function to find everything a mob is holding.
/mob/living/get_contents(var/obj/item/weapon/storage/Storage = null)
/mob/living/get_contents(var/obj/item/storage/Storage = null)
var/list/L = list()
if(Storage) //If it called itself
L += Storage.return_inv()
//Leave this commented out, it will cause storage items to exponentially add duplicate to the list
//for(var/obj/item/weapon/storage/S in Storage.return_inv()) //Check for storage items
//for(var/obj/item/storage/S in Storage.return_inv()) //Check for storage items
// L += get_contents(S)
for(var/obj/item/weapon/gift/G in Storage.return_inv()) //Check for gift-wrapped items
for(var/obj/item/gift/G in Storage.return_inv()) //Check for gift-wrapped items
L += G.gift
if(istype(G.gift, /obj/item/weapon/storage))
if(istype(G.gift, /obj/item/storage))
L += get_contents(G.gift)
for(var/obj/item/smallDelivery/D in Storage.return_inv()) //Check for package wrapped items
L += D.wrapped
if(istype(D.wrapped, /obj/item/weapon/storage)) //this should never happen
if(istype(D.wrapped, /obj/item/storage)) //this should never happen
L += get_contents(D.wrapped)
return L
else
L += contents
for(var/obj/item/weapon/storage/S in contents) //Check for storage items
for(var/obj/item/storage/S in contents) //Check for storage items
L += get_contents(S)
for(var/obj/item/clothing/suit/storage/S in contents)//Check for labcoats and jackets
L += get_contents(S)
for(var/obj/item/clothing/accessory/storage/S in contents)//Check for holsters
L += get_contents(S)
for(var/obj/item/weapon/implant/storage/I in contents) //Check for storage implants.
for(var/obj/item/implant/storage/I in contents) //Check for storage implants.
L += I.get_contents()
for(var/obj/item/weapon/gift/G in contents) //Check for gift-wrapped items
for(var/obj/item/gift/G in contents) //Check for gift-wrapped items
L += G.gift
if(istype(G.gift, /obj/item/weapon/storage))
if(istype(G.gift, /obj/item/storage))
L += get_contents(G.gift)
for(var/obj/item/smallDelivery/D in contents) //Check for package wrapped items
L += D.wrapped
if(istype(D.wrapped, /obj/item/weapon/storage)) //this should never happen
if(istype(D.wrapped, /obj/item/storage)) //this should never happen
L += get_contents(D.wrapped)
for(var/obj/item/weapon/folder/F in contents)
for(var/obj/item/folder/F in contents)
L += F.contents //Folders can't store any storage items.
return L
@@ -658,14 +660,14 @@
TH.transfer_mob_blood_dna(src)
if(ishuman(src))
var/mob/living/carbon/human/H = src
if(H.species.blood_color)
TH.color = H.species.blood_color
if(H.dna.species.blood_color)
TH.color = H.dna.species.blood_color
else
TH.color = "#A10808"
/mob/living/carbon/human/makeTrail(turf/T)
if((NO_BLOOD in species.species_traits) || species.exotic_blood || !bleed_rate || bleedsuppress)
if((NO_BLOOD in dna.species.species_traits) || dna.species.exotic_blood || !bleed_rate || bleedsuppress)
return
..()
@@ -716,7 +718,7 @@
qdel(O)
resisting++
for(var/X in grabbed_by)
var/obj/item/weapon/grab/G = X
var/obj/item/grab/G = X
resisting++
switch(G.state)
if(GRAB_PASSIVE)
@@ -793,7 +795,7 @@
/mob/living/proc/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash)
if(check_eye_prot() < intensity && (override_blindness_check || !(disabilities & BLIND)))
overlay_fullscreen("flash", type)
addtimer(src, "clear_fullscreen", 25, FALSE, "flash", 25)
addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25)
return 1
/mob/living/proc/check_eye_prot()
@@ -816,7 +818,7 @@
who.unEquip(what)
if(silent)
put_in_hands(what)
add_logs(src, who, "stripped", addition="of [what]", print_attack_log = isLivingSSD(who))
add_attack_logs(src, who, "Stripped of [what]")
// The src mob is trying to place an item on someone
// Override if a certain mob should be behave differently when placing items (can't, for example)
@@ -835,8 +837,7 @@
if(what && Adjacent(who))
unEquip(what)
who.equip_to_slot_if_possible(what, where, 0, 1)
add_logs(src, who, "equipped", what, print_attack_log = isLivingSSD(who))
add_attack_logs(src, who, "Equipped [what]")
/mob/living/singularity_act()
var/gain = 20
@@ -852,81 +853,11 @@
makeNewConstruct(/mob/living/simple_animal/hostile/construct/harvester, src, null, 1)
spawn_dust()
gib()
return
/atom/movable/proc/do_attack_animation(atom/A, end_pixel_y)
var/pixel_x_diff = 0
var/pixel_y_diff = 0
var/final_pixel_y = initial(pixel_y)
if(end_pixel_y)
final_pixel_y = end_pixel_y
var/direction = get_dir(src, A)
if(direction & NORTH)
pixel_y_diff = 8
else if(direction & SOUTH)
pixel_y_diff = -8
if(direction & EAST)
pixel_x_diff = 8
else if(direction & WEST)
pixel_x_diff = -8
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = 2)
animate(pixel_x = initial(pixel_x), pixel_y = final_pixel_y, time = 2)
/mob/living/do_attack_animation(atom/A)
var/final_pixel_y = get_standard_pixel_y_offset(lying)
..(A, final_pixel_y)
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
// What icon do we use for the attack?
var/image/I
if(hand && l_hand) // Attacked with item in left hand.
I = image(l_hand.icon, A, l_hand.icon_state, A.layer + 1)
else if(!hand && r_hand) // Attacked with item in right hand.
I = image(r_hand.icon, A, r_hand.icon_state, A.layer + 1)
else // Attacked with a fist?
return
// Who can see the attack?
var/list/viewing = list()
for(var/mob/M in viewers(A))
if(M.client && M.client.prefs.show_ghostitem_attack)
viewing |= M.client
flick_overlay(I, viewing, 5) // 5 ticks/half a second
// Scale the icon.
I.transform *= 0.75
// The icon should not rotate.
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
// Set the direction of the icon animation.
var/direction = get_dir(src, A)
if(direction & NORTH)
I.pixel_y = -16
else if(direction & SOUTH)
I.pixel_y = 16
if(direction & EAST)
I.pixel_x = -16
else if(direction & WEST)
I.pixel_x = 16
if(!direction) // Attacked self?!
I.pixel_z = 16
// And animate the attack!
animate(I, alpha = 175, pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 3)
/atom/movable/proc/receiving_damage(atom/A)
var/pixel_x_diff = rand(-3,3)
var/pixel_y_diff = rand(-3,3)
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, time = 2)
animate(pixel_x = initial(pixel_x), pixel_y = initial(pixel_y), time = 2)
/mob/living/receiving_damage(atom/A)
/mob/living/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
end_pixel_y = get_standard_pixel_y_offset(lying)
if(!used_item)
used_item = get_active_hand()
..()
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
@@ -983,16 +914,17 @@
return 0
/mob/living/proc/attempt_harvest(obj/item/I, mob/user)
if(stat == DEAD && !isnull(butcher_results)) //can we butcher it?
if(istype(I, /obj/item/weapon/kitchen/knife))
if(user.a_intent == INTENT_HARM && stat == DEAD && butcher_results) //can we butcher it?
var/sharpness = is_sharp(I)
if(sharpness)
to_chat(user, "<span class='notice'>You begin to butcher [src]...</span>")
playsound(loc, 'sound/weapons/slice.ogg', 50, 1, -1)
if(do_mob(user, src, 80))
if(do_mob(user, src, 80 / sharpness) && Adjacent(I))
harvest(user)
return 1
/mob/living/proc/harvest(mob/living/user)
if(qdeleted(src))
if(QDELETED(src))
return
if(butcher_results)
for(var/path in butcher_results)
@@ -1021,7 +953,7 @@
. += config.walk_speed
/mob/living/proc/can_use_guns(var/obj/item/weapon/gun/G)
/mob/living/proc/can_use_guns(var/obj/item/gun/G)
if(G.trigger_guard != TRIGGER_GUARD_ALLOW_ALL && !IsAdvancedToolUser() && !issmall(src))
to_chat(src, "<span class='warning'>You don't have the dexterity to do this!</span>")
return 0
+88 -15
View File
@@ -79,8 +79,8 @@
var/zone = ran_zone("chest", 65)//Hits a random part of the body, geared towards the chest
var/dtype = BRUTE
var/volume = I.get_volume_by_throwforce_and_or_w_class()
if(istype(I, /obj/item/weapon))
var/obj/item/weapon/W = I
if(istype(I, /obj/item))
var/obj/item/W = I
dtype = W.damtype
if(W.throwforce > 0) //If the weapon's throwforce is greater than zero...
if(W.hitsound) //...and hitsound is defined...
@@ -98,7 +98,7 @@
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].", I.armour_penetration)
apply_damage(I.throwforce, dtype, zone, armor, is_sharp(I), I)
if(I.thrownby)
add_logs(I.thrownby, src, "hit", I)
add_attack_logs(I.thrownby, src, "Hit with thrown [I]")
else
return 1
else
@@ -126,14 +126,10 @@
M.occupant_message("<span class='danger'>You hit [src].</span>")
visible_message("<span class='danger'>[src] has been hit by [M.name].</span>", \
"<span class='userdanger'>[src] has been hit by [M.name].</span>")
create_attack_log("<font color='orange'>Has been attacked by \the [M] controlled by [key_name(M.occupant)] (INTENT: [uppertext(M.occupant.a_intent)])</font>")
M.occupant.create_attack_log("<font color='red'>Attacked [src] with \the [M] (INTENT: [uppertext(M.occupant.a_intent)])</font>")
msg_admin_attack("[key_name_admin(M.occupant)] attacked [key_name_admin(src)] with \the [M] (INTENT: [uppertext(M.occupant.a_intent)])")
add_attack_logs(M.occupant, src, "Mecha-meleed with [M]")
else
step_away(src,M)
add_logs(M.occupant, src, "pushed", object=M, admin=0, print_attack_log = 0)
add_attack_logs(M.occupant, src, "Mecha-pushed with [M]", ATKLOG_ALL)
M.occupant_message("<span class='warning'>You push [src] out of the way.</span>")
visible_message("<span class='warning'>[M] pushes [src] out of the way.</span>")
return
@@ -233,22 +229,22 @@
// End BS12 momentum-transfer code.
/mob/living/proc/grabbedby(mob/living/carbon/user,var/supress_message = 0)
/mob/living/proc/grabbedby(mob/living/carbon/user, supress_message = 0)
if(user == src || anchored)
return 0
if(!(status_flags & CANPUSH))
return 0
for(var/obj/item/weapon/grab/G in src.grabbed_by)
for(var/obj/item/grab/G in grabbed_by)
if(G.assailant == user)
to_chat(user, "<span class='notice'>You already grabbed [src].</span>")
return
add_logs(user, src, "grabbed", addition="passively")
add_attack_logs(user, src, "Grabbed passively", ATKLOG_ALL)
var/obj/item/weapon/grab/G = new /obj/item/weapon/grab(user, src)
var/obj/item/grab/G = new /obj/item/grab(user, src)
if(buckled)
to_chat(user, "<span class='notice'>You cannot grab [src], \he is buckled in!</span>")
to_chat(user, "<span class='notice'>You cannot grab [src]; [p_they()] [p_are()] buckled in!</span>")
if(!G) //the grab will delete itself in New if src is anchored
return 0
user.put_in_active_hand(G)
@@ -265,4 +261,81 @@
if(!supress_message)
visible_message("<span class='warning'>[user] has grabbed [src] passively!</span>")
return G
return G
/mob/living/attack_slime(mob/living/carbon/slime/M)
if(!ticker)
to_chat(M, "You cannot attack people before the game has started.")
return
if(M.Victim)
return // can't attack while eating!
if(stat != DEAD)
M.do_attack_animation(src)
visible_message("<span class='danger'>The [M.name] glomps [src]!</span>", \
"<span class='userdanger'>The [M.name] glomps [src]!</span>")
if(M.powerlevel > 0)
var/stunprob = M.powerlevel * 7 + 10 // 17 at level 1, 80 at level 10
if(prob(stunprob))
M.powerlevel -= 3
if(M.powerlevel < 0)
M.powerlevel = 0
visible_message("<span class='danger'>The [M.name] has shocked [src]!</span>", \
"<span class='userdanger'>The [M.name] has shocked [src]!</span>")
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(5, 1, src)
s.start()
return 1
add_attack_logs(src, M, "Slime'd")
return
/mob/living/attack_animal(mob/living/simple_animal/M)
if(M.melee_damage_upper == 0)
M.custom_emote(1, "[M.friendly] [src]")
return 0
else
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
M.do_attack_animation(src)
visible_message("<span class='danger'>\The [M] [M.attacktext] [src]!</span>", \
"<span class='userdanger'>\The [M] [M.attacktext] [src]!</span>")
add_attack_logs(M, src, "Animal attacked")
return 1
/mob/living/attack_larva(mob/living/carbon/alien/larva/L)
switch(L.a_intent)
if(INTENT_HELP)
visible_message("<span class='notice'>[L.name] rubs its head against [src].</span>")
return 0
else
L.do_attack_animation(src)
if(prob(90))
add_attack_logs(L, src, "Larva attacked")
visible_message("<span class='danger'>[L.name] bites [src]!</span>", \
"<span class='userdanger'>[L.name] bites [src]!</span>")
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
return 1
else
visible_message("<span class='danger'>[L.name] has attempted to bite [src]!</span>", \
"<span class='userdanger'>[L.name] has attempted to bite [src]!</span>")
return 0
/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
switch(M.a_intent)
if(INTENT_HELP)
visible_message("<span class='notice'>[M] caresses [src] with its scythe like arm.</span>")
return FALSE
if(INTENT_GRAB)
grabbedby(M)
return FALSE
if(INTENT_HARM)
M.do_attack_animation(src)
return TRUE
if(INTENT_DISARM)
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
return TRUE
+5 -5
View File
@@ -164,10 +164,10 @@ proc/get_radio_key_from_channel(var/channel)
if(is_muzzled())
var/obj/item/clothing/mask/muzzle/G = wear_mask
if(G.mute == MUTE_ALL) //if the mask is supposed to mute you completely or just muffle you
if(G.mute == MUZZLE_MUTE_ALL) //if the mask is supposed to mute you completely or just muffle you
to_chat(src, "<span class='danger'>You're muzzled and cannot speak!</span>")
return
else if(G.mute == MUTE_MUFFLE)
else if(G.mute == MUZZLE_MUTE_MUFFLE)
message = muffledspeech(message)
verb = "mumbles"
@@ -286,7 +286,7 @@ proc/get_radio_key_from_channel(var/channel)
//Log of what we've said, plain message, no spans or junk
say_log += message
log_say("[name]/[key] : [message]")
log_say(message, src)
return 1
/mob/living/proc/say_signlang(var/message, var/verb="gestures", var/datum/language/language)
@@ -313,7 +313,7 @@ proc/get_radio_key_from_channel(var/channel)
return 1
if(act && type && message) //parent call
log_emote("[name]/[key] : [message]")
log_emote(message, src)
for(var/mob/M in dead_mob_list)
if(!M.client || istype(M, /mob/new_player))
@@ -485,7 +485,7 @@ proc/get_radio_key_from_channel(var/channel)
for(var/mob/M in watching)
M.show_message(rendered, 2)
log_whisper("[name]/[key] : [message]")
log_whisper(message, src)
return 1
/mob/living/speech_bubble(var/bubble_state = "",var/bubble_loc = src, var/list/bubble_recipients = list())
+41 -72
View File
@@ -54,12 +54,12 @@ var/list/ai_verbs_default = list(
var/viewalerts = 0
var/icon/holo_icon//Default is assigned when AI is created.
var/obj/mecha/controlled_mech //For controlled_mech a mech, to determine whether to relaymove or use the AI eye.
var/obj/item/device/pda/silicon/ai/aiPDA = null
var/obj/item/device/multitool/aiMulti = null
var/obj/item/pda/silicon/ai/aiPDA = null
var/obj/item/multitool/aiMulti = null
var/custom_sprite = 0 //For our custom sprites
var/custom_hologram = 0 //For our custom holograms
var/obj/item/device/radio/headset/heads/ai_integrated/aiRadio = null
var/obj/item/radio/headset/heads/ai_integrated/aiRadio = null
//MALFUNCTION
var/datum/module_picker/malf_picker
@@ -87,11 +87,12 @@ var/list/ai_verbs_default = list(
var/mob/living/simple_animal/bot/Bot
var/turf/waypoint //Holds the turf of the currently selected waypoint.
var/waypoint_mode = 0 //Waypoint mode is for selecting a turf via clicking.
var/apc_override = FALSE //hack for letting the AI use its APC even when visionless
var/nuking = 0
var/obj/machinery/doomsday_device/doomsday_device
var/obj/machinery/hologram/holopad/holo = null
var/mob/camera/aiEye/eyeobj = new()
var/mob/camera/aiEye/eyeobj
var/sprint = 10
var/cooldown = 0
var/acceleration = 1
@@ -111,7 +112,7 @@ var/list/ai_verbs_default = list(
verbs -= ai_verbs_default
verbs -= silicon_subsystems
/mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0)
/mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/mmi/B, var/safety = 0)
announcement = new()
announcement.title = "A.I. Announcement"
announcement.announcement_type = "A.I. Announcement"
@@ -128,7 +129,7 @@ var/list/ai_verbs_default = list(
possibleNames -= pickedName
pickedName = null
aiPDA = new/obj/item/device/pda/silicon/ai(src)
aiPDA = new/obj/item/pda/silicon/ai(src)
rename_character(null, pickedName)
anchored = 1
canmove = 0
@@ -154,7 +155,7 @@ var/list/ai_verbs_default = list(
additional_law_channels["Binary"] = ":b "
additional_law_channels["Holopad"] = ":h"
aiCamera = new/obj/item/device/camera/siliconcam/ai_camera(src)
aiCamera = new/obj/item/camera/siliconcam/ai_camera(src)
if(isturf(loc))
add_ai_verbs(src)
@@ -191,9 +192,7 @@ var/list/ai_verbs_default = list(
spawn(5)
new /obj/machinery/ai_powersupply(src)
eyeobj.ai = src
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
eyeobj.loc = src.loc
create_eye()
builtInCamera = new /obj/machinery/camera/portable(src)
builtInCamera.c_tag = name
@@ -268,6 +267,9 @@ var/list/ai_verbs_default = list(
shuttle_caller_list -= src
shuttle_master.autoEvac()
QDEL_NULL(eyeobj) // No AI, no Eye
if(malfhacking)
deltimer(malfhacking)
malfhacking = null
malfhack = null
return ..()
@@ -686,62 +688,6 @@ var/list/ai_verbs_default = list(
updatehealth()
return 2
/mob/living/silicon/ai/attack_alien(mob/living/carbon/alien/humanoid/M)
if(!ticker)
to_chat(M, "You cannot attack people before the game has started.")
return
if(isturf(loc) && istype(loc.loc, /area/start))
to_chat(M, "No attacking people at spawn, you jackass.")
return
switch(M.a_intent)
if(INTENT_HELP)
visible_message("<span class='notice'>[M] caresses [src]'s plating with its scythe like arm.</span>")
else //harm
M.do_attack_animation(src)
var/damage = rand(10, 20)
if(prob(90))
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has slashed at [src]!</span>",\
"<span class='userdanger'>[M] has slashed at [src]!</span>")
adjustBruteLoss(damage)
updatehealth()
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] took a swipe at [src]!</span>", \
"<span class='userdanger'>[M] took a swipe at [src]!</span>")
return
/mob/living/silicon/ai/attack_animal(mob/living/simple_animal/M)
if(M.melee_damage_upper == 0)
M.custom_emote(1, "[M.friendly] [src]")
else
M.do_attack_animation(src)
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
visible_message("<span class='danger'><B>[M]</B> [M.attacktext] [src]!")
add_logs(M, src, "attacked", admin=0, print_attack_log = 0)
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
switch(M.melee_damage_type)
if(BRUTE)
adjustBruteLoss(damage)
if(BURN)
adjustFireLoss(damage)
if(TOX)
adjustToxLoss(damage)
if(OXY)
adjustOxyLoss(damage)
if(CLONE)
adjustCloneLoss(damage)
if(STAMINA)
adjustStaminaLoss(damage)
updatehealth()
/mob/living/silicon/ai/reset_perspective(atom/A)
if(camera_light_on)
light_cameras()
@@ -1128,8 +1074,8 @@ var/list/ai_verbs_default = list(
lit_cameras |= C
/mob/living/silicon/ai/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/wrench))
/mob/living/silicon/ai/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/wrench))
if(anchored)
user.visible_message("<span class='notice'>\The [user] starts to unbolt \the [src] from the plating...</span>")
if(!do_after(user, 40 * W.toolspeed, target = src))
@@ -1183,7 +1129,7 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/proc/is_in_chassis()
return isturf(loc)
/mob/living/silicon/ai/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/device/aicard/card)
/mob/living/silicon/ai/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card)
if(!..())
return
if(interaction == AI_TRANS_TO_CARD)//The only possible interaction. Upload AI mob to a card.
@@ -1204,7 +1150,7 @@ var/list/ai_verbs_default = list(
set category = "IC"
resting = 0
var/obj/item/weapon/rig/rig = get_rig()
var/obj/item/rig/rig = get_rig()
if(rig)
rig.force_rest(src)
@@ -1216,6 +1162,17 @@ var/list/ai_verbs_default = list(
client.eye = eyeobj
return TRUE
/mob/living/silicon/ai/proc/can_see(atom/A)
if(isturf(loc)) //AI in core, check if on cameras
//get_turf_pixel() is because APCs in maint aren't actually in view of the inner camera
//apc_override is needed here because AIs use their own APC when depowered
return (cameranet && cameranet.checkTurfVis(get_turf_pixel(A))) || apc_override
//AI is carded/shunted
//view(src) returns nothing for carded/shunted AIs and they have x-ray vision so just use get_dist
var/list/viewscale = getviewsize(client.view)
return get_dist(src, A) <= max(viewscale[1]*0.5,viewscale[2]*0.5)
/mob/living/silicon/ai/proc/relay_speech(mob/living/M, text, verb, datum/language/speaking)
if(!say_understands(M, speaking))//The AI will be able to understand most mobs talking through the holopad.
if(speaking)
@@ -1236,7 +1193,7 @@ var/list/ai_verbs_default = list(
malfhacking = 0
clear_alert("hackingapc")
if(!istype(apc) || qdeleted(apc) || apc.stat & BROKEN)
if(!istype(apc) || QDELETED(apc) || apc.stat & BROKEN)
to_chat(src, "<span class='danger'>Hack aborted. The designated APC no longer exists on the power network.</span>")
playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 1)
else if(apc.aidisabled)
@@ -1292,4 +1249,16 @@ var/list/ai_verbs_default = list(
to_chat(src, "<span class='warning'>Unable to locate an airlock near [target].</span>")
else
to_chat(src, "<span class='warning'>Target is not on or near any active cameras on the station.</span>")
to_chat(src, "<span class='warning'>Target is not on or near any active cameras on the station.</span>")
/mob/living/silicon/ai/handle_fire()
return
/mob/living/silicon/ai/update_fire()
return
/mob/living/silicon/ai/IgniteMob()
return FALSE
/mob/living/silicon/ai/ExtinguishMob()
return
@@ -0,0 +1,8 @@
/mob/living/silicon/ai/attack_alien(mob/living/carbon/alien/humanoid/M)
if(!ticker)
to_chat(M, "You cannot attack people before the game has started.")
return
..()
/mob/living/silicon/ai/attack_slime(mob/living/carbon/slime/user)
return //immune to slimes
+3 -3
View File
@@ -21,7 +21,7 @@
if(nuking)
set_security_level("red")
nuking = 0
for(var/obj/item/weapon/pinpointer/point in pinpointer_list)
for(var/obj/item/pinpointer/point in pinpointer_list)
point.the_disk = null //Point back to the disk.
if(doomsday_device)
@@ -40,10 +40,10 @@
for(var/obj/machinery/ai_status_display/O in world) //change status
spawn( 0 )
O.mode = 2
if(istype(loc, /obj/item/device/aicard))
if(istype(loc, /obj/item/aicard))
loc.icon_state = "aicard-404"
timeofdeath = world.time
if(mind) mind.store_memory("Time of death: [worldtime2text(timeofdeath)]", 0)
if(mind) mind.store_memory("Time of death: [station_time_timestamp("hh:mm:ss", timeofdeath)]", 0)
return ..(gibbed)
@@ -28,7 +28,7 @@
eye.visibleCameraChunks += src
visible++
seenby += eye
if(changed && !updating)
if(changed)
update()
// Remove an AI eye from the chunk, then update if changed.
@@ -20,7 +20,6 @@
// It will also stream the chunk that the new loc is in.
/mob/camera/aiEye/setLoc(T)
if(ai)
if(!isturf(ai.loc))
return
@@ -30,8 +29,9 @@
if(ai.client)
ai.client.eye = src
//Holopad
if(ai.holo)
ai.holo.move_hologram()
if(istype(ai.current, /obj/machinery/hologram/holopad))
var/obj/machinery/hologram/holopad/H = ai.current
H.move_hologram(ai, T)
/mob/camera/aiEye/Move()
return 0
@@ -41,8 +41,22 @@
return ai.client
return null
/mob/camera/aiEye/proc/RemoveImages()
var/client/C = GetViewerClient()
if(C)
for(var/V in visibleCameraChunks)
var/datum/camerachunk/chunk = V
C.images -= chunk.obscured
/mob/camera/aiEye/Destroy()
ai = null
if(ai)
//ai.all_eyes -= src
ai = null
for(var/V in visibleCameraChunks)
var/datum/camerachunk/chunk = V
chunk.remove(src)
return ..()
/atom/proc/move_camera_by_click()
@@ -102,12 +116,18 @@
src.eyeobj.loc = src.loc
else
to_chat(src, "ERROR: Eyeobj not found. Creating new eye...")
src.eyeobj = new(src.loc)
src.eyeobj.ai = src
src.eyeobj.name = "[src.name] (AI Eye)" // Give it a name
create_eye()
eyeobj.setLoc(loc)
/mob/living/silicon/ai/proc/create_eye()
if(eyeobj)
return
eyeobj = new /mob/camera/aiEye()
eyeobj.ai = src
eyeobj.setLoc(loc)
eyeobj.name = "[name] (AI Eye)"
/mob/living/silicon/ai/proc/toggle_acceleration()
set category = "AI Commands"
set name = "Toggle Camera Acceleration"
+9 -5
View File
@@ -3,7 +3,7 @@
#define POWER_RESTORATION_SEARCH_APC 2
#define POWER_RESTORATION_APC_FOUND 3
/mob/living/silicon/ai/Life()
/mob/living/silicon/ai/Life(seconds, times_fired)
//doesn't call parent because it's a horrible mess
if(stat == DEAD)
return
@@ -21,7 +21,7 @@
death()
return 0
if(!eyeobj || qdeleted(eyeobj) || !eyeobj.loc)
if(!eyeobj || QDELETED(eyeobj) || !eyeobj.loc)
view_core()
if(machine)
@@ -29,8 +29,10 @@
if(malfhack && malfhack.aidisabled)
to_chat(src, "<span class='danger'>ERROR: APC access disabled, hack attempt canceled.</span>")
malfhacking = 0
malfhack = null
deltimer(malfhacking)
// This proc handles cleanup of screen notifications and
// messenging the client
malfhacked(malfhack)
if(aiRestorePowerRoutine)
adjustOxyLoss(1)
@@ -127,8 +129,10 @@
to_chat(src, "Receiving control information from APC.")
sleep(2)
//bring up APC dialog
aiRestorePowerRoutine = 3
apc_override = 1
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)
+1 -1
View File
@@ -14,7 +14,7 @@
if(ishuman(speaker))
var/mob/living/carbon/human/H = speaker
var/obj/item/weapon/card/id/id = H.wear_id
var/obj/item/card/id/id = H.wear_id
if((istype(id) && id.is_untrackable()) && H.HasVoiceChanger())
changed_voice = 1
var/mob/living/carbon/human/I = locate(speaker_name)
@@ -1,4 +1,4 @@
/mob/living/silicon/decoy/Life()
/mob/living/silicon/decoy/Life(seconds, times_fired)
if(src.stat == 2)
return
else

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