Merge remote-tracking branch 'upstream/dev' into emergency-shuttle

Conflicts:
	code/setup.dm
This commit is contained in:
mwerezak
2014-06-24 00:09:17 -04:00
157 changed files with 3337 additions and 1664 deletions

View File

@@ -139,7 +139,6 @@
#include "code\datums\diseases\advance\symptoms\weight.dm" #include "code\datums\diseases\advance\symptoms\weight.dm"
#include "code\datums\helper_datums\construction_datum.dm" #include "code\datums\helper_datums\construction_datum.dm"
#include "code\datums\helper_datums\events.dm" #include "code\datums\helper_datums\events.dm"
#include "code\datums\helper_datums\getrev.dm"
#include "code\datums\helper_datums\global_iterator.dm" #include "code\datums\helper_datums\global_iterator.dm"
#include "code\datums\helper_datums\teleport.dm" #include "code\datums\helper_datums\teleport.dm"
#include "code\datums\helper_datums\topic_input.dm" #include "code\datums\helper_datums\topic_input.dm"
@@ -488,6 +487,7 @@
#include "code\game\objects\items\devices\pipe_painter.dm" #include "code\game\objects\items\devices\pipe_painter.dm"
#include "code\game\objects\items\devices\powersink.dm" #include "code\game\objects\items\devices\powersink.dm"
#include "code\game\objects\items\devices\scanners.dm" #include "code\game\objects\items\devices\scanners.dm"
#include "code\game\objects\items\devices\suit_cooling.dm"
#include "code\game\objects\items\devices\taperecorder.dm" #include "code\game\objects\items\devices\taperecorder.dm"
#include "code\game\objects\items\devices\traitordevices.dm" #include "code\game\objects\items\devices\traitordevices.dm"
#include "code\game\objects\items\devices\transfer_valve.dm" #include "code\game\objects\items\devices\transfer_valve.dm"
@@ -1215,6 +1215,7 @@
#include "code\modules\research\xenoarchaeology\chemistry.dm" #include "code\modules\research\xenoarchaeology\chemistry.dm"
#include "code\modules\research\xenoarchaeology\geosample.dm" #include "code\modules\research\xenoarchaeology\geosample.dm"
#include "code\modules\research\xenoarchaeology\manuals.dm" #include "code\modules\research\xenoarchaeology\manuals.dm"
#include "code\modules\research\xenoarchaeology\master_controller.dm"
#include "code\modules\research\xenoarchaeology\misc.dm" #include "code\modules\research\xenoarchaeology\misc.dm"
#include "code\modules\research\xenoarchaeology\artifact\artifact.dm" #include "code\modules\research\xenoarchaeology\artifact\artifact.dm"
#include "code\modules\research\xenoarchaeology\artifact\artifact_autocloner.dm" #include "code\modules\research\xenoarchaeology\artifact\artifact_autocloner.dm"
@@ -1250,7 +1251,11 @@
#include "code\modules\research\xenoarchaeology\finds\finds_defines.dm" #include "code\modules\research\xenoarchaeology\finds\finds_defines.dm"
#include "code\modules\research\xenoarchaeology\finds\finds_fossils.dm" #include "code\modules\research\xenoarchaeology\finds\finds_fossils.dm"
#include "code\modules\research\xenoarchaeology\finds\finds_misc.dm" #include "code\modules\research\xenoarchaeology\finds\finds_misc.dm"
#include "code\modules\research\xenoarchaeology\finds\finds_special.dm"
#include "code\modules\research\xenoarchaeology\finds\finds_talkingitem.dm" #include "code\modules\research\xenoarchaeology\finds\finds_talkingitem.dm"
#include "code\modules\research\xenoarchaeology\genetics\prehistoric_animals.dm"
#include "code\modules\research\xenoarchaeology\genetics\prehistoric_plants.dm"
#include "code\modules\research\xenoarchaeology\genetics\reconstitutor.dm"
#include "code\modules\research\xenoarchaeology\machinery\artifact_analyser.dm" #include "code\modules\research\xenoarchaeology\machinery\artifact_analyser.dm"
#include "code\modules\research\xenoarchaeology\machinery\artifact_harvester.dm" #include "code\modules\research\xenoarchaeology\machinery\artifact_harvester.dm"
#include "code\modules\research\xenoarchaeology\machinery\artifact_scanner.dm" #include "code\modules\research\xenoarchaeology\machinery\artifact_scanner.dm"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 70 KiB

View File

@@ -227,7 +227,7 @@ Alien plants should do something if theres a lot of poison
del(src) del(src)
/obj/effect/alien/flesh/weeds/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/effect/alien/flesh/weeds/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300) if(exposed_temperature > 300)
health -= 5 health -= 5
healthcheck() healthcheck()

View File

@@ -259,6 +259,7 @@
if(4) if(4)
if(pa.Find("left")) if(pa.Find("left"))
if(istype(object, /atom/movable))
holder.throw_atom = object holder.throw_atom = object
if(pa.Find("right")) if(pa.Find("right"))
if(holder.throw_atom) if(holder.throw_atom)

View File

@@ -50,7 +50,7 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
icon = 'icons/effects/fire.dmi' icon = 'icons/effects/fire.dmi'
icon_state = "1" icon_state = "1"
l_color = "#ED9200"
layer = TURF_LAYER layer = TURF_LAYER
var/firelevel = 10000 //Calculated by gas_mixture.calculate_firelevel() var/firelevel = 10000 //Calculated by gas_mixture.calculate_firelevel()
@@ -84,7 +84,7 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
air_contents.trace_gases.Remove(fuel) air_contents.trace_gases.Remove(fuel)
//check if there is something to combust //check if there is something to combust
if(!air_contents.check_recombustability(liquid)) if(!air_contents.check_combustability(liquid))
//del src //del src
RemoveFire() RemoveFire()
@@ -116,7 +116,7 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
var/datum/gas_mixture/acs = enemy_tile.return_air() var/datum/gas_mixture/acs = enemy_tile.return_air()
var/obj/effect/decal/cleanable/liquid_fuel/liq = locate() in enemy_tile var/obj/effect/decal/cleanable/liquid_fuel/liq = locate() in enemy_tile
if(!acs) continue if(!acs) continue
if(!acs.check_recombustability(liq)) continue if(!acs.check_combustability(liq)) continue
//If extinguisher mist passed over the turf it's trying to spread to, don't spread and //If extinguisher mist passed over the turf it's trying to spread to, don't spread and
//reduce firelevel. //reduce firelevel.
if(enemy_tile.fire_protection > world.time-30) if(enemy_tile.fire_protection > world.time-30)
@@ -134,15 +134,7 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
///////////////////////////////// FLOW HAS BEEN CREATED /// DONT DELETE THE FIRE UNTIL IT IS MERGED BACK OR YOU WILL DELETE AIR /////////////////////////////////////////////// ///////////////////////////////// FLOW HAS BEEN CREATED /// DONT DELETE THE FIRE UNTIL IT IS MERGED BACK OR YOU WILL DELETE AIR ///////////////////////////////////////////////
if(flow) if(flow)
if(flow.check_recombustability(liquid))
//Ensure flow temperature is higher than minimum fire temperatures.
//this creates some energy ex nihilo but is necessary to get a fire started
//lets just pretend this energy comes from the ignition source and dont mention this again
//flow.temperature = max(PHORON_MINIMUM_BURN_TEMPERATURE+0.1,flow.temperature)
//burn baby burn! //burn baby burn!
flow.zburn(liquid,1) flow.zburn(liquid,1)
//merge the air back //merge the air back
S.assume_air(flow) S.assume_air(flow)
@@ -275,9 +267,9 @@ datum/gas_mixture/proc/check_combustability(obj/effect/decal/cleanable/liquid_fu
if(oxygen && (phoron || fuel || liquid)) if(oxygen && (phoron || fuel || liquid))
if(liquid) if(liquid)
return 1 return 1
if (phoron >= 0.1) if(QUANTIZE(phoron * vsc.fire_consuption_rate) >= 0.1)
return 1 return 1
if(fuel && fuel.moles >= 0.1) if(fuel && QUANTIZE(fuel.moles * vsc.fire_consuption_rate) >= 0.1)
return 1 return 1
return 0 return 0

View File

@@ -366,3 +366,36 @@ datum/projectile_data
var/dest_y = src_y + distance*cos(rotation); var/dest_y = src_y + distance*cos(rotation);
return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y) return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y)
/proc/GetRedPart(const/hexa)
return hex2num(copytext(hexa,2,4))
/proc/GetGreenPart(const/hexa)
return hex2num(copytext(hexa,4,6))
/proc/GetBluePart(const/hexa)
return hex2num(copytext(hexa,6,8))
/proc/GetHexColors(const/hexa)
return list(
GetRedPart(hexa),
GetGreenPart(hexa),
GetBluePart(hexa)
)
/proc/MixColors(const/list/colors)
var/list/reds = list()
var/list/blues = list()
var/list/greens = list()
var/list/weights = list()
for (var/i = 0, ++i <= colors.len)
reds.Add(GetRedPart(colors[i]))
blues.Add(GetBluePart(colors[i]))
greens.Add(GetGreenPart(colors[i]))
weights.Add(1)
var/r = mixOneColor(weights, reds)
var/g = mixOneColor(weights, greens)
var/b = mixOneColor(weights, blues)
return rgb(r,g,b)

View File

@@ -11,6 +11,7 @@
/proc/error(msg) /proc/error(msg)
world.log << "## ERROR: [msg][log_end]" world.log << "## ERROR: [msg][log_end]"
#define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [src] usr: [usr].")
//print a warning message to world.log //print a warning message to world.log
/proc/warning(msg) /proc/warning(msg)
world.log << "## WARNING: [msg][log_end]" world.log << "## WARNING: [msg][log_end]"

View File

@@ -3,6 +3,11 @@
var/const/E = 2.71828183 var/const/E = 2.71828183
var/const/Sqrt2 = 1.41421356 var/const/Sqrt2 = 1.41421356
// List of square roots for the numbers 1-100.
var/list/sqrtTable = list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10)
/proc/Atan2(x, y) /proc/Atan2(x, y)
if(!x && !y) return 0 if(!x && !y) return 0

View File

