diff --git a/code/ZAS/FEA_gas_mixture.dm b/code/ZAS/FEA_gas_mixture.dm
index a4bdb022068..cea0efc3ab7 100644
--- a/code/ZAS/FEA_gas_mixture.dm
+++ b/code/ZAS/FEA_gas_mixture.dm
@@ -1007,6 +1007,18 @@ What are the archived variables for?
return 0
return 1
+/datum/gas_mixture/proc/compare_unsim(turf/list/samples)
+ //Purpose: Compares a list of unsimulated tiles to self to see if within acceptable ranges that group processing may be enabled
+ //Called by: ZAS sleeping detection.
+ //Inputs: List of unsimulated turfs to compare to
+ //Outputs: 1 if within an acceptable range to sleep, 0 otherwise.
+ var/datum/gas_mixture/after_share = new
+ after_share.copy_from(src)
+
+ ShareSpace(after_share, samples)
+
+ return src.compare(after_share)
+
/datum/gas_mixture/proc/subtract(datum/gas_mixture/right_side)
//Purpose: Subtracts right_side from air_mixture. Used to help turfs mingle
//Called by: Pipelines ending in a break (or something)
diff --git a/code/ZAS/ZAS_Turfs.dm b/code/ZAS/ZAS_Turfs.dm
index 7ba40ef715a..12ac2df2445 100644
--- a/code/ZAS/ZAS_Turfs.dm
+++ b/code/ZAS/ZAS_Turfs.dm
@@ -179,6 +179,8 @@
if((air_check_directions & direction && !(air_directions_archived & direction)) || \
(unsim_check_directions & direction && !(unsim_directions_archived & direction)))
ZConnect(src,T)
+ zone.ActivateIfNeeded()
+ if(T.zone) T.zone.ActivateIfNeeded()
//Something like a wall was built, changing the geometry.
else if((!(air_check_directions & direction) && air_directions_archived & direction) || \
diff --git a/code/ZAS/ZAS_Zones.dm b/code/ZAS/ZAS_Zones.dm
index 371be846a9c..b58cdd1903a 100644
--- a/code/ZAS/ZAS_Zones.dm
+++ b/code/ZAS/ZAS_Zones.dm
@@ -21,6 +21,7 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
var/last_rebuilt = 0
var/status = ZONE_ACTIVE
var/interactions_with_neighbors = 0
+ var/interactions_with_unsim = 0
var/progress = "nothing"
@@ -185,10 +186,14 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
unsimulated_tiles -= T
if(unsimulated_tiles.len)
+ var/old_pressure = air.return_pressure()
var/moved_air = ShareSpace(air,unsimulated_tiles)
if(moved_air > vsc.airflow_lightest_pressure)
AirflowSpace(src)
+
+ if(old_pressure && (moved_air / old_pressure) > MINIMUM_AIR_RATIO_TO_SUSPEND) //Check if we've moved enough air to be considered awake.
+ interactions_with_unsim++
else
unsimulated_tiles = null
@@ -305,10 +310,11 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
Z.interactions_with_neighbors++
interactions_with_neighbors++
- if(!interactions_with_neighbors && !unsimulated_tiles)
+ if(!interactions_with_neighbors && !interactions_with_unsim)
SetStatus(ZONE_SLEEPING)
interactions_with_neighbors = 0
+ interactions_with_unsim = 0
progress = "all components completed successfully, the problem is not here"
@@ -329,6 +335,28 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
/zone/proc/CheckStatus()
return status
+
+/zone/proc/ActivateIfNeeded()
+ if(status == ZONE_ACTIVE) return
+
+ var/difference = 0
+
+ if(unsimulated_tiles && unsimulated_tiles.len)
+ if(air.compare_unsim(unsimulated_tiles))
+ difference = 1
+
+ if(!difference)
+ for(var/zone/Z in connected_zones) //Check adjacent zones for air difference.
+ if(air.compare(Z.air))
+ difference = 1
+ break
+
+ if(difference) //We have a difference, activate the zone.
+ SetStatus(ZONE_ACTIVE)
+
+ return
+
+
/zone/proc/assume_air(var/datum/gas_mixture/giver)
if(status == ZONE_ACTIVE)
return air.merge(giver)
diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm
index 3ac34da573b..e66aed88b87 100644
--- a/code/game/gamemodes/changeling/changeling_powers.dm
+++ b/code/game/gamemodes/changeling/changeling_powers.dm
@@ -368,27 +368,26 @@
spawn(rand(800,2000))
if(changeling_power(20,1,100,DEAD))
+ // charge the changeling chemical cost for stasis
changeling.chem_charges -= 20
- if(C.stat == DEAD)
- dead_mob_list -= C
- living_mob_list += C
- C.stat = CONSCIOUS
- C.tod = null
- C.setToxLoss(0)
- C.setOxyLoss(0)
- C.setCloneLoss(0)
- C.SetParalysis(0)
- C.SetStunned(0)
- C.SetWeakened(0)
- C.radiation = 0
- C.heal_overall_damage(C.getBruteLoss(), C.getFireLoss())
- C.reagents.clear_reagents()
+
+ // restore us to health
+ C.rejuvenate()
+
+ // remove our fake death flag
+ C.status_flags &= ~(FAKEDEATH)
+
+ // let us move again
+ C.update_canmove()
+
+ // re-add out changeling powers
+ C.make_changeling()
+
+ // sending display messages
C << "We have regenerated."
C.visible_message("[src] appears to wake from the dead, having healed all wounds.")
-
- C.status_flags &= ~(FAKEDEATH)
- C.update_canmove()
- C.make_changeling()
+
+
feedback_add_details("changeling_powers","FD")
return 1
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index b4ba1064e18..81a4ea8ffb0 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -198,7 +198,7 @@
nextstate = CLOSED
- latetoggle()
+ proc/latetoggle()
if(operating || stat & NOPOWER || !nextstate)
return
switch(nextstate)
@@ -285,4 +285,4 @@
/obj/machinery/door/firedoor/multi_tile
icon = 'icons/obj/doors/DoorHazard2x1.dmi'
- width = 2
\ No newline at end of file
+ width = 2
diff --git a/code/game/mecha/combat/honker.dm b/code/game/mecha/combat/honker.dm
index 622d5bb8ef7..45159458a90 100644
--- a/code/game/mecha/combat/honker.dm
+++ b/code/game/mecha/combat/honker.dm
@@ -22,7 +22,7 @@
weapons += new /datum/mecha_weapon/honker(src)
weapons += new /datum/mecha_weapon/missile_rack/banana_mortar(src)
- weapons += new /datum/mecha_weapon/missile_rack/mousetrap_mortar(src)
+ weapons += new /datum/mecha_weapon/missile_rack/banana_mortar/mousetrap_mortar(src)
selected_weapon = weapons[1]
return
*/
diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm
index 6e924e13ebb..fdce02f5d2e 100644
--- a/code/game/mecha/combat/marauder.dm
+++ b/code/game/mecha/combat/marauder.dm
@@ -47,7 +47,7 @@
..()
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse
ME.attach(src)
- ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack
+ ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src)
ME.attach(src)
@@ -66,7 +66,7 @@
del(ME)
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot(src)
ME.attach(src)
- ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack(src)
+ ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive(src)
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/teleporter(src)
ME.attach(src)
diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm
index b461cd4b12b..192599073a6 100644
--- a/code/game/mecha/equipment/weapons/weapons.dm
+++ b/code/game/mecha/equipment/weapons/weapons.dm
@@ -2,41 +2,68 @@
name = "mecha weapon"
range = RANGED
origin_tech = "materials=3;combat=3"
- var/projectile
- var/fire_sound
-
+ var/projectile //Type of projectile fired.
+ var/projectiles = 1 //Amount of projectiles loaded.
+ var/projectiles_per_shot = 1 //Amount of projectiles fired per single shot.
+ var/deviation = 0 //Inaccuracy of shots.
+ var/fire_cooldown = 0 //Duration of sleep between firing projectiles in single shot.
+ var/fire_sound //Sound played while firing.
+ var/fire_volume = 50 //How loud it is played.
+ var/auto_rearm = 0 //Does the weapon reload itself after each shot?
/obj/item/mecha_parts/mecha_equipment/weapon/can_attach(var/obj/mecha/combat/M as obj)
- if(..())
- if(istype(M))
- return 1
- return 0
+ if(!istype(M))
+ return 0
+ return ..()
+/obj/item/mecha_parts/mecha_equipment/weapon/action_checks(atom/target)
+ if(projectiles <= 0)
+ return 0
+ return ..()
+
+/obj/item/mecha_parts/mecha_equipment/weapon/action(atom/target)
+ if(!action_checks(target))
+ return
+ var/turf/curloc = chassis.loc
+ var/turf/targloc = get_turf(target)
+ if(!curloc || !targloc)
+ return
+ chassis.use_power(energy_drain)
+ chassis.visible_message("[chassis] fires [src]!")
+ occupant_message("You fire [src]!")
+ log_message("Fired from [src], targeting [target].")
+ for(var/i = 1 to min(projectiles, projectiles_per_shot))
+ var/turf/aimloc = targloc
+ if(deviation)
+ aimloc = locate(targloc.x+GaussRandRound(deviation,1),targloc.y+GaussRandRound(deviation,1),targloc.z)
+ if(!aimloc || aimloc == curloc)
+ break
+ playsound(chassis, fire_sound, fire_volume, 1)
+ projectiles--
+ var/P = new projectile(curloc)
+ Fire(P, target, aimloc)
+ if(fire_cooldown)
+ sleep(fire_cooldown)
+ if(auto_rearm)
+ projectiles = projectiles_per_shot
+ set_ready_state(0)
+ do_after_cooldown()
+ return
+
+/obj/item/mecha_parts/mecha_equipment/weapon/proc/Fire(atom/A, atom/target, turf/aimloc)
+ var/obj/item/projectile/P = A
+ P.shot_from = src
+ P.original = target
+ P.starting = P.loc
+ P.current = P.loc
+ P.firer = chassis.occupant
+ P.yo = aimloc.y - P.loc.y
+ P.xo = aimloc.x - P.loc.x
+ P.process()
/obj/item/mecha_parts/mecha_equipment/weapon/energy
name = "General Energy Weapon"
-
- action(target)
- if(!action_checks(target)) return
- var/turf/curloc = chassis.loc
- var/atom/targloc = get_turf(target)
- if (!targloc || !istype(targloc, /turf) || !curloc)
- return
- if (targloc == curloc)
- return
- set_ready_state(0)
- playsound(chassis, fire_sound, 50, 1)
- var/obj/item/projectile/A = new projectile(curloc)
- A.original = target
- A.current = curloc
- A.yo = targloc.y - curloc.y
- A.xo = targloc.x - curloc.x
- chassis.use_power(energy_drain)
- A.process()
- chassis.log_message("Fired from [src.name], targeting [target].")
- do_after_cooldown()
- return
-
+ auto_rearm = 1
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser
equip_cooldown = 8
@@ -104,10 +131,9 @@
construction_cost = list("metal"=20000,"bananium"=10000)
can_attach(obj/mecha/combat/honker/M as obj)
- if(..())
- if(istype(M))
- return 1
- return 0
+ if(!istype(M))
+ return 0
+ return ..()
action(target)
if(!chassis)
@@ -152,15 +178,8 @@
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic
name = "General Ballisic Weapon"
- var/projectiles
var/projectile_energy_cost
- action_checks(atom/target)
- if(..())
- if(projectiles > 0)
- return 1
- return 0
-
get_equip_info()
return "[..()]\[[src.projectiles]\][(src.projectiles < initial(src.projectiles))?" - Rearm":null]"
@@ -188,38 +207,11 @@
equip_cooldown = 20
projectile = /obj/item/projectile/bullet/midbullet
fire_sound = 'sound/weapons/Gunshot.ogg'
+ fire_volume = 80
projectiles = 40
+ projectiles_per_shot = 4
+ deviation = 0.7
projectile_energy_cost = 25
- var/projectiles_per_shot = 4
- var/deviation = 0.7
-
- action(atom/target)
- if(!action_checks(target)) return
- var/turf/curloc = get_turf(chassis)
- var/turf/targloc = get_turf(target)
- if(!curloc || !targloc) return
- var/target_x = targloc.x
- var/target_y = targloc.y
- var/target_z = targloc.z
- targloc = null
- for(var/i=1 to min(projectiles, projectiles_per_shot))
- targloc = locate(target_x+GaussRandRound(deviation,1),target_y+GaussRandRound(deviation,1),target_z)
- if(!targloc || targloc == curloc)
- break
- playsound(chassis, fire_sound, 80, 1)
- var/obj/item/projectile/A = new projectile(curloc)
- src.projectiles--
- A.original = target
- A.current = curloc
- A.yo = targloc.y - curloc.y
- A.xo = targloc.x - curloc.x
- set_ready_state(0)
- A.process()
- log_message("Fired from [src.name], targeting [target].")
- do_after_cooldown()
- return
-
-
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg
name = "Ultra AC 2"
@@ -228,41 +220,19 @@
projectile = /obj/item/projectile/bullet/weakbullet
fire_sound = 'sound/weapons/Gunshot.ogg'
projectiles = 300
+ projectiles_per_shot = 3
+ deviation = 0.3
projectile_energy_cost = 20
- var/projectiles_per_shot = 3
- var/deviation = 0.3
-
- action(atom/target)
- if(!action_checks(target)) return
- var/turf/targloc = get_turf(target)
- var/target_x = targloc.x
- var/target_y = targloc.y
- var/target_z = targloc.z
- targloc = null
- spawn for(var/i=1 to min(projectiles, projectiles_per_shot))
- if(!chassis) break
- var/turf/curloc = get_turf(chassis)
- targloc = locate(target_x+GaussRandRound(deviation,1),target_y+GaussRandRound(deviation,1),target_z)
- if (!targloc || !curloc)
- continue
- if (targloc == curloc)
- continue
-
- playsound(chassis, fire_sound, 50, 1)
- var/obj/item/projectile/A = new projectile(curloc)
- src.projectiles--
- A.original = target
- A.current = curloc
- A.yo = targloc.y - curloc.y
- A.xo = targloc.x - curloc.x
- A.process()
- sleep(2)
- set_ready_state(0)
- log_message("Fired from [src.name], targeting [target].")
- do_after_cooldown()
- return
+ fire_cooldown = 2
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack
+ var/missile_speed = 2
+ var/missile_range = 30
+
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/Fire(atom/movable/AM, atom/target, turf/aimloc)
+ AM.throw_at(target,missile_range, missile_speed)
+
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive
name = "SRM-8 Missile Rack"
icon_state = "mecha_missilerack"
projectile = /obj/item/missile
@@ -270,21 +240,11 @@
projectiles = 8
projectile_energy_cost = 1000
equip_cooldown = 60
- var/missile_speed = 2
- var/missile_range = 30
-
- action(target)
- if(!action_checks(target)) return
- set_ready_state(0)
- var/obj/item/missile/M = new projectile(chassis.loc)
- M.primed = 1
- playsound(chassis, fire_sound, 50, 1)
- M.throw_at(target, missile_range, missile_speed)
- projectiles--
- log_message("Fired from [src.name], targeting [target].")
- do_after_cooldown()
- return
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive/Fire(atom/movable/AM, atom/target, turf/aimloc)
+ var/obj/item/missile/M = AM
+ M.primed = 1
+ ..()
/obj/item/missile
icon = 'icons/obj/grenade.dmi'
@@ -311,18 +271,11 @@
equip_cooldown = 60
var/det_time = 20
- action(target)
- if(!action_checks(target)) return
- set_ready_state(0)
- var/obj/item/weapon/grenade/flashbang/F = new projectile(chassis.loc)
- playsound(chassis, fire_sound, 50, 1)
- F.throw_at(target, missile_range, missile_speed)
- projectiles--
- log_message("Fired from [src.name], targeting [target].")
- spawn(det_time)
- F.prime()
- do_after_cooldown()
- return
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang/Fire(atom/movable/AM, atom/target, turf/aimloc)
+ ..()
+ var/obj/item/weapon/grenade/flashbang/F = AM
+ spawn(det_time)
+ F.prime()
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang/clusterbang//Because I am a heartless bastard -Sieve
name = "SOP-6 Grenade Launcher"
@@ -348,49 +301,17 @@
construction_cost = list("metal"=20000,"bananium"=5000)
can_attach(obj/mecha/combat/honker/M as obj)
- if(..())
- if(istype(M))
- return 1
- return 0
+ if(!istype(M))
+ return 0
+ return ..()
- action(target)
- if(!action_checks(target)) return
- set_ready_state(0)
- var/obj/item/weapon/bananapeel/B = new projectile(chassis.loc)
- playsound(chassis, fire_sound, 60, 1)
- B.throw_at(target, missile_range, missile_speed)
- projectiles--
- log_message("Bananed from [src.name], targeting [target]. HONK!")
- do_after_cooldown()
- return
-
-
-/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/mousetrap_mortar
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/banana_mortar/mousetrap_mortar
name = "Mousetrap Mortar"
icon_state = "mecha_mousetrapmrtr"
projectile = /obj/item/device/assembly/mousetrap
- fire_sound = 'sound/items/bikehorn.ogg'
- projectiles = 15
- missile_speed = 1.5
- projectile_energy_cost = 100
equip_cooldown = 10
- construction_time = 300
- construction_cost = list("metal"=20000,"bananium"=5000)
- can_attach(obj/mecha/combat/honker/M as obj)
- if(..())
- if(istype(M))
- return 1
- return 0
-
- action(target)
- if(!action_checks(target)) return
- set_ready_state(0)
- var/obj/item/device/assembly/mousetrap/M = new projectile(chassis.loc)
- M.secured = 1
- playsound(chassis, fire_sound, 60, 1)
- M.throw_at(target, missile_range, missile_speed)
- projectiles--
- log_message("Launched a mouse-trap from [src.name], targeting [target]. HONK!")
- do_after_cooldown()
- return
\ No newline at end of file
+/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/banana_mortar/mousetrap_mortar/Fire(atom/movable/AM, atom/target, turf/aimloc)
+ var/obj/item/device/assembly/mousetrap/M = AM
+ M.secured = 1
+ ..()
\ No newline at end of file
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index 7b72a5597bf..9e9e578ecf1 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -112,7 +112,7 @@
///obj/item/mecha_parts/mecha_equipment/jetpack, //TODO MECHA JETPACK SPRITE MISSING
/obj/item/mecha_parts/mecha_equipment/weapon/energy/taser,
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg,
- ///obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/mousetrap_mortar, HONK-related mech part
+ ///obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/banana_mortar/mousetrap_mortar, HONK-related mech part
///obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/banana_mortar, Also HONK-related
///obj/item/mecha_parts/mecha_equipment/weapon/honker Thirdly HONK-related
),
diff --git a/code/game/mecha/mecha_parts.dm b/code/game/mecha/mecha_parts.dm
index 9d8c0696b29..2db25119fb3 100644
--- a/code/game/mecha/mecha_parts.dm
+++ b/code/game/mecha/mecha_parts.dm
@@ -6,7 +6,7 @@
name = "mecha part"
icon = 'icons/mecha/mech_construct.dmi'
icon_state = "blank"
- w_class = 20
+ w_class = 5
flags = FPRINT | TABLEPASS | CONDUCT
origin_tech = "programming=2;materials=2"
var/construction_time = 100
diff --git a/code/game/mecha/medical/medical.dm b/code/game/mecha/medical/medical.dm
index a63a8d3d6dd..0b94990cd2f 100644
--- a/code/game/mecha/medical/medical.dm
+++ b/code/game/mecha/medical/medical.dm
@@ -1,6 +1,8 @@
/obj/mecha/medical/New()
..()
- new /obj/item/mecha_parts/mecha_tracking(src)
+ var/turf/T = get_turf(src)
+ if(T.z != 2)
+ new /obj/item/mecha_parts/mecha_tracking(src)
return
diff --git a/code/game/mecha/working/working.dm b/code/game/mecha/working/working.dm
index 7a59b6190ed..ad66d310321 100644
--- a/code/game/mecha/working/working.dm
+++ b/code/game/mecha/working/working.dm
@@ -3,7 +3,9 @@
/obj/mecha/working/New()
..()
- new /obj/item/mecha_parts/mecha_tracking(src)
+ var/turf/T = get_turf(src)
+ if(T.z != 2)
+ new /obj/item/mecha_parts/mecha_tracking(src)
return
/*
diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm
index 6fb0ab4cc9a..cd0b988bea7 100644
--- a/code/game/objects/items/weapons/storage/fancy.dm
+++ b/code/game/objects/items/weapons/storage/fancy.dm
@@ -27,6 +27,7 @@
/obj/item/weapon/storage/fancy/examine()
set src in oview(1)
+ ..()
if(contents.len <= 0)
usr << "There are no [src.icon_type]s left in the box."
else if(contents.len == 1)
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 00129e936fa..3c76e6753dd 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -313,9 +313,6 @@ BLIND // can't see anything
if(usr.stat) return
if(hastie)
- usr.put_in_hands(hastie)
- hastie = null
-
if (istype(hastie,/obj/item/clothing/tie/holster))
verbs -= /obj/item/clothing/under/proc/holster
@@ -323,7 +320,10 @@ BLIND // can't see anything
verbs -= /obj/item/clothing/under/proc/storage
var/obj/item/clothing/tie/storage/W = hastie
if (W.hold)
- W.hold.loc = hastie
+ W.hold.close(usr)
+
+ usr.put_in_hands(hastie)
+ hastie = null
if(istype(loc, /mob/living/carbon/human))
var/mob/living/carbon/human/H = loc
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 6cf4a99b6b6..ae544c43d54 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -74,7 +74,7 @@ Works together with spawning an observer, noted above.
if(key)
var/mob/dead/observer/ghost = new(src) //Transfer safety to observer spawning proc.
ghost.can_reenter_corpse = can_reenter_corpse
- ghost.timeofdeath = timeofdeath //BS12 EDIT
+ ghost.timeofdeath = src.timeofdeath //BS12 EDIT
ghost.key = key
return ghost
@@ -89,10 +89,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(stat == DEAD)
ghostize(1)
else
- var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you may not play again this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
+ var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost, you won't be able to play this round for another 30 minutes! You can't change your mind so choose wisely!)","Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost") return //didn't want to ghost after-all
resting = 1
- ghostize(0) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
+ var/mob/dead/observer/ghost = ghostize(0) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
+ ghost.timeofdeath = world.time // Because the living mob won't have a time of death and we want the respawn timer to work properly.
return
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index f281015f757..4ca6efea54c 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -174,6 +174,21 @@
////////////////////////////////////////////
+/*
+This function restores the subjects blood to max.
+*/
+/mob/living/carbon/human/proc/restore_blood()
+ var/blood_volume = vessel.get_reagent_amount("blood")
+ vessel.add_reagent("blood",560.0-blood_volume)
+
+
+/*
+This function restores all organs.
+*/
+/mob/living/carbon/human/restore_all_organs()
+ for(var/datum/organ/external/current_organ in organs)
+ current_organ.rejuvenate()
+
/mob/living/carbon/human/proc/HealDamage(zone, brute, burn)
var/datum/organ/external/E = get_organ(zone)
if(istype(E, /datum/organ/external))
diff --git a/code/modules/mob/living/carbon/monkey/diona.dm b/code/modules/mob/living/carbon/monkey/diona.dm
index 7846965a6d3..3780cdb6836 100644
--- a/code/modules/mob/living/carbon/monkey/diona.dm
+++ b/code/modules/mob/living/carbon/monkey/diona.dm
@@ -93,7 +93,7 @@
set desc = "Take a blood sample from a suitable donor."
var/list/choices = list()
- for(var/mob/living/C in view(1,src))
+ for(var/mob/living/carbon/C in view(1,src))
if(C.real_name != real_name)
choices += C
diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm
index 552f5014e09..d7add5b0888 100644
--- a/code/modules/mob/living/carbon/monkey/monkey.dm
+++ b/code/modules/mob/living/carbon/monkey/monkey.dm
@@ -39,7 +39,7 @@
reagents = R
R.my_atom = src
- if(name == "monkey" || name == "farwa" || name == "stok" || name == "neara" || name == "diona nymph") //Hideous but necessary to stop Pun-Pun becoming generic.
+ if(name == initial(name)) //To stop Pun-Pun becoming generic.
name = "[name] ([rand(1, 1000)])"
real_name = name
diff --git a/code/modules/mob/living/carbon/species.dm b/code/modules/mob/living/carbon/species.dm
index 1c26c0051bd..76ab17fbd47 100644
--- a/code/modules/mob/living/carbon/species.dm
+++ b/code/modules/mob/living/carbon/species.dm
@@ -39,6 +39,7 @@
/datum/species/human
name = "Human"
+ language = "Sol Common"
primitive = /mob/living/carbon/monkey
flags = HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 134cd56c43e..8305766568a 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -246,7 +246,21 @@
adjustFireLoss(burn)
src.updatehealth()
+/mob/living/proc/restore_all_organs()
+ return
+
+
+
/mob/living/proc/revive()
+ rejuvenate()
+ buckled = initial(src.buckled)
+ if(iscarbon(src))
+ var/mob/living/carbon/C = src
+ C.handcuffed = initial(C.handcuffed)
+
+/mob/living/proc/rejuvenate()
+
+ // shut down various types of badness
setToxLoss(0)
setOxyLoss(0)
setCloneLoss(0)
@@ -254,30 +268,43 @@
SetParalysis(0)
SetStunned(0)
SetWeakened(0)
+
+ // shut down ongoing problems
radiation = 0
nutrition = 400
- bodytemperature = 310
+ bodytemperature = T20C
sdisabilities = 0
disabilities = 0
+
+ // fix blindness and deafness
blinded = 0
eye_blind = 0
eye_blurry = 0
eye_stat = 0
ear_deaf = 0
ear_damage = 0
- heal_overall_damage(1000, 1000)
- buckled = initial(src.buckled)
- if(iscarbon(src))
- var/mob/living/carbon/C = src
- C.handcuffed = initial(C.handcuffed)
- for(var/datum/disease/D in viruses)
- D.cure(0)
+ heal_overall_damage(getBruteLoss(), getFireLoss())
+
+ // restore all of a human's blood
+ if(ishuman(src))
+ var/mob/living/carbon/human/human_mob = src
+ human_mob.restore_blood()
+
+ // fix all of our organs
+ restore_all_organs()
+
+ // remove the character from the list of the dead
if(stat == 2)
dead_mob_list -= src
living_mob_list += src
+ tod = null
+
+ // restore us to conciousness
stat = CONSCIOUS
+
+ // make the icons look correct
regenerate_icons()
- ..()
+
return
/mob/living/proc/UpdateDamageIcon()
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index a0bf7f2ed31..77b4dbd884d 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -119,6 +119,7 @@
var/obj/O = locate("landmark*Observer-Start")
src << "\blue Now teleporting."
observer.loc = O.loc
+ observer.timeofdeath = world.time // Set the time of death so that the respawn timer works correctly.
client.prefs.update_preview_icon()
observer.icon = client.prefs.preview_icon
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index d7d6fe3398e..bbf17280840 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -181,8 +181,31 @@
var/result = update_icon()
return result
-
-
+
+/*
+This function completely restores a damaged organ to perfect condition.
+*/
+/datum/organ/external/proc/rejuvenate()
+ damage_state = "00"
+ status = 0
+ perma_injury = 0
+ brute_dam = 0
+ burn_dam = 0
+
+ // handle internal organs
+ for(var/datum/organ/internal/current_organ in internal_organs)
+ current_organ.rejuvenate()
+
+ // remove embedded objects and drop them on the floor
+ for(var/obj/implanted_object in implants)
+ if(!istype(implanted_object,/obj/item/weapon/implant)) // We don't want to remove REAL implants. Just shrapnel etc.
+ implanted_object.loc = owner.loc
+ implants -= implanted_object
+
+ owner.updatehealth()
+ update_icon()
+
+
/datum/organ/external/proc/createwound(var/type = CUT, var/damage)
if(damage == 0) return
diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm
index a3b1d59fe42..43d0a180d88 100644
--- a/code/modules/organs/organ_internal.dm
+++ b/code/modules/organs/organ_internal.dm
@@ -11,6 +11,9 @@
var/min_broken_damage = 30
var/parent_organ = "chest"
+/datum/organ/internal/proc/rejuvenate()
+ damage=0
+
/datum/organ/internal/proc/is_bruised()
return damage >= min_bruised_damage
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index 439bf62baf1..66cbc91419a 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -16,7 +16,7 @@
pressure_resistance = 1
slot_flags = SLOT_HEAD
body_parts_covered = HEAD
- attack_verb = list("")
+ attack_verb = list("bapped")
var/info //What's actually written on the paper.
var/info_links //A different version of the paper which includes html links at fields and EOF
diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm
index f513c83da33..3024ea1aa41 100644
--- a/code/modules/projectiles/projectile/beams.dm
+++ b/code/modules/projectiles/projectile/beams.dm
@@ -71,13 +71,13 @@ var/list/beam_master = list()
..()
proc/cleanup(reference) //Waits .3 seconds then removes the overlay.
- src = null
- sleep(3)
- var/list/turf_master = beam_master[reference]
- for(var/laser_state in turf_master)
- var/list/turfs = turf_master[laser_state]
- for(var/turf/T in turfs)
- T.overlays -= beam_master[laser_state]
+ src = null //we're getting deleted! this will keep the code running
+ spawn(3)
+ var/list/turf_master = beam_master[reference]
+ for(var/laser_state in turf_master)
+ var/list/turfs = turf_master[laser_state]
+ for(var/turf/T in turfs)
+ T.overlays -= beam_master[laser_state]
return
/obj/item/projectile/beam/practice
diff --git a/code/modules/surgery/braincore.dm b/code/modules/surgery/braincore.dm
index f4d81d37f59..c95904dcd7c 100644
--- a/code/modules/surgery/braincore.dm
+++ b/code/modules/surgery/braincore.dm
@@ -122,8 +122,8 @@
return ..() && target.brain_op_stage == 2
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("[user] starts taking out bone chips and out of [target]'s brain with \the [tool].", \
- "You start taking out bone chips and out of [target]'s brain with \the [tool].")
+ user.visible_message("[user] starts taking out bone chips out of [target]'s brain with \the [tool].", \
+ "You start taking out bone chips out of [target]'s brain with \the [tool].")
..()
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi
index 2a5ac9f9d6d..eeedc960747 100644
Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