Merge remote-tracking branch 'tgstation/master' into toolboxcrusaders

This commit is contained in:
KorPhaeron
2015-09-22 23:41:02 -05:00
220 changed files with 5747 additions and 5972 deletions
+6 -24
View File
@@ -86,22 +86,14 @@
/mob/living/carbon/human/interactive/proc/random()
//this is here because this has no client/prefs/brain whatever.
underwear = random_underwear(gender)
skin_tone = random_skin_tone()
hair_style = random_hair_style(gender)
facial_hair_style = random_facial_hair_style(gender)
hair_color = random_short_color()
facial_hair_color = hair_color
eye_color = "blue"
age = rand(AGE_MIN,AGE_MAX)
ready_dna(src,random_blood_type())
//job handling
var/list/jobs = SSjob.occupations
for(var/datum/job/J in jobs)
if(J.title == "Cyborg" || J.title == "AI" || J.title == "Chaplain" || J.title == "Mime")
jobs -= J
myjob = pick(jobs)
src.job = myjob.title
job = myjob.title
if(!graytide)
myjob.equip(src)
myjob.apply_fingerprints(src)
@@ -120,25 +112,18 @@
/mob/living/carbon/human/interactive/New()
..()
gender = pick(MALE,FEMALE)
if(gender == MALE)
name = "[pick(first_names_male)] [pick(last_names)]"
real_name = name
else
name = "[pick(first_names_female)] [pick(last_names)]"
real_name = name
random()
MYID = new(src)
MYID.name = "[src.real_name]'s ID Card ([myjob.title])"
MYID.assignment = "[myjob.title]"
MYID.registered_name = src.real_name
MYID.access = myjob.access
src.equip_to_slot_or_del(MYID, slot_wear_id)
equip_to_slot_or_del(MYID, slot_wear_id)
MYPDA = new(src)
MYPDA.owner = src.real_name
MYPDA.owner = real_name
MYPDA.ownjob = "Crew"
MYPDA.name = "PDA-[src.real_name] ([myjob.title])"
src.equip_to_slot_or_del(MYPDA, slot_belt)
MYPDA.name = "PDA-[real_name] ([myjob.title])"
equip_to_slot_or_del(MYPDA, slot_belt)
zone_sel = new /obj/screen/zone_sel()
zone_sel.selecting = "chest"
if(prob(10)) //my x is augmented
@@ -371,9 +356,7 @@
if(!l_hand || !r_hand)
var/obj/item/clothing/C = TARGET
take_to_slot(C)
if(equip_to_appropriate_slot(C))
C.update_icon()
else
if(!equip_to_appropriate_slot(C))
var/obj/item/I = get_item_by_slot(C)
unEquip(I)
equip_to_appropriate_slot(C)
@@ -384,7 +367,6 @@
equip_to_appropriate_slot(MYPDA)
if(MYID in src.loc)
equip_to_appropriate_slot(MYID)
update_icons()
//THIEVING SKILLS END
//-------------TOUCH ME
if(istype(TARGET,/obj/structure))
+59 -18
View File
@@ -31,11 +31,23 @@ obj/effect/dummy/slaughter/relaymove(mob/user, direction)
/mob/living/proc/phaseout(obj/effect/decal/cleanable/B)
if(iscarbon(src))
var/mob/living/carbon/C = src
if(C.l_hand || C.r_hand)
C << "<span class='warning'>You may not hold items while blood crawling!</span>"
return 0
var/obj/item/weapon/bloodcrawl/B1 = new(C)
var/obj/item/weapon/bloodcrawl/B2 = new(C)
B1.icon_state = "bloodhand_left"
B2.icon_state = "bloodhand_right"
C.put_in_hands(B1)
C.put_in_hands(B2)
C.regenerate_icons()
var/mob/living/kidnapped = null
var/turf/mobloc = get_turf(src.loc)
src.notransform = TRUE
spawn(0)
src.visible_message("[src] sinks into the pool of blood.")
src.visible_message("<span class='warning'>[src] sinks into the pool of blood!</span>")
playsound(get_turf(src), 'sound/magic/enter_blood.ogg', 100, 1, -1)
var/obj/effect/dummy/slaughter/holder = PoolOrNew(/obj/effect/dummy/slaughter,mobloc)
src.ExtinguishMob()
@@ -45,42 +57,71 @@ obj/effect/dummy/slaughter/relaymove(mob/user, direction)
if(istype(src.pulling, /mob/living))
var/mob/living/victim = src.pulling
if(victim.stat == CONSCIOUS)
src.visible_message("[victim] kicks free of the [src] at the last second!")
src.visible_message("<span class='warning'>[victim] kicks free of the blood pool just before entering it!</span>")
else
victim.loc = holder
src.visible_message("<span class='warning'><B>The [src] drags [victim] into the pool of blood!</B>")
victim.emote("scream")
src.visible_message("<span class='warning'><b>[src] drags [victim] into the pool of blood!</b></span>")
kidnapped = victim
src.loc = holder
src.holder = holder
if(kidnapped)
src << "<B>You begin to feast on [kidnapped]. You can not move while you are doing this.</B>"
playsound(get_turf(src),'sound/magic/Demon_consume.ogg', 100, 1)
sleep(30)
playsound(get_turf(src),'sound/magic/Demon_consume.ogg', 100, 1)
sleep(30)
playsound(get_turf(src),'sound/magic/Demon_consume.ogg', 100, 1)
sleep(30)
src << "<span class='danger'>You begin to feast on [kidnapped]. You can not move while you are doing this.</span>"
for(var/i = 3; i > 0; i--)
playsound(get_turf(src),'sound/magic/Demon_consume.ogg', 100, 1)
sleep(30)
if(kidnapped)
src << "<B>You devour [kidnapped]. Your health is fully restored.</B>"
src << "<span class='danger'>You devour [kidnapped]. Your health is fully restored.</span>"
src.adjustBruteLoss(-1000)
src.adjustFireLoss(-1000)
src.adjustOxyLoss(-1000)
src.adjustToxLoss(-1000)
kidnapped.ghostize()
qdel(kidnapped)
if(istype(src, /mob/living/simple_animal/slaughter))
var/mob/living/simple_animal/slaughter/S = src
kidnapped << "<span class='userdanger'>You feel teeth sink into your flesh, and the--</span>"
kidnapped.adjustBruteLoss(1000)
kidnapped.loc = src
S.consumed_mobs.Add(kidnapped)
else
kidnapped.ghostize()
qdel(kidnapped)
else
src << "<B>You happily devour...nothing? Your meal vanished at some point!</B>"
src << "<span class='danger'>You happily devour... nothing? Your meal vanished at some point!</span>"
src.notransform = 0
return 1
/obj/item/weapon/bloodcrawl
name = "blood crawl"
desc = "You are unable to hold anything while in this form."
icon = 'icons/effects/blood.dmi'
flags = NODROP
/mob/living/proc/phasein(obj/effect/decal/cleanable/B)
if(src.notransform)
src << "<B>Finish eating first!</B>"
src << "<span class='warning'>Finish eating first!</span>"
return 0
B.visible_message("<span class='warning'>[B] starts to bubble...</span>")
if(!do_after(src, 20, target = B))
return
if(!B)
return
src.loc = B.loc
src.client.eye = src
src.visible_message("<span class='warning'><B>The [src] rises out of the pool of blood!</B>")
src.visible_message("<span class='warning'><B>[src] rises out of the pool of blood!</B>")
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1)
if(iscarbon(src))
var/mob/living/carbon/C = src
for(var/obj/item/weapon/bloodcrawl/BC in C)
C.flags = null
C.unEquip(BC)
qdel(BC)
var/oldcolor = src.color
if(istype(B, /obj/effect/decal/cleanable/xenoblood)) //Makes the mob have the color of the blood pool it came out of for a few seconds
src.color = rgb(43, 186, 0)
else
src.color = rgb(149, 10, 10)
qdel(src.holder)
src.holder = null
return 1
spawn(30)
src.color = oldcolor
return 1
+9 -6
View File
@@ -85,15 +85,18 @@
update_icon()
name = "Man-Machine Interface"
/obj/item/device/mmi/proc/transfer_identity(mob/living/carbon/human/H) //Same deal as the regular brain proc. Used for human-->robot people.
/obj/item/device/mmi/proc/transfer_identity(mob/living/L) //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
if(check_dna_integrity(H))
brainmob.dna = H.dna
brainmob.name = L.real_name
brainmob.real_name = L.real_name
if(L.has_dna())
var/mob/living/carbon/C = L
brainmob.dna = C.dna
brainmob.dna.holder = brainmob
brainmob.container = src
if(istype(H))
if(ishuman(L))
var/mob/living/carbon/human/H = L
var/obj/item/organ/internal/brain/newbrain = H.getorgan(/obj/item/organ/internal/brain)
newbrain.loc = src
brain = newbrain
@@ -26,10 +26,10 @@
qdel(brainmob)
//Update the body's icon so it doesnt appear debrained anymore
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.update_hair(0)
//Update the body's icon so it doesnt appear debrained anymore
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.update_hair(0)
/obj/item/organ/internal/brain/Remove(mob/living/carbon/M, special = 0)
..()
@@ -56,9 +56,10 @@
brainmob.name = L.real_name
brainmob.real_name = L.real_name
brainmob.timeofhostdeath = L.timeofdeath
if(iscarbon(L))
if(L.has_dna())
var/mob/living/carbon/C = L
brainmob.dna = C.dna
brainmob.dna.holder = brainmob
if(L.mind)
L.mind.transfer_to(brainmob)
brainmob << "<span class='notice'>You feel slightly disoriented. That's normal when you're just a brain.</span>"
@@ -55,17 +55,20 @@ var/global/posibrain_notif_cooldown = 0
return
transfer_personality(user)
/obj/item/device/mmi/posibrain/transfer_identity(mob/living/carbon/H)
name = "positronic brain ([H])"
brainmob.name = H.real_name
brainmob.real_name = H.real_name
brainmob.dna = H.dna
brainmob.timeofhostdeath = H.timeofdeath
/obj/item/device/mmi/posibrain/transfer_identity(mob/living/carbon/C)
name = "positronic brain ([C])"
brainmob.name = C.real_name
brainmob.real_name = C.real_name
brainmob.dna = C.dna
if(C.has_dna())
brainmob.dna = C.dna
brainmob.dna.holder = brainmob
brainmob.timeofhostdeath = C.timeofdeath
brainmob.stat = 0
if(brainmob.mind)
brainmob.mind.assigned_role = "Positronic Brain"
if(H.mind)
H.mind.transfer_to(brainmob)
if(C.mind)
C.mind.transfer_to(brainmob)
brainmob.mind.remove_all_antag()
brainmob.mind.wipe_memory()
+2
View File
@@ -22,6 +22,8 @@
for(var/atom/movable/food in stomach_contents)
qdel(food)
remove_from_all_data_huds()
if(dna)
qdel(dna)
return ..()
/mob/living/carbon/Move(NewLoc, direct)
@@ -9,9 +9,6 @@
var/obj/item/handcuffed = null //Whether or not the mob is handcuffed
var/obj/item/legcuffed = null //Same as handcuffs but for legs. Bear traps use this.
var/list/features = list("mcolor" = "FFF", "tail" = "Smooth", "snout" = "Round", "horns" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None")
//inventory slots
var/obj/item/back = null
var/obj/item/clothing/mask/wear_mask = null
@@ -272,10 +272,9 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
source = M.get_blood(M.vessel)
else if(istype(source,/mob/living/carbon/monkey))
var/mob/living/carbon/monkey/donor = source
if(donor.dna)
source = new()
source.data["blood_DNA"] = donor.dna.unique_enzymes
source.data["blood_type"] = donor.dna.blood_type
source = new()
source.data["blood_DNA"] = donor.dna.unique_enzymes
source.data["blood_type"] = donor.dna.blood_type
// Are we dripping or splattering?
var/list/drips = list()
@@ -8,10 +8,7 @@
..()
/mob/living/carbon/human/spawn_gibs()
if(dna)
hgibs(loc, viruses, dna)
else
hgibs(loc, viruses, null)
hgibs(loc, viruses, dna)
/mob/living/carbon/human/spawn_dust()
new /obj/effect/decal/remains/human(loc)
@@ -35,8 +32,7 @@
update_canmove()
if(client) blind.layer = 0
if(dna)
dna.species.spec_death(gibbed,src)
dna.species.spec_death(gibbed,src)
tod = worldtime2text() //weasellos time of death patch
if(mind) mind.store_memory("Time of death: [tod]", 0)
@@ -47,9 +43,8 @@
return ..(gibbed)
/mob/living/carbon/human/proc/makeSkeleton()
if(!check_dna_integrity(src)) return
status_flags |= DISFIGURED
hardset_dna(src, null, null, null, null, /datum/species/skeleton)
set_species(/datum/species/skeleton)
return 1
/mob/living/carbon/proc/ChangeToHusk()
@@ -308,7 +308,7 @@
m_type = 2
if("wag","wags")
if(dna && dna.species && (("tail_lizard" in dna.species.mutant_bodyparts) || (features["tail_human"] != "None")))
if(dna && dna.species && (("tail_lizard" in dna.species.mutant_bodyparts) || (dna.features["tail_human"] != "None")))
message = "<B>[src]</B> wags \his tail."
startTailWag()
else
+10 -9
View File
@@ -16,6 +16,12 @@
/mob/living/carbon/human/New()
verbs += /mob/living/proc/mob_sleep
verbs += /mob/living/proc/lay_down
//initialize dna. for spawned humans; overwritten by other code
create_dna(src)
randomize_human(src)
dna.initialize_dna()
//initialise organs
organs = newlist(/obj/item/organ/limb/chest, /obj/item/organ/limb/head, /obj/item/organ/limb/l_arm,
/obj/item/organ/limb/r_arm, /obj/item/organ/limb/r_leg, /obj/item/organ/limb/l_leg)
@@ -28,11 +34,6 @@
for(var/obj/item/organ/internal/I in internal_organs)
I.Insert(src)
// for spawned humans; overwritten by other code
create_dna(src)
randomize_human(src)
ready_dna(src)
make_blood()
..()
@@ -90,9 +91,8 @@
stat("Energy Charge:", "[round(SN.cell.charge/100)]%")
stat("Smoke Bombs:", "\Roman [SN.s_bombs]")
//Ninja status
if(dna)
stat("Fingerprints:", "[md5(dna.uni_identity)]")
stat("Unique Identity:", "[dna.unique_enzymes]")
stat("Fingerprints:", "[md5(dna.uni_identity)]")
stat("Unique Identity:", "[dna.unique_enzymes]")
stat("Overall Status:", "[stat > 1 ? "dead" : "[health]% healthy"]")
stat("Nutrition Status:", "[nutrition]")
stat("Oxygen Loss:", "[getOxyLoss()]")
@@ -663,7 +663,8 @@
facial_hair_style = "Shaved"
hair_style = pick("Bedhead", "Bedhead 2", "Bedhead 3")
underwear = "Nude"
regenerate_icons()
update_body()
update_hair()
/mob/living/carbon/human/singularity_act()
var/gain = 20
@@ -7,11 +7,7 @@
/mob/living/carbon/human/attack_hand(mob/living/carbon/human/M)
if(..()) //to allow surgery to return properly.
return
if(dna)
dna.species.spec_attack_hand(M, src)
return
dna.species.spec_attack_hand(M, src)
/mob/living/carbon/human/proc/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, inrange, params)
return
@@ -160,38 +160,5 @@
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = 0)
if(dna) // if you have a species, it will run the apply_damage code there instead
dna.species.apply_damage(damage, damagetype, def_zone, blocked, src)
else
if((damagetype != BRUTE) && (damagetype != BURN))
..(damage, damagetype, def_zone, blocked)
return 1
else
blocked = (100-blocked)/100
if(blocked <= 0) return 0
var/obj/item/organ/limb/organ = null
if(islimb(def_zone))
organ = def_zone
else
if(!def_zone) def_zone = ran_zone(def_zone)
organ = get_organ(check_zone(def_zone))
if(!organ) return 0
damage = (damage * blocked)
switch(damagetype)
if(BRUTE)
damageoverlaytemp = 20
if(organ.take_damage(damage, 0))
update_damage_overlays(0)
if(BURN)
damageoverlaytemp = 20
if(organ.take_damage(0, damage))
update_damage_overlays(0)
// Will set our damageoverlay icon to the next level, which will then be set back to the normal level the next mob.Life().
updatehealth()
return 1
// depending on the species, it will run the corresponding apply_damage code there
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src)
@@ -37,9 +37,7 @@ emp_act
return protection
/mob/living/carbon/human/on_hit(proj_type)
if(dna)
dna.species.on_hit(proj_type, src)
return
dna.species.on_hit(proj_type, src)
/mob/living/carbon/human/bullet_act(obj/item/projectile/P, def_zone)
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
@@ -128,91 +126,8 @@ emp_act
feedback_add_details("item_used_for_combat","[I.type]|[I.force]")
feedback_add_details("zone_targeted","[target_area]")
if(dna) // allows your species to affect the attacked_by code
return dna.species.spec_attacked_by(I,user,def_zone,affecting,hit_area,src.a_intent,target_limb,target_area,src)
else
if(user != src)
user.do_attack_animation(src)
if(check_shields(I.force, "the [I.name]", I))
return 0
if(I.attack_verb && I.attack_verb.len)
visible_message("<span class='danger'>[user] has [pick(I.attack_verb)] [src] in the [hit_area] with [I]!</span>", \
"<span class='userdanger'>[user] has [pick(I.attack_verb)] [src] in the [hit_area] with [I]!</span>")
else if(I.force)
visible_message("<span class='danger'>[user] has attacked [src] in the [hit_area] with [I]!</span>", \
"<span class='userdanger'>[user] has attacked [src] in the [hit_area] with [I]!</span>")
else
return 0
var/armor = run_armor_check(affecting, "melee", "<span class='notice'>Your armor has protected your [hit_area].</span>", "<span class='notice'>Your armor has softened a hit to your [hit_area].</span>", I.armour_penetration)
armor = min(90,armor) //cap damage reduction at 90%
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 , I)
var/bloody = 0
if(((I.damtype == BRUTE) && I.force && prob(25 + (I.force * 2))))
if(affecting.status == ORGAN_ORGANIC)
I.add_blood(src) //Make the weapon bloody, not the person.
if(prob(I.force * 2)) //blood spatter!
bloody = 1
var/turf/location = loc
if(istype(location, /turf/simulated))
location.add_blood(src)
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(get_dist(H, src) <= 1) //people with TK won't get smeared with blood
if(H.wear_suit)
H.wear_suit.add_blood(src)
H.update_inv_wear_suit() //updates mob overlays to show the new blood (no refresh)
else if(H.w_uniform)
H.w_uniform.add_blood(src)
H.update_inv_w_uniform() //updates mob overlays to show the new blood (no refresh)
if (H.gloves)
var/obj/item/clothing/gloves/G = H.gloves
G.add_blood(H)
else
H.add_blood(H)
H.update_inv_gloves() //updates on-mob overlays for bloody hands and/or bloody gloves
switch(hit_area)
if("head") //Harder to score a stun but if you do it lasts a bit longer
if(stat == CONSCIOUS)
if(prob(I.force))
visible_message("<span class='danger'>[src] has been knocked unconscious!</span>", \
"<span class='userdanger'>[src] has been knocked unconscious!</span>")
apply_effect(20, PARALYZE, armor)
if(prob(I.force + min(100,100 - src.health)) && src != user && I.damtype == BRUTE)
ticker.mode.remove_revolutionary(mind)
if(bloody) //Apply blood
if(wear_mask)
wear_mask.add_blood(src)
update_inv_wear_mask()
if(head)
head.add_blood(src)
update_inv_head()
if(glasses && prob(33))
glasses.add_blood(src)
update_inv_glasses()
if("chest") //Easier to score a stun but lasts less time
if(stat == CONSCIOUS && I.force && prob(I.force + 10))
visible_message("<span class='danger'>[src] has been knocked down!</span>", \
"<span class='userdanger'>[src] has been knocked down!</span>")
apply_effect(5, WEAKEN, armor)
if(bloody)
if(wear_suit)
wear_suit.add_blood(src)
update_inv_wear_suit()
if(w_uniform)
w_uniform.add_blood(src)
update_inv_w_uniform()
if(Iforce > 10 || Iforce >= 5 && prob(33))
forcesay(hit_appends) //forcesay checks stat already
// the attacked_by code varies among species
return dna.species.spec_attacked_by(I,user,def_zone,affecting,hit_area,src.a_intent,target_limb,target_area,src)
/mob/living/carbon/human/emp_act(severity)
var/informed = 0
@@ -128,11 +128,9 @@
return (health <= config.health_threshold_crit && stat == UNCONSCIOUS)
/mob/living/carbon/human/reagent_check(datum/reagent/R)
if(dna)
var/bypass = dna.species.handle_chemicals(R,src)
return bypass // if it returns 0, it will run the usual on_mob_life for that reagent. otherwise, it will stop after running handle_chemicals for the species.
else
return 0
return dna.species.handle_chemicals(R,src)
// if it returns 0, it will run the usual on_mob_life for that reagent. otherwise, it will stop after running handle_chemicals for the species.
/mob/living/carbon/human/can_track(mob/living/user)
if(wear_id && istype(wear_id.GetID(), /obj/item/weapon/card/id/syndicate))
@@ -1,6 +1,6 @@
/mob/living/carbon/human/movement_delay()
if(dna)
. += dna.species.movement_delay(src)
. += dna.species.movement_delay(src)
. += ..()
. += config.human_delay
@@ -46,9 +46,8 @@
/mob/living/carbon/human/Move(NewLoc, direct)
. = ..()
if(dna)
for(var/datum/mutation/human/HM in dna.mutations)
HM.on_move(src, NewLoc)
for(var/datum/mutation/human/HM in dna.mutations)
HM.on_move(src, NewLoc)
if(shoes)
if(!lying)
if(loc == NewLoc)
@@ -1,158 +1,5 @@
/mob/living/carbon/human/can_equip(obj/item/I, slot, disable_warning = 0)
if(dna)
return dna.species.can_equip(I, slot, disable_warning, src)
else
switch(slot)
if(slot_l_hand)
if(l_hand)
return 0
return 1
if(slot_r_hand)
if(r_hand)
return 0
return 1
if(slot_wear_mask)
if(wear_mask)
return 0
if( !(I.slot_flags & SLOT_MASK) )
return 0
return 1
if(slot_back)
if(back)
return 0
if( !(I.slot_flags & SLOT_BACK) )
return 0
return 1
if(slot_wear_suit)
if(wear_suit)
return 0
if( !(I.slot_flags & SLOT_OCLOTHING) )
return 0
return 1
if(slot_gloves)
if(gloves)
return 0
if( !(I.slot_flags & SLOT_GLOVES) )
return 0
return 1
if(slot_shoes)
if(shoes)
return 0
if( !(I.slot_flags & SLOT_FEET) )
return 0
return 1
if(slot_belt)
if(belt)
return 0
if(!w_uniform)
if(!disable_warning)
src << "<span class='warning'>You need a jumpsuit before you can attach this [I.name]!</span>"
return 0
if( !(I.slot_flags & SLOT_BELT) )
return
return 1
if(slot_glasses)
if(glasses)
return 0
if( !(I.slot_flags & SLOT_EYES) )
return 0
return 1
if(slot_head)
if(head)
return 0
if( !(I.slot_flags & SLOT_HEAD) )
return 0
return 1
if(slot_ears)
if(ears)
return 0
if( !(I.slot_flags & SLOT_EARS) )
return 0
return 1
if(slot_w_uniform)
if(w_uniform)
return 0
if( !(I.slot_flags & SLOT_ICLOTHING) )
return 0
return 1
if(slot_wear_id)
if(wear_id)
return 0
if(!w_uniform)
if(!disable_warning)
src << "<span class='warning'>You need a jumpsuit before you can attach this [I.name]!</span>"
return 0
if( !(I.slot_flags & SLOT_ID) )
return 0
return 1
if(slot_l_store)
if(I.flags & NODROP) //Pockets aren't visible, so you can't move NODROP items into them.
return 0
if(l_store)
return 0
if(!w_uniform)
if(!disable_warning)
src << "<span class='warning'>You need a jumpsuit before you can attach this [I.name]!</span>"
return 0
if(I.slot_flags & SLOT_DENYPOCKET)
return
if( I.w_class <= 2 || (I.slot_flags & SLOT_POCKET) )
return 1
if(slot_r_store)
if(I.flags & NODROP)
return 0
if(r_store)
return 0
if(!w_uniform)
if(!disable_warning)
src << "<span class='warning'>You need a jumpsuit before you can attach this [I.name]!</span>"
return 0
if(I.slot_flags & SLOT_DENYPOCKET)
return 0
if( I.w_class <= 2 || (I.slot_flags & SLOT_POCKET) )
return 1
return 0
if(slot_s_store)
if(I.flags & NODROP) //Suit storage NODROP items drop if you take a suit off, this is to prevent people exploiting this.
return 0
if(s_store)
return 0
if(!wear_suit)
if(!disable_warning)
src << "<span class='warning'>You need a suit before you can attach this [I.name]!</span>"
return 0
if(!wear_suit.allowed)
if(!disable_warning)
usr << "<span class='warning'>You somehow have a suit with no defined allowed items for suit storage, stop that!</span>" //should be src?
return 0
if(I.w_class > 4)
if(!disable_warning)
usr << "<span class='warning'>The [I.name] is too big to attach!</span>" //should be src?
return 0
if( istype(I, /obj/item/device/pda) || istype(I, /obj/item/weapon/pen) || is_type_in_list(I, wear_suit.allowed) ) //ugly and un-polymorphic.
return 1
return 0
if(slot_handcuffed)
if(handcuffed)
return 0
if(!istype(I, /obj/item/weapon/restraints/handcuffs))
return 0
return 1
if(slot_legcuffed)
if(legcuffed)
return 0
if(!istype(I, /obj/item/weapon/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(B.contents.len < B.storage_slots && I.w_class <= B.max_w_class)
return 1
return 0
return 0 //Unsupported slot
return dna.species.can_equip(I, slot, disable_warning, src)
/mob/living/carbon/human/verb/quick_equip()
set name = "quick-equip"
@@ -477,7 +324,7 @@
/mob/living/carbon/human/proc/equipOutfit(outfit)
var/datum/outfit/O = null
if(ispath(outfit))
O = new outfit
else
@@ -486,5 +333,5 @@
return 0
if(!O)
return 0
return O.equip(src)
+9 -17
View File
@@ -38,9 +38,8 @@
tinttotal = tintcheck() //here as both hud updates and status updates call it
if(..())
if(dna)
for(var/datum/mutation/human/HM in dna.mutations)
HM.on_life(src)
for(var/datum/mutation/human/HM in dna.mutations)
HM.on_life(src)
//heart attack stuff
handle_heart()
@@ -50,8 +49,7 @@
//Update our name based on whether our face is obscured/disfigured
name = get_visible_name()
if(dna)
dna.species.spec_life(src) // for mutantraces
dna.species.spec_life(src) // for mutantraces
/mob/living/carbon/human/calculate_affecting_pressure(pressure)
@@ -98,16 +96,15 @@
reagents.metabolize(src, can_overdose=1)
/mob/living/carbon/human/breathe()
if(!dna || !dna.species.breathe(src))
if(!dna.species.breathe(src))
..()
/mob/living/carbon/human/check_breath(datum/gas_mixture/breath)
if(!dna || !dna.species.check_breath(breath, src))
if(!dna.species.check_breath(breath, src))
..()
/mob/living/carbon/human/handle_environment(datum/gas_mixture/environment)
if(dna)
dna.species.handle_environment(environment, src)
dna.species.handle_environment(environment, src)
///FIRE CODE
/mob/living/carbon/human/handle_fire()
@@ -263,10 +260,7 @@
/mob/living/carbon/human/handle_chemicals_in_body()
..()
if(dna)
dna.species.handle_chemicals_in_body(src)
return //TODO: DEFERRED
dna.species.handle_chemicals_in_body(src)
/mob/living/carbon/human/handle_vision()
client.screen.Remove(global_hud.blurry, global_hud.druggy, global_hud.vimpaired, global_hud.darkMask)
@@ -275,12 +269,10 @@
else
if(!client.adminobs) reset_view(null)
if(dna)
dna.species.handle_vision(src)
dna.species.handle_vision(src)
/mob/living/carbon/human/handle_hud_icons()
if(dna)
dna.species.handle_hud_icons(src)
dna.species.handle_hud_icons(src)
/mob/living/carbon/human/handle_random_events()
// Puke if toxloss is too high
+2 -4
View File
@@ -9,8 +9,7 @@
return ..()
/mob/living/carbon/human/treat_message(message)
if(dna)
message = dna.species.handle_speech(message,src)
message = dna.species.handle_speech(message,src)
if(viruses.len)
for(var/datum/disease/pierrot_throat/D in viruses)
var/list/temp_message = text2list(message, " ") //List each word in the message
@@ -25,8 +24,7 @@
pick_list -= H //Make sure that you dont HONK the same word twice
message = list2text(temp_message, " ")
message = ..(message)
if(dna)
message = dna.mutations_say_mods(message)
message = dna.mutations_say_mods(message)
return message
/mob/living/carbon/human/get_spans()
+31 -65
View File
@@ -247,7 +247,7 @@
if(H.undershirt)
var/datum/sprite_accessory/undershirt/U2 = undershirt_list[H.undershirt]
if(U2)
if(H.dna && H.dna.species.sexes && H.gender == FEMALE)
if(H.dna.species.sexes && H.gender == FEMALE)
standing += H.wear_female_version(U2.icon_state, U2.icon, BODY_LAYER)
else
standing += image("icon"=U2.icon, "icon_state"="[U2.icon_state]_s", "layer"=-BODY_LAYER)
@@ -804,8 +804,8 @@
if(prob(1))
H << "<span class='danger'>You mutate!</span>"
randmutb(H)
domutcheck(H,null)
H.emote("gasp")
H.domutcheck()
return 0
return 1
@@ -907,22 +907,14 @@
else
M.do_attack_animation(H)
var/atk_verb = "punch"
var/atk_verb = M.dna.species.attack_verb
if(H.lying)
atk_verb = "kick"
else if(M.dna)
atk_verb = M.dna.species.attack_verb
var/damage = rand(0, 9)
if(M.dna)
damage += M.dna.species.punchmod
var/damage = rand(0, 9) + M.dna.species.punchmod
if(!damage)
if(M.dna)
playsound(H.loc, M.dna.species.miss_sound, 25, 1, -1)
else
playsound(H.loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
playsound(H.loc, M.dna.species.miss_sound, 25, 1, -1)
H.visible_message("<span class='warning'>[M] has attempted to [atk_verb] [H]!</span>")
return 0
@@ -930,11 +922,7 @@
var/obj/item/organ/limb/affecting = H.get_organ(ran_zone(M.zone_sel.selecting))
var/armor_block = H.run_armor_check(affecting, "melee")
if(M.dna)
playsound(H.loc, M.dna.species.attack_sound, 25, 1, -1)
else
playsound(H.loc, 'sound/weapons/punch1.ogg', 25, 1, -1)
playsound(H.loc, M.dna.species.attack_sound, 25, 1, -1)
H.visible_message("<span class='danger'>[M] has [atk_verb]ed [H]!</span>", \
"<span class='userdanger'>[M] has [atk_verb]ed [H]!</span>")
@@ -1008,9 +996,9 @@
/datum/species/proc/spec_attacked_by(obj/item/I, mob/living/user, def_zone, obj/item/organ/limb/affecting, hit_area, intent, obj/item/organ/limb/target_limb, target_area, mob/living/carbon/human/H)
// Allows you to put in item-specific reactions based on species
if(user != src)
if(user != H)
user.do_attack_animation(H)
if((user != H) && H.check_shields(I.force, "the [I.name]", I))
if(H.check_shields(I.force, "the [I.name]", I))
return 0
if(I.attack_verb && I.attack_verb.len)
@@ -1022,11 +1010,11 @@
else
return 0
var/armor = H.run_armor_check(affecting, "melee", "<span class='notice'>Your armor has protected your [hit_area].</span>", "<span class='notice'>Your armor has softened a hit to your [hit_area].</span>",I.armour_penetration)
armor = min(90,armor) //cap damage reduction at 90%
var/armor_block = H.run_armor_check(affecting, "melee", "<span class='notice'>Your armor has protected your [hit_area].</span>", "<span class='notice'>Your armor has softened a hit to your [hit_area].</span>",I.armour_penetration)
armor_block = min(90,armor_block) //cap damage reduction at 90%
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, H)
apply_damage(I.force, I.damtype, affecting, armor_block, H)
var/bloody = 0
if(((I.damtype == BRUTE) && I.force && prob(25 + (I.force * 2))))
@@ -1037,28 +1025,30 @@
var/turf/location = H.loc
if(istype(location, /turf/simulated))
location.add_blood(H)
if(get_dist(H, H) <= 1) //people with TK won't get smeared with blood
if(H.wear_suit)
H.wear_suit.add_blood(H)
H.update_inv_wear_suit() //updates mob overlays to show the new blood (no refresh)
else if(H.w_uniform)
H.w_uniform.add_blood(H)
H.update_inv_w_uniform() //updates mob overlays to show the new blood (no refresh)
if (H.gloves)
var/obj/item/clothing/gloves/G = H.gloves
G.add_blood(H)
else
H.add_blood(H)
H.update_inv_gloves() //updates on-mob overlays for bloody hands and/or bloody gloves
if(ishuman(user))
var/mob/living/carbon/human/M = user
if(get_dist(M, H) <= 1) //people with TK won't get smeared with blood
if(M.wear_suit)
M.wear_suit.add_blood(H)
M.update_inv_wear_suit() //updates mob overlays to show the new blood (no refresh)
else if(M.w_uniform)
M.w_uniform.add_blood(H)
M.update_inv_w_uniform() //updates mob overlays to show the new blood (no refresh)
if (M.gloves)
var/obj/item/clothing/gloves/G = M.gloves
G.add_blood(H)
else
M.add_blood(H)
M.update_inv_gloves() //updates on-mob overlays for bloody hands and/or bloody gloves
switch(hit_area)
if("head") //Harder to score a stun but if you do it lasts a bit longer
if(H.stat == CONSCIOUS && armor < 50)
if(H.stat == CONSCIOUS && armor_block < 50)
if(prob(I.force))
H.visible_message("<span class='danger'>[H] has been knocked unconscious!</span>", \
"<span class='userdanger'>[H] has been knocked unconscious!</span>")
H.apply_effect(20, PARALYZE, armor)
H.apply_effect(20, PARALYZE, armor_block)
if(prob(I.force + ((100 - H.health)/2)) && H != user && I.damtype == BRUTE)
ticker.mode.remove_revolutionary(H.mind)
@@ -1077,7 +1067,7 @@
if(H.stat == CONSCIOUS && I.force && prob(I.force + 10))
H.visible_message("<span class='danger'>[H] has been knocked down!</span>", \
"<span class='userdanger'>[H] has been knocked down!</span>")
H.apply_effect(5, WEAKEN, armor)
H.apply_effect(5, WEAKEN, armor_block)
if(bloody)
if(H.wear_suit)
@@ -1091,34 +1081,9 @@
H.forcesay(hit_appends) //forcesay checks stat already.
return
/datum/species/proc/attacked_by(obj/item/I, mob/living/user, def_zone, mob/living/carbon/human/H)
H.apply_damage(I.force, I.damtype)
if(I.damtype == "brute")
if(prob(33) && I.force && !(NOBLOOD in specflags))
var/turf/location = H.loc
if(istype(location, /turf/simulated))
location.add_blood_floor(H)
var/message_verb = ""
if(I.attack_verb && I.attack_verb.len)
message_verb = "[pick(I.attack_verb)]"
else if(I.force)
message_verb = "attacked"
var/attack_message = "[H] has been [message_verb] with [I]."
if(user)
user.do_attack_animation(src)
if(user in viewers(src, null))
attack_message = "[user] has [message_verb] [H] with [I]!"
if(message_verb)
H.visible_message("<span class='danger'>[attack_message]</span>",
"<span class='userdanger'>[attack_message]</span>")
return
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H)
blocked = (100-(blocked+armor))/100
if(blocked <= 0) return 0
if(!damage || blocked <= 0) return 0
var/obj/item/organ/limb/organ = null
if(islimb(def_zone))
@@ -1147,6 +1112,7 @@
H.adjustCloneLoss(damage * blocked)
if(STAMINA)
H.adjustStaminaLoss(damage * blocked)
return 1
/datum/species/proc/on_hit(obj/item/projectile/proj_type, mob/living/carbon/human/H)
// called when hit by a projectile
@@ -38,8 +38,7 @@
/datum/species/human/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.id == "mutationtoxin")
H << "<span class='danger'>Your flesh rapidly mutates!</span>"
hardset_dna(H, null, null, null, null, /datum/species/slime)
H.regenerate_icons()
H.set_species(/datum/species/slime)
H.reagents.del_reagent(chem.type)
H.faction |= "slime"
return 1
@@ -128,10 +127,9 @@ datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
H.visible_message("<span class='warning'>[H] writhes in pain as \his vacuoles boil.</span>", "<span class='userdanger'>You writhe in pain as your vacuoles boil!</span>", "<span class='italics'>You hear the crunching of leaves.</span>")
if(prob(80))
randmutb(H)
domutcheck(H,null)
else
randmutg(H)
domutcheck(H,null)
H.domutcheck()
else
H.adjustFireLoss(rand(5,15))
H.show_message("<span class='userdanger'>The radiation beam singes you!</span>")
@@ -53,30 +53,10 @@ Please contact me on #coderbus IRC. ~Carnie x
*/
/mob/living/carbon/human/proc/update_base_icon_state()
if(dna)
base_icon_state = dna.species.update_base_icon_state(src)
else
if(disabilities & HUSK)
base_icon_state = "husk"
else
base_icon_state = "[skin_tone]_[(gender == FEMALE) ? "f" : "m"]"
base_icon_state = dna.species.update_base_icon_state(src)
icon_state = "[base_icon_state]_s"
//UPDATES OVERLAYS FROM OVERLAYS_STANDING
//TODO: Remove all instances where this proc is called. It used to be the fastest way to swap between standing/lying.
/mob/living/carbon/human/update_icons()
update_hud() //TODO: remove the need for this
if(overlays.len != overlays_standing.len)
overlays.Cut()
for(var/thing in overlays_standing)
if(thing) overlays += thing
update_transform()
//DAMAGE OVERLAYS
//constructs damage icon for each organ from mask * damage field and saves it in our overlays_ lists
/mob/living/carbon/human/update_damage_overlays()
@@ -105,25 +85,21 @@ Please contact me on #coderbus IRC. ~Carnie x
if((wear_suit) && (wear_suit.hooded) && (wear_suit.suittoggled == 1))
return
if(dna)
dna.species.handle_hair(src)
dna.species.handle_hair(src)
/mob/living/carbon/human/proc/update_mutcolor()
if(dna && !(disabilities & HUSK))
if(!(disabilities & HUSK))
dna.species.update_color(src)
//used when putting/removing clothes that hide certain mutant body parts to just update those and not update the whole body.
/mob/living/carbon/human/proc/update_mutant_bodyparts()
if(dna)
dna.species.handle_mutant_bodyparts(src)
dna.species.handle_mutant_bodyparts(src)
/mob/living/carbon/human/proc/update_body()
remove_overlay(BODY_LAYER)
update_base_icon_state()
if(dna)
dna.species.handle_body(src)
dna.species.handle_body(src)
/mob/living/carbon/human/update_fire()
..("Standing")
@@ -181,6 +157,8 @@ Please contact me on #coderbus IRC. ~Carnie x
update_hud()
// Mutantrace colors
update_mutcolor()
//mutations
update_mutations_overlay()
/* --------------------------------------- */
//vvvvvv UPDATE_INV PROCS vvvvvv
@@ -38,8 +38,8 @@
if(prob(1))
src << "<span class='danger'>You mutate!</span>"
randmutb(src)
domutcheck(src,null)
emote("gasp")
domutcheck()
..()
/mob/living/carbon/monkey/handle_chemicals_in_body()
@@ -16,16 +16,24 @@
verbs += /mob/living/proc/mob_sleep
verbs += /mob/living/proc/lay_down
gender = pick(MALE, FEMALE)
real_name = name
if(good_mutations.len) //genetic mutations have been set up.
initialize()
internal_organs += new /obj/item/organ/internal/appendix
internal_organs += new /obj/item/organ/internal/heart
internal_organs += new /obj/item/organ/internal/brain
for(var/obj/item/organ/internal/I in internal_organs)
I.Insert(src)
gender = pick(MALE, FEMALE)
..()
/mob/living/carbon/monkey/initialize()
create_dna(src)
dna.initialize_dna(random_blood_type())
/mob/living/carbon/monkey/prepare_data_huds()
//Prepare our med HUD...
..()
+2 -2
View File
@@ -605,8 +605,8 @@ Sorry Giacom. Please don't be mad :(
if((!(newdir in H.existing_dirs) || trail_type == "trails_1" || trail_type == "trails_2") && H.existing_dirs.len <= 16) //maximum amount of overlays is 16 (all light & heavy directions filled)
H.existing_dirs += newdir
H.overlays.Add(image('icons/effects/blood.dmi',trail_type,dir = newdir))
if(check_dna_integrity(M)) //blood DNA
var/mob/living/carbon/DNA_helper = pulling
if(M.has_dna()) //blood DNA
var/mob/living/carbon/DNA_helper = M
H.blood_DNA[DNA_helper.dna.unique_enzymes] = DNA_helper.dna.blood_type
/mob/living/proc/getTrail() //silicon and simple_animals don't get blood trails
@@ -1,99 +0,0 @@
#define BORG_CAMERA_BUFFER 30
//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update.
// TURFS
/turf
var/image/obscured
/turf/proc/visibilityChanged()
if(ticker)
cameranet.updateVisibility(src)
/turf/simulated/Del()
visibilityChanged()
..()
/turf/simulated/New()
..()
visibilityChanged()
// STRUCTURES
/obj/structure/Destroy()
if(ticker)
cameranet.updateVisibility(src)
return ..()
/obj/structure/New()
..()
if(ticker)
cameranet.updateVisibility(src)
// EFFECTS
/obj/effect/Destroy()
if(ticker)
cameranet.updateVisibility(src)
return ..()
/obj/effect/New()
..()
if(ticker)
cameranet.updateVisibility(src)
// DOORS
// Simply updates the visibility of the area when it opens/closes/destroyed.
/obj/machinery/door/proc/update_freelook_sight()
// Glass door glass = 1
// don't check then?
if(!glass && cameranet)
cameranet.updateVisibility(src, 0)
// ROBOT MOVEMENT
// Update the portable camera everytime the Robot moves.
// This might be laggy, comment it out if there are problems.
/mob/living/silicon/robot/var/updating = 0
/mob/living/silicon/robot/Move()
var/oldLoc = src.loc
. = ..()
if(.)
if(src.camera)
if(!updating)
updating = 1
spawn(BORG_CAMERA_BUFFER)
if(oldLoc != src.loc)
cameranet.updatePortableCamera(src.camera)
updating = 0
// CAMERA
// An addition to deactivate which removes/adds the camera from the chunk list based on if it works or not.
/obj/machinery/camera/deactivate(mob/user, choice = 1)
..(user, choice)
if(src.can_use())
cameranet.addCamera(src)
else
src.SetLuminosity(0)
cameranet.removeCamera(src)
/obj/machinery/camera/New()
..()
cameranet.cameras += src
cameranet.addCamera(src)
/obj/machinery/camera/Destroy()
cameranet.cameras -= src
cameranet.removeCamera(src)
return ..()
#undef BORG_CAMERA_BUFFER
@@ -375,7 +375,7 @@
M.visible_message("<span class='notice'>[M] presses \his thumb against [P].</span>",\
"<span class='notice'>You press your thumb against [P].</span>",\
"<span class='notice'>[P] makes a sharp clicking sound as it extracts DNA material from [M].</span>")
if(!check_dna_integrity(M))
if(!M.has_dna())
P << "<b>No DNA detected</b>"
return
P << "<font color = red><h3>[M]'s UE string : [M.dna.unique_enzymes]</h3></font>"
+13 -1
View File
@@ -67,6 +67,8 @@
var/lamp_intensity = 0 //Luminosity of the headlamp. 0 is off. Higher settings than the minimum require power.
var/lamp_recharging = 0 //Flag for if the lamp is on cooldown after being forcibly disabled.
var/updating = 0 //portable camera camerachunk update
/mob/living/silicon/robot/New(loc)
spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src)
@@ -882,9 +884,18 @@
/mob/living/silicon/robot/proc/radio_menu()
radio.interact(src)//Just use the radio's Topic() instead of bullshit special-snowflake code
#define BORG_CAMERA_BUFFER 30
/mob/living/silicon/robot/Move(a, b, flag)
var/oldLoc = src.loc
. = ..()
if(.)
if(src.camera)
if(!updating)
updating = 1
spawn(BORG_CAMERA_BUFFER)
if(oldLoc != src.loc)
cameranet.updatePortableCamera(src.camera)
updating = 0
if(module)
if(module.type == /obj/item/weapon/robot_module/janitor)
var/turf/tile = loc
@@ -924,6 +935,7 @@
loc.attackby(module_state_2,src)
else if(istype(module_state_3,/obj/item/weapon/storage/bag/ore))
loc.attackby(module_state_3,src)
#undef BORG_CAMERA_BUFFER
/mob/living/silicon/robot/proc/self_destruct()
if(emagged)
@@ -229,6 +229,9 @@
/mob/living/simple_animal/slime/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S << "<span class='warning'>This biological resource is somehow resisting our bluespace transceiver. Aborting.</span>"
/obj/machinery/droneDispenser/swarmer/swarmer_act(mob/living/simple_animal/hostile/swarmer/S)
S << "<span class='warning'>This object is receiving unactivated swarmer shells to help us. Aborting.</span>"
////END CTRL CLICK FOR SWARMERS////
@@ -0,0 +1,30 @@
/datum/round_event_control/spawn_swarmer
name = "Spawn Swarmer Shell"
typepath = /datum/round_event/spawn_swarmer
weight = 7
max_occurrences = 1 //Only once okay fam
earliest_start = 18000 //30 minutes
/datum/round_event/spawn_swarmer
/datum/round_event/spawn_swarmer/start()
if(find_swarmer())
return 0
if(!the_gateway)
return 0
new /obj/item/unactivated_swarmer(get_turf(the_gateway))
if(prob(25)) //25% chance to announce it to the crew
var/swarmer_report = "<font size=3><b>[command_name()] High-Priority Update</b></span>"
swarmer_report += "<br><br>Our long-range sensors have detected an odd signal emanating from your station's gateway. We recommend immediate investigation of your gateway, as something may have come \
through."
print_command_report(swarmer_report,"Classified [command_name()] Update")
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/AI/commandreport.ogg')
/datum/round_event/spawn_swarmer/proc/find_swarmer()
for(var/mob/living/M in mob_list)
if(istype(M, /mob/living/simple_animal/hostile/swarmer) && M.client) //If there is a swarmer with an active client, we've found our swarmer
return 1
return 0
@@ -1,9 +1,9 @@
#define MORPH_COOLDOWN 50
/mob/living/simple_animal/hostile/morph
name = "Morph"
real_name = "Morph"
desc = "some amorphous blob"
name = "morph"
real_name = "morph"
desc = "A revolting, pulsating pile of flesh."
speak_emote = list("gurgles")
emote_hear = list("gurgles")
icon = 'icons/mob/animal.dmi'
@@ -28,16 +28,25 @@
see_invisible = SEE_INVISIBLE_MINIMUM
idle_vision_range = 1 // Only attack when target is close
wander = 0
attacktext = "glomps"
attack_sound = 'sound/effects/blobattack.ogg'
var/morphed = 0
var/atom/movable/form = null
var/morph_time = 0
var/playstyle_string = "<b><font size=3 color='red'>You are a morph,</font> an abomination of science created primarily with changeling cells. \
You may take the form of anything nearby by middle-clicking it. This process will alert any nearby \
observers, and can only be performed once every five seconds. While morphed, you move faster, but do \
less damage. In addition, anyone within three tiles will note an uncanny wrongness if examining you. \
You can attack any item or dead creature to consume it - creatures will fully restore your health. \
Finally, you can restore yourself to your original form while morphed by middle-clicking yourself.</b>"
/mob/living/simple_animal/hostile/morph/examine(mob/user)
if(morphed)
form.examine(user) // Refactor examine to return desc so it's static? Not sure if worth it
if(get_dist(user,src)<=3)
user << "<span class='notice'>Looks odd!</span>"
user << "<span class='warning'>It doesn't look quite right...</span>"
else
..()
return
@@ -57,6 +66,7 @@
if(istype(A) && allowed(A))
assume(A)
else
src << "<span class='warning'>Your chameleon skin is still repairing itself!</span>"
..()
/mob/living/simple_animal/hostile/morph/proc/assume(atom/movable/target)
@@ -72,11 +82,15 @@
else
overlays = target.overlays.Copy()
visible_message("<span class='warning'>[src] suddenly twists and changes shape, becoming a copy of [target]!</span>", \
"<span class='notice'>You twist your body and assume the form of [target].</span>")
name = target.name
icon = target.icon
icon_state = target.icon_state
overlays = target.overlays
//Morphed is weaker
melee_damage_lower = 5
melee_damage_upper = 5
@@ -93,6 +107,8 @@
//anim(loc,src,'icons/mob/mob.dmi',,"morph",,src.dir)
visible_message("<span class='warning'>[src] suddenly collapses in on itself, dissolving into a pile of green flesh!</span>", \
"<span class='notice'>You reform to your normal body.</span>")
name = initial(name)
icon = initial(icon)
icon_state = initial(icon_state)
@@ -108,7 +124,8 @@
/mob/living/simple_animal/hostile/morph/death()
if(morphed)
visible_message("<span class='danger'>The [src] dissolves!</span>")
visible_message("<span class='warning'>[src] twists and dissolves into a pile of green flesh!</span>", \
"<span class='userdanger'>Your skin ruptures! Your flesh breaks apart! No disguise can ward off de--</span>")
restore()
//Dump eaten stuff
@@ -148,7 +165,7 @@
var/mob/living/L = target
if(L.stat == DEAD)
if(do_after(src, 30, target = L))
visible_message("<span class='warning'>[src] swallows the [target] whole!</span>")
visible_message("<span class='warning'>[src] swallows [target] whole!</span>")
L.loc = src
adjustBruteLoss(-50)
return
@@ -156,7 +173,7 @@
var/obj/item/I = target
if(!I.anchored)
if(do_after(src,20, target = I))
visible_message("<span class='warning'>[src] swallows the [target] whole!</span>")
visible_message("<span class='warning'>[src] swallows [target] whole!</span>")
I.loc = src
return
target.attack_animal(src)
@@ -198,15 +215,10 @@
player_mind.assigned_role = "Morph"
player_mind.special_role = "Morph"
ticker.mode.traitors |= player_mind
var/info = {"<B>You are a Morph, a shapeshifting alien creature.</B>
You can assume the shape of anything in sight by Shift-Clicking it.
You can only transform every 5 seconds.
To return to your basic form Shift-Click on yourself.
Base form is slow but strong, you're much weaker and faster when disguised.
You can eat items and corpses by clicking on them,eating corpses will heal you."}
S << info
message_admins("[key_of_morph] has been made into Morph by an event.")
log_game("[key_of_morph] was spawned as a Morph by an event.")
S << S.playstyle_string
S << 'sound/magic/Mutate.ogg'
message_admins("[key_of_morph] has been made into morph by an event.")
log_game("[key_of_morph] was spawned as a morph by an event.")
return 1
/datum/round_event/morph/start()
@@ -214,11 +226,11 @@
/datum/round_event/morph/proc/find_morph()
message_admins("Attempted to spawn a Morph but there was no players available. Will try again momentarily.")
message_admins("Attempted to spawn a morph but there was no players available. Will try again momentarily.")
spawn(50)
if(get_morph(1))
message_admins("Situation has been resolved, [key_of_morph] has been spawned as a Morph.")
log_game("[key_of_morph] was spawned as a Morph by an event.")
message_admins("Situation has been resolved, [key_of_morph] has been spawned as a morph.")
log_game("[key_of_morph] was spawned as a morph by an event.")
return 0
message_admins("Unfortunately, no candidates were available for becoming a Morph. Shutting down.")
message_admins("Unfortunately, no candidates were available for becoming a morph. Shutting down.")
return kill()
@@ -3,17 +3,19 @@
//Don't hear deadchat and are NOT normal ghosts
//Admin-spawn or random event
#define INVISIBILITY_REVENANT 30
/mob/living/simple_animal/revenant
name = "revenant"
desc = "A malevolent spirit."
icon = 'icons/mob/mob.dmi'
icon_state = "revenant_idle"
incorporeal_move = 3
invisibility = INVISIBILITY_OBSERVER
invisibility = INVISIBILITY_REVENANT
health = 25
maxHealth = 25
healable = 0
see_invisible = SEE_INVISIBLE_OBSERVER
see_invisible = INVISIBILITY_REVENANT
languages = ALL
response_help = "passes through"
response_disarm = "swings at"
@@ -137,7 +139,8 @@
if(target) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining.
change_essence_amount(essence_drained * 5, 0, target)
src << "<span class='info'>[target]'s soul has been considerably weakened and will yield no more essence for the time being.</span>"
target.visible_message("<span class='warning'>[target] gently slumps back onto the ground.</span>")
target.visible_message("<span class='warning'>[target] slumps onto the ground.</span>", \
"<span class='userdanger'>Violets lights, dancing in your vision, getting clo--</span>")
drained_mobs.Add(target)
target.death(0)
icon_state = "revenant_idle"
@@ -150,7 +153,10 @@
/mob/living/simple_animal/revenant/say(message)
return 0 //Revenants cannot speak out loud.
for(var/mob/M in mob_list)
if(istype(M, /mob/living/simple_animal/revenant) || M.stat == DEAD)
M << "<span class='deadsay'><b>REVENANT: [src]</b> says, \"[message]\"" //Can commune with the dead
return
/mob/living/simple_animal/revenant/Stat()
..()
@@ -182,14 +188,16 @@
src.mind.objectives += objective2
src << "<b>Objective #2</b>: [objective2.explanation_text]"
ticker.mode.traitors |= src.mind //Necessary for announcing
mob_spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_transmit
mob_spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_light
mob_spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_defile
mob_spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_malf
AddSpell(new /obj/effect/proc_holder/spell/targeted/revenant_transmit(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant_light(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant_defile(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant_malf(null))
/mob/living/simple_animal/revenant/death()
if(!revealed) //Revenants cannot die if they aren't revealed
return 0
..(1)
src << "<span class='userdanger'><b>NO! No... it's too late, you can feel yourself fading...</b></span>"
src << "<span class='userdanger'>NO! No... it's too late, you can feel yourself fading...</span>"
notransform = 1
revealed = 1
invisibility = 0
@@ -199,8 +207,9 @@
for(var/i = alpha, i > 0, i -= 10)
sleep(0.1)
alpha = i
visible_message("<span class='danger'>[src]'s body breaks apart into blue dust.</span>")
new /obj/item/weapon/ectoplasm/revenant(get_turf(src))
visible_message("<span class='danger'>[src]'s body breaks apart into a fine pile of blue dust.</span>")
var/obj/item/weapon/ectoplasm/revenant/R = new (get_turf(src))
R.client_to_revive = src.client //If the essence reforms, the old revenant is put back in the body
ghostize()
qdel(src)
return
@@ -209,7 +218,7 @@
/mob/living/simple_animal/revenant/attackby(obj/item/W, mob/living/user, params)
if(istype(W, /obj/item/weapon/nullrod))
visible_message("<span class='warning'>[src] violently flinches!</span>", \
"<span class='boldannounce'>As the null rod passes through you, you feel your essence draining away!</span>")
"<span class='userdanger'>As the null rod passes through you, you feel your essence draining away!</span>")
essence -= 25 //hella effective
inhibited = 1
spawn(30)
@@ -263,7 +272,7 @@
src << "<span class='warning'>You have been revealed.</span>"
spawn(time)
revealed = 0
invisibility = INVISIBILITY_OBSERVER
invisibility = INVISIBILITY_REVENANT
src << "<span class='notice'>You are once more concealed.</span>"
/mob/living/simple_animal/revenant/proc/stun(time)
@@ -323,7 +332,8 @@
icon_state = "revenantEctoplasm"
w_class = 2
var/reforming = 0
var/reformed = 0
var/inert = 0
var/client/client_to_revive
/obj/item/weapon/ectoplasm/revenant/New()
..()
@@ -332,17 +342,12 @@
if(src && reforming)
return reform()
if(src && !reforming)
reforming = 1
visible_message("<span class='warning'>[src] settles down and seems lifeless.</span>")
return
/obj/item/weapon/ectoplasm/revenant/attack_hand(mob/user)
if(reformed)
user << "<span class='warning'>[src] keeps slipping out of your hands, you can't get a hold on it!</span>"
return
..()
/obj/item/weapon/ectoplasm/revenant/attack_self(mob/user)
if(!reforming)
if(!reforming || inert)
return ..()
user.visible_message("<span class='notice'>[user] scatters [src] in all directions.</span>", \
"<span class='notice'>You scatter [src] across the area. The particles slowly fade away.</span>")
@@ -351,6 +356,8 @@
/obj/item/weapon/ectoplasm/revenant/throw_impact(atom/hit_atom)
..()
if(inert)
return
visible_message("<span class='notice'>[src] breaks into particles upon impact, which fade away to nothingness.</span>")
qdel(src)
@@ -364,20 +371,29 @@
/obj/item/weapon/ectoplasm/revenant/proc/reform()
if(!reforming || !src)
return
var/key_of_revenant
message_admins("Revenant ectoplasm was left undestroyed for 1 minute and has reformed into a new revenant.")
loc = get_turf(src) //In case it's in a backpack or someone's hand
visible_message("<span class='boldannounce'>[src] suddenly rises into the air before fading away.</span>")
var/mob/living/simple_animal/revenant/R = new(get_turf(src))
qdel(src)
var/list/candidates = get_candidates(BE_REVENANT)
if(!candidates.len)
message_admins("No candidates were found for the new revenant. Oh well!")
return 0
var/client/C = pick(candidates)
var/key_of_revenant = C.key
if(!key_of_revenant)
message_admins("No ckey was found for the new revenant. Oh well!")
return 0
if(client_to_revive)
for(var/mob/M in mob_list)
if(M.client == client_to_revive && M.stat == DEAD) //Only recreates the mob if the mob the client is in is dead
message_admins("[R.client] was a revenant and died. Re-making them into the new revenant formed by ectoplasm.")
R.client = client_to_revive
key_of_revenant = client_to_revive.key
break
message_admins("The new revenant's old client either could not be found or is in a new, living mob - grabbing a random candidate instead...")
else
var/list/candidates = get_candidates(BE_REVENANT)
if(!candidates.len)
message_admins("No candidates were found for the new revenant. Oh well!")
return 0
var/client/C = pick(candidates)
key_of_revenant = C.key
if(!key_of_revenant)
message_admins("No ckey was found for the new revenant. Oh well!")
return 0
var/datum/mind/player_mind = new /datum/mind(key_of_revenant)
player_mind.active = 1
player_mind.transfer_to(R)
@@ -386,4 +402,7 @@
ticker.mode.traitors |= player_mind
message_admins("[key_of_revenant] has been made into a revenant by reforming ectoplasm.")
log_game("[key_of_revenant] was spawned as a revenant by reforming ectoplasm.")
qdel(src)
if(src) //Should never happen, but just in case
inert = 1
return 1
@@ -7,6 +7,8 @@
clothes_req = 0
range = 7
include_user = 0
action_icon_state = "r_transmit"
action_background_icon_state = "bg_revenant"
/obj/effect/proc_holder/spell/targeted/revenant_transmit/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
for(var/mob/living/M in targets)
@@ -16,7 +18,7 @@
charge_counter = charge_max
return
usr << "<span class='info'><b>You transmit to [M]:</b> [msg]</span>"
M << "<span class='deadsay'><b>A strange voice resonates in your head...</b></span><i> [msg]</I>"
M << "<span class='deadsay'><b>An alien voice resonates from all around...</b></span><i> [msg]</I>"
//Overload Light: Breaks a light that's online and sends out lightning bolts to all nearby people.
@@ -30,6 +32,8 @@
var/reveal = 80
var/stun = 20
var/locked = 1
action_icon_state = "overload_lights"
action_background_icon_state = "bg_revenant"
/obj/effect/proc_holder/spell/aoe_turf/revenant_light/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(locked)
@@ -40,7 +44,7 @@
name = "Overload Lights (20E)"
panel = "Revenant Abilities"
locked = 0
range = 6
range = 2
charge_counter = charge_max
return
if(!user.castcheck(-20))
@@ -58,7 +62,7 @@
s.set_up(4, 1, L)
s.start()
sleep(10)
for(var/mob/living/M in orange(4, L))
for(var/mob/living/M in range(4, L))
if(M == user)
return
M.Beam(L,icon_state="lightning",icon='icons/effects/effects.dmi',time=5)
@@ -73,8 +77,8 @@
//Defile: Corrupts nearby stuff, unblesses floor tiles.
/obj/effect/proc_holder/spell/aoe_turf/revenant_defile
name = "Defile (35E)"
desc = "Twists and corrupts the nearby area. Also dispels holy auras on floors, but not salt lines."
name = "Defile (20E)"
desc = "Twists and corrupts the nearby area. Also dispels holy auras on floors."
panel = "Revenant Abilities (Locked)"
charge_max = 200
clothes_req = 0
@@ -82,6 +86,8 @@
var/reveal = 100
var/stun = 20
var/locked = 1
action_icon_state = "defile"
action_background_icon_state = "bg_revenant"
/obj/effect/proc_holder/spell/aoe_turf/revenant_defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(locked)
@@ -89,7 +95,7 @@
charge_counter = charge_max
return
user << "<span class='info'>You have unlocked Defile!</span>"
name = "Defile (20E)"
name = "Defile (10E)"
panel = "Revenant Abilities"
locked = 0
range = 3
@@ -102,10 +108,6 @@
spawn(0)
if(T.flags & NOJAUNT)
T.flags -= NOJAUNT
if(!istype(T, /turf/simulated/wall/cult) && istype(T, /turf/simulated/wall) && prob(40))
T.ChangeTurf(/turf/simulated/wall/cult)
if(!istype(T, /turf/simulated/floor/engine/cult) && istype(T, /turf/simulated/floor) && prob(40))
T.ChangeTurf(/turf/simulated/floor/engine/cult)
for(var/mob/living/carbon/human/human in T.contents)
human << "<span class='warning'>You suddenly feel tired.</span>"
human.adjustStaminaLoss(35)
@@ -128,6 +130,8 @@
var/reveal = 60
var/stun = 30
var/locked = 1
action_icon_state = "malfunction"
action_background_icon_state = "bg_revenant"
/obj/effect/proc_holder/spell/aoe_turf/revenant_malf/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(locked)
@@ -152,8 +156,19 @@
bot.open = 1
bot.Emag(null)
for(var/obj/machinery/mach in T.contents)
if(istype(mach, /obj/machinery/dominator) || istype(mach, /obj/machinery/power/apc)) //Doesn't work on dominators and APCs, to prevent kekkery
continue
if(prob(10))
mach.emag_act(null)
empulse(user.loc, 3, 5)
else
mach.emp_act(1)
for(var/mob/living/silicon/robot/S in T.contents) //Only works on cyborgs, not AI
S << "<span class='warning'><b>ERROR $!(@ ERROR )#^! SENSORY OVERLOAD \[$(!@#</b></span>"
S << 'sound/misc/interference.ogg'
playsound(S, 'sound/machines/warning-buzzer.ogg', 50, 1)
var/datum/effect/effect/system/spark_spread/sp = new /datum/effect/effect/system/spark_spread
sp.set_up(5, 1, S)
sp.start()
S.Weaken(6)
user.reveal(reveal)
user.stun(stun)
@@ -1,9 +1,9 @@
//////////////////The Monster
/mob/living/simple_animal/slaughter
name = "Slaughter Demon"
real_name = "Slaughter Demon"
desc = "You should run."
name = "slaughter demon"
real_name = "slaughter demon"
desc = "A large, menacing creature covered in armored black scales."
speak_emote = list("gurgles")
emote_hear = list("wails","screeches")
response_help = "thinks better of touching"
@@ -31,10 +31,11 @@
var/boost = 0
bloodcrawl = BLOODCRAWL_EAT
see_invisible = SEE_INVISIBLE_MINIMUM
var/playstyle_string = "<B>You are the Slaughter Demon, a terible creature from another existence. You have a single desire: To kill. \
You may Ctrl+Click on blood pools to travel through them, appearing and dissaapearing from the station at will. \
Pulling a dead or critical mob while you enter a pool will pull them in with you, allowing you to feast. \
You move quickly upon leaving a pool of blood, but the material world will soon sap your strength and leave you sluggish. </B>"
var/list/consumed_mobs = list()
var/playstyle_string = "<B><font size=3 color='red'>You are a slaughter demon,</font> a terrible creature from another realm. You have a single desire: To kill. \
You may use the \"Blood Crawl\" ability near blood pools to travel through them, appearing and dissaapearing from the station at will. \
Pulling a dead or unconscious mob while you enter a pool will pull them in with you, allowing you to feast and regain your health. \
You move quickly upon leaving a pool of blood, but the material world will soon sap your strength and leave you sluggish. </B>"
/mob/living/simple_animal/slaughter/New()
..()
@@ -52,10 +53,17 @@
/mob/living/simple_animal/slaughter/death()
..(1)
new /obj/effect/decal/cleanable/blood (src.loc)
new /obj/item/weapon/demonheart (src.loc)
new /obj/effect/decal/cleanable/blood (get_turf(src))
var/obj/effect/decal/cleanable/blood/innards = new (get_turf(src))
innards.icon = 'icons/obj/surgery.dmi'
innards.icon_state = "innards"
innards.name = "pile of viscera"
innards.desc = "A repulsive pile of guts and gore."
new /obj/item/organ/internal/heart/demon (src.loc)
playsound(get_turf(src),'sound/magic/demon_dies.ogg', 200, 1)
visible_message("<span class='danger'>The [src] screams in anger as its form collapes into a pool of viscera.</span>")
visible_message("<span class='danger'>[src] screams in anger as it collapses into a puddle of viscera, its most recent meals spilling out of it.</span>")
for(var/mob/living/M in consumed_mobs)
M.loc = get_turf(src)
ghostize()
qdel(src)
return
@@ -64,26 +72,44 @@
/mob/living/simple_animal/slaughter/phasein()
. = ..()
speed = 0
boost = world.time + 30
boost = world.time + 60
//////////The Loot
/obj/item/weapon/demonheart
name = "demon's heart"
desc = "It's still faintly beating with rage"
//The loot from killing a slaughter demon - can be consumed to allow the user to blood crawl
/obj/item/organ/internal/heart/demon
name = "demon heart"
desc = "Still it beats furiously, emanating an aura of utter hate."
icon = 'icons/obj/surgery.dmi'
icon_state = "heart-on"
icon_state = "demon_heart"
origin_tech = "combat=5;biotech=8"
/obj/item/weapon/demonheart/attack_self(mob/living/user)
visible_message("[user] feasts upon the [src].")
/obj/item/organ/internal/heart/demon/attack(mob/M, mob/living/carbon/user, obj/target)
if(M != user)
return ..()
user.visible_message("<span class='warning'>[user] raises [src] to their mouth and tears into it with their teeth!</span>", \
"<span class='danger'>An unnatural hunger consumes you. You raise [src] your mouth and devour it!</span>")
playsound(user, 'sound/magic/Demon_consume.ogg', 50, 1)
for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list)
if(knownspell.type == /obj/effect/proc_holder/spell/bloodcrawl)
user <<"<span class='notice'>You already know how to blood crawl.</span>"
user <<"<span class='warning'>...and you don't feel any different.</span>"
qdel(src)
return
user << "You absorb some of the demon's power!"
user.mind.AddSpell(new /obj/effect/proc_holder/spell/bloodcrawl)
qdel(src)
user.visible_message("<span class='warning'>[user]'s eyes flare a deep crimson!</span>", \
"<span class='userdanger'>You feel a strange power seep into your body... you have absorbed the demon's blood-travelling powers!</span>")
/*for(var/obj/item/organ/internal/O in user.internal_organs)
if(istype(O, /obj/item/organ/internal/heart))
O.Remove(user, 1)
O.loc = get_turf(user)
qdel(O)*/
user.drop_item()
src.Insert(user) //Consuming the heart literally replaces your heart with a demon heart. H A R D C O R E
/obj/item/organ/internal/heart/demon/Insert(mob/living/carbon/M, special = 0)
..()
if(M.mind)
M.mind.AddSpell(new /obj/effect/proc_holder/spell/bloodcrawl(null))
/obj/item/organ/internal/heart/demon/Remove(mob/living/carbon/M, special = 0)
..()
if(M.mind)
M.mind.remove_spell(/obj/effect/proc_holder/spell/bloodcrawl)
@@ -44,9 +44,10 @@
player_mind.special_role = "Slaughter Demon"
ticker.mode.traitors |= player_mind
S << S.playstyle_string
S << "<B>You are currently not currently in the same plane of existence as the station. Ctrl+Click a blood pool to manifest.</B>"
message_admins("[key_of_slaughter] has been made into a Slaughter Demon by an event.")
log_game("[key_of_slaughter] was spawned as a Slaughter Demon by an event.")
S << "<B>You are currently not currently in the same plane of existence as the station. Blood Crawl near a blood pool to manifest.</B>"
S << 'sound/magic/demon_dies.ogg'
message_admins("[key_of_slaughter] has been made into a slaughter demon by an event.")
log_game("[key_of_slaughter] was spawned as a slaughter demon by an event.")
return 1
@@ -57,11 +58,11 @@
/datum/round_event/slaughter/proc/find_slaughter()
message_admins("Attempted to spawn a Slaughter Demon but there was no players available. Will try again momentarily.")
message_admins("Attempted to spawn a slaughter demon but there was no players available. Will try again momentarily.")
spawn(50)
if(get_slaughter(1))
message_admins("Situation has been resolved, [key_of_slaughter] has been spawned as a Slaughter Demon.")
log_game("[key_of_slaughter] was spawned as a Slaughter Demon by an event.")
message_admins("Situation has been resolved, [key_of_slaughter] has been spawned as a slaughter demon.")
log_game("[key_of_slaughter] was spawned as a slaughter demon by an event.")
return 0
message_admins("Unfortunately, no candidates were available for becoming a Slaugter Demon. Shutting down.")
message_admins("Unfortunately, no candidates were available for becoming a slaughter demon. Shutting down.")
return kill()
@@ -251,9 +251,8 @@
if(istype(L, /mob/living/carbon/human)) //Ignore slime(wo)men
var/mob/living/carbon/human/H = L
if(H.dna)
if(src.type in H.dna.species.ignored_by)
continue
if(src.type in H.dna.species.ignored_by)
continue
if(!L.canmove) // Only one slime can latch on at a time.
var/notarget = 0
+9 -2
View File
@@ -200,8 +200,15 @@
M.animate_movement = 2
return
if(mob.confused && IsEven(world.time))
step(mob, pick(cardinal))
if(mob.confused)
if(mob.confused > 40)
step(mob, pick(cardinal))
else if(prob(mob.confused * 1.5))
step(mob, angle2dir(dir2angle(direct) + pick(90, -90)))
else if(prob(mob.confused * 3))
step(mob, angle2dir(dir2angle(direct) + pick(45, -45)))
else
step(mob, direct)
else
. = ..()
@@ -40,15 +40,11 @@
M.name = src.name
M.real_name = src.real_name
if(check_dna_integrity(src))
if(has_dna() && M.has_dna())
var/mob/living/carbon/C = src
var/mob/living/carbon/D = M
D.dna = C.dna
updateappearance(D)
else
if(istype(M, /mob/living/carbon/human))
src.client.prefs.copy_to(M)
ready_dna(M)
C.dna.transfer_identity(D)
D.updateappearance(mutcolor_update=1, mutations_overlay_update=1)
if(mind && istype(M, /mob/living))
mind.transfer_to(M)
+1 -5
View File
@@ -362,21 +362,17 @@
var/mob/living/carbon/human/new_character = new(loc)
new_character.lastarea = get_area(loc)
create_dna(new_character)
if(config.force_random_names || appearance_isbanned(src))
client.prefs.random_character()
client.prefs.real_name = client.prefs.pref_species.random_name(gender,1)
client.prefs.copy_to(new_character)
new_character.dna.update_dna_identity()
if(mind)
mind.active = 0 //we wish to transfer the key manually
mind.transfer_to(new_character) //won't transfer key since the mind is not active
new_character.name = real_name
ready_dna(new_character, client.prefs.blood_type)
new_character.key = key //Manually transfer the key to log them in
new_character.stopLobbySound()
+45 -54
View File
@@ -1,4 +1,4 @@
/mob/living/carbon/proc/monkeyize(tr_flags = (TR_KEEPITEMS | TR_KEEPVIRUS | TR_DEFAULTMSG), newname = null)
/mob/living/carbon/proc/monkeyize(tr_flags = (TR_KEEPITEMS | TR_KEEPVIRUS | TR_DEFAULTMSG))
if (notransform)
return
//Handle items on mob
@@ -16,8 +16,11 @@
int_organs += I
I.Remove(src, 1)
if(tr_flags & TR_KEEPITEMS)
for(var/obj/item/W in (src.contents-implants-int_organs))
unEquip(W)
//Make mob invisible and spawn animation
regenerate_icons()
notransform = 1
canmove = 0
stunned = 1
@@ -35,18 +38,18 @@
qdel(animation)
// hash the original name?
if (tr_flags & TR_HASHNAME)
if(tr_flags & TR_HASHNAME)
O.name = "monkey ([copytext(md5(real_name), 2, 6)])"
O.real_name = "monkey ([copytext(md5(real_name), 2, 6)])"
if (newname) //if there's a name as an argument, always take that one over the current name
O.name = newname
O.real_name = newname
//handle DNA and other attributes
if(dna)
dna.transfer_identity(O)
if(tr_flags & TR_KEEPSE)
O.dna.struc_enzymes = dna.struc_enzymes
dna.transfer_identity(O)
O.updateappearance(icon_update=0)
if(tr_flags & TR_KEEPSE)
O.dna.struc_enzymes = dna.struc_enzymes
var/datum/mutation/human/race/R = mutations_list[RACEMUT]
O.dna.struc_enzymes = R.set_se(O.dna.struc_enzymes, on=1)//we don't want to keep the race block inactive
if(suiciding)
O.suiciding = suiciding
@@ -70,9 +73,10 @@
O.radiation = radiation
//re-add implants to new mob
for(var/obj/item/weapon/implant/I in implants)
I.loc = O
I.implanted = O
if (tr_flags & TR_KEEPIMPLANTS)
for(var/obj/item/weapon/implant/I in implants)
I.loc = O
I.implanted = O
//re-add organs to new mob
if(tr_flags & TR_KEEPORGANS)
@@ -96,16 +100,14 @@
if(loc.vars[A] == src)
loc.vars[A] = O
updateappearance(O)
. = O
if ( !(tr_flags & TR_KEEPSRC) ) //flag should be used if monkeyize() is called inside another proc of src so that one does not crash
qdel(src)
qdel(src)
////////////////////////// Humanize //////////////////////////////
//Could probably be merged with monkeyize but other transformations got their own procs, too
/mob/living/carbon/proc/humanize(tr_flags = (TR_KEEPITEMS | TR_KEEPVIRUS | TR_DEFAULTMSG), newname = null)
/mob/living/carbon/proc/humanize(tr_flags = (TR_KEEPITEMS | TR_KEEPVIRUS | TR_DEFAULTMSG))
if (notransform)
return
//Handle items on mob
@@ -125,7 +127,7 @@
//now the rest
if (tr_flags & TR_KEEPITEMS)
for(var/obj/item/W in (src.contents-implants))
for(var/obj/item/W in (src.contents-implants-int_organs))
unEquip(W)
if (client)
client.screen -= W
@@ -134,11 +136,7 @@
W.dropped(src)
W.layer = initial(W.layer)
// for(var/obj/item/W in src)
// unEquip(W)
//Make mob invisible and spawn animation
regenerate_icons()
notransform = 1
canmove = 0
stunned = 1
@@ -156,27 +154,21 @@
O.equip_to_appropriate_slot(C)
qdel(animation)
O.gender = (deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? FEMALE : MALE
dna.transfer_identity(O)
O.updateappearance(mutcolor_update=1)
if(dna)
dna.transfer_identity(O)
O.update_icons()
if(tr_flags & TR_KEEPSE)
O.dna.struc_enzymes = dna.struc_enzymes
domutcheck(O)
if(!dna.species)
hardset_dna(O, null, null, null, null, /datum/species/human)
if(cmptext("monkey",copytext(O.dna.real_name,1,7)))
O.real_name = random_unique_name(O.gender)
O.dna.generate_unique_enzymes(O)
else
hardset_dna(O, null, null, null, null, dna.species.type)
if(newname) //if there's a name as an argument, always take that one over the current name
O.real_name = newname
else
if(cmptext("monkey",copytext(O.dna.real_name,1,7)))
O.dna.real_name = random_unique_name(O.gender)
O.real_name = O.dna.real_name
O.name = O.real_name
O.name = O.real_name
if(tr_flags & TR_KEEPSE)
O.dna.struc_enzymes = dna.struc_enzymes
var/datum/mutation/human/race/R = mutations_list[RACEMUT]
O.dna.struc_enzymes = R.set_se(O.dna.struc_enzymes, on=0)//we don't want to keep the race block active
O.domutcheck()
if(suiciding)
O.suiciding = suiciding
@@ -201,10 +193,11 @@
O.radiation = radiation
//re-add implants to new mob
for(var/obj/item/weapon/implant/I in implants)
I.loc = O
I.implanted = O
O.sec_hud_set_implants()
if (tr_flags & TR_KEEPIMPLANTS)
for(var/obj/item/weapon/implant/I in implants)
I.loc = O
I.implanted = O
O.sec_hud_set_implants()
if(tr_flags & TR_KEEPORGANS)
for(var/obj/item/organ/internal/I in O.internal_organs)
@@ -215,21 +208,23 @@
if(mind)
mind.transfer_to(O)
if(O.mind.changeling)
for(var/obj/effect/proc_holder/changeling/humanform/HF in O.mind.changeling.purchasedpowers)
mind.changeling.purchasedpowers -= HF
O.a_intent = "help"
if (tr_flags & TR_DEFAULTMSG)
O << "<B>You are now a human.</B>"
O.update_pipe_vision()
updateappearance(O)
. = O
for(var/A in loc.vars)
if(loc.vars[A] == src)
loc.vars[A] = O
if ( !(tr_flags & TR_KEEPSRC) ) //don't delete src yet if it's needed to finish calling proc
qdel(src)
qdel(src)
/mob/new_player/AIize()
@@ -431,14 +426,10 @@
/mob/living/carbon/human/proc/Blobize()
if (notransform)
return
var/obj/effect/blob/core/new_blob = new /obj/effect/blob/core (loc)
if(!client)
for(var/mob/dead/observer/G in player_list)
if(ckey == "@[G.ckey]")
new_blob.create_overmind(G.client , 1)
break
if(!client) //TOO BAD
new /obj/effect/blob/core (loc)
else
new_blob.create_overmind(src.client , 1)
new /obj/effect/blob/core (loc,new_overmind = src.client)
gib(src)