Merge branch 'bleeding-edge-freeze' of https://github.com/Baystation12/Baystation12 into bleeding-edge-freeze

Conflicts:
	code/modules/surgery/braincore.dm
This commit is contained in:
Chinsky
2013-04-20 12:11:52 +04:00
129 changed files with 24511 additions and 20206 deletions

View File

@@ -14,7 +14,6 @@
#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/ShieldGen"
#define FILE_DIR "code/WorkInProgress/Cael_Aislinn/Supermatter"
#define FILE_DIR "code/WorkInProgress/Susan"
#define FILE_DIR "code/WorkInProgress/Uristqwerty"
#define FILE_DIR "html"
#define FILE_DIR "icons"
#define FILE_DIR "icons/48x48"
@@ -393,6 +392,7 @@
#include "code\game\machinery\embedded_controller\airlock_controller.dm"
#include "code\game\machinery\embedded_controller\embedded_controller_base.dm"
#include "code\game\machinery\embedded_controller\simple_vent_controller.dm"
#include "code\game\machinery\embedded_controller\smart_airlock_controller.dm"
#include "code\game\machinery\kitchen\gibber.dm"
#include "code\game\machinery\kitchen\juicer.dm"
#include "code\game\machinery\kitchen\microwave.dm"
@@ -606,6 +606,7 @@
#include "code\game\objects\structures\tables_racks.dm"
#include "code\game\objects\structures\tank_dispenser.dm"
#include "code\game\objects\structures\target_stake.dm"
#include "code\game\objects\structures\transit_tubes.dm"
#include "code\game\objects\structures\watercloset.dm"
#include "code\game\objects\structures\windoor_assembly.dm"
#include "code\game\objects\structures\window.dm"
@@ -1288,10 +1289,10 @@
#include "code\WorkInProgress\Chinsky\ashtray.dm"
#include "code\WorkInProgress\Cib\MedicalSideEffects.dm"
#include "code\WorkInProgress\Mini\ATM.dm"
#include "code\WorkInProgress\Mini\atmos_control.dm"
#include "code\WorkInProgress\Ported\policetape.dm"
#include "code\WorkInProgress\SkyMarshal\Ultralight_procs.dm"
#include "code\WorkInProgress\Susan\susan_desert_turfs.dm"
#include "code\WorkInProgress\Uristqwerty\transit_tubes.dm"
#include "code\WorkInProgress\virus2\analyser.dm"
#include "code\WorkInProgress\virus2\antibodies.dm"
#include "code\WorkInProgress\virus2\base.dm"
@@ -1301,6 +1302,7 @@
#include "code\WorkInProgress\virus2\isolator.dm"
#include "code\ZAS\Airflow.dm"
#include "code\ZAS\Connection.dm"
#include "code\ZAS\Debug.dm"
#include "code\ZAS\FEA_gas_mixture.dm"
#include "code\ZAS\FEA_system.dm"
#include "code\ZAS\Fire.dm"

View File

@@ -62,7 +62,7 @@ Filter types:
var/output_starting_pressure = air3.return_pressure()
if(output_starting_pressure >= target_pressure)
if(output_starting_pressure >= target_pressure || air2.return_pressure() >= target_pressure )
//No need to mix if target is already full!
return 1

View File

@@ -4,6 +4,7 @@ var/global/datum/money_account/station_account
var/global/list/datum/money_account/department_accounts = list()
var/global/next_account_number = 0
var/global/obj/machinery/account_database/centcomm_account_db
var/global/datum/money_account/vendor_account
/proc/create_station_account()
if(!station_account)
@@ -99,6 +100,9 @@ var/global/obj/machinery/account_database/centcomm_account_db
if(department_accounts.len == 0)
for(var/department in station_departments)
create_department_account(department)
if(!vendor_account)
create_department_account("Vendor")
vendor_account = department_accounts["Vendor"]
if(!current_date_string)
current_date_string = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], 2557"

View File

@@ -199,11 +199,11 @@
T.time = worldtime2text()
linked_account.transaction_log.Add(T)
else
usr << "\icon[src]<span class='warning'>You don't have that much money!<span>"
usr << "\icon[src]<span class='warning'>You don't have that much money!</span>"
else
usr << "\icon[src]<span class='warning'>Unable to access account. Check security settings and try again.</span>"
else
usr << "\icon[src]<span class='warning'>EFTPOS is not connected to an account.<span>"
usr << "\icon[src]<span class='warning'>EFTPOS is not connected to an account.</span>"
else
..()

View File

@@ -62,6 +62,7 @@ max volume of plasma storeable by the field = the total volume of a number of ti
active_power_usage = 500 //multiplied by field strength
var/cached_power_avail = 0
directwired = 1
anchored = 0
var/state = 0
var/locked = 1

View File

@@ -3,17 +3,19 @@
name = "Fuel Injector"
icon = 'code/WorkInProgress/Cael_Aislinn/Rust/rust.dmi'
icon_state = "injector0"
density = 1
var/state = 2
anchored = 0
var/state = 0
var/locked = 0
req_access = list(access_engine)
var/obj/item/weapon/fuel_assembly/cur_assembly
var/fuel_usage = 0.0001 //percentage of available fuel to use per cycle
var/id_tag = "One"
var/injecting = 0
var/trying_to_swap_fuel = 0
//
req_access = list(access_engine)
//
use_power = 1
idle_power_usage = 10
active_power_usage = 500

View File

@@ -13,9 +13,19 @@
var/overridden = 0 //not set yet, can't think of a good way to do it
req_access = list(access_ce)
/obj/machinery/computer/atmoscontrol/attack_ai(var/mob/user as mob)
return interact(user)
/obj/machinery/computer/atmoscontrol/attack_paw(var/mob/user as mob)
return interact(user)
/obj/machinery/computer/atmoscontrol/attack_hand(mob/user)
if(..())
return
return interact(user)
/obj/machinery/computer/atmoscontrol/interact(mob/user)
user.set_machine(src)
if(allowed(user))
overridden = 1
@@ -62,7 +72,6 @@
return
if(href_list["reset"])
current = null
src.updateUsrDialog()
if(href_list["alarm"])
current = locate(href_list["alarm"])
if(href_list["command"])
@@ -129,6 +138,11 @@
selected[2] = selected[4]
if(selected[3] > selected[4])
selected[3] = selected[4]
//Sets the temperature the built-in heater/cooler tries to maintain.
if(env == "temperature")
current.target_temperature = (selected[2] + selected[3])/2
spawn(1)
updateUsrDialog()
return
@@ -167,7 +181,7 @@
spawn(5)
src.updateUsrDialog()
return
src.updateUsrDialog()
updateUsrDialog()
//copypasta from alarm code, changed to work with this without derping hard
//---START COPYPASTA----
@@ -185,7 +199,7 @@
output += {"
<a href='?src=\ref[src];alarm=\ref[current];screen=[AALARM_SCREEN_SCRUB]'>Scrubbers Control</a><br>
<a href='?src=\ref[src];alarm=\ref[current];screen=[AALARM_SCREEN_VENT]'>Vents Control</a><br>
<a href='?src=\ref[src];alarm=\ref[current];screen=[AALARM_SCREEN_MODE]'>Set envirenomentals mode</a><br>
<a href='?src=\ref[src];alarm=\ref[current];screen=[AALARM_SCREEN_MODE]'>Set environmental mode</a><br>
<a href='?src=\ref[src];alarm=\ref[current];screen=[AALARM_SCREEN_SENSORS]'>Sensor Control</a><br>
<HR>
"}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,405 +0,0 @@
// Basic transit tubes. Straight pieces, curved sections,
// and basic splits/joins (no routing logic).
// Mappers: you can use "Generate Instances from Icon-states"
// to get the different pieces.
/obj/structure/transit_tube
icon = 'transit_tube.dmi'
icon_state = "E-W"
density = 1
layer = 3.1
anchored = 1.0
var/list/tube_dirs = null
var/exit_delay = 2
var/enter_delay = 1
// A place where tube pods stop, and people can get in or out.
// Mappers: use "Generate Instances from Directions" for this
// one.
/obj/structure/transit_tube/station
icon = 'transit_tube_station.dmi'
icon_state = "closed"
exit_delay = 2
enter_delay = 3
var/pod_moving = 0
var/automatic_launch_time = 100
var/const/OPEN_DURATION = 6
var/const/CLOSE_DURATION = 6
/obj/structure/transit_tube_pod
icon = 'transit_tube_pod.dmi'
icon_state = "pod"
animate_movement = FORWARD_STEPS
var/moving = 0
var/datum/gas_mixture/air_contents
/obj/structure/transit_tube/station/New(loc)
..(loc)
spawn(automatic_launch_time)
launch_pod()
/obj/structure/transit_tube/station/Bumped(mob/AM as mob|obj)
if(!pod_moving && icon_state == "open" && istype(AM, /mob))
for(var/obj/structure/transit_tube_pod/pod in loc)
if(!pod.moving && pod.dir in directions())
AM.loc = pod
return
/obj/structure/transit_tube/station/attack_hand(mob/user as mob)
if(!pod_moving)
for(var/obj/structure/transit_tube_pod/pod in loc)
if(!pod.moving && pod.dir in directions())
if(icon_state == "closed")
open_animation()
else if(icon_state == "open")
close_animation()
/obj/structure/transit_tube/station/proc/open_animation()
if(icon_state == "closed")
icon_state = "opening"
spawn(OPEN_DURATION)
if(icon_state == "opening")
icon_state = "open"
/obj/structure/transit_tube/station/proc/close_animation()
if(icon_state == "open")
icon_state = "closing"
spawn(CLOSE_DURATION)
if(icon_state == "closing")
icon_state = "closed"
/obj/structure/transit_tube/station/proc/launch_pod()
for(var/obj/structure/transit_tube_pod/pod in loc)
if(!pod.moving && pod.dir in directions())
spawn(5)
pod_moving = 1
close_animation()
sleep(CLOSE_DURATION + 2)
if(icon_state == "closed" && pod)
pod.follow_tube()
pod_moving = 0
return
/obj/structure/transit_tube/proc/should_stop_pod(pod, from_dir)
return 0
/obj/structure/transit_tube/station/should_stop_pod(pod, from_dir)
return 1
/obj/structure/transit_tube/proc/pod_stopped(pod, from_dir)
return 0
/obj/structure/transit_tube/station/pod_stopped(obj/structure/transit_tube_pod/pod, from_dir)
pod_moving = 1
spawn(5)
open_animation()
sleep(OPEN_DURATION + 2)
pod_moving = 0
pod.mix_air()
if(automatic_launch_time)
var/const/wait_step = 5
var/i = 0
while(i < automatic_launch_time)
sleep(wait_step)
i += wait_step
if(pod_moving || icon_state != "open")
return
launch_pod()
// Returns a /list of directions this tube section can
// connect to.
/obj/structure/transit_tube/proc/directions()
return tube_dirs
/obj/structure/transit_tube/proc/has_entrance(from_dir)
from_dir = turn(from_dir, 180)
for(var/direction in directions())
if(direction == from_dir)
return 1
return 0
/obj/structure/transit_tube/proc/has_exit(in_dir)
for(var/direction in directions())
if(direction == in_dir)
return 1
return 0
// Searches for an exit direction within 45 degrees of the
// specified dir. Returns that direction, or 0 if none match.
/obj/structure/transit_tube/proc/get_exit(in_dir)
var/near_dir = 0
var/in_dir_cw = turn(in_dir, -45)
var/in_dir_ccw = turn(in_dir, 45)
for(var/direction in directions())
if(direction == in_dir)
return direction
else if(direction == in_dir_cw)
near_dir = direction
else if(direction == in_dir_ccw)
near_dir = direction
return near_dir
/obj/structure/transit_tube/proc/exit_delay(pod, to_dir)
return exit_delay
/obj/structure/transit_tube/proc/enter_delay(pod, to_dir)
return enter_delay
/obj/structure/transit_tube_pod/proc/follow_tube()
if(moving)
return
moving = 1
spawn()
var/obj/structure/transit_tube/current_tube = null
var/next_dir
var/next_loc
for(var/obj/structure/transit_tube/tube in loc)
if(tube.has_exit(dir))
current_tube = tube
break
while(current_tube)
next_dir = current_tube.get_exit(dir)
if(!next_dir)
break
sleep(current_tube.exit_delay(src, dir))
next_loc = get_step(loc, next_dir)
current_tube = null
for(var/obj/structure/transit_tube/tube in next_loc)
if(tube.has_entrance(next_dir))
current_tube = tube
break
if(current_tube == null)
dir = next_dir
step(src, dir)
break
sleep(current_tube.enter_delay(src, next_dir))
dir = next_dir
loc = next_loc
if(current_tube && current_tube.should_stop_pod(src, next_dir))
current_tube.pod_stopped(src, dir)
break
moving = 0
// HUGE HACK: Because the pod isn't a mecha, travelling through tubes over space
// won't protect people from space.
// This avoids editing an additional file, so that adding
// tubes to a SS13 codebase is a simple as dropping this code file and the
// required icon files somewhere where BYOND can find them.
/mob/living/carbon/human/handle_environment(datum/gas_mixture/environment)
if(!istype(loc, /obj/structure/transit_tube_pod))
return ..(environment)
/obj/structure/transit_tube_pod/return_air()
var/datum/gas_mixture/GM = new()
GM.oxygen = MOLES_O2STANDARD * 2
GM.nitrogen = MOLES_N2STANDARD
GM.temperature = T20C
return GM
// For now, copying what I found in an unused FEA file (and almost identical in a
// used ZAS file). Means that assume_air and remove_air don't actually alter the
// air contents.
/obj/structure/transit_tube_pod/assume_air(datum/gas_mixture/giver)
return 0
/obj/structure/transit_tube_pod/remove_air(amount)
var/oxygen = MOLES_O2STANDARD
var/carbon_dioxide = 0
var/nitrogen = MOLES_N2STANDARD
var/toxins = 0
var/datum/gas_mixture/GM = new()
var/sum = oxygen + carbon_dioxide + nitrogen + toxins
if(sum>0)
GM.oxygen = (oxygen/sum)*amount
GM.carbon_dioxide = (carbon_dioxide/sum)*amount
GM.nitrogen = (nitrogen/sum)*amount
GM.toxins = (toxins/sum)*amount
GM.temperature = T20C
GM.update_values() //Needed in ZAS to prevent suffocation. Not present in FEA. Comment/uncomment as nessecary.
return GM
// Called when a pod arrives at, and before a pod departs from a station,
// giving it a chance to mix its internal air supply with the turf it is
// currently on.
/obj/structure/transit_tube_pod/proc/mix_air()
//Needs to be implemented at some point
// When the player moves, check if the pos is currently stopped at a station.
// if it is, check the direction. If the direction matches the direction of
// the station, try to exit. If the direction matches one of the station's
// tube directions, launch the pod in that direction.
/obj/structure/transit_tube_pod/relaymove(mob/mob, direction)
if(!moving && istype(mob, /mob) && mob.client)
for(var/obj/structure/transit_tube/station/station in loc)
if(!station.pod_moving && (dir in station.directions()))
if(direction == station.dir)
if(station.icon_state == "open")
mob.loc = loc
mob.client.Move(get_step(loc, direction), direction)
else
station.open_animation()
else if(direction in station.directions())
dir = direction
station.launch_pod()
/obj/structure/transit_tube/New(loc)
..(loc)
if(tube_dirs == null)
init_dirs()
// Parse the icon_state into a list of directions.
// This means that mappers can use Dream Maker's built in
// "Generate Instances from Icon-states" option to get all
// variations. Additionally, as a separate proc, sub-types
// can handle it more intelligently.
/obj/structure/transit_tube/proc/init_dirs()
tube_dirs = parse_dirs(icon_state)
if(copytext(icon_state, 1, 3) == "D-")
density = 0
// Tube station directions are simply 90 to either side of
// the exit.
/obj/structure/transit_tube/station/init_dirs()
tube_dirs = list(turn(dir, 90), turn(dir, -90))
// Uses a list() to cache return values. Since they should
// never be edited directly, all tubes with a certain
// icon_state can just reference the same list. In theory,
// reduces memory usage, and improves CPU cache usage.
// In reality, I don't know if that is quite how BYOND works,
// but it is probably safer to assume the existence of, and
// rely on, a sufficiently smart compiler/optimizer.
/obj/structure/transit_tube/proc/parse_dirs(text)
var/global/list/direction_table = list()
if(text in direction_table)
return direction_table[text]
var/list/split_text = stringsplit(text, "-")
// If the first token is D, the icon_state represents
// a purely decorative tube, and doesn't actually
// connect to anything.
if(split_text[1] == "D")
direction_table[text] = list()
return null
var/list/directions = list()
for(var/text_part in split_text)
var/direction = text2dir_extended(text_part)
if(direction > 0)
directions += direction
direction_table[text] = directions
return directions
// A copy of text2dir, extended to accept one and two letter
// directions, and to clearly return 0 otherwise.
/obj/structure/transit_tube/proc/text2dir_extended(direction)
switch(uppertext(direction))
if("NORTH", "N")
return 1
if("SOUTH", "S")
return 2
if("EAST", "E")
return 4
if("WEST", "W")
return 8
if("NORTHEAST", "NE")
return 5
if("NORTHWEST", "NW")
return 9
if("SOUTHEAST", "SE")
return 6
if("SOUTHWEST", "SW")
return 10
else
return 0

View File

@@ -248,8 +248,8 @@ atom/movable
if(src:buckled)
return
if(src:shoes)
if(src:shoes.type == /obj/item/clothing/shoes/magboots)
if(src:shoes.flags & NOSLIP)
if(istype(src:shoes, /obj/item/clothing/shoes/magboots))
if(src:shoes:magpulse)
return
src << "\red You are sucked away by airflow!"
var/airflow_falloff = 9 - ul_FalloffAmount(airflow_dest) //It's a fast falloff calc. Very useful.
@@ -303,7 +303,6 @@ atom/movable
if(airflow_speed)
airflow_speed = n/max(get_dist(src,airflow_dest),1)
return
last_airflow = world.time
if(airflow_dest == loc)
step_away(src,loc)
if(ismob(src))
@@ -317,6 +316,7 @@ atom/movable
if(src:shoes.flags & NOSLIP)
return
src << "\red You are pushed away by airflow!"
last_airflow = world.time
var/airflow_falloff = 9 - ul_FalloffAmount(airflow_dest) //It's a fast falloff calc. Very useful.
if(airflow_falloff < 1)
airflow_dest = null

View File

@@ -17,7 +17,7 @@ connection
zone_B
ref_A
ref_B
indirect = 0 //If the connection is purely indirect, the zones should not join.
indirect = CONNECTION_DIRECT //If the connection is purely indirect, the zones should not join.
last_updated //The tick at which this was last updated.
no_zone_count = 0
@@ -47,24 +47,48 @@ connection
else
air_master.turfs_with_connections[ref_B] = list(src)
if(!A.zone.connected_zones)
A.zone.connected_zones = list()
if(!B.zone.connected_zones)
B.zone.connected_zones = list()
if(A.CanPass(null, B, 0, 0))
if(B.zone in A.zone.connected_zones)
A.zone.connected_zones[B.zone]++
else
A.zone.connected_zones += B.zone
A.zone.connected_zones[B.zone] = 1
if(!A.zone.connected_zones)
A.zone.connected_zones = list()
if(!B.zone.connected_zones)
B.zone.connected_zones = list()
if(B.zone in A.zone.connected_zones)
A.zone.connected_zones[B.zone]++
else
A.zone.connected_zones += B.zone
A.zone.connected_zones[B.zone] = 1
if(A.zone in B.zone.connected_zones)
B.zone.connected_zones[A.zone]++
else
B.zone.connected_zones += A.zone
B.zone.connected_zones[A.zone] = 1
if(A.HasDoor(B) || B.HasDoor(A))
indirect = CONNECTION_INDIRECT
if(A.zone in B.zone.connected_zones)
B.zone.connected_zones[A.zone]++
else
B.zone.connected_zones += A.zone
B.zone.connected_zones[A.zone] = 1
if(A.HasDoor(B) || B.HasDoor(A))
indirect = 1
indirect = CONNECTION_CLOSED
if(!A.zone.closed_connection_zones)
A.zone.closed_connection_zones = list()
if(B.zone in A.zone.closed_connection_zones)
A.zone.closed_connection_zones[B.zone]++
else
A.zone.closed_connection_zones += B.zone
A.zone.closed_connection_zones[B.zone] = 1
if(!B.zone.closed_connection_zones)
B.zone.closed_connection_zones = list()
if(A.zone in B.zone.closed_connection_zones)
B.zone.closed_connection_zones[A.zone]++
else
B.zone.closed_connection_zones += A.zone
B.zone.closed_connection_zones[A.zone] = 1
else
world.log << "Attempted to create connection object for non-zone tiles: [T] -> [O]"
del(src)
@@ -168,6 +192,75 @@ connection
zone_B.connected_zones -= zone_A
if(zone_B.connected_zones && !zone_B.connected_zones.len)
zone_B.connected_zones = null
else
if(A && A.zone)
if(B && B.zone)
if(B.zone in A.zone.closed_connection_zones)
if(A.zone.closed_connection_zones[B.zone] > 1)
A.zone.closed_connection_zones[B.zone]--
else
A.zone.closed_connection_zones -= B.zone
if(A.zone.closed_connection_zones && !A.zone.closed_connection_zones.len)
A.zone.closed_connection_zones = null
if( zone_B && (!B.zone || zone_B != B.zone) )
if(zone_B in A.zone.closed_connection_zones)
if(A.zone.closed_connection_zones[zone_B] > 1)
A.zone.closed_connection_zones[zone_B]--
else
A.zone.closed_connection_zones -= zone_B
if(A.zone.closed_connection_zones && !A.zone.closed_connection_zones.len)
A.zone.closed_connection_zones = null
if(zone_A && (!A.zone || zone_A != A.zone))
if(B && B.zone)
if(B.zone in zone_A.closed_connection_zones)
if(zone_A.closed_connection_zones[B.zone] > 1)
zone_A.closed_connection_zones[B.zone]--
else
zone_A.closed_connection_zones -= B.zone
if(zone_A.closed_connection_zones && !zone_A.closed_connection_zones.len)
zone_A.closed_connection_zones = null
if( zone_B && (!B.zone || zone_B != B.zone) )
if(zone_B in zone_A.closed_connection_zones)
if(zone_A.closed_connection_zones[zone_B] > 1)
zone_A.closed_connection_zones[zone_B]--
else
zone_A.closed_connection_zones -= zone_B
if(zone_A.closed_connection_zones && !zone_A.closed_connection_zones.len)
zone_A.closed_connection_zones = null
if(B && B.zone)
if(A && A.zone)
if(A.zone in B.zone.closed_connection_zones)
if(B.zone.closed_connection_zones[A.zone] > 1)
B.zone.closed_connection_zones[A.zone]--
else
B.zone.closed_connection_zones -= A.zone
if(B.zone.closed_connection_zones && !B.zone.closed_connection_zones.len)
B.zone.closed_connection_zones = null
if( zone_A && (!A.zone || zone_A != A.zone) )
if(zone_A in B.zone.closed_connection_zones)
if(B.zone.closed_connection_zones[zone_A] > 1)
B.zone.closed_connection_zones[zone_A]--
else
B.zone.closed_connection_zones -= zone_A
if(B.zone.closed_connection_zones && !B.zone.closed_connection_zones.len)
B.zone.closed_connection_zones = null
if(zone_B && (!B.zone || zone_B != B.zone))
if(A && A.zone)
if(A.zone in zone_B.closed_connection_zones)
if(zone_B.closed_connection_zones[A.zone] > 1)
zone_B.closed_connection_zones[A.zone]--
else
zone_B.closed_connection_zones -= A.zone
if(zone_B.closed_connection_zones && !zone_B.closed_connection_zones.len)
zone_B.closed_connection_zones = null
if( zone_A && (!A.zone || zone_A != A.zone) )
if(zone_A in zone_B.closed_connection_zones)
if(zone_B.closed_connection_zones[zone_A] > 1)
zone_B.closed_connection_zones[zone_A]--
else
zone_B.closed_connection_zones -= zone_A
if(zone_B.closed_connection_zones && !zone_B.closed_connection_zones.len)
zone_B.closed_connection_zones = null
. = ..()
proc/Cleanup()
@@ -212,12 +305,32 @@ connection
else
B.zone.connected_zones += A.zone
B.zone.connected_zones[A.zone] = 1
if(A.zone.closed_connection_zones)
if(A.zone.closed_connection_zones[B.zone] > 1)
A.zone.closed_connection_zones[B.zone]--
else
A.zone.closed_connection_zones.Remove(B.zone)
if(A.zone.closed_connection_zones && !A.zone.closed_connection_zones.len)
A.zone.closed_connection_zones = null
if(B.zone.closed_connection_zones)
if(B.zone.closed_connection_zones[A.zone] > 1)
B.zone.closed_connection_zones[A.zone]--
else
B.zone.closed_connection_zones.Remove(A.zone)
if(B.zone.closed_connection_zones && !B.zone.closed_connection_zones.len)
B.zone.closed_connection_zones = null
if(door_pass)
indirect = CONNECTION_DIRECT
else if(!door_pass)
indirect = CONNECTION_INDIRECT
else if(indirect > CONNECTION_CLOSED)
indirect = CONNECTION_CLOSED
//ADJUST FOR CANNOT CONNECT
if(A.zone.connected_zones)
if(A.zone.connected_zones[B.zone] > 1)
@@ -226,13 +339,33 @@ connection
A.zone.connected_zones.Remove(B.zone)
if(A.zone.connected_zones && !A.zone.connected_zones.len)
A.zone.connected_zones = null
if(B.zone.connected_zones)
if(B.zone.connected_zones[A.zone] > 1)
B.zone.connected_zones[A.zone]--
else
B.zone.connected_zones.Remove(A.zone)
if(B.zone.connected_zones && !B.zone.connected_zones.len)
B.zone.connected_zones = null
//Add to the closed connections list(s)
if(!A.zone.closed_connection_zones)
A.zone.closed_connection_zones = list()
if(B.zone in A.zone.closed_connection_zones)
A.zone.closed_connection_zones[B.zone]++
else
A.zone.closed_connection_zones += B.zone
A.zone.closed_connection_zones[B.zone] = 1
if(!B.zone.closed_connection_zones)
B.zone.closed_connection_zones = list()
if(A.zone in B.zone.closed_connection_zones)
B.zone.closed_connection_zones[A.zone]++
else
B.zone.closed_connection_zones += A.zone
B.zone.closed_connection_zones[A.zone] = 1
else //If I can no longer pass air, better delete
del src
@@ -268,6 +401,16 @@ connection
if(zone_A.connected_zones && !zone_A.connected_zones.len)
zone_A.connected_zones = null
else
if(zone_A.closed_connection_zones)
if(zone_A.closed_connection_zones[zone_B] > 1)
zone_A.closed_connection_zones[zone_B]--
else
zone_A.closed_connection_zones.Remove(zone_B)
if(zone_A.closed_connection_zones && !zone_A.closed_connection_zones.len)
zone_A.closed_connection_zones = null
if(zone_B)
if(zone_B.connections)
zone_B.connections.Remove(src)
@@ -283,6 +426,15 @@ connection
if(zone_B.connected_zones && !zone_B.connected_zones.len)
zone_B.connected_zones = null
else
if(zone_B.closed_connection_zones)
if(zone_B.closed_connection_zones[zone_A] > 1)
zone_B.closed_connection_zones[zone_A]--
else
zone_B.closed_connection_zones.Remove(zone_A)
if(zone_B.closed_connection_zones && !zone_B.closed_connection_zones.len)
zone_B.closed_connection_zones = null
if(indirect != CONNECTION_CLOSED)
if(!A.zone.connections)
A.zone.connections = list()
@@ -307,6 +459,31 @@ connection
B.zone.connected_zones += A.zone
B.zone.connected_zones[A.zone] = 1
else
if(!A.zone.connections)
A.zone.connections = list()
A.zone.connections |= src
if(!B.zone.connections)
B.zone.connections = list()
B.zone.connections |= src
if(!A.zone.closed_connection_zones)
A.zone.closed_connection_zones = list()
if(B.zone in A.zone.closed_connection_zones)
A.zone.closed_connection_zones[B.zone]++
else
A.zone.closed_connection_zones += B.zone
A.zone.closed_connection_zones[B.zone] = 1
if(!B.zone.closed_connection_zones)
B.zone.closed_connection_zones = list()
if(A.zone in B.zone.closed_connection_zones)
B.zone.closed_connection_zones[A.zone]++
else
B.zone.closed_connection_zones += A.zone
B.zone.closed_connection_zones[A.zone] = 1
zone_B = B.zone
zone_A = A.zone
@@ -340,6 +517,23 @@ connection
else
A.zone.connected_zones[zone_B]++
else
if(zone_A.closed_connection_zones)
if(zone_A.closed_connection_zones[zone_B] > 1)
zone_A.closed_connection_zones[zone_B]--
else
zone_A.closed_connection_zones.Remove(zone_B)
if(zone_A.closed_connection_zones && !zone_A.closed_connection_zones.len)
zone_A.closed_connection_zones = null
if(!A.zone.closed_connection_zones)
A.zone.closed_connection_zones = list()
if(!(zone_B in A.zone.closed_connection_zones))
A.zone.closed_connection_zones += zone_B
A.zone.closed_connection_zones[zone_B] = 1
else
A.zone.closed_connection_zones[zone_B]++
zone_A = A.zone
else
@@ -373,6 +567,23 @@ connection
else
B.zone.connected_zones[zone_A]++
else
if(zone_B.closed_connection_zones)
if(zone_B.closed_connection_zones[zone_A] > 1)
zone_B.closed_connection_zones[zone_A]--
else
zone_B.closed_connection_zones.Remove(zone_A)
if(zone_B.closed_connection_zones && !zone_B.closed_connection_zones.len)
zone_B.closed_connection_zones = null
if(!B.zone.closed_connection_zones)
B.zone.closed_connection_zones = list()
if(!(zone_A in B.zone.closed_connection_zones))
B.zone.closed_connection_zones += zone_A
B.zone.closed_connection_zones[zone_A] = 1
else
B.zone.closed_connection_zones[zone_A]++
zone_B = B.zone
else

View File

@@ -1,5 +1,5 @@
client/verb/Zone_Info(turf/T as null|turf)
client/proc/Zone_Info(turf/T as null|turf)
set category = "Debug"
if(T)
if(T.zone)
@@ -12,6 +12,50 @@ client/verb/Zone_Info(turf/T as null|turf)
T.overlays -= 'debug_group.dmi'
T.overlays -= 'debug_connect.dmi'
client/proc/Test_ZAS_Connection(var/turf/simulated/T as turf)
set category = "Debug"
if(!istype(T))
return
var/direction_list = list(\
"North" = NORTH,\
"South" = SOUTH,\
"East" = EAST,\
"West" = WEST,\
"None" = null)
var/direction = input("What direction do you wish to test?","Set direction") as null|anything in direction_list
if(!direction)
return
if(direction == "None")
if(T.CanPass(null, T, 0,0))
mob << "The turf can pass air! :D"
else
mob << "No air passage :x"
return
var/turf/simulated/other_turf = get_step(T, direction_list[direction])
if(!istype(other_turf))
return
var/pass_directions = T.CanPass(null, other_turf, 0, 0) + 2*other_turf.CanPass(null, T, 0, 0)
switch(pass_directions)
if(0)
mob << "Neither turf can connect. :("
if(1)
mob << "The initial turf only can connect. :\\"
if(2)
mob << "The other turf can connect, but not the initial turf. :/"
if(3)
mob << "Both turfs can connect! :)"
zone/proc
DebugDisplay(mob/M)
if(!dbg_output)

View File

@@ -346,7 +346,7 @@ datum
if(current == NT)
return //We made it, yaaay~
stepped_back = 0
zone.rebuild = 1
zone.rebuild = 1
else if ( current.air_check_directions&test_dir )
//Try to connect to the left hand side.

View File

@@ -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,35 +19,25 @@ 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)
var/datum/gas_mixture/air_contents = return_air()
if(!air_contents || exposed_temperature < PLASMA_MINIMUM_BURN_TEMPERATURE)
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/obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in src
if(air_contents.calculate_firelevel(liquid) > vsc.IgnitionLevel && (fuel || liquid || air_contents.toxins > 0.1))
if(air_contents.calculate_firelevel(liquid) > vsc.IgnitionLevel && (fuel || liquid || air_contents.toxins > 0.5))
igniting = 1
if(air_contents.oxygen < 0.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
new /obj/fire(src,1000)
//active_hotspot.just_spawned = (current_cycle < air_master.current_cycle)
//remove just_spawned protection if no longer processing this cell
@@ -63,7 +51,7 @@ obj
anchored = 1
mouse_opacity = 0
luminosity = 3
//luminosity = 3
icon = 'fire.dmi'
icon_state = "1"
@@ -71,199 +59,200 @@ obj
layer = TURF_LAYER
var
volume = CELL_VOLUME
temperature = FIRE_MINIMUM_TEMPERATURE_TO_EXIST
firelevel = 10000 //Calculated by gas_mixture.calculate_firelevel()
archived_firelevel = 0
process()
. = 1
var/turf/simulated/floor/S = loc
if(!S.zone) del src //Cannot exist where zones are broken.
if(firelevel > vsc.IgnitionLevel)
if(istype(S,/turf/simulated/floor))
var
datum/gas_mixture/air_contents = S.return_air()
//Get whatever trace fuels are in the area
datum/gas/volatile_fuel/fuel = locate(/datum/gas/volatile_fuel/) in air_contents.trace_gases
//Also get liquid fuels on the ground.
obj/effect/decal/cleanable/liquid_fuel/liquid = locate() in S
var/turf/simulated/floor/S = loc
if(!S.zone) del src //Cannot exist where zones are broken.
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(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
firelevel = air_contents.calculate_firelevel(liquid)
var/datum/gas_mixture/flow = air_contents.remove_ratio(vsc.fire_consuption_rate)
//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.
//Ensure that there is an appropriate amount of fuel and O2 here.
if(firelevel > 0.25 && flow.oxygen > 0.1 && (air_contents.toxins || fuel || liquid))
firelevel = air_contents.calculate_firelevel(liquid)
for(var/direction in cardinal)
if(S.air_check_directions&direction) //Grab all valid bordering tiles
//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))
var/turf/simulated/enemy_tile = get_step(S, direction)
for(var/direction in cardinal)
if(S.air_check_directions&direction) //Grab all valid bordering tiles
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
var/turf/simulated/enemy_tile = get_step(S, direction)
//Spread the fire.
if(!(locate(/obj/fire) in enemy_tile))
if( prob( firelevel*10 ) )
new/obj/fire(enemy_tile,firelevel)
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
if(flow)
//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)
//Ensure adequate oxygen and fuel.
if(flow.oxygen > 0.1 && (flow.toxins || fuel || liquid))
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"
SetLuminosity(7)
else if(firelevel > 2.5)
icon_state = "2"
SetLuminosity(5)
else
icon_state = "1"
SetLuminosity(3)
//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)
air_contents.trace_gases.Remove(fuel)
//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.2,flow.temperature)
//Burn the gas mixture.
if(!flow.zburn(liquid))
del src
S.assume_air(flow) //Then put it back where you found it.
else
del src
S.assume_air(flow) //Then put it back where you found it.
else
del src
else
del src
for(var/mob/living/carbon/human/M in loc)
M.FireBurn(min(max(0.1,firelevel / 20),10)) //Burn the humans!
M.FireBurn(firelevel) //Burn the humans!
New(newLoc,fl)
..()
if(!istype(loc, /turf) || !loc.CanPass(null, loc, 0, 0))
if(!istype(loc, /turf))
del src
dir = pick(cardinal)
//sd_SetLuminosity(3,2,0)
SetLuminosity(3)
firelevel = fl
for(var/mob/living/carbon/human/M in loc)
M.FireBurn(min(max(0.1,firelevel / 20),10)) //Burn the humans!
air_master.active_hotspots.Add(src)
Del()
if (istype(loc, /turf/simulated))
//sd_SetLuminosity(0)
SetLuminosity(0)
loc = null
air_master.active_hotspots.Remove(src)
..()
turf/simulated/var/fire_protection = 0 //Protects newly extinguished tiles from being overrun again.
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_MINIMUM_BURN_TEMPERATURE)
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(fuel)
//Volatile Fuel
if(fuel.moles < 0.01)
trace_gases.Remove(fuel)
del fuel
else
total_fuel += fuel.moles
fuel_sources++
//Volatile Fuel
total_fuel += fuel.moles
if(liquid)
//Liquid Fuel
//Liquid Fuel
if(liquid.amount <= 0)
del liquid
else
total_fuel += liquid.amount
fuel_sources++
total_fuel += liquid.amount*15
//Toxins
if(toxins > 0.1) fuel_sources++
if(! (fuel || toxins || liquid) )
return 0 //If there's no fuel, there's no burn. Can't divide by zero anyway.
if(!fuel_sources) return 0 //If there's no fuel, there's no burn. Can't divide by zero anyway.
if(oxygen > 0.1)
if(oxygen > 0.3)
//Calculate the firelevel.
var/firelevel = calculate_firelevel(liquid)
if(firelevel < 0.01)
return 0
//Reaches a maximum practical temperature of around 4500.
//Increase temperature.
temperature = max( 1700*log(0.4*firelevel + 1.23) , temperature )
temperature = max( vsc.fire_temperature_multiplier*log(0.04*firelevel + 1.24) , temperature )
var/total_reactants = min(oxygen, 2*total_fuel) + total_fuel
//Consume some gas.
var/consumed_gas = min(oxygen,firelevel * 50,total_fuel) / fuel_sources
var/consumed_gas = max( min( total_reactants, vsc.fire_gas_combustion_ratio*firelevel ), 0.2)
oxygen = max(0,oxygen-consumed_gas)
oxygen -= min(oxygen, (total_reactants-total_fuel)*consumed_gas/total_reactants )
toxins = max(0,toxins-consumed_gas)
toxins -= min(toxins, toxins*consumed_gas/total_reactants )
carbon_dioxide += consumed_gas*2
carbon_dioxide += max(consumed_gas, 0)
if(fuel)
fuel.moles -= consumed_gas
fuel.moles -= fuel.moles*consumed_gas/total_reactants
if(fuel.moles <= 0) del fuel
if(liquid)
liquid.amount -= consumed_gas
liquid.amount -= liquid.amount*consumed_gas/(total_reactants)
if(liquid.amount <= 0) del liquid
update_values()
return consumed_gas*fuel_sources
return consumed_gas
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
fuel_concentration = 0
oxy_concentration = oxygen / volume
tox_concentration = toxins / volume
var/total_fuel = toxins - 0.5
if(fuel) fuel_concentration = (fuel.moles) / volume
if(liquid) liquid_concentration = (liquid.amount*15) / volume
if(liquid)
total_fuel += (liquid.amount*15)
var/final = tox_concentration + liquid_concentration + fuel_concentration
if(final > oxy_concentration)
final = oxy_concentration
if(fuel)
total_fuel += fuel.moles
return final * 100
var/total_combustables = (total_fuel + oxygen)
if(total_fuel <= 0 || oxygen <= 0)
return 0
/mob/living/carbon/human/proc/FireBurn(mx as num)
return max( 0, vsc.fire_firelevel_multiplier*(total_combustables/(total_combustables + nitrogen))*log(2*total_combustables/oxygen)*log(total_combustables/total_fuel))
/mob/living/carbon/human/proc/FireBurn(var/firelevel)
//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
@@ -272,20 +261,26 @@ datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fue
legs_exposure = 1
arms_exposure = 1
var/mx = min(max(0.1,firelevel / 20),10)
var/last_temperature = vsc.fire_temperature_multiplier*log(0.04*firelevel + 1.24)
//Get heat transfer coefficients for clothing.
//skytodo: different handling of temp with tg //Jesus, mate. Don't ask me. I have no diea how their crap works, and Aryn wrote this proc.
/*for(var/obj/item/clothing/C in src)
if(l_hand == C || r_hand == C) continue
if(C.body_parts_covered & HEAD)
head_exposure *= C.heat_transfer_coefficient
if(C.body_parts_covered & UPPER_TORSO)
chest_exposure *= C.heat_transfer_coefficient
if(C.body_parts_covered & LOWER_TORSO)
groin_exposure *= C.heat_transfer_coefficient
if(C.body_parts_covered & LEGS)
legs_exposure *= C.heat_transfer_coefficient
if(C.body_parts_covered & ARMS)
arms_exposure *= C.heat_transfer_coefficient*/
//skytodo: kill anyone who breaks things then orders me to fix them
for(var/obj/item/clothing/C in src)
if(l_hand == C || r_hand == C)
continue
if( C.max_heat_protection_temperature >= last_temperature )
if(C.body_parts_covered & HEAD)
head_exposure = 0
if(C.body_parts_covered & UPPER_TORSO)
chest_exposure = 0
if(C.body_parts_covered & LOWER_TORSO)
groin_exposure = 0
if(C.body_parts_covered & LEGS)
legs_exposure = 0
if(C.body_parts_covered & ARMS)
arms_exposure = 0
//Always check these damage procs first if fire damage isn't working. They're probably what's wrong.
@@ -297,4 +292,5 @@ datum/gas_mixture/proc/calculate_firelevel(obj/effect/decal/cleanable/liquid_fue
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()
//flash_pain()
#undef ZAS_FIRE_CONSUMPTION_RATE

View File

@@ -21,7 +21,24 @@ proc/FloodFill(turf/simulated/start)
if(istype(O) && !(O in open) && !(O in closed) && O.ZCanPass(T))
if(!O.HasDoor())
if(T.HasDoor())
//If they both have doors, then they are nto able to connect period.
if(O.HasDoor())
continue
//connect first to north and west
if(d == NORTH || d == WEST)
open += O
else
var/turf/simulated/W = get_step(O, WEST)
var/turf/simulated/N = get_step(O, NORTH)
if( !O.ZCanPass(N) && !O.ZCanPass(W) )
//If it cannot connect either to the north or west, connect it!
open += O
else if(!O.HasDoor())
open += O
else
@@ -92,6 +109,7 @@ proc/ZMerge(zone/A,zone/B)
proc/ZConnect(turf/simulated/A,turf/simulated/B)
//Connects two zones by forming a connection object representing turfs A and B.
//Make sure that if it's space, it gets added to unsimulated_tiles instead.
if(!istype(B))
if(A.zone)
@@ -108,8 +126,8 @@ proc/ZConnect(turf/simulated/A,turf/simulated/B)
//Make some preliminary checks to see if the connection is valid.
if(!A.zone || !B.zone) return
if(A.zone == B.zone) return
if(!A.CanPass(null,B,0,0)) return
if(A.CanPass(null,B,1.5,1))
if(A.CanPass(null,B,0,1))
return ZMerge(A.zone,B.zone)
//Ensure the connection isn't already made.

View File

@@ -5,7 +5,7 @@ pl_control/var
PLASMA_DMG_NAME = "Plasma Damage Amount"
PLASMA_DMG_DESC = "Self Descriptive"
CLOTH_CONTAMINATION = 0
CLOTH_CONTAMINATION = 1
CLOTH_CONTAMINATION_NAME = "Cloth Contamination"
CLOTH_CONTAMINATION_DESC = "If this is on, plasma does damage by getting into cloth."
@@ -17,7 +17,7 @@ pl_control/var
GENETIC_CORRUPTION_NAME = "Genetic Corruption Chance"
GENETIC_CORRUPTION_DESC = "Chance of genetic corruption as well as toxic damage, X in 10,000."
SKIN_BURNS = 1
SKIN_BURNS = 0
SKIN_BURNS_DESC = "Plasma has an effect similar to mustard gas on the un-suited."
SKIN_BURNS_NAME = "Skin Burns"
@@ -25,7 +25,7 @@ pl_control/var
EYE_BURNS_NAME = "Eye Burns"
EYE_BURNS_DESC = "Plasma burns the eyes of anyone not wearing eye protection."
CONTAMINATION_LOSS = 0.01
CONTAMINATION_LOSS = 0.02
CONTAMINATION_LOSS_NAME = "Contamination Loss"
CONTAMINATION_LOSS_DESC = "How much toxin damage is dealt from contaminated clothing" //Per tick? ASK ARYN
@@ -42,11 +42,10 @@ obj/var/contaminated = 0
obj/item/proc
can_contaminate()
return 0
//Clothing and backpacks can be contaminated.
if(flags & PLASMAGUARD) return 0
else if(istype(src,/obj/item/weapon/storage/backpack)) return 0 //Cannot be washed :(
else if(istype(src,/obj/item/clothing)) return 1
else if(istype(src,/obj/item/weapon/storage/backpack)) return 1
contaminate()
//Do a contamination overlay? Temporary measure to keep contamination less deadly than it was.

View File

@@ -2,40 +2,69 @@ var/global/vs_control/vsc = new
vs_control/var
IgnitionLevel = 0.5
IgnitionLevel_DESC = "Moles of oxygen+plasma - co2 needed to burn."
airflow_lightest_pressure = 30
IgnitionLevel_DESC = "Determines point at which fire can ignite"
fire_consuption_rate = 0.25
fire_consuption_rate_NAME = "Fire - Air Consumption Ratio"
fire_consuption_rate_DESC = "Ratio of air removed and combusted per tick."
fire_firelevel_multiplier = 25
fire_firelevel_multiplier_NAME = "Fire - Firelevel Constant"
fire_firelevel_multiplier_DESC = "Multiplied by the equation for firelevel, affects the combustion and ignition of gas mixes."
fire_temperature_multiplier = 1700
fire_temperature_multiplier_NAME = "Fire - Temperature Multiplier"
fire_temperature_multiplier_DESC = "Base value for fire temperatures."
fire_gas_combustion_ratio = 0.25
fire_gas_combustion_ratio_NAME = "Fire - Gas Conversion Ratio"
fire_gas_combustion_ratio_DESC = "The rate at which oxygen and plasma are converted to CO2, expressed in terms of the firelevel."
airflow_lightest_pressure = 20
airflow_lightest_pressure_NAME = "Airflow - Small Movement Threshold %"
airflow_lightest_pressure_DESC = "Percent of 1 Atm. at which items with the small weight classes will move."
airflow_light_pressure = 45
airflow_light_pressure = 35
airflow_light_pressure_NAME = "Airflow - Medium Movement Threshold %"
airflow_light_pressure_DESC = "Percent of 1 Atm. at which items with the medium weight classes will move."
airflow_medium_pressure = 90
airflow_medium_pressure = 50
airflow_medium_pressure_NAME = "Airflow - Heavy Movement Threshold %"
airflow_medium_pressure_DESC = "Percent of 1 Atm. at which items with the largest weight classes will move."
airflow_heavy_pressure = 95
airflow_heavy_pressure = 65
airflow_heavy_pressure_NAME = "Airflow - Mob Movement Threshold %"
airflow_heavy_pressure_DESC = "Percent of 1 Atm. at which mobs will move."
airflow_dense_pressure = 120
airflow_dense_pressure = 85
airflow_dense_pressure_NAME = "Airflow - Dense Movement Threshold %"
airflow_dense_pressure_DESC = "Percent of 1 Atm. at which items with canisters and closets will move."
airflow_stun_pressure = 100
airflow_stun_pressure = 60
airflow_stun_pressure_NAME = "Airflow - Mob Stunning Threshold %"
airflow_stun_pressure_DESC = "Percent of 1 Atm. at which mobs will be stunned by airflow."
airflow_stun_cooldown = 60
airflow_stun_cooldown_NAME = "Aiflow Stunning - Cooldown"
airflow_stun_cooldown_DESC = "How long, in tenths of a second, to wait before stunning them again."
airflow_stun = 0.15
airflow_stun = 1
airflow_stun_NAME = "Airflow Impact - Stunning"
airflow_stun_DESC = "How much a mob is stunned when hit by an object."
airflow_damage = 0.3
airflow_damage = 2
airflow_damage_NAME = "Airflow Impact - Damage"
airflow_damage_DESC = "Damage from airflow impacts."
airflow_speed_decay = 1.5
airflow_speed_decay_NAME = "Airflow Speed Decay"
airflow_speed_decay_DESC = "How rapidly the speed gained from airflow decays."
airflow_delay = 30
airflow_delay_NAME = "Airflow Retrigger Delay"
airflow_delay_DESC = "Time in deciseconds before things can be moved by airflow again."
airflow_mob_slowdown = 1
airflow_mob_slowdown_NAME = "Airflow Slowdown"
airflow_mob_slowdown_DESC = "Time in tenths of a second to add as a delay to each movement by a mob if they are fighting the pull of the airflow."
@@ -164,21 +193,22 @@ vs_control
return
switch(def)
if("Plasma - Standard")
plc.CLOTH_CONTAMINATION = 0 //If this is on, plasma does damage by getting into cloth.
plc.CLOTH_CONTAMINATION = 1 //If this is on, plasma does damage by getting into cloth.
plc.PLASMAGUARD_ONLY = 0
plc.GENETIC_CORRUPTION = 0 //Chance of genetic corruption as well as toxic damage, X in 1000.
plc.SKIN_BURNS = 0 //Plasma has an effect similar to mustard gas on the un-suited.
plc.EYE_BURNS = 0 //Plasma burns the eyes of anyone not wearing eye protection.
plc.EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection.
plc.PLASMA_HALLUCINATION = 0
plc.CONTAMINATION_LOSS = 0
plc.CONTAMINATION_LOSS = 0.02
if("Plasma - Low Hazard")
plc.CLOTH_CONTAMINATION = 0 //If this is on, plasma does damage by getting into cloth.
plc.PLASMAGUARD_ONLY = 0
plc.GENETIC_CORRUPTION = 0 //Chance of genetic corruption as well as toxic damage, X in 1000
plc.SKIN_BURNS = 1 //Plasma has an effect similar to mustard gas on the un-suited.
plc.EYE_BURNS = 0 //Plasma burns the eyes of anyone not wearing eye protection.
plc.CONTAMINATION_LOSS = 0
plc.SKIN_BURNS = 0 //Plasma has an effect similar to mustard gas on the un-suited.
plc.EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection.
plc.PLASMA_HALLUCINATION = 0
plc.CONTAMINATION_LOSS = 0.01
if("Plasma - High Hazard")
plc.CLOTH_CONTAMINATION = 1 //If this is on, plasma does damage by getting into cloth.
@@ -186,6 +216,8 @@ vs_control
plc.GENETIC_CORRUPTION = 0 //Chance of genetic corruption as well as toxic damage, X in 1000.
plc.SKIN_BURNS = 1 //Plasma has an effect similar to mustard gas on the un-suited.
plc.EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection.
plc.PLASMA_HALLUCINATION = 1
plc.CONTAMINATION_LOSS = 0.05
if("Plasma - Oh Shit!")
plc.CLOTH_CONTAMINATION = 1 //If this is on, plasma does damage by getting into cloth.
@@ -193,18 +225,20 @@ vs_control
plc.GENETIC_CORRUPTION = 5 //Chance of genetic corruption as well as toxic damage, X in 1000.
plc.SKIN_BURNS = 1 //Plasma has an effect similar to mustard gas on the un-suited.
plc.EYE_BURNS = 1 //Plasma burns the eyes of anyone not wearing eye protection.
plc.PLASMA_HALLUCINATION = 1
plc.CONTAMINATION_LOSS = 0.075
if("ZAS - Normal")
IgnitionLevel = 0.5
airflow_lightest_pressure = 30
airflow_light_pressure = 45
airflow_medium_pressure = 90
airflow_heavy_pressure = 95
airflow_dense_pressure = 120
airflow_stun_pressure = 100
airflow_lightest_pressure = 20
airflow_light_pressure = 35
airflow_medium_pressure = 50
airflow_heavy_pressure = 65
airflow_dense_pressure = 85
airflow_stun_pressure = 60
airflow_stun_cooldown = 60
airflow_stun = 0.15
airflow_damage = 0.3
airflow_stun = 1
airflow_damage = 2
airflow_speed_decay = 1.5
airflow_delay = 30
airflow_mob_slowdown = 1
@@ -226,15 +260,15 @@ vs_control
if("ZAS - Dangerous")
IgnitionLevel = 0.4
airflow_lightest_pressure = 25
airflow_light_pressure = 35
airflow_medium_pressure = 75
airflow_heavy_pressure = 80
airflow_dense_pressure = 100
airflow_stun_pressure = 90
airflow_lightest_pressure = 15
airflow_light_pressure = 30
airflow_medium_pressure = 45
airflow_heavy_pressure = 55
airflow_dense_pressure = 70
airflow_stun_pressure = 50
airflow_stun_cooldown = 50
airflow_stun = 2
airflow_damage = 1
airflow_damage = 3
airflow_speed_decay = 1.2
airflow_delay = 25
airflow_mob_slowdown = 2
@@ -243,13 +277,13 @@ vs_control
IgnitionLevel = 0.3
airflow_lightest_pressure = 20
airflow_light_pressure = 30
airflow_medium_pressure = 70
airflow_heavy_pressure = 75
airflow_dense_pressure = 80
airflow_stun_pressure = 70
airflow_medium_pressure = 40
airflow_heavy_pressure = 50
airflow_dense_pressure = 60
airflow_stun_pressure = 40
airflow_stun_cooldown = 40
airflow_stun = 3
airflow_damage = 2
airflow_damage = 4
airflow_speed_decay = 1
airflow_delay = 20
airflow_mob_slowdown = 3

View File

@@ -198,6 +198,9 @@ turf
else
zone.RemoveTurf(NT) //Not adjacent to anything, and unsimulated. Goodbye~
//To make a closed connection through closed door.
ZConnect(T, src)
if(T.zone && !T.zone.rebuild) //I block air.
var/turf/NT = get_step(src, reverse_direction(direction))
if(istype(NT,/turf/simulated) && (NT in T.zone.contents || (NT.zone && T in NT.zone.contents)))

View File

@@ -12,6 +12,7 @@ zone
list/connections // /connection objects which refer to connections with other zones, e.g. through a door.
list/connected_zones //Parallels connections, but lists zones to which this one is connected and the number
//of points they're connected at.
list/closed_connection_zones //Same as connected_zones, but for zones where the door or whatever is closed.
list/unsimulated_tiles // Any space tiles in this list will cause air to flow out.
last_update = 0
progress = "nothing"
@@ -200,7 +201,7 @@ zone/proc/process()
progress = "problem with an inbuilt byond function: some conditional checks"
//Only run through the individual turfs if there's reason to.
if(air.graphic != air.graphic_archived || air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
if(air.graphic != air.graphic_archived || air.temperature > PLASMA_FLASHPOINT)
progress = "problem with: turf/simulated/update_visuals()"
@@ -215,10 +216,10 @@ zone/proc/process()
progress = "problem with: item or turf temperature_expose()"
//Expose stuff to extreme heat.
if(air.temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
if(air.temperature > PLASMA_FLASHPOINT)
for(var/atom/movable/item in S)
item.temperature_expose(air, air.temperature, CELL_VOLUME)
S.temperature_expose(air, air.temperature, CELL_VOLUME)
S.hotspot_expose(air.temperature, CELL_VOLUME)
progress = "problem with: calculating air graphic"
@@ -244,9 +245,11 @@ zone/proc/process()
//Do merging if conditions are met. Specifically, if there's a non-door connection
//to somewhere with space, the zones are merged regardless of equilibrium, to speed
//up spacing in areas with double-plated windows.
if(C && C.indirect == 2 && C.A.zone && C.B.zone) //indirect = 2 is a direct connection.
if(C.A.zone.air.compare(C.B.zone.air) || unsimulated_tiles)
ZMerge(C.A.zone,C.B.zone)
if(C && C.A.zone && C.B.zone)
//indirect = 2 is a direct connection.
if(C.indirect == 2 )
if(C.A.zone.air.compare(C.B.zone.air) || unsimulated_tiles)
ZMerge(C.A.zone,C.B.zone)
progress = "problem with: ShareRatio(), Airflow(), a couple of misc procs"
@@ -269,18 +272,25 @@ zone/proc/process()
Airflow(src,Z)
ShareRatio( air , Z.air , connected_zones[Z] )
for(var/zone/Z in closed_connection_zones)
if(air && Z.air)
if( abs(air.temperature - Z.air.temperature) > 10 )
ShareHeat(air, Z.air, closed_connection_zones[Z])
progress = "all components completed successfully, the problem is not here"
////////////////
//Air Movement//
////////////////
var/list/sharing_lookup_table = list(0.06, 0.11, 0.15, 0.18, 0.20, 0.21)
var/list/sharing_lookup_table = list(0.15, 0.20, 0.24, 0.27, 0.30, 0.33)
proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
//Shares a specific ratio of gas between mixtures using simple weighted averages.
var
ratio = 0.50
//WOOT WOOT TOUCH THIS AND YOU ARE A RETARD
ratio = 0.33
//WOOT WOOT TOUCH THIS AND YOU ARE A RETARD
size = max(1,A.group_multiplier)
share_size = max(1,B.group_multiplier)
@@ -306,6 +316,11 @@ proc/ShareRatio(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
temp_avg = (A.temperature * full_heat_capacity + B.temperature * s_full_heat_capacity) / (full_heat_capacity + s_full_heat_capacity)
//WOOT WOOT TOUCH THIS AND YOU ARE A RETARD
if(sharing_lookup_table.len >= connecting_tiles) //6 or more interconnecting tiles will max at 42% of air moved per tick.
ratio = sharing_lookup_table[connecting_tiles]
//WOOT WOOT TOUCH THIS AND YOU ARE A RETARD
A.oxygen = max(0, (A.oxygen - oxy_avg) * (1-ratio) + oxy_avg )
A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1-ratio) + nit_avg )
A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg )
@@ -360,34 +375,37 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles)
unsim_temperature += T.temperature/unsimulated_tiles.len
var
// Depressurize very, very fast(it's fine since many rooms are internally multiple zones)
ratio = 0.50
ratio = 0.33
old_pressure = A.return_pressure()
size = max(1,A.group_multiplier)
share_size = max(1,unsimulated_tiles.len)
//full_oxy = A.oxygen * size
//full_nitro = A.nitrogen * size
//full_co2 = A.carbon_dioxide * size
//full_plasma = A.toxins * size
full_oxy = A.oxygen * size
full_nitro = A.nitrogen * size
full_co2 = A.carbon_dioxide * size
full_plasma = A.toxins * size
//full_heat_capacity = A.heat_capacity() * size
full_heat_capacity = A.heat_capacity() * size
oxy_avg = unsim_oxygen//(full_oxy + unsim_oxygen) / (size + share_size)
nit_avg = unsim_nitrogen//(full_nitro + unsim_nitrogen) / (size + share_size)
co2_avg = unsim_co2//(full_co2 + unsim_co2) / (size + share_size)
plasma_avg = unsim_plasma//(full_plasma + unsim_plasma) / (size + share_size)
oxy_avg = (full_oxy + unsim_oxygen) / (size + share_size)
nit_avg = (full_nitro + unsim_nitrogen) / (size + share_size)
co2_avg = (full_co2 + unsim_co2) / (size + share_size)
plasma_avg = (full_plasma + unsim_plasma) / (size + share_size)
temp_avg = (A.temperature * full_heat_capacity + unsim_temperature * unsim_heat_capacity) / (full_heat_capacity + unsim_heat_capacity)
if(sharing_lookup_table.len >= unsimulated_tiles.len) //6 or more interconnecting tiles will max at 42% of air moved per tick.
ratio = sharing_lookup_table[unsimulated_tiles.len]
ratio *= 2
A.oxygen = max(0, (A.oxygen - oxy_avg) * (1-ratio) + oxy_avg )
A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1-ratio) + nit_avg )
A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1-ratio) + co2_avg )
A.toxins = max(0, (A.toxins - plasma_avg) * (1-ratio) + plasma_avg )
// EXPERIMENTAL: Disable space being cold
//A.temperature = max(TCMB, (A.temperature - temp_avg) * (1-ratio) + temp_avg )
A.temperature = max(TCMB, (A.temperature - temp_avg) * (1-ratio) + temp_avg )
for(var/datum/gas/G in A.trace_gases)
var/G_avg = (G.moles*size + 0) / (size+share_size)
@@ -397,6 +415,29 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles)
return abs(old_pressure - A.return_pressure())
proc/ShareHeat(datum/gas_mixture/A, datum/gas_mixture/B, connecting_tiles)
//Shares a specific ratio of gas between mixtures using simple weighted averages.
var
//WOOT WOOT TOUCH THIS AND YOU ARE A RETARD
ratio = 0.33
//WOOT WOOT TOUCH THIS AND YOU ARE A RETARD
full_heat_capacity = A.heat_capacity()
s_full_heat_capacity = B.heat_capacity()
temp_avg = (A.temperature * full_heat_capacity + B.temperature * s_full_heat_capacity) / (full_heat_capacity + s_full_heat_capacity)
//WOOT WOOT TOUCH THIS AND YOU ARE A RETARD
if(sharing_lookup_table.len >= connecting_tiles) //6 or more interconnecting tiles will max at 42% of air moved per tick.
ratio = sharing_lookup_table[connecting_tiles]
//WOOT WOOT TOUCH THIS AND YOU ARE A RETARD
A.temperature = max(0, (A.temperature - temp_avg) * (1- (ratio / max(1,A.group_multiplier)) ) + temp_avg )
B.temperature = max(0, (B.temperature - temp_avg) * (1- (ratio / max(1,B.group_multiplier)) ) + temp_avg )
///////////////////
//Zone Rebuilding//
///////////////////
@@ -477,6 +518,7 @@ zone/proc/Rebuild()
if(istype(T) && T.zone && S.CanPass(null, T, 0, 0))
T.zone.AddTurf(S)
proc/play_wind_sound(var/turf/random_border, var/n)
if(random_border)
var/windsound = 'sound/effects/wind/wind_2_1.ogg'

View File

@@ -38,12 +38,6 @@ datum/controller/game_controller/New()
del(master_controller)
master_controller = src
createRandomZlevel()
if(!air_master)
air_master = new /datum/controller/air_system()
air_master.setup()
if(!job_master)
job_master = new /datum/controller/occupations()
job_master.SetupOccupations()
@@ -52,13 +46,20 @@ datum/controller/game_controller/New()
if(!syndicate_code_phrase) syndicate_code_phrase = generate_code_phrase()
if(!syndicate_code_response) syndicate_code_response = generate_code_phrase()
if(!ticker) ticker = new /datum/controller/gameticker()
if(!emergency_shuttle) emergency_shuttle = new /datum/shuttle_controller/emergency_shuttle()
datum/controller/game_controller/proc/setup()
world.tick_lag = config.Ticklag
createRandomZlevel()
if(!air_master)
air_master = new /datum/controller/air_system()
air_master.setup()
if(!ticker)
ticker = new /datum/controller/gameticker()
setup_objects()
setupgenetics()
setupfactions()
@@ -71,6 +72,9 @@ datum/controller/game_controller/proc/setup()
if(ticker)
ticker.pregame()
lighting_controller.Initialize()
datum/controller/game_controller/proc/setup_objects()
world << "\red \b Initializing objects"
sleep(-1)

View File

@@ -191,7 +191,7 @@ proc/get_id_photo(var/mob/living/carbon/human/H)
clothes_s = new /icon('icons/mob/uniform.dmi', "miner_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "black"), ICON_UNDERLAY)
if("Lawyer")
clothes_s = new /icon('icons/mob/uniform.dmi', "lawyer_blue_s")
clothes_s = new /icon('icons/mob/uniform.dmi', "internalaffairs_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY)
if("Chaplain")
clothes_s = new /icon('icons/mob/uniform.dmi', "chapblack_s")

View File

@@ -2,14 +2,15 @@
var/angle
var/dx
var/dy
var/counter = 50 // to make the vars update during 1st call
// var/counter = 50 // to make the vars update during 1st call
var/rate
var/list/solars // for debugging purposes, references solars_list at the constructor
var/nexttime = 3600 // Replacement for var/counter to force the sun to move every X IC minutes
/datum/sun/New()
solars = solars_list
rate = rand(75,125)/100 // 75% - 125% of standard rotation
rate = rand(750,1250)/1000 // 75.0% - 125.0% of standard rotation
if(prob(50))
rate = -rate
@@ -17,13 +18,22 @@
/datum/sun/proc/calc_position()
counter++
/* counter++
if(counter<50) // count 50 pticks (50 seconds, roughly - about a 5deg change)
return
counter = 0
counter = 0 */
angle = ((rate*world.time/100)%360 + 360)%360
/*
Yields a 45 - 75 IC minute rotational period
Rotation rate can vary from 4.8 deg/min to 8 deg/min (288 to 480 deg/hr)
*/
// To prevent excess server load the server only updates the sun's sight lines every 6 minutes
if(nexttime < world.time)
return
nexttime = nexttime + 3600 // 600 world.time ticks = 1 minute, 3600 = 6 minutes.
angle = ((rate*world.realtime/100)%360 + 360)%360 // gives about a 60 minute rotation time
// now 45 - 75 minutes, depending on rate
// now calculate and cache the (dx,dy) increments for line drawing
var/s = sin(angle)

View File

@@ -24,7 +24,7 @@
U.hastie = new /obj/item/clothing/tie/medal/gold/captain(U)
H.equip_to_slot_or_del(U, slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/device/pda/captain(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/captain(H), slot_wear_suit)
//H.equip_to_slot_or_del(new /obj/item/clothing/suit/armor/captain(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/clothing/head/caphat(H), slot_head)
H.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses(H), slot_glasses)

View File

@@ -326,19 +326,18 @@
var/global/lawyer = 0//Checks for another lawyer
//var/global/lawyer = 0//Checks for another lawyer //This changed clothes on 2nd lawyer, both IA get the same dreds.
/datum/job/lawyer
title = "Lawyer"
title = "Internal Affairs Agent"
flag = LAWYER
department_flag = CIVILIAN
faction = "Station"
total_positions = 2
spawn_positions = 2
supervisors = "the head of personnel"
supervisors = "the captain"
selection_color = "#dddddd"
access = list(access_lawyer, access_court, access_sec_doors, access_maint_tunnels)
minimal_access = list(access_lawyer, access_court, access_sec_doors)
alt_titles = list("Attorney", "IA Consultant")
equip(var/mob/living/carbon/human/H)
@@ -347,21 +346,19 @@ var/global/lawyer = 0//Checks for another lawyer
if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back)
if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
if(!lawyer)
lawyer = 1
H.equip_to_slot_or_del(new /obj/item/clothing/under/lawyer/bluesuit(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/lawyer/bluejacket(H), slot_wear_suit)
else
H.equip_to_slot_or_del(new /obj/item/clothing/under/lawyer/purpsuit(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/lawyer/purpjacket(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/internalaffairs(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/internalaffairs(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/clothing/glasses/sunglasses/big(H), slot_glasses)
H.equip_to_slot_or_del(new /obj/item/device/pda/lawyer(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/briefcase(H), slot_l_hand)
if(H.backbag == 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
else
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
var/obj/item/weapon/implant/loyalty/L = new/obj/item/weapon/implant/loyalty(H)
L.imp_in = H
L.implanted = 1
return 1

File diff suppressed because it is too large Load Diff

View File

@@ -136,6 +136,9 @@
else
can_label = 0
if(air_contents.temperature > PLASMA_FLASHPOINT)
air_contents.zburn()
src.updateDialog()
return

View File

@@ -1,5 +1,5 @@
/obj/effect/bee
/mob/living/simple_animal/bee
name = "bees"
icon = 'icons/obj/apiary_bees_etc.dmi'
icon_state = "bees1"
@@ -11,162 +11,154 @@
var/mob/target_mob
var/obj/machinery/apiary/parent
pass_flags = PASSGRILLE|PASSTABLE
turns_per_move = 6
var/obj/machinery/hydroponics/my_hydrotray
/obj/effect/bee/New(loc, var/obj/machinery/apiary/new_parent)
/mob/living/simple_animal/bee/New(loc, var/obj/machinery/apiary/new_parent)
..()
processing_objects.Add(src)
parent = new_parent
verbs -= /atom/movable/verb/pull
/obj/effect/bee/Del()
processing_objects.Remove(src)
/mob/living/simple_animal/bee/Del()
if(parent)
parent.owned_bee_swarms.Remove(src)
..()
/obj/effect/bee/process()
/mob/living/simple_animal/bee/Life()
..()
//if we're strong enough, sting some people
var/overrun = strength - 5 + feral / 2
if(prob(max( overrun * 10 + feral * 10, 0)))
var/mob/living/carbon/human/M = locate() in src.loc
if(M)
var/sting_prob = 100
var/obj/item/clothing/worn_suit = M.wear_suit
var/obj/item/clothing/worn_helmet = M.head
if(worn_suit)
sting_prob -= worn_suit.armor["bio"]
if(worn_helmet)
sting_prob -= worn_helmet.armor["bio"]
if(stat == CONSCIOUS)
//if we're strong enough, sting some people
var/overrun = strength - 5 + feral / 2
if(prob(max( overrun * 10 + feral * 10, 0)))
var/mob/living/carbon/human/M = pick(range(1,src))
if(M)
var/sting_prob = 100
var/obj/item/clothing/worn_suit = M.wear_suit
var/obj/item/clothing/worn_helmet = M.head
if(worn_suit)
sting_prob -= worn_suit.armor["bio"]
if(worn_helmet)
sting_prob -= worn_helmet.armor["bio"]
if( prob(sting_prob) && (M.stat == CONSCIOUS || (M.stat == UNCONSCIOUS && prob(25))) )
M.apply_damage(overrun / 2 + mut / 2, BRUTE)
M.apply_damage(overrun / 2 + toxic / 2, TOX)
M << "\red You have been stung!"
M.flash_pain()
if( prob(sting_prob) && (M.stat == CONSCIOUS || (M.stat == UNCONSCIOUS && prob(25))) )
M.apply_damage(overrun / 2 + mut / 2, BRUTE)
M.apply_damage(overrun / 2 + toxic / 2, TOX)
M << "\red You have been stung!"
M.flash_pain()
//if we're chasing someone, get a little bit angry
if(target_mob && prob(10))
feral++
//if we're chasing someone, get a little bit angry
if(target_mob && prob(10))
feral++
//calm down a little bit
var/move_prob = 40
if(feral > 0)
if(prob(feral * 10))
feral -= 1
else
//if feral is less than 0, we're becalmed by smoke or steam
if(feral < 0)
feral += 1
if(target_mob)
target_mob = null
target_turf = null
if(strength > 5)
//calm down and spread out a little
var/obj/effect/bee/B = new(get_turf(pick(orange(src,1))))
B.strength = rand(1,5)
src.strength -= B.strength
if(src.strength <= 5)
src.icon_state = "bees[src.strength]"
B.icon_state = "bees[B.strength]"
if(src.parent)
B.parent = src.parent
src.parent.owned_bee_swarms.Add(B)
//make some noise
if(prob(0.5))
src.visible_message("\blue [pick("Buzzzz.","Hmmmmm.","Bzzz.")]")
//smoke, water and steam calms us down
var/calming = 0
var/list/calmers = list(/obj/effect/effect/chem_smoke, /obj/effect/effect/water, /obj/effect/effect/foam, /obj/effect/effect/steam, /obj/effect/mist)
for(var/this_type in calmers)
var/obj/effect/check_effect = locate() in src.loc
if(check_effect.type == this_type)
calming = 1
break
if(calming)
//calm down a little bit
if(feral > 0)
src.visible_message("\blue The bees calm down!")
feral = -10
target_mob = null
target_turf = null
for(var/obj/effect/bee/B in src.loc)
if(B == src)
continue
if(feral > 0)
src.strength += B.strength
del(B)
src.icon_state = "bees[src.strength]"
if(strength > 5)
icon_state = "bees_swarm"
else if(prob(10))
//make the other swarm of bees stronger, then move away
var/total_bees = B.strength + src.strength
if(total_bees < 10)
B.strength = min(5, total_bees)
src.strength = total_bees - B.strength
B.icon_state = "bees[B.strength]"
if(src.strength <= 0)
del(src)
return
src.icon_state = "bees[B.strength]"
var/turf/simulated/floor/T = get_turf(get_step(src, pick(1,2,4,8)))
density = 1
if(T.Enter(src, get_turf(src)))
src.loc = T
density = 0
break
if(target_mob)
if(target_mob in view(src,7))
target_turf = get_turf(target_mob)
if(prob(feral * 10))
feral -= 1
else
for(var/mob/living/carbon/M in view(src,7))
target_mob = M
//if feral is less than 0, we're becalmed by smoke or steam
if(feral < 0)
feral += 1
if(target_mob)
target_mob = null
target_turf = null
if(strength > 5)
//calm down and spread out a little
var/mob/living/simple_animal/bee/B = new(get_turf(pick(orange(src,1))))
B.strength = rand(1,5)
src.strength -= B.strength
if(src.strength <= 5)
src.icon_state = "bees[src.strength]"
B.icon_state = "bees[B.strength]"
if(src.parent)
B.parent = src.parent
src.parent.owned_bee_swarms.Add(B)
//make some noise
if(prob(0.5))
src.visible_message("\blue [pick("Buzzzz.","Hmmmmm.","Bzzz.")]")
//smoke, water and steam calms us down
var/calming = 0
var/list/calmers = list(/obj/effect/effect/chem_smoke, \
/obj/effect/effect/water, \
/obj/effect/effect/foam, \
/obj/effect/effect/steam, \
/obj/effect/mist)
for(var/this_type in calmers)
var/mob/living/simple_animal/check_effect = locate() in src.loc
if(check_effect.type == this_type)
calming = 1
break
if(target_turf)
var/turf/next_turf = get_step(src.loc, get_dir(src,target_turf))
if(calming)
if(feral > 0)
src.visible_message("\blue The bees calm down!")
feral = -10
target_mob = null
target_turf = null
wander = 1
for(var/mob/living/simple_animal/bee/B in src.loc)
if(B == src)
continue
if(feral > 0)
src.strength += B.strength
del(B)
src.icon_state = "bees[src.strength]"
if(strength > 5)
icon_state = "bees_swarm"
else if(prob(10))
//make the other swarm of bees stronger, then move away
var/total_bees = B.strength + src.strength
if(total_bees < 10)
B.strength = min(5, total_bees)
src.strength = total_bees - B.strength
B.icon_state = "bees[B.strength]"
if(src.strength <= 0)
del(src)
return
src.icon_state = "bees[B.strength]"
var/turf/simulated/floor/T = get_turf(get_step(src, pick(1,2,4,8)))
density = 1
if(T.Enter(src, get_turf(src)))
src.loc = T
density = 0
break
if(target_mob)
if(target_mob in view(src,7))
target_turf = get_turf(target_mob)
wander = 0
else
for(var/mob/living/carbon/M in view(src,7))
target_mob = M
break
if(target_turf)
Move(get_step(src, get_dir(src,target_turf)))
//hacky, but w/e
var/old_density = -1
if(target_mob && get_dist(src, target_mob) <= 1)
old_density = target_mob.density
target_mob.density = 0
density = 1
if(next_turf.Enter(src, get_turf(src)))
src.loc = next_turf
density = 0
if(src.loc == target_turf)
target_turf = null
if(target_mob && old_density != -1)
target_mob.density = old_density
wander = 1
else
//find some flowers, harvest
//angry bee swarms don't hang around
if(feral > 0)
move_prob = 60
turns_per_move = rand(1,3)
else if(feral < 0)
move_prob = 0
else
var/obj/machinery/hydroponics/H = locate() in src.loc
if(H)
if(H.planted && !H.dead && H.myseed)
move_prob = 1
//chance to wander around
if(prob(move_prob))
var/turf/simulated/floor/T = get_turf(get_step(src, pick(1,2,4,8)))
density = 1
if(T.Enter(src, get_turf(src)))
src.loc = T
density = 0
turns_since_move = 0
else if(!my_hydrotray || my_hydrotray.loc != src.loc || !my_hydrotray.planted || my_hydrotray.dead || !my_hydrotray.myseed)
var/obj/machinery/hydroponics/my_hydrotray = locate() in src.loc
if(my_hydrotray)
if(my_hydrotray.planted && !my_hydrotray.dead && my_hydrotray.myseed)
turns_per_move = rand(20,50)
else
my_hydrotray = null
pixel_x = rand(-12,12)
pixel_y = rand(-12,12)

View File

@@ -22,6 +22,7 @@
var/bees_in_hive = 0
var/list/owned_bee_swarms = list()
var/hydrotray_type = /obj/machinery/hydroponics
//overwrite this after it's created if the apiary needs a custom machinery sprite
/obj/machinery/apiary/New()
@@ -69,7 +70,7 @@
else
user << "\blue You begin to dislodge the dead apiary from the tray."
if(do_after(user, 50))
new /obj/machinery/hydroponics(src.loc)
new hydrotray_type(src.loc)
new /obj/item/apiary(src.loc)
user << "\red You dislodge the apiary from the tray."
del(src)
@@ -112,11 +113,11 @@
if(swarming > 0)
swarming -= 1
if(swarming <= 0)
for(var/obj/effect/bee/B in src.loc)
for(var/mob/living/simple_animal/bee/B in src.loc)
bees_in_hive += B.strength
del(B)
else if(bees_in_hive < 10)
for(var/obj/effect/bee/B in src.loc)
for(var/mob/living/simple_animal/bee/B in src.loc)
bees_in_hive += B.strength
del(B)
@@ -144,7 +145,7 @@
health += max(nutrilevel - 1, round(-health / 2))
bees_in_hive += max(nutrilevel - 1, round(-bees_in_hive / 2))
if(owned_bee_swarms.len)
var/obj/effect/bee/B = pick(owned_bee_swarms)
var/mob/living/simple_animal/bee/B = pick(owned_bee_swarms)
B.target_turf = get_turf(src)
//clear out some toxins
@@ -161,7 +162,7 @@
//make some new bees
if(bees_in_hive >= 10 && prob(bees_in_hive * 10))
var/obj/effect/bee/B = new(get_turf(src), src)
var/mob/living/simple_animal/bee/B = new(get_turf(src), src)
owned_bee_swarms.Add(B)
B.mut = mut
B.toxic = toxic
@@ -193,7 +194,7 @@
/obj/machinery/apiary/proc/die()
if(owned_bee_swarms.len)
var/obj/effect/bee/B = pick(owned_bee_swarms)
var/mob/living/simple_animal/bee/B = pick(owned_bee_swarms)
B.target_turf = get_turf(src)
B.strength -= 1
if(B.strength <= 0)
@@ -204,7 +205,7 @@
health = 0
/obj/machinery/apiary/proc/angry_swarm(var/mob/M)
for(var/obj/effect/bee/B in owned_bee_swarms)
for(var/mob/living/simple_animal/bee/B in owned_bee_swarms)
B.feral = 50
B.target_mob = M
@@ -215,7 +216,7 @@
if(bees_in_hive >= 5)
spawn_strength = 6
var/obj/effect/bee/B = new(get_turf(src), src)
var/mob/living/simple_animal/bee/B = new(get_turf(src), src)
B.target_mob = M
B.strength = spawn_strength
B.feral = 5

View File

@@ -17,7 +17,7 @@
/obj/item/weapon/bee_net/attack_self(mob/user as mob)
var/turf/T = get_step(get_turf(user), user.dir)
for(var/obj/effect/bee/B in T)
for(var/mob/living/simple_animal/bee/B in T)
if(B.feral < 0)
caught_bees += B.strength
del(B)
@@ -38,7 +38,7 @@
while(caught_bees > 0)
//release a few super massive swarms
while(caught_bees > 5)
var/obj/effect/bee/B = new(src.loc)
var/mob/living/simple_animal/bee/B = new(src.loc)
B.feral = 5
B.target_mob = M
B.strength = 6
@@ -46,7 +46,7 @@
caught_bees -= 6
//what's left over
var/obj/effect/bee/B = new(src.loc)
var/mob/living/simple_animal/bee/B = new(src.loc)
B.strength = caught_bees
B.icon_state = "bees[B.strength]"
B.feral = 5

View File

@@ -117,7 +117,7 @@
laws.add_inherent_law(M.newFreeFormLaw)
usr << "Added a freeform law."
if(istype(P, /obj/item/device/mmi) || istype(P, /obj/item/device/posibrain))
if(istype(P, /obj/item/device/mmi) || istype(P, /obj/item/device/mmi/posibrain))
if(!P:brainmob)
user << "\red Sticking an empty [P] into the frame would sort of defeat the purpose."
return

View File

@@ -78,6 +78,8 @@
/obj/machinery/door/proc/bumpopen(mob/user as mob)
if(operating) return
if(user.last_airflow > world.time - vsc.airflow_delay) //Fakkit
return
src.add_fingerprint(user)
if(!src.requiresID())
user = null
@@ -229,6 +231,11 @@
SetOpacity(1) //caaaaarn!
operating = 0
update_nearby_tiles()
//I shall not add a check every x ticks if a door has closed over some fire.
var/obj/fire/fire = locate() in loc
if(fire)
del fire
return
/obj/machinery/door/proc/requiresID()

View File

@@ -17,6 +17,11 @@
New()
. = ..()
for(var/obj/machinery/door/firedoor/F in loc)
if(F != src)
spawn(1)
del src
return .
var/area/A = get_area(src)
ASSERT(istype(A))
@@ -134,7 +139,7 @@
else
users_name = "Unknown"
if( !stat && ( istype(C, /obj/item/weapon/card/id) || istype(C, /obj/item/device/pda) ) )
if( ishuman(user) && !stat && ( istype(C, /obj/item/weapon/card/id) || istype(C, /obj/item/device/pda) ) )
var/obj/item/weapon/card/id/ID = C
if( istype(C, /obj/item/device/pda) )
@@ -223,6 +228,8 @@
/obj/machinery/door/firedoor/border_only
//These are playing merry hell on ZAS. Sorry fellas :(
/*
icon = 'icons/obj/doors/edge_Doorfire.dmi'
glass = 1 //There is a glass window so you can see through the door
//This is needed due to BYOND limitations in controlling visibility
@@ -257,3 +264,4 @@
if(istype(source)) air_master.tiles_to_update += source
if(istype(destination)) air_master.tiles_to_update += destination
return 1
*/

View File

@@ -0,0 +1,369 @@
//States for airlock_control
#define AIRLOCK_STATE_WAIT 0
#define AIRLOCK_STATE_DEPRESSURIZE 1
#define AIRLOCK_STATE_PRESSURIZE 2
#define AIRLOCK_TARGET_INOPEN -1
#define AIRLOCK_TARGET_NONE 0
#define AIRLOCK_TARGET_OUTOPEN 1
datum/computer/file/embedded_program/smart_airlock_controller
var/id_tag
var/tag_exterior_door
var/tag_interior_door
var/tag_airpump
var/tag_chamber_sensor
var/tag_exterior_sensor
var/tag_interior_sensor
//var/sanitize_external
state = AIRLOCK_STATE_WAIT
var/target_state = AIRLOCK_TARGET_NONE
datum/computer/file/embedded_program/smart_airlock_controller/New()
..()
memory["chamber_sensor_pressure"] = ONE_ATMOSPHERE
memory["external_sensor_pressure"] = ONE_ATMOSPHERE
memory["internal_sensor_pressure"] = ONE_ATMOSPHERE
memory["exterior_status"] = "unknown"
memory["interior_status"] = "unknown"
memory["pump_status"] = "unknown"
memory["target_pressure"] = ONE_ATMOSPHERE
datum/computer/file/embedded_program/smart_airlock_controller/receive_signal(datum/signal/signal, receive_method, receive_param)
var/receive_tag = signal.data["tag"]
if(!receive_tag) return
if(receive_tag==tag_chamber_sensor)
if(signal.data["pressure"])
memory["chamber_sensor_pressure"] = text2num(signal.data["pressure"])
else if(receive_tag==tag_exterior_sensor)
if(signal.data["pressure"])
memory["external_sensor_pressure"] = text2num(signal.data["pressure"])
else if(receive_tag==tag_interior_sensor)
if(signal.data["pressure"])
memory["internal_sensor_pressure"] = text2num(signal.data["pressure"])
else if(receive_tag==tag_exterior_door)
memory["exterior_status"] = signal.data["door_status"]
else if(receive_tag==tag_interior_door)
memory["interior_status"] = signal.data["door_status"]
else if(receive_tag==tag_airpump)
if(signal.data["power"])
memory["pump_status"] = signal.data["direction"]
else
memory["pump_status"] = "off"
else if(receive_tag==id_tag)
switch(signal.data["command"])
if("cycle_exterior")
state = AIRLOCK_STATE_WAIT
target_state = AIRLOCK_TARGET_OUTOPEN
if("cycle_interior")
state = AIRLOCK_STATE_WAIT
target_state = AIRLOCK_TARGET_INOPEN
master.updateDialog()
datum/computer/file/embedded_program/smart_airlock_controller/receive_user_command(command)
var/shutdown_pump = 0
switch(command)
if("cycle_closed")
state = AIRLOCK_STATE_WAIT
target_state = AIRLOCK_TARGET_NONE
if(memory["interior_status"] != "closed")
var/datum/signal/signal = new
signal.data["tag"] = tag_interior_door
signal.data["command"] = "secure_close"
post_signal(signal)
if(memory["exterior_status"] != "closed")
var/datum/signal/signal = new
signal.data["tag"] = tag_exterior_door
signal.data["command"] = "secure_close"
post_signal(signal)
shutdown_pump = 1
if("open_interior")
state = AIRLOCK_STATE_WAIT
target_state = AIRLOCK_TARGET_NONE
if(memory["interior_status"] != "open")
var/datum/signal/signal = new
signal.data["tag"] = tag_interior_door
signal.data["command"] = "secure_open"
post_signal(signal)
if("close_interior")
if(memory["interior_status"] != "closed")
var/datum/signal/signal = new
signal.data["tag"] = tag_interior_door
signal.data["command"] = "secure_close"
post_signal(signal)
shutdown_pump = 1
if("close_exterior")
if(memory["exterior_status"] != "closed")
var/datum/signal/signal = new
signal.data["tag"] = tag_exterior_door
signal.data["command"] = "secure_close"
post_signal(signal)
shutdown_pump = 1
if("open_exterior")
state = AIRLOCK_STATE_WAIT
target_state = AIRLOCK_TARGET_NONE
if(memory["exterior_status"] != "open")
var/datum/signal/signal = new
signal.data["tag"] = tag_exterior_door
signal.data["command"] = "secure_open"
post_signal(signal)
if("cycle_exterior")
state = AIRLOCK_STATE_WAIT
target_state = AIRLOCK_TARGET_OUTOPEN
if("cycle_interior")
state = AIRLOCK_STATE_WAIT
target_state = AIRLOCK_TARGET_INOPEN
if(shutdown_pump)
//send a signal to stop pressurizing
if(memory["pump_status"] != "off")
var/datum/signal/signal = new
signal.data = list(
"tag" = tag_airpump,
"power" = 0,
"sigtype"="command"
)
post_signal(signal)
master.updateDialog()
datum/computer/file/embedded_program/smart_airlock_controller/process()
var/process_again = 1
while(process_again)
process_again = 0
if(!state && target_state)
//we're ready to do stuff, now what do we want to do?
switch(target_state)
if(AIRLOCK_TARGET_INOPEN)
memory["target_pressure"] = memory["internal_sensor_pressure"]
if(AIRLOCK_TARGET_OUTOPEN)
memory["target_pressure"] = memory["external_sensor_pressure"]
//work out whether we need to pressurize or depressurize the chamber (5% leeway with target pressure)
var/chamber_pressure = memory["chamber_sensor_pressure"]
var/target_pressure = memory["target_pressure"]
if(chamber_pressure <= target_pressure)
state = AIRLOCK_STATE_PRESSURIZE
//send a signal to start pressurizing
var/datum/signal/signal = new
signal.data = list(
"tag" = tag_airpump,
"sigtype"="command",
"power"=1,
"direction"=1,
"set_external_pressure"=target_pressure
)
post_signal(signal)
else if(chamber_pressure > target_pressure)
state = AIRLOCK_STATE_DEPRESSURIZE
//send a signal to start depressurizing
var/datum/signal/signal = new
signal.transmission_method = 1 //radio signal
signal.data = list(
"tag" = tag_airpump,
"sigtype"="command",
"power"=1,
"direction"=0,
"set_external_pressure"=target_pressure
)
post_signal(signal)
//actually do stuff
//override commands are handled elsewhere, otherwise everything proceeds automatically
switch(state)
if(AIRLOCK_STATE_PRESSURIZE)
if(memory["chamber_sensor_pressure"] >= memory["target_pressure"] * 0.95)
if(target_state < 0)
if(memory["interior_status"] != "open")
var/datum/signal/signal = new
signal.data["tag"] = tag_interior_door
signal.data["command"] = "secure_open"
post_signal(signal)
else if(target_state > 0)
if(memory["exterior_status"] != "open")
var/datum/signal/signal = new
signal.data["tag"] = tag_exterior_door
signal.data["command"] = "secure_open"
post_signal(signal)
state = AIRLOCK_STATE_WAIT
target_state = AIRLOCK_TARGET_NONE
//send a signal to stop pumping
if(memory["pump_status"] != "off")
var/datum/signal/signal = new
signal.data = list(
"tag" = tag_airpump,
"sigtype"="command",
"power" = 0
)
post_signal(signal)
master.updateDialog()
if(AIRLOCK_STATE_DEPRESSURIZE)
if(memory["chamber_sensor_pressure"] <= memory["target_pressure"] * 1.05)
if(target_state > 0)
if(memory["exterior_status"] != "open")
var/datum/signal/signal = new
signal.data["tag"] = tag_exterior_door
signal.data["command"] = "secure_open"
post_signal(signal)
else if(target_state < 0)
if(memory["interior_status"] != "open")
var/datum/signal/signal = new
signal.data["tag"] = tag_interior_door
signal.data["command"] = "secure_open"
post_signal(signal)
state = AIRLOCK_STATE_WAIT
target_state = AIRLOCK_TARGET_NONE
//send a signal to stop pumping
if(memory["pump_status"] != "off")
var/datum/signal/signal = new
signal.data = list(
"tag" = tag_airpump,
"sigtype"="command",
"power" = 0
)
post_signal(signal)
master.updateDialog()
//memory["sensor_pressure"] = sensor_pressure
memory["processing"] = state != target_state
//sensor_pressure = null //not sure if we can comment this out. Uncomment in case of problems -rastaf0
return 1
obj/machinery/embedded_controller/radio/smart_airlock_controller
icon = 'icons/obj/airlock_machines.dmi'
icon_state = "airlock_control_standby"
name = "Cycling Airlock Console"
density = 0
frequency = 1449
power_channel = ENVIRON
// Setup parameters only
var/id_tag
var/tag_exterior_door
var/tag_interior_door
var/tag_airpump
var/tag_chamber_sensor
var/tag_exterior_sensor
var/tag_interior_sensor
//var/sanitize_external
initialize()
..()
var/datum/computer/file/embedded_program/smart_airlock_controller/new_prog = new
new_prog.id_tag = id_tag
new_prog.tag_exterior_door = tag_exterior_door
new_prog.tag_interior_door = tag_interior_door
new_prog.tag_airpump = tag_airpump
new_prog.tag_chamber_sensor = tag_chamber_sensor
new_prog.tag_exterior_sensor = tag_exterior_sensor
new_prog.tag_interior_sensor = tag_interior_sensor
//new_prog.sanitize_external = sanitize_external
new_prog.master = src
program = new_prog
update_icon()
if(on && program)
if(program.memory["processing"])
icon_state = "airlock_control_process"
else
icon_state = "airlock_control_standby"
else
icon_state = "airlock_control_off"
return_text()
var/state_options = ""
var/state = 0
var/chamber_sensor_pressure = "----"
var/external_sensor_pressure = "----"
var/internal_sensor_pressure = "----"
var/exterior_status = "----"
var/interior_status = "----"
var/pump_status = "----"
var/target_pressure = "----"
if(program)
state = program.state
chamber_sensor_pressure = program.memory["chamber_sensor_pressure"]
external_sensor_pressure = program.memory["external_sensor_pressure"]
internal_sensor_pressure = program.memory["internal_sensor_pressure"]
exterior_status = program.memory["exterior_status"]
interior_status = program.memory["interior_status"]
pump_status = program.memory["pump_status"]
target_pressure = program.memory["target_pressure"]
var/exterior_closed = 0
if(exterior_status == "closed")
exterior_closed = 1
var/interior_closed = 0
if(interior_status == "closed")
interior_closed = 1
state_options += "<B>Exterior status: </B> [exterior_status] ([external_sensor_pressure] kPa)<br>"
if(exterior_closed)
state_options += "<A href='?src=\ref[src];command=open_exterior'>Open exterior airlock</A> "
if(abs(chamber_sensor_pressure - external_sensor_pressure) > ONE_ATMOSPHERE * 0.05)
state_options += "<font color='red'><b>WARNING</b></font>"
state_options += "<BR>"
if(!state && exterior_closed && interior_closed)
state_options += "<A href='?src=\ref[src];command=cycle_exterior'>Cycle to Exterior Airlock</A><BR>"
else
state_options += "<br>"
else
state_options += "<A href='?src=\ref[src];command=close_exterior'>Close exterior airlock</A><BR>"
state_options += "<BR>"
state_options += "<B>Interior status: </B> [interior_status] ([internal_sensor_pressure] kPa)<br>"
if(interior_closed)
state_options += "<A href='?src=\ref[src];command=open_interior'>Open interior airlock</A> "
if(abs(chamber_sensor_pressure - internal_sensor_pressure) > ONE_ATMOSPHERE * 0.05)
state_options += "<font color='red'><b>WARNING</b></font>"
state_options += "<BR>"
if(!state && exterior_closed && interior_closed)
state_options += "<A href='?src=\ref[src];command=cycle_interior'>Cycle to Interior Airlock</A><BR>"
else
state_options += "<br>"
else
state_options += "<A href='?src=\ref[src];command=close_interior'>Close interior airlock</A><BR>"
state_options += "<BR>"
state_options += "<br>"
state_options += "<B>Chamber Pressure:</B> [chamber_sensor_pressure] kPa<BR>"
state_options += "<B>Target Chamber Pressure:</B> [target_pressure] kPa<BR>"
state_options += "<B>Control Pump: </B> [pump_status]<BR>"
if(state)
state_options += "<A href='?src=\ref[src];command=cycle_closed'>Abort Cycling</A><BR>"
else
state_options += "<br>"
return state_options
#undef AIRLOCK_STATE_PRESSURIZE
#undef AIRLOCK_STATE_WAIT
#undef AIRLOCK_STATE_DEPRESSURIZE
#undef AIRLOCK_TARGET_INOPEN
#undef AIRLOCK_TARGET_CLOSED
#undef AIRLOCK_TARGET_OUTOPEN

View File

@@ -779,6 +779,7 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob)
var/obj/machinery/apiary/A = new(src.loc)
A.icon = src.icon
A.icon_state = src.icon_state
A.hydrotray_type = src.type
del(src)
return

View File

@@ -83,6 +83,10 @@
attack_hand(mob/user as mob)
src.add_fingerprint(user)
interact(user)
interact(mob/user as mob)
if(open)
var/dat
@@ -127,7 +131,7 @@
var/value = text2num(href_list["val"])
// limit to 20-90 degC
set_temperature = dd_range(20, 90, set_temperature + value)
set_temperature = dd_range(0, 90, set_temperature + value)
if("cellremove")
if(open && cell && !usr.get_active_hand())
@@ -164,7 +168,7 @@
var/turf/simulated/L = loc
if(istype(L))
var/datum/gas_mixture/env = L.return_air()
if(env.temperature < (set_temperature+T0C))
if(env.temperature != set_temperature + T0C)
var/transfer_moles = 0.25 * env.total_moles()
@@ -176,10 +180,12 @@
var/heat_capacity = removed.heat_capacity()
//world << "heating ([heat_capacity])"
if(heat_capacity == 0 || heat_capacity == null) // Added check to avoid divide by zero (oshi-) runtime errors -- TLE
heat_capacity = 1
removed.temperature = min((removed.temperature*heat_capacity + heating_power)/heat_capacity, 1000) // Added min() check to try and avoid wacky superheating issues in low gas scenarios -- TLE
cell.use(heating_power/20000)
if(heat_capacity) // Added check to avoid divide by zero (oshi-) runtime errors -- TLE
if(removed.temperature < set_temperature + T0C)
removed.temperature = min(removed.temperature + heating_power/heat_capacity, 1000) // Added min() check to try and avoid wacky superheating issues in low gas scenarios -- TLE
else
removed.temperature = max(removed.temperature - heating_power/heat_capacity, TCMB)
cell.use(heating_power/20000)
//world << "now at [removed.temperature]"

View File

@@ -2,6 +2,7 @@
var/product_name = "generic"
var/product_path = null
var/amount = 0
var/price = 0
var/display_color = "blue"
@@ -17,11 +18,13 @@
var/active = 1 //No sales pitches if off!
var/vend_ready = 1 //Are we ready to vend?? Is it time??
var/vend_delay = 10 //How long does it take to vend?
var/datum/data/vending_product/currently_vending = null // A /datum/data/vending_product instance of what we're paying for right now.
// To be filled out at compile time
var/list/products = list() // For each, use the following pattern:
var/list/contraband = list() // list(/type/path = amount,/type/path2 = amount2)
var/list/premium = list() // No specified amount = only one in stock
var/list/prices = list() // Prices for each item, list(/type/path = price), items not in the list don't have a price.
var/product_slogans = "" //String of slogans separated by semicolons, optional
var/product_ads = "" //String of small ad messages in the vending screen - random chance
@@ -49,6 +52,9 @@
var/const/WIRE_SHOCK = 3
var/const/WIRE_SHOOTINV = 4
var/obj/machinery/account_database/linked_db
var/datum/money_account/linked_account
/obj/machinery/vending/New()
..()
spawn(4)
@@ -64,10 +70,20 @@
src.build_inventory(contraband, 1)
src.build_inventory(premium, 0, 1)
power_change()
reconnect_database()
linked_account = vendor_account
return
return
/obj/machinery/vending/proc/reconnect_database()
for(var/obj/machinery/account_database/DB in world)
if(DB.z == src.z)
linked_db = DB
break
/obj/machinery/vending/ex_act(severity)
switch(severity)
if(1.0)
@@ -98,6 +114,7 @@
/obj/machinery/vending/proc/build_inventory(var/list/productlist,hidden=0,req_coin=0)
for(var/typepath in productlist)
var/amount = productlist[typepath]
var/price = prices[typepath]
if(isnull(amount)) amount = 1
var/atom/temp = new typepath(null)
@@ -105,6 +122,7 @@
R.product_name = temp.name
R.product_path = typepath
R.amount = amount
R.price = price
R.display_color = pick("red","blue","green")
if(hidden)
@@ -139,9 +157,69 @@
coin = W
user << "\blue You insert the [W] into the [src]"
return
else if(istype(W, /obj/item/weapon/card) && currently_vending)
//attempt to connect to a new db, and if that doesn't work then fail
if(!linked_db)
reconnect_database()
if(linked_db)
if(linked_account)
var/obj/item/weapon/card/I = W
scan_card(I)
else
usr << "\icon[src]<span class='warning'>Unable to connect to linked account.</span>"
else
usr << "\icon[src]<span class='warning'>Unable to connect to accounts database.</span>"
else
..()
/obj/machinery/vending/proc/scan_card(var/obj/item/weapon/card/I)
if(!currently_vending) return
if (istype(I, /obj/item/weapon/card/id))
var/obj/item/weapon/card/id/C = I
visible_message("<span class='info'>[usr] swipes a card through [src].</span>")
if(linked_account)
var/attempt_pin = input("Enter pin code", "Vendor transaction") as num
var/datum/money_account/D = linked_db.attempt_account_access(C.associated_account_number, attempt_pin, 2)
if(D)
var/transaction_amount = currently_vending.price
if(transaction_amount <= D.money)
//transfer the money
D.money -= transaction_amount
linked_account.money += transaction_amount
//create entries in the two account transaction logs
var/datum/transaction/T = new()
T.target_name = "[linked_account.owner_name] (via [src.name])"
T.purpose = "Purchase of [currently_vending.product_name]"
if(transaction_amount > 0)
T.amount = "([transaction_amount])"
else
T.amount = "[transaction_amount]"
T.source_terminal = src.name
T.date = current_date_string
T.time = worldtime2text()
D.transaction_log.Add(T)
//
T = new()
T.target_name = D.owner_name
T.purpose = "Purchase of [currently_vending.product_name]"
T.amount = "[transaction_amount]"
T.source_terminal = src.name
T.date = current_date_string
T.time = worldtime2text()
linked_account.transaction_log.Add(T)
// Vend the item
src.vend(src.currently_vending, usr)
currently_vending = null
else
usr << "\icon[src]<span class='warning'>You don't have that much money!</span>"
else
usr << "\icon[src]<span class='warning'>Unable to access account. Check security settings and try again.</span>"
else
usr << "\icon[src]<span class='warning'>EFTPOS is not connected to an account.</span>"
/obj/machinery/vending/attack_paw(mob/user as mob)
return attack_hand(user)
@@ -158,6 +236,15 @@
return
var/vendorname = (src.name) //import the machine's name
if(src.currently_vending)
var/dat = "<TT><center><b>[vendorname]</b></center><hr /><br>" //display the name, and added a horizontal rule
dat += "<b>You have selected [currently_vending.product_name].<br>Please swipe your ID to pay for the article.</b><br>"
dat += "<a href='byond://?src=\ref[src];cancel_buying=1'>Cancel</a>"
user << browse(dat, "window=vending")
onclose(user, "")
return
var/dat = "<TT><center><b>[vendorname]</b></center><hr /><br>" //display the name, and added a horizontal rule
dat += "<b>Select an item: </b><br><br>" //the rest is just general spacing and bolding
@@ -178,8 +265,10 @@
for (var/datum/data/vending_product/R in display_records)
dat += "<FONT color = '[R.display_color]'><B>[R.product_name]</B>:"
dat += " <b>[R.amount]</b> </font>"
if(R.price)
dat += " <b>(Price: [R.price])</b>"
if (R.amount > 0)
dat += "<a href='byond://?src=\ref[src];vend=\ref[R]'>(Vend)</A>"
dat += " <a href='byond://?src=\ref[src];vend=\ref[R]'>(Vend)</A>"
else
dat += " <font color = 'red'>SOLD OUT</font>"
dat += "<br>"
@@ -247,48 +336,27 @@
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))))
usr.set_machine(src)
if ((href_list["vend"]) && (src.vend_ready))
if ((href_list["vend"]) && (src.vend_ready) && (!currently_vending))
if ((!src.allowed(usr)) && (!src.emagged) && (src.wires & WIRE_SCANID)) //For SECURE VENDING MACHINES YEAH
usr << "\red Access denied." //Unless emagged of course
flick(src.icon_deny,src)
return
src.vend_ready = 0 //One thing at a time!!
var/datum/data/vending_product/R = locate(href_list["vend"])
if (!R || !istype(R) || !R.product_path || R.amount <= 0)
src.vend_ready = 1
return
if (R in coin_records)
if(!coin)
usr << "\blue You need to insert a coin to get this item."
return
if(coin.string_attached)
if(prob(50))
usr << "\blue You successfully pull the coin out before the [src] could swallow it."
else
usr << "\blue You weren't able to pull the coin out fast enough, the machine ate it, string and all."
del(coin)
else
del(coin)
if(R.price == null)
src.vend(R, usr)
else
src.currently_vending = R
src.updateUsrDialog()
R.amount--
if(((src.last_reply + (src.vend_delay + 200)) <= world.time) && src.vend_reply)
spawn(0)
src.speak(src.vend_reply)
src.last_reply = world.time
use_power(5)
if (src.icon_vend) //Show the vending animation if needed
flick(src.icon_vend,src)
spawn(src.vend_delay)
new R.product_path(get_turf(src))
src.vend_ready = 1
return
return
else if (href_list["cancel_buying"])
src.currently_vending = null
src.updateUsrDialog()
return
@@ -323,6 +391,43 @@
return
return
/obj/machinery/vending/proc/vend(datum/data/vending_product/R, mob/user)
if ((!src.allowed(user)) && (!src.emagged) && (src.wires & WIRE_SCANID)) //For SECURE VENDING MACHINES YEAH
user << "\red Access denied." //Unless emagged of course
flick(src.icon_deny,src)
return
src.vend_ready = 0 //One thing at a time!!
if (R in coin_records)
if(!coin)
user << "\blue You need to insert a coin to get this item."
return
if(coin.string_attached)
if(prob(50))
user << "\blue You successfully pull the coin out before the [src] could swallow it."
else
user << "\blue You weren't able to pull the coin out fast enough, the machine ate it, string and all."
del(coin)
else
del(coin)
R.amount--
if(((src.last_reply + (src.vend_delay + 200)) <= world.time) && src.vend_reply)
spawn(0)
src.speak(src.vend_reply)
src.last_reply = world.time
use_power(5)
if (src.icon_vend) //Show the vending animation if needed
flick(src.icon_vend,src)
spawn(src.vend_delay)
new R.product_path(get_turf(src))
src.vend_ready = 1
return
src.updateUsrDialog()
/obj/machinery/vending/process()
if(stat & (BROKEN|NOPOWER))
return
@@ -532,6 +637,8 @@
vend_delay = 34
products = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25,/obj/item/weapon/reagent_containers/food/drinks/tea = 25,/obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25)
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/ice = 10)
prices = list(/obj/item/weapon/reagent_containers/food/drinks/coffee = 25, /obj/item/weapon/reagent_containers/food/drinks/tea = 25, /obj/item/weapon/reagent_containers/food/drinks/h_chocolate = 25)
@@ -545,6 +652,9 @@
/obj/item/weapon/reagent_containers/food/snacks/sosjerky = 6,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 6,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 6,
/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 6)
contraband = list(/obj/item/weapon/reagent_containers/food/snacks/syndicake = 6)
prices = list(/obj/item/weapon/reagent_containers/food/snacks/candy = 20,/obj/item/weapon/reagent_containers/food/drinks/dry_ramen = 30,/obj/item/weapon/reagent_containers/food/snacks/chips =25,
/obj/item/weapon/reagent_containers/food/snacks/sosjerky = 30,/obj/item/weapon/reagent_containers/food/snacks/no_raisin = 20,/obj/item/weapon/reagent_containers/food/snacks/spacetwinkie = 30,
/obj/item/weapon/reagent_containers/food/snacks/cheesiehonkers = 25)
@@ -558,6 +668,9 @@
/obj/item/weapon/reagent_containers/food/drinks/dr_gibb = 10,/obj/item/weapon/reagent_containers/food/drinks/starkist = 10,
/obj/item/weapon/reagent_containers/food/drinks/space_up = 10)
contraband = list(/obj/item/weapon/reagent_containers/food/drinks/thirteenloko = 5)
prices = list(/obj/item/weapon/reagent_containers/food/drinks/cola = 20,/obj/item/weapon/reagent_containers/food/drinks/space_mountain_wind = 20,
/obj/item/weapon/reagent_containers/food/drinks/dr_gibb = 20,/obj/item/weapon/reagent_containers/food/drinks/starkist = 20,
/obj/item/weapon/reagent_containers/food/drinks/space_up = 20)
//This one's from bay12
/obj/machinery/vending/cart
@@ -581,6 +694,8 @@
products = list(/obj/item/weapon/storage/fancy/cigarettes = 10,/obj/item/weapon/storage/box/matches = 10,/obj/item/weapon/lighter/random = 4)
contraband = list(/obj/item/weapon/lighter/zippo = 4)
premium = list(/obj/item/clothing/mask/cigarette/cigar/havana = 2)
prices = list(/obj/item/weapon/storage/fancy/cigarettes = 60,/obj/item/weapon/storage/box/matches = 10,/obj/item/weapon/lighter/random = 60)
/obj/machinery/vending/medical
name = "NanoMed Plus"

View File

@@ -40,6 +40,9 @@
for(var/atom/A in contents)
A.clean_blood()
for(var/obj/item/I in contents)
I.decontaminate()
//Tanning!
for(var/obj/item/stack/sheet/hairlesshide/HH in contents)
var/obj/item/stack/sheet/wetleather/WL = new(src)

View File

@@ -651,7 +651,7 @@
/obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/posibrain))
if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/mmi/posibrain))
if(mmi_move_inside(W,user))
user << "[src]-MMI interface initialized successfuly"
else
@@ -1136,7 +1136,7 @@
src.occupant.client.perspective = MOB_PERSPECTIVE
*/
src.occupant << browse(null, "window=exosuit")
if(istype(mob_container, /obj/item/device/mmi) || istype(mob_container, /obj/item/device/posibrain))
if(istype(mob_container, /obj/item/device/mmi) || istype(mob_container, /obj/item/device/mmi/posibrain))
var/obj/item/device/mmi/mmi = mob_container
if(mmi.brainmob)
occupant.loc = mmi

View File

@@ -26,10 +26,11 @@ obj/effect/decal/cleanable/liquid_fuel
if(!istype(S)) return
for(var/d in cardinal)
if(rand(25))
var/turf/simulated/O = get_step(src,d)
if(O.CanPass(target = get_turf(src), air_group = 1))
if(!locate(/obj/effect/decal/cleanable/liquid_fuel) in O)
new/obj/effect/decal/cleanable/liquid_fuel(O,amount*0.25)
var/turf/simulated/target = get_step(src,d)
var/turf/simulated/origin = get_turf(src)
if(origin.CanPass(null, target, 0, 0) && target.CanPass(null, origin, 0, 0))
if(!locate(/obj/effect/decal/cleanable/liquid_fuel) in target)
new/obj/effect/decal/cleanable/liquid_fuel(target, amount*0.25)
amount *= 0.75
flamethrower_fuel
@@ -38,18 +39,19 @@ obj/effect/decal/cleanable/liquid_fuel
New(newLoc, amt = 1, d = 0)
dir = d //Setting this direction means you won't get torched by your own flamethrower.
. = ..()
Spread()
//The spread for flamethrower fuel is much more precise, to create a wide fire pattern.
if(amount < 0.1) return
var/turf/simulated/S = loc
if(!istype(S)) return
for(var/d in list(turn(dir,90),turn(dir,-90)))
for(var/d in list(turn(dir,90),turn(dir,-90), dir))
var/turf/simulated/O = get_step(S,d)
if(locate(/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel) in O)
continue
if(O.CanPass(target = get_turf(src), air_group = 1))
if(O.CanPass(null, S, 0, 0) && S.CanPass(null, O, 0, 0))
new/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(O,amount*0.25,d)
O.hotspot_expose((T20C*2) + 380,500) //Light flamethrower fuel on fire immediately.
amount *= 0.5
amount *= 0.25

View File

@@ -110,15 +110,11 @@
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
var/btype = 0 // 0=radio, 1=prox, 2=time
var/btemp1 = 1500
var/btemp2 = 1000 // tank temperatures
timer
btype = 2
syndicate
btemp1 = 150
btemp2 = 20
proximity
btype = 1
@@ -130,75 +126,49 @@
/obj/effect/spawner/newbomb/New()
..()
var/obj/item/device/transfer_valve/V = new(src.loc)
var/obj/item/weapon/tank/plasma/PT = new(V)
var/obj/item/weapon/tank/oxygen/OT = new(V)
V.tank_one = PT
V.tank_two = OT
PT.master = V
OT.master = V
PT.air_contents.temperature = PLASMA_FLASHPOINT
PT.air_contents.toxins = 15
PT.air_contents.carbon_dioxide = 33
PT.air_contents.update_values()
OT.air_contents.temperature = PLASMA_FLASHPOINT
OT.air_contents.oxygen = 48
OT.air_contents.update_values()
var/obj/item/device/assembly/S
switch (src.btype)
// radio
if (0)
var/obj/item/device/transfer_valve/V = new(src.loc)
var/obj/item/weapon/tank/plasma/PT = new(V)
var/obj/item/weapon/tank/oxygen/OT = new(V)
var/obj/item/device/assembly/signaler/S = new(V)
V.tank_one = PT
V.tank_two = OT
V.attached_device = S
S.holder = V
S.toggle_secure()
PT.master = V
OT.master = V
PT.air_contents.temperature = btemp1 + T0C
OT.air_contents.temperature = btemp2 + T0C
V.update_icon()
S = new/obj/item/device/assembly/signaler(V)
// proximity
if (1)
var/obj/item/device/transfer_valve/V = new(src.loc)
var/obj/item/weapon/tank/plasma/PT = new(V)
var/obj/item/weapon/tank/oxygen/OT = new(V)
var/obj/item/device/assembly/prox_sensor/P = new(V)
V.tank_one = PT
V.tank_two = OT
V.attached_device = P
P.holder = V
P.toggle_secure()
PT.master = V
OT.master = V
PT.air_contents.temperature = btemp1 + T0C
OT.air_contents.temperature = btemp2 + T0C
V.update_icon()
S = new/obj/item/device/assembly/prox_sensor(V)
// timer
if (2)
var/obj/item/device/transfer_valve/V = new(src.loc)
var/obj/item/weapon/tank/plasma/PT = new(V)
var/obj/item/weapon/tank/oxygen/OT = new(V)
var/obj/item/device/assembly/timer/T = new(V)
S = new/obj/item/device/assembly/timer(V)
V.tank_one = PT
V.tank_two = OT
V.attached_device = T
T.holder = V
T.toggle_secure()
PT.master = V
OT.master = V
T.time = 30
V.attached_device = S
PT.air_contents.temperature = btemp1 + T0C
OT.air_contents.temperature = btemp2 + T0C
S.holder = V
S.toggle_secure()
V.update_icon()
V.update_icon()
del(src)

View File

@@ -114,7 +114,8 @@
/obj/effect/spider/spiderling/proc/die()
visible_message("<span class='alert'>[src] dies!</span>")
icon_state = "greenshatter"
new /obj/effect/decal/cleanable/spiderling_remains(src.loc)
del(src)
/obj/effect/spider/spiderling/healthcheck()
if(health <= 0)
@@ -189,6 +190,12 @@
new spawn_type(src.loc)
del(src)
/obj/effect/decal/cleanable/spiderling_remains
name = "spiderling remains"
desc = "Green squishy mess."
icon = 'icons/effects/effects.dmi'
icon_state = "greenshatter"
/obj/effect/spider/cocoon
name = "cocoon"
desc = "Something wrapped in silky spider web"

View File

@@ -117,7 +117,8 @@ var/global/list/obj/item/device/pda/PDAs = list()
/obj/item/device/pda/captain
default_cartridge = /obj/item/weapon/cartridge/captain
icon_state = "pda-c"
toff = 1
detonate = 0
//toff = 1
/obj/item/device/pda/cargo
default_cartridge = /obj/item/weapon/cartridge/quartermaster
@@ -144,7 +145,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
/obj/item/device/pda/lawyer
default_cartridge = /obj/item/weapon/cartridge/lawyer
icon_state = "pda-lawyer"
ttone = "objection"
ttone = "..."
/obj/item/device/pda/botanist
//default_cartridge = /obj/item/weapon/cartridge/botanist

View File

@@ -210,10 +210,12 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use
if (!connection)
return
Broadcast_Message(connection, new /mob/living/silicon/ai(src,null,null,1),
var/mob/living/silicon/ai/A = new /mob/living/silicon/ai(src, null, null, 1)
Broadcast_Message(connection, A,
0, "*garbled automated announcement*", src,
message, from, "Automated Announcement", from, "synthesized voice",
4, 0, 1)
4, 0, list(1), 1459)
del(A)
return
/obj/item/device/radio/talk_into(mob/living/M as mob, message, channel)

View File

@@ -126,9 +126,11 @@ MASS SPECTROMETER
if(M.status_flags & FAKEDEATH)
OX = fake_oxy > 50 ? "\red Severe oxygen deprivation detected\blue" : "Subject bloodstream oxygen level normal"
user.show_message("[OX] | [TX] | [BU] | [BR]")
if (istype(M, /mob/living/carbon/human))
if(M:virus2 || M:reagents.total_volume > 0)
if (istype(M, /mob/living/carbon))
if(M:reagents.total_volume > 0)
user.show_message(text("\red Warning: Unknown substance detected in subject's blood."))
if(M:virus2)
user.show_message(text("\red Warning: Unknown pathogen detected in subject's blood."))
if (M.getCloneLoss())
user.show_message("\red Subject appears to have been imperfectly cloned.")
for(var/datum/disease/D in M.viruses)

View File

@@ -161,7 +161,7 @@
else
user << "\blue You need to attach a flash to it first!"
if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/posibrain))
if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/mmi/posibrain))
var/obj/item/device/mmi/M = W
if(check_completion())
if(!istype(loc,/turf))

View File

@@ -1,7 +1,7 @@
/obj/item/stack/nanopaste
name = "nanopaste"
singular_name = "nanite swarm"
desc = "A tube of paste containing swarms of repair nanties. Very effective in repairing robotic machinery."
desc = "A tube of paste containing swarms of repair nanites. Very effective in repairing robotic machinery."
icon = 'icons/obj/nanopaste.dmi'
icon_state = "tube"
origin_tech = "materials=4;engineering=3"
@@ -18,8 +18,8 @@
R.adjustFireLoss(-60)
R.updatehealth()
use(1)
user.visible_message("<span class='notice'>You apply some [src] at [R]'s damaged areas.</span>",\
"<span class='notice'>\The [user] applied some [src] at [R]'s damaged areas.</span>")
user.visible_message("<span class='notice'>\The [user] applied some [src] at [R]'s damaged areas.</span>",\
"<span class='notice'>You apply some [src] at [R]'s damaged areas.</span>")
else
user << "<span class='notice'>All [R]'s systems are nominal.</span>"
@@ -31,7 +31,7 @@
S.heal_damage(30, 30, robo_repair = 1)
H.updatehealth()
use(1)
user.visible_message("<span class='notice'>You apply some nanite paste at [user == M ? "your" : "[M]'s"] [S.display_name]</span>",\
"<span class='notice'>\The [user] applies some nanite paste at[user != M ? " \the [M]'s" : " \the"][S.display_name] with \the [src]</span>")
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>"

View File

@@ -209,15 +209,17 @@
/obj/item/weapon/flamethrower/proc/ignite_turf(turf/target)
//TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this...
//Transfer 5% of current tank air contents to turf
var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(0.05)
air_transfer.toxins = air_transfer.toxins * 5 // This is me not comprehending the air system. I realize this is retarded and I could probably make it work without fucking it up like this, but there you have it. -- TLE
var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(0.02*(throw_amount/100))
//air_transfer.toxins = air_transfer.toxins * 5 // This is me not comprehending the air system. I realize this is retarded and I could probably make it work without fucking it up like this, but there you have it. -- TLE
new/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel(target,air_transfer.toxins,get_dir(loc,target))
air_transfer.toxins = 0
target.assume_air(air_transfer)
//Burn it based on transfered gas
//target.hotspot_expose(part4.air_contents.temperature*2,300)
target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500) // -- More of my "how do I shot fire?" dickery. -- TLE
//location.hotspot_expose(1000,500,1)
return
/obj/item/weapon/flamethrower/full/New(var/loc)
..()
weldtool = new /obj/item/weapon/weldingtool(src)

View File

@@ -114,7 +114,7 @@
activate(mob/user as mob)
if(active) return
if(detonator)
if(!isigniter(detonator.a_left))
detonator.a_left.activate()
@@ -216,9 +216,11 @@
var/obj/item/weapon/reagent_containers/glass/beaker/B1 = new(src)
var/obj/item/weapon/reagent_containers/glass/beaker/B2 = new(src)
B1.reagents.add_reagent("aluminum", 25)
B2.reagents.add_reagent("plasma", 25)
B2.reagents.add_reagent("sacid", 25)
B1.reagents.add_reagent("aluminum", 15)
B1.reagents.add_reagent("fuel",20)
B2.reagents.add_reagent("plasma", 15)
B2.reagents.add_reagent("sacid", 15)
B1.reagents.add_reagent("fuel",20)
detonator = new/obj/item/device/assembly_holder/timer_igniter(src)

View File

@@ -75,13 +75,13 @@
else
user.take_organ_damage(2*force)
return
/*this is already called in ..()
src.add_fingerprint(user)
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been attacked with [src.name] by [user.name] ([user.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to attack [M.name] ([M.ckey])</font>")
log_attack("<font color='red'>[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])</font>")
*/
if (user.a_intent == "hurt")
if(!..()) return
playsound(src.loc, "swing_hit", 50, 1, -1)
@@ -90,13 +90,88 @@
M.Stun(8)
M.Weaken(8)
for(var/mob/O in viewers(M))
if (O.client) O.show_message("\red <B>[M] has been beaten with the police baton by [user]!</B>", 1, "\red You hear someone fall", 2)
if (O.client) O.show_message("\red <B>[M] has been beaten with \the [src] by [user]!</B>", 1, "\red You hear someone fall", 2)
else
playsound(src.loc, 'sound/weapons/Genhit.ogg', 50, 1, -1)
M.Stun(5)
M.Weaken(5)
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been attacked with [src.name] by [user.name] ([user.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to attack [M.name] ([M.ckey])</font>")
log_attack("<font color='red'>[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])</font>")
src.add_fingerprint(user)
for(var/mob/O in viewers(M))
if (O.client) O.show_message("\red <B>[M] has been stunned with the police baton by [user]!</B>", 1, "\red You hear someone fall", 2)
if (O.client) O.show_message("\red <B>[M] has been stunned with \the [src] by [user]!</B>", 1, "\red You hear someone fall", 2)
//Telescopic baton
/obj/item/weapon/melee/telebaton
name = "telescopic baton"
desc = "A compact yet robust personal defense weapon. Can be concealed when folded."
icon = 'icons/obj/weapons.dmi'
icon_state = "telebaton_0"
item_state = "telebaton_0"
flags = FPRINT | TABLEPASS
slot_flags = SLOT_BELT
w_class = 2
force = 3
var/on = 0
/obj/item/weapon/melee/telebaton/attack_self(mob/user as mob)
on = !on
if(on)
user.visible_message("\red You extend the baton.",\
"\red With a flick of their wrist, [user] extends their telescopic baton.",\
"You hear an ominous click.")
icon_state = "telebaton_1"
item_state = "telebaton_1"
w_class = 4
force = 15//quite robust
attack_verb = list("smacked", "struck", "slapped")
else
user.visible_message("\blue You collapse the baton.",\
"\blue [user] collapses their telescopic baton.",\
"You hear a click.")
icon_state = "telebaton_0"
item_state = "telebaton_0"
w_class = 2
force = 3//not so robust now
attack_verb = list("hit", "punched")
playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1)
add_fingerprint(user)
if(blood_overlay && (blood_DNA.len >= 1)) //updates blood overlay, if any
overlays.Cut()//this might delete other item overlays as well but eeeeeeeh
var/icon/I = new /icon(src.icon, src.icon_state)
I.Blend(new /icon('icons/effects/blood.dmi', rgb(255,255,255)),ICON_ADD)
I.Blend(new /icon('icons/effects/blood.dmi', "itemblood"),ICON_MULTIPLY)
blood_overlay = I
overlays += blood_overlay
return
/obj/item/weapon/melee/telebaton/attack(mob/target as mob, mob/living/user as mob)
if(on)
if ((CLUMSY in user.mutations) && prob(50))
user << "\red You club yourself over the head."
user.Weaken(3 * force)
if(ishuman(user))
var/mob/living/carbon/human/H = user
H.apply_damage(2*force, BRUTE, "head")
else
user.take_organ_damage(2*force)
return
if(!..()) return
playsound(src.loc, "swing_hit", 50, 1, -1)
//target.Stun(4) //naaah
target.Weaken(4)
return
else
return ..()
/*
*Energy Blade

View File

@@ -17,7 +17,7 @@
/obj/item/weapon/nullrod
name = "null rod"
desc = "A rod of pure obsidian, its very presence disrupts and dampens the powers of Nar-Sie's followers."
desc = "A rod of pure obsidian, its very presence disrupts and dampens the powers of paranormal phenomenae."
icon_state = "nullrod"
item_state = "nullrod"
flags = FPRINT | TABLEPASS
@@ -32,6 +32,46 @@
viewers(user) << "\red <b>[user] is impaling \himself with the [src.name]! It looks like \he's trying to commit suicide.</b>"
return (BRUTELOSS|FIRELOSS)
/obj/item/weapon/nullrod/attack(mob/M as mob, mob/living/user as mob) //Paste from old-code to decult with a null rod.
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been attacked with [src.name] by [user.name] ([user.ckey])</font>")
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Used the [src.name] to attack [M.name] ([M.ckey])</font>")
log_admin("ATTACK: [user] ([user.ckey]) attacked [M] ([M.ckey]) with [src].")
message_admins("ATTACK: [user] ([user.ckey]) attacked [M] ([M.ckey]) with [src].")
log_attack("<font color='red'>[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])</font>")
if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
user << "\red You don't have the dexterity to do this!"
return
if ((CLUMSY in user.mutations) && prob(50))
user << "\red The rod slips out of your hand and hits your head."
user.take_organ_damage(10)
user.Paralyse(20)
return
if (M.stat !=2)
if((M.mind in ticker.mode.cult) && prob(33))
M << "\red The power of [src] clears your mind of the cult's influence!"
user << "\red You wave [src] over [M]'s head and see their eyes become clear, their mind returning to normal."
ticker.mode.remove_cultist(M.mind)
for(var/mob/O in viewers(M, null))
O.show_message(text("\red [] waves [] over []'s head.", user, src, M), 1)
else if(prob(10))
user << "\red The rod slips in your hand."
..()
else
user << "\red The rod appears to do nothing."
for(var/mob/O in viewers(M, null))
O.show_message(text("\red [] waves [] over []'s head.", user, src, M), 1)
return
/obj/item/weapon/nullrod/afterattack(atom/A, mob/user as mob)
if (istype(A, /turf/simulated/floor))
user << "\blue You hit the floor with the [src]."
call(/obj/effect/rune/proc/revealrunes)(src)
/obj/item/weapon/sord
name = "\improper SORD"
desc = "This thing is so unspeakably shitty you are having a hard time even holding it."

View File

@@ -46,7 +46,7 @@
for(var/obj/effect/dummy/chameleon/AD in src)
AD.loc = src.loc
for(var/obj/item/I in src)
for(var/obj/I in src)
I.loc = src.loc
for(var/mob/M in src)

View File

@@ -12,6 +12,11 @@
new /obj/item/clothing/under/shorts/red(src)
new /obj/item/clothing/under/shorts/blue(src)
new /obj/item/clothing/under/shorts/green(src)
new /obj/item/clothing/under/swimsuit/red(src)
new /obj/item/clothing/under/swimsuit/black(src)
new /obj/item/clothing/under/swimsuit/blue(src)
new /obj/item/clothing/under/swimsuit/green(src)
new /obj/item/clothing/under/swimsuit/purple(src)
/obj/structure/closet/boxinggloves

View File

@@ -16,6 +16,7 @@
else
new /obj/item/weapon/storage/backpack/satchel_cap(src)
new /obj/item/clothing/suit/captunic(src)
new /obj/item/clothing/suit/captunic/trek(src)
new /obj/item/clothing/head/helmet/cap(src)
new /obj/item/clothing/under/rank/captain(src)
new /obj/item/clothing/suit/armor/vest(src)
@@ -26,6 +27,8 @@
new /obj/item/clothing/gloves/captain(src)
new /obj/item/weapon/gun/energy/gun(src)
new /obj/item/clothing/suit/armor/captain(src)
new /obj/item/weapon/melee/telebaton(src)
new /obj/item/clothing/under/dress/dress_cap(src)
return
@@ -54,6 +57,7 @@
new /obj/item/weapon/gun/energy/gun(src)
new /obj/item/device/flash(src)
new /obj/item/clothing/glasses/sunglasses(src)
new /obj/item/clothing/under/dress/dress_hop(src)
return
@@ -90,6 +94,7 @@
new /obj/item/weapon/melee/baton(src)
new /obj/item/weapon/gun/energy/gun(src)
new /obj/item/clothing/tie/holster/waist(src)
new /obj/item/weapon/melee/telebaton(src)
return

View File

@@ -175,15 +175,29 @@
redlight = "largemetalr"
greenlight = "largemetalg"
/obj/structure/closet/crate/secure/large_reinforced
name = "large crate"
/obj/structure/closet/crate/secure/large/close()
//we can hold up to one large item
var/found = 0
for(var/obj/structure/S in src.loc)
if(S == src)
continue
if(!S.anchored)
found = 1
S.loc = src
break
if(!found)
for(var/obj/machinery/M in src.loc)
if(!M.anchored)
M.loc = src
break
..()
//fluff variant
/obj/structure/closet/crate/secure/large/reinforced
desc = "A hefty, reinforced metal crate with an electronic locking system."
icon = 'icons/obj/storage.dmi'
icon_state = "largermetal"
icon_opened = "largermetalopen"
icon_closed = "largermetal"
redlight = "largemetalr"
greenlight = "largemetalg"
/obj/structure/closet/crate/secure
desc = "A secure crate."
@@ -206,6 +220,23 @@
icon_opened = "largemetalopen"
icon_closed = "largemetal"
/obj/structure/closet/crate/large/close()
//we can hold up to one large item
var/found = 0
for(var/obj/structure/S in src.loc)
if(S == src)
continue
if(!S.anchored)
found = 1
S.loc = src
break
if(!found)
for(var/obj/machinery/M in src.loc)
if(!M.anchored)
M.loc = src
break
..()
/obj/structure/closet/crate/hydroponics
name = "Hydroponics crate"
desc = "All you need to destroy those pesky weeds and pests."

View File

@@ -0,0 +1,621 @@
// Basic transit tubes. Straight pieces, curved sections,
// and basic splits/joins (no routing logic).
// Mappers: you can use "Generate Instances from Icon-states"
// to get the different pieces.
/obj/structure/transit_tube
icon = 'icons/obj/pipes/transit_tube.dmi'
icon_state = "E-W"
density = 1
layer = 3.1
anchored = 1.0
var/list/tube_dirs = null
var/exit_delay = 2
var/enter_delay = 1
// alldirs in global.dm is the same list of directions, but since
// the specific order matters to get a usable icon_state, it is
// copied here so that, in the unlikely case that alldirs is changed,
// this continues to work.
var/global/list/tube_dir_list = list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)
// A place where tube pods stop, and people can get in or out.
// Mappers: use "Generate Instances from Directions" for this
// one.
/obj/structure/transit_tube/station
icon = 'icons/obj/pipes/transit_tube_station.dmi'
icon_state = "closed"
exit_delay = 2
enter_delay = 3
var/pod_moving = 0
var/automatic_launch_time = 100
var/const/OPEN_DURATION = 6
var/const/CLOSE_DURATION = 6
/obj/structure/transit_tube_pod
icon = 'icons/obj/pipes/transit_tube_pod.dmi'
icon_state = "pod"
animate_movement = FORWARD_STEPS
anchored = 1.0
density = 1
var/moving = 0
var/datum/gas_mixture/air_contents = new()
/obj/structure/transit_tube_pod/Del()
for(var/atom/movable/AM in contents)
AM.loc = loc
..()
// When destroyed by explosions, properly handle contents.
obj/structure/ex_act(severity)
switch(severity)
if(1.0)
for(var/atom/movable/AM in contents)
AM.loc = loc
AM.ex_act(severity++)
del(src)
return
if(2.0)
if(prob(50))
for(var/atom/movable/AM in contents)
AM.loc = loc
AM.ex_act(severity++)
del(src)
return
if(3.0)
return
/obj/structure/transit_tube_pod/New(loc)
..(loc)
air_contents.oxygen = MOLES_O2STANDARD * 2
air_contents.nitrogen = MOLES_N2STANDARD
air_contents.temperature = T20C
// Give auto tubes time to align before trying to start moving
spawn(5)
follow_tube()
/obj/structure/transit_tube/New(loc)
..(loc)
if(tube_dirs == null)
init_dirs()
/obj/structure/transit_tube/station/New(loc)
..(loc)
/obj/structure/transit_tube/station/Bumped(mob/AM as mob|obj)
if(!pod_moving && icon_state == "open" && istype(AM, /mob))
for(var/obj/structure/transit_tube_pod/pod in loc)
if(!pod.moving && pod.dir in directions())
AM.loc = pod
return
/obj/structure/transit_tube/station/attack_hand(mob/user as mob)
if(!pod_moving)
for(var/obj/structure/transit_tube_pod/pod in loc)
if(!pod.moving && pod.dir in directions())
if(icon_state == "closed")
open_animation()
else if(icon_state == "open")
close_animation()
/obj/structure/transit_tube/station/proc/open_animation()
if(icon_state == "closed")
icon_state = "opening"
spawn(OPEN_DURATION)
if(icon_state == "opening")
icon_state = "open"
/obj/structure/transit_tube/station/proc/close_animation()
if(icon_state == "open")
icon_state = "closing"
spawn(CLOSE_DURATION)
if(icon_state == "closing")
icon_state = "closed"
/obj/structure/transit_tube/station/proc/launch_pod()
for(var/obj/structure/transit_tube_pod/pod in loc)
if(!pod.moving && pod.dir in directions())
spawn(5)
pod_moving = 1
close_animation()
sleep(CLOSE_DURATION + 2)
if(icon_state == "closed" && pod)
pod.follow_tube()
pod_moving = 0
return
// Called to check if a pod should stop upon entering this tube.
/obj/structure/transit_tube/proc/should_stop_pod(pod, from_dir)
return 0
/obj/structure/transit_tube/station/should_stop_pod(pod, from_dir)
return 1
// Called when a pod stops in this tube section.
/obj/structure/transit_tube/proc/pod_stopped(pod, from_dir)
return
/obj/structure/transit_tube/station/pod_stopped(obj/structure/transit_tube_pod/pod, from_dir)
pod_moving = 1
spawn(5)
open_animation()
sleep(OPEN_DURATION + 2)
pod_moving = 0
pod.mix_air()
if(automatic_launch_time)
var/const/wait_step = 5
var/i = 0
while(i < automatic_launch_time)
sleep(wait_step)
i += wait_step
if(pod_moving || icon_state != "open")
return
launch_pod()
// Returns a /list of directions this tube section can connect to.
// Tubes that have some sort of logic or changing direction might
// override it with additional logic.
/obj/structure/transit_tube/proc/directions()
return tube_dirs
/obj/structure/transit_tube/proc/has_entrance(from_dir)
from_dir = turn(from_dir, 180)
for(var/direction in directions())
if(direction == from_dir)
return 1
return 0
/obj/structure/transit_tube/proc/has_exit(in_dir)
for(var/direction in directions())
if(direction == in_dir)
return 1
return 0
// Searches for an exit direction within 45 degrees of the
// specified dir. Returns that direction, or 0 if none match.
/obj/structure/transit_tube/proc/get_exit(in_dir)
var/near_dir = 0
var/in_dir_cw = turn(in_dir, -45)
var/in_dir_ccw = turn(in_dir, 45)
for(var/direction in directions())
if(direction == in_dir)
return direction
else if(direction == in_dir_cw)
near_dir = direction
else if(direction == in_dir_ccw)
near_dir = direction
return near_dir
// Return how many BYOND ticks to wait before entering/exiting
// the tube section. Default action is to return the value of
// a var, which wouldn't need a proc, but it makes it possible
// for later tube types to interact in more interesting ways
// such as being very fast in one direction, but slow in others
/obj/structure/transit_tube/proc/exit_delay(pod, to_dir)
return exit_delay
/obj/structure/transit_tube/proc/enter_delay(pod, to_dir)
return enter_delay
/obj/structure/transit_tube_pod/proc/follow_tube()
if(moving)
return
moving = 1
spawn()
var/obj/structure/transit_tube/current_tube = null
var/next_dir
var/next_loc
var/last_delay = 0
var/exit_delay
for(var/obj/structure/transit_tube/tube in loc)
if(tube.has_exit(dir))
current_tube = tube
break
while(current_tube)
next_dir = current_tube.get_exit(dir)
if(!next_dir)
break
exit_delay = current_tube.exit_delay(src, dir)
last_delay += exit_delay
sleep(exit_delay)
next_loc = get_step(loc, next_dir)
current_tube = null
for(var/obj/structure/transit_tube/tube in next_loc)
if(tube.has_entrance(next_dir))
current_tube = tube
break
if(current_tube == null)
dir = next_dir
Move(get_step(loc, dir)) // Allow collisions when leaving the tubes.
break
last_delay = current_tube.enter_delay(src, next_dir)
sleep(last_delay)
dir = next_dir
loc = next_loc // When moving from one tube to another, skip collision and such.
density = current_tube.density
if(current_tube && current_tube.should_stop_pod(src, next_dir))
current_tube.pod_stopped(src, dir)
break
density = 1
// If the pod is no longer in a tube, move in a line until stopped or slowed to a halt.
// /turf/inertial_drift appears to only work on mobs, and re-implementing some of the
// logic allows a gradual slowdown and eventual stop when passing over non-space turfs.
if(!current_tube && last_delay <= 10)
do
sleep(last_delay)
if(!istype(loc, /turf/space))
last_delay++
if(last_delay > 10)
break
while(isturf(loc) && Move(get_step(loc, dir)))
moving = 0
// Should I return a copy here? If the caller edits or del()s the returned
// datum, there might be problems if I don't...
/obj/structure/transit_tube_pod/return_air()
var/datum/gas_mixture/GM = new()
GM.oxygen = air_contents.oxygen
GM.carbon_dioxide = air_contents.carbon_dioxide
GM.nitrogen = air_contents.nitrogen
GM.toxins = air_contents.toxins
GM.temperature = air_contents.temperature
return GM
// For now, copying what I found in an unused FEA file (and almost identical in a
// used ZAS file). Means that assume_air and remove_air don't actually alter the
// air contents.
/obj/structure/transit_tube_pod/assume_air(datum/gas_mixture/giver)
return air_contents.merge(giver)
/obj/structure/transit_tube_pod/remove_air(amount)
return air_contents.remove(amount)
// Called when a pod arrives at, and before a pod departs from a station,
// giving it a chance to mix its internal air supply with the turf it is
// currently on.
/obj/structure/transit_tube_pod/proc/mix_air()
var/datum/gas_mixture/environment = loc.return_air()
var/env_pressure = environment.return_pressure()
var/int_pressure = air_contents.return_pressure()
var/total_pressure = env_pressure + int_pressure
if(total_pressure == 0)
return
// Math here: Completely made up, not based on realistic equasions.
// Goal is to balance towards equal pressure, but ensure some gas
// transfer in both directions regardless.
// Feel free to rip this out and replace it with something better,
// I don't really know muhch about how gas transfer rates work in
// SS13.
var/transfer_in = max(0.1, 0.5 * (env_pressure - int_pressure) / total_pressure)
var/transfer_out = max(0.1, 0.3 * (int_pressure - env_pressure) / total_pressure)
var/datum/gas_mixture/from_env = loc.remove_air(environment.total_moles() * transfer_in)
var/datum/gas_mixture/from_int = air_contents.remove(air_contents.total_moles() * transfer_out)
loc.assume_air(from_int)
air_contents.merge(from_env)
// When the player moves, check if the pos is currently stopped at a station.
// if it is, check the direction. If the direction matches the direction of
// the station, try to exit. If the direction matches one of the station's
// tube directions, launch the pod in that direction.
/obj/structure/transit_tube_pod/relaymove(mob/mob, direction)
if(istype(mob, /mob) && mob.client)
// If the pod is not in a tube at all, you can get out at any time.
if(!(locate(/obj/structure/transit_tube) in loc))
mob.loc = loc
mob.client.Move(get_step(loc, direction), direction)
//if(moving && istype(loc, /turf/space))
// Todo: If you get out of a moving pod in space, you should move as well.
// Same direction as pod? Direcion you moved? Halfway between?
if(!moving)
for(var/obj/structure/transit_tube/station/station in loc)
if(dir in station.directions())
if(!station.pod_moving)
if(direction == station.dir)
if(station.icon_state == "open")
mob.loc = loc
mob.client.Move(get_step(loc, direction), direction)
else
station.open_animation()
else if(direction in station.directions())
dir = direction
station.launch_pod()
return
for(var/obj/structure/transit_tube/tube in loc)
if(dir in tube.directions())
if(tube.has_exit(direction))
dir = direction
return
// Parse the icon_state into a list of directions.
// This means that mappers can use Dream Maker's built in
// "Generate Instances from Icon-states" option to get all
// variations. Additionally, as a separate proc, sub-types
// can handle it more intelligently.
/obj/structure/transit_tube/proc/init_dirs()
if(icon_state == "auto")
// Additional delay, for map loading.
spawn(1)
init_dirs_automatic()
else
tube_dirs = parse_dirs(icon_state)
if(copytext(icon_state, 1, 3) == "D-" || findtextEx(icon_state, "Pass"))
density = 0
// Tube station directions are simply 90 to either side of
// the exit.
/obj/structure/transit_tube/station/init_dirs()
tube_dirs = list(turn(dir, 90), turn(dir, -90))
// Initialize dirs by searching for tubes that do/might connect
// on nearby turfs. Create corner pieces if nessecary.
// Pick two directions, preferring tubes that already connect
// to loc, or other auto tubes if there aren't enough connections.
/obj/structure/transit_tube/proc/init_dirs_automatic()
var/list/connected = list()
var/list/connected_auto = list()
for(var/direction in tube_dir_list)
var/location = get_step(loc, direction)
for(var/obj/structure/transit_tube/tube in location)
if(tube.directions() == null && tube.icon_state == "auto")
connected_auto += direction
break
else if(turn(direction, 180) in tube.directions())
connected += direction
break
connected += connected_auto
tube_dirs = select_automatic_dirs(connected)
if(length(tube_dirs) == 2 && tube_dir_list.Find(tube_dirs[1]) > tube_dir_list.Find(tube_dirs[2]))
tube_dirs.Swap(1, 2)
generate_automatic_corners(tube_dirs)
select_automatic_icon_state(tube_dirs)
// Given a list of directions, look a pair that forms a 180 or
// 135 degree angle, and return a list containing the pair.
// If none exist, return list(connected[1], turn(connected[1], 180)
/obj/structure/transit_tube/proc/select_automatic_dirs(connected)
if(length(connected) < 1)
return list()
for(var/i = 1, i <= length(connected), i++)
for(var/j = i + 1, j <= length(connected), j++)
var/d1 = connected[i]
var/d2 = connected[j]
if(d1 == turn(d2, 135) || d1 == turn(d2, 180) || d1 == turn(d2, 225))
return list(d1, d2)
return list(connected[1], turn(connected[1], 180))
/obj/structure/transit_tube/proc/select_automatic_icon_state(directions)
if(length(directions) == 2)
icon_state = "[dir2text_short(directions[1])]-[dir2text_short(directions[2])]"
// Look for diagonal directions, generate the decorative corners in each.
/obj/structure/transit_tube/proc/generate_automatic_corners(directions)
for(var/direction in directions)
if(direction == 5 || direction == 6 || direction == 9 || direction == 10)
if(direction & NORTH)
create_automatic_decorative_corner(get_step(loc, NORTH), direction ^ 3)
else
create_automatic_decorative_corner(get_step(loc, SOUTH), direction ^ 3)
if(direction & EAST)
create_automatic_decorative_corner(get_step(loc, EAST), direction ^ 12)
else
create_automatic_decorative_corner(get_step(loc, WEST), direction ^ 12)
// Generate a corner, if one doesn't exist for the direction on the turf.
/obj/structure/transit_tube/proc/create_automatic_decorative_corner(location, direction)
var/state = "D-[dir2text_short(direction)]"
for(var/obj/structure/transit_tube/tube in location)
if(tube.icon_state == state)
return
var/obj/structure/transit_tube/tube = new(location)
tube.icon_state = state
tube.init_dirs()
// Uses a list() to cache return values. Since they should
// never be edited directly, all tubes with a certain
// icon_state can just reference the same list. In theory,
// reduces memory usage, and improves CPU cache usage.
// In reality, I don't know if that is quite how BYOND works,
// but it is probably safer to assume the existence of, and
// rely on, a sufficiently smart compiler/optimizer.
/obj/structure/transit_tube/proc/parse_dirs(text)
var/global/list/direction_table = list()
if(text in direction_table)
return direction_table[text]
var/list/split_text = stringsplit(text, "-")
// If the first token is D, the icon_state represents
// a purely decorative tube, and doesn't actually
// connect to anything.
if(split_text[1] == "D")
direction_table[text] = list()
return null
var/list/directions = list()
for(var/text_part in split_text)
var/direction = text2dir_extended(text_part)
if(direction > 0)
directions += direction
direction_table[text] = directions
return directions
// A copy of text2dir, extended to accept one and two letter
// directions, and to clearly return 0 otherwise.
/obj/structure/transit_tube/proc/text2dir_extended(direction)
switch(uppertext(direction))
if("NORTH", "N")
return 1
if("SOUTH", "S")
return 2
if("EAST", "E")
return 4
if("WEST", "W")
return 8
if("NORTHEAST", "NE")
return 5
if("NORTHWEST", "NW")
return 9
if("SOUTHEAST", "SE")
return 6
if("SOUTHWEST", "SW")
return 10
else
return 0
// A copy of dir2text, which returns the short one or two letter
// directions used in tube icon states.
/obj/structure/transit_tube/proc/dir2text_short(direction)
switch(direction)
if(1)
return "N"
if(2)
return "S"
if(4)
return "E"
if(8)
return "W"
if(5)
return "NE"
if(6)
return "SE"
if(9)
return "NW"
if(10)
return "SW"
else
return

View File

@@ -160,6 +160,9 @@
name = "Water"
icon_state = "water"
/turf/simulated/floor/beach/water/New()
..()
overlays += image("icon"='icons/misc/beach.dmi',"icon_state"="water5","layer"=MOB_LAYER+0.1)
/turf/simulated/floor/grass
name = "Grass patch"

View File

@@ -251,8 +251,9 @@
W.zone = src.zone
W.zone.AddTurf(W)
for(var/turf/simulated/T in orange(src,1))
air_master.tiles_to_update.Add(T)
if(air_master)
for(var/turf/simulated/T in orange(src,1))
air_master.tiles_to_update.Add(T)
W.levelupdate()
return W

View File

@@ -499,9 +499,12 @@ var/global/floorIsLava = 0
<A href='?src=\ref[src];quick_create_object=1'>Quick Create Object</A><br>
<A href='?src=\ref[src];create_turf=1'>Create Turf</A><br>
<A href='?src=\ref[src];create_mob=1'>Create Mob</A><br>
<br><A href='?src=\ref[src];vsc=airflow'>Edit Airflow Settings</A><br>
<A href='?src=\ref[src];vsc=plasma'>Edit Plasma Settings</A><br>
<A href='?src=\ref[src];vsc=default'>Choose a default ZAS setting</A><br>
"}
usr << browse(dat, "window=admin2;size=210x180")
usr << browse(dat, "window=admin2;size=210x280")
return
/datum/admins/proc/Secrets()

View File

@@ -120,7 +120,6 @@ var/list/admin_verbs_server = list(
/client/proc/check_customitem_activity
)
var/list/admin_verbs_debug = list(
/client/proc/restart_controller,
/client/proc/cmd_admin_list_open_jobs,
/client/proc/Debug2,
/client/proc/kill_air,

View File

@@ -2422,6 +2422,15 @@
if(check_rights(R_ADMIN|R_SERVER))
populate_inactive_customitems_list(src.owner)
else if(href_list["vsc"])
if(check_rights(R_ADMIN|R_SERVER))
if(href_list["vsc"] == "airflow")
vsc.ChangeSettingsDialog(usr,vsc.settings)
if(href_list["vsc"] == "plasma")
vsc.ChangeSettingsDialog(usr,vsc.plc.settings)
if(href_list["vsc"] == "default")
vsc.SetDefault(usr)
// player info stuff
if(href_list["add_player_info"])

View File

@@ -159,6 +159,8 @@ var/intercom_range_display_status = 0
src.verbs += /client/proc/kill_air_processing
src.verbs += /client/proc/disable_communication
src.verbs += /client/proc/disable_movement
src.verbs += /client/proc/Zone_Info
src.verbs += /client/proc/Test_ZAS_Connection
//src.verbs += /client/proc/cmd_admin_rejuvenate
feedback_add_details("admin_verb","mDV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

View File

@@ -7,12 +7,18 @@
/obj/effect/spawner/lootdrop/initialize()
var/list/things = params2list(loot)
if(things && things.len)
for(var/i = lootcount, i > 0, i--)
if(!things.len) return
var/lootspawn = text2path(pick(things))
if(!lootdoubles)
things.Remove(lootspawn)
if(!things.len)
return
new lootspawn(get_turf(src))
var/loot_spawn = pick(things)
var/loot_path = text2path(loot_spawn)
if(!loot_path || !lootdoubles)
things.Remove(loot_spawn)
continue
new loot_path(get_turf(src))
del(src)

View File

@@ -7,6 +7,13 @@
flags = FPRINT|TABLEPASS
item_state = "centhat"
/obj/item/clothing/head/hairflower
name = "hair flower pin"
icon_state = "hairflower"
desc = "Smells nice."
item_state = "hairflower"
flags = FPRINT|TABLEPASS
/obj/item/clothing/head/powdered_wig
name = "powdered wig"
desc = "A powdered wig."

View File

@@ -68,6 +68,12 @@
permeability_coefficient = 0.01
color = "white"
/obj/item/clothing/shoes/leather
name = "leather shoes"
desc = "A sturdy pair of leather shoes."
icon_state = "leather"
color = "leather"
/obj/item/clothing/shoes/rainbow
name = "rainbow shoes"
desc = "Very gay shoes."

View File

@@ -21,6 +21,11 @@
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEJUMPSUIT
/obj/item/clothing/suit/captunic/trek
name = "captain's uniform jacket"
desc = "A less formal jacket for everyday captain use."
icon_state = "capjacket"
//Chaplain
/obj/item/clothing/suit/chaplain_hoodie
name = "chaplain hoodie"
@@ -113,6 +118,35 @@
blood_overlay_type = "coat"
body_parts_covered = UPPER_TORSO|ARMS
//Internal Affairs
/obj/item/clothing/suit/storage/internalaffairs
name = "Internal Affairs Jacket"
desc = "A smooth black jacket."
icon_state = "ia_jacket_open"
item_state = "ia_jacket"
blood_overlay_type = "coat"
body_parts_covered = UPPER_TORSO|ARMS
verb/toggle()
set name = "Toggle Coat Buttons"
set category = "Object"
set src in usr
if(!usr.canmove || usr.stat || usr.restrained())
return 0
switch(icon_state)
if("ia_jacket_open")
src.icon_state = "ia_jacket"
usr << "You button up the jacket."
if("ia_jacket")
src.icon_state = "ia_jacket_open"
usr << "You unbutton the jacket."
else
usr << "You attempt to button-up the velcro on your [src], before promptly realising how retarded you are."
return
usr.update_inv_wear_suit() //so our overlays update
//Mime
/obj/item/clothing/suit/suspenders
name = "suspenders"

View File

@@ -287,6 +287,13 @@
desc = "A rather skimpy green dress."
icon_state = "stripper_g_over"
item_state = "stripper_g"
/obj/item/clothing/under/stripper/mankini
name = "the mankini"
desc = "No honest man would wear this abomination"
icon_state = "mankini"
color = "mankini"
/obj/item/clothing/suit/xenos
name = "xenos suit"
desc = "A suit made out of chitinous alien hide."
@@ -294,3 +301,35 @@
item_state = "xenos_helm"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS|HANDS
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
//swimsuit
/obj/item/clothing/under/swimsuit/black
name = "black swimsuit"
desc = "An oldfashioned black swimsuit."
icon_state = "swim_black"
color = "swim_black"
/obj/item/clothing/under/swimsuit/blue
name = "blue swimsuit"
desc = "An oldfashioned blue swimsuit."
icon_state = "swim_blue"
color = "swim_blue"
/obj/item/clothing/under/swimsuit/purple
name = "purple swimsuit"
desc = "An oldfashioned purple swimsuit."
icon_state = "swim_purp"
color = "swim_purp"
/obj/item/clothing/under/swimsuit/green
name = "green swimsuit"
desc = "An oldfashioned green swimsuit."
icon_state = "swim_green"
color = "swim_green"
/obj/item/clothing/under/swimsuit/red
name = "red swimsuit"
desc = "An oldfashioned red swimsuit."
icon_state = "swim_red"
color = "swim_red"

View File

@@ -80,6 +80,15 @@
flags = FPRINT | TABLEPASS
/obj/item/clothing/under/rank/internalaffairs
desc = "The plain, professional attire of an Internal Affairs Agent. The collar is <i>immaculately</i> starched."
name = "Internal Affairs uniform"
icon_state = "internalaffairs"
item_state = "internalaffairs"
color = "internalaffairs"
flags = FPRINT | TABLEPASS
/obj/item/clothing/under/rank/janitor
desc = "It's the official uniform of the station's janitor. It has minor protection from biohazards."
name = "janitor's jumpsuit"

View File

@@ -12,6 +12,13 @@
color = "blue_pyjamas"
item_state = "w_suit"
/obj/item/clothing/under/captain_fly
name = "rogue captains uniform"
desc = "For the man who doesn't care because he's still free."
icon_state = "captain_fly"
item_state = "captain_fly"
color = "captain_fly"
/obj/item/clothing/under/scratch
name = "white suit"
desc = "A white suit, suitable for an excellent host"
@@ -232,70 +239,116 @@
color = "gladiator"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS
//dress
/obj/item/clothing/under/dress/dress_fire
name = "flame dress"
desc = "A small black dress with blue flames print on it."
icon_state = "dress_fire"
color = "dress_fire"
/obj/item/clothing/under/dress/dress_green
name = "green dress"
desc = "A simple, tight fitting green dress."
icon_state = "dress_green"
color = "dress_green"
/obj/item/clothing/under/dress/dress_orange
name = "orange dress"
desc = "A fancy orange gown for those who like to show leg."
icon_state = "dress_orange"
color = "dress_orange"
/obj/item/clothing/under/dress/dress_pink
name = "pink dress"
desc = "A simple, tight fitting pink dress."
icon_state = "dress_pink"
color = "dress_pink"
/obj/item/clothing/under/dress/dress_yellow
name = "yellow dress"
desc = "A flirty, little yellow dress."
icon_state = "dress_yellow"
color = "dress_yellow"
/obj/item/clothing/under/dress/dress_saloon
name = "saloon girl dress"
desc = "A old western inspired gown for the girl who likes to drink."
icon_state = "dress_saloon"
color = "dress_saloon"
/obj/item/clothing/under/dress/dress_rd
name = "research director dress uniform"
desc = "Feminine fashion for the style concious RD."
icon_state = "dress_rd"
color = "dress_rd"
/obj/item/clothing/under/dress/dress_cap
name = "captain dress uniform"
desc = "Feminine fashion for the style concious captain."
icon_state = "dress_cap"
color = "dress_cap"
/obj/item/clothing/under/dress/dress_hop
name = "head of personal dress uniform"
desc = "Feminine fashion for the style concious HoP."
icon_state = "dress_hop"
color = "dress_hop"
/obj/item/clothing/under/dress/plaid_blue
name = "blue plaid skirt"
desc = "A preppy blue skirt with a white blouse."
icon_state = "plaid_blue"
color = "plaid_blue"
/obj/item/clothing/under/dress/plaid_red
name = "red plaid skirt"
desc = "A preppy red skirt with a white blouse."
icon_state = "plaid_red"
color = "plaid_red"
/obj/item/clothing/under/dress/plaid_purple
name = "blue purple skirt"
desc = "A preppy purple skirt with a white blouse."
icon_state = "plaid_purple"
color = "plaid_purple"
//wedding stuff
/obj/item/clothing/under/wedding/bride_orange
name = "orange wedding dress"
desc = "A big and puffy orange dress."
icon_state = "bride_orange"
item_state = "creamsuit"
color = "bride_orange"
flags_inv = HIDESHOES
/obj/item/clothing/under/wedding/suit_white
name = "white suit"
desc = "A fabulous white suit with orange shirt."
icon_state = "white_suit"
item_state = "creamsuit"
color = "white_suit"
/obj/item/clothing/under/wedding/bride_purple
name = "purple wedding dress"
desc = "A big and puffy purple dress."
icon_state = "bride_purple"
color = "bride_purple"
flags_inv = HIDESHOES
/obj/item/clothing/under/wedding/bridesmaid
name = "yellow dress"
desc = "A big and puffy orange dress."
icon_state = "bridesmaid"
item_state = "creamsuit"
color = "bridesmaid"
/obj/item/clothing/under/wedding/bride_blue
name = "blue wedding dress"
desc = "A big and puffy blue dress."
icon_state = "bride_blue"
color = "bride_blue"
flags_inv = HIDESHOES
/obj/item/clothing/under/wedding/firedress
name = "flaming hot black dress"
desc = "A small black dress with blue flames print on it."
icon_state = "dress_fire"
item_state = "creamsuit"
color = "dress_fire"
/obj/item/clothing/under/wedding/bride_red
name = "red wedding dress"
desc = "A big and puffy red dress."
icon_state = "bride_red"
color = "bride_red"
flags_inv = HIDESHOES
/obj/item/clothing/under/wedding/dress_orange
name = "orange dress"
icon_state = "d_orange"
color = "d_orange"
/obj/item/clothing/under/wedding/dress_green
name = "green dress"
icon_state = "d_green"
color = "d_green"
/obj/item/clothing/under/wedding/dress_purple
name = "purple dress"
icon_state = "d_purple"
color = "d_purple"
/obj/item/clothing/under/wedding/dress_red
name = "red dress"
icon_state = "d_red"
color = "d_red"
/obj/item/clothing/under/wedding/dress_blue
name = "blue dress"
icon_state = "d_blue"
color = "d_blue"
/obj/item/clothing/under/wedding/officer_blue
name = "blue officer dress"
icon_state = "officer_blue"
color = "officer_blue"
/obj/item/clothing/under/wedding/dress_vampire
name = "vampire dress"
icon_state = "d_vampire"
color = "d_vampire"
/obj/item/clothing/under/wedding/bride_white
name = "orange wedding dress"
desc = "A white wedding gown made from the finest silk."
icon_state = "bride_white"
color = "bride_white"
flags_inv = HIDESHOES
/obj/item/clothing/under/sundress
name = "sundress"

View File

@@ -194,6 +194,13 @@ hi
icon_state = "orangecamera"
pictures_left = 30
/obj/item/device/camera/fluff/oldcamera //magmaram: Maria Crash
name = "Old Camera"
icon = 'custom_items.dmi'
desc = "An old, slightly beat-up digital camera, with a cheap photo printer taped on. It's a nice shade of blue."
icon_state = "oldcamera"
pictures_left = 30
/obj/item/weapon/card/id/fluff/lifetime //fastler: Fastler Greay; it seemed like something multiple people would have
name = "Lifetime ID Card"
desc = "A modified ID card given only to those people who have devoted their lives to the better interests of NanoTrasen. It sparkles blue."
@@ -459,6 +466,11 @@ hi
icon = 'custom_items.dmi'
icon_state = "edvin_telephosphor_1"
/obj/item/clothing/head/hardhat/fluff/neil_patterson_1 //superboredguy: Neil Patterson
name = "Engineering Cap"
desc = "Much safer than a hard helmet."
icon = 'custom_items.dmi'
icon_state = "neilpatterson0_hat"
//////////// Suits ////////////
/obj/item/clothing/suit/storage/labcoat/fluff/pink //spaceman96: Trenna Seber
@@ -697,12 +709,12 @@ hi
///// Colt Peacemaker - Ana Ka'Rimah - SueTheCake
/obj/item/weapon/gun/energy/stunrevolver/fluff/ana_peacemaker
//obj/item/weapon/gun/energy/stunrevolver/fluff/ana_peacemaker
name = "Peacemaker"
/* name = "Peacemaker"
desc = "A nickel-plated revolver with pearl grips. It has a certain Old West flair!"
icon = 'custom_items.dmi'
icon_state = "peacemaker"
icon_state = "peacemaker"*/
///// Well-used baton - Oen'g Issek - Donofnyc3

View File

@@ -350,6 +350,8 @@ commented out in r5061, I left it because of the shroom thingies
excavate_find(5, src.finds[1])
else if(prob(50))
src.finds.Remove(src.finds[1])
if(prob(50))
artifact_debris()
if(do_after(user,P.digspeed))
user << "\blue You finish [P.drill_verb] the rock."
@@ -387,9 +389,8 @@ commented out in r5061, I left it because of the shroom thingies
B = new(src)
if(artifact_find)
B.artifact_find = artifact_find
else if(src.excavation_level + P.excavation_amount >= 100)
spawn(0)
artifact_debris()
else if(artifact_find && src.excavation_level + P.excavation_amount >= 100)
artifact_debris(1)
gets_drilled(B ? 0 : 1)
return
@@ -477,13 +478,8 @@ commented out in r5061, I left it because of the shroom thingies
for (var/i=0;i<mineralAmt;i++)
drop_mineral()
/*if (prob(src.artifactChance))
//spawn a rare artifact here
new /obj/machinery/artifact(src)*/
var/turf/simulated/floor/plating/airless/asteroid/N = ChangeTurf(/turf/simulated/floor/plating/airless/asteroid)
N.fullUpdateMineralOverlays()
//destroyed artifacts have weird, unpleasant effects
//make sure to destroy them before changing the turf though
if(artifact_find && artifact_fail)
var/pain = 0
if(prob(50))
@@ -500,6 +496,12 @@ commented out in r5061, I left it because of the shroom thingies
M.Stun(5)
M.apply_effect(25, IRRADIATE)
/*if (prob(src.artifactChance))
//spawn a rare artifact here
new /obj/machinery/artifact(src)*/
var/turf/simulated/floor/plating/airless/asteroid/N = ChangeTurf(/turf/simulated/floor/plating/airless/asteroid)
N.fullUpdateMineralOverlays()
/*if(destroyed) //Display message about being a terrible miner
usr << "\red You destroy some of the rocks!"*/
return
@@ -528,73 +530,60 @@ commented out in r5061, I left it because of the shroom thingies
var/obj/effect/suspension_field/S = locate() in src
if(!S || S.field_type != get_responsive_reagent(F.find_type))
if(X)
src.visible_message("\red<b>[pick("[display_name] crumbles away into dust","[display_name] breaks apart","[display_name] collapses onto itself")].</b>")
src.visible_message("\red<b>[pick("[display_name] crumbles away into dust","[display_name] breaks apart")].</b>")
del(X)
src.finds.Remove(F)
/turf/simulated/mineral/proc/artifact_debris()
/turf/simulated/mineral/proc/artifact_debris(var/severity = 0)
//cael's patented random limited drop componentized loot system!
severity = max(min(severity,1),0)
var/materials = 0
var/list/viable_materials = list(1,2,4,8,16,32,64,128,256)
var/num_materials = rand(1,5)
var/num_materials = rand(1,3 + severity*2)
for(var/i=0, i<num_materials, i++)
var/chosen = pick(viable_materials)
materials |= chosen
viable_materials.Remove(chosen)
if(materials & 1)
var/quantity = rand(0,3)
for(var/i=0, i<quantity, i++)
var/obj/item/stack/rods/R = new(src)
R.amount = rand(5,25)
var/obj/item/stack/rods/R = new(src)
R.amount = rand(5,25)
if(materials & 2)
var/quantity = pick(0, 0, 1)
for(var/i=0, i<quantity, i++)
var/obj/item/stack/tile/R = new(src)
R.amount = rand(1,5)
var/obj/item/stack/tile/R = new(src)
R.amount = rand(1,5)
if(materials & 4)
var/quantity = rand(0,3)
for(var/i=0, i<quantity, i++)
var/obj/item/stack/sheet/metal/R = new(src)
R.amount = rand(5,25)
var/obj/item/stack/sheet/metal/R = new(src)
R.amount = rand(5,25)
if(materials & 8)
var/quantity = rand(0,3)
for(var/i=0, i<quantity, i++)
var/obj/item/stack/sheet/plasteel/R = new(src)
R.amount = rand(5,25)
var/obj/item/stack/sheet/plasteel/R = new(src)
R.amount = rand(5,25)
if(materials & 16)
var/quantity = rand(0,3)
var/quantity = rand(1,3)
for(var/i=0, i<quantity, i++)
new /obj/item/weapon/shard(src)
if(materials & 32)
var/quantity = rand(0,3)
var/quantity = rand(1,3)
for(var/i=0, i<quantity, i++)
new /obj/item/weapon/shard/plasma(src)
if(materials & 64)
var/quantity = rand(0,3)
for(var/i=0, i<quantity, i++)
var/obj/item/stack/sheet/mineral/uranium/R = new(src)
R.amount = rand(5,25)
var/obj/item/stack/sheet/mineral/uranium/R = new(src)
R.amount = rand(5,25)
if(materials & 128)
var/quantity = rand(0,3)
for(var/i=0, i<quantity, i++)
var/obj/item/stack/sheet/mineral/mythril/R = new(src)
R.amount = rand(5,25)
var/obj/item/stack/sheet/mineral/mythril/R = new(src)
R.amount = rand(1,5)
if(materials & 256)
var/quantity = rand(0,3)
for(var/i=0, i<quantity, i++)
var/obj/item/stack/sheet/mineral/adamantine/R = new(src)
R.amount = rand(5,25)
var/obj/item/stack/sheet/mineral/adamantine/R = new(src)
R.amount = rand(1,5)
/*
/turf/simulated/mineral/proc/setRandomMinerals()

View File

@@ -1,4 +1,4 @@
/obj/item/device/posibrain
/obj/item/device/mmi/posibrain
name = "positronic brain"
desc = "A cube of shining metal, four inches to a side and covered in shallow grooves."
icon = 'icons/obj/assemblies.dmi'
@@ -6,17 +6,18 @@
w_class = 3
origin_tech = "engineering=4;materials=4;bluespace=2;programming=4"
var/list/construction_cost = list("metal"=500,"glass"=500,"silver"=200,"gold"=200,"plasma"=100,"diamond"=10)
var/construction_time = 75
construction_cost = list("metal"=500,"glass"=500,"silver"=200,"gold"=200,"plasma"=100,"diamond"=10)
construction_time = 75
var/searching = 0
var/askDelay = 10 * 60 * 1
var/mob/living/carbon/brain/brainmob = null
mob/living/carbon/brain/brainmob = null
req_access = list(access_robotics)
var/locked = 0
var/obj/mecha = null//This does not appear to be used outside of reference in mecha.dm.
locked = 0
mecha = null//This does not appear to be used outside of reference in mecha.dm.
attack_self(mob/user as mob)
if(!brainmob.key && searching == 0)
if(brainmob && !brainmob.key && searching == 0)
//Start the process of searching for a new user.
user << "\blue You carefully locate the manual activation switch and start the positronic brain's boot process."
icon_state = "posibrain-searching"
@@ -64,7 +65,7 @@
proc/reset_search() //We give the players sixty seconds to decide, then reset the timer.
if(brainmob) return
if(src.brainmob && src.brainmob.key) return
src.searching = 0
icon_state = "posibrain"
@@ -73,7 +74,7 @@
for (var/mob/M in viewers(T))
M.show_message("\blue The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?")
/obj/item/device/posibrain/examine()
/obj/item/device/mmi/posibrain/examine()
set src in oview()
@@ -85,7 +86,7 @@
var/msg = "<span class='info'>*---------*\nThis is \icon[src] \a <EM>[src]</EM>!\n[desc]\n"
msg += "<span class='warning'>"
if(src.brainmob.key)
if(src.brainmob && src.brainmob.key)
switch(src.brainmob.stat)
if(CONSCIOUS)
if(!src.brainmob.client) msg += "It appears to be in stand-by mode.\n" //afk
@@ -97,20 +98,20 @@
usr << msg
return
/obj/item/device/posibrain/emp_act(severity)
if(!brainmob)
/obj/item/device/mmi/posibrain/emp_act(severity)
if(!src.brainmob)
return
else
switch(severity)
if(1)
brainmob.emp_damage += rand(20,30)
src.brainmob.emp_damage += rand(20,30)
if(2)
brainmob.emp_damage += rand(10,20)
src.brainmob.emp_damage += rand(10,20)
if(3)
brainmob.emp_damage += rand(0,10)
src.brainmob.emp_damage += rand(0,10)
..()
/obj/item/device/posibrain/New()
/obj/item/device/mmi/posibrain/New()
src.brainmob = new(src)
src.brainmob.name = "[pick(list("PBU","HIU","SINA","ARMA","OSI"))]-[rand(100, 999)]"
@@ -123,4 +124,4 @@
src.brainmob.brain_op_stage = 4.0
dead_mob_list -= src.brainmob
..()
..()

View File

@@ -2,10 +2,10 @@
if (silent)
return
if(!(container && (istype(container, /obj/item/device/mmi) || istype(container, /obj/item/device/posibrain))))
if(!(container && (istype(container, /obj/item/device/mmi) || istype(container, /obj/item/device/mmi/posibrain))))
return //No MMI, can't speak, bucko./N
else
if ((copytext(message, 1, 3) == ":b") || (copytext(message, 1, 3) == ":B") && (container && istype(container, /obj/item/device/posibrain)))
if ((copytext(message, 1, 3) == ":b") || (copytext(message, 1, 3) == ":B") && (container && istype(container, /obj/item/device/mmi/posibrain)))
message = copytext(message, 3)
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
robot_talk(message)

View File

@@ -413,7 +413,7 @@
msg += "<span class = 'deptradio'>Criminal status:</span> <a href='?src=\ref[src];criminal=1'>\[[criminal]\]</a>\n"
msg += "<span class = 'deptradio'>Security records:</span> <a href='?src=\ref[src];secrecord=`'>\[View\]</a>\n"
msg += "<span class = 'deptradio'>Security records:</span> <a href='?src=\ref[src];secrecord=`'>\[View\]</a> <a href='?src=\ref[src];secrecordadd=`'>\[Add comment\]</a>\n"
//msg += "\[Set Hostile Identification\]\n"
if(istype(usr, /mob/living/carbon/human))
@@ -439,7 +439,7 @@
msg += "<span class = 'deptradio'>Physical status:</span> <a href='?src=\ref[src];medical=1'>\[[medical]\]</a>\n"
msg += "<span class = 'deptradio'>Medical records:</span> <a href='?src=\ref[src];medrecord=`'>\[View\]</a>\n"
msg += "<span class = 'deptradio'>Medical records:</span> <a href='?src=\ref[src];medrecord=`'>\[View\]</a> <a href='?src=\ref[src];medrecordadd=`'>\[Add comment\]</a>\n"
if(print_flavor_text()) msg += "[print_flavor_text()]\n"

View File

@@ -568,11 +568,70 @@
usr << "<b>Major Crimes:</b> [R.fields["ma_crim"]]"
usr << "<b>Details:</b> [R.fields["ma_crim_d"]]"
usr << "<b>Notes:</b> [R.fields["notes"]]"
usr << "<a href='?src=\ref[src];secrecordComment=`'>\[View Comment Log\]</a>"
read = 1
if(!read)
usr << "\red Unable to locate a data core entry for this person."
if (href_list["secrecordComment"])
if(istype(usr, /mob/living/carbon/human))
var/mob/living/carbon/human/H = usr
if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud))
var/perpname = "wot"
var/read = 0
if(wear_id)
if(istype(wear_id,/obj/item/weapon/card/id))
perpname = wear_id:registered_name
else if(istype(wear_id,/obj/item/device/pda))
var/obj/item/device/pda/tempPda = wear_id
perpname = tempPda.owner
else
perpname = src.name
for (var/datum/data/record/E in data_core.general)
if (E.fields["name"] == perpname)
for (var/datum/data/record/R in data_core.security)
if (R.fields["id"] == E.fields["id"])
if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud))
read = 1
var/counter = 1
while(R.fields[text("com_[]", counter)])
usr << text("[]", R.fields[text("com_[]", counter)])
counter++
if (counter == 1)
usr << "No comment found"
usr << "<a href='?src=\ref[src];secrecordadd=`'>\[Add comment\]</a>"
if(!read)
usr << "\red Unable to locate a data core entry for this person."
if (href_list["secrecordadd"])
if(istype(usr, /mob/living/carbon/human))
var/mob/living/carbon/human/H = usr
if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud))
var/perpname = "wot"
if(wear_id)
if(istype(wear_id,/obj/item/weapon/card/id))
perpname = wear_id:registered_name
else if(istype(wear_id,/obj/item/device/pda))
var/obj/item/device/pda/tempPda = wear_id
perpname = tempPda.owner
else
perpname = src.name
for (var/datum/data/record/E in data_core.general)
if (E.fields["name"] == perpname)
for (var/datum/data/record/R in data_core.security)
if (R.fields["id"] == E.fields["id"])
if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud))
var/t1 = copytext(sanitize(input("Add Comment:", "Sec. records", null, null) as message),1,MAX_MESSAGE_LEN)
if ((!( t1 ) || src.stat || src.restrained() || !(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.glasses, /obj/item/clothing/glasses/sunglasses/sechud))))
return
var/counter = 1
while(R.fields[text("com_[]", counter)])
counter++
R.fields[text("com_[]", counter)] = text("Made by [] ([]) on [], 2053<BR>[]",H.get_authentification_name(), H.get_assignment(), time2text(world.realtime, "DDD MMM DD hh:mm:ss"), t1)
if (href_list["medical"])
if(istype(usr, /mob/living/carbon/human))
var/mob/living/carbon/human/H = usr
@@ -594,7 +653,7 @@
for (var/datum/data/record/R in data_core.general)
if (R.fields["id"] == E.fields["id"])
var/setmedical = input(usr, "Specify a new criminal status for this person.", "Medical HUD", R.fields["p_stat"]) in list("*Deceased*", "*Unconscious*", "Physically Unfit", "Active", "Cancel")
var/setmedical = input(usr, "Specify a new medical status for this person.", "Medical HUD", R.fields["p_stat"]) in list("*Deceased*", "*Unconscious*", "Physically Unfit", "Active", "Cancel")
if(istype(H.glasses, /obj/item/clothing/glasses/hud/health))
if(setmedical != "Cancel")
@@ -634,10 +693,69 @@
usr << "<b>Major Disabilities:</b> [R.fields["ma_dis"]]"
usr << "<b>Details:</b> [R.fields["ma_dis_d"]]"
usr << "<b>Notes:</b> [R.fields["notes"]]"
usr << "<a href='?src=\ref[src];medrecordComment=`'>\[View Comment Log\]</a>"
read = 1
if(!read)
usr << "\red Unable to locate a data core entry for this person."
if (href_list["medrecordComment"])
if(istype(usr, /mob/living/carbon/human))
var/mob/living/carbon/human/H = usr
if(istype(H.glasses, /obj/item/clothing/glasses/hud/health))
var/perpname = "wot"
var/read = 0
if(wear_id)
if(istype(wear_id,/obj/item/weapon/card/id))
perpname = wear_id:registered_name
else if(istype(wear_id,/obj/item/device/pda))
var/obj/item/device/pda/tempPda = wear_id
perpname = tempPda.owner
else
perpname = src.name
for (var/datum/data/record/E in data_core.general)
if (E.fields["name"] == perpname)
for (var/datum/data/record/R in data_core.medical)
if (R.fields["id"] == E.fields["id"])
if(istype(H.glasses, /obj/item/clothing/glasses/hud/health))
read = 1
var/counter = 1
while(R.fields[text("com_[]", counter)])
usr << text("[]", R.fields[text("com_[]", counter)])
counter++
if (counter == 1)
usr << "No comment found"
usr << "<a href='?src=\ref[src];medrecordadd=`'>\[Add comment\]</a>"
if(!read)
usr << "\red Unable to locate a data core entry for this person."
if (href_list["medrecordadd"])
if(istype(usr, /mob/living/carbon/human))
var/mob/living/carbon/human/H = usr
if(istype(H.glasses, /obj/item/clothing/glasses/hud/health))
var/perpname = "wot"
if(wear_id)
if(istype(wear_id,/obj/item/weapon/card/id))
perpname = wear_id:registered_name
else if(istype(wear_id,/obj/item/device/pda))
var/obj/item/device/pda/tempPda = wear_id
perpname = tempPda.owner
else
perpname = src.name
for (var/datum/data/record/E in data_core.general)
if (E.fields["name"] == perpname)
for (var/datum/data/record/R in data_core.medical)
if (R.fields["id"] == E.fields["id"])
if(istype(H.glasses, /obj/item/clothing/glasses/hud/health))
var/t1 = copytext(sanitize(input("Add Comment:", "Med. records", null, null) as message),1,MAX_MESSAGE_LEN)
if ((!( t1 ) || src.stat || src.restrained() || !(istype(H.glasses, /obj/item/clothing/glasses/hud/health))))
return
var/counter = 1
while(R.fields[text("com_[]", counter)])
counter++
R.fields[text("com_[]", counter)] = text("Made by [] ([]) on [], 2053<BR>[]",H.get_authentification_name(), H.get_assignment(), time2text(world.realtime, "DDD MMM DD hh:mm:ss"), t1)
..()
return
@@ -684,7 +802,7 @@
if(dna)
switch(dna.mutantrace)
if("lizard")
return "Soghun"
return "Unathi"
if("tajaran")
return "Tajaran"
if("skrell")
@@ -699,7 +817,7 @@
/mob/living/carbon/get_species()
if(src.dna)
if(src.dna.mutantrace == "lizard")
return "Soghun"
return "Unathi"
else if(src.dna.mutantrace == "skrell")
return "Skrell"
else if(src.dna.mutantrace == "tajaran")

View File

@@ -84,6 +84,8 @@
//Random events (vomiting etc)
handle_random_events()
handle_virus_updates()
//Handle temperature/pressure differences between body and environment
handle_environment(environment)
@@ -562,6 +564,9 @@
pressure_alert = -2
else
pressure_alert = -1
if(environment.toxins > MOLES_PLASMA_VISIBLE)
pl_effects()
return
/*
@@ -775,6 +780,12 @@
proc/handle_chemicals_in_body()
if(reagents) reagents.metabolize(src)
var/total_plasmaloss = 0
for(var/obj/item/I in src)
if(I.contaminated)
total_plasmaloss += vsc.plc.CONTAMINATION_LOSS
adjustToxLoss(total_plasmaloss)
// if(dna && dna.mutantrace == "plant") //couldn't think of a better place to place it, since it handles nutrition -- Urist
if(PLANT in mutations)
@@ -1262,6 +1273,7 @@
if(bodytemperature > 406)
for(var/datum/disease/D in viruses)
D.cure()
if(virus2) virus2.cure(src)
if(!virus2)
for(var/obj/effect/decal/cleanable/blood/B in view(1,src))
if(B.virus2 && get_infection_chance())

View File

@@ -126,7 +126,7 @@ Please contact me on #coderbus IRC. ~Carn x
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/race_icon
//UPDATES OVERLAYS FROM OVERLAYS_LYING/OVERLAYS_STANDING
//this proc is messy as I was forced to include some old laggy cloaking code to it so that I don't break cloakers
@@ -234,24 +234,8 @@ proc/get_damage_icon_part(damage_state, body_part)
var/g = "m"
if(gender == FEMALE) g = "f"
var/icon/icobase
if(skeleton)
icobase = 'icons/mob/human_races/r_skeleton.dmi'
else if(dna)
switch(dna.mutantrace)
if("tajaran")
icobase = 'icons/mob/human_races/r_tajaran.dmi'
if("lizard")
icobase = 'icons/mob/human_races/r_lizard.dmi'
if("skrell")
icobase = 'icons/mob/human_races/r_skrell.dmi'
else
icobase = 'icons/mob/human_races/r_human.dmi'
else
icobase = 'icons/mob/human_races/r_human.dmi'
if(!skeleton)
stand_icon = new /icon(icobase, "torso_[g][fat?"_fat":""]")
stand_icon = new /icon(race_icon, "torso_[g][fat?"_fat":""]")
if(husk)
stand_icon.ColorTone(husk_color_mod)
else if(hulk)
@@ -261,7 +245,7 @@ proc/get_damage_icon_part(damage_state, body_part)
else if(plant)
stand_icon.ColorTone(plant_color_mod)
else
stand_icon = new /icon(icobase, "torso")
stand_icon = new /icon(race_icon, "torso")
var/datum/organ/external/head = get_organ("head")
var/has_head = 0
@@ -273,16 +257,16 @@ proc/get_damage_icon_part(damage_state, body_part)
var/icon/temp
if(istype(part, /datum/organ/external/groin))
if(skeleton)
temp = new /icon(icobase, "groin")
temp = new /icon(race_icon, "groin")
else
temp = new /icon(icobase, "groin_[g]")
temp = new /icon(race_icon, "groin_[g]")
else if(istype(part, /datum/organ/external/head))
if(skeleton)
temp = new /icon(icobase, "head")
temp = new /icon(race_icon, "head")
else
temp = new /icon(icobase, "head_[g]")
temp = new /icon(race_icon, "head_[g]")
else
temp = new /icon(icobase, "[part.icon_name]")
temp = new /icon(race_icon, "[part.icon_name]")
if(part.status & ORGAN_ROBOT)
temp.GrayScale()
if(part.status & ORGAN_DEAD)
@@ -327,7 +311,7 @@ proc/get_damage_icon_part(damage_state, body_part)
if(husk)
var/icon/mask = new(stand_icon)
var/icon/husk_over = new(icobase,"overlay_husk")
var/icon/husk_over = new(race_icon,"overlay_husk")
mask.MapColors(0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,1, 0,0,0,0)
husk_over.Blend(mask, ICON_ADD)
stand_icon.Blend(husk_over, ICON_OVERLAY)
@@ -451,14 +435,30 @@ proc/get_damage_icon_part(damage_state, body_part)
// var/g = "m"
// if (gender == FEMALE) g = "f"
//BS12 EDIT
var/skeleton = (SKELETON in src.mutations)
if(skeleton)
race_icon = 'icons/mob/human_races/r_skeleton.dmi'
else if(dna)
switch(dna.mutantrace)
if("tajaran")
race_icon = 'icons/mob/human_races/r_tajaran.dmi'
if("lizard")
race_icon = 'icons/mob/human_races/r_lizard.dmi'
if("skrell")
race_icon = 'icons/mob/human_races/r_skrell.dmi'
else
race_icon = 'icons/mob/human_races/r_human.dmi'
else
icon = 'icons/mob/human_races/r_human.dmi'
if(dna)
switch(dna.mutantrace)
if("lizard","golem","slime","shadow","adamantine")
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")
if("lizard","tajaran","skrell")
overlays_lying[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.mutantrace]_[gender]_l")
overlays_standing[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.mutantrace]_[gender]_s")
// if("lizard","tajaran","skrell")
// overlays_lying[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.mutantrace]_[gender]_l")
// overlays_standing[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.mutantrace]_[gender]_s")
if("plant")
if(stat == DEAD) //TODO
overlays_lying[MUTANTRACE_LAYER] = image("icon" = 'icons/effects/genetics.dmi', "icon_state" = "[dna.mutantrace]_d")

View File

@@ -140,5 +140,5 @@
for (var/mob/M in dead_mob_list)
if (!(M.client))
continue
if (M.stat > 1 && !(M in heard_a))
if (M.stat > 1 && !(M in heard_a) && (M.client.prefs.toggles & CHAT_GHOSTEARS))
M.show_message(rendered, 2)

View File

@@ -42,6 +42,9 @@
//Disabilities
handle_disabilities()
//Virus updates, duh
handle_virus_updates()
//Apparently, the person who wrote this code designed it so that
//blinded get reset each cycle and then get activated later in the
//code. Very ugly. I dont care. Moving this stuff here so its easy
@@ -147,6 +150,28 @@
emote("gasp")
updatehealth()
proc/handle_virus_updates()//copypaste from mob/carbon/human/life.dm
if(bodytemperature > 406)
for(var/datum/disease/D in viruses)
D.cure()
if(!virus2)
for(var/obj/effect/decal/cleanable/blood/B in view(1,src))
if(B.virus2 && get_infection_chance())
infect_virus2(src,B.virus2)
for(var/obj/effect/decal/cleanable/mucus/M in view(1,src))
if(M.virus2 && get_infection_chance())
infect_virus2(src,M.virus2)
else
if(isnull(virus2)) // Trying to figure out a runtime error that keeps repeating
CRASH("virus2 nulled before calling activate()")
else
virus2.activate(src)
// activate may have deleted the virus
if(!virus2) return
// check if we're immune
if(virus2.antigen & src.antibodies) virus2.dead = 1
proc/breathe()
if(reagents)

View File

@@ -239,7 +239,7 @@
src.updatehealth()
// damage MANY external organs, in random order
/mob/living/proc/take_overall_damage(var/brute, var/burn)
/mob/living/proc/take_overall_damage(var/brute, var/burn, var/used_weapon = null)
adjustBruteLoss(brute)
adjustFireLoss(burn)
src.updatehealth()

View File

@@ -194,7 +194,7 @@
/mob/living/silicon/robot/proc/updatename(var/prefix as text)
if(istype(mmi, /obj/item/device/posibrain))
if(istype(mmi, /obj/item/device/mmi/posibrain))
braintype = "Android"
else
braintype = "Cyborg"

View File

@@ -43,7 +43,7 @@
/mob/living/simple_animal/spiderbot/attackby(var/obj/item/O as obj, var/mob/user as mob)
if(istype(O, /obj/item/device/mmi) || istype(O, /obj/item/device/posibrain))
if(istype(O, /obj/item/device/mmi) || istype(O, /obj/item/device/mmi/posibrain))
var/obj/item/device/mmi/B = O
if(src.mmi) //There's already a brain in it.
user << "\red There's already a brain in [src]!"
@@ -203,6 +203,9 @@
if(camera)
camera.status = 0
held_item.loc = src.loc
held_item = null
robogibs(src.loc, viruses)
src.Del()
return
@@ -281,14 +284,14 @@
return 0
if(istype(held_item, /obj/item/weapon/grenade))
visible_message("\red [src] launches the [held_item]!", "\red You launch the [held_item]!", "You hear a skittering noise and a thump!")
visible_message("\red [src] launches \the [held_item]!", "\red You launch \the [held_item]!", "You hear a skittering noise and a thump!")
var/obj/item/weapon/grenade/G = held_item
G.loc = src.loc
G.prime()
held_item = null
return 1
visible_message("\blue [src] drops the [held_item]!", "\blue You drop the [held_item]!", "You hear a skittering noise and a soft thump.")
visible_message("\blue [src] drops \the [held_item]!", "\blue You drop \the [held_item]!", "You hear a skittering noise and a soft thump.")
held_item.loc = src.loc
held_item = null
@@ -305,7 +308,7 @@
return -1
if(held_item)
src << "\red You are already holding the [held_item]"
src << "\red You are already holding \the [held_item]"
return 1
var/list/items = list()
@@ -316,10 +319,18 @@
var/obj/selection = input("Select an item.", "Pickup") in items
if(selection)
held_item = selection
selection.loc = src
visible_message("\blue [src] scoops up the [held_item]!", "\blue You grab the [held_item]!", "You hear a skittering noise and a clink.")
return held_item
for(var/obj/item/I in view(1, src))
if(selection == I)
held_item = selection
selection.loc = src
visible_message("\blue [src] scoops up \the [held_item]!", "\blue You grab \the [held_item]!", "You hear a skittering noise and a clink.")
return held_item
src << "\red \The [selection] is too far away."
src << "\red There is nothing of interest to take."
return 0
return 0
/mob/living/simple_animal/spiderbot/examine()
..()
if(src.held_item)
usr << "It is carrying \a [src.held_item] \icon[src.held_item]."

View File

@@ -224,9 +224,11 @@
return "[emote], \"[text]\""
return "says, \"[text]\"";
/mob/living/simple_animal/emote(var/act)
/mob/living/simple_animal/emote(var/act, var/type, var/desc)
if(act)
if(act == "scream") act = "makes a loud and pained whimper" //ugly hack to stop animals screaming when crushed :P
if(act == "me") //Allow me-emotes.
act = desc
if( findtext(act,".",lentext(act)) == 0 && findtext(act,"!",lentext(act)) == 0 && findtext(act,"?",lentext(act)) == 0 )
act = addtext(act,".") //Makes sure all emotes end with a period.
for (var/mob/O in viewers(src, null))

View File

@@ -129,7 +129,10 @@
return
if(client.prefs.species != "Human")
if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist)
var/S = client.prefs.species
if(S == "Unathi") S = "Soghun"
if(!is_alien_whitelisted(src, S) && config.usealienwhitelist)
src << alert("You are currently not whitelisted to play [client.prefs.species].")
return 0
@@ -144,7 +147,9 @@
usr << "\blue There is an administrative lock on entering the game!"
return
if(!is_alien_whitelisted(src, client.prefs.species) && config.usealienwhitelist)
var/S = client.prefs.species
if(S == "Unathi") S = "Soghun"
if(!is_alien_whitelisted(src, S) && config.usealienwhitelist)
src << alert("You are currently not whitelisted to play [client.prefs.species].")
return 0
@@ -286,13 +291,9 @@
proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank)
if (ticker.current_state == GAME_STATE_PLAYING)
var/obj/item/device/radio/intercom/a = new /obj/item/device/radio/intercom(null)// BS12 EDIT Arrivals Announcement Computer, rather than the AI.
//unlikely for this to be an issue, but just in case
if(istype(character.wear_id, /obj/item/weapon/card/id))
var/obj/item/weapon/card/id/I = character.wear_id
a.autosay("\"[character.real_name],[I.assignment ? " [I.assignment]," : "" ] has arrived on the station.\"", "Arrivals Announcement Computer")
else
a.autosay("\"[character.real_name], visitor, has arrived on the station.\"", "Arrivals Announcement Computer")
if(character.mind.role_alt_title)
rank = character.mind.role_alt_title
a.autosay("[character.real_name],[rank ? " [rank]," : " visitor," ] has arrived on the station.", "Arrivals Announcement Computer")
del(a)
proc/LateChoices()
@@ -331,15 +332,15 @@
new_character.lastarea = get_area(loc)
if(client.prefs.species == "Tajaran") //This is like the worst, but it works, so meh. - Erthilo
if(is_alien_whitelisted(src, "Tajaran") || !config.usealienwhitelist)
if(is_alien_whitelisted(src, "Tajaran"|| !config.usealienwhitelist))
new_character.dna.mutantrace = "tajaran"
new_character.tajaran_talk_understand = 1
if(client.prefs.species == "Unathi")
if(is_alien_whitelisted(src, "Soghun") || !config.usealienwhitelist)
if(is_alien_whitelisted(src, "Soghun"|| !config.usealienwhitelist))
new_character.dna.mutantrace = "lizard"
new_character.soghun_talk_understand = 1
if(client.prefs.species == "Skrell")
if(is_alien_whitelisted(src, "Skrell") || !config.usealienwhitelist)
if(is_alien_whitelisted(src, "Skrell"|| !config.usealienwhitelist))
new_character.dna.mutantrace = "skrell"
new_character.skrell_talk_understand = 1

View File

@@ -135,37 +135,34 @@ datum/preferences
var/g = "m"
if(gender == FEMALE) g = "f"
if(species == "Tajaran")
preview_icon = new /icon('icons/effects/species.dmi', "tajaran_[g]_s")
preview_icon.Blend(new /icon('icons/effects/species.dmi', "tajtail_s"), ICON_OVERLAY)
else if(species == "Unathi")
preview_icon = new /icon('icons/effects/species.dmi', "lizard_[g]_s")
preview_icon.Blend(new /icon('icons/effects/species.dmi', "sogtail_s"), ICON_OVERLAY)
else if(species == "Skrell")
preview_icon = new /icon('icons/effects/species.dmi', "skrell_[g]_s")
else
preview_icon = new /icon('human.dmi', "torso_[g]_s")
preview_icon.Blend(new /icon('human.dmi', "chest_[g]_s"), ICON_OVERLAY)
var/icon/icobase
switch(species)
if("Tajaran")
icobase = 'icons/mob/human_races/r_tajaran.dmi'
if("Unathi")
icobase = 'icons/mob/human_races/r_lizard.dmi'
if("Skrell")
icobase = 'icons/mob/human_races/r_skrell.dmi'
else
icobase = 'icons/mob/human_races/r_human.dmi'
preview_icon = new /icon(icobase, "torso_[g]")
preview_icon.Blend(new /icon(icobase, "groin_[g]"), ICON_OVERLAY)
preview_icon.Blend(new /icon(icobase, "head_[g]"), ICON_OVERLAY)
if(organ_data["head"] != "amputated")
preview_icon.Blend(new /icon('human.dmi', "head_[g]_s"), ICON_OVERLAY)
for(var/name in list("l_arm","r_arm","l_leg","r_leg","l_foot","r_foot","l_hand","r_hand"))
// make sure the organ is added to the list so it's drawn
if(organ_data[name] == null)
organ_data[name] = null
for(var/name in list("l_arm","r_arm","l_leg","r_leg","l_foot","r_foot","l_hand","r_hand"))
// make sure the organ is added to the list so it's drawn
if(organ_data[name] == null)
organ_data[name] = null
for(var/name in organ_data)
if(organ_data[name] == "amputated") continue
for(var/name in organ_data)
if(organ_data[name] == "amputated") continue
var/icon/temp = new /icon(icobase, "[name]")
if(organ_data[name] == "cyborg")
temp.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
var/icon/temp = new /icon('human.dmi', "[name]_s")
if(organ_data[name] == "cyborg")
temp.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
preview_icon.Blend(temp, ICON_OVERLAY)
preview_icon.Blend(new /icon('human.dmi', "groin_[g]_s"), ICON_OVERLAY)
preview_icon.Blend(temp, ICON_OVERLAY)
// Skin tone
if(species == "Human")
@@ -302,7 +299,7 @@ datum/preferences
if(4)
clothes_s.Blend(new /icon('icons/mob/back.dmi', "satchel"), ICON_OVERLAY)
if(LAWYER)
clothes_s = new /icon('icons/mob/uniform.dmi', "lawyer_blue_s")
clothes_s = new /icon('icons/mob/uniform.dmi', "internalaffairs_s")
clothes_s.Blend(new /icon('icons/mob/feet.dmi', "brown"), ICON_UNDERLAY)
clothes_s.Blend(new /icon('icons/mob/items_righthand.dmi', "briefcase"), ICON_UNDERLAY)

View File

@@ -25,7 +25,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
for(var/datum/reagent/blood/B in vessel.reagent_list)
if(B.id == "blood")
B.data = list( "donor"=src,"viruses"=null,"blood_DNA"=dna.unique_enzymes,"blood_type"=dna.b_type, \
"resistances"=null,"trace_chem"=null, "virus2" = null, "antobodies" = null)
"resistances"=null,"trace_chem"=null, "virus2" = null, "antibodies" = null)
// Takes care blood loss and regeneration
/mob/living/carbon/human/proc/handle_blood()
@@ -165,7 +165,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
B.data["donor"] = src
if(src.virus2)
B.data["virus2"] = src.virus2.getcopy()
B.data["antibodies"] |= src.antibodies
B.data["antibodies"] = src.antibodies
B.data["blood_DNA"] = copytext(src.dna.unique_enzymes,1,0)
if(src.resistances && src.resistances.len)
if(B.data["resistances"])
@@ -176,8 +176,8 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
var/list/temp_chem = list()
for(var/datum/reagent/R in src.reagents.reagent_list)
temp_chem += R.name
temp_chem[R.name] = R.volume
temp_chem += R.id
temp_chem[R.id] = R.volume
B.data["trace_chem"] = list2params(temp_chem)
return B
@@ -197,9 +197,16 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
reagents.add_reagent("toxin",amount * 0.5)
reagents.update_total()
else
vessel.add_reagent("blood", amount)
vessel.add_reagent("blood", amount, injected.data)
vessel.update_total()
var/list/chems = list()
chems = params2list(injected.data["trace_chem"])
for(var/C in chems)
src.reagents.add_reagent(C, (text2num(chems[C]) / 560) * amount)//adds trace chemicals to owner's blood
//world << "added [(text2num(chems[C])/560) * amount] = [text2num(chems[C])]/560*[amount] units of [C] to [src]" //DEBUG
reagents.update_total()
container.reagents.remove_reagent("blood", amount)
//Gets human's own blood.

View File

@@ -277,10 +277,10 @@ var/list/solars_list = list()
var/cdir = 0
var/gen = 0
var/lastgen = 0
var/track = 0 // 0= off 1=timed 2=auto (tracker)
var/trackrate = 600 // 300-900 seconds
var/trackdir = 1 // 0 =CCW, 1=CW
var/nexttime = 0
var/track = 0 // 0=off 1=manual 2=automatic
var/trackrate = 60 // Measured in tenths of degree per minute (i.e. defaults to 6.0 deg/min)
var/trackdir = 1 // -1=CCW, 1=CW
var/nexttime = 0 // Next clock time that manual tracking will move the array
/obj/machinery/power/solar_control/New()
@@ -371,9 +371,11 @@ var/list/solars_list = list()
return
use_power(250)
if(track==1 && nexttime < world.timeofday && trackrate)
nexttime = world.timeofday + 3600/abs(trackrate)
cdir = (cdir+trackrate/abs(trackrate)+360)%360
if(track==1 && nexttime < world.time && trackdir*trackrate)
// Increments nexttime using itself and not world.time to prevent drift
nexttime = nexttime + 6000/trackrate
// Nudges array 1 degree in desired direction
cdir = (cdir+trackdir+360)%360
set_panels(cdir)
update_icon()
@@ -402,19 +404,28 @@ var/list/solars_list = list()
user.set_machine(src)
var/t = "<TT><B>Solar Generator Control</B><HR><PRE>"
t += "Generated power : [round(lastgen)] W<BR><BR>"
t += "<B>Orientation</B>: [rate_control(src,"cdir","[cdir]&deg",1,15)] ([angle2text(cdir)])<BR><BR><BR>"
t += "<BR><HR><BR><BR>"
t += "<B>Generated power</B> : [round(lastgen)] W<BR>"
t += "Station Rotational Period: [60/abs(sun.rate)] minutes<BR>"
t += "Station Rotational Direction: [sun.rate<0 ? "CCW" : "CW"]<BR>"
t += "Star Orientation: [sun.angle]&deg ([angle2text(sun.angle)])<BR>"
t += "Array Orientation: [rate_control(src,"cdir","[cdir]&deg",1,10,60)] ([angle2text(cdir)])<BR>"
t += "<BR><HR><BR>"
t += "Tracking: "
switch(track)
if(0)
t += "<B>Off</B> <A href='?src=\ref[src];track=1'>Timed</A> <A href='?src=\ref[src];track=2'>Auto</A><BR>"
t += "<B>Off</B> <A href='?src=\ref[src];track=1'>Manual</A> <A href='?src=\ref[src];track=2'>Automatic</A><BR>"
if(1)
t += "<A href='?src=\ref[src];track=0'>Off</A> <B>Timed</B> <A href='?src=\ref[src];track=2'>Auto</A><BR>"
t += "<A href='?src=\ref[src];track=0'>Off</A> <B>Manual</B> <A href='?src=\ref[src];track=2'>Automatic</A><BR>"
if(2)
t += "<A href='?src=\ref[src];track=0'>Off</A> <A href='?src=\ref[src];track=1'>Timed</A> <B>Auto</B><BR>"
t += "<A href='?src=\ref[src];track=0'>Off</A> <A href='?src=\ref[src];track=1'>Manual</A> <B>Automatic</B><BR>"
t += "Tracking Rate: [rate_control(src,"tdir","[trackrate] deg/h ([trackrate<0 ? "CCW" : "CW"])",5,30,180)]<BR><BR>"
t += "Manual Tracking Rate: [rate_control(src,"tdir","[trackrate/10]&deg/min ([trackdir<0 ? "CCW" : "CW"])",1,10)]<BR>"
t += "Manual Tracking Direction: "
switch(trackdir)
if(-1)
t += "<A href='?src=\ref[src];trackdir=1'>CW</A> <B>CCW</B><BR>"
if(1)
t += "<B>CW</B> <A href='?src=\ref[src];trackdir=-1'>CCW</A><BR>"
t += "<A href='?src=\ref[src];close=1'>Close</A></TT>"
user << browse(t, "window=solcon")
onclose(user, "solcon")
@@ -443,11 +454,11 @@ var/list/solars_list = list()
set_panels(cdir)
update_icon()
if(href_list["tdir"])
src.trackrate = dd_range(-7200,7200,src.trackrate+text2num(href_list["tdir"]))
if(src.trackrate) nexttime = world.timeofday + 3600/abs(trackrate)
src.trackrate = dd_range(0,360,src.trackrate+text2num(href_list["tdir"]))
if(src.trackrate) nexttime = world.time + 6000/trackrate
if(href_list["track"])
if(src.trackrate) nexttime = world.timeofday + 3600/abs(trackrate)
if(src.trackrate) nexttime = world.time + 6000/trackrate
track = text2num(href_list["track"])
if(powernet && (track == 2))
for(var/obj/machinery/power/tracker/T in get_solars_powernet())
@@ -455,6 +466,9 @@ var/list/solars_list = list()
cdir = T.sun_angle
break
if(href_list["trackdir"])
trackdir = text2num(href_list["trackdir"])
set_panels(cdir)
update_icon()
src.updateUsrDialog()

View File

@@ -340,6 +340,9 @@
P.pixel_y = rand(-7, 7)
P.icon_state = "pill"+pillsprite
reagents.trans_to(P,50)
if(src.loaded_pill_bottle)
P.loc = src.loaded_pill_bottle
src.updateUsrDialog()
else if (href_list["createbottle"])
if(!condi)
var/name = reject_bad_text(input(usr,"Name:","Name your bottle!",reagents.get_master_reagent_name()))

View File

@@ -103,7 +103,7 @@ datum
blood
data = new/list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null)
data = new/list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null, "antibodies" = null)
name = "Blood"
id = "blood"
reagent_state = LIQUID
@@ -122,11 +122,14 @@ datum
M.contract_disease(D)
else //injected
M.contract_disease(D, 1, 0)
if(self.data && self.data["virus2"])
if(self.data && self.data["virus2"] && istype(M, /mob/living/carbon))//infecting...
if(method == TOUCH)
infect_virus2(M,self.data["virus2"])
else
infect_virus2(M,self.data["virus2"],1)
if(self.data && self.data["antibodies"] && istype(M, /mob/living/carbon))//... and curing
var/mob/living/carbon/C = M
C.antibodies |= self.data["antibodies"]
@@ -500,6 +503,23 @@ datum
holder.remove_reagent(src.id, 0.5 * REAGENTS_METABOLISM)
return
holywater
name = "Holy Water"
id = "holywater"
description = "An ashen-obsidian-water mix, this solution will alter certain sections of the brain's rationality."
reagent_state = LIQUID
color = "#0064C8" // rgb: 0, 100, 200
on_mob_life(var/mob/living/M as mob)
if(ishuman(M))
if((M.mind in ticker.mode.cult) && prob(10))
M << "\blue A cooling sensation from inside you brings you an untold calmness."
ticker.mode.remove_cultist(M.mind)
for(var/mob/O in viewers(M, null))
O.show_message(text("\blue []'s eyes blink and become clearer.", M), 1) // So observers know it worked.
holder.remove_reagent(src.id, 10 * REAGENTS_METABOLISM) //high metabolism to prevent extended uncult rolls.
return
serotrotium
name = "Serotrotium"
id = "serotrotium"
@@ -1101,26 +1121,15 @@ datum
reagent_state = LIQUID
color = "#660000" // rgb: 102, 0, 0
//Commenting this out as it's horribly broken. It's a neat effect though, so it might be worth making a new reagent (that is less common) with similar effects. -Pete
/*
reaction_obj(var/obj/O, var/volume)
src = null
var/turf/the_turf = get_turf(O)
if(!the_turf)
return //No sense trying to start a fire if you don't have a turf to set on fire. --NEO
var/datum/gas_mixture/napalm = new
var/datum/gas/volatile_fuel/fuel = new
fuel.moles = 15
napalm.trace_gases += fuel
the_turf.assume_air(napalm)
new /obj/effect/decal/cleanable/liquid_fuel(the_turf, volume)
reaction_turf(var/turf/T, var/volume)
src = null
var/datum/gas_mixture/napalm = new
var/datum/gas/volatile_fuel/fuel = new
fuel.moles = 15
napalm.trace_gases += fuel
T.assume_air(napalm)
return*/
new /obj/effect/decal/cleanable/liquid_fuel(T, volume)
return
on_mob_life(var/mob/living/M as mob)
if(!M) M = holder.my_atom
M.adjustToxLoss(1)
@@ -1676,6 +1685,13 @@ datum
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
holywater
name = "Holy Water"
id = "holywater"
description = "A ubiquitous chemical substance that is composed of hydrogen and oxygen."
reagent_state = LIQUID
color = "#535E66" // rgb: 83, 94, 102
nanites
name = "Nanomachines"
id = "nanites"

View File

@@ -385,8 +385,10 @@ datum
for(var/turf/simulated/floor/target_tile in range(0,location))
var/datum/gas_mixture/napalm = new
var/datum/gas/volatile_fuel/fuel = new
fuel.moles = created_volume
napalm.trace_gases += fuel
napalm.toxins = created_volume*10
napalm.temperature = 400+T0C
napalm.update_values()

View File

@@ -11,10 +11,12 @@
var/slices_num
//Placeholder for effect that trigger on eating that aren't tied to reagents.
/obj/item/weapon/reagent_containers/food/snacks/proc/On_Consume()
/obj/item/weapon/reagent_containers/food/snacks/proc/On_Consume(var/mob/M)
if(!usr) return
if(!reagents.total_volume)
usr.visible_message("<span class='notice'>[usr] finishes eating [src].</span>","<span class='notice'>You finish eating [src].</span>")
if(M == usr)
usr << "<span class='notice'>You finish eating \the [src].</span>"
usr.visible_message("<span class='notice'>[usr] finishes eating \the [src].</span>")
usr.drop_from_inventory(src) //so icons update :[
if(trash)
@@ -90,7 +92,7 @@
else
reagents.trans_to(M, reagents.total_volume)
bitecount++
On_Consume()
On_Consume(M)
return 1
return 0

View File

@@ -158,7 +158,7 @@
update_icon()
if(mode == SYRINGE_BROKEN)
icon_state = "broken"
overlays = null //dirty fix
overlays.Cut()
return
var/rounded_vol = round(reagents.total_volume,5)
overlays.Cut()
@@ -207,15 +207,15 @@
if (target != user && target.getarmor(target_zone, "melee") > 5 && prob(50))
for(var/mob/O in viewers(world.view, user))
O.show_message(text("\red <B>[user] tries to stab [target] in the [hit_area] with [src.name], but the attack is deflected by armor!</B>"), 1)
O.show_message(text("\red <B>[user] tries to stab [target] in \the [hit_area] with [src.name], but the attack is deflected by armor!</B>"), 1)
user.u_equip(src)
del(src)
return
for(var/mob/O in viewers(world.view, user))
O.show_message(text("\red <B>[user] stabs [target] in the [hit_area] with [src.name]!</B>"), 1)
O.show_message(text("\red <B>[user] stabs [target] in \the [hit_area] with [src.name]!</B>"), 1)
if(affecting.take_damage(7))
if(affecting.take_damage(3))
target:UpdateDamageIcon()
else

View File

@@ -22,16 +22,20 @@
usr << "\blue [syringes.len] / [max_syringes] syringes."
attackby(obj/item/I as obj, mob/user as mob)
if(istype(I, /obj/item/weapon/reagent_containers/syringe))
if(syringes.len < max_syringes)
user.drop_item()
I.loc = src
syringes += I
user << "\blue You put the syringe in [src]."
user << "\blue [syringes.len] / [max_syringes] syringes."
var/obj/item/weapon/reagent_containers/syringe/S = I
if(S.mode != 2)//SYRINGE_BROKEN in syringes.dm
if(syringes.len < max_syringes)
user.drop_item()
I.loc = src
syringes += I
user << "\blue You put the syringe in [src]."
user << "\blue [syringes.len] / [max_syringes] syringes."
else
usr << "\red [src] cannot hold more syringes."
else
usr << "\red [src] cannot hold more syringes."
usr << "\red This syringe is broken!"
afterattack(obj/target, mob/user , flag)
if(!isturf(target.loc) || target == user) return

View File

@@ -1323,7 +1323,7 @@ datum/design/synthetic_flash
datum/design/nanopaste
name = "nanopaste"
desc = "A tube of paste containing swarms of repair nanties. Very effective in repairing robotic machinery."
desc = "A tube of paste containing swarms of repair nanites. Very effective in repairing robotic machinery."
id = "nanopaste"
req_tech = list("materials" = 4, "engineering" = 3)
build_type = PROTOLATHE

View File

@@ -33,19 +33,19 @@
return 0
//these three procs overriden to play different sounds
/obj/mecha/mechturn(direction)
/obj/mecha/working/hoverpod/mechturn(direction)
dir = direction
//playsound(src,'sound/machines/hiss.ogg',40,1)
return 1
/obj/mecha/mechstep(direction)
/obj/mecha/working/hoverpod/mechstep(direction)
var/result = step(src,direction)
if(result)
playsound(src,'sound/machines/hiss.ogg',40,1)
return result
/obj/mecha/mechsteprand()
/obj/mecha/working/hoverpod/mechsteprand()
var/result = step_rand(src)
if(result)
playsound(src,'sound/machines/hiss.ogg',40,1)

View File

@@ -1,3 +1,14 @@
//Handles how much the temperature changes on power use. (Joules/Kelvin)
//Equates to as much heat energy per kelvin as a quarter tile of air.
#define XENOARCH_HEAT_CAPACITY 5000
//Handles heat transfer to the air. (In watts)
//Can heat a single tile 2 degrees per tick.
#define XENOARCH_MAX_ENERGY_TRANSFER 4000
//How many joules of electrical energy produce how many joules of heat energy?
#define XENOARCH_HEAT_COEFFICIENT 10
/obj/machinery/anomaly
name = "Analysis machine"
@@ -6,13 +17,15 @@
density = 1
icon = 'icons/obj/virology.dmi'
icon_state = "analyser"
//
idle_power_usage = 20 //watts
active_power_usage = 300 //Because I need to make up numbers~
var/obj/item/weapon/reagent_containers/glass/held_container
var/obj/item/weapon/tank/fuel_container
var/target_scan_ticks = 60
var/report_num = 0
var/scan_process = 0
var/heat_accumulation_rate = 1
var/temperature = 273 //measured in kelvin, if this exceeds 1200, the machine is damaged and requires repairs
//if this exceeds 600 and safety is enabled it will shutdown
//temp greater than 600 also requires a safety prompt to initiate scanning
@@ -37,9 +50,6 @@
if(scan_process++ > target_scan_ticks)
FinishScan()
//heat up as we go, but if the air is freezing then heat up much slower
var/new_heat = heat_accumulation_rate + heat_accumulation_rate * rand(-5,5) / 10
temperature += new_heat
if(temperature > 350 && prob(10))
src.visible_message("\blue \icon[src] bleets plaintively.", 2)
if(temperature > 400)
@@ -49,26 +59,43 @@
if(prob(5))
src.visible_message("\blue \icon[src] [pick("whirrs","chuffs","clicks")][pick(" quietly"," softly"," sadly"," excitedly"," energetically"," angrily"," plaintively")].", 2)
else if(temperature > environmental_temp)
use_power = 2
else
use_power = 1
auto_use_power()
//Add 200 joules when idle, or 3000 when active. This is about 0.6 degrees per tick.
//May need adjustment
var/heat_added = ( use_power == 1 ? active_power_usage : idle_power_usage )*XENOARCH_HEAT_COEFFICIENT
temperature += heat_added/XENOARCH_HEAT_CAPACITY
var/temperature_difference = abs(environmental_temp-temperature)
var/datum/gas_mixture/removed = loc.remove_air(env.total_moles*0.25)
var/heat_capacity = removed.heat_capacity()
heat_added = max(temperature_difference*heat_capacity, XENOARCH_MAX_ENERGY_TRANSFER)
if(temperature > environmental_temp)
//cool down to match the air
temperature -= heat_accumulation_rate + heat_accumulation_rate * rand(-5,5) / 10
if(temperature < environmental_temp)
temperature = environmental_temp
if(prob(5))
temperature = max(TCMB, temperature - heat_added/XENOARCH_HEAT_CAPACITY)
removed.temperature = max(TCMB, removed.temperature + heat_added/heat_capacity)
if(temperature_difference > 10 && prob(5))
src.visible_message("\blue \icon[src] hisses softly.", 2)
else if(temperature < environmental_temp)
else
//heat up to match the air
temperature += heat_accumulation_rate + rand(-5,5) / 10
if(temperature > environmental_temp)
temperature = environmental_temp
else
if(prob(5))
src.visible_message("\blue \icon[src] plinks quietly.", 2)
temperature = max(TCMB, temperature + heat_added/XENOARCH_HEAT_CAPACITY)
removed.temperature = max(TCMB, removed.temperature - heat_added/heat_capacity)
if(temperature_difference > 10 && prob(5))
src.visible_message("\blue \icon[src] plinks quietly.", 2)
env.merge(removed)
//warm up the lab slightly
if(env.temperature < temperature)
env.temperature += (temperature - env.temperature) * 0.1
//this proc should be overriden by each individual machine
/obj/machinery/anomaly/attack_hand(var/mob/user as mob)

View File

@@ -312,7 +312,7 @@
the the denser clumps of matter out of the refined sample. This is done by mixing 1 part lithium, 2 parts sodium, 1 part tungsten, 4 parts oxygen.</li>
<li><b>Mix separator with sample</b> - The resulting mixture is very close to the final product, but make sure to extract any leftover reagents and
the chemical waste byproduct.</li>
<li><b>Bring sample to boil</b> - Using a standard bunsen burner, bring the mixture to a boil to vaporise the remaining unwanted matter. Remember
<li><b>Bring sample to boil</b> - Using a standard bunsen burner, bring the mixture containing at least 5u of DST to a boil to vaporise the remaining unwanted matter. Remember
to again clear out any waste byproducts.</li>
</list><br>
<a href="#Contents">Contents</a>
@@ -411,3 +411,65 @@
</body>
</html>
"}
/obj/item/weapon/book/manual/stasis
name = "Cellular suspension, the new Cryogenics?"
icon_state = "stasis"
author = "Elvin Schmidt"
title = "Cellular suspension, the new Cryogenics?"
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>
<h1><a name="Contents">Contents</a></h1>
<ol>
<li><a href="#Forward">Forward: A replacement for cryosleep?</a></li>
<li><a href="#Development">The breakthrough</a></li>
<li><a href="#Application">Applying this new principle</a></li>
</ol>
<br>
<h1><a name="Forward">Forward: A replacement for cryosleep?</a></h1>
The development of rudimentary cryofreezing in the 20th and 21st centuries was hailed as a crank science by some, but many early visionaries recognised the
potential it had to change the way we approach so many fields, such as medicine, therapeutics and space travel. It was breakthroughs in the field in the 22nd and
later centures that turned the procedure from science fiction to science fact, however. Since then, cryogenics has become a hallmark of modern science, and
regarded as one of the great achievements of our era. As with all sciences however, they have their time and are superseded by newer technological miracles when
it is over.<br>
<a href="#Contents">Contents</a>
<h1><a name="Development">The breakthrough</a></h1>
It was in examining the effects of decellerated, blue-space high energy particles when transphased through bluespace that the effects where primarily noticed.
Due to exigent properties of that dimension, transphasing those particles capable of existing in bluespace with high stability levels has the effect of bringing
some of those effects into realspace. Examining the Hoffman emissions in particular, it was discovered that they exhibited a-entropic behaviour, and in what is
now termed the 'Effete Hoffman Principle,' it was found that metastabilising the Hoffman radiation resulted in the effect being applied across other physical
interactions, in particular forces and reactions.<br>
<a href="#Contents">Contents</a>
<h1><a name="Application">Applying this new principle</a></h1>
When combined with an appropriate energy-effect replicate for cryogenics (slowing down biological activity, thus stabilising the organics), the effect is
effectively identical to cryogenics, and while it consumes vastly more power and requires extremely complex equipment, it's (for all intents and purposes) superior
to cryogenics, all that remains is to 'commercialise' the process by enabling cheaper development and mass production.<br>
The Effete Hoffman Principle can be tweak-combined with other effects however, for different purposes. A division of PMC Research initially developed the application
in prisons as a literal 'suspension field' where convincts are held immobile in the air, and the use quickly spread to numerous other areas.<br>
<br>
By examining the material resonance properties of certain strong waveforms when combined with Hoffman radiation, an effect was produced able to reverse energy
transferral through matter, and to slow the effects of gravity. When combined with energy repulse technology, the triple effects compound themselves into a much
stronger field, although all three componenets do slightly different things. High energy researchers assure me of the following key points:<br>
<ol>
<li>The energy repulsion factor provides a 'shell' capable of weak suspension.</li>
<li>The Hoffman emissions nullify energy transferral and other kinetic activity, maintaining stability inside the field.</li>
<li>The resonant waveform combines the effects of the above two points, and applies it magnified onto it's synched 'resonance' materials.</li>
</ol>
As an interesting aside, a carbon waveform was chosen for the field in prison suspension fields, due to it's resonance with organic matter.<br>
<a href="#Contents">Contents</a>
</body>
</html>
"}

View File

@@ -53,6 +53,7 @@
new /obj/item/weapon/book/manual/materials_chemistry_analysis(src)
new /obj/item/weapon/book/manual/anomaly_testing(src)
new /obj/item/weapon/book/manual/anomaly_spectroscopy(src)
new /obj/item/weapon/book/manual/stasis(src)
update_icon()
//---- Lockers and closets
@@ -82,6 +83,8 @@
/obj/structure/closet/excavation
name = "Excavation tools"
icon_state = "toolcloset"
icon_closed = "toolcloset"
icon_opened = "toolclosetopen"
New()
..()
@@ -96,10 +99,11 @@
new /obj/item/device/radio/beacon(src)
new /obj/item/clothing/glasses/meson(src)
new /obj/item/weapon/pickaxe(src)
new /obj/item/device/measuring_tape(src)
return
//---- Isolation room air alarms
/obj/machinery/alarm/isolation
name = "Isolation room air control"
req_access = list(access_research)
req_access = list(access_research)

View File

@@ -82,13 +82,14 @@
dat += "<hr>"
if(!locked)
dat += "<b>Select field mode</b><br>"
dat += "[field_type=="carbon"?"<b>":"" ]<A href='?src=\ref[src];select_field=carbon'>Diffracted CO2 laser</A></b><br>"
dat += "[field_type=="carbon"?"<b>":"" ]<A href='?src=\ref[src];select_field=carbon'>Diffracted carbon dioxide laser</A></b><br>"
dat += "[field_type=="nitrogen"?"<b>":"" ]<A href='?src=\ref[src];select_field=nitrogen'>Nitrogen tracer field</A></b><br>"
dat += "[field_type=="potassium"?"<b>":"" ]<A href='?src=\ref[src];select_field=potassium'>Potassium refrigerant cloud</A></b><br>"
dat += "[field_type=="mercury"?"<b>":"" ]<A href='?src=\ref[src];select_field=mercury'>Mercury dispersion wave</A></b><br>"
dat += "[field_type=="iron"?"<b>":"" ]<A href='?src=\ref[src];select_field=iron'>Iron wafer conduction field</A></b><br>"
dat += "[field_type=="calcium"?"<b>":"" ]<A href='?src=\ref[src];select_field=calcium'>Calcium binary deoxidiser</A></b><br>"
dat += "[field_type=="plasma"?"<b>":"" ]<A href='?src=\ref[src];select_field=chlorine'>Plasma saturated field</A></b><br>"
dat += "[field_type=="plasma"?"<b>":"" ]<A href='?src=\ref[src];select_field=chlorine'>Chlorine diffusion emissions</A></b><br>"
dat += "[field_type=="plasma"?"<b>":"" ]<A href='?src=\ref[src];select_field=plasma'>Plasma saturated field</A></b><br>"
else
dat += "<br>"
dat += "<br>"
@@ -260,6 +261,9 @@
if("plasma")
success = 1
//
if("calcium")
success = 1
//
if("iron")
success = 1
for(var/mob/living/silicon/R in T)

View File

@@ -72,6 +72,7 @@
excavation_amount = 5
drill_sound = 'sound/items/Screwdriver.ogg'
drill_verb = "delicately picking"
w_class = 2
/obj/item/weapon/pickaxe/six_pick
name = "1/1 pick"
@@ -118,6 +119,7 @@
"/obj/item/weapon/pickaxe/six_pick",\
"/obj/item/weapon/pickaxe/hand")
max_combined_w_class = 20
max_w_class = 4
use_to_pickup = 1 // for picking up broken bulbs, not that most people will try
/obj/item/weapon/storage/box/excavation/New()

View File

@@ -122,6 +122,7 @@
//Plasma fire properties
#define PLASMA_MINIMUM_BURN_TEMPERATURE 100+T0C
#define PLASMA_FLASHPOINT 246+T0C
#define PLASMA_UPPER_TEMPERATURE 1370+T0C
#define PLASMA_MINIMUM_OXYGEN_NEEDED 2
#define PLASMA_MINIMUM_OXYGEN_PLASMA_RATIO 20

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