@@ -16,8 +16,10 @@
Note that this proc can be overridden, and is in the case of screen objects. Note that this proc can be overridden, and is in the case of screen objects.
*/ */
/atom/Click(location,control,params) /atom/Click(location,control,params)
if(src)
usr.ClickOn(src, params) usr.ClickOn(src, params)
/atom/DblClick(location,control,params) /atom/DblClick(location,control,params)
if(src)
usr.DblClickOn(src,params) usr.DblClickOn(src,params)
/* /*

View File

@@ -5,7 +5,8 @@
ShadowDarke's respective lighting libraries. Credits, where due, to them. ShadowDarke's respective lighting libraries. Credits, where due, to them.
Like sd_DAL (what we used to use), it changes the shading overlays of areas by splitting each type of area into sub-areas Like sd_DAL (what we used to use), it changes the shading overlays of areas by splitting each type of area into sub-areas
by using the var/tag variable and moving turfs into the contents list of the correct sub-area. by using the var/tag variable and moving turfs into the contents list of the correct sub-area. This method is
much less costly than using overlays or objects.
Unlike sd_DAL however it uses a queueing system. Everytime we call a change to opacity or luminosity Unlike sd_DAL however it uses a queueing system. Everytime we call a change to opacity or luminosity
(through SetOpacity() or SetLuminosity()) we are simply updating variables and scheduling certain lights/turfs for an (through SetOpacity() or SetLuminosity()) we are simply updating variables and scheduling certain lights/turfs for an
@@ -15,50 +16,40 @@
setting lighting_controller.processing = 0 at say, the start of a large explosion, waiting for it to finish, and then setting lighting_controller.processing = 0 at say, the start of a large explosion, waiting for it to finish, and then
turning it back on with lighting_controller.processing = 1. turning it back on with lighting_controller.processing = 1.
Unlike our old system there is a hardcoded maximum luminosity. This is to discourage coders using large luminosity values Unlike our old system there are hardcoded maximum luminositys (different for certain atoms).
for dynamic lighting, as the cost of lighting grows rapidly at large luminosity levels (especially when changing opacity This is to cap the cost of creating lighting effects.
at runtime) (without this, an atom with luminosity of 20 would have to update 41^2 turfs!) :s
Also, in order for the queueing system to work, each light remembers the effect it casts on each turf. This is going to Also, in order for the queueing system to work, each light remembers the effect it casts on each turf. This is going to
have larger memory requirements than our previous system but hopefully it's worth the hassle for the greater control we have larger memory requirements than our previous system but it's easily worth the hassle for the greater control we
gain. Besides, there are far far worse uses of needless lists in the game, it'd be worth pruning some of them to offset gain. It also reduces cost of removing lighting effects by a lot!
costs.
Known Issues/TODO: Known Issues/TODO:
admin-spawned turfs will have broken lumcounts. Not willing to fix it at this moment
mob luminosity will be lower than expected when one of multiple light sources is dropped after exceeding the maximum luminosity
Shuttles still do not have support for dynamic lighting (I hope to fix this at some point) Shuttles still do not have support for dynamic lighting (I hope to fix this at some point)
No directional lighting support. Fairly easy to add this and the code is ready. No directional lighting support. (prototype looked ugly)
*/ */
#define LIGHTING_MAX_LUMINOSITY 12 //Hard maximum luminosity to prevet lag which could be caused by coders making mini-suns #define LIGHTING_CIRCULAR 1 //comment this out to use old square lighting effects.
#define LIGHTING_MAX_LUMINOSITY_MOB 7 //Mobs get their own max because 60-odd human suns running around would be pretty silly
#define LIGHTING_LAYER 10 //Drawing layer for lighting overlays #define LIGHTING_LAYER 10 //Drawing layer for lighting overlays
#define LIGHTING_ICON 'icons/effects/ss13_dark_alpha7.dmi' //Icon used for lighting shading effects #define LIGHTING_ICON 'icons/effects/ss13_dark_alpha6.dmi' //Icon used for lighting shading effects
datum/light_source datum/light_source
var/atom/owner var/atom/owner
var/changed = 1 var/changed = 1
var/mobile = 1
var/list/effect = list() var/list/effect = list()
var/__x = 0 //x coordinate at last update var/__x = 0 //x coordinate at last update
var/__y = 0 //y coordinate at last update var/__y = 0 //y coordinate at last update
var/l_color
New(atom/A) New(atom/A)
if(!istype(A)) if(!istype(A))
CRASH("The first argument to the light object's constructor must be the atom that is the light source. Expected atom, received '[A]' instead.") CRASH("The first argument to the light object's constructor must be the atom that is the light source. Expected atom, received '[A]' instead.")
..() ..()
owner = A owner = A
l_color = owner.l_color
if(istype(owner, /atom/movable)) mobile = 1 //apparantly this is faster than type-checking
else mobile = 0 //Perhaps removing support for luminous turfs would be a good idea.
__x = owner.x __x = owner.x
__y = owner.y __y = owner.y
// the lighting object maintains a list of all light sources // the lighting object maintains a list of all light sources
lighting_controller.lights += src lighting_controller.lights += src
@@ -69,13 +60,15 @@ datum/light_source
remove_effect() remove_effect()
return 1 //causes it to be removed from our list of lights. The garbage collector will then destroy it. return 1 //causes it to be removed from our list of lights. The garbage collector will then destroy it.
if(mobile)
// check to see if we've moved since last update // check to see if we've moved since last update
if(owner.x != __x || owner.y != __y) if(owner.x != __x || owner.y != __y)
__x = owner.x __x = owner.x
__y = owner.y __y = owner.y
changed = 1 changed = 1
if (owner.l_color != l_color)
changed = 1
if(changed) if(changed)
changed = 0 changed = 0
remove_effect() remove_effect()
@@ -85,197 +78,264 @@ datum/light_source
proc/remove_effect() proc/remove_effect()
// before we apply the effect we remove the light's current effect. // before we apply the effect we remove the light's current effect.
if(effect.len) for(var/turf/T in effect) // negate the effect of this light source
for(var/turf in effect) // negate the effect of this light source T.update_lumcount(-effect[T], l_color, 1)
var/turf/T = turf
T.update_lumcount(-effect[T])
effect.Cut() // clear the effect list effect.Cut() // clear the effect list
proc/add_effect() proc/add_effect()
// only do this if the light is turned on and is on the map // only do this if the light is turned on and is on the map
if(owner.loc && owner.luminosity > 0) if(owner.loc && owner.luminosity > 0)
effect = new_effect() // identify the effects of this light source l_color = owner.l_color
for(var/turf in effect) effect = list()
var/turf/T = turf for(var/turf/T in view(owner.get_light_range(),owner))
T.update_lumcount(effect[T]) // apply the effect var/delta_lumen = lum(T)
if(delta_lumen > 0)
effect[T] = delta_lumen
T.update_lumcount(delta_lumen, l_color, 0)
return 0 return 0
else else
owner.light = null owner.light = null
return 1 //cause the light to be removed from the lights list and garbage collected once it's no return 1 //cause the light to be removed from the lights list and garbage collected once it's no
//longer referenced by the queue //longer referenced by the queue
proc/new_effect()
. = list()
for(var/turf/T in view(owner.luminosity, owner))
// var/area/A = T.loc
// if(!A) continue
var/change_in_lumcount = lum(T)
if(change_in_lumcount > 0)
.[T] = change_in_lumcount
return .
proc/lum(turf/A) proc/lum(turf/A)
return owner.luminosity - max(abs(A.x-__x),abs(A.y-__y)) if (owner.trueLuminosity < 1)
// var/dist = cheap_hypotenuse(A.x,A.y,__x,__y) //fetches the pythagorean distance between A and the light return 0
// if(owner.luminosity < dist) //if the turf is outside the radius the light doesn't illuminate it var/dist
// return 0 if(!A)
// return round(owner.luminosity - (dist/2),0.1) dist = 0
else
#ifdef LIGHTING_CIRCULAR
dist = cheap_hypotenuse(A.x, A.y, __x, __y)
#else
dist = max(abs(A.x - __x), abs(A.y - __y))
#endif
if (owner.trueLuminosity > 100) // This will never happen... right?
return sqrt(owner.trueLuminosity) - dist
else
return sqrtTable[owner.trueLuminosity] - dist
atom atom
var/datum/light_source/light var/datum/light_source/light
var/trueLuminosity = 0 // Typically 'luminosity' squared. The builtin luminosity must remain linear.
// We may read it, but NEVER set it directly.
var/l_color
//Turfs with opacity when they are constructed will trigger nearby lights to update //Turfs with opacity when they are constructed will trigger nearby lights to update
//Turfs atoms with luminosity when they are constructed will create a light_source automatically //Turfs and atoms with luminosity when they are constructed will create a light_source automatically
//TODO: lag reduction
turf/New() turf/New()
..() ..()
if(opacity)
UpdateAffectingLights()
if(luminosity) if(luminosity)
world.log << "[type] has luminosity at New()" if(light) WARNING("[type] - Don't set lights up manually during New(), We do it automatically.")
if(light) world.log << "## WARNING: [type] - Don't set lights up manually during New(), We do it automatically." trueLuminosity = luminosity * luminosity
light = new(src) light = new(src)
//Movable atoms with opacity when they are constructed will trigger nearby lights to update //Movable atoms with opacity when they are constructed will trigger nearby lights to update
//Movable atoms with luminosity when they are constructed will create a light_source automatically //Movable atoms with luminosity when they are constructed will create a light_source automatically
//TODO: lag reduction
atom/movable/New() atom/movable/New()
..() ..()
if(opacity) if(opacity)
if(isturf(loc))
if(loc:lighting_lumcount > 1)
UpdateAffectingLights() UpdateAffectingLights()
if(luminosity) if(luminosity)
if(light) world.log << "## WARNING: [type] - Don't set lights up manually during New(), We do it automatically." if(light) WARNING("[type] - Don't set lights up manually during New(), We do it automatically.")
trueLuminosity = luminosity * luminosity
light = new(src) light = new(src)
//Turfs with opacity will trigger nearby lights to update at next lighting process.
//TODO: is this really necessary? Removing it could help reduce lag during singulo-mayhem somewhat
turf/Del()
if(opacity)
UpdateAffectingLights()
..()
//Objects with opacity will trigger nearby lights to update at next lighting process. //Objects with opacity will trigger nearby lights to update at next lighting process.
atom/movable/Del() atom/movable/Del()
if(opacity) if(opacity)
if(isturf(loc))
if(loc:lighting_lumcount > 1)
UpdateAffectingLights() UpdateAffectingLights()
..() ..()
//Sets our luminosity. Enforces a hardcoded maximum luminosity by default. This maximum can be overridden but it is extremely //Sets our luminosity.
//unwise to do so.
//If we have no light it will create one. //If we have no light it will create one.
//If we are setting luminosity to 0 the light will be cleaned up and delted once all its queues are complete //If we are setting luminosity to 0 the light will be cleaned up by the controller and garbage collected once all its
//if we have a light already it is merely updated //queues are complete.
atom/proc/SetLuminosity(new_luminosity, max_luminosity = LIGHTING_MAX_LUMINOSITY) //if we have a light already it is merely updated, rather than making a new one.
atom/proc/SetLuminosity(new_luminosity, trueLum = FALSE)
if(new_luminosity < 0) if(new_luminosity < 0)
new_luminosity = 0 new_luminosity = 0
// world.log << "## WARNING: [type] - luminosity cannot be negative" if(!trueLum)
else if(max_luminosity < new_luminosity) new_luminosity *= new_luminosity
new_luminosity = max_luminosity
// if(luminosity != new_luminosity)
// world.log << "## WARNING: [type] - LIGHT_MAX_LUMINOSITY exceeded"
if(isturf(loc))
if(light) if(light)
if(luminosity != new_luminosity) //TODO: remove lights from the light list when they're not luminous? DONE in add_effect if(trueLuminosity != new_luminosity) //non-luminous lights are removed from the lights list in add_effect()
light.changed = 1 light.changed = 1
else else
if(new_luminosity) if(new_luminosity)
light = new(src) light = new(src)
trueLuminosity = new_luminosity
if (trueLuminosity < 1)
luminosity = 0
else if (trueLuminosity <= 100)
luminosity = sqrtTable[trueLuminosity]
else
luminosity = sqrt(trueLuminosity)
luminosity = new_luminosity atom/proc/AddLuminosity(delta_luminosity)
if(delta_luminosity > 0)
SetLuminosity(trueLuminosity + delta_luminosity*delta_luminosity, TRUE)
else if(delta_luminosity < 0)
SetLuminosity(trueLuminosity - delta_luminosity*delta_luminosity, TRUE)
area/SetLuminosity(new_luminosity) //we don't want dynamic lighting for areas
luminosity = !!new_luminosity
trueLuminosity = luminosity
//Snowflake code to prevent mobs becoming suns (lag-prevention)
mob/SetLuminosity(new_luminosity)
..(new_luminosity,LIGHTING_MAX_LUMINOSITY_MOB)
//change our opacity (defaults to toggle), and then update all lights that affect us. //change our opacity (defaults to toggle), and then update all lights that affect us.
atom/proc/SetOpacity(var/new_opacity) atom/proc/SetOpacity(new_opacity)
if(new_opacity == null) new_opacity = !opacity if(new_opacity == null)
else if(opacity == new_opacity) return new_opacity = !opacity //default = toggle opacity
opacity = new_opacity else if(opacity == new_opacity)
return 0 //opacity hasn't changed! don't bother doing anything
opacity = new_opacity //update opacity, the below procs now call light updates.
return 1
turf/SetOpacity(new_opacity)
if(..()==1) //only bother if opacity changed
if(lighting_lumcount) //only bother with an update if our turf is currently affected by a light
UpdateAffectingLights() UpdateAffectingLights()
//set the changed status of all lights which could have possibly lit this atom. /atom/movable/SetOpacity(new_opacity)
//We don't need to worry about lights which lit us but moved away, since they will have change status set already if(..()==1) //only bother if opacity changed
atom/proc/UpdateAffectingLights() if(isturf(loc)) //only bother with an update if we're on a turf
var/turf/T = src var/turf/T = loc
if(!isturf(T)) if(T.lighting_lumcount) //only bother with an update if our turf is currently affected by a light
T = loc UpdateAffectingLights()
if(!isturf(T)) return
for(var/atom in range(LIGHTING_MAX_LUMINOSITY,T)) //TODO: this will probably not work very well :(
var/atom/A = atom
if(A.light && A.luminosity)
A.light.changed = 1 //force it to update at next process()
// for(var/light in lighting_controller.lights) //TODO: this will probably laaaaaag
// var/datum/light_source/L = light
// if(L.changed) continue
// if(!L.owner) continue
// if(!L.owner.luminosity) continue
// if(src in L.effect)
// L.changed = 1
turf turf
var/lighting_lumcount = 0 var/lighting_lumcount = 0
var/lighting_changed = 0 var/lighting_changed = 0
var/color_lighting_lumcount = 0
var/list/colors = list()
turf/space turf/space
lighting_lumcount = 4 //starlight lighting_lumcount = 4 //starlight
turf/proc/update_lumcount(amount) turf/proc/update_lumcount(amount, _lcolor, removing = 0)
lighting_lumcount += amount lighting_lumcount += amount
// if(lighting_lumcount < 0 || lighting_lumcount > 100) var/blended
// world.log << "## WARNING: [type] ([src]) lighting_lumcount = [lighting_lumcount]"
if (_lcolor)
if (removing)
colors.Remove(_lcolor) // Remove the color that's leaving us from our list.
if (colors && !colors.len)
l_color = null // All our color is gone, no color for us.
else if (colors && colors.len > 1)
var/maxdepth = 3 // Will blend 3 colors, anymore than that and it looks bad or we will get lag on every tile update.
var/currentblended = colors
if (colors.len > maxdepth)
currentblended = MixColors(colors.Copy(1,maxdepth+1))
if (currentblended)
//world << "Ended up with [currentblended]"
l_color = currentblended // blended the remaining colors so apply it.
else
l_color = null // Something went wrong, no color for you.
else
l_color = colors[colors.len]
else // we added a color.
colors.Add(_lcolor) // Add the base color to the list.
if (l_color && _lcolor && l_color != _lcolor) // Blend colors.
blended = MixColors(list(l_color,_lcolor))
if (blended)
l_color = blended // If we had a blended color, this is what we get otherwise.
else
l_color = _lcolor // Basecolor is our color.
// if ((l_color != LIGHT_WHITE && l_color != "#FFF") || removing)
color_lighting_lumcount = max(color_lighting_lumcount + amount, 0) // Minimum of 0.
if(!lighting_changed) if(!lighting_changed)
lighting_controller.changed_turfs += src lighting_controller.changed_turfs += src
lighting_changed = 1 lighting_changed = 1
turf/proc/lighting_tag(const/level)
var/area/A = loc
return A.tagbase + "sd_L[level]"
turf/proc/build_lighting_area(const/tag, const/level, const/color_light)
var/area/Area = loc
var/area/A = new Area.type() // create area if it wasn't found
// replicate vars
for(var/V in Area.vars)
switch(V)
if ("contents","lighting_overlay", "color_overlay", "overlays")
continue
else
if(issaved(Area.vars[V])) A.vars[V] = Area.vars[V]
A.tag = tag
A.lighting_subarea = 1
A.lighting_space = 0 // in case it was copied from a space subarea
if (l_color != A.l_color)
A.l_color = l_color
//color_light = min(max(round(color_lighting_lumcount, 1), 0), lighting_controller.lighting_states)
//world << "[color_light] [color_lighting_lumcount]"
A.SetLightLevel(level, color_light)
Area.related += A
return A
turf/proc/shift_to_subarea() turf/proc/shift_to_subarea()
lighting_changed = 0 lighting_changed = 0
var/area/Area = loc var/area/Area = loc
if(!istype(Area) || !Area.lighting_use_dynamic) return if(!istype(Area) || !Area.lighting_use_dynamic) return
// change the turf's area depending on its brightness var/level = min(max(round(lighting_lumcount,1),0),lighting_controller.lighting_states)
// restrict light to valid levels var/new_tag = lighting_tag(level)
var/light = min(max(round(lighting_lumcount,1),0),lighting_controller.lighting_states)
var/find = findtextEx(Area.tag, "sd_L") // pomf - If we have a lighting color that is not null, apply the new tag to seperate the areas.
var/new_tag = copytext(Area.tag, 1, find) if (l_color)
new_tag += "sd_L[light]" new_tag += "[l_color][color_lighting_lumcount]" // pomf - We append the color lighting lumcount so we can have colored lights.
if(Area.tag!=new_tag) //skip if already in this area if(Area.tag!=new_tag) //skip if already in this area
var/area/A = locate(new_tag) // find an appropriate area var/area/A = locate(new_tag) // find an appropriate area
var/color_light = min(max(round(color_lighting_lumcount,1),0),lighting_controller.lighting_states)
if (!A) if (!A)
A = build_lighting_area(new_tag, level, color_light)
A = new Area.type() // create area if it wasn't found else if (l_color != A.l_color)
// replicate vars A.l_color = l_color
for(var/V in Area.vars) //color_light = min(max(round(color_lighting_lumcount, 1), 0), lighting_controller.lighting_states)
switch(V) A.SetLightLevel(level, color_light)
if("contents","lighting_overlay","overlays") continue
else
if(issaved(Area.vars[V])) A.vars[V] = Area.vars[V]
A.tag = new_tag
A.lighting_subarea = 1
A.SetLightLevel(light)
Area.related += A
A.contents += src // move the turf into the area A.contents += src // move the turf into the area
// Dedicated lighting sublevel for space turfs
// helps us depower things in space, remove space fire alarms,
// and evens out space lighting
turf/space/lighting_tag(var/level)
var/area/A = loc
return A.tagbase + "sd_L_space"
turf/space/build_lighting_area(var/tag,var/level)
var/area/A = ..(tag,4)
A.lighting_space = 1
A.SetLightLevel(4)
A.icon_state = null
return A
area area
var/lighting_use_dynamic = 1 //Turn this flag off to prevent sd_DynamicAreaLighting from affecting this area var/lighting_use_dynamic = 1 //Turn this flag off to prevent sd_DynamicAreaLighting from affecting this area
var/image/lighting_overlay //tracks the darkness image of the area for easy removal var/image/lighting_overlay //tracks the darkness image of the area for easy removal
var/lighting_subarea = 0 //tracks whether we're a lighting sub-area var/lighting_subarea = 0 //tracks whether we're a lighting sub-area
var/lighting_space = 0 // true for space-only lighting subareas
var/tagbase
var/image/color_overlay //Tracks the color image.
proc/SetLightLevel(light) proc/SetLightLevel(light, color_light = 0)
if(!src) return if(!src) return
if(light <= 0) if(light <= 0)
light = 0 light = 0
@@ -291,17 +351,97 @@ area
else else
lighting_overlay = image(LIGHTING_ICON,,num2text(light),LIGHTING_LAYER) lighting_overlay = image(LIGHTING_ICON,,num2text(light),LIGHTING_LAYER)
overlays += lighting_overlay if (color_overlay)
overlays.Remove(color_overlay)
color_overlay.icon_state = "5"
else
if (l_color)
color_overlay = image('icons/effects/effects.dmi', ,"5", 10.1)
//color_overlay = image('icons/effects/effects.dmi', ,"white", 10.1)
if (istype(color_overlay))
color_overlay.color = l_color
switch (color_light)
if (6)
color_overlay.icon_state = "5"
//color_overlay.alpha = 180
if (5)
color_overlay.icon_state = "4"
//color_overlay.alpha = 150
if (4)
color_overlay.icon_state = "3"
//color_overlay.alpha = 120
if (3)
color_overlay.icon_state = "2"
//color_overlay.alpha = 90
if (2)
color_overlay.icon_state = "1"
//color_overlay.alpha = 60
if (1)
color_overlay.icon_state = "1"
color_overlay.alpha = 200
//color_overlay.alpha = 30
if (-INFINITY to 0)
//world << "Zero or below, [color_light]."
color_overlay.alpha = 0
else
//world << "Setting the alpha to max... color_light [color_light]."
color_overlay.alpha = 180
color_overlay.blend_mode = BLEND_ADD
if (color_overlay.color)
overlays.Add(color_overlay)
if (isnull(color_overlay))
overlays.Add(lighting_overlay)
else if (light < 6)
overlays.Add(lighting_overlay)
proc/SetDynamicLighting()
src.lighting_use_dynamic = 1
for(var/turf/T in src.contents)
T.update_lumcount(0)
proc/InitializeLighting() //TODO: could probably improve this bit ~Carn proc/InitializeLighting() //TODO: could probably improve this bit ~Carn
if(!tag) tag = "[type]" tagbase = "[type]"
if(!tag) tag = tagbase
if(!lighting_use_dynamic) if(!lighting_use_dynamic)
if(!lighting_subarea) // see if this is a lighting subarea already if(!lighting_subarea) // see if this is a lighting subarea already
//show the dark overlay so areas, not yet in a lighting subarea, won't be bright as day and look silly. //show the dark overlay so areas, not yet in a lighting subarea, won't be bright as day and look silly.
SetLightLevel(4) SetLightLevel(4)
//#undef LIGHTING_LAYER
#undef LIGHTING_MAX_LUMINOSITY #undef LIGHTING_CIRCULAR
#undef LIGHTING_MAX_LUMINOSITY_MOB
#undef LIGHTING_LAYER
//#undef LIGHTING_ICON //#undef LIGHTING_ICON
#define LIGHTING_MAX_LUMINOSITY_STATIC 8 //Maximum luminosity to reduce lag.
#define LIGHTING_MAX_LUMINOSITY_MOBILE 5 //Moving objects have a lower max luminosity since these update more often. (lag reduction)
#define LIGHTING_MAX_LUMINOSITY_TURF 1 //turfs have a severely shortened range to protect from inevitable floor-lighttile spam.
//set the changed status of all lights which could have possibly lit this atom.
//We don't need to worry about lights which lit us but moved away, since they will have change status set already
//This proc can cause lots of lights to be updated. :(
atom/proc/UpdateAffectingLights()
for(var/atom/A in oview(LIGHTING_MAX_LUMINOSITY_STATIC-1,src))
if(A.light)
A.light.changed = 1 //force it to update at next process()
//caps luminosity effects max-range based on what type the light's owner is.
atom/proc/get_light_range()
return min(luminosity, LIGHTING_MAX_LUMINOSITY_STATIC)
atom/movable/get_light_range()
return min(luminosity, LIGHTING_MAX_LUMINOSITY_MOBILE)
obj/machinery/light/get_light_range()
return min(luminosity, LIGHTING_MAX_LUMINOSITY_STATIC)
turf/get_light_range()
return min(luminosity, LIGHTING_MAX_LUMINOSITY_TURF)
#undef LIGHTING_MAX_LUMINOSITY_STATIC
#undef LIGHTING_MAX_LUMINOSITY_MOBILE
#undef LIGHTING_MAX_LUMINOSITY_TURF

View File

@@ -147,6 +147,11 @@ proc/get_id_photo(var/mob/living/carbon/human/H)
temp.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0)) temp.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
preview_icon.Blend(temp, ICON_OVERLAY) preview_icon.Blend(temp, ICON_OVERLAY)
//Tail
if(H.species.tail && H.species.flags & HAS_TAIL)
temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[H.species.tail]_s")
preview_icon.Blend(temp, ICON_OVERLAY)
// Skin tone // Skin tone
if(H.species.flags & HAS_SKIN_TONE) if(H.species.flags & HAS_SKIN_TONE)
if (H.s_tone >= 0) if (H.s_tone >= 0)

View File

