From 79a814b43478684b0257f7c211dca12d32717839 Mon Sep 17 00:00:00 2001 From: phil235 Date: Sun, 18 Oct 2015 01:28:48 +0200 Subject: [PATCH] Fixes some runtimes when picking candidates for certain simple_animals, especially sentience potion. If the player chose 'Yes' and then immediately disconnected, it would make the chosen client null. Same thing for xeno larva bursting (player disconnection mid bursting animation) Fixes runtimes with chem grenade calling prime() after being GC'd. Fixes some hardsuits having "unacidable = 1" twice. Fixes runtime with alien whisper. Fixes runtime with check_shields() Fixes runtime with Venom, Formaldehyde, corn syrup and holy water. Fixes cult sacrifice soulstoning not working (giving a dead shade). --- code/game/gamemodes/cult/runes.dm | 3 + code/game/gamemodes/wizard/soulstone.dm | 83 ++++++++++--------- code/game/objects/effects/spiders.dm | 3 + .../items/weapons/grenades/chem_grenade.dm | 2 +- code/modules/clothing/spacesuits/hardsuit.dm | 3 - .../carbon/alien/humanoid/alien_powers.dm | 2 + .../carbon/alien/special/alien_embryo.dm | 22 +++-- .../mob/living/carbon/human/human_defense.dm | 2 +- .../Consumable-Reagents/Food-Reagents.dm | 4 +- .../Chemistry-Reagents/Other-Reagents.dm | 1 + .../Chemistry-Reagents/Toxin-Reagents.dm | 17 ++-- .../research/xenobiology/xenobiology.dm | 2 + 12 files changed, 80 insertions(+), 64 deletions(-) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 946b7490caa..76a6ee5f3f4 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -398,8 +398,11 @@ var/list/teleport_other_runes = list() M << "\"I accept this meager sacrifice.\"" if(T.mind) var/obj/item/device/soulstone/stone = new /obj/item/device/soulstone(get_turf(src)) + stone.invisibility = INVISIBILITY_MAXIMUM //so it's not picked up during transfer_soul() if(!stone.transfer_soul("FORCE", T, usr)) //If it cannot be added qdel(stone) + if(stone) + stone.invisibility = 0 if(!T) rune_in_use = 0 return diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index e19a6ae1100..3f9e30a536d 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -101,93 +101,88 @@ ////////////////////////////Proc for moving soul in and out off stone////////////////////////////////////// -/obj/item/device/soulstone/proc/transfer_soul(choice as text, target, mob/U). +/obj/item/device/soulstone/proc/transfer_soul(choice as text, target, mob/user). switch(choice) if("FORCE") if(!iscarbon(target)) //TO-DO: Add sacrifice stoning for non-organics, just because you have no body doesnt mean you dont have a soul return 0 + if(contents.len) + return 0 var/mob/living/carbon/T = target - var/obj/item/device/soulstone/C = src if(T.client != null) - if(C.contents.len) - return 0 - else - for(var/obj/item/W in T) - T.unEquip(W) - init_shade(C, T, U) + for(var/obj/item/W in T) + T.unEquip(W) + init_shade(src, T, user) return 1 else - U << "Capture failed!: The soul has already fled it's mortal frame. You attempt to bring it back..." - getCultGhost(C,T,U) - return 0 + user << "Capture failed!: The soul has already fled it's mortal frame. You attempt to bring it back..." + return getCultGhost(src,T,user) + if("VICTIM") var/mob/living/carbon/human/T = target - var/obj/item/device/soulstone/C = src if(ticker.mode.name == "cult" && T.mind == ticker.mode:sacrifice_target) - if(iscultist(U)) - U << "The Geometer of blood wants this mortal sacrificed with the rune." + if(iscultist(user)) + user << "The Geometer of blood wants this mortal sacrificed with the rune." else - U << "The soul stone doesn't work for no apparent reason." + user << "The soul stone doesn't work for no apparent reason." return 0 - if(C.imprinted != "empty") - U << "Capture failed!: The soul stone has already been imprinted with [C.imprinted]'s mind!" + if(imprinted != "empty") + user << "Capture failed!: The soul stone has already been imprinted with [imprinted]'s mind!" else if (T.stat == 0) - U << "Capture failed!: Kill or maim the victim first!" + user << "Capture failed!: Kill or maim the victim first!" else if(T.client == null) - U << "Capture failed!: The soul has already fled it's mortal frame. You attempt to bring it back..." - getCultGhost(C,T,U) + user << "Capture failed!: The soul has already fled it's mortal frame. You attempt to bring it back..." + getCultGhost(src,T,user) else - if(C.contents.len) - U << "Capture failed!: The soul stone is full! Use or free an existing soul to make room." + if(contents.len) + user << "Capture failed!: The soul stone is full! Use or free an existing soul to make room." else for(var/obj/item/W in T) T.unEquip(W) - init_shade(C, T, U, vic = 1) + init_shade(src, T, user, vic = 1) qdel(T) if("SHADE") var/mob/living/simple_animal/shade/T = target - var/obj/item/device/soulstone/C = src if (T.stat == DEAD) - U << "Capture failed!: The shade has already been banished!" + user << "Capture failed!: The shade has already been banished!" else - if(C.contents.len) - U << "Capture failed!: The soul stone is full! Use or free an existing soul to make room." + if(contents.len) + user << "Capture failed!: The soul stone is full! Use or free an existing soul to make room." else - if(T.name != C.imprinted) - U << "Capture failed!: The soul stone has already been imprinted with [C.imprinted]'s mind!" + if(T.name != imprinted) + user << "Capture failed!: The soul stone has already been imprinted with [imprinted]'s mind!" else - T.loc = C //put shade in stone + T.loc = src //put shade in stone T.status_flags |= GODMODE T.canmove = 0 T.health = T.maxHealth - C.icon_state = "soulstone2" + icon_state = "soulstone2" T << "Your soul has been recaptured by the soul stone, its arcane energies are reknitting your ethereal form" - if(U != T) - U << "Capture successful!: [T.name]'s has been recaptured and stored within the soul stone." + if(user != T) + user << "Capture successful!: [T.name]'s has been recaptured and stored within the soul stone." if("CONSTRUCT") var/obj/structure/constructshell/T = target - var/obj/item/device/soulstone/C = src - var/mob/living/simple_animal/shade/A = locate() in C + var/mob/living/simple_animal/shade/A = locate() in src if(A) - var/construct_class = alert(U, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer") + var/construct_class = alert(user, "Please choose which type of construct you wish to create.",,"Juggernaut","Wraith","Artificer") if(!T || !T.loc) return switch(construct_class) if("Juggernaut") - makeNewConstruct(/mob/living/simple_animal/construct/armored, A, U) + makeNewConstruct(/mob/living/simple_animal/construct/armored, A, user) if("Wraith") - makeNewConstruct(/mob/living/simple_animal/construct/wraith, A, U) + makeNewConstruct(/mob/living/simple_animal/construct/wraith, A, user) if("Artificer") - makeNewConstruct(/mob/living/simple_animal/construct/builder, A, U) + makeNewConstruct(/mob/living/simple_animal/construct/builder, A, user) qdel(T) - qdel(C) + qdel(src) else - U << "Creation failed!: The soul stone is empty! Go kill someone!" + user << "Creation failed!: The soul stone is empty! Go kill someone!" return @@ -261,6 +256,10 @@ sleep(50) + if(!T) //target mob got soulstoned or gibbed during sleep(50) + return 0 + listclearnulls(consenting_candidates) //some candidates might have left during sleep(50) + if(consenting_candidates.len) var/client/ghost = null ghost = pick(consenting_candidates) @@ -272,5 +271,7 @@ T.unEquip(W) init_shade(C, T, U) qdel(T) + return 1 else U << "The ghost has fled beyond your grasp." + return 0 diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 6815d522d29..b6b3866915c 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -219,6 +219,9 @@ if(!src) return + listclearnulls(consenting_candidates) //some candidates might have left during sleep(50) + + if(consenting_candidates.len) var/client/C = null C = pick(consenting_candidates) diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index a1e69bfb83e..7c43326ac03 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -156,7 +156,7 @@ nadeassembly.on_found(finder) /obj/item/weapon/grenade/chem_grenade/prime() - if(stage != READY) + if(stage != READY || !reagents) return var/has_reagents diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index 143d308367d..9c05314a0c6 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -274,8 +274,6 @@ armor = list(melee = 40, bullet = 40, laser = 40, energy = 20, bomb = 35, bio = 100, rad = 50) heat_protection = HEAD //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_HELM_MAX_TEMP_PROTECT - unacidable = 1 - /obj/item/clothing/suit/space/hardsuit/wizard icon_state = "hardsuit-wiz" @@ -289,7 +287,6 @@ allowed = list(/obj/item/weapon/teleportation_scroll,/obj/item/weapon/tank/internals) heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS //Uncomment to enable firesuit protection max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT - unacidable = 1 helmettype = /obj/item/clothing/head/helmet/space/hardsuit/wizard diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index 291b50f5681..a0c39c21c27 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -106,6 +106,8 @@ Doesn't work on other aliens/AI.*/ for(var/mob/living/Ms in oview(user)) options += Ms var/mob/living/M = input("Select who to whisper to:","Whisper to?",null) as null|mob in options + if(!M) + return 0 var/msg = sanitize(input("Message:", "Alien Whisper") as text|null) if(msg) log_say("AlienWhisper: [key_name(user)]->[M.key] : [msg]") diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm index bb7abd6f7f9..d3022d2f010 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -73,7 +73,7 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds // To stop clientless larva, we will check that our host has a client // if we find no ghosts to become the alien. If the host has a client // he will become the alien but if he doesn't then we will set the stage - // to 2, so we don't do a process heavy check everytime. + // to 4, so we don't do a process heavy check everytime. if(candidates.len) C = pick(candidates) @@ -85,16 +85,20 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds var/overlay = image('icons/mob/alien.dmi', loc = owner, icon_state = "burst_lie") owner.overlays += overlay - spawn(6) - var/atom/xeno_loc = owner - if(!gib_on_success) - xeno_loc = get_turf(xeno_loc) - var/mob/living/carbon/alien/larva/new_xeno = new(xeno_loc) - new_xeno.key = C.key - new_xeno << sound('sound/voice/hiss5.ogg',0,0,0,100) //To get the player's attention + var/atom/xeno_loc = get_turf(owner) + var/mob/living/carbon/alien/larva/new_xeno = new(xeno_loc) + new_xeno.key = C.key + new_xeno << sound('sound/voice/hiss5.ogg',0,0,0,100) //To get the player's attention + new_xeno.canmove = 0 //so we don't move during the bursting animation + new_xeno.notransform = 1 + new_xeno.invisibility = INVISIBILITY_MAXIMUM + spawn(6) + if(new_xeno) + new_xeno.canmove = 1 + new_xeno.notransform = 0 + new_xeno.invisibility = 0 if(gib_on_success) - owner.stomach_contents += new_xeno owner.gib() else owner.adjustBruteLoss(40) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 7734a6616ae..de99f7ed285 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -296,7 +296,7 @@ emp_act /mob/living/carbon/human/attack_animal(mob/living/simple_animal/M) if(..()) var/damage = rand(M.melee_damage_lower, M.melee_damage_upper) - if(check_shields(damage, "the [M.name]", "", "", M.armour_penetration)) + if(check_shields(damage, "the [M.name]", null, 0, M.armour_penetration)) return 0 var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg") var/obj/item/organ/limb/affecting = get_organ(ran_zone(dam_zone)) diff --git a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm index daf6892b53b..9f73634deea 100644 --- a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm @@ -429,8 +429,8 @@ id = "corn_syrup" description = "Decays into sugar." color = "#C8A5DC" + metabolization_rate = 3 * REAGENTS_METABOLISM /datum/reagent/consumable/corn_syrup/on_mob_life(mob/living/M) - M.reagents.add_reagent("sugar", 3) - M.reagents.remove_reagent("corn_syrup", 1) + holder.add_reagent("sugar", 3) ..() diff --git a/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm index c12c6be1f6d..019564bbb68 100644 --- a/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm @@ -188,6 +188,7 @@ M.jitteriness = 0 M.stuttering = 0 M.confused = 0 + return holder.remove_reagent(src.id, 0.4) //fixed consumption to prevent balancing going out of whack return diff --git a/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm index aaaaf09c20e..2fee0dd550b 100644 --- a/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm @@ -377,9 +377,10 @@ /datum/reagent/toxin/formaldehyde/on_mob_life(mob/living/M) if(prob(5)) - M.reagents.add_reagent("histamine",pick(5,15)) - M.reagents.remove_reagent("formaldehyde",1) - ..() + holder.add_reagent("histamine", pick(5,15)) + holder.remove_reagent("formaldehyde", 1.2) + else + ..() /datum/reagent/toxin/venom name = "Venom" @@ -394,9 +395,10 @@ toxpwr = 0.2*volume M.adjustBruteLoss((0.3*volume)*REM) if(prob(15)) - M.reagents.add_reagent("histamine",pick(5,10)) - M.reagents.remove_reagent("venom",1) - ..() + M.reagents.add_reagent("histamine", pick(5,10)) + M.reagents.remove_reagent("venom", 1.1) + else + ..() /datum/reagent/toxin/neurotoxin2 name = "Neurotoxin" @@ -467,7 +469,8 @@ M.adjustBruteLoss(0.2*REM) if(prob(3)) M.reagents.add_reagent("histamine",rand(1,3)) - M.reagents.remove_reagent("itching_powder",1) + M.reagents.remove_reagent("itching_powder",1.2) + return ..() /datum/reagent/toxin/initropidril diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index e82a394fd92..add78861908 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -204,6 +204,8 @@ if(!src) return + listclearnulls(consenting_candidates) //some candidates might have left during sleep(50) + if(consenting_candidates.len) var/client/C = null C = pick(consenting_candidates)