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\helper_datums\construction_datum.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\teleport.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\powersink.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\traitordevices.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\geosample.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\artifact\artifact.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_fossils.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\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_harvester.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)
/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)
health -= 5
healthcheck()

View File

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

View File

@@ -50,7 +50,7 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
icon = 'icons/effects/fire.dmi'
icon_state = "1"
l_color = "#ED9200"
layer = TURF_LAYER
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)
//check if there is something to combust
if(!air_contents.check_recombustability(liquid))
if(!air_contents.check_combustability(liquid))
//del src
RemoveFire()
@@ -116,7 +116,7 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
var/datum/gas_mixture/acs = enemy_tile.return_air()
var/obj/effect/decal/cleanable/liquid_fuel/liq = locate() in enemy_tile
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
//reduce firelevel.
if(enemy_tile.fire_protection > world.time-30)
@@ -134,16 +134,8 @@ 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 ///////////////////////////////////////////////
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!
flow.zburn(liquid,1)
//burn baby burn!
flow.zburn(liquid,1)
//merge the air back
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(liquid)
return 1
if (phoron >= 0.1)
if(QUANTIZE(phoron * vsc.fire_consuption_rate) >= 0.1)
return 1
if(fuel && fuel.moles >= 0.1)
if(fuel && QUANTIZE(fuel.moles * vsc.fire_consuption_rate) >= 0.1)
return 1
return 0

View File

@@ -366,3 +366,36 @@ datum/projectile_data
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)
/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

@@ -6,11 +6,12 @@
// in the logs. ascii character 13 = CR
/var/global/log_end= world.system_type == UNIX ? ascii2text(13) : ""
/proc/error(msg)
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
/proc/warning(msg)
world.log << "## WARNING: [msg][log_end]"
@@ -79,4 +80,4 @@
diary << "\[[time_stamp()]]PDA: [text][log_end]"
/proc/log_misc(text)
diary << "\[[time_stamp()]]MISC: [text][log_end]"
diary << "\[[time_stamp()]]MISC: [text][log_end]"

View File

@@ -3,6 +3,11 @@
var/const/E = 2.71828183
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)
if(!x && !y) return 0

View File

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

View File

@@ -5,9 +5,10 @@
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
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
update. Actual updates are handled periodically by the lighting_controller. This carries additional overheads, however it
means that each thing is changed only once per lighting_controller.processing_interval ticks. Allowing for greater control
@@ -15,50 +16,40 @@
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.
Unlike our old system there is a hardcoded maximum luminosity. This is to discourage coders using large luminosity values
for dynamic lighting, as the cost of lighting grows rapidly at large luminosity levels (especially when changing opacity
at runtime)
Unlike our old system there are hardcoded maximum luminositys (different for certain atoms).
This is to cap the cost of creating lighting effects.
(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
have larger memory requirements than our previous system but hopefully it's 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
costs.
have larger memory requirements than our previous system but it's easily worth the hassle for the greater control we
gain. It also reduces cost of removing lighting effects by a lot!
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)
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_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_ICON 'icons/effects/ss13_dark_alpha7.dmi' //Icon used for lighting shading effects
#define LIGHTING_CIRCULAR 1 //comment this out to use old square lighting effects.
#define LIGHTING_LAYER 10 //Drawing layer for lighting overlays
#define LIGHTING_ICON 'icons/effects/ss13_dark_alpha6.dmi' //Icon used for lighting shading effects
datum/light_source
var/atom/owner
var/changed = 1
var/mobile = 1
var/list/effect = list()
var/__x = 0 //x coordinate at last update
var/__y = 0 //y coordinate at last update
var/l_color
New(atom/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.")
..()
owner = A
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.
l_color = owner.l_color
__x = owner.x
__y = owner.y
// the lighting object maintains a list of all light sources
lighting_controller.lights += src
@@ -69,12 +60,14 @@ datum/light_source
remove_effect()
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
if(owner.x != __x || owner.y != __y)
__x = owner.x
__y = owner.y
changed = 1
// check to see if we've moved since last update
if(owner.x != __x || owner.y != __y)
__x = owner.x
__y = owner.y
changed = 1
if (owner.l_color != l_color)
changed = 1
if(changed)
changed = 0
@@ -85,197 +78,264 @@ datum/light_source
proc/remove_effect()
// before we apply the effect we remove the light's current effect.
if(effect.len)
for(var/turf in effect) // negate the effect of this light source
var/turf/T = turf
T.update_lumcount(-effect[T])
effect.Cut() // clear the effect list
for(var/turf/T in effect) // negate the effect of this light source
T.update_lumcount(-effect[T], l_color, 1)
effect.Cut() // clear the effect list
proc/add_effect()
// only do this if the light is turned on and is on the map
if(owner.loc && owner.luminosity > 0)
effect = new_effect() // identify the effects of this light source
for(var/turf in effect)
var/turf/T = turf
T.update_lumcount(effect[T]) // apply the effect
l_color = owner.l_color
effect = list()
for(var/turf/T in view(owner.get_light_range(),owner))
var/delta_lumen = lum(T)
if(delta_lumen > 0)
effect[T] = delta_lumen
T.update_lumcount(delta_lumen, l_color, 0)
return 0
else
owner.light = null
return 1 //cause the light to be removed from the lights list and garbage collected once it's no
//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)
return owner.luminosity - max(abs(A.x-__x),abs(A.y-__y))
// var/dist = cheap_hypotenuse(A.x,A.y,__x,__y) //fetches the pythagorean distance between A and the light
// if(owner.luminosity < dist) //if the turf is outside the radius the light doesn't illuminate it
// return 0
// return round(owner.luminosity - (dist/2),0.1)
if (owner.trueLuminosity < 1)
return 0
var/dist
if(!A)
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
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 atoms with luminosity when they are constructed will create a light_source automatically
//TODO: lag reduction
//Turfs and atoms with luminosity when they are constructed will create a light_source automatically
turf/New()
..()
if(opacity)
UpdateAffectingLights()
if(luminosity)
world.log << "[type] has luminosity at New()"
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)
//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
//TODO: lag reduction
atom/movable/New()
..()
if(opacity)
UpdateAffectingLights()
if(isturf(loc))
if(loc:lighting_lumcount > 1)
UpdateAffectingLights()
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)
//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.
atom/movable/Del()
if(opacity)
UpdateAffectingLights()
if(isturf(loc))
if(loc:lighting_lumcount > 1)
UpdateAffectingLights()
..()
//Sets our luminosity. Enforces a hardcoded maximum luminosity by default. This maximum can be overridden but it is extremely
//unwise to do so.
//Sets our luminosity.
//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 have a light already it is merely updated
atom/proc/SetLuminosity(new_luminosity, max_luminosity = LIGHTING_MAX_LUMINOSITY)
//If we are setting luminosity to 0 the light will be cleaned up by the controller and garbage collected once all its
//queues are complete.
//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)
new_luminosity = 0
// world.log << "## WARNING: [type] - luminosity cannot be negative"
else if(max_luminosity < new_luminosity)
new_luminosity = max_luminosity
// if(luminosity != new_luminosity)
// world.log << "## WARNING: [type] - LIGHT_MAX_LUMINOSITY exceeded"
if(!trueLum)
new_luminosity *= new_luminosity
if(light)
if(trueLuminosity != new_luminosity) //non-luminous lights are removed from the lights list in add_effect()
light.changed = 1
else
if(new_luminosity)
light = new(src)
trueLuminosity = new_luminosity
if (trueLuminosity < 1)
luminosity = 0
else if (trueLuminosity <= 100)
luminosity = sqrtTable[trueLuminosity]
else
luminosity = sqrt(trueLuminosity)
if(isturf(loc))
if(light)
if(luminosity != new_luminosity) //TODO: remove lights from the light list when they're not luminous? DONE in add_effect
light.changed = 1
else
if(new_luminosity)
light = new(src)
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)
luminosity = new_luminosity
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.
atom/proc/SetOpacity(var/new_opacity)
if(new_opacity == null) new_opacity = !opacity
else if(opacity == new_opacity) return
opacity = new_opacity
atom/proc/SetOpacity(new_opacity)
if(new_opacity == null)
new_opacity = !opacity //default = toggle 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
UpdateAffectingLights()
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()
//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
atom/proc/UpdateAffectingLights()
var/turf/T = src
if(!isturf(T))
T = loc
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()
/atom/movable/SetOpacity(new_opacity)
if(..()==1) //only bother if opacity changed
if(isturf(loc)) //only bother with an update if we're on a turf
var/turf/T = loc
if(T.lighting_lumcount) //only bother with an update if our turf is currently affected by a light
UpdateAffectingLights()
// 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
var/lighting_lumcount = 0
var/lighting_changed = 0
var/color_lighting_lumcount = 0
var/list/colors = list()
turf/space
lighting_lumcount = 4 //starlight
turf/proc/update_lumcount(amount)
turf/proc/update_lumcount(amount, _lcolor, removing = 0)
lighting_lumcount += amount
// if(lighting_lumcount < 0 || lighting_lumcount > 100)
// world.log << "## WARNING: [type] ([src]) lighting_lumcount = [lighting_lumcount]"
var/blended
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)
lighting_controller.changed_turfs += src
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()
lighting_changed = 0
var/area/Area = loc
if(!istype(Area) || !Area.lighting_use_dynamic) return
// change the turf's area depending on its brightness
// restrict light to valid levels
var/light = min(max(round(lighting_lumcount,1),0),lighting_controller.lighting_states)
var/level = min(max(round(lighting_lumcount,1),0),lighting_controller.lighting_states)
var/new_tag = lighting_tag(level)
var/find = findtextEx(Area.tag, "sd_L")
var/new_tag = copytext(Area.tag, 1, find)
new_tag += "sd_L[light]"
// pomf - If we have a lighting color that is not null, apply the new tag to seperate the areas.
if (l_color)
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
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)
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","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
if (!A)
A = build_lighting_area(new_tag, level, color_light)
else 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)
A.SetLightLevel(level, color_light)
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
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/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(light <= 0)
light = 0
@@ -291,17 +351,97 @@ area
else
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
if(!tag) tag = "[type]"
tagbase = "[type]"
if(!tag) tag = tagbase
if(!lighting_use_dynamic)
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.
SetLightLevel(4)
//#undef LIGHTING_LAYER
#undef LIGHTING_CIRCULAR
//#undef LIGHTING_ICON
#undef LIGHTING_MAX_LUMINOSITY
#undef LIGHTING_MAX_LUMINOSITY_MOB
#undef LIGHTING_LAYER
//#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

