mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-14 16:44:33 +01:00
Merge branch 'bleeding-edge-freeze' into organ
Conflicts: html/changelog.html
This commit is contained in:
@@ -8,62 +8,60 @@
|
||||
icon_state = "circ-off"
|
||||
anchored = 0
|
||||
|
||||
//var/side = 1 // 1=left 2=right
|
||||
var/status = 0
|
||||
|
||||
var/recent_moles_transferred = 0
|
||||
var/last_heat_capacity = 0
|
||||
var/last_temperature = 0
|
||||
var/last_pressure_delta = 0
|
||||
var/last_worldtime_transfer = 0
|
||||
|
||||
density = 1
|
||||
|
||||
/obj/machinery/atmospherics/binary/circulator/New()
|
||||
..()
|
||||
desc = initial(desc) + " Its outlet port is to the [dir2text(dir)]."
|
||||
desc = initial(desc) + " Its outlet port is to the [dir2text(dir)]."
|
||||
|
||||
/obj/machinery/atmospherics/binary/circulator/proc/return_transfer_air()
|
||||
if(!anchored)
|
||||
return null
|
||||
var/datum/gas_mixture/removed
|
||||
if(anchored && !(stat&BROKEN) )
|
||||
var/input_starting_pressure = air1.return_pressure()
|
||||
var/output_starting_pressure = air2.return_pressure()
|
||||
last_pressure_delta = max(input_starting_pressure - output_starting_pressure + 10, 0)
|
||||
|
||||
var/output_starting_pressure = air2.return_pressure()
|
||||
var/input_starting_pressure = air1.return_pressure()
|
||||
//only circulate air if there is a pressure difference (plus 10 kPa to represent friction in the machine)
|
||||
if(air1.temperature > 0 && last_pressure_delta > 0)
|
||||
|
||||
if(output_starting_pressure >= input_starting_pressure-10)
|
||||
//Need at least 10 KPa difference to overcome friction in the mechanism
|
||||
last_pressure_delta = 0
|
||||
return null
|
||||
//Calculate necessary moles to transfer using PV = nRT
|
||||
recent_moles_transferred = last_pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
//Calculate necessary moles to transfer using PV = nRT
|
||||
if(air1.temperature>0)
|
||||
var/pressure_delta = (input_starting_pressure - output_starting_pressure)/2
|
||||
//Actually transfer the gas
|
||||
removed = air1.remove(recent_moles_transferred)
|
||||
if(removed)
|
||||
last_heat_capacity = removed.heat_capacity()
|
||||
last_temperature = removed.temperature
|
||||
|
||||
var/transfer_moles = pressure_delta*air2.volume/(air1.temperature * R_IDEAL_GAS_EQUATION)
|
||||
//Update the gas networks.
|
||||
if(network1)
|
||||
network1.update = 1
|
||||
|
||||
last_pressure_delta = pressure_delta
|
||||
|
||||
//world << "pressure_delta = [pressure_delta]; transfer_moles = [transfer_moles];"
|
||||
|
||||
//Actually transfer the gas
|
||||
var/datum/gas_mixture/removed = air1.remove(transfer_moles)
|
||||
|
||||
if(network1)
|
||||
network1.update = 1
|
||||
|
||||
if(network2)
|
||||
network2.update = 1
|
||||
last_worldtime_transfer = world.time
|
||||
else
|
||||
recent_moles_transferred = 0
|
||||
|
||||
update_icon()
|
||||
return removed
|
||||
|
||||
else
|
||||
last_pressure_delta = 0
|
||||
|
||||
/obj/machinery/atmospherics/binary/circulator/process()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
if(last_worldtime_transfer < world.time - 50)
|
||||
recent_moles_transferred = 0
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/binary/circulator/update_icon()
|
||||
if(stat & (BROKEN|NOPOWER) || !anchored)
|
||||
icon_state = "circ-p"
|
||||
else if(last_pressure_delta > 0)
|
||||
if(last_pressure_delta > ONE_ATMOSPHERE)
|
||||
else if(last_pressure_delta > 0 && recent_moles_transferred > 0)
|
||||
if(last_pressure_delta > 5*ONE_ATMOSPHERE)
|
||||
icon_state = "circ-run"
|
||||
else
|
||||
icon_state = "circ-slow"
|
||||
@@ -105,9 +103,9 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/binary/circulator/verb/rotate()
|
||||
/obj/machinery/atmospherics/binary/circulator/verb/rotate_clockwise()
|
||||
set category = "Object"
|
||||
set name = "Rotate Circulator"
|
||||
set name = "Rotate Circulator (Clockwise)"
|
||||
set src in view(1)
|
||||
|
||||
if (usr.stat || usr.restrained() || anchored)
|
||||
@@ -115,3 +113,15 @@
|
||||
|
||||
src.dir = turn(src.dir, 90)
|
||||
desc = initial(desc) + " Its outlet port is to the [dir2text(dir)]."
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/binary/circulator/verb/rotate_anticlockwise()
|
||||
set category = "Object"
|
||||
set name = "Rotate Circulator (Counterclockwise)"
|
||||
set src in view(1)
|
||||
|
||||
if (usr.stat || usr.restrained() || anchored)
|
||||
return
|
||||
|
||||
src.dir = turn(src.dir, -90)
|
||||
desc = initial(desc) + " Its outlet port is to the [dir2text(dir)]."
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -101,7 +101,11 @@
|
||||
if("change_code")
|
||||
var/attempt_code = input("Re-enter the current EFTPOS access code", "Confirm old EFTPOS code") as num
|
||||
if(attempt_code == access_code)
|
||||
access_code = input("Enter a new access code for this device", "Enter new EFTPOS code") as num
|
||||
var/trycode = input("Enter a new access code for this device (4-6 digits, numbers only)", "Enter new EFTPOS code") as num
|
||||
if(trycode >= 1000 && trycode <= 999999)
|
||||
access_code = trycode
|
||||
else
|
||||
alert("That is not a valid code!")
|
||||
print_reference()
|
||||
else
|
||||
usr << "\icon[src]<span class='warning'>Incorrect code entered.</span>"
|
||||
@@ -124,7 +128,11 @@
|
||||
if("trans_purpose")
|
||||
transaction_purpose = input("Enter reason for EFTPOS transaction", "Transaction purpose")
|
||||
if("trans_value")
|
||||
transaction_amount = input("Enter amount for EFTPOS transaction", "Transaction amount") as num
|
||||
var/try_num = input("Enter amount for EFTPOS transaction", "Transaction amount") as num
|
||||
if(try_num < 0)
|
||||
alert("That is not a valid amount!")
|
||||
else
|
||||
transaction_amount = try_num
|
||||
if("toggle_lock")
|
||||
if(transaction_locked)
|
||||
var/attempt_code = input("Enter EFTPOS access code", "Reset Transaction") as num
|
||||
@@ -199,11 +207,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
|
||||
..()
|
||||
|
||||
|
||||
@@ -130,207 +130,202 @@
|
||||
desc = "a mysterious and ancient piece of machinery"
|
||||
var/list/animal_spawners = list()
|
||||
|
||||
New()
|
||||
..()
|
||||
Initialise()
|
||||
|
||||
/obj/machinery/jungle_controller/proc/Initialise()
|
||||
set background = 1
|
||||
spawn(0)
|
||||
world << "\red \b Setting up jungle, this may take a moment..."
|
||||
/obj/machinery/jungle_controller/initialize()
|
||||
world << "\red \b Setting up jungle, this may take a bleeding eternity..."
|
||||
|
||||
//crash dat shuttle
|
||||
var/area/start_location = locate(/area/jungle/crash_ship_source)
|
||||
var/area/clean_location = locate(/area/jungle/crash_ship_clean)
|
||||
var/list/ship_locations = list(/area/jungle/crash_ship_one, /area/jungle/crash_ship_two, /area/jungle/crash_ship_three, /area/jungle/crash_ship_four)
|
||||
var/area/end_location = locate( pick(ship_locations) )
|
||||
ship_locations -= end_location.type
|
||||
//crash dat shuttle
|
||||
var/area/start_location = locate(/area/jungle/crash_ship_source)
|
||||
var/area/clean_location = locate(/area/jungle/crash_ship_clean)
|
||||
var/list/ship_locations = list(/area/jungle/crash_ship_one, /area/jungle/crash_ship_two, /area/jungle/crash_ship_three, /area/jungle/crash_ship_four)
|
||||
var/area/end_location = locate( pick(ship_locations) )
|
||||
ship_locations -= end_location.type
|
||||
|
||||
start_location.move_contents_to(end_location)
|
||||
for(var/area_type in ship_locations)
|
||||
var/area/cur_location = locate(area_type)
|
||||
clean_location.copy_turfs_to(cur_location)
|
||||
start_location.move_contents_to(end_location)
|
||||
for(var/area_type in ship_locations)
|
||||
var/area/cur_location = locate(area_type)
|
||||
clean_location.copy_turfs_to(cur_location)
|
||||
|
||||
//drop some random river nodes
|
||||
var/list/river_nodes = list()
|
||||
var/max = rand(1,3)
|
||||
var/num_spawned = 0
|
||||
while(num_spawned < max)
|
||||
var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
|
||||
if(!istype(J))
|
||||
continue
|
||||
if(!J.bushes_spawn)
|
||||
continue
|
||||
river_nodes.Add(new /obj/effect/landmark/river_waypoint(J))
|
||||
num_spawned++
|
||||
//drop some random river nodes
|
||||
var/list/river_nodes = list()
|
||||
var/max = rand(1,3)
|
||||
var/num_spawned = 0
|
||||
while(num_spawned < max)
|
||||
var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
|
||||
if(!istype(J))
|
||||
continue
|
||||
if(!J.bushes_spawn)
|
||||
continue
|
||||
river_nodes.Add(new /obj/effect/landmark/river_waypoint(J))
|
||||
num_spawned++
|
||||
|
||||
//make some randomly pathing rivers
|
||||
for(var/obj/effect/landmark/river_waypoint/W in world)
|
||||
if (W.z != src.z || W.connected)
|
||||
continue
|
||||
//make some randomly pathing rivers
|
||||
for(var/obj/effect/landmark/river_waypoint/W in world)
|
||||
if (W.z != src.z || W.connected)
|
||||
continue
|
||||
|
||||
W.connected = 1
|
||||
var/turf/cur_turf = new /turf/unsimulated/jungle/water(get_turf(W))
|
||||
var/turf/target_turf = get_turf(pick(river_nodes))
|
||||
W.connected = 1
|
||||
var/turf/cur_turf = new /turf/unsimulated/jungle/water(get_turf(W))
|
||||
var/turf/target_turf = get_turf(pick(river_nodes))
|
||||
|
||||
var/detouring = 0
|
||||
var/cur_dir = get_dir(cur_turf, target_turf)
|
||||
//
|
||||
while(cur_turf != target_turf)
|
||||
//randomly snake around a bit
|
||||
if(detouring)
|
||||
if(prob(20))
|
||||
detouring = 0
|
||||
cur_dir = get_dir(cur_turf, target_turf)
|
||||
else if(prob(20))
|
||||
detouring = 1
|
||||
if(prob(50))
|
||||
cur_dir = turn(cur_dir, 45)
|
||||
else
|
||||
cur_dir = turn(cur_dir, -45)
|
||||
else
|
||||
cur_dir = get_dir(cur_turf, target_turf)
|
||||
|
||||
cur_turf = get_step(cur_turf, cur_dir)
|
||||
|
||||
var/skip = 0
|
||||
if(!istype(cur_turf, /turf/unsimulated/jungle) || istype(cur_turf, /turf/unsimulated/jungle/rock))
|
||||
var/detouring = 0
|
||||
var/cur_dir = get_dir(cur_turf, target_turf)
|
||||
//
|
||||
while(cur_turf != target_turf)
|
||||
//randomly snake around a bit
|
||||
if(detouring)
|
||||
if(prob(20))
|
||||
detouring = 0
|
||||
cur_dir = get_dir(cur_turf, target_turf)
|
||||
cur_turf = get_step(cur_turf, cur_dir)
|
||||
continue
|
||||
|
||||
if(!skip)
|
||||
var/turf/unsimulated/jungle/water/water_turf = new(cur_turf)
|
||||
water_turf.Spread(75, rand(65, 25))
|
||||
|
||||
var/list/path_nodes = list()
|
||||
|
||||
//place some ladders leading down to pre-generated temples
|
||||
max = rand(2,5)
|
||||
num_spawned = 0
|
||||
while(num_spawned < max)
|
||||
var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
|
||||
if(!J || !J.bushes_spawn)
|
||||
continue
|
||||
new /obj/effect/landmark/temple(J)
|
||||
path_nodes.Add(new /obj/effect/landmark/path_waypoint(J))
|
||||
num_spawned++
|
||||
|
||||
//put a native tribe somewhere
|
||||
num_spawned = 0
|
||||
while(num_spawned < 1)
|
||||
var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
|
||||
if(!J || !J.bushes_spawn)
|
||||
continue
|
||||
new /obj/effect/jungle_tribe_spawn(J)
|
||||
path_nodes.Add(new /obj/effect/landmark/path_waypoint(J))
|
||||
num_spawned++
|
||||
|
||||
//place some random path waypoints to confuse players
|
||||
max = rand(1,3)
|
||||
num_spawned = 0
|
||||
while(num_spawned < max)
|
||||
var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
|
||||
if(!J || !J.bushes_spawn)
|
||||
continue
|
||||
path_nodes.Add(new /obj/effect/landmark/path_waypoint(J))
|
||||
num_spawned++
|
||||
|
||||
//get any path nodes placed on the map
|
||||
for(var/obj/effect/landmark/path_waypoint/W in world)
|
||||
if (W.z == src.z)
|
||||
path_nodes.Add(W)
|
||||
|
||||
//make random, connecting paths
|
||||
for(var/obj/effect/landmark/path_waypoint/W in path_nodes)
|
||||
if (W.connected)
|
||||
continue
|
||||
|
||||
W.connected = 1
|
||||
var/turf/cur_turf = get_turf(W)
|
||||
path_nodes.Remove(W)
|
||||
var/turf/target_turf = get_turf(pick(path_nodes))
|
||||
path_nodes.Add(W)
|
||||
//
|
||||
cur_turf = new /turf/unsimulated/jungle/path(cur_turf)
|
||||
|
||||
var/detouring = 0
|
||||
var/cur_dir = get_dir(cur_turf, target_turf)
|
||||
//
|
||||
while(cur_turf != target_turf)
|
||||
//randomly snake around a bit
|
||||
if(detouring)
|
||||
if(prob(20) || get_dist(cur_turf, target_turf) < 5)
|
||||
detouring = 0
|
||||
cur_dir = get_dir(cur_turf, target_turf)
|
||||
else if(prob(20) && get_dist(cur_turf, target_turf) > 5)
|
||||
detouring = 1
|
||||
if(prob(50))
|
||||
cur_dir = turn(cur_dir, 45)
|
||||
else
|
||||
cur_dir = turn(cur_dir, -45)
|
||||
else if(prob(20))
|
||||
detouring = 1
|
||||
if(prob(50))
|
||||
cur_dir = turn(cur_dir, 45)
|
||||
else
|
||||
cur_dir = get_dir(cur_turf, target_turf)
|
||||
cur_dir = turn(cur_dir, -45)
|
||||
else
|
||||
cur_dir = get_dir(cur_turf, target_turf)
|
||||
|
||||
//move a step forward
|
||||
cur_turf = get_step(cur_turf, cur_dir)
|
||||
|
||||
var/skip = 0
|
||||
if(!istype(cur_turf, /turf/unsimulated/jungle) || istype(cur_turf, /turf/unsimulated/jungle/rock))
|
||||
detouring = 0
|
||||
cur_dir = get_dir(cur_turf, target_turf)
|
||||
cur_turf = get_step(cur_turf, cur_dir)
|
||||
continue
|
||||
|
||||
//if we're not a jungle turf, get back to what we were doing
|
||||
if(!istype(cur_turf, /turf/unsimulated/jungle/))
|
||||
if(!skip)
|
||||
var/turf/unsimulated/jungle/water/water_turf = new(cur_turf)
|
||||
water_turf.Spread(75, rand(65, 25))
|
||||
|
||||
var/list/path_nodes = list()
|
||||
|
||||
//place some ladders leading down to pre-generated temples
|
||||
max = rand(2,5)
|
||||
num_spawned = 0
|
||||
while(num_spawned < max)
|
||||
var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
|
||||
if(!J || !J.bushes_spawn)
|
||||
continue
|
||||
new /obj/effect/landmark/temple(J)
|
||||
path_nodes.Add(new /obj/effect/landmark/path_waypoint(J))
|
||||
num_spawned++
|
||||
|
||||
//put a native tribe somewhere
|
||||
num_spawned = 0
|
||||
while(num_spawned < 1)
|
||||
var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
|
||||
if(!J || !J.bushes_spawn)
|
||||
continue
|
||||
new /obj/effect/jungle_tribe_spawn(J)
|
||||
path_nodes.Add(new /obj/effect/landmark/path_waypoint(J))
|
||||
num_spawned++
|
||||
|
||||
//place some random path waypoints to confuse players
|
||||
max = rand(1,3)
|
||||
num_spawned = 0
|
||||
while(num_spawned < max)
|
||||
var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
|
||||
if(!J || !J.bushes_spawn)
|
||||
continue
|
||||
path_nodes.Add(new /obj/effect/landmark/path_waypoint(J))
|
||||
num_spawned++
|
||||
|
||||
//get any path nodes placed on the map
|
||||
for(var/obj/effect/landmark/path_waypoint/W in world)
|
||||
if (W.z == src.z)
|
||||
path_nodes.Add(W)
|
||||
|
||||
//make random, connecting paths
|
||||
for(var/obj/effect/landmark/path_waypoint/W in path_nodes)
|
||||
if (W.connected)
|
||||
continue
|
||||
|
||||
W.connected = 1
|
||||
var/turf/cur_turf = get_turf(W)
|
||||
path_nodes.Remove(W)
|
||||
var/turf/target_turf = get_turf(pick(path_nodes))
|
||||
path_nodes.Add(W)
|
||||
//
|
||||
cur_turf = new /turf/unsimulated/jungle/path(cur_turf)
|
||||
|
||||
var/detouring = 0
|
||||
var/cur_dir = get_dir(cur_turf, target_turf)
|
||||
//
|
||||
while(cur_turf != target_turf)
|
||||
//randomly snake around a bit
|
||||
if(detouring)
|
||||
if(prob(20) || get_dist(cur_turf, target_turf) < 5)
|
||||
detouring = 0
|
||||
cur_dir = get_dir(cur_turf, target_turf)
|
||||
cur_turf = get_step(cur_turf, cur_dir)
|
||||
continue
|
||||
else if(prob(20) && get_dist(cur_turf, target_turf) > 5)
|
||||
detouring = 1
|
||||
if(prob(50))
|
||||
cur_dir = turn(cur_dir, 45)
|
||||
else
|
||||
cur_dir = turn(cur_dir, -45)
|
||||
else
|
||||
cur_dir = get_dir(cur_turf, target_turf)
|
||||
|
||||
var/turf/unsimulated/jungle/J = cur_turf
|
||||
if(istype(J, /turf/unsimulated/jungle/impenetrable) || istype(J, /turf/unsimulated/jungle/water/deep))
|
||||
cur_dir = get_dir(cur_turf, target_turf)
|
||||
cur_turf = get_step(cur_turf, cur_dir)
|
||||
continue
|
||||
//move a step forward
|
||||
cur_turf = get_step(cur_turf, cur_dir)
|
||||
|
||||
if(!istype(J, /turf/unsimulated/jungle/water))
|
||||
J = new /turf/unsimulated/jungle/path(cur_turf)
|
||||
J.Spread(PATH_SPREAD_CHANCE_START, rand(PATH_SPREAD_CHANCE_LOSS_UPPER, PATH_SPREAD_CHANCE_LOSS_LOWER))
|
||||
|
||||
//create monkey spawners
|
||||
num_spawned = 0
|
||||
max = rand(3,6)
|
||||
while(num_spawned < max)
|
||||
var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
|
||||
if(!J || !J.bushes_spawn)
|
||||
//if we're not a jungle turf, get back to what we were doing
|
||||
if(!istype(cur_turf, /turf/unsimulated/jungle/))
|
||||
cur_dir = get_dir(cur_turf, target_turf)
|
||||
cur_turf = get_step(cur_turf, cur_dir)
|
||||
continue
|
||||
animal_spawners.Add(new /obj/effect/landmark/animal_spawner/monkey(J))
|
||||
num_spawned++
|
||||
|
||||
//create panther spawners
|
||||
num_spawned = 0
|
||||
max = rand(6,12)
|
||||
while(num_spawned < max)
|
||||
var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
|
||||
if(!J || !istype(J) || !J.bushes_spawn)
|
||||
var/turf/unsimulated/jungle/J = cur_turf
|
||||
if(istype(J, /turf/unsimulated/jungle/impenetrable) || istype(J, /turf/unsimulated/jungle/water/deep))
|
||||
cur_dir = get_dir(cur_turf, target_turf)
|
||||
cur_turf = get_step(cur_turf, cur_dir)
|
||||
continue
|
||||
animal_spawners.Add(new /obj/effect/landmark/animal_spawner/panther(J))
|
||||
num_spawned++
|
||||
|
||||
//create snake spawners
|
||||
num_spawned = 0
|
||||
max = rand(6,12)
|
||||
while(num_spawned < max)
|
||||
var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
|
||||
if(!J || !istype(J) || !J.bushes_spawn)
|
||||
continue
|
||||
animal_spawners.Add(new /obj/effect/landmark/animal_spawner/snake(J))
|
||||
num_spawned++
|
||||
if(!istype(J, /turf/unsimulated/jungle/water))
|
||||
J = new /turf/unsimulated/jungle/path(cur_turf)
|
||||
J.Spread(PATH_SPREAD_CHANCE_START, rand(PATH_SPREAD_CHANCE_LOSS_UPPER, PATH_SPREAD_CHANCE_LOSS_LOWER))
|
||||
|
||||
//create parrot spawners
|
||||
num_spawned = 0
|
||||
max = rand(3,6)
|
||||
while(num_spawned < max)
|
||||
var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
|
||||
if(!J || !istype(J) || !J.bushes_spawn)
|
||||
continue
|
||||
animal_spawners.Add(new /obj/effect/landmark/animal_spawner/parrot(J))
|
||||
num_spawned++
|
||||
//create monkey spawners
|
||||
num_spawned = 0
|
||||
max = rand(3,6)
|
||||
while(num_spawned < max)
|
||||
var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
|
||||
if(!J || !J.bushes_spawn)
|
||||
continue
|
||||
animal_spawners.Add(new /obj/effect/landmark/animal_spawner/monkey(J))
|
||||
num_spawned++
|
||||
|
||||
//create panther spawners
|
||||
num_spawned = 0
|
||||
max = rand(6,12)
|
||||
while(num_spawned < max)
|
||||
var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
|
||||
if(!J || !istype(J) || !J.bushes_spawn)
|
||||
continue
|
||||
animal_spawners.Add(new /obj/effect/landmark/animal_spawner/panther(J))
|
||||
num_spawned++
|
||||
|
||||
//create snake spawners
|
||||
num_spawned = 0
|
||||
max = rand(6,12)
|
||||
while(num_spawned < max)
|
||||
var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
|
||||
if(!J || !istype(J) || !J.bushes_spawn)
|
||||
continue
|
||||
animal_spawners.Add(new /obj/effect/landmark/animal_spawner/snake(J))
|
||||
num_spawned++
|
||||
|
||||
//create parrot spawners
|
||||
num_spawned = 0
|
||||
max = rand(3,6)
|
||||
while(num_spawned < max)
|
||||
var/turf/unsimulated/jungle/J = locate(rand(RANDOM_LOWER_X, RANDOM_UPPER_X), rand(RANDOM_LOWER_Y, RANDOM_UPPER_Y), src.z)
|
||||
if(!J || !istype(J) || !J.bushes_spawn)
|
||||
continue
|
||||
animal_spawners.Add(new /obj/effect/landmark/animal_spawner/parrot(J))
|
||||
num_spawned++
|
||||
|
||||
#undef PATH_SPREAD_CHANCE_START
|
||||
#undef PATH_SPREAD_CHANCE_LOSS_UPPER
|
||||
|
||||
@@ -163,11 +163,11 @@ Deuterium-tritium fusion: 4.5 x 10^7 K
|
||||
React()
|
||||
|
||||
//forcibly radiate any excess energy
|
||||
var/energy_max = transfer_ratio * 100000
|
||||
/*var/energy_max = transfer_ratio * 100000
|
||||
if(mega_energy > energy_max)
|
||||
var/energy_lost = rand( 1.5 * (mega_energy - energy_max), 2.5 * (mega_energy - energy_max) )
|
||||
mega_energy -= energy_lost
|
||||
radiation += energy_lost
|
||||
radiation += energy_lost*/
|
||||
|
||||
//change held plasma temp according to energy levels
|
||||
//SPECIFIC_HEAT_TOXIN
|
||||
@@ -200,12 +200,14 @@ Deuterium-tritium fusion: 4.5 x 10^7 K
|
||||
//held_plasma.update_values()
|
||||
|
||||
//handle some reactants formatting
|
||||
//helium-4 has no use at the moment, but a buttload of it is produced
|
||||
if(dormant_reactant_quantities["Helium-4"] > 1000)
|
||||
dormant_reactant_quantities["Helium-4"] = rand(0,dormant_reactant_quantities["Helium-4"])
|
||||
for(var/reactant in dormant_reactant_quantities)
|
||||
if(!dormant_reactant_quantities[reactant])
|
||||
var/amount = dormant_reactant_quantities[reactant]
|
||||
if(amount < 1)
|
||||
dormant_reactant_quantities.Remove(reactant)
|
||||
else if(amount >= 1000000)
|
||||
var/radiate = rand(3 * amount / 4, amount / 4)
|
||||
dormant_reactant_quantities[reactant] -= radiate
|
||||
radiation += radiate
|
||||
|
||||
return 1
|
||||
|
||||
@@ -236,6 +238,10 @@ Deuterium-tritium fusion: 4.5 x 10^7 K
|
||||
energy += a_energy - a_energy * energy_loss_ratio
|
||||
mega_energy += a_mega_energy - a_mega_energy * energy_loss_ratio
|
||||
|
||||
while(energy > 100000)
|
||||
energy -= 100000
|
||||
mega_energy += 0.1
|
||||
|
||||
/obj/effect/rust_em_field/proc/AddParticles(var/name, var/quantity = 1)
|
||||
if(name in dormant_reactant_quantities)
|
||||
dormant_reactant_quantities[name] += quantity
|
||||
@@ -296,9 +302,7 @@ Deuterium-tritium fusion: 4.5 x 10^7 K
|
||||
return changed
|
||||
|
||||
//the !!fun!! part
|
||||
//reactions have to be individually hardcoded, see AttemptReaction() below this
|
||||
/obj/effect/rust_em_field/proc/React()
|
||||
//world << "React()"
|
||||
//loop through the reactants in random order
|
||||
var/list/reactants_reacting_pool = dormant_reactant_quantities.Copy()
|
||||
/*
|
||||
@@ -316,8 +320,8 @@ Deuterium-tritium fusion: 4.5 x 10^7 K
|
||||
if(!reactants_reacting_pool[reactant])
|
||||
reactants_reacting_pool -= reactant
|
||||
|
||||
var/list/produced_reactants = new/list
|
||||
//loop through all the reacting reagents, picking out random reactions for them
|
||||
var/list/produced_reactants = new/list
|
||||
var/list/primary_reactant_pool = reactants_reacting_pool.Copy()
|
||||
while(primary_reactant_pool.len)
|
||||
//pick one of the unprocessed reacting reagents randomly
|
||||
@@ -331,95 +335,80 @@ Deuterium-tritium fusion: 4.5 x 10^7 K
|
||||
possible_secondary_reactants[cur_primary_reactant] -= 1
|
||||
if(possible_secondary_reactants[cur_primary_reactant] < 1)
|
||||
possible_secondary_reactants.Remove(cur_primary_reactant)
|
||||
var/list/possible_reactions = new/list
|
||||
|
||||
//loop through and work out all the possible reactions
|
||||
while(possible_secondary_reactants.len)
|
||||
var/cur_secondary_reactant = pick(possible_secondary_reactants)
|
||||
var/list/possible_reactions = new/list
|
||||
for(var/cur_secondary_reactant in possible_secondary_reactants)
|
||||
if(possible_secondary_reactants[cur_secondary_reactant] < 1)
|
||||
possible_secondary_reactants.Remove(cur_secondary_reactant)
|
||||
continue
|
||||
possible_secondary_reactants.Remove(cur_secondary_reactant)
|
||||
var/list/reaction_products = AttemptReaction(cur_primary_reactant, cur_secondary_reactant)
|
||||
if(reaction_products.len)
|
||||
var/datum/fusion_reaction/cur_reaction = get_fusion_reaction(cur_primary_reactant, cur_secondary_reactant)
|
||||
if(cur_reaction)
|
||||
//world << "\blue secondary reactant: [cur_secondary_reactant], [reaction_products.len]"
|
||||
possible_reactions[cur_secondary_reactant] = reaction_products
|
||||
possible_reactions.Add(cur_reaction)
|
||||
|
||||
//if there are no possible reactions here, abandon this primary reactant and move on
|
||||
if(!possible_reactions.len)
|
||||
//world << "\blue no reactions"
|
||||
continue
|
||||
|
||||
//split up the reacting atoms between the possible reactions
|
||||
//the problem is in this while statement below
|
||||
while(possible_reactions.len)
|
||||
//pick another substance to react with
|
||||
var/cur_secondary_reactant = pick(possible_reactions)
|
||||
if(!reactants_reacting_pool[cur_secondary_reactant])
|
||||
possible_reactions.Remove(cur_secondary_reactant)
|
||||
continue
|
||||
var/list/cur_reaction_products = possible_reactions[cur_secondary_reactant]
|
||||
//pick a random substance to react with
|
||||
var/datum/fusion_reaction/cur_reaction = pick(possible_reactions)
|
||||
possible_reactions.Remove(cur_reaction)
|
||||
|
||||
//set the randmax to be the lower of the two involved reactants
|
||||
var/max_num_reactants = reactants_reacting_pool[cur_primary_reactant] > reactants_reacting_pool[cur_secondary_reactant] ? reactants_reacting_pool[cur_secondary_reactant] : reactants_reacting_pool[cur_primary_reactant]
|
||||
var/max_num_reactants = reactants_reacting_pool[cur_reaction.primary_reactant] > reactants_reacting_pool[cur_reaction.secondary_reactant] ? \
|
||||
reactants_reacting_pool[cur_reaction.secondary_reactant] : reactants_reacting_pool[cur_reaction.primary_reactant]
|
||||
if(max_num_reactants < 1)
|
||||
continue
|
||||
|
||||
//make sure we have enough energy
|
||||
if( mega_energy < max_num_reactants*cur_reaction_products["consumption"])
|
||||
max_num_reactants = round(mega_energy / cur_reaction_products["consumption"])
|
||||
if(mega_energy < max_num_reactants * cur_reaction.energy_consumption)
|
||||
max_num_reactants = round(mega_energy / cur_reaction.energy_consumption)
|
||||
if(max_num_reactants < 1)
|
||||
continue
|
||||
|
||||
//randomly determined amount to react
|
||||
var/amount_reacting = rand(1, max_num_reactants)
|
||||
|
||||
//removing the reacting substances from the list of substances that are primed to react this cycle
|
||||
//if there aren't enough of that substance (there should be) then modify the reactant amounts accordingly
|
||||
if( reactants_reacting_pool[cur_primary_reactant] - amount_reacting > -1 )
|
||||
reactants_reacting_pool[cur_primary_reactant] -= amount_reacting
|
||||
if( reactants_reacting_pool[cur_reaction.primary_reactant] - amount_reacting >= 0 )
|
||||
reactants_reacting_pool[cur_reaction.primary_reactant] -= amount_reacting
|
||||
else
|
||||
amount_reacting = reactants_reacting_pool[cur_primary_reactant]
|
||||
reactants_reacting_pool[cur_primary_reactant] = 0
|
||||
//
|
||||
if( reactants_reacting_pool[cur_secondary_reactant] - amount_reacting > -1 )
|
||||
reactants_reacting_pool[cur_secondary_reactant] -= amount_reacting
|
||||
amount_reacting = reactants_reacting_pool[cur_reaction.primary_reactant]
|
||||
reactants_reacting_pool[cur_reaction.primary_reactant] = 0
|
||||
//same again for secondary reactant
|
||||
if( reactants_reacting_pool[cur_reaction.secondary_reactant] - amount_reacting >= 0 )
|
||||
reactants_reacting_pool[cur_reaction.secondary_reactant] -= amount_reacting
|
||||
else
|
||||
reactants_reacting_pool[cur_primary_reactant] += amount_reacting - reactants_reacting_pool[cur_primary_reactant]
|
||||
amount_reacting = reactants_reacting_pool[cur_secondary_reactant]
|
||||
reactants_reacting_pool[cur_secondary_reactant] = 0
|
||||
reactants_reacting_pool[cur_reaction.primary_reactant] += amount_reacting - reactants_reacting_pool[cur_reaction.primary_reactant]
|
||||
amount_reacting = reactants_reacting_pool[cur_reaction.secondary_reactant]
|
||||
reactants_reacting_pool[cur_reaction.secondary_reactant] = 0
|
||||
|
||||
//remove the consumed energy
|
||||
if(cur_reaction_products["consumption"])
|
||||
mega_energy -= max_num_reactants * cur_reaction_products["consumption"]
|
||||
cur_reaction_products.Remove("consumption")
|
||||
mega_energy -= max_num_reactants * cur_reaction.energy_consumption
|
||||
|
||||
//grab any radiation and put it separate
|
||||
//var/new_radiation = 0
|
||||
if("production" in cur_reaction_products)
|
||||
mega_energy += max_num_reactants * cur_reaction_products["production"]
|
||||
cur_reaction_products.Remove("production")
|
||||
/*for(var/i=0, i<dormant_reactant_quantities["proton_quantity"], i++)
|
||||
radiation.Add("proton")
|
||||
radiation_charge.Add(dormant_reactant_quantities["proton_charge"])
|
||||
dormant_reactant_quantities.Remove("proton_quantity")
|
||||
dormant_reactant_quantities.Remove("proton_charge")
|
||||
new_radiation = 1*/
|
||||
//
|
||||
if("radiation" in cur_reaction_products)
|
||||
radiation += max_num_reactants * cur_reaction_products["radiation"]
|
||||
cur_reaction_products.Remove("radiation")
|
||||
/*for(var/i=0, i<dormant_reactant_quantities["neutron_quantity"], i++)
|
||||
radiation.Add("neutron")
|
||||
radiation_charge.Add(dormant_reactant_quantities["neutron_charge"])
|
||||
dormant_reactant_quantities.Remove("neutron_quantity")
|
||||
dormant_reactant_quantities.Remove("neutron_charge")
|
||||
new_radiation = 1*/
|
||||
//add any produced energy
|
||||
mega_energy += max_num_reactants * cur_reaction.energy_production
|
||||
|
||||
//add any produced radiation
|
||||
radiation += max_num_reactants * cur_reaction.radiation
|
||||
|
||||
//create the reaction products
|
||||
for(var/reactant in cur_reaction_products)
|
||||
if(produced_reactants[reactant])
|
||||
produced_reactants[reactant] += cur_reaction_products[reactant] * amount_reacting
|
||||
else
|
||||
produced_reactants[reactant] = cur_reaction_products[reactant] * amount_reacting
|
||||
for(var/reactant in cur_reaction.products)
|
||||
var/success = 0
|
||||
for(var/check_reactant in produced_reactants)
|
||||
if(check_reactant == reactant)
|
||||
produced_reactants[reactant] += cur_reaction.products[reactant] * amount_reacting
|
||||
success = 1
|
||||
break
|
||||
if(!success)
|
||||
produced_reactants[reactant] = cur_reaction.products[reactant] * amount_reacting
|
||||
|
||||
//this reaction is done, and can't be repeated this sub-cycle
|
||||
possible_reactions.Remove(cur_secondary_reactant)
|
||||
possible_reactions.Remove(cur_reaction.secondary_reactant)
|
||||
|
||||
//
|
||||
/*if(new_radiation)
|
||||
@@ -431,7 +420,7 @@ Deuterium-tritium fusion: 4.5 x 10^7 K
|
||||
//var/list/neutronic_radiation = new
|
||||
//var/list/protonic_radiation = new
|
||||
for(var/reactant in produced_reactants)
|
||||
AddParticles(reactant, dormant_reactant_quantities[reactant])
|
||||
AddParticles(reactant, produced_reactants[reactant])
|
||||
//world << "produced: [reactant], [dormant_reactant_quantities[reactant]]"
|
||||
|
||||
//check whether there are reactants left, and add them back to the pool
|
||||
@@ -439,213 +428,6 @@ Deuterium-tritium fusion: 4.5 x 10^7 K
|
||||
AddParticles(reactant, reactants_reacting_pool[reactant])
|
||||
//world << "retained: [reactant], [reactants_reacting_pool[reactant]]"
|
||||
|
||||
//default fuel assembly quantities
|
||||
/*
|
||||
//new_assembly_quantities["Helium-3"] = 0
|
||||
//new_assembly_quantities["Deuterium"] = 200
|
||||
//new_assembly_quantities["Tritium"] = 100
|
||||
//new_assembly_quantities["Lithium-6"] = 0
|
||||
//new_assembly_quantities["Silver"] = 0
|
||||
*/
|
||||
|
||||
//reactions involving D-T (hydrogen) need 0.1 MeV of core energy
|
||||
//reactions involving helium require 0.4 MeV of energy
|
||||
//reactions involving lithium require 0.6 MeV of energy
|
||||
//reactions involving boron require 1 MeV of energy
|
||||
//returns a list of products, or an empty list if no reaction possible
|
||||
/obj/effect/rust_em_field/proc/AttemptReaction(var/reactant_one, var/reactant_two)
|
||||
//any charge on the atomic reactants / protons produced is abstracted away to enter the core energy pool straightaway
|
||||
//atomic products remain in the core and produce more reactions next cycle
|
||||
//any charged neutrons escape as radiation
|
||||
var/check = 1
|
||||
recheck_reactions:
|
||||
var/list/products = new/list
|
||||
switch(reactant_one)
|
||||
if("Tritium")
|
||||
switch(reactant_two)
|
||||
if("Tritium")
|
||||
if(mega_energy > 0.1)
|
||||
products["Helium-4"] = 1
|
||||
//
|
||||
products["production"] = 11.3
|
||||
products["radiation"] = 1
|
||||
/*products["photon"] = 11.3
|
||||
//
|
||||
products["neutron_quantity"] = 1
|
||||
products["neutron_charge"] = 0*/
|
||||
//
|
||||
mega_energy -= 0.1
|
||||
if("Deuterium")
|
||||
if(mega_energy > 0.1)
|
||||
products["Helium-4"] = 1
|
||||
//
|
||||
products["production"] = 3.5
|
||||
products["radiation"] = 14.1
|
||||
/*products["photon"] = 3.5
|
||||
//
|
||||
products["neutron_quantity"] = 1
|
||||
products["neutron_charge"] = 14.1
|
||||
//
|
||||
products["consumption"] = 0.1*/
|
||||
if("Helium-3")
|
||||
if(mega_energy > 0.4)
|
||||
if(prob(51))
|
||||
products["Helium-4"] = 1
|
||||
//
|
||||
products["production"] = 13.1
|
||||
products["radiation"] = 1
|
||||
/*products["photon"] = 12.1
|
||||
//
|
||||
products["proton_quantity"] = 1
|
||||
products["proton_charge"] = 0
|
||||
//
|
||||
products["neutron_quantity"] = 1
|
||||
products["neutron_charge"] = 0*/
|
||||
else if (prob(43))
|
||||
products["Helium-4"] = 1
|
||||
products["Deuterium"] = 1
|
||||
//
|
||||
products["production"] = 14.3
|
||||
/*products["photon"] = 4.8 + 9.5//14.3
|
||||
*/
|
||||
else
|
||||
products["Helium-4"] = 1
|
||||
products["production"] = 2.4
|
||||
products["radiation"] = 11.9
|
||||
/*products["photon"] = 0.5//12.4
|
||||
//
|
||||
products["proton_quantity"] = 1
|
||||
products["proton_charge"] = 1.9
|
||||
//
|
||||
products["neutron_quantity"] = 1
|
||||
products["neutron_charge"] = 11.9*/
|
||||
//
|
||||
products["consumption"] = 0.4
|
||||
if("Deuterium")
|
||||
switch(reactant_two)
|
||||
if("Deuterium")
|
||||
if(mega_energy > 0.1)
|
||||
if(prob(50))
|
||||
products["Tritium"] = 1
|
||||
//
|
||||
products["production"] = 4.03
|
||||
/*products["photon"] = 1.01
|
||||
//
|
||||
products["proton_quantity"] = 1
|
||||
products["proton_charge"] = 3.02*/
|
||||
else
|
||||
products["Helium-3"] = 1
|
||||
//
|
||||
products["production"] = 0.82
|
||||
products["radiation"] = 2.45
|
||||
/*products["photon"] = 0.82
|
||||
//
|
||||
products["neutron_quantity"] = 1
|
||||
products["neutron_charge"] = 2.45*/
|
||||
//
|
||||
products["consumption"] = 0.1
|
||||
if("Helium-3")
|
||||
if(mega_energy > 0.4)
|
||||
products["Helium-4"] = 1
|
||||
//
|
||||
products["production"] = 18.3
|
||||
/*products["photon"] = 3.6
|
||||
//
|
||||
products["proton_quantity"] = 1
|
||||
products["proton_charge"] = 14.7*/
|
||||
//
|
||||
products["consumption"] = 0.4
|
||||
if("Lithium-6")
|
||||
if(mega_energy > 0.6)
|
||||
if(prob(25))
|
||||
products["Helium-4"] = 2
|
||||
products["production"] = 1
|
||||
/*products["photon"] = 22.4*/
|
||||
else if(prob(33))
|
||||
products["Helium-3"] = 1
|
||||
products["Helium-4"] = 1
|
||||
//
|
||||
products["radiation"] = 1
|
||||
/*products["neutron_quantity"] = 1
|
||||
products["neutron_charge"] = 0*/
|
||||
else if(prob(50))
|
||||
products["Lithium-7"] = 1
|
||||
//
|
||||
products["production"] = 1
|
||||
/*products["proton_quantity"] = 1
|
||||
products["proton_charge"] = 0*/
|
||||
else
|
||||
products["Beryllium-7"] = 1
|
||||
products["production"] = 3.4
|
||||
products["radiation"] = 1
|
||||
/*products["photon"] = 3.4
|
||||
//
|
||||
products["neutron_quantity"] = 1
|
||||
products["neutron_charge"] = 0*/
|
||||
//
|
||||
products["consumption"] = 0.6
|
||||
if("Helium-3")
|
||||
switch(reactant_two)
|
||||
if("Helium-3")
|
||||
if(mega_energy > 0.4)
|
||||
products["Helium-4"] = 1
|
||||
products["production"] = 14.9
|
||||
/*products["photon"] = 12.9
|
||||
//
|
||||
products["proton_quantity"] = 2
|
||||
products["proton_charge"] = 0*/
|
||||
//
|
||||
products["consumption"] = 0.4
|
||||
if("Lithium-6")
|
||||
if(mega_energy > 0.6)
|
||||
products["Helium-4"] = 2
|
||||
//
|
||||
products["production"] = 17.9
|
||||
/*products["photon"] = 16.9
|
||||
//
|
||||
products["proton_quantity"] = 1
|
||||
products["proton_charge"] = 0*/
|
||||
//
|
||||
products["consumption"] = 0.6
|
||||
/*
|
||||
if("proton")
|
||||
switch(reactant_two)
|
||||
if("Lithium-6")
|
||||
if(mega_energy > 0.6)
|
||||
products["Helium-4"] = 1
|
||||
products["Helium-3"] = 1
|
||||
products["photon"] = 4
|
||||
//
|
||||
mega_energy -= 0.6
|
||||
if("Boron-11")
|
||||
if(mega_energy > 1)
|
||||
products["Helium-4"] = 3
|
||||
products["photon"] = 8.7
|
||||
//
|
||||
mega_energy -= 1
|
||||
*/
|
||||
|
||||
//if no reaction happened, switch the two reactants and try again
|
||||
if(!products.len && check)
|
||||
check = 0
|
||||
var/temp = reactant_one
|
||||
reactant_one = reactant_two
|
||||
reactant_two = temp
|
||||
goto recheck_reactions
|
||||
/*if(products.len)
|
||||
world << "\blue [reactant_one] + [reactant_two] reaction occured"
|
||||
for(var/reagent in products)
|
||||
world << "\blue [reagent]: [products[reagent]]"*/
|
||||
/*if(products["neutron"])
|
||||
products -= "neutron"
|
||||
if(products["proton"])
|
||||
products -= "proton"
|
||||
if(products["photon"])
|
||||
products -= "photon"
|
||||
if(products["radiated charge"])
|
||||
products -= "radiated charge"*/
|
||||
return products
|
||||
|
||||
/obj/effect/rust_em_field/Del()
|
||||
//radiate everything in one giant burst
|
||||
for(var/obj/effect/rust_particle_catcher/catcher in particle_catchers)
|
||||
|
||||
@@ -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
|
||||
@@ -281,6 +282,6 @@ max volume of plasma storeable by the field = the total volume of a number of ti
|
||||
return 0
|
||||
|
||||
/obj/machinery/power/rust_core/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(Proj.flag != "bullet" && owned_field)
|
||||
owned_field.AddEnergy(Proj.damage, 0, 1)
|
||||
if(owned_field)
|
||||
return owned_field.bullet_act(Proj)
|
||||
return 0
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
name = "Fuel Rod Assembly"
|
||||
var/list/rod_quantities
|
||||
var/percent_depleted = 1
|
||||
layer = 3.1
|
||||
//
|
||||
New()
|
||||
rod_quantities = new/list
|
||||
|
||||
@@ -64,14 +64,14 @@
|
||||
|
||||
/obj/machinery/rust_fuel_assembly_port/proc/eject_assembly()
|
||||
if(cur_assembly)
|
||||
cur_assembly.loc = get_step(get_turf(src), src.dir)
|
||||
cur_assembly.loc = src.loc//get_step(get_turf(src), src.dir)
|
||||
cur_assembly = null
|
||||
icon_state = "port0"
|
||||
return 1
|
||||
|
||||
/obj/machinery/rust_fuel_assembly_port/proc/try_draw_assembly()
|
||||
var/success = 0
|
||||
if(cur_assembly)
|
||||
if(!cur_assembly)
|
||||
var/turf/check_turf = get_step(get_turf(src), src.dir)
|
||||
check_turf = get_step(check_turf, src.dir)
|
||||
for(var/obj/machinery/power/rust_fuel_injector/I in check_turf)
|
||||
@@ -89,31 +89,14 @@
|
||||
I.cur_assembly = null
|
||||
icon_state = "port1"
|
||||
success = 1
|
||||
break
|
||||
|
||||
return success
|
||||
|
||||
/*
|
||||
/obj/machinery/rust_fuel_assembly_port/verb/try_insert_assembly_verb()
|
||||
set name = "Attempt to insert assembly from port into injector"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if(!busy)
|
||||
try_insert_assembly()
|
||||
|
||||
/obj/machinery/rust_fuel_assembly_port/verb/eject_assembly_verb()
|
||||
set name = "Attempt to eject assembly from port"
|
||||
set name = "Eject assembly from port"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if(!busy)
|
||||
eject_assembly()
|
||||
eject_assembly()
|
||||
|
||||
/obj/machinery/rust_fuel_assembly_port/verb/try_draw_assembly_verb()
|
||||
set name = "Draw assembly from injector"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if(!busy)
|
||||
try_draw_assembly()
|
||||
*/
|
||||
|
||||
@@ -4,7 +4,7 @@ var/const/max_assembly_amount = 300
|
||||
icon = 'code/WorkInProgress/Cael_Aislinn/Rust/rust.dmi'
|
||||
icon_state = "fuel_compressor1"
|
||||
name = "Fuel Compressor"
|
||||
var/list/new_assembly_quantities = list("Deuterium" = 200,"Tritium" = 100,"Helium-3" = 0,"Lithium-6" = 0,"Silver" = 0)
|
||||
var/list/new_assembly_quantities = list("Deuterium" = 150,"Tritium" = 150,"Rodinium-6" = 0,"Stravium-7" = 0, "Pergium" = 0, "Dilithium" = 0)
|
||||
var/compressed_matter = 0
|
||||
anchored = 1
|
||||
layer = 2.9
|
||||
@@ -79,12 +79,16 @@ var/const/max_assembly_amount = 300
|
||||
var/fail = 0
|
||||
var/old_matter = compressed_matter
|
||||
for(var/reagent in new_assembly_quantities)
|
||||
var/req_matter = new_assembly_quantities[reagent] / 30
|
||||
var/req_matter = round(new_assembly_quantities[reagent] / 30)
|
||||
//world << "[reagent] matter: [req_matter]/[compressed_matter]"
|
||||
if(req_matter <= compressed_matter)
|
||||
F.rod_quantities[reagent] = new_assembly_quantities[reagent]
|
||||
compressed_matter -= req_matter
|
||||
if(compressed_matter < 1)
|
||||
compressed_matter = 0
|
||||
else
|
||||
/*world << "bad reagent: [reagent], [req_matter > compressed_matter ? "req_matter > compressed_matter"\
|
||||
: (req_matter < compressed_matter ? "req_matter < compressed_matter" : "req_matter == compressed_matter")]"*/
|
||||
fail = 1
|
||||
break
|
||||
//world << "\blue [reagent]: new_assembly_quantities[reagent]<br>"
|
||||
@@ -93,7 +97,7 @@ var/const/max_assembly_amount = 300
|
||||
compressed_matter = old_matter
|
||||
usr << "\red \icon[src] [src] flashes red: \'Out of matter.\'"
|
||||
else
|
||||
F.loc = get_step(get_turf(src), src.dir)
|
||||
F.loc = src.loc//get_step(get_turf(src), src.dir)
|
||||
F.percent_depleted = 0
|
||||
if(compressed_matter < 0.034)
|
||||
compressed_matter = 0
|
||||
|
||||
@@ -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
|
||||
@@ -177,11 +179,7 @@
|
||||
id_tag = input("Enter new ID tag", "Modifying ID tag") as text|null
|
||||
|
||||
if( href_list["fuel_assembly"] )
|
||||
if(!trying_to_swap_fuel)
|
||||
trying_to_swap_fuel = 1
|
||||
spawn(50)
|
||||
attempt_fuel_swap()
|
||||
trying_to_swap_fuel = 0
|
||||
attempt_fuel_swap()
|
||||
|
||||
if( href_list["emergency_fuel_assembly"] )
|
||||
if(cur_assembly)
|
||||
@@ -288,3 +286,23 @@
|
||||
updateDialog()
|
||||
else
|
||||
src.visible_message("\red \icon[src] a red light flashes on [src].")
|
||||
|
||||
/obj/machinery/power/rust_fuel_injector/verb/rotate_clock()
|
||||
set category = "Object"
|
||||
set name = "Rotate Generator (Clockwise)"
|
||||
set src in view(1)
|
||||
|
||||
if (usr.stat || usr.restrained() || anchored)
|
||||
return
|
||||
|
||||
src.dir = turn(src.dir, 90)
|
||||
|
||||
/obj/machinery/power/rust_fuel_injector/verb/rotate_anticlock()
|
||||
set category = "Object"
|
||||
set name = "Rotate Generator (Counterclockwise)"
|
||||
set src in view(1)
|
||||
|
||||
if (usr.stat || usr.restrained() || anchored)
|
||||
return
|
||||
|
||||
src.dir = turn(src.dir, -90)
|
||||
@@ -0,0 +1,160 @@
|
||||
|
||||
datum/fusion_reaction
|
||||
var/primary_reactant = ""
|
||||
var/secondary_reactant = ""
|
||||
var/energy_consumption = 0
|
||||
var/energy_production = 0
|
||||
var/radiation = 0
|
||||
var/list/products = list()
|
||||
|
||||
/datum/controller/game_controller/var/list/fusion_reactions
|
||||
|
||||
proc/get_fusion_reaction(var/primary_reactant, var/secondary_reactant)
|
||||
if(!master_controller.fusion_reactions)
|
||||
populate_fusion_reactions()
|
||||
if(master_controller.fusion_reactions.Find(primary_reactant))
|
||||
var/list/secondary_reactions = master_controller.fusion_reactions[primary_reactant]
|
||||
if(secondary_reactions.Find(secondary_reactant))
|
||||
return master_controller.fusion_reactions[primary_reactant][secondary_reactant]
|
||||
|
||||
proc/populate_fusion_reactions()
|
||||
if(!master_controller.fusion_reactions)
|
||||
master_controller.fusion_reactions = list()
|
||||
for(var/cur_reaction_type in typesof(/datum/fusion_reaction) - /datum/fusion_reaction)
|
||||
var/datum/fusion_reaction/cur_reaction = new cur_reaction_type()
|
||||
if(!master_controller.fusion_reactions[cur_reaction.primary_reactant])
|
||||
master_controller.fusion_reactions[cur_reaction.primary_reactant] = list()
|
||||
master_controller.fusion_reactions[cur_reaction.primary_reactant][cur_reaction.secondary_reactant] = cur_reaction
|
||||
if(!master_controller.fusion_reactions[cur_reaction.secondary_reactant])
|
||||
master_controller.fusion_reactions[cur_reaction.secondary_reactant] = list()
|
||||
master_controller.fusion_reactions[cur_reaction.secondary_reactant][cur_reaction.primary_reactant] = cur_reaction
|
||||
|
||||
//Fake elements and fake reactions, but its nicer gameplay-wise
|
||||
//Deuterium
|
||||
//Tritium
|
||||
//Uridium-3
|
||||
//Obdurium
|
||||
//Solonium
|
||||
//Rodinium-6
|
||||
//Dilithium
|
||||
//Trilithium
|
||||
//Pergium
|
||||
//Stravium-7
|
||||
|
||||
//Primary Production Reactions
|
||||
|
||||
datum/fusion_reaction/tritium_deuterium
|
||||
primary_reactant = "Tritium"
|
||||
secondary_reactant = "Deuterium"
|
||||
energy_consumption = 1
|
||||
energy_production = 5
|
||||
radiation = 0
|
||||
|
||||
//Secondary Production Reactions
|
||||
|
||||
datum/fusion_reaction/deuterium_deuterium
|
||||
primary_reactant = "Deuterium"
|
||||
secondary_reactant = "Deuterium"
|
||||
energy_consumption = 1
|
||||
energy_production = 4
|
||||
radiation = 1
|
||||
products = list("Obdurium" = 2)
|
||||
|
||||
datum/fusion_reaction/tritium_tritium
|
||||
primary_reactant = "Tritium"
|
||||
secondary_reactant = "Tritium"
|
||||
energy_consumption = 1
|
||||
energy_production = 4
|
||||
radiation = 1
|
||||
products = list("Solonium" = 2)
|
||||
|
||||
//Cleanup Reactions
|
||||
|
||||
datum/fusion_reaction/rodinium6_obdurium
|
||||
primary_reactant = "Rodinium-6"
|
||||
secondary_reactant = "Obdurium"
|
||||
energy_consumption = 1
|
||||
energy_production = 2
|
||||
radiation = 2
|
||||
|
||||
datum/fusion_reaction/rodinium6_solonium
|
||||
primary_reactant = "Rodinium-6"
|
||||
secondary_reactant = "Solonium"
|
||||
energy_consumption = 1
|
||||
energy_production = 2
|
||||
radiation = 2
|
||||
|
||||
//Breeder Reactions
|
||||
|
||||
datum/fusion_reaction/dilithium_obdurium
|
||||
primary_reactant = "Dilithium"
|
||||
secondary_reactant = "Obdurium"
|
||||
energy_consumption = 1
|
||||
energy_production = 1
|
||||
radiation = 3
|
||||
products = list("Deuterium" = 1, "Dilithium" = 1)
|
||||
|
||||
datum/fusion_reaction/dilithium_solonium
|
||||
primary_reactant = "Dilithium"
|
||||
secondary_reactant = "Solonium"
|
||||
energy_consumption = 1
|
||||
energy_production = 1
|
||||
radiation = 3
|
||||
products = list("Tritium" = 1, "Dilithium" = 1)
|
||||
|
||||
//Breeder Inhibitor Reactions
|
||||
|
||||
datum/fusion_reaction/stravium7_dilithium
|
||||
primary_reactant = "Stravium-7"
|
||||
secondary_reactant = "Dilithium"
|
||||
energy_consumption = 2
|
||||
energy_production = 1
|
||||
radiation = 4
|
||||
|
||||
//Enhanced Breeder Reactions
|
||||
|
||||
datum/fusion_reaction/trilithium_obdurium
|
||||
primary_reactant = "Trilithium"
|
||||
secondary_reactant = "Obdurium"
|
||||
energy_consumption = 1
|
||||
energy_production = 2
|
||||
radiation = 5
|
||||
products = list("Dilithium" = 1, "Trilithium" = 1, "Deuterium" = 1)
|
||||
|
||||
datum/fusion_reaction/trilithium_solonium
|
||||
primary_reactant = "Trilithium"
|
||||
secondary_reactant = "Solonium"
|
||||
energy_consumption = 1
|
||||
energy_production = 2
|
||||
radiation = 5
|
||||
products = list("Dilithium" = 1, "Trilithium" = 1, "Tritium" = 1)
|
||||
|
||||
//Control Reactions
|
||||
|
||||
datum/fusion_reaction/pergium_deuterium
|
||||
primary_reactant = "Pergium"
|
||||
secondary_reactant = "Deuterium"
|
||||
energy_consumption = 5
|
||||
energy_production = 0
|
||||
radiation = 5
|
||||
|
||||
datum/fusion_reaction/pergium_tritium
|
||||
primary_reactant = "Pergium"
|
||||
secondary_reactant = "Tritium"
|
||||
energy_consumption = 5
|
||||
energy_production = 0
|
||||
radiation = 5
|
||||
|
||||
datum/fusion_reaction/pergium_deuterium
|
||||
primary_reactant = "Pergium"
|
||||
secondary_reactant = "Obdurium"
|
||||
energy_consumption = 5
|
||||
energy_production = 0
|
||||
radiation = 5
|
||||
|
||||
datum/fusion_reaction/pergium_tritium
|
||||
primary_reactant = "Pergium"
|
||||
secondary_reactant = "Solonium"
|
||||
energy_consumption = 5
|
||||
energy_production = 0
|
||||
radiation = 5
|
||||
@@ -34,16 +34,16 @@
|
||||
/obj/effect/rust_particle_catcher/proc/UpdateSize()
|
||||
if(parent.size >= mysize)
|
||||
density = 1
|
||||
invisibility = 0
|
||||
//invisibility = 0
|
||||
name = "collector [mysize] ON"
|
||||
else
|
||||
density = 0
|
||||
invisibility = 101
|
||||
//invisibility = 101
|
||||
name = "collector [mysize] OFF"
|
||||
|
||||
/obj/effect/rust_particle_catcher/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(Proj.flag != "bullet" && parent)
|
||||
parent.AddEnergy(Proj.damage, 0, 1)
|
||||
parent.AddEnergy(Proj.damage * 20, 0, 1)
|
||||
update_icon()
|
||||
return 0
|
||||
|
||||
|
||||
@@ -1,55 +1,55 @@
|
||||
|
||||
//---------- actual energy field
|
||||
|
||||
/obj/effect/energy_field
|
||||
name = "energy field"
|
||||
desc = "Impenetrable field of energy, capable of blocking anything as long as it's active."
|
||||
icon = 'shielding.dmi'
|
||||
icon_state = "shieldsparkles"
|
||||
anchored = 1
|
||||
layer = 2.1
|
||||
density = 0
|
||||
invisibility = 101
|
||||
var/strength = 0
|
||||
|
||||
/obj/effect/energy_field/ex_act(var/severity)
|
||||
Stress(0.5 + severity)
|
||||
|
||||
/obj/effect/energy_field/bullet_act(var/obj/item/projectile/Proj)
|
||||
Stress(Proj.damage / 10)
|
||||
|
||||
/obj/effect/energy_field/meteorhit(obj/effect/meteor/M as obj)
|
||||
if(M)
|
||||
walk(M,0)
|
||||
Stress(2)
|
||||
|
||||
/obj/effect/energy_field/proc/Stress(var/severity)
|
||||
strength -= severity
|
||||
|
||||
//if we take too much damage, drop out - the generator will bring us back up if we have enough power
|
||||
if(strength < 1)
|
||||
invisibility = 101
|
||||
density = 0
|
||||
else if(strength >= 1)
|
||||
invisibility = 0
|
||||
density = 1
|
||||
|
||||
/obj/effect/energy_field/proc/Strengthen(var/severity)
|
||||
strength += severity
|
||||
|
||||
//if we take too much damage, drop out - the generator will bring us back up if we have enough power
|
||||
if(strength >= 1)
|
||||
invisibility = 0
|
||||
density = 1
|
||||
else if(strength < 1)
|
||||
invisibility = 101
|
||||
density = 0
|
||||
|
||||
/obj/effect/energy_field/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
|
||||
//Purpose: Determines if the object (or airflow) can pass this atom.
|
||||
//Called by: Movement, airflow.
|
||||
//Inputs: The moving atom (optional), target turf, "height" and air group
|
||||
//Outputs: Boolean if can pass.
|
||||
|
||||
//return (!density || !height || air_group)
|
||||
return !density
|
||||
|
||||
//---------- actual energy field
|
||||
|
||||
/obj/effect/energy_field
|
||||
name = "energy field"
|
||||
desc = "Impenetrable field of energy, capable of blocking anything as long as it's active."
|
||||
icon = 'shielding.dmi'
|
||||
icon_state = "shieldsparkles"
|
||||
anchored = 1
|
||||
layer = 4.1 //just above mobs
|
||||
density = 0
|
||||
invisibility = 101
|
||||
var/strength = 0
|
||||
|
||||
/obj/effect/energy_field/ex_act(var/severity)
|
||||
Stress(0.5 + severity)
|
||||
|
||||
/obj/effect/energy_field/bullet_act(var/obj/item/projectile/Proj)
|
||||
Stress(Proj.damage / 10)
|
||||
|
||||
/obj/effect/energy_field/meteorhit(obj/effect/meteor/M as obj)
|
||||
if(M)
|
||||
walk(M,0)
|
||||
Stress(2)
|
||||
|
||||
/obj/effect/energy_field/proc/Stress(var/severity)
|
||||
strength -= severity
|
||||
|
||||
//if we take too much damage, drop out - the generator will bring us back up if we have enough power
|
||||
if(strength < 1)
|
||||
invisibility = 101
|
||||
density = 0
|
||||
else if(strength >= 1)
|
||||
invisibility = 0
|
||||
density = 1
|
||||
|
||||
/obj/effect/energy_field/proc/Strengthen(var/severity)
|
||||
strength += severity
|
||||
|
||||
//if we take too much damage, drop out - the generator will bring us back up if we have enough power
|
||||
if(strength >= 1)
|
||||
invisibility = 0
|
||||
density = 1
|
||||
else if(strength < 1)
|
||||
invisibility = 101
|
||||
density = 0
|
||||
|
||||
/obj/effect/energy_field/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
|
||||
//Purpose: Determines if the object (or airflow) can pass this atom.
|
||||
//Called by: Movement, airflow.
|
||||
//Inputs: The moving atom (optional), target turf, "height" and air group
|
||||
//Outputs: Boolean if can pass.
|
||||
|
||||
//return (!density || !height || air_group)
|
||||
return !density
|
||||
|
||||
@@ -150,11 +150,10 @@
|
||||
var/strength_change = target_field_strength - E.strength
|
||||
if(strength_change > stored_renwicks)
|
||||
strength_change = stored_renwicks
|
||||
if(E.strength >= 1)
|
||||
E.Strengthen(strength_change)
|
||||
else if(E.strength < 0)
|
||||
if(E.strength < 0)
|
||||
E.strength = 0
|
||||
E.Strengthen(0.1)
|
||||
else
|
||||
E.Strengthen(strength_change)
|
||||
|
||||
stored_renwicks -= strength_change
|
||||
|
||||
|
||||
@@ -206,10 +206,12 @@ log transactions
|
||||
switch(href_list["choice"])
|
||||
if("transfer")
|
||||
if(authenticated_account && linked_db)
|
||||
var/target_account_number = text2num(href_list["target_acc_number"])
|
||||
var/transfer_amount = text2num(href_list["funds_amount"])
|
||||
var/transfer_purpose = href_list["purpose"]
|
||||
if(transfer_amount <= authenticated_account.money)
|
||||
if(transfer_amount <= 0)
|
||||
alert("That is not a valid amount.")
|
||||
else if(transfer_amount <= authenticated_account.money)
|
||||
var/target_account_number = text2num(href_list["target_acc_number"])
|
||||
var/transfer_purpose = href_list["purpose"]
|
||||
if(linked_db.charge_to_account(target_account_number, authenticated_account.owner_name, transfer_purpose, machine_id, transfer_amount))
|
||||
usr << "\icon[src]<span class='info'>Funds transfer successful.</span>"
|
||||
authenticated_account.money -= transfer_amount
|
||||
@@ -284,7 +286,9 @@ log transactions
|
||||
previous_account_number = tried_account_num
|
||||
if("withdrawal")
|
||||
var/amount = max(text2num(href_list["funds_amount"]),0)
|
||||
if(authenticated_account && amount > 0)
|
||||
if(amount <= 0)
|
||||
alert("That is not a valid amount.")
|
||||
else if(authenticated_account && amount > 0)
|
||||
if(amount <= authenticated_account.money)
|
||||
playsound(src, 'chime.ogg', 50, 1)
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -29,9 +39,9 @@
|
||||
dat += "<a href='?src=\ref[src]&alarm=\ref[alarm]'>"
|
||||
switch(max(alarm.danger_level, alarm.alarm_area.atmosalm))
|
||||
if (0)
|
||||
dat += "<font color=blue>"
|
||||
dat += "<font color=green>"
|
||||
if (1)
|
||||
dat += "<font color=yellow>"
|
||||
dat += "<font color=blue>"
|
||||
if (2)
|
||||
dat += "<font color=red>"
|
||||
dat += "[alarm]</font></a><br/>"
|
||||
@@ -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>
|
||||
"}
|
||||
@@ -288,8 +302,8 @@ Nitrous Oxide
|
||||
AALARM_MODE_REPLACEMENT = "<font color='red'>REPLACE AIR</font>",
|
||||
AALARM_MODE_PANIC = "<font color='red'>PANIC</font>",
|
||||
AALARM_MODE_CYCLE = "<font color='red'>CYCLE</font>",
|
||||
AALARM_MODE_FILL = "<font color='red'>FILL</font>",
|
||||
)
|
||||
AALARM_MODE_FILL = "<font color='red'>FILL</font>",\
|
||||
AALARM_MODE_OFF = "<font color='blue'>OFFF</font>",)
|
||||
for (var/m=1,m<=modes.len,m++)
|
||||
if (current.mode==m)
|
||||
output += {"<li><A href='?src=\ref[src];alarm=\ref[current];mode=[m]'><b>[modes[m]]</b></A> (selected)</li>"}
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
//is_blocked_turf(var/turf/T)
|
||||
usr << "\blue You finish placing the [src]." //Git Test
|
||||
|
||||
/obj/item/taperoll/police/afterattack(var/atom/A, mob/user as mob)
|
||||
/obj/item/taperoll/afterattack(var/atom/A, mob/user as mob)
|
||||
if (istype(A, /obj/machinery/door/airlock))
|
||||
var/turf/T = get_turf(A)
|
||||
var/obj/item/tape/P = new tape_type(T.x,T.y,T.z)
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
// Reference: http://www.teuse.net/personal/harrington/hh_bible.htm
|
||||
// http://www.trmn.org/portal/images/uniforms/rmn/rmn_officer_srv_dress_lrg.png
|
||||
|
||||
/obj/item/clothing/head/beret/centcom/officer
|
||||
name = "officers beret"
|
||||
desc = "A black beret adorned with the shield—a silver kite shield with an engraved sword—of the NanoTrasen security forces, announcing to the world that the wearer is a defender of NanoTrasen."
|
||||
icon_state = "centcomofficerberet"
|
||||
flags = FPRINT | TABLEPASS
|
||||
|
||||
/obj/item/clothing/head/beret/centcom/captain
|
||||
name = "captains beret"
|
||||
desc = "A white beret adorned with the shield—a cobalt kite shield with an engraved sword—of the NanoTrasen security forces, worn only by those captaining a vessel of the NanoTrasen Navy."
|
||||
icon_state = "centcomcaptain"
|
||||
flags = FPRINT | TABLEPASS
|
||||
|
||||
/obj/item/clothing/shoes/centcom
|
||||
name = "dress shoes"
|
||||
desc = "They appear impeccably polished."
|
||||
icon_state = "laceups"
|
||||
|
||||
/obj/item/clothing/under/rank/centcom/representative
|
||||
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Ensign\" and bears \"N.C.V. Fearless CV-286\" on the left shounder."
|
||||
name = "\improper NanoTrasen Navy Uniform"
|
||||
icon_state = "officer"
|
||||
item_state = "g_suit"
|
||||
color = "officer"
|
||||
displays_id = 0
|
||||
|
||||
/obj/item/clothing/under/rank/centcom/officer
|
||||
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Lieutenant Commander\" and bears \"N.C.V. Fearless CV-286\" on the left shounder."
|
||||
name = "\improper NanoTrasen Officers Uniform"
|
||||
icon_state = "officer"
|
||||
item_state = "g_suit"
|
||||
color = "officer"
|
||||
displays_id = 0
|
||||
|
||||
/obj/item/clothing/under/rank/centcom/captain
|
||||
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Captain\" and bears \"N.C.V. Fearless CV-286\" on the left shounder."
|
||||
name = "\improper NanoTrasen Captains Uniform"
|
||||
icon_state = "centcom"
|
||||
item_state = "dg_suit"
|
||||
color = "centcom"
|
||||
displays_id = 0
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 7.0 KiB |
@@ -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
|
||||
@@ -0,0 +1,117 @@
|
||||
// This system defines news that will be displayed in the course of a round.
|
||||
// Uses BYOND's type system to put everything into a nice format
|
||||
|
||||
/datum/news_announcement
|
||||
var
|
||||
round_time // time of the round at which this should be announced, in seconds
|
||||
message // body of the message
|
||||
author = "NanoTrasen Editor"
|
||||
channel_name = "Tau Ceti Daily"
|
||||
can_be_redacted = 0
|
||||
|
||||
revolution_inciting_event
|
||||
|
||||
paycuts_suspicion
|
||||
round_time = 60*10
|
||||
message = "Reports have leaked that Nanotrasen Inc. is planning to put paycuts into effect on many of its Research Stations in Tau Ceti. Apparently these research stations haven't been able to yield the expected revenue, and thus adjustments have to be made."
|
||||
author = "Unauthorized"
|
||||
|
||||
paycuts_confirmation
|
||||
round_time = 60*40
|
||||
message = "Earlier rumours about paycuts on Research Stations in the Tau Ceti system have been confirmed. Shockingly, however, the cuts will only affect lower tier personnel. Heads of Staff will, according to our sources, not be affected."
|
||||
author = "Unauthorized"
|
||||
|
||||
human_experiments
|
||||
round_time = 60*90
|
||||
message = "Unbelievable reports about human experimentation have reached our ears. According to a refugee from one of the Tau Ceti Research Stations, their station, in order to increase revenue, has refactored several of their facilities to perform experiments on live humans, including virology research, genetic manipulation, and \"feeding them to the slimes to see what happens\". Allegedly, these test subjects were neither humanified monkeys nor volunteers, but rather unqualified staff that were forced into the experiments, and reported to have died in a \"work accident\" by Nanotrasen Inc."
|
||||
author = "Unauthorized"
|
||||
|
||||
bluespace_research
|
||||
|
||||
announcement
|
||||
round_time = 60*20
|
||||
message = "The new field of research trying to explain several interesting spacetime oddities, also known as \"Bluespace Research\", has reached new heights. Of the several hundred space stations now orbiting in Tau Ceti, fifteen are now specially equipped to experiment with and research Bluespace effects. Rumours have it some of these stations even sport functional \"travel gates\" that can instantly move a whole research team to an alternate reality."
|
||||
|
||||
random_junk
|
||||
cheesy_honkers
|
||||
author = "Assistant Editor Carl Ritz"
|
||||
channel_name = "The Gibson Gazzette"
|
||||
message = "Do cheesy honkers increase risk of having a miscarriage? Several health administrations say so!"
|
||||
round_time = 60 * 15
|
||||
|
||||
net_block
|
||||
author = "Assistant Editor Carl Ritz"
|
||||
channel_name = "The Gibson Gazzette"
|
||||
message = "Several corporations banding together to block access to 'wetskrell.nt', site administrators claiming violation of net laws."
|
||||
round_time = 60 * 50
|
||||
|
||||
found_ssd
|
||||
channel_name = "Tau Ceti Daily"
|
||||
author = "Doctor Eric Hanfield"
|
||||
|
||||
message = "Several people have been found unconscious at their terminals. It is thought that it was due to a lack of sleep or of simply migraines from staring at the screen too long. Camera footage reveals that many of them were playing games instead of working and their pay has been docked accordingly."
|
||||
round_time = 60 * 90
|
||||
|
||||
lotus_tree
|
||||
explosions
|
||||
channel_name = "Tau Ceti Daily"
|
||||
author = "Reporter Leland H. Howards"
|
||||
|
||||
message = "The newly-christened civillian transport Lotus Tree suffered two very large explosions near the bridge today, and there are unconfirmed reports that the death toll has passed 50. The cause of the explosions remain unknown, but there is speculation that it might have something to do with the recent change of regulation in the Moore-Lee Corporation, a major funder of the ship, when M-L announced that they were officially acknowledging inter-species marriage and providing couples with marriage tax-benefits."
|
||||
round_time = 60 * 30
|
||||
|
||||
food_riots
|
||||
breaking_news
|
||||
channel_name = "Tau Ceti Daily"
|
||||
author = "Reporter Ro'kii Ar-Raqis"
|
||||
|
||||
message = "Breaking news: Food riots have broken out throughout the Refuge asteroid colony in the Tenebrae Lupus system. This comes only hours after NanoTrasen officials announced they will no longer trade with the colony, citing the increased presence of \"hostile factions\" on the colony has made trade too dangerous to continue. NanoTrasen officials have not given any details about said factions. More on that at the top of the hour."
|
||||
round_time = 60 * 10
|
||||
|
||||
more
|
||||
channel_name = "Tau Ceti Daily"
|
||||
author = "Reporter Ro'kii Ar-Raqis"
|
||||
|
||||
message = "More on the Refuge food riots: The Refuge Council has condemned NanoTrasen's withdrawal from the colony, claiming \"there has been no increase in anti-NanoTrasen activity\", and \"\[the only] reason NanoTrasen withdrew was because the \[Tenebrae Lupus] system's Plasma deposits have been completely mined out. We have little to trade with them now\". NanoTrasen officials have denied these allegations, calling them \"further proof\" of the colony's anti-NanoTrasen stance. Meanwhile, Refuge Security has been unable to quell the riots. More on this at 6."
|
||||
round_time = 60 * 60
|
||||
|
||||
|
||||
var/global/list/newscaster_standard_feeds = list(/datum/news_announcement/bluespace_research, /datum/news_announcement/lotus_tree, /datum/news_announcement/random_junk, /datum/news_announcement/lotus_tree)
|
||||
|
||||
proc/process_newscaster()
|
||||
check_for_newscaster_updates(ticker.mode.newscaster_announcements)
|
||||
|
||||
var/global/tmp/announced_news_types = list()
|
||||
proc/check_for_newscaster_updates(type)
|
||||
for(var/subtype in typesof(type)-type)
|
||||
var/datum/news_announcement/news = new subtype()
|
||||
if(news.round_time * 10 <= world.time && !(subtype in announced_news_types))
|
||||
announced_news_types += subtype
|
||||
announce_newscaster_news(news)
|
||||
|
||||
proc/announce_newscaster_news(datum/news_announcement/news)
|
||||
|
||||
var/datum/feed_message/newMsg = new /datum/feed_message
|
||||
newMsg.author = news.author
|
||||
newMsg.is_admin_message = !news.can_be_redacted
|
||||
|
||||
newMsg.body = news.message
|
||||
|
||||
var/datum/feed_channel/sendto
|
||||
for(var/datum/feed_channel/FC in news_network.network_channels)
|
||||
if(FC.channel_name == news.channel_name)
|
||||
sendto = FC
|
||||
break
|
||||
|
||||
if(!sendto)
|
||||
sendto = new /datum/feed_channel
|
||||
sendto.channel_name = news.channel_name
|
||||
sendto.author = news.author
|
||||
sendto.locked = 1
|
||||
sendto.is_admin_channel = 1
|
||||
news_network.network_channels += sendto
|
||||
|
||||
sendto.messages += newMsg
|
||||
|
||||
for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
|
||||
NEWSCASTER.newsAlert(news.channel_name)
|
||||
+3
-3
@@ -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
|
||||
|
||||
+229
-228
@@ -17,10 +17,11 @@ 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
|
||||
|
||||
|
||||
New(turf/T,turf/O)
|
||||
A = T
|
||||
B = O
|
||||
@@ -47,29 +48,25 @@ 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
|
||||
ConnectZones(A.zone, B.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
|
||||
ConnectZones(A.zone, B.zone)
|
||||
indirect = CONNECTION_CLOSED
|
||||
|
||||
|
||||
else
|
||||
world.log << "Attempted to create connection object for non-zone tiles: [T] -> [O]"
|
||||
world.log << "Attempted to create connection object for non-zone tiles: [T] ([T.x],[T.y],[T.z]) -> [O] ([O.x],[O.y],[O.z])"
|
||||
del(src)
|
||||
|
||||
|
||||
Del()
|
||||
//remove connections from master lists.
|
||||
if(ref_B in air_master.turfs_with_connections)
|
||||
var/list/connections = air_master.turfs_with_connections[ref_B]
|
||||
connections.Remove(src)
|
||||
@@ -78,170 +75,203 @@ connection
|
||||
var/list/connections = air_master.turfs_with_connections[ref_A]
|
||||
connections.Remove(src)
|
||||
|
||||
//Ensure we delete the right values by sanity checkign right before deletion.
|
||||
Sanitize()
|
||||
|
||||
//Remove connection from current zones.
|
||||
if(A)
|
||||
if(A.zone && A.zone.connections)
|
||||
A.zone.connections.Remove(src)
|
||||
if(!A.zone.connections.len)
|
||||
del A.zone.connections
|
||||
A.zone.connections = null
|
||||
if(B)
|
||||
if(B.zone && B.zone.connections)
|
||||
B.zone.connections.Remove(src)
|
||||
if(!B.zone.connections.len)
|
||||
del B.zone.connections
|
||||
if(zone_A)
|
||||
if(zone_A && zone_A.connections)
|
||||
zone_A.connections.Remove(src)
|
||||
if(!zone_A.connections.len)
|
||||
del zone_A.connections
|
||||
if(zone_B)
|
||||
if(zone_B && zone_B.connections)
|
||||
zone_B.connections.Remove(src)
|
||||
if(!zone_B.connections.len)
|
||||
del zone_B.connections
|
||||
B.zone.connections = null
|
||||
|
||||
if(indirect != CONNECTION_CLOSED)
|
||||
if(A && A.zone)
|
||||
if(B && B.zone)
|
||||
if(B.zone in A.zone.connected_zones)
|
||||
if(A.zone.connected_zones[B.zone] > 1)
|
||||
A.zone.connected_zones[B.zone]--
|
||||
else
|
||||
A.zone.connected_zones -= B.zone
|
||||
if(A.zone.connected_zones && !A.zone.connected_zones.len)
|
||||
A.zone.connected_zones = null
|
||||
if( zone_B && (!B.zone || zone_B != B.zone) )
|
||||
if(zone_B in A.zone.connected_zones)
|
||||
if(A.zone.connected_zones[zone_B] > 1)
|
||||
A.zone.connected_zones[zone_B]--
|
||||
else
|
||||
A.zone.connected_zones -= zone_B
|
||||
if(A.zone.connected_zones && !A.zone.connected_zones.len)
|
||||
A.zone.connected_zones = null
|
||||
if(zone_A && (!A.zone || zone_A != A.zone))
|
||||
if(B && B.zone)
|
||||
if(B.zone in zone_A.connected_zones)
|
||||
if(zone_A.connected_zones[B.zone] > 1)
|
||||
zone_A.connected_zones[B.zone]--
|
||||
else
|
||||
zone_A.connected_zones -= B.zone
|
||||
if(zone_A.connected_zones && !zone_A.connected_zones.len)
|
||||
zone_A.connected_zones = null
|
||||
if( zone_B && (!B.zone || zone_B != B.zone) )
|
||||
if(zone_B in zone_A.connected_zones)
|
||||
if(zone_A.connected_zones[zone_B] > 1)
|
||||
zone_A.connected_zones[zone_B]--
|
||||
else
|
||||
zone_A.connected_zones -= zone_B
|
||||
if(zone_A.connected_zones && !zone_A.connected_zones.len)
|
||||
zone_A.connected_zones = null
|
||||
if(B && B.zone)
|
||||
if(A && A.zone)
|
||||
if(A.zone in B.zone.connected_zones)
|
||||
if(B.zone.connected_zones[A.zone] > 1)
|
||||
B.zone.connected_zones[A.zone]--
|
||||
else
|
||||
B.zone.connected_zones -= A.zone
|
||||
if(B.zone.connected_zones && !B.zone.connected_zones.len)
|
||||
B.zone.connected_zones = null
|
||||
if( zone_A && (!A.zone || zone_A != A.zone) )
|
||||
if(zone_A in B.zone.connected_zones)
|
||||
if(B.zone.connected_zones[zone_A] > 1)
|
||||
B.zone.connected_zones[zone_A]--
|
||||
else
|
||||
B.zone.connected_zones -= zone_A
|
||||
if(B.zone.connected_zones && !B.zone.connected_zones.len)
|
||||
B.zone.connected_zones = null
|
||||
if(zone_B && (!B.zone || zone_B != B.zone))
|
||||
if(A && A.zone)
|
||||
if(A.zone in zone_B.connected_zones)
|
||||
if(zone_B.connected_zones[A.zone] > 1)
|
||||
zone_B.connected_zones[A.zone]--
|
||||
else
|
||||
zone_B.connected_zones -= A.zone
|
||||
if(zone_B.connected_zones && !zone_B.connected_zones.len)
|
||||
zone_B.connected_zones = null
|
||||
if( zone_A && (!A.zone || zone_A != A.zone) )
|
||||
if(zone_A in zone_B.connected_zones)
|
||||
if(zone_B.connected_zones[zone_A] > 1)
|
||||
zone_B.connected_zones[zone_A]--
|
||||
else
|
||||
zone_B.connected_zones -= zone_A
|
||||
if(zone_B.connected_zones && !zone_B.connected_zones.len)
|
||||
zone_B.connected_zones = null
|
||||
//Disconnect zones while handling unusual conditions.
|
||||
// e.g. loss of a zone on a turf
|
||||
if(A && A.zone && B && B.zone)
|
||||
DisconnectZones(A.zone, B.zone)
|
||||
|
||||
//Finally, preform actual deletion.
|
||||
. = ..()
|
||||
|
||||
|
||||
proc/ConnectZones(var/zone/zone_1, var/zone/zone_2, open = 0)
|
||||
|
||||
//Sanity checking
|
||||
if(!istype(zone_1) || !istype(zone_2))
|
||||
return
|
||||
|
||||
//Handle zones connecting indirectly/directly.
|
||||
if(open)
|
||||
|
||||
//Create the lists if necessary.
|
||||
if(!zone_1.connected_zones)
|
||||
zone_1.connected_zones = list()
|
||||
|
||||
if(!zone_2.connected_zones)
|
||||
zone_2.connected_zones = list()
|
||||
|
||||
//Increase the number of connections between zones.
|
||||
if(zone_2 in zone_1.connected_zones)
|
||||
zone_1.connected_zones[zone_2]++
|
||||
else
|
||||
zone_1.connected_zones += zone_2
|
||||
zone_1.connected_zones[zone_2] = 1
|
||||
|
||||
if(zone_1 in zone_2.connected_zones)
|
||||
zone_2.connected_zones[zone_1]++
|
||||
else
|
||||
zone_2.connected_zones += zone_1
|
||||
zone_2.connected_zones[zone_1] = 1
|
||||
|
||||
//Handle closed connections.
|
||||
else
|
||||
|
||||
//Create the lists
|
||||
if(!zone_1.closed_connection_zones)
|
||||
zone_1.closed_connection_zones = list()
|
||||
|
||||
if(!zone_2.closed_connection_zones)
|
||||
zone_2.closed_connection_zones = list()
|
||||
|
||||
//Increment the connections.
|
||||
if(zone_2 in zone_1.closed_connection_zones)
|
||||
zone_1.closed_connection_zones[zone_2]++
|
||||
else
|
||||
zone_1.closed_connection_zones += zone_2
|
||||
zone_1.closed_connection_zones[zone_2] = 1
|
||||
|
||||
if(zone_1 in zone_2.closed_connection_zones)
|
||||
zone_2.closed_connection_zones[zone_1]++
|
||||
else
|
||||
zone_2.closed_connection_zones += zone_1
|
||||
zone_2.closed_connection_zones[zone_1] = 1
|
||||
|
||||
|
||||
proc/DisconnectZones(var/zone/zone_1, var/zone/zone_2)
|
||||
|
||||
//Sanity checking
|
||||
if(!istype(zone_1) || !istype(zone_2))
|
||||
return
|
||||
|
||||
//Handle disconnection of indirectly or directly connected zones.
|
||||
if( (zone_1 in zone_2.connected_zones) || (zone_2 in zone_1.connected_zones) )
|
||||
|
||||
//If there are more than one connection, decrement the number of connections
|
||||
//Otherwise, remove all connections between the zones.
|
||||
if(zone_1.connected_zones[zone_2] > 1)
|
||||
zone_1.connected_zones[zone_2]--
|
||||
else
|
||||
zone_1.connected_zones -= zone_2
|
||||
//remove the list if it is empty
|
||||
if(!zone_1.connected_zones.len)
|
||||
zone_1.connected_zones = null
|
||||
|
||||
//Then do the same for the other zone.
|
||||
if(zone_2.connected_zones[zone_1] > 1)
|
||||
zone_2.connected_zones[zone_1]--
|
||||
else
|
||||
zone_2.connected_zones -= zone_1
|
||||
if(!zone_2.connected_zones.len)
|
||||
zone_2.connected_zones = null
|
||||
|
||||
//Handle disconnection of closed zones.
|
||||
if( (zone_1 in zone_2.closed_connection_zones) || (zone_2 in zone_1.closed_connection_zones) )
|
||||
|
||||
//If there are more than one connection, decrement the number of connections
|
||||
//Otherwise, remove all connections between the zones.
|
||||
if(zone_1.closed_connection_zones[zone_2] > 1)
|
||||
zone_1.closed_connection_zones[zone_2]--
|
||||
else
|
||||
zone_1.closed_connection_zones -= zone_2
|
||||
//remove the list if it is empty
|
||||
if(!zone_1.closed_connection_zones.len)
|
||||
zone_1.closed_connection_zones = null
|
||||
|
||||
//Then do the same for the other zone.
|
||||
if(zone_2.closed_connection_zones[zone_1] > 1)
|
||||
zone_2.closed_connection_zones[zone_1]--
|
||||
else
|
||||
zone_2.closed_connection_zones -= zone_1
|
||||
if(!zone_2.closed_connection_zones.len)
|
||||
zone_2.closed_connection_zones = null
|
||||
|
||||
|
||||
proc/Cleanup()
|
||||
|
||||
//Check sanity: existance of turfs
|
||||
if(!A || !B)
|
||||
//world.log << "Connection removed: [A] or [B] missing entirely."
|
||||
del src
|
||||
|
||||
//Check sanity: zones are different
|
||||
if(A.zone == B.zone)
|
||||
//world.log << "Connection removed: Zones now merged."
|
||||
del src
|
||||
|
||||
//Check sanity: same turfs as before.
|
||||
if(ref_A != "\ref[A]" || ref_B != "\ref[B]")
|
||||
del src
|
||||
|
||||
//Handle zones changing on a turf.
|
||||
if((A.zone && A.zone != zone_A) || (B.zone && B.zone != zone_B))
|
||||
Sanitize()
|
||||
|
||||
//Manage sudden loss of a turfs zone. (e.g. a wall being built)
|
||||
if(!A.zone || !B.zone)
|
||||
no_zone_count++
|
||||
if(no_zone_count >= 5)
|
||||
//world.log << "Connection removed: [A] or [B] missing a zone."
|
||||
del src
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
proc/CheckPassSanity()
|
||||
Cleanup()
|
||||
if(A.zone && B.zone)
|
||||
if(A.ZAirPass(B))
|
||||
var/door_pass = A.CanPass(null,B,1.5,1)
|
||||
if(door_pass || A.CanPass(null,B,0,0))
|
||||
if(indirect == CONNECTION_CLOSED)
|
||||
//ADJUST FOR CAN CONNECT
|
||||
if(!A.zone.connected_zones)
|
||||
A.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(!B.zone.connected_zones)
|
||||
B.zone.connected_zones = list()
|
||||
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
|
||||
proc/CheckPassSanity()
|
||||
//Sanity check, first.
|
||||
Cleanup()
|
||||
|
||||
if(A.zone && B.zone)
|
||||
|
||||
//If no walls are blocking us...
|
||||
if(A.ZAirPass(B))
|
||||
//...we check to see if there is a door in the way...
|
||||
var/door_pass = A.CanPass(null,B,1.5,1)
|
||||
//...and if it is opened.
|
||||
if(door_pass || A.CanPass(null,B,0,0))
|
||||
|
||||
//Make and remove connections to let air pass.
|
||||
if(indirect == CONNECTION_CLOSED)
|
||||
DisconnectZones(A.zone, B.zone)
|
||||
ConnectZones(A.zone, B.zone, 1)
|
||||
|
||||
if(door_pass)
|
||||
indirect = CONNECTION_DIRECT
|
||||
else if(!door_pass)
|
||||
indirect = CONNECTION_INDIRECT
|
||||
|
||||
//The door is instead closed.
|
||||
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)
|
||||
A.zone.connected_zones[B.zone]--
|
||||
else
|
||||
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
|
||||
else //If I can no longer pass air, better delete
|
||||
|
||||
DisconnectZones(A.zone, B.zone)
|
||||
ConnectZones(A.zone, B.zone)
|
||||
|
||||
//If I can no longer pass air, better delete
|
||||
else
|
||||
del src
|
||||
|
||||
proc/Sanitize()
|
||||
//If the zones change on connected turfs, update it.
|
||||
if(A.zone && A.zone != zone_A && B.zone && B.zone != zone_B)
|
||||
if(!A.zone || !B.zone)
|
||||
del src
|
||||
|
||||
//Both zones changed (wat)
|
||||
if(A.zone && A.zone != zone_A && B.zone && B.zone != zone_B)
|
||||
|
||||
//If the zones have gotten swapped
|
||||
// (do not ask me how, I am just being anal retentive about sanity)
|
||||
if(A.zone == zone_B && B.zone == zone_A)
|
||||
var/turf/temp = B
|
||||
B = A
|
||||
@@ -253,130 +283,101 @@ connection
|
||||
ref_B = temp_ref
|
||||
return
|
||||
|
||||
if(zone_A)
|
||||
if(zone_A.connections)
|
||||
zone_A.connections.Remove(src)
|
||||
if(!zone_A.connections.len)
|
||||
del zone_A.connections
|
||||
//Handle removal of connections from archived zones.
|
||||
if(zone_A && zone_A.connections)
|
||||
zone_A.connections.Remove(src)
|
||||
if(!zone_A.connections.len)
|
||||
zone_A.connections = null
|
||||
|
||||
if(indirect != CONNECTION_CLOSED)
|
||||
if(zone_A.connected_zones)
|
||||
if(zone_A.connected_zones[zone_B] > 1)
|
||||
zone_A.connected_zones[zone_B]--
|
||||
else
|
||||
zone_A.connected_zones.Remove(zone_B)
|
||||
if(zone_A.connected_zones && !zone_A.connected_zones.len)
|
||||
zone_A.connected_zones = null
|
||||
if(zone_B && zone_B.connections)
|
||||
zone_B.connections.Remove(src)
|
||||
if(!zone_B.connections.len)
|
||||
zone_B.connections = null
|
||||
|
||||
if(zone_B)
|
||||
if(zone_B.connections)
|
||||
zone_B.connections.Remove(src)
|
||||
if(!zone_B.connections.len)
|
||||
del zone_B.connections
|
||||
|
||||
if(indirect != CONNECTION_CLOSED)
|
||||
if(zone_B.connected_zones)
|
||||
if(zone_B.connected_zones[zone_A] > 1)
|
||||
zone_B.connected_zones[zone_A]--
|
||||
else
|
||||
zone_B.connected_zones.Remove(zone_A)
|
||||
if(zone_B.connected_zones && !zone_B.connected_zones.len)
|
||||
zone_B.connected_zones = null
|
||||
|
||||
if(indirect != CONNECTION_CLOSED)
|
||||
if(A.zone)
|
||||
if(!A.zone.connections)
|
||||
A.zone.connections = list()
|
||||
A.zone.connections |= src
|
||||
|
||||
if(B.zone)
|
||||
if(!B.zone.connections)
|
||||
B.zone.connections = list()
|
||||
B.zone.connections |= src
|
||||
|
||||
if(!A.zone.connected_zones)
|
||||
A.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 either zone is null, we disconnect the archived ones after cleaning up the connections.
|
||||
if(!A.zone || !B.zone)
|
||||
if(zone_A && zone_B)
|
||||
DisconnectZones(zone_B, zone_A)
|
||||
|
||||
if(!B.zone.connected_zones)
|
||||
B.zone.connected_zones = list()
|
||||
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.zone)
|
||||
zone_A = A.zone
|
||||
|
||||
if(!B.zone)
|
||||
zone_B = B.zone
|
||||
return
|
||||
|
||||
//Handle diconnection and reconnection of zones.
|
||||
if(zone_A && zone_B)
|
||||
DisconnectZones(zone_A, zone_B)
|
||||
ConnectZones(A.zone, B.zone, indirect)
|
||||
|
||||
//resetting values of archived values.
|
||||
zone_B = B.zone
|
||||
|
||||
zone_A = A.zone
|
||||
|
||||
|
||||
//The "A" zone changed.
|
||||
else if(A.zone && A.zone != zone_A)
|
||||
if(zone_A)
|
||||
|
||||
//Handle connection cleanup
|
||||
if(zone_A)
|
||||
if(zone_A.connections)
|
||||
zone_A.connections.Remove(src)
|
||||
if(!zone_A.connections.len)
|
||||
del zone_A.connections
|
||||
zone_A.connections = null
|
||||
|
||||
if(A.zone)
|
||||
if(!A.zone.connections)
|
||||
A.zone.connections = list()
|
||||
A.zone.connections |= src
|
||||
|
||||
if(indirect != CONNECTION_CLOSED)
|
||||
if(zone_A.connected_zones)
|
||||
if(zone_A.connected_zones[zone_B] > 1)
|
||||
zone_A.connected_zones[zone_B]--
|
||||
else
|
||||
zone_A.connected_zones.Remove(zone_B)
|
||||
if(zone_A.connected_zones && !zone_A.connected_zones.len)
|
||||
zone_A.connected_zones = null
|
||||
|
||||
if(!A.zone.connected_zones)
|
||||
A.zone.connected_zones = list()
|
||||
if(!(zone_B in A.zone.connected_zones))
|
||||
A.zone.connected_zones += zone_B
|
||||
A.zone.connected_zones[zone_B] = 1
|
||||
else
|
||||
A.zone.connected_zones[zone_B]++
|
||||
|
||||
//If the "A" zone is null, we disconnect the archived ones after cleaning up the connections.
|
||||
if(!A.zone)
|
||||
if(zone_A && zone_B)
|
||||
DisconnectZones(zone_A, zone_B)
|
||||
zone_A = A.zone
|
||||
return
|
||||
|
||||
else
|
||||
del src
|
||||
//Handle diconnection and reconnection of zones.
|
||||
if(zone_A && zone_B)
|
||||
DisconnectZones(zone_A, zone_B)
|
||||
ConnectZones(A.zone, B.zone, indirect)
|
||||
|
||||
//The "B" zone changed.
|
||||
else if(B.zone && B.zone != zone_B)
|
||||
if(zone_B)
|
||||
|
||||
//Handle connection cleanup
|
||||
if(zone_B)
|
||||
if(zone_B.connections)
|
||||
zone_B.connections.Remove(src)
|
||||
if(!zone_B.connections.len)
|
||||
del zone_B.connections
|
||||
zone_B.connections = null
|
||||
|
||||
if(B.zone)
|
||||
if(!B.zone.connections)
|
||||
B.zone.connections = list()
|
||||
B.zone.connections |= src
|
||||
|
||||
if(indirect != CONNECTION_CLOSED)
|
||||
if(zone_B.connected_zones)
|
||||
if(zone_B.connected_zones[zone_A] > 1)
|
||||
zone_B.connected_zones[zone_A]--
|
||||
else
|
||||
zone_B.connected_zones.Remove(zone_A)
|
||||
if(zone_B.connected_zones && !zone_B.connected_zones.len)
|
||||
zone_B.connected_zones = null
|
||||
|
||||
if(!B.zone.connected_zones)
|
||||
B.zone.connected_zones = list()
|
||||
if(!(zone_A in B.zone.connected_zones))
|
||||
B.zone.connected_zones += zone_A
|
||||
B.zone.connected_zones[zone_A] = 1
|
||||
else
|
||||
B.zone.connected_zones[zone_A]++
|
||||
|
||||
//If the "B" zone is null, we disconnect the archived ones after cleaning up the connections.
|
||||
if(!B.zone)
|
||||
if(zone_A && zone_B)
|
||||
DisconnectZones(zone_A, zone_B)
|
||||
zone_B = B.zone
|
||||
return
|
||||
|
||||
else
|
||||
del src
|
||||
//Handle diconnection and reconnection of zones.
|
||||
if(zone_A && zone_B)
|
||||
DisconnectZones(zone_A, zone_B)
|
||||
ConnectZones(A.zone, B.zone, indirect)
|
||||
|
||||
|
||||
#undef CONNECTION_DIRECT
|
||||
|
||||
+46
-5
@@ -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)
|
||||
@@ -36,12 +80,9 @@ zone/proc
|
||||
M << "<u>Connections: [length(connections)]</u>"
|
||||
|
||||
for(var/connection/C in connections)
|
||||
M << "[C.A] --> [C.B] [(C.indirect?"Indirect":"Direct")]"
|
||||
M << "[C.A] --> [C.B] [(C.indirect?"Open":"Closed")]"
|
||||
C.A.overlays += 'debug_connect.dmi'
|
||||
C.B.overlays += 'debug_connect.dmi'
|
||||
spawn(50)
|
||||
C.A.overlays -= 'debug_connect.dmi'
|
||||
C.B.overlays -= 'debug_connect.dmi'
|
||||
for(var/C in connections)
|
||||
if(!istype(C,/connection))
|
||||
M << "[C] (Not Connection!)"
|
||||
|
||||
+18
-178
@@ -101,12 +101,10 @@ datum
|
||||
//Geometry updates lists
|
||||
var/list/tiles_to_update = list()
|
||||
var/list/connections_to_check = list()
|
||||
var/list/rebuilds_to_consider = list()
|
||||
|
||||
var/current_cycle = 0
|
||||
var/update_delay = 5 //How long between check should it try to process atmos again.
|
||||
var/failed_ticks = 0 //How many ticks have runtimed?
|
||||
var/next_stat_check = 10
|
||||
|
||||
var/tick_progress = 0
|
||||
|
||||
@@ -137,7 +135,10 @@ datum
|
||||
|
||||
var/start_time = world.timeofday
|
||||
|
||||
var/simulated_turf_count = 0
|
||||
|
||||
for(var/turf/simulated/S in world)
|
||||
simulated_turf_count++
|
||||
if(!S.zone && !S.blocks_air)
|
||||
if(S.CanPass(null, S, 0, 0))
|
||||
new/zone(S)
|
||||
@@ -145,8 +146,12 @@ datum
|
||||
for(var/turf/simulated/S in world)
|
||||
S.update_air_properties()
|
||||
|
||||
world << "\red \b Geometry processed in [time2text(world.timeofday-start_time, "mm:ss")] minutes!"
|
||||
// spawn start()
|
||||
world << {"<font color='red'><b>Geometry initialized in [round(0.1*(world.timeofday-start_time),0.1)] seconds.</b>
|
||||
Total Simulated Turfs: [simulated_turf_count]
|
||||
Total Zones: [zones.len]
|
||||
Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_count]</font>"}
|
||||
/*
|
||||
spawn start()
|
||||
|
||||
proc/start()
|
||||
//Purpose: This is kicked off by the master controller, and controls the processing of all atmosphere.
|
||||
@@ -154,7 +159,7 @@ datum
|
||||
//Inputs: None.
|
||||
//Outputs: None.
|
||||
|
||||
/*
|
||||
|
||||
set background = 1
|
||||
|
||||
while(1)
|
||||
@@ -172,55 +177,30 @@ datum
|
||||
proc/tick()
|
||||
. = 1 //Set the default return value, for runtime detection.
|
||||
|
||||
tick_progress = "next_stat_check (atmos statistics)"
|
||||
if(current_cycle >= next_stat_check)
|
||||
var/zone/z = pick(zones)
|
||||
var/log_file = file("[time2text(world.timeofday, "statistics/DD-MM-YYYY-air.txt")]")
|
||||
log_file << "\"\The [get_area(pick(z.contents))]\",[z.air.oxygen],[z.air.nitrogen],[z.air.carbon_dioxide],[z.air.toxins],[z.air.temperature],[z.air.group_multiplier * z.air.volume]"
|
||||
next_stat_check = current_cycle + (rand(5,7)*60)
|
||||
|
||||
tick_progress = "update_air_properties"
|
||||
if(tiles_to_update.len) //If there are tiles to update, do so.
|
||||
for(var/turf/simulated/T in tiles_to_update)
|
||||
var/output = T.update_air_properties()
|
||||
if(. && T && !output)
|
||||
if(. && T && !T.update_air_properties())
|
||||
. = 0 //If a runtime occured, make sure we can sense it.
|
||||
//message_admins("ZASALERT: Unable run turf/simualted/update_air_properties()")
|
||||
tiles_to_update = list()
|
||||
|
||||
tick_progress = "reconsider_zones"
|
||||
if(rebuilds_to_consider.len)
|
||||
for(var/turf/T in rebuilds_to_consider)
|
||||
if(istype(T, /turf/simulated) && T.zone && !T.zone.rebuild)
|
||||
var/turf/simulated/other_turf = rebuilds_to_consider[T]
|
||||
if(istype(other_turf))
|
||||
ConsiderRebuild(T,other_turf)
|
||||
else if(istype(other_turf, /list))
|
||||
var/list/temp_turfs = other_turf
|
||||
for(var/turf/NT in temp_turfs)
|
||||
ConsiderRebuild(T,NT)
|
||||
else if (istype(T))
|
||||
var/turf/simulated/other_turf = rebuilds_to_consider[T]
|
||||
if(istype(other_turf))
|
||||
ConsiderRebuild(other_turf,T)
|
||||
else if(istype(other_turf, /list))
|
||||
var/list/temp_turfs = other_turf
|
||||
for(var/turf/simulated/NT in temp_turfs)
|
||||
ConsiderRebuild(NT,T)
|
||||
rebuilds_to_consider = list()
|
||||
|
||||
//Check sanity on connection objects.
|
||||
tick_progress = "connections_to_check"
|
||||
if(connections_to_check.len)
|
||||
for(var/connection/C in connections_to_check)
|
||||
C.CheckPassSanity()
|
||||
connections_to_check = list()
|
||||
|
||||
//Ensure tiles still have zones.
|
||||
tick_progress = "tiles_to_reconsider_zones"
|
||||
if(tiles_to_reconsider_zones.len)
|
||||
for(var/turf/simulated/T in tiles_to_reconsider_zones)
|
||||
if(!T.zone)
|
||||
new /zone(T)
|
||||
tiles_to_reconsider_zones = list()
|
||||
|
||||
//Process zones.
|
||||
tick_progress = "zone/process()"
|
||||
for(var/zone/Z in zones)
|
||||
if(Z.last_update < current_cycle)
|
||||
@@ -229,150 +209,10 @@ datum
|
||||
Z.last_update = current_cycle
|
||||
if(. && Z && !output)
|
||||
. = 0
|
||||
log_admin("ZASALERT: unable run zone/process(), [Z.progress]")
|
||||
message_admins("ZASALERT. ZASALERT: unable run zone/proc/process(), [Z.progress], tell someone about this!")
|
||||
|
||||
//Process fires.
|
||||
tick_progress = "active_hotspots (fire)"
|
||||
for(var/obj/fire/F in active_hotspots)
|
||||
var/output = F.process()
|
||||
if(. && F && !output)
|
||||
if(. && F && !F.process())
|
||||
. = 0
|
||||
//message_admins("ZASALERT: Unable run obj/fire/process()")
|
||||
|
||||
tick_progress = "success"
|
||||
|
||||
proc/AddToConsiderRebuild(var/turf/simulated/T, var/turf/NT)
|
||||
var/turf/existing_test = rebuilds_to_consider[T]
|
||||
var/turf/existing_test_alternate = rebuilds_to_consider[NT]
|
||||
|
||||
if(existing_test)
|
||||
if(NT == existing_test)
|
||||
return
|
||||
else if(islist(existing_test) && existing_test[NT])
|
||||
return
|
||||
|
||||
else if(existing_test_alternate)
|
||||
if(T == existing_test_alternate)
|
||||
return
|
||||
else if(islist(existing_test_alternate) && existing_test_alternate[T])
|
||||
return
|
||||
|
||||
if(istype(T))
|
||||
if(istype(existing_test))
|
||||
var/list/temp_list = list(NT = 1, existing_test = 1)
|
||||
rebuilds_to_consider[T] = temp_list
|
||||
else if(istype(existing_test, /list))
|
||||
existing_test[NT] = 1
|
||||
else
|
||||
rebuilds_to_consider[T] = NT
|
||||
|
||||
else if(istype(NT, /turf/simulated))
|
||||
if(istype(existing_test_alternate))
|
||||
var/list/temp_list = list(T = 1, existing_test_alternate = 1)
|
||||
rebuilds_to_consider[NT] = temp_list
|
||||
else if(istype(existing_test_alternate, /list))
|
||||
existing_test_alternate[T] = 1
|
||||
else
|
||||
rebuilds_to_consider[NT] = T
|
||||
|
||||
proc/ConsiderRebuild(var/turf/simulated/T, var/turf/NT)
|
||||
|
||||
if(!istype(T)) return
|
||||
//zones should naturally spread to these tiles eventually
|
||||
if(!T.zone || !NT.zone)
|
||||
return
|
||||
|
||||
if(istype(NT, /turf/simulated) && NT.zone != T.zone)
|
||||
T.zone.RemoveTurf(NT)
|
||||
if(NT.zone)
|
||||
NT.zone.RemoveTurf(T)
|
||||
return
|
||||
if(T.zone.rebuild)
|
||||
return
|
||||
|
||||
var/zone/zone = T.zone
|
||||
|
||||
var/target_dir = get_dir(T, NT)
|
||||
if(target_dir in list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
|
||||
T.zone.rebuild = 1
|
||||
return
|
||||
var/test_dir = turn(target_dir, 90)
|
||||
|
||||
var/turf/simulated/current = T
|
||||
var/turf/simulated/next
|
||||
var/stepped_back = 0
|
||||
|
||||
if( !(T.air_check_directions&test_dir || T.air_check_directions&turn(target_dir, 270)) )
|
||||
//Step back, then try to connect.
|
||||
if(!(T.air_check_directions&get_dir(NT, T)))
|
||||
zone.rebuild = 1
|
||||
return
|
||||
current = get_step(T, get_dir(NT, T))
|
||||
if(!istype(current) || !(current.air_check_directions&test_dir || current.air_check_directions&turn(target_dir, 270)) )
|
||||
zone.rebuild = 1
|
||||
return
|
||||
stepped_back = 1
|
||||
|
||||
if ( !(current.air_check_directions&test_dir) && current.air_check_directions&turn(target_dir, 270) )
|
||||
//Try to connect to the right hand side.
|
||||
var/flipped = 0
|
||||
test_dir = turn(target_dir, 270)
|
||||
|
||||
for(var/i = 1, i <= 10, i++)
|
||||
if(get_dir(current, NT) in cardinal)
|
||||
target_dir = get_dir(current, NT)
|
||||
|
||||
if(!istype(current) || !(current.air_check_directions&target_dir || current.air_check_directions&test_dir))
|
||||
if(flipped)
|
||||
zone.rebuild = 1
|
||||
return
|
||||
current = T
|
||||
test_dir = turn(target_dir, 180)
|
||||
i = 0
|
||||
target_dir = get_dir(current, NT)
|
||||
flipped = 1
|
||||
continue
|
||||
|
||||
if(current.air_check_directions&target_dir && !stepped_back)
|
||||
next = get_step(current, target_dir)
|
||||
if(!next.HasDoor())
|
||||
current = next
|
||||
|
||||
if(current.air_check_directions&test_dir && current != next)
|
||||
next = get_step(current, test_dir)
|
||||
if(!next.HasDoor())
|
||||
current = next
|
||||
|
||||
if(current == NT)
|
||||
return //We made it, yaaay~
|
||||
stepped_back = 0
|
||||
zone.rebuild = 1
|
||||
|
||||
else if ( current.air_check_directions&test_dir )
|
||||
//Try to connect to the left hand side.
|
||||
for(var/i = 1, i <= 10, i++)
|
||||
if(get_dir(current, NT) in cardinal)
|
||||
target_dir = get_dir(current, NT)
|
||||
|
||||
if(!istype(current) || !(current.air_check_directions&target_dir || current.air_check_directions&test_dir))
|
||||
zone.rebuild = 1
|
||||
return
|
||||
|
||||
if(current.air_check_directions&target_dir && !stepped_back)
|
||||
next = get_step(current, target_dir)
|
||||
if(!next.HasDoor())
|
||||
current = next
|
||||
|
||||
if(current.air_check_directions&test_dir && current != next)
|
||||
next = get_step(current, test_dir)
|
||||
if(!next.HasDoor())
|
||||
current = next
|
||||
|
||||
if(current == NT)
|
||||
return //We made it, yaaay~
|
||||
stepped_back = 0
|
||||
zone.rebuild = 1
|
||||
|
||||
else
|
||||
//FUCK IT
|
||||
zone.rebuild = 1
|
||||
tick_progress = "success"
|
||||
+123
-127
@@ -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
|
||||
+60
-108
@@ -1,29 +1,57 @@
|
||||
//Global Functions
|
||||
//Contents: FloodFill, ZMerge, ZConnect
|
||||
|
||||
//Floods outward from an initial turf to fill everywhere it's zone would reach.
|
||||
proc/FloodFill(turf/simulated/start)
|
||||
|
||||
if(!istype(start))
|
||||
return list()
|
||||
var
|
||||
list
|
||||
open = list(start)
|
||||
closed = list()
|
||||
|
||||
//The list of tiles waiting to be evaulated.
|
||||
var/list/open = list(start)
|
||||
//The list of tiles which have been evaulated.
|
||||
var/list/closed = list()
|
||||
|
||||
//Loop through the turfs in the open list in order to find which adjacent turfs should be added to the zone.
|
||||
while(open.len)
|
||||
var/turf/simulated/T = pick(open)
|
||||
|
||||
//sanity!
|
||||
if(!istype(T))
|
||||
open -= T
|
||||
continue
|
||||
|
||||
//Check all cardinal directions
|
||||
for(var/d in cardinal)
|
||||
var/turf/simulated/O = get_step(T,d)
|
||||
|
||||
//Ensure the turf is of proper type, that it is not in either list, and that air can reach it.
|
||||
if(istype(O) && !(O in open) && !(O in closed) && O.ZCanPass(T))
|
||||
|
||||
if(!O.HasDoor())
|
||||
//Handle connections from a tile with a door.
|
||||
if(T.HasDoor())
|
||||
//If they both have doors, then they are not able to connect period.
|
||||
if(O.HasDoor())
|
||||
continue
|
||||
|
||||
//Connect first to north and west
|
||||
if(d == NORTH || d == WEST)
|
||||
open += O
|
||||
|
||||
//If that fails, and north/west cannot be connected to, see if west or south can be connected instead.
|
||||
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
|
||||
|
||||
//If no doors are involved, add it immediately.
|
||||
else if(!O.HasDoor())
|
||||
open += O
|
||||
|
||||
//Handle connecting to a tile with a door.
|
||||
else
|
||||
if(d == SOUTH || d == EAST)
|
||||
//doors prefer connecting to zones to the north or west
|
||||
@@ -39,19 +67,25 @@ proc/FloodFill(turf/simulated/start)
|
||||
//If it cannot connect either to the north or west, connect it!
|
||||
closed += O
|
||||
|
||||
//This tile is now evaluated, and can be moved to the list of evaluated tiles.
|
||||
open -= T
|
||||
closed += T
|
||||
|
||||
return closed
|
||||
|
||||
|
||||
//Procedure to merge two zones together.
|
||||
proc/ZMerge(zone/A,zone/B)
|
||||
|
||||
//Sanity~
|
||||
if(!istype(A) || !istype(B))
|
||||
return
|
||||
|
||||
//Merges two zones so that they are one.
|
||||
var
|
||||
a_size = A.air.group_multiplier
|
||||
b_size = B.air.group_multiplier
|
||||
c_size = a_size + b_size
|
||||
new_contents = A.contents + B.contents
|
||||
var/a_size = A.air.group_multiplier
|
||||
var/b_size = B.air.group_multiplier
|
||||
var/c_size = a_size + b_size
|
||||
var/new_contents = A.contents + B.contents
|
||||
|
||||
//Set air multipliers to one so air represents gas per tile.
|
||||
A.air.group_multiplier = 1
|
||||
@@ -65,32 +99,28 @@ proc/ZMerge(zone/A,zone/B)
|
||||
A.air.merge(B.air)
|
||||
A.air.group_multiplier = c_size
|
||||
|
||||
//Check for connections to merge into the new zone.
|
||||
for(var/connection/C in B.connections)
|
||||
if((C.A in new_contents) && (C.B in new_contents))
|
||||
del C
|
||||
continue
|
||||
if(!A.connections) A.connections = list()
|
||||
A.connections += C
|
||||
|
||||
//Add space tiles.
|
||||
A.unsimulated_tiles += B.unsimulated_tiles
|
||||
|
||||
//Add contents.
|
||||
A.contents = new_contents
|
||||
|
||||
//Set all the zone vars.
|
||||
for(var/turf/simulated/T in B.contents)
|
||||
T.zone = A
|
||||
|
||||
for(var/connection/C in A.connections)
|
||||
//Check for connections to merge into the new zone.
|
||||
for(var/connection/C in B.connections)
|
||||
//The Cleanup proc will delete the connection if the zones are the same.
|
||||
// It will also set the zone variables correctly.
|
||||
C.Cleanup()
|
||||
|
||||
//Add space tiles.
|
||||
A.unsimulated_tiles |= B.unsimulated_tiles
|
||||
|
||||
//Add contents.
|
||||
A.contents = new_contents
|
||||
|
||||
//Remove the "B" zone, finally.
|
||||
B.SoftDelete()
|
||||
|
||||
|
||||
//Connects two zones by forming a connection object representing turfs A and 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))
|
||||
@@ -108,8 +138,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.
|
||||
@@ -119,83 +149,5 @@ proc/ZConnect(turf/simulated/A,turf/simulated/B)
|
||||
if(C && (C.B == B || C.A == B))
|
||||
return
|
||||
|
||||
new /connection(A,B)
|
||||
|
||||
/*
|
||||
proc/ZDisconnect(turf/A,turf/B)
|
||||
//Removes a zone connection. Can split zones in the case of a permanent barrier.
|
||||
|
||||
//If one of them doesn't have a zone, it might be space, so check for that.
|
||||
if(A.zone && B.zone)
|
||||
//If the two zones are different, just remove a connection.
|
||||
if(A.zone != B.zone)
|
||||
for(var/connection/C in A.zone.connections)
|
||||
if((C.A == A && C.B == B) || (C.A == B && C.B == A))
|
||||
del C
|
||||
if(C)
|
||||
C.Cleanup()
|
||||
//If they're the same, split the zone at this line.
|
||||
else
|
||||
//Preliminary checks to prevent stupidity.
|
||||
if(A == B) return
|
||||
if(A.CanPass(0,B,0,0)) return
|
||||
if(A.HasDoor(B) || B.HasDoor(A)) return
|
||||
|
||||
//Do a test fill. If turf B is still in the floodfill, then the zone isn't really split.
|
||||
var/zone/oldzone = A.zone
|
||||
var/list/test = FloodFill(A)
|
||||
if(B in test) return
|
||||
|
||||
else
|
||||
var/zone/Z = new(test,oldzone.air) //Create a new zone based on the old air and the test fill.
|
||||
|
||||
//Add connections from the old zone.
|
||||
for(var/connection/C in oldzone.connections)
|
||||
if((C.A in Z.contents) || (C.B in Z.contents))
|
||||
if(!Z.connections) Z.connections = list()
|
||||
Z.connections += C
|
||||
C.Cleanup()
|
||||
|
||||
//Check for space.
|
||||
for(var/turf/T in test)
|
||||
T.check_for_space()
|
||||
|
||||
//Make a new, identical air mixture for the other zone.
|
||||
var/datum/gas_mixture/Y_Air = new
|
||||
Y_Air.copy_from(oldzone.air)
|
||||
|
||||
var/zone/Y = new(B,Y_Air) //Make a new zone starting at B and using Y_Air.
|
||||
|
||||
//Add relevant connections from old zone.
|
||||
for(var/connection/C in oldzone.connections)
|
||||
if((C.A in Y.contents) || (C.B in Y.contents))
|
||||
if(!Y.connections) Y.connections = list()
|
||||
Y.connections += C
|
||||
C.Cleanup()
|
||||
|
||||
//Add the remaining space tiles to this zone.
|
||||
for(var/turf/space/T in oldzone.unsimulated_tiles)
|
||||
if(!(T in Z.unsimulated_tiles))
|
||||
Y.AddSpace(T)
|
||||
|
||||
oldzone.air = null
|
||||
del oldzone
|
||||
else
|
||||
if(B.zone)
|
||||
if(istype(A,/turf/space))
|
||||
B.zone.RemoveSpace(A)
|
||||
else
|
||||
for(var/connection/C in B.zone.connections)
|
||||
if((C.A == A && C.B == B) || (C.A == B && C.B == A))
|
||||
del C
|
||||
if(C)
|
||||
C.Cleanup()
|
||||
if(A.zone)
|
||||
if(istype(B,/turf/space))
|
||||
A.zone.RemoveSpace(B)
|
||||
else
|
||||
for(var/connection/C in A.zone.connections)
|
||||
if((C.A == A && C.B == B) || (C.A == B && C.B == A))
|
||||
del C
|
||||
if(C)
|
||||
C.Cleanup()*/
|
||||
//Make the connection.
|
||||
new /connection(A,B)
|
||||
+9
-7
@@ -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.
|
||||
@@ -69,8 +68,9 @@ obj/item/proc
|
||||
if(!pl_head_protected())
|
||||
if(prob(1)) suit_contamination() //Plasma can sometimes get through such an open suit.
|
||||
|
||||
if(istype(back,/obj/item/weapon/storage/backpack))
|
||||
back.contaminate()
|
||||
//Cannot wash backpacks currently.
|
||||
// if(istype(back,/obj/item/weapon/storage/backpack))
|
||||
// back.contaminate()
|
||||
|
||||
/mob/proc/pl_effects()
|
||||
|
||||
@@ -156,6 +156,8 @@ turf/Entered(obj/item/I)
|
||||
//Items that are in plasma, but not on a mob, can still be contaminated.
|
||||
if(istype(I) && vsc.plc.CLOTH_CONTAMINATION)
|
||||
var/datum/gas_mixture/env = return_air(1)
|
||||
if(!env)
|
||||
return
|
||||
if(env.toxins > MOLES_PLASMA_VISIBLE + 1)
|
||||
if(I.can_contaminate())
|
||||
I.contaminate()
|
||||
@@ -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
|
||||
|
||||
+62
-29
@@ -165,27 +165,32 @@ turf
|
||||
if(!zone) //Still no zone, the floodfill determined it is not part of a larger zone. Force a zone on it.
|
||||
new/zone(list(src))
|
||||
|
||||
if("\ref[src]" in air_master.turfs_with_connections) //Check pass sanity of the connections.
|
||||
//Check pass sanity of the connections.
|
||||
if("\ref[src]" in air_master.turfs_with_connections)
|
||||
for(var/connection/C in air_master.turfs_with_connections["\ref[src]"])
|
||||
if(!(C in air_master.connections_to_check))
|
||||
air_master.connections_to_check += C
|
||||
air_master.connections_to_check |= C
|
||||
|
||||
if(zone && !zone.rebuild)
|
||||
for(var/direction in cardinal)
|
||||
if(zone.rebuild)
|
||||
break
|
||||
|
||||
var/turf/T = get_step(src,direction)
|
||||
if(!istype(T))
|
||||
continue
|
||||
// var/list/zone/adjacent_zones = list()
|
||||
|
||||
if(air_check_directions&direction) //I can connect air in this direction
|
||||
if(!CanPass(null, T, 0, 0)) //If either block air, we must look to see if the adjacent turfs need rebuilt.
|
||||
if(!T.CanPass(null, T, 0, 0)) //Target blocks air
|
||||
//I can connect to air in this direction
|
||||
if(air_check_directions&direction)
|
||||
|
||||
//If either block air, we must look to see if the adjacent turfs need rebuilt.
|
||||
if(!CanPass(null, T, 0, 0))
|
||||
|
||||
//Target blocks air
|
||||
if(!T.CanPass(null, T, 0, 0))
|
||||
var/turf/NT = get_step(T, direction)
|
||||
|
||||
//If that turf is in my zone still, rebuild.
|
||||
if(istype(NT,/turf/simulated) && NT in zone.contents)
|
||||
air_master.AddToConsiderRebuild(src,NT)
|
||||
zone.rebuild = 1
|
||||
|
||||
//If that is an unsimulated tile in my zone, see if we need to rebuild or just remove.
|
||||
else if(istype(NT) && NT in zone.unsimulated_tiles)
|
||||
var/consider_rebuild = 0
|
||||
for(var/d in cardinal)
|
||||
@@ -194,14 +199,22 @@ turf
|
||||
consider_rebuild = 1
|
||||
break
|
||||
if(consider_rebuild)
|
||||
air_master.AddToConsiderRebuild(src,NT) //Gotta check if we need to rebuild, dammit
|
||||
zone.rebuild = 1 //Gotta check if we need to rebuild, dammit
|
||||
else
|
||||
zone.RemoveTurf(NT) //Not adjacent to anything, and unsimulated. Goodbye~
|
||||
|
||||
if(T.zone && !T.zone.rebuild) //I block air.
|
||||
//To make a closed connection through closed door.
|
||||
ZConnect(T, src)
|
||||
|
||||
//If I block air.
|
||||
else if(T.zone && !T.zone.rebuild)
|
||||
var/turf/NT = get_step(src, reverse_direction(direction))
|
||||
|
||||
//If I am splitting a zone, rebuild.
|
||||
if(istype(NT,/turf/simulated) && (NT in T.zone.contents || (NT.zone && T in NT.zone.contents)))
|
||||
air_master.AddToConsiderRebuild(T,NT)
|
||||
T.zone.rebuild = 1
|
||||
|
||||
//If NT is unsimulated, parse if I should remove it or rebuild.
|
||||
else if(istype(NT) && NT in T.zone.unsimulated_tiles)
|
||||
var/consider_rebuild = 0
|
||||
for(var/d in cardinal)
|
||||
@@ -209,30 +222,48 @@ turf
|
||||
if(istype(UT, /turf/simulated) && UT.zone == T.zone && UT.CanPass(null, NT, 0, 0)) //If we find a neighboring tile that is in the same zone, check if we need to rebuild
|
||||
consider_rebuild = 1
|
||||
break
|
||||
|
||||
//Needs rebuilt.
|
||||
if(consider_rebuild)
|
||||
air_master.AddToConsiderRebuild(T,NT) //Gotta check if we need to rebuild, dammit
|
||||
T.zone.rebuild = 1
|
||||
|
||||
//Not adjacent to anything, and unsimulated. Goodbye~
|
||||
else
|
||||
T.zone.RemoveTurf(NT) //Not adjacent to anything, and unsimulated. Goodbye~
|
||||
T.zone.RemoveTurf(NT)
|
||||
|
||||
else
|
||||
//Produce connection through open door.
|
||||
ZConnect(src,T)
|
||||
|
||||
else if(air_directions_archived&direction) //Something like a wall was built, changing the geometry.
|
||||
//Something like a wall was built, changing the geometry.
|
||||
else if(air_directions_archived&direction)
|
||||
var/turf/NT = get_step(T, direction)
|
||||
if(istype(NT,/turf/simulated) && NT in zone.contents)
|
||||
air_master.AddToConsiderRebuild(src,NT)
|
||||
|
||||
else if(istype(NT) && NT in zone.unsimulated_tiles) //Parse if we need to remove the tile, or rebuild the zone.
|
||||
//If the tile is in our own zone, and we cannot connect to it, better rebuild.
|
||||
if(istype(NT,/turf/simulated) && NT in zone.contents)
|
||||
zone.rebuild = 1
|
||||
|
||||
//Parse if we need to remove the tile, or rebuild the zone.
|
||||
else if(istype(NT) && NT in zone.unsimulated_tiles)
|
||||
var/consider_rebuild = 0
|
||||
|
||||
//Loop through all neighboring turfs to see if we should remove the turf or just rebuild.
|
||||
for(var/d in cardinal)
|
||||
var/turf/UT = get_step(NT,d)
|
||||
if(istype(UT, /turf/simulated) && UT.zone == zone && UT.CanPass(null, NT, 0, 0)) //If we find a neighboring tile that is in the same zone, check if we need to rebuild
|
||||
|
||||
//If we find a neighboring tile that is in the same zone, rebuild
|
||||
if(istype(UT, /turf/simulated) && UT.zone == zone && UT.CanPass(null, NT, 0, 0))
|
||||
consider_rebuild = 1
|
||||
break
|
||||
|
||||
//The unsimulated turf is adjacent to another one of our zone's turfs,
|
||||
// better rebuild to be sure we didn't get cut in twain
|
||||
if(consider_rebuild)
|
||||
air_master.AddToConsiderRebuild(src,NT) //Gotta check if we need to rebuild, dammit
|
||||
NT.zone.rebuild = 1
|
||||
|
||||
//Not adjacent to anything, and unsimulated. Goodbye~
|
||||
else
|
||||
zone.RemoveTurf(NT) //Not adjacent to anything, and unsimulated. Goodbye~
|
||||
zone.RemoveTurf(NT)
|
||||
|
||||
if(air_check_directions)
|
||||
processing = 1
|
||||
@@ -251,8 +282,10 @@ turf
|
||||
if(isnum(O) && O)
|
||||
if(!D.density) continue
|
||||
if(istype(D,/obj/machinery/door/window))
|
||||
if(!O) continue
|
||||
if(D.dir == get_dir(D,O)) return 1
|
||||
if(!istype(O))
|
||||
continue
|
||||
if(D.dir == get_dir(D,O))
|
||||
return 1
|
||||
else
|
||||
return 1
|
||||
|
||||
@@ -268,13 +301,13 @@ turf/proc/ZCanPass(turf/simulated/T, var/include_space = 0)
|
||||
return 0
|
||||
|
||||
for(var/obj/obstacle in src)
|
||||
if(istype(obstacle,/obj/machinery/door) && !istype(obstacle,/obj/machinery/door/window))
|
||||
if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
|
||||
continue
|
||||
if(!obstacle.CanPass(null, T, 1.5, 1))
|
||||
return 0
|
||||
|
||||
for(var/obj/obstacle in T)
|
||||
if(istype(obstacle,/obj/machinery/door) && !istype(obstacle,/obj/machinery/door/window))
|
||||
if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
|
||||
continue
|
||||
if(!obstacle.CanPass(null, src, 1.5, 1))
|
||||
return 0
|
||||
@@ -290,13 +323,13 @@ turf/proc/ZAirPass(turf/T)
|
||||
return 0
|
||||
|
||||
for(var/obj/obstacle in src)
|
||||
if(istype(obstacle,/obj/machinery/door) && !istype(obstacle,/obj/machinery/door/window))
|
||||
if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
|
||||
continue
|
||||
if(!obstacle.CanPass(null, T, 0, 0))
|
||||
return 0
|
||||
|
||||
for(var/obj/obstacle in T)
|
||||
if(istype(obstacle,/obj/machinery/door) && !istype(obstacle,/obj/machinery/door/window))
|
||||
if(istype(obstacle, /obj/machinery/door) && !obstacle:air_properties_vary_with_direction)
|
||||
continue
|
||||
if(!obstacle.CanPass(null, src, 0, 0))
|
||||
return 0
|
||||
|
||||
+94
-28
@@ -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"
|
||||
@@ -19,6 +20,7 @@ zone
|
||||
// To make sure you're not spammed to death by airflow sound effects
|
||||
tmp/playsound_cooldown = 0
|
||||
|
||||
|
||||
//CREATION AND DELETION
|
||||
New(turf/start)
|
||||
. = ..()
|
||||
@@ -52,6 +54,7 @@ zone
|
||||
//Add this zone to the global list.
|
||||
zones.Add(src)
|
||||
|
||||
|
||||
//LEGACY, DO NOT USE. Use the SoftDelete proc.
|
||||
Del()
|
||||
//Ensuring the zone list doesn't get clogged with null values.
|
||||
@@ -67,25 +70,27 @@ zone
|
||||
air = null
|
||||
. = ..()
|
||||
|
||||
|
||||
//Handles deletion via garbage collection.
|
||||
proc/SoftDelete()
|
||||
zones.Remove(src)
|
||||
air = null
|
||||
|
||||
//Ensuring the zone list doesn't get clogged with null values.
|
||||
for(var/turf/simulated/T in contents)
|
||||
RemoveTurf(T)
|
||||
air_master.tiles_to_reconsider_zones += T
|
||||
|
||||
//Removing zone connections and scheduling connection cleanup
|
||||
for(var/zone/Z in connected_zones)
|
||||
if(src in Z.connected_zones)
|
||||
Z.connected_zones.Remove(src)
|
||||
for(var/connection/C in connections)
|
||||
if(C.zone_A == src)
|
||||
C.zone_A = null
|
||||
if(C.zone_B == src)
|
||||
C.zone_B = null
|
||||
air_master.connections_to_check += C
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
//ZONE MANAGEMENT FUNCTIONS
|
||||
proc/AddTurf(turf/T)
|
||||
//Adds the turf to contents, increases the size of the zone, and sets the zone var.
|
||||
@@ -200,7 +205,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 +220,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 +249,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"
|
||||
|
||||
@@ -267,7 +274,18 @@ zone/proc/process()
|
||||
if(moles_delta > 0.1 || abs(air.temperature - Z.air.temperature) > 0.1)
|
||||
if(abs(Z.air.return_pressure() - air.return_pressure()) > vsc.airflow_lightest_pressure)
|
||||
Airflow(src,Z)
|
||||
ShareRatio( air , Z.air , connected_zones[Z] )
|
||||
var/unsimulated_boost = 0
|
||||
if(unsimulated_tiles)
|
||||
unsimulated_boost += unsimulated_tiles.len
|
||||
if(Z.unsimulated_tiles)
|
||||
unsimulated_boost += Z.unsimulated_tiles.len
|
||||
unsimulated_boost = min(3, unsimulated_boost)
|
||||
ShareRatio( air , Z.air , connected_zones[Z] + unsimulated_boost)
|
||||
|
||||
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"
|
||||
|
||||
@@ -275,12 +293,14 @@ zone/proc/process()
|
||||
//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 +326,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 )
|
||||
@@ -356,38 +381,55 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles)
|
||||
unsim_co2 += T.carbon_dioxide
|
||||
unsim_nitrogen += T.nitrogen
|
||||
unsim_plasma += T.toxins
|
||||
unsim_heat_capacity += T.heat_capacity
|
||||
|
||||
// Make sure it actually has gas in it, and use the heat capacity of that.
|
||||
// Space and unsimulated tiles do NOT have a heat capacity. Thus we don't
|
||||
// add them. This means "space is not cold", which turns out just fine in
|
||||
// gameplay terms.
|
||||
if(istype(T, /turf/simulated))
|
||||
unsim_heat_capacity += T:air.heat_capacity()
|
||||
|
||||
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
|
||||
// We use the same size for the potentially single space tile
|
||||
// as we use for the entire room. Why is this?
|
||||
// Short answer: We do not want larger rooms to depressurize more
|
||||
// slowly than small rooms, preserving our good old "hollywood-style"
|
||||
// oh-shit effect when large rooms get breached, but still having small
|
||||
// rooms remain pressurized for long enough to make escape possible.
|
||||
share_size = max(1,size - 5 + unsimulated_tiles.len)
|
||||
|
||||
//full_heat_capacity = A.heat_capacity() * size
|
||||
full_oxy = A.oxygen * size
|
||||
full_nitro = A.nitrogen * size
|
||||
full_co2 = A.carbon_dioxide * size
|
||||
full_plasma = A.toxins * 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)
|
||||
full_heat_capacity = A.heat_capacity() * 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 +439,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 +542,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'
|
||||
|
||||
+31
-6
@@ -146,11 +146,12 @@ proc/listclearnulls(list/list)
|
||||
* Sorting
|
||||
*/
|
||||
|
||||
//Reverses the order of items in the list (Turning a stack into a queue)
|
||||
/proc/reverselist(var/list/input)
|
||||
var/list/output = new/list()
|
||||
for(var/A in input)
|
||||
output += A
|
||||
//Reverses the order of items in the list
|
||||
/proc/reverselist(list/L)
|
||||
var/list/output = list()
|
||||
if(L)
|
||||
for(var/i = L.len; i >= 1; i--)
|
||||
output += L[i]
|
||||
return output
|
||||
|
||||
//Randomize: Return the list in a random order
|
||||
@@ -320,4 +321,28 @@ proc/listclearnulls(list/list)
|
||||
for(var/T in L)
|
||||
if(istype(T, type))
|
||||
i++
|
||||
return i
|
||||
return i
|
||||
|
||||
//Don't use this on lists larger than half a dozen or so
|
||||
/proc/insertion_sort_numeric_list_ascending(var/list/L)
|
||||
//world.log << "ascending len input: [L.len]"
|
||||
var/list/out = list(pop(L))
|
||||
for(var/entry in L)
|
||||
if(isnum(entry))
|
||||
var/success = 0
|
||||
for(var/i=1, i<=out.len, i++)
|
||||
if(entry <= out[i])
|
||||
success = 1
|
||||
out.Insert(i, entry)
|
||||
break
|
||||
if(!success)
|
||||
out.Add(entry)
|
||||
|
||||
//world.log << " output: [out.len]"
|
||||
return out
|
||||
|
||||
/proc/insertion_sort_numeric_list_descending(var/list/L)
|
||||
//world.log << "descending len input: [L.len]"
|
||||
var/list/out = insertion_sort_numeric_list_ascending(L)
|
||||
//world.log << " output: [out.len]"
|
||||
return reverselist(out)
|
||||
|
||||
@@ -15,6 +15,16 @@
|
||||
if (config.log_admin)
|
||||
diary << "\[[time_stamp()]]ADMIN: [text]"
|
||||
|
||||
|
||||
/proc/log_debug(text)
|
||||
if (config.log_debug)
|
||||
diary << "\[[time_stamp()]]DEBUG: [text]"
|
||||
|
||||
for(var/client/C in admins)
|
||||
if(C.prefs.toggles & CHAT_DEBUGLOGS)
|
||||
C << "DEBUG: [text]"
|
||||
|
||||
|
||||
/proc/log_game(text)
|
||||
if (config.log_game)
|
||||
diary << "\[[time_stamp()]]GAME: [text]"
|
||||
|
||||
+18
-1
@@ -140,7 +140,24 @@
|
||||
|
||||
return t_out
|
||||
|
||||
|
||||
//checks text for html tags
|
||||
//if tag is not in whitelist (var/list/paper_tag_whitelist in global.dm)
|
||||
//relpaces < with <
|
||||
proc/checkhtml(var/t)
|
||||
t = sanitize_simple(t, list("&#"="."))
|
||||
var/p = findtext(t,"<",1)
|
||||
while (p) //going through all the tags
|
||||
var/start = p++
|
||||
var/tag = copytext(t,p, p+1)
|
||||
if (tag != "/")
|
||||
while (reject_bad_text(copytext(t, p, p+1), 1))
|
||||
tag = copytext(t,start, p)
|
||||
p++
|
||||
tag = copytext(t,start+1, p)
|
||||
if (!(tag in paper_tag_whitelist)) //if it's unkown tag, disarming it
|
||||
t = copytext(t,1,start-1) + "<" + copytext(t,start+1)
|
||||
p = findtext(t,"<",p)
|
||||
return t
|
||||
/*
|
||||
* Text searches
|
||||
*/
|
||||
|
||||
@@ -1327,7 +1327,9 @@ proc/is_hot(obj/item/W as obj)
|
||||
|
||||
//Is this even used for anything besides balloons? Yes I took out the W:lit stuff because : really shouldnt be used.
|
||||
/proc/is_sharp(obj/item/W as obj) // For the record, WHAT THE HELL IS THIS METHOD OF DOING IT?
|
||||
if(W.sharp) return 1
|
||||
return ( \
|
||||
W.sharp || \
|
||||
istype(W, /obj/item/weapon/screwdriver) || \
|
||||
istype(W, /obj/item/weapon/pen) || \
|
||||
istype(W, /obj/item/weapon/weldingtool) || \
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
var/log_access = 0 // log login/logout
|
||||
var/log_say = 0 // log client say
|
||||
var/log_admin = 0 // log admin actions
|
||||
var/log_debug = 1 // log debug output
|
||||
var/log_game = 0 // log game events
|
||||
var/log_vote = 0 // log voting
|
||||
var/log_whisper = 0 // log client whisper
|
||||
@@ -193,6 +194,9 @@
|
||||
if ("log_admin")
|
||||
config.log_admin = 1
|
||||
|
||||
if ("log_debug")
|
||||
config.log_debug = text2num(value)
|
||||
|
||||
if ("log_game")
|
||||
config.log_game = 1
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -113,6 +117,7 @@ datum/controller/game_controller/proc/process()
|
||||
controller_iteration++
|
||||
|
||||
vote.process()
|
||||
process_newscaster()
|
||||
|
||||
//AIR
|
||||
|
||||
@@ -128,11 +133,12 @@ datum/controller/game_controller/proc/process()
|
||||
air_master.current_cycle++
|
||||
var/success = air_master.tick() //Changed so that a runtime does not crash the ticker.
|
||||
if(!success) //Runtimed.
|
||||
log_adminwarn("ZASALERT: air_system/tick() failed: [air_master.tick_progress]")
|
||||
air_master.failed_ticks++
|
||||
if(air_master.failed_ticks > 5)
|
||||
world << "<font color='red'><b>RUNTIMES IN ATMOS TICKER. Killing air simulation!</font></b>"
|
||||
kill_air = 1
|
||||
message_admins("ZASALERT: unable run [air_master.tick_progress], tell someone about this!")
|
||||
log_admin("ZASALERT: unable run zone/process() -- [air_master.tick_progress]")
|
||||
air_processing_killed = 1
|
||||
air_master.failed_ticks = 0
|
||||
air_cost = (world.timeofday - timer) / 10
|
||||
|
||||
|
||||
@@ -130,9 +130,10 @@ datum/shuttle_controller
|
||||
|
||||
start_location.move_contents_to(end_location, null, NORTH)
|
||||
|
||||
for(var/obj/machinery/door/D in world)
|
||||
for(var/obj/machinery/door/unpowered/D in world)
|
||||
if( get_area(D) == end_location )
|
||||
spawn(0)
|
||||
D.locked = 0
|
||||
D.open()
|
||||
|
||||
for(var/mob/M in end_location)
|
||||
@@ -291,9 +292,10 @@ datum/shuttle_controller
|
||||
// Just before it leaves, close the damn doors!
|
||||
if(timeleft == 2 || timeleft == 1)
|
||||
var/area/start_location = locate(/area/shuttle/escape/station)
|
||||
for(var/obj/machinery/door/D in start_location)
|
||||
for(var/obj/machinery/door/unpowered/shuttle/D in start_location)
|
||||
spawn(0)
|
||||
D.close()
|
||||
D.locked = 1
|
||||
|
||||
if(timeleft>0)
|
||||
return 0
|
||||
|
||||
@@ -132,6 +132,9 @@ datum/controller/vote
|
||||
restart = 1
|
||||
else
|
||||
master_mode = .
|
||||
if(!going)
|
||||
going = 1
|
||||
world << "<font color='red'><b>The round will start soon.</b></font>"
|
||||
if("crew_transfer")
|
||||
if(. == "Initiate Crew Transfer")
|
||||
init_shift_change(null, 1)
|
||||
@@ -162,7 +165,7 @@ datum/controller/vote
|
||||
|
||||
proc/initiate_vote(var/vote_type, var/initiator_key)
|
||||
if(!mode)
|
||||
if(started_time != null)
|
||||
if(started_time != null && !check_rights(R_ADMIN))
|
||||
var/next_allowed_time = (started_time + config.vote_delay)
|
||||
if(next_allowed_time > world.time)
|
||||
return 0
|
||||
@@ -194,8 +197,20 @@ datum/controller/vote
|
||||
var/text = "[capitalize(mode)] vote started by [initiator]."
|
||||
if(mode == "custom")
|
||||
text += "\n[question]"
|
||||
|
||||
log_vote(text)
|
||||
world << "<font color='purple'><b>[text]</b>\nType vote to place your votes.\nYou have [config.vote_period/10] seconds to vote.</font>"
|
||||
switch(vote_type)
|
||||
if("crew_transfer")
|
||||
world << sound('sound/voice/Serithi/Shuttlehere.ogg')
|
||||
if("gamemode")
|
||||
world << sound('sound/voice/Serithi/pretenddemoc.ogg')
|
||||
if("custom")
|
||||
world << sound('sound/voice/Serithi/weneedvote.ogg')
|
||||
if(mode == "gamemode" && going)
|
||||
going = 0
|
||||
world << "<font color='red'><b>Round start has been delayed.</b></font>"
|
||||
|
||||
time_remaining = round(config.vote_period/10)
|
||||
return 1
|
||||
return 0
|
||||
@@ -296,4 +311,4 @@ datum/controller/vote
|
||||
set name = "Vote"
|
||||
|
||||
if(vote)
|
||||
src << browse(vote.interface(client),"window=vote;can_close=0")
|
||||
src << browse(vote.interface(client),"window=vote;can_close=0")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -61,4 +61,27 @@
|
||||
summon_type = list(/obj/machinery/bot/ed209)
|
||||
summon_amt = 10
|
||||
range = 3
|
||||
newVars = list("emagged" = 1,"name" = "Wizard's Justicebot")
|
||||
newVars = list("emagged" = 1,"name" = "Wizard's Justicebot")
|
||||
|
||||
|
||||
//This was previously left in the old wizard code, not being included.
|
||||
//Wasn't sure if I should transfer it here, or to code/datums/spells.dm
|
||||
//But I decided because it is a conjuration related object it would fit better here
|
||||
//Feel free to change this, I don't know.
|
||||
/obj/effect/forcefield
|
||||
desc = "A space wizard's magic wall."
|
||||
name = "FORCEWALL"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "m_shield"
|
||||
anchored = 1.0
|
||||
opacity = 0
|
||||
density = 1
|
||||
unacidable = 1
|
||||
|
||||
|
||||
bullet_act(var/obj/item/projectile/Proj, var/def_zone)
|
||||
var/turf/T = get_turf(src.loc)
|
||||
if(T)
|
||||
for(var/mob/M in T)
|
||||
Proj.on_hit(M,M.bullet_act(Proj, def_zone))
|
||||
return
|
||||
+16
-6
@@ -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)
|
||||
|
||||
@@ -662,6 +662,24 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
|
||||
access = access_armory
|
||||
group = "Security"
|
||||
|
||||
/datum/supply_packs/shotgunammo
|
||||
name = "Shotgun shells"
|
||||
contains = list(/obj/item/ammo_casing/shotgun,
|
||||
/obj/item/ammo_casing/shotgun,
|
||||
/obj/item/ammo_casing/shotgun,
|
||||
/obj/item/ammo_casing/shotgun,
|
||||
/obj/item/ammo_casing/shotgun,
|
||||
/obj/item/ammo_casing/shotgun,
|
||||
/obj/item/ammo_casing/shotgun,
|
||||
/obj/item/ammo_casing/shotgun,
|
||||
/obj/item/ammo_casing/shotgun,
|
||||
/obj/item/ammo_casing/shotgun)
|
||||
cost = 20
|
||||
containertype = /obj/structure/closet/crate/secure
|
||||
containername = "Shotgun shells"
|
||||
access = access_armory
|
||||
group = "Security"
|
||||
|
||||
/datum/supply_packs/expenergy
|
||||
name = "Experimental energy gear crate"
|
||||
contains = list(/obj/item/clothing/suit/armor/laserproof,
|
||||
|
||||
@@ -63,6 +63,24 @@
|
||||
plant_type = 0
|
||||
growthstages = 6
|
||||
|
||||
/obj/item/seeds/plastiseed
|
||||
name = "plastellium mycelium"
|
||||
desc = "This mycelium grows into Plastellium"
|
||||
icon_state = "mycelium-plast"
|
||||
mypath = "/obj/item/seeds/plastiseed"
|
||||
species = "plastellium"
|
||||
plantname = "Plastellium"
|
||||
productname = "/obj/item/weapon/reagent_containers/food/snacks/grown/plastellium"
|
||||
lifespan = 15
|
||||
endurance = 17
|
||||
maturation = 5
|
||||
production = 6
|
||||
yield = 6
|
||||
oneharvest = 1
|
||||
potency = 20
|
||||
plant_type = 2
|
||||
growthstages = 3
|
||||
|
||||
/obj/item/seeds/replicapod
|
||||
name = "pack of replica pod seeds"
|
||||
desc = "These seeds grow into replica pods. They say these are used to harvest humans."
|
||||
@@ -413,6 +431,24 @@
|
||||
plant_type = 0
|
||||
growthstages = 6
|
||||
|
||||
/obj/item/seeds/riceseed
|
||||
name = "pack of rice seeds"
|
||||
desc = "These seeds grow into rice stalks."
|
||||
icon_state = "seed-rice"
|
||||
mypath = "/obj/item/seeds/riceseed"
|
||||
species = "rice"
|
||||
plantname = "Rice Stalks"
|
||||
productname = "/obj/item/weapon/reagent_containers/food/snacks/grown/ricestalk"
|
||||
lifespan = 25
|
||||
endurance = 15
|
||||
maturation = 6
|
||||
production = 1
|
||||
yield = 4
|
||||
potency = 5
|
||||
oneharvest = 1
|
||||
plant_type = 0
|
||||
growthstages = 4
|
||||
|
||||
/obj/item/seeds/carrotseed
|
||||
name = "pack of carrot seeds"
|
||||
desc = "These seeds grow into carrots."
|
||||
|
||||
@@ -1139,6 +1139,10 @@ proc/process_ghost_teleport_locs()
|
||||
name = "\improper Vacant Office"
|
||||
icon_state = "security"
|
||||
|
||||
/area/security/vacantoffice2
|
||||
name = "\improper Vacant Office"
|
||||
icon_state = "security"
|
||||
|
||||
/area/quartermaster
|
||||
name = "\improper Quartermasters"
|
||||
icon_state = "quart"
|
||||
|
||||
+14
-2
@@ -550,8 +550,16 @@ its easier to just keep the beam vertical.
|
||||
|
||||
/atom/Click(location,control,params)
|
||||
//world << "atom.Click() on [src] by [usr] : src.type is [src.type]"
|
||||
if(!istype(src,/obj/item/weapon/gun))
|
||||
var/acting_bad = 1 //Check for gun targeting code.
|
||||
if (istype(src,/obj/item/weapon/gun)) //Allow people to lower weapon
|
||||
acting_bad = 0
|
||||
if (istype(src, /turf) && istype(usr,/mob/living/carbon/human)) //Allow people to turn around
|
||||
var/mob/living/carbon/human/H = usr
|
||||
if (!H.equipped())
|
||||
acting_bad = 0
|
||||
if(acting_bad)
|
||||
usr.last_target_click = world.time
|
||||
|
||||
if(usr.client.buildmode)
|
||||
build_click(usr, usr.client.buildmode, location, control, params, src)
|
||||
return
|
||||
@@ -696,7 +704,11 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl
|
||||
if (in_range)
|
||||
if (!( human.restrained() || human.lying ))
|
||||
if (W)
|
||||
attackby(W,human)
|
||||
var/was_used = 0
|
||||
if(W)
|
||||
was_used = W.is_used_on(src, human)
|
||||
if(!was_used)
|
||||
attackby(W,human)
|
||||
if (W)
|
||||
W.afterattack(src, human)
|
||||
else
|
||||
|
||||
@@ -112,6 +112,7 @@ var/list/radiochannels = list(
|
||||
var/list/DEPT_FREQS = list(1351,1355,1357,1359,1213,1441,1347)
|
||||
var/const/COMM_FREQ = 1353 //command, colored gold in chat window
|
||||
var/const/SYND_FREQ = 1213
|
||||
var/const/ERT_FREQ = 1439
|
||||
|
||||
#define TRANSMISSION_WIRE 0
|
||||
#define TRANSMISSION_RADIO 1
|
||||
|
||||
+1
-1
@@ -331,7 +331,7 @@
|
||||
if(!M) return
|
||||
var/num
|
||||
var/newdna
|
||||
num = rand(1,STRUCDNASIZE-1)
|
||||
num = rand(1,UNIDNASIZE)
|
||||
M.dna.check_integrity()
|
||||
newdna = setblock(M.dna.uni_identity,num,add_zero2(num2hex(rand(1,4095),1),3),3)
|
||||
M.dna.uni_identity = newdna
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
traitorcheckloop()
|
||||
|
||||
|
||||
/*
|
||||
|
||||
/datum/game_mode/traitor/autotraitor/latespawn(mob/living/carbon/human/character)
|
||||
..()
|
||||
if(emergency_shuttle.departed)
|
||||
@@ -192,6 +192,5 @@
|
||||
//message_admins("New traitor roll failed. No new traitor.")
|
||||
//else
|
||||
//message_admins("Late Joiner does not have Be Syndicate")
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
armor = list(melee = 30, bullet = 10, laser = 5,energy = 5, bomb = 0, bio = 0, rad = 0)
|
||||
cold_protection = HEAD
|
||||
min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECITON_TEMPERATURE
|
||||
siemens_coefficient = 0
|
||||
|
||||
|
||||
/obj/item/clothing/head/culthood/alt
|
||||
@@ -58,6 +59,7 @@
|
||||
allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade)
|
||||
armor = list(melee = 50, bullet = 30, laser = 50,energy = 20, bomb = 25, bio = 10, rad = 0)
|
||||
flags_inv = HIDEJUMPSUIT
|
||||
siemens_coefficient = 0
|
||||
|
||||
/obj/item/clothing/head/magus
|
||||
name = "magus helm"
|
||||
@@ -67,6 +69,7 @@
|
||||
flags_inv = HIDEFACE
|
||||
flags = FPRINT|TABLEPASS|HEADCOVERSEYES|HEADCOVERSMOUTH|BLOCKHAIR
|
||||
armor = list(melee = 30, bullet = 30, laser = 30,energy = 20, bomb = 0, bio = 0, rad = 0)
|
||||
siemens_coefficient = 0
|
||||
|
||||
/obj/item/clothing/suit/magusred
|
||||
name = "magus robes"
|
||||
@@ -78,6 +81,7 @@
|
||||
allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade)
|
||||
armor = list(melee = 50, bullet = 30, laser = 50,energy = 20, bomb = 25, bio = 10, rad = 0)
|
||||
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT
|
||||
siemens_coefficient = 0
|
||||
|
||||
|
||||
/obj/item/clothing/head/helmet/space/cult
|
||||
@@ -86,6 +90,7 @@
|
||||
icon_state = "cult_helmet"
|
||||
item_state = "cult_helmet"
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
siemens_coefficient = 0
|
||||
|
||||
/obj/item/clothing/suit/space/cult
|
||||
name = "cult armour"
|
||||
@@ -95,4 +100,5 @@
|
||||
w_class = 3
|
||||
allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade,/obj/item/weapon/tank/emergency_oxygen)
|
||||
slowdown = 1
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
|
||||
siemens_coefficient = 0
|
||||
@@ -168,9 +168,9 @@ var/engwords = list("travel", "blood", "join", "hell", "destroy", "technology",
|
||||
proc
|
||||
fizzle()
|
||||
if(istype(src,/obj/effect/rune))
|
||||
usr.say(pick("B'ADMINES SP'WNIN SH'T","IC'IN O'OC","RO'SHA'M I'SA GRI'FF'N ME'AI","TOX'IN'S O'NM FI'RAH","IA BL'AME TOX'IN'S","FIR'A NON'AN RE'SONA","A'OI I'RS ROUA'GE","LE'OAN JU'STA SP'A'C Z'EE SH'EF","IA PT'WOBEA'RD, IA A'DMI'NEH'LP"))
|
||||
usr.say(pick("Hakkrutju gopoenjim.", "Nherasai pivroiashan.", "Firjji prhiv mazenhor.", "Tanah eh wakantahe.", "Obliyae na oraie.", "Miyf hon vnor'c.", "Wakabai hij fen juswix."))
|
||||
else
|
||||
usr.whisper(pick("B'ADMINES SP'WNIN SH'T","IC'IN O'OC","RO'SHA'M I'SA GRI'FF'N ME'AI","TOX'IN'S O'NM FI'RAH","IA BL'AME TOX'IN'S","FIR'A NON'AN RE'SONA","A'OI I'RS ROUA'GE","LE'OAN JU'STA SP'A'C Z'EE SH'EF","IA PT'WOBEA'RD, IA A'DMI'NEH'LP"))
|
||||
usr.whisper(pick("Hakkrutju gopoenjim.", "Nherasai pivroiashan.", "Firjji prhiv mazenhor.", "Tanah eh wakantahe.", "Obliyae na oraie.", "Miyf hon vnor'c.", "Wakabai hij fen juswix."))
|
||||
for (var/mob/V in viewers(src))
|
||||
V.show_message("\red The markings pulse with a small burst of light, then fall dark.", 3, "\red You hear a faint fizzle.", 2)
|
||||
return
|
||||
|
||||
@@ -107,7 +107,7 @@ var/list/sacrificed = list()
|
||||
M.visible_message("\red [M] writhes in pain as the markings below him glow a bloody red.", \
|
||||
"\red AAAAAAHHHH!.", \
|
||||
"\red You hear an anguished scream.")
|
||||
if(is_convertable_to_cult(M.mind))
|
||||
if(is_convertable_to_cult(M.mind) && !jobban_isbanned(M, "cultist"))//putting jobban check here because is_convertable uses mind as argument
|
||||
ticker.mode.add_cultist(M.mind)
|
||||
M.mind.special_role = "Cultist"
|
||||
M << "<font color=\"purple\"><b><i>Your blood pulses. Your head throbs. The world goes red. All at once you are aware of a horrible, horrible truth. The veil of reality has been ripped away and in the festering wound left behind something sinister takes root.</b></i></font>"
|
||||
@@ -202,13 +202,20 @@ var/list/sacrificed = list()
|
||||
|
||||
seer()
|
||||
if(usr.loc==src.loc)
|
||||
usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium vivira. Itonis al'ra matum!")
|
||||
if(usr.see_invisible!=0 && usr.see_invisible!=15)
|
||||
if(usr.seer==1)
|
||||
usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium viortia.")
|
||||
usr << "\red The world beyond fades from your vision."
|
||||
usr.see_invisible = SEE_INVISIBLE_LIVING
|
||||
usr.seer = 0
|
||||
else if(usr.see_invisible!=SEE_INVISIBLE_LIVING)
|
||||
usr << "\red The world beyond flashes your eyes but disappears quickly, as if something is disrupting your vision."
|
||||
usr.see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
usr.seer = 0
|
||||
else
|
||||
usr.say("Rash'tla sektath mal[pick("'","`")]zua. Zasan therium vivira. Itonis al'ra matum!")
|
||||
usr << "\red The world beyond opens to your eyes."
|
||||
usr.see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
usr.seer = 1
|
||||
usr.see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
usr.seer = 1
|
||||
return
|
||||
return fizzle()
|
||||
|
||||
@@ -310,7 +317,7 @@ var/list/sacrificed = list()
|
||||
var/S=0
|
||||
for(var/obj/effect/rune/R in orange(rad,src))
|
||||
if(R!=src)
|
||||
R:visibility=0
|
||||
R.invisibility=INVISIBILITY_OBSERVER
|
||||
S=1
|
||||
if(S)
|
||||
if(istype(src,/obj/effect/rune))
|
||||
@@ -370,6 +377,8 @@ var/list/sacrificed = list()
|
||||
break
|
||||
if(!ghost)
|
||||
return this_rune.fizzle()
|
||||
if(jobban_isbanned(ghost, "cultist"))
|
||||
return this_rune.fizzle()
|
||||
|
||||
usr.say("Gal'h'rfikk harfrandid mud[pick("'","`")]gib!")
|
||||
var/mob/living/carbon/human/dummy/D = new(this_rune.loc)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
var/required_players_secret = 0 //Minimum number of players for that game mode to be chose in Secret
|
||||
var/required_enemies = 0
|
||||
var/recommended_enemies = 0
|
||||
var/newscaster_announcements = null
|
||||
var/uplink_welcome = "Syndicate Uplink Console:"
|
||||
var/uplink_uses = 10
|
||||
var/uplink_items = {"Highly Visible and Dangerous Weapons;
|
||||
@@ -205,27 +206,42 @@ Implants;
|
||||
|
||||
/datum/game_mode/proc/send_intercept()
|
||||
var/intercepttext = "<FONT size = 3><B>Cent. Com. Update</B> Requested status information:</FONT><HR>"
|
||||
intercepttext += "<B> Cent. Com has recently been contacted by the following syndicate affiliated organisations in your area, please investigate any information you may have:</B>"
|
||||
intercepttext += "<B> In case you have misplaced your copy, attached is a list of personnel whom reliable sources™ suspect may be affiliated with the Syndicate:</B><br>"
|
||||
|
||||
var/list/possible_modes = list()
|
||||
possible_modes.Add("revolution", "wizard", "nuke", "traitor", "malf", "changeling", "cult")
|
||||
//possible_modes -= "[ticker.mode]"
|
||||
var/number = pick(2, 3)
|
||||
var/i = 0
|
||||
for(i = 0, i < number, i++)
|
||||
possible_modes.Remove(pick(possible_modes))
|
||||
|
||||
if(!intercept_hacked)
|
||||
possible_modes.Insert(rand(possible_modes.len), "[ticker.mode]")
|
||||
var/list/suspects = list()
|
||||
for(var/mob/living/carbon/human/man in player_list) if(man.client && man.mind)
|
||||
// NT relation option
|
||||
var/special_role = man.mind.special_role
|
||||
if(man.client.prefs.nanotrasen_relation == "Opposed" && prob(50) || \
|
||||
man.client.prefs.nanotrasen_relation == "Skeptical" && prob(20))
|
||||
suspects += man
|
||||
// Antags
|
||||
else if(special_role == "traitor" && prob(40) || \
|
||||
special_role == "Changeling" && prob(50) || \
|
||||
special_role == "Cultist" && prob(30) || \
|
||||
special_role == "Head Revolutionary" && prob(30))
|
||||
suspects += man
|
||||
|
||||
shuffle(possible_modes)
|
||||
// If they're a traitor or likewise, give them extra TC in exchange.
|
||||
var/obj/item/device/uplink/hidden/suplink = man.mind.find_syndicate_uplink()
|
||||
if(suplink)
|
||||
var/extra = 4
|
||||
suplink.uses += extra
|
||||
man << "\red We have received notice that enemy intelligence suspects you to be linked with us. We have thus invested significant resources to increase your uplink's capacity."
|
||||
else
|
||||
// Give them a warning!
|
||||
man << "\red They are on to you!"
|
||||
|
||||
var/datum/intercept_text/i_text = new /datum/intercept_text
|
||||
for(var/A in possible_modes)
|
||||
if(modePlayer.len == 0)
|
||||
intercepttext += i_text.build(A)
|
||||
else
|
||||
intercepttext += i_text.build(A, pick(modePlayer))
|
||||
// Some poor people who were just in the wrong place at the wrong time..
|
||||
else if(prob(10))
|
||||
suspects += man
|
||||
for(var/mob/M in suspects)
|
||||
switch(rand(1, 100))
|
||||
if(1 to 50)
|
||||
intercepttext += "Someone with the job of <b>[M.mind.assigned_role]</b> <br>"
|
||||
else
|
||||
intercepttext += "<b>[M.name]</b>, the <b>[M.mind.assigned_role]</b> <br>"
|
||||
|
||||
for (var/obj/machinery/computer/communications/comm in world)
|
||||
if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept)
|
||||
@@ -275,6 +291,7 @@ Implants;
|
||||
if(player.client.prefs.be_special & role)
|
||||
if(!jobban_isbanned(player, "Syndicate") && !jobban_isbanned(player, roletext)) //Nodrak/Carn: Antag Job-bans
|
||||
candidates += player.mind // Get a list of all the people who want to be the antagonist for this round
|
||||
log_debug("[player.key] had [roletext] enabled, so drafting them.")
|
||||
|
||||
if(restricted_jobs)
|
||||
for(var/datum/mind/player in candidates)
|
||||
@@ -302,6 +319,7 @@ Implants;
|
||||
applicant = pick(drafted)
|
||||
if(applicant)
|
||||
candidates += applicant
|
||||
log_debug("[applicant.key] was force-drafted as [roletext], because there aren't enough candidates.")
|
||||
drafted.Remove(applicant)
|
||||
|
||||
else // Not enough scrubs, ABORT ABORT ABORT
|
||||
@@ -327,7 +345,7 @@ Implants;
|
||||
if(applicant)
|
||||
candidates += applicant
|
||||
drafted.Remove(applicant)
|
||||
message_admins("[applicant.key] drafted into antagonist role against their preferences.")
|
||||
log_debug("[applicant.key] was force-drafted as [roletext], because there aren't enough candidates.")
|
||||
|
||||
else // Not enough scrubs, ABORT ABORT ABORT
|
||||
break
|
||||
@@ -336,9 +354,10 @@ Implants;
|
||||
// recommended_enemies if the number of people with that role set to yes is less than recomended_enemies,
|
||||
// Less if there are not enough valid players in the game entirely to make recommended_enemies.
|
||||
|
||||
/*
|
||||
|
||||
/datum/game_mode/proc/latespawn(var/mob)
|
||||
|
||||
/*
|
||||
/datum/game_mode/proc/check_player_role_pref(var/role, var/mob/new_player/player)
|
||||
if(player.preferences.be_special & role)
|
||||
return 1
|
||||
@@ -373,6 +392,9 @@ Implants;
|
||||
heads += player.mind
|
||||
return heads
|
||||
|
||||
/datum/game_mode/New()
|
||||
newscaster_announcements = pick(newscaster_standard_feeds)
|
||||
|
||||
//////////////////////////
|
||||
//Reports player logouts//
|
||||
//////////////////////////
|
||||
|
||||
@@ -39,7 +39,8 @@ var/global/datum/controller/gameticker/ticker
|
||||
/datum/controller/gameticker/proc/pregame()
|
||||
login_music = pick(\
|
||||
'sound/music/space.ogg',\
|
||||
'sound/music/traitor.ogg')
|
||||
'sound/music/traitor.ogg',\
|
||||
'sound/music/space_oddity.ogg') //Ground Control to Major Tom, this song is cool, what's going on?
|
||||
do
|
||||
pregame_timeleft = 180
|
||||
world << "<B><FONT color='blue'>Welcome to the pre-game lobby!</FONT></B>"
|
||||
@@ -264,6 +265,8 @@ var/global/datum/controller/gameticker/ticker
|
||||
if(player.mind.assigned_role=="AI")
|
||||
player.close_spawn_windows()
|
||||
player.AIize()
|
||||
else if(!player.mind.assigned_role)
|
||||
continue
|
||||
else
|
||||
player.create_character()
|
||||
del(player)
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
required_enemies = 3
|
||||
recommended_enemies = 3
|
||||
|
||||
uplink_welcome = "Revolutionary Uplink Console:"
|
||||
uplink_uses = 5
|
||||
|
||||
newscaster_announcements = /datum/news_announcement/revolution_inciting_event
|
||||
|
||||
var/last_command_report = 0
|
||||
var/list/heads = list()
|
||||
var/tried_to_add_revheads = 0
|
||||
|
||||
@@ -57,7 +63,7 @@
|
||||
var/datum/objective/mutiny/rp/rev_obj = new
|
||||
rev_obj.owner = rev_mind
|
||||
rev_obj.target = head_mind
|
||||
rev_obj.explanation_text = "Assassinate or capture [head_mind.name], the [head_mind.assigned_role]."
|
||||
rev_obj.explanation_text = "Assassinate, convert or capture [head_mind.name], the [head_mind.assigned_role]."
|
||||
rev_mind.objectives += rev_obj
|
||||
|
||||
update_rev_icons_added(rev_mind)
|
||||
@@ -65,6 +71,8 @@
|
||||
for(var/datum/mind/rev_mind in head_revolutionaries)
|
||||
greet_revolutionary(rev_mind)
|
||||
rev_mind.current.verbs += /mob/living/carbon/human/proc/RevConvert
|
||||
equip_traitor(rev_mind.current, 1) //changing how revs get assigned their uplink so they can get PDA uplinks. --NEO
|
||||
|
||||
modePlayer += head_revolutionaries
|
||||
spawn (rand(waittime_l, waittime_h))
|
||||
send_intercept()
|
||||
@@ -183,8 +191,7 @@
|
||||
active_revs++
|
||||
|
||||
if(active_revs == 0)
|
||||
log_admin("There are zero active head revolutionists, trying to add some..")
|
||||
message_admins("There are zero active head revolutionists, trying to add some..")
|
||||
log_debug("There are zero active heads of revolution, trying to add some..")
|
||||
var/added_heads = 0
|
||||
for(var/mob/living/carbon/human/H in world) if(H.client && H.mind && H.client.inactivity <= 10*60*20 && H.mind in revolutionaries)
|
||||
head_revolutionaries += H.mind
|
||||
@@ -210,4 +217,38 @@
|
||||
message_admins("Unable to add new heads of revolution.")
|
||||
tried_to_add_revheads = world.time + 6000 // wait 10 minutes
|
||||
|
||||
return ..()
|
||||
if(last_command_report == 0 && world.time >= 10 * 60 * 10)
|
||||
src.command_report("We are regrettably announcing that your performance has been disappointing, and we are thus forced to cut down on financial support to your station. To achieve this, the pay of all personnal, except the Heads of Staff, has been halved.")
|
||||
last_command_report = 1
|
||||
else if(last_command_report == 1 && world.time >= 10 * 60 * 30)
|
||||
src.command_report("Statistics hint that a high amount of leisure time, and associated activities, are responsible for the poor performance of many of our stations. You are to bolt and close down any leisure facilities, such as the holodeck, the theatre and the bar. Food can be distributed through vendors and the kitchen.")
|
||||
last_command_report = 2
|
||||
else if(last_command_report == 2 && world.time >= 10 * 60 * 60)
|
||||
src.command_report("It is reported that merely closing down leisure facilities has not been successful. You and your Heads of Staff are to ensure that all crew are working hard, and not wasting time or energy. Any crew caught off duty without leave from their Head of Staff are to be warned, and on repeated offence, to be brigged until the next transfer shuttle arrives, which will take them to facilities where they can be of more use.")
|
||||
last_command_report = 3
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/game_mode/revolution/rp_revolution/proc/command_report(message)
|
||||
for (var/obj/machinery/computer/communications/comm in world)
|
||||
if (!(comm.stat & (BROKEN | NOPOWER)) && comm.prints_intercept)
|
||||
var/obj/item/weapon/paper/intercept = new /obj/item/weapon/paper( comm.loc )
|
||||
intercept.name = "paper- 'Cent. Com. Announcement'"
|
||||
intercept.info = message
|
||||
|
||||
comm.messagetitle.Add("Cent. Com. Announcement")
|
||||
comm.messagetext.Add(message)
|
||||
world << sound('commandreport.ogg')
|
||||
|
||||
/datum/game_mode/revolution/rp_revolution/latespawn(mob/M)
|
||||
if(M.mind.assigned_role in command_positions)
|
||||
log_debug("Adding head kill/capture/convert objective for [M.name]")
|
||||
heads += M
|
||||
|
||||
for(var/datum/mind/rev_mind in head_revolutionaries)
|
||||
var/datum/objective/mutiny/rp/rev_obj = new
|
||||
rev_obj.owner = rev_mind
|
||||
rev_obj.target = M.mind
|
||||
rev_obj.explanation_text = "Assassinate, convert or capture [M.real_name], the [M.mind.assigned_role]."
|
||||
rev_mind.objectives += rev_obj
|
||||
rev_mind.current << "\red A new Head of Staff, [M.real_name], the [M.mind.assigned_role] has appeared. Your objectives have been updated."
|
||||
@@ -115,7 +115,7 @@
|
||||
steal_objective.find_target()
|
||||
traitor.objectives += steal_objective
|
||||
switch(rand(1,100))
|
||||
if(1 to 90)
|
||||
if(1 to 100)
|
||||
if (!(locate(/datum/objective/escape) in traitor.objectives))
|
||||
var/datum/objective/escape/escape_objective = new
|
||||
escape_objective.owner = traitor
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
escape_objective.owner = wizard
|
||||
wizard.objectives += escape_objective
|
||||
|
||||
if(61 to 85)
|
||||
if(61 to 100)
|
||||
var/datum/objective/assassinate/kill_objective = new
|
||||
kill_objective.owner = wizard
|
||||
kill_objective.find_target()
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
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/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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels,
|
||||
access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva,
|
||||
access_heads, access_construction, access_sec_doors,
|
||||
access_ce, access_RC_announce, access_keycard_auth, access_tcomsat)
|
||||
access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload)
|
||||
minimal_access = list(access_engine, access_engine_equip, access_tech_storage, access_maint_tunnels,
|
||||
access_teleporter, access_external_airlocks, access_atmospherics, access_emergency_storage, access_eva,
|
||||
access_heads, access_construction, access_sec_doors,
|
||||
access_ce, access_RC_announce, access_keycard_auth, access_tcomsat)
|
||||
access_ce, access_RC_announce, access_keycard_auth, access_tcomsat, access_ai_upload)
|
||||
minimal_player_age = 7
|
||||
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
var/title = "NOPE"
|
||||
|
||||
//Job access. The use of minimal_access or access is determined by a config setting: config.jobs_have_minimal_access
|
||||
var/minimal_access = list() //Useful for servers which prefer to only have access given to the places a job absolutely needs (Larger server population)
|
||||
var/access = list() //Useful for servers which either have fewer players, so each person needs to fill more than one role, or servers which like to give more access, so players can't hide forever in their super secure departments (I'm looking at you, chemistry!)
|
||||
var/list/minimal_access = list() //Useful for servers which prefer to only have access given to the places a job absolutely needs (Larger server population)
|
||||
var/list/access = list() //Useful for servers which either have fewer players, so each person needs to fill more than one role, or servers which like to give more access, so players can't hide forever in their super secure departments (I'm looking at you, chemistry!)
|
||||
|
||||
//Bitflags for the job
|
||||
var/flag = 0
|
||||
@@ -46,12 +46,12 @@
|
||||
|
||||
/datum/job/proc/get_access()
|
||||
if(!config) //Needed for robots.
|
||||
return src.minimal_access
|
||||
return src.minimal_access.Copy()
|
||||
|
||||
if(config.jobs_have_minimal_access)
|
||||
return src.minimal_access
|
||||
return src.minimal_access.Copy()
|
||||
else
|
||||
return src.access
|
||||
return src.access.Copy()
|
||||
|
||||
//If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1
|
||||
/datum/job/proc/player_old_enough(client/C)
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
switch(H.mind.role_alt_title)
|
||||
if("Emergency Physician")
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical(H), slot_w_uniform)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/fr_jacket(H), slot_wear_suit)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/fr_jacket(H), slot_wear_suit)
|
||||
if("Surgeon")
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical/blue(H), slot_w_uniform)
|
||||
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit)
|
||||
@@ -215,4 +215,4 @@
|
||||
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)
|
||||
return 1
|
||||
return 1
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
var/global/datum/controller/occupations/job_master
|
||||
|
||||
#define GET_RANDOM_JOB 0
|
||||
#define BE_ASSISTANT 1
|
||||
#define RETURN_TO_LOBBY 2
|
||||
|
||||
/datum/controller/occupations
|
||||
//List of all jobs
|
||||
var/list/occupations = list()
|
||||
@@ -270,9 +274,8 @@ var/global/datum/controller/occupations/job_master
|
||||
// Hand out random jobs to the people who didn't get any in the last check
|
||||
// Also makes sure that they got their preference correct
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
if(player.client.prefs.userandomjob)
|
||||
if(player.client.prefs.alternate_option == GET_RANDOM_JOB)
|
||||
GiveRandomJob(player)
|
||||
|
||||
/*
|
||||
Old job system
|
||||
for(var/level = 1 to 3)
|
||||
@@ -297,8 +300,14 @@ var/global/datum/controller/occupations/job_master
|
||||
|
||||
// For those who wanted to be assistant if their preferences were filled, here you go.
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
Debug("AC2 Assistant located, Player: [player]")
|
||||
AssignRole(player, "Assistant")
|
||||
if(player.client.prefs.alternate_option == BE_ASSISTANT)
|
||||
Debug("AC2 Assistant located, Player: [player]")
|
||||
AssignRole(player, "Assistant")
|
||||
|
||||
//For ones returning to lobby
|
||||
for(var/mob/new_player/player in unassigned)
|
||||
if(player.client.prefs.alternate_option == RETURN_TO_LOBBY)
|
||||
unassigned -= player
|
||||
return 1
|
||||
|
||||
|
||||
@@ -389,6 +398,13 @@ var/global/datum/controller/occupations/job_master
|
||||
|
||||
spawnId(H, rank, alt_title)
|
||||
H.equip_to_slot_or_del(new /obj/item/device/radio/headset(H), slot_ears)
|
||||
|
||||
//Gives glasses to the vision impaired
|
||||
if(H.disabilities & NEARSIGHTED)
|
||||
var/equipped = H.equip_to_slot_or_del(new /obj/item/clothing/glasses/regular(H), slot_glasses)
|
||||
if(equipped != 1)
|
||||
var/obj/item/clothing/glasses/G = H.glasses
|
||||
G.prescription = 1
|
||||
// H.update_icons()
|
||||
return 1
|
||||
|
||||
|
||||
@@ -45,12 +45,6 @@ var/const/ASSISTANT =(1<<13)
|
||||
|
||||
|
||||
var/list/assistant_occupations = list(
|
||||
"Assistant",
|
||||
"Atmospheric Technician",
|
||||
"Cargo Technician",
|
||||
"Chaplain",
|
||||
"Lawyer",
|
||||
"Librarian"
|
||||
)
|
||||
|
||||
|
||||
@@ -68,7 +62,6 @@ var/list/engineering_positions = list(
|
||||
"Chief Engineer",
|
||||
"Station Engineer",
|
||||
"Atmospheric Technician",
|
||||
"Roboticist"
|
||||
)
|
||||
|
||||
|
||||
@@ -85,7 +78,7 @@ var/list/science_positions = list(
|
||||
"Research Director",
|
||||
"Scientist",
|
||||
"Geneticist", //Part of both medical and science
|
||||
"Roboticist" //Part of both engineering and science
|
||||
"Roboticist"
|
||||
)
|
||||
|
||||
//BS12 EDIT
|
||||
|
||||
+943
-921
File diff suppressed because it is too large
Load Diff
@@ -136,6 +136,9 @@
|
||||
else
|
||||
can_label = 0
|
||||
|
||||
if(air_contents.temperature > PLASMA_FLASHPOINT)
|
||||
air_contents.zburn()
|
||||
|
||||
src.updateDialog()
|
||||
return
|
||||
|
||||
|
||||
@@ -129,5 +129,5 @@
|
||||
if (!target)
|
||||
src.target = loc
|
||||
|
||||
/obj/machinery/meter/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
|
||||
return
|
||||
/obj/machinery/meter/turf/attackby(var/obj/item/weapon/W as obj, var/mob/user as mob)
|
||||
return
|
||||
|
||||
@@ -19,6 +19,14 @@
|
||||
|
||||
return 1
|
||||
|
||||
initialize()
|
||||
. = ..()
|
||||
spawn()
|
||||
var/obj/machinery/atmospherics/portables_connector/port = locate() in loc
|
||||
if(port)
|
||||
connect(port)
|
||||
update_icon()
|
||||
|
||||
process()
|
||||
if(!connected_port) //only react when pipe_network will ont it do it for you
|
||||
//Allow for reactions
|
||||
@@ -135,4 +143,4 @@
|
||||
user << "\blue Tank is empty!"
|
||||
return
|
||||
|
||||
return
|
||||
return
|
||||
|
||||
+125
-133
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -225,7 +225,6 @@ text("<A href='?src=\ref[src];operation=oddbutton'>[src.oddbutton ? "Yes" : "No"
|
||||
next_dest_loc = closest_loc
|
||||
if (next_dest_loc)
|
||||
src.patrol_path = AStar(src.loc, next_dest_loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id=botcard, exclude=null)
|
||||
src.patrol_path = reverselist(src.patrol_path)
|
||||
else
|
||||
patrol_move()
|
||||
|
||||
@@ -235,7 +234,6 @@ text("<A href='?src=\ref[src];operation=oddbutton'>[src.oddbutton ? "Yes" : "No"
|
||||
spawn(0)
|
||||
if(!src || !target) return
|
||||
src.path = AStar(src.loc, src.target.loc, /turf/proc/AdjacentTurfs, /turf/proc/Distance, 0, 30)
|
||||
src.path = reverselist(src.path)
|
||||
if(src.path.len == 0)
|
||||
src.oldtarget = src.target
|
||||
src.target = null
|
||||
|
||||
@@ -615,7 +615,6 @@ Auto Patrol: []"},
|
||||
// given an optional turf to avoid
|
||||
/obj/machinery/bot/ed209/proc/calc_path(var/turf/avoid = null)
|
||||
src.path = AStar(src.loc, patrol_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id=botcard, exclude=avoid)
|
||||
src.path = reverselist(src.path)
|
||||
|
||||
|
||||
// look for a criminal in view of the bot
|
||||
|
||||
@@ -357,7 +357,6 @@
|
||||
var/turf/dest = get_step_towards(target,src) //Can't pathfind to a tray, as it is dense, so pathfind to the spot next to the tray
|
||||
|
||||
src.path = AStar(src.loc, dest, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30,id=botcard)
|
||||
src.path = reverselist(src.path)
|
||||
if(src.path.len == 0)
|
||||
for ( var/turf/spot in orange(1,target) ) //The closest one is unpathable, try the other spots
|
||||
if ( spot == dest ) //We already tried this spot
|
||||
|
||||
@@ -244,7 +244,6 @@
|
||||
src.path = AStar(src.loc, src.target.loc, /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30)
|
||||
else
|
||||
src.path = AStar(src.loc, src.target, /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30)
|
||||
src.path = reverselist(src.path)
|
||||
if(src.path.len == 0)
|
||||
src.oldtarget = src.target
|
||||
src.target = null
|
||||
|
||||
@@ -299,7 +299,6 @@
|
||||
if(src.patient && src.path.len == 0 && (get_dist(src,src.patient) > 1))
|
||||
spawn(0)
|
||||
src.path = AStar(src.loc, get_turf(src.patient), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 30,id=botcard)
|
||||
src.path = reverselist(src.path)
|
||||
if(src.path.len == 0)
|
||||
src.oldpatient = src.patient
|
||||
src.patient = null
|
||||
|
||||
@@ -706,7 +706,8 @@
|
||||
// given an optional turf to avoid
|
||||
/obj/machinery/bot/mulebot/proc/calc_path(var/turf/avoid = null)
|
||||
src.path = AStar(src.loc, src.target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 250, id=botcard, exclude=avoid)
|
||||
src.path = reverselist(src.path)
|
||||
if(!src.path)
|
||||
src.path = list()
|
||||
|
||||
|
||||
// sets the current destination
|
||||
|
||||
@@ -583,7 +583,6 @@ Auto Patrol: []"},
|
||||
// given an optional turf to avoid
|
||||
/obj/machinery/bot/secbot/proc/calc_path(var/turf/avoid = null)
|
||||
src.path = AStar(src.loc, patrol_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id=botcard, exclude=avoid)
|
||||
src.path = reverselist(src.path)
|
||||
|
||||
|
||||
// look for a criminal in view of the bot
|
||||
|
||||
@@ -197,6 +197,7 @@
|
||||
if(H.dna)
|
||||
H.dna.mutantrace = mrace
|
||||
H.update_mutantrace()
|
||||
H.update_mutantrace_languages()
|
||||
H.suiciding = 0
|
||||
src.attempting = 0
|
||||
return 1
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -194,6 +194,10 @@
|
||||
name = "Circuit board (Mining Shuttle)"
|
||||
build_path = "/obj/machinery/computer/mining_shuttle"
|
||||
origin_tech = "programming=2"
|
||||
/obj/item/weapon/circuitboard/research_shuttle
|
||||
name = "Circuit board (Research Shuttle)"
|
||||
build_path = "/obj/machinery/computer/research_shuttle"
|
||||
origin_tech = "programming=2"
|
||||
/obj/item/weapon/circuitboard/HolodeckControl // Not going to let people get this, but it's just here for future
|
||||
name = "Circuit board (Holodeck Control)"
|
||||
build_path = "/obj/machinery/computer/HolodeckControl"
|
||||
|
||||
@@ -122,15 +122,6 @@
|
||||
if(emergency_shuttle.online)
|
||||
post_status("shuttle")
|
||||
src.state = STATE_DEFAULT
|
||||
if("crewtransfer")
|
||||
src.state= STATE_DEFAULT
|
||||
if(src.authenticated)
|
||||
src.state = STATE_CREWTRANSFER
|
||||
if("crewtransfer2")
|
||||
if(src.authenticated)
|
||||
init_shift_change(usr) //key difference here
|
||||
if(emergency_shuttle.online)
|
||||
post_status("shuttle")
|
||||
if("cancelshuttle")
|
||||
src.state = STATE_DEFAULT
|
||||
if(src.authenticated)
|
||||
@@ -323,7 +314,6 @@
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=cancelshuttle'>Cancel Shuttle Call</A> \]"
|
||||
else
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=callshuttle'>Call Emergency Shuttle</A> \]"
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=crewtransfer'>Initiate Crew Transfer</A> \]"
|
||||
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=status'>Set Status Display</A> \]"
|
||||
else
|
||||
@@ -331,8 +321,6 @@
|
||||
dat += "<BR>\[ <A HREF='?src=\ref[src];operation=messagelist'>Message List</A> \]"
|
||||
if(STATE_CALLSHUTTLE)
|
||||
dat += "Are you sure you want to call the shuttle? \[ <A HREF='?src=\ref[src];operation=callshuttle2'>OK</A> | <A HREF='?src=\ref[src];operation=main'>Cancel</A> \]"
|
||||
if(STATE_CREWTRANSFER) // this is the shiftchage screen.
|
||||
dat += "Are you sure you want to initiate a crew transfer? This will call the shuttle. \[ <a HREF='?src=\ref[src];operation=crewtransfer2'>OK</a> | <A HREF='?src=\ref[src];operation=main'>Cancel</A> \]"
|
||||
if(STATE_CANCELSHUTTLE)
|
||||
dat += "Are you sure you want to cancel the shuttle? \[ <A HREF='?src=\ref[src];operation=cancelshuttle2'>OK</A> | <A HREF='?src=\ref[src];operation=main'>Cancel</A> \]"
|
||||
if(STATE_MESSAGELIST)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
/obj/machinery/computer/crew/update_icon()
|
||||
|
||||
if(stat & BROKEN)
|
||||
icon_state = "broken"
|
||||
icon_state = "crewb"
|
||||
else
|
||||
if(stat & NOPOWER)
|
||||
src.icon_state = "c_unpowered"
|
||||
|
||||
@@ -1169,7 +1169,7 @@ About the new airlock wires panel:
|
||||
return
|
||||
|
||||
src.add_fingerprint(user)
|
||||
if((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && src.density))
|
||||
if((istype(C, /obj/item/weapon/weldingtool) && !( src.operating > 0 ) && src.density))
|
||||
var/obj/item/weapon/weldingtool/W = C
|
||||
if(W.remove_fuel(0,user))
|
||||
if(!src.welded)
|
||||
@@ -1198,7 +1198,7 @@ About the new airlock wires panel:
|
||||
beingcrowbarred = 1 //derp, Agouri
|
||||
else
|
||||
beingcrowbarred = 0
|
||||
if( beingcrowbarred && (density && welded && !operating && src.p_open && (!src.arePowerSystemsOn() || stat & NOPOWER) && !src.locked) )
|
||||
if( beingcrowbarred && (operating == -1 || density && welded && operating != 1 && src.p_open && (!src.arePowerSystemsOn() || stat & NOPOWER) && !src.locked) )
|
||||
playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
|
||||
user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove electronics from the airlock assembly.")
|
||||
if(do_after(user,40))
|
||||
@@ -1243,6 +1243,9 @@ About the new airlock wires panel:
|
||||
ae = electronics
|
||||
electronics = null
|
||||
ae.loc = src.loc
|
||||
if(operating == -1)
|
||||
ae.icon_state = "door_electronics_smoked"
|
||||
operating = 0
|
||||
|
||||
del(src)
|
||||
return
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
var/glass = 0
|
||||
var/normalspeed = 1
|
||||
var/heat_proof = 0 // For glass airlocks/opacity firedoors
|
||||
var/air_properties_vary_with_direction = 0
|
||||
|
||||
/obj/machinery/door/New()
|
||||
..()
|
||||
@@ -78,6 +79,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
|
||||
@@ -216,7 +219,7 @@
|
||||
|
||||
/obj/machinery/door/proc/close()
|
||||
if(density) return 1
|
||||
if(operating) return
|
||||
if(operating > 0) return
|
||||
operating = 1
|
||||
|
||||
animate("closing")
|
||||
@@ -229,6 +232,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()
|
||||
|
||||
@@ -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,10 +228,13 @@
|
||||
|
||||
|
||||
/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
|
||||
heat_proof = 1
|
||||
air_properties_vary_with_direction = 1
|
||||
|
||||
CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||
if(istype(mover) && mover.checkpass(PASSGLASS))
|
||||
@@ -257,3 +265,4 @@
|
||||
if(istype(source)) air_master.tiles_to_update += source
|
||||
if(istype(destination)) air_master.tiles_to_update += destination
|
||||
return 1
|
||||
*/
|
||||
@@ -11,6 +11,7 @@
|
||||
opacity = 0
|
||||
var/obj/item/weapon/airlock_electronics/electronics = null
|
||||
explosion_resistance = 5
|
||||
air_properties_vary_with_direction = 1
|
||||
|
||||
|
||||
/obj/machinery/door/window/update_nearby_tiles(need_rebuild)
|
||||
|
||||
@@ -153,6 +153,7 @@ obj/machinery/embedded_controller/radio/access_controller
|
||||
name = "Access Console"
|
||||
density = 0
|
||||
power_channel = ENVIRON
|
||||
unacidable = 1
|
||||
|
||||
frequency = 1449
|
||||
|
||||
|
||||
@@ -262,6 +262,7 @@ obj/machinery/embedded_controller/radio/airlock_controller
|
||||
|
||||
name = "Airlock Console"
|
||||
density = 0
|
||||
unacidable = 1
|
||||
|
||||
frequency = 1449
|
||||
power_channel = ENVIRON
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
name = "Vent Controller"
|
||||
density = 0
|
||||
unacidable = 1
|
||||
|
||||
frequency = 1229
|
||||
power_channel = ENVIRON
|
||||
|
||||
@@ -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
|
||||
unacidable = 1
|
||||
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
|
||||
@@ -6,66 +6,58 @@
|
||||
icon_state = "flood00"
|
||||
density = 1
|
||||
var/on = 0
|
||||
var/obj/item/weapon/cell/cell = null
|
||||
var/use = 1
|
||||
var/obj/item/weapon/cell/high/cell = null
|
||||
var/use = 5
|
||||
var/unlocked = 0
|
||||
var/open = 0
|
||||
var/brightness_on = 999 //can't remember what the maxed out value is
|
||||
|
||||
/obj/machinery/floodlight/New()
|
||||
src.cell = new(src)
|
||||
..()
|
||||
|
||||
/obj/machinery/floodlight/proc/updateicon()
|
||||
icon_state = "flood[open ? "o" : ""][open && cell ? "b" : ""]0[on]"
|
||||
|
||||
/obj/machinery/floodlight/process()
|
||||
if (!on)
|
||||
if (luminosity)
|
||||
if(on)
|
||||
cell.charge -= use
|
||||
if(cell.charge <= 0)
|
||||
on = 0
|
||||
updateicon()
|
||||
//sd_SetLuminosity(0)
|
||||
return
|
||||
|
||||
if(!luminosity && cell && cell.charge > 0)
|
||||
//sd_SetLuminosity(10)
|
||||
updateicon()
|
||||
|
||||
if(!cell && luminosity)
|
||||
on = 0
|
||||
updateicon()
|
||||
//sd_SetLuminosity(0)
|
||||
return
|
||||
|
||||
cell.charge -= use
|
||||
|
||||
if(cell.charge <= 0 && luminosity)
|
||||
on = 0
|
||||
updateicon()
|
||||
//sd_SetLuminosity(0)
|
||||
return
|
||||
SetLuminosity(0)
|
||||
src.visible_message("<span class='warning'>[src] shuts down due to lack of power!</span>")
|
||||
return
|
||||
|
||||
/obj/machinery/floodlight/attack_hand(mob/user as mob)
|
||||
if(open && cell)
|
||||
cell.loc = usr
|
||||
cell.layer = 20
|
||||
if (user.hand )
|
||||
user.l_hand = cell
|
||||
if(ishuman(user))
|
||||
if(!user.get_active_hand())
|
||||
user.put_in_hands(cell)
|
||||
cell.loc = user.loc
|
||||
else
|
||||
user.r_hand = cell
|
||||
cell.loc = loc
|
||||
|
||||
cell.add_fingerprint(user)
|
||||
updateicon()
|
||||
cell.updateicon()
|
||||
|
||||
src.cell = null
|
||||
user << "You remove the power cell"
|
||||
updateicon()
|
||||
return
|
||||
|
||||
if(on)
|
||||
on = 0
|
||||
user << "You turn off the light"
|
||||
user << "\blue You turn off the light"
|
||||
SetLuminosity(0)
|
||||
else
|
||||
if(!cell)
|
||||
return
|
||||
if(cell.charge <= 0)
|
||||
return
|
||||
on = 1
|
||||
user << "You turn on the light"
|
||||
user << "\blue You turn on the light"
|
||||
SetLuminosity(brightness_on)
|
||||
|
||||
updateicon()
|
||||
|
||||
@@ -101,10 +93,3 @@
|
||||
cell = W
|
||||
user << "You insert the power cell."
|
||||
updateicon()
|
||||
|
||||
/obj/machinery/floodlight/New()
|
||||
src.cell = new/obj/item/weapon/cell(src)
|
||||
cell.maxcharge = 1000
|
||||
cell.charge = 1000
|
||||
..()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -99,4 +99,32 @@ obj/machinery/recharger/update_icon() //we have an update_icon() in addition to
|
||||
if(charging)
|
||||
icon_state = "recharger1"
|
||||
else
|
||||
icon_state = "recharger0"
|
||||
icon_state = "recharger0"
|
||||
|
||||
obj/machinery/recharger/wallcharger
|
||||
name = "wall recharger"
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "wrecharger0"
|
||||
|
||||
obj/machinery/recharger/wallcharger/process()
|
||||
if(stat & (NOPOWER|BROKEN) || !anchored)
|
||||
return
|
||||
|
||||
if(charging)
|
||||
if(istype(charging, /obj/item/weapon/gun/energy))
|
||||
var/obj/item/weapon/gun/energy/E = charging
|
||||
if(E.power_supply.charge < E.power_supply.maxcharge)
|
||||
E.power_supply.give(100)
|
||||
icon_state = "wrecharger1"
|
||||
use_power(250)
|
||||
else
|
||||
icon_state = "wrecharger2"
|
||||
return
|
||||
if(istype(charging, /obj/item/weapon/melee/baton))
|
||||
var/obj/item/weapon/melee/baton/B = charging
|
||||
if(B.charges < initial(B.charges))
|
||||
B.charges++
|
||||
icon_state = "wrecharger1"
|
||||
use_power(150)
|
||||
else
|
||||
icon_state = "wrecharger2"
|
||||
@@ -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]"
|
||||
|
||||
|
||||
@@ -85,6 +85,8 @@
|
||||
|
||||
M << "<B>You have joined the ranks of the Syndicate and become a traitor to the station!</B>"
|
||||
|
||||
message_admins("[N]/([N.ckey]) has accepted a traitor objective from a syndicate beacon.")
|
||||
|
||||
var/obj_count = 1
|
||||
for(var/datum/objective/OBJ in M.mind.objectives)
|
||||
M << "<B>Objective #[obj_count]</B>: [OBJ.explanation_text]"
|
||||
|
||||
@@ -148,6 +148,15 @@ var/message_delay = 0 // To make sure restarting the recentmessages list is kept
|
||||
signal.data["radio"], signal.data["message"],
|
||||
signal.data["name"], signal.data["job"],
|
||||
signal.data["realname"], signal.data["vname"],, signal.data["compression"], list(0), connection.frequency)
|
||||
|
||||
if(connection.frequency == ERT_FREQ)
|
||||
Broadcast_Message(signal.data["connection"], signal.data["mob"],
|
||||
signal.data["vmask"], signal.data["vmessage"],
|
||||
signal.data["radio"], signal.data["message"],
|
||||
signal.data["name"], signal.data["job"],
|
||||
signal.data["realname"], signal.data["vname"],, signal.data["compression"], list(0), connection.frequency)
|
||||
|
||||
|
||||
else
|
||||
if(intercept)
|
||||
Broadcast_Message(signal.data["connection"], signal.data["mob"],
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user