mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2026-01-03 14:04:41 +00:00
Merge branch 'dev' of https://github.com/Baystation12/Baystation12 into dev
This commit is contained in:
@@ -684,6 +684,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"
|
||||
@@ -805,7 +808,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"
|
||||
@@ -1201,22 +1203,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"
|
||||
@@ -1254,6 +1252,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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
403
code/ZAS/Fire.dm
403
code/ZAS/Fire.dm
@@ -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()
|
||||
@@ -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"
|
||||
|
||||
@@ -519,7 +519,7 @@ proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
|
||||
|
||||
for(var/datum/gas/G in B.trace_gases)
|
||||
var/datum/gas/H = locate(G.type) in A.trace_gases
|
||||
if(H)
|
||||
if(!H)
|
||||
H = new G.type
|
||||
A.trace_gases += H
|
||||
var/G_avg = (G.moles*size) / (size+share_size)
|
||||
|
||||
@@ -16,6 +16,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.
|
||||
@@ -76,6 +77,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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
@@ -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"
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -11,6 +11,13 @@
|
||||
density = 1
|
||||
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)
|
||||
@@ -71,22 +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>"
|
||||
if(src.connected.beaker)
|
||||
if(src.connected.filtering)
|
||||
dat += "<HR><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>"
|
||||
|
||||
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)
|
||||
@@ -108,19 +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["togglefilter"])
|
||||
src.connected.toggle_filter()
|
||||
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
|
||||
@@ -143,15 +155,15 @@
|
||||
density = 1
|
||||
anchored = 1
|
||||
var/orient = "LEFT" // "RIGHT" changes the dir suffix to "-r"
|
||||
var/mob/living/carbon/human/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
|
||||
var/obj/item/weapon/reagent_containers/glass/beaker = null
|
||||
var/filtering = 0
|
||||
|
||||
New()
|
||||
..()
|
||||
beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large()
|
||||
beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large()
|
||||
spawn( 5 )
|
||||
if(orient == "RIGHT")
|
||||
icon_state = "sleeper_0-r"
|
||||
@@ -164,15 +176,14 @@
|
||||
|
||||
|
||||
process()
|
||||
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)
|
||||
// world << "FILTERING CHEMS"
|
||||
src.occupant.reagents.trans_to(beaker, 3)
|
||||
src.occupant.vessel.trans_to(beaker, 1)
|
||||
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
|
||||
|
||||
|
||||
@@ -184,59 +195,60 @@
|
||||
del(src)
|
||||
return
|
||||
|
||||
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]!")
|
||||
return
|
||||
else
|
||||
user << "\red The sleeper has a beaker already."
|
||||
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
|
||||
|
||||
else if(istype(G, /obj/item/weapon/grab))
|
||||
if(!ismob(G:affecting))
|
||||
return
|
||||
else if(istype(G, /obj/item/weapon/grab))
|
||||
if(!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."
|
||||
return
|
||||
|
||||
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)
|
||||
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
|
||||
|
||||
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()
|
||||
if(filtering)
|
||||
toggle_filter()
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
for(var/atom/movable/A as mob|obj in src)
|
||||
@@ -260,8 +272,8 @@
|
||||
return
|
||||
return
|
||||
emp_act(severity)
|
||||
if(filtering)
|
||||
toggle_filter()
|
||||
if(filtering)
|
||||
toggle_filter()
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
..(severity)
|
||||
return
|
||||
@@ -286,15 +298,15 @@
|
||||
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/toggle_filter()
|
||||
if(filtering)
|
||||
filtering = 0
|
||||
else
|
||||
filtering = 1
|
||||
|
||||
proc/go_out()
|
||||
if(filtering)
|
||||
toggle_filter()
|
||||
if(filtering)
|
||||
toggle_filter()
|
||||
if(!src.occupant)
|
||||
return
|
||||
if(src.occupant.client)
|
||||
@@ -337,10 +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."
|
||||
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
|
||||
@@ -359,19 +371,19 @@
|
||||
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/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"
|
||||
set category = "Object"
|
||||
@@ -402,10 +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>"
|
||||
|
||||
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
|
||||
|
||||
@@ -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/
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
..()
|
||||
|
||||
@@ -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
|
||||
@@ -759,8 +774,8 @@
|
||||
/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/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/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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
|
||||
@@ -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<72>s 50 dead people lying on the floor, chairs are spinning like no tomorrow and you haven<65>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<73>t for you and you should get a job-change as soon as possible before you<6F>re sued for malpractice.
|
||||
So there<72>s 50 dead people lying on the floor, chairs are spinning like no tomorrow and you haven<65>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<73>t for you and you should get a job-change as soon as possible before you<6F>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<61>t clone anyone if they<65>re wearing clothes, so take all of it off. If it<69>s just one person, it<69>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<6F>t mix them around and for God<6F>s sake don<6F>t let people in to steal them.
|
||||
The cloning machine does not like abiotic items. What this means is you can<61>t clone anyone if they<65>re wearing clothes, so take all of it off. If it<69>s just one person, it<69>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<6F>t mix them around and for God<6F>s sake don<6F>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 <20>Scan - <Subject Name Here><3E>. If you<6F>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<64>t turn on their suit sensors)! If not, and it says <20>Error: Mental interface failure.<2E>, 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 <20>Refresh<73> and try scanning them again. If there<72>s no success, threaten them with gibbing. Still no success? Skip over to Step 7 and don<6F>t continue after it, as you have an unresponsive body and it cannot be cloned. If you got <20>Error: Unable to locate valid genetic data.<2E>, you are trying to clone a monkey - start over.
|
||||
Go onto the computer and scan the body by pressing <20>Scan - <Subject Name Here><3E>. If you<6F>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<64>t turn on their suit sensors)!
|
||||
If not, and it says <20>Error: Mental interface failure.<2E>, 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 <20>Refresh<73> and try scanning them again. If there<72>s no success, threaten them with gibbing.
|
||||
Still no success? Skip over to Step 7 and don<6F>t continue after it, as you have an unresponsive body and it cannot be cloned.
|
||||
If you got <20>Error: Unable to locate valid genetic data.<2E>, 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 <20>View Records<64>, click the subject<63>s name, and then click <20>Clone<6E> to start the cloning process. Congratulations! You<6F>re halfway there. Remember not to <20>Eject<63> the cloning pod as this will kill the developing clone and you<6F>ll have to start the process again.
|
||||
Now that the body has a record, click <20>View Records<64>, click the subject<63>s name, and then click <20>Clone<6E> to start the cloning process. Congratulations! You<6F>re halfway there.
|
||||
Remember not to <20>Eject<63> the cloning pod as this will kill the developing clone and you<6F>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<65>re done. If you<6F>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 <20>SE<53> to save it. Then click <20>Injector<6F> 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<65>re done. If you<6F>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 <20>SE<53> to save it. Then click <20>Injector<6F> 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 <20>CHEF MEAT<41> 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 <20>CHEF MEAT<41> 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<6F>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<6F>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<6F>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<65>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<69>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<65>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<69>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<6F>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<6F>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<6F>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<6F>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<6F>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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -393,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>"
|
||||
@@ -423,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
|
||||
|
||||
@@ -456,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()
|
||||
@@ -465,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
|
||||
|
||||
@@ -482,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()
|
||||
@@ -646,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
|
||||
@@ -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())
|
||||
|
||||
@@ -807,7 +807,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,8 @@ 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/allow_character_respawn /* Allows a ghost to respawn */
|
||||
)
|
||||
var/list/admin_verbs_ban = list(
|
||||
/client/proc/unban_panel,
|
||||
@@ -139,7 +140,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,
|
||||
|
||||
@@ -685,6 +685,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 +847,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
|
||||
|
||||
497
code/modules/admin/verbs/SDQL.dm
Normal file
497
code/modules/admin/verbs/SDQL.dm
Normal file
@@ -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
|
||||
426
code/modules/admin/verbs/SDQL_2.dm
Normal file
426
code/modules/admin/verbs/SDQL_2.dm
Normal file
@@ -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
|
||||
531
code/modules/admin/verbs/SDQL_2_parser.dm
Normal file
531
code/modules/admin/verbs/SDQL_2_parser.dm
Normal file
@@ -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,50 @@ 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/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."
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
var/any = 0
|
||||
var/list/mobs = list()
|
||||
var/list/ghosts = list()
|
||||
var/list/sortmob = sortAtom(mob_list) // get the mob list.
|
||||
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)
|
||||
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
|
||||
|
||||
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/M = ghosts[target]
|
||||
M.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.
|
||||
*/
|
||||
M: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(M)] to bypass the 30 minute respawn limit")
|
||||
message_admins("Admin [key_name_admin(usr)] allowed [key_name_admin(M)] to bypass the 30 minute respawn limit", 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.
|
||||
|
||||
@@ -66,7 +66,7 @@ var/global/vox_tick = 1
|
||||
C.registered_user = src
|
||||
var/obj/item/weapon/storage/wallet/W = new(src)
|
||||
W.handle_item_insertion(C)
|
||||
spawn_money(rand(100,300)*5,W)
|
||||
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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -180,7 +180,7 @@ This function restores the subjects blood to max.
|
||||
/mob/living/carbon/human/proc/restore_blood()
|
||||
var/blood_volume = vessel.get_reagent_amount("blood")
|
||||
vessel.add_reagent("blood",560.0-blood_volume)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
This function restores all organs.
|
||||
@@ -252,8 +252,9 @@ This function restores all organs.
|
||||
W.loc = src
|
||||
|
||||
else if(istype(used_weapon,/obj/item/projectile)) //We don't want to use the actual projectile item, so we spawn some shrapnel.
|
||||
if(prob(75) && damagetype == BRUTE)
|
||||
var/obj/item/projectile/P = used_weapon
|
||||
|
||||
var/obj/item/projectile/P = used_weapon
|
||||
if(prob(75) && P.embed)
|
||||
var/obj/item/weapon/shard/shrapnel/S = new()
|
||||
S.name = "[P.name] shrapnel"
|
||||
S.desc = "[S.desc] It looks like it was fired from [P.shot_from]."
|
||||
|
||||
@@ -159,6 +159,9 @@ emp_act
|
||||
for(var/datum/organ/external/O in organs)
|
||||
if(O.status & ORGAN_DESTROYED) continue
|
||||
O.emp_act(severity)
|
||||
for(var/datum/organ/internal/I in O.internal_organs)
|
||||
if(I.robotic == 0) continue
|
||||
I.emp_act(severity)
|
||||
..()
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
var/lip_style = null //no lipstick by default- arguably misleading, as it could be used for general makeup
|
||||
|
||||
var/age = 30 //Player's age (pure fluff)
|
||||
var/b_type = "A+" //Player's bloodtype (Not currently used, just character fluff)
|
||||
var/b_type = "A+" //Player's bloodtype
|
||||
|
||||
var/underwear = 1 //Which underwear the player wants
|
||||
var/backbag = 2 //Which backpack type the player has chosen. Nothing, Satchel or Backpack.
|
||||
|
||||
@@ -359,7 +359,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)
|
||||
@@ -960,6 +960,9 @@
|
||||
var/datum/organ/internal/liver/liver = internal_organs["liver"]
|
||||
liver.process()
|
||||
|
||||
var/datum/organ/internal/eyes/eyes = internal_organs["eyes"]
|
||||
eyes.process()
|
||||
|
||||
updatehealth()
|
||||
|
||||
return //TODO: DEFERRED
|
||||
@@ -1335,10 +1338,6 @@
|
||||
if(!O.up && tinted_weldhelh)
|
||||
client.screen += global_hud.darkMask
|
||||
|
||||
if(eye_stat > 20)
|
||||
if(eye_stat > 30) client.screen += global_hud.darkMask
|
||||
else client.screen += global_hud.vimpaired
|
||||
|
||||
if(machine)
|
||||
if(!machine.check_eye(src)) reset_view(null)
|
||||
else
|
||||
@@ -1433,7 +1432,7 @@
|
||||
else if(health < config.health_threshold_softcrit)
|
||||
shock_stage = max(shock_stage, 61)
|
||||
else
|
||||
shock_stage = min(shock_stage, 100)
|
||||
shock_stage = min(shock_stage, 160)
|
||||
shock_stage = max(shock_stage-1, 0)
|
||||
return
|
||||
|
||||
@@ -1450,15 +1449,26 @@
|
||||
|
||||
if (shock_stage >= 60)
|
||||
if(shock_stage == 60) emote("me",1,"'s body becomes limp.")
|
||||
if (prob(2))
|
||||
src << "<font color='red'><b>"+pick("The pain is excrutiating!", "Please, just end the pain!", "Your whole body is going numb!")
|
||||
Weaken(20)
|
||||
|
||||
if(shock_stage >= 80)
|
||||
if (prob(5))
|
||||
Stun(20)
|
||||
lying = 1
|
||||
src << "<font color='red'><b>"+pick("The pain is excrutiating!", "Please, just end the pain!", "Your whole body is going numb!")
|
||||
Weaken(20)
|
||||
|
||||
if(shock_stage == 80)
|
||||
src << "<font color='red'><b>"+pick("You see a light at the end of the tunnel!", "You feel like you could die any moment now.", "You're about to lose consciousness.")
|
||||
if(shock_stage >= 120)
|
||||
if (prob(2))
|
||||
src << "<font color='red'><b>"+pick("You black out!", "You feel like you could die any moment now.", "You're about to lose consciousness.")
|
||||
Paralyse(5)
|
||||
|
||||
if(shock_stage > 80)
|
||||
Paralyse(rand(15,28))
|
||||
if(shock_stage == 150)
|
||||
emote("me",1,"can no longer stand, collapsing!")
|
||||
Weaken(20)
|
||||
|
||||
if(shock_stage >= 150)
|
||||
Weaken(20)
|
||||
|
||||
proc/handle_pulse()
|
||||
if(life_tick % 5) return pulse //update pulse every 5 life ticks (~1 tick/sec, depending on server load)
|
||||
@@ -1485,6 +1495,15 @@
|
||||
if(temp <= PULSE_FAST && temp >= PULSE_NONE)
|
||||
temp++
|
||||
break
|
||||
for(var/datum/reagent/R in reagents.reagent_list) //To avoid using fakedeath
|
||||
if(R.id in heartstopper)
|
||||
temp = PULSE_NONE
|
||||
break
|
||||
for(var/datum/reagent/R in reagents.reagent_list) //Conditional heart-stoppage
|
||||
if(R.id in cheartstopper)
|
||||
if(R.volume >= R.overdose)
|
||||
temp = PULSE_NONE
|
||||
break
|
||||
|
||||
return temp
|
||||
|
||||
|
||||
@@ -123,7 +123,6 @@ Please contact me on #coderbus IRC. ~Carn x
|
||||
//////////////////////////////////
|
||||
|
||||
/mob/living/carbon/human
|
||||
var/list/overlays_lying[TOTAL_LAYERS]
|
||||
var/list/overlays_standing[TOTAL_LAYERS]
|
||||
var/previous_damage_appearance // store what the body last looked like, so we only have to update it if something changed
|
||||
var/icon/race_icon
|
||||
@@ -137,28 +136,32 @@ Please contact me on #coderbus IRC. ~Carn x
|
||||
update_hud() //TODO: remove the need for this
|
||||
overlays.Cut()
|
||||
|
||||
if(lying) //can't be cloaked when lying. (for now)
|
||||
icon = lying_icon
|
||||
for(var/image/I in overlays_lying)
|
||||
overlays += I
|
||||
var/stealth = 0
|
||||
//cloaking devices. //TODO: get rid of this :<
|
||||
for(var/obj/item/weapon/cloaking_device/S in list(l_hand,r_hand,belt,l_store,r_store))
|
||||
if(S.active)
|
||||
stealth = 1
|
||||
break
|
||||
if(stealth)
|
||||
icon = 'icons/mob/human.dmi'
|
||||
icon_state = "body_cloaked"
|
||||
var/image/I = overlays_standing[L_HAND_LAYER]
|
||||
if(istype(I)) overlays += I
|
||||
I = overlays_standing[R_HAND_LAYER]
|
||||
if(istype(I)) overlays += I
|
||||
else
|
||||
var/stealth = 0
|
||||
//cloaking devices. //TODO: get rid of this :<
|
||||
for(var/obj/item/weapon/cloaking_device/S in list(l_hand,r_hand,belt,l_store,r_store))
|
||||
if(S.active)
|
||||
stealth = 1
|
||||
break
|
||||
if(stealth)
|
||||
icon = 'icons/mob/human.dmi'
|
||||
icon_state = "body_cloaked"
|
||||
var/image/I = overlays_standing[L_HAND_LAYER]
|
||||
if(istype(I)) overlays += I
|
||||
I = overlays_standing[R_HAND_LAYER]
|
||||
if(istype(I)) overlays += I
|
||||
else
|
||||
icon = stand_icon
|
||||
for(var/image/I in overlays_standing)
|
||||
overlays += I
|
||||
icon = stand_icon
|
||||
for(var/image/I in overlays_standing)
|
||||
overlays += I
|
||||
|
||||
if(lying)
|
||||
var/matrix/M = matrix()
|
||||
M.Turn(90)
|
||||
M.Translate(1,-6)
|
||||
src.transform = M
|
||||
else
|
||||
var/matrix/M = matrix()
|
||||
src.transform = M
|
||||
|
||||
var/global/list/damage_icon_parts = list()
|
||||
proc/get_damage_icon_part(damage_state, body_part)
|
||||
@@ -188,10 +191,8 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
previous_damage_appearance = damage_appearance
|
||||
|
||||
var/icon/standing = new /icon('icons/mob/dam_human.dmi', "00")
|
||||
var/icon/lying = new /icon('icons/mob/dam_human.dmi', "00-2")
|
||||
|
||||
var/image/standing_image = new /image("icon" = standing)
|
||||
var/image/lying_image = new /image("icon" = lying)
|
||||
|
||||
|
||||
// blend the individual damage states with our icons
|
||||
@@ -204,19 +205,14 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
|
||||
standing_image.overlays += DI
|
||||
|
||||
DI = get_damage_icon_part("[O.damage_state]-2", "[O.icon_name]2")
|
||||
lying_image.overlays += DI
|
||||
|
||||
|
||||
overlays_standing[DAMAGE_LAYER] = standing_image
|
||||
overlays_lying[DAMAGE_LAYER] = lying_image
|
||||
|
||||
if(update_icons) update_icons()
|
||||
|
||||
//BASE MOB SPRITE
|
||||
/mob/living/carbon/human/proc/update_body(var/update_icons=1)
|
||||
if(stand_icon) del(stand_icon)
|
||||
if(lying_icon) del(lying_icon)
|
||||
|
||||
var/husk_color_mod = rgb(96,88,80)
|
||||
var/hulk_color_mod = rgb(48,224,40)
|
||||
@@ -252,9 +248,6 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
else
|
||||
temp = part.get_icon()
|
||||
|
||||
if(part.status & ORGAN_ROBOT)
|
||||
temp.GrayScale()
|
||||
|
||||
if(part.status & ORGAN_DEAD)
|
||||
temp.ColorTone(necrosis_color_mod)
|
||||
temp.SetIntensity(0.7)
|
||||
@@ -316,8 +309,6 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
if(!fat && !skeleton)
|
||||
stand_icon.Blend(new /icon('icons/mob/human.dmi', "underwear[underwear]_[g]_s"), ICON_OVERLAY)
|
||||
|
||||
lying_icon = stand_icon.MakeLying()
|
||||
|
||||
if(update_icons)
|
||||
update_icons()
|
||||
|
||||
@@ -328,7 +319,6 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
//HAIR OVERLAY
|
||||
/mob/living/carbon/human/proc/update_hair(var/update_icons=1)
|
||||
//Reset our hair
|
||||
overlays_lying[HAIR_LAYER] = null
|
||||
overlays_standing[HAIR_LAYER] = null
|
||||
|
||||
var/datum/organ/external/head/head_organ = get_organ("head")
|
||||
@@ -343,33 +333,25 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
|
||||
//base icons
|
||||
var/icon/face_standing = new /icon('icons/mob/human_face.dmi',"bald_s")
|
||||
var/icon/face_lying = new /icon('icons/mob/human_face.dmi',"bald_l")
|
||||
|
||||
if(f_style)
|
||||
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style]
|
||||
if(facial_hair_style && src.species.name in facial_hair_style.species_allowed)
|
||||
var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
|
||||
var/icon/facial_l = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_l")
|
||||
if(facial_hair_style.do_colouration)
|
||||
facial_s.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD)
|
||||
facial_l.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD)
|
||||
|
||||
face_standing.Blend(facial_s, ICON_OVERLAY)
|
||||
face_lying.Blend(facial_l, ICON_OVERLAY)
|
||||
|
||||
if(h_style && !(head && (head.flags & BLOCKHEADHAIR)))
|
||||
var/datum/sprite_accessory/hair_style = hair_styles_list[h_style]
|
||||
if(hair_style && src.species.name in hair_style.species_allowed)
|
||||
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
|
||||
var/icon/hair_l = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_l")
|
||||
if(hair_style.do_colouration)
|
||||
hair_s.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
|
||||
hair_l.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
|
||||
|
||||
face_standing.Blend(hair_s, ICON_OVERLAY)
|
||||
face_lying.Blend(hair_l, ICON_OVERLAY)
|
||||
|
||||
overlays_lying[HAIR_LAYER] = image(face_lying)
|
||||
overlays_standing[HAIR_LAYER] = image(face_standing)
|
||||
|
||||
if(update_icons) update_icons()
|
||||
@@ -379,7 +361,6 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
if(FAT in mutations)
|
||||
fat = "fat"
|
||||
|
||||
var/image/lying = image("icon" = 'icons/effects/genetics.dmi')
|
||||
var/image/standing = image("icon" = 'icons/effects/genetics.dmi')
|
||||
var/add_image = 0
|
||||
var/g = "m"
|
||||
@@ -388,29 +369,22 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
switch(mut)
|
||||
if(HULK)
|
||||
if(fat)
|
||||
lying.underlays += "hulk_[fat]_l"
|
||||
standing.underlays += "hulk_[fat]_s"
|
||||
else
|
||||
lying.underlays += "hulk_[g]_l"
|
||||
standing.underlays += "hulk_[g]_s"
|
||||
add_image = 1
|
||||
if(COLD_RESISTANCE)
|
||||
lying.underlays += "fire[fat]_l"
|
||||
standing.underlays += "fire[fat]_s"
|
||||
add_image = 1
|
||||
if(TK)
|
||||
lying.underlays += "telekinesishead[fat]_l"
|
||||
standing.underlays += "telekinesishead[fat]_s"
|
||||
add_image = 1
|
||||
if(LASER)
|
||||
lying.overlays += "lasereyes_l"
|
||||
standing.overlays += "lasereyes_s"
|
||||
add_image = 1
|
||||
if(add_image)
|
||||
overlays_lying[MUTATIONS_LAYER] = lying
|
||||
overlays_standing[MUTATIONS_LAYER] = standing
|
||||
else
|
||||
overlays_lying[MUTATIONS_LAYER] = null
|
||||
overlays_standing[MUTATIONS_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
@@ -433,10 +407,8 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
if(dna)
|
||||
switch(dna.mutantrace)
|
||||
if("golem","slime","shadow","adamantine")
|
||||
overlays_lying[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/genetics.dmi', "icon_state" = "[dna.mutantrace][fat]_[gender]_l")
|
||||
overlays_standing[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/genetics.dmi', "icon_state" = "[dna.mutantrace][fat]_[gender]_s")
|
||||
else
|
||||
overlays_lying[MUTANTRACE_LAYER] = null
|
||||
overlays_standing[MUTANTRACE_LAYER] = null
|
||||
|
||||
if(!dna || !(dna.mutantrace in list("golem","metroid")))
|
||||
@@ -448,12 +420,10 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
//Call when target overlay should be added/removed
|
||||
/mob/living/carbon/human/update_targeted(var/update_icons=1)
|
||||
if (targeted_by && target_locked)
|
||||
overlays_lying[TARGETED_LAYER] = target_locked
|
||||
overlays_standing[TARGETED_LAYER] = target_locked
|
||||
else if (!targeted_by && target_locked)
|
||||
del(target_locked)
|
||||
if (!targeted_by)
|
||||
overlays_lying[TARGETED_LAYER] = null
|
||||
overlays_standing[TARGETED_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
@@ -495,27 +465,20 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
w_uniform.screen_loc = ui_iclothing
|
||||
var/t_color = w_uniform.item_color
|
||||
if(!t_color) t_color = icon_state
|
||||
var/image/lying = image("icon_state" = "[t_color]_l")
|
||||
var/image/standing = image("icon_state" = "[t_color]_s")
|
||||
|
||||
|
||||
lying.icon = 'icons/mob/uniform.dmi'
|
||||
standing.icon = 'icons/mob/uniform.dmi'
|
||||
|
||||
if(w_uniform.blood_DNA)
|
||||
lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "uniformblood2")
|
||||
standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "uniformblood")
|
||||
|
||||
if(w_uniform:hastie) //WE CHECKED THE TYPE ABOVE. THIS REALLY SHOULD BE FINE.
|
||||
var/tie_color = w_uniform:hastie.item_color
|
||||
if(!tie_color) tie_color = w_uniform:hastie.icon_state
|
||||
lying.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]2")
|
||||
standing.overlays += image("icon" = 'icons/mob/ties.dmi', "icon_state" = "[tie_color]")
|
||||
|
||||
overlays_lying[UNIFORM_LAYER] = lying
|
||||
overlays_standing[UNIFORM_LAYER] = standing
|
||||
else
|
||||
overlays_lying[UNIFORM_LAYER] = null
|
||||
overlays_standing[UNIFORM_LAYER] = null
|
||||
// Automatically drop anything in store / id / belt if you're not wearing a uniform. //CHECK IF NECESARRY
|
||||
for( var/obj/item/thing in list(r_store, l_store, wear_id, belt) ) //
|
||||
@@ -534,13 +497,10 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
if(wear_id)
|
||||
wear_id.screen_loc = ui_id //TODO
|
||||
if(w_uniform && w_uniform:displays_id)
|
||||
overlays_lying[ID_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "id2")
|
||||
overlays_standing[ID_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "id")
|
||||
else
|
||||
overlays_lying[ID_LAYER] = null
|
||||
overlays_standing[ID_LAYER] = null
|
||||
else
|
||||
overlays_lying[ID_LAYER] = null
|
||||
overlays_standing[ID_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
@@ -548,57 +508,43 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
if(gloves)
|
||||
var/t_state = gloves.item_state
|
||||
if(!t_state) t_state = gloves.icon_state
|
||||
var/image/lying = image("icon" = 'icons/mob/hands.dmi', "icon_state" = "[t_state]2")
|
||||
var/image/standing = image("icon" = 'icons/mob/hands.dmi', "icon_state" = "[t_state]")
|
||||
if(gloves.blood_DNA)
|
||||
lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands2")
|
||||
standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands")
|
||||
gloves.screen_loc = ui_gloves
|
||||
overlays_lying[GLOVES_LAYER] = lying
|
||||
overlays_standing[GLOVES_LAYER] = standing
|
||||
else
|
||||
if(blood_DNA)
|
||||
overlays_lying[GLOVES_LAYER] = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands2")
|
||||
overlays_standing[GLOVES_LAYER] = image("icon" = 'icons/effects/blood.dmi', "icon_state" = "bloodyhands")
|
||||
else
|
||||
overlays_lying[GLOVES_LAYER] = null
|
||||
overlays_standing[GLOVES_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_glasses(var/update_icons=1)
|
||||
if(glasses)
|
||||
overlays_lying[GLASSES_LAYER] = image("icon" = 'icons/mob/eyes.dmi', "icon_state" = "[glasses.icon_state]2")
|
||||
overlays_standing[GLASSES_LAYER] = image("icon" = 'icons/mob/eyes.dmi', "icon_state" = "[glasses.icon_state]")
|
||||
else
|
||||
overlays_lying[GLASSES_LAYER] = null
|
||||
overlays_standing[GLASSES_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/update_inv_ears(var/update_icons=1)
|
||||
if(l_ear || r_ear)
|
||||
if(l_ear)
|
||||
overlays_lying[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[l_ear.icon_state]2")
|
||||
overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[l_ear.icon_state]")
|
||||
if(r_ear)
|
||||
overlays_lying[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[r_ear.icon_state]2")
|
||||
overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[r_ear.icon_state]")
|
||||
else
|
||||
overlays_lying[EARS_LAYER] = null
|
||||
overlays_standing[EARS_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/update_inv_shoes(var/update_icons=1)
|
||||
if(shoes)
|
||||
var/image/lying = image("icon" = 'icons/mob/feet.dmi', "icon_state" = "[shoes.icon_state]2")
|
||||
var/image/standing = image("icon" = 'icons/mob/feet.dmi', "icon_state" = "[shoes.icon_state]")
|
||||
if(shoes.blood_DNA)
|
||||
lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "shoeblood2")
|
||||
standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "shoeblood")
|
||||
overlays_lying[SHOES_LAYER] = lying
|
||||
overlays_standing[SHOES_LAYER] = standing
|
||||
else
|
||||
overlays_lying[SHOES_LAYER] = null
|
||||
overlays_standing[SHOES_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
@@ -606,11 +552,9 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
if(s_store)
|
||||
var/t_state = s_store.item_state
|
||||
if(!t_state) t_state = s_store.icon_state
|
||||
overlays_lying[SUIT_STORE_LAYER] = image("icon" = 'icons/mob/belt_mirror.dmi', "icon_state" = "[t_state]2")
|
||||
overlays_standing[SUIT_STORE_LAYER] = image("icon" = 'icons/mob/belt_mirror.dmi', "icon_state" = "[t_state]")
|
||||
s_store.screen_loc = ui_sstore1 //TODO
|
||||
else
|
||||
overlays_lying[SUIT_STORE_LAYER] = null
|
||||
overlays_standing[SUIT_STORE_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
@@ -618,21 +562,15 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
/mob/living/carbon/human/update_inv_head(var/update_icons=1)
|
||||
if(head)
|
||||
head.screen_loc = ui_head //TODO
|
||||
var/image/lying
|
||||
var/image/standing
|
||||
if(istype(head,/obj/item/clothing/head/kitty))
|
||||
lying = image("icon" = head:mob2)
|
||||
standing = image("icon" = head:mob)
|
||||
else
|
||||
lying = image("icon" = 'icons/mob/head.dmi', "icon_state" = "[head.icon_state]2")
|
||||
standing = image("icon" = 'icons/mob/head.dmi', "icon_state" = "[head.icon_state]")
|
||||
if(head.blood_DNA)
|
||||
lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "helmetblood2")
|
||||
standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "helmetblood")
|
||||
overlays_lying[HEAD_LAYER] = lying
|
||||
overlays_standing[HEAD_LAYER] = standing
|
||||
else
|
||||
overlays_lying[HEAD_LAYER] = null
|
||||
overlays_standing[HEAD_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
@@ -641,10 +579,8 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
belt.screen_loc = ui_belt //TODO
|
||||
var/t_state = belt.item_state
|
||||
if(!t_state) t_state = belt.icon_state
|
||||
overlays_lying[BELT_LAYER] = image("icon" = 'icons/mob/belt.dmi', "icon_state" = "[t_state]2")
|
||||
overlays_standing[BELT_LAYER] = image("icon" = 'icons/mob/belt.dmi', "icon_state" = "[t_state]")
|
||||
else
|
||||
overlays_lying[BELT_LAYER] = null
|
||||
overlays_standing[BELT_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
@@ -652,7 +588,6 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
/mob/living/carbon/human/update_inv_wear_suit(var/update_icons=1)
|
||||
if( wear_suit && istype(wear_suit, /obj/item/clothing/suit) ) //TODO check this
|
||||
wear_suit.screen_loc = ui_oclothing //TODO
|
||||
var/image/lying = image("icon" = 'icons/mob/suit.dmi', "icon_state" = "[wear_suit.icon_state]2")
|
||||
var/image/standing = image("icon" = 'icons/mob/suit.dmi', "icon_state" = "[wear_suit.icon_state]")
|
||||
|
||||
if( istype(wear_suit, /obj/item/clothing/suit/straight_jacket) )
|
||||
@@ -662,16 +597,13 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
|
||||
if(wear_suit.blood_DNA)
|
||||
var/obj/item/clothing/suit/S = wear_suit
|
||||
lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "[S.blood_overlay_type]blood2")
|
||||
standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "[S.blood_overlay_type]blood")
|
||||
|
||||
overlays_lying[SUIT_LAYER] = lying
|
||||
overlays_standing[SUIT_LAYER] = standing
|
||||
|
||||
update_tail_showing(0)
|
||||
|
||||
else
|
||||
overlays_lying[SUIT_LAYER] = null
|
||||
overlays_standing[SUIT_LAYER] = null
|
||||
|
||||
update_tail_showing(0)
|
||||
@@ -687,15 +619,11 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
/mob/living/carbon/human/update_inv_wear_mask(var/update_icons=1)
|
||||
if( wear_mask && ( istype(wear_mask, /obj/item/clothing/mask) || istype(wear_mask, /obj/item/clothing/tie) ) )
|
||||
wear_mask.screen_loc = ui_mask //TODO
|
||||
var/image/lying = image("icon" = 'icons/mob/mask.dmi', "icon_state" = "[wear_mask.icon_state]2")
|
||||
var/image/standing = image("icon" = 'icons/mob/mask.dmi', "icon_state" = "[wear_mask.icon_state]")
|
||||
if( !istype(wear_mask, /obj/item/clothing/mask/cigarette) && wear_mask.blood_DNA )
|
||||
lying.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "maskblood2")
|
||||
standing.overlays += image("icon" = 'icons/effects/blood.dmi', "icon_state" = "maskblood")
|
||||
overlays_lying[FACEMASK_LAYER] = lying
|
||||
overlays_standing[FACEMASK_LAYER] = standing
|
||||
else
|
||||
overlays_lying[FACEMASK_LAYER] = null
|
||||
overlays_standing[FACEMASK_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
@@ -703,10 +631,8 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
/mob/living/carbon/human/update_inv_back(var/update_icons=1)
|
||||
if(back)
|
||||
back.screen_loc = ui_back //TODO
|
||||
overlays_lying[BACK_LAYER] = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]2")
|
||||
overlays_standing[BACK_LAYER] = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]")
|
||||
else
|
||||
overlays_lying[BACK_LAYER] = null
|
||||
overlays_standing[BACK_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
@@ -723,16 +649,13 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
drop_r_hand()
|
||||
drop_l_hand()
|
||||
stop_pulling() //TODO: should be handled elsewhere
|
||||
overlays_lying[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff2")
|
||||
overlays_standing[HANDCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1")
|
||||
else
|
||||
overlays_lying[HANDCUFF_LAYER] = null
|
||||
overlays_standing[HANDCUFF_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/update_inv_legcuffed(var/update_icons=1)
|
||||
if(legcuffed)
|
||||
overlays_lying[LEGCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "legcuff2")
|
||||
overlays_standing[LEGCUFF_LAYER] = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "legcuff1")
|
||||
if(src.m_intent != "walk")
|
||||
src.m_intent = "walk"
|
||||
@@ -740,7 +663,6 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
src.hud_used.move_intent.icon_state = "walking"
|
||||
|
||||
else
|
||||
overlays_lying[LEGCUFF_LAYER] = null
|
||||
overlays_standing[LEGCUFF_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
@@ -769,12 +691,10 @@ proc/get_damage_icon_part(damage_state, body_part)
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/proc/update_tail_showing(var/update_icons=1)
|
||||
overlays_lying[TAIL_LAYER] = null
|
||||
overlays_standing[TAIL_LAYER] = null
|
||||
|
||||
if(species.tail && species.flags & HAS_TAIL)
|
||||
if(!wear_suit || !(wear_suit.flags_inv & HIDEJUMPSUIT) && !istype(wear_suit, /obj/item/clothing/suit/space))
|
||||
overlays_lying[TAIL_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_l")
|
||||
overlays_standing[TAIL_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_s")
|
||||
|
||||
if(update_icons)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
name = "diona nymph"
|
||||
voice_name = "diona nymph"
|
||||
speak_emote = list("chirrups")
|
||||
ico = "nymph"
|
||||
icon_state = "nymph1"
|
||||
var/list/donors = list()
|
||||
var/ready_evolve = 0
|
||||
|
||||
|
||||
@@ -250,7 +250,7 @@
|
||||
block = 1
|
||||
|
||||
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)
|
||||
|
||||
@@ -10,28 +10,27 @@
|
||||
|
||||
var/obj/item/weapon/card/id/wear_id = null // Fix for station bounced radios -- Skie
|
||||
var/greaterform = "Human" // Used when humanizing a monkey.
|
||||
var/ico = "monkey" // Used when updating icons.
|
||||
var/uni_append = "12C4E2" // Small appearance modifier for different species.
|
||||
|
||||
/mob/living/carbon/monkey/tajara
|
||||
name = "farwa"
|
||||
voice_name = "farwa"
|
||||
speak_emote = list("mews")
|
||||
ico = "tajkey"
|
||||
icon_state = "tajkey1"
|
||||
uni_append = "0A0E00"
|
||||
|
||||
/mob/living/carbon/monkey/skrell
|
||||
name = "neaera"
|
||||
voice_name = "neaera"
|
||||
speak_emote = list("squicks")
|
||||
ico = "skrellkey"
|
||||
icon_state = "skrellkey1"
|
||||
uni_append = "01CC92"
|
||||
|
||||
/mob/living/carbon/monkey/unathi
|
||||
name = "stok"
|
||||
voice_name = "stok"
|
||||
speak_emote = list("hisses")
|
||||
ico = "stokkey"
|
||||
icon_state = "stokkey1"
|
||||
uni_append = "044C5D"
|
||||
|
||||
/mob/living/carbon/monkey/New()
|
||||
|
||||
@@ -28,25 +28,25 @@
|
||||
update_hud()
|
||||
lying_prev = lying //so we don't update overlays for lying/standing unless our stance changes again
|
||||
overlays.Cut()
|
||||
for(var/image/I in overlays_standing)
|
||||
overlays += I
|
||||
|
||||
if(lying)
|
||||
icon_state = ico + "0"
|
||||
for(var/image/I in overlays_lying)
|
||||
overlays += I
|
||||
var/matrix/M = matrix()
|
||||
M.Turn(90)
|
||||
M.Translate(1,-6)
|
||||
src.transform = M
|
||||
else
|
||||
icon_state = ico + "1"
|
||||
for(var/image/I in overlays_standing)
|
||||
overlays += I
|
||||
var/matrix/M = matrix()
|
||||
src.transform = M
|
||||
|
||||
|
||||
////////
|
||||
/mob/living/carbon/monkey/update_inv_wear_mask(var/update_icons=1)
|
||||
if( wear_mask && istype(wear_mask, /obj/item/clothing/mask) )
|
||||
overlays_lying[M_MASK_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "[wear_mask.icon_state]2")
|
||||
overlays_standing[M_MASK_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "[wear_mask.icon_state]")
|
||||
wear_mask.screen_loc = ui_monkey_mask
|
||||
else
|
||||
overlays_lying[M_MASK_LAYER] = null
|
||||
overlays_standing[M_MASK_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
@@ -77,11 +77,9 @@
|
||||
|
||||
/mob/living/carbon/monkey/update_inv_back(var/update_icons=1)
|
||||
if(back)
|
||||
overlays_lying[M_BACK_LAYER] = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]2")
|
||||
overlays_standing[M_BACK_LAYER] = image("icon" = 'icons/mob/back.dmi', "icon_state" = "[back.icon_state]")
|
||||
back.screen_loc = ui_monkey_back
|
||||
else
|
||||
overlays_lying[M_BACK_LAYER] = null
|
||||
overlays_standing[M_BACK_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
@@ -91,10 +89,8 @@
|
||||
drop_r_hand()
|
||||
drop_l_hand()
|
||||
stop_pulling()
|
||||
overlays_lying[M_HANDCUFF_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "handcuff2")
|
||||
overlays_standing[M_HANDCUFF_LAYER] = image("icon" = 'icons/mob/monkey.dmi', "icon_state" = "handcuff1")
|
||||
else
|
||||
overlays_lying[M_HANDCUFF_LAYER] = null
|
||||
overlays_standing[M_HANDCUFF_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
@@ -106,12 +102,10 @@
|
||||
//Call when target overlay should be added/removed
|
||||
/mob/living/carbon/monkey/update_targeted(var/update_icons=1)
|
||||
if (targeted_by && target_locked)
|
||||
overlays_lying[TARGETED_LAYER] = target_locked
|
||||
overlays_standing[TARGETED_LAYER] = target_locked
|
||||
else if (!targeted_by && target_locked)
|
||||
del(target_locked)
|
||||
if (!targeted_by)
|
||||
overlays_lying[TARGETED_LAYER] = null
|
||||
overlays_standing[TARGETED_LAYER] = null
|
||||
if(update_icons) update_icons()
|
||||
|
||||
|
||||
@@ -5,20 +5,24 @@
|
||||
/mob/living/carbon/proc/updateshock()
|
||||
src.traumatic_shock = \
|
||||
1 * src.getOxyLoss() + \
|
||||
0.5 * src.getToxLoss() + \
|
||||
2.5 * src.getFireLoss() + \
|
||||
1.5 * src.getBruteLoss() + \
|
||||
2 * src.getCloneLoss() + \
|
||||
1 * src.halloss
|
||||
0.7 * src.getToxLoss() + \
|
||||
1.5 * src.getFireLoss() + \
|
||||
1.2 * src.getBruteLoss() + \
|
||||
1.7 * src.getCloneLoss() + \
|
||||
2 * src.halloss
|
||||
|
||||
if(reagents.has_reagent("alkysine"))
|
||||
src.traumatic_shock -= 10
|
||||
if(reagents.has_reagent("inaprovaline"))
|
||||
src.traumatic_shock -= 25
|
||||
if(reagents.has_reagent("synaptizine"))
|
||||
src.traumatic_shock -= 40
|
||||
if(reagents.has_reagent("paracetamol"))
|
||||
src.traumatic_shock -= 50
|
||||
if(reagents.has_reagent("tramadol"))
|
||||
src.traumatic_shock -= 80 // make synaptizine function as good painkiller
|
||||
src.traumatic_shock -= 80
|
||||
if(reagents.has_reagent("oxycodone"))
|
||||
src.traumatic_shock -= 200 // make synaptizine function as good painkiller
|
||||
src.traumatic_shock -= 200
|
||||
if(src.slurring)
|
||||
src.traumatic_shock -= 20
|
||||
if(src.analgesic)
|
||||
@@ -35,7 +39,7 @@
|
||||
else if(organ.status & ORGAN_BROKEN || organ.open)
|
||||
src.traumatic_shock += 30
|
||||
if(organ.status & ORGAN_SPLINTED)
|
||||
src.traumatic_shock -= 20
|
||||
src.traumatic_shock -= 25
|
||||
|
||||
if(src.traumatic_shock < 0)
|
||||
src.traumatic_shock = 0
|
||||
|
||||
@@ -280,7 +280,6 @@
|
||||
blinded = 0
|
||||
eye_blind = 0
|
||||
eye_blurry = 0
|
||||
eye_stat = 0
|
||||
ear_deaf = 0
|
||||
ear_damage = 0
|
||||
heal_overall_damage(getBruteLoss(), getFireLoss())
|
||||
|
||||
@@ -302,6 +302,7 @@ var/list/department_radio_keys = list(
|
||||
var/list/listening
|
||||
|
||||
listening = get_mobs_in_view(message_range, src)
|
||||
var/list/onscreen = get_mobs_in_view(7, src)
|
||||
for(var/mob/M in player_list)
|
||||
if (!M.client)
|
||||
continue //skip monkeys and leavers
|
||||
@@ -370,16 +371,19 @@ var/list/department_radio_keys = list(
|
||||
for(var/mob/M in hearers(5, src))
|
||||
if(M != src && is_speaking_radio)
|
||||
M:show_message("<span class='notice'>[src] talks into [used_radios.len ? used_radios[1] : "radio"]</span>")
|
||||
|
||||
|
||||
var/rendered = null
|
||||
|
||||
if (length(heard_a))
|
||||
var/message_a = say_quote(message,speaking)
|
||||
|
||||
if (italics)
|
||||
message_a = "<i>[message_a]</i>"
|
||||
|
||||
var/message_ghost = "<b>[message_a]</b>" // bold so ghosts know the person is in view.
|
||||
rendered = "<span class='game say'><span class='name'>[GetVoice()]</span>[alt_name] <span class='message'>[message_a]</span></span>"
|
||||
for (var/M in heard_a)
|
||||
var/rendered_ghost = "<span class='game say'><span class='name'>[GetVoice()]</span>[alt_name] <span class='message'>[message_ghost]</span></span>"
|
||||
for (var/mob/M in heard_a)
|
||||
if(hascall(M,"show_message"))
|
||||
var/deaf_message = ""
|
||||
var/deaf_type = 1
|
||||
@@ -388,7 +392,10 @@ var/list/department_radio_keys = list(
|
||||
else
|
||||
deaf_message = "<span class='notice'>You cannot hear yourself!</span>"
|
||||
deaf_type = 2 // Since you should be able to hear yourself without looking
|
||||
M:show_message(rendered, 2, deaf_message, deaf_type)
|
||||
if (M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTEARS) && M in onscreen)
|
||||
M:show_message(rendered_ghost, 2, deaf_message, deaf_type)
|
||||
else
|
||||
M:show_message(rendered, 2, deaf_message, deaf_type)
|
||||
M << speech_bubble
|
||||
|
||||
if (length(heard_b))
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
//smoke, water and steam calms us down
|
||||
var/calming = 0
|
||||
var/list/calmers = list(/obj/effect/effect/chem_smoke, \
|
||||
var/list/calmers = list(/obj/effect/effect/smoke/chem, \
|
||||
/obj/effect/effect/water, \
|
||||
/obj/effect/effect/foam, \
|
||||
/obj/effect/effect/steam, \
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
New()
|
||||
..()
|
||||
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.loc)
|
||||
smoke.start()
|
||||
visible_message("\red <B>The [src] warps in!</B>")
|
||||
|
||||
@@ -240,6 +240,8 @@ var/list/slot_equipment_priority = list( \
|
||||
set category = "Object"
|
||||
set src = usr
|
||||
|
||||
if(istype(loc,/obj/mecha)) return
|
||||
|
||||
if(hand)
|
||||
var/obj/item/W = l_hand
|
||||
if (W)
|
||||
|
||||
@@ -81,7 +81,6 @@
|
||||
var/lying = 0
|
||||
var/lying_prev = 0
|
||||
var/canmove = 1
|
||||
var/eye_stat = null//Living, potentially Carbon
|
||||
var/lastpuke = 0
|
||||
var/unacidable = 0
|
||||
var/small = 0
|
||||
|
||||
@@ -114,6 +114,11 @@
|
||||
name = "Ponytail 3"
|
||||
icon_state = "hair_ponytail3"
|
||||
|
||||
sideponytail
|
||||
name = "Side Ponytail"
|
||||
icon_state = "hair_stail"
|
||||
gender = FEMALE
|
||||
|
||||
parted
|
||||
name = "Parted"
|
||||
icon_state = "hair_parted"
|
||||
@@ -241,6 +246,11 @@
|
||||
icon_state = "hair_gelled"
|
||||
gender = FEMALE
|
||||
|
||||
gentle
|
||||
name = "Gentle"
|
||||
icon_state = "hair_gentle"
|
||||
gender = FEMALE
|
||||
|
||||
spiky
|
||||
name = "Spiky"
|
||||
icon_state = "hair_spikey"
|
||||
@@ -264,6 +274,11 @@
|
||||
icon_state = "hair_braid"
|
||||
gender = FEMALE
|
||||
|
||||
braid2
|
||||
name = "Long Braid"
|
||||
icon_state = "hair_hbraid"
|
||||
gender = FEMALE
|
||||
|
||||
odango
|
||||
name = "Odango"
|
||||
icon_state = "hair_odango"
|
||||
@@ -469,6 +484,18 @@
|
||||
species_allowed = list("Tajaran")
|
||||
do_colouration = 0
|
||||
|
||||
taj_ears_bangs
|
||||
name = "Tajara Bangs"
|
||||
icon_state = "hair_bangs"
|
||||
species_allowed = list("Tajaran")
|
||||
do_colouration = 0
|
||||
|
||||
taj_ears_braid
|
||||
name = "Tajara Braid"
|
||||
icon_state = "hair_tbraid"
|
||||
species_allowed = list("Tajaran")
|
||||
do_colouration = 0
|
||||
|
||||
taj_ears_shaggy
|
||||
name = "Tajara Shaggy"
|
||||
icon_state = "hair_shaggy"
|
||||
|
||||
@@ -235,9 +235,14 @@
|
||||
|
||||
O.loc = loc
|
||||
O.job = "Cyborg"
|
||||
|
||||
O.mmi = new /obj/item/device/mmi(O)
|
||||
O.mmi.transfer_identity(src)//Does not transfer key/client.
|
||||
if(O.mind.assigned_role == "Cyborg")
|
||||
if(O.mind.role_alt_title == "Android")
|
||||
O.mmi = new /obj/item/device/mmi/posibrain(O)
|
||||
if(O.mind.role_alt_title == "Robot")
|
||||
O.mmi = new /obj/item/device/mmi/posibrain(O) //Ravensdale wants a circuit based brain for another robot class, this is a placeholder.
|
||||
else
|
||||
O.mmi = new /obj/item/device/mmi(O)
|
||||
O.mmi.transfer_identity(src)//Does not transfer key/client.
|
||||
|
||||
O.Namepick()
|
||||
|
||||
|
||||
@@ -55,11 +55,11 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
|
||||
// being pumped properly anymore.
|
||||
var/datum/organ/internal/heart/heart = internal_organs["heart"]
|
||||
switch(heart.damage)
|
||||
if(5 to 10)
|
||||
if(1 to heart.min_bruised_damage)
|
||||
blood_volume *= 0.8
|
||||
if(11 to 20)
|
||||
blood_volume *= 0.5
|
||||
if(21 to INFINITY)
|
||||
if(heart.min_bruised_damage to heart.min_broken_damage)
|
||||
blood_volume *= 0.6
|
||||
if(heart.min_broken_damage to INFINITY)
|
||||
blood_volume *= 0.3
|
||||
|
||||
//Effects of bloodloss
|
||||
@@ -93,7 +93,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
|
||||
src << "\red You feel extremely [word]"
|
||||
if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD)
|
||||
oxyloss += 5
|
||||
toxloss += 5
|
||||
toxloss += 3
|
||||
if(prob(15))
|
||||
var/word = pick("dizzy","woosey","faint")
|
||||
src << "\red You feel extremely [word]"
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
/mob/living/carbon/human/var/list/organs = list()
|
||||
/mob/living/carbon/human/var/list/organs_by_name = list() // map organ names to organs
|
||||
/mob/living/carbon/human/var/list/internal_organs_by_name = list() // so internal organs have less ickiness too
|
||||
|
||||
//Creates and initializes and connects external and internal organs
|
||||
/mob/living/carbon/human/proc/make_organs()
|
||||
@@ -51,11 +52,12 @@
|
||||
organs_by_name["l_foot"] = new/datum/organ/external/l_foot(organs_by_name["l_leg"])
|
||||
organs_by_name["r_foot"] = new/datum/organ/external/r_foot(organs_by_name["r_leg"])
|
||||
|
||||
new/datum/organ/internal/heart(src)
|
||||
new/datum/organ/internal/lungs(src)
|
||||
new/datum/organ/internal/liver(src)
|
||||
new/datum/organ/internal/kidney(src)
|
||||
new/datum/organ/internal/brain(src)
|
||||
internal_organs_by_name["heart"] = new/datum/organ/internal/heart(src)
|
||||
internal_organs_by_name["lungs"] = new/datum/organ/internal/lungs(src)
|
||||
internal_organs_by_name["liver"] = new/datum/organ/internal/liver(src)
|
||||
internal_organs_by_name["kidney"] = new/datum/organ/internal/kidney(src)
|
||||
internal_organs_by_name["brain"] = new/datum/organ/internal/brain(src)
|
||||
internal_organs_by_name["eyes"] = new/datum/organ/internal/eyes(src)
|
||||
|
||||
for(var/name in organs_by_name)
|
||||
organs += organs_by_name[name]
|
||||
@@ -91,7 +93,7 @@
|
||||
I.take_damage(rand(3,5))
|
||||
|
||||
//Special effects for limbs.
|
||||
if(E.name in list("l_hand","l_arm","r_hand","r_arm"))
|
||||
if(E.name in list("l_hand","l_arm","r_hand","r_arm") && (broken||malfunction))
|
||||
var/obj/item/c_hand //Getting what's in this hand
|
||||
if(E.name == "l_hand" || E.name == "l_arm")
|
||||
c_hand = l_hand
|
||||
@@ -99,8 +101,7 @@
|
||||
c_hand = r_hand
|
||||
|
||||
if (c_hand)
|
||||
if (broken||malfunction)
|
||||
u_equip(c_hand)
|
||||
u_equip(c_hand)
|
||||
|
||||
if(broken)
|
||||
emote("me", 1, "screams in pain and drops what they were holding in their [E.display_name?"[E.display_name]":"[E]"]!")
|
||||
@@ -124,35 +125,11 @@
|
||||
paralysis = 10
|
||||
|
||||
//Check arms and legs for existence
|
||||
var/canstand_l = 1 //Can stand on left leg
|
||||
var/canstand_r = 1 //Can stand on right leg
|
||||
var/hasleg_l = 1 //Have left leg
|
||||
var/hasleg_r = 1 //Have right leg
|
||||
var/hasarm_l = 1 //Have left arm
|
||||
var/hasarm_r = 1 //Have right arm
|
||||
var/datum/organ/external/E
|
||||
E = get_organ("l_leg")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
canstand_l = 0
|
||||
hasleg_l = 0
|
||||
E = get_organ("r_leg")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
canstand_r = 0
|
||||
hasleg_r = 0
|
||||
E = get_organ("l_foot")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
canstand_l = 0
|
||||
E = get_organ("r_foot")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
canstand_r = 0
|
||||
E = get_organ("l_arm")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
hasarm_l = 0
|
||||
E = get_organ("r_arm")
|
||||
if(E.status & ORGAN_DESTROYED && !(E.status & ORGAN_SPLINTED))
|
||||
hasarm_r = 0
|
||||
can_stand = 2 //can stand on both legs
|
||||
var/datum/organ/external/E = organs_by_name["l_foot"]
|
||||
if(E.status & ORGAN_DESTROYED)
|
||||
can_stand--
|
||||
|
||||
// Can stand if have at least one full leg (with leg and foot parts present)
|
||||
// Has limbs to move around if at least one arm or leg is at least partially there
|
||||
can_stand = canstand_l||canstand_r
|
||||
has_limbs = hasleg_l||hasleg_r||hasarm_l||hasarm_r
|
||||
E = organs_by_name["r_foot"]
|
||||
if(E.status & ORGAN_DESTROYED)
|
||||
can_stand--
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
// how often wounds should be updated, a higher number means less often
|
||||
var/wound_update_accuracy = 1
|
||||
|
||||
|
||||
/datum/organ/external/New(var/datum/organ/external/P)
|
||||
if(P)
|
||||
parent = P
|
||||
@@ -181,7 +182,7 @@
|
||||
|
||||
var/result = update_icon()
|
||||
return result
|
||||
|
||||
|
||||
/*
|
||||
This function completely restores a damaged organ to perfect condition.
|
||||
*/
|
||||
@@ -191,21 +192,20 @@ This function completely restores a damaged organ to perfect condition.
|
||||
perma_injury = 0
|
||||
brute_dam = 0
|
||||
burn_dam = 0
|
||||
|
||||
|
||||
// handle internal organs
|
||||
for(var/datum/organ/internal/current_organ in internal_organs)
|
||||
current_organ.rejuvenate()
|
||||
|
||||
|
||||
// remove embedded objects and drop them on the floor
|
||||
for(var/obj/implanted_object in implants)
|
||||
if(!istype(implanted_object,/obj/item/weapon/implant)) // We don't want to remove REAL implants. Just shrapnel etc.
|
||||
implanted_object.loc = owner.loc
|
||||
implants -= implanted_object
|
||||
|
||||
|
||||
owner.updatehealth()
|
||||
update_icon()
|
||||
|
||||
|
||||
|
||||
|
||||
/datum/organ/external/proc/createwound(var/type = CUT, var/damage)
|
||||
if(damage == 0) return
|
||||
|
||||
@@ -290,7 +290,6 @@ This function completely restores a damaged organ to perfect condition.
|
||||
perma_injury = 0
|
||||
|
||||
update_germs()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
//Updating germ levels. Handles organ germ levels and necrosis.
|
||||
@@ -299,6 +298,11 @@ This function completely restores a damaged organ to perfect condition.
|
||||
#define GANGREN_LEVEL_TERMINAL 2500
|
||||
#define GERM_TRANSFER_AMOUNT germ_level/500
|
||||
/datum/organ/external/proc/update_germs()
|
||||
|
||||
if(status & ORGAN_ROBOT|ORGAN_DESTROYED) //Robotic limbs shouldn't be infected, nor should nonexistant limbs.
|
||||
germ_level = 0
|
||||
return
|
||||
|
||||
if(germ_level > 0 && owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
|
||||
//Syncing germ levels with external wounds
|
||||
for(var/datum/wound/W in wounds)
|
||||
@@ -338,8 +342,9 @@ This function completely restores a damaged organ to perfect condition.
|
||||
|
||||
for(var/datum/wound/W in wounds)
|
||||
// wounds can disappear after 10 minutes at the earliest
|
||||
if(W.damage == 0 && W.created + 10 * 10 * 60 <= world.time)
|
||||
if(W.damage <= 0 && W.created + 10 * 10 * 60 <= world.time)
|
||||
wounds -= W
|
||||
continue
|
||||
// let the GC handle the deletion of the wound
|
||||
|
||||
// Internal wounds get worse over time. Low temperatures (cryo) stop them.
|
||||
@@ -347,17 +352,17 @@ This function completely restores a damaged organ to perfect condition.
|
||||
if(!owner.reagents.has_reagent("bicaridine")) //bicard stops internal wounds from growing bigger with time, and also stop bleeding
|
||||
W.open_wound(0.1 * wound_update_accuracy)
|
||||
owner.vessel.remove_reagent("blood",0.05 * W.damage * wound_update_accuracy)
|
||||
if(!owner.reagents.has_reagent("inaprovaline")) //This little copypaste will allow inaprovaline to work too, giving it a much needed buff to help medical.
|
||||
W.open_wound(0.1 * wound_update_accuracy)
|
||||
owner.vessel.remove_reagent("blood",0.05 * W.damage * wound_update_accuracy)
|
||||
|
||||
owner.vessel.remove_reagent("blood",0.02 * W.damage * wound_update_accuracy)//Bicaridine slows Internal Bleeding
|
||||
if(prob(1 * wound_update_accuracy))
|
||||
owner.custom_pain("You feel a stabbing pain in your [display_name]!",1)
|
||||
|
||||
//overdose of bicaridine begins healing IB
|
||||
if(owner.reagents.has_reagent("bicaridine") && (owner.reagents.get_reagent_amount("bicaridine") >= 30))
|
||||
var/healinternal = 0.2
|
||||
if(W.damage <= healinternal)
|
||||
W.damage = 0
|
||||
else
|
||||
W.damage -= healinternal
|
||||
//overdose of bicaridine begins healing IB
|
||||
if(owner.reagents.get_reagent_amount("bicaridine") >= 30)
|
||||
W.damage = max(0, W.damage - 0.2)
|
||||
|
||||
// slow healing
|
||||
var/heal_amt = 0
|
||||
@@ -385,6 +390,8 @@ This function completely restores a damaged organ to perfect condition.
|
||||
|
||||
// sync the organ's damage with its wounds
|
||||
src.update_damages()
|
||||
if (update_icon())
|
||||
owner.UpdateDamageIcon(1)
|
||||
|
||||
//Updates brute_damn and burn_damn from wound damages. Updates BLEEDING status.
|
||||
/datum/organ/external/proc/update_damages()
|
||||
@@ -417,7 +424,6 @@ This function completely restores a damaged organ to perfect condition.
|
||||
var/n_is = damage_state_text()
|
||||
if (n_is != damage_state)
|
||||
damage_state = n_is
|
||||
owner.update_body(1)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -549,7 +555,7 @@ This function completely restores a damaged organ to perfect condition.
|
||||
var/lol = pick(cardinal)
|
||||
step(organ,lol)
|
||||
|
||||
owner.regenerate_icons()
|
||||
owner.update_body(1)
|
||||
|
||||
|
||||
/****************************************************
|
||||
@@ -619,10 +625,13 @@ This function completely restores a damaged organ to perfect condition.
|
||||
return 0
|
||||
|
||||
/datum/organ/external/get_icon(gender="")
|
||||
if (status & ORGAN_ROBOT)
|
||||
return new /icon('icons/mob/human_races/robotic.dmi', "[icon_name][gender ? "_[gender]" : ""]")
|
||||
|
||||
if (status & ORGAN_MUTATED)
|
||||
return new /icon(owner.deform_icon, "[icon_name][gender ? "_[gender]" : ""]")
|
||||
else
|
||||
return new /icon(owner.race_icon, "[icon_name][gender ? "_[gender]" : ""]")
|
||||
|
||||
return new /icon(owner.race_icon, "[icon_name][gender ? "_[gender]" : ""]")
|
||||
|
||||
|
||||
/datum/organ/external/proc/is_usable()
|
||||
@@ -886,17 +895,17 @@ obj/item/weapon/organ/head/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
switch(brain_op_stage)
|
||||
if(0)
|
||||
for(var/mob/O in (oviewers(brainmob) - user))
|
||||
O.show_message("\red [brainmob] is beginning to have \his head cut open with [src] by [user].", 1)
|
||||
brainmob << "\red [user] begins to cut open your head with [src]!"
|
||||
user << "\red You cut [brainmob]'s head open with [src]!"
|
||||
O.show_message("\red [brainmob] is beginning to have \his head cut open with [W] by [user].", 1)
|
||||
brainmob << "\red [user] begins to cut open your head with [W]!"
|
||||
user << "\red You cut [brainmob]'s head open with [W]!"
|
||||
|
||||
brain_op_stage = 1
|
||||
|
||||
if(2)
|
||||
for(var/mob/O in (oviewers(brainmob) - user))
|
||||
O.show_message("\red [brainmob] is having \his connections to the brain delicately severed with [src] by [user].", 1)
|
||||
brainmob << "\red [user] begins to cut open your head with [src]!"
|
||||
user << "\red You cut [brainmob]'s head open with [src]!"
|
||||
O.show_message("\red [brainmob] is having \his connections to the brain delicately severed with [W] by [user].", 1)
|
||||
brainmob << "\red [user] begins to cut open your head with [W]!"
|
||||
user << "\red You cut [brainmob]'s head open with [W]!"
|
||||
|
||||
brain_op_stage = 3.0
|
||||
else
|
||||
@@ -905,20 +914,20 @@ obj/item/weapon/organ/head/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
switch(brain_op_stage)
|
||||
if(1)
|
||||
for(var/mob/O in (oviewers(brainmob) - user))
|
||||
O.show_message("\red [brainmob] has \his skull sawed open with [src] by [user].", 1)
|
||||
brainmob << "\red [user] begins to saw open your head with [src]!"
|
||||
user << "\red You saw [brainmob]'s head open with [src]!"
|
||||
O.show_message("\red [brainmob] has \his skull sawed open with [W] by [user].", 1)
|
||||
brainmob << "\red [user] begins to saw open your head with [W]!"
|
||||
user << "\red You saw [brainmob]'s head open with [W]!"
|
||||
|
||||
brain_op_stage = 2
|
||||
if(3)
|
||||
for(var/mob/O in (oviewers(brainmob) - user))
|
||||
O.show_message("\red [brainmob] has \his spine's connection to the brain severed with [src] by [user].", 1)
|
||||
brainmob << "\red [user] severs your brain's connection to the spine with [src]!"
|
||||
user << "\red You sever [brainmob]'s brain's connection to the spine with [src]!"
|
||||
O.show_message("\red [brainmob] has \his spine's connection to the brain severed with [W] by [user].", 1)
|
||||
brainmob << "\red [user] severs your brain's connection to the spine with [W]!"
|
||||
user << "\red You sever [brainmob]'s brain's connection to the spine with [W]!"
|
||||
|
||||
user.attack_log += "\[[time_stamp()]\]<font color='red'> Debrained [brainmob.name] ([brainmob.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])</font>"
|
||||
brainmob.attack_log += "\[[time_stamp()]\]<font color='orange'> Debrained by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])</font>"
|
||||
msg_admin_attack("[brainmob] ([brainmob.ckey]) debrained [user] ([user.ckey]) (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
user.attack_log += "\[[time_stamp()]\]<font color='red'> Debrained [brainmob.name] ([brainmob.ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)])</font>"
|
||||
brainmob.attack_log += "\[[time_stamp()]\]<font color='orange'> Debrained by [user.name] ([user.ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)])</font>"
|
||||
msg_admin_attack("[user] ([user.ckey]) debrained [brainmob] ([brainmob.ckey]) (INTENT: [uppertext(user.a_intent)]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[user.x];Y=[user.y];Z=[user.z]'>JMP</a>)")
|
||||
|
||||
var/obj/item/brain/B = new(loc)
|
||||
B.transfer_identity(brainmob)
|
||||
|
||||
@@ -5,15 +5,15 @@
|
||||
/mob/living/carbon/human/var/list/internal_organs = list()
|
||||
|
||||
/datum/organ/internal
|
||||
// amount of damage to the organ
|
||||
var/damage = 0
|
||||
var/damage = 0 // amount of damage to the organ
|
||||
var/min_bruised_damage = 10
|
||||
var/min_broken_damage = 30
|
||||
var/parent_organ = "chest"
|
||||
var/robotic = 0 //For being a robot
|
||||
|
||||
/datum/organ/internal/proc/rejuvenate()
|
||||
damage=0
|
||||
|
||||
|
||||
/datum/organ/internal/proc/is_bruised()
|
||||
return damage >= min_bruised_damage
|
||||
|
||||
@@ -31,12 +31,51 @@
|
||||
src.owner = H
|
||||
|
||||
/datum/organ/internal/proc/take_damage(amount, var/silent=0)
|
||||
src.damage += amount
|
||||
if(src.robotic == 2)
|
||||
src.damage += (amount * 0.8)
|
||||
else
|
||||
src.damage += amount
|
||||
|
||||
var/datum/organ/external/parent = owner.get_organ(parent_organ)
|
||||
if (!silent)
|
||||
owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1)
|
||||
|
||||
|
||||
/datum/organ/internal/proc/emp_act(severity)
|
||||
switch(robotic)
|
||||
if(0)
|
||||
return
|
||||
if(1)
|
||||
switch (severity)
|
||||
if (1.0)
|
||||
take_damage(20,0)
|
||||
return
|
||||
if (2.0)
|
||||
take_damage(7,0)
|
||||
return
|
||||
if(3.0)
|
||||
take_damage(3,0)
|
||||
return
|
||||
if(2)
|
||||
switch (severity)
|
||||
if (1.0)
|
||||
take_damage(40,0)
|
||||
return
|
||||
if (2.0)
|
||||
take_damage(15,0)
|
||||
return
|
||||
if(3.0)
|
||||
take_damage(10,0)
|
||||
return
|
||||
|
||||
/datum/organ/internal/proc/mechanize() //Being used to make robutt hearts, etc
|
||||
robotic = 2
|
||||
|
||||
/datum/organ/internal/proc/mechassist() //Used to add things like pacemakers, etc
|
||||
robotic = 1
|
||||
min_bruised_damage = 15
|
||||
min_broken_damage = 35
|
||||
|
||||
/****************************************************
|
||||
INTERNAL ORGANS DEFINES
|
||||
****************************************************/
|
||||
@@ -102,4 +141,14 @@
|
||||
|
||||
/datum/organ/internal/brain
|
||||
name = "brain"
|
||||
parent_organ = "head"
|
||||
parent_organ = "head"
|
||||
|
||||
/datum/organ/internal/eyes
|
||||
name = "eyes"
|
||||
parent_organ = "head"
|
||||
|
||||
process() //Eye damage replaces the old eye_stat var.
|
||||
if(is_bruised())
|
||||
owner.eye_blurry = 20
|
||||
if(is_broken())
|
||||
owner.eye_blind = 20
|
||||
|
||||
@@ -9,6 +9,8 @@ mob/var/next_pain_time = 0
|
||||
// amount is a num from 1 to 100
|
||||
mob/living/carbon/proc/pain(var/partname, var/amount, var/force, var/burning = 0)
|
||||
if(stat >= 2) return
|
||||
if(reagents.has_reagent("paracetamol"))
|
||||
return
|
||||
if(reagents.has_reagent("tramadol"))
|
||||
return
|
||||
if(reagents.has_reagent("oxycodone"))
|
||||
|
||||
@@ -962,7 +962,7 @@
|
||||
cell.corrupt()
|
||||
src.malfhack = 1
|
||||
update_icon()
|
||||
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(3, 0, src.loc)
|
||||
smoke.attach(src)
|
||||
smoke.start()
|
||||
|
||||
@@ -303,7 +303,7 @@
|
||||
for(var/mob/M in viewers(src))
|
||||
M.show_message("\red The [src.name] is making strange noises!", 3, "\red You hear sizzling electronics.", 2)
|
||||
sleep(10*pick(4,5,6,7,10,14))
|
||||
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(3, 0, src.loc)
|
||||
smoke.attach(src)
|
||||
smoke.start()
|
||||
@@ -321,7 +321,7 @@
|
||||
emp_act(2)
|
||||
if(prob(5)) //smoke only
|
||||
world << "\red SMES smoke in [src.loc.loc]"
|
||||
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(3, 0, src.loc)
|
||||
smoke.attach(src)
|
||||
smoke.start()
|
||||
|
||||
@@ -136,6 +136,14 @@
|
||||
in_chamber.current = curloc
|
||||
in_chamber.yo = targloc.y - curloc.y
|
||||
in_chamber.xo = targloc.x - curloc.x
|
||||
if(istype(user, /mob/living/carbon))
|
||||
var/mob/living/carbon/mob = user
|
||||
if(mob.shock_stage > 120)
|
||||
in_chamber.yo += rand(-2,2)
|
||||
in_chamber.xo += rand(-2,2)
|
||||
else if(mob.shock_stage > 70)
|
||||
in_chamber.yo += rand(-1,1)
|
||||
in_chamber.xo += rand(-1,1)
|
||||
|
||||
if(params)
|
||||
var/list/mouse_control = params2list(params)
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
var/drowsy = 0
|
||||
var/agony = 0
|
||||
|
||||
var/embed = 0 // whether or not the projectile can embed itself in the mob
|
||||
|
||||
proc/on_hit(var/atom/target, var/blocked = 0)
|
||||
if(blocked >= 2) return 0//Full block
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user