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 9c9f926a61f..3a1c8fa1094 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 155726e63aa..f05aad65d01 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -299,7 +299,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)