mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-08-26 14:47:50 +01:00
Reverted a couple of outdated files for merge.
This commit is contained in:
+11
-9
@@ -679,6 +679,9 @@
|
||||
#include "code\modules\admin\verbs\possess.dm"
|
||||
#include "code\modules\admin\verbs\pray.dm"
|
||||
#include "code\modules\admin\verbs\randomverbs.dm"
|
||||
#include "code\modules\admin\verbs\SDQL.dm"
|
||||
#include "code\modules\admin\verbs\SDQL_2.dm"
|
||||
#include "code\modules\admin\verbs\SDQL_2_parser.dm"
|
||||
#include "code\modules\admin\verbs\striketeam.dm"
|
||||
#include "code\modules\admin\verbs\striketeam_syndicate.dm"
|
||||
#include "code\modules\admin\verbs\ticklag.dm"
|
||||
@@ -766,6 +769,7 @@
|
||||
#include "code\modules\economy\Accounts.dm"
|
||||
#include "code\modules\economy\Accounts_DB.dm"
|
||||
#include "code\modules\economy\ATM.dm"
|
||||
#include "code\modules\economy\cash.dm"
|
||||
#include "code\modules\economy\economy_misc.dm"
|
||||
#include "code\modules\economy\EFTPOS.dm"
|
||||
#include "code\modules\economy\Events.dm"
|
||||
@@ -799,7 +803,6 @@
|
||||
#include "code\modules\events\spider_infestation.dm"
|
||||
#include "code\modules\events\spontaneous_appendicitis.dm"
|
||||
#include "code\modules\events\viral_infection.dm"
|
||||
#include "code\modules\events\viral_outbreak.dm"
|
||||
#include "code\modules\events\wallrot.dm"
|
||||
#include "code\modules\ext_scripts\irc.dm"
|
||||
#include "code\modules\ext_scripts\python.dm"
|
||||
@@ -1189,22 +1192,18 @@
|
||||
#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_talkingitem.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\analysis_accelerator.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\analysis_base.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\analysis_fourier_transform.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\analysis_gas_chromatography.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\analysis_hyperspectral.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\analysis_ion_mobility.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\analysis_isotope_ratio.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"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\coolant.dm"
|
||||
#include "code\modules\research\xenoarchaeology\machinery\geosample_scanner.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\ano_device_battery.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\anomaly_suit.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\bunsen_burner.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\gearbelt.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\suspension_generator.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\tools.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\tools_anoscanner.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\tools_coresampler.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\tools_depthscanner.dm"
|
||||
#include "code\modules\research\xenoarchaeology\tools\tools_locater.dm"
|
||||
@@ -1242,6 +1241,9 @@
|
||||
#include "code\modules\surgery\ribcage.dm"
|
||||
#include "code\modules\surgery\robolimbs.dm"
|
||||
#include "code\modules\surgery\surgery.dm"
|
||||
#include "code\modules\telesci\gps.dm"
|
||||
#include "code\modules\telesci\telepad.dm"
|
||||
#include "code\modules\telesci\telesci_computer.dm"
|
||||
#include "code\modules\virus2\analyser.dm"
|
||||
#include "code\modules\virus2\antibodies.dm"
|
||||
#include "code\modules\virus2\centrifuge.dm"
|
||||
@@ -1290,7 +1292,6 @@
|
||||
#include "code\WorkInProgress\Cael_Aislinn\ShieldGen\shield_gen.dm"
|
||||
#include "code\WorkInProgress\Cael_Aislinn\ShieldGen\shield_gen_external.dm"
|
||||
#include "code\WorkInProgress\Cael_Aislinn\Supermatter\LaserComputer.dm"
|
||||
#include "code\WorkInProgress\Cael_Aislinn\Supermatter\SuperMatter.dm"
|
||||
#include "code\WorkInProgress\Cael_Aislinn\Supermatter\ZeroPointLaser.dm"
|
||||
#include "code\WorkInProgress\Chinsky\ashtray.dm"
|
||||
#include "code\WorkInProgress\Cib\MedicalSideEffects.dm"
|
||||
@@ -1299,6 +1300,7 @@
|
||||
#include "code\WorkInProgress\Ported\policetape.dm"
|
||||
#include "code\WorkInProgress\SkyMarshal\officer_stuff.dm"
|
||||
#include "code\WorkInProgress\SkyMarshal\Ultralight_procs.dm"
|
||||
#include "code\WorkInProgress\Yinadele\Supermatter.dm"
|
||||
#include "code\ZAS\Airflow.dm"
|
||||
#include "code\ZAS\Connection.dm"
|
||||
#include "code\ZAS\Debug.dm"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// BEGIN_INTERNALS
|
||||
/*
|
||||
MAP_ICON_TYPE: 0
|
||||
AUTO_FILE_DIR: OFF
|
||||
*/
|
||||
// END_INTERNALS
|
||||
|
||||
@@ -161,7 +161,7 @@ obj/machinery/atmospherics/pipe
|
||||
proc/burst()
|
||||
src.visible_message("\red \bold [src] bursts!");
|
||||
playsound(src.loc, 'sound/effects/bang.ogg', 25, 1)
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new
|
||||
smoke.set_up(1,0, src.loc, 0)
|
||||
smoke.start()
|
||||
del(src)
|
||||
|
||||
@@ -145,14 +145,14 @@ datum/fusion_reaction/pergium_tritium
|
||||
energy_production = 0
|
||||
radiation = 5
|
||||
|
||||
datum/fusion_reaction/pergium_deuterium
|
||||
datum/fusion_reaction/pergium_obdurium
|
||||
primary_reactant = "Pergium"
|
||||
secondary_reactant = "Obdurium"
|
||||
energy_consumption = 5
|
||||
energy_production = 0
|
||||
radiation = 5
|
||||
|
||||
datum/fusion_reaction/pergium_tritium
|
||||
datum/fusion_reaction/pergium_solonium
|
||||
primary_reactant = "Pergium"
|
||||
secondary_reactant = "Solonium"
|
||||
energy_consumption = 5
|
||||
|
||||
@@ -1,186 +0,0 @@
|
||||
#define NITROGEN_RETARDATION_FACTOR 12 //Higher == N2 slows reaction more
|
||||
#define THERMAL_RELEASE_MODIFIER 0.55 //Percentage of output power given to heat generation.
|
||||
|
||||
#define PLASMA_RELEASE_MODIFIER 0.24 //Percentage of output power given to plasma generation.
|
||||
#define PLASMA_CONVERSION_FACTOR 50 //How much energy per mole of plasma
|
||||
#define MAX_PLASMA_RELATIVE_INCREASE 0.3 //Percentage of current plasma amounts that can be added to preexisting plasma.
|
||||
|
||||
#define OXYGEN_RELEASE_MODIFIER 0.13 //Percentage of output power given to oxygen generation.
|
||||
#define OXYGEN_CONVERSION_FACTOR 150 //How much energy per mole of oxygen.
|
||||
#define MAX_OXYGEN_RELATIVE_INCREASE 0.2 //Percentage of current oxygen amounts that can be added to preexisting oxygen.
|
||||
|
||||
#define RADIATION_POWER_MODIFIER 0.03 //How much power goes to irradiating the area.
|
||||
#define RADIATION_FACTOR 10
|
||||
#define HALLUCINATION_POWER_MODIFIER 0.05 //How much power goes to hallucinations.
|
||||
#define HALLUCINATION_FACTOR 20
|
||||
|
||||
#define REACTION_POWER_MODIFIER 4 //Higher == more overall power
|
||||
|
||||
#define WARNING_DELAY 45 //45 seconds between warnings.
|
||||
|
||||
/obj/machinery/power/supermatter
|
||||
name = "Supermatter"
|
||||
desc = "A strangely translucent and iridescent crystal. \red You get headaches just from looking at it."
|
||||
icon = 'icons/obj/engine.dmi'
|
||||
icon_state = "darkmatter"
|
||||
density = 1
|
||||
anchored = 0
|
||||
|
||||
var/gasefficency = 0.25
|
||||
|
||||
var/base_icon_state = "darkmatter"
|
||||
|
||||
var/damage = 0
|
||||
var/damage_archived = 0
|
||||
var/safe_alert = "Crystaline hyperstructure returning to safe operating levels."
|
||||
var/warning_point = 100
|
||||
var/warning_alert = "Danger! Crystal hyperstructure instability!"
|
||||
var/emergency_point = 700
|
||||
var/emergency_alert = "CRYSTAL DELAMINATION IMMINENT"
|
||||
var/explosion_point = 1000
|
||||
|
||||
var/emergency_issued = 0
|
||||
|
||||
var/explosion_power = 8
|
||||
|
||||
var/lastwarning = 0 // Time in 1/10th of seconds since the last sent warning
|
||||
|
||||
var/power = 0
|
||||
|
||||
|
||||
shard //Small subtype, less efficient and more sensitive, but less boom.
|
||||
name = "Supermatter Shard"
|
||||
desc = "A strangely translucent and iridescent crystal. Looks like it used to be part of a larger structure. \red You get headaches just from looking at it."
|
||||
icon_state = "darkmatter_shard"
|
||||
base_icon_state = "darkmatter_shard"
|
||||
|
||||
warning_point = 50
|
||||
emergency_point = 500
|
||||
explosion_point = 900
|
||||
|
||||
gasefficency = 0.125
|
||||
|
||||
explosion_power = 3 //3,6,9,12? Or is that too small?
|
||||
|
||||
|
||||
process()
|
||||
|
||||
var/turf/L = loc
|
||||
|
||||
if(!istype(L)) //If we are not on a turf, uh oh.
|
||||
del src
|
||||
|
||||
//Ok, get the air from the turf
|
||||
var/datum/gas_mixture/env = L.return_air()
|
||||
|
||||
//Remove gas from surrounding area
|
||||
var/datum/gas_mixture/removed = env.remove(gasefficency * env.total_moles)
|
||||
|
||||
if (!removed)
|
||||
return 1
|
||||
|
||||
if(damage > warning_point) // while the core is still damaged and it's still worth noting its status
|
||||
if((world.timeofday - lastwarning) / 10 >= WARNING_DELAY)
|
||||
|
||||
if(damage > emergency_point)
|
||||
//radioalert("states, \"[emergency_alert]\"","Supermatter Monitor")
|
||||
lastwarning = world.timeofday
|
||||
else if(damage >= damage_archived) // The damage is still going up
|
||||
//radioalert("states, \"[warning_alert]\"","Supermatter Monitor")
|
||||
lastwarning = world.timeofday-150
|
||||
else // Phew, we're safe
|
||||
//radioalert("states, \"[safe_alert]\"","Supermatter Monitor")
|
||||
lastwarning = world.timeofday
|
||||
|
||||
if(damage > explosion_point)
|
||||
explosion(loc,explosion_power,explosion_power*2,explosion_power*3,explosion_power*4,1)
|
||||
del src
|
||||
|
||||
damage_archived = damage
|
||||
damage = max( damage + ( (removed.temperature - 800) / 150 ) , 0 )
|
||||
|
||||
if(!removed.total_moles)
|
||||
damage += max((power-1600)/10,0)
|
||||
power = max(power,1600)
|
||||
return 1
|
||||
|
||||
var/nitrogen_mod = abs((removed.nitrogen / removed.total_moles)) * NITROGEN_RETARDATION_FACTOR
|
||||
var/oxygen = max(min(removed.oxygen / removed.total_moles - nitrogen_mod, 1), 0)
|
||||
|
||||
var/temp_factor = 0
|
||||
if(oxygen > 0.8)
|
||||
// with a perfect gas mix, make the power less based on heat
|
||||
temp_factor = 100
|
||||
icon_state = "[base_icon_state]_glow"
|
||||
else
|
||||
// in normal mode, base the produced energy around the heat
|
||||
temp_factor = 60
|
||||
icon_state = base_icon_state
|
||||
|
||||
//Calculate power released as heat and gas, in as the sqrt of the power.
|
||||
var/power_factor = (power/500) ** 3
|
||||
var/device_energy = oxygen * power_factor
|
||||
power = max(round((removed.temperature - T0C) / temp_factor) + power - power_factor, 0) //Total laser power plus an overload factor
|
||||
|
||||
//Final energy calcs.
|
||||
device_energy = max(device_energy * REACTION_POWER_MODIFIER,0)
|
||||
|
||||
//To figure out how much temperature to add each tick, consider that at one atmosphere's worth
|
||||
//of pure oxygen, with all four lasers firing at standard energy and no N2 present, at room temperature
|
||||
//that the device energy is around 2140. At that stage, we don't want too much heat to be put out
|
||||
//Since the core is effectively "cold"
|
||||
|
||||
//Also keep in mind we are only adding this temperature to (efficiency)% of the one tile the rock
|
||||
//is on. An increase of 4*C @ 25% efficiency here results in an increase of 1*C / (#tilesincore) overall.
|
||||
|
||||
var/plasma_energy = device_energy * PLASMA_RELEASE_MODIFIER
|
||||
var/oxygen_energy = device_energy * OXYGEN_RELEASE_MODIFIER
|
||||
var/other_energy = device_energy * (1- (OXYGEN_RELEASE_MODIFIER + PLASMA_RELEASE_MODIFIER))
|
||||
|
||||
//Put as much plasma out as is permitted.
|
||||
if( plasma_energy > removed.total_moles * PLASMA_CONVERSION_FACTOR * MAX_PLASMA_RELATIVE_INCREASE / gasefficency)
|
||||
removed.toxins += (MAX_PLASMA_RELATIVE_INCREASE * removed.total_moles / gasefficency)
|
||||
other_energy += plasma_energy - (removed.total_moles * PLASMA_CONVERSION_FACTOR * MAX_PLASMA_RELATIVE_INCREASE / gasefficency)
|
||||
else
|
||||
removed.toxins += plasma_energy/PLASMA_CONVERSION_FACTOR
|
||||
|
||||
//Put as much plasma out as is permitted.
|
||||
if( oxygen_energy > removed.total_moles * OXYGEN_CONVERSION_FACTOR * MAX_OXYGEN_RELATIVE_INCREASE / gasefficency)
|
||||
removed.oxygen += (MAX_OXYGEN_RELATIVE_INCREASE * removed.total_moles / gasefficency)
|
||||
other_energy += oxygen_energy - (removed.total_moles * OXYGEN_CONVERSION_FACTOR * MAX_OXYGEN_RELATIVE_INCREASE / gasefficency)
|
||||
else
|
||||
removed.oxygen += oxygen_energy/OXYGEN_CONVERSION_FACTOR
|
||||
|
||||
|
||||
var/heat_energy = (other_energy*THERMAL_RELEASE_MODIFIER)/(1-(OXYGEN_RELEASE_MODIFIER + PLASMA_RELEASE_MODIFIER))
|
||||
var/hallucination_energy = (other_energy*HALLUCINATION_POWER_MODIFIER*HALLUCINATION_FACTOR)/(1-(OXYGEN_RELEASE_MODIFIER + PLASMA_RELEASE_MODIFIER))
|
||||
var/rad_energy = (other_energy*RADIATION_POWER_MODIFIER*RADIATION_FACTOR)/(1-(OXYGEN_RELEASE_MODIFIER + PLASMA_RELEASE_MODIFIER))
|
||||
|
||||
var/heat_applied = max(heat_energy,0)
|
||||
if(heat_applied + removed.temperature > 800)
|
||||
removed.temperature = 800
|
||||
var/energy_to_reconsider = (heat_applied + removed.temperature - 800)
|
||||
hallucination_energy += (energy_to_reconsider*HALLUCINATION_POWER_MODIFIER)/(HALLUCINATION_POWER_MODIFIER+RADIATION_POWER_MODIFIER)
|
||||
rad_energy += (energy_to_reconsider*RADIATION_POWER_MODIFIER)/(HALLUCINATION_POWER_MODIFIER+RADIATION_POWER_MODIFIER)
|
||||
else
|
||||
removed.temperature += heat_applied
|
||||
|
||||
removed.update_values()
|
||||
|
||||
env.merge(removed)
|
||||
|
||||
for(var/mob/living/carbon/human/l in view(src, round(hallucination_energy**0.25))) // you have to be seeing the core to get hallucinations
|
||||
if(prob(10) && !istype(l.glasses, /obj/item/clothing/glasses/meson))
|
||||
l.hallucination += hallucination_energy/((get_dist(l,src)**2))
|
||||
|
||||
for(var/mob/living/l in range(src,round(rad_energy**0.25)))
|
||||
var/rads = rad_energy/((get_dist(l,src)**2))
|
||||
l.apply_effect(rads, IRRADIATE)
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
bullet_act(var/obj/item/projectile/Proj)
|
||||
if(Proj.flag != "bullet")
|
||||
power += Proj.damage
|
||||
return 0
|
||||
@@ -23,7 +23,8 @@
|
||||
/datum/medical_effect/proc/cure(mob/living/carbon/human/H)
|
||||
for(var/R in cures)
|
||||
if(H.reagents.has_reagent(R))
|
||||
H <<"\red [cure_message]"
|
||||
if (cure_message)
|
||||
H <<"\blue [cure_message]"
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -39,16 +40,21 @@
|
||||
M.start = life_tick
|
||||
return
|
||||
|
||||
var/list/L = typesof(/datum/medical_effect)-/datum/medical_effect
|
||||
|
||||
for(var/T in L)
|
||||
var/datum/medical_effect/M = new T
|
||||
if(M.name == name)
|
||||
M.strength = strength
|
||||
M.start = life_tick
|
||||
side_effects += M
|
||||
var/T = side_effects[name]
|
||||
if (!T)
|
||||
return
|
||||
|
||||
var/datum/medical_effect/M = new T
|
||||
if(M.name == name)
|
||||
M.strength = strength
|
||||
M.start = life_tick
|
||||
side_effects += M
|
||||
|
||||
/mob/living/carbon/human/proc/handle_medical_side_effects()
|
||||
//Going to handle those things only every few ticks.
|
||||
if(life_tick % 15 != 0)
|
||||
return 0
|
||||
|
||||
var/list/L = typesof(/datum/medical_effect)-/datum/medical_effect
|
||||
for(var/T in L)
|
||||
@@ -60,18 +66,14 @@
|
||||
for (var/datum/medical_effect/M in side_effects)
|
||||
if (!M) continue
|
||||
var/strength_percent = sin((life_tick - M.start) / 2)
|
||||
log_debug ("[src], tick [life_tick] : Processing [M], Current phase: [strength_percent]")
|
||||
|
||||
// Only do anything if the effect is currently strong enough
|
||||
if(strength_percent >= 0.4)
|
||||
log_debug ("[src], tick [life_tick] : Active phase ; strength [M.strength]")
|
||||
if (M.cure(src) || M.strength > 50)
|
||||
log_debug ("[src], tick [life_tick] : [M] cured or reached end of lifecycle")
|
||||
side_effects -= M
|
||||
del(M)
|
||||
M = null
|
||||
else
|
||||
if(life_tick % 45 == 0)
|
||||
log_debug ("[src], tick [life_tick] : Activating [M] ")
|
||||
M.on_life(src, strength_percent*M.strength)
|
||||
// Effect slowly growing stronger
|
||||
M.strength+=0.08
|
||||
@@ -81,7 +83,7 @@
|
||||
/datum/medical_effect/headache
|
||||
name = "Headache"
|
||||
triggers = list("cryoxadone" = 10, "bicaridine" = 15, "tricordrazine" = 15)
|
||||
cures = list("alkysine", "tramadol")
|
||||
cures = list("alkysine", "tramadol", "paracetamol", "oxycodone")
|
||||
cure_message = "Your head stops throbbing..."
|
||||
|
||||
/datum/medical_effect/headache/on_life(mob/living/carbon/human/H, strength)
|
||||
@@ -92,7 +94,6 @@
|
||||
H.custom_pain("You feel a throbbing pain in your head!",1)
|
||||
if(31 to INFINITY)
|
||||
H.custom_pain("You feel an excrutiating pain in your head!",1)
|
||||
H.adjustBrainLoss(1)
|
||||
|
||||
// BAD STOMACH
|
||||
// ===========
|
||||
@@ -110,7 +111,6 @@
|
||||
H.custom_pain("Your stomach hurts.",0)
|
||||
if(31 to INFINITY)
|
||||
H.custom_pain("You feel sick.",1)
|
||||
H.adjustToxLoss(1)
|
||||
|
||||
// CRAMPS
|
||||
// ======
|
||||
@@ -129,7 +129,6 @@
|
||||
if(31 to INFINITY)
|
||||
H.emote("me",1,"flinches as all the muscles in their body cramp up.")
|
||||
H.custom_pain("There's pain all over your body.",1)
|
||||
H.adjustToxLoss(1)
|
||||
|
||||
// ITCH
|
||||
// ====
|
||||
@@ -148,4 +147,3 @@
|
||||
if(31 to INFINITY)
|
||||
H.emote("me",1,"shivers slightly.")
|
||||
H.custom_pain("This itch makes it really hard to concentrate.",1)
|
||||
H.adjustToxLoss(1)
|
||||
@@ -148,7 +148,7 @@
|
||||
|
||||
if(!block)
|
||||
|
||||
for(var/obj/effect/effect/chem_smoke/smoke in view(1, src))
|
||||
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
|
||||
if(smoke.reagents.total_volume)
|
||||
smoke.reagents.reaction(src, INGEST)
|
||||
spawn(5)
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
|
||||
#define NITROGEN_RETARDATION_FACTOR 4 //Higher == N2 slows reaction more
|
||||
#define THERMAL_RELEASE_MODIFIER 10 //Higher == less heat released during reaction
|
||||
#define PLASMA_RELEASE_MODIFIER 1500 //Higher == less plasma released by reaction
|
||||
#define OXYGEN_RELEASE_MODIFIER 750 //Higher == less oxygen released at high temperature/power
|
||||
#define REACTION_POWER_MODIFIER 1.1 //Higher == more overall power
|
||||
|
||||
|
||||
//These would be what you would get at point blank, decreases with distance
|
||||
#define DETONATION_RADS 200
|
||||
#define DETONATION_HALLUCINATION 600
|
||||
|
||||
|
||||
#define WARNING_DELAY 60 //45 seconds between warnings.
|
||||
|
||||
/obj/machinery/power/supermatter
|
||||
name = "Supermatter"
|
||||
desc = "A strangely translucent and iridescent crystal. \red You get headaches just from looking at it."
|
||||
icon = 'icons/obj/engine.dmi'
|
||||
icon_state = "darkmatter"
|
||||
density = 1
|
||||
anchored = 0
|
||||
|
||||
var/gasefficency = 0.25
|
||||
|
||||
var/base_icon_state = "darkmatter"
|
||||
|
||||
var/damage = 0
|
||||
var/damage_archived = 0
|
||||
var/safe_alert = "Crystaline hyperstructure returning to safe operating levels."
|
||||
var/warning_point = 100
|
||||
var/warning_alert = "Danger! Crystal hyperstructure instability!"
|
||||
var/emergency_point = 700
|
||||
var/emergency_alert = "CRYSTAL DELAMINATION IMMINENT."
|
||||
var/explosion_point = 1000
|
||||
|
||||
var/emergency_issued = 0
|
||||
|
||||
var/explosion_power = 8
|
||||
|
||||
var/lastwarning = 0 // Time in 1/10th of seconds since the last sent warning
|
||||
|
||||
var/power = 0
|
||||
|
||||
//Temporary values so that we can optimize this
|
||||
//How much the bullets damage should be multiplied by when it is added to the internal variables
|
||||
var/config_bullet_energy = 2
|
||||
//How much of the power is left after processing is finished?
|
||||
// var/config_power_reduction_per_tick = 0.5
|
||||
//How much hallucination should it produce per unit of power?
|
||||
var/config_hallucination_power = 0.1
|
||||
|
||||
var/obj/item/device/radio/radio
|
||||
|
||||
shard //Small subtype, less efficient and more sensitive, but less boom.
|
||||
name = "Supermatter Shard"
|
||||
desc = "A strangely translucent and iridescent crystal that looks like it used to be part of a larger structure. \red You get headaches just from looking at it."
|
||||
icon_state = "darkmatter_shard"
|
||||
base_icon_state = "darkmatter_shard"
|
||||
|
||||
warning_point = 50
|
||||
emergency_point = 500
|
||||
explosion_point = 900
|
||||
|
||||
gasefficency = 0.125
|
||||
|
||||
explosion_power = 3 //3,6,9,12? Or is that too small?
|
||||
|
||||
|
||||
/obj/machinery/power/supermatter/New()
|
||||
. = ..()
|
||||
radio = new (src)
|
||||
|
||||
|
||||
/obj/machinery/power/supermatter/Del()
|
||||
del radio
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/power/supermatter/proc/explode()
|
||||
explosion(get_turf(src), explosion_power, explosion_power * 2, explosion_power * 3, explosion_power * 4, 1)
|
||||
del src
|
||||
return
|
||||
|
||||
/obj/machinery/power/supermatter/process()
|
||||
|
||||
var/turf/L = loc
|
||||
|
||||
if(!istype(L)) //If we are not on a turf, uh oh.
|
||||
del src
|
||||
|
||||
//Ok, get the air from the turf
|
||||
var/datum/gas_mixture/env = L.return_air()
|
||||
|
||||
//Remove gas from surrounding area
|
||||
var/datum/gas_mixture/removed = env.remove(gasefficency * env.total_moles)
|
||||
|
||||
if(!removed || !removed.total_moles)
|
||||
damage += max((power-1600)/10, 0)
|
||||
power = min(power, 1600)
|
||||
return 1
|
||||
|
||||
if (!removed)
|
||||
return 1
|
||||
|
||||
damage_archived = damage
|
||||
damage = max( damage + ( (removed.temperature - 800) / 150 ) , 0 )
|
||||
|
||||
if(damage > warning_point) // while the core is still damaged and it's still worth noting its status
|
||||
if((world.timeofday - lastwarning) / 10 >= WARNING_DELAY)
|
||||
|
||||
if(damage > emergency_point)
|
||||
radio.autosay(emergency_alert, "Supermatter Monitor")
|
||||
lastwarning = world.timeofday
|
||||
|
||||
else if(damage >= damage_archived) // The damage is still going up
|
||||
radio.autosay(warning_alert, "Supermatter Monitor")
|
||||
lastwarning = world.timeofday - 150
|
||||
|
||||
else // Phew, we're safe
|
||||
radio.autosay(safe_alert, "Supermatter Monitor")
|
||||
lastwarning = world.timeofday
|
||||
|
||||
if(damage > explosion_point)
|
||||
for(var/mob/living/mob in living_mob_list)
|
||||
if(istype(mob, /mob/living/carbon/human))
|
||||
//Hilariously enough, running into a closet should make you get hit the hardest.
|
||||
mob:hallucination += max(50, min(300, DETONATION_HALLUCINATION * sqrt(1 / (get_dist(mob, src) + 1)) ) )
|
||||
var/rads = DETONATION_RADS * sqrt( 1 / (get_dist(mob, src) + 1) )
|
||||
mob.apply_effect(rads, IRRADIATE)
|
||||
|
||||
explode()
|
||||
|
||||
//Ok, 100% oxygen atmosphere = best reaction
|
||||
//Maxes out at 100% oxygen pressure
|
||||
var/oxygen = max(min((removed.oxygen - (removed.nitrogen * NITROGEN_RETARDATION_FACTOR)) / MOLES_CELLSTANDARD, 1), 0)
|
||||
|
||||
var/temp_factor = 100
|
||||
|
||||
if(oxygen > 0.8)
|
||||
// with a perfect gas mix, make the power less based on heat
|
||||
icon_state = "[base_icon_state]_glow"
|
||||
else
|
||||
// in normal mode, base the produced energy around the heat
|
||||
temp_factor = 60
|
||||
icon_state = base_icon_state
|
||||
|
||||
power = max( (removed.temperature * temp_factor / T0C) * oxygen + power, 0) //Total laser power plus an overload
|
||||
|
||||
//We've generated power, now let's transfer it to the collectors for storing/usage
|
||||
transfer_energy()
|
||||
|
||||
var/device_energy = power * REACTION_POWER_MODIFIER
|
||||
|
||||
//To figure out how much temperature to add each tick, consider that at one atmosphere's worth
|
||||
//of pure oxygen, with all four lasers firing at standard energy and no N2 present, at room temperature
|
||||
//that the device energy is around 2140. At that stage, we don't want too much heat to be put out
|
||||
//Since the core is effectively "cold"
|
||||
|
||||
//Also keep in mind we are only adding this temperature to (efficiency)% of the one tile the rock
|
||||
//is on. An increase of 4*C @ 25% efficiency here results in an increase of 1*C / (#tilesincore) overall.
|
||||
removed.temperature += (device_energy / THERMAL_RELEASE_MODIFIER)
|
||||
|
||||
removed.temperature = max(0, min(removed.temperature, 2500))
|
||||
|
||||
//Calculate how much gas to release
|
||||
removed.toxins += max(device_energy / PLASMA_RELEASE_MODIFIER, 0)
|
||||
|
||||
removed.oxygen += max((device_energy + removed.temperature - T0C) / OXYGEN_RELEASE_MODIFIER, 0)
|
||||
|
||||
removed.update_values()
|
||||
|
||||
env.merge(removed)
|
||||
|
||||
for(var/mob/living/carbon/human/l in view(src, round(power ** 0.25))) // you have to be seeing the core to get hallucinations
|
||||
if(!istype(l.glasses, /obj/item/clothing/glasses/meson))
|
||||
l.hallucination = max(0, min(200, l.hallucination + power * config_hallucination_power * sqrt( 1 / get_dist(l, src) ) ) )
|
||||
|
||||
for(var/mob/living/l in range(src, round((power / 100) ** 0.25)))
|
||||
var/rads = (power / 10) * sqrt( 1 / get_dist(l, src) )
|
||||
l.apply_effect(rads, IRRADIATE)
|
||||
|
||||
power -= (power/500)**3
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/power/supermatter/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(Proj.flag != "bullet")
|
||||
power += Proj.damage * config_bullet_energy
|
||||
else
|
||||
damage += Proj.damage * config_bullet_energy
|
||||
return 0
|
||||
|
||||
|
||||
/obj/machinery/power/supermatter/attack_paw(mob/user as mob)
|
||||
return attack_hand(user)
|
||||
|
||||
|
||||
/obj/machinery/power/supermatter/attack_robot(mob/user as mob)
|
||||
return attack_hand(user)
|
||||
|
||||
|
||||
/obj/machinery/power/supermatter/attack_hand(mob/user as mob)
|
||||
user.visible_message("<span class=\"warning\">\The [user] reaches out and touches \the [src] inducing a resonance... \his body starts to glow and catch flame before flashing into ash.</span>",\
|
||||
"<span class=\"danger\">You reach out and touch \the [src], everything starts burning and all you can hear is ringing. Your last thought is \"That was not a wise decision.\"</span>",\
|
||||
"<span class=\"warning\">You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.</span>")
|
||||
|
||||
Consume(user)
|
||||
|
||||
/obj/machinery/power/supermatter/proc/transfer_energy()
|
||||
for(var/obj/machinery/power/rad_collector/R in rad_collectors)
|
||||
if(get_dist(R, src) <= 15) // Better than using orange() every process
|
||||
R.receive_pulse(power)
|
||||
return
|
||||
|
||||
/obj/machinery/power/supermatter/attackby(obj/item/weapon/W as obj, mob/living/user as mob)
|
||||
user.visible_message("<span class=\"warning\">\The [user] touches \a [W] to \the [src] as a silence fills the room...</span>",\
|
||||
"<span class=\"danger\">You touch \the [W] to \the [src] when everything suddenly goes silent.\"</span>\n<span class=\"notice\">\The [W] flashes into dust as you flinch away from \the [src].</span>",\
|
||||
"<span class=\"warning\">Everything suddenly goes silent.</span>")
|
||||
|
||||
user.drop_from_inventory(W)
|
||||
Consume(W)
|
||||
|
||||
user.apply_effect(150, IRRADIATE)
|
||||
|
||||
|
||||
/obj/machinery/power/supermatter/Bumped(atom/AM as mob|obj)
|
||||
if(istype(AM, /mob/living))
|
||||
AM.visible_message("<span class=\"warning\">\The [AM] slams into \the [src] inducing a resonance... \his body starts to glow and catch flame before flashing into ash.</span>",\
|
||||
"<span class=\"danger\">You slam into \the [src] as your ears are filled with unearthly ringing. Your last thought is \"Oh, fuck.\"</span>",\
|
||||
"<span class=\"warning\">You hear an uneartly ringing, then what sounds like a shrilling kettle as you are washed with a wave of heat.</span>")
|
||||
else
|
||||
AM.visible_message("<span class=\"warning\">\The [AM] smacks into \the [src] and rapidly flashes to ash.</span>",\
|
||||
"<span class=\"warning\">You hear a loud crack as you are washed with a wave of heat.</span>")
|
||||
|
||||
Consume(AM)
|
||||
|
||||
|
||||
/obj/machinery/power/supermatter/proc/Consume(var/mob/living/user)
|
||||
if(istype(user))
|
||||
user.dust()
|
||||
power += 200
|
||||
else
|
||||
del user
|
||||
|
||||
power += 200
|
||||
|
||||
//Some poor sod got eaten, go ahead and irradiate people nearby.
|
||||
for(var/mob/living/l in range(10))
|
||||
if(l in view())
|
||||
l.show_message("<span class=\"warning\">As \the [src] slowly stops resonating, you find your skin covered in new radiation burns.</span>", 1,\
|
||||
"<span class=\"warning\">The unearthly ringing subsides and you notice you have new radiation burns.</span>", 2)
|
||||
else
|
||||
l.show_message("<span class=\"warning\">You hear an uneartly ringing and notice your skin is covered in fresh radiation burns.</span>", 2)
|
||||
var/rads = 500 * sqrt( 1 / (get_dist(l, src) + 1) )
|
||||
l.apply_effect(rads, IRRADIATE)
|
||||
|
||||
@@ -65,6 +65,6 @@
|
||||
P.set_up(10,location)
|
||||
P.start()
|
||||
spawn(5)
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/S = new/datum/effect/effect/system/harmless_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/S = new/datum/effect/effect/system/smoke_spread()
|
||||
S.set_up(5,0,location,null)
|
||||
S.start()
|
||||
@@ -1,19 +1,35 @@
|
||||
var/list/obj/machinery/faxmachine/allfaxes = list()
|
||||
var/list/alldepartments = list("Central Command")
|
||||
|
||||
/obj/machinery/faxmachine
|
||||
name = "fax machine"
|
||||
icon = 'icons/obj/library.dmi'
|
||||
icon_state = "fax"
|
||||
req_access = list(access_lawyer)
|
||||
req_one_access = list(access_lawyer, access_heads)
|
||||
anchored = 1
|
||||
density = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 30
|
||||
active_power_usage = 200
|
||||
power_channel = EQUIP
|
||||
|
||||
var/obj/item/weapon/card/id/scan = null // identification
|
||||
var/authenticated = 0
|
||||
var/obj/item/weapon/paper/tofax = null // what we're sending to central
|
||||
|
||||
var/obj/item/weapon/paper/tofax = null // what we're sending
|
||||
var/sendcooldown = 0 // to avoid spamming fax messages
|
||||
|
||||
var/department = "Unknown" // our department
|
||||
|
||||
var/dpt = "Central Command" // the department we're sending to
|
||||
|
||||
/obj/machinery/faxmachine/New()
|
||||
..()
|
||||
allfaxes += src
|
||||
|
||||
if( !("[department]" in alldepartments) )
|
||||
alldepartments += department
|
||||
|
||||
/obj/machinery/faxmachine/process()
|
||||
return 0
|
||||
|
||||
@@ -26,7 +42,7 @@
|
||||
/obj/machinery/faxmachine/attack_hand(mob/user as mob)
|
||||
user.set_machine(src)
|
||||
|
||||
var/dat = "Central Command Fax Machine<BR>"
|
||||
var/dat = "Fax Machine<BR>"
|
||||
|
||||
var/scan_name
|
||||
if(scan)
|
||||
@@ -54,14 +70,15 @@
|
||||
|
||||
else
|
||||
dat += "<a href='byond://?src=\ref[src];send=1'>Send</a><br>"
|
||||
dat += "<b>Currently sending:</b> [tofax.name]"
|
||||
dat += "<b>Currently sending:</b> [tofax.name]<br>"
|
||||
dat += "<b>Sending to:</b> <a href='byond://?src=\ref[src];dept=1'>[dpt]</a><br>"
|
||||
|
||||
else
|
||||
if(sendcooldown)
|
||||
dat += "Please insert paper to send to Central Command via secure connection.<br><br>"
|
||||
dat += "Please insert paper to send via secure connection.<br><br>"
|
||||
dat += "<b>Transmitter arrays realigning. Please stand by.</b><br>"
|
||||
else
|
||||
dat += "Please insert paper to send to Central Command via secure connection.<br><br>"
|
||||
dat += "Please insert paper to send via secure connection.<br><br>"
|
||||
|
||||
else
|
||||
dat += "Proper authentication is required to use this device.<br><br>"
|
||||
@@ -76,10 +93,18 @@
|
||||
/obj/machinery/faxmachine/Topic(href, href_list)
|
||||
if(href_list["send"])
|
||||
if(tofax)
|
||||
Centcomm_fax(tofax.info, tofax.name, usr)
|
||||
usr << "Message transmitted."
|
||||
sendcooldown = 1
|
||||
spawn(3000) // three minute cooldown. might mess with this number a bit as time goes on
|
||||
|
||||
if(dpt == "Central Command")
|
||||
Centcomm_fax(tofax.info, tofax.name, usr)
|
||||
sendcooldown = 1800
|
||||
|
||||
else
|
||||
SendFax(tofax.info, tofax.name, usr, dpt)
|
||||
sendcooldown = 600
|
||||
|
||||
usr << "Message transmitted successfully."
|
||||
|
||||
spawn(sendcooldown) // cooldown time
|
||||
sendcooldown = 0
|
||||
|
||||
if(href_list["remove"])
|
||||
@@ -107,6 +132,9 @@
|
||||
scan = I
|
||||
authenticated = 0
|
||||
|
||||
if(href_list["dept"])
|
||||
dpt = input(usr, "Which department?", "Choose a department", "") as null|anything in alldepartments
|
||||
|
||||
if(href_list["auth"])
|
||||
if ( (!( authenticated ) && (scan)) )
|
||||
if (check_access(scan))
|
||||
@@ -148,3 +176,20 @@
|
||||
|
||||
var/msg = "\blue <b><font color='orange'>CENTCOMM FAX: </font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<a href='?_src_=holder;CentcommFaxReply=\ref[Sender]'>RPLY</a>)</b>: Receiving '[sentname]' via secure connection ... <a href='?_src_=holder;CentcommFaxView=\ref[sent]'>view message</a>"
|
||||
admins << msg
|
||||
|
||||
proc/SendFax(var/sent, var/sentname, var/mob/Sender, var/dpt)
|
||||
|
||||
for(var/obj/machinery/faxmachine/F in allfaxes)
|
||||
if( F.department == dpt )
|
||||
if(! (F.stat & (BROKEN|NOPOWER) ) )
|
||||
|
||||
flick("faxreceive", F)
|
||||
|
||||
// give the sprite some time to flick
|
||||
spawn(20)
|
||||
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( F.loc )
|
||||
P.name = "[sentname]"
|
||||
P.info = "[sent]"
|
||||
P.update_icon()
|
||||
|
||||
playsound(F.loc, "sound/items/polaroid1.ogg", 50, 1)
|
||||
|
||||
+71
-37
@@ -965,6 +965,7 @@ What are the archived variables for?
|
||||
//Outputs: 1 if can rebuild, 0 if not.
|
||||
if(!sample) return 0
|
||||
|
||||
|
||||
if((abs(oxygen-sample.oxygen) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((oxygen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.oxygen)))
|
||||
return 0
|
||||
@@ -972,52 +973,61 @@ What are the archived variables for?
|
||||
((nitrogen < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen) || (nitrogen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.nitrogen)))
|
||||
return 0
|
||||
if((abs(carbon_dioxide-sample.carbon_dioxide) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((carbon_dioxide < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide) || (oxygen > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide)))
|
||||
((carbon_dioxide < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide) || (carbon_dioxide > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.carbon_dioxide)))
|
||||
return 0
|
||||
if((abs(toxins-sample.toxins) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((toxins < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins) || (toxins > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*sample.toxins)))
|
||||
return 0
|
||||
|
||||
|
||||
if(total_moles() > MINIMUM_AIR_TO_SUSPEND)
|
||||
if((abs(temperature-sample.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) && \
|
||||
((temperature < (1-MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature) || (temperature > (1+MINIMUM_TEMPERATURE_RATIO_TO_SUSPEND)*sample.temperature)))
|
||||
//world << "temp fail [temperature] & [sample.temperature]"
|
||||
return 0
|
||||
|
||||
var/check_moles
|
||||
if(sample.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in sample.trace_gases)
|
||||
if(trace_gas.moles_archived > MINIMUM_AIR_TO_SUSPEND)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(corresponding)
|
||||
if((abs(trace_gas.moles - corresponding.moles) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((corresponding.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles) || (corresponding.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles)))
|
||||
return 0
|
||||
else
|
||||
return 0
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(corresponding)
|
||||
check_moles = corresponding.moles
|
||||
else
|
||||
check_moles = 0
|
||||
|
||||
if((abs(trace_gas.moles - check_moles) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((check_moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles) || (check_moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*trace_gas.moles)))
|
||||
return 0
|
||||
|
||||
if(trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
if(trace_gas.moles > MINIMUM_AIR_TO_SUSPEND)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in sample.trace_gases
|
||||
if(corresponding)
|
||||
if((abs(trace_gas.moles - corresponding.moles) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((trace_gas.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*corresponding.moles) || (trace_gas.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*corresponding.moles)))
|
||||
return 0
|
||||
else
|
||||
return 0
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(corresponding)
|
||||
check_moles = corresponding.moles
|
||||
else
|
||||
check_moles = 0
|
||||
|
||||
if((abs(trace_gas.moles - check_moles) > MINIMUM_AIR_TO_SUSPEND) && \
|
||||
((trace_gas.moles < (1-MINIMUM_AIR_RATIO_TO_SUSPEND)*check_moles) || (trace_gas.moles > (1+MINIMUM_AIR_RATIO_TO_SUSPEND)*check_moles)))
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/proc/compare_unsim(turf/list/samples)
|
||||
//Purpose: Compares a list of unsimulated tiles to self to see if within acceptable ranges that group processing may be enabled
|
||||
//Called by: ZAS sleeping detection.
|
||||
//Inputs: List of unsimulated turfs to compare to
|
||||
//Outputs: 1 if within an acceptable range to sleep, 0 otherwise.
|
||||
var/datum/gas_mixture/after_share = new
|
||||
after_share.copy_from(src)
|
||||
/datum/gas_mixture/proc/add(datum/gas_mixture/right_side)
|
||||
oxygen += right_side.oxygen
|
||||
carbon_dioxide += right_side.carbon_dioxide
|
||||
nitrogen += right_side.nitrogen
|
||||
toxins += right_side.toxins
|
||||
|
||||
ShareSpace(after_share, samples)
|
||||
if(trace_gases.len || right_side.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in right_side.trace_gases)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(!corresponding)
|
||||
corresponding = new trace_gas.type()
|
||||
trace_gases += corresponding
|
||||
corresponding.moles += trace_gas.moles
|
||||
|
||||
return src.compare(after_share)
|
||||
update_values()
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/proc/subtract(datum/gas_mixture/right_side)
|
||||
//Purpose: Subtracts right_side from air_mixture. Used to help turfs mingle
|
||||
@@ -1025,18 +1035,42 @@ What are the archived variables for?
|
||||
//Inputs: Gas mix to remove
|
||||
//Outputs: 1
|
||||
|
||||
oxygen -= right_side.oxygen
|
||||
carbon_dioxide -= right_side.carbon_dioxide
|
||||
nitrogen -= right_side.nitrogen
|
||||
toxins -= right_side.toxins
|
||||
oxygen = max(oxygen - right_side.oxygen)
|
||||
carbon_dioxide = max(carbon_dioxide - right_side.carbon_dioxide)
|
||||
nitrogen = max(nitrogen - right_side.nitrogen)
|
||||
toxins = max(toxins - right_side.toxins)
|
||||
|
||||
if((trace_gases.len > 0)||(right_side.trace_gases.len > 0))
|
||||
if(trace_gases.len || right_side.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in right_side.trace_gases)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in trace_gases
|
||||
if(!corresponding)
|
||||
corresponding = new trace_gas.type()
|
||||
trace_gases += corresponding
|
||||
if(corresponding)
|
||||
corresponding.moles = max(0, corresponding.moles - trace_gas.moles)
|
||||
|
||||
corresponding.moles -= trace_gas.moles
|
||||
update_values()
|
||||
return 1
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/proc/multiply(factor)
|
||||
oxygen *= factor
|
||||
carbon_dioxide *= factor
|
||||
nitrogen *= factor
|
||||
toxins *= factor
|
||||
|
||||
if(trace_gases && trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
trace_gas.moles *= factor
|
||||
|
||||
update_values()
|
||||
return 1
|
||||
|
||||
/datum/gas_mixture/proc/divide(factor)
|
||||
oxygen /= factor
|
||||
carbon_dioxide /= factor
|
||||
nitrogen /= factor
|
||||
toxins /= factor
|
||||
|
||||
if(trace_gases && trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in trace_gases)
|
||||
trace_gas.moles /= factor
|
||||
|
||||
update_values()
|
||||
return 1
|
||||
|
||||
+228
-175
@@ -11,8 +11,6 @@ Attach to transfer valve and open. BOOM.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
//Some legacy definitions so fires can be started.
|
||||
atom/proc/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
return null
|
||||
@@ -21,160 +19,164 @@ atom/proc/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed
|
||||
turf/proc/hotspot_expose(exposed_temperature, exposed_volume, soh = 0)
|
||||
|
||||
|
||||
|
||||
turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
|
||||
if(fire_protection > world.time-300) return
|
||||
var/datum/gas_mixture/air_contents = return_air(1)
|
||||
if(!air_contents)
|
||||
if(fire_protection > world.time-300)
|
||||
return 0
|
||||
|
||||
/*if(active_hotspot)
|
||||
if(soh)
|
||||
if(air_contents.toxins > 0.5 && air_contents.oxygen > 0.5)
|
||||
if(active_hotspot.temperature < exposed_temperature)
|
||||
active_hotspot.temperature = exposed_temperature
|
||||
if(active_hotspot.volume < exposed_volume)
|
||||
active_hotspot.volume = exposed_volume
|
||||
return 1*/
|
||||
var/igniting = 0
|
||||
if(locate(/obj/fire) in src)
|
||||
return 1
|
||||
var/datum/gas/volatile_fuel/fuel = locate() in air_contents.trace_gases
|
||||
var/datum/gas_mixture/air_contents = return_air()
|
||||
if(!air_contents || exposed_temperature < PLASMA_MINIMUM_BURN_TEMPERATURE)
|
||||
return 0
|
||||
|
||||
var/igniting = 0
|
||||
var/obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in src
|
||||
if(air_contents.calculate_firelevel(liquid) > vsc.IgnitionLevel && (fuel || liquid || air_contents.toxins > 0.5))
|
||||
|
||||
if(air_contents.check_combustability(liquid))
|
||||
igniting = 1
|
||||
if(air_contents.oxygen < 0.5)
|
||||
return 0
|
||||
|
||||
if(! (locate(/obj/fire) in src))
|
||||
var/obj/fire/F = new(src,1000)
|
||||
F.temperature = exposed_temperature
|
||||
F.volume = CELL_VOLUME
|
||||
|
||||
//active_hotspot.just_spawned = (current_cycle < air_master.current_cycle)
|
||||
//remove just_spawned protection if no longer processing this cell
|
||||
new /obj/fire(src,1000)
|
||||
|
||||
return igniting
|
||||
|
||||
obj
|
||||
fire
|
||||
//Icon for fire on turfs.
|
||||
/obj/fire
|
||||
//Icon for fire on turfs.
|
||||
|
||||
anchored = 1
|
||||
mouse_opacity = 0
|
||||
anchored = 1
|
||||
mouse_opacity = 0
|
||||
|
||||
//luminosity = 3
|
||||
//luminosity = 3
|
||||
|
||||
icon = 'icons/effects/fire.dmi'
|
||||
icon = 'icons/effects/fire.dmi'
|
||||
icon_state = "1"
|
||||
|
||||
layer = TURF_LAYER
|
||||
|
||||
var/firelevel = 10000 //Calculated by gas_mixture.calculate_firelevel()
|
||||
|
||||
/obj/fire/process()
|
||||
. = 1
|
||||
|
||||
//get location and check if it is in a proper ZAS zone
|
||||
var/turf/simulated/S = loc
|
||||
|
||||
if(!istype(S))
|
||||
del src
|
||||
|
||||
if(!S.zone)
|
||||
del src
|
||||
|
||||
var/datum/gas_mixture/air_contents = S.return_air()
|
||||
//get liquid fuels on the ground.
|
||||
var/obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in S
|
||||
//and the volatile stuff from the air
|
||||
var/datum/gas/volatile_fuel/fuel = locate() in air_contents.trace_gases
|
||||
|
||||
//since the air is processed in fractions, we need to make sure not to have any minuscle residue or
|
||||
//the amount of moles might get to low for some functions to catch them and thus result in wonky behaviour
|
||||
if(air_contents.oxygen < 0.001)
|
||||
air_contents.oxygen = 0
|
||||
if(air_contents.toxins < 0.001)
|
||||
air_contents.toxins = 0
|
||||
if(fuel)
|
||||
if(fuel.moles < 0.001)
|
||||
air_contents.trace_gases.Remove(fuel)
|
||||
|
||||
//check if there is something to combust
|
||||
if(!air_contents.check_recombustability(liquid))
|
||||
//del src
|
||||
RemoveFire()
|
||||
|
||||
//get a firelevel and set the icon
|
||||
firelevel = air_contents.calculate_firelevel(liquid)
|
||||
|
||||
if(firelevel > 6)
|
||||
icon_state = "3"
|
||||
SetLuminosity(7)
|
||||
else if(firelevel > 2.5)
|
||||
icon_state = "2"
|
||||
SetLuminosity(5)
|
||||
else
|
||||
icon_state = "1"
|
||||
SetLuminosity(3)
|
||||
|
||||
var
|
||||
volume = CELL_VOLUME
|
||||
temperature = PLASMA_MINIMUM_BURN_TEMPERATURE
|
||||
firelevel = 10000 //Calculated by gas_mixture.calculate_firelevel()
|
||||
archived_firelevel = 0
|
||||
//im not sure how to implement a version that works for every creature so for now monkeys are firesafe
|
||||
for(var/mob/living/carbon/human/M in loc)
|
||||
M.FireBurn(firelevel, air_contents.temperature, air_contents.return_pressure() ) //Burn the humans!
|
||||
for(var/atom/A in loc)
|
||||
A.fire_act(air_contents, air_contents.temperature, air_contents.return_volume())
|
||||
//spread
|
||||
for(var/direction in cardinal)
|
||||
if(S.air_check_directions&direction) //Grab all valid bordering tiles
|
||||
|
||||
process()
|
||||
. = 1
|
||||
var/turf/simulated/enemy_tile = get_step(S, direction)
|
||||
|
||||
if(firelevel > vsc.IgnitionLevel)
|
||||
if(istype(enemy_tile))
|
||||
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 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)
|
||||
firelevel -= 1.5
|
||||
continue
|
||||
|
||||
var/turf/simulated/floor/S = loc
|
||||
if(!S.zone) del src //Cannot exist where zones are broken.
|
||||
//Spread the fire.
|
||||
if(!(locate(/obj/fire) in enemy_tile))
|
||||
if( prob( 50 + 50 * (firelevel/vsc.fire_firelevel_multiplier) ) && S.CanPass(null, enemy_tile, 0,0) && enemy_tile.CanPass(null, S, 0,0))
|
||||
new/obj/fire(enemy_tile,firelevel)
|
||||
|
||||
if(istype(S))
|
||||
var
|
||||
datum/gas_mixture/air_contents = S.return_air()
|
||||
//Get whatever trace fuels are in the area
|
||||
datum/gas/volatile_fuel/fuel = locate() in air_contents.trace_gases
|
||||
//Also get liquid fuels on the ground.
|
||||
obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in S
|
||||
//seperate part of the present gas
|
||||
//this is done to prevent the fire burning all gases in a single pass
|
||||
var/datum/gas_mixture/flow = air_contents.remove_ratio(vsc.fire_consuption_rate)
|
||||
///////////////////////////////// FLOW HAS BEEN CREATED /// DONT DELETE THE FIRE UNTIL IT IS MERGED BACK OR YOU WILL DELETE AIR ///////////////////////////////////////////////
|
||||
|
||||
var/datum/gas_mixture/flow = air_contents.remove_ratio(0.25)
|
||||
//The reason we're taking a part of the air instead of all of it is so that it doesn't jump to
|
||||
//the fire's max temperature instantaneously.
|
||||
if(flow)
|
||||
|
||||
firelevel = air_contents.calculate_firelevel(liquid)
|
||||
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(PLASMA_MINIMUM_BURN_TEMPERATURE+0.1,flow.temperature)
|
||||
|
||||
//Ensure that there is an appropriate amount of fuel and O2 here.
|
||||
if(firelevel > 0.25 && flow.oxygen > 0.3 && (air_contents.toxins || fuel || liquid))
|
||||
//burn baby burn!
|
||||
|
||||
for(var/direction in cardinal)
|
||||
if(S.air_check_directions&direction) //Grab all valid bordering tiles
|
||||
flow.zburn(liquid,1)
|
||||
//merge the air back
|
||||
S.assume_air(flow)
|
||||
|
||||
var/turf/simulated/enemy_tile = get_step(S, direction)
|
||||
|
||||
if(istype(enemy_tile))
|
||||
//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)
|
||||
firelevel -= 1.5
|
||||
continue
|
||||
|
||||
//Spread the fire.
|
||||
if(!(locate(/obj/fire) in enemy_tile))
|
||||
if( prob( firelevel*10 ) && S.CanPass(null, enemy_tile, 0,0) && enemy_tile.CanPass(null, S, 0,0))
|
||||
new/obj/fire(enemy_tile,firelevel)
|
||||
|
||||
if(flow)
|
||||
|
||||
//Ensure adequate oxygen and fuel.
|
||||
if(flow.oxygen > 0.3 && (flow.toxins || fuel || liquid))
|
||||
|
||||
//Change icon depending on the fuel, and thus temperature.
|
||||
if(firelevel > 6)
|
||||
icon_state = "3"
|
||||
else if(firelevel > 2.5)
|
||||
icon_state = "2"
|
||||
else
|
||||
icon_state = "1"
|
||||
|
||||
//Ensure flow temperature is higher than minimum fire temperatures.
|
||||
flow.temperature = max(PLASMA_MINIMUM_BURN_TEMPERATURE+0.1,flow.temperature)
|
||||
|
||||
//Burn the gas mixture.
|
||||
flow.zburn(liquid)
|
||||
if(fuel && fuel.moles <= 0.00001)
|
||||
del fuel
|
||||
|
||||
else
|
||||
|
||||
del src
|
||||
///////////////////////////////// FLOW HAS BEEN REMERGED /// feel free to delete the fire again from here on //////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
S.assume_air(flow) //Then put it back where you found it.
|
||||
/obj/fire/New(newLoc,fl)
|
||||
..()
|
||||
|
||||
else
|
||||
del src
|
||||
else
|
||||
del src
|
||||
else
|
||||
del src
|
||||
if(!istype(loc, /turf))
|
||||
del src
|
||||
|
||||
dir = pick(cardinal)
|
||||
SetLuminosity(3)
|
||||
firelevel = fl
|
||||
air_master.active_hotspots.Add(src)
|
||||
|
||||
|
||||
for(var/mob/living/carbon/human/M in loc)
|
||||
M.FireBurn(temperature, min(max(0.1,firelevel / 20),10)) //Burn the humans!
|
||||
/obj/fire/Del()
|
||||
if (istype(loc, /turf/simulated))
|
||||
SetLuminosity(0)
|
||||
|
||||
loc = null
|
||||
air_master.active_hotspots.Remove(src)
|
||||
|
||||
New(newLoc,fl)
|
||||
..()
|
||||
..()
|
||||
|
||||
if(!istype(loc, /turf))
|
||||
del src
|
||||
/obj/fire/proc/RemoveFire()
|
||||
if (istype(loc, /turf/simulated))
|
||||
SetLuminosity(0)
|
||||
loc = null
|
||||
air_master.active_hotspots.Remove(src)
|
||||
|
||||
dir = pick(cardinal)
|
||||
//sd_SetLuminosity(3,2,0)
|
||||
firelevel = fl
|
||||
air_master.active_hotspots.Add(src)
|
||||
|
||||
Del()
|
||||
if (istype(loc, /turf/simulated))
|
||||
//sd_SetLuminosity(0)
|
||||
|
||||
loc = null
|
||||
air_master.active_hotspots.Remove(src)
|
||||
|
||||
..()
|
||||
|
||||
|
||||
turf/simulated/var/fire_protection = 0 //Protects newly extinguished tiles from being overrun again.
|
||||
@@ -182,22 +184,19 @@ turf/proc/apply_fire_protection()
|
||||
turf/simulated/apply_fire_protection()
|
||||
fire_protection = world.time
|
||||
|
||||
datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid)
|
||||
//This proc is similar to fire(), but uses a simple logarithm to calculate temp, and is thus more stable with ZAS.
|
||||
|
||||
if(temperature > PLASMA_FLASHPOINT && !reacting)
|
||||
reacting = 1
|
||||
datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid, force_burn)
|
||||
var/value = 0
|
||||
|
||||
if(temperature > PLASMA_MINIMUM_BURN_TEMPERATURE && reacting)
|
||||
var
|
||||
total_fuel = toxins
|
||||
fuel_sources = 0 //We'll divide by this later so that fuel is consumed evenly.
|
||||
datum/gas/volatile_fuel/fuel = locate() in trace_gases
|
||||
if((temperature > PLASMA_MINIMUM_BURN_TEMPERATURE || force_burn) && check_recombustability(liquid))
|
||||
var/total_fuel = 0
|
||||
var/datum/gas/volatile_fuel/fuel = locate() in trace_gases
|
||||
|
||||
total_fuel += toxins
|
||||
|
||||
if(fuel)
|
||||
//Volatile Fuel
|
||||
total_fuel += fuel.moles
|
||||
fuel_sources++
|
||||
|
||||
if(liquid)
|
||||
//Liquid Fuel
|
||||
@@ -205,72 +204,126 @@ datum/gas_mixture/proc/zburn(obj/effect/decal/cleanable/liquid_fuel/liquid)
|
||||
del liquid
|
||||
else
|
||||
total_fuel += liquid.amount
|
||||
fuel_sources++
|
||||
|
||||
//Toxins
|
||||
if(toxins > 0.3) fuel_sources++
|
||||
//Calculate the firelevel.
|
||||
var/firelevel = calculate_firelevel(liquid)
|
||||
|
||||
if(!fuel_sources) return 0 //If there's no fuel, there's no burn. Can't divide by zero anyway.
|
||||
//get the current inner energy of the gas mix
|
||||
//this must be taken here to prevent the addition or deletion of energy by a changing heat capacity
|
||||
var/starting_energy = temperature * heat_capacity()
|
||||
|
||||
if(oxygen > 0.3)
|
||||
//determine the amount of oxygen used
|
||||
var/total_oxygen = min(oxygen, 2 * total_fuel)
|
||||
|
||||
//Calculate the firelevel.
|
||||
var/firelevel = calculate_firelevel(liquid)
|
||||
//determine the amount of fuel actually used
|
||||
var/used_fuel_ratio = min(oxygen / 2 , total_fuel) / total_fuel
|
||||
total_fuel = total_fuel * used_fuel_ratio
|
||||
|
||||
//Reaches a maximum practical temperature of around 4500.
|
||||
var/total_reactants = total_fuel + total_oxygen
|
||||
|
||||
//Increase temperature.
|
||||
temperature = max( 1700*log(0.4*firelevel + 1.23) , temperature )
|
||||
//determine the amount of reactants actually reacting
|
||||
var/used_reactants_ratio = min( max(total_reactants * firelevel / vsc.fire_firelevel_multiplier, 0.2), total_reactants) / total_reactants
|
||||
|
||||
//Consume some gas.
|
||||
var/consumed_gas = min(oxygen,0.05*firelevel,total_fuel) / fuel_sources
|
||||
//remove and add gasses as calculated
|
||||
oxygen -= min(oxygen, total_oxygen * used_reactants_ratio )
|
||||
|
||||
oxygen = max(0,oxygen-consumed_gas)
|
||||
toxins -= min(toxins, (toxins * used_fuel_ratio * used_reactants_ratio ) * 3)
|
||||
if(toxins < 0)
|
||||
toxins = 0
|
||||
|
||||
toxins = max(0,toxins-consumed_gas)
|
||||
carbon_dioxide += max(2 * total_fuel, 0)
|
||||
|
||||
carbon_dioxide += consumed_gas*2
|
||||
if(fuel)
|
||||
fuel.moles -= (fuel.moles * used_fuel_ratio * used_reactants_ratio) * 5 //Fuel burns 5 times as quick
|
||||
if(fuel.moles <= 0) del fuel
|
||||
|
||||
if(fuel)
|
||||
fuel.moles -= consumed_gas
|
||||
if(fuel.moles <= 0) del fuel
|
||||
if(liquid)
|
||||
liquid.amount -= (liquid.amount * used_fuel_ratio * used_reactants_ratio) * 5 // liquid fuel burns 5 times as quick
|
||||
|
||||
if(liquid)
|
||||
liquid.amount -= consumed_gas
|
||||
if(liquid.amount <= 0) del liquid
|
||||
if(liquid.amount <= 0) del liquid
|
||||
|
||||
update_values()
|
||||
return consumed_gas*fuel_sources
|
||||
//calculate the energy produced by the reaction and then set the new temperature of the mix
|
||||
temperature = (starting_energy + vsc.fire_fuel_energy_release * total_fuel) / heat_capacity()
|
||||
|
||||
else
|
||||
reacting = 0
|
||||
update_values()
|
||||
value = total_reactants * used_reactants_ratio
|
||||
return value
|
||||
|
||||
datum/gas_mixture/proc/check_recombustability(obj/effect/decal/cleanable/liquid_fuel/liquid)
|
||||
//this is a copy proc to continue a fire after its been started.
|
||||
|
||||
var/datum/gas/volatile_fuel/fuel = locate() in trace_gases
|
||||
|
||||
if(oxygen && (toxins || fuel || liquid))
|
||||
if(liquid)
|
||||
return 1
|
||||
if (toxins)
|
||||
return 1
|
||||
if(fuel)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
datum/gas_mixture/proc/check_combustability(obj/effect/decal/cleanable/liquid_fuel/liquid)
|
||||
//this check comes up very often and is thus centralized here to ease adding stuff
|
||||
|
||||
var/datum/gas/volatile_fuel/fuel = locate() in trace_gases
|
||||
|
||||
if(oxygen && (toxins || fuel || liquid))
|
||||
if(liquid)
|
||||
return 1
|
||||
if (toxins >= 0.7)
|
||||
return 1
|
||||
if(fuel && fuel.moles >= 1.4)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fuel/liquid)
|
||||
//Calculates the firelevel based on one equation instead of having to do this multiple times in different areas.
|
||||
var
|
||||
datum/gas/volatile_fuel/fuel = locate() in trace_gases
|
||||
liquid_concentration = 0
|
||||
//Calculates the firelevel based on one equation instead of having to do this multiple times in different areas.
|
||||
|
||||
oxy_concentration = oxygen / volume
|
||||
tox_concentration = toxins / volume
|
||||
fuel_concentration = 0
|
||||
var/datum/gas/volatile_fuel/fuel = locate() in trace_gases
|
||||
var/total_fuel = 0
|
||||
var/firelevel = 0
|
||||
|
||||
if(fuel) fuel_concentration = (fuel.moles) / volume
|
||||
if(liquid) liquid_concentration = (liquid.amount*15) / volume
|
||||
return (oxy_concentration + tox_concentration + liquid_concentration + fuel_concentration)*100
|
||||
if(check_recombustability(liquid))
|
||||
|
||||
/mob/living/carbon/human/proc/FireBurn(last_temperature, mx as num)
|
||||
total_fuel += toxins
|
||||
|
||||
if(liquid)
|
||||
total_fuel += liquid.amount
|
||||
|
||||
if(fuel)
|
||||
total_fuel += fuel.moles
|
||||
|
||||
var/total_combustables = (total_fuel + oxygen)
|
||||
|
||||
if(total_fuel > 0 && oxygen > 0)
|
||||
|
||||
//slows down the burning when the concentration of the reactants is low
|
||||
var/dampening_multiplier = total_combustables / (total_combustables + nitrogen + carbon_dioxide)
|
||||
//calculates how close the mixture of the reactants is to the optimum
|
||||
var/mix_multiplier = 1 / (1 + (5 * ((oxygen / total_combustables) ** 2)))
|
||||
//toss everything together
|
||||
firelevel = vsc.fire_firelevel_multiplier * mix_multiplier * dampening_multiplier
|
||||
|
||||
return max( 0, firelevel)
|
||||
|
||||
|
||||
/mob/living/proc/FireBurn(var/firelevel, var/last_temperature, var/pressure)
|
||||
var/mx = 5 * firelevel/vsc.fire_firelevel_multiplier * min(pressure / ONE_ATMOSPHERE, 1)
|
||||
apply_damage(2.5*mx, BURN)
|
||||
|
||||
|
||||
/mob/living/carbon/human/FireBurn(var/firelevel, var/last_temperature, var/pressure)
|
||||
//Burns mobs due to fire. Respects heat transfer coefficients on various body parts.
|
||||
//Due to TG reworking how fireprotection works, this is kinda less meaningful.
|
||||
|
||||
var
|
||||
head_exposure = 1
|
||||
chest_exposure = 1
|
||||
groin_exposure = 1
|
||||
legs_exposure = 1
|
||||
arms_exposure = 1
|
||||
var/head_exposure = 1
|
||||
var/chest_exposure = 1
|
||||
var/groin_exposure = 1
|
||||
var/legs_exposure = 1
|
||||
var/arms_exposure = 1
|
||||
|
||||
//Get heat transfer coefficients for clothing.
|
||||
|
||||
@@ -289,6 +342,8 @@ datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fue
|
||||
legs_exposure = 0
|
||||
if(C.body_parts_covered & ARMS)
|
||||
arms_exposure = 0
|
||||
//minimize this for low-pressure enviroments
|
||||
var/mx = 5 * firelevel/vsc.fire_firelevel_multiplier * min(pressure / ONE_ATMOSPHERE, 1)
|
||||
|
||||
//Always check these damage procs first if fire damage isn't working. They're probably what's wrong.
|
||||
|
||||
@@ -299,5 +354,3 @@ datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fue
|
||||
apply_damage(0.6*mx*legs_exposure, BURN, "r_leg", 0, 0, "Fire")
|
||||
apply_damage(0.4*mx*arms_exposure, BURN, "l_arm", 0, 0, "Fire")
|
||||
apply_damage(0.4*mx*arms_exposure, BURN, "r_arm", 0, 0, "Fire")
|
||||
|
||||
//flash_pain()
|
||||
+3
-3
@@ -118,12 +118,12 @@ obj/var/contaminated = 0
|
||||
/mob/living/carbon/human/proc/burn_eyes()
|
||||
//The proc that handles eye burning.
|
||||
if(prob(20)) src << "\red Your eyes burn!"
|
||||
eye_stat += 2.5
|
||||
var/datum/organ/internal/eyes/E = internal_organs["eyes"]
|
||||
E.damage += 2.5
|
||||
eye_blurry = min(eye_blurry+1.5,50)
|
||||
if (prob(max(0,eye_stat - 20) + 1) &&!eye_blind)
|
||||
if (prob(max(0,E.damage - 15) + 1) &&!eye_blind)
|
||||
src << "\red You are blinded!"
|
||||
eye_blind += 20
|
||||
eye_stat = 0
|
||||
|
||||
/mob/living/carbon/human/proc/pl_head_protected()
|
||||
//Checks if the head is adequately sealed.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
var/global/vs_control/vsc = new
|
||||
|
||||
/vs_control
|
||||
/* var/fire_consuption_rate = 0.25
|
||||
var/fire_consuption_rate = 0.25
|
||||
var/fire_consuption_rate_NAME = "Fire - Air Consumption Ratio"
|
||||
var/fire_consuption_rate_DESC = "Ratio of air removed and combusted per tick."
|
||||
|
||||
@@ -12,7 +12,7 @@ var/global/vs_control/vsc = new
|
||||
var/fire_fuel_energy_release = 397000
|
||||
var/fire_fuel_energy_release_NAME = "Fire - Fuel energy release"
|
||||
var/fire_fuel_energy_release_DESC = "The energy in joule released when burning one mol of a burnable substance"
|
||||
*/
|
||||
|
||||
|
||||
var/IgnitionLevel = 0.5
|
||||
var/IgnitionLevel_DESC = "Determines point at which fire can ignite"
|
||||
|
||||
+123
-27
@@ -10,6 +10,9 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
||||
var/list/contents //All the tiles that are contained in this zone.
|
||||
var/list/unsimulated_tiles // Any space tiles in this list will cause air to flow out.
|
||||
|
||||
var/datum/gas_mixture/air_unsim //Overall average of the air in connected unsimualted tiles.
|
||||
var/unsim_air_needs_update = 0 //Set to 1 on geometry changes, marks air_unsim as needing update.
|
||||
|
||||
var/list/connections //connection objects which refer to connections with other zones, e.g. through a door.
|
||||
var/list/direct_connections //connections which directly connect two zones.
|
||||
|
||||
@@ -126,6 +129,8 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
||||
unsimulated_tiles += T
|
||||
contents -= T
|
||||
|
||||
unsim_air_needs_update = 1
|
||||
|
||||
/zone/proc/RemoveTurf(turf/T)
|
||||
//Same, but in reverse.
|
||||
if(istype(T, /turf/simulated))
|
||||
@@ -146,6 +151,48 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
||||
if(!unsimulated_tiles.len)
|
||||
unsimulated_tiles = null
|
||||
|
||||
unsim_air_needs_update = 1
|
||||
|
||||
//Updates the air_unsim var
|
||||
/zone/proc/UpdateUnsimAvg()
|
||||
if(!unsimulated_tiles || !unsimulated_tiles.len) //if we don't have any unsimulated tiles, we can't do much.
|
||||
return
|
||||
|
||||
if(!unsim_air_needs_update && air_unsim) //if air_unsim doesn't exist, we need to create it even if we don't need an update.
|
||||
return
|
||||
|
||||
unsim_air_needs_update = 0
|
||||
|
||||
if(!air_unsim)
|
||||
air_unsim = new /datum/gas_mixture
|
||||
|
||||
air_unsim.oxygen = 0
|
||||
air_unsim.nitrogen = 0
|
||||
air_unsim.carbon_dioxide = 0
|
||||
air_unsim.toxins = 0
|
||||
air_unsim.temperature = 0
|
||||
|
||||
var/correction_ratio = max(1, max(max(1, air.group_multiplier) + 3, 1) + unsimulated_tiles.len) / unsimulated_tiles.len
|
||||
|
||||
for(var/turf/T in unsimulated_tiles)
|
||||
if(!istype(T, /turf/simulated))
|
||||
air_unsim.oxygen += T.oxygen
|
||||
air_unsim.carbon_dioxide += T.carbon_dioxide
|
||||
air_unsim.nitrogen += T.nitrogen
|
||||
air_unsim.toxins += T.toxins
|
||||
air_unsim.temperature += T.temperature/unsimulated_tiles.len
|
||||
|
||||
//These values require adjustment in order to properly represent a room of the specified size.
|
||||
air_unsim.oxygen *= correction_ratio
|
||||
air_unsim.carbon_dioxide *= correction_ratio
|
||||
air_unsim.nitrogen *= correction_ratio
|
||||
air_unsim.toxins *= correction_ratio
|
||||
|
||||
air_unsim.group_multiplier = unsimulated_tiles.len
|
||||
|
||||
air_unsim.update_values()
|
||||
return
|
||||
|
||||
//////////////
|
||||
//PROCESSING//
|
||||
//////////////
|
||||
@@ -180,20 +227,23 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
||||
|
||||
progress = "problem with: ShareSpace()"
|
||||
|
||||
if(unsim_air_needs_update)
|
||||
unsim_air_needs_update = 0
|
||||
UpdateUnsimAvg()
|
||||
|
||||
if(unsimulated_tiles)
|
||||
if(locate(/turf/simulated) in unsimulated_tiles)
|
||||
for(var/turf/simulated/T in unsimulated_tiles)
|
||||
unsimulated_tiles -= T
|
||||
|
||||
if(unsimulated_tiles.len)
|
||||
var/old_pressure = air.return_pressure()
|
||||
var/moved_air = ShareSpace(air,unsimulated_tiles)
|
||||
var/moved_air = ShareSpace(air, air_unsim)
|
||||
|
||||
if(!air.compare(air_unsim))
|
||||
interactions_with_unsim++
|
||||
|
||||
if(moved_air > vsc.airflow_lightest_pressure)
|
||||
AirflowSpace(src)
|
||||
|
||||
if(old_pressure && (moved_air / old_pressure) > MINIMUM_AIR_RATIO_TO_SUSPEND) //Check if we've moved enough air to be considered awake.
|
||||
interactions_with_unsim++
|
||||
else
|
||||
unsimulated_tiles = null
|
||||
|
||||
@@ -310,11 +360,11 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
||||
Z.interactions_with_neighbors++
|
||||
interactions_with_neighbors++
|
||||
|
||||
if(!interactions_with_neighbors && !interactions_with_unsim)
|
||||
SetStatus(ZONE_SLEEPING)
|
||||
if(!interactions_with_neighbors && !interactions_with_unsim)
|
||||
SetStatus(ZONE_SLEEPING)
|
||||
|
||||
interactions_with_neighbors = 0
|
||||
interactions_with_unsim = 0
|
||||
interactions_with_neighbors = 0
|
||||
interactions_with_unsim = 0
|
||||
|
||||
progress = "all components completed successfully, the problem is not here"
|
||||
|
||||
@@ -327,6 +377,11 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
||||
else if(status == ZONE_ACTIVE && new_status == ZONE_SLEEPING)
|
||||
air_master.active_zones.Remove(src)
|
||||
status = ZONE_SLEEPING
|
||||
|
||||
if(unsimulated_tiles && unsimulated_tiles.len)
|
||||
UpdateUnsimAvg()
|
||||
air.copy_from(air_unsim)
|
||||
|
||||
if(!archived_air)
|
||||
archived_air = new
|
||||
archived_air.copy_from(air)
|
||||
@@ -342,12 +397,13 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
||||
var/difference = 0
|
||||
|
||||
if(unsimulated_tiles && unsimulated_tiles.len)
|
||||
if(air.compare_unsim(unsimulated_tiles))
|
||||
UpdateUnsimAvg()
|
||||
if(!air.compare(air_unsim))
|
||||
difference = 1
|
||||
|
||||
if(!difference)
|
||||
for(var/zone/Z in connected_zones) //Check adjacent zones for air difference.
|
||||
if(air.compare(Z.air))
|
||||
if(!air.compare(Z.air))
|
||||
difference = 1
|
||||
break
|
||||
|
||||
@@ -362,11 +418,20 @@ var/list/CounterDoorDirections = list(SOUTH,EAST) //Which directions doors turfs
|
||||
return air.merge(giver)
|
||||
|
||||
else
|
||||
if(unsimulated_tiles && unsimulated_tiles.len)
|
||||
UpdateUnsimAvg()
|
||||
var/datum/gas_mixture/compare_air = new
|
||||
compare_air.copy_from(giver)
|
||||
compare_air.add(air_unsim)
|
||||
compare_air.divide(air.group_multiplier)
|
||||
|
||||
if(air_unsim.compare(compare_air))
|
||||
return 0
|
||||
|
||||
var/result = air.merge(giver)
|
||||
|
||||
if(!archived_air.compare(air))
|
||||
SetStatus(ZONE_ACTIVE)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@@ -443,6 +508,7 @@ proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
|
||||
if(H)
|
||||
var/G_avg = (G.moles*size + H.moles*share_size) / (size+share_size)
|
||||
G.moles = (G.moles - G_avg) * (1-ratio) + G_avg
|
||||
|
||||
H.moles = (H.moles - G_avg) * (1-ratio) + G_avg
|
||||
else
|
||||
H = new G.type
|
||||
@@ -451,6 +517,15 @@ proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
|
||||
G.moles = (G.moles - G_avg) * (1-ratio) + G_avg
|
||||
H.moles = (H.moles - G_avg) * (1-ratio) + G_avg
|
||||
|
||||
for(var/datum/gas/G in B.trace_gases)
|
||||
var/datum/gas/H = locate(G.type) in A.trace_gases
|
||||
if(!H)
|
||||
H = new G.type
|
||||
A.trace_gases += H
|
||||
var/G_avg = (G.moles*size) / (size+share_size)
|
||||
G.moles = (G.moles - G_avg) * (1-ratio) + G_avg
|
||||
H.moles = (H.moles - G_avg) * (1-ratio) + G_avg
|
||||
|
||||
A.update_values()
|
||||
B.update_values()
|
||||
|
||||
@@ -459,7 +534,7 @@ proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
|
||||
|
||||
proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
|
||||
//A modified version of ShareRatio for spacing gas at the same rate as if it were going into a large airless room.
|
||||
if(!unsimulated_tiles || !unsimulated_tiles.len)
|
||||
if(!unsimulated_tiles)
|
||||
return 0
|
||||
|
||||
var
|
||||
@@ -472,6 +547,22 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
|
||||
|
||||
size = max(1,A.group_multiplier)
|
||||
|
||||
var/tileslen
|
||||
var/share_size
|
||||
|
||||
if(istype(unsimulated_tiles, /datum/gas_mixture))
|
||||
var/datum/gas_mixture/avg_unsim = unsimulated_tiles
|
||||
unsim_oxygen = avg_unsim.oxygen
|
||||
unsim_co2 = avg_unsim.carbon_dioxide
|
||||
unsim_nitrogen = avg_unsim.nitrogen
|
||||
unsim_plasma = avg_unsim.toxins
|
||||
unsim_temperature = avg_unsim.temperature
|
||||
share_size = max(1, max(size + 3, 1) + avg_unsim.group_multiplier)
|
||||
tileslen = avg_unsim.group_multiplier
|
||||
|
||||
else if(istype(unsimulated_tiles, /list))
|
||||
if(!unsimulated_tiles.len)
|
||||
return 0
|
||||
// We use the same size for the potentially single space tile
|
||||
// as we use for the entire room. Why is this?
|
||||
// Short answer: We do not want larger rooms to depressurize more
|
||||
@@ -479,20 +570,25 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
|
||||
// oh-shit effect when large rooms get breached, but still having small
|
||||
// rooms remain pressurized for long enough to make escape possible.
|
||||
share_size = max(1, max(size + 3, 1) + unsimulated_tiles.len)
|
||||
correction_ratio = share_size / unsimulated_tiles.len
|
||||
var/correction_ratio = share_size / unsimulated_tiles.len
|
||||
|
||||
for(var/turf/T in unsimulated_tiles)
|
||||
unsim_oxygen += T.oxygen
|
||||
unsim_co2 += T.carbon_dioxide
|
||||
unsim_nitrogen += T.nitrogen
|
||||
unsim_plasma += T.toxins
|
||||
unsim_temperature += T.temperature/unsimulated_tiles.len
|
||||
for(var/turf/T in unsimulated_tiles)
|
||||
unsim_oxygen += T.oxygen
|
||||
unsim_co2 += T.carbon_dioxide
|
||||
unsim_nitrogen += T.nitrogen
|
||||
unsim_plasma += T.toxins
|
||||
unsim_temperature += T.temperature/unsimulated_tiles.len
|
||||
|
||||
//These values require adjustment in order to properly represent a room of the specified size.
|
||||
unsim_oxygen *= correction_ratio
|
||||
unsim_co2 *= correction_ratio
|
||||
unsim_nitrogen *= correction_ratio
|
||||
unsim_plasma *= correction_ratio
|
||||
tileslen = unsimulated_tiles.len
|
||||
|
||||
else //invalid input type
|
||||
return 0
|
||||
|
||||
//These values require adjustment in order to properly represent a room of the specified size.
|
||||
unsim_oxygen *= correction_ratio
|
||||
unsim_co2 *= correction_ratio
|
||||
unsim_nitrogen *= correction_ratio
|
||||
unsim_plasma *= correction_ratio
|
||||
unsim_heat_capacity = HEAT_CAPACITY_CALCULATION(unsim_oxygen, unsim_co2, unsim_nitrogen, unsim_plasma)
|
||||
|
||||
var
|
||||
@@ -517,8 +613,8 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output)
|
||||
if((full_heat_capacity + unsim_heat_capacity) > 0)
|
||||
temp_avg = (A.temperature * full_heat_capacity + unsim_temperature * unsim_heat_capacity) / (full_heat_capacity + unsim_heat_capacity)
|
||||
|
||||
if(sharing_lookup_table.len >= unsimulated_tiles.len) //6 or more interconnecting tiles will max at 42% of air moved per tick.
|
||||
ratio = sharing_lookup_table[unsimulated_tiles.len]
|
||||
if(sharing_lookup_table.len >= tileslen) //6 or more interconnecting tiles will max at 42% of air moved per tick.
|
||||
ratio = sharing_lookup_table[tileslen]
|
||||
|
||||
A.oxygen = max(0, (A.oxygen - oxy_avg) * (1 - ratio) + oxy_avg )
|
||||
A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1 - ratio) + nit_avg )
|
||||
|
||||
@@ -15,6 +15,7 @@ var/global/list/chemical_reactions_list //list of all /datum/chemical_reactio
|
||||
var/global/list/chemical_reagents_list //list of all /datum/reagent datums indexed by reagent id. Used by chemistry stuff
|
||||
var/global/list/landmarks_list = list() //list of all landmarks created
|
||||
var/global/list/surgery_steps = list() //list of all surgery steps |BS12
|
||||
var/global/list/side_effects = list() //list of all medical sideeffects types by thier names |BS12
|
||||
var/global/list/mechas_list = list() //list of all mechs. Used by hostile mobs target tracking.
|
||||
|
||||
//Languages/species/whitelist.
|
||||
@@ -75,6 +76,13 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al
|
||||
surgery_steps += S
|
||||
sort_surgeries()
|
||||
|
||||
//Medical side effects. List all effects by their names
|
||||
paths = typesof(/datum/medical_effect)-/datum/medical_effect
|
||||
for(var/T in paths)
|
||||
var/datum/medical_effect/M = new T
|
||||
side_effects[M.name] = T
|
||||
|
||||
|
||||
//Languages and species.
|
||||
paths = typesof(/datum/language)-/datum/language
|
||||
for(var/T in paths)
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
if(modifiers["ctrl"])
|
||||
CtrlClickOn(A)
|
||||
return
|
||||
|
||||
|
||||
if(stat || paralysis || stunned || weakened)
|
||||
return
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
return
|
||||
|
||||
if(istype(loc,/obj/mecha))
|
||||
if(!locate(/turf) in list(A,A.loc)) // Prevents inventory from being drilled
|
||||
return
|
||||
var/obj/mecha/M = loc
|
||||
return M.click_action(A,src)
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
return 1
|
||||
if(usr.next_move >= world.time)
|
||||
return
|
||||
usr.next_move = world.time + 10
|
||||
usr.next_move = world.time + 6
|
||||
|
||||
if(usr.stat || usr.restrained() || usr.stunned || usr.lying)
|
||||
return 1
|
||||
@@ -86,6 +86,8 @@
|
||||
return 1
|
||||
if(usr.stat || usr.paralysis || usr.stunned || usr.weakened)
|
||||
return 1
|
||||
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
|
||||
return 1
|
||||
if(master)
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
if(I)
|
||||
@@ -207,6 +209,8 @@
|
||||
usr.hud_used.hidden_inventory_update()
|
||||
|
||||
if("equip")
|
||||
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
|
||||
return 1
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/H = usr
|
||||
H.quick_equip()
|
||||
@@ -421,6 +425,8 @@
|
||||
return 1
|
||||
if(usr.stat || usr.paralysis || usr.stunned || usr.weakened)
|
||||
return 1
|
||||
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
|
||||
return 1
|
||||
switch(name)
|
||||
if("r_hand")
|
||||
if(iscarbon(usr))
|
||||
|
||||
@@ -26,7 +26,9 @@
|
||||
if (!istype(M)) // not sure if this is the right thing...
|
||||
return
|
||||
var/messagesource = M
|
||||
|
||||
if (can_operate(M)) //Checks if mob is lying down on table for surgery
|
||||
if (do_surgery(M,user,src))
|
||||
return
|
||||
if (istype(M,/mob/living/carbon/brain))
|
||||
messagesource = M:container
|
||||
if (hitsound)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
var/vote_delay = 6000 // minimum time between voting sessions (deciseconds, 10 minute default)
|
||||
var/vote_period = 600 // length of voting period (deciseconds, default 1 minute)
|
||||
var/vote_autotransfer_initial = 108000 // Length of time before the first autotransfer vote is called
|
||||
var/vote_autotransfer_interval = 3600 // length of time before next sequential autotransfer vote
|
||||
var/vote_autotransfer_interval = 36000 // length of time before next sequential autotransfer vote
|
||||
var/vote_no_default = 0 // vote does not default to nochange/norestart (tbi)
|
||||
var/vote_no_dead = 0 // dead people can't vote (tbi)
|
||||
// var/enable_authentication = 0 // goon authentication
|
||||
@@ -43,7 +43,8 @@
|
||||
var/Tickcomp = 0
|
||||
var/socket_talk = 0 // use socket_talk to communicate with other processes
|
||||
var/list/resource_urls = null
|
||||
|
||||
var/antag_hud_allowed = 0 // Ghosts can turn on Antagovision to see a HUD of who is the bad guys this round.
|
||||
var/antag_hud_restricted = 0 // Ghosts that turn on Antagovision cannot rejoin the round.
|
||||
var/list/mode_names = list()
|
||||
var/list/modes = list() // allowed modes
|
||||
var/list/votable_modes = list() // votable modes
|
||||
@@ -385,6 +386,11 @@
|
||||
if("ticklag")
|
||||
Ticklag = text2num(value)
|
||||
|
||||
if("allow_antag_hud")
|
||||
config.antag_hud_allowed = 1
|
||||
if("antag_hud_restricted")
|
||||
config.antag_hud_restricted = 1
|
||||
|
||||
if("socket_talk")
|
||||
socket_talk = text2num(value)
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ datum/controller/vote
|
||||
|
||||
proc/autotransfer()
|
||||
initiate_vote("crew_transfer","the server")
|
||||
log_debug("The server has called an Autotransfer")
|
||||
|
||||
|
||||
proc/reset()
|
||||
@@ -206,14 +207,16 @@ datum/controller/vote
|
||||
return 0
|
||||
choices.Add(config.votable_modes)
|
||||
if("crew_transfer")
|
||||
if(check_rights(R_ADMIN) || check_rights(R_MOD))
|
||||
if(check_rights(R_ADMIN|R_MOD, 0))
|
||||
question = "End the shift?"
|
||||
choices.Add("Initiate Crew Transfer", "Continue The Round")
|
||||
else
|
||||
if (get_security_level() == "red" || get_security_level() == "delta")
|
||||
initiator_key << "The current alert status is too high to call for a crew transfer!"
|
||||
return 0
|
||||
if(ticker.current_state <= 2)
|
||||
return 0
|
||||
initiator_key << "The crew transfer button has been disabled!"
|
||||
question = "End the shift?"
|
||||
choices.Add("Initiate Crew Transfer", "Continue The Round")
|
||||
if("custom")
|
||||
|
||||
@@ -173,11 +173,11 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
|
||||
sparks.start()
|
||||
if(smoke_spread)
|
||||
if(smoke_spread == 1)
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
|
||||
smoke.set_up(smoke_amt, 0, location) //no idea what the 0 is
|
||||
smoke.start()
|
||||
else if(smoke_spread == 2)
|
||||
var/datum/effect/effect/system/bad_smoke_spread/smoke = new /datum/effect/effect/system/bad_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/bad/smoke = new /datum/effect/effect/system/smoke_spread/bad()
|
||||
smoke.set_up(smoke_amt, 0, location) //no idea what the 0 is
|
||||
smoke.start()
|
||||
|
||||
|
||||
@@ -456,6 +456,14 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
containername = "fuel tank crate"
|
||||
group = "Engineering"
|
||||
|
||||
/datum/supply_packs/coolanttank
|
||||
name = "Coolant tank crate"
|
||||
contains = list(/obj/structure/reagent_dispensers/coolanttank)
|
||||
cost = 16
|
||||
containertype = /obj/structure/largecrate
|
||||
containername = "coolant tank crate"
|
||||
group = "Medical / Science"
|
||||
|
||||
/datum/supply_packs/solar
|
||||
name = "Solar Pack crate"
|
||||
contains = list(/obj/item/solar_assembly,
|
||||
@@ -814,7 +822,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
contains = list(/obj/item/seeds/bloodtomatoseed,
|
||||
/obj/item/weapon/storage/pill_bottle/zoom,
|
||||
/obj/item/weapon/storage/pill_bottle/happy,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe)
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/pwine)
|
||||
|
||||
name = "Contraband crate"
|
||||
cost = 30
|
||||
@@ -945,6 +953,25 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
group = "Engineering"
|
||||
access = access_ce
|
||||
|
||||
/datum/supply_packs/smbig
|
||||
name = "Supermatter Core"
|
||||
contains = list(/obj/machinery/power/supermatter)
|
||||
cost = 50
|
||||
containertype = /obj/structure/closet/crate/secure/plasma
|
||||
containername = "Supermatter crate (CAUTIION)"
|
||||
access = access_ce
|
||||
group = "Engineering"
|
||||
|
||||
|
||||
/datum/supply_packs/smsmall
|
||||
name = "Supermatter Shard"
|
||||
contains = list(/obj/machinery/power/supermatter/shard)
|
||||
cost = 25
|
||||
containertype = /obj/structure/closet/crate/secure/plasma
|
||||
containername = "Supermatter crate (CAUTIION)"
|
||||
access = access_ce
|
||||
group = "Engineering"
|
||||
|
||||
/datum/supply_packs/shield_cap
|
||||
contains = list(/obj/item/weapon/circuitboard/shield_cap)
|
||||
name = "Experimental shield capacitor circuitry"
|
||||
@@ -997,7 +1024,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
containername = "Disposal Dispenser Crate"
|
||||
group = "Engineering"
|
||||
access = access_atmospherics
|
||||
|
||||
|
||||
/datum/supply_packs/bee_keeper
|
||||
name = "Beekeeping Crate"
|
||||
contains = list(/obj/item/beezeez,
|
||||
|
||||
@@ -132,6 +132,40 @@
|
||||
plant_type = 0
|
||||
growthstages = 1
|
||||
|
||||
/obj/item/seeds/shandseed
|
||||
name = "pack of s'rendarr's hand seeds"
|
||||
desc = "These seeds grow into a helpful herb called S'Rendarr's Hand, native to Ahdomai."
|
||||
icon_state = "seed-shand"
|
||||
mypath = "/obj/item/seeds/shandseed"
|
||||
species = "shand"
|
||||
plantname = "S'Rendarr's Hand"
|
||||
productname = "/obj/item/stack/medical/bruise_pack/tajaran"
|
||||
lifespan = 50
|
||||
endurance = 25
|
||||
maturation = 3
|
||||
production = 5
|
||||
yield = 4
|
||||
potency = 10
|
||||
plant_type = 0
|
||||
growthstages = 3
|
||||
|
||||
/obj/item/seeds/mtearseed
|
||||
name = "pack of messa's tear seeds"
|
||||
desc = "These seeds grow into a helpful herb called Messa's Tear, native to Ahdomai."
|
||||
icon_state = "seed-mtear"
|
||||
mypath = "/obj/item/seeds/mtearseed"
|
||||
species = "mtear"
|
||||
plantname = "Messa's Tear"
|
||||
productname = "/obj/item/stack/medical/ointment/tajaran"
|
||||
lifespan = 50
|
||||
endurance = 25
|
||||
maturation = 3
|
||||
production = 5
|
||||
yield = 4
|
||||
potency = 10
|
||||
plant_type = 0
|
||||
growthstages = 3
|
||||
|
||||
/obj/item/seeds/berryseed
|
||||
name = "pack of berry seeds"
|
||||
desc = "These seeds grow into berry bushes."
|
||||
|
||||
@@ -25,75 +25,6 @@
|
||||
flags = TABLEPASS
|
||||
w_class = 3.0
|
||||
|
||||
|
||||
/obj/item/weapon/spacecash
|
||||
name = "1 credit chip"
|
||||
desc = "It's worth 1 credit."
|
||||
gender = PLURAL
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "spacecash"
|
||||
opacity = 0
|
||||
density = 0
|
||||
anchored = 0.0
|
||||
force = 1.0
|
||||
throwforce = 1.0
|
||||
throw_speed = 1
|
||||
throw_range = 2
|
||||
w_class = 1.0
|
||||
var/access = list()
|
||||
access = access_crate_cash
|
||||
var/worth = 1
|
||||
|
||||
/obj/item/weapon/spacecash/c10
|
||||
name = "10 credit chip"
|
||||
icon_state = "spacecash10"
|
||||
access = access_crate_cash
|
||||
desc = "It's worth 10 credits."
|
||||
worth = 10
|
||||
|
||||
/obj/item/weapon/spacecash/c20
|
||||
name = "20 credit chip"
|
||||
icon_state = "spacecash20"
|
||||
access = access_crate_cash
|
||||
desc = "It's worth 20 credits."
|
||||
worth = 20
|
||||
|
||||
/obj/item/weapon/spacecash/c50
|
||||
name = "50 credit chip"
|
||||
icon_state = "spacecash50"
|
||||
access = access_crate_cash
|
||||
desc = "It's worth 50 credits."
|
||||
worth = 50
|
||||
|
||||
/obj/item/weapon/spacecash/c100
|
||||
name = "100 credit chip"
|
||||
icon_state = "spacecash100"
|
||||
access = access_crate_cash
|
||||
desc = "It's worth 100 credits."
|
||||
worth = 100
|
||||
|
||||
/obj/item/weapon/spacecash/c200
|
||||
name = "200 credit chip"
|
||||
icon_state = "spacecash200"
|
||||
access = access_crate_cash
|
||||
desc = "It's worth 200 credits."
|
||||
worth = 200
|
||||
|
||||
/obj/item/weapon/spacecash/c500
|
||||
name = "500 credit chip"
|
||||
icon_state = "spacecash500"
|
||||
access = access_crate_cash
|
||||
desc = "It's worth 500 credits."
|
||||
worth = 500
|
||||
|
||||
/obj/item/weapon/spacecash/c1000
|
||||
name = "1000 credit chip"
|
||||
icon_state = "spacecash1000"
|
||||
access = access_crate_cash
|
||||
desc = "It's worth 1000 credits."
|
||||
worth = 1000
|
||||
|
||||
|
||||
/obj/item/weapon/bananapeel
|
||||
name = "banana peel"
|
||||
desc = "A peel from a banana."
|
||||
|
||||
@@ -1322,6 +1322,10 @@ proc/process_ghost_teleport_locs()
|
||||
name = "\improper Miscellaneous Research"
|
||||
icon_state = "toxmisc"
|
||||
|
||||
/area/toxins/telesci
|
||||
name = "\improper Telescience Lab"
|
||||
icon_state = "toxmisc"
|
||||
|
||||
/area/toxins/server
|
||||
name = "\improper Server Room"
|
||||
icon_state = "server"
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
/obj/machinery/dna_scannernew/proc/eject_occupant()
|
||||
src.go_out()
|
||||
for(var/obj/O in src)
|
||||
if((!istype(O,/obj/item/weapon/circuitboard/clonescanner)) && (!istype(O,/obj/item/weapon/stock_parts)) && (!istype(O,/obj/item/weapon/cable_coil)))
|
||||
if((!istype(O,/obj/item/weapon/reagent_containers)) && (!istype(O,/obj/item/weapon/circuitboard/clonescanner)) && (!istype(O,/obj/item/weapon/stock_parts)) && (!istype(O,/obj/item/weapon/cable_coil)))
|
||||
O.loc = get_turf(src)//Ejects items that manage to get in there (exluding the components)
|
||||
if(!occupant)
|
||||
for(var/mob/M in src)//Failsafe so you can get mobs out
|
||||
|
||||
@@ -57,7 +57,7 @@ Not sure why this would be useful (it's not) but whatever. Ninjas need their smo
|
||||
if(!ninjacost(,2))
|
||||
var/mob/living/carbon/human/U = affecting
|
||||
U << "\blue There are <B>[s_bombs]</B> smoke bombs remaining."
|
||||
var/datum/effect/effect/system/bad_smoke_spread/smoke = new /datum/effect/effect/system/bad_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/bad/smoke = new /datum/effect/effect/system/smoke_spread/bad()
|
||||
smoke.set_up(10, 0, U.loc)
|
||||
smoke.start()
|
||||
playsound(U.loc, 'sound/effects/bamf.ogg', 50, 2)
|
||||
|
||||
@@ -40,8 +40,13 @@ var/global/datum/controller/gameticker/ticker
|
||||
|
||||
/datum/controller/gameticker/proc/pregame()
|
||||
login_music = pick(\
|
||||
/*'sound/music/halloween/skeletons.ogg',\
|
||||
'sound/music/halloween/halloween.ogg',\
|
||||
'sound/music/halloween/ghosts.ogg'*/
|
||||
'sound/music/space.ogg',\
|
||||
'sound/music/traitor.ogg',\
|
||||
'sound/music/title2.ogg',\
|
||||
'sound/music/clouds.s3m',\
|
||||
'sound/music/space_oddity.ogg') //Ground Control to Major Tom, this song is cool, what's going on?
|
||||
do
|
||||
pregame_timeleft = 180
|
||||
|
||||
@@ -8,6 +8,8 @@ var/bomb_set
|
||||
density = 1
|
||||
var/deployable = 0.0
|
||||
var/extended = 0.0
|
||||
var/lighthack = 0
|
||||
var/opened = 0.0
|
||||
var/timeleft = 60.0
|
||||
var/timing = 0.0
|
||||
var/r_code = "ADMIN"
|
||||
@@ -15,15 +17,36 @@ var/bomb_set
|
||||
var/yes_code = 0.0
|
||||
var/safety = 1.0
|
||||
var/obj/item/weapon/disk/nuclear/auth = null
|
||||
var/list/wires = list()
|
||||
var/light_wire
|
||||
var/safety_wire
|
||||
var/timing_wire
|
||||
var/removal_stage = 0 // 0 is no removal, 1 is covers removed, 2 is covers open,
|
||||
// 3 is sealant open, 4 is unwrenched, 5 is removed from bolts.
|
||||
flags = FPRINT
|
||||
use_power = 0
|
||||
|
||||
|
||||
|
||||
/obj/machinery/nuclearbomb/New()
|
||||
..()
|
||||
r_code = "[rand(10000, 99999.0)]"//Creates a random code upon object spawn.
|
||||
|
||||
src.wires["Red"] = 0
|
||||
src.wires["Blue"] = 0
|
||||
src.wires["Green"] = 0
|
||||
src.wires["Marigold"] = 0
|
||||
src.wires["Fuschia"] = 0
|
||||
src.wires["Black"] = 0
|
||||
src.wires["Pearl"] = 0
|
||||
var/list/w = list("Red","Blue","Green","Marigold","Black","Fuschia","Pearl")
|
||||
src.light_wire = pick(w)
|
||||
w -= src.light_wire
|
||||
src.timing_wire = pick(w)
|
||||
w -= src.timing_wire
|
||||
src.safety_wire = pick(w)
|
||||
w -= src.safety_wire
|
||||
|
||||
/obj/machinery/nuclearbomb/process()
|
||||
if (src.timing)
|
||||
bomb_set = 1 //So long as there is one nuke timing, it means one nuke is armed.
|
||||
@@ -36,6 +59,30 @@ var/bomb_set
|
||||
return
|
||||
|
||||
/obj/machinery/nuclearbomb/attackby(obj/item/weapon/O as obj, mob/user as mob)
|
||||
|
||||
if (istype(O, /obj/item/weapon/screwdriver))
|
||||
src.add_fingerprint(user)
|
||||
if (src.auth)
|
||||
if (src.opened == 0)
|
||||
src.opened = 1
|
||||
overlays += image(icon, "npanel_open")
|
||||
user << "You unscrew the control panel of [src]."
|
||||
|
||||
else
|
||||
src.opened = 0
|
||||
overlays -= image(icon, "npanel_open")
|
||||
user << "You screw the control panel of [src] back on."
|
||||
else
|
||||
if (src.opened == 0)
|
||||
user << "The [src] emits a buzzing noise, the panel staying locked in."
|
||||
if (src.opened == 1)
|
||||
src.opened = 0
|
||||
overlays -= image(icon, "npanel_open")
|
||||
user << "You screw the control panel of [src] back on."
|
||||
flick("nuclearbombc", src)
|
||||
|
||||
return
|
||||
|
||||
if (src.extended)
|
||||
if (istype(O, /obj/item/weapon/disk/nuclear))
|
||||
usr.drop_item()
|
||||
@@ -119,6 +166,8 @@ var/bomb_set
|
||||
|
||||
/obj/machinery/nuclearbomb/attack_hand(mob/user as mob)
|
||||
if (src.extended)
|
||||
if (src.opened)
|
||||
nukehack_win(user,50)
|
||||
user.set_machine(src)
|
||||
var/dat = text("<TT><B>Nuclear Fission Explosive</B><BR>\nAuth. Disk: <A href='?src=\ref[];auth=1'>[]</A><HR>", src, (src.auth ? "++++++++++" : "----------"))
|
||||
if (src.auth)
|
||||
@@ -145,11 +194,23 @@ var/bomb_set
|
||||
visible_message("\red With a steely snap, bolts slide out of [src] and anchor it to the flooring!")
|
||||
else
|
||||
visible_message("\red \The [src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.")
|
||||
flick("nuclearbombc", src)
|
||||
src.icon_state = "nuclearbomb1"
|
||||
if(!src.lighthack)
|
||||
flick("nuclearbombc", src)
|
||||
src.icon_state = "nuclearbomb1"
|
||||
src.extended = 1
|
||||
return
|
||||
|
||||
obj/machinery/nuclearbomb/proc/nukehack_win(mob/user as mob)
|
||||
var/dat as text
|
||||
dat += "<TT><B>Nuclear Fission Explosive</B><BR>\nNuclear Device Wires:</A><HR>"
|
||||
for(var/wire in src.wires)
|
||||
dat += text("[wire] Wire: <A href='?src=\ref[src];wire=[wire];act=wire'>[src.wires[wire] ? "Mend" : "Cut"]</A> <A href='?src=\ref[src];wire=[wire];act=pulse'>Pulse</A><BR>")
|
||||
dat += text("<HR>The device is [src.timing ? "shaking!" : "still"]<BR>")
|
||||
dat += text("The device is [src.safety ? "quiet" : "whirring"].<BR>")
|
||||
dat += text("The lights are [src.lighthack ? "static" : "functional"].<BR>")
|
||||
user << browse("<HTML><HEAD><TITLE>Bomb Defusion</TITLE></HEAD><BODY>[dat]</BODY></HTML>","window=nukebomb_hack")
|
||||
onclose(user, "nukebomb_hack")
|
||||
|
||||
/obj/machinery/nuclearbomb/verb/make_deployable()
|
||||
set category = "Object"
|
||||
set name = "Make Deployable"
|
||||
@@ -161,16 +222,57 @@ var/bomb_set
|
||||
else
|
||||
usr << "\red You adjust some panels to make [src] deployable."
|
||||
src.deployable = 1
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/nuclearbomb/Topic(href, href_list)
|
||||
..()
|
||||
if (!usr.canmove || usr.stat || usr.restrained())
|
||||
return
|
||||
if (!ishuman(usr))
|
||||
usr << "\red You don't have the dexterity to do this!"
|
||||
return 1
|
||||
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))))
|
||||
usr.set_machine(src)
|
||||
if(href_list["act"])
|
||||
var/temp_wire = href_list["wire"]
|
||||
if(href_list["act"] == "pulse")
|
||||
if (!istype(usr.get_active_hand(), /obj/item/device/multitool))
|
||||
usr << "You need a multitool!"
|
||||
else
|
||||
if(src.wires[temp_wire])
|
||||
usr << "You can't pulse a cut wire."
|
||||
else
|
||||
if(src.light_wire == temp_wire)
|
||||
src.lighthack = !src.lighthack
|
||||
spawn(100) src.lighthack = !src.lighthack
|
||||
if(src.timing_wire == temp_wire)
|
||||
if(src.timing)
|
||||
explode()
|
||||
if(src.safety_wire == temp_wire)
|
||||
src.safety = !src.safety
|
||||
spawn(100) src.safety = !src.safety
|
||||
if(src.safety == 1)
|
||||
visible_message("\blue The [src] quiets down.")
|
||||
if(!src.lighthack)
|
||||
if (src.icon_state == "nuclearbomb2")
|
||||
src.icon_state = "nuclearbomb1"
|
||||
else
|
||||
visible_message("\blue The [src] emits a quiet whirling noise!")
|
||||
if(href_list["act"] == "wire")
|
||||
if (!istype(usr.get_active_hand(), /obj/item/weapon/wirecutters))
|
||||
usr << "You need wirecutters!"
|
||||
else
|
||||
wires[temp_wire] = !wires[temp_wire]
|
||||
if(src.safety_wire == temp_wire)
|
||||
if(src.timing)
|
||||
explode()
|
||||
if(src.timing_wire == temp_wire)
|
||||
if(!src.lighthack)
|
||||
if (src.icon_state == "nuclearbomb2")
|
||||
src.icon_state = "nuclearbomb1"
|
||||
src.timing = 0
|
||||
bomb_set = 0
|
||||
if(src.light_wire == temp_wire)
|
||||
src.lighthack = !src.lighthack
|
||||
|
||||
if (href_list["auth"])
|
||||
if (src.auth)
|
||||
src.auth.loc = src.loc
|
||||
@@ -211,14 +313,16 @@ var/bomb_set
|
||||
return
|
||||
src.timing = !( src.timing )
|
||||
if (src.timing)
|
||||
src.icon_state = "nuclearbomb2"
|
||||
if(!src.lighthack)
|
||||
src.icon_state = "nuclearbomb2"
|
||||
if(!src.safety)
|
||||
bomb_set = 1//There can still be issues with this reseting when there are multiple bombs. Not a big deal tho for Nuke/N
|
||||
else
|
||||
bomb_set = 0
|
||||
else
|
||||
src.icon_state = "nuclearbomb1"
|
||||
bomb_set = 0
|
||||
if(!src.lighthack)
|
||||
src.icon_state = "nuclearbomb1"
|
||||
if (href_list["safety"])
|
||||
src.safety = !( src.safety )
|
||||
if(safety)
|
||||
@@ -266,7 +370,8 @@ var/bomb_set
|
||||
src.timing = -1.0
|
||||
src.yes_code = 0
|
||||
src.safety = 1
|
||||
src.icon_state = "nuclearbomb3"
|
||||
if(!src.lighthack)
|
||||
src.icon_state = "nuclearbomb3"
|
||||
playsound(src,'sound/machines/Alarm.ogg',100,0,5)
|
||||
if (ticker && ticker.mode)
|
||||
ticker.mode.explosion_in_progress = 1
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
supervisors = "your laws and the AI" //Nodrak
|
||||
selection_color = "#ddffdd"
|
||||
minimal_player_age = 21
|
||||
alt_titles = list("Android", "Robot")
|
||||
|
||||
equip(var/mob/living/carbon/human/H)
|
||||
if(!H) return 0
|
||||
|
||||
+114
-44
@@ -12,6 +12,12 @@
|
||||
var/orient = "LEFT" // "RIGHT" changes the dir suffix to "-r"
|
||||
|
||||
|
||||
/obj/machinery/sleep_console/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/sleep_console/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
@@ -72,12 +78,25 @@
|
||||
if(occupant.reagents)
|
||||
for(var/chemical in connected.available_chemicals)
|
||||
dat += "[connected.available_chemicals[chemical]]: [occupant.reagents.get_reagent_amount(chemical)] units<br>"
|
||||
dat += "<HR><A href='?src=\ref[src];refresh=1'>Refresh meter readings each second</A><BR>"
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>Refresh Meter Readings</A><BR>"
|
||||
if(src.connected.beaker)
|
||||
dat += "<HR><A href='?src=\ref[src];removebeaker=1'>Remove Beaker</A><BR>"
|
||||
if(src.connected.filtering)
|
||||
dat += "<A href='?src=\ref[src];togglefilter=1'>Stop Dialysis</A><BR>"
|
||||
dat += text("Output Beaker has [] units of free space remaining<BR><HR>", src.connected.beaker.reagents.maximum_volume - src.connected.beaker.reagents.total_volume)
|
||||
else
|
||||
dat += "<HR><A href='?src=\ref[src];togglefilter=1'>Start Dialysis</A><BR>"
|
||||
dat += text("Output Beaker has [] units of free space remaining<BR><HR>", src.connected.beaker.reagents.maximum_volume - src.connected.beaker.reagents.total_volume)
|
||||
else
|
||||
dat += "<HR>No Dialysis Output Beaker is present.<BR><HR>"
|
||||
|
||||
for(var/chemical in connected.available_chemicals)
|
||||
dat += "Inject [connected.available_chemicals[chemical]]: "
|
||||
for(var/amount in connected.amounts)
|
||||
dat += "<a href ='?src=\ref[src];chemical=[chemical];amount=[amount]'>[amount] units</a> "
|
||||
dat += "<br>"
|
||||
dat += "<a href ='?src=\ref[src];chemical=[chemical];amount=[amount]'>[amount] units</a><br> "
|
||||
|
||||
|
||||
dat += "<HR><A href='?src=\ref[src];ejectify=1'>Eject Patient</A>"
|
||||
else
|
||||
dat += "The sleeper is empty."
|
||||
dat += text("<BR><BR><A href='?src=\ref[];mach_close=sleeper'>Close</A>", user)
|
||||
@@ -99,16 +118,21 @@
|
||||
src.connected.inject_chemical(usr,href_list["chemical"],text2num(href_list["amount"]))
|
||||
else
|
||||
usr << "\red \b This person is not in good enough condition for sleepers to be effective! Use another means of treatment, such as cryogenics!"
|
||||
src.updateUsrDialog()
|
||||
if (href_list["refresh"])
|
||||
src.updateUsrDialog()
|
||||
if (href_list["removebeaker"])
|
||||
src.connected.remove_beaker()
|
||||
src.updateUsrDialog()
|
||||
if (href_list["togglefilter"])
|
||||
src.connected.toggle_filter()
|
||||
src.updateUsrDialog()
|
||||
if (href_list["ejectify"])
|
||||
src.connected.eject()
|
||||
src.updateUsrDialog()
|
||||
src.add_fingerprint(usr)
|
||||
return
|
||||
|
||||
/obj/machinery/sleep_console/process()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/sleep_console/power_change()
|
||||
return
|
||||
@@ -131,13 +155,15 @@
|
||||
density = 1
|
||||
anchored = 1
|
||||
var/orient = "LEFT" // "RIGHT" changes the dir suffix to "-r"
|
||||
var/mob/living/occupant = null
|
||||
var/available_chemicals = list("inaprovaline" = "Inaprovaline", "stoxin" = "Soporific", "dermaline" = "Dermaline", "bicaridine" = "Bicaridine", "dexalin" = "Dexalin")
|
||||
var/mob/living/carbon/human/occupant = null
|
||||
var/available_chemicals = list("inaprovaline" = "Inaprovaline", "stoxin" = "Soporific", "paracetamol" = "Paracetamol", "anti_toxin" = "Dylovene", "dexalin" = "Dexalin")
|
||||
var/amounts = list(5, 10)
|
||||
|
||||
var/obj/item/weapon/reagent_containers/glass/beaker = null
|
||||
var/filtering = 0
|
||||
|
||||
New()
|
||||
..()
|
||||
beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large()
|
||||
spawn( 5 )
|
||||
if(orient == "RIGHT")
|
||||
icon_state = "sleeper_0-r"
|
||||
@@ -150,7 +176,14 @@
|
||||
|
||||
|
||||
process()
|
||||
src.updateDialog()
|
||||
if(filtering > 0)
|
||||
if(beaker)
|
||||
if(beaker.reagents.total_volume < beaker.reagents.maximum_volume)
|
||||
src.occupant.vessel.trans_to(beaker, 1)
|
||||
for(var/datum/reagent/x in src.occupant.reagents.reagent_list)
|
||||
src.occupant.reagents.trans_to(beaker, 3)
|
||||
src.occupant.vessel.trans_to(beaker, 1)
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
|
||||
@@ -162,47 +195,60 @@
|
||||
del(src)
|
||||
return
|
||||
|
||||
|
||||
attackby(obj/item/weapon/grab/G as obj, mob/user as mob)
|
||||
if((!( istype(G, /obj/item/weapon/grab)) || !( ismob(G.affecting))))
|
||||
return
|
||||
if(src.occupant)
|
||||
user << "\blue <B>The sleeper is already occupied!</B>"
|
||||
return
|
||||
|
||||
for(var/mob/living/carbon/slime/M in range(1,G.affecting))
|
||||
if(M.Victim == G.affecting)
|
||||
usr << "[G.affecting.name] will not fit into the sleeper because they have a slime latched onto their head."
|
||||
attackby(var/obj/item/weapon/G as obj, var/mob/user as mob)
|
||||
if(istype(G, /obj/item/weapon/reagent_containers/glass))
|
||||
if(!beaker)
|
||||
beaker = G
|
||||
user.drop_item()
|
||||
G.loc = src
|
||||
user.visible_message("[user] adds \a [G] to \the [src]!", "You add \a [G] to \the [src]!")
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
else
|
||||
user << "\red The sleeper has a beaker already."
|
||||
return
|
||||
|
||||
visible_message("[user] starts putting [G.affecting.name] into the sleeper.", 3)
|
||||
else if(istype(G, /obj/item/weapon/grab))
|
||||
if(!ismob(G:affecting))
|
||||
return
|
||||
|
||||
if(do_after(user, 20))
|
||||
if(src.occupant)
|
||||
user << "\blue <B>The sleeper is already occupied!</B>"
|
||||
return
|
||||
if(!G || !G.affecting) return
|
||||
var/mob/M = G.affecting
|
||||
if(M.client)
|
||||
M.client.perspective = EYE_PERSPECTIVE
|
||||
M.client.eye = src
|
||||
M.loc = src
|
||||
src.occupant = M
|
||||
src.icon_state = "sleeper_1"
|
||||
if(orient == "RIGHT")
|
||||
icon_state = "sleeper_1-r"
|
||||
|
||||
M << "\blue <b>You feel cool air surround you. You go numb as your senses turn inward.</b>"
|
||||
for(var/mob/living/carbon/slime/M in range(1,G:affecting))
|
||||
if(M.Victim == G:affecting)
|
||||
usr << "[G:affecting.name] will not fit into the sleeper because they have a slime latched onto their head."
|
||||
return
|
||||
|
||||
for(var/obj/O in src)
|
||||
O.loc = src.loc
|
||||
src.add_fingerprint(user)
|
||||
del(G)
|
||||
visible_message("[user] starts putting [G:affecting:name] into the sleeper.", 3)
|
||||
|
||||
if(do_after(user, 20))
|
||||
if(src.occupant)
|
||||
user << "\blue <B>The sleeper is already occupied!</B>"
|
||||
return
|
||||
if(!G || !G:affecting) return
|
||||
var/mob/M = G:affecting
|
||||
if(M.client)
|
||||
M.client.perspective = EYE_PERSPECTIVE
|
||||
M.client.eye = src
|
||||
M.loc = src
|
||||
src.occupant = M
|
||||
src.icon_state = "sleeper_1"
|
||||
if(orient == "RIGHT")
|
||||
icon_state = "sleeper_1-r"
|
||||
|
||||
M << "\blue <b>You feel cool air surround you. You go numb as your senses turn inward.</b>"
|
||||
|
||||
src.add_fingerprint(user)
|
||||
del(G)
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
ex_act(severity)
|
||||
if(filtering)
|
||||
toggle_filter()
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
for(var/atom/movable/A as mob|obj in src)
|
||||
@@ -226,6 +272,8 @@
|
||||
return
|
||||
return
|
||||
emp_act(severity)
|
||||
if(filtering)
|
||||
toggle_filter()
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
..(severity)
|
||||
return
|
||||
@@ -250,13 +298,17 @@
|
||||
if (M:reagents.get_reagent_amount("inaprovaline") < 5)
|
||||
M:reagents.add_reagent("inaprovaline", 5)
|
||||
return
|
||||
|
||||
proc/toggle_filter()
|
||||
if(filtering)
|
||||
filtering = 0
|
||||
else
|
||||
filtering = 1
|
||||
|
||||
proc/go_out()
|
||||
if(filtering)
|
||||
toggle_filter()
|
||||
if(!src.occupant)
|
||||
return
|
||||
for(var/obj/O in src)
|
||||
O.loc = src.loc
|
||||
if(src.occupant.client)
|
||||
src.occupant.client.eye = src.occupant.client.mob
|
||||
src.occupant.client.perspective = MOB_PERSPECTIVE
|
||||
@@ -297,6 +349,10 @@
|
||||
user << text("[]\t -Burn Severity %: []", (src.occupant.getFireLoss() < 60 ? "\blue " : "\red "), src.occupant.getFireLoss())
|
||||
user << "\blue Expected time till occupant can safely awake: (note: If health is below 20% these times are inaccurate)"
|
||||
user << text("\blue \t [] second\s (if around 1 or 2 the sleeper is keeping them asleep.)", src.occupant.paralysis / 5)
|
||||
if(src.beaker)
|
||||
user << text("\blue \t Dialysis Output Beaker has [] of free space remaining.", src.beaker.reagents.maximum_volume - src.beaker.reagents.total_volume)
|
||||
else
|
||||
user << "\blue No Dialysis Output Beaker loaded."
|
||||
else
|
||||
user << "\blue There is no one inside!"
|
||||
return
|
||||
@@ -315,6 +371,18 @@
|
||||
add_fingerprint(usr)
|
||||
return
|
||||
|
||||
verb/remove_beaker()
|
||||
set name = "Remove Beaker"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
if(usr.stat != 0)
|
||||
return
|
||||
if(beaker)
|
||||
filtering = 0
|
||||
beaker.loc = usr.loc
|
||||
beaker = null
|
||||
add_fingerprint(usr)
|
||||
return
|
||||
|
||||
verb/move_inside()
|
||||
set name = "Enter Sleeper"
|
||||
@@ -346,8 +414,10 @@
|
||||
if(orient == "RIGHT")
|
||||
icon_state = "sleeper_1-r"
|
||||
|
||||
usr << "\blue <b>You feel cool air surround you. You go numb as your senses turn inward.</b>"
|
||||
|
||||
for(var/obj/O in src)
|
||||
del(O)
|
||||
src.add_fingerprint(usr)
|
||||
return
|
||||
return
|
||||
return
|
||||
|
||||
@@ -281,6 +281,7 @@
|
||||
var/infected = ""
|
||||
var/imp = ""
|
||||
var/bled = ""
|
||||
var/robot = ""
|
||||
var/splint = ""
|
||||
var/internal_bleeding = ""
|
||||
var/lung_ruptured = ""
|
||||
@@ -295,6 +296,8 @@
|
||||
bled = "Bleeding:"
|
||||
if(e.status & ORGAN_BROKEN)
|
||||
AN = "[e.broken_description]:"
|
||||
if(e.status & ORGAN_ROBOT)
|
||||
robot = "Prosthetic:"
|
||||
if(e.open)
|
||||
open = "Open:"
|
||||
var/unknown_body = 0
|
||||
@@ -308,16 +311,25 @@
|
||||
if(!AN && !open && !infected & !imp)
|
||||
AN = "None:"
|
||||
if(!(e.status & ORGAN_DESTROYED))
|
||||
dat += "<td>[e.display_name]</td><td>[e.burn_dam]</td><td>[e.brute_dam]</td><td>[bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured]</td>"
|
||||
dat += "<td>[e.display_name]</td><td>[e.burn_dam]</td><td>[e.brute_dam]</td><td>[robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured]</td>"
|
||||
else
|
||||
dat += "<td>[e.display_name]</td><td>-</td><td>-</td><td>Not Found</td>"
|
||||
dat += "</tr>"
|
||||
for(var/organ_name in occupant.internal_organs)
|
||||
var/datum/organ/internal/i = occupant.internal_organs[organ_name]
|
||||
var/mech = ""
|
||||
if(i.robotic == 1)
|
||||
mech = "Assisted:"
|
||||
if(i.robotic == 2)
|
||||
mech = "Mechanical:"
|
||||
dat += "<tr>"
|
||||
dat += "<td>[i.name]</td><td>N/A</td><td>[i.damage]</td><td>None:</td>"
|
||||
dat += "<td>[i.name]</td><td>N/A</td><td>[i.damage]</td><td>None:[mech]</td><td></td>"
|
||||
dat += "</tr>"
|
||||
dat += "</table>"
|
||||
if(occupant.sdisabilities & BLIND)
|
||||
dat += text("<font color='red'>Cataracts detected.</font><BR>")
|
||||
if(occupant.sdisabilities & NEARSIGHTED)
|
||||
dat += text("<font color='red'>Retinal misalignment detected.</font><BR>")
|
||||
else
|
||||
dat += "\The [src] is empty."
|
||||
else
|
||||
|
||||
@@ -184,7 +184,7 @@
|
||||
var/datum/gas_mixture/gas
|
||||
gas = location.remove_air(0.25*environment.total_moles)
|
||||
var/heat_capacity = gas.heat_capacity()
|
||||
var/energy_used = max( abs( heat_capacity*(gas.temperature - target_temperature) ), MAX_ENERGY_CHANGE)
|
||||
var/energy_used = min( abs( heat_capacity*(gas.temperature - target_temperature) ), MAX_ENERGY_CHANGE)
|
||||
|
||||
//Use power. Assuming that each power unit represents 1000 watts....
|
||||
use_power(energy_used/1000, ENVIRON)
|
||||
@@ -1511,7 +1511,7 @@ FIRE ALARM
|
||||
pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
|
||||
pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0
|
||||
|
||||
if(z == 1)
|
||||
if(z == 1 || z == 5)
|
||||
if(security_level)
|
||||
src.overlays += image('icons/obj/monitors.dmi', "overlay_[get_security_level()]")
|
||||
else
|
||||
|
||||
@@ -28,6 +28,7 @@ var/global/list/autolathe_recipes = list( \
|
||||
new /obj/item/weapon/surgicaldrill(),\
|
||||
new /obj/item/weapon/retractor(),\
|
||||
new /obj/item/weapon/cautery(),\
|
||||
new /obj/item/weapon/hemostat(),\
|
||||
new /obj/item/weapon/reagent_containers/glass/beaker(), \
|
||||
new /obj/item/weapon/reagent_containers/glass/beaker/large(), \
|
||||
new /obj/item/weapon/reagent_containers/glass/beaker/vial(), \
|
||||
|
||||
@@ -298,6 +298,7 @@ text("<A href='?src=\ref[src];operation=oddbutton'>[src.oddbutton ? "Yes" : "No"
|
||||
target_types += /obj/effect/decal/cleanable/robot_debris
|
||||
target_types += /obj/effect/decal/cleanable/crayon
|
||||
target_types += /obj/effect/decal/cleanable/liquid_fuel
|
||||
target_types += /obj/effect/decal/cleanable/mucus
|
||||
|
||||
if(src.blood)
|
||||
target_types += /obj/effect/decal/cleanable/xenoblood/
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
var/mess = 0 //Need to clean out it if it's full of exploded clone.
|
||||
var/attempting = 0 //One clone attempt at a time thanks
|
||||
var/eject_wait = 0 //Don't eject them as soon as they are created fuckkk
|
||||
var/biomass = CLONE_BIOMASS
|
||||
var/biomass = CLONE_BIOMASS * 3
|
||||
|
||||
//The return of data disks?? Just for transferring between genetics machine/cloning machine.
|
||||
//TO-DO: Make the genetics machine accept them.
|
||||
|
||||
@@ -200,4 +200,10 @@
|
||||
name = "Engineering Cameras"
|
||||
desc = "Used to monitor fires and breaches."
|
||||
icon_state = "engineeringcameras"
|
||||
network = list("Engineering","Power Alarms","Atmosphere Alarms","Fire Alarms")
|
||||
network = list("Engineering","Power Alarms","Atmosphere Alarms","Fire Alarms")
|
||||
|
||||
/obj/machinery/computer/security/nuclear
|
||||
name = "Mission Monitor"
|
||||
desc = "Used to access the built-in cameras in helmets."
|
||||
icon_state = "syndicam"
|
||||
network = list("NUKE")
|
||||
@@ -152,7 +152,7 @@
|
||||
carddesc += "<input type='hidden' name='src' value='\ref[src]'>"
|
||||
carddesc += "<input type='hidden' name='choice' value='account'>"
|
||||
carddesc += "<b>Stored account number:</b> <input type='text' id='accountfield' name='account' value='[modify.associated_account_number]' style='width:250px; background-color:white;' onchange='markAccountRed()'>"
|
||||
carddesc += "<input type='submit' value='Rename' onclick='markAccountGreen()'>"
|
||||
carddesc += "<input type='submit' value='Modify' onclick='markAccountGreen()'>"
|
||||
carddesc += "</form>"
|
||||
|
||||
carddesc += "<b>Assignment:</b> "
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
for(var/x in verbs)
|
||||
verbs -= x
|
||||
set_broken()
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
|
||||
smoke.set_up(5, 0, src)
|
||||
smoke.start()
|
||||
return
|
||||
|
||||
@@ -79,13 +79,15 @@
|
||||
continue
|
||||
|
||||
O.Weaken(strength)
|
||||
if ((O.eye_stat > 15 && prob(O.eye_stat + 50)))
|
||||
flick("e_flash", O:flash)
|
||||
O.eye_stat += rand(1, 2)
|
||||
if (istype(O, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = O
|
||||
var/datum/organ/internal/eyes/E = H.internal_organs["eyes"]
|
||||
if ((E.damage > E.min_bruised_damage && prob(E.damage + 50)))
|
||||
flick("e_flash", O:flash)
|
||||
E.damage += rand(1, 5)
|
||||
else
|
||||
if(!O.blinded)
|
||||
flick("flash", O:flash)
|
||||
O.eye_stat += rand(0, 2)
|
||||
|
||||
|
||||
/obj/machinery/flasher/emp_act(severity)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/orange = "orangejuice",
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/lime = "limejuice",
|
||||
/obj/item/weapon/reagent_containers/food/snacks/watermelonslice = "watermelonjuice",
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/grapes = "grapejuice",
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/poisonberries = "poisonberryjuice",
|
||||
)
|
||||
|
||||
|
||||
@@ -148,6 +148,14 @@
|
||||
else if(istype(W, /obj/item/weapon/card) && currently_vending)
|
||||
var/obj/item/weapon/card/I = W
|
||||
scan_card(I)
|
||||
|
||||
else if(src.panel_open)
|
||||
|
||||
for(var/datum/data/vending_product/R in product_records)
|
||||
if(istype(W, R.product_path))
|
||||
stock(R, user)
|
||||
del(W)
|
||||
|
||||
else
|
||||
..()
|
||||
|
||||
@@ -192,12 +200,12 @@
|
||||
// Vend the item
|
||||
src.vend(src.currently_vending, usr)
|
||||
currently_vending = null
|
||||
else
|
||||
usr << "\icon[src]<span class='warning'>You don't have that much money!</span>"
|
||||
else
|
||||
usr << "\icon[src]<span class='warning'>Unable to access account. Check security settings and try again.</span>"
|
||||
usr << "\icon[src]<span class='warning'>You don't have that much money!</span>"
|
||||
else
|
||||
usr << "\icon[src]<span class='warning'>Unable to access vendor account. Please record the machine ID and call CentComm Support.</span>"
|
||||
usr << "\icon[src]<span class='warning'>Unable to access account. Check security settings and try again.</span>"
|
||||
else
|
||||
usr << "\icon[src]<span class='warning'>Unable to access vendor account. Please record the machine ID and call CentComm Support.</span>"
|
||||
|
||||
/obj/machinery/vending/attack_paw(mob/user as mob)
|
||||
return attack_hand(user)
|
||||
@@ -407,6 +415,13 @@
|
||||
|
||||
src.updateUsrDialog()
|
||||
|
||||
/obj/machinery/vending/proc/stock(var/datum/data/vending_product/R, var/mob/user)
|
||||
if(src.panel_open)
|
||||
user << "\blue You stock the [src] with \a [R.product_name]"
|
||||
R.amount++
|
||||
|
||||
src.updateUsrDialog()
|
||||
|
||||
/obj/machinery/vending/process()
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
@@ -594,7 +609,9 @@
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/tomatojuice = 4,/obj/item/weapon/reagent_containers/food/drinks/bottle/limejuice = 4,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/cream = 4,/obj/item/weapon/reagent_containers/food/drinks/tonic = 8,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/cola = 8, /obj/item/weapon/reagent_containers/food/drinks/sodawater = 15,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 30,/obj/item/weapon/reagent_containers/food/drinks/ice = 9)
|
||||
/obj/item/weapon/reagent_containers/food/drinks/drinkingglass = 30,/obj/item/weapon/reagent_containers/food/drinks/ice = 9,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/melonliquor = 2,/obj/item/weapon/reagent_containers/food/drinks/bottle/bluecuracao = 2,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe = 2,/obj/item/weapon/reagent_containers/food/drinks/bottle/grenadine = 5)
|
||||
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/tea = 10)
|
||||
vend_delay = 15
|
||||
product_slogans = "I hope nobody asks me for a bloody cup o' tea...;Alcohol is humanity's friend. Would you abandon a friend?;Quite delighted to serve you!;Is nobody thirsty on this station?"
|
||||
@@ -631,9 +648,9 @@
|
||||
/obj/item/weapon/reagent_containers/food/snacks/sosjerky = 6,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 6,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 6,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 6)
|
||||
contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 6)
|
||||
prices = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 20,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 30,/obj/item/weapon/reagent_containers/food/snacks/chips =25,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/sosjerky = 30,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 20,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 30,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 25)
|
||||
prices = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 1,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 5,/obj/item/weapon/reagent_containers/food/snacks/chips = 1,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/sosjerky = 2,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 1,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 1,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 1)
|
||||
|
||||
|
||||
|
||||
@@ -645,11 +662,13 @@
|
||||
product_ads = "Refreshing!;Hope you're thirsty!;Over 1 million drinks sold!;Thirsty? Why not cola?;Please, have a drink!;Drink up!;The best drinks in space."
|
||||
products = list(/obj/item/weapon/reagent_containers/food/drinks/cola = 10,/obj/item/weapon/reagent_containers/food/drinks/space_mountain_wind = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/dr_gibb = 10,/obj/item/weapon/reagent_containers/food/drinks/starkist = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/space_up = 10)
|
||||
/obj/item/weapon/reagent_containers/food/drinks/waterbottle = 10,/obj/item/weapon/reagent_containers/food/drinks/space_up = 10,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/iced_tea = 10, /obj/item/weapon/reagent_containers/food/drinks/grape_juice = 10)
|
||||
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/thirteenloko = 5)
|
||||
prices = list(/obj/item/weapon/reagent_containers/food/drinks/cola = 20,/obj/item/weapon/reagent_containers/food/drinks/space_mountain_wind = 20,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/dr_gibb = 20,/obj/item/weapon/reagent_containers/food/drinks/starkist = 20,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/space_up = 20)
|
||||
prices = list(/obj/item/weapon/reagent_containers/food/drinks/cola = 1,/obj/item/weapon/reagent_containers/food/drinks/space_mountain_wind = 1,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/dr_gibb = 1,/obj/item/weapon/reagent_containers/food/drinks/starkist = 1,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/waterbottle = 2,/obj/item/weapon/reagent_containers/food/drinks/space_up = 1,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/iced_tea = 1,/obj/item/weapon/reagent_containers/food/drinks/grape_juice = 1)
|
||||
|
||||
//This one's from bay12
|
||||
/obj/machinery/vending/cart
|
||||
@@ -673,7 +692,7 @@
|
||||
products = list(/obj/item/weapon/storage/fancy/cigarettes = 10,/obj/item/weapon/storage/box/matches = 10,/obj/item/weapon/lighter/random = 4)
|
||||
contraband = list(/obj/item/weapon/lighter/zippo = 4)
|
||||
premium = list(/obj/item/clothing/mask/cigarette/cigar/havana = 2)
|
||||
prices = list(/obj/item/weapon/storage/fancy/cigarettes = 60,/obj/item/weapon/storage/box/matches = 10,/obj/item/weapon/lighter/random = 60)
|
||||
prices = list(/obj/item/weapon/storage/fancy/cigarettes = 15,/obj/item/weapon/storage/box/matches = 1,/obj/item/weapon/lighter/random = 2)
|
||||
|
||||
|
||||
/obj/machinery/vending/medical
|
||||
@@ -741,7 +760,7 @@
|
||||
icon_deny = "nutri-deny"
|
||||
products = list(/obj/item/beezeez = 45,/obj/item/nutrient/ez = 35,/obj/item/nutrient/l4z = 25,/obj/item/nutrient/rh = 15,/obj/item/weapon/pestspray = 20,
|
||||
/obj/item/weapon/reagent_containers/syringe = 5,/obj/item/weapon/storage/bag/plants = 5)
|
||||
contraband = list(/obj/item/weapon/reagent_containers/glass/bottle/ammonia = 10,/obj/item/weapon/reagent_containers/glass/bottle/diethylamine = 5)
|
||||
premium = list(/obj/item/weapon/reagent_containers/glass/bottle/ammonia = 10,/obj/item/weapon/reagent_containers/glass/bottle/diethylamine = 5)
|
||||
|
||||
/obj/machinery/vending/hydroseeds
|
||||
name = "MegaSeed Servitor"
|
||||
@@ -753,10 +772,10 @@
|
||||
/obj/item/seeds/cornseed = 3, /obj/item/seeds/eggplantseed = 3, /obj/item/seeds/potatoseed = 3, /obj/item/seeds/replicapod = 3,/obj/item/seeds/soyaseed = 3,
|
||||
/obj/item/seeds/sunflowerseed = 3,/obj/item/seeds/tomatoseed = 3,/obj/item/seeds/towermycelium = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/appleseed = 3,
|
||||
/obj/item/seeds/poppyseed = 3,/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/whitebeetseed = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/limeseed = 3,
|
||||
/obj/item/seeds/lemonseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/cocoapodseed = 3,
|
||||
/obj/item/seeds/lemonseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/cocoapodseed = 3,/obj/item/seeds/plumpmycelium = 2,
|
||||
/obj/item/seeds/cabbageseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/plastiseed = 3,/obj/item/seeds/riceseed = 3)
|
||||
contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/nettleseed = 2,
|
||||
/obj/item/seeds/plumpmycelium = 2,/obj/item/seeds/reishimycelium = 2)
|
||||
contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/mtearseed = 2,
|
||||
/obj/item/seeds/nettleseed = 2,/obj/item/seeds/reishimycelium = 2,/obj/item/seeds/reishimycelium = 2,/obj/item/seeds/shandseed = 2,)
|
||||
premium = list(/obj/item/toy/waterflower = 1)
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
var/smoke = 5
|
||||
var/smoke_ready = 1
|
||||
var/smoke_cooldown = 100
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke_system = new
|
||||
var/datum/effect/effect/system/smoke_spread/smoke_system = new
|
||||
operation_req_access = list(access_cent_specops)
|
||||
wreckage = /obj/effect/decal/mecha_wreckage/marauder
|
||||
add_req_access = 0
|
||||
|
||||
@@ -149,11 +149,11 @@ obj/structure/sign/poster/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if("No")
|
||||
return
|
||||
|
||||
/obj/structure/sign/poster/proc/roll_and_drop(turf/loc)
|
||||
/obj/structure/sign/poster/proc/roll_and_drop(turf/newloc)
|
||||
var/obj/item/weapon/contraband/poster/P = new(src, serial_number)
|
||||
P.resulting_poster = src
|
||||
P.loc = loc
|
||||
loc = P
|
||||
P.loc = newloc
|
||||
src.loc = P
|
||||
|
||||
|
||||
//seperated to reduce code duplication. Moved here for ease of reference and to unclutter r_wall/attackby()
|
||||
|
||||
@@ -21,15 +21,6 @@ would spawn and follow the beaker, even if it is carried or thrown.
|
||||
flags = TABLEPASS
|
||||
mouse_opacity = 0
|
||||
|
||||
/obj/effect/effect/smoke
|
||||
name = "smoke"
|
||||
icon = 'icons/effects/water.dmi'
|
||||
icon_state = "smoke"
|
||||
opacity = 1
|
||||
anchored = 0.0
|
||||
mouse_opacity = 0
|
||||
var/amount = 8.0
|
||||
|
||||
/obj/effect/proc/delete()
|
||||
loc = null
|
||||
if(reagents)
|
||||
@@ -222,196 +213,186 @@ steam.start() -- spawns the effect
|
||||
/////////////////////////////////////////////
|
||||
|
||||
|
||||
/obj/effect/effect/harmless_smoke
|
||||
/obj/effect/effect/smoke
|
||||
name = "smoke"
|
||||
icon_state = "smoke"
|
||||
opacity = 1
|
||||
anchored = 0.0
|
||||
mouse_opacity = 0
|
||||
var/amount = 6.0
|
||||
var/time_to_live = 100
|
||||
|
||||
//Remove this bit to use the old smoke
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
|
||||
/obj/effect/effect/harmless_smoke/New()
|
||||
/obj/effect/effect/smoke/New()
|
||||
..()
|
||||
spawn (100)
|
||||
spawn (time_to_live)
|
||||
delete()
|
||||
return
|
||||
|
||||
/obj/effect/effect/harmless_smoke/Move()
|
||||
/obj/effect/effect/smoke/HasEntered(mob/living/carbon/M as mob )
|
||||
..()
|
||||
return
|
||||
|
||||
/datum/effect/effect/system/harmless_smoke_spread
|
||||
var/total_smoke = 0 // To stop it being spammed and lagging!
|
||||
var/direction
|
||||
|
||||
set_up(n = 5, c = 0, loca, direct)
|
||||
if(n > 10)
|
||||
n = 10
|
||||
number = n
|
||||
cardinals = c
|
||||
if(istype(loca, /turf/))
|
||||
location = loca
|
||||
else
|
||||
location = get_turf(loca)
|
||||
if(direct)
|
||||
direction = direct
|
||||
|
||||
|
||||
start()
|
||||
var/i = 0
|
||||
for(i=0, i<src.number, i++)
|
||||
if(src.total_smoke > 20)
|
||||
return
|
||||
spawn(0)
|
||||
if(holder)
|
||||
src.location = get_turf(holder)
|
||||
var/obj/effect/effect/harmless_smoke/smoke = new /obj/effect/effect/harmless_smoke(src.location)
|
||||
src.total_smoke++
|
||||
var/direction = src.direction
|
||||
if(!direction)
|
||||
if(src.cardinals)
|
||||
direction = pick(cardinal)
|
||||
else
|
||||
direction = pick(alldirs)
|
||||
for(i=0, i<pick(0,1,1,1,2,2,2,3), i++)
|
||||
sleep(10)
|
||||
step(smoke,direction)
|
||||
spawn(75+rand(10,30))
|
||||
smoke.delete()
|
||||
src.total_smoke--
|
||||
if(istype(M))
|
||||
affect(M)
|
||||
|
||||
/obj/effect/effect/smoke/proc/affect(var/mob/living/carbon/M)
|
||||
if (istype(M))
|
||||
return 0
|
||||
if (M.internal != null && M.wear_mask && (M.wear_mask.flags & MASKINTERNALS))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Bad smoke
|
||||
/////////////////////////////////////////////
|
||||
|
||||
/obj/effect/effect/bad_smoke
|
||||
name = "smoke"
|
||||
icon_state = "smoke"
|
||||
opacity = 1
|
||||
anchored = 0.0
|
||||
mouse_opacity = 0
|
||||
var/amount = 6.0
|
||||
//Remove this bit to use the old smoke
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
/obj/effect/effect/smoke/bad
|
||||
time_to_live = 200
|
||||
|
||||
/obj/effect/effect/bad_smoke/New()
|
||||
..()
|
||||
spawn (200+rand(10,30))
|
||||
delete()
|
||||
return
|
||||
|
||||
/obj/effect/effect/bad_smoke/Move()
|
||||
/obj/effect/effect/smoke/bad/Move()
|
||||
..()
|
||||
for(var/mob/living/carbon/M in get_turf(src))
|
||||
if (M.internal != null && M.wear_mask && (M.wear_mask.flags & MASKINTERNALS))
|
||||
else
|
||||
M.drop_item()
|
||||
M.adjustOxyLoss(1)
|
||||
if (M.coughedtime != 1)
|
||||
M.coughedtime = 1
|
||||
M.emote("cough")
|
||||
spawn ( 20 )
|
||||
M.coughedtime = 0
|
||||
return
|
||||
affect(M)
|
||||
|
||||
/obj/effect/effect/smoke/bad/affect(var/mob/living/carbon/M)
|
||||
if (!..())
|
||||
return 0
|
||||
M.drop_item()
|
||||
M.adjustOxyLoss(1)
|
||||
if (M.coughedtime != 1)
|
||||
M.coughedtime = 1
|
||||
M.emote("cough")
|
||||
spawn ( 20 )
|
||||
M.coughedtime = 0
|
||||
|
||||
/obj/effect/effect/bad_smoke/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
/obj/effect/effect/smoke/bad/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(air_group || (height==0)) return 1
|
||||
if(istype(mover, /obj/item/projectile/beam))
|
||||
var/obj/item/projectile/beam/B = mover
|
||||
B.damage = (B.damage/2)
|
||||
return 1
|
||||
/////////////////////////////////////////////
|
||||
// Sleep smoke
|
||||
/////////////////////////////////////////////
|
||||
|
||||
/obj/effect/effect/smoke/sleepy
|
||||
|
||||
/obj/effect/effect/bad_smoke/HasEntered(mob/living/carbon/M as mob )
|
||||
/obj/effect/effect/smoke/sleepy/Move()
|
||||
..()
|
||||
if(istype(M, /mob/living/carbon))
|
||||
if (M.internal != null && M.wear_mask && (M.wear_mask.flags & MASKINTERNALS))
|
||||
return
|
||||
else
|
||||
M.drop_item()
|
||||
M.adjustOxyLoss(1)
|
||||
if (M.coughedtime != 1)
|
||||
M.coughedtime = 1
|
||||
M.emote("cough")
|
||||
spawn ( 20 )
|
||||
M.coughedtime = 0
|
||||
for(var/mob/living/carbon/M in get_turf(src))
|
||||
affect(M)
|
||||
|
||||
/obj/effect/effect/smoke/sleepy/affect(mob/living/carbon/M as mob )
|
||||
if (!..())
|
||||
return 0
|
||||
|
||||
M.drop_item()
|
||||
M:sleeping += 1
|
||||
if (M.coughedtime != 1)
|
||||
M.coughedtime = 1
|
||||
M.emote("cough")
|
||||
spawn ( 20 )
|
||||
M.coughedtime = 0
|
||||
/////////////////////////////////////////////
|
||||
// Mustard Gas
|
||||
/////////////////////////////////////////////
|
||||
|
||||
|
||||
/obj/effect/effect/smoke/mustard
|
||||
name = "mustard gas"
|
||||
icon_state = "mustard"
|
||||
|
||||
/obj/effect/effect/smoke/mustard/Move()
|
||||
..()
|
||||
for(var/mob/living/carbon/human/R in get_turf(src))
|
||||
affect(R)
|
||||
|
||||
/obj/effect/effect/smoke/mustard/affect(var/mob/living/carbon/human/R)
|
||||
if (!..())
|
||||
return 0
|
||||
if (R.wear_suit != null)
|
||||
return 0
|
||||
|
||||
R.burn_skin(0.75)
|
||||
if (R.coughedtime != 1)
|
||||
R.coughedtime = 1
|
||||
R.emote("gasp")
|
||||
spawn (20)
|
||||
R.coughedtime = 0
|
||||
R.updatehealth()
|
||||
return
|
||||
|
||||
/datum/effect/effect/system/bad_smoke_spread
|
||||
/////////////////////////////////////////////
|
||||
// Smoke spread
|
||||
/////////////////////////////////////////////
|
||||
|
||||
/datum/effect/effect/system/smoke_spread
|
||||
var/total_smoke = 0 // To stop it being spammed and lagging!
|
||||
var/direction
|
||||
var/smoke_type = /obj/effect/effect/smoke
|
||||
|
||||
set_up(n = 5, c = 0, loca, direct)
|
||||
if(n > 20)
|
||||
n = 20
|
||||
number = n
|
||||
cardinals = c
|
||||
if(istype(loca, /turf/))
|
||||
location = loca
|
||||
else
|
||||
location = get_turf(loca)
|
||||
if(direct)
|
||||
direction = direct
|
||||
/datum/effect/effect/system/smoke_spread/set_up(n = 5, c = 0, loca, direct)
|
||||
if(n > 10)
|
||||
n = 10
|
||||
number = n
|
||||
cardinals = c
|
||||
if(istype(loca, /turf/))
|
||||
location = loca
|
||||
else
|
||||
location = get_turf(loca)
|
||||
if(direct)
|
||||
direction = direct
|
||||
|
||||
start()
|
||||
var/i = 0
|
||||
for(i=0, i<src.number, i++)
|
||||
if(src.total_smoke > 20)
|
||||
return
|
||||
spawn(0)
|
||||
if(holder)
|
||||
src.location = get_turf(holder)
|
||||
var/obj/effect/effect/bad_smoke/smoke = new /obj/effect/effect/bad_smoke(src.location)
|
||||
src.total_smoke++
|
||||
var/direction = src.direction
|
||||
if(!direction)
|
||||
if(src.cardinals)
|
||||
direction = pick(cardinal)
|
||||
else
|
||||
direction = pick(alldirs)
|
||||
for(i=0, i<pick(0,1,1,1,2,2,2,3), i++)
|
||||
sleep(10)
|
||||
step(smoke,direction)
|
||||
spawn(150+rand(10,30))
|
||||
smoke.delete()
|
||||
src.total_smoke--
|
||||
/datum/effect/effect/system/smoke_spread/start()
|
||||
var/i = 0
|
||||
for(i=0, i<src.number, i++)
|
||||
if(src.total_smoke > 20)
|
||||
return
|
||||
spawn(0)
|
||||
if(holder)
|
||||
src.location = get_turf(holder)
|
||||
var/obj/effect/effect/smoke/smoke = new smoke_type(src.location)
|
||||
src.total_smoke++
|
||||
var/direction = src.direction
|
||||
if(!direction)
|
||||
if(src.cardinals)
|
||||
direction = pick(cardinal)
|
||||
else
|
||||
direction = pick(alldirs)
|
||||
for(i=0, i<pick(0,1,1,1,2,2,2,3), i++)
|
||||
sleep(10)
|
||||
step(smoke,direction)
|
||||
spawn(smoke.time_to_live*0.75+rand(10,30))
|
||||
if (smoke) smoke.delete()
|
||||
src.total_smoke--
|
||||
|
||||
|
||||
/datum/effect/effect/system/smoke_spread/bad
|
||||
smoke_type = /obj/effect/effect/smoke/bad
|
||||
|
||||
/datum/effect/effect/system/smoke_spread/sleepy
|
||||
smoke_type = /obj/effect/effect/smoke/sleepy
|
||||
|
||||
|
||||
/datum/effect/effect/system/smoke_spread/mustard
|
||||
smoke_type = /obj/effect/effect/smoke/mustard
|
||||
/////////////////////////////////////////////
|
||||
// Chem smoke
|
||||
/////////////////////////////////////////////
|
||||
|
||||
|
||||
/obj/effect/effect/chem_smoke
|
||||
name = "smoke"
|
||||
opacity = 1
|
||||
anchored = 0.0
|
||||
mouse_opacity = 0
|
||||
var/amount = 6.0
|
||||
|
||||
/obj/effect/effect/smoke/chem
|
||||
icon = 'icons/effects/chemsmoke.dmi'
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
|
||||
/obj/effect/effect/chem_smoke/New()
|
||||
/obj/effect/effect/smoke/chem/New()
|
||||
..()
|
||||
var/datum/reagents/R = new/datum/reagents(500)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
|
||||
spawn (200+rand(10,30))
|
||||
delete()
|
||||
return
|
||||
|
||||
/obj/effect/effect/chem_smoke/Move()
|
||||
/obj/effect/effect/smoke/chem/Move()
|
||||
..()
|
||||
for(var/atom/A in view(2, src))
|
||||
if(reagents.has_reagent("radium")||reagents.has_reagent("uranium")||reagents.has_reagent("carbon")||reagents.has_reagent("thermite"))//Prevents unholy radium spam by reducing the number of 'greenglows' down to something reasonable -Sieve
|
||||
@@ -422,15 +403,11 @@ steam.start() -- spawns the effect
|
||||
|
||||
return
|
||||
|
||||
/obj/effect/effect/chem_smoke/HasEntered(mob/living/carbon/M as mob )
|
||||
..()
|
||||
/obj/effect/effect/smoke/chem/affect(mob/living/carbon/M as mob )
|
||||
reagents.reaction(M)
|
||||
|
||||
return
|
||||
|
||||
/datum/effect/effect/system/chem_smoke_spread
|
||||
var/total_smoke = 0 // To stop it being spammed and lagging!
|
||||
var/direction
|
||||
/datum/effect/effect/system/smoke_spread/chem
|
||||
smoke_type = /obj/effect/effect/smoke/chem
|
||||
var/obj/chemholder
|
||||
|
||||
New()
|
||||
@@ -487,7 +464,7 @@ steam.start() -- spawns the effect
|
||||
spawn(0)
|
||||
if(holder)
|
||||
src.location = get_turf(holder)
|
||||
var/obj/effect/effect/chem_smoke/smoke = new /obj/effect/effect/chem_smoke(src.location)
|
||||
var/obj/effect/effect/smoke/chem/smoke = new /obj/effect/effect/smoke/chem(src.location)
|
||||
src.total_smoke++
|
||||
var/direction = src.direction
|
||||
if(!direction)
|
||||
@@ -513,189 +490,6 @@ steam.start() -- spawns the effect
|
||||
smoke.delete()
|
||||
src.total_smoke--
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Sleep smoke
|
||||
/////////////////////////////////////////////
|
||||
|
||||
/obj/effect/effect/sleep_smoke
|
||||
name = "smoke"
|
||||
icon_state = "smoke"
|
||||
opacity = 1
|
||||
anchored = 0.0
|
||||
mouse_opacity = 0
|
||||
var/amount = 6.0
|
||||
//Remove this bit to use the old smoke
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
|
||||
/obj/effect/effect/sleep_smoke/New()
|
||||
..()
|
||||
spawn (200+rand(10,30))
|
||||
delete()
|
||||
return
|
||||
|
||||
/obj/effect/effect/sleep_smoke/Move()
|
||||
..()
|
||||
for(var/mob/living/carbon/M in get_turf(src))
|
||||
if (M.internal != null && M.wear_mask && (M.wear_mask.flags & MASKINTERNALS))
|
||||
// if (M.wear_suit, /obj/item/clothing/suit/wizrobe && (M.hat, /obj/item/clothing/head/wizard) && (M.shoes, /obj/item/clothing/shoes/sandal)) // I'll work on it later
|
||||
else
|
||||
M.drop_item()
|
||||
M:sleeping += 1
|
||||
if (M.coughedtime != 1)
|
||||
M.coughedtime = 1
|
||||
M.emote("cough")
|
||||
spawn ( 20 )
|
||||
M.coughedtime = 0
|
||||
return
|
||||
|
||||
/obj/effect/effect/sleep_smoke/HasEntered(mob/living/carbon/M as mob )
|
||||
..()
|
||||
if(istype(M, /mob/living/carbon))
|
||||
if (M.internal != null && M.wear_mask && (M.wear_mask.flags & MASKINTERNALS))
|
||||
// if (M.wear_suit, /obj/item/clothing/suit/wizrobe && (M.hat, /obj/item/clothing/head/wizard) && (M.shoes, /obj/item/clothing/shoes/sandal)) // Work on it later
|
||||
return
|
||||
else
|
||||
M.drop_item()
|
||||
M:sleeping += 1
|
||||
if (M.coughedtime != 1)
|
||||
M.coughedtime = 1
|
||||
M.emote("cough")
|
||||
spawn ( 20 )
|
||||
M.coughedtime = 0
|
||||
return
|
||||
|
||||
/datum/effect/effect/system/sleep_smoke_spread
|
||||
var/total_smoke = 0 // To stop it being spammed and lagging!
|
||||
var/direction
|
||||
|
||||
set_up(n = 5, c = 0, loca, direct)
|
||||
if(n > 20)
|
||||
n = 20
|
||||
number = n
|
||||
cardinals = c
|
||||
if(istype(loca, /turf/))
|
||||
location = loca
|
||||
else
|
||||
location = get_turf(loca)
|
||||
if(direct)
|
||||
direction = direct
|
||||
|
||||
|
||||
start()
|
||||
var/i = 0
|
||||
for(i=0, i<src.number, i++)
|
||||
if(src.total_smoke > 20)
|
||||
return
|
||||
spawn(0)
|
||||
if(holder)
|
||||
src.location = get_turf(holder)
|
||||
var/obj/effect/effect/sleep_smoke/smoke = new /obj/effect/effect/sleep_smoke(src.location)
|
||||
src.total_smoke++
|
||||
var/direction = src.direction
|
||||
if(!direction)
|
||||
if(src.cardinals)
|
||||
direction = pick(cardinal)
|
||||
else
|
||||
direction = pick(alldirs)
|
||||
for(i=0, i<pick(0,1,1,1,2,2,2,3), i++)
|
||||
sleep(10)
|
||||
step(smoke,direction)
|
||||
spawn(150+rand(10,30))
|
||||
smoke.delete()
|
||||
src.total_smoke--
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Mustard Gas
|
||||
/////////////////////////////////////////////
|
||||
|
||||
|
||||
/obj/effect/effect/mustard_gas
|
||||
name = "mustard gas"
|
||||
icon_state = "mustard"
|
||||
opacity = 1
|
||||
anchored = 0.0
|
||||
mouse_opacity = 0
|
||||
var/amount = 6.0
|
||||
|
||||
/obj/effect/effect/mustard_gas/New()
|
||||
..()
|
||||
spawn (100)
|
||||
del(src)
|
||||
return
|
||||
|
||||
/obj/effect/effect/mustard_gas/Move()
|
||||
..()
|
||||
for(var/mob/living/carbon/human/R in get_turf(src))
|
||||
if (R.internal != null && usr.wear_mask && (R.wear_mask.flags & MASKINTERNALS) && R.wear_suit != null && !istype(R.wear_suit, /obj/item/clothing/suit/storage/labcoat) && !istype(R.wear_suit, /obj/item/clothing/suit/straight_jacket) && !istype(R.wear_suit, /obj/item/clothing/suit/straight_jacket && !istype(R.wear_suit, /obj/item/clothing/suit/armor)))
|
||||
else
|
||||
R.burn_skin(0.75)
|
||||
if (R.coughedtime != 1)
|
||||
R.coughedtime = 1
|
||||
R.emote("gasp")
|
||||
spawn (20)
|
||||
R.coughedtime = 0
|
||||
R.updatehealth()
|
||||
return
|
||||
|
||||
/obj/effect/effect/mustard_gas/HasEntered(mob/living/carbon/human/R as mob )
|
||||
..()
|
||||
if (istype(R, /mob/living/carbon/human))
|
||||
if (R.internal != null && usr.wear_mask && (R.wear_mask.flags & MASKINTERNALS) && R.wear_suit != null && !istype(R.wear_suit, /obj/item/clothing/suit/storage/labcoat) && !istype(R.wear_suit, /obj/item/clothing/suit/straight_jacket) && !istype(R.wear_suit, /obj/item/clothing/suit/straight_jacket && !istype(R.wear_suit, /obj/item/clothing/suit/armor)))
|
||||
return
|
||||
R.burn_skin(0.75)
|
||||
if (R.coughedtime != 1)
|
||||
R.coughedtime = 1
|
||||
R.emote("gasp")
|
||||
spawn (20)
|
||||
R.coughedtime = 0
|
||||
R.updatehealth()
|
||||
return
|
||||
|
||||
/datum/effect/effect/system/mustard_gas_spread
|
||||
var/total_smoke = 0 // To stop it being spammed and lagging!
|
||||
var/direction
|
||||
|
||||
set_up(n = 5, c = 0, loca, direct)
|
||||
if(n > 20)
|
||||
n = 20
|
||||
number = n
|
||||
cardinals = c
|
||||
if(istype(loca, /turf/))
|
||||
location = loca
|
||||
else
|
||||
location = get_turf(loca)
|
||||
if(direct)
|
||||
direction = direct
|
||||
|
||||
start()
|
||||
var/i = 0
|
||||
for(i=0, i<src.number, i++)
|
||||
if(src.total_smoke > 20)
|
||||
return
|
||||
spawn(0)
|
||||
if(holder)
|
||||
src.location = get_turf(holder)
|
||||
var/obj/effect/effect/mustard_gas/smoke = new /obj/effect/effect/mustard_gas(src.location)
|
||||
src.total_smoke++
|
||||
var/direction = src.direction
|
||||
if(!direction)
|
||||
if(src.cardinals)
|
||||
direction = pick(cardinal)
|
||||
else
|
||||
direction = pick(alldirs)
|
||||
for(i=0, i<pick(0,1,1,1,2,2,2,3), i++)
|
||||
sleep(10)
|
||||
step(smoke,direction)
|
||||
spawn(100)
|
||||
del(smoke)
|
||||
src.total_smoke--
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//////// Attach an Ion trail to any object, that spawns when it moves (like for the jetpack)
|
||||
/// just pass in the object to attach it to in set_up
|
||||
|
||||
+16
-17
@@ -522,29 +522,28 @@
|
||||
"\red You stab yourself in the eyes with [src]!" \
|
||||
)
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
var/datum/organ/internal/eyes/eyes = H.internal_organs["eyes"]
|
||||
eyes.damage += rand(3,4)
|
||||
if(eyes.damage >= eyes.min_bruised_damage)
|
||||
if(M.stat != 2)
|
||||
if(eyes.robotic <= 1) //robot eyes bleeding might be a bit silly
|
||||
M << "\red Your eyes start to bleed profusely!"
|
||||
if(prob(50))
|
||||
if(M.stat != 2)
|
||||
M << "\red You drop what you're holding and clutch at your eyes!"
|
||||
M.drop_item()
|
||||
M.eye_blurry += 10
|
||||
M.Paralyse(1)
|
||||
M.Weaken(4)
|
||||
if (eyes.damage >= eyes.min_broken_damage)
|
||||
if(M.stat != 2)
|
||||
M << "\red You go blind!"
|
||||
var/datum/organ/external/affecting = M:get_organ("head")
|
||||
if(affecting.take_damage(7))
|
||||
M:UpdateDamageIcon()
|
||||
else
|
||||
M.take_organ_damage(7)
|
||||
M.eye_blurry += rand(3,4)
|
||||
M.eye_stat += rand(2,4)
|
||||
if (M.eye_stat >= 10)
|
||||
M.eye_blurry += 15+(0.1*M.eye_blurry)
|
||||
M.disabilities |= NEARSIGHTED
|
||||
if(M.stat != 2)
|
||||
M << "\red Your eyes start to bleed profusely!"
|
||||
if(prob(50))
|
||||
if(M.stat != 2)
|
||||
M << "\red You drop what you're holding and clutch at your eyes!"
|
||||
M.drop_item()
|
||||
M.eye_blurry += 10
|
||||
M.Paralyse(1)
|
||||
M.Weaken(4)
|
||||
if (prob(M.eye_stat - 10 + 1))
|
||||
if(M.stat != 2)
|
||||
M << "\red You go blind!"
|
||||
M.sdisabilities |= BLIND
|
||||
return
|
||||
|
||||
/obj/item/clean_blood()
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
if(M.stat == DEAD || M.sdisabilities & BLIND) //mob is dead or fully blind
|
||||
user << "<span class='notice'>[M] pupils does not react to the light!</span>"
|
||||
else if(XRAY in M.mutations) //mob has X-RAY vision
|
||||
flick("flash", M.flash) //Yes, you can still get flashed wit X-Ray.
|
||||
user << "<span class='notice'>[M] pupils give an eerie glow!</span>"
|
||||
else //they're okay!
|
||||
if(!M.blinded)
|
||||
|
||||
@@ -65,24 +65,31 @@
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/datum/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
|
||||
|
||||
if(!affecting.bandage())
|
||||
user << "\red The wounds on [M]'s [affecting.display_name] have already been bandaged."
|
||||
return 1
|
||||
if(affecting.open == 0)
|
||||
if(!affecting.bandage())
|
||||
user << "\red The wounds on [M]'s [affecting.display_name] have already been bandaged."
|
||||
return 1
|
||||
else
|
||||
for (var/datum/wound/W in affecting.wounds)
|
||||
if (W.internal)
|
||||
continue
|
||||
if (W.current_stage <= W.max_bleeding_stage)
|
||||
user.visible_message( "\blue [user] bandages [W.desc] on [M]'s [affecting.display_name].", \
|
||||
"\blue You bandage [W.desc] on [M]'s [affecting.display_name]." )
|
||||
//H.add_side_effect("Itch")
|
||||
else if (istype(W,/datum/wound/bruise))
|
||||
user.visible_message( "\blue [user] places bruise patch over [W.desc] on [M]'s [affecting.display_name].", \
|
||||
"\blue You place bruise patch over [W.desc] on [M]'s [affecting.display_name]." )
|
||||
else
|
||||
user.visible_message( "\blue [user] places bandaid over [W.desc] on [M]'s [affecting.display_name].", \
|
||||
"\blue You place bandaid over [W.desc] on [M]'s [affecting.display_name]." )
|
||||
use(1)
|
||||
else
|
||||
for (var/datum/wound/W in affecting.wounds)
|
||||
if (W.internal)
|
||||
continue
|
||||
if (W.current_stage <= W.max_bleeding_stage)
|
||||
user.visible_message( "\blue [user] bandages [W.desc] on [M]'s [affecting.display_name].", \
|
||||
"\blue You bandage [W.desc] on [M]'s [affecting.display_name]." )
|
||||
//H.add_side_effect("Itch")
|
||||
else if (istype(W,/datum/wound/bruise))
|
||||
user.visible_message( "\blue [user] places bruise patch over [W.desc] on [M]'s [affecting.display_name].", \
|
||||
"\blue You place bruise patch over [W.desc] on [M]'s [affecting.display_name]." )
|
||||
else
|
||||
user.visible_message( "\blue [user] places bandaid over [W.desc] on [M]'s [affecting.display_name].", \
|
||||
"\blue You place bandaid over [W.desc] on [M]'s [affecting.display_name]." )
|
||||
use(1)
|
||||
if (can_operate(H)) //Checks if mob is lying down on table for surgery
|
||||
if (do_surgery(H,user,src))
|
||||
return
|
||||
else
|
||||
user << "<span class='notice'>The [affecting.display_name] is cut open, you'll need more than a bandage!</span>"
|
||||
|
||||
/obj/item/stack/medical/ointment
|
||||
name = "ointment"
|
||||
@@ -101,30 +108,38 @@
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/datum/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
|
||||
|
||||
if(!affecting.salve())
|
||||
user << "\red The wounds on [M]'s [affecting.display_name] have already been salved."
|
||||
return 1
|
||||
if(affecting.open == 0)
|
||||
if(!affecting.salve())
|
||||
user << "\red The wounds on [M]'s [affecting.display_name] have already been salved."
|
||||
return 1
|
||||
else
|
||||
user.visible_message( "\blue [user] salves wounds on [M]'s [affecting.display_name].", \
|
||||
"\blue You salve wounds on [M]'s [affecting.display_name]." )
|
||||
use(1)
|
||||
else
|
||||
user.visible_message( "\blue [user] salves wounds on [M]'s [affecting.display_name].", \
|
||||
"\blue You salve wounds on [M]'s [affecting.display_name]." )
|
||||
use(1)
|
||||
if (can_operate(H)) //Checks if mob is lying down on table for surgery
|
||||
if (do_surgery(H,user,src))
|
||||
return
|
||||
else
|
||||
user << "<span class='notice'>The [affecting.display_name] is cut open, you'll need more than a bandage!</span>"
|
||||
|
||||
/obj/item/stack/medical/bruise_pack/tajaran
|
||||
name = "\improper S'rendarr's Hand leaf"
|
||||
singular_name = "S'rendarr's Hand leaf"
|
||||
desc = "A soft leaf that is rubbed on bruises."
|
||||
desc = "A poultice made of soft leaves that is rubbed on bruises."
|
||||
icon = 'icons/obj/harvest.dmi'
|
||||
icon_state = "cabbage"
|
||||
icon_state = "shandp"
|
||||
heal_brute = 7
|
||||
|
||||
/obj/item/stack/medical/ointment/tajaran
|
||||
name = "\improper Messa's Tear leaf"
|
||||
singular_name = "Messa's Tear leaf"
|
||||
desc = "A cold leaf that is rubbed on burns."
|
||||
name = "\improper Messa's Tear petals"
|
||||
singular_name = "Messa's Tear petals"
|
||||
desc = "A poultice made of cold, blue petals that is rubbed on burns."
|
||||
icon = 'icons/obj/harvest.dmi'
|
||||
icon_state = "ambrosiavulgaris"
|
||||
icon_state = "mtearp"
|
||||
heal_burn = 7
|
||||
|
||||
|
||||
/obj/item/stack/medical/advanced/bruise_pack
|
||||
name = "advanced trauma kit"
|
||||
singular_name = "advanced trauma kit"
|
||||
@@ -141,25 +156,32 @@
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/datum/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
|
||||
|
||||
if(!affecting.bandage())
|
||||
user << "\red The wounds on [M]'s [affecting.display_name] have already been treated."
|
||||
return 1
|
||||
if(affecting.open == 0)
|
||||
if(!affecting.bandage())
|
||||
user << "\red The wounds on [M]'s [affecting.display_name] have already been treated."
|
||||
return 1
|
||||
else
|
||||
for (var/datum/wound/W in affecting.wounds)
|
||||
if (W.internal)
|
||||
continue
|
||||
if (W.current_stage <= W.max_bleeding_stage)
|
||||
user.visible_message( "\blue [user] cleans [W.desc] on [M]'s [affecting.display_name] and seals edges with bioglue.", \
|
||||
"\blue You clean and seal [W.desc] on [M]'s [affecting.display_name]." )
|
||||
//H.add_side_effect("Itch")
|
||||
else if (istype(W,/datum/wound/bruise))
|
||||
user.visible_message( "\blue [user] places medicine patch over [W.desc] on [M]'s [affecting.display_name].", \
|
||||
"\blue You place medicine patch over [W.desc] on [M]'s [affecting.display_name]." )
|
||||
else
|
||||
user.visible_message( "\blue [user] smears some bioglue over [W.desc] on [M]'s [affecting.display_name].", \
|
||||
"\blue You smear some bioglue over [W.desc] on [M]'s [affecting.display_name]." )
|
||||
affecting.heal_damage(heal_brute,0)
|
||||
use(1)
|
||||
else
|
||||
for (var/datum/wound/W in affecting.wounds)
|
||||
if (W.internal)
|
||||
continue
|
||||
if (W.current_stage <= W.max_bleeding_stage)
|
||||
user.visible_message( "\blue [user] cleans [W.desc] on [M]'s [affecting.display_name] and seals edges with bioglue.", \
|
||||
"\blue You clean and seal [W.desc] on [M]'s [affecting.display_name]." )
|
||||
//H.add_side_effect("Itch")
|
||||
else if (istype(W,/datum/wound/bruise))
|
||||
user.visible_message( "\blue [user] places medicine patch over [W.desc] on [M]'s [affecting.display_name].", \
|
||||
"\blue You place medicine patch over [W.desc] on [M]'s [affecting.display_name]." )
|
||||
else
|
||||
user.visible_message( "\blue [user] smears some bioglue over [W.desc] on [M]'s [affecting.display_name].", \
|
||||
"\blue You smear some bioglue over [W.desc] on [M]'s [affecting.display_name]." )
|
||||
affecting.heal_damage(heal_brute,0)
|
||||
use(1)
|
||||
if (can_operate(H)) //Checks if mob is lying down on table for surgery
|
||||
if (do_surgery(H,user,src))
|
||||
return
|
||||
else
|
||||
user << "<span class='notice'>The [affecting.display_name] is cut open, you'll need more than a bandage!</span>"
|
||||
|
||||
/obj/item/stack/medical/advanced/ointment
|
||||
name = "advanced burn kit"
|
||||
@@ -178,14 +200,21 @@
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/datum/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
|
||||
|
||||
if(!affecting.salve())
|
||||
user << "\red The wounds on [M]'s [affecting.display_name] have already been salved."
|
||||
return 1
|
||||
if(affecting.open == 0)
|
||||
if(!affecting.salve())
|
||||
user << "\red The wounds on [M]'s [affecting.display_name] have already been salved."
|
||||
return 1
|
||||
else
|
||||
user.visible_message( "\blue [user] covers wounds on [M]'s [affecting.display_name] with regenerative membrane.", \
|
||||
"\blue You cover wounds on [M]'s [affecting.display_name] with regenerative membrane." )
|
||||
affecting.heal_damage(0,heal_burn)
|
||||
use(1)
|
||||
else
|
||||
user.visible_message( "\blue [user] covers wounds on [M]'s [affecting.display_name] with regenerative membrane.", \
|
||||
"\blue You cover wounds on [M]'s [affecting.display_name] with regenerative membrane." )
|
||||
affecting.heal_damage(0,heal_burn)
|
||||
use(1)
|
||||
if (can_operate(H)) //Checks if mob is lying down on table for surgery
|
||||
if (do_surgery(H,user,src))
|
||||
return
|
||||
else
|
||||
user << "<span class='notice'>The [affecting.display_name] is cut open, you'll need more than a bandage!</span>"
|
||||
|
||||
/obj/item/stack/medical/splint
|
||||
name = "medical splints"
|
||||
|
||||
@@ -26,12 +26,20 @@
|
||||
if (istype(M,/mob/living/carbon/human)) //Repairing robolimbs
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/datum/organ/external/S = H.get_organ(user.zone_sel.selecting)
|
||||
if (S && (S.status & ORGAN_ROBOT))
|
||||
if(S.get_damage())
|
||||
S.heal_damage(15, 15, robo_repair = 1)
|
||||
H.updatehealth()
|
||||
use(1)
|
||||
user.visible_message("<span class='notice'>\The [user] applies some nanite paste at[user != M ? " \the [M]'s" : " \the"][S.display_name] with \the [src].</span>",\
|
||||
"<span class='notice'>You apply some nanite paste at [user == M ? "your" : "[M]'s"] [S.display_name].</span>")
|
||||
|
||||
if(S.open == 1)
|
||||
if (S && (S.status & ORGAN_ROBOT))
|
||||
if(S.get_damage())
|
||||
S.heal_damage(15, 15, robo_repair = 1)
|
||||
H.updatehealth()
|
||||
use(1)
|
||||
user.visible_message("<span class='notice'>\The [user] applies some nanite paste at[user != M ? " \the [M]'s" : " \the"][S.display_name] with \the [src].</span>",\
|
||||
"<span class='notice'>You apply some nanite paste at [user == M ? "your" : "[M]'s"] [S.display_name].</span>")
|
||||
else
|
||||
user << "<span class='notice'>Nothing to fix here.</span>"
|
||||
else
|
||||
if (can_operate(H))
|
||||
if (do_surgery(H,user,src))
|
||||
return
|
||||
else
|
||||
user << "<span class='notice'>Nothing to fix here.</span>"
|
||||
user << "<span class='notice'>Nothing to fix in here.</span>"
|
||||
@@ -2,6 +2,8 @@
|
||||
* Contains:
|
||||
* Glass sheets
|
||||
* Reinforced glass sheets
|
||||
* Plasma Glass Sheets
|
||||
* Reinforced Plasma Glass Sheets (AKA Holy fuck strong windows)
|
||||
* Glass shards - TODO: Move this into code/game/object/item/weapons
|
||||
*/
|
||||
|
||||
@@ -15,6 +17,7 @@
|
||||
icon_state = "sheet-glass"
|
||||
g_amt = 3750
|
||||
origin_tech = "materials=1"
|
||||
var/created_window = /obj/structure/window/basic
|
||||
|
||||
|
||||
/obj/item/stack/sheet/glass/attack_self(mob/user as mob)
|
||||
@@ -81,9 +84,8 @@
|
||||
if(!found)
|
||||
dir_to_set = direction
|
||||
break
|
||||
|
||||
var/obj/structure/window/W
|
||||
W = new /obj/structure/window/basic( user.loc, 0 )
|
||||
W = new created_window( user.loc, 0 )
|
||||
W.dir = dir_to_set
|
||||
W.ini_dir = W.dir
|
||||
W.anchored = 0
|
||||
@@ -98,7 +100,7 @@
|
||||
user << "\red There is a window in the way."
|
||||
return 1
|
||||
var/obj/structure/window/W
|
||||
W = new /obj/structure/window/basic( user.loc, 0 )
|
||||
W = new created_window( user.loc, 0 )
|
||||
W.dir = SOUTHWEST
|
||||
W.ini_dir = SOUTHWEST
|
||||
W.anchored = 0
|
||||
@@ -293,3 +295,54 @@
|
||||
H.UpdateDamageIcon()
|
||||
H.updatehealth()
|
||||
..()
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Plasma Glass sheets
|
||||
*/
|
||||
/obj/item/stack/sheet/glass/plasmaglass
|
||||
name = "plasma glass"
|
||||
desc = "A very strong and very resistant sheet of a plasma-glass alloy."
|
||||
singular_name = "glass sheet"
|
||||
icon_state = "sheet-plasmaglass"
|
||||
g_amt = 7500
|
||||
origin_tech = "materials=3;plasma=2"
|
||||
created_window = /obj/structure/window/plasmabasic
|
||||
|
||||
/obj/item/stack/sheet/glass/plasmaglass/attack_self(mob/user as mob)
|
||||
construct_window(user)
|
||||
|
||||
/obj/item/stack/sheet/glass/plasmaglass/attackby(obj/item/W, mob/user)
|
||||
..()
|
||||
if( istype(W, /obj/item/stack/rods) )
|
||||
var/obj/item/stack/rods/V = W
|
||||
var/obj/item/stack/sheet/glass/plasmarglass/RG = new (user.loc)
|
||||
RG.add_fingerprint(user)
|
||||
RG.add_to_stacks(user)
|
||||
V.use(1)
|
||||
var/obj/item/stack/sheet/glass/G = src
|
||||
src = null
|
||||
var/replace = (user.get_inactive_hand()==G)
|
||||
G.use(1)
|
||||
if (!G && !RG && replace)
|
||||
user.put_in_hands(RG)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/*
|
||||
* Reinforced plasma glass sheets
|
||||
*/
|
||||
/obj/item/stack/sheet/glass/plasmarglass
|
||||
name = "reinforced plasma glass"
|
||||
desc = "Plasma glass which seems to have rods or something stuck in them."
|
||||
singular_name = "reinforced plasma glass sheet"
|
||||
icon_state = "sheet-plasmarglass"
|
||||
g_amt = 7500
|
||||
m_amt = 1875
|
||||
origin_tech = "materials=4;plasma=2"
|
||||
created_window = /obj/structure/window/plasmareinforced
|
||||
|
||||
/obj/item/stack/sheet/glass/plasmarglass/attack_self(mob/user as mob)
|
||||
construct_window(user)
|
||||
@@ -126,7 +126,7 @@ var/global/list/datum/stack_recipe/plasma_recipes = list ( \
|
||||
perunit = 2000
|
||||
|
||||
var/global/list/datum/stack_recipe/plastic_recipes = list ( \
|
||||
new/datum/stack_recipe("plastic crate", /obj/structure/closet/pcrate, 10, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("plastic crate", /obj/structure/closet/crate/plastic, 10, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("plastic ashtray", /obj/item/ashtray/plastic, 2, one_per_turf = 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("plastic fork", /obj/item/weapon/kitchen/utensil/pfork, 1, on_floor = 1), \
|
||||
new/datum/stack_recipe("plastic spoon", /obj/item/weapon/kitchen/utensil/pspoon, 1, on_floor = 1), \
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
icon_state = "id"
|
||||
item_state = "card-id"
|
||||
var/access = list()
|
||||
var/registered_name = null // The name registered_name on the card
|
||||
var/registered_name = "Unknown" // The name registered_name on the card
|
||||
slot_flags = SLOT_ID
|
||||
|
||||
var/blood_type = "\[UNSET\]"
|
||||
@@ -280,4 +280,4 @@
|
||||
assignment = "General"
|
||||
New()
|
||||
access = get_all_centcom_access()
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
//Flashing everyone
|
||||
if(eye_safety < 1)
|
||||
flick("e_flash", M.flash)
|
||||
M.eye_stat += rand(1, 3)
|
||||
M.Stun(2)
|
||||
M.Weaken(10)
|
||||
|
||||
@@ -80,13 +79,14 @@
|
||||
M.ear_deaf = max(M.ear_deaf,5)
|
||||
|
||||
//This really should be in mob not every check
|
||||
if (M.eye_stat >= 20)
|
||||
M << "\red Your eyes start to burn badly!"
|
||||
M.disabilities |= NEARSIGHTED
|
||||
if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang)))
|
||||
if (prob(M.eye_stat - 20 + 1))
|
||||
M << "\red You can't see anything!"
|
||||
M.sdisabilities |= BLIND
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
var/datum/organ/internal/eyes/E = H.internal_organs["eyes"]
|
||||
if (E.damage >= E.min_bruised_damage)
|
||||
M << "\red Your eyes start to burn badly!"
|
||||
if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang)))
|
||||
if (E.damage >= E.min_broken_damage)
|
||||
M << "\red You can't see anything!"
|
||||
if (M.ear_damage >= 15)
|
||||
M << "\red Your ears start to ring badly!"
|
||||
if(!banglet && !(istype(src , /obj/item/weapon/grenade/flashbang/clusterbang)))
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
item_state = "flashbang"
|
||||
flags = FPRINT | TABLEPASS
|
||||
slot_flags = SLOT_BELT
|
||||
var/datum/effect/effect/system/bad_smoke_spread/smoke
|
||||
var/datum/effect/effect/system/smoke_spread/bad/smoke
|
||||
|
||||
New()
|
||||
..()
|
||||
src.smoke = new /datum/effect/effect/system/bad_smoke_spread
|
||||
src.smoke = new /datum/effect/effect/system/smoke_spread/bad
|
||||
src.smoke.attach(src)
|
||||
|
||||
prime()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
/obj/item/weapon/implant/freedom
|
||||
name = "freedom"
|
||||
name = "freedom implant"
|
||||
desc = "Use this to escape from those evil Red Shirts."
|
||||
item_color = "r"
|
||||
var/activation_emote = "chuckle"
|
||||
|
||||
@@ -122,7 +122,8 @@
|
||||
<b>Step eight:</b> Put in the new, <b>full power cell</b> - if you don't have one, continue with step 15.<br>
|
||||
<b>Step nine:</b> Quickly put on a <b>Radiation suit.</b><br>
|
||||
<b>Step ten:</b> Check if the <b>singularity field generators</b> withstood the down-time - if they didn't, continue with step 15.<br>
|
||||
<b>Step eleven:</b> Since disaster was averted you now have to ensure it doesn't repeat. If it was a powersink which caused it and if the engineering apc is wired to the same powernet, which the powersink is on, you have to remove the piece of wire which links the apc to the powernet. If it wasn't a powersink which caused it, then skip to step 14.<br>
|
||||
<b>Step eleven:</b> Since disaster was averted you now have to ensure it doesn't repeat. If it was a powersink which caused it and if the engineering apc is wired to the same powernet,
|
||||
which the powersink is on, you have to remove the piece of wire which links the apc to the powernet. If it wasn't a powersink which caused it, then skip to step 14.<br>
|
||||
<b>Step twelve:</b> Grab your crowbar and pry away the tile closest to the APC.<br>
|
||||
<b>Step thirteen:</b> Use the wirecutters to cut the wire which is conecting the grid to the terminal. <br>
|
||||
<b>Step fourteen:</b> Go to the bar and tell the guys how you saved them all. Stop reading this guide here.<br>
|
||||
@@ -189,7 +190,9 @@
|
||||
<body>
|
||||
|
||||
<H3>How to Clone People</H3>
|
||||
So there’s 50 dead people lying on the floor, chairs are spinning like no tomorrow and you haven’t the foggiest idea of what to do? Not to worry! This guide is intended to teach you how to clone people and how to do it right, in a simple step-by-step process! If at any point of the guide you have a mental meltdown, genetics probably isn’t for you and you should get a job-change as soon as possible before you’re sued for malpractice.
|
||||
So there’s 50 dead people lying on the floor, chairs are spinning like no tomorrow and you haven’t the foggiest idea of what to do? Not to worry!
|
||||
This guide is intended to teach you how to clone people and how to do it right, in a simple step-by-step process! If at any point of the guide you have a mental meltdown,
|
||||
genetics probably isn’t for you and you should get a job-change as soon as possible before you’re sued for malpractice.
|
||||
|
||||
<ol>
|
||||
<li><a href='#1'>Acquire body</a></li>
|
||||
@@ -209,34 +212,48 @@
|
||||
This is pretty much vital for the process because without a body, you cannot clone it. Usually, bodies will be brought to you, so you do not need to worry so much about this step. If you already have a body, great! Move on to the next step.
|
||||
|
||||
<a name='2'><H4>Step 2: Strip body</H4>
|
||||
The cloning machine does not like abiotic items. What this means is you can’t clone anyone if they’re wearing clothes, so take all of it off. If it’s just one person, it’s courteous to put their possessions in the closet. If you have about seven people awaiting cloning, just leave the piles where they are, but don’t mix them around and for God’s sake don’t let people in to steal them.
|
||||
The cloning machine does not like abiotic items. What this means is you can’t clone anyone if they’re wearing clothes, so take all of it off. If it’s just one person, it’s courteous to put their possessions in the closet.
|
||||
If you have about seven people awaiting cloning, just leave the piles where they are, but don’t mix them around and for God’s sake don’t let people in to steal them.
|
||||
|
||||
<a name='3'><H4>Step 3: Put body in cloning machine</H4>
|
||||
Grab the body and then put it inside the DNA modifier. If you cannot do this, then you messed up at Step 2. Go back and check you took EVERYTHING off - a commonly missed item is their headset.
|
||||
|
||||
<a name='4'><H4>Step 4: Scan body</H4>
|
||||
Go onto the computer and scan the body by pressing ‘Scan - <Subject Name Here>’. If you’re successful, they will be added to the records (note that this can be done at any time, even with living people, so that they can be cloned without a body in the event that they are lying dead on port solars and didn‘t turn on their suit sensors)! If not, and it says “Error: Mental interface failure.”, then they have left their bodily confines and are one with the spirits. If this happens, just shout at them to get back in their body, click ‘Refresh‘ and try scanning them again. If there’s no success, threaten them with gibbing. Still no success? Skip over to Step 7 and don‘t continue after it, as you have an unresponsive body and it cannot be cloned. If you got “Error: Unable to locate valid genetic data.“, you are trying to clone a monkey - start over.
|
||||
Go onto the computer and scan the body by pressing ‘Scan - <Subject Name Here>’. If you’re successful, they will be added to the records (note that this can be done at any time, even with living people,
|
||||
so that they can be cloned without a body in the event that they are lying dead on port solars and didn‘t turn on their suit sensors)!
|
||||
If not, and it says “Error: Mental interface failure.”, then they have left their bodily confines and are one with the spirits. If this happens, just shout at them to get back in their body,
|
||||
click ‘Refresh‘ and try scanning them again. If there’s no success, threaten them with gibbing.
|
||||
Still no success? Skip over to Step 7 and don‘t continue after it, as you have an unresponsive body and it cannot be cloned.
|
||||
If you got “Error: Unable to locate valid genetic data.“, you are trying to clone a monkey - start over.
|
||||
|
||||
<a name='5'><H4>Step 5: Clone body</H4>
|
||||
Now that the body has a record, click ’View Records’, click the subject’s name, and then click ‘Clone’ to start the cloning process. Congratulations! You’re halfway there. Remember not to ‘Eject’ the cloning pod as this will kill the developing clone and you’ll have to start the process again.
|
||||
Now that the body has a record, click ’View Records’, click the subject’s name, and then click ‘Clone’ to start the cloning process. Congratulations! You’re halfway there.
|
||||
Remember not to ‘Eject’ the cloning pod as this will kill the developing clone and you’ll have to start the process again.
|
||||
|
||||
<a name='6'><H4>Step 6: Get clean SEs for body</H4>
|
||||
Cloning is a finicky and unreliable process. Whilst it will most certainly bring someone back from the dead, they can have any number of nasty disabilities given to them during the cloning process! For this reason, you need to prepare a clean, defect-free Structural Enzyme (SE) injection for when they’re done. If you’re a competent Geneticist, you will already have one ready on your working computer. If, for any reason, you do not, then eject the body from the DNA modifier (NOT THE CLONING POD) and take it next door to the Genetics research room. Put the body in one of those DNA modifiers and then go onto the console. Go into View/Edit/Transfer Buffer, find an open slot and click “SE“ to save it. Then click ‘Injector’ to get the SEs in syringe form. Put this in your pocket or something for when the body is done.
|
||||
Cloning is a finicky and unreliable process. Whilst it will most certainly bring someone back from the dead, they can have any number of nasty disabilities given to them during the cloning process!
|
||||
For this reason, you need to prepare a clean, defect-free Structural Enzyme (SE) injection for when they’re done. If you’re a competent Geneticist, you will already have one ready on your working computer.
|
||||
If, for any reason, you do not, then eject the body from the DNA modifier (NOT THE CLONING POD) and take it next door to the Genetics research room. Put the body in one of those DNA modifiers and then go onto the console.
|
||||
Go into View/Edit/Transfer Buffer, find an open slot and click “SE“ to save it. Then click ‘Injector’ to get the SEs in syringe form. Put this in your pocket or something for when the body is done.
|
||||
|
||||
<a name='7'><H4>Step 7: Put body in morgue</H4>
|
||||
Now that the cloning process has been initiated and you have some clean Structural Enzymes, you no longer need the body! Drag it to the morgue and tell the Chef over the radio that they have some fresh meat waiting for them in there. To put a body in a morgue bed, simply open the tray, grab the body, put it on the open tray, then close the tray again. Use one of the nearby pens to label the bed “CHEF MEAT” in order to avoid confusion.
|
||||
Now that the cloning process has been initiated and you have some clean Structural Enzymes, you no longer need the body! Drag it to the morgue and tell the Chef over the radio that they have some fresh meat waiting for them in there.
|
||||
To put a body in a morgue bed, simply open the tray, grab the body, put it on the open tray, then close the tray again. Use one of the nearby pens to label the bed “CHEF MEAT” in order to avoid confusion.
|
||||
|
||||
<a name='8'><H4>Step 8: Await cloned body</H4>
|
||||
Now go back to the lab and wait for your patient to be cloned. It won’t be long now, I promise.
|
||||
|
||||
<a name='9'><H4>Step 9: Cyo and clean clean SE injector on person</H4>
|
||||
Has your body been cloned yet? Great! As soon as the guy pops out, grab them and stick them in cryo. Clonexadone and Cryoxadone help rebuild their genetic material. Then grab your cleanr SE injector and jab it in them. Once you’ve injected them, they now have clean Structural Enzymes and their defects, if any, will disappear in a short while.
|
||||
Has your body been cloned yet? Great! As soon as the guy pops out, grab them and stick them in cryo. Clonexadone and Cryoxadone help rebuild their genetic material. Then grab your cleanr SE injector and jab it in them. Once you’ve injected them,
|
||||
they now have clean Structural Enzymes and their defects, if any, will disappear in a short while.
|
||||
|
||||
<a name='10'><H4>Step 10: Give person clothes back</H4>
|
||||
Obviously the person will be naked after they have been cloned. Provided you weren’t an irresponsible little shit, you should have protected their possessions from thieves and should be able to give them back to the patient. No matter how cruel you are, it’s simply against protocol to force your patients to walk outside naked.
|
||||
Obviously the person will be naked after they have been cloned. Provided you weren’t an irresponsible little shit, you should have protected their possessions from thieves and should be able to give them back to the patient.
|
||||
No matter how cruel you are, it’s simply against protocol to force your patients to walk outside naked.
|
||||
|
||||
<a name='11'><H4>Step 11: Send person on their way</H4>
|
||||
Give the patient one last check-over - make sure they don’t still have any defects and that they have all their possessions. Ask them how they died, if they know, so that you can report any foul play over the radio. Once you’re done, your patient is ready to go back to work! Chances are they do not have Medbay access, so you should let them out of Genetics and the Medbay main entrance.
|
||||
Give the patient one last check-over - make sure they don’t still have any defects and that they have all their possessions. Ask them how they died, if they know, so that you can report any foul play over the radio.
|
||||
Once you’re done, your patient is ready to go back to work! Chances are they do not have Medbay access, so you should let them out of Genetics and the Medbay main entrance.
|
||||
|
||||
<p>If you’ve gotten this far, congratulations! You have mastered the art of cloning. Now, the real problem is how to resurrect yourself after that traitor had his way with you for cloning his target.
|
||||
|
||||
@@ -248,7 +265,7 @@
|
||||
/obj/item/weapon/book/manual/ripley_build_and_repair
|
||||
name = "APLU \"Ripley\" Construction and Operation Manual"
|
||||
icon_state ="book"
|
||||
author = "Weyland-Yutani Corp" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned
|
||||
author = "Randall Varn, Einstein Engines Senior Mechanic" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned
|
||||
title = "APLU \"Ripley\" Construction and Operation Manual"
|
||||
|
||||
dat = {"<html>
|
||||
@@ -347,23 +364,38 @@
|
||||
Those are the basic steps to furthing science. What do you do science with, however? Well, you have four major tools: R&D Console, the Destructive Analyzer, the Protolathe, and the Circuit Imprinter.
|
||||
|
||||
<h2>The R&D Console</h2>
|
||||
The R&D console is the cornerstone of any research lab. It is the central system from which the Destructive Analyzer, Protolathe, and Circuit Imprinter (your R&D systems) are controled. More on those systems in their own sections. On its own, the R&D console acts as a database for all your technological gains and new devices you discover. So long as the R&D console remains intact, you'll retain all that SCIENCE you've discovered. Protect it though, because if it gets damaged, you'll lose your data! In addition to this important purpose, the R&D console has a disk menu that lets you transfer data from the database onto disk or from the disk into the database. It also has a settings menu that lets you re-sync with nearby R&D devices (if they've become disconnected), lock the console from the unworthy, upload the data to all other R&D consoles in the network (all R&D consoles are networked by default), connect/disconnect from the network, and purge all data from the database.
|
||||
The R&D console is the cornerstone of any research lab. It is the central system from which the Destructive Analyzer, Protolathe, and Circuit Imprinter (your R&D systems) are controled. More on those systems in their own sections.
|
||||
On its own, the R&D console acts as a database for all your technological gains and new devices you discover. So long as the R&D console remains intact, you'll retain all that SCIENCE you've discovered. Protect it though,
|
||||
because if it gets damaged, you'll lose your data!
|
||||
In addition to this important purpose, the R&D console has a disk menu that lets you transfer data from the database onto disk or from the disk into the database.
|
||||
It also has a settings menu that lets you re-sync with nearby R&D devices (if they've become disconnected), lock the console from the unworthy,
|
||||
upload the data to all other R&D consoles in the network (all R&D consoles are networked by default), connect/disconnect from the network, and purge all data from the database.
|
||||
<b>NOTE:</b> The technology list screen, circuit imprinter, and protolathe menus are accessible by non-scientists. This is intended to allow 'public' systems for the plebians to utilize some new devices.
|
||||
|
||||
<h2>Destructive Analyzer</h2>
|
||||
This is the source of all technology. Whenever you put a handheld object in it, it analyzes it and determines what sort of technological advancements you can discover from it. If the technology of the object is equal or higher then your current knowledge, you can destroy the object to further those sciences. Some devices (notably, some devices made from the protolathe and circuit imprinter) aren't 100% reliable when you first discover them. If these devices break down, you can put them into the Destructive Analyzer and improve their reliability rather then futher science. If their reliability is high enough ,it'll also advance their related technologies.
|
||||
This is the source of all technology. Whenever you put a handheld object in it, it analyzes it and determines what sort of technological advancements you can discover from it. If the technology of the object is equal or higher then your current knowledge,
|
||||
you can destroy the object to further those sciences.
|
||||
Some devices (notably, some devices made from the protolathe and circuit imprinter) aren't 100% reliable when you first discover them. If these devices break down, you can put them into the Destructive Analyzer and improve their reliability rather then futher science.
|
||||
If their reliability is high enough ,it'll also advance their related technologies.
|
||||
|
||||
<h2>Circuit Imprinter</h2>
|
||||
This machine, along with the Protolathe, is used to actually produce new devices. The Circuit Imprinter takes glass and various chemicals (depends on the design) to produce new circuit boards to build new machines or computers. It can even be used to print AI modules.
|
||||
|
||||
<h2>Protolathe</h2>
|
||||
This machine is an advanced form of the Autolathe that produce non-circuit designs. Unlike the Autolathe, it can use processed metal, glass, solid plasma, silver, gold, and diamonds along with a variety of chemicals to produce devices. The downside is that, again, not all devices you make are 100% reliable when you first discover them.
|
||||
This machine is an advanced form of the Autolathe that produce non-circuit designs. Unlike the Autolathe, it can use processed metal, glass, solid plasma, silver, gold, and diamonds along with a variety of chemicals to produce devices.
|
||||
The downside is that, again, not all devices you make are 100% reliable when you first discover them.
|
||||
|
||||
<h1>Reliability and You</h1>
|
||||
As it has been stated, many devices when they're first discovered do not have a 100% reliablity when you first discover them. Instead, the reliablity of the device is dependent upon a base reliability value, whatever improvements to the design you've discovered through the Destructive Analyzer, and any advancements you've made with the device's source technologies. To be able to improve the reliability of a device, you have to use the device until it breaks beyond repair. Once that happens, you can analyze it in a Destructive Analyzer. Once the device reachs a certain minimum reliability, you'll gain tech advancements from it.
|
||||
As it has been stated, many devices when they're first discovered do not have a 100% reliablity when you first discover them. Instead,
|
||||
the reliablity of the device is dependent upon a base reliability value, whatever improvements to the design you've discovered through the Destructive Analyzer,
|
||||
and any advancements you've made with the device's source technologies. To be able to improve the reliability of a device, you have to use the device until it breaks beyond repair. Once that happens, you can analyze it in a Destructive Analyzer.
|
||||
Once the device reachs a certain minimum reliability, you'll gain tech advancements from it.
|
||||
|
||||
<h1>Building a Better Machine</h1>
|
||||
Many machines produces from circuit boards and inserted into a machine frame require a variety of parts to construct. These are parts like capacitors, batteries, matter bins, and so forth. As your knowledge of science improves, more advanced versions are unlocked. If you use these parts when constructing something, its attributes may be improved. For example, if you use an advanced matter bin when constructing an autolathe (rather then a regular one), it'll hold more materials. Experiment around with stock parts of various qualities to see how they affect the end results! Be warned, however: Tier 3 and higher stock parts don't have 100% reliability and their low reliability may affect the reliability of the end machine.
|
||||
Many machines produces from circuit boards and inserted into a machine frame require a variety of parts to construct. These are parts like capacitors, batteries, matter bins, and so forth. As your knowledge of science improves, more advanced versions are unlocked.
|
||||
If you use these parts when constructing something, its attributes may be improved.
|
||||
For example, if you use an advanced matter bin when constructing an autolathe (rather then a regular one), it'll hold more materials. Experiment around with stock parts of various qualities to see how they affect the end results! Be warned, however:
|
||||
Tier 3 and higher stock parts don't have 100% reliability and their low reliability may affect the reliability of the end machine.
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
@@ -796,4 +828,170 @@
|
||||
<b>Disk, Code, Safety, Timer, Disk, RUN!</b><br>
|
||||
Intelligence Analysts believe that normal Nanotrasen procedure is for the Captain to secure the nuclear authorisation disk.<br>
|
||||
Good luck!
|
||||
</html>"}
|
||||
</html>"}
|
||||
|
||||
/obj/item/weapon/book/manual/atmospipes
|
||||
name = "Pipes and You: Getting To Know Your Scary Tools"
|
||||
icon_state = "pipingbook"
|
||||
author = "Maria Crash, Senior Atmospherics Technician"
|
||||
title = "Pipes and You: Getting To Know Your Scary Tools"
|
||||
dat = {"<html>
|
||||
<head>
|
||||
<style>
|
||||
h1 {font-size: 18px; margin: 15px 0px 5px;}
|
||||
h1 {font-size: 15px; margin: 15px 0px 5px;}
|
||||
li {margin: 2px 0px 2px 15px;}
|
||||
ul {list-style: none; margin: 5px; padding: 0px;}
|
||||
ol {margin: 5px; padding: 0px 15px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<font face="Verdana" color=black>
|
||||
|
||||
<h1><a name="Contents">Contents</a></h1>
|
||||
<ol>
|
||||
<li><a href="#Forward">Author's Forward</a></li>
|
||||
<li><a href="#Basic">Basic Piping</a></li>
|
||||
<li><a href="#Insulated">Insulated Pipes</a></li>
|
||||
<li><a href="#Devices">Atmospherics Devices</a></li>
|
||||
<li><a href="#HES">Heat Exchange Systems</a></li>
|
||||
<li><a href="#Final">Final Checks</a></li>
|
||||
</ol>
|
||||
<br><BR>
|
||||
|
||||
<h1><a name="Forward"><U><B>HOW TO NOT SUCK QUITE SO HARD AT ATMOSPHERICS</B></U></a></h1><BR>
|
||||
<I>Or: What the fuck does a "passive gate" do?</I><BR><BR>
|
||||
|
||||
Alright. It has come to my attention that a variety of people are unsure of what a "pipe" is and what it does.
|
||||
Apparently there is an unnatural fear of these arcane devices and their "gases". Spooky, spooky. So,
|
||||
this will tell you what every device constructable by an ordinary pipe dispenser within atmospherics actually does.
|
||||
You are not going to learn what to do with them to be the super best person ever, or how to play guitar with passive gates,
|
||||
or something like that. Just what stuff does.<BR><BR>
|
||||
|
||||
|
||||
<h1><a name="Basic"><B>Basic Pipes</B></a></h1><BR>
|
||||
<I>The boring ones.</I><BR>
|
||||
TMost ordinary pipes are pretty straightforward. They hold gas. If gas is moving in a direction for some reason, gas will flow in that direction.
|
||||
That's about it. Even so, here's all of your wonderful pipe options.<BR>
|
||||
|
||||
<li><I>Straight pipes:</I> They're pipes. One-meter sections. Straight line. Pretty simple. Just about every pipe and device is based around this
|
||||
standard one-meter size, so most things will take up as much space as one of these.</li>
|
||||
<li><I>Bent pipes:</I> Pipes with a 90 degree bend at the half-meter mark. My goodness.</li>
|
||||
<li><I>Pipe manifolds:</I> Pipes that are essentially a "T" shape, allowing you to connect three things at one point.</li>
|
||||
<li><I>4-way manifold:</I> A four-way junction.</li>
|
||||
<li><I>Pipe cap:</I> Caps off the end of a pipe. Open ends don't actually vent air, because of the way the pipes are assembled, so, uh. Use them to decorate your house or something.</li>
|
||||
<li><I>Manual Valve:</I> A valve that will block off airflow when turned. Can't be used by the AI or cyborgs, because they don't have hands.</li>
|
||||
< <li><I>Manual T-Valve:</I> Like a manual valve, but at the center of a manifold instead of a straight pipe.</li><BR><BR>
|
||||
|
||||
<h1><a name="Insulated"><B>Insulated Pipes</B></a></h1><BR>
|
||||
<I>Special Public Service Announcement.</I><BR>
|
||||
Our regular pipes are already insulated. These are completely worthless. Punch anyone who uses them.<BR><BR>
|
||||
|
||||
<h1><a name="Devices"><B>Devices: </B></a></h1><BR>
|
||||
<I>They actually do something.</I><BR>
|
||||
This is usually where people get frightened, </font><font face="Verdana" color=black>afraid, and start calling on their gods and/or cowering in fear. Yes, I can see you doing that right now.
|
||||
Stop it. It's unbecoming. Most of these are fairly straightforward.<BR>
|
||||
|
||||
<li><I>Gas Pump:</I> Take a wild guess. It moves gas in the direction it's pointing (marked by the red line on one end). It moves it based on pressure, the maximum output being 4500 kPa (kilopascals).
|
||||
Ordinary atmospheric pressure, for comparison, is 101.3 kPa, and the minimum pressure of room-temperature pure oxygen needed to not suffocate in a matter of minutes is 16 kPa
|
||||
(though 18 is preferred using internals, for various reasons).</li>
|
||||
<li><I>Volume pump:</I> This pump goes based on volume, instead of pressure, and the possible maximum pressure it can create in the pipe on the recieving end is double the gas pump because of this,
|
||||
clocking in at an incredible 9000 kPa. If a pipe with this is destroyed or damaged, and this pressure of gas escapes, it can be incredibly dangerous depending on the size of the pipe filled.
|
||||
Don't hook this to the distribution loop, or you will make babies cry and the Chief Engineer brutally beat you.</li>
|
||||
<li><I>Passive gate:</I> This is essentially a cap on the pressure of gas allowed to flow in a specific direction.
|
||||
When turned on, instead of actively pumping gas, it measures the pressure flowing through it, and whatever pressure you set is the maximum: it'll cap after that.
|
||||
In addition, it only lets gas flow one way. The direction the gas flows is opposite the red handle on it, which is confusing to people used to the red stripe on pumps pointing the way.</li>
|
||||
<li><I>Unary vent:</I> The basic vent used in rooms. It pumps gas into the room, but can't suck it back out. Controlled by the room's air alarm system.</li>
|
||||
<li><I>Scrubber:</I> The other half of room equipment. Filters air, and can suck it in entirely in what's called a "panic siphon". Actvating a panic siphon without very good reason will kill someone. Don't do it.</li>
|
||||
<li><I>Meter:</I> A little box with some gagues and numbers. Fasten it to any pipe or manifold, and it'll read you the pressure in it. Very useful.</li>
|
||||
<li><I>Gas mixer:</I> Two sides are input, one side is output. Mixes the gases pumped into it at the ratio defined. The side perpendicular to the other two is "node 2", for reference.
|
||||
Can output this gas at pressures from 0-4500 kPa.</li>
|
||||
<li><I>Gas filter:</I> Essentially the opposite of a gas mixer. One side is input. The other two sides are output. One gas type will be filtered into the perpendicular output pipe,
|
||||
the rest will continue out the other side. Can also output from 0-4500 kPa.</li>
|
||||
|
||||
<h1><a name="HES"><B>Heat Exchange Systems</B></a></h1><BR>
|
||||
<I>Will not set you on fire.</I><BR>
|
||||
These systems are used to transfer heat only between two pipes. They will not move gases or any other element, but will equalize the temperature (eventually). Note that because of how gases work (remember: pv=nRt),
|
||||
a higher temperature will raise pressure, and a lower one will lower temperature.<BR>
|
||||
|
||||
<li><I>Pipe:</I> This is a pipe that will exchange heat with the surrounding atmosphere. Place in fire for superheating. Place in space for supercooling.</li>
|
||||
<li><I>Bent Pipe:</I> Take a wild guess.</li>
|
||||
<li><I>Junction:</I><I>Junction:</I>The point where you connect your normal pipes to heat exchange pipes. Not necessary for heat exchangers, but necessary for H/E pipes/bent pipes.</li>
|
||||
<li><I>Heat Exchanger:</I> These funky-looking bits attach to an open pipe end. Put another heat exchanger directly across from it, and you can transfer heat across two pipes without having to have the gases touch.
|
||||
This normally shouldn't exchange with the ambient air, despite being totally exposed. Just don't ask questions...</li><BR>
|
||||
|
||||
|
||||
That's about it for pipes. Go forth, armed with this knowledge, and try not to break, burn down, or kill anything. Please.</font>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
|
||||
/obj/item/weapon/book/manual/evaguide
|
||||
name = "EVA Gear and You: Not Spending All Day Inside"
|
||||
icon_state = "evabook"
|
||||
author = "Maria Crash, Senior Atmospherics Technician"
|
||||
title = "EVA Gear and You: Not Spending All Day Inside"
|
||||
dat = {"<html>
|
||||
<head>
|
||||
<style>
|
||||
h1 {font-size: 18px; margin: 15px 0px 5px;}
|
||||
h1 {font-size: 15px; margin: 15px 0px 5px;}
|
||||
li {margin: 2px 0px 2px 15px;}
|
||||
ul {list-style: none; margin: 5px; padding: 0px;}
|
||||
ol {margin: 5px; padding: 0px 15px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<font face="Verdana" color=black>
|
||||
|
||||
<h1><a name="Contents">Contents</a></h1>
|
||||
<ol>
|
||||
<li><a href="#Forward">A forward on using EVA gear</a></li>
|
||||
<li><a href="#Civilian">Donning a Civilian Suits</a></li>
|
||||
<li><a href="#Hardsuit">Putting on a Hardsuit</a></li>
|
||||
<li><a href="#Final">Final Checks</a></li>
|
||||
</ol>
|
||||
<br><BR>
|
||||
|
||||
<h1><a name="Forward">EVA Gear and You: Not Spending All Day Inside</a></h1><BR>
|
||||
<I>Or: How not to suffocate because there's a hole in your shoes</I><BR><BR>
|
||||
|
||||
EVA gear. Wonderful to use. It's useful for mining, engineering, and occasionally just surviving, if things are that bad. Most people have EVA training,
|
||||
but apparently there are some on a space station who don't. This guide should give you a basic idea of how to use this gear, safely. It's split into two sections:
|
||||
Civilian suits and hardsuits.<BR><BR>
|
||||
|
||||
<h1><a name="Civilian">Civilian Suits</a></h1><BR>
|
||||
<I>The bulkiest things this side of Alpha Centauri</I><BR>
|
||||
These suits are the grey ones that are stored in EVA. They're the more simple to get on, but are also a lot bulkier, and provide less protection from environmental hazards such as radiaion or physical impact.
|
||||
As Medical, Engineering, Security, and Mining all have hardsuits of their own, these don't see much use, but knowing how to put them on is quite useful anyways.<BR><BR>
|
||||
|
||||
First, take the suit. It should be in three pieces: A top, a bottom, </font><font face="Verdana" color=black>and a helmet. Put the bottom on first, shoes and the like will fit in it. If you have magnetic boots, however,
|
||||
put them on on top of the suit's feet. Next, get the top on, as you would a shirt. It can be somewhat awkward putting these pieces on, due to the makeup of the suit,
|
||||
but to an extent they will adjust to you. You can then find the snaps and seals around the waist, where the two pieces meet. Fasten these, and double-check their tightness.
|
||||
The red indicators around the waist of the lower half will turn green when this is done correctly. Next, put on whatever breathing apparatus you're using, be it a gas mask or a breath mask. Make sure the oxygen tube is fastened into it.
|
||||
Put on the helmet now, straight forward, and make sure the tube goes into the small opening specifically for internals. Again, fasten seals around the neck, a small indicator light in the inside of the helmet should go from red to off when all is fastened.
|
||||
There is a small slot on the side of the suit where an emergency oxygen tank or</font><font face="Verdana" color=black> extended emergency oxygen tank will fit,
|
||||
but it is reccomended to have a full-sized tank on your back for EVA.<BR><BR>
|
||||
|
||||
<h1><a name="Hardsuit">Hardsuits</a></h1><BR>
|
||||
<I>Heavy, uncomfortable, still the best option.</I><BR>
|
||||
These suits come in Engineering, Mining, and the Armory. There's also a couple Medical Hardsuits in EVA. These provide a lot more protection than the standard suits.<BR><BR>
|
||||
|
||||
Similarly to the other suits, these are split into three parts. Fastening the pant and top are mostly the same as the other spacesuits, with the exception that these are a bit heavier,
|
||||
though not as bulky. The helmet goes on differently, with the air tube feeing into the suit and out a hole near the left shoulder, while the helmet goes on turned ninety degrees counter-clockwise,
|
||||
and then is screwed in for one and a quarter full rotations clockwise, leaving the faceplate directly in front of you. There is a small button on the right side of the helmet that activates the helmet light.
|
||||
The tanks that fasten onto the side slot are emergency tanks, as</font><font face="Verdana" color=black> well as full-sized oxygen tanks, leaving your back free for a backpack or satchel.<BR><BR>
|
||||
|
||||
<h1><a name="Final">FINAL CHECKS:</a></h1><BR>
|
||||
<li>Are all seals fastened correctly?</li>
|
||||
<li>Do you either have shoes on under the suit, or magnetic boots on over it?</li>
|
||||
<li>Do you have a mask on and internals on the suit or your back?</li>
|
||||
<li>Do you have a way to communicate with the station in case something goes wrong?</li>
|
||||
<li>Do you have a second person watching if this is a training session?</li><BR>
|
||||
|
||||
If you don't have any further issues, go out and do whatever is necessary.</font>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
@@ -50,7 +50,7 @@
|
||||
if(!((user == loc || (in_range(src, user) && istype(src.loc, /turf)))))
|
||||
return
|
||||
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
|
||||
smoke.set_up(5, 0, user.loc)
|
||||
smoke.attach(user)
|
||||
smoke.start()
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
if (ishuman(usr) || ismonkey(usr)) //so monkeys can take off their backpacks -- Urist
|
||||
var/mob/M = usr
|
||||
|
||||
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
|
||||
return
|
||||
|
||||
if(over_object == M && Adjacent(M)) // this must come before the screen objects only block
|
||||
orient2hud(M) // dunno why it wasn't before
|
||||
if(M.s_active)
|
||||
@@ -206,6 +209,8 @@
|
||||
break
|
||||
if(!ok)
|
||||
if(!stop_messages)
|
||||
if (istype(W, /obj/item/weapon/hand_labeler))
|
||||
return 0
|
||||
usr << "<span class='notice'>[src] cannot hold [W].</span>"
|
||||
return 0
|
||||
|
||||
@@ -311,7 +316,7 @@
|
||||
return 1 //Robots can't interact with storage items.
|
||||
|
||||
if(!can_be_inserted(W))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
if(istype(W, /obj/item/weapon/tray))
|
||||
var/obj/item/weapon/tray/T = W
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
if(.)
|
||||
if(W == front_id)
|
||||
front_id = null
|
||||
name = initial(name)
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/storage/wallet/handle_item_insertion(obj/item/W as obj, prevent_warning = 0)
|
||||
@@ -41,6 +42,7 @@
|
||||
if(.)
|
||||
if(!front_id && istype(W, /obj/item/weapon/card/id))
|
||||
front_id = W
|
||||
name = "[name] ([front_id])"
|
||||
update_icon()
|
||||
|
||||
/obj/item/weapon/storage/wallet/update_icon()
|
||||
|
||||
@@ -354,33 +354,36 @@
|
||||
/obj/item/weapon/weldingtool/proc/eyecheck(mob/user as mob)
|
||||
if(!iscarbon(user)) return 1
|
||||
var/safety = user:eyecheck()
|
||||
switch(safety)
|
||||
if(1)
|
||||
usr << "\red Your eyes sting a little."
|
||||
user.eye_stat += rand(1, 2)
|
||||
if(user.eye_stat > 12)
|
||||
user.eye_blurry += rand(3,6)
|
||||
if(0)
|
||||
usr << "\red Your eyes burn."
|
||||
user.eye_stat += rand(2, 4)
|
||||
if(user.eye_stat > 10)
|
||||
user.eye_blurry += rand(4,10)
|
||||
if(-1)
|
||||
usr << "\red Your thermals intensify the welder's glow. Your eyes itch and burn severely."
|
||||
user.eye_blurry += rand(12,20)
|
||||
user.eye_stat += rand(12, 16)
|
||||
if(user.eye_stat > 10 && safety < 2)
|
||||
user << "\red Your eyes are really starting to hurt. This can't be good for you!"
|
||||
if (prob(user.eye_stat - 25 + 1))
|
||||
user << "\red You go blind!"
|
||||
user.sdisabilities |= BLIND
|
||||
else if (prob(user.eye_stat - 15 + 1))
|
||||
user << "\red You go blind!"
|
||||
user.eye_blind = 5
|
||||
user.eye_blurry = 5
|
||||
user.disabilities |= NEARSIGHTED
|
||||
spawn(100)
|
||||
user.disabilities &= ~NEARSIGHTED
|
||||
if(istype(user, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/datum/organ/internal/eyes/E = H.internal_organs["eyes"]
|
||||
switch(safety)
|
||||
if(1)
|
||||
usr << "\red Your eyes sting a little."
|
||||
E.damage += rand(1, 2)
|
||||
if(E.damage > 12)
|
||||
user.eye_blurry += rand(3,6)
|
||||
if(0)
|
||||
usr << "\red Your eyes burn."
|
||||
E.damage += rand(2, 4)
|
||||
if(E.damage > 10)
|
||||
E.damage += rand(4,10)
|
||||
if(-1)
|
||||
usr << "\red Your thermals intensify the welder's glow. Your eyes itch and burn severely."
|
||||
user.eye_blurry += rand(12,20)
|
||||
E.damage += rand(12, 16)
|
||||
if(E.damage > 10 && safety < 2)
|
||||
user << "\red Your eyes are really starting to hurt. This can't be good for you!"
|
||||
if (E.damage >= E.min_broken_damage)
|
||||
user << "\red You go blind!"
|
||||
user.sdisabilities |= BLIND
|
||||
else if (E.damage >= E.min_bruised_damage)
|
||||
user << "\red You go blind!"
|
||||
user.eye_blind = 5
|
||||
user.eye_blurry = 5
|
||||
user.disabilities |= NEARSIGHTED
|
||||
spawn(100)
|
||||
user.disabilities &= ~NEARSIGHTED
|
||||
return
|
||||
|
||||
|
||||
@@ -406,7 +409,6 @@
|
||||
m_amt = 70
|
||||
g_amt = 120
|
||||
origin_tech = "engineering=4;plasma=3"
|
||||
icon_state = "ewelder"
|
||||
var/last_gen = 0
|
||||
|
||||
|
||||
|
||||
@@ -5,392 +5,62 @@
|
||||
desc = "A rectangular steel crate."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "crate"
|
||||
density = 1
|
||||
icon_opened = "crateopen"
|
||||
icon_closed = "crate"
|
||||
req_access = null
|
||||
opened = 0
|
||||
flags = FPRINT
|
||||
// mouse_drag_pointer = MOUSE_ACTIVE_POINTER //???
|
||||
var/rigged = 0
|
||||
|
||||
/obj/structure/closet/pcrate
|
||||
name = "plastic crate"
|
||||
desc = "A rectangular plastic crate."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "plasticcrate"
|
||||
density = 1
|
||||
icon_opened = "plasticcrateopen"
|
||||
icon_closed = "plasticcrate"
|
||||
req_access = null
|
||||
opened = 0
|
||||
flags = FPRINT
|
||||
// mouse_drag_pointer = MOUSE_ACTIVE_POINTER //???
|
||||
var/rigged = 0
|
||||
/obj/structure/closet/crate/can_open()
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/crate/internals
|
||||
desc = "A internals crate."
|
||||
name = "Internals crate"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "o2crate"
|
||||
density = 1
|
||||
icon_opened = "o2crateopen"
|
||||
icon_closed = "o2crate"
|
||||
|
||||
/obj/structure/closet/crate/trashcart
|
||||
desc = "A heavy, metal trashcart with wheels."
|
||||
name = "Trash Cart"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "trashcart"
|
||||
density = 1
|
||||
icon_opened = "trashcartopen"
|
||||
icon_closed = "trashcart"
|
||||
|
||||
/*these aren't needed anymore
|
||||
/obj/structure/closet/crate/hat
|
||||
desc = "A crate filled with Valuable Collector's Hats!."
|
||||
name = "Hat Crate"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "crate"
|
||||
density = 1
|
||||
icon_opened = "crateopen"
|
||||
icon_closed = "crate"
|
||||
|
||||
/obj/structure/closet/crate/contraband
|
||||
name = "Poster crate"
|
||||
desc = "A random assortment of posters manufactured by providers NOT listed under Nanotrasen's whitelist."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "crate"
|
||||
density = 1
|
||||
icon_opened = "crateopen"
|
||||
icon_closed = "crate"
|
||||
*/
|
||||
|
||||
/obj/structure/closet/crate/medical
|
||||
desc = "A medical crate."
|
||||
name = "Medical crate"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "medicalcrate"
|
||||
density = 1
|
||||
icon_opened = "medicalcrateopen"
|
||||
icon_closed = "medicalcrate"
|
||||
|
||||
/obj/structure/closet/crate/rcd
|
||||
desc = "A crate for the storage of the RCD."
|
||||
name = "RCD crate"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "crate"
|
||||
density = 1
|
||||
icon_opened = "crateopen"
|
||||
icon_closed = "crate"
|
||||
|
||||
/obj/structure/closet/crate/freezer
|
||||
desc = "A freezer."
|
||||
name = "Freezer"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "freezer"
|
||||
density = 1
|
||||
icon_opened = "freezeropen"
|
||||
icon_closed = "freezer"
|
||||
var/target_temp = T0C - 40
|
||||
var/cooling_power = 40
|
||||
|
||||
return_air()
|
||||
var/datum/gas_mixture/gas = (..())
|
||||
if(!gas) return null
|
||||
var/datum/gas_mixture/newgas = new/datum/gas_mixture()
|
||||
newgas.oxygen = gas.oxygen
|
||||
newgas.carbon_dioxide = gas.carbon_dioxide
|
||||
newgas.nitrogen = gas.nitrogen
|
||||
newgas.toxins = gas.toxins
|
||||
newgas.volume = gas.volume
|
||||
newgas.temperature = gas.temperature
|
||||
if(newgas.temperature <= target_temp) return
|
||||
|
||||
if((newgas.temperature - cooling_power) > target_temp)
|
||||
newgas.temperature -= cooling_power
|
||||
else
|
||||
newgas.temperature = target_temp
|
||||
return newgas
|
||||
|
||||
|
||||
/obj/structure/closet/crate/bin
|
||||
desc = "A large bin."
|
||||
name = "Large bin"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "largebin"
|
||||
density = 1
|
||||
icon_opened = "largebinopen"
|
||||
icon_closed = "largebin"
|
||||
|
||||
/obj/structure/closet/crate/radiation
|
||||
desc = "A crate with a radiation sign on it."
|
||||
name = "Radioactive gear crate"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "radiation"
|
||||
density = 1
|
||||
icon_opened = "radiationopen"
|
||||
icon_closed = "radiation"
|
||||
|
||||
/obj/structure/closet/crate/secure/weapon
|
||||
desc = "A secure weapons crate."
|
||||
name = "Weapons crate"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "weaponcrate"
|
||||
density = 1
|
||||
icon_opened = "weaponcrateopen"
|
||||
icon_closed = "weaponcrate"
|
||||
|
||||
/obj/structure/closet/crate/secure/plasma
|
||||
desc = "A secure plasma crate."
|
||||
name = "Plasma crate"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "plasmacrate"
|
||||
density = 1
|
||||
icon_opened = "plasmacrateopen"
|
||||
icon_closed = "plasmacrate"
|
||||
|
||||
/obj/structure/closet/crate/secure/gear
|
||||
desc = "A secure gear crate."
|
||||
name = "Gear crate"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "secgearcrate"
|
||||
density = 1
|
||||
icon_opened = "secgearcrateopen"
|
||||
icon_closed = "secgearcrate"
|
||||
|
||||
/obj/structure/closet/crate/secure/hydrosec
|
||||
desc = "A crate with a lock on it, painted in the scheme of the station's botanists."
|
||||
name = "secure hydroponics crate"
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "hydrosecurecrate"
|
||||
density = 1
|
||||
icon_opened = "hydrosecurecrateopen"
|
||||
icon_closed = "hydrosecurecrate"
|
||||
|
||||
/obj/structure/closet/crate/secure/bin
|
||||
desc = "A secure bin."
|
||||
name = "Secure bin"
|
||||
icon_state = "largebins"
|
||||
icon_opened = "largebinsopen"
|
||||
icon_closed = "largebins"
|
||||
redlight = "largebinr"
|
||||
greenlight = "largebing"
|
||||
sparks = "largebinsparks"
|
||||
emag = "largebinemag"
|
||||
|
||||
/obj/structure/closet/crate/secure/large
|
||||
name = "large crate"
|
||||
desc = "A hefty metal crate with an electronic locking system."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "largemetal"
|
||||
icon_opened = "largemetalopen"
|
||||
icon_closed = "largemetal"
|
||||
redlight = "largemetalr"
|
||||
greenlight = "largemetalg"
|
||||
|
||||
/obj/structure/closet/crate/secure/large/close()
|
||||
//we can hold up to one large item
|
||||
var/found = 0
|
||||
for(var/obj/structure/S in src.loc)
|
||||
if(S == src)
|
||||
continue
|
||||
if(!S.anchored)
|
||||
found = 1
|
||||
S.loc = src
|
||||
break
|
||||
if(!found)
|
||||
for(var/obj/machinery/M in src.loc)
|
||||
if(!M.anchored)
|
||||
M.loc = src
|
||||
break
|
||||
..()
|
||||
|
||||
//fluff variant
|
||||
/obj/structure/closet/crate/secure/large/reinforced
|
||||
desc = "A hefty, reinforced metal crate with an electronic locking system."
|
||||
icon_state = "largermetal"
|
||||
icon_opened = "largermetalopen"
|
||||
icon_closed = "largermetal"
|
||||
|
||||
/obj/structure/closet/crate/secure
|
||||
desc = "A secure crate."
|
||||
name = "Secure crate"
|
||||
icon_state = "securecrate"
|
||||
icon_opened = "securecrateopen"
|
||||
icon_closed = "securecrate"
|
||||
var/redlight = "securecrater"
|
||||
var/greenlight = "securecrateg"
|
||||
var/sparks = "securecratesparks"
|
||||
var/emag = "securecrateemag"
|
||||
var/broken = 0
|
||||
var/locked = 1
|
||||
|
||||
/obj/structure/closet/crate/large
|
||||
name = "large crate"
|
||||
desc = "A hefty metal crate."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "largemetal"
|
||||
icon_opened = "largemetalopen"
|
||||
icon_closed = "largemetal"
|
||||
|
||||
/obj/structure/closet/crate/large/close()
|
||||
//we can hold up to one large item
|
||||
var/found = 0
|
||||
for(var/obj/structure/S in src.loc)
|
||||
if(S == src)
|
||||
continue
|
||||
if(!S.anchored)
|
||||
found = 1
|
||||
S.loc = src
|
||||
break
|
||||
if(!found)
|
||||
for(var/obj/machinery/M in src.loc)
|
||||
if(!M.anchored)
|
||||
M.loc = src
|
||||
break
|
||||
..()
|
||||
|
||||
/obj/structure/closet/crate/hydroponics
|
||||
name = "Hydroponics crate"
|
||||
desc = "All you need to destroy those pesky weeds and pests."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "hydrocrate"
|
||||
icon_opened = "hydrocrateopen"
|
||||
icon_closed = "hydrocrate"
|
||||
density = 1
|
||||
|
||||
/obj/structure/closet/crate/hydroponics/prespawned
|
||||
//This exists so the prespawned hydro crates spawn with their contents.
|
||||
/* name = "Hydroponics crate"
|
||||
desc = "All you need to destroy those pesky weeds and pests."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "hydrocrate"
|
||||
icon_opened = "hydrocrateopen"
|
||||
icon_closed = "hydrocrate"
|
||||
density = 1*/
|
||||
New()
|
||||
..()
|
||||
new /obj/item/weapon/reagent_containers/spray/plantbgone(src)
|
||||
new /obj/item/weapon/reagent_containers/spray/plantbgone(src)
|
||||
new /obj/item/weapon/minihoe(src)
|
||||
// new /obj/item/weapon/weedspray(src)
|
||||
// new /obj/item/weapon/weedspray(src)
|
||||
// new /obj/item/weapon/pestspray(src)
|
||||
// new /obj/item/weapon/pestspray(src)
|
||||
// new /obj/item/weapon/pestspray(src)
|
||||
|
||||
|
||||
/obj/structure/closet/crate/secure/New()
|
||||
..()
|
||||
if(locked)
|
||||
overlays.Cut()
|
||||
overlays += redlight
|
||||
else
|
||||
overlays.Cut()
|
||||
overlays += greenlight
|
||||
|
||||
/obj/structure/closet/crate/rcd/New()
|
||||
..()
|
||||
new /obj/item/weapon/rcd_ammo(src)
|
||||
new /obj/item/weapon/rcd_ammo(src)
|
||||
new /obj/item/weapon/rcd_ammo(src)
|
||||
new /obj/item/weapon/rcd(src)
|
||||
|
||||
/obj/structure/closet/crate/radiation/New()
|
||||
..()
|
||||
new /obj/item/clothing/suit/radiation(src)
|
||||
new /obj/item/clothing/head/radiation(src)
|
||||
new /obj/item/clothing/suit/radiation(src)
|
||||
new /obj/item/clothing/head/radiation(src)
|
||||
new /obj/item/clothing/suit/radiation(src)
|
||||
new /obj/item/clothing/head/radiation(src)
|
||||
new /obj/item/clothing/suit/radiation(src)
|
||||
new /obj/item/clothing/head/radiation(src)
|
||||
/obj/structure/closet/crate/can_close()
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/crate/open()
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 15, 1, -3)
|
||||
if(src.opened)
|
||||
return 0
|
||||
if(!src.can_open())
|
||||
return 0
|
||||
|
||||
if(rigged && locate(/obj/item/device/radio/electropack) in src)
|
||||
if(isliving(usr))
|
||||
var/mob/living/L = usr
|
||||
if(L.electrocute_act(17, src))
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
return 2
|
||||
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 15, 1, -3)
|
||||
for(var/obj/O in src)
|
||||
O.loc = get_turf(src)
|
||||
|
||||
icon_state = icon_opened
|
||||
src.opened = 1
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/crate/close()
|
||||
if(!src.opened)
|
||||
return 0
|
||||
if(!src.can_close())
|
||||
return 0
|
||||
|
||||
playsound(src.loc, 'sound/machines/click.ogg', 15, 1, -3)
|
||||
|
||||
var/itemcount = 0
|
||||
|
||||
for(var/obj/O in get_turf(src))
|
||||
if(itemcount >= storage_capacity)
|
||||
break
|
||||
|
||||
if(O.density || O.anchored || istype(O,/obj/structure/closet))
|
||||
continue
|
||||
|
||||
if(istype(O, /obj/structure/stool/bed)) //This is only necessary because of rollerbeds and swivel chairs.
|
||||
var/obj/structure/stool/bed/B = O
|
||||
if(B.buckled_mob)
|
||||
continue
|
||||
|
||||
O.loc = src
|
||||
itemcount++
|
||||
|
||||
icon_state = icon_closed
|
||||
src.opened = 0
|
||||
|
||||
/obj/structure/closet/crate/attack_hand(mob/user as mob)
|
||||
if(opened)
|
||||
close()
|
||||
else
|
||||
if(rigged && locate(/obj/item/device/radio/electropack) in src)
|
||||
if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
if(L.electrocute_act(17, src))
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
return
|
||||
open()
|
||||
return
|
||||
|
||||
/obj/structure/closet/crate/secure/attack_hand(mob/user as mob)
|
||||
if(locked && !broken)
|
||||
if (allowed(user))
|
||||
user << "<span class='notice'>You unlock [src].</span>"
|
||||
src.locked = 0
|
||||
overlays.Cut()
|
||||
overlays += greenlight
|
||||
return
|
||||
else
|
||||
user << "<span class='notice'>[src] is locked.</span>"
|
||||
return
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/structure/closet/crate/secure/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype(W, /obj/item/weapon/card) && src.allowed(user) && !locked && !opened && !broken)
|
||||
user << "<span class='notice'>You lock \the [src].</span>"
|
||||
src.locked = 1
|
||||
overlays.Cut()
|
||||
overlays += redlight
|
||||
return
|
||||
else if ( (istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)) && locked &&!broken)
|
||||
overlays.Cut()
|
||||
overlays += emag
|
||||
overlays += sparks
|
||||
spawn(6) overlays -= sparks //Tried lots of stuff but nothing works right. so i have to use this *sadface*
|
||||
playsound(src.loc, "sparks", 60, 1)
|
||||
src.locked = 0
|
||||
src.broken = 1
|
||||
user << "<span class='notice'>You unlock \the [src].</span>"
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/crate/attack_paw(mob/user as mob)
|
||||
return attack_hand(user)
|
||||
return 1
|
||||
|
||||
/obj/structure/closet/crate/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(opened)
|
||||
@@ -424,6 +94,107 @@
|
||||
return
|
||||
else return attack_hand(user)
|
||||
|
||||
/obj/structure/closet/crate/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
for(var/obj/O in src.contents)
|
||||
del(O)
|
||||
del(src)
|
||||
return
|
||||
if(2.0)
|
||||
for(var/obj/O in src.contents)
|
||||
if(prob(50))
|
||||
del(O)
|
||||
del(src)
|
||||
return
|
||||
if(3.0)
|
||||
if (prob(50))
|
||||
del(src)
|
||||
return
|
||||
else
|
||||
return
|
||||
|
||||
/obj/structure/closet/crate/secure
|
||||
desc = "A secure crate."
|
||||
name = "Secure crate"
|
||||
icon_state = "securecrate"
|
||||
icon_opened = "securecrateopen"
|
||||
icon_closed = "securecrate"
|
||||
var/redlight = "securecrater"
|
||||
var/greenlight = "securecrateg"
|
||||
var/sparks = "securecratesparks"
|
||||
var/emag = "securecrateemag"
|
||||
var/broken = 0
|
||||
var/locked = 1
|
||||
|
||||
/obj/structure/closet/crate/secure/New()
|
||||
..()
|
||||
if(locked)
|
||||
overlays.Cut()
|
||||
overlays += redlight
|
||||
else
|
||||
overlays.Cut()
|
||||
overlays += greenlight
|
||||
|
||||
/obj/structure/closet/crate/secure/can_open()
|
||||
return !locked
|
||||
|
||||
/obj/structure/closet/crate/secure/proc/togglelock(mob/user as mob)
|
||||
if(src.opened)
|
||||
user << "<span class='notice'>Close the crate first.</span>"
|
||||
return
|
||||
if(src.broken)
|
||||
user << "<span class='warning'>The crate appears to be broken.</span>"
|
||||
return
|
||||
if(src.allowed(user))
|
||||
src.locked = !src.locked
|
||||
for(var/mob/O in viewers(user, 3))
|
||||
if((O.client && !( O.blinded )))
|
||||
O << "<span class='notice'>The crate has been [locked ? null : "un"]locked by [user].</span>"
|
||||
overlays.Cut()
|
||||
overlays += locked ? redlight : greenlight
|
||||
else
|
||||
user << "<span class='notice'>Access Denied</span>"
|
||||
|
||||
/obj/structure/closet/crate/secure/verb/verb_togglelock()
|
||||
set src in oview(1) // One square distance
|
||||
set category = "Object"
|
||||
set name = "Toggle Lock"
|
||||
|
||||
if(!usr.canmove || usr.stat || usr.restrained()) // Don't use it if you're not able to! Checks for stuns, ghost and restrain
|
||||
return
|
||||
|
||||
if(ishuman(usr))
|
||||
src.add_fingerprint(usr)
|
||||
src.togglelock(usr)
|
||||
else
|
||||
usr << "<span class='warning'>This mob type can't use this verb.</span>"
|
||||
|
||||
/obj/structure/closet/crate/secure/attack_hand(mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
if(locked)
|
||||
src.togglelock(user)
|
||||
else
|
||||
src.toggle(user)
|
||||
|
||||
/obj/structure/closet/crate/secure/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(is_type_in_list(W, list(/obj/item/weapon/packageWrap, /obj/item/weapon/cable_coil, /obj/item/device/radio/electropack, /obj/item/weapon/wirecutters)))
|
||||
return ..()
|
||||
if(locked && (istype(W, /obj/item/weapon/card/emag)||istype(W, /obj/item/weapon/melee/energy/blade)))
|
||||
overlays.Cut()
|
||||
overlays += emag
|
||||
overlays += sparks
|
||||
spawn(6) overlays -= sparks //Tried lots of stuff but nothing works right. so i have to use this *sadface*
|
||||
playsound(src.loc, "sparks", 60, 1)
|
||||
src.locked = 0
|
||||
src.broken = 1
|
||||
user << "<span class='notice'>You unlock \the [src].</span>"
|
||||
return
|
||||
if(!opened)
|
||||
src.togglelock(user)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/crate/secure/emp_act(severity)
|
||||
for(var/obj/O in src)
|
||||
O.emp_act(severity)
|
||||
@@ -447,23 +218,234 @@
|
||||
src.req_access += pick(get_all_accesses())
|
||||
..()
|
||||
|
||||
/obj/structure/closet/crate/plastic
|
||||
name = "plastic crate"
|
||||
desc = "A rectangular plastic crate."
|
||||
icon_state = "plasticcrate"
|
||||
icon_opened = "plasticcrateopen"
|
||||
icon_closed = "plasticcrate"
|
||||
|
||||
/obj/structure/closet/crate/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
for(var/obj/O in src.contents)
|
||||
del(O)
|
||||
del(src)
|
||||
return
|
||||
if(2.0)
|
||||
for(var/obj/O in src.contents)
|
||||
if(prob(50))
|
||||
del(O)
|
||||
del(src)
|
||||
return
|
||||
if(3.0)
|
||||
if (prob(50))
|
||||
del(src)
|
||||
return
|
||||
/obj/structure/closet/crate/internals
|
||||
desc = "A internals crate."
|
||||
name = "Internals crate"
|
||||
icon_state = "o2crate"
|
||||
icon_opened = "o2crateopen"
|
||||
icon_closed = "o2crate"
|
||||
|
||||
/obj/structure/closet/crate/trashcart
|
||||
desc = "A heavy, metal trashcart with wheels."
|
||||
name = "Trash Cart"
|
||||
icon_state = "trashcart"
|
||||
icon_opened = "trashcartopen"
|
||||
icon_closed = "trashcart"
|
||||
|
||||
/*these aren't needed anymore
|
||||
/obj/structure/closet/crate/hat
|
||||
desc = "A crate filled with Valuable Collector's Hats!."
|
||||
name = "Hat Crate"
|
||||
icon_state = "crate"
|
||||
icon_opened = "crateopen"
|
||||
icon_closed = "crate"
|
||||
|
||||
/obj/structure/closet/crate/contraband
|
||||
name = "Poster crate"
|
||||
desc = "A random assortment of posters manufactured by providers NOT listed under Nanotrasen's whitelist."
|
||||
icon_state = "crate"
|
||||
icon_opened = "crateopen"
|
||||
icon_closed = "crate"
|
||||
*/
|
||||
|
||||
/obj/structure/closet/crate/medical
|
||||
desc = "A medical crate."
|
||||
name = "Medical crate"
|
||||
icon_state = "medicalcrate"
|
||||
icon_opened = "medicalcrateopen"
|
||||
icon_closed = "medicalcrate"
|
||||
|
||||
/obj/structure/closet/crate/rcd
|
||||
desc = "A crate for the storage of the RCD."
|
||||
name = "RCD crate"
|
||||
icon_state = "crate"
|
||||
icon_opened = "crateopen"
|
||||
icon_closed = "crate"
|
||||
|
||||
/obj/structure/closet/crate/rcd/New()
|
||||
..()
|
||||
new /obj/item/weapon/rcd_ammo(src)
|
||||
new /obj/item/weapon/rcd_ammo(src)
|
||||
new /obj/item/weapon/rcd_ammo(src)
|
||||
new /obj/item/weapon/rcd(src)
|
||||
|
||||
/obj/structure/closet/crate/freezer
|
||||
desc = "A freezer."
|
||||
name = "Freezer"
|
||||
icon_state = "freezer"
|
||||
icon_opened = "freezeropen"
|
||||
icon_closed = "freezer"
|
||||
var/target_temp = T0C - 40
|
||||
var/cooling_power = 40
|
||||
|
||||
return_air()
|
||||
var/datum/gas_mixture/gas = (..())
|
||||
if(!gas) return null
|
||||
var/datum/gas_mixture/newgas = new/datum/gas_mixture()
|
||||
newgas.oxygen = gas.oxygen
|
||||
newgas.carbon_dioxide = gas.carbon_dioxide
|
||||
newgas.nitrogen = gas.nitrogen
|
||||
newgas.toxins = gas.toxins
|
||||
newgas.volume = gas.volume
|
||||
newgas.temperature = gas.temperature
|
||||
if(newgas.temperature <= target_temp) return
|
||||
|
||||
if((newgas.temperature - cooling_power) > target_temp)
|
||||
newgas.temperature -= cooling_power
|
||||
else
|
||||
newgas.temperature = target_temp
|
||||
return newgas
|
||||
|
||||
|
||||
/obj/structure/closet/crate/bin
|
||||
desc = "A large bin."
|
||||
name = "Large bin"
|
||||
icon_state = "largebin"
|
||||
icon_opened = "largebinopen"
|
||||
icon_closed = "largebin"
|
||||
|
||||
/obj/structure/closet/crate/radiation
|
||||
desc = "A crate with a radiation sign on it."
|
||||
name = "Radioactive gear crate"
|
||||
icon_state = "radiation"
|
||||
icon_opened = "radiationopen"
|
||||
icon_closed = "radiation"
|
||||
|
||||
/obj/structure/closet/crate/radiation/New()
|
||||
..()
|
||||
new /obj/item/clothing/suit/radiation(src)
|
||||
new /obj/item/clothing/head/radiation(src)
|
||||
new /obj/item/clothing/suit/radiation(src)
|
||||
new /obj/item/clothing/head/radiation(src)
|
||||
new /obj/item/clothing/suit/radiation(src)
|
||||
new /obj/item/clothing/head/radiation(src)
|
||||
new /obj/item/clothing/suit/radiation(src)
|
||||
new /obj/item/clothing/head/radiation(src)
|
||||
|
||||
/obj/structure/closet/crate/secure/weapon
|
||||
desc = "A secure weapons crate."
|
||||
name = "Weapons crate"
|
||||
icon_state = "weaponcrate"
|
||||
icon_opened = "weaponcrateopen"
|
||||
icon_closed = "weaponcrate"
|
||||
|
||||
/obj/structure/closet/crate/secure/plasma
|
||||
desc = "A secure plasma crate."
|
||||
name = "Plasma crate"
|
||||
icon_state = "plasmacrate"
|
||||
icon_opened = "plasmacrateopen"
|
||||
icon_closed = "plasmacrate"
|
||||
|
||||
/obj/structure/closet/crate/secure/gear
|
||||
desc = "A secure gear crate."
|
||||
name = "Gear crate"
|
||||
icon_state = "secgearcrate"
|
||||
icon_opened = "secgearcrateopen"
|
||||
icon_closed = "secgearcrate"
|
||||
|
||||
/obj/structure/closet/crate/secure/hydrosec
|
||||
desc = "A crate with a lock on it, painted in the scheme of the station's botanists."
|
||||
name = "secure hydroponics crate"
|
||||
icon_state = "hydrosecurecrate"
|
||||
icon_opened = "hydrosecurecrateopen"
|
||||
icon_closed = "hydrosecurecrate"
|
||||
|
||||
/obj/structure/closet/crate/secure/bin
|
||||
desc = "A secure bin."
|
||||
name = "Secure bin"
|
||||
icon_state = "largebins"
|
||||
icon_opened = "largebinsopen"
|
||||
icon_closed = "largebins"
|
||||
redlight = "largebinr"
|
||||
greenlight = "largebing"
|
||||
sparks = "largebinsparks"
|
||||
emag = "largebinemag"
|
||||
|
||||
/obj/structure/closet/crate/large
|
||||
name = "large crate"
|
||||
desc = "A hefty metal crate."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "largemetal"
|
||||
icon_opened = "largemetalopen"
|
||||
icon_closed = "largemetal"
|
||||
|
||||
/obj/structure/closet/crate/large/close()
|
||||
. = ..()
|
||||
if (.)//we can hold up to one large item
|
||||
var/found = 0
|
||||
for(var/obj/structure/S in src.loc)
|
||||
if(S == src)
|
||||
continue
|
||||
if(!S.anchored)
|
||||
found = 1
|
||||
S.loc = src
|
||||
break
|
||||
if(!found)
|
||||
for(var/obj/machinery/M in src.loc)
|
||||
if(!M.anchored)
|
||||
M.loc = src
|
||||
break
|
||||
return
|
||||
|
||||
/obj/structure/closet/crate/secure/large
|
||||
name = "large crate"
|
||||
desc = "A hefty metal crate with an electronic locking system."
|
||||
icon = 'icons/obj/storage.dmi'
|
||||
icon_state = "largemetal"
|
||||
icon_opened = "largemetalopen"
|
||||
icon_closed = "largemetal"
|
||||
redlight = "largemetalr"
|
||||
greenlight = "largemetalg"
|
||||
|
||||
/obj/structure/closet/crate/secure/large/close()
|
||||
. = ..()
|
||||
if (.)//we can hold up to one large item
|
||||
var/found = 0
|
||||
for(var/obj/structure/S in src.loc)
|
||||
if(S == src)
|
||||
continue
|
||||
if(!S.anchored)
|
||||
found = 1
|
||||
S.loc = src
|
||||
break
|
||||
if(!found)
|
||||
for(var/obj/machinery/M in src.loc)
|
||||
if(!M.anchored)
|
||||
M.loc = src
|
||||
break
|
||||
return
|
||||
|
||||
//fluff variant
|
||||
/obj/structure/closet/crate/secure/large/reinforced
|
||||
desc = "A hefty, reinforced metal crate with an electronic locking system."
|
||||
icon_state = "largermetal"
|
||||
icon_opened = "largermetalopen"
|
||||
icon_closed = "largermetal"
|
||||
|
||||
/obj/structure/closet/crate/hydroponics
|
||||
name = "Hydroponics crate"
|
||||
desc = "All you need to destroy those pesky weeds and pests."
|
||||
icon_state = "hydrocrate"
|
||||
icon_opened = "hydrocrateopen"
|
||||
icon_closed = "hydrocrate"
|
||||
|
||||
/obj/structure/closet/crate/hydroponics/prespawned
|
||||
//This exists so the prespawned hydro crates spawn with their contents.
|
||||
|
||||
New()
|
||||
..()
|
||||
new /obj/item/weapon/reagent_containers/spray/plantbgone(src)
|
||||
new /obj/item/weapon/reagent_containers/spray/plantbgone(src)
|
||||
new /obj/item/weapon/minihoe(src)
|
||||
// new /obj/item/weapon/weedspray(src)
|
||||
// new /obj/item/weapon/weedspray(src)
|
||||
// new /obj/item/weapon/pestspray(src)
|
||||
// new /obj/item/weapon/pestspray(src)
|
||||
// new /obj/item/weapon/pestspray(src)
|
||||
@@ -73,6 +73,11 @@
|
||||
..()
|
||||
icon_state = "snowbush[rand(1, 6)]"
|
||||
|
||||
/obj/structure/flora/pottedplant
|
||||
name = "potted plant"
|
||||
icon = 'icons/obj/plants.dmi'
|
||||
icon_state = "plant-26"
|
||||
|
||||
//newbushes
|
||||
|
||||
/obj/structure/flora/ausbushes
|
||||
|
||||
@@ -13,11 +13,10 @@
|
||||
icon_state = "bed"
|
||||
var/mob/living/buckled_mob
|
||||
|
||||
/obj/structure/stool/psychbed
|
||||
/obj/structure/stool/bed/psych
|
||||
name = "psych bed"
|
||||
desc = "For prime comfort during psychiatric evaluations."
|
||||
icon_state = "psychbed"
|
||||
var/mob/living/buckled_mob
|
||||
|
||||
/obj/structure/stool/bed/alien
|
||||
name = "resting contraption"
|
||||
|
||||
@@ -48,29 +48,30 @@
|
||||
|
||||
|
||||
/obj/structure/table/update_icon()
|
||||
if(flipped)
|
||||
var/type = 0
|
||||
var/tabledirs = 0
|
||||
for(var/direction in list(turn(dir,90), turn(dir,-90)) )
|
||||
var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,direction))
|
||||
if (T && T.flipped)
|
||||
type++
|
||||
tabledirs |= direction
|
||||
var/base = "table"
|
||||
if (istype(src, /obj/structure/table/woodentable))
|
||||
base = "wood"
|
||||
if (istype(src, /obj/structure/table/reinforced))
|
||||
base = "rtable"
|
||||
|
||||
icon_state = "[base]flip[type]"
|
||||
if (type==1)
|
||||
if (tabledirs & turn(dir,90))
|
||||
icon_state = icon_state+"-"
|
||||
if (tabledirs & turn(dir,-90))
|
||||
icon_state = icon_state+"+"
|
||||
return 1
|
||||
|
||||
spawn(2) //So it properly updates when deleting
|
||||
|
||||
if(flipped)
|
||||
var/type = 0
|
||||
var/tabledirs = 0
|
||||
for(var/direction in list(turn(dir,90), turn(dir,-90)) )
|
||||
var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,direction))
|
||||
if (T && T.flipped && T.dir == src.dir)
|
||||
type++
|
||||
tabledirs |= direction
|
||||
var/base = "table"
|
||||
if (istype(src, /obj/structure/table/woodentable))
|
||||
base = "wood"
|
||||
if (istype(src, /obj/structure/table/reinforced))
|
||||
base = "rtable"
|
||||
|
||||
icon_state = "[base]flip[type]"
|
||||
if (type==1)
|
||||
if (tabledirs & turn(dir,90))
|
||||
icon_state = icon_state+"-"
|
||||
if (tabledirs & turn(dir,-90))
|
||||
icon_state = icon_state+"+"
|
||||
return 1
|
||||
|
||||
var/dir_sum = 0
|
||||
for(var/direction in list(1,2,4,8,5,6,9,10))
|
||||
var/skip_sum = 0
|
||||
@@ -348,6 +349,7 @@
|
||||
|
||||
|
||||
/obj/structure/table/attackby(obj/item/W as obj, mob/user as mob)
|
||||
if (!W) return
|
||||
if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2)
|
||||
var/obj/item/weapon/grab/G = W
|
||||
if (istype(G.affecting, /mob/living))
|
||||
@@ -392,29 +394,36 @@
|
||||
return
|
||||
|
||||
/obj/structure/table/proc/straight_table_check(var/direction)
|
||||
var/turf/left = get_step(src,turn(direction,90))
|
||||
var/turf/right = get_step(src,turn(direction,-90))
|
||||
var/turf/next = get_step(src,direction)
|
||||
if(locate(/obj/structure/table,left) || locate(/obj/structure/table,right))
|
||||
return 0
|
||||
var/obj/structure/table/T = locate(/obj/structure/table, next)
|
||||
var/obj/structure/table/T
|
||||
for(var/angle in list(-90,90))
|
||||
T = locate() in get_step(src.loc,turn(direction,angle))
|
||||
if(T && !T.flipped)
|
||||
return 0
|
||||
T = locate() in get_step(src.loc,direction)
|
||||
if (!T || T.flipped)
|
||||
return 1
|
||||
if (istype(T,/obj/structure/table/reinforced/))
|
||||
var/obj/structure/table/reinforced/R = T
|
||||
if (R.status == 2)
|
||||
return 0
|
||||
if (!T)
|
||||
return 1
|
||||
else
|
||||
return T.straight_table_check(direction)
|
||||
return T.straight_table_check(direction)
|
||||
|
||||
/obj/structure/table/verb/can_touch(var/mob/user)
|
||||
if (!user)
|
||||
return 0
|
||||
if (user.stat) //zombie goasts go away
|
||||
return 0
|
||||
if (issilicon(user))
|
||||
user << "<span class='notice'>You need hands for this.</span>"
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/structure/table/verb/do_flip()
|
||||
set name = "Flip table"
|
||||
set desc = "Flips a non-reinforced table"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if (issilicon(usr))
|
||||
usr << "<span class='notice'>You need hands for this.</span>"
|
||||
if (!can_touch(usr))
|
||||
return
|
||||
if(!flip(get_cardinal_dir(usr,src)))
|
||||
usr << "<span class='notice'>It won't budge.</span>"
|
||||
@@ -422,21 +431,38 @@
|
||||
usr.visible_message("<span class='warning'>[usr] flips \the [src]!</span>")
|
||||
return
|
||||
|
||||
/obj/structure/table/proc/unflipping_check(var/direction)
|
||||
for(var/mob/M in oview(src,0))
|
||||
return 0
|
||||
|
||||
var/list/L = list()
|
||||
if(direction)
|
||||
L.Add(direction)
|
||||
else
|
||||
L.Add(turn(src.dir,-90))
|
||||
L.Add(turn(src.dir,90))
|
||||
for(var/new_dir in L)
|
||||
var/obj/structure/table/T = locate() in get_step(src.loc,new_dir)
|
||||
if(T)
|
||||
if(T.flipped && T.dir == src.dir && !T.unflipping_check(new_dir))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/structure/table/proc/do_put()
|
||||
set name = "Put table back"
|
||||
set desc = "Puts flipped table back"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if (!unflip())
|
||||
usr << "<span class='notice'>It won't budge.</span>"
|
||||
if (!can_touch(usr))
|
||||
return
|
||||
|
||||
if (!unflipping_check())
|
||||
usr << "<span class='notice'>It won't budge.</span>"
|
||||
return
|
||||
unflip()
|
||||
|
||||
/obj/structure/table/proc/flip(var/direction)
|
||||
if (flipped)
|
||||
return 0
|
||||
|
||||
if( !straight_table_check(turn(direction,90)) || !straight_table_check(turn(direction,-90)) )
|
||||
return 0
|
||||
|
||||
@@ -455,8 +481,8 @@
|
||||
flipped = 1
|
||||
flags |= ON_BORDER
|
||||
for(var/D in list(turn(direction, 90), turn(direction, -90)))
|
||||
if(locate(/obj/structure/table,get_step(src,D)))
|
||||
var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,D))
|
||||
var/obj/structure/table/T = locate() in get_step(src,D)
|
||||
if(T && !T.flipped)
|
||||
T.flip(direction)
|
||||
update_icon()
|
||||
update_adjacent()
|
||||
@@ -464,16 +490,6 @@
|
||||
return 1
|
||||
|
||||
/obj/structure/table/proc/unflip()
|
||||
if (!flipped)
|
||||
return 0
|
||||
|
||||
var/can_flip = 1
|
||||
for (var/mob/A in oview(src,0))//src.loc)
|
||||
if (istype(A))
|
||||
can_flip = 0
|
||||
if (!can_flip)
|
||||
return 0
|
||||
|
||||
verbs -=/obj/structure/table/proc/do_put
|
||||
verbs +=/obj/structure/table/verb/do_flip
|
||||
|
||||
@@ -481,8 +497,8 @@
|
||||
flipped = 0
|
||||
flags &= ~ON_BORDER
|
||||
for(var/D in list(turn(dir, 90), turn(dir, -90)))
|
||||
if(locate(/obj/structure/table,get_step(src,D)))
|
||||
var/obj/structure/table/T = locate(/obj/structure/table,get_step(src,D))
|
||||
var/obj/structure/table/T = locate() in get_step(src.loc,D)
|
||||
if(T && T.flipped && T.dir == src.dir)
|
||||
T.unflip()
|
||||
update_icon()
|
||||
update_adjacent()
|
||||
@@ -645,4 +661,4 @@
|
||||
del(src)
|
||||
|
||||
/obj/structure/rack/attack_tk() // no telehulk sorry
|
||||
return
|
||||
return
|
||||
@@ -99,6 +99,16 @@ obj/structure/ex_act(severity)
|
||||
|
||||
|
||||
|
||||
/obj/structure/transit_tube/Bumped(mob/AM as mob|obj)
|
||||
var/obj/structure/transit_tube/T = locate() in AM.loc
|
||||
if(T)
|
||||
AM << "<span class='warning'>The tube's support pylons block your way.</span>"
|
||||
return ..()
|
||||
else
|
||||
AM.loc = src.loc
|
||||
AM << "<span class='info'>You slip under the tube.</span>"
|
||||
|
||||
|
||||
/obj/structure/transit_tube/station/New(loc)
|
||||
..(loc)
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
var/ini_dir = null
|
||||
var/state = 0
|
||||
var/reinf = 0
|
||||
var/basestate
|
||||
var/shardtype = /obj/item/weapon/shard
|
||||
// var/silicate = 0 // number of units of silicate
|
||||
// var/icon/silicateIcon = null // the silicated icon
|
||||
|
||||
@@ -219,11 +221,11 @@
|
||||
var/index = null
|
||||
index = 0
|
||||
while(index < 2)
|
||||
new /obj/item/weapon/shard(loc)
|
||||
new shardtype(loc)
|
||||
if(reinf) new /obj/item/stack/rods(loc)
|
||||
index++
|
||||
else
|
||||
new /obj/item/weapon/shard(loc)
|
||||
new shardtype(loc)
|
||||
if(reinf) new /obj/item/stack/rods(loc)
|
||||
del(src)
|
||||
return
|
||||
@@ -282,19 +284,9 @@
|
||||
/obj/structure/window/New(Loc,re=0)
|
||||
..()
|
||||
|
||||
if(re) reinf = re
|
||||
// if(re) reinf = re
|
||||
|
||||
ini_dir = dir
|
||||
if(reinf)
|
||||
icon_state = "rwindow"
|
||||
desc = "A reinforced window."
|
||||
name = "reinforced window"
|
||||
state = 2*anchored
|
||||
health = 40
|
||||
if(opacity)
|
||||
icon_state = "twindow"
|
||||
else
|
||||
icon_state = "window"
|
||||
|
||||
update_nearby_tiles(need_rebuild=1)
|
||||
update_nearby_icons()
|
||||
@@ -354,12 +346,12 @@
|
||||
if(abs(x-W.x)-abs(y-W.y) ) //doesn't count windows, placed diagonally to src
|
||||
junction |= get_dir(src,W)
|
||||
if(opacity)
|
||||
icon_state = "twindow[junction]"
|
||||
icon_state = "[basestate][junction]"
|
||||
else
|
||||
if(reinf)
|
||||
icon_state = "rwindow[junction]"
|
||||
icon_state = "[basestate][junction]"
|
||||
else
|
||||
icon_state = "window[junction]"
|
||||
icon_state = "[basestate][junction]"
|
||||
|
||||
return
|
||||
|
||||
@@ -371,18 +363,53 @@
|
||||
|
||||
|
||||
/obj/structure/window/basic
|
||||
desc = "It looks thin and flimsy. A few knocks with... anything, really should shatter it."
|
||||
icon_state = "window"
|
||||
basestate = "window"
|
||||
|
||||
/obj/structure/window/plasmabasic
|
||||
name = "plasma window"
|
||||
desc = "A plasma-glass alloy window. It looks insanely tough to break. It appears it's also insanely tough to burn through."
|
||||
basestate = "plasmawindow"
|
||||
icon_state = "plasmawindow"
|
||||
shardtype = /obj/item/weapon/shard/plasma
|
||||
health = 120
|
||||
|
||||
/obj/structure/window/plasmabasic/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature > T0C + 32000)
|
||||
hit(round(exposed_volume / 1000), 0)
|
||||
..()
|
||||
|
||||
/obj/structure/window/plasmareinforced
|
||||
name = "reinforced plasma window"
|
||||
desc = "A plasma-glass alloy window, with rods supporting it. It looks hopelessly tough to break. It also looks completely fireproof, considering how basic plasma windows are insanely fireproof."
|
||||
basestate = "plasmarwindow"
|
||||
icon_state = "plasmarwindow"
|
||||
shardtype = /obj/item/weapon/shard/plasma
|
||||
reinf = 1
|
||||
health = 160
|
||||
|
||||
/obj/structure/window/plasmareinforced/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
return
|
||||
|
||||
/obj/structure/window/reinforced
|
||||
name = "reinforced window"
|
||||
desc = "It looks rather strong. Might take a few good hits to shatter it."
|
||||
icon_state = "rwindow"
|
||||
basestate = "rwindow"
|
||||
health = 40
|
||||
reinf = 1
|
||||
|
||||
/obj/structure/window/reinforced/tinted
|
||||
name = "tinted window"
|
||||
desc = "It looks rather strong and opaque. Might take a few good hits to shatter it."
|
||||
icon_state = "twindow"
|
||||
basestate = "twindow"
|
||||
opacity = 1
|
||||
|
||||
/obj/structure/window/reinforced/tinted/frosted
|
||||
name = "frosted window"
|
||||
icon_state = "fwindow"
|
||||
desc = "It looks rather strong and frosted over. Looks like it might take a few less hits then a normal reinforced window."
|
||||
icon_state = "fwindow"
|
||||
basestate = "fwindow"
|
||||
health = 30
|
||||
@@ -1,196 +0,0 @@
|
||||
//trees
|
||||
/obj/structure/flora/tree
|
||||
name = "tree"
|
||||
anchored = 1
|
||||
density = 1
|
||||
pixel_x = -16
|
||||
layer = 9
|
||||
|
||||
/obj/structure/flora/tree/pine
|
||||
name = "pine tree"
|
||||
icon = 'icons/obj/flora/pinetrees.dmi'
|
||||
icon_state = "pine_1"
|
||||
|
||||
/obj/structure/flora/tree/pine/New()
|
||||
icon_state = "pine_[rand(1, 3)]"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/tree/pine/xmas
|
||||
name = "xmas tree"
|
||||
icon = 'icons/obj/flora/pinetrees.dmi'
|
||||
icon_state = "pine_c"
|
||||
|
||||
/obj/structure/flora/tree/pine/xmas/New()
|
||||
..()
|
||||
icon_state = "pine_c"
|
||||
|
||||
/obj/structure/flora/tree/dead
|
||||
icon = 'icons/obj/flora/deadtrees.dmi'
|
||||
icon_state = "tree_1"
|
||||
|
||||
/obj/structure/flora/tree/dead/New()
|
||||
icon_state = "tree_[rand(1, 6)]"
|
||||
..()
|
||||
|
||||
|
||||
//grass
|
||||
/obj/structure/flora/grass
|
||||
name = "grass"
|
||||
icon = 'icons/obj/flora/snowflora.dmi'
|
||||
anchored = 1
|
||||
|
||||
/obj/structure/flora/grass/brown
|
||||
icon_state = "snowgrass1bb"
|
||||
|
||||
/obj/structure/flora/grass/brown/New()
|
||||
icon_state = "snowgrass[rand(1, 3)]bb"
|
||||
..()
|
||||
|
||||
|
||||
/obj/structure/flora/grass/green
|
||||
icon_state = "snowgrass1gb"
|
||||
|
||||
/obj/structure/flora/grass/green/New()
|
||||
icon_state = "snowgrass[rand(1, 3)]gb"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/grass/both
|
||||
icon_state = "snowgrassall1"
|
||||
|
||||
/obj/structure/flora/grass/both/New()
|
||||
icon_state = "snowgrassall[rand(1, 3)]"
|
||||
..()
|
||||
|
||||
|
||||
//bushes
|
||||
/obj/structure/flora/bush
|
||||
name = "bush"
|
||||
icon = 'icons/obj/flora/snowflora.dmi'
|
||||
icon_state = "snowbush1"
|
||||
anchored = 1
|
||||
|
||||
/obj/structure/flora/bush/New()
|
||||
icon_state = "snowbush[rand(1, 6)]"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/pottedplant
|
||||
name = "potted plant"
|
||||
icon = 'icons/obj/plants.dmi'
|
||||
icon_state = "plant-26"
|
||||
|
||||
//newbushes
|
||||
|
||||
/obj/structure/flora/ausbushes
|
||||
name = "bush"
|
||||
icon = 'icons/obj/flora/ausflora.dmi'
|
||||
icon_state = "firstbush_1"
|
||||
anchored = 1
|
||||
|
||||
/obj/structure/flora/ausbushes/New()
|
||||
icon_state = "firstbush_[rand(1, 4)]"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/ausbushes/reedbush
|
||||
icon_state = "reedbush_1"
|
||||
|
||||
/obj/structure/flora/ausbushes/reedbush/New()
|
||||
icon_state = "reedbush_[rand(1, 4)]"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/ausbushes/leafybush
|
||||
icon_state = "leafybush_1"
|
||||
|
||||
/obj/structure/flora/ausbushes/leafybush/New()
|
||||
icon_state = "leafybush_[rand(1, 3)]"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/ausbushes/palebush
|
||||
icon_state = "palebush_1"
|
||||
|
||||
/obj/structure/flora/ausbushes/palebush/New()
|
||||
icon_state = "palebush_[rand(1, 4)]"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/ausbushes/stalkybush
|
||||
icon_state = "stalkybush_1"
|
||||
|
||||
/obj/structure/flora/ausbushes/stalkybush/New()
|
||||
icon_state = "stalkybush_[rand(1, 3)]"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/ausbushes/grassybush
|
||||
icon_state = "grassybush_1"
|
||||
|
||||
/obj/structure/flora/ausbushes/grassybush/New()
|
||||
icon_state = "grassybush_[rand(1, 4)]"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/ausbushes/fernybush
|
||||
icon_state = "fernybush_1"
|
||||
|
||||
/obj/structure/flora/ausbushes/fernybush/New()
|
||||
icon_state = "fernybush_[rand(1, 3)]"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/ausbushes/sunnybush
|
||||
icon_state = "sunnybush_1"
|
||||
|
||||
/obj/structure/flora/ausbushes/sunnybush/New()
|
||||
icon_state = "sunnybush_[rand(1, 3)]"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/ausbushes/genericbush
|
||||
icon_state = "genericbush_1"
|
||||
|
||||
/obj/structure/flora/ausbushes/genericbush/New()
|
||||
icon_state = "genericbush_[rand(1, 4)]"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/ausbushes/pointybush
|
||||
icon_state = "pointybush_1"
|
||||
|
||||
/obj/structure/flora/ausbushes/pointybush/New()
|
||||
icon_state = "pointybush_[rand(1, 4)]"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/ausbushes/lavendergrass
|
||||
icon_state = "lavendergrass_1"
|
||||
|
||||
/obj/structure/flora/ausbushes/lavendergrass/New()
|
||||
icon_state = "lavendergrass_[rand(1, 4)]"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/ausbushes/ywflowers
|
||||
icon_state = "ywflowers_1"
|
||||
|
||||
/obj/structure/flora/ausbushes/ywflowers/New()
|
||||
icon_state = "ywflowers_[rand(1, 3)]"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/ausbushes/brflowers
|
||||
icon_state = "brflowers_1"
|
||||
|
||||
/obj/structure/flora/ausbushes/brflowers/New()
|
||||
icon_state = "brflowers_[rand(1, 3)]"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/ausbushes/ppflowers
|
||||
icon_state = "ppflowers_1"
|
||||
|
||||
/obj/structure/flora/ausbushes/ppflowers/New()
|
||||
icon_state = "ppflowers_[rand(1, 4)]"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/ausbushes/sparsegrass
|
||||
icon_state = "sparsegrass_1"
|
||||
|
||||
/obj/structure/flora/ausbushes/sparsegrass/New()
|
||||
icon_state = "sparsegrass_[rand(1, 3)]"
|
||||
..()
|
||||
|
||||
/obj/structure/flora/ausbushes/fullgrass
|
||||
icon_state = "fullgrass_1"
|
||||
|
||||
/obj/structure/flora/ausbushes/fullgrass/New()
|
||||
icon_state = "fullgrass_[rand(1, 3)]"
|
||||
..()
|
||||
@@ -46,6 +46,8 @@ var/global/normal_ooc_colour = "#002eb8"
|
||||
display_colour = "#0099cc" //light blue
|
||||
if(holder.rights & R_MOD && !(holder.rights & R_ADMIN))
|
||||
display_colour = "#184880" //dark blue
|
||||
if(holder.rights & R_DEBUG && !(holder.rights & R_ADMIN))
|
||||
display_colour = "#1b521f" //dark green
|
||||
else if(holder.rights & R_ADMIN)
|
||||
if(config.allow_admin_ooccolor)
|
||||
display_colour = src.prefs.ooccolor
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
datum/admins/proc/DB_ban_record(var/bantype, var/mob/banned_mob, var/duration = -1, var/reason, var/job = "", var/rounds = 0, var/banckey = null)
|
||||
|
||||
if(!check_rights(R_BAN)) return
|
||||
if(!check_rights(R_MOD,0) && !check_rights(R_BAN)) return
|
||||
|
||||
establish_db_connection()
|
||||
if(!dbcon.IsConnected())
|
||||
|
||||
@@ -806,7 +806,7 @@ var/global/floorIsLava = 0
|
||||
set desc="Delay the game start/end"
|
||||
set name="Delay"
|
||||
|
||||
if(!check_rights(R_ADMIN)) return
|
||||
if(!check_rights(R_SERVER)) return
|
||||
if (!ticker || ticker.current_state != GAME_STATE_PREGAME)
|
||||
ticker.delay_end = !ticker.delay_end
|
||||
log_admin("[key_name(usr)] [ticker.delay_end ? "delayed the round end" : "has made the round end normally"].")
|
||||
|
||||
@@ -69,7 +69,10 @@ var/list/admin_verbs_admin = list(
|
||||
/client/proc/check_customitem_activity,
|
||||
/client/proc/man_up,
|
||||
/client/proc/global_man_up,
|
||||
/client/proc/response_team // Response Teams admin verb
|
||||
/client/proc/response_team, // Response Teams admin verb
|
||||
/client/proc/toggle_antagHUD_use,
|
||||
/client/proc/toggle_antagHUD_restrictions,
|
||||
/client/proc/allow_character_respawn /* Allows a ghost to respawn */
|
||||
)
|
||||
var/list/admin_verbs_ban = list(
|
||||
/client/proc/unban_panel,
|
||||
@@ -139,7 +142,9 @@ var/list/admin_verbs_debug = list(
|
||||
/client/proc/restart_controller,
|
||||
/client/proc/enable_debug_verbs,
|
||||
/client/proc/callproc,
|
||||
/client/proc/toggledebuglogs
|
||||
/client/proc/toggledebuglogs,
|
||||
/client/proc/SDQL_query,
|
||||
/client/proc/SDQL2_query
|
||||
)
|
||||
var/list/admin_verbs_possess = list(
|
||||
/proc/possess,
|
||||
|
||||
@@ -515,7 +515,7 @@
|
||||
//Non-Human (Green)
|
||||
counter = 0
|
||||
jobs += "<table cellpadding='1' cellspacing='0' width='100%'>"
|
||||
jobs += "<tr bgcolor='ccffcc'><th colspan='[length(nonhuman_positions)]'><a href='?src=\ref[src];jobban3=nonhumandept;jobban4=\ref[M]'>Non-human Positions</a></th></tr><tr align='center'>"
|
||||
jobs += "<tr bgcolor='ccffcc'><th colspan='[length(nonhuman_positions)+1]'><a href='?src=\ref[src];jobban3=nonhumandept;jobban4=\ref[M]'>Non-human Positions</a></th></tr><tr align='center'>"
|
||||
for(var/jobPos in nonhuman_positions)
|
||||
if(!jobPos) continue
|
||||
var/datum/job/job = job_master.GetJob(jobPos)
|
||||
@@ -533,11 +533,15 @@
|
||||
counter = 0
|
||||
|
||||
//pAI isn't technically a job, but it goes in here.
|
||||
|
||||
if(jobban_isbanned(M, "pAI"))
|
||||
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=pAI;jobban4=\ref[M]'><font color=red>pAI</font></a></td>"
|
||||
else
|
||||
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=pAI;jobban4=\ref[M]'>pAI</a></td>"
|
||||
|
||||
if(jobban_isbanned(M, "AntagHUD"))
|
||||
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=AntagHUD;jobban4=\ref[M]'><font color=red>AntagHUD</font></a></td>"
|
||||
else
|
||||
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=AntagHUD;jobban4=\ref[M]'>AntagHUD</a></td>"
|
||||
jobs += "</tr></table>"
|
||||
|
||||
//Antagonist (Orange)
|
||||
@@ -685,6 +689,7 @@
|
||||
if(notbannedlist.len) //at least 1 unbanned job exists in joblist so we have stuff to ban.
|
||||
switch(alert("Temporary Ban?",,"Yes","No", "Cancel"))
|
||||
if("Yes")
|
||||
if(!check_rights(R_MOD,0) && !check_rights(R_BAN)) return
|
||||
if(config.ban_legacy_system)
|
||||
usr << "\red Your server is using the legacy banning system, which does not support temporary job bans. Consider upgrading. Aborting ban."
|
||||
return
|
||||
@@ -846,7 +851,7 @@
|
||||
del(M.client)
|
||||
//del(M) // See no reason why to delete mob. Important stuff can be lost. And ban can be lifted before round ends.
|
||||
if("No")
|
||||
if(check_rights(R_BAN)) return
|
||||
if(!check_rights(R_BAN)) return
|
||||
var/reason = input(usr,"Reason?","reason","Griefer") as text|null
|
||||
if(!reason)
|
||||
return
|
||||
@@ -2593,4 +2598,4 @@
|
||||
show_player_info(ckey)
|
||||
if("list")
|
||||
PlayerNotesPage(text2num(href_list["index"]))
|
||||
return
|
||||
return
|
||||
|
||||
@@ -0,0 +1,497 @@
|
||||
|
||||
//Structured Datum Query Language. Basically SQL meets BYOND objects.
|
||||
|
||||
//Note: For use in BS12, need text_starts_with proc, and to modify the action on select to use BS12's object edit command(s).
|
||||
|
||||
/client/proc/SDQL_query(query_text as message)
|
||||
set category = "Admin"
|
||||
if(!check_rights(R_DEBUG)) //Shouldn't happen... but just to be safe.
|
||||
message_admins("\red ERROR: Non-admin [usr.key] attempted to execute a SDQL query!")
|
||||
log_admin("Non-admin [usr.key] attempted to execute a SDQL query!")
|
||||
|
||||
var/list/query_list = SDQL_tokenize(query_text)
|
||||
|
||||
if(query_list.len < 2)
|
||||
if(query_list.len > 0)
|
||||
usr << "\red SDQL: Too few discrete tokens in query \"[query_text]\". Please check your syntax and try again."
|
||||
return
|
||||
|
||||
if(!(lowertext(query_list[1]) in list("select", "delete", "update")))
|
||||
usr << "\red SDQL: Unknown query type: \"[query_list[1]]\" in query \"[query_text]\". Please check your syntax and try again."
|
||||
return
|
||||
|
||||
var/list/types = list()
|
||||
|
||||
var/i
|
||||
for(i = 2; i <= query_list.len; i += 2)
|
||||
types += query_list[i]
|
||||
|
||||
if(i + 1 >= query_list.len || query_list[i + 1] != ",")
|
||||
break
|
||||
|
||||
i++
|
||||
|
||||
var/list/from = list()
|
||||
|
||||
if(i <= query_list.len)
|
||||
if(lowertext(query_list[i]) in list("from", "in"))
|
||||
for(i++; i <= query_list.len; i += 2)
|
||||
from += query_list[i]
|
||||
|
||||
if(i + 1 >= query_list.len || query_list[i + 1] != ",")
|
||||
break
|
||||
|
||||
i++
|
||||
|
||||
if(from.len < 1)
|
||||
from += "world"
|
||||
|
||||
var/list/set_vars = list()
|
||||
|
||||
if(lowertext(query_list[1]) == "update")
|
||||
if(i <= query_list.len && lowertext(query_list[i]) == "set")
|
||||
for(i++; i <= query_list.len; i++)
|
||||
if(i + 2 <= query_list.len && query_list[i + 1] == "=")
|
||||
set_vars += query_list[i]
|
||||
set_vars[query_list[i]] = query_list[i + 2]
|
||||
|
||||
else
|
||||
usr << "\red SDQL: Invalid set parameter in query \"[query_text]\". Please check your syntax and try again."
|
||||
return
|
||||
|
||||
i += 3
|
||||
|
||||
if(i >= query_list.len || query_list[i] != ",")
|
||||
break
|
||||
|
||||
if(set_vars.len < 1)
|
||||
usr << "\red SDQL: Invalid or missing set in query \"[query_text]\". Please check your syntax and try again."
|
||||
return
|
||||
|
||||
var/list/where = list()
|
||||
|
||||
if(i <= query_list.len && lowertext(query_list[i]) == "where")
|
||||
where = query_list.Copy(i + 1)
|
||||
|
||||
var/list/from_objs = list()
|
||||
if("world" in from)
|
||||
from_objs += world
|
||||
else
|
||||
for(var/f in from)
|
||||
if(copytext(f, 1, 2) == "'" || copytext(f, 1, 2) == "\"")
|
||||
from_objs += locate(copytext(f, 2, length(f)))
|
||||
else if(copytext(f, 1, 2) != "/")
|
||||
from_objs += locate(f)
|
||||
else
|
||||
var/f2 = text2path(f)
|
||||
if(text_starts_with(f, "/mob"))
|
||||
for(var/mob/m in world)
|
||||
if(istype(m, f2))
|
||||
from_objs += m
|
||||
|
||||
else if(text_starts_with(f, "/turf/space"))
|
||||
for(var/turf/space/m in world)
|
||||
if(istype(m, f2))
|
||||
from_objs += m
|
||||
|
||||
else if(text_starts_with(f, "/turf/simulated"))
|
||||
for(var/turf/simulated/m in world)
|
||||
if(istype(m, f2))
|
||||
from_objs += m
|
||||
|
||||
else if(text_starts_with(f, "/turf/unsimulated"))
|
||||
for(var/turf/unsimulated/m in world)
|
||||
if(istype(m, f2))
|
||||
from_objs += m
|
||||
|
||||
else if(text_starts_with(f, "/turf"))
|
||||
for(var/turf/m in world)
|
||||
if(istype(m, f2))
|
||||
from_objs += m
|
||||
|
||||
else if(text_starts_with(f, "/area"))
|
||||
for(var/area/m in world)
|
||||
if(istype(m, f2))
|
||||
from_objs += m
|
||||
|
||||
else if(text_starts_with(f, "/obj/item"))
|
||||
for(var/obj/item/m in world)
|
||||
if(istype(m, f2))
|
||||
from_objs += m
|
||||
|
||||
else if(text_starts_with(f, "/obj/machinery"))
|
||||
for(var/obj/machinery/m in world)
|
||||
if(istype(m, f2))
|
||||
from_objs += m
|
||||
|
||||
else if(text_starts_with(f, "/obj"))
|
||||
for(var/obj/m in world)
|
||||
if(istype(m, f2))
|
||||
from_objs += m
|
||||
|
||||
else if(text_starts_with(f, "/atom"))
|
||||
for(var/atom/m in world)
|
||||
if(istype(m, f2))
|
||||
from_objs += m
|
||||
/*
|
||||
else
|
||||
for(var/datum/m in world)
|
||||
if(istype(m, f2))
|
||||
from_objs += m
|
||||
*/
|
||||
|
||||
var/list/objs = list()
|
||||
|
||||
for(var/from_obj in from_objs)
|
||||
if("*" in types)
|
||||
objs += from_obj:contents
|
||||
else
|
||||
for(var/f in types)
|
||||
if(copytext(f, 1, 2) == "'" || copytext(f, 1, 2) == "\"")
|
||||
objs += locate(copytext(f, 2, length(f))) in from_obj
|
||||
else if(copytext(f, 1, 2) != "/")
|
||||
objs += locate(f) in from_obj
|
||||
else
|
||||
var/f2 = text2path(f)
|
||||
if(text_starts_with(f, "/mob"))
|
||||
for(var/mob/m in from_obj)
|
||||
if(istype(m, f2))
|
||||
objs += m
|
||||
|
||||
else if(text_starts_with(f, "/turf/space"))
|
||||
for(var/turf/space/m in from_obj)
|
||||
if(istype(m, f2))
|
||||
objs += m
|
||||
|
||||
else if(text_starts_with(f, "/turf/simulated"))
|
||||
for(var/turf/simulated/m in from_obj)
|
||||
if(istype(m, f2))
|
||||
objs += m
|
||||
|
||||
else if(text_starts_with(f, "/turf/unsimulated"))
|
||||
for(var/turf/unsimulated/m in from_obj)
|
||||
if(istype(m, f2))
|
||||
objs += m
|
||||
|
||||
else if(text_starts_with(f, "/turf"))
|
||||
for(var/turf/m in from_obj)
|
||||
if(istype(m, f2))
|
||||
objs += m
|
||||
|
||||
else if(text_starts_with(f, "/area"))
|
||||
for(var/area/m in from_obj)
|
||||
if(istype(m, f2))
|
||||
objs += m
|
||||
|
||||
else if(text_starts_with(f, "/obj/item"))
|
||||
for(var/obj/item/m in from_obj)
|
||||
if(istype(m, f2))
|
||||
objs += m
|
||||
|
||||
else if(text_starts_with(f, "/obj/machinery"))
|
||||
for(var/obj/machinery/m in from_obj)
|
||||
if(istype(m, f2))
|
||||
objs += m
|
||||
|
||||
else if(text_starts_with(f, "/obj"))
|
||||
for(var/obj/m in from_obj)
|
||||
if(istype(m, f2))
|
||||
objs += m
|
||||
|
||||
else if(text_starts_with(f, "/atom"))
|
||||
for(var/atom/m in from_obj)
|
||||
if(istype(m, f2))
|
||||
objs += m
|
||||
|
||||
else
|
||||
for(var/datum/m in from_obj)
|
||||
if(istype(m, f2))
|
||||
objs += m
|
||||
|
||||
|
||||
for(var/datum/t in objs)
|
||||
var/currently_false = 0
|
||||
for(i = 1, i - 1 < where.len, i++)
|
||||
var/v = where[i++]
|
||||
var/compare_op = where[i++]
|
||||
if(!(compare_op in list("==", "=", "<>", "<", ">", "<=", ">=", "!=")))
|
||||
usr << "\red SDQL: Unknown comparison operator [compare_op] in where clause following [v] in query \"[query_text]\". Please check your syntax and try again."
|
||||
return
|
||||
|
||||
var/j
|
||||
for(j = i, j <= where.len, j++)
|
||||
if(lowertext(where[j]) in list("and", "or", ";"))
|
||||
break
|
||||
|
||||
if(!currently_false)
|
||||
var/value = SDQL_text2value(t, v)
|
||||
var/result = SDQL_evaluate(t, where.Copy(i, j))
|
||||
|
||||
switch(compare_op)
|
||||
if("=", "==")
|
||||
currently_false = !(value == result)
|
||||
|
||||
if("!=", "<>")
|
||||
currently_false = !(value != result)
|
||||
|
||||
if("<")
|
||||
currently_false = !(value < result)
|
||||
|
||||
if(">")
|
||||
currently_false = !(value > result)
|
||||
|
||||
if("<=")
|
||||
currently_false = !(value <= result)
|
||||
|
||||
if(">=")
|
||||
currently_false = !(value >= result)
|
||||
|
||||
|
||||
if(j > where.len || lowertext(where[j]) == ";")
|
||||
break
|
||||
else if(lowertext(where[j]) == "or")
|
||||
if(currently_false)
|
||||
currently_false = 0
|
||||
else
|
||||
break
|
||||
|
||||
i = j
|
||||
|
||||
if(currently_false)
|
||||
objs -= t
|
||||
|
||||
|
||||
|
||||
usr << "\blue SQDL Query: [query_text]"
|
||||
message_admins("[usr] executed SDQL query: \"[query_text]\".")
|
||||
/*
|
||||
for(var/t in types)
|
||||
usr << "Type: [t]"
|
||||
|
||||
for(var/t in from)
|
||||
usr << "From: [t]"
|
||||
|
||||
for(var/t in set_vars)
|
||||
usr << "Set: [t] = [set_vars[t]]"
|
||||
|
||||
if(where.len)
|
||||
var/where_str = ""
|
||||
for(var/t in where)
|
||||
where_str += "[t] "
|
||||
|
||||
usr << "Where: [where_str]"
|
||||
|
||||
usr << "From objects:"
|
||||
for(var/datum/t in from_objs)
|
||||
usr << t
|
||||
|
||||
usr << "Objects:"
|
||||
for(var/datum/t in objs)
|
||||
usr << t
|
||||
*/
|
||||
switch(lowertext(query_list[1]))
|
||||
if("delete")
|
||||
for(var/datum/t in objs)
|
||||
del t
|
||||
|
||||
if("update")
|
||||
for(var/datum/t in objs)
|
||||
objs[t] = list()
|
||||
for(var/v in set_vars)
|
||||
if(v in t.vars)
|
||||
objs[t][v] = SDQL_text2value(t, set_vars[v])
|
||||
|
||||
for(var/datum/t in objs)
|
||||
for(var/v in objs[t])
|
||||
t.vars[v] = objs[t][v]
|
||||
|
||||
if("select")
|
||||
var/text = ""
|
||||
for(var/datum/t in objs)
|
||||
if(istype(t, /atom))
|
||||
var/atom/a = t
|
||||
|
||||
if(a.x)
|
||||
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t] at ([a.x], [a.y], [a.z])<br>"
|
||||
|
||||
else if(a.loc && a.loc.x)
|
||||
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z])<br>"
|
||||
|
||||
else
|
||||
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t]<br>"
|
||||
|
||||
else
|
||||
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t]<br>"
|
||||
|
||||
//text += "[t]<br>"
|
||||
usr << browse(text, "window=sdql_result")
|
||||
|
||||
|
||||
/client/Topic(href,href_list[],hsrc)
|
||||
if(href_list["SDQL_select"])
|
||||
debug_variables(locate(href_list["SDQL_select"]))
|
||||
|
||||
..()
|
||||
|
||||
|
||||
/proc/SDQL_evaluate(datum/object, list/equation)
|
||||
if(equation.len == 0)
|
||||
return null
|
||||
|
||||
else if(equation.len == 1)
|
||||
return SDQL_text2value(object, equation[1])
|
||||
|
||||
else if(equation[1] == "!")
|
||||
return !SDQL_evaluate(object, equation.Copy(2))
|
||||
|
||||
else if(equation[1] == "-")
|
||||
return -SDQL_evaluate(object, equation.Copy(2))
|
||||
|
||||
|
||||
else
|
||||
usr << "\red SDQL: Sorry, equations not yet supported :("
|
||||
return null
|
||||
|
||||
|
||||
/proc/SDQL_text2value(datum/object, text)
|
||||
if(text2num(text) != null)
|
||||
return text2num(text)
|
||||
else if(text == "null")
|
||||
return null
|
||||
else if(copytext(text, 1, 2) == "'" || copytext(text, 1, 2) == "\"" )
|
||||
return copytext(text, 2, length(text))
|
||||
else if(copytext(text, 1, 2) == "/")
|
||||
return text2path(text)
|
||||
else
|
||||
if(findtext(text, "."))
|
||||
var/split = findtext(text, ".")
|
||||
var/v = copytext(text, 1, split)
|
||||
|
||||
if((v in object.vars) && istype(object.vars[v], /datum))
|
||||
return SDQL_text2value(object.vars[v], copytext(text, split + 1))
|
||||
else
|
||||
return null
|
||||
|
||||
else
|
||||
if(text in object.vars)
|
||||
return object.vars[text]
|
||||
else
|
||||
return null
|
||||
|
||||
|
||||
/proc/text_starts_with(text, start)
|
||||
if(copytext(text, 1, length(start) + 1) == start)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/proc/SDQL_tokenize(query_text)
|
||||
|
||||
var/list/whitespace = list(" ", "\n", "\t")
|
||||
var/list/single = list("(", ")", ",", "+", "-")
|
||||
var/list/multi = list(
|
||||
"=" = list("", "="),
|
||||
"<" = list("", "=", ">"),
|
||||
">" = list("", "="),
|
||||
"!" = list("", "="))
|
||||
|
||||
var/word = ""
|
||||
var/list/query_list = list()
|
||||
var/len = length(query_text)
|
||||
|
||||
for(var/i = 1, i <= len, i++)
|
||||
var/char = copytext(query_text, i, i + 1)
|
||||
|
||||
if(char in whitespace)
|
||||
if(word != "")
|
||||
query_list += word
|
||||
word = ""
|
||||
|
||||
else if(char in single)
|
||||
if(word != "")
|
||||
query_list += word
|
||||
word = ""
|
||||
|
||||
query_list += char
|
||||
|
||||
else if(char in multi)
|
||||
if(word != "")
|
||||
query_list += word
|
||||
word = ""
|
||||
|
||||
var/char2 = copytext(query_text, i + 1, i + 2)
|
||||
|
||||
if(char2 in multi[char])
|
||||
query_list += "[char][char2]"
|
||||
i++
|
||||
|
||||
else
|
||||
query_list += char
|
||||
|
||||
else if(char == "'")
|
||||
if(word != "")
|
||||
usr << "\red SDQL: You have an error in your SDQL syntax, unexpected ' in query: \"<font color=gray>[query_text]</font>\" following \"<font color=gray>[word]</font>\". Please check your syntax, and try again."
|
||||
return null
|
||||
|
||||
word = "'"
|
||||
|
||||
for(i++, i <= len, i++)
|
||||
char = copytext(query_text, i, i + 1)
|
||||
|
||||
if(char == "'")
|
||||
if(copytext(query_text, i + 1, i + 2) == "'")
|
||||
word += "'"
|
||||
i++
|
||||
|
||||
else
|
||||
break
|
||||
|
||||
else
|
||||
word += char
|
||||
|
||||
if(i > len)
|
||||
usr << "\red SDQL: You have an error in your SDQL syntax, unmatched ' in query: \"<font color=gray>[query_text]</font>\". Please check your syntax, and try again."
|
||||
return null
|
||||
|
||||
query_list += "[word]'"
|
||||
word = ""
|
||||
|
||||
else if(char == "\"")
|
||||
if(word != "")
|
||||
usr << "\red SDQL: You have an error in your SDQL syntax, unexpected \" in query: \"<font color=gray>[query_text]</font>\" following \"<font color=gray>[word]</font>\". Please check your syntax, and try again."
|
||||
return null
|
||||
|
||||
word = "\""
|
||||
|
||||
for(i++, i <= len, i++)
|
||||
char = copytext(query_text, i, i + 1)
|
||||
|
||||
if(char == "\"")
|
||||
if(copytext(query_text, i + 1, i + 2) == "'")
|
||||
word += "\""
|
||||
i++
|
||||
|
||||
else
|
||||
break
|
||||
|
||||
else
|
||||
word += char
|
||||
|
||||
if(i > len)
|
||||
usr << "\red SDQL: You have an error in your SDQL syntax, unmatched \" in query: \"<font color=gray>[query_text]</font>\". Please check your syntax, and try again."
|
||||
return null
|
||||
|
||||
query_list += "[word]\""
|
||||
word = ""
|
||||
|
||||
else
|
||||
word += char
|
||||
|
||||
if(word != "")
|
||||
query_list += word
|
||||
|
||||
return query_list
|
||||
@@ -0,0 +1,426 @@
|
||||
|
||||
|
||||
/client/proc/SDQL2_query(query_text as message)
|
||||
set category = "Admin"
|
||||
if(!check_rights(R_DEBUG)) //Shouldn't happen... but just to be safe.
|
||||
message_admins("\red ERROR: Non-admin [usr.key] attempted to execute a SDQL query!")
|
||||
log_admin("Non-admin [usr.key] attempted to execute a SDQL query!")
|
||||
|
||||
if(!query_text || length(query_text) < 1)
|
||||
return
|
||||
|
||||
//world << query_text
|
||||
|
||||
var/list/query_list = SDQL2_tokenize(query_text)
|
||||
|
||||
if(!query_list || query_list.len < 1)
|
||||
return
|
||||
|
||||
var/list/query_tree = SDQL_parse(query_list)
|
||||
|
||||
if(query_tree.len < 1)
|
||||
return
|
||||
|
||||
var/list/from_objs = list()
|
||||
var/list/select_types = list()
|
||||
|
||||
switch(query_tree[1])
|
||||
if("explain")
|
||||
SDQL_testout(query_tree["explain"])
|
||||
return
|
||||
|
||||
if("call")
|
||||
if("on" in query_tree)
|
||||
select_types = query_tree["on"]
|
||||
else
|
||||
return
|
||||
|
||||
if("select", "delete", "update")
|
||||
select_types = query_tree[query_tree[1]]
|
||||
|
||||
from_objs = SDQL_from_objs(query_tree["from"])
|
||||
|
||||
var/list/objs = list()
|
||||
|
||||
for(var/type in select_types)
|
||||
var/char = copytext(type, 1, 2)
|
||||
|
||||
if(char == "/" || char == "*")
|
||||
for(var/from in from_objs)
|
||||
objs += SDQL_get_all(type, from)
|
||||
|
||||
else if(char == "'" || char == "\"")
|
||||
objs += locate(copytext(type, 2, length(type)))
|
||||
|
||||
if("where" in query_tree)
|
||||
var/objs_temp = objs
|
||||
objs = list()
|
||||
for(var/datum/d in objs_temp)
|
||||
if(SDQL_expression(d, query_tree["where"]))
|
||||
objs += d
|
||||
|
||||
//usr << "Query: [query_text]"
|
||||
message_admins("[usr] executed SDQL query: \"[query_text]\".")
|
||||
|
||||
switch(query_tree[1])
|
||||
if("delete")
|
||||
for(var/datum/d in objs)
|
||||
del d
|
||||
|
||||
if("select")
|
||||
var/text = ""
|
||||
for(var/datum/t in objs)
|
||||
if(istype(t, /atom))
|
||||
var/atom/a = t
|
||||
|
||||
if(a.x)
|
||||
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t] at ([a.x], [a.y], [a.z])<br>"
|
||||
|
||||
else if(a.loc && a.loc.x)
|
||||
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t] in [a.loc] at ([a.loc.x], [a.loc.y], [a.loc.z])<br>"
|
||||
|
||||
else
|
||||
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t]<br>"
|
||||
|
||||
else
|
||||
text += "<a href='?src=\ref[t];SDQL_select=\ref[t]'>\ref[t]</a>: [t]<br>"
|
||||
|
||||
usr << browse(text, "window=SDQL-result")
|
||||
|
||||
if("update")
|
||||
if("set" in query_tree)
|
||||
var/list/set_list = query_tree["set"]
|
||||
for(var/datum/d in objs)
|
||||
var/list/vals = list()
|
||||
for(var/v in set_list)
|
||||
if(v in d.vars)
|
||||
vals += v
|
||||
vals[v] = SDQL_expression(d, set_list[v])
|
||||
|
||||
if(istype(d, /turf))
|
||||
for(var/v in vals)
|
||||
if(v == "x" || v == "y" || v == "z")
|
||||
continue
|
||||
|
||||
d.vars[v] = vals[v]
|
||||
|
||||
else
|
||||
for(var/v in vals)
|
||||
d.vars[v] = vals[v]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/proc/SDQL_parse(list/query_list)
|
||||
var/datum/SDQL_parser/parser = new(query_list)
|
||||
var/list/query_tree = parser.parse()
|
||||
|
||||
del(parser)
|
||||
|
||||
return query_tree
|
||||
|
||||
|
||||
|
||||
/proc/SDQL_testout(list/query_tree, indent = 0)
|
||||
var/spaces = ""
|
||||
for(var/s = 0, s < indent, s++)
|
||||
spaces += " "
|
||||
|
||||
for(var/item in query_tree)
|
||||
if(istype(item, /list))
|
||||
world << "[spaces]("
|
||||
SDQL_testout(item, indent + 1)
|
||||
world << "[spaces])"
|
||||
|
||||
else
|
||||
world << "[spaces][item]"
|
||||
|
||||
if(!isnum(item) && query_tree[item])
|
||||
|
||||
if(istype(query_tree[item], /list))
|
||||
world << "[spaces] ("
|
||||
SDQL_testout(query_tree[item], indent + 2)
|
||||
world << "[spaces] )"
|
||||
|
||||
else
|
||||
world << "[spaces] [query_tree[item]]"
|
||||
|
||||
|
||||
|
||||
/proc/SDQL_from_objs(list/tree)
|
||||
if("world" in tree)
|
||||
return list(world)
|
||||
|
||||
var/list/out = list()
|
||||
|
||||
for(var/type in tree)
|
||||
var/char = copytext(type, 1, 2)
|
||||
|
||||
if(char == "/")
|
||||
out += SDQL_get_all(type, world)
|
||||
|
||||
else if(char == "'" || char == "\"")
|
||||
out += locate(copytext(type, 2, length(type)))
|
||||
|
||||
return out
|
||||
|
||||
|
||||
/proc/SDQL_get_all(type, location)
|
||||
var/list/out = list()
|
||||
|
||||
if(type == "*")
|
||||
for(var/datum/d in location)
|
||||
out += d
|
||||
|
||||
return out
|
||||
|
||||
type = text2path(type)
|
||||
|
||||
if(ispath(type, /mob))
|
||||
for(var/mob/d in location)
|
||||
if(istype(d, type))
|
||||
out += d
|
||||
|
||||
else if(ispath(type, /turf))
|
||||
for(var/turf/d in location)
|
||||
if(istype(d, type))
|
||||
out += d
|
||||
|
||||
else if(ispath(type, /obj))
|
||||
for(var/obj/d in location)
|
||||
if(istype(d, type))
|
||||
out += d
|
||||
|
||||
else if(ispath(type, /area))
|
||||
for(var/area/d in location)
|
||||
if(istype(d, type))
|
||||
out += d
|
||||
|
||||
else if(ispath(type, /atom))
|
||||
for(var/atom/d in location)
|
||||
if(istype(d, type))
|
||||
out += d
|
||||
|
||||
else
|
||||
for(var/datum/d in location)
|
||||
if(istype(d, type))
|
||||
out += d
|
||||
|
||||
return out
|
||||
|
||||
|
||||
/proc/SDQL_expression(datum/object, list/expression, start = 1)
|
||||
var/result = 0
|
||||
var/val
|
||||
|
||||
for(var/i = start, i <= expression.len, i++)
|
||||
var/op = ""
|
||||
|
||||
if(i > start)
|
||||
op = expression[i]
|
||||
i++
|
||||
|
||||
var/list/ret = SDQL_value(object, expression, i)
|
||||
val = ret["val"]
|
||||
i = ret["i"]
|
||||
|
||||
if(op != "")
|
||||
switch(op)
|
||||
if("+")
|
||||
result += val
|
||||
if("-")
|
||||
result -= val
|
||||
if("*")
|
||||
result *= val
|
||||
if("/")
|
||||
result /= val
|
||||
if("&")
|
||||
result &= val
|
||||
if("|")
|
||||
result |= val
|
||||
if("^")
|
||||
result ^= val
|
||||
if("=", "==")
|
||||
result = (result == val)
|
||||
if("!=", "<>")
|
||||
result = (result != val)
|
||||
if("<")
|
||||
result = (result < val)
|
||||
if("<=")
|
||||
result = (result <= val)
|
||||
if(">")
|
||||
result = (result > val)
|
||||
if(">=")
|
||||
result = (result >= val)
|
||||
if("and", "&&")
|
||||
result = (result && val)
|
||||
if("or", "||")
|
||||
result = (result || val)
|
||||
else
|
||||
usr << "\red SDQL2: Unknown op [op]"
|
||||
result = null
|
||||
else
|
||||
result = val
|
||||
|
||||
return result
|
||||
|
||||
/proc/SDQL_value(datum/object, list/expression, start = 1)
|
||||
var/i = start
|
||||
var/val = null
|
||||
|
||||
if(i > expression.len)
|
||||
return list("val" = null, "i" = i)
|
||||
|
||||
if(istype(expression[i], /list))
|
||||
val = SDQL_expression(object, expression[i])
|
||||
|
||||
else if(expression[i] == "!")
|
||||
var/list/ret = SDQL_value(object, expression, i + 1)
|
||||
val = !ret["val"]
|
||||
i = ret["i"]
|
||||
|
||||
else if(expression[i] == "~")
|
||||
var/list/ret = SDQL_value(object, expression, i + 1)
|
||||
val = ~ret["val"]
|
||||
i = ret["i"]
|
||||
|
||||
else if(expression[i] == "-")
|
||||
var/list/ret = SDQL_value(object, expression, i + 1)
|
||||
val = -ret["val"]
|
||||
i = ret["i"]
|
||||
|
||||
else if(expression[i] == "null")
|
||||
val = null
|
||||
|
||||
else if(isnum(expression[i]))
|
||||
val = expression[i]
|
||||
|
||||
else if(copytext(expression[i], 1, 2) in list("'", "\""))
|
||||
val = copytext(expression[i], 2, length(expression[i]))
|
||||
|
||||
else
|
||||
val = SDQL_var(object, expression, i)
|
||||
i = expression.len
|
||||
|
||||
return list("val" = val, "i" = i)
|
||||
|
||||
/proc/SDQL_var(datum/object, list/expression, start = 1)
|
||||
|
||||
if(expression[start] in object.vars)
|
||||
|
||||
if(start < expression.len && expression[start + 1] == ".")
|
||||
return SDQL_var(object.vars[expression[start]], expression[start + 2])
|
||||
|
||||
else
|
||||
return object.vars[expression[start]]
|
||||
|
||||
else
|
||||
return null
|
||||
|
||||
/proc/SDQL2_tokenize(query_text)
|
||||
|
||||
var/list/whitespace = list(" ", "\n", "\t")
|
||||
var/list/single = list("(", ")", ",", "+", "-", ".")
|
||||
var/list/multi = list(
|
||||
"=" = list("", "="),
|
||||
"<" = list("", "=", ">"),
|
||||
">" = list("", "="),
|
||||
"!" = list("", "="))
|
||||
|
||||
var/word = ""
|
||||
var/list/query_list = list()
|
||||
var/len = length(query_text)
|
||||
|
||||
for(var/i = 1, i <= len, i++)
|
||||
var/char = copytext(query_text, i, i + 1)
|
||||
|
||||
if(char in whitespace)
|
||||
if(word != "")
|
||||
query_list += word
|
||||
word = ""
|
||||
|
||||
else if(char in single)
|
||||
if(word != "")
|
||||
query_list += word
|
||||
word = ""
|
||||
|
||||
query_list += char
|
||||
|
||||
else if(char in multi)
|
||||
if(word != "")
|
||||
query_list += word
|
||||
word = ""
|
||||
|
||||
var/char2 = copytext(query_text, i + 1, i + 2)
|
||||
|
||||
if(char2 in multi[char])
|
||||
query_list += "[char][char2]"
|
||||
i++
|
||||
|
||||
else
|
||||
query_list += char
|
||||
|
||||
else if(char == "'")
|
||||
if(word != "")
|
||||
usr << "\red SDQL2: You have an error in your SDQL syntax, unexpected ' in query: \"<font color=gray>[query_text]</font>\" following \"<font color=gray>[word]</font>\". Please check your syntax, and try again."
|
||||
return null
|
||||
|
||||
word = "'"
|
||||
|
||||
for(i++, i <= len, i++)
|
||||
char = copytext(query_text, i, i + 1)
|
||||
|
||||
if(char == "'")
|
||||
if(copytext(query_text, i + 1, i + 2) == "'")
|
||||
word += "'"
|
||||
i++
|
||||
|
||||
else
|
||||
break
|
||||
|
||||
else
|
||||
word += char
|
||||
|
||||
if(i > len)
|
||||
usr << "\red SDQL2: You have an error in your SDQL syntax, unmatched ' in query: \"<font color=gray>[query_text]</font>\". Please check your syntax, and try again."
|
||||
return null
|
||||
|
||||
query_list += "[word]'"
|
||||
word = ""
|
||||
|
||||
else if(char == "\"")
|
||||
if(word != "")
|
||||
usr << "\red SDQL2: You have an error in your SDQL syntax, unexpected \" in query: \"<font color=gray>[query_text]</font>\" following \"<font color=gray>[word]</font>\". Please check your syntax, and try again."
|
||||
return null
|
||||
|
||||
word = "\""
|
||||
|
||||
for(i++, i <= len, i++)
|
||||
char = copytext(query_text, i, i + 1)
|
||||
|
||||
if(char == "\"")
|
||||
if(copytext(query_text, i + 1, i + 2) == "'")
|
||||
word += "\""
|
||||
i++
|
||||
|
||||
else
|
||||
break
|
||||
|
||||
else
|
||||
word += char
|
||||
|
||||
if(i > len)
|
||||
usr << "\red SDQL2: You have an error in your SDQL syntax, unmatched \" in query: \"<font color=gray>[query_text]</font>\". Please check your syntax, and try again."
|
||||
return null
|
||||
|
||||
query_list += "[word]\""
|
||||
word = ""
|
||||
|
||||
else
|
||||
word += char
|
||||
|
||||
if(word != "")
|
||||
query_list += word
|
||||
|
||||
return query_list
|
||||
@@ -0,0 +1,531 @@
|
||||
//I'm pretty sure that this is a recursive [s]descent[/s] ascent parser.
|
||||
|
||||
|
||||
|
||||
//Spec
|
||||
|
||||
//////////
|
||||
//
|
||||
// query : select_query | delete_query | update_query | call_query | explain
|
||||
// explain : 'EXPLAIN' query
|
||||
//
|
||||
// select_query : 'SELECT' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
|
||||
// delete_query : 'DELETE' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
|
||||
// update_query : 'UPDATE' select_list [('FROM' | 'IN') from_list] 'SET' assignments ['WHERE' bool_expression]
|
||||
// call_query : 'CALL' call_function ['ON' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]]
|
||||
//
|
||||
// select_list : select_item [',' select_list]
|
||||
// select_item : '*' | select_function | object_type
|
||||
// select_function : count_function
|
||||
// count_function : 'COUNT' '(' '*' ')' | 'COUNT' '(' object_types ')'
|
||||
//
|
||||
// from_list : from_item [',' from_list]
|
||||
// from_item : 'world' | object_type
|
||||
//
|
||||
// call_function : <function name> ['(' [arguments] ')']
|
||||
// arguments : expression [',' arguments]
|
||||
//
|
||||
// object_type : <type path> | string
|
||||
//
|
||||
// assignments : assignment, [',' assignments]
|
||||
// assignment : <variable name> '=' expression
|
||||
// variable : <variable name> | <variable name> '.' variable
|
||||
//
|
||||
// bool_expression : expression comparitor expression [bool_operator bool_expression]
|
||||
// expression : ( unary_expression | '(' expression ')' | value ) [binary_operator expression]
|
||||
// unary_expression : unary_operator ( unary_expression | value | '(' expression ')' )
|
||||
// comparitor : '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>='
|
||||
// value : variable | string | number | 'null'
|
||||
// unary_operator : '!' | '-' | '~'
|
||||
// binary_operator : comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^'
|
||||
// bool_operator : 'AND' | '&&' | 'OR' | '||'
|
||||
//
|
||||
// string : ''' <some text> ''' | '"' <some text > '"'
|
||||
// number : <some digits>
|
||||
//
|
||||
//////////
|
||||
|
||||
/datum/SDQL_parser
|
||||
var/query_type
|
||||
var/error = 0
|
||||
|
||||
var/list/query
|
||||
var/list/tree
|
||||
|
||||
var/list/select_functions = list("count")
|
||||
var/list/boolean_operators = list("and", "or", "&&", "||")
|
||||
var/list/unary_operators = list("!", "-", "~")
|
||||
var/list/binary_operators = list("+", "-", "/", "*", "&", "|", "^")
|
||||
var/list/comparitors = list("=", "==", "!=", "<>", "<", "<=", ">", ">=")
|
||||
|
||||
|
||||
|
||||
/datum/SDQL_parser/New(query_list)
|
||||
query = query_list
|
||||
|
||||
|
||||
|
||||
/datum/SDQL_parser/proc/parse_error(error_message)
|
||||
error = 1
|
||||
usr << "\red SQDL2 Parsing Error: [error_message]"
|
||||
return query.len + 1
|
||||
|
||||
/datum/SDQL_parser/proc/parse()
|
||||
tree = list()
|
||||
query(1, tree)
|
||||
|
||||
if(error)
|
||||
return list()
|
||||
else
|
||||
return tree
|
||||
|
||||
/datum/SDQL_parser/proc/token(i)
|
||||
if(i <= query.len)
|
||||
return query[i]
|
||||
|
||||
else
|
||||
return null
|
||||
|
||||
/datum/SDQL_parser/proc/tokens(i, num)
|
||||
if(i + num <= query.len)
|
||||
return query.Copy(i, i + num)
|
||||
|
||||
else
|
||||
return null
|
||||
|
||||
/datum/SDQL_parser/proc/tokenl(i)
|
||||
return lowertext(token(i))
|
||||
|
||||
|
||||
|
||||
/datum/SDQL_parser/proc
|
||||
|
||||
//query: select_query | delete_query | update_query
|
||||
query(i, list/node)
|
||||
query_type = tokenl(i)
|
||||
|
||||
switch(query_type)
|
||||
if("select")
|
||||
select_query(i, node)
|
||||
|
||||
if("delete")
|
||||
delete_query(i, node)
|
||||
|
||||
if("update")
|
||||
update_query(i, node)
|
||||
|
||||
if("call")
|
||||
call_query(i, node)
|
||||
|
||||
if("explain")
|
||||
node += "explain"
|
||||
node["explain"] = list()
|
||||
query(i + 1, node["explain"])
|
||||
|
||||
|
||||
// select_query: 'SELECT' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
|
||||
select_query(i, list/node)
|
||||
var/list/select = list()
|
||||
i = select_list(i + 1, select)
|
||||
|
||||
node += "select"
|
||||
node["select"] = select
|
||||
|
||||
var/list/from = list()
|
||||
if(tokenl(i) in list("from", "in"))
|
||||
i = from_list(i + 1, from)
|
||||
else
|
||||
from += "world"
|
||||
|
||||
node += "from"
|
||||
node["from"] = from
|
||||
|
||||
if(tokenl(i) == "where")
|
||||
var/list/where = list()
|
||||
i = bool_expression(i + 1, where)
|
||||
|
||||
node += "where"
|
||||
node["where"] = where
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//delete_query: 'DELETE' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]
|
||||
delete_query(i, list/node)
|
||||
var/list/select = list()
|
||||
i = select_list(i + 1, select)
|
||||
|
||||
node += "delete"
|
||||
node["delete"] = select
|
||||
|
||||
var/list/from = list()
|
||||
if(tokenl(i) in list("from", "in"))
|
||||
i = from_list(i + 1, from)
|
||||
else
|
||||
from += "world"
|
||||
|
||||
node += "from"
|
||||
node["from"] = from
|
||||
|
||||
if(tokenl(i) == "where")
|
||||
var/list/where = list()
|
||||
i = bool_expression(i + 1, where)
|
||||
|
||||
node += "where"
|
||||
node["where"] = where
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//update_query: 'UPDATE' select_list [('FROM' | 'IN') from_list] 'SET' assignments ['WHERE' bool_expression]
|
||||
update_query(i, list/node)
|
||||
var/list/select = list()
|
||||
i = select_list(i + 1, select)
|
||||
|
||||
node += "update"
|
||||
node["update"] = select
|
||||
|
||||
var/list/from = list()
|
||||
if(tokenl(i) in list("from", "in"))
|
||||
i = from_list(i + 1, from)
|
||||
else
|
||||
from += "world"
|
||||
|
||||
node += "from"
|
||||
node["from"] = from
|
||||
|
||||
if(tokenl(i) != "set")
|
||||
i = parse_error("UPDATE has misplaced SET")
|
||||
|
||||
var/list/set_assignments = list()
|
||||
i = assignments(i + 1, set_assignments)
|
||||
|
||||
node += "set"
|
||||
node["set"] = set_assignments
|
||||
|
||||
if(tokenl(i) == "where")
|
||||
var/list/where = list()
|
||||
i = bool_expression(i + 1, where)
|
||||
|
||||
node += "where"
|
||||
node["where"] = where
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//call_query: 'CALL' call_function ['ON' select_list [('FROM' | 'IN') from_list] ['WHERE' bool_expression]]
|
||||
call_query(i, list/node)
|
||||
var/list/func = list()
|
||||
i = call_function(i + 1, func)
|
||||
|
||||
node += "call"
|
||||
node["call"] = func
|
||||
|
||||
if(tokenl(i) != "on")
|
||||
return i
|
||||
|
||||
var/list/select = list()
|
||||
i = select_list(i + 1, select)
|
||||
|
||||
node += "on"
|
||||
node["on"] = select
|
||||
|
||||
var/list/from = list()
|
||||
if(tokenl(i) in list("from", "in"))
|
||||
i = from_list(i + 1, from)
|
||||
else
|
||||
from += "world"
|
||||
|
||||
node += "from"
|
||||
node["from"] = from
|
||||
|
||||
if(tokenl(i) == "where")
|
||||
var/list/where = list()
|
||||
i = bool_expression(i + 1, where)
|
||||
|
||||
node += "where"
|
||||
node["where"] = where
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//select_list: select_item [',' select_list]
|
||||
select_list(i, list/node)
|
||||
i = select_item(i, node)
|
||||
|
||||
if(token(i) == ",")
|
||||
i = select_list(i + 1, node)
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//from_list: from_item [',' from_list]
|
||||
from_list(i, list/node)
|
||||
i = from_item(i, node)
|
||||
|
||||
if(token(i) == ",")
|
||||
i = from_list(i + 1, node)
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//assignments: assignment, [',' assignments]
|
||||
assignments(i, list/node)
|
||||
i = assignment(i, node)
|
||||
|
||||
if(token(i) == ",")
|
||||
i = assignments(i + 1, node)
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//select_item: '*' | select_function | object_type
|
||||
select_item(i, list/node)
|
||||
|
||||
if(token(i) == "*")
|
||||
node += "*"
|
||||
i++
|
||||
|
||||
else if(tokenl(i) in select_functions)
|
||||
i = select_function(i, node)
|
||||
|
||||
else
|
||||
i = object_type(i, node)
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//from_item: 'world' | object_type
|
||||
from_item(i, list/node)
|
||||
|
||||
if(token(i) == "world")
|
||||
node += "world"
|
||||
i++
|
||||
|
||||
else
|
||||
i = object_type(i, node)
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//bool_expression: expression [bool_operator bool_expression]
|
||||
bool_expression(i, list/node)
|
||||
|
||||
var/list/bool = list()
|
||||
i = expression(i, bool)
|
||||
|
||||
node[++node.len] = bool
|
||||
|
||||
if(tokenl(i) in boolean_operators)
|
||||
i = bool_operator(i, node)
|
||||
i = bool_expression(i, node)
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//assignment: <variable name> '=' expression
|
||||
assignment(i, list/node)
|
||||
|
||||
node += token(i)
|
||||
|
||||
if(token(i + 1) == "=")
|
||||
var/varname = token(i)
|
||||
node[varname] = list()
|
||||
|
||||
i = expression(i + 2, node[varname])
|
||||
|
||||
else
|
||||
parse_error("Assignment expected, but no = found")
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//variable: <variable name> | <variable name> '.' variable
|
||||
variable(i, list/node)
|
||||
var/list/L = list(token(i))
|
||||
node[++node.len] = L
|
||||
|
||||
if(token(i + 1) == ".")
|
||||
L += "."
|
||||
i = variable(i + 2, L)
|
||||
|
||||
else
|
||||
i++
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//object_type: <type path> | string
|
||||
object_type(i, list/node)
|
||||
|
||||
if(copytext(token(i), 1, 2) == "/")
|
||||
node += token(i)
|
||||
|
||||
else
|
||||
i = string(i, node)
|
||||
|
||||
return i + 1
|
||||
|
||||
|
||||
//comparitor: '=' | '==' | '!=' | '<>' | '<' | '<=' | '>' | '>='
|
||||
comparitor(i, list/node)
|
||||
|
||||
if(token(i) in list("=", "==", "!=", "<>", "<", "<=", ">", ">="))
|
||||
node += token(i)
|
||||
|
||||
else
|
||||
parse_error("Unknown comparitor [token(i)]")
|
||||
|
||||
return i + 1
|
||||
|
||||
|
||||
//bool_operator: 'AND' | '&&' | 'OR' | '||'
|
||||
bool_operator(i, list/node)
|
||||
|
||||
if(tokenl(i) in list("and", "or", "&&", "||"))
|
||||
node += token(i)
|
||||
|
||||
else
|
||||
parse_error("Unknown comparitor [token(i)]")
|
||||
|
||||
return i + 1
|
||||
|
||||
|
||||
//string: ''' <some text> ''' | '"' <some text > '"'
|
||||
string(i, list/node)
|
||||
|
||||
if(copytext(token(i), 1, 2) in list("'", "\""))
|
||||
node += token(i)
|
||||
|
||||
else
|
||||
parse_error("Expected string but found '[token(i)]'")
|
||||
|
||||
return i + 1
|
||||
|
||||
|
||||
//call_function: <function name> ['(' [arguments] ')']
|
||||
call_function(i, list/node)
|
||||
|
||||
parse_error("Sorry, function calls aren't available yet")
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//select_function: count_function
|
||||
select_function(i, list/node)
|
||||
|
||||
parse_error("Sorry, function calls aren't available yet")
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//expression: ( unary_expression | '(' expression ')' | value ) [binary_operator expression]
|
||||
expression(i, list/node)
|
||||
|
||||
if(token(i) in unary_operators)
|
||||
i = unary_expression(i, node)
|
||||
|
||||
else if(token(i) == "(")
|
||||
var/list/expr = list()
|
||||
|
||||
i = expression(i + 1, expr)
|
||||
|
||||
if(token(i) != ")")
|
||||
parse_error("Missing ) at end of expression.")
|
||||
|
||||
else
|
||||
i++
|
||||
|
||||
node[++node.len] = expr
|
||||
|
||||
else
|
||||
i = value(i, node)
|
||||
|
||||
if(token(i) in binary_operators)
|
||||
i = binary_operator(i, node)
|
||||
i = expression(i, node)
|
||||
|
||||
else if(token(i) in comparitors)
|
||||
i = binary_operator(i, node)
|
||||
|
||||
var/list/rhs = list()
|
||||
i = expression(i, rhs)
|
||||
|
||||
node[++node.len] = rhs
|
||||
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//unary_expression: unary_operator ( unary_expression | value | '(' expression ')' )
|
||||
unary_expression(i, list/node)
|
||||
|
||||
if(token(i) in unary_operators)
|
||||
var/list/unary_exp = list()
|
||||
|
||||
unary_exp += token(i)
|
||||
i++
|
||||
|
||||
if(token(i) in unary_operators)
|
||||
i = unary_expression(i, unary_exp)
|
||||
|
||||
else if(token(i) == "(")
|
||||
var/list/expr = list()
|
||||
|
||||
i = expression(i + 1, expr)
|
||||
|
||||
if(token(i) != ")")
|
||||
parse_error("Missing ) at end of expression.")
|
||||
|
||||
else
|
||||
i++
|
||||
|
||||
unary_exp[++unary_exp.len] = expr
|
||||
|
||||
else
|
||||
i = value(i, unary_exp)
|
||||
|
||||
node[++node.len] = unary_exp
|
||||
|
||||
|
||||
else
|
||||
parse_error("Expected unary operator but found '[token(i)]'")
|
||||
|
||||
return i
|
||||
|
||||
|
||||
//binary_operator: comparitor | '+' | '-' | '/' | '*' | '&' | '|' | '^'
|
||||
binary_operator(i, list/node)
|
||||
|
||||
if(token(i) in (binary_operators + comparitors))
|
||||
node += token(i)
|
||||
|
||||
else
|
||||
parse_error("Unknown binary operator [token(i)]")
|
||||
|
||||
return i + 1
|
||||
|
||||
|
||||
//value: variable | string | number | 'null'
|
||||
value(i, list/node)
|
||||
|
||||
if(token(i) == "null")
|
||||
node += "null"
|
||||
i++
|
||||
|
||||
else if(isnum(text2num(token(i))))
|
||||
node += text2num(token(i))
|
||||
i++
|
||||
|
||||
else if(copytext(token(i), 1, 2) in list("'", "\""))
|
||||
i = string(i, node)
|
||||
|
||||
else
|
||||
i = variable(i, node)
|
||||
|
||||
return i
|
||||
|
||||
|
||||
|
||||
|
||||
/*EXPLAIN SELECT * WHERE 42 = 6 * 9 OR val = - 5 == 7*/
|
||||
@@ -221,6 +221,124 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
|
||||
message_admins("\blue [key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste].", 1)
|
||||
return 1
|
||||
|
||||
/*
|
||||
Allow admins to set players to be able to respawn/bypass 30 min wait, without the admin having to edit variables directly
|
||||
Ccomp's first proc.
|
||||
*/
|
||||
|
||||
/client/proc/get_ghosts(var/notify = 0,var/what = 2)
|
||||
// what = 1, return ghosts ass list.
|
||||
// what = 2, return mob list
|
||||
|
||||
var/list/mobs = list()
|
||||
var/list/ghosts = list()
|
||||
var/list/sortmob = sortAtom(mob_list) // get the mob list.
|
||||
/var/any=0
|
||||
for(var/mob/dead/observer/M in sortmob)
|
||||
mobs.Add(M) //filter it where it's only ghosts
|
||||
any = 1 //if no ghosts show up, any will just be 0
|
||||
if(!any)
|
||||
if(notify)
|
||||
src << "There doesn't appear to be any ghosts for you to select."
|
||||
return
|
||||
|
||||
for(var/mob/M in mobs)
|
||||
var/name = M.name
|
||||
ghosts[name] = M //get the name of the mob for the popup list
|
||||
if(what==1)
|
||||
return ghosts
|
||||
else
|
||||
return mobs
|
||||
|
||||
|
||||
/client/proc/allow_character_respawn()
|
||||
set category = "Special Verbs"
|
||||
set name = "Allow player to respawn"
|
||||
set desc = "Let's the player bypass the 30 minute wait to respawn or allow them to re-enter their corpse."
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
var/list/ghosts= get_ghosts(1,1)
|
||||
|
||||
var/target = input("Please, select a ghost!", "COME BACK TO LIFE!", null, null) as null|anything in ghosts
|
||||
if(!target)
|
||||
src << "Hrm, appears you didn't select a ghost" // Sanity check, if no ghosts in the list we don't want to edit a null variable and cause a runtime error.
|
||||
return
|
||||
|
||||
var/mob/dead/observer/G = ghosts[target]
|
||||
if(G.has_enabled_antagHUD && config.antag_hud_restricted)
|
||||
var/response = alert(src, "Are you sure you wish to allow this individual to play?","Ghost has used AntagHUD","Yes","No")
|
||||
if(response == "No") return
|
||||
G.timeofdeath=-19999 /* time of death is checked in /mob/verb/abandon_mob() which is the Respawn verb.
|
||||
timeofdeath is used for bodies on autopsy but since we're messing with a ghost I'm pretty sure
|
||||
there won't be an autopsy.
|
||||
*/
|
||||
G.has_enabled_antagHUD = 2
|
||||
G.can_reenter_corpse = 1
|
||||
|
||||
G:show_message(text("\blue <B>You may now respawn. You should roleplay as if you learned nothing about the round during your time with the dead.</B>"), 1)
|
||||
log_admin("[key_name(usr)] allowed [key_name(G)] to bypass the 30 minute respawn limit")
|
||||
message_admins("Admin [key_name_admin(usr)] allowed [key_name_admin(G)] to bypass the 30 minute respawn limit", 1)
|
||||
|
||||
|
||||
/client/proc/toggle_antagHUD_use()
|
||||
set category = "Server"
|
||||
set name = "Toggle antagHUD usage"
|
||||
set desc = "Toggles antagHUD usage for observers"
|
||||
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
var/action=""
|
||||
if(config.antag_hud_allowed)
|
||||
for(var/mob/dead/observer/g in get_ghosts())
|
||||
if(g.antagHUD)
|
||||
g.antagHUD = 0 // Disable it on those that have it enabled
|
||||
g.has_enabled_antagHUD = 2 // We'll allow them to respawn
|
||||
g << "\red <B>The Administrator has disabled AntagHUD </B>"
|
||||
config.antag_hud_allowed = 0
|
||||
src << "\red <B>AntagHUD usage has been disabled</B>"
|
||||
action = "disabled"
|
||||
else
|
||||
for(var/mob/dead/observer/g in get_ghosts())
|
||||
g << "\blue <B>The Administrator has enabled AntagHUD </B>" // Notify all observers they can now use AntagHUD
|
||||
config.antag_hud_allowed = 1
|
||||
action = "enabled"
|
||||
src << "\blue <B>AntagHUD usage has been enabled</B>"
|
||||
|
||||
|
||||
log_admin("[key_name(usr)] has [action] antagHUD usage for observers")
|
||||
message_admins("Admin [key_name_admin(usr)] has [action] antagHUD usage for observers", 1)
|
||||
|
||||
|
||||
|
||||
/client/proc/toggle_antagHUD_restrictions()
|
||||
set category = "Server"
|
||||
set name = "Toggle antagHUD Restrictions"
|
||||
set desc = "Restricts players that have used antagHUD from being able to join this round."
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
var/action=""
|
||||
if(config.antag_hud_restricted)
|
||||
for(var/mob/dead/observer/g in get_ghosts())
|
||||
g << "\blue <B>The administrator has lifted restrictions on joining the round if you use AntagHUD</B>"
|
||||
action = "lifted restrictions"
|
||||
config.antag_hud_restricted = 0
|
||||
src << "\blue <B>AntagHUD restrictions have been lifted</B>"
|
||||
else
|
||||
for(var/mob/dead/observer/g in get_ghosts())
|
||||
g << "\red <B>The administrator has placed restrictions on joining the round if you use AntagHUD</B>"
|
||||
g << "\red <B>Your AntagHUD has been disabled, you may choose to re-enabled it but will be under restrictions </B>"
|
||||
g.antagHUD = 0
|
||||
g.has_enabled_antagHUD = 0
|
||||
action = "placed restrictions"
|
||||
config.antag_hud_restricted = 1
|
||||
src << "\red <B>AntagHUD restrictions have been enabled</B>"
|
||||
|
||||
log_admin("[key_name(usr)] has [action] on joining the round if they use AntagHUD")
|
||||
message_admins("Admin [key_name_admin(usr)] has [action] on joining the round if they use AntagHUD", 1)
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
If a guy was gibbed and you want to revive him, this is a good way to do so.
|
||||
Works kind of like entering the game with a new character. Character receives a new mind if they didn't have one.
|
||||
|
||||
@@ -57,13 +57,16 @@ var/global/vox_tick = 1
|
||||
equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(src), slot_back)
|
||||
equip_to_slot_or_del(new /obj/item/device/flashlight(src), slot_r_store)
|
||||
|
||||
var/obj/item/weapon/card/id/syndicate/W = new(src)
|
||||
W.name = "[real_name]'s Legitimate Human ID Card"
|
||||
W.icon_state = "id"
|
||||
W.access = list(access_syndicate)
|
||||
W.assignment = "Trader"
|
||||
W.registered_name = real_name
|
||||
W.registered_user = src
|
||||
var/obj/item/weapon/card/id/syndicate/C = new(src)
|
||||
C.name = "[real_name]'s Legitimate Human ID Card"
|
||||
C.icon_state = "id"
|
||||
C.access = list(access_syndicate)
|
||||
C.assignment = "Trader"
|
||||
C.registered_name = real_name
|
||||
C.registered_user = src
|
||||
var/obj/item/weapon/storage/wallet/W = new(src)
|
||||
W.handle_item_insertion(C)
|
||||
spawn_money(rand(50,150)*10,W)
|
||||
equip_to_slot_or_del(W, slot_wear_id)
|
||||
|
||||
var/obj/item/weapon/implant/cortical/I = new(src)
|
||||
|
||||
@@ -31,11 +31,11 @@
|
||||
s.start()
|
||||
|
||||
if(entersmoke)
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/s = new /datum/effect/effect/system/harmless_smoke_spread
|
||||
var/datum/effect/effect/system/smoke_spread/s = new /datum/effect/effect/system/smoke_spread
|
||||
s.set_up(4, 1, src, 0)
|
||||
s.start()
|
||||
if(exitsmoke)
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/s = new /datum/effect/effect/system/harmless_smoke_spread
|
||||
var/datum/effect/effect/system/smoke_spread/s = new /datum/effect/effect/system/smoke_spread
|
||||
s.set_up(4, 1, dest, 0)
|
||||
s.start()
|
||||
|
||||
|
||||
@@ -251,6 +251,7 @@
|
||||
'nano/css/icons.css',
|
||||
'nano/templates/chem_dispenser.tmpl',
|
||||
'nano/templates/cryo.tmpl',
|
||||
'nano/templates/geoscanner.tmpl',
|
||||
'nano/templates/dna_modifier.tmpl',
|
||||
'nano/images/uiBackground.png',
|
||||
'nano/images/uiIcons16.png',
|
||||
@@ -298,9 +299,5 @@
|
||||
'icons/spideros_icons/sos_11.png',
|
||||
'icons/spideros_icons/sos_12.png',
|
||||
'icons/spideros_icons/sos_13.png',
|
||||
'icons/spideros_icons/sos_14.png',
|
||||
'icons/xenoarch_icons/chart1.jpg',
|
||||
'icons/xenoarch_icons/chart2.jpg',
|
||||
'icons/xenoarch_icons/chart3.jpg',
|
||||
'icons/xenoarch_icons/chart4.jpg'
|
||||
'icons/spideros_icons/sos_14.png'
|
||||
)
|
||||
|
||||
@@ -262,6 +262,7 @@ datum/preferences
|
||||
//dat += "Skin pattern: <a href='byond://?src=\ref[user];preference=skin_style;task=input'>Adjust</a><br>"
|
||||
dat += "Needs Glasses: <a href='?_src_=prefs;preference=disabilities'><b>[disabilities == 0 ? "No" : "Yes"]</b></a><br>"
|
||||
dat += "Limbs: <a href='byond://?src=\ref[user];preference=limbs;task=input'>Adjust</a><br>"
|
||||
dat += "Internal Organs: <a href='byond://?src=\ref[user];preference=organs;task=input'>Adjust</a><br>"
|
||||
|
||||
//display limbs below
|
||||
var/ind = 0
|
||||
@@ -286,6 +287,10 @@ datum/preferences
|
||||
organ_name = "left hand"
|
||||
if("r_hand")
|
||||
organ_name = "right hand"
|
||||
if("heart")
|
||||
organ_name = "heart"
|
||||
if("eyes")
|
||||
organ_name = "eyes"
|
||||
|
||||
if(status == "cyborg")
|
||||
++ind
|
||||
@@ -297,6 +302,24 @@ datum/preferences
|
||||
if(ind > 1)
|
||||
dat += ", "
|
||||
dat += "\tAmputated [organ_name]"
|
||||
else if(status == "mechanical")
|
||||
++ind
|
||||
if(ind > 1)
|
||||
dat += ", "
|
||||
dat += "\tMechanical [organ_name]"
|
||||
else if(status == "assisted")
|
||||
++ind
|
||||
if(ind > 1)
|
||||
dat += ", "
|
||||
switch(organ_name)
|
||||
if("heart")
|
||||
dat += "\tPacemaker-assisted [organ_name]"
|
||||
if("voicebox") //on adding voiceboxes for speaking skrell/similar replacements
|
||||
dat += "\tSurgically altered [organ_name]"
|
||||
if("eyes")
|
||||
dat += "\tRetinal overlayed [organ_name]"
|
||||
else
|
||||
dat += "\tMechanically assisted [organ_name]"
|
||||
if(!ind)
|
||||
dat += "\[...\]<br><br>"
|
||||
else
|
||||
@@ -1048,6 +1071,28 @@ datum/preferences
|
||||
if(second_limb)
|
||||
organ_data[second_limb] = "cyborg"
|
||||
|
||||
if("organs")
|
||||
var/organ_name = input(user, "Which internal function do you want to change?") as null|anything in list("Heart", "Eyes")
|
||||
if(!organ_name) return
|
||||
|
||||
var/organ = null
|
||||
switch(organ_name)
|
||||
if("Heart")
|
||||
organ = "heart"
|
||||
if("Eyes")
|
||||
organ = "eyes"
|
||||
|
||||
var/new_state = input(user, "What state do you wish the organ to be in?") as null|anything in list("Normal","Assisted","Mechanical")
|
||||
if(!new_state) return
|
||||
|
||||
switch(new_state)
|
||||
if("Normal")
|
||||
organ_data[organ] = null
|
||||
if("Assisted")
|
||||
organ_data[organ] = "assisted"
|
||||
if("Mechanical")
|
||||
organ_data[organ] = "mechanical"
|
||||
|
||||
if("skin_style")
|
||||
var/skin_style_name = input(user, "Select a new skin style") as null|anything in list("default1", "default2", "default3")
|
||||
if(!skin_style_name) return
|
||||
@@ -1167,19 +1212,27 @@ datum/preferences
|
||||
character.skills = skills
|
||||
|
||||
// Destroy/cyborgize organs
|
||||
|
||||
for(var/name in organ_data)
|
||||
var/datum/organ/external/O = character.organs_by_name[name]
|
||||
if(!O) continue
|
||||
|
||||
var/datum/organ/internal/I = character.internal_organs_by_name[name]
|
||||
var/status = organ_data[name]
|
||||
|
||||
if(status == "amputated")
|
||||
O.amputated = 1
|
||||
O.status |= ORGAN_DESTROYED
|
||||
O.destspawn = 1
|
||||
else if(status == "cyborg")
|
||||
if(status == "cyborg")
|
||||
O.status |= ORGAN_ROBOT
|
||||
if(status == "assisted")
|
||||
I.mechassist()
|
||||
else if(status == "mechanical")
|
||||
I.mechanize()
|
||||
|
||||
else continue
|
||||
|
||||
if(underwear > underwear_m.len || underwear < 1)
|
||||
underwear = 1 //I'm sure this is 100% unnecessary, but I'm paranoid... sue me.
|
||||
underwear = 0 //I'm sure this is 100% unnecessary, but I'm paranoid... sue me. //HAH NOW NO MORE MAGIC CLONING UNDIES
|
||||
character.underwear = underwear
|
||||
|
||||
if(backbag > 4 || backbag < 1)
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
icon_state = "night"
|
||||
item_state = "glasses"
|
||||
origin_tech = "magnets=2"
|
||||
vision_flags = SEE_TURFS
|
||||
darkness_view = 3
|
||||
|
||||
/obj/item/clothing/glasses/eyepatch
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
heat_protection = HEAD
|
||||
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECITON_TEMPERATURE
|
||||
species_restricted = list("exclude","Unathi","Tajaran","Skrell","Diona","Vox")
|
||||
|
||||
attack_self(mob/user)
|
||||
if(!isturf(user.loc))
|
||||
user << "You cannot turn the light on while in this [user.loc]" //To prevent some lighting anomalities.
|
||||
@@ -90,7 +89,7 @@
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 35, bio = 100, rad = 60)
|
||||
siemens_coefficient = 0.6
|
||||
var/obj/machinery/camera/camera
|
||||
|
||||
species_restricted = list("exclude","Vox")
|
||||
/obj/item/clothing/head/helmet/space/rig/syndi/attack_self(mob/user)
|
||||
if(camera)
|
||||
..(user)
|
||||
@@ -116,6 +115,7 @@
|
||||
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)
|
||||
siemens_coefficient = 0.6
|
||||
species_restricted = list("exclude","Vox")
|
||||
|
||||
|
||||
//Wizard Rig
|
||||
|
||||
@@ -257,15 +257,6 @@
|
||||
item_state = "neocoat"
|
||||
flags = FPRINT | TABLEPASS
|
||||
|
||||
//actual suits
|
||||
|
||||
/obj/item/clothing/suit/creamsuit
|
||||
name = "cream suit"
|
||||
desc = "A cream coloured, genteel suit."
|
||||
icon_state = "creamsuit"
|
||||
item_state = "creamsuit"
|
||||
flags = FPRINT | TABLEPASS
|
||||
|
||||
//stripper
|
||||
|
||||
/obj/item/clothing/under/stripper/stripper_pink
|
||||
|
||||
@@ -478,6 +478,7 @@
|
||||
siemens_coefficient = 0.30
|
||||
permeability_coefficient = 0.01
|
||||
item_color="white"
|
||||
species_restricted = list("exclude","Unathi")
|
||||
|
||||
/obj/item/clothing/gloves/fluff/walter_brooks_1 //botanistpower: Walter Brooks
|
||||
name = "mittens"
|
||||
@@ -860,6 +861,7 @@
|
||||
desc = "Made of a special fiber that gives special protection against biohazards. Has a cross on the chest denoting that the wearer is trained medical personnel and short sleeves."
|
||||
icon = 'icons/obj/custom_items.dmi'
|
||||
icon_state = "medical_short"
|
||||
item_state = "medical_short"
|
||||
item_color = "medical_short"
|
||||
|
||||
/obj/item/clothing/suit/storage/labcoat/fluff/red
|
||||
|
||||
@@ -282,7 +282,7 @@ log transactions
|
||||
|
||||
//remove the money
|
||||
authenticated_account.money -= amount
|
||||
withdraw_arbitrary_sum(amount)
|
||||
spawn_money(amount,src.loc)
|
||||
|
||||
//create an entry in the account transaction log
|
||||
var/datum/transaction/T = new()
|
||||
@@ -340,33 +340,6 @@ log transactions
|
||||
|
||||
src.attack_hand(usr)
|
||||
|
||||
//create the most effective combination of notes to make up the requested amount
|
||||
/obj/machinery/atm/proc/withdraw_arbitrary_sum(var/arbitrary_sum)
|
||||
while(arbitrary_sum >= 1000)
|
||||
arbitrary_sum -= 1000
|
||||
new /obj/item/weapon/spacecash/c1000(src)
|
||||
while(arbitrary_sum >= 500)
|
||||
arbitrary_sum -= 500
|
||||
new /obj/item/weapon/spacecash/c500(src)
|
||||
while(arbitrary_sum >= 200)
|
||||
arbitrary_sum -= 200
|
||||
new /obj/item/weapon/spacecash/c200(src)
|
||||
while(arbitrary_sum >= 100)
|
||||
arbitrary_sum -= 100
|
||||
new /obj/item/weapon/spacecash/c100(src)
|
||||
while(arbitrary_sum >= 50)
|
||||
arbitrary_sum -= 50
|
||||
new /obj/item/weapon/spacecash/c50(src)
|
||||
while(arbitrary_sum >= 20)
|
||||
arbitrary_sum -= 20
|
||||
new /obj/item/weapon/spacecash/c20(src)
|
||||
while(arbitrary_sum >= 10)
|
||||
arbitrary_sum -= 10
|
||||
new /obj/item/weapon/spacecash/c10(src)
|
||||
while(arbitrary_sum >= 1)
|
||||
arbitrary_sum -= 1
|
||||
new /obj/item/weapon/spacecash(src)
|
||||
|
||||
//stolen wholesale and then edited a bit from newscasters, which are awesome and by Agouri
|
||||
/obj/machinery/atm/proc/scan_user(mob/living/carbon/human/human_user as mob)
|
||||
if(!authenticated_account)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
var/money = 0
|
||||
var/list/transaction_log = list()
|
||||
var/suspended = 0
|
||||
var/security_level = 1 //0 - auto-identify from worn ID, require only account number
|
||||
var/security_level = 0 //0 - auto-identify from worn ID, require only account number
|
||||
//1 - require manual login / account number and pin
|
||||
//2 - require card and manual login
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/obj/item/weapon/spacecash
|
||||
name = "0 credit chip"
|
||||
desc = "It's worth 0 credits."
|
||||
gender = PLURAL
|
||||
icon = 'icons/obj/items.dmi'
|
||||
icon_state = "spacecash"
|
||||
opacity = 0
|
||||
density = 0
|
||||
anchored = 0.0
|
||||
force = 1.0
|
||||
throwforce = 1.0
|
||||
throw_speed = 1
|
||||
throw_range = 2
|
||||
w_class = 1.0
|
||||
var/access = list()
|
||||
access = access_crate_cash
|
||||
var/worth = 0
|
||||
|
||||
/obj/item/weapon/spacecash/c1
|
||||
name = "1 credip chip"
|
||||
icon_state = "spacecash"
|
||||
desc = "It's worth 1 credit."
|
||||
worth = 1
|
||||
|
||||
/obj/item/weapon/spacecash/c10
|
||||
name = "10 credit chip"
|
||||
icon_state = "spacecash10"
|
||||
desc = "It's worth 10 credits."
|
||||
worth = 10
|
||||
|
||||
/obj/item/weapon/spacecash/c20
|
||||
name = "20 credit chip"
|
||||
icon_state = "spacecash20"
|
||||
desc = "It's worth 20 credits."
|
||||
worth = 20
|
||||
|
||||
/obj/item/weapon/spacecash/c50
|
||||
name = "50 credit chip"
|
||||
icon_state = "spacecash50"
|
||||
desc = "It's worth 50 credits."
|
||||
worth = 50
|
||||
|
||||
/obj/item/weapon/spacecash/c100
|
||||
name = "100 credit chip"
|
||||
icon_state = "spacecash100"
|
||||
desc = "It's worth 100 credits."
|
||||
worth = 100
|
||||
|
||||
/obj/item/weapon/spacecash/c200
|
||||
name = "200 credit chip"
|
||||
icon_state = "spacecash200"
|
||||
desc = "It's worth 200 credits."
|
||||
worth = 200
|
||||
|
||||
/obj/item/weapon/spacecash/c500
|
||||
name = "500 credit chip"
|
||||
icon_state = "spacecash500"
|
||||
desc = "It's worth 500 credits."
|
||||
worth = 500
|
||||
|
||||
/obj/item/weapon/spacecash/c1000
|
||||
name = "1000 credit chip"
|
||||
icon_state = "spacecash1000"
|
||||
desc = "It's worth 1000 credits."
|
||||
worth = 1000
|
||||
|
||||
proc/spawn_money(var/sum, spawnloc)
|
||||
var/cash_type
|
||||
for(var/i in list(1000,500,200,100,50,20,10,1))
|
||||
cash_type = text2path("/obj/item/weapon/spacecash/c[i]")
|
||||
while(sum >= i)
|
||||
sum -= i
|
||||
new cash_type(spawnloc)
|
||||
return
|
||||
@@ -76,7 +76,7 @@ var/list/event_last_fired = list()
|
||||
if(active_with_role["Medical"] > 0)
|
||||
possibleEvents[/datum/event/radiation_storm] = active_with_role["Medical"] * 50
|
||||
possibleEvents[/datum/event/spontaneous_appendicitis] = active_with_role["Medical"] * 150
|
||||
possibleEvents[/datum/event/viral_outbreak] = active_with_role["Medical"] * 10
|
||||
possibleEvents[/datum/event/viral_infection] = active_with_role["Medical"] * 10
|
||||
possibleEvents[/datum/event/organ_failure] = active_with_role["Medical"] * 50
|
||||
|
||||
possibleEvents[/datum/event/prison_break] = active_with_role["Security"] * 50
|
||||
@@ -92,7 +92,7 @@ var/list/event_last_fired = list()
|
||||
var/time_passed = world.time - event_last_fired[event_type]
|
||||
var/full_recharge_after = 60 * 60 * 10 * 3 // 3 hours
|
||||
var/weight_modifier = max(0, (full_recharge_after - time_passed) / 300)
|
||||
|
||||
|
||||
possibleEvents[event_type] = max(possibleEvents[event_type] - weight_modifier, 0)
|
||||
|
||||
var/picked_event = pickweight(possibleEvents)
|
||||
|
||||
@@ -1107,18 +1107,15 @@ I said no!
|
||||
)
|
||||
result = /obj/item/weapon/reagent_containers/food/snacks/appletart
|
||||
|
||||
/datum/recipe/herbsalad
|
||||
/datum/recipe/tossedsalad
|
||||
items = list(
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiavulgaris,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/cabbage,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/cabbage,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/tomato,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/carrot,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/grown/apple,
|
||||
)
|
||||
result = /obj/item/weapon/reagent_containers/food/snacks/herbsalad
|
||||
make_food(var/obj/container as obj)
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/herbsalad/being_cooked = ..(container)
|
||||
being_cooked.reagents.del_reagent("toxin")
|
||||
return being_cooked
|
||||
result = /obj/item/weapon/reagent_containers/food/snacks/tossedsalad
|
||||
|
||||
/datum/recipe/aesirsalad
|
||||
items = list(
|
||||
|
||||
@@ -99,8 +99,9 @@
|
||||
new /obj/item/weapon/book/manual/engineering_particle_accelerator(src)
|
||||
new /obj/item/weapon/book/manual/engineering_hacking(src)
|
||||
new /obj/item/weapon/book/manual/engineering_guide(src)
|
||||
new /obj/item/weapon/book/manual/atmospipes(src)
|
||||
new /obj/item/weapon/book/manual/engineering_singularity_safety(src)
|
||||
new /obj/item/weapon/book/manual/robotics_cyborgs(src)
|
||||
new /obj/item/weapon/book/manual/evaguide(src)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/bookcase/manuals/research_and_development
|
||||
|
||||
@@ -298,9 +298,25 @@
|
||||
new /obj/item/stack/sheet/mineral/clown(output.loc)
|
||||
else
|
||||
on = 0
|
||||
if (selected_glass == 1 && selected_gold == 0 && selected_silver == 0 && selected_diamond == 0 && selected_plasma == 1 && selected_uranium == 0 && selected_iron == 0 && selected_clown == 0)
|
||||
if (ore_glass > 0 && ore_plasma > 0)
|
||||
ore_glass--;
|
||||
ore_plasma--;
|
||||
new /obj/item/stack/sheet/glass/plasmaglass(output.loc)
|
||||
else
|
||||
on = 0
|
||||
if (selected_glass == 1 && selected_gold == 0 && selected_silver == 0 && selected_diamond == 0 && selected_plasma == 1 && selected_uranium == 0 && selected_iron == 1 && selected_clown == 0)
|
||||
if (ore_glass > 0 && ore_plasma > 0 && ore_iron > 0)
|
||||
ore_glass--;
|
||||
ore_iron--;
|
||||
ore_plasma--;
|
||||
new /obj/item/stack/sheet/glass/plasmarglass(output.loc)
|
||||
else
|
||||
on = 0
|
||||
continue
|
||||
//THESE TWO ARE CODED FOR URIST TO USE WHEN HE GETS AROUND TO IT.
|
||||
//They were coded on 18 Feb 2012. If you're reading this in 2015, then firstly congratulations on the world not ending on 21 Dec 2012 and secondly, Urist is apparently VERY lazy. ~Errorage
|
||||
//Iamgoofball here, this comment I'm typing right now was made in 11/1/2013. If you're reading this in 2020, then please let me know if the world has gone into a nuclear apocalypse. Also Urist has been tried and hung for how lazy he was. That and he was jaywalking.
|
||||
/*if (selected_glass == 0 && selected_gold == 0 && selected_silver == 0 && selected_diamond == 1 && selected_plasma == 0 && selected_uranium == 1 && selected_iron == 0 && selected_clown == 0)
|
||||
if (ore_uranium >= 2 && ore_diamond >= 1)
|
||||
ore_uranium -= 2
|
||||
@@ -380,34 +396,42 @@
|
||||
if (O)
|
||||
if (istype(O,/obj/item/weapon/ore/iron))
|
||||
ore_iron++;
|
||||
O.loc = null
|
||||
del(O)
|
||||
continue
|
||||
if (istype(O,/obj/item/weapon/ore/glass))
|
||||
ore_glass++;
|
||||
O.loc = null
|
||||
del(O)
|
||||
continue
|
||||
if (istype(O,/obj/item/weapon/ore/diamond))
|
||||
ore_diamond++;
|
||||
O.loc = null
|
||||
del(O)
|
||||
continue
|
||||
if (istype(O,/obj/item/weapon/ore/plasma))
|
||||
ore_plasma++
|
||||
O.loc = null
|
||||
del(O)
|
||||
continue
|
||||
if (istype(O,/obj/item/weapon/ore/gold))
|
||||
ore_gold++
|
||||
O.loc = null
|
||||
del(O)
|
||||
continue
|
||||
if (istype(O,/obj/item/weapon/ore/silver))
|
||||
ore_silver++
|
||||
O.loc = null
|
||||
del(O)
|
||||
continue
|
||||
if (istype(O,/obj/item/weapon/ore/uranium))
|
||||
ore_uranium++
|
||||
O.loc = null
|
||||
del(O)
|
||||
continue
|
||||
if (istype(O,/obj/item/weapon/ore/clown))
|
||||
ore_clown++
|
||||
O.loc = null
|
||||
del(O)
|
||||
continue
|
||||
O.loc = src.output.loc
|
||||
|
||||
@@ -42,6 +42,10 @@
|
||||
dat += text("Reinforced Glass: [machine.ore_rglass] <A href='?src=\ref[src];release=rglass'>Release</A><br>")
|
||||
if(machine.ore_plasma)
|
||||
dat += text("Plasma: [machine.ore_plasma] <A href='?src=\ref[src];release=plasma'>Release</A><br>")
|
||||
if(machine.ore_plasmaglass)
|
||||
dat += text("Plasma Glass: [machine.ore_plasmaglass] <A href='?src=\ref[src];release=plasmaglass'>Release</A><br>")
|
||||
if(machine.ore_plasmarglass)
|
||||
dat += text("Reinforced Plasma Glass: [machine.ore_plasmarglass] <A href='?src=\ref[src];release=plasmarglass'>Release</A><br>")
|
||||
if(machine.ore_gold)
|
||||
dat += text("Gold: [machine.ore_gold] <A href='?src=\ref[src];release=gold'>Release</A><br>")
|
||||
if(machine.ore_silver)
|
||||
@@ -83,6 +87,18 @@
|
||||
G.amount = machine.ore_plasma
|
||||
G.loc = machine.output.loc
|
||||
machine.ore_plasma = 0
|
||||
if ("plasmaglass")
|
||||
if (machine.ore_plasmaglass > 0)
|
||||
var/obj/item/stack/sheet/glass/plasmaglass/G = new /obj/item/stack/sheet/glass/plasmaglass
|
||||
G.amount = machine.ore_plasmaglass
|
||||
G.loc = machine.output.loc
|
||||
machine.ore_plasmaglass = 0
|
||||
if ("plasmarglass")
|
||||
if (machine.ore_plasmarglass > 0)
|
||||
var/obj/item/stack/sheet/glass/plasmarglass/G = new /obj/item/stack/sheet/glass/plasmarglass
|
||||
G.amount = machine.ore_plasmarglass
|
||||
G.loc = machine.output.loc
|
||||
machine.ore_plasmarglass = 0
|
||||
if ("uranium")
|
||||
if (machine.ore_uranium > 0)
|
||||
var/obj/item/stack/sheet/mineral/uranium/G = new /obj/item/stack/sheet/mineral/uranium
|
||||
@@ -195,6 +211,8 @@
|
||||
var/ore_silver = 0;
|
||||
var/ore_diamond = 0;
|
||||
var/ore_plasma = 0;
|
||||
var/ore_plasmaglass = 0;
|
||||
var/ore_plasmarglass = 0;
|
||||
var/ore_iron = 0;
|
||||
var/ore_uranium = 0;
|
||||
var/ore_clown = 0;
|
||||
@@ -263,6 +281,14 @@
|
||||
ore_rglass+= O:amount
|
||||
del(O)
|
||||
continue
|
||||
if (istype(O,/obj/item/stack/sheet/glass/plasmaglass))
|
||||
ore_plasmaglass+= O:amount
|
||||
del(O)
|
||||
continue
|
||||
if (istype(O,/obj/item/stack/sheet/glass/plasmarglass))
|
||||
ore_plasmarglass+= O:amount
|
||||
del(O)
|
||||
continue
|
||||
if (istype(O,/obj/item/stack/sheet/plasteel))
|
||||
ore_plasteel+= O:amount
|
||||
del(O)
|
||||
@@ -349,6 +375,18 @@
|
||||
G.loc = output.loc
|
||||
ore_rglass -= stack_amt
|
||||
return
|
||||
if (ore_plasmaglass >= stack_amt)
|
||||
var/obj/item/stack/sheet/glass/plasmaglass/G = new /obj/item/stack/sheet/glass/plasmaglass
|
||||
G.amount = stack_amt
|
||||
G.loc = output.loc
|
||||
ore_plasmaglass -= stack_amt
|
||||
return
|
||||
if (ore_plasmarglass >= stack_amt)
|
||||
var/obj/item/stack/sheet/glass/plasmarglass/G = new /obj/item/stack/sheet/glass/plasmarglass
|
||||
G.amount = stack_amt
|
||||
G.loc = output.loc
|
||||
ore_plasmarglass -= stack_amt
|
||||
return
|
||||
if (ore_plasteel >= stack_amt)
|
||||
var/obj/item/stack/sheet/plasteel/G = new /obj/item/stack/sheet/plasteel
|
||||
G.amount = stack_amt
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#define XENOARCH_SPREAD_CHANCE 15
|
||||
#define ARTIFACT_SPAWN_CHANCE 20
|
||||
|
||||
/datum/controller/game_controller/var/list/artifact_spawning_turfs = list()
|
||||
|
||||
/turf/simulated/mineral //wall piece
|
||||
name = "Rock"
|
||||
icon = 'icons/turf/walls.dmi'
|
||||
@@ -127,7 +129,7 @@
|
||||
//dont create artifact machinery in animal or plant digsites, or if we already have one
|
||||
if(!artifact_find && digsite != 1 && digsite != 2 && prob(ARTIFACT_SPAWN_CHANCE))
|
||||
artifact_find = new()
|
||||
artifact_spawning_turfs.Add(src)
|
||||
master_controller.artifact_spawning_turfs.Add(src)
|
||||
|
||||
if(!src.geological_data)
|
||||
src.geological_data = new/datum/geosample(src)
|
||||
@@ -369,29 +371,25 @@ commented out in r5061, I left it because of the shroom thingies
|
||||
//just pull the surrounding rock out
|
||||
excavate_find(0, F)
|
||||
|
||||
if( src.excavation_level + P.excavation_amount >= 100 || (!finds.len && !excavation_minerals.len) )
|
||||
//if players have been excavating this turf, have a chance to leave some rocky debris behind
|
||||
var/boulder_prob = 0
|
||||
if( src.excavation_level + P.excavation_amount >= 100 )
|
||||
//if players have been excavating this turf, leave some rocky debris behind
|
||||
var/obj/structure/boulder/B
|
||||
|
||||
if(src.excavation_level > 15)
|
||||
boulder_prob = 10
|
||||
if(artifact_find)
|
||||
boulder_prob += 25
|
||||
if(src.excavation_level >= 100)
|
||||
boulder_prob += 40
|
||||
else if(src.excavation_level > 95)
|
||||
boulder_prob += 25
|
||||
else if(src.excavation_level > 90)
|
||||
boulder_prob += 10
|
||||
if(prob(boulder_prob))
|
||||
if( src.excavation_level > 0 || prob(15) )
|
||||
//boulder with an artifact inside
|
||||
B = new(src)
|
||||
if(artifact_find)
|
||||
B.artifact_find = artifact_find
|
||||
else
|
||||
artifact_debris(1)
|
||||
else if(prob(15))
|
||||
//empty boulder
|
||||
B = new(src)
|
||||
if(artifact_find)
|
||||
B.artifact_find = artifact_find
|
||||
else if(artifact_find && src.excavation_level + P.excavation_amount >= 100)
|
||||
artifact_debris(1)
|
||||
|
||||
gets_drilled(B ? 0 : 1)
|
||||
if(B)
|
||||
gets_drilled(0)
|
||||
else
|
||||
gets_drilled(1)
|
||||
return
|
||||
else
|
||||
src.excavation_level += P.excavation_amount
|
||||
@@ -475,7 +473,7 @@ commented out in r5061, I left it because of the shroom thingies
|
||||
if(prob(50))
|
||||
pain = 1
|
||||
for(var/mob/living/M in range(src, 200))
|
||||
M << "<font color='red'><b>[pick("A high pitched [pick("keening","wailing","whistle")]","A rumbling noise like [pick("thunder","heavy machinery")]")] somehow penetrates your mind before fadaing away!</b></font>"
|
||||
M << "<font color='red'><b>[pick("A high pitched [pick("keening","wailing","whistle")]","A rumbling noise like [pick("thunder","heavy machinery")]")] somehow penetrates your mind before fading away!</b></font>"
|
||||
if(pain)
|
||||
flick("pain",M.pain)
|
||||
if(prob(50))
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
var/started_as_observer //This variable is set to 1 when you enter the game as an observer.
|
||||
//If you died in the game and are a ghsot - this will remain as null.
|
||||
//Note that this is not a reliable way to determine if admins started as observers, since they change mobs a lot.
|
||||
var/has_enabled_antagHUD = 0
|
||||
var/antagHUD = 0
|
||||
universal_speak = 1
|
||||
var/atom/movable/following = null
|
||||
/mob/dead/observer/New(mob/body)
|
||||
@@ -70,6 +72,60 @@ Transfer_mind is there to check if mob is being deleted/not going to have a body
|
||||
Works together with spawning an observer, noted above.
|
||||
*/
|
||||
|
||||
/mob/dead/observer/Life()
|
||||
..()
|
||||
if(!loc) return
|
||||
if(!client) return 0
|
||||
|
||||
|
||||
if(client.images.len)
|
||||
for(var/image/hud in client.images)
|
||||
if(copytext(hud.icon_state,1,4) == "hud")
|
||||
client.images.Remove(hud)
|
||||
if(antagHUD)
|
||||
var/list/target_list = list()
|
||||
for(var/mob/living/target in oview(src))
|
||||
if( target.mind&&(target.mind.special_role||issilicon(target)) )
|
||||
target_list += target
|
||||
if(target_list.len)
|
||||
assess_targets(target_list, src)
|
||||
|
||||
|
||||
|
||||
/mob/dead/proc/assess_targets(list/target_list, mob/dead/observer/U)
|
||||
var/icon/tempHud = 'icons/mob/hud.dmi'
|
||||
for(var/mob/living/target in target_list)
|
||||
if(iscarbon(target))
|
||||
switch(target.mind.special_role)
|
||||
if("traitor","Syndicate")
|
||||
U.client.images += image(tempHud,target,"hudsyndicate")
|
||||
if("Revolutionary")
|
||||
U.client.images += image(tempHud,target,"hudrevolutionary")
|
||||
if("Head Revolutionary")
|
||||
U.client.images += image(tempHud,target,"hudheadrevolutionary")
|
||||
if("Cultist")
|
||||
U.client.images += image(tempHud,target,"hudcultist")
|
||||
if("Changeling")
|
||||
U.client.images += image(tempHud,target,"hudchangeling")
|
||||
if("Wizard","Fake Wizard")
|
||||
U.client.images += image(tempHud,target,"hudwizard")
|
||||
if("Hunter","Sentinel","Drone","Queen")
|
||||
U.client.images += image(tempHud,target,"hudalien")
|
||||
if("Death Commando")
|
||||
U.client.images += image(tempHud,target,"huddeathsquad")
|
||||
if("Ninja")
|
||||
U.client.images += image(tempHud,target,"hudninja")
|
||||
else//If we don't know what role they have but they have one.
|
||||
U.client.images += image(tempHud,target,"hudunknown1")
|
||||
else//If the silicon mob has no law datum, no inherent laws, or a law zero, add them to the hud.
|
||||
var/mob/living/silicon/silicon_target = target
|
||||
if(!silicon_target.laws||(silicon_target.laws&&(silicon_target.laws.zeroth||!silicon_target.laws.inherent.len))||silicon_target.mind.special_role=="traitor")
|
||||
if(isrobot(silicon_target))//Different icons for robutts and AI.
|
||||
U.client.images += image(tempHud,silicon_target,"hudmalborg")
|
||||
else
|
||||
U.client.images += image(tempHud,silicon_target,"hudmalai")
|
||||
return 1
|
||||
|
||||
/mob/proc/ghostize(var/can_reenter_corpse = 1)
|
||||
if(key)
|
||||
var/mob/dead/observer/ghost = new(src) //Transfer safety to observer spawning proc.
|
||||
@@ -153,7 +209,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
if(mind.current.key && copytext(mind.current.key,1,2)!="@") //makes sure we don't accidentally kick any clients
|
||||
usr << "<span class='warning'>Another consciousness is in your body...It is resisting you.</span>"
|
||||
return
|
||||
if(mind.current.ajourn && mind.current.stat != DEAD) //check if the corpse is astral-journeying (it's client ghosted using a cultist rune).
|
||||
if(mind.current.ajourn && mind.current.stat != DEAD) //check if the corpse is astral-journeying (it's client ghosted using a cultist rune).
|
||||
var/obj/effect/rune/R = locate() in mind.current.loc //whilst corpse is alive, we can only reenter the body if it's on the rune
|
||||
if(!(R && R.word1 == cultwords["hell"] && R.word2 == cultwords["travel"] && R.word3 == cultwords["self"])) //astral journeying rune
|
||||
usr << "<span class='warning'>The astral cord that ties your body and your spirit has been severed. You are likely to wander the realm beyond until your body is finally dead and thus reunited with you.</span>"
|
||||
@@ -162,6 +218,32 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
mind.current.key = key
|
||||
return 1
|
||||
|
||||
/mob/dead/observer/verb/toggle_antagHUD()
|
||||
set category = "Ghost"
|
||||
set name = "Toggle AntagHUD"
|
||||
set desc = "Toggles AntagHUD allowing you to see who is the antagonist"
|
||||
if(!config.antag_hud_allowed && !client.holder)
|
||||
src << "\red Admins have disabled this for this round."
|
||||
return
|
||||
if(!client)
|
||||
return
|
||||
var/mob/dead/observer/M = src
|
||||
if(jobban_isbanned(M, "AntagHUD"))
|
||||
src << "\red <B>You have been banned from using this feature</B>"
|
||||
return
|
||||
if(config.antag_hud_restricted && !M.has_enabled_antagHUD &&!client.holder)
|
||||
var/response = alert(src, "If you turn this on, you will not be able to take any part in the round.","Are you sure you want to turn this feature on?","Yes","No")
|
||||
if(response == "No") return
|
||||
M.can_reenter_corpse = 0
|
||||
if(!M.has_enabled_antagHUD && !client.holder)
|
||||
M.has_enabled_antagHUD = 1
|
||||
if(M.antagHUD)
|
||||
M.antagHUD = 0
|
||||
src << "\blue <B>AntagHUD Disabled</B>"
|
||||
else
|
||||
M.antagHUD = 1
|
||||
src << "\blue <B>AntagHUD Enabled</B>"
|
||||
|
||||
/mob/dead/observer/proc/dead_tele()
|
||||
set category = "Ghost"
|
||||
set name = "Teleport"
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
breath = loc.remove_air(breath_moles)
|
||||
|
||||
// Handle chem smoke effect -- Doohl
|
||||
for(var/obj/effect/effect/chem_smoke/smoke in view(1, src))
|
||||
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
|
||||
if(smoke.reagents.total_volume)
|
||||
smoke.reagents.reaction(src, INGEST)
|
||||
spawn(5)
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
breath = loc.remove_air(breath_moles)
|
||||
|
||||
// Handle chem smoke effect -- Doohl
|
||||
for(var/obj/effect/effect/chem_smoke/smoke in view(1, src))
|
||||
for(var/obj/effect/effect/smoke/chem/smoke in view(1, src))
|
||||
if(smoke.reagents.total_volume)
|
||||
smoke.reagents.reaction(src, INGEST)
|
||||
spawn(5)
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
proc/request_player()
|
||||
for(var/mob/dead/observer/O in player_list)
|
||||
if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
|
||||
continue
|
||||
if(jobban_isbanned(O, "pAI"))
|
||||
continue
|
||||
if(O.client)
|
||||
|
||||
@@ -468,21 +468,20 @@
|
||||
//gets name from ID or PDA itself, ID inside PDA doesn't matter
|
||||
//Useful when player is being seen by other mobs
|
||||
/mob/living/carbon/human/proc/get_id_name(var/if_no_id = "Unknown")
|
||||
var/obj/item/device/pda/pda = wear_id
|
||||
var/obj/item/weapon/card/id/id = wear_id
|
||||
if(istype(pda)) . = pda.owner
|
||||
else if(istype(id)) . = id.registered_name
|
||||
if(!.) . = if_no_id //to prevent null-names making the mob unclickable
|
||||
. = if_no_id
|
||||
if(istype(wear_id,/obj/item/device/pda))
|
||||
var/obj/item/device/pda/P = wear_id
|
||||
return P.owner
|
||||
if(wear_id)
|
||||
var/obj/item/weapon/card/id/I = wear_id.GetID()
|
||||
if(I)
|
||||
return I.registered_name
|
||||
return
|
||||
|
||||
//gets ID card object from special clothes slot or null.
|
||||
/mob/living/carbon/human/proc/get_idcard()
|
||||
var/obj/item/weapon/card/id/id = wear_id
|
||||
var/obj/item/device/pda/pda = wear_id
|
||||
if (istype(pda) && pda.id)
|
||||
id = pda.id
|
||||
if (istype(id))
|
||||
return id
|
||||
if(wear_id)
|
||||
return wear_id.GetID()
|
||||
|
||||
//Added a safety check in case you want to shock a human mob directly through electrocute_act.
|
||||
/mob/living/carbon/human/electrocute_act(var/shock_damage, var/obj/source, var/siemens_coeff = 1.0, var/safety = 0)
|
||||
@@ -1252,12 +1251,6 @@ mob/living/carbon/human/yank_out_object()
|
||||
|
||||
species = all_species[new_species]
|
||||
|
||||
see_in_dark = species.darksight
|
||||
if(see_in_dark > 2)
|
||||
see_invisible = SEE_INVISIBLE_LEVEL_ONE
|
||||
else
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
|
||||
spawn(0)
|
||||
update_icons()
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user