@@ -146,6 +146,11 @@ proc/get_id_photo(var/mob/living/carbon/human/H)
if(E.status & ORGAN_ROBOT)
temp.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
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
if(H.species.flags & HAS_SKIN_TONE)

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/pass_flags = 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.
var/datum/reagents/reagents = null

View File

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

View File

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

View File

@@ -188,7 +188,8 @@
//message_admins("The probability of a new traitor is [traitor_prob]%")
if(prob(traitor_prob))
message_admins("New traitor roll passed. Making a new Traitor.")
forge_traitor_objectives(character.mind)
if (!config.objectives_disabled)
forge_traitor_objectives(character.mind)
equip_traitor(character)
traitors += character.mind
character << "\red <B>You are the traitor.</B>"

View File

@@ -87,7 +87,7 @@
return 1
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)
health -= 0.01 * temperature
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
//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
absorb_objective.owner = changeling
absorb_objective.gen_amount_goal(2, 3)

View File

@@ -98,7 +98,7 @@
item_state = "cult_armour"
desc = "A bulky suit of armour, bristling with spikes. It looks space proof."
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
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
siemens_coefficient = 0

View File

@@ -154,7 +154,7 @@
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

View File

@@ -1367,17 +1367,20 @@ It is possible to destroy the net by the occupant or someone else.
playsound(M.loc, 'sound/effects/sparks4.ogg', 50, 1)
anim(M.loc,M,'icons/mob/mob.dmi',,"phaseout",,M.dir)
M.loc = pick(holdingfacility)//Throw mob in to the holding facility.
M << "\red You appear in a strange place!"
if(holdingfacility.len)
M.loc = pick(holdingfacility)//Throw mob in to the holding facility.
spawn(0)
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.start()
playsound(M.loc, 'sound/effects/phasein.ogg', 25, 1)
playsound(M.loc, 'sound/effects/sparks2.ogg', 50, 1)
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).
else
M.loc = null
spawn(0)
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.start()
playsound(M.loc, 'sound/effects/phasein.ogg', 25, 1)
playsound(M.loc, 'sound/effects/sparks2.ogg', 50, 1)
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).
M << "\red You appear in a strange place!"
for(var/mob/O in viewers(src, 3))
O.show_message(text("[] vanished!", M), 1, text("You hear sparks flying!"), 2)

View File

@@ -239,7 +239,7 @@
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
//Carn: Spacevines random event.

View File

@@ -112,8 +112,6 @@ Implants;
feedback_set_details("round_start","[time2text(world.realtime)]")
if(ticker && 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]")
return 1

View File

@@ -108,6 +108,9 @@
/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
var/datum/objective/meme_attune/attune_objective = new
attune_objective.owner = meme

View File

@@ -85,6 +85,8 @@
return 1
/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)
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)
if (config.objectives_disabled)
return
var/datum/objective/nuclear/syndobj = new
syndobj.owner = syndicate
syndicate.objectives += syndobj

View File

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

View File

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

View File