@@ -1,96 +0,0 @@
/*
* This datum gets revision info from local svn 'entries' file
* Path to the directory containing it should be in 'config/svndir.txt' file
*
*/
var/global/datum/getrev/revdata = new("config/svndir.txt")
//Oh yeah, I'm an OOP fag, lalala
/datum/getrev
var/revision
var/commiter
var/svndirpath
var/revhref
proc/abort()
spawn()
del src
New(filename)
..()
var/list/Lines = file2list(filename)
if(!Lines.len) return abort()
for(var/t in Lines)
if(!t) continue
t = trim(t)
if (length(t) == 0)
continue
else if (copytext(t, 1, 2) == "#")
continue
var/pos = findtext(t, " ")
var/name = null
var/value = null
if (pos)
name = lowertext(copytext(t, 1, pos))
value = copytext(t, pos + 1)
else
name = lowertext(t)
if(!name)
continue
switch(name)
if("svndir")
svndirpath = value
if("revhref")
revhref = value
if(svndirpath && fexists(svndirpath) && fexists("[svndirpath]/entries") && isfile(file("[svndirpath]/entries")))
var/list/filelist = file2list("[svndirpath]/entries")
var/s_archive = "" //Stores the previous line so the revision owner can be assigned.
//This thing doesn't count blank lines, so doing filelist[4] isn't working.
for(var/s in filelist)
if(!commiter)
if(s == "has-props")//The line before this is the committer.
commiter = s_archive
if(!revision)
var/n = text2num(s)
if(isnum(n))
if(n > 5000 && n < 99999) //Do you think we'll still be up and running at r100000? :) ~Errorage
revision = s
if(revision && commiter)
break
s_archive = s
if(!revision)
abort()
log_misc("Revision info loaded succesfully")
return
return abort()
proc/getRevisionText()
var/output
if(revhref)
output = {"<a href="[revhref][revision]">[revision]</a>"}
else
output = revision
return output
proc/showInfo()
return {"<html>
<head>
</head>
<body>
<p><b>Server Revision:</b> [getRevisionText()]<br/>
<b>Author:</b> [commiter]</p>
</body>
<html>"}
client/verb/showrevinfo()
set category = "OOC"
set name = "Show Server Revision"
var/output = "Sorry, the revision info is unavailable."
output = file2text("/home/bay12/live/data/gitcommit")
output += "Current Infomational Settings: <br>"
output += "Protect Authority Roles From Traitor: [config.protect_roles_from_antagonist]<br>"
usr << browse(output,"window=revdata");
return

View File

@@ -10,7 +10,7 @@
var/last_bumped = 0 var/last_bumped = 0
var/pass_flags = 0 var/pass_flags = 0
var/throwpass = 0 var/throwpass = 0
var/germ_level = 0 // The higher the germ level, the more germ on the atom. var/germ_level = GERM_LEVEL_AMBIENT // The higher the germ level, the more germ on the atom.
///Chemistry. ///Chemistry.
var/datum/reagents/reagents = null var/datum/reagents/reagents = null

View File

@@ -15,8 +15,8 @@
/atom/movable/Move() /atom/movable/Move()
var/atom/A = src.loc var/atom/A = src.loc
. = ..() . = ..()
src.move_speed = world.timeofday - src.l_move_time src.move_speed = world.time - src.l_move_time
src.l_move_time = world.timeofday src.l_move_time = world.time
src.m_flag = 1 src.m_flag = 1
if ((A != src.loc && A && A.z == src.z)) if ((A != src.loc && A && A.z == src.z))
src.last_move = get_dir(A, src.loc) src.last_move = get_dir(A, src.loc)

View File

@@ -6,7 +6,7 @@
#define MUTCHK_FORCED 1 #define MUTCHK_FORCED 1
/proc/domutcheck(var/mob/living/M, var/connected=null, var/flags=0) /proc/domutcheck(var/mob/living/M, var/connected=null, var/flags=0)
for(var/datum/dna/gene/gene in dna_genes) for(var/datum/dna/gene/gene in dna_genes)
if(!M) if(!M || !M.dna)
return return
if(!gene.block) if(!gene.block)
continue continue

View File

@@ -188,6 +188,7 @@
//message_admins("The probability of a new traitor is [traitor_prob]%") //message_admins("The probability of a new traitor is [traitor_prob]%")
if(prob(traitor_prob)) if(prob(traitor_prob))
message_admins("New traitor roll passed. Making a new Traitor.") message_admins("New traitor roll passed. Making a new Traitor.")
if (!config.objectives_disabled)
forge_traitor_objectives(character.mind) forge_traitor_objectives(character.mind)
equip_traitor(character) equip_traitor(character)
traitors += character.mind traitors += character.mind

View File

@@ -87,7 +87,7 @@
return 1 return 1
return 0 return 0
/* temperature_expose(datum/gas_mixture/air, temperature, volume) Blob is currently fireproof /* fire_act(datum/gas_mixture/air, temperature, volume) Blob is currently fireproof
if(temperature > T0C+200) if(temperature > T0C+200)
health -= 0.01 * temperature health -= 0.01 * temperature
update() update()

View File

@@ -88,6 +88,9 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
//No escape alone because changelings aren't suited for it and it'd probably just lead to rampant robusting //No escape alone because changelings aren't suited for it and it'd probably just lead to rampant robusting
//If it seems like they'd be able to do it in play, add a 10% chance to have to escape alone //If it seems like they'd be able to do it in play, add a 10% chance to have to escape alone
if (config.objectives_disabled)
return
var/datum/objective/absorb/absorb_objective = new var/datum/objective/absorb/absorb_objective = new
absorb_objective.owner = changeling absorb_objective.owner = changeling
absorb_objective.gen_amount_goal(2, 3) absorb_objective.gen_amount_goal(2, 3)

View File

@@ -98,7 +98,7 @@
item_state = "cult_armour" item_state = "cult_armour"
desc = "A bulky suit of armour, bristling with spikes. It looks space proof." desc = "A bulky suit of armour, bristling with spikes. It looks space proof."
w_class = 3 w_class = 3
allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade,/obj/item/weapon/tank/emergency_oxygen) allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade,/obj/item/weapon/tank/emergency_oxygen,/obj/item/device/suit_cooling_unit)
slowdown = 1 slowdown = 1
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
siemens_coefficient = 0 siemens_coefficient = 0

View File

@@ -154,7 +154,7 @@
return return
return return
/obj/effect/biomass/temperature_expose(null, temp, volume) //hotspots kill biomass /obj/effect/biomass/fire_act(null, temp, volume) //hotspots kill biomass
del src del src

View File

@@ -1367,9 +1367,8 @@ It is possible to destroy the net by the occupant or someone else.
playsound(M.loc, 'sound/effects/sparks4.ogg', 50, 1) playsound(M.loc, 'sound/effects/sparks4.ogg', 50, 1)
anim(M.loc,M,'icons/mob/mob.dmi',,"phaseout",,M.dir) anim(M.loc,M,'icons/mob/mob.dmi',,"phaseout",,M.dir)
if(holdingfacility.len)
M.loc = pick(holdingfacility)//Throw mob in to the holding facility. M.loc = pick(holdingfacility)//Throw mob in to the holding facility.
M << "\red You appear in a strange place!"
spawn(0) spawn(0)
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread() var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, M.loc) spark_system.set_up(5, 0, M.loc)
@@ -1378,6 +1377,10 @@ It is possible to destroy the net by the occupant or someone else.
playsound(M.loc, 'sound/effects/sparks2.ogg', 50, 1) playsound(M.loc, 'sound/effects/sparks2.ogg', 50, 1)
anim(M.loc,M,'icons/mob/mob.dmi',,"phasein",,M.dir) anim(M.loc,M,'icons/mob/mob.dmi',,"phasein",,M.dir)
del(src)//Wait for everything to finish, delete the net. Else it will stop everything once net is deleted, including the spawn(0). del(src)//Wait for everything to finish, delete the net. Else it will stop everything once net is deleted, including the spawn(0).
else
M.loc = null
M << "\red You appear in a strange place!"
for(var/mob/O in viewers(src, 3)) for(var/mob/O in viewers(src, 3))
O.show_message(text("[] vanished!", M), 1, text("You hear sparks flying!"), 2) O.show_message(text("[] vanished!", M), 1, text("You hear sparks flying!"), 2)

View File

@@ -239,7 +239,7 @@
return return
return return
/obj/effect/spacevine/temperature_expose(null, temp, volume) //hotspots kill vines /obj/effect/spacevine/fire_act(null, temp, volume) //hotspots kill vines
del src del src
//Carn: Spacevines random event. //Carn: Spacevines random event.

View File

@@ -112,8 +112,6 @@ Implants;
feedback_set_details("round_start","[time2text(world.realtime)]") feedback_set_details("round_start","[time2text(world.realtime)]")
if(ticker && ticker.mode) if(ticker && ticker.mode)
feedback_set_details("game_mode","[ticker.mode]") feedback_set_details("game_mode","[ticker.mode]")
if(revdata)
feedback_set_details("revision","[revdata.revision]")
feedback_set_details("server_ip","[world.internet_address]:[world.port]") feedback_set_details("server_ip","[world.internet_address]:[world.port]")
return 1 return 1

View File

@@ -108,6 +108,9 @@
/datum/game_mode/proc/forge_meme_objectives(var/datum/mind/meme, var/datum/mind/first_host) /datum/game_mode/proc/forge_meme_objectives(var/datum/mind/meme, var/datum/mind/first_host)
if (config.objectives_disabled)
return
// meme always needs to attune X hosts // meme always needs to attune X hosts
var/datum/objective/meme_attune/attune_objective = new var/datum/objective/meme_attune/attune_objective = new
attune_objective.owner = meme attune_objective.owner = meme

View File

@@ -85,6 +85,8 @@
return 1 return 1
/datum/game_mode/ninja/proc/forge_ninja_objectives(var/datum/mind/ninja) /datum/game_mode/ninja/proc/forge_ninja_objectives(var/datum/mind/ninja)
if (config.objectives_disabled)
return
var/objective_list = list(1,2,3,4,5) var/objective_list = list(1,2,3,4,5)
for(var/i=rand(2,4),i>0,i--) for(var/i=rand(2,4),i>0,i--)

View File

@@ -186,6 +186,8 @@
/datum/game_mode/proc/forge_syndicate_objectives(var/datum/mind/syndicate) /datum/game_mode/proc/forge_syndicate_objectives(var/datum/mind/syndicate)
if (config.objectives_disabled)
return
var/datum/objective/nuclear/syndobj = new var/datum/objective/nuclear/syndobj = new
syndobj.owner = syndicate syndobj.owner = syndicate
syndicate.objectives += syndobj syndicate.objectives += syndobj

View File

@@ -78,6 +78,9 @@
/datum/game_mode/proc/forge_traitor_objectives(var/datum/mind/traitor) /datum/game_mode/proc/forge_traitor_objectives(var/datum/mind/traitor)
if (config.objectives_disabled)
return
if(istype(traitor.current, /mob/living/silicon)) if(istype(traitor.current, /mob/living/silicon))
var/datum/objective/assassinate/kill_objective = new var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = traitor kill_objective.owner = traitor

View File

@@ -64,6 +64,9 @@
/datum/game_mode/proc/forge_wizard_objectives(var/datum/mind/wizard) /datum/game_mode/proc/forge_wizard_objectives(var/datum/mind/wizard)
if (config.objectives_disabled)
return
switch(rand(1,100)) switch(rand(1,100))
if(1 to 30) if(1 to 30)

View File

@@ -91,11 +91,11 @@
H.equip_to_slot_or_del(new /obj/item/clothing/suit/apron(H), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/clothing/suit/apron(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/device/analyzer/plant_analyzer(H), slot_s_store) H.equip_to_slot_or_del(new /obj/item/device/analyzer/plant_analyzer(H), slot_s_store)
H.equip_to_slot_or_del(new /obj/item/device/pda/botanist(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/device/pda/botanist(H), slot_belt)
if(H.backbag == 3) switch(H.backbag)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_hyd(H), slot_back) if(1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else if(H.backbag == 1) if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_hyd(H), slot_back)
else if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
return 1 return 1

View File

@@ -71,8 +71,12 @@
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/virologist(H), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/virologist(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/virologist(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/virologist(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/mask/surgical(H), slot_wear_mask) H.equip_to_slot_or_del(new /obj/item/clothing/mask/surgical(H), slot_wear_mask)
if(H.backbag == 3) switch(H.backbag)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_vir(H), slot_back) if(1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
if("Medical Doctor") if("Medical Doctor")
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit)
@@ -122,11 +126,11 @@
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/device/pda/chemist(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/device/pda/chemist(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/chemist(H), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/chemist(H), slot_wear_suit)
if(H.backbag == 3) switch(H.backbag)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_chem(H), slot_back) if(1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else if(H.backbag == 1) if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_chem(H), slot_back)
else if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
return 1 return 1
@@ -153,11 +157,11 @@
H.equip_to_slot_or_del(new /obj/item/device/pda/geneticist(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/device/pda/geneticist(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/genetics(H), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/genetics(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/device/flashlight/pen(H), slot_s_store) H.equip_to_slot_or_del(new /obj/item/device/flashlight/pen(H), slot_s_store)
if(H.backbag == 3) switch(H.backbag)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_gen(H), slot_back) if(1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else if(H.backbag == 1) if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_gen(H), slot_back)
else if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
return 1 return 1

View File

@@ -27,11 +27,11 @@
H.equip_to_slot_or_del(new /obj/item/device/pda/heads/rd(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/device/pda/heads/rd(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/weapon/clipboard(H), slot_l_hand) H.equip_to_slot_or_del(new /obj/item/weapon/clipboard(H), slot_l_hand)
if(H.backbag == 3) switch(H.backbag)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back) if(1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else if(H.backbag == 1) if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
else if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
return 1 return 1
@@ -57,11 +57,11 @@
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/device/pda/science(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/device/pda/science(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/science(H), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/science(H), slot_wear_suit)
if(H.backbag == 3) switch(H.backbag)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back) if(1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else if(H.backbag == 1) if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
else if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
return 1 return 1
@@ -86,11 +86,11 @@
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/device/pda/science(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/device/pda/science(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/science(H), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/science(H), slot_wear_suit)
if(H.backbag == 3) switch(H.backbag)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back) if(1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else if(H.backbag == 1) if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
else if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
return 1 return 1

View File

@@ -36,8 +36,6 @@ var/list/whitelist = list()
return 1 return 1
if(species == "human" || species == "Human") if(species == "human" || species == "Human")
return 1 return 1
if(species == "machine" || species == "Machine")
return 1
if(check_rights(R_ADMIN, 0)) if(check_rights(R_ADMIN, 0))
return 1 return 1
if(!alien_whitelist) if(!alien_whitelist)

View File

@@ -308,6 +308,13 @@
robot = "Prosthetic:" robot = "Prosthetic:"
if(e.open) if(e.open)
open = "Open:" open = "Open:"
switch (e.germ_level)
if (INFECTION_LEVEL_ONE + 50 to INFECTION_LEVEL_TWO)
infected = "Mild Infection:"
if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_THREE)
infected = "Acute Infection:"
if (INFECTION_LEVEL_THREE to INFINITY)
infected = "Septic:"
var/unknown_body = 0 var/unknown_body = 0
for(var/I in e.implants) for(var/I in e.implants)
@@ -332,8 +339,16 @@
mech = "Assisted:" mech = "Assisted:"
if(i.robotic == 2) if(i.robotic == 2)
mech = "Mechanical:" mech = "Mechanical:"
var/infection = "None"
switch (i.germ_level)
if (1 to INFECTION_LEVEL_TWO)
infection = "Mild Infection:"
if (INFECTION_LEVEL_TWO to INFINITY)
infection = "Acute Infection:"
dat += "<tr>" dat += "<tr>"
dat += "<td>[i.name]</td><td>N/A</td><td>[i.damage]</td><td>None:[mech]</td><td></td>" dat += "<td>[i.name]</td><td>N/A</td><td>[i.damage]</td><td>[infection]:[mech]</td><td></td>"
dat += "</tr>" dat += "</tr>"
dat += "</table>" dat += "</table>"
if(occupant.sdisabilities & BLIND) if(occupant.sdisabilities & BLIND)

View File

@@ -1325,7 +1325,7 @@ FIRE ALARM
else else
icon_state = "fire0" icon_state = "fire0"
/obj/machinery/firealarm/temperature_expose(datum/gas_mixture/air, temperature, volume) /obj/machinery/firealarm/fire_act(datum/gas_mixture/air, temperature, volume)
if(src.detecting) if(src.detecting)
if(temperature > T0C+200) if(temperature > T0C+200)
src.alarm() // added check of detector status here src.alarm() // added check of detector status here

View File

@@ -110,7 +110,7 @@ update_flag
overlays += "can-o3" overlays += "can-o3"
return return
/obj/machinery/portable_atmospherics/canister/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/machinery/portable_atmospherics/canister/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > temperature_resistance) if(exposed_temperature > temperature_resistance)
health -= 5 health -= 5
healthcheck() healthcheck()

View File

@@ -304,6 +304,21 @@
user.drop_item() user.drop_item()
del(W) del(W)
return return
else if (istype(W, /obj/item/weapon/wrench))
if(src.locked && (src.anchored || src.occupant))
user << "\red Can not do that while [src] is in use."
else
if(src.anchored)
src.anchored = 0
connected.pod1 = null
connected = null
else
src.anchored = 1
playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
if(anchored)
user.visible_message("[user] secures [src] to the floor.", "You secure [src] to the floor.")
else
user.visible_message("[user] unsecures [src] from the floor.", "You unsecure [src] from the floor.")
else else
..() ..()

View File

@@ -108,13 +108,9 @@
/obj/machinery/computer/crew/proc/scan() /obj/machinery/computer/crew/proc/scan()
for(var/obj/item/clothing/under/C in world) for(var/mob/living/carbon/human/H in mob_list)
if((C.has_sensor) && (istype(C.loc, /mob/living/carbon/human))) if(istype(H.w_uniform, /obj/item/clothing/under))
var/check = 0 var/obj/item/clothing/under/C = H.w_uniform
for(var/O in src.tracked) if (C.has_sensor)
if(O == C) tracked |= C
check = 1
break
if(!check)
src.tracked.Add(C)
return 1 return 1

View File

@@ -277,7 +277,7 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }.
icon = 'icons/obj/doors/Doorphoron.dmi' icon = 'icons/obj/doors/Doorphoron.dmi'
mineral = "phoron" mineral = "phoron"
/obj/machinery/door/airlock/phoron/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/machinery/door/airlock/phoron/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300) if(exposed_temperature > 300)
PhoronBurn(exposed_temperature) PhoronBurn(exposed_temperature)

View File

@@ -26,7 +26,7 @@
********************/ ********************/
/obj/machinery/microwave/New() /obj/machinery/microwave/New()
//..() //do not need this ..()
reagents = new/datum/reagents(100) reagents = new/datum/reagents(100)
reagents.my_atom = src reagents.my_atom = src
if (!available_recipes) if (!available_recipes)

View File

@@ -92,7 +92,7 @@ Growing it to term with nothing injected will grab a ghost from the observers. *
/obj/item/seeds/replicapod/proc/request_player() /obj/item/seeds/replicapod/proc/request_player()
for(var/mob/dead/observer/O in player_list) for(var/mob/dead/observer/O in player_list)
if(jobban_isbanned(O, "Dionaea")) if(jobban_isbanned(O, "Dionaea") || (!is_alien_whitelisted(src, "Diona") && config.usealienwhitelist))
continue continue
if(O.client) if(O.client)
if(O.client.prefs.be_special & BE_PLANT) if(O.client.prefs.be_special & BE_PLANT)
@@ -101,7 +101,7 @@ Growing it to term with nothing injected will grab a ghost from the observers. *
/obj/item/seeds/replicapod/proc/question(var/client/C) /obj/item/seeds/replicapod/proc/question(var/client/C)
spawn(0) spawn(0)
if(!C) return if(!C) return
var/response = alert(C, "Someone is harvesting a replica pod. Would you like to play as a Dionaea?", "Replica pod harvest", "Yes", "No", "Never for this round.") var/response = alert(C, "Someone is harvesting a diona pod. Would you like to play as a diona?", "Dionaea harvest", "Yes", "No", "Never for this round.")
if(!C || ckey) if(!C || ckey)
return return
if(response == "Yes") if(response == "Yes")

View File

@@ -618,7 +618,7 @@
check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1) check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1)
return return
/obj/mecha/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/mecha/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature>src.max_temperature) if(exposed_temperature>src.max_temperature)
src.log_message("Exposed to dangerous temperature.",1) src.log_message("Exposed to dangerous temperature.",1)
src.take_damage(5,"fire") src.take_damage(5,"fire")

View File

@@ -287,7 +287,7 @@ Alien plants should do something if theres a lot of poison
del(src) del(src)
/obj/effect/alien/weeds/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/effect/alien/weeds/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300) if(exposed_temperature > 300)
health -= 5 health -= 5
healthcheck() healthcheck()
@@ -469,7 +469,7 @@ Alien plants should do something if theres a lot of poison
if(health <= 0) if(health <= 0)
Burst() Burst()
/obj/effect/alien/egg/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/effect/alien/egg/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 500) if(exposed_temperature > 500)
health -= 5 health -= 5
healthcheck() healthcheck()

View File

@@ -27,24 +27,6 @@ would spawn and follow the beaker, even if it is carried or thrown.
reagents.delete() reagents.delete()
return return
/obj/effect/effect/water/New()
..()
//var/turf/T = src.loc
//if (istype(T, /turf))
// T.firelevel = 0 //TODO: FIX
spawn( 70 )
delete()
return
return
/obj/effect/effect/water/Del()
//var/turf/T = src.loc
//if (istype(T, /turf))
// T.firelevel = 0 //TODO: FIX
..()
return
/obj/effect/effect/water/Move(turf/newloc) /obj/effect/effect/water/Move(turf/newloc)
//var/turf/T = src.loc //var/turf/T = src.loc
//if (istype(T, /turf)) //if (istype(T, /turf))
@@ -559,7 +541,7 @@ steam.start() -- spawns the effect
// foam disolves when heated // foam disolves when heated
// except metal foams // except metal foams
/obj/effect/effect/foam/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/effect/effect/foam/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(!metal && prob(max(0, exposed_temperature - 475))) if(!metal && prob(max(0, exposed_temperature - 475)))
flick("[icon_state]-disolve", src) flick("[icon_state]-disolve", src)

View File

@@ -154,7 +154,7 @@
else else
return return
/obj/effect/glowshroom/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/effect/glowshroom/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300) if(exposed_temperature > 300)
endurance -= 5 endurance -= 5
CheckEndurance() CheckEndurance()

View File

@@ -47,7 +47,7 @@
if(health <= 0) if(health <= 0)
del(src) del(src)
/obj/effect/spider/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/effect/spider/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300) if(exposed_temperature > 300)
health -= 5 health -= 5
healthcheck() healthcheck()

View File

@@ -92,6 +92,17 @@ REAGENT SCANNER
usr << "\red You don't have the dexterity to do this!" usr << "\red You don't have the dexterity to do this!"
return return
user.visible_message("<span class='notice'> [user] has analyzed [M]'s vitals.","<span class='notice'> You have analyzed [M]'s vitals.") user.visible_message("<span class='notice'> [user] has analyzed [M]'s vitals.","<span class='notice'> You have analyzed [M]'s vitals.")
if (!istype(M, /mob/living/carbon) || (ishuman(M) && (M:species.flags & IS_SYNTHETIC)))
//these sensors are designed for organic life
user.show_message("\blue Analyzing Results for ERROR:\n\t Overall Status: ERROR")
user.show_message("\t Key: <font color='blue'>Suffocation</font>/<font color='green'>Toxin</font>/<font color='#FFA500'>Burns</font>/<font color='red'>Brute</font>", 1)
user.show_message("\t Damage Specifics: <font color='blue'>?</font> - <font color='green'>?</font> - <font color='#FFA500'>?</font> - <font color='red'>?</font>")
user.show_message("\blue Body Temperature: [M.bodytemperature-T0C]&deg;C ([M.bodytemperature*1.8-459.67]&deg;F)", 1)
user.show_message("\red <b>Warning: Blood Level ERROR: --% --cl.\blue Type: ERROR")
user.show_message("\blue Subject's pulse: <font color='red'>-- bpm.</font>")
return
var/fake_oxy = max(rand(1,40), M.getOxyLoss(), (300 - (M.getToxLoss() + M.getFireLoss() + M.getBruteLoss()))) var/fake_oxy = max(rand(1,40), M.getOxyLoss(), (300 - (M.getToxLoss() + M.getFireLoss() + M.getBruteLoss())))
var/OX = M.getOxyLoss() > 50 ? "<b>[M.getOxyLoss()]</b>" : M.getOxyLoss() var/OX = M.getOxyLoss() > 50 ? "<b>[M.getOxyLoss()]</b>" : M.getOxyLoss()
var/TX = M.getToxLoss() > 50 ? "<b>[M.getToxLoss()]</b>" : M.getToxLoss() var/TX = M.getToxLoss() > 50 ? "<b>[M.getToxLoss()]</b>" : M.getToxLoss()
@@ -161,7 +172,7 @@ REAGENT SCANNER
if(e.status & ORGAN_BROKEN) if(e.status & ORGAN_BROKEN)
if(((e.name == "l_arm") || (e.name == "r_arm") || (e.name == "l_leg") || (e.name == "r_leg")) && (!(e.status & ORGAN_SPLINTED))) if(((e.name == "l_arm") || (e.name == "r_arm") || (e.name == "l_leg") || (e.name == "r_leg")) && (!(e.status & ORGAN_SPLINTED)))
user << "\red Unsecured fracture in subject [limb]. Splinting recommended for transport." user << "\red Unsecured fracture in subject [limb]. Splinting recommended for transport."
if(e.is_infected()) if(e.has_infected_wound())
user << "\red Infected wound detected in subject [limb]. Disinfection recommended." user << "\red Infected wound detected in subject [limb]. Disinfection recommended."
for(var/name in H.organs_by_name) for(var/name in H.organs_by_name)

View File

@@ -0,0 +1,177 @@
/obj/item/device/suit_cooling_unit
name = "portable suit cooling unit"
desc = "A portable heat sink and liquid cooled radiator that can be hooked up to a space suit's existing temperature controls to provide industrial levels of cooling."
w_class = 4
icon = 'icons/obj/device.dmi' //temporary, I hope
icon_state = "suitcooler0"
slot_flags = SLOT_BACK //you can carry it on your back if you want, but it won't do anything unless attached to suit storage
var/on = 0 //is it turned on?
var/cover_open = 0 //is the cover open?
var/obj/item/weapon/cell/cell
var/max_cooling = 12 //in degrees per second - probably don't need to mess with heat capacity here
var/charge_consumption = 16.6 //charge per second at max_cooling
var/thermostat = T20C
//TODO: make it heat up the surroundings when not in space
/obj/item/device/suit_cooling_unit/New()
processing_objects |= src
cell = new/obj/item/weapon/cell() //comes with the crappy default power cell - high-capacity ones shouldn't be hard to find
cell.loc = src
/obj/item/device/suit_cooling_unit/process()
if (!on || !cell)
return
if (!ismob(loc))
return
if (!attached_to_suit(loc)) //make sure they have a suit and we are attached to it
return
var/mob/living/carbon/human/H = loc
var/efficiency = H.get_pressure_protection() //you need to have a good seal for effective cooling
var/env_temp = get_environment_temperature() //wont save you from a fire
var/temp_adj = min(H.bodytemperature - max(thermostat, env_temp), max_cooling)
if (temp_adj < 0.5) //only cools, doesn't heat, also we don't need extreme precision
return
var/charge_usage = (temp_adj/max_cooling)*charge_consumption
H.bodytemperature -= temp_adj*efficiency
cell.use(charge_usage)
if(cell.charge <= 0)
turn_off()
/obj/item/device/suit_cooling_unit/proc/get_environment_temperature()
if (ishuman(loc))
var/mob/living/carbon/human/H = loc
if(istype(H.loc, /obj/mecha))
var/obj/mecha/M = loc
return M.return_temperature()
else if(istype(H.loc, /obj/machinery/atmospherics/unary/cryo_cell))
return H.loc:air_contents.temperature
var/turf/T = get_turf(src)
if(istype(T, /turf/space))
return 0 //space has no temperature, this just makes sure the cooling unit works in space
var/datum/gas_mixture/environment = T.return_air()
if (!environment)
return 0
return environment.temperature
/obj/item/device/suit_cooling_unit/proc/attached_to_suit(mob/M)
if (!ishuman(M))
return 0
var/mob/living/carbon/human/H = M
if (!H.wear_suit || H.s_store != src)
return 0
return 1
/obj/item/device/suit_cooling_unit/proc/turn_on()
if(!cell)
return
if(cell.charge <= 0)
return
on = 1
updateicon()
/obj/item/device/suit_cooling_unit/proc/turn_off()
if (ismob(src.loc))
var/mob/M = src.loc
M.show_message("\The [src] clicks and whines as it powers down.", 2) //let them know in case it's run out of power.
on = 0
updateicon()
/obj/item/device/suit_cooling_unit/attack_self(mob/user as mob)
if(cover_open && cell)
if(ishuman(user))
user.put_in_hands(cell)
else
cell.loc = get_turf(loc)
cell.add_fingerprint(user)
cell.updateicon()
user << "You remove the [src.cell]."
src.cell = null
updateicon()
return
//TODO use a UI like the air tanks
if(on)
turn_off()
else
turn_on()
if (on)
user << "You switch on the [src]."
/obj/item/device/suit_cooling_unit/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/screwdriver))
if(cover_open)
cover_open = 0
user << "You screw the panel into place."
else
cover_open = 1
user << "You unscrew the panel."
updateicon()
return
if (istype(W, /obj/item/weapon/cell))
if(cover_open)
if(cell)
user << "There is a [cell] already installed here."
else
user.drop_item()
W.loc = src
cell = W
user << "You insert the [cell]."
updateicon()
return
return ..()
/obj/item/device/suit_cooling_unit/proc/updateicon()
if (cover_open)
if (cell)
icon_state = "suitcooler1"
else
icon_state = "suitcooler2"
else
icon_state = "suitcooler0"
/obj/item/device/suit_cooling_unit/examine()
set src in view(1)
..()
if (on)
if (attached_to_suit(src.loc))
usr << "It's switched on and running."
else
usr << "It's switched on, but not attached to anything."
else
usr << "It is switched off."
if (cover_open)
if(cell)
usr << "The panel is open, exposing the [cell]."
else
usr << "The panel is open."
if (cell)
usr << "The charge meter reads [round(cell.percent())]%."
else
usr << "It doesn't have a power cell installed."

View File

@@ -38,7 +38,7 @@
/obj/item/latexballon/bullet_act() /obj/item/latexballon/bullet_act()
burst() burst()
/obj/item/latexballon/temperature_expose(datum/gas_mixture/air, temperature, volume) /obj/item/latexballon/fire_act(datum/gas_mixture/air, temperature, volume)
if(temperature > T0C+100) if(temperature > T0C+100)
burst() burst()
return return

View File

@@ -117,7 +117,7 @@
//Step two - washing..... it's actually in washing machine code. //Step two - washing..... it's actually in washing machine code.
//Step three - drying //Step three - drying
/obj/item/stack/sheet/wetleather/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/item/stack/sheet/wetleather/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
..() ..()
if(exposed_temperature >= drying_threshold_temperature) if(exposed_temperature >= drying_threshold_temperature)
wetness-- wetness--

View File

@@ -1,14 +1,18 @@
/* Toys! /* Toys!
* ContainsL * Contains:
* Balloons * Balloons
* Fake telebeacon * Fake telebeacon
* Fake singularity * Fake singularity
* Toy gun * Toy gun
* Toy crossbow * Toy crossbow
* Toy swords * Toy swords
* Toy mechs
* Crayons * Crayons
* Snap pops * Snap pops
* Water flower * Water flower
* Therapy dolls
* Toddler doll
* Inflatable duck
*/ */
@@ -579,6 +583,55 @@
w_class = 3 w_class = 3
attack_verb = list("attacked", "slashed", "stabbed", "sliced") attack_verb = list("attacked", "slashed", "stabbed", "sliced")
/obj/item/toy/therapy_red
name = "red therapy doll"
desc = "A toy for therapeutic and recreational purposes. This one is red."
icon = 'icons/obj/weapons.dmi'
icon_state = "therapyred"
item_state = "egg4" // It's the red egg in items_left/righthand
w_class = 1
/obj/item/toy/therapy_purple
name = "purple therapy doll"
desc = "A toy for therapeutic and recreational purposes. This one is purple."
icon = 'icons/obj/weapons.dmi'
icon_state = "therapypurple"
item_state = "egg1" // It's the magenta egg in items_left/righthand
w_class = 1
/obj/item/toy/therapy_blue
name = "blue therapy doll"
desc = "A toy for therapeutic and recreational purposes. This one is blue."
icon = 'icons/obj/weapons.dmi'
icon_state = "therapyblue"
item_state = "egg2" // It's the blue egg in items_left/righthand
w_class = 1
/obj/item/toy/therapy_yellow
name = "yellow therapy doll"
desc = "A toy for therapeutic and recreational purposes. This one is yellow."
icon = 'icons/obj/weapons.dmi'
icon_state = "therapyyellow"
item_state = "egg5" // It's the yellow egg in items_left/righthand
w_class = 1
/obj/item/toy/therapy_orange
name = "orange therapy doll"
desc = "A toy for therapeutic and recreational purposes. This one is orange."
icon = 'icons/obj/weapons.dmi'
icon_state = "therapyorange"
item_state = "egg4" // It's the red one again, lacking an orange item_state and making a new one is pointless
w_class = 1
/obj/item/toy/therapy_green
name = "green therapy doll"
desc = "A toy for therapeutic and recreational purposes. This one is green."
icon = 'icons/obj/weapons.dmi'
icon_state = "therapygreen"
item_state = "egg3" // It's the green egg in items_left/righthand
w_class = 1
/* NYET. /* NYET.
/obj/item/weapon/toddler /obj/item/weapon/toddler
icon_state = "toddler" icon_state = "toddler"
@@ -590,6 +643,7 @@
*/ */
//This should really be somewhere else but I don't know where. w/e //This should really be somewhere else but I don't know where. w/e
/obj/item/weapon/inflatable_duck /obj/item/weapon/inflatable_duck
name = "inflatable duck" name = "inflatable duck"
desc = "No bother to sink or swim when you can just float!" desc = "No bother to sink or swim when you can just float!"

View File

@@ -127,6 +127,7 @@
W.reagents.reaction(atm) W.reagents.reaction(atm)
if(W.loc == my_target) break if(W.loc == my_target) break
sleep(2) sleep(2)
W.delete()
if((istype(usr.loc, /turf/space)) || (usr.lastarea.has_gravity == 0)) if((istype(usr.loc, /turf/space)) || (usr.lastarea.has_gravity == 0))
user.inertia_dir = get_dir(target, user) user.inertia_dir = get_dir(target, user)

View File

@@ -7,19 +7,21 @@
prime() prime()
..() ..()
for(var/obj/structure/closet/L in view(get_turf(src), null)) for(var/obj/structure/closet/L in hear(7, get_turf(src)))
if(locate(/mob/living/carbon/, L)) if(locate(/mob/living/carbon/, L))
for(var/mob/living/carbon/M in L) for(var/mob/living/carbon/M in L)
bang(get_turf(src), M) bang(get_turf(src), M)
for(var/mob/living/carbon/M in viewers(get_turf(src), null)) for(var/mob/living/carbon/M in hear(7, get_turf(src)))
bang(get_turf(src), M) bang(get_turf(src), M)
for(var/obj/effect/blob/B in view(8,get_turf(src))) //Blob damage here for(var/obj/effect/blob/B in hear(8,get_turf(src))) //Blob damage here
var/damage = round(30/(get_dist(B,get_turf(src))+1)) var/damage = round(30/(get_dist(B,get_turf(src))+1))
B.health -= damage B.health -= damage
B.update_icon() B.update_icon()
new/obj/effect/effect/smoke/flashbang(src.loc)
del(src) del(src)
return return
@@ -30,7 +32,7 @@
S.icon_state = "shield0" S.icon_state = "shield0"
M << "\red <B>BANG</B>" M << "\red <B>BANG</B>"
playsound(src.loc, 'sound/effects/bang.ogg', 25, 1) playsound(src.loc, 'sound/effects/bang.ogg', 50, 1, 5)
//Checking for protections //Checking for protections
var/eye_safety = 0 var/eye_safety = 0
@@ -98,6 +100,15 @@
M << "\red Your ears start to ring!" M << "\red Your ears start to ring!"
M.update_icons() M.update_icons()
/obj/effect/effect/smoke/flashbang
name = "illumination"
time_to_live = 10
opacity = 0
icon_state = "sparks"
/obj/effect/effect/smoke/flashbang/New()
..()
SetLuminosity(15)
/obj/item/weapon/grenade/flashbang/clusterbang//Created by Polymorph, fixed by Sieve /obj/item/weapon/grenade/flashbang/clusterbang//Created by Polymorph, fixed by Sieve
desc = "Use of this weapon may constiute a war crime in your area, consult your local captain." desc = "Use of this weapon may constiute a war crime in your area, consult your local captain."

View File

@@ -25,86 +25,65 @@
flags = FPRINT | TABLEPASS | CONDUCT flags = FPRINT | TABLEPASS | CONDUCT
origin_tech = "materials=1" origin_tech = "materials=1"
attack_verb = list("attacked", "stabbed", "poked") attack_verb = list("attacked", "stabbed", "poked")
sharp = 0
var/loaded //Descriptive string for currently loaded food object.
/obj/item/weapon/kitchen/utensil/New() /obj/item/weapon/kitchen/utensil/New()
if (prob(60)) if (prob(60))
src.pixel_y = rand(0, 4) src.pixel_y = rand(0, 4)
return return
/* create_reagents(5)
* Spoons
*/
/obj/item/weapon/kitchen/utensil/spoon
name = "spoon"
desc = "SPOON!"
icon_state = "spoon"
attack_verb = list("attacked", "poked")
/obj/item/weapon/kitchen/utensil/pspoon /obj/item/weapon/kitchen/utensil/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
name = "plastic spoon"
desc = "Super dull action!"
icon_state = "pspoon"
attack_verb = list("attacked", "poked")
/*
* Forks
*/
/obj/item/weapon/kitchen/utensil/fork
name = "fork"
desc = "Pointy."
icon_state = "fork"
sharp = 1
/obj/item/weapon/kitchen/utensil/fork/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(!istype(M)) if(!istype(M))
return ..() return ..()
if(user.zone_sel.selecting != "eyes" && user.zone_sel.selecting != "head") if(user.a_intent != "help")
return ..() if(user.zone_sel.selecting == "head" || user.zone_sel.selecting == "eyes")
if (src.icon_state == "forkloaded") //This is a poor way of handling it, but a proper rewrite of the fork to allow for a more varied foodening can happen when I'm in the mood. --NEO
if(M == user)
for(var/mob/O in viewers(M, null))
O.show_message(text("\blue [] eats a delicious forkful of omelette!", user), 1)
M.reagents.add_reagent("nutriment", 1)
else
for(var/mob/O in viewers(M, null))
O.show_message(text("\blue [] feeds [] a delicious forkful of omelette!", user, M), 1)
M.reagents.add_reagent("nutriment", 1)
src.icon_state = "fork"
return
else
if((CLUMSY in user.mutations) && prob(50)) if((CLUMSY in user.mutations) && prob(50))
M = user M = user
return eyestab(M,user) return eyestab(M,user)
else
return ..()
if (reagents.total_volume > 0)
reagents.trans_to_ingest(M, reagents.total_volume)
if(M == user)
for(var/mob/O in viewers(M, null))
O.show_message(text("\blue [] eats some [] from \the [].", user, loaded, src), 1)
M.reagents.add_reagent("nutriment", 1)
else
for(var/mob/O in viewers(M, null))
O.show_message(text("\blue [] feeds [] some [] from \the []", user, M, loaded, src), 1)
M.reagents.add_reagent("nutriment", 1)
overlays.Cut()
return
/obj/item/weapon/kitchen/utensil/fork
name = "fork"
desc = "It's a fork. Sure is pointy."
icon_state = "fork"
sharp = 1
/obj/item/weapon/kitchen/utensil/pfork /obj/item/weapon/kitchen/utensil/pfork
name = "plastic fork" name = "plastic fork"
desc = "Yay, no washing up to do." desc = "Yay, no washing up to do."
icon_state = "pfork" icon_state = "pfork"
/obj/item/weapon/kitchen/utensil/pfork/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) /obj/item/weapon/kitchen/utensil/spoon
if(!istype(M)) name = "spoon"
return ..() desc = "It's a spoon. You can see your own upside-down face in it."
icon_state = "spoon"
attack_verb = list("attacked", "poked")
if(user.zone_sel.selecting != "eyes" && user.zone_sel.selecting != "head") /obj/item/weapon/kitchen/utensil/pspoon
return ..() name = "plastic spoon"
desc = "It's a plastic spoon. How dull."
if (src.icon_state == "forkloaded") //This is a poor way of handling it, but a proper rewrite of the fork to allow for a more varied foodening can happen when I'm in the mood. --NEO icon_state = "pspoon"
if(M == user) attack_verb = list("attacked", "poked")
for(var/mob/O in viewers(M, null))
O.show_message(text("\blue [] eats a delicious forkful of omelette!", user), 1)
M.reagents.add_reagent("nutriment", 1)
else
for(var/mob/O in viewers(M, null))
O.show_message(text("\blue [] feeds [] a delicious forkful of omelette!", user, M), 1)
M.reagents.add_reagent("nutriment", 1)
src.icon_state = "fork"
return
else
if((CLUMSY in user.mutations) && prob(50))
M = user
return eyestab(M,user)
/* /*
* Knives * Knives
@@ -478,48 +457,3 @@
if(I) if(I)
step(I, pick(NORTH,SOUTH,EAST,WEST)) step(I, pick(NORTH,SOUTH,EAST,WEST))
sleep(rand(2,4)) sleep(rand(2,4))
/////////////////////////////////////////////////////////////////////////////////////////
//Enough with the violent stuff, here's what happens if you try putting food on it
/////////////////////////////////////////////////////////////////////////////////////////////
/*/obj/item/weapon/tray/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W,/obj/item/weapon/kitchen/utensil/fork))
if (W.icon_state == "forkloaded")
user << "\red You already have omelette on your fork."
return
W.icon = 'icons/obj/kitchen.dmi'
W.icon_state = "forkloaded"
viewers(3,user) << "[user] takes a piece of omelette with his fork!"
reagents.remove_reagent("nutriment", 1)
if (reagents.total_volume <= 0)
del(src)*/
/* if (prob(33))
var/turf/location = H.loc
if (istype(location, /turf/simulated))
location.add_blood(H)
if (H.wear_mask)
H.wear_mask.add_blood(H)
if (H.head)
H.head.add_blood(H)
if (H.glasses && prob(33))
H.glasses.add_blood(H)
if (istype(user, /mob/living/carbon/human))
var/mob/living/carbon/human/user2 = user
if (user2.gloves)
user2.gloves.add_blood(H)
else
user2.add_blood(H)
if (prob(15))
if (user2.wear_suit)
user2.wear_suit.add_blood(H)
else if (user2.w_uniform)
user2.w_uniform.add_blood(H)*/

View File

@@ -182,16 +182,12 @@ datum/reagent/paint
reaction_turf(var/turf/T, var/volume) reaction_turf(var/turf/T, var/volume)
if(!istype(T) || istype(T, /turf/space)) if(!istype(T) || istype(T, /turf/space))
return return
var/ind = "[initial(T.icon)][color]" T.color = color
if(!cached_icons[ind])
var/icon/overlay = new/icon(initial(T.icon)) reaction_obj(var/obj/O, var/volume)
overlay.Blend(color,ICON_MULTIPLY) ..()
overlay.SetIntensity(1.4) if(istype(O,/obj/item/weapon/light))
T.icon = overlay O.color = color
cached_icons[ind] = T.icon
else
T.icon = cached_icons[ind]
return
red red
name = "Red Paint" name = "Red Paint"

View File

@@ -48,6 +48,8 @@
/obj/item/weapon/storage/box/gloves /obj/item/weapon/storage/box/gloves
name = "box of latex gloves" name = "box of latex gloves"
desc = "Contains white gloves." desc = "Contains white gloves."
icon_state = "latex"
New() New()
..() ..()
new /obj/item/clothing/gloves/latex(src) new /obj/item/clothing/gloves/latex(src)

View File

@@ -6,6 +6,7 @@
icon = 'icons/obj/tank.dmi' icon = 'icons/obj/tank.dmi'
flags = FPRINT | TABLEPASS | CONDUCT flags = FPRINT | TABLEPASS | CONDUCT
slot_flags = SLOT_BACK slot_flags = SLOT_BACK
w_class = 3
pressure_resistance = ONE_ATMOSPHERE*5 pressure_resistance = ONE_ATMOSPHERE*5

View File

@@ -121,6 +121,8 @@
/obj/proc/hear_talk(mob/M as mob, text) /obj/proc/hear_talk(mob/M as mob, text)
if(talking_atom)
talking_atom.catchMessage(text, M)
/* /*
var/mob/mo = locate(/mob) in src var/mob/mo = locate(/mob) in src
if(mo) if(mo)

View File

@@ -216,7 +216,7 @@
return 0 return 0
return 0 return 0
/obj/structure/grille/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/structure/grille/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(!destroyed) if(!destroyed)
if(exposed_temperature > T0C + 1500) if(exposed_temperature > T0C + 1500)
health -= 1 health -= 1

View File

@@ -82,6 +82,7 @@
state = 1 state = 1
update_icon() update_icon()
isSwitchingStates = 0 isSwitchingStates = 0
update_nearby_tiles()
proc/Close() proc/Close()
isSwitchingStates = 1 isSwitchingStates = 1
@@ -93,6 +94,7 @@
state = 0 state = 0
update_icon() update_icon()
isSwitchingStates = 0 isSwitchingStates = 0
update_nearby_tiles()
update_icon() update_icon()
if(state) if(state)
@@ -198,7 +200,7 @@
TemperatureAct(100) TemperatureAct(100)
..() ..()
temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300) if(exposed_temperature > 300)
TemperatureAct(exposed_temperature) TemperatureAct(exposed_temperature)

View File

@@ -361,7 +361,7 @@
return return
/obj/structure/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/structure/window/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > T0C + 800) if(exposed_temperature > T0C + 800)
hit(round(exposed_volume / 100), 0) hit(round(exposed_volume / 100), 0)
..() ..()
@@ -381,7 +381,7 @@
shardtype = /obj/item/weapon/shard/phoron shardtype = /obj/item/weapon/shard/phoron
health = 120 health = 120
/obj/structure/window/phoronbasic/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/structure/window/phoronbasic/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > T0C + 32000) if(exposed_temperature > T0C + 32000)
hit(round(exposed_volume / 1000), 0) hit(round(exposed_volume / 1000), 0)
..() ..()
@@ -395,7 +395,7 @@
reinf = 1 reinf = 1
health = 160 health = 160
/obj/structure/window/phoronreinforced/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/structure/window/phoronreinforced/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return return
/obj/structure/window/reinforced /obj/structure/window/reinforced

View File

@@ -144,8 +144,11 @@
for(var/obj/effect/decal/cleanable/blood/B in contents) for(var/obj/effect/decal/cleanable/blood/B in contents)
if(!B.blood_DNA[M.dna.unique_enzymes]) if(!B.blood_DNA[M.dna.unique_enzymes])
B.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type B.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
B.virus2 = virus_copylist(M.virus2)
return 1 //we bloodied the floor return 1 //we bloodied the floor
//if there isn't a blood decal already, make one. //if there isn't a blood decal already, make one.
var/obj/effect/decal/cleanable/blood/newblood = new /obj/effect/decal/cleanable/blood(src) var/obj/effect/decal/cleanable/blood/newblood = new /obj/effect/decal/cleanable/blood(src)
@@ -156,6 +159,7 @@
newblood.basecolor = "#A10808" newblood.basecolor = "#A10808"
newblood.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type newblood.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
newblood.virus2 = virus_copylist(M.virus2)
newblood.update_icon() newblood.update_icon()
return 1 //we bloodied the floor return 1 //we bloodied the floor

View File

@@ -104,7 +104,7 @@
for(var/obj/machinery/door/airlock/phoron/D in range(3,src)) for(var/obj/machinery/door/airlock/phoron/D in range(3,src))
D.ignite(temperature/4) D.ignite(temperature/4)
/turf/simulated/wall/mineral/phoron/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)//Doesn't fucking work because walls don't interact with air :( /turf/simulated/wall/mineral/phoron/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)//Doesn't fucking work because walls don't interact with air :(
if(exposed_temperature > 300) if(exposed_temperature > 300)
PhoronBurn(exposed_temperature) PhoronBurn(exposed_temperature)

View File

@@ -252,3 +252,6 @@ var/DBConnection/dbcon_old = new() //Tgstation database (Old database) - See the
// Reference list for disposal sort junctions. Filled up by sorting junction's New() // Reference list for disposal sort junctions. Filled up by sorting junction's New()
/var/list/tagger_locations = list() /var/list/tagger_locations = list()
//added for Xenoarchaeology, might be useful for other stuff
var/global/list/alphabet_uppercase = list("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z")

View File

@@ -114,7 +114,7 @@
//play the recieving admin the adminhelp sound (if they have them enabled) //play the recieving admin the adminhelp sound (if they have them enabled)
//non-admins shouldn't be able to disable this //non-admins shouldn't be able to disable this
if(C.prefs.toggles & SOUND_ADMINHELP) if(C.prefs && C.prefs.toggles & SOUND_ADMINHELP)
C << 'sound/effects/adminhelp.ogg' C << 'sound/effects/adminhelp.ogg'
log_admin("PM: [key_name(src)]->[key_name(C)]: [msg]") log_admin("PM: [key_name(src)]->[key_name(C)]: [msg]")

View File

@@ -220,7 +220,7 @@ BLIND // can't see anything
permeability_coefficient = 0.02 permeability_coefficient = 0.02
flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE | THICKMATERIAL flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE | THICKMATERIAL
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen) allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/device/suit_cooling_unit)
slowdown = 3 slowdown = 3
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50) armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL

View File

@@ -13,7 +13,7 @@
desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins." desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins."
icon_state = "s-ninja" icon_state = "s-ninja"
item_state = "s-ninja_suit" item_state = "s-ninja_suit"
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/weapon/cell) allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/cell)
slowdown = 0 slowdown = 0
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30) armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
siemens_coefficient = 0.2 siemens_coefficient = 0.2

View File

@@ -55,7 +55,7 @@
item_state = "eng_hardsuit" item_state = "eng_hardsuit"
slowdown = 1 slowdown = 1
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 80) armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 80)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd) allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd)
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
@@ -359,7 +359,7 @@
slowdown = 1 slowdown = 1
w_class = 3 w_class = 3
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 60) armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 60)
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs) allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs)
siemens_coefficient = 0.6 siemens_coefficient = 0.6
species_restricted = list("exclude","Unathi","Tajaran","Skrell","Vox") species_restricted = list("exclude","Unathi","Tajaran","Skrell","Vox")
@@ -402,7 +402,7 @@
name = "medical hardsuit" name = "medical hardsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has minor radiation shielding." desc = "A special suit that protects against hazardous, low pressure environments. Has minor radiation shielding."
item_state = "medical_hardsuit" item_state = "medical_hardsuit"
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical) allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical)
armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 50) armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 50)
//Security //Security
@@ -421,7 +421,7 @@
desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor." desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor."
item_state = "sec_hardsuit" item_state = "sec_hardsuit"
armor = list(melee = 60, bullet = 10, laser = 30, energy = 5, bomb = 45, bio = 100, rad = 10) armor = list(melee = 60, bullet = 10, laser = 30, energy = 5, bomb = 45, bio = 100, rad = 10)
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/melee/baton) allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton)
siemens_coefficient = 0.7 siemens_coefficient = 0.7

View File

@@ -4,12 +4,15 @@
//for multiple items just add mutliple entries, unless i change it to be a listlistlist //for multiple items just add mutliple entries, unless i change it to be a listlistlist
//yes, it has to be an item, you can't pick up nonitems //yes, it has to be an item, you can't pick up nonitems
/proc/EquipCustomItems(mob/living/carbon/human/M) /var/list/custom_items = list()
// load lines
var/file = file2text("config/custom_items.txt")
var/lines = text2list(file, "\n")
for(var/line in lines) /hook/startup/proc/loadCustomItems()
var/custom_items_file = file2text("config/custom_items.txt")
custom_items = text2list(custom_items_file, "\n")
return 1
/proc/EquipCustomItems(mob/living/carbon/human/M)
for(var/line in custom_items)
// split & clean up // split & clean up
var/list/Entry = text2list(line, ":") var/list/Entry = text2list(line, ":")
for(var/i = 1 to Entry.len) for(var/i = 1 to Entry.len)
@@ -24,6 +27,8 @@
var/ok = 0 // 1 if the item was placed successfully var/ok = 0 // 1 if the item was placed successfully
P = trim(P) P = trim(P)
var/path = text2path(P) var/path = text2path(P)
if(!path) continue
var/obj/item/Item = new path() var/obj/item/Item = new path()
if(istype(Item,/obj/item/weapon/card/id)) if(istype(Item,/obj/item/weapon/card/id))
//id card needs to replace the original ID //id card needs to replace the original ID

View File

@@ -21,9 +21,25 @@ datum/event/organ_failure/start()
while(severity > 0 && candidates.len) while(severity > 0 && candidates.len)
var/mob/living/carbon/human/C = candidates[1] var/mob/living/carbon/human/C = candidates[1]
// Bruise one of their organs var/acute = prob(15)
if (prob(75))
//internal organ infection
var/O = pick(C.internal_organs) var/O = pick(C.internal_organs)
var/datum/organ/internal/I = C.internal_organs[O] var/datum/organ/internal/I = C.internal_organs[O]
I.damage = I.min_bruised_damage
candidates.Remove(C) if (acute)
I.germ_level = max(INFECTION_LEVEL_TWO, I.germ_level)
else
I.germ_level = max(rand(INFECTION_LEVEL_ONE,INFECTION_LEVEL_ONE*2), I.germ_level)
else
//external organ infection
var/datum/organ/external/O = pick(C.organs)
if (acute)
O.germ_level = max(INFECTION_LEVEL_TWO, O.germ_level)
else
O.germ_level = max(rand(INFECTION_LEVEL_ONE,INFECTION_LEVEL_ONE*2), O.germ_level)
C.bad_external_organs |= O
severity-- severity--

View File

@@ -1,9 +1,6 @@
/**********************Mineral deposits**************************/ /**********************Mineral deposits**************************/
datum/controller/game_controller/var/list/artifact_spawning_turfs = list()
var/list/artifact_spawn = list() // Runtime fix for geometry loading before controller is instantiated.
/turf/simulated/mineral //wall piece /turf/simulated/mineral //wall piece
name = "Rock" name = "Rock"
icon = 'icons/turf/walls.dmi' icon = 'icons/turf/walls.dmi'
@@ -39,19 +36,19 @@ var/list/artifact_spawn = list() // Runtime fix for geometry loading before cont
if((istype(get_step(src, NORTH), /turf/simulated/floor)) || (istype(get_step(src, NORTH), /turf/space)) || (istype(get_step(src, NORTH), /turf/simulated/shuttle/floor))) if((istype(get_step(src, NORTH), /turf/simulated/floor)) || (istype(get_step(src, NORTH), /turf/space)) || (istype(get_step(src, NORTH), /turf/simulated/shuttle/floor)))
T = get_step(src, NORTH) T = get_step(src, NORTH)
if (T) if (T)
T.overlays += image('icons/turf/walls.dmi', "rock_side_s") T.overlays += image('icons/turf/walls.dmi', "rock_side_s", layer=2)
if((istype(get_step(src, SOUTH), /turf/simulated/floor)) || (istype(get_step(src, SOUTH), /turf/space)) || (istype(get_step(src, SOUTH), /turf/simulated/shuttle/floor))) if((istype(get_step(src, SOUTH), /turf/simulated/floor)) || (istype(get_step(src, SOUTH), /turf/space)) || (istype(get_step(src, SOUTH), /turf/simulated/shuttle/floor)))
T = get_step(src, SOUTH) T = get_step(src, SOUTH)
if (T) if (T)
T.overlays += image('icons/turf/walls.dmi', "rock_side_n", layer=6) T.overlays += image('icons/turf/walls.dmi', "rock_side_n", layer=2)
if((istype(get_step(src, EAST), /turf/simulated/floor)) || (istype(get_step(src, EAST), /turf/space)) || (istype(get_step(src, EAST), /turf/simulated/shuttle/floor))) if((istype(get_step(src, EAST), /turf/simulated/floor)) || (istype(get_step(src, EAST), /turf/space)) || (istype(get_step(src, EAST), /turf/simulated/shuttle/floor)))
T = get_step(src, EAST) T = get_step(src, EAST)
if (T) if (T)
T.overlays += image('icons/turf/walls.dmi', "rock_side_w", layer=6) T.overlays += image('icons/turf/walls.dmi', "rock_side_w", layer=2)
if((istype(get_step(src, WEST), /turf/simulated/floor)) || (istype(get_step(src, WEST), /turf/space)) || (istype(get_step(src, WEST), /turf/simulated/shuttle/floor))) if((istype(get_step(src, WEST), /turf/simulated/floor)) || (istype(get_step(src, WEST), /turf/space)) || (istype(get_step(src, WEST), /turf/simulated/shuttle/floor)))
T = get_step(src, WEST) T = get_step(src, WEST)
if (T) if (T)
T.overlays += image('icons/turf/walls.dmi', "rock_side_e", layer=6) T.overlays += image('icons/turf/walls.dmi', "rock_side_e", layer=2)
ex_act(severity) ex_act(severity)
@@ -480,6 +477,12 @@ var/list/artifact_spawn = list() // Runtime fix for geometry loading before cont
for(var/obj/item/weapon/ore/O in contents) for(var/obj/item/weapon/ore/O in contents)
O.attackby(W,user) O.attackby(W,user)
return return
else if(istype(W,/obj/item/weapon/storage/bag/fossils))
var/obj/item/weapon/storage/bag/fossils/S = W
if(S.collection_mode)
for(var/obj/item/weapon/fossil/F in contents)
F.attackby(W,user)
return
else else
..(W,user) ..(W,user)

View File

@@ -72,7 +72,7 @@ var/const/MAX_ACTIVE_TIME = 400
Die() Die()
return return
/obj/item/clothing/mask/facehugger/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/item/clothing/mask/facehugger/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300) if(exposed_temperature > 300)
Die() Die()
return return

View File

@@ -1,3 +1,10 @@
/mob/living/carbon/Life()
..()
// Increase germ_level regularly
if(germ_level < GERM_LEVEL_AMBIENT && prob(80)) //if you're just standing there, you shouldn't get more germs beyond an ambient level
germ_level++
/mob/living/carbon/Move(NewLoc, direct) /mob/living/carbon/Move(NewLoc, direct)
. = ..() . = ..()
if(.) if(.)
@@ -8,6 +15,10 @@
if((FAT in src.mutations) && src.m_intent == "run" && src.bodytemperature <= 360) if((FAT in src.mutations) && src.m_intent == "run" && src.bodytemperature <= 360)
src.bodytemperature += 2 src.bodytemperature += 2
// Moving around increases germ_level faster
if(germ_level < GERM_LEVEL_MOVE_CAP && prob(8))
germ_level++
/mob/living/carbon/relaymove(var/mob/user, direction) /mob/living/carbon/relaymove(var/mob/user, direction)
if(user in src.stomach_contents) if(user in src.stomach_contents)
if(prob(40)) if(prob(40))
@@ -252,10 +263,12 @@
/mob/living/carbon/proc/throw_mode_off() /mob/living/carbon/proc/throw_mode_off()
src.in_throw_mode = 0 src.in_throw_mode = 0
if(src.throw_icon) //in case we don't have the HUD and we use the hotkey
src.throw_icon.icon_state = "act_throw_off" src.throw_icon.icon_state = "act_throw_off"
/mob/living/carbon/proc/throw_mode_on() /mob/living/carbon/proc/throw_mode_on()
src.in_throw_mode = 1 src.in_throw_mode = 1
if(src.throw_icon)
src.throw_icon.icon_state = "act_throw_on" src.throw_icon.icon_state = "act_throw_on"
/mob/proc/throw_item(atom/target) /mob/proc/throw_item(atom/target)

View File

@@ -243,7 +243,7 @@
msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n" msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
if(!key && brain_op_stage != 4 && stat != DEAD) if(!key && brain_op_stage != 4 && stat != DEAD)
msg += "<span class='deadsay'>[t_He] [t_is] totally catatonic. The stresses of life in deep-space must have been too much for [t_him]. Any recovery is unlikely</span>\n" msg += "<span class='deadsay'>[t_He] [t_is] fast asleep. It doesn't look like they are waking up anytime soon.</span>\n"
else if(!client && brain_op_stage != 4 && stat != DEAD) else if(!client && brain_op_stage != 4 && stat != DEAD)
msg += "[t_He] [t_has] suddenly fallen asleep.\n" msg += "[t_He] [t_has] suddenly fallen asleep.\n"
@@ -262,7 +262,7 @@
wound_flavor_text["[temp.display_name]"] = "<span class='warning'>[t_He] has a robot [temp.display_name]!</span>\n" wound_flavor_text["[temp.display_name]"] = "<span class='warning'>[t_He] has a robot [temp.display_name]!</span>\n"
continue continue
else else
wound_flavor_text["[temp.display_name]"] = "<span class='warning'>[t_He] has a robot [temp.display_name], it has" wound_flavor_text["[temp.display_name]"] = "<span class='warning'>[t_He] has a robot [temp.display_name]. It has"
if(temp.brute_dam) switch(temp.brute_dam) if(temp.brute_dam) switch(temp.brute_dam)
if(0 to 20) if(0 to 20)
wound_flavor_text["[temp.display_name]"] += " some dents" wound_flavor_text["[temp.display_name]"] += " some dents"
@@ -284,8 +284,8 @@
var/this_wound_desc = W.desc var/this_wound_desc = W.desc
if(W.bleeding()) this_wound_desc = "bleeding [this_wound_desc]" if(W.bleeding()) this_wound_desc = "bleeding [this_wound_desc]"
else if(W.bandaged) this_wound_desc = "bandaged [this_wound_desc]" else if(W.bandaged) this_wound_desc = "bandaged [this_wound_desc]"
if(W.germ_level > 1000) this_wound_desc = "badly infected [this_wound_desc]" if(W.germ_level > 600) this_wound_desc = "badly infected [this_wound_desc]"
else if(W.germ_level > 100) this_wound_desc = "lightly infected [this_wound_desc]" else if(W.germ_level > 330) this_wound_desc = "lightly infected [this_wound_desc]"
if(this_wound_desc in wound_descriptors) if(this_wound_desc in wound_descriptors)
wound_descriptors[this_wound_desc] += W.amount wound_descriptors[this_wound_desc] += W.amount
continue continue
@@ -389,7 +389,7 @@
msg += "<span class='warning'><b>[src] has blood running from under [t_his] gloves!</b></span>\n" msg += "<span class='warning'><b>[src] has blood running from under [t_his] gloves!</b></span>\n"
for(var/implant in get_visible_implants(1)) for(var/implant in get_visible_implants(1))
msg += "<span class='warning'><b>[src] has \a [implant] sticking out of their flesh!</span>\n" msg += "<span class='warning'><b>[src] has \a [implant] sticking out of [t_his] flesh!</span>\n"
if(digitalcamo) if(digitalcamo)
msg += "[t_He] [t_is] repulsively uncanny!\n" msg += "[t_He] [t_is] repulsively uncanny!\n"

View File

@@ -1220,7 +1220,7 @@
return return
usr << "Don't move until counting is finished." usr << "Don't move until counting is finished."
var/time = world.timeofday var/time = world.time
sleep(60) sleep(60)
if(usr.l_move_time >= time) //checks if our mob has moved during the sleep() if(usr.l_move_time >= time) //checks if our mob has moved during the sleep()
usr << "You moved while counting. Try again." usr << "You moved while counting. Try again."

View File

@@ -302,14 +302,6 @@ This function restores all organs.
if(istype(used_weapon,/obj/item/weapon)) if(istype(used_weapon,/obj/item/weapon))
var/obj/item/weapon/W = used_weapon //Sharp objects will always embed if they do enough damage. var/obj/item/weapon/W = used_weapon //Sharp objects will always embed if they do enough damage.
if( (damage > (10*W.w_class)) && ( (sharp && !ismob(W.loc)) || prob(damage/W.w_class) ) ) if( (damage > (10*W.w_class)) && ( (sharp && !ismob(W.loc)) || prob(damage/W.w_class) ) )
organ.implants += W organ.embed(W)
visible_message("<span class='danger'>\The [W] sticks in the wound!</span>")
embedded_flag = 1
src.verbs += /mob/proc/yank_out_object
W.add_blood(src)
if(ismob(W.loc))
var/mob/living/H = W.loc
H.drop_item()
W.loc = src
return 1 return 1

View File

@@ -98,11 +98,7 @@ emp_act
(SP.name) = "[P.name] shrapnel" (SP.name) = "[P.name] shrapnel"
(SP.desc) = "[SP.desc] It looks like it was fired from [P.shot_from]." (SP.desc) = "[SP.desc] It looks like it was fired from [P.shot_from]."
(SP.loc) = organ (SP.loc) = organ
organ.implants += SP organ.embed(SP)
visible_message("<span class='danger'>The projectile sticks in the wound!</span>")
embedded_flag = 1
src.verbs += /mob/proc/yank_out_object
SP.add_blood(src)
return (..(P , def_zone)) return (..(P , def_zone))

View File

@@ -129,10 +129,8 @@
G.process() G.process()
/mob/living/carbon/human/calculate_affecting_pressure(var/pressure) //Much like get_heat_protection(), this returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
..() /mob/living/carbon/human/proc/get_pressure_protection()
var/pressure_difference = abs( pressure - ONE_ATMOSPHERE )
var/pressure_adjustment_coefficient = 1 //Determins how much the clothing you are wearing protects you in percent. var/pressure_adjustment_coefficient = 1 //Determins how much the clothing you are wearing protects you in percent.
if(head && (head.flags & STOPSPRESSUREDMAGE)) if(head && (head.flags & STOPSPRESSUREDMAGE))
@@ -150,7 +148,13 @@
pressure_adjustment_coefficient = min(1,max(pressure_adjustment_coefficient,0)) //So it isn't less than 0 or larger than 1. pressure_adjustment_coefficient = min(1,max(pressure_adjustment_coefficient,0)) //So it isn't less than 0 or larger than 1.
pressure_difference = pressure_difference * pressure_adjustment_coefficient return 1 - pressure_adjustment_coefficient //want 0 to be bad protection, 1 to be good protection
/mob/living/carbon/human/calculate_affecting_pressure(var/pressure)
..()
var/pressure_difference = abs( pressure - ONE_ATMOSPHERE )
pressure_difference = pressure_difference * (1 - get_pressure_protection())
if(pressure > ONE_ATMOSPHERE) if(pressure > ONE_ATMOSPHERE)
return ONE_ATMOSPHERE + pressure_difference return ONE_ATMOSPHERE + pressure_difference
@@ -316,9 +320,6 @@
if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return
if(species && (species.flags & NO_BREATHE || species.flags & IS_SYNTHETIC)) return if(species && (species.flags & NO_BREATHE || species.flags & IS_SYNTHETIC)) return
var/datum/organ/internal/lungs/L = internal_organs["lungs"]
L.process()
var/datum/gas_mixture/environment = loc.return_air() var/datum/gas_mixture/environment = loc.return_air()
var/datum/gas_mixture/breath var/datum/gas_mixture/breath
@@ -619,14 +620,14 @@
adjustOxyLoss(-5) adjustOxyLoss(-5)
// Hot air hurts :( // Hot air hurts :(
if( (abs(310.15 - breath.temperature) > 50) && !(COLD_RESISTANCE in mutations)) if( (breath.temperature < species.cold_level_1 || breath.temperature > species.heat_level_1) && !(COLD_RESISTANCE in mutations))
if(status_flags & GODMODE) if(status_flags & GODMODE)
return 1 return 1
if(breath.temperature < species.cold_level_1) if(breath.temperature < species.cold_level_1)
if(prob(20)) if(prob(20))
src << "\red You feel your face freezing and an icicle forming in your lungs!" src << "\red You feel your face freezing and icicles forming in your lungs!"
else if(breath.temperature > species.heat_level_1) else if(breath.temperature > species.heat_level_1)
if(prob(20)) if(prob(20))
src << "\red You feel your face burning and a searing heat in your lungs!" src << "\red You feel your face burning and a searing heat in your lungs!"
@@ -651,8 +652,20 @@
apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Heat") apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Heat")
fire_alert = max(fire_alert, 2) fire_alert = max(fire_alert, 2)
//Temporary fixes to the alerts. //breathing in hot/cold air also heats/cools you a bit
var/temp_adj = breath.temperature - bodytemperature
if (temp_adj < 0)
temp_adj /= (BODYTEMP_COLD_DIVISOR * 5) //don't raise temperature as much as if we were directly exposed
else
temp_adj /= (BODYTEMP_HEAT_DIVISOR * 5) //don't raise temperature as much as if we were directly exposed
var/relative_density = breath.total_moles() / (MOLES_CELLSTANDARD * BREATH_PERCENTAGE)
temp_adj *= relative_density
if (temp_adj > BODYTEMP_HEATING_MAX) temp_adj = BODYTEMP_HEATING_MAX
if (temp_adj < BODYTEMP_COOLING_MAX) temp_adj = BODYTEMP_COOLING_MAX
//world << "Breath: [breath.temperature], [src]: [bodytemperature], Adjusting: [temp_adj]"
bodytemperature += temp_adj
return 1 return 1
proc/handle_environment(datum/gas_mixture/environment) proc/handle_environment(datum/gas_mixture/environment)
@@ -668,60 +681,63 @@
if(istype(loc, /obj/mecha)) if(istype(loc, /obj/mecha))
var/obj/mecha/M = loc var/obj/mecha/M = loc
loc_temp = M.return_temperature() loc_temp = M.return_temperature()
else if(istype(get_turf(src), /turf/space))
else if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) else if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
loc_temp = loc:air_contents.temperature loc_temp = loc:air_contents.temperature
else else
loc_temp = environment.temperature loc_temp = environment.temperature
if(adjusted_pressure < species.warning_low_pressure && adjusted_pressure > species.warning_low_pressure && abs(loc_temp - 293.15) < 20 && abs(bodytemperature - 310.14) < 0.5 && environment.phoron < MOLES_PHORON_VISIBLE) if(adjusted_pressure < species.warning_high_pressure && adjusted_pressure > species.warning_low_pressure && abs(loc_temp - bodytemperature) < 20 && bodytemperature < species.heat_level_1 && bodytemperature > species.cold_level_1 && environment.phoron < MOLES_PHORON_VISIBLE)
return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp
//Body temperature is adjusted in two steps. Firstly your body tries to stabilize itself a bit. //Body temperature adjusts depending on surrounding atmosphere based on your thermal protection
if(stat != 2) var/temp_adj = 0
stabilize_temperature_from_calories() if(loc_temp < bodytemperature) //Place is colder than we are
//After then, it reacts to the surrounding atmosphere based on your thermal protection
if(loc_temp < BODYTEMP_COLD_DAMAGE_LIMIT) //Place is colder than we are
var/thermal_protection = get_cold_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to. var/thermal_protection = get_cold_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
if(thermal_protection < 1) if(thermal_protection < 1)
var/amt = min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX) temp_adj = (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR) //this will be negative
bodytemperature += amt else if (loc_temp > bodytemperature) //Place is hotter than we are
else if (loc_temp > BODYTEMP_HEAT_DAMAGE_LIMIT) //Place is hotter than we are
var/thermal_protection = get_heat_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to. var/thermal_protection = get_heat_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
if(thermal_protection < 1) if(thermal_protection < 1)
var/amt = min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX) temp_adj = (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR)
bodytemperature += amt
//Use heat transfer as proportional to the gas density. However, we only care about the relative density vs standard 101 kPa/20 C air. Therefore we can use mole ratios
var/relative_density = environment.total_moles() / MOLES_CELLSTANDARD
temp_adj *= relative_density
if (temp_adj > BODYTEMP_HEATING_MAX) temp_adj = BODYTEMP_HEATING_MAX
if (temp_adj < BODYTEMP_COOLING_MAX) temp_adj = BODYTEMP_COOLING_MAX
//world << "Environment: [loc_temp], [src]: [bodytemperature], Adjusting: [temp_adj]"
bodytemperature += temp_adj
// +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt. // +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt.
if(bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT) if(bodytemperature > species.heat_level_1)
//Body temperature is too hot. //Body temperature is too hot.
fire_alert = max(fire_alert, 1) fire_alert = max(fire_alert, 1)
if(status_flags & GODMODE) return 1 //godmode if(status_flags & GODMODE) return 1 //godmode
switch(bodytemperature) switch(bodytemperature)
if(360 to 400) if(species.heat_level_1 to species.heat_level_2)
apply_damage(HEAT_DAMAGE_LEVEL_1, BURN, used_weapon = "High Body Temperature") take_overall_damage(burn=HEAT_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 2) fire_alert = max(fire_alert, 2)
if(400 to 1000) if(species.heat_level_2 to species.heat_level_3)
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN, used_weapon = "High Body Temperature") take_overall_damage(burn=HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 2) fire_alert = max(fire_alert, 2)
if(1000 to INFINITY) if(species.heat_level_3 to INFINITY)
apply_damage(HEAT_DAMAGE_LEVEL_3, BURN, used_weapon = "High Body Temperature") take_overall_damage(burn=HEAT_DAMAGE_LEVEL_3, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 2) fire_alert = max(fire_alert, 2)
else if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT) else if(bodytemperature < species.cold_level_1)
fire_alert = max(fire_alert, 1) fire_alert = max(fire_alert, 1)
if(status_flags & GODMODE) return 1 //godmode if(status_flags & GODMODE) return 1 //godmode
if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
switch(bodytemperature) switch(bodytemperature)
if(200 to 260) if(species.cold_level_2 to species.cold_level_1)
apply_damage(COLD_DAMAGE_LEVEL_1, BURN, used_weapon = "Low Body Temperature") take_overall_damage(burn=COLD_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 1) fire_alert = max(fire_alert, 1)
if(120 to 200) if(species.cold_level_3 to species.cold_level_2)
apply_damage(COLD_DAMAGE_LEVEL_2, BURN, used_weapon = "Low Body Temperature") take_overall_damage(burn=COLD_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 1) fire_alert = max(fire_alert, 1)
if(-INFINITY to 120) if(-INFINITY to species.cold_level_3)
apply_damage(COLD_DAMAGE_LEVEL_3, BURN, used_weapon = "Low Body Temperature") take_overall_damage(burn=COLD_DAMAGE_LEVEL_3, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 1) fire_alert = max(fire_alert, 1)
// Account for massive pressure differences. Done by Polymorph // Account for massive pressure differences. Done by Polymorph
@@ -729,7 +745,8 @@
if(status_flags & GODMODE) return 1 //godmode if(status_flags & GODMODE) return 1 //godmode
if(adjusted_pressure >= species.hazard_high_pressure) if(adjusted_pressure >= species.hazard_high_pressure)
adjustBruteLoss( min( ( (adjusted_pressure / species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) ) var/pressure_damage = min( ( (adjusted_pressure / species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE)
take_overall_damage(brute=pressure_damage, used_weapon = "High Pressure")
pressure_alert = 2 pressure_alert = 2
else if(adjusted_pressure >= species.warning_high_pressure) else if(adjusted_pressure >= species.warning_high_pressure)
pressure_alert = 1 pressure_alert = 1
@@ -737,17 +754,9 @@
pressure_alert = 0 pressure_alert = 0
else if(adjusted_pressure >= species.hazard_low_pressure) else if(adjusted_pressure >= species.hazard_low_pressure)
pressure_alert = -1 pressure_alert = -1
if(species && species.flags & IS_SYNTHETIC)
bodytemperature += 0.5 * TEMPERATURE_DAMAGE_COEFFICIENT //Synthetics suffer overheating in a vaccuum. ~Z
else else
if(species && species.flags & IS_SYNTHETIC)
bodytemperature += 1 * TEMPERATURE_DAMAGE_COEFFICIENT
if( !(COLD_RESISTANCE in mutations)) if( !(COLD_RESISTANCE in mutations))
adjustBruteLoss( LOW_PRESSURE_DAMAGE ) take_overall_damage(brute=LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure")
pressure_alert = -2 pressure_alert = -2
else else
pressure_alert = -1 pressure_alert = -1
@@ -775,24 +784,32 @@
return temp_change return temp_change
*/ */
proc/stabilize_temperature_from_calories() proc/stabilize_body_temperature()
var/body_temperature_difference = 310.15 - bodytemperature if (species.flags & IS_SYNTHETIC)
bodytemperature += species.synth_temp_gain //just keep putting out heat.
return
var/body_temperature_difference = species.body_temperature - bodytemperature
if (abs(body_temperature_difference) < 0.5) if (abs(body_temperature_difference) < 0.5)
return //fuck this precision return //fuck this precision
switch(bodytemperature)
if(-INFINITY to 260.15) //260.15 is 310.15 - 50, the temperature where you start to feel effects. if(bodytemperature < species.cold_level_1) //260.15 is 310.15 - 50, the temperature where you start to feel effects.
if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up. if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up.
nutrition -= 2 nutrition -= 2
var/recovery_amt = max((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM) var/recovery_amt = max((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM)
//world << "Cold. Difference = [body_temperature_difference]. Recovering [recovery_amt]"
// log_debug("Cold. Difference = [body_temperature_difference]. Recovering [recovery_amt]") // log_debug("Cold. Difference = [body_temperature_difference]. Recovering [recovery_amt]")
bodytemperature += recovery_amt bodytemperature += recovery_amt
if(260.15 to 360.15) else if(species.cold_level_1 <= bodytemperature && bodytemperature <= species.heat_level_1)
var/recovery_amt = body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR var/recovery_amt = body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR
//world << "Norm. Difference = [body_temperature_difference]. Recovering [recovery_amt]"
// log_debug("Norm. Difference = [body_temperature_difference]. Recovering [recovery_amt]") // log_debug("Norm. Difference = [body_temperature_difference]. Recovering [recovery_amt]")
bodytemperature += recovery_amt bodytemperature += recovery_amt
if(360.15 to INFINITY) //360.15 is 310.15 + 50, the temperature where you start to feel effects. else if(bodytemperature > species.heat_level_1) //360.15 is 310.15 + 50, the temperature where you start to feel effects.
//We totally need a sweat system cause it totally makes sense...~ //We totally need a sweat system cause it totally makes sense...~
var/recovery_amt = min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers var/recovery_amt = min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers
//world << "Hot. Difference = [body_temperature_difference]. Recovering [recovery_amt]"
// log_debug("Hot. Difference = [body_temperature_difference]. Recovering [recovery_amt]") // log_debug("Hot. Difference = [body_temperature_difference]. Recovering [recovery_amt]")
bodytemperature += recovery_amt bodytemperature += recovery_amt
@@ -1074,12 +1091,6 @@
if(!(species.flags & IS_SYNTHETIC)) handle_trace_chems() if(!(species.flags & IS_SYNTHETIC)) handle_trace_chems()
var/datum/organ/internal/liver/liver = internal_organs["liver"]
liver.process()
var/datum/organ/internal/eyes/eyes = internal_organs["eyes"]
eyes.process()
updatehealth() updatehealth()
return //TODO: DEFERRED return //TODO: DEFERRED
@@ -1091,6 +1102,7 @@
else //ALIVE. LIGHTS ARE ON else //ALIVE. LIGHTS ARE ON
updatehealth() //TODO updatehealth() //TODO
if(!in_stasis) if(!in_stasis)
stabilize_body_temperature() //Body temperature adjusts itself
handle_organs() //Optimized. handle_organs() //Optimized.
handle_blood() handle_blood()
@@ -1215,14 +1227,11 @@
if(druggy) if(druggy)
druggy = max(druggy-1, 0) druggy = max(druggy-1, 0)
/*
// Increase germ_level regularly
if(prob(40))
germ_level += 1
// If you're dirty, your gloves will become dirty, too. // If you're dirty, your gloves will become dirty, too.
if(gloves && germ_level > gloves.germ_level && prob(10)) if(gloves && germ_level > gloves.germ_level && prob(10))
gloves.germ_level += 1 gloves.germ_level += 1
*/
return 1 return 1
proc/handle_regular_hud_updates() proc/handle_regular_hud_updates()
@@ -1449,6 +1458,7 @@
else fire.icon_state = "fire0" else fire.icon_state = "fire0"
if(bodytemp) if(bodytemp)
if (!species)
switch(bodytemperature) //310.055 optimal body temp switch(bodytemperature) //310.055 optimal body temp
if(370 to INFINITY) bodytemp.icon_state = "temp4" if(370 to INFINITY) bodytemp.icon_state = "temp4"
if(350 to 370) bodytemp.icon_state = "temp3" if(350 to 370) bodytemp.icon_state = "temp3"
@@ -1459,7 +1469,35 @@
if(280 to 295) bodytemp.icon_state = "temp-2" if(280 to 295) bodytemp.icon_state = "temp-2"
if(260 to 280) bodytemp.icon_state = "temp-3" if(260 to 280) bodytemp.icon_state = "temp-3"
else bodytemp.icon_state = "temp-4" else bodytemp.icon_state = "temp-4"
else
var/temp_step
if (bodytemperature >= species.body_temperature)
temp_step = (species.heat_level_1 - species.body_temperature)/4
if (bodytemperature >= species.heat_level_1)
bodytemp.icon_state = "temp4"
else if (bodytemperature >= species.body_temperature + temp_step*3)
bodytemp.icon_state = "temp3"
else if (bodytemperature >= species.body_temperature + temp_step*2)
bodytemp.icon_state = "temp2"
else if (bodytemperature >= species.body_temperature + temp_step*1)
bodytemp.icon_state = "temp1"
else
bodytemp.icon_state = "temp0"
else if (bodytemperature < species.body_temperature)
temp_step = (species.body_temperature - species.cold_level_1)/4
if (bodytemperature <= species.cold_level_1)
bodytemp.icon_state = "temp-4"
else if (bodytemperature <= species.body_temperature - temp_step*3)
bodytemp.icon_state = "temp-3"
else if (bodytemperature <= species.body_temperature - temp_step*2)
bodytemp.icon_state = "temp-2"
else if (bodytemperature <= species.body_temperature - temp_step*1)
bodytemp.icon_state = "temp-1"
else
bodytemp.icon_state = "temp0"
if(blind) if(blind)
if(blinded) blind.layer = 18 if(blinded) blind.layer = 18
else blind.layer = 0 else blind.layer = 0
@@ -1520,21 +1558,21 @@
for (var/ID in virus2) for (var/ID in virus2)
var/datum/disease2/disease/V = virus2[ID] var/datum/disease2/disease/V = virus2[ID]
V.cure(src) V.cure(src)
if(life_tick % 3) //don't spam checks over all objects in view every tick.
for(var/obj/effect/decal/cleanable/O in view(1,src)) for(var/obj/effect/decal/cleanable/O in view(1,src))
if(istype(O,/obj/effect/decal/cleanable/blood)) if(istype(O,/obj/effect/decal/cleanable/blood))
var/obj/effect/decal/cleanable/blood/B = O var/obj/effect/decal/cleanable/blood/B = O
if(B.virus2.len) if(B.virus2.len)
for (var/ID in B.virus2) for (var/ID in B.virus2)
var/datum/disease2/disease/V = B.virus2[ID] var/datum/disease2/disease/V = B.virus2[ID]
infect_virus2(src,V) infect_virus2(src,V.getcopy())
else if(istype(O,/obj/effect/decal/cleanable/mucus)) else if(istype(O,/obj/effect/decal/cleanable/mucus))
var/obj/effect/decal/cleanable/mucus/M = O var/obj/effect/decal/cleanable/mucus/M = O
if(M.virus2.len) if(M.virus2.len)
for (var/ID in M.virus2) for (var/ID in M.virus2)
var/datum/disease2/disease/V = M.virus2[ID] var/datum/disease2/disease/V = M.virus2[ID]
infect_virus2(src,V) infect_virus2(src,V.getcopy())
if(virus2.len) if(virus2.len)

View File

@@ -10,6 +10,8 @@
icon_state = "nymph1" icon_state = "nymph1"
var/list/donors = list() var/list/donors = list()
var/ready_evolve = 0 var/ready_evolve = 0
universal_understand = 0 // Dionaea do not need to speak to people
universal_speak = 0 // before becoming an adult. Use *chirp.
/mob/living/carbon/monkey/diona/attack_hand(mob/living/carbon/human/M as mob) /mob/living/carbon/monkey/diona/attack_hand(mob/living/carbon/human/M as mob)
@@ -207,7 +209,7 @@
src.visible_message("\red [src] flicks out a feeler and neatly steals a sample of [M]'s blood.","\red You flick out a feeler and neatly steal a sample of [M]'s blood.") src.visible_message("\red [src] flicks out a feeler and neatly steals a sample of [M]'s blood.","\red You flick out a feeler and neatly steal a sample of [M]'s blood.")
donors += M.real_name donors += M.real_name
for(var/datum/language/L in M.languages) for(var/datum/language/L in M.languages)
languages += L languages |= L
spawn(25) spawn(25)
update_progression() update_progression()
@@ -245,14 +247,11 @@
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
if(stat == 2) if(stat == 2)
return say_dead(message) return say_dead(message)
var/datum/language/speaking = null var/datum/language/speaking = null
if(length(message) >= 2) if(length(message) >= 2)
var/channel_prefix = copytext(message, 1 ,3) var/channel_prefix = copytext(message, 1 ,3)
if(languages.len) if(languages.len)
@@ -270,6 +269,4 @@
if(!message || stat) if(!message || stat)
return return
..(message, speaking, verb, null, null, message_range, null) ..(message, speaking, verb, null, null, message_range, null)

View File

@@ -29,6 +29,9 @@
var/heat_level_2 = 400 // Heat damage level 2 above this point. var/heat_level_2 = 400 // Heat damage level 2 above this point.
var/heat_level_3 = 1000 // Heat damage level 2 above this point. var/heat_level_3 = 1000 // Heat damage level 2 above this point.
var/body_temperature = 310.15 //non-IS_SYNTHETIC species will try to stabilize at this temperature. (also affects temperature processing)
var/synth_temp_gain = 0 //IS_SYNTHETIC species will gain this much temperature every second
var/darksight = 2 var/darksight = 2
var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure. var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure.
var/warning_high_pressure = WARNING_HIGH_PRESSURE // High pressure warning. var/warning_high_pressure = WARNING_HIGH_PRESSURE // High pressure warning.
@@ -279,6 +282,8 @@
heat_level_2 = 3000 heat_level_2 = 3000
heat_level_3 = 4000 heat_level_3 = 4000
body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not
flags = IS_WHITELISTED | NO_BREATHE | REQUIRE_LIGHT | NO_SCAN | IS_PLANT | RAD_ABSORB | NO_BLOOD | IS_SLOW | NO_PAIN flags = IS_WHITELISTED | NO_BREATHE | REQUIRE_LIGHT | NO_SCAN | IS_PLANT | RAD_ABSORB | NO_BLOOD | IS_SLOW | NO_PAIN
blood_color = "#004400" blood_color = "#004400"
@@ -317,15 +322,17 @@
burn_mod = 1 burn_mod = 1
warning_low_pressure = 50 warning_low_pressure = 50
hazard_low_pressure = 10 hazard_low_pressure = 0
cold_level_1 = 50 cold_level_1 = 50
cold_level_2 = -1 cold_level_2 = -1
cold_level_3 = -1 cold_level_3 = -1
heat_level_1 = 2000 heat_level_1 = 500 //gives them about 25 seconds in space before taking damage
heat_level_2 = 3000 heat_level_2 = 1000
heat_level_3 = 4000 heat_level_3 = 2000
synth_temp_gain = 10 //this should cause IPCs to stabilize at ~80 C in a 20 C environment.
flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | IS_SYNTHETIC flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | IS_SYNTHETIC

View File

@@ -431,7 +431,8 @@
else else
stop_pulling() stop_pulling()
. = ..() . = ..()
if ((s_active && !( s_active in contents ) ))
if (s_active && !( s_active in contents ) && get_turf(s_active) != get_turf(src)) //check !( s_active in contents ) first so we hopefully don't have to call get_turf() so much.
s_active.close(src) s_active.close(src)
if(update_slimes) if(update_slimes)

View File

@@ -113,6 +113,7 @@ var/list/department_radio_keys = list(
for(var/obj/O in objects) for(var/obj/O in objects)
spawn(0) spawn(0)
if(O) //It's possible that it could be deleted in the meantime.
O.hear_talk(src, message, verb, speaking) O.hear_talk(src, message, verb, speaking)
var/speech_bubble_test = say_test(message) var/speech_bubble_test = say_test(message)

View File

@@ -407,22 +407,10 @@ var/list/ai_list = list()
if (href_list["track"]) if (href_list["track"])
var/mob/target = locate(href_list["track"]) in mob_list var/mob/target = locate(href_list["track"]) in mob_list
/*
var/mob/living/silicon/ai/A = locate(href_list["track2"]) in mob_list
if(A && target)
A.ai_actual_track(target)
*/
//Strip off any "(as Derplord)". if(target && (!istype(target, /mob/living/carbon/human) || html_decode(href_list["trackname"]) == target:get_face_name()))
//If there's a way to do this via a var that doesn't give the AI extra info, please let me know.
var/seeking = target.name
var/index = findtext(seeking, "(as ")
if(index)
seeking = copytext(seeking, 1, index-1)
if(target && html_decode(href_list["trackname"]) == seeking)
ai_actual_track(target) ai_actual_track(target)
else
src << "\red System error. Cannot locate [html_decode(href_list["trackname"])]." src << "\red System error. Cannot locate [html_decode(href_list["trackname"])]."
return return

View File

@@ -188,7 +188,7 @@
if(!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey") if(!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
user << "\red You don't have the dexterity to do this!" user << "\red You don't have the dexterity to do this!"
return return
if(!istype(M, /mob/living/silicon/robot)) if(!istype(M, /mob/living/silicon/robot) && !(ishuman(M) && (M:species.flags & IS_SYNTHETIC)))
user << "\red You can't analyze non-robotic things!" user << "\red You can't analyze non-robotic things!"
return return
@@ -201,6 +201,7 @@
if(M.tod && M.stat == DEAD) if(M.tod && M.stat == DEAD)
user.show_message("\blue Time of Disable: [M.tod]") user.show_message("\blue Time of Disable: [M.tod]")
if (istype(M, /mob/living/silicon/robot))
var/mob/living/silicon/robot/H = M var/mob/living/silicon/robot/H = M
var/list/damaged = H.get_damaged_components(1,1,1) var/list/damaged = H.get_damaged_components(1,1,1)
user.show_message("\blue Localized Damage:",1) user.show_message("\blue Localized Damage:",1)
@@ -217,5 +218,21 @@
user.show_message("\blue \t Components are OK.",1) user.show_message("\blue \t Components are OK.",1)
if(H.emagged && prob(5)) if(H.emagged && prob(5))
user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1) user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1)
if (ishuman(M) && (M:species.flags & IS_SYNTHETIC))
var/mob/living/carbon/human/H = M
var/list/damaged = H.get_damaged_organs(1,1)
user.show_message("\blue Localized Damage, Brute/Electronics:",1)
if(length(damaged)>0)
for(var/datum/organ/external/org in damaged)
user.show_message(text("\blue \t []: [] - []", \
capitalize(org.display_name), \
(org.brute_dam > 0) ? "\red [org.brute_dam]" :0, \
(org.burn_dam > 0) ? "<font color='#FFA500'>[org.burn_dam]</font>" :0),1)
else
user.show_message("\blue \t Components are OK.",1)
user.show_message("\blue Operating Temperature: [M.bodytemperature-T0C]&deg;C ([M.bodytemperature*1.8-459.67]&deg;F)", 1)
src.add_fingerprint(user) src.add_fingerprint(user)
return return

View File

@@ -760,6 +760,12 @@ note dizziness decrements automatically in the mob's Life() proc.
canmove = 0 canmove = 0
if( istype(buckled,/obj/structure/stool/bed/chair) ) if( istype(buckled,/obj/structure/stool/bed/chair) )
lying = 0 lying = 0
else if(istype(buckled, /obj/vehicle))
var/obj/vehicle/V = buckled
if(V.standing_mob)
lying = 0
else
lying = 1
else else
lying = 1 lying = 1
else if( stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH)) else if( stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH))

View File

@@ -199,7 +199,7 @@
if(!mob.canmove) if(!mob.canmove)
if (mob.buckled && (istype(mob.buckled, /obj/structure/stool/bed/chair/wheelchair))) // Exception for wheelchairs if (mob.buckled && (istype(mob.buckled, /obj/structure/stool/bed/chair/wheelchair) || istype(mob.buckled, /obj/vehicle))) // Exception for wheelchairs
else return else return
//if(istype(mob.loc, /turf/space) || (mob.flags & NOGRAV)) //if(istype(mob.loc, /turf/space) || (mob.flags & NOGRAV))
@@ -247,6 +247,8 @@
var/tickcomp = ((1/(world.tick_lag))*1.3) var/tickcomp = ((1/(world.tick_lag))*1.3)
move_delay = move_delay + tickcomp move_delay = move_delay + tickcomp
if(istype(mob.buckled, /obj/vehicle))
return mob.buckled.relaymove(mob,direct)
if(mob.pulledby || mob.buckled) // Wheelchair driving! if(mob.pulledby || mob.buckled) // Wheelchair driving!
if(istype(mob.loc, /turf/space)) if(istype(mob.loc, /turf/space))

View File

@@ -198,12 +198,7 @@ datum/preferences
preview_icon.Blend(new /icon(icobase, "groin_[g]"), ICON_OVERLAY) preview_icon.Blend(new /icon(icobase, "groin_[g]"), ICON_OVERLAY)
preview_icon.Blend(new /icon(icobase, "head_[g]"), ICON_OVERLAY) preview_icon.Blend(new /icon(icobase, "head_[g]"), ICON_OVERLAY)
for(var/name in list("l_arm","r_arm","l_leg","r_leg","l_foot","r_foot","l_hand","r_hand")) for(var/name in list("r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","l_arm","l_hand"))
// make sure the organ is added to the list so it's drawn
if(organ_data[name] == null)
organ_data[name] = null
for(var/name in organ_data)
if(organ_data[name] == "amputated") continue if(organ_data[name] == "amputated") continue
var/icon/temp = new /icon(icobase, "[name]") var/icon/temp = new /icon(icobase, "[name]")
@@ -212,6 +207,11 @@ datum/preferences
preview_icon.Blend(temp, ICON_OVERLAY) preview_icon.Blend(temp, ICON_OVERLAY)
//Tail
if(current_species && (current_species.flags & HAS_TAIL))
var/icon/temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[current_species.tail]_s")
preview_icon.Blend(temp, ICON_OVERLAY)
// Skin color // Skin color
if(current_species && (current_species.flags & HAS_SKIN_COLOR)) if(current_species && (current_species.flags & HAS_SKIN_COLOR))
preview_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD) preview_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)

View File

@@ -159,6 +159,9 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
this.icon_state = pick(iconL) this.icon_state = pick(iconL)
this.blood_DNA = list() this.blood_DNA = list()
this.blood_DNA[dna.unique_enzymes] = dna.b_type this.blood_DNA[dna.unique_enzymes] = dna.b_type
for (var/ID in virus2)
var/datum/disease2/disease/V = virus2[ID]
this.virus2[ID] = V.getcopy()
if (species) this.basecolor = species.blood_color if (species) this.basecolor = species.blood_color
this.update_icon() this.update_icon()

View File

@@ -5,6 +5,9 @@
var/list/datum/autopsy_data/autopsy_data = list() var/list/datum/autopsy_data/autopsy_data = list()
var/list/trace_chemicals = list() // traces of chemicals in the organ, var/list/trace_chemicals = list() // traces of chemicals in the organ,
// links chemical IDs to number of ticks for which they'll stay in the blood // links chemical IDs to number of ticks for which they'll stay in the blood
var/germ_level = 0 // INTERNAL germs inside the organ, this is BAD if it's greater than INFECTION_LEVEL_ONE
proc/process() proc/process()
return 0 return 0
@@ -46,13 +49,18 @@
if(damage_this_tick > last_dam) if(damage_this_tick > last_dam)
force_process = 1 force_process = 1
last_dam = damage_this_tick last_dam = damage_this_tick
if(!force_process && !bad_external_organs.len)
return
if(force_process) if(force_process)
bad_external_organs.Cut() bad_external_organs.Cut()
for(var/datum/organ/external/Ex in organs) for(var/datum/organ/external/Ex in organs)
bad_external_organs += Ex bad_external_organs += Ex
//processing internal organs is pretty cheap, do that first.
for(var/datum/organ/internal/I in internal_organs)
I.process()
if(!force_process && !bad_external_organs.len)
return
for(var/datum/organ/external/E in bad_external_organs) for(var/datum/organ/external/E in bad_external_organs)
if(!E) if(!E)
continue continue
@@ -62,51 +70,22 @@
else else
E.process() E.process()
number_wounds += E.number_wounds number_wounds += E.number_wounds
//Robotic limb malfunctions
var/malfunction = 0
if (E.status & ORGAN_ROBOT && prob(E.brute_dam + E.burn_dam))
malfunction = 1
//Broken limbs hurt too
var/broken = 0
if(E.status & ORGAN_BROKEN && !(E.status & ORGAN_SPLINTED) )
broken = 1
if (!lying && world.time - l_move_time < 15)
//Moving around with fractured ribs won't do you any good //Moving around with fractured ribs won't do you any good
if (broken && E.internal_organs && prob(15)) if (E.is_broken() && E.internal_organs && prob(15))
if (!lying && world.timeofday - l_move_time < 15)
var/datum/organ/internal/I = pick(E.internal_organs) var/datum/organ/internal/I = pick(E.internal_organs)
custom_pain("You feel broken bones moving in your [E.display_name]!", 1) custom_pain("You feel broken bones moving in your [E.display_name]!", 1)
I.take_damage(rand(3,5)) I.take_damage(rand(3,5))
//Special effects for limbs. //Moving makes open wounds get infected much faster
if(E.name in list("l_hand","l_arm","r_hand","r_arm")) if (E.wounds.len)
var/obj/item/c_hand //Getting what's in this hand for(var/datum/wound/W in E.wounds)
var/hand if (W.infection_check())
if(E.name == "l_hand" || E.name == "l_arm") W.germ_level += 1
c_hand = l_hand
hand = "left hand"
if(E.name == "r_hand" || E.name == "r_arm")
c_hand = r_hand
hand = "right hand"
if (c_hand)
if(broken) if(E.name in list("l_leg","l_foot","r_leg","r_foot") && !lying)
u_equip(c_hand) if (!E.is_usable() || E.is_malfunctioning() || (E.is_broken() && !(E.status & ORGAN_SPLINTED)))
var/emote_scream = pick("screams in pain and", "let's out a sharp hiss and", "cries out and")
emote("me", 1, "[(species && species.flags & NO_PAIN) ? "" : emote_scream ] drops what they were holding in their [hand]!")
if(malfunction)
u_equip(c_hand)
emote("me", 1, "drops what they were holding, their [hand] malfunctioning!")
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
spark_system.start()
spawn(10)
del(spark_system)
else if(E.name in list("l_leg","l_foot","r_leg","r_foot") && !lying)
if (!E.is_usable() || malfunction || (broken && !(E.status & ORGAN_SPLINTED)))
leg_tally-- // let it fail even if just foot&leg leg_tally-- // let it fail even if just foot&leg
// standing is poor // standing is poor

View File

@@ -40,8 +40,6 @@
var/obj/item/hidden = null var/obj/item/hidden = null
var/list/implants = list() var/list/implants = list()
// INTERNAL germs inside the organ, this is BAD if it's greater 0
var/germ_level = 0
// how often wounds should be updated, a higher number means less often // how often wounds should be updated, a higher number means less often
var/wound_update_accuracy = 1 var/wound_update_accuracy = 1
@@ -240,6 +238,7 @@ This function completely restores a damaged organ to perfect condition.
if (W.can_worsen(type, damage)) if (W.can_worsen(type, damage))
compatible_wounds += W compatible_wounds += W
if(compatible_wounds.len)
var/datum/wound/W = pick(compatible_wounds) var/datum/wound/W = pick(compatible_wounds)
W.open_wound(damage) W.open_wound(damage)
if(prob(25)) if(prob(25))
@@ -251,6 +250,8 @@ This function completely restores a damaged organ to perfect condition.
//Creating wound //Creating wound
var/wound_type = get_wound_type(type, damage) var/wound_type = get_wound_type(type, damage)
if(wound_type)
var/datum/wound/W = new wound_type(damage) var/datum/wound/W = new wound_type(damage)
//Check whether we can add the wound to an existing wound //Check whether we can add the wound to an existing wound
@@ -279,7 +280,7 @@ This function completely restores a damaged organ to perfect condition.
if (damage <= 15) return /datum/wound/burn/large if (damage <= 15) return /datum/wound/burn/large
if (damage <= 30) return /datum/wound/burn/severe if (damage <= 30) return /datum/wound/burn/severe
if (damage <= 40) return /datum/wound/burn/deep if (damage <= 40) return /datum/wound/burn/deep
if (damage <= 50) return /datum/wound/burn/carbonised return /datum/wound/burn/carbonised
/**************************************************** /****************************************************
PROCESSING & UPDATING PROCESSING & UPDATING
@@ -295,7 +296,10 @@ This function completely restores a damaged organ to perfect condition.
if(last_dam != brute_dam + burn_dam) // Process when we are fully healed up. if(last_dam != brute_dam + burn_dam) // Process when we are fully healed up.
last_dam = brute_dam + burn_dam last_dam = brute_dam + burn_dam
return 1 return 1
else
last_dam = brute_dam + burn_dam last_dam = brute_dam + burn_dam
if(germ_level)
return 1
return 0 return 0
/datum/organ/external/process() /datum/organ/external/process()
@@ -327,50 +331,89 @@ This function completely restores a damaged organ to perfect condition.
if(!(status & ORGAN_BROKEN)) if(!(status & ORGAN_BROKEN))
perma_injury = 0 perma_injury = 0
//Infections
update_germs() update_germs()
return return
//Updating germ levels. Handles organ germ levels and necrosis. //Updating germ levels. Handles organ germ levels and necrosis.
#define GANGREN_LEVEL_ONE 100 /*
#define GANGREN_LEVEL_TWO 1000 The INFECTION_LEVEL values defined in setup.dm control the time it takes to reach the different
#define GANGREN_LEVEL_TERMINAL 2500 infection levels. Since infection growth is exponential, you can adjust the time it takes to get
#define GERM_TRANSFER_AMOUNT germ_level/500 from one germ_level to another using the rough formula:
desired_germ_level = initial_germ_level*e^(desired_time_in_seconds/1000)
So if I wanted it to take an average of 15 minutes to get from level one (100) to level two
I would set INFECTION_LEVEL_TWO to 100*e^(15*60/1000) = 245. Note that this is the average time,
the actual time is dependent on RNG.
INFECTION_LEVEL_ONE below this germ level nothing happens, and the infection doesn't grow
INFECTION_LEVEL_TWO above this germ level the infection will start to spread to internal and adjacent organs
INFECTION_LEVEL_THREE above this germ level the player will take additional toxin damage per second, and will die in minutes without
antitox. also, above this germ level you will need to overdose on spaceacillin to reduce the germ_level.
Note that amputating the affected organ does in fact remove the infection from the
player's body, though, antitox and spaceacillin are easy enough to get I doubt it will ever be needed.
*/
/datum/organ/external/proc/update_germs() /datum/organ/external/proc/update_germs()
if(status & ORGAN_ROBOT|ORGAN_DESTROYED) //Robotic limbs shouldn't be infected, nor should nonexistant limbs. if(status & (ORGAN_ROBOT|ORGAN_DESTROYED)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs.
germ_level = 0 germ_level = 0
return return
if(germ_level > 0 && owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs if(owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
//Syncing germ levels with external wounds //Syncing germ levels with external wounds
for(var/datum/wound/W in wounds) for(var/datum/wound/W in wounds)
if(!W.bandaged && !W.salved) //Open wounds can become infected
if (owner.germ_level > W.germ_level && W.infection_check())
W.germ_level++
//Infected wounds raise the organ's germ level
W.germ_level = max(W.germ_level, germ_level) //Wounds get all the germs W.germ_level = max(W.germ_level, germ_level) //Wounds get all the germs
if (W.germ_level > germ_level) //Badly infected wounds raise internal germ levels if (W.germ_level > germ_level) //Badly infected wounds raise internal germ levels
germ_level++ germ_level++
if(germ_level > GANGREN_LEVEL_ONE && prob(round(germ_level/100))) var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
if (germ_level > 0 && antibiotics > 5)
if (prob(4*antibiotics)) germ_level-- //the higher the germ level the more antibiotics you'll need.
if(germ_level >= INFECTION_LEVEL_ONE)
//having an infection raises your body temperature
var/fever_temperature = (owner.species.heat_level_1 - owner.species.body_temperature - 1)* min(germ_level/INFECTION_LEVEL_THREE, 1) + owner.species.body_temperature
if (owner.bodytemperature < fever_temperature)
//world << "fever: [owner.bodytemperature] < [fever_temperature], raising temperature."
owner.bodytemperature++
if(prob(round(germ_level/10)))
germ_level++ germ_level++
if (prob(5)) //adjust this to tweak how fast people take toxin damage from infections
owner.adjustToxLoss(1) owner.adjustToxLoss(1)
if(germ_level > GANGREN_LEVEL_TWO) if(germ_level >= INFECTION_LEVEL_TWO)
germ_level++ //spread the infection
owner.adjustToxLoss(1) for (var/datum/organ/internal/I in internal_organs)
/* if (I.germ_level < germ_level)
if(germ_level > GANGREN_LEVEL_TERMINAL) I.germ_level++
if (children) //To child organs
for (var/datum/organ/external/child in children)
if (child.germ_level < germ_level && !(child.status & ORGAN_ROBOT))
if (child.germ_level < INFECTION_LEVEL_ONE*2 || prob(30))
child.germ_level++
if (parent)
if (parent.germ_level < germ_level && !(parent.status & ORGAN_ROBOT))
if (parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30))
parent.germ_level++
if(germ_level >= INFECTION_LEVEL_THREE && antibiotics < 30) //overdosing is necessary to stop severe infections
if (!(status & ORGAN_DEAD)) if (!(status & ORGAN_DEAD))
status |= ORGAN_DEAD status |= ORGAN_DEAD
owner << "<span class='notice'>You can't feel your [display_name] anymore...</span>" owner << "<span class='notice'>You can't feel your [display_name] anymore...</span>"
owner.update_body(1)
if (prob(10)) //Spreading the fun germ_level++
if (children) //To child organs owner.adjustToxLoss(1)
for (var/datum/organ/external/child in children)
if (!(child.status & (ORGAN_DEAD|ORGAN_DESTROYED|ORGAN_ROBOT)))
child.germ_level += round(GERM_TRANSFER_AMOUNT)
if (parent)
if (!(parent.status & (ORGAN_DEAD|ORGAN_DESTROYED|ORGAN_ROBOT)))
parent.germ_level += round(GERM_TRANSFER_AMOUNT)
*/
//Updating wounds. Handles wound natural I had some free spachealing, internal bleedings and infections //Updating wounds. Handles wound natural I had some free spachealing, internal bleedings and infections
/datum/organ/external/proc/update_wounds() /datum/organ/external/proc/update_wounds()
@@ -681,9 +724,9 @@ This function completely restores a damaged organ to perfect condition.
/datum/organ/external/proc/get_damage() //returns total damage /datum/organ/external/proc/get_damage() //returns total damage
return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use health? return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use health?
/datum/organ/external/proc/is_infected() /datum/organ/external/proc/has_infected_wound()
for(var/datum/wound/W in wounds) for(var/datum/wound/W in wounds)
if(W.germ_level > 100) if(W.germ_level > 150)
return 1 return 1
return 0 return 0
@@ -700,7 +743,42 @@ This function completely restores a damaged organ to perfect condition.
/datum/organ/external/proc/is_usable() /datum/organ/external/proc/is_usable()
return !(status & (ORGAN_DESTROYED|ORGAN_MUTATED|ORGAN_DEAD)) return !(status & (ORGAN_DESTROYED|ORGAN_MUTATED|ORGAN_DEAD))
/**************************************************** /datum/organ/external/proc/is_broken()
return ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED))
/datum/organ/external/proc/is_malfunctioning()
return ((status & ORGAN_ROBOT) && prob(brute_dam + burn_dam))
//for arms and hands
/datum/organ/external/proc/process_grasp(var/obj/item/c_hand, var/hand_name)
if (!c_hand)
return
if(is_broken())
owner.u_equip(c_hand)
var/emote_scream = pick("screams in pain and", "lets out a sharp cry and", "cries out and")
owner.emote("me", 1, "[(owner.species && owner.species.flags & NO_PAIN) ? "" : emote_scream ] drops what they were holding in their [hand_name]!")
if(is_malfunctioning())
owner.u_equip(c_hand)
owner.emote("me", 1, "drops what they were holding, their [hand_name] malfunctioning!")
var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
spark_system.set_up(5, 0, src)
spark_system.attach(src)
spark_system.start()
spawn(10)
del(spark_system)
/datum/organ/external/proc/embed(var/obj/item/weapon/W, var/silent = 0)
if(!silent)
owner.visible_message("<span class='danger'>\The [W] sticks in the wound!</span>")
implants += W
owner.embedded_flag = 1
owner.verbs += /mob/proc/yank_out_object
W.add_blood(owner)
if(ismob(W.loc))
var/mob/living/H = W.loc
H.drop_item()
W.loc = owner/****************************************************
ORGAN DEFINES ORGAN DEFINES
****************************************************/ ****************************************************/
@@ -729,6 +807,10 @@ This function completely restores a damaged organ to perfect condition.
min_broken_damage = 20 min_broken_damage = 20
body_part = ARM_LEFT body_part = ARM_LEFT
process()
..()
process_grasp(owner.l_hand, "left hand")
/datum/organ/external/l_leg /datum/organ/external/l_leg
name = "l_leg" name = "l_leg"
display_name = "left leg" display_name = "left leg"
@@ -746,6 +828,10 @@ This function completely restores a damaged organ to perfect condition.
min_broken_damage = 20 min_broken_damage = 20
body_part = ARM_RIGHT body_part = ARM_RIGHT
process()
..()
process_grasp(owner.r_hand, "right hand")
/datum/organ/external/r_leg /datum/organ/external/r_leg
name = "r_leg" name = "r_leg"
display_name = "right leg" display_name = "right leg"
@@ -781,6 +867,10 @@ This function completely restores a damaged organ to perfect condition.
min_broken_damage = 15 min_broken_damage = 15
body_part = HAND_RIGHT body_part = HAND_RIGHT
process()
..()
process_grasp(owner.r_hand, "right hand")
/datum/organ/external/l_hand /datum/organ/external/l_hand
name = "l_hand" name = "l_hand"
display_name = "left hand" display_name = "left hand"
@@ -789,6 +879,10 @@ This function completely restores a damaged organ to perfect condition.
min_broken_damage = 15 min_broken_damage = 15
body_part = HAND_LEFT body_part = HAND_LEFT
process()
..()
process_grasp(owner.l_hand, "left hand")
/datum/organ/external/head /datum/organ/external/head
name = "head" name = "head"
icon_name = "head" icon_name = "head"

View File

@@ -21,6 +21,7 @@
return damage >= min_broken_damage return damage >= min_broken_damage
/datum/organ/internal/New(mob/living/carbon/human/H) /datum/organ/internal/New(mob/living/carbon/human/H)
..() ..()
var/datum/organ/external/E = H.organs_by_name[src.parent_organ] var/datum/organ/external/E = H.organs_by_name[src.parent_organ]
@@ -30,6 +31,37 @@
H.internal_organs[src.name] = src H.internal_organs[src.name] = src
src.owner = H src.owner = H
/datum/organ/internal/process()
//Process infections
if (!germ_level)
return
if (robotic >= 2) //TODO make robotic internal and external organs separate types of organ instead of a flag
germ_level = 0
return
var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
if (germ_level > 0 && antibiotics > 5)
if (prob(4*antibiotics)) germ_level--
if (antibiotics > 30) germ_level--
if (germ_level >= INFECTION_LEVEL_ONE/2)
if(prob(round(germ_level/6))) //aiming for germ level to go from ambient to INFECTION_LEVEL_TWO in an average of 15 minutes
germ_level++
if(prob(1))
take_damage(1,silent=0)
if (germ_level >= INFECTION_LEVEL_TWO)
var/datum/organ/external/parent = owner.get_organ(parent_organ)
if (parent.germ_level < germ_level && ( parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30) ))
parent.germ_level++
if (prob(5)) //about once every 20 seconds
take_damage(1,silent=prob(30))
/datum/organ/internal/proc/take_damage(amount, var/silent=0) /datum/organ/internal/proc/take_damage(amount, var/silent=0)
if(src.robotic == 2) if(src.robotic == 2)
src.damage += (amount * 0.8) src.damage += (amount * 0.8)
@@ -40,7 +72,6 @@
if (!silent) if (!silent)
owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1) owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1)
/datum/organ/internal/proc/emp_act(severity) /datum/organ/internal/proc/emp_act(severity)
switch(robotic) switch(robotic)
if(0) if(0)
@@ -96,7 +127,7 @@
owner.drip(10) owner.drip(10)
if(prob(4)) if(prob(4))
spawn owner.emote("me", 1, "gasps for air!") spawn owner.emote("me", 1, "gasps for air!")
owner.losebreath += 5 owner.losebreath += 15
/datum/organ/internal/liver /datum/organ/internal/liver
name = "liver" name = "liver"

View File

@@ -119,7 +119,7 @@
// checks if wound is considered open for external infections // checks if wound is considered open for external infections
// untreated cuts (and bleeding bruises) and burns are possibly infectable, chance higher if wound is bigger // untreated cuts (and bleeding bruises) and burns are possibly infectable, chance higher if wound is bigger
proc/can_infect() proc/infection_check()
if (is_treated() && damage < 10) if (is_treated() && damage < 10)
return 0 return 0
if (disinfected) if (disinfected)

View File

@@ -228,6 +228,8 @@
src.amount = length src.amount = length
if (param_color) if (param_color)
color = param_color color = param_color
else
color = item_color
pixel_x = rand(-2,2) pixel_x = rand(-2,2)
pixel_y = rand(-2,2) pixel_y = rand(-2,2)
updateicon() updateicon()
@@ -236,6 +238,7 @@
/obj/item/weapon/cable_coil/proc/updateicon() /obj/item/weapon/cable_coil/proc/updateicon()
if (!color) if (!color)
color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_ORANGE, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN) color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_ORANGE, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
item_color = color
if(amount == 1) if(amount == 1)
icon_state = "coil1" icon_state = "coil1"
name = "cable piece" name = "cable piece"

View File

@@ -356,6 +356,7 @@
switchcount = L.switchcount switchcount = L.switchcount
rigged = L.rigged rigged = L.rigged
brightness = L.brightness brightness = L.brightness
l_color = L.color
on = has_power() on = has_power()
update() update()
@@ -514,6 +515,7 @@
L.status = status L.status = status
L.rigged = rigged L.rigged = rigged
L.brightness = src.brightness L.brightness = src.brightness
L.color = l_color
// light item inherits the switchcount, then zero it // light item inherits the switchcount, then zero it
L.switchcount = switchcount L.switchcount = switchcount
@@ -539,6 +541,7 @@
L.status = status L.status = status
L.rigged = rigged L.rigged = rigged
L.brightness = brightness L.brightness = brightness
L.color = l_color
// light item inherits the switchcount, then zero it // light item inherits the switchcount, then zero it
L.switchcount = switchcount L.switchcount = switchcount
@@ -618,7 +621,7 @@
// called when on fire // called when on fire
/obj/machinery/light/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/machinery/light/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(prob(max(0, exposed_temperature - 673))) //0% at <400C, 100% at >500C if(prob(max(0, exposed_temperature - 673))) //0% at <400C, 100% at >500C
broken() broken()

View File

@@ -34,7 +34,7 @@
var/blue = mixOneColor(weight,bluecolor) var/blue = mixOneColor(weight,bluecolor)
//assemble all the pieces //assemble all the pieces
var/finalcolor = "#[red][green][blue]" var/finalcolor = rgb(red, green, blue)
return finalcolor return finalcolor
/proc/mixOneColor(var/list/weight, var/list/color) /proc/mixOneColor(var/list/weight, var/list/color)
@@ -58,10 +58,9 @@
mixedcolor = round(mixedcolor) mixedcolor = round(mixedcolor)
//until someone writes a formal proof for this algorithm, let's keep this in //until someone writes a formal proof for this algorithm, let's keep this in
if(mixedcolor<0x00 || mixedcolor>0xFF) // if(mixedcolor<0x00 || mixedcolor>0xFF)
return 0 // return 0
//that's not the kind of operation we are running here, nerd
mixedcolor=min(max(mixedcolor,0),255)
var/finalcolor = num2hex(mixedcolor) return mixedcolor
while(length(finalcolor)<2)
finalcolor = text("0[]",finalcolor) //Takes care of leading zeroes
return finalcolor

View File

@@ -293,6 +293,7 @@
var/max_pill_count = 20 var/max_pill_count = 20
/obj/machinery/chem_master/New() /obj/machinery/chem_master/New()
..()
var/datum/reagents/R = new/datum/reagents(100) var/datum/reagents/R = new/datum/reagents(100)
reagents = R reagents = R
R.my_atom = src R.my_atom = src

View File

@@ -118,10 +118,15 @@ datum
else //injected else //injected
M.contract_disease(D, 1, 0) M.contract_disease(D, 1, 0)
if(self.data && self.data["virus2"] && istype(M, /mob/living/carbon))//infecting... if(self.data && self.data["virus2"] && istype(M, /mob/living/carbon))//infecting...
var/list/vlist = self.data["virus2"]
if (vlist.len)
for (var/ID in vlist)
var/datum/disease2/disease/V = vlist[ID]
if(method == TOUCH) if(method == TOUCH)
infect_virus2(M,self.data["virus2"]) infect_virus2(M,V.getcopy())
else else
infect_virus2(M,self.data["virus2"],1) //injected, force infection! infect_virus2(M,V.getcopy(),1) //injected, force infection!
if(self.data && self.data["antibodies"] && istype(M, /mob/living/carbon))//... and curing if(self.data && self.data["antibodies"] && istype(M, /mob/living/carbon))//... and curing
var/mob/living/carbon/C = M var/mob/living/carbon/C = M
C.antibodies |= self.data["antibodies"] C.antibodies |= self.data["antibodies"]
@@ -146,6 +151,9 @@ datum
blood_prop.viruses += newVirus blood_prop.viruses += newVirus
newVirus.holder = blood_prop newVirus.holder = blood_prop
if(self.data["virus2"])
blood_prop.virus2 = virus_copylist(self.data["virus2"])
else if(istype(self.data["donor"], /mob/living/carbon/monkey)) else if(istype(self.data["donor"], /mob/living/carbon/monkey))
var/obj/effect/decal/cleanable/blood/blood_prop = locate() in T var/obj/effect/decal/cleanable/blood/blood_prop = locate() in T
@@ -1573,14 +1581,14 @@ datum
var/turf/the_turf = get_turf(O) var/turf/the_turf = get_turf(O)
var/datum/gas_mixture/napalm = new var/datum/gas_mixture/napalm = new
var/datum/gas/volatile_fuel/fuel = new var/datum/gas/volatile_fuel/fuel = new
fuel.moles = 5 fuel.moles = volume
napalm.trace_gases += fuel napalm.trace_gases += fuel
the_turf.assume_air(napalm) the_turf.assume_air(napalm)
reaction_turf(var/turf/T, var/volume) reaction_turf(var/turf/T, var/volume)
src = null src = null
var/datum/gas_mixture/napalm = new var/datum/gas_mixture/napalm = new
var/datum/gas/volatile_fuel/fuel = new var/datum/gas/volatile_fuel/fuel = new
fuel.moles = 5 fuel.moles = volume
napalm.trace_gases += fuel napalm.trace_gases += fuel
T.assume_air(napalm) T.assume_air(napalm)
return return

View File

@@ -127,8 +127,39 @@
..() // -> item/attackby() ..() // -> item/attackby()
if(istype(W,/obj/item/weapon/storage)) if(istype(W,/obj/item/weapon/storage))
..() // -> item/attackby() ..() // -> item/attackby()
if(istype(W,/obj/item/weapon/kitchen/utensil))
var/obj/item/weapon/kitchen/utensil/U = W
if(!U.reagents)
U.create_reagents(5)
if (U.reagents.total_volume > 0)
user << "\red You already have something on your [U]."
return
user.visible_message( \
"[user] scoops up some [src] with \the [U]!", \
"\blue You scoop up some [src] with \the [U]!" \
)
src.bitecount++
U.overlays.Cut()
U.loaded = "[src]"
var/image/I = new(U.icon, "loadedfood")
I.color = src.filling_color
U.overlays += I
reagents.trans_to(U,min(reagents.total_volume,5))
if (reagents.total_volume <= 0)
del(src)
return
if((slices_num <= 0 || !slices_num) || !slice_path) if((slices_num <= 0 || !slices_num) || !slice_path)
return 0 return 0
var/inaccurate = 0 var/inaccurate = 0
if( \ if( \
istype(W, /obj/item/weapon/kitchenknife) || \ istype(W, /obj/item/weapon/kitchenknife) || \
@@ -173,8 +204,8 @@
) )
else else
user.visible_message( \ user.visible_message( \
"\blue [user] inaccurately slices \the [src] with [W]!", \ "\blue [user] crudely slices \the [src] with [W]!", \
"\blue You inaccurately slice \the [src] with your [W]!" \ "\blue You crudely slice \the [src] with your [W]!" \
) )
slices_lost = rand(1,min(1,round(slices_num/2))) slices_lost = rand(1,min(1,round(slices_num/2)))
var/reagents_per_slice = reagents.total_volume/slices_num var/reagents_per_slice = reagents.total_volume/slices_num
@@ -182,6 +213,7 @@
var/obj/slice = new slice_path (src.loc) var/obj/slice = new slice_path (src.loc)
reagents.trans_to(slice,reagents_per_slice) reagents.trans_to(slice,reagents_per_slice)
del(src) del(src)
return return
/obj/item/weapon/reagent_containers/food/snacks/Del() /obj/item/weapon/reagent_containers/food/snacks/Del()
@@ -876,33 +908,6 @@
..() ..()
reagents.add_reagent("nutriment", 8) reagents.add_reagent("nutriment", 8)
bitesize = 1 bitesize = 1
attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W,/obj/item/weapon/kitchen/utensil/fork))
if (W.icon_state == "forkloaded")
user << "\red You already have omelette on your fork."
return
//W.icon = 'icons/obj/kitchen.dmi'
W.icon_state = "forkloaded"
/*if (herp)
world << "[user] takes a piece of omelette with his fork!"*/
//Why this unecessary check? Oh I know, because I'm bad >:C
// Yes, you are. You griefing my badmin toys. --rastaf0
user.visible_message( \
"[user] takes a piece of omelette with their fork!", \
"\blue You take a piece of omelette with your fork!" \
)
reagents.remove_reagent("nutriment", 1)
if (reagents.total_volume <= 0)
del(src)
/*
* Unsused.
/obj/item/weapon/reagent_containers/food/snacks/omeletteforkload
name = "Omelette Du Fromage"
desc = "That's all you can say!"
New()
..()
reagents.add_reagent("nutriment", 1)
*/
/obj/item/weapon/reagent_containers/food/snacks/muffin /obj/item/weapon/reagent_containers/food/snacks/muffin
name = "Muffin" name = "Muffin"
@@ -1532,7 +1537,7 @@
filling_color = "#ADAC7F" filling_color = "#ADAC7F"
var/wrapped = 0 var/wrapped = 0
var/monkey_type = null var/monkey_type = /mob/living/carbon/monkey
New() New()
..() ..()
@@ -1550,19 +1555,46 @@
if(wrapped) if(wrapped)
Unwrap(user) Unwrap(user)
On_Consume(var/mob/M)
M << "<span class = 'warning'>Something inside of you suddently expands!</span>"
if (istype(M, /mob/living/carbon/human))
//Do not try to understand.
var/obj/item/weapon/surprise = new/obj/item/weapon(M)
var/mob/living/carbon/monkey/ook = new monkey_type(null) //no other way to get access to the vars, alas
surprise.icon = ook.icon
surprise.icon_state = ook.icon_state
surprise.name = "malformed [ook.name]"
surprise.desc = "Looks like \a very deformed [ook.name], a little small for its kind. It shows no signs of life."
del(ook) //rip nullspace monkey
surprise.transform *= 0.6
surprise.add_blood(M)
var/mob/living/carbon/human/H = M
var/datum/organ/external/E = H.get_organ("chest")
E.fracture()
for (var/datum/organ/internal/I in E.internal_organs)
I.take_damage(rand(I.min_bruised_damage, I.min_broken_damage+1))
if (!E.hidden && prob(60)) //set it snuggly
E.hidden = surprise
E.cavity = 0
else //someone is having a bad day
E.createwound(CUT, 30)
E.embed(surprise)
else if (ismonkey(M))
M.visible_message("<span class='danger'>[M] suddenly tears in half!</span>")
var/mob/living/carbon/monkey/ook = new monkey_type(M.loc)
ook.name = "malformed [ook.name]"
ook.transform *= 0.6
ook.add_blood(M)
M.gib()
..()
proc/Expand() proc/Expand()
for(var/mob/M in viewers(src,7)) for(var/mob/M in viewers(src,7))
M << "\red \The [src] expands!" M << "\red \The [src] expands!"
if(monkey_type) new monkey_type(src)
switch(monkey_type)
if("tajara")
new /mob/living/carbon/monkey/tajara(get_turf(src))
if("unathi")
new /mob/living/carbon/monkey/unathi(get_turf(src))
if("skrell")
new /mob/living/carbon/monkey/skrell(get_turf(src))
else
new /mob/living/carbon/monkey(get_turf(src))
del(src) del(src)
proc/Unwrap(mob/user as mob) proc/Unwrap(mob/user as mob)
@@ -1580,18 +1612,18 @@
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/farwacube /obj/item/weapon/reagent_containers/food/snacks/monkeycube/farwacube
name = "farwa cube" name = "farwa cube"
monkey_type ="tajara" monkey_type = /mob/living/carbon/monkey/tajara
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/farwacube /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/farwacube
name = "farwa cube" name = "farwa cube"
monkey_type ="tajara" monkey_type =/mob/living/carbon/monkey/tajara
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/stokcube /obj/item/weapon/reagent_containers/food/snacks/monkeycube/stokcube
name = "stok cube" name = "stok cube"
monkey_type ="unathi" monkey_type = /mob/living/carbon/monkey/unathi
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/stokcube /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/stokcube
name = "stok cube" name = "stok cube"
monkey_type ="unathi" monkey_type =/mob/living/carbon/monkey/unathi
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/neaeracube /obj/item/weapon/reagent_containers/food/snacks/monkeycube/neaeracube
@@ -1599,7 +1631,7 @@
monkey_type ="skrell" monkey_type ="skrell"
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/neaeracube /obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/neaeracube
name = "neaera cube" name = "neaera cube"
monkey_type ="skrell" monkey_type =/mob/living/carbon/monkey/skrell
/obj/item/weapon/reagent_containers/food/snacks/spellburger /obj/item/weapon/reagent_containers/food/snacks/spellburger

View File

@@ -166,7 +166,7 @@
if(src) if(src)
del(src) del(src)
/obj/structure/reagent_dispensers/fueltank/temperature_expose(datum/gas_mixture/air, temperature, volume) /obj/structure/reagent_dispensers/fueltank/fire_act(datum/gas_mixture/air, temperature, volume)
if(temperature > T0C+500) if(temperature > T0C+500)
explode() explode()
return ..() return ..()

View File

@@ -234,20 +234,8 @@
flush() flush()
flushing = 1 flushing = 1
flick("intake-closing", src) flick("intake-closing", src)
var/deliveryCheck = 0
var/obj/structure/disposalholder/H = new() // virtual holder object which actually var/obj/structure/disposalholder/H = new() // virtual holder object which actually
// travels through the pipes. // travels through the pipes.
for(var/obj/structure/bigDelivery/O in src)
deliveryCheck = 1
if(O.sortTag == 0)
O.sortTag = 1
for(var/obj/item/smallDelivery/O in src)
deliveryCheck = 1
if (O.sortTag == 0)
O.sortTag = 1
if(deliveryCheck == 0)
H.destinationTag = 1
air_contents = new() // new empty gas resv. air_contents = new() // new empty gas resv.
sleep(10) sleep(10)

View File

@@ -5,8 +5,9 @@
icon = 'icons/obj/cryogenics.dmi' icon = 'icons/obj/cryogenics.dmi'
icon_state = "cellold0" icon_state = "cellold0"
var/spawn_type var/spawn_type
var/current_ticks_spawning = 0 var/time_spent_spawning = 0
var/ticks_required_to_spawn var/time_per_spawn = 0
var/last_process= 0
density = 1 density = 1
var/previous_power_state = 0 var/previous_power_state = 0
@@ -17,7 +18,7 @@
/obj/machinery/auto_cloner/New() /obj/machinery/auto_cloner/New()
..() ..()
ticks_required_to_spawn = rand(240,1440) time_per_spawn = rand(1200,3600)
//33% chance to spawn nasties //33% chance to spawn nasties
if(prob(33)) if(prob(33))
@@ -53,13 +54,12 @@
src.visible_message("\blue \icon[src] [src] suddenly comes to life!") src.visible_message("\blue \icon[src] [src] suddenly comes to life!")
//slowly grow a mob //slowly grow a mob
current_ticks_spawning++
if(prob(5)) if(prob(5))
src.visible_message("\blue \icon[src] [src] [pick("gloops","glugs","whirrs","whooshes","hisses","purrs","hums","gushes")].") src.visible_message("\blue \icon[src] [src] [pick("gloops","glugs","whirrs","whooshes","hisses","purrs","hums","gushes")].")
//if we've finished growing... //if we've finished growing...
if(current_ticks_spawning >= ticks_required_to_spawn) if(time_spent_spawning >= time_per_spawn)
current_ticks_spawning = 0 time_spent_spawning = 0
use_power = 1 use_power = 1
src.visible_message("\blue \icon[src] [src] pings!") src.visible_message("\blue \icon[src] [src] pings!")
icon_state = "cellold1" icon_state = "cellold1"
@@ -68,7 +68,7 @@
new spawn_type(src.loc) new spawn_type(src.loc)
//if we're getting close to finished, kick into overdrive power usage //if we're getting close to finished, kick into overdrive power usage
if(current_ticks_spawning / ticks_required_to_spawn > 0.75) if(time_spent_spawning / time_per_spawn > 0.75)
use_power = 2 use_power = 2
icon_state = "cellold2" icon_state = "cellold2"
desc = "It's full of a bubbling viscous liquid, and is lit by a mysterious glow. A dark shape appears to be forming inside..." desc = "It's full of a bubbling viscous liquid, and is lit by a mysterious glow. A dark shape appears to be forming inside..."
@@ -76,6 +76,8 @@
use_power = 1 use_power = 1
icon_state = "cellold1" icon_state = "cellold1"
desc = "It's full of a bubbling viscous liquid, and is lit by a mysterious glow." desc = "It's full of a bubbling viscous liquid, and is lit by a mysterious glow."
time_spent_spawning = time_spent_spawning + world.time - last_process
else else
if(previous_power_state) if(previous_power_state)
previous_power_state = 0 previous_power_state = 0
@@ -83,5 +85,6 @@
src.visible_message("\blue \icon[src] [src] suddenly shuts down.") src.visible_message("\blue \icon[src] [src] suddenly shuts down.")
//cloned mob slowly breaks down //cloned mob slowly breaks down
if(current_ticks_spawning > 0) time_spent_spawning = max(time_spent_spawning + last_process - world.time, 0)
current_ticks_spawning--
last_process = world.time

Some files were not shown because too many files have changed in this diff Show More