From afd9720abc564b12ead87addea7da894f897623e Mon Sep 17 00:00:00 2001 From: Jack Edge Date: Mon, 23 May 2016 16:05:20 +0100 Subject: [PATCH 1/2] Polymorph bugs, time since death, groundwork laid :cl: coiax fix: Fixes bug where bolt of change to the host would kill an attached guardian. fix: Fixes bug where bolt of change to laughter demon would not release its friends. fix: Fixes bug where bolt of change to morphling would not release its contents. fix: Fixes bug where bolt of change transforming someone into a drone would not give them hacked laws and vision. rscadd: Medical scanners now inform the user if the dead subject is within the (currently) 120 second defib window. /:cl: - Also laid the groundwork for force pushing ghosts back into bodies when defibbing, along with standardising the ghost back into body process. - Defib limit and defib brain loss times are now #defines. --- code/__DEFINES/misc.dm | 3 + code/datums/mind.dm | 6 +- code/game/gamemodes/miniantags/morph/morph.dm | 8 +- .../miniantags/slaughter/slaughter.dm | 27 +- code/game/objects/items/devices/scanners.dm | 4 + code/game/objects/items/weapons/defib.dm | 341 +++++++++--------- code/modules/mob/living/living.dm | 15 + .../friendly/drone/interaction.dm | 7 + .../mob/living/simple_animal/slime/slime.dm | 36 +- code/modules/mob/mob.dm | 4 + code/modules/projectiles/projectile/magic.dm | 22 +- 11 files changed, 264 insertions(+), 209 deletions(-) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 3720cdf17e3..74f542bda05 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -433,3 +433,6 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE // Evil narsie colour #define NARSIE_WINDOW_COLOUR "#7D1919" +// Defib stats +#define DEFIB_TIME_LIMIT 120 +#define DEFIB_TIME_LOSS 60 diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 9c1a5522b93..c37717b2f75 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1689,7 +1689,11 @@ return G break - +/datum/mind/proc/grab_ghost(force) + var/mob/dead/observer/G = get_ghost(even_if_they_cant_reenter = force) + . = G + if(G) + G.reenter_corpse() /mob/proc/sync_mind() mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist) diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm index b6fccab0bb2..a2b0f999bb8 100644 --- a/code/game/gamemodes/miniantags/morph/morph.dm +++ b/code/game/gamemodes/miniantags/morph/morph.dm @@ -144,14 +144,18 @@ visible_message("[src] twists and dissolves into a pile of green flesh!", \ "Your skin ruptures! Your flesh breaks apart! No disguise can ward off de--") restore() + barf_contents() ..() -/mob/living/simple_animal/hostile/morph/Destroy() +/mob/living/simple_animal/hostile/morph/proc/barf_contents() for(var/atom/movable/AM in src) AM.loc = loc if(prob(90)) step(AM, pick(alldirs)) - return ..() + +/mob/living/simple_animal/hostile/morph/wabbajack_act(mob/living/new_mob) + barf_contents() + . = ..() /mob/living/simple_animal/hostile/morph/Aggro() // automated only ..() diff --git a/code/game/gamemodes/miniantags/slaughter/slaughter.dm b/code/game/gamemodes/miniantags/slaughter/slaughter.dm index 3495ad1344a..6925d1b392f 100644 --- a/code/game/gamemodes/miniantags/slaughter/slaughter.dm +++ b/code/game/gamemodes/miniantags/slaughter/slaughter.dm @@ -137,27 +137,24 @@ // HOT. PINK. //color = "#FF69B4" - -/mob/living/simple_animal/slaughter/laughter/New() - ..() - /mob/living/simple_animal/slaughter/laughter/death() + release_friends() + . = ..() + +/mob/living/simple_animal/slaughter/laughter/wabbajack_act() + release_friends() + . = ..() + +/mob/living/simple_animal/slaughter/laughter/proc/release_friends() if(!consumed_mobs) - return ..() + return for(var/mob/living/M in consumed_mobs) M.loc = get_turf(src) if(M.revive(full_heal = 1)) - // Feel there should be a better way of FORCING a mob's ghost - // back into the body - if(!M.ckey) - for(var/mob/dead/observer/ghost in player_list) - if(M.real_name == ghost.real_name) - ghost.reenter_corpse() - break - M << "You leave the [src]'s warm embrace, and feel ready to take on the world." - - return ..() + M.grab_ghost(force = FALSE) + M << "You leave the [src]'s warm embrace, \ + and feel ready to take on the world." /mob/living/simple_animal/slaughter/laughter/bloodcrawl_swallow(var/mob/living/victim) if(consumed_mobs) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 6102f97caee..146610a5197 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -173,6 +173,10 @@ MASS SPECTROMETER // Time of death if(M.tod && (M.stat == DEAD || (M.status_flags & FAKEDEATH))) user << "Time of Death: [M.tod]" + var/tdelta = world.time - M.timeofdeath + if(tdelta < (DEFIB_TIME_LIMIT * 10)) + user << "Subject died [tdelta / 10] seconds \ + ago, defibrillation may be possible!" for(var/datum/disease/D in M.viruses) if(!(D.visibility_flags & HIDDEN_SCANNER)) diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index c04ead47e26..0bb8b547514 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -1,5 +1,4 @@ //backpack item - /obj/item/weapon/defibrillator name = "defibrillator" desc = "A device that delivers powerful shocks to detachable paddles that resuscitate incapacitated patients." @@ -19,6 +18,7 @@ var/obj/item/weapon/twohanded/shockpaddles/paddles var/obj/item/weapon/stock_parts/cell/high/bcell = null var/combat = 0 //can we revive through space suits? + var/grab_ghost = FALSE // Do we pull the ghost back into their body? /obj/item/weapon/defibrillator/New() //starts without a cell for rnd ..() @@ -297,6 +297,7 @@ var/obj/item/weapon/defibrillator/defib var/req_defib = 1 var/combat = 0 //If it penetrates armor and gives additional functionality + var/grab_ghost = FALSE /obj/item/weapon/twohanded/shockpaddles/proc/recharge(var/time) if(req_defib || !time) @@ -382,178 +383,186 @@ else user << "You aren't sure how to revive that..." return - else - var/mob/living/carbon/human/H = M - if(user.a_intent == "disarm") - if(req_defib && defib.safety) - return - if(!req_defib && !combat) - return - busy = 1 - H.visible_message("[user] has touched [H.name] with [src]!", \ - "[user] has touched [H.name] with [src]!") - H.adjustStaminaLoss(50) - H.Weaken(5) - H.updatehealth() //forces health update before next life tick - playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) - H.emote("gasp") - add_logs(user, M, "stunned", src) - if(req_defib) - defib.deductcharge(revivecost) - cooldown = 1 - busy = 0 - update_icon() - if(req_defib) - defib.cooldowncheck(user) - else - recharge(60) + var/mob/living/carbon/human/H = M + + if(user.a_intent == "disarm") + if(req_defib && defib.safety) return - if(user.zone_selected == "chest") - if(user.a_intent == "harm") - if(req_defib && defib.safety) + if(!req_defib && !combat) + return + busy = 1 + H.visible_message("[user] has touched [H.name] with [src]!", \ + "[user] has touched [H.name] with [src]!") + H.adjustStaminaLoss(50) + H.Weaken(5) + H.updatehealth() //forces health update before next life tick + playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) + H.emote("gasp") + add_logs(user, M, "stunned", src) + if(req_defib) + defib.deductcharge(revivecost) + cooldown = 1 + busy = 0 + update_icon() + if(req_defib) + defib.cooldowncheck(user) + else + recharge(60) + return + + if(user.zone_selected != "chest") + user << "You need to target your patient's \ + chest with [src]!" + return + if(user.a_intent == "harm") + if(req_defib && defib.safety) + return + if(!req_defib && !combat) + return + user.visible_message("[user] begins to place [src] on [M.name]'s chest.", + "You overcharge the paddles and begin to place them onto [M]'s chest...") + busy = 1 + update_icon() + if(do_after(user, 30, target = M)) + user.visible_message("[user] places [src] on [M.name]'s chest.", + "You place [src] on [M.name]'s chest and begin to charge them.") + var/turf/T = get_turf(defib) + playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0) + if(req_defib) + T.audible_message("\The [defib] lets out an urgent beep and lets out a steadily rising hum...") + else + user.audible_message("[src] let out an urgent beep.") + if(do_after(user, 30, target = M)) //Takes longer due to overcharging + if(!M) + busy = 0 + update_icon() return - if(!req_defib && !combat) + if(M && M.stat == DEAD) + user << "[M] is dead." + playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) + busy = 0 + update_icon() return - user.visible_message("[user] begins to place [src] on [M.name]'s chest.", - "You overcharge the paddles and begin to place them onto [M]'s chest...") - busy = 1 - update_icon() - if(do_after(user, 30, target = M)) - user.visible_message("[user] places [src] on [M.name]'s chest.", - "You place [src] on [M.name]'s chest and begin to charge them.") - var/turf/T = get_turf(defib) - playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0) - if(req_defib) - T.audible_message("\The [defib] lets out an urgent beep and lets out a steadily rising hum...") - else - user.audible_message("[src] let out an urgent beep.") - if(do_after(user, 30, target = M)) //Takes longer due to overcharging - if(!M) - busy = 0 - update_icon() - return - if(M && M.stat == DEAD) - user << "[M] is dead." - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) - busy = 0 - update_icon() - return - user.visible_message("[user] shocks [M] with \the [src]!", "You shock [M] with \the [src]!") - playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 100, 1, -1) - playsound(loc, 'sound/weapons/Egloves.ogg', 100, 1, -1) - var/mob/living/carbon/human/HU = M - M.emote("scream") - if(!HU.heart_attack) - HU.heart_attack = 1 - if(!HU.stat) - HU.visible_message("[M] thrashes wildly, clutching at their chest!", - "You feel a horrible agony in your chest!") - HU.apply_damage(50, BURN, "chest") - add_logs(user, M, "overloaded the heart of", defib) - M.Weaken(5) - M.Jitter(100) - if(req_defib) - defib.deductcharge(revivecost) - cooldown = 1 - busy = 0 - update_icon() - if(!req_defib) - recharge(60) - if(req_defib && (defib.cooldowncheck(user))) - return + user.visible_message("[user] shocks [M] with \the [src]!", "You shock [M] with \the [src]!") + playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 100, 1, -1) + playsound(loc, 'sound/weapons/Egloves.ogg', 100, 1, -1) + var/mob/living/carbon/human/HU = M + M.emote("scream") + if(!HU.heart_attack) + HU.heart_attack = 1 + if(!HU.stat) + HU.visible_message("[M] thrashes wildly, clutching at their chest!", + "You feel a horrible agony in your chest!") + HU.apply_damage(50, BURN, "chest") + add_logs(user, M, "overloaded the heart of", defib) + M.Weaken(5) + M.Jitter(100) + if(req_defib) + defib.deductcharge(revivecost) + cooldown = 1 busy = 0 update_icon() - return - if(!H.suiciding && !(H.disabilities & NOCLONE)&& !H.hellbound) - H.notify_ghost_cloning("Your heart is being defibrillated. Re-enter your corpse if you want to be revived!", source = src) + if(!req_defib) + recharge(60) + if(req_defib && (defib.cooldowncheck(user))) + return + busy = 0 + update_icon() + return + if((!req_defib && grab_ghost) || (req_defib && defib.grab_ghost)) + H.notify_ghost_cloning("Your heart is being defibrillated!") + H.grab_ghost() // Shove them back in their body. + else if(!H.suiciding && !(H.disabilities & NOCLONE)&& !H.hellbound) + H.notify_ghost_cloning("Your heart is being defibrillated. Re-enter your corpse if you want to be revived!", source = src) - user.visible_message("[user] begins to place [src] on [M.name]'s chest.", "You begin to place [src] on [M.name]'s chest...") - busy = 1 - update_icon() - if(do_after(user, 30, target = M)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process - user.visible_message("[user] places [src] on [M.name]'s chest.", "You place [src] on [M.name]'s chest.") - playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0) - var/tplus = world.time - H.timeofdeath - var/tlimit = 1200 //past this much time the patient is unrecoverable (in deciseconds) - var/tloss = 600 //brain damage starts setting in on the patient after some time left rotting - var/total_burn = 0 - var/total_brute = 0 - if(do_after(user, 20, target = M)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total - for(var/obj/item/carried_item in H.contents) - if(istype(carried_item, /obj/item/clothing/suit/space)) - if((!src.combat && !req_defib) || (req_defib && !defib.combat)) - user.audible_message("[req_defib ? "[defib]" : "[src]"] buzzes: Patient's chest is obscured. Operation aborted.") - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) - busy = 0 - update_icon() - return - if(H.stat == DEAD) - M.visible_message("[M]'s body convulses a bit.") - playsound(get_turf(src), "bodyfall", 50, 1) - playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) - total_brute = H.getBruteLoss() - total_burn = H.getFireLoss() - - var/failed = null - - if (H.suiciding || (H.disabilities & NOCLONE)) - failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Recovery of patient impossible. Further attempts futile." - else if (H.hellbound) - failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's soul appears to be on another plane of existance. Further attempts futile." - else if (tplus > tlimit) - failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Body has decayed for too long. Further attempts futile." - else if (!H.getorgan(/obj/item/organ/heart)) - failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's heart is missing." - else if(total_burn >= 180 || total_brute >= 180) - failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Severe tissue damage makes recovery of patient impossible via defibrillator. Further attempts futile." - else if(H.get_ghost()) - failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - No activity in patient's brain. Further attempts may be successful." - else - var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain) - if(!BR || BR.damaged_brain) - failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain is missing or damaged beyond point of no return. Further attempts futile." - - if(failed) - user.visible_message(failed) - playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) - else - //If the body has been fixed so that they would not be in crit when defibbed, give them oxyloss to put them back into crit - if (H.health > halfwaycritdeath) - H.adjustOxyLoss(H.health - halfwaycritdeath, 0) - else - var/overall_damage = total_brute + total_burn + H.getToxLoss() + H.getOxyLoss() - var/mobhealth = H.health - H.adjustOxyLoss((mobhealth - halfwaycritdeath) * (H.getOxyLoss() / overall_damage), 0) - H.adjustToxLoss((mobhealth - halfwaycritdeath) * (H.getToxLoss() / overall_damage), 0) - H.adjustFireLoss((mobhealth - halfwaycritdeath) * (total_burn / overall_damage), 0) - H.adjustBruteLoss((mobhealth - halfwaycritdeath) * (total_brute / overall_damage), 0) - user.visible_message("[req_defib ? "[defib]" : "[src]"] pings: Resuscitation successful.") - playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0) - H.revive() - H.emote("gasp") - if(tplus > tloss) - H.setBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100)))) - add_logs(user, M, "revived", defib) - if(req_defib) - defib.deductcharge(revivecost) - cooldown = 1 - update_icon() - if(req_defib) - defib.cooldowncheck(user) - else - recharge(60) - else if(H.heart_attack) - H.heart_attack = 0 - user.visible_message("[req_defib ? "[defib]" : "[src]"] pings: Patient's heart is now beating again.") - playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) - else - user.visible_message("[req_defib ? "[defib]" : "[src]"] buzzes: Patient is not in a valid state. Operation aborted.") + user.visible_message("[user] begins to place [src] on [M.name]'s chest.", "You begin to place [src] on [M.name]'s chest...") + busy = 1 + update_icon() + if(do_after(user, 30, target = M)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process + user.visible_message("[user] places [src] on [M.name]'s chest.", "You place [src] on [M.name]'s chest.") + playsound(get_turf(src), 'sound/machines/defib_charge.ogg', 50, 0) + var/tplus = world.time - H.timeofdeath + // past this much time the patient is unrecoverable + // (in deciseconds) + var/tlimit = DEFIB_TIME_LIMIT * 10 + // brain damage starts setting in on the patient after + // some time left rotting + var/tloss = DEFIB_TIME_LOSS * 10 + var/total_burn = 0 + var/total_brute = 0 + if(do_after(user, 20, target = M)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total + for(var/obj/item/carried_item in H.contents) + if(istype(carried_item, /obj/item/clothing/suit/space)) + if((!src.combat && !req_defib) || (req_defib && !defib.combat)) + user.audible_message("[req_defib ? "[defib]" : "[src]"] buzzes: Patient's chest is obscured. Operation aborted.") playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) - busy = 0 - update_icon() - else - user << "You need to target your patient's chest with [src]!" - return + busy = 0 + update_icon() + return + if(H.stat == DEAD) + M.visible_message("[M]'s body convulses a bit.") + playsound(get_turf(src), "bodyfall", 50, 1) + playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) + total_brute = H.getBruteLoss() + total_burn = H.getFireLoss() + + var/failed = null + + if (H.suiciding || (H.disabilities & NOCLONE)) + failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Recovery of patient impossible. Further attempts futile." + else if (H.hellbound) + failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's soul appears to be on another plane of existance. Further attempts futile." + else if (tplus > tlimit) + failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Body has decayed for too long. Further attempts futile." + else if (!H.getorgan(/obj/item/organ/heart)) + failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's heart is missing." + else if(total_burn >= 180 || total_brute >= 180) + failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Severe tissue damage makes recovery of patient impossible via defibrillator. Further attempts futile." + else if(H.get_ghost()) + failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - No activity in patient's brain. Further attempts may be successful." + else + var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain) + if(!BR || BR.damaged_brain) + failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain is missing or damaged beyond point of no return. Further attempts futile." + + if(failed) + user.visible_message(failed) + playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) + else + //If the body has been fixed so that they would not be in crit when defibbed, give them oxyloss to put them back into crit + if (H.health > halfwaycritdeath) + H.adjustOxyLoss(H.health - halfwaycritdeath, 0) + else + var/overall_damage = total_brute + total_burn + H.getToxLoss() + H.getOxyLoss() + var/mobhealth = H.health + H.adjustOxyLoss((mobhealth - halfwaycritdeath) * (H.getOxyLoss() / overall_damage), 0) + H.adjustToxLoss((mobhealth - halfwaycritdeath) * (H.getToxLoss() / overall_damage), 0) + H.adjustFireLoss((mobhealth - halfwaycritdeath) * (total_burn / overall_damage), 0) + H.adjustBruteLoss((mobhealth - halfwaycritdeath) * (total_brute / overall_damage), 0) + user.visible_message("[req_defib ? "[defib]" : "[src]"] pings: Resuscitation successful.") + playsound(get_turf(src), 'sound/machines/defib_success.ogg', 50, 0) + H.revive() + H.emote("gasp") + if(tplus > tloss) + H.setBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100)))) + add_logs(user, M, "revived", defib) + if(req_defib) + defib.deductcharge(revivecost) + cooldown = 1 + update_icon() + if(req_defib) + defib.cooldowncheck(user) + else + recharge(60) + else if(H.heart_attack) + H.heart_attack = 0 + user.visible_message("[req_defib ? "[defib]" : "[src]"] pings: Patient's heart is now beating again.") + playsound(get_turf(src), 'sound/machines/defib_zap.ogg', 50, 1, -1) + else + user.visible_message("[req_defib ? "[defib]" : "[src]"] buzzes: Patient is not in a valid state. Operation aborted.") + playsound(get_turf(src), 'sound/machines/defib_failed.ogg', 50, 0) + busy = 0 + update_icon() /obj/item/weapon/twohanded/shockpaddles/syndicate name = "syndicate defibrillator paddles" diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index a04bb808579..2e077506d22 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1024,3 +1024,18 @@ Sorry Giacom. Please don't be mad :( for(var/datum/objective/sintouched/acedia/A in src.mind.objectives) return 1 return 0 + +// Called when we are hit by a bolt of polymorph and changed +// Generally the mob we are currently in, is about to be deleted +/mob/living/proc/wabbajack_act(mob/living/new_mob) + if(mind) + mind.transfer_to(new_mob) + else + new_mob.key = key + + for(var/para in hasparasites()) + var/mob/living/simple_animal/hostile/guardian/G = para + G.summoner = new_mob + G.Recall() + G << "Your summoner has changed \ + form to [new_mob]!" diff --git a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm index c6b108c951a..7c710cf6c8c 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm @@ -156,6 +156,13 @@ update_drone_icon() updateSeeStaticMobs() +/mob/living/simple_animal/drone/proc/liberate() + // F R E E D R O N E + laws = "1. You are a Free Drone." + src << laws + seeStatic = FALSE + updateSeeStaticMobs() + /mob/living/simple_animal/drone/proc/update_drone_icon() //Different icons for different hack states if(!hacked) diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index 5b0ed1aaa8d..7f67da0ad76 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -1,3 +1,8 @@ +var/list/slime_colours = list("rainbow", "grey", "purple", "metal", "orange", + "blue", "dark blue", "dark purple", "yellow", "silver", "pink", "red", + "gold", "green", "adamantine", "oil", "light pink", "bluespace", + "cerulean", "sepia", "black", "pyrite") + /mob/living/simple_animal/slime name = "baby slime" icon = 'icons/mob/slimes.dmi' @@ -16,7 +21,7 @@ response_disarm = "shoos" response_harm = "stomps on" emote_see = list("jiggles", "bounces in place") - speak_emote = list("chirps") + speak_emote = list("telepathically chirps") bubble_icon = "slime" layer = 5 @@ -83,19 +88,26 @@ var/datum/action/innate/slime/evolve/E = new E.Grant(src) create_reagents(100) - spawn (0) - number = rand(1, 1000) - name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])" - icon_state = "[colour] [is_adult ? "adult" : "baby"] slime" - icon_dead = "[icon_state] dead" - real_name = name - slime_mutation = mutation_table(colour) - var/sanitizedcolour = replacetext(colour, " ", "") - coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]") + spawn(0) + set_colour(colour) ..() +/mob/living/simple_animal/slime/proc/set_colour(new_colour) + colour = new_colour + + number = rand(1, 1000) + name = "[colour] [is_adult ? "adult" : "baby"] slime ([number])" + real_name = name + slime_mutation = mutation_table(colour) + var/sanitizedcolour = replacetext(colour, " ", "") + coretype = text2path("/obj/item/slime_extract/[sanitizedcolour]") + regenerate_icons() + +/mob/living/simple_animal/slime/proc/random_colour() + set_colour(pick(slime_colours)) + /mob/living/simple_animal/slime/regenerate_icons() - overlays.len = 0 + overlays.Cut() var/icon_text = "[colour] [is_adult ? "adult" : "baby"] slime" icon_dead = "[icon_text] dead" if(stat != DEAD) @@ -107,7 +119,7 @@ ..() /mob/living/simple_animal/slime/movement_delay() - if(bodytemperature >= 330.23) // 135 F + if(bodytemperature >= 330.23) // 135 F or 57.08 C return -1 // slimes become supercharged at high temperatures . = ..() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 5efb361452b..543a564c788 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -764,6 +764,10 @@ var/next_mob_id = 0 if(mind) return mind.get_ghost(even_if_they_cant_reenter) +/mob/proc/grab_ghost(force) + if(mind) + return mind.grab_ghost(force = force) + /mob/proc/notify_ghost_cloning(var/message = "Someone is trying to revive you. Re-enter your corpse if you want to be revived!", var/sound = 'sound/effects/genetics.ogg', var/atom/source = null) var/mob/dead/observer/ghost = get_ghost() if(ghost) diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index cbe4524c9f9..90b82a35c98 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -61,12 +61,9 @@ var/mob/living/carbon/C = target C.regenerate_limbs() if(target.revive(full_heal = 1)) - if(!target.ckey) - for(var/mob/dead/observer/ghost in player_list) - if(target.real_name == ghost.real_name) - ghost.reenter_corpse() - break - target << "You rise with a start, you're alive!!!" + target.grab_ghost(force = TRUE) // even suicides + target << "You rise with a start, \ + you're alive!!!" else if(target.stat != DEAD) target << "You feel great!" @@ -175,7 +172,7 @@ if("drone") new_mob = new /mob/living/simple_animal/drone(M.loc) var/mob/living/simple_animal/drone/D = new_mob - D.update_drone_hack() + D.liberate() // F R E E D R O N E if(issilicon(new_mob)) new_mob.gender = M.gender new_mob.invisibility = 0 @@ -186,9 +183,10 @@ new_mob.languages |= HUMAN if("slime") new_mob = new /mob/living/simple_animal/slime(M.loc) + var/mob/living/simple_animal/slime/slimey = new_mob if(prob(50)) - var/mob/living/simple_animal/slime/Slime = new_mob - Slime.is_adult = 1 + slimey.is_adult = 1 + slimey.random_colour() new_mob.languages |= HUMAN if("xeno") if(prob(50)) @@ -279,10 +277,8 @@ M.attack_log += text("\[[time_stamp()]\] [M.real_name] ([M.ckey]) became [new_mob.real_name].") new_mob.a_intent = "harm" - if(M.mind) - M.mind.transfer_to(new_mob) - else - new_mob.key = M.key + + M.wabbajack_act(new_mob) new_mob << "Your form morphs into that of a [randomize]." From d29af3a94b88f1d742f1ef311a03211ab813d1d1 Mon Sep 17 00:00:00 2001 From: Jack Edge Date: Sat, 21 May 2016 19:55:05 +0100 Subject: [PATCH 2/2] Independent blobbernauts --- code/game/gamemodes/blob/blobs/blob_mobs.dm | 10 +++++++++- code/modules/projectiles/projectile/magic.dm | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index e22248ff602..66bcfd61398 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -212,13 +212,17 @@ mob_size = MOB_SIZE_LARGE see_invisible = SEE_INVISIBLE_MINIMUM see_in_dark = 8 + var/independent = FALSE /mob/living/simple_animal/hostile/blob/blobbernaut/New() ..() - verbs -= /mob/living/verb/pulled //no pulling people deep into the blob + if(!independent) //no pulling people deep into the blob + verbs -= /mob/living/verb/pulled /mob/living/simple_animal/hostile/blob/blobbernaut/Life() if(..()) + if(independent) + return // strong independent blobbernaut that don't need no blob var/damagesources = 0 if(!(locate(/obj/effect/blob) in range(2, src))) damagesources++ @@ -271,3 +275,7 @@ factory.naut = null //remove this naut from its factory factory.maxhealth = initial(factory.maxhealth) flick("blobbernaut_death", src) + +/mob/living/simple_animal/hostile/blob/blobbernaut/independent + independent = TRUE + gold_core_spawnable = 1 diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 90b82a35c98..b0e825110af 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -218,7 +218,7 @@ if("spiderhunter") new_mob = new /mob/living/simple_animal/hostile/poison/giant_spider/hunter(M.loc) if("blobbernaut") - new_mob = new /mob/living/simple_animal/hostile/blob/blobbernaut(M.loc) + new_mob = new /mob/living/simple_animal/hostile/blob/blobbernaut/independent(M.loc) if("magicarp") new_mob = new /mob/living/simple_animal/hostile/carp/ranged(M.loc) if("chaosmagicarp")