@@ -91,12 +91,12 @@
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/pda/botanist(H), slot_belt)
if(H.backbag == 3)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_hyd(H), slot_back)
else if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
switch(H.backbag)
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_hyd(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)
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/under/rank/virologist(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/mask/surgical(H), slot_wear_mask)
if(H.backbag == 3)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_vir(H), slot_back)
switch(H.backbag)
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")
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)
@@ -122,12 +126,12 @@
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/clothing/suit/storage/labcoat/chemist(H), slot_wear_suit)
if(H.backbag == 3)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_chem(H), slot_back)
else if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
switch(H.backbag)
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_chem(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)
return 1
@@ -153,12 +157,12 @@
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/device/flashlight/pen(H), slot_s_store)
if(H.backbag == 3)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_gen(H), slot_back)
else if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
switch(H.backbag)
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_gen(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)
return 1
/*/datum/job/virologist

View File

@@ -27,12 +27,12 @@
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/weapon/clipboard(H), slot_l_hand)
if(H.backbag == 3)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
else if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
switch(H.backbag)
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)
return 1
@@ -57,12 +57,12 @@
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/clothing/suit/storage/labcoat/science(H), slot_wear_suit)
if(H.backbag == 3)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
else if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
switch(H.backbag)
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)
return 1
@@ -86,12 +86,12 @@
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/clothing/suit/storage/labcoat/science(H), slot_wear_suit)
if(H.backbag == 3)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
else if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
switch(H.backbag)
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)
return 1

View File

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

View File

@@ -308,6 +308,13 @@
robot = "Prosthetic:"
if(e.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
for(var/I in e.implants)
@@ -332,8 +339,16 @@
mech = "Assisted:"
if(i.robotic == 2)
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 += "<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 += "</table>"
if(occupant.sdisabilities & BLIND)

View File

@@ -1325,7 +1325,7 @@ FIRE ALARM
else
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(temperature > T0C+200)
src.alarm() // added check of detector status here

View File

@@ -110,7 +110,7 @@ update_flag
overlays += "can-o3"
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)
health -= 5
healthcheck()

View File

@@ -304,6 +304,21 @@
user.drop_item()
del(W)
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
..()

View File

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

View File

@@ -26,7 +26,7 @@
********************/
/obj/machinery/microwave/New()
//..() //do not need this
..()
reagents = new/datum/reagents(100)
reagents.my_atom = src
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()
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
if(O.client)
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)
spawn(0)
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)
return
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)
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)
src.log_message("Exposed to dangerous temperature.",1)
src.take_damage(5,"fire")

View File

@@ -287,7 +287,7 @@ Alien plants should do something if theres a lot of poison
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)
health -= 5
healthcheck()
@@ -469,7 +469,7 @@ Alien plants should do something if theres a lot of poison
if(health <= 0)
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)
health -= 5
healthcheck()

View File

@@ -27,24 +27,6 @@ would spawn and follow the beaker, even if it is carried or thrown.
reagents.delete()
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)
//var/turf/T = src.loc
//if (istype(T, /turf))
@@ -559,7 +541,7 @@ steam.start() -- spawns the effect
// foam disolves when heated
// 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)))
flick("[icon_state]-disolve", src)

View File

@@ -154,7 +154,7 @@
else
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)
endurance -= 5
CheckEndurance()

View File

@@ -47,7 +47,7 @@
if(health <= 0)
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)
health -= 5
healthcheck()

View File

@@ -92,6 +92,17 @@ REAGENT SCANNER
usr << "\red You don't have the dexterity to do this!"
return
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/OX = M.getOxyLoss() > 50 ? "<b>[M.getOxyLoss()]</b>" : M.getOxyLoss()
var/TX = M.getToxLoss() > 50 ? "<b>[M.getToxLoss()]</b>" : M.getToxLoss()
@@ -161,7 +172,7 @@ REAGENT SCANNER
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)))
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."
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()
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)
burst()
return

View File

@@ -117,7 +117,7 @@
//Step two - washing..... it's actually in washing machine code.
//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)
wetness--

View File

@@ -1,14 +1,18 @@
/* Toys!
* ContainsL
* Contains:
* Balloons
* Fake telebeacon
* Fake singularity
* Toy gun
* Toy crossbow
* Toy swords
* Toy mechs
* Crayons
* Snap pops
* Water flower
* Therapy dolls
* Toddler doll
* Inflatable duck
*/
@@ -579,6 +583,55 @@
w_class = 3
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.
/obj/item/weapon/toddler
icon_state = "toddler"
@@ -590,6 +643,7 @@
*/
//This should really be somewhere else but I don't know where. w/e
/obj/item/weapon/inflatable_duck
name = "inflatable duck"
desc = "No bother to sink or swim when you can just float!"

View File

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

View File

@@ -7,19 +7,21 @@
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))
for(var/mob/living/carbon/M in L)
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)
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))
B.health -= damage
B.update_icon()
new/obj/effect/effect/smoke/flashbang(src.loc)
del(src)
return
@@ -30,7 +32,7 @@
S.icon_state = "shield0"
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
var/eye_safety = 0
@@ -98,6 +100,15 @@
M << "\red Your ears start to ring!"
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
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
origin_tech = "materials=1"
attack_verb = list("attacked", "stabbed", "poked")
sharp = 0
var/loaded //Descriptive string for currently loaded food object.
/obj/item/weapon/kitchen/utensil/New()
if (prob(60))
src.pixel_y = rand(0, 4)
return
/*
* Spoons
*/
/obj/item/weapon/kitchen/utensil/spoon
name = "spoon"
desc = "SPOON!"
icon_state = "spoon"
attack_verb = list("attacked", "poked")
create_reagents(5)
/obj/item/weapon/kitchen/utensil/pspoon
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)
/obj/item/weapon/kitchen/utensil/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(!istype(M))
return ..()
if(user.zone_sel.selecting != "eyes" && user.zone_sel.selecting != "head")
return ..()
if(user.a_intent != "help")
if(user.zone_sel.selecting == "head" || user.zone_sel.selecting == "eyes")
if((CLUMSY in user.mutations) && prob(50))
M = user
return eyestab(M,user)
else
return ..()
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 (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 a delicious forkful of omelette!", user), 1)
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 [] a delicious forkful of omelette!", user, M), 1)
O.show_message(text("\blue [] feeds [] some [] from \the []", user, M, loaded, src), 1)
M.reagents.add_reagent("nutriment", 1)
src.icon_state = "fork"
overlays.Cut()
return
else
if((CLUMSY in user.mutations) && prob(50))
M = user
return eyestab(M,user)
/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
name = "plastic fork"
desc = "Yay, no washing up to do."
icon_state = "pfork"
/obj/item/weapon/kitchen/utensil/pfork/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(!istype(M))
return ..()
/obj/item/weapon/kitchen/utensil/spoon
name = "spoon"
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")
return ..()
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))
M = user
return eyestab(M,user)
/obj/item/weapon/kitchen/utensil/pspoon
name = "plastic spoon"
desc = "It's a plastic spoon. How dull."
icon_state = "pspoon"
attack_verb = list("attacked", "poked")
/*
* Knives
@@ -477,49 +456,4 @@
for(var/i = 1, i <= rand(1,2), i++)
if(I)
step(I, pick(NORTH,SOUTH,EAST,WEST))
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)*/
sleep(rand(2,4))

View File

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

View File

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

View File

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

View File

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

View File

@@ -216,7 +216,7 @@
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(exposed_temperature > T0C + 1500)
health -= 1

View File

@@ -82,6 +82,7 @@
state = 1
update_icon()
isSwitchingStates = 0
update_nearby_tiles()
proc/Close()
isSwitchingStates = 1
@@ -93,6 +94,7 @@
state = 0
update_icon()
isSwitchingStates = 0
update_nearby_tiles()
update_icon()
if(state)
@@ -198,7 +200,7 @@
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)
TemperatureAct(exposed_temperature)

View File

@@ -361,7 +361,7 @@
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)
hit(round(exposed_volume / 100), 0)
..()
@@ -381,7 +381,7 @@
shardtype = /obj/item/weapon/shard/phoron
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)
hit(round(exposed_volume / 1000), 0)
..()
@@ -395,7 +395,7 @@
reinf = 1
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
/obj/structure/window/reinforced

View File

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

View File

@@ -104,7 +104,7 @@
for(var/obj/machinery/door/airlock/phoron/D in range(3,src))
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)
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()
/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)
//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'
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
flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE | THICKMATERIAL
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
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50)
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."
icon_state = "s-ninja"
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
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
siemens_coefficient = 0.2

View File

@@ -55,7 +55,7 @@
item_state = "eng_hardsuit"
slowdown = 1
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
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
@@ -359,7 +359,7 @@
slowdown = 1
w_class = 3
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
species_restricted = list("exclude","Unathi","Tajaran","Skrell","Vox")
@@ -402,7 +402,7 @@
name = "medical hardsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has minor radiation shielding."
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)
//Security
@@ -421,7 +421,7 @@
desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor."
item_state = "sec_hardsuit"
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

View File

@@ -4,12 +4,15 @@
//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
/proc/EquipCustomItems(mob/living/carbon/human/M)
// load lines
var/file = file2text("config/custom_items.txt")
var/lines = text2list(file, "\n")
/var/list/custom_items = list()
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
var/list/Entry = text2list(line, ":")
for(var/i = 1 to Entry.len)
@@ -24,6 +27,8 @@
var/ok = 0 // 1 if the item was placed successfully
P = trim(P)
var/path = text2path(P)
if(!path) continue
var/obj/item/Item = new path()
if(istype(Item,/obj/item/weapon/card/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)
var/mob/living/carbon/human/C = candidates[1]
// Bruise one of their organs
var/O = pick(C.internal_organs)
var/datum/organ/internal/I = C.internal_organs[O]
I.damage = I.min_bruised_damage
candidates.Remove(C)
severity--
var/acute = prob(15)
if (prob(75))
//internal organ infection
var/O = pick(C.internal_organs)
var/datum/organ/internal/I = C.internal_organs[O]
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--

View File

@@ -1,9 +1,6 @@
/**********************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
name = "Rock"
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)))
T = get_step(src, NORTH)
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)))
T = get_step(src, SOUTH)
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)))
T = get_step(src, EAST)
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)))
T = get_step(src, WEST)
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)
@@ -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)
O.attackby(W,user)
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
..(W,user)

View File

@@ -72,7 +72,7 @@ var/const/MAX_ACTIVE_TIME = 400
Die()
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)
Die()
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)
. = ..()
if(.)
@@ -7,6 +14,10 @@
src.nutrition -= HUNGER_FACTOR/10
if((FAT in src.mutations) && src.m_intent == "run" && src.bodytemperature <= 360)
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)
if(user in src.stomach_contents)
@@ -252,11 +263,13 @@
/mob/living/carbon/proc/throw_mode_off()
src.in_throw_mode = 0
src.throw_icon.icon_state = "act_throw_off"
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"
/mob/living/carbon/proc/throw_mode_on()
src.in_throw_mode = 1
src.throw_icon.icon_state = "act_throw_on"
if(src.throw_icon)
src.throw_icon.icon_state = "act_throw_on"
/mob/proc/throw_item(atom/target)
return

View File

@@ -243,7 +243,7 @@
msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
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)
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"
continue
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(0 to 20)
wound_flavor_text["[temp.display_name]"] += " some dents"
@@ -284,8 +284,8 @@
var/this_wound_desc = W.desc
if(W.bleeding()) this_wound_desc = "bleeding [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]"
else if(W.germ_level > 100) this_wound_desc = "lightly infected [this_wound_desc]"
if(W.germ_level > 600) this_wound_desc = "badly 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)
wound_descriptors[this_wound_desc] += W.amount
continue
@@ -389,7 +389,7 @@
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))
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)
msg += "[t_He] [t_is] repulsively uncanny!\n"

View File

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

View File

@@ -65,13 +65,13 @@
if (organ_name in organs_by_name)
var/datum/organ/external/O = get_organ(organ_name)
if(amount > 0)
O.take_damage(amount, 0, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
else
//if you don't want to heal robot organs, they you will have to check that yourself before using this proc.
O.heal_damage(-amount, 0, internal=0, robo_repair=(O.status & ORGAN_ROBOT))
hud_updateflag |= 1 << HEALTH_HUD
/mob/living/carbon/human/proc/adjustFireLossByPart(var/amount, var/organ_name, var/obj/damage_source = null)
@@ -80,13 +80,13 @@
if (organ_name in organs_by_name)
var/datum/organ/external/O = get_organ(organ_name)
if(amount > 0)
O.take_damage(0, amount, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
else
//if you don't want to heal robot organs, they you will have to check that yourself before using this proc.
O.heal_damage(0, -amount, internal=0, robo_repair=(O.status & ORGAN_ROBOT))
hud_updateflag |= 1 << HEALTH_HUD
/mob/living/carbon/human/Stun(amount)
@@ -302,14 +302,6 @@ This function restores all organs.
if(istype(used_weapon,/obj/item/weapon))
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) ) )
organ.implants += 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
organ.embed(W)
return 1

View File

@@ -98,11 +98,7 @@ emp_act
(SP.name) = "[P.name] shrapnel"
(SP.desc) = "[SP.desc] It looks like it was fired from [P.shot_from]."
(SP.loc) = organ
organ.implants += 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)
organ.embed(SP)
return (..(P , def_zone))
@@ -236,7 +232,7 @@ emp_act
if ((weapon_sharp || weapon_edge) && prob(getarmor(def_zone, "melee")))
weapon_sharp = 0
weapon_edge = 0
if(armor >= 2) return 0
if(!I.force) return 0
@@ -314,4 +310,4 @@ emp_act
var/obj/item/clothing/suit/space/SS = wear_suit
var/penetrated_dam = max(0,(damage - max(0,(SS.breach_threshold - SS.damage))))
if(penetrated_dam) SS.create_breaches(damtype, penetrated_dam)
if(penetrated_dam) SS.create_breaches(damtype, penetrated_dam)

View File

@@ -129,12 +129,10 @@
G.process()
/mob/living/carbon/human/calculate_affecting_pressure(var/pressure)
..()
var/pressure_difference = abs( pressure - ONE_ATMOSPHERE )
//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_adjustment_coefficient = 1 //Determins how much the clothing you are wearing protects you in percent.
if(head && (head.flags & STOPSPRESSUREDMAGE))
pressure_adjustment_coefficient -= PRESSURE_HEAD_REDUCTION_COEFFICIENT
@@ -147,10 +145,16 @@
if(S.can_breach && S.damage)
var/pressure_loss = S.damage * 0.1
pressure_adjustment_coefficient += pressure_loss
pressure_adjustment_coefficient = min(1,max(pressure_adjustment_coefficient,0)) //So it isn't less than 0 or larger than 1.
return 1 - pressure_adjustment_coefficient //want 0 to be bad protection, 1 to be good protection
pressure_difference = pressure_difference * pressure_adjustment_coefficient
/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)
return ONE_ATMOSPHERE + pressure_difference
@@ -316,16 +320,13 @@
if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) 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/breath
// HACK NEED CHANGING LATER
if(health < config.health_threshold_crit && !reagents.has_reagent("inaprovaline"))
losebreath++
if(losebreath>0) //Suffocating so do not take a breath
losebreath--
if (prob(10)) //Gasp per 10 ticks? Sounds about right.
@@ -619,14 +620,14 @@
adjustOxyLoss(-5)
// 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)
return 1
if(breath.temperature < species.cold_level_1)
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)
if(prob(20))
src << "\red You feel your face burning and a searing heat in your lungs!"
@@ -650,9 +651,21 @@
if(species.heat_level_3 to INFINITY)
apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Heat")
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
proc/handle_environment(datum/gas_mixture/environment)
@@ -668,60 +681,63 @@
if(istype(loc, /obj/mecha))
var/obj/mecha/M = loc
loc_temp = M.return_temperature()
else if(istype(get_turf(src), /turf/space))
else if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
loc_temp = loc:air_contents.temperature
else
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
//Body temperature is adjusted in two steps. Firstly your body tries to stabilize itself a bit.
if(stat != 2)
stabilize_temperature_from_calories()
//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
//Body temperature adjusts depending on surrounding atmosphere based on your thermal protection
var/temp_adj = 0
if(loc_temp < bodytemperature) //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.
if(thermal_protection < 1)
var/amt = min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX)
bodytemperature += amt
else if (loc_temp > BODYTEMP_HEAT_DAMAGE_LIMIT) //Place is hotter than we are
temp_adj = (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR) //this will be negative
else if (loc_temp > bodytemperature) //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.
if(thermal_protection < 1)
var/amt = min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX)
bodytemperature += amt
temp_adj = (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR)
//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.
if(bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT)
if(bodytemperature > species.heat_level_1)
//Body temperature is too hot.
fire_alert = max(fire_alert, 1)
if(status_flags & GODMODE) return 1 //godmode
switch(bodytemperature)
if(360 to 400)
apply_damage(HEAT_DAMAGE_LEVEL_1, BURN, used_weapon = "High Body Temperature")
if(species.heat_level_1 to species.heat_level_2)
take_overall_damage(burn=HEAT_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 2)
if(400 to 1000)
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN, used_weapon = "High Body Temperature")
if(species.heat_level_2 to species.heat_level_3)
take_overall_damage(burn=HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 2)
if(1000 to INFINITY)
apply_damage(HEAT_DAMAGE_LEVEL_3, BURN, used_weapon = "High Body Temperature")
if(species.heat_level_3 to INFINITY)
take_overall_damage(burn=HEAT_DAMAGE_LEVEL_3, used_weapon = "High Body Temperature")
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)
if(status_flags & GODMODE) return 1 //godmode
if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
switch(bodytemperature)
if(200 to 260)
apply_damage(COLD_DAMAGE_LEVEL_1, BURN, used_weapon = "Low Body Temperature")
if(species.cold_level_2 to species.cold_level_1)
take_overall_damage(burn=COLD_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 1)
if(120 to 200)
apply_damage(COLD_DAMAGE_LEVEL_2, BURN, used_weapon = "Low Body Temperature")
if(species.cold_level_3 to species.cold_level_2)
take_overall_damage(burn=COLD_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 1)
if(-INFINITY to 120)
apply_damage(COLD_DAMAGE_LEVEL_3, BURN, used_weapon = "Low Body Temperature")
if(-INFINITY to species.cold_level_3)
take_overall_damage(burn=COLD_DAMAGE_LEVEL_3, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 1)
// Account for massive pressure differences. Done by Polymorph
@@ -729,7 +745,8 @@
if(status_flags & GODMODE) return 1 //godmode
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
else if(adjusted_pressure >= species.warning_high_pressure)
pressure_alert = 1
@@ -737,17 +754,9 @@
pressure_alert = 0
else if(adjusted_pressure >= species.hazard_low_pressure)
pressure_alert = -1
if(species && species.flags & IS_SYNTHETIC)
bodytemperature += 0.5 * TEMPERATURE_DAMAGE_COEFFICIENT //Synthetics suffer overheating in a vaccuum. ~Z
else
if(species && species.flags & IS_SYNTHETIC)
bodytemperature += 1 * TEMPERATURE_DAMAGE_COEFFICIENT
if( !(COLD_RESISTANCE in mutations))
adjustBruteLoss( LOW_PRESSURE_DAMAGE )
take_overall_damage(brute=LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure")
pressure_alert = -2
else
pressure_alert = -1
@@ -774,27 +783,35 @@
temp_change = (temperature - current)
return temp_change
*/
proc/stabilize_temperature_from_calories()
var/body_temperature_difference = 310.15 - bodytemperature
proc/stabilize_body_temperature()
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)
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(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up.
nutrition -= 2
var/recovery_amt = max((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM)
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.
nutrition -= 2
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]")
bodytemperature += recovery_amt
if(260.15 to 360.15)
var/recovery_amt = body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR
bodytemperature += recovery_amt
else if(species.cold_level_1 <= bodytemperature && bodytemperature <= species.heat_level_1)
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]")
bodytemperature += recovery_amt
if(360.15 to INFINITY) //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...~
var/recovery_amt = min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers
bodytemperature += recovery_amt
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...~
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]")
bodytemperature += recovery_amt
bodytemperature += recovery_amt
//This proc returns a number made up of the flags for body parts which you are protected on. (such as HEAD, UPPER_TORSO, LOWER_TORSO, etc. See setup.dm for the full list)
proc/get_heat_protection_flags(temperature) //Temperature is the temperature you're being exposed to.
@@ -1074,12 +1091,6 @@
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()
return //TODO: DEFERRED
@@ -1091,6 +1102,7 @@
else //ALIVE. LIGHTS ARE ON
updatehealth() //TODO
if(!in_stasis)
stabilize_body_temperature() //Body temperature adjusts itself
handle_organs() //Optimized.
handle_blood()
@@ -1215,14 +1227,11 @@
if(druggy)
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(gloves && germ_level > gloves.germ_level && prob(10))
gloves.germ_level += 1
*/
return 1
proc/handle_regular_hud_updates()
@@ -1449,17 +1458,46 @@
else fire.icon_state = "fire0"
if(bodytemp)
switch(bodytemperature) //310.055 optimal body temp
if(370 to INFINITY) bodytemp.icon_state = "temp4"
if(350 to 370) bodytemp.icon_state = "temp3"
if(335 to 350) bodytemp.icon_state = "temp2"
if(320 to 335) bodytemp.icon_state = "temp1"
if(300 to 320) bodytemp.icon_state = "temp0"
if(295 to 300) bodytemp.icon_state = "temp-1"
if(280 to 295) bodytemp.icon_state = "temp-2"
if(260 to 280) bodytemp.icon_state = "temp-3"
else bodytemp.icon_state = "temp-4"
if (!species)
switch(bodytemperature) //310.055 optimal body temp
if(370 to INFINITY) bodytemp.icon_state = "temp4"
if(350 to 370) bodytemp.icon_state = "temp3"
if(335 to 350) bodytemp.icon_state = "temp2"
if(320 to 335) bodytemp.icon_state = "temp1"
if(300 to 320) bodytemp.icon_state = "temp0"
if(295 to 300) bodytemp.icon_state = "temp-1"
if(280 to 295) bodytemp.icon_state = "temp-2"
if(260 to 280) bodytemp.icon_state = "temp-3"
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(blinded) blind.layer = 18
else blind.layer = 0
@@ -1520,21 +1558,21 @@
for (var/ID in virus2)
var/datum/disease2/disease/V = virus2[ID]
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))
if(istype(O,/obj/effect/decal/cleanable/blood))
var/obj/effect/decal/cleanable/blood/B = O
if(B.virus2.len)
for (var/ID in B.virus2)
var/datum/disease2/disease/V = B.virus2[ID]
infect_virus2(src,V.getcopy())
for(var/obj/effect/decal/cleanable/O in view(1,src))
if(istype(O,/obj/effect/decal/cleanable/blood))
var/obj/effect/decal/cleanable/blood/B = O
if(B.virus2.len)
for (var/ID in B.virus2)
var/datum/disease2/disease/V = B.virus2[ID]
infect_virus2(src,V)
else if(istype(O,/obj/effect/decal/cleanable/mucus))
var/obj/effect/decal/cleanable/mucus/M = O
if(M.virus2.len)
for (var/ID in M.virus2)
var/datum/disease2/disease/V = M.virus2[ID]
infect_virus2(src,V)
else if(istype(O,/obj/effect/decal/cleanable/mucus))
var/obj/effect/decal/cleanable/mucus/M = O
if(M.virus2.len)
for (var/ID in M.virus2)
var/datum/disease2/disease/V = M.virus2[ID]
infect_virus2(src,V.getcopy())
if(virus2.len)

View File

@@ -10,6 +10,8 @@
icon_state = "nymph1"
var/list/donors = list()
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)
@@ -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.")
donors += M.real_name
for(var/datum/language/L in M.languages)
languages += L
languages |= L
spawn(25)
update_progression()
@@ -245,14 +247,11 @@
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
if(stat == 2)
return say_dead(message)
var/datum/language/speaking = null
if(length(message) >= 2)
var/channel_prefix = copytext(message, 1 ,3)
if(languages.len)
@@ -270,6 +269,4 @@
if(!message || stat)
return
..(message, speaking, verb, null, null, message_range, null)

View File

@@ -28,6 +28,9 @@
var/heat_level_1 = 360 // Heat damage level 1 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/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/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure.
@@ -279,6 +282,8 @@
heat_level_2 = 3000
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
blood_color = "#004400"
@@ -317,15 +322,17 @@
burn_mod = 1
warning_low_pressure = 50
hazard_low_pressure = 10
hazard_low_pressure = 0
cold_level_1 = 50
cold_level_2 = -1
cold_level_3 = -1
heat_level_1 = 2000
heat_level_2 = 3000
heat_level_3 = 4000
heat_level_1 = 500 //gives them about 25 seconds in space before taking damage
heat_level_2 = 1000
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

View File

@@ -431,7 +431,8 @@
else
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)
if(update_slimes)

View File

@@ -103,7 +103,7 @@ var/list/department_radio_keys = list(
var/obj/O = I
hearturfs += O.locs[1]
objects |= O
for(var/mob/M in player_list)
if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS))
listening |= M
@@ -113,7 +113,8 @@ var/list/department_radio_keys = list(
for(var/obj/O in objects)
spawn(0)
O.hear_talk(src, message, verb, speaking)
if(O) //It's possible that it could be deleted in the meantime.
O.hear_talk(src, message, verb, speaking)
var/speech_bubble_test = say_test(message)
var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]")

View File

@@ -250,13 +250,13 @@ var/list/ai_list = list()
for (var/area_name in alarmlist)
var/datum/alarm/alarm = alarmlist[area_name]
dat += "<NOBR>"
var/cameratext = ""
if (alarm.cameras)
for (var/obj/machinery/camera/I in alarm.cameras)
cameratext += text("[]<A HREF=?src=\ref[];switchcamera=\ref[]>[]</A>", (cameratext=="") ? "" : " | ", src, I, I.c_tag)
dat += text("-- [] ([])", alarm.area.name, (cameratext)? cameratext : "No Camera")
if (alarm.sources.len > 1)
dat += text(" - [] sources", alarm.sources.len)
dat += "</NOBR><BR>\n"
@@ -407,23 +407,11 @@ var/list/ai_list = list()
if (href_list["track"])
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 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)
if(target && (!istype(target, /mob/living/carbon/human) || html_decode(href_list["trackname"]) == target:get_face_name()))
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
else if (href_list["faketrack"])
@@ -539,24 +527,24 @@ var/list/ai_list = list()
/mob/living/silicon/ai/triggerAlarm(var/class, area/A, list/cameralist, var/source)
if (stat == 2)
return 1
..()
var/cameratext = ""
for (var/obj/machinery/camera/C in cameralist)
cameratext += "[(cameratext == "")? "" : "|"]<A HREF=?src=\ref[src];switchcamera=\ref[C]>[C.c_tag]</A>"
queueAlarm("--- [class] alarm detected in [A.name]! ([(cameratext)? cameratext : "No Camera"])", class)
if (viewalerts) ai_alerts()
/mob/living/silicon/ai/cancelAlarm(var/class, area/A as area, var/source)
var/has_alarm = ..()
if (!has_alarm)
queueAlarm(text("--- [] alarm in [] has been cleared.", class, A.name), class, 0)
if (viewalerts) ai_alerts()
return has_alarm
/mob/living/silicon/ai/cancel_camera()

View File

@@ -188,7 +188,7 @@
if(!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
user << "\red You don't have the dexterity to do this!"
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!"
return
@@ -200,22 +200,39 @@
user.show_message("\t Damage Specifics: <font color='#FFA500'>[BU]</font> - <font color='red'>[BR]</font>")
if(M.tod && M.stat == DEAD)
user.show_message("\blue Time of Disable: [M.tod]")
var/mob/living/silicon/robot/H = M
var/list/damaged = H.get_damaged_components(1,1,1)
user.show_message("\blue Localized Damage:",1)
if(length(damaged)>0)
for(var/datum/robot_component/org in damaged)
user.show_message(text("\blue \t []: [][] - [] - [] - []", \
capitalize(org.name), \
(org.installed == -1) ? "<font color='red'><b>DESTROYED</b></font> " :"",\
(org.electronics_damage > 0) ? "<font color='#FFA500'>[org.electronics_damage]</font>" :0, \
(org.brute_damage > 0) ? "<font color='red'>[org.brute_damage]</font>" :0, \
(org.toggled) ? "Toggled ON" : "<font color='red'>Toggled OFF</font>",\
(org.powered) ? "Power ON" : "<font color='red'>Power OFF</font>"),1)
else
user.show_message("\blue \t Components are OK.",1)
if(H.emagged && prob(5))
user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1)
if (istype(M, /mob/living/silicon/robot))
var/mob/living/silicon/robot/H = M
var/list/damaged = H.get_damaged_components(1,1,1)
user.show_message("\blue Localized Damage:",1)
if(length(damaged)>0)
for(var/datum/robot_component/org in damaged)
user.show_message(text("\blue \t []: [][] - [] - [] - []", \
capitalize(org.name), \
(org.installed == -1) ? "<font color='red'><b>DESTROYED</b></font> " :"",\
(org.electronics_damage > 0) ? "<font color='#FFA500'>[org.electronics_damage]</font>" :0, \
(org.brute_damage > 0) ? "<font color='red'>[org.brute_damage]</font>" :0, \
(org.toggled) ? "Toggled ON" : "<font color='red'>Toggled OFF</font>",\
(org.powered) ? "Power ON" : "<font color='red'>Power OFF</font>"),1)
else
user.show_message("\blue \t Components are OK.",1)
if(H.emagged && prob(5))
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)
return

View File

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

View File

@@ -199,7 +199,7 @@
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
//if(istype(mob.loc, /turf/space) || (mob.flags & NOGRAV))
@@ -246,7 +246,9 @@
move_delay -= 1.3
var/tickcomp = ((1/(world.tick_lag))*1.3)
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(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, "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"))
// 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)
for(var/name in list("r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","l_arm","l_hand"))
if(organ_data[name] == "amputated") continue
var/icon/temp = new /icon(icobase, "[name]")
@@ -212,6 +207,11 @@ datum/preferences
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
if(current_species && (current_species.flags & HAS_SKIN_COLOR))
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.blood_DNA = list()
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
this.update_icon()

View File

@@ -5,6 +5,9 @@
var/list/datum/autopsy_data/autopsy_data = list()
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
var/germ_level = 0 // INTERNAL germs inside the organ, this is BAD if it's greater than INFECTION_LEVEL_ONE
proc/process()
return 0
@@ -46,13 +49,18 @@
if(damage_this_tick > last_dam)
force_process = 1
last_dam = damage_this_tick
if(!force_process && !bad_external_organs.len)
return
if(force_process)
bad_external_organs.Cut()
for(var/datum/organ/external/Ex in organs)
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)
if(!E)
continue
@@ -62,53 +70,24 @@
else
E.process()
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
if (broken && E.internal_organs && prob(15))
if (!lying && world.timeofday - l_move_time < 15)
if (E.is_broken() && E.internal_organs && prob(15))
var/datum/organ/internal/I = pick(E.internal_organs)
custom_pain("You feel broken bones moving in your [E.display_name]!", 1)
I.take_damage(rand(3,5))
//Moving makes open wounds get infected much faster
if (E.wounds.len)
for(var/datum/wound/W in E.wounds)
if (W.infection_check())
W.germ_level += 1
//Special effects for limbs.
if(E.name in list("l_hand","l_arm","r_hand","r_arm"))
var/obj/item/c_hand //Getting what's in this hand
var/hand
if(E.name == "l_hand" || E.name == "l_arm")
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)
u_equip(c_hand)
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)))
if(E.name in list("l_leg","l_foot","r_leg","r_foot") && !lying)
if (!E.is_usable() || E.is_malfunctioning() || (E.is_broken() && !(E.status & ORGAN_SPLINTED)))
leg_tally-- // let it fail even if just foot&leg
// standing is poor
if(leg_tally <= 0 && !paralysis && !(lying || resting) && prob(5))
if(species && species.flags & NO_PAIN)

View File

@@ -40,8 +40,6 @@
var/obj/item/hidden = null
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
var/wound_update_accuracy = 1
@@ -239,28 +237,31 @@ This function completely restores a damaged organ to perfect condition.
for (var/datum/wound/W in wounds)
if (W.can_worsen(type, damage))
compatible_wounds += W
var/datum/wound/W = pick(compatible_wounds)
W.open_wound(damage)
if(prob(25))
//maybe have a separate message for BRUISE type damage?
owner.visible_message("\red The wound on [owner.name]'s [display_name] widens with a nasty ripping voice.",\
"\red The wound on your [display_name] widens with a nasty ripping voice.",\
"You hear a nasty ripping noise, as if flesh is being torn apart.")
return
if(compatible_wounds.len)
var/datum/wound/W = pick(compatible_wounds)
W.open_wound(damage)
if(prob(25))
//maybe have a separate message for BRUISE type damage?
owner.visible_message("\red The wound on [owner.name]'s [display_name] widens with a nasty ripping voice.",\
"\red The wound on your [display_name] widens with a nasty ripping voice.",\
"You hear a nasty ripping noise, as if flesh is being torn apart.")
return
//Creating wound
var/wound_type = get_wound_type(type, damage)
var/datum/wound/W = new wound_type(damage)
//Check whether we can add the wound to an existing wound
for(var/datum/wound/other in wounds)
if(other.can_merge(W))
other.merge_wound(W)
W = null // to signify that the wound was added
break
if(W)
wounds += W
if(wound_type)
var/datum/wound/W = new wound_type(damage)
//Check whether we can add the wound to an existing wound
for(var/datum/wound/other in wounds)
if(other.can_merge(W))
other.merge_wound(W)
W = null // to signify that the wound was added
break
if(W)
wounds += W
/datum/organ/external/proc/get_wound_type(var/type = CUT, var/damage)
//if you look a the names in the wound's stages list for each wound type you will see the logic behind these values
@@ -279,7 +280,7 @@ This function completely restores a damaged organ to perfect condition.
if (damage <= 15) return /datum/wound/burn/large
if (damage <= 30) return /datum/wound/burn/severe
if (damage <= 40) return /datum/wound/burn/deep
if (damage <= 50) return /datum/wound/burn/carbonised
return /datum/wound/burn/carbonised
/****************************************************
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.
last_dam = brute_dam + burn_dam
return 1
last_dam = brute_dam + burn_dam
else
last_dam = brute_dam + burn_dam
if(germ_level)
return 1
return 0
/datum/organ/external/process()
@@ -327,50 +331,89 @@ This function completely restores a damaged organ to perfect condition.
if(!(status & ORGAN_BROKEN))
perma_injury = 0
//Infections
update_germs()
return
//Updating germ levels. Handles organ germ levels and necrosis.
#define GANGREN_LEVEL_ONE 100
#define GANGREN_LEVEL_TWO 1000
#define GANGREN_LEVEL_TERMINAL 2500
#define GERM_TRANSFER_AMOUNT germ_level/500
/*
The INFECTION_LEVEL values defined in setup.dm control the time it takes to reach the different
infection levels. Since infection growth is exponential, you can adjust the time it takes to get
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()
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
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
for(var/datum/wound/W in wounds)
if(!W.bandaged && !W.salved)
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
germ_level++
//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
if (W.germ_level > germ_level) //Badly infected wounds raise internal germ levels
germ_level++
if(germ_level > GANGREN_LEVEL_ONE && prob(round(germ_level/100)))
germ_level++
owner.adjustToxLoss(1)
if(germ_level > GANGREN_LEVEL_TWO)
germ_level++
owner.adjustToxLoss(1)
/*
if(germ_level > GANGREN_LEVEL_TERMINAL)
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++
if (prob(5)) //adjust this to tweak how fast people take toxin damage from infections
owner.adjustToxLoss(1)
if(germ_level >= INFECTION_LEVEL_TWO)
//spread the infection
for (var/datum/organ/internal/I in internal_organs)
if (I.germ_level < germ_level)
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))
status |= ORGAN_DEAD
owner << "<span class='notice'>You can't feel your [display_name] anymore...</span>"
owner.update_body(1)
if (prob(10)) //Spreading the fun
if (children) //To child organs
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)
*/
germ_level++
owner.adjustToxLoss(1)
//Updating wounds. Handles wound natural I had some free spachealing, internal bleedings and infections
/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
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)
if(W.germ_level > 100)
if(W.germ_level > 150)
return 1
return 0
@@ -700,7 +743,42 @@ This function completely restores a damaged organ to perfect condition.
/datum/organ/external/proc/is_usable()
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
****************************************************/
@@ -728,6 +806,10 @@ This function completely restores a damaged organ to perfect condition.
max_damage = 50
min_broken_damage = 20
body_part = ARM_LEFT
process()
..()
process_grasp(owner.l_hand, "left hand")
/datum/organ/external/l_leg
name = "l_leg"
@@ -745,6 +827,10 @@ This function completely restores a damaged organ to perfect condition.
max_damage = 50
min_broken_damage = 20
body_part = ARM_RIGHT
process()
..()
process_grasp(owner.r_hand, "right hand")
/datum/organ/external/r_leg
name = "r_leg"
@@ -780,6 +866,10 @@ This function completely restores a damaged organ to perfect condition.
max_damage = 30
min_broken_damage = 15
body_part = HAND_RIGHT
process()
..()
process_grasp(owner.r_hand, "right hand")
/datum/organ/external/l_hand
name = "l_hand"
@@ -788,6 +878,10 @@ This function completely restores a damaged organ to perfect condition.
max_damage = 30
min_broken_damage = 15
body_part = HAND_LEFT
process()
..()
process_grasp(owner.l_hand, "left hand")
/datum/organ/external/head
name = "head"

View File

@@ -21,6 +21,7 @@
return damage >= min_broken_damage
/datum/organ/internal/New(mob/living/carbon/human/H)
..()
var/datum/organ/external/E = H.organs_by_name[src.parent_organ]
@@ -30,6 +31,37 @@
H.internal_organs[src.name] = src
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)
if(src.robotic == 2)
src.damage += (amount * 0.8)
@@ -40,7 +72,6 @@
if (!silent)
owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1)
/datum/organ/internal/proc/emp_act(severity)
switch(robotic)
if(0)
@@ -96,7 +127,7 @@
owner.drip(10)
if(prob(4))
spawn owner.emote("me", 1, "gasps for air!")
owner.losebreath += 5
owner.losebreath += 15
/datum/organ/internal/liver
name = "liver"

View File

@@ -119,7 +119,7 @@
// 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
proc/can_infect()
proc/infection_check()
if (is_treated() && damage < 10)
return 0
if (disinfected)

View File

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

View File

@@ -356,6 +356,7 @@
switchcount = L.switchcount
rigged = L.rigged
brightness = L.brightness
l_color = L.color
on = has_power()
update()
@@ -514,6 +515,7 @@
L.status = status
L.rigged = rigged
L.brightness = src.brightness
L.color = l_color
// light item inherits the switchcount, then zero it
L.switchcount = switchcount
@@ -539,6 +541,7 @@
L.status = status
L.rigged = rigged
L.brightness = brightness
L.color = l_color
// light item inherits the switchcount, then zero it
L.switchcount = switchcount
@@ -618,7 +621,7 @@
// 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
broken()

View File

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

View File

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

View File

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

View File

@@ -127,8 +127,39 @@
..() // -> item/attackby()
if(istype(W,/obj/item/weapon/storage))
..() // -> 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)
return 0
var/inaccurate = 0
if( \
istype(W, /obj/item/weapon/kitchenknife) || \
@@ -173,8 +204,8 @@
)
else
user.visible_message( \
"\blue [user] inaccurately slices \the [src] with [W]!", \
"\blue You inaccurately slice \the [src] with your [W]!" \
"\blue [user] crudely slices \the [src] with [W]!", \
"\blue You crudely slice \the [src] with your [W]!" \
)
slices_lost = rand(1,min(1,round(slices_num/2)))
var/reagents_per_slice = reagents.total_volume/slices_num
@@ -182,6 +213,7 @@
var/obj/slice = new slice_path (src.loc)
reagents.trans_to(slice,reagents_per_slice)
del(src)
return
/obj/item/weapon/reagent_containers/food/snacks/Del()
@@ -876,33 +908,6 @@
..()
reagents.add_reagent("nutriment", 8)
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
name = "Muffin"
@@ -1532,7 +1537,7 @@
filling_color = "#ADAC7F"
var/wrapped = 0
var/monkey_type = null
var/monkey_type = /mob/living/carbon/monkey
New()
..()
@@ -1550,19 +1555,46 @@
if(wrapped)
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()
for(var/mob/M in viewers(src,7))
M << "\red \The [src] expands!"
if(monkey_type)
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))
new monkey_type(src)
del(src)
proc/Unwrap(mob/user as mob)
@@ -1580,18 +1612,18 @@
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/farwacube
name = "farwa cube"
monkey_type ="tajara"
monkey_type = /mob/living/carbon/monkey/tajara
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/farwacube
name = "farwa cube"
monkey_type ="tajara"
monkey_type =/mob/living/carbon/monkey/tajara
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/stokcube
name = "stok cube"
monkey_type ="unathi"
monkey_type = /mob/living/carbon/monkey/unathi
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/stokcube
name = "stok cube"
monkey_type ="unathi"
monkey_type =/mob/living/carbon/monkey/unathi
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/neaeracube
@@ -1599,7 +1631,7 @@
monkey_type ="skrell"
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/neaeracube
name = "neaera cube"
monkey_type ="skrell"
monkey_type =/mob/living/carbon/monkey/skrell
/obj/item/weapon/reagent_containers/food/snacks/spellburger

View File

@@ -166,7 +166,7 @@
if(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)
explode()
return ..()

View File

@@ -234,20 +234,8 @@
flush()
flushing = 1
flick("intake-closing", src)
var/deliveryCheck = 0
var/obj/structure/disposalholder/H = new() // virtual holder object which actually
// 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.
sleep(10)

View File

@@ -5,8 +5,9 @@
icon = 'icons/obj/cryogenics.dmi'
icon_state = "cellold0"
var/spawn_type
var/current_ticks_spawning = 0
var/ticks_required_to_spawn
var/time_spent_spawning = 0
var/time_per_spawn = 0
var/last_process= 0
density = 1
var/previous_power_state = 0
@@ -17,7 +18,7 @@
/obj/machinery/auto_cloner/New()
..()
ticks_required_to_spawn = rand(240,1440)
time_per_spawn = rand(1200,3600)
//33% chance to spawn nasties
if(prob(33))
@@ -53,13 +54,12 @@
src.visible_message("\blue \icon[src] [src] suddenly comes to life!")
//slowly grow a mob
current_ticks_spawning++
if(prob(5))
src.visible_message("\blue \icon[src] [src] [pick("gloops","glugs","whirrs","whooshes","hisses","purrs","hums","gushes")].")
//if we've finished growing...
if(current_ticks_spawning >= ticks_required_to_spawn)
current_ticks_spawning = 0
if(time_spent_spawning >= time_per_spawn)
time_spent_spawning = 0
use_power = 1
src.visible_message("\blue \icon[src] [src] pings!")
icon_state = "cellold1"
@@ -68,7 +68,7 @@
new spawn_type(src.loc)
//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
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..."
@@ -76,6 +76,8 @@
use_power = 1
icon_state = "cellold1"
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
if(previous_power_state)
previous_power_state = 0
@@ -83,5 +85,6 @@
src.visible_message("\blue \icon[src] [src] suddenly shuts down.")
//cloned mob slowly breaks down
if(current_ticks_spawning > 0)
current_ticks_spawning--
time_spent_spawning = max(time_spent_spawning + last_process - world.time, 0)
last_process = world.time

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