Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into upstream-merge-33829

# Conflicts:
#	code/modules/events/alien_infestation.dm
#	code/modules/events/spider_infestation.dm
#	code/modules/events/vent_clog.dm
#	code/modules/mob/living/simple_animal/hostile/hostile.dm
This commit is contained in:
LetterJay
2018-01-02 05:16:13 -06:00
74 changed files with 370 additions and 338 deletions

View File

@@ -129,38 +129,12 @@
#define MAX_OUTPUT_PRESSURE 4500 // (kPa) What pressure pumps and powered equipment max out at.
#define MAX_TRANSFER_RATE 200 // (L/s) Maximum speed powered equipment can work at.
//used for device_type vars; used by DEVICE_TYPE_LOOP
//used for device_type vars
#define UNARY 1
#define BINARY 2
#define TRINARY 3
#define QUATERNARY 4
//TODO: finally remove this bullshit
//this is the standard for loop used by all sorts of atmos machinery procs
#define DEVICE_TYPE_LOOP var/I in 1 to device_type
//defines for the various machinery lists
//NODE_I, AIR_I, PARENT_I are used within DEVICE_TYPE_LOOP
//nodes list - all atmos machinery
#define NODE1 nodes[1]
#define NODE2 nodes[2]
#define NODE3 nodes[3]
#define NODE4 nodes[4]
#define NODE_I nodes[I]
//airs list - components only
#define AIR1 airs[1]
#define AIR2 airs[2]
#define AIR3 airs[3]
#define AIR_I airs[I]
//parents list - components only
#define PARENT1 parents[1]
#define PARENT2 parents[2]
#define PARENT3 parents[3]
#define PARENT_I parents[I]
//TANKS
#define TANK_MELT_TEMPERATURE 1000000 //temperature in kelvins at which a tank will start to melt
#define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE) //Tank starts leaking

View File

@@ -108,6 +108,7 @@
#define AI_ON 1
#define AI_IDLE 2
#define AI_OFF 3
#define AI_Z_OFF 4
//determines if a mob can smash through it
#define ENVIRONMENT_SMASH_NONE 0

View File

@@ -70,6 +70,40 @@
#define INIT_ORDER_SQUEAK -40
#define INIT_ORDER_PERSISTENCE -100
// Subsystem fire priority, from lowest to highest priority
// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
#define FIRE_PRIORITY_IDLE_NPC 1
#define FIRE_PRIORITY_SERVER_MAINT 1
#define FIRE_PRIORITY_GARBAGE 4
#define FIRE_PRIORITY_RESEARCH 4
#define FIRE_PRIORITY_AIR 5
#define FIRE_PRIORITY_NPC 5
#define FIRE_PRIORITY_PROCESS 6
#define FIRE_PRIORITY_THROWING 6
#define FIRE_PRIORITY_FLIGHTPACKS 7
#define FIRE_PRIORITY_SPACEDRIFT 7
#define FIRE_PRIOTITY_SMOOTHING 8
#define FIRE_PRIORITY_ORBIT 8
#define FIRE_PRIORITY_OBJ 9
#define FIRE_PRIORUTY_FIELDS 9
#define FIRE_PRIORITY_ACID 9
#define FIRE_PRIOTITY_BURNING 9
#define FIRE_PRIORITY_INBOUNDS 9
#define FIRE_PRIORITY_DEFAULT 10
#define FIRE_PRIORITY_PARALLAX 11
#define FIRE_PRIORITY_NETWORKS 12
#define FIRE_PRIORITY_MOBS 13
#define FIRE_PRIORITY_TGUI 14
#define FIRE_PRIORITY_TICKER 19
#define FIRE_PRIORITY_OVERLAYS 20
#define FIRE_PRIORITY_INPUT 100 // This must always always be the max highest priority. Player input must never be lost.
// SS runlevels
#define RUNLEVEL_INIT 0

View File

@@ -22,7 +22,7 @@ GLOBAL_LIST_EMPTY(carbon_list) //all instances of /mob/living/carbon and subt
GLOBAL_LIST_EMPTY(ai_list)
GLOBAL_LIST_EMPTY(pai_list)
GLOBAL_LIST_EMPTY(available_ai_shells)
GLOBAL_LIST_INIT(simple_animals, list(list(),list(),list())) // One for each AI_* status define
GLOBAL_LIST_INIT(simple_animals, list(list(),list(),list(),list())) // One for each AI_* status define
GLOBAL_LIST_EMPTY(spidermobs) //all sentient spider mobs
GLOBAL_LIST_EMPTY(bots_list)

View File

@@ -4,7 +4,7 @@
name = "fire coderbus" //name of the subsystem
var/init_order = INIT_ORDER_DEFAULT //order of initialization. Higher numbers are initialized first, lower numbers later. Use defines in __DEFINES/subsystems.dm for easy understanding of order.
var/wait = 20 //time to wait (in deciseconds) between each call to fire(). Must be a positive integer.
var/priority = 50 //When mutiple subsystems need to run in the same tick, higher priority subsystems will run first and be given a higher share of the tick before MC_TICK_CHECK triggers a sleep
var/priority = FIRE_PRIORITY_DEFAULT //When mutiple subsystems need to run in the same tick, higher priority subsystems will run first and be given a higher share of the tick before MC_TICK_CHECK triggers a sleep
var/flags = 0 //see MC.dm in __DEFINES Most flags must be set on world start to take full effect. (You can also restart the mc to force them to process again)

View File

@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(acid)
name = "Acid"
priority = 40
priority = FIRE_PRIORITY_ACID
flags = SS_NO_INIT|SS_BACKGROUND
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME

View File

@@ -9,7 +9,7 @@
SUBSYSTEM_DEF(air)
name = "Atmospherics"
init_order = INIT_ORDER_AIR
priority = 20
priority = FIRE_PRIORITY_AIR
wait = 5
flags = SS_BACKGROUND
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME

View File

@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(fire_burning)
name = "Fire Burning"
priority = 40
priority = FIRE_PRIOTITY_BURNING
flags = SS_NO_INIT|SS_BACKGROUND
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME

View File

@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(garbage)
name = "Garbage"
priority = 15
priority = FIRE_PRIORITY_GARBAGE
wait = 2 SECONDS
flags = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY

View File

@@ -2,7 +2,7 @@ SUBSYSTEM_DEF(icon_smooth)
name = "Icon Smoothing"
init_order = INIT_ORDER_ICON_SMOOTHING
wait = 1
priority = 35
priority = FIRE_PRIOTITY_SMOOTHING
flags = SS_TICKER
var/list/smooth_queue = list()

View File

@@ -1,15 +1,21 @@
SUBSYSTEM_DEF(idlenpcpool)
name = "Idling NPC Pool"
flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND
priority = 10
flags = SS_POST_FIRE_TIMING|SS_BACKGROUND
priority = FIRE_PRIORITY_IDLE_NPC
wait = 60
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
var/list/currentrun = list()
var/static/list/idle_mobs_by_zlevel[][]
/datum/controller/subsystem/idlenpcpool/stat_entry()
var/list/idlelist = GLOB.simple_animals[AI_IDLE]
..("IdleNPCS:[idlelist.len]")
var/list/zlist = GLOB.simple_animals[AI_Z_OFF]
..("IdleNPCS:[idlelist.len]|Z:[zlist.len]")
/datum/controller/subsystem/idlenpcpool/Initialize(start_timeofday)
idle_mobs_by_zlevel = new /list(world.maxz,0)
return ..()
/datum/controller/subsystem/idlenpcpool/fire(resumed = FALSE)
@@ -24,6 +30,9 @@ SUBSYSTEM_DEF(idlenpcpool)
while(currentrun.len)
var/mob/living/simple_animal/SA = currentrun[currentrun.len]
--currentrun.len
if (!SA)
GLOB.simple_animals[AI_IDLE] -= SA
continue
if(!SA.ckey)
if(SA.stat != DEAD)
@@ -32,3 +41,4 @@ SUBSYSTEM_DEF(idlenpcpool)
SA.consider_wakeup()
if (MC_TICK_CHECK)
return

View File

@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(inbounds)
name = "Inbounds"
priority = 40
priority = FIRE_PRIORITY_INBOUNDS
flags = SS_NO_INIT
runlevels = RUNLEVEL_GAME

View File

@@ -2,7 +2,7 @@ SUBSYSTEM_DEF(input)
name = "Input"
wait = 1 //SS_TICKER means this runs every tick
flags = SS_TICKER | SS_NO_INIT
priority = 1000
priority = FIRE_PRIORITY_INPUT
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
/datum/controller/subsystem/input/fire()

View File

@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(mobs)
name = "Mobs"
priority = 100
priority = FIRE_PRIORITY_MOBS
flags = SS_KEEP_TIMING
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME

View File

@@ -6,7 +6,7 @@
SUBSYSTEM_DEF(npcpool)
name = "NPC Pool"
flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND
priority = 20
priority = FIRE_PRIORITY_NPC
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
var/list/canBeUsed = list()

View File

@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(orbit)
name = "Orbits"
priority = 35
priority = FIRE_PRIORITY_ORBIT
wait = 2
flags = SS_NO_INIT|SS_TICKER
@@ -40,5 +40,3 @@ SUBSYSTEM_DEF(orbit)
O.Check(targetloc)
if (MC_TICK_CHECK)
return

View File

@@ -2,7 +2,7 @@ SUBSYSTEM_DEF(overlays)
name = "Overlay"
flags = SS_TICKER
wait = 1
priority = 500
priority = FIRE_PRIORITY_OVERLAYS
init_order = INIT_ORDER_OVERLAY
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_SETUP

View File

@@ -2,7 +2,7 @@ SUBSYSTEM_DEF(parallax)
name = "Parallax"
wait = 2
flags = SS_POST_FIRE_TIMING | SS_BACKGROUND | SS_NO_INIT
priority = 65
priority = FIRE_PRIORITY_PARALLAX
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
var/list/currentrun

View File

@@ -1,6 +1,6 @@
PROCESSING_SUBSYSTEM_DEF(fields)
name = "Fields"
wait = 2
priority = 40
priority = FIRE_PRIORUTY_FIELDS
flags = SS_KEEP_TIMING | SS_NO_INIT
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME

View File

@@ -1,6 +1,6 @@
PROCESSING_SUBSYSTEM_DEF(flightpacks)
name = "Flightpack Movement"
priority = 30
priority = FIRE_PRIORITY_FLIGHTPACKS
wait = 2
stat_tag = "FM"
flags = SS_NO_INIT|SS_TICKER|SS_KEEP_TIMING

View File

@@ -1,6 +1,6 @@
PROCESSING_SUBSYSTEM_DEF(networks)
name = "Networks"
priority = 80
priority = FIRE_PRIORITY_NETWORKS
wait = 1
stat_tag = "NET"
flags = SS_KEEP_TIMING

View File

@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(obj)
name = "Objects"
priority = 40
priority = FIRE_PRIORITY_OBJ
flags = SS_NO_INIT
var/list/processing = list()

View File

@@ -2,7 +2,7 @@
SUBSYSTEM_DEF(processing)
name = "Processing"
priority = 25
priority = FIRE_PRIORITY_PROCESS
flags = SS_BACKGROUND|SS_POST_FIRE_TIMING|SS_NO_INIT
wait = 10

View File

@@ -1,6 +1,5 @@
PROCESSING_SUBSYSTEM_DEF(projectiles)
name = "Projectiles"
priority = 25
wait = 1
stat_tag = "PP"
flags = SS_NO_INIT|SS_TICKER|SS_KEEP_TIMING

View File

@@ -1,7 +1,6 @@
PROCESSING_SUBSYSTEM_DEF(radiation)
name = "Radiation"
flags = SS_NO_INIT | SS_BACKGROUND
priority = 25
var/list/warned_atoms = list()

View File

@@ -2,7 +2,7 @@
SUBSYSTEM_DEF(research)
name = "Research"
flags = SS_KEEP_TIMING
priority = 15 //My powergame is priority.
priority = FIRE_PRIORITY_RESEARCH
wait = 10
init_order = INIT_ORDER_RESEARCH
var/list/invalid_design_ids = list() //associative id = number of times

View File

@@ -4,7 +4,7 @@ SUBSYSTEM_DEF(server_maint)
name = "Server Tasks"
wait = 6
flags = SS_POST_FIRE_TIMING
priority = 10
priority = FIRE_PRIORITY_SERVER_MAINT
init_order = INIT_ORDER_SERVER_MAINT
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
var/list/currentrun

View File

@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(spacedrift)
name = "Space Drift"
priority = 30
priority = FIRE_PRIORITY_SPACEDRIFT
wait = 5
flags = SS_NO_INIT|SS_KEEP_TIMING
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME

View File

@@ -2,7 +2,7 @@ SUBSYSTEM_DEF(tgui)
name = "tgui"
wait = 9
flags = SS_NO_INIT
priority = 110
priority = FIRE_PRIORITY_TGUI
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
var/list/currentrun = list()

View File

@@ -3,7 +3,7 @@
SUBSYSTEM_DEF(throwing)
name = "Throwing"
priority = 25
priority = FIRE_PRIORITY_THROWING
wait = 1
flags = SS_NO_INIT|SS_KEEP_TIMING|SS_TICKER
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME

View File

@@ -4,7 +4,7 @@ SUBSYSTEM_DEF(ticker)
name = "Ticker"
init_order = INIT_ORDER_TICKER
priority = 200
priority = FIRE_PRIORITY_TICKER
flags = SS_KEEP_TIMING
runlevels = RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME

View File

@@ -27,7 +27,7 @@
if(QDELETED(temp_vent))
continue
if(temp_vent.loc.z == ZLEVEL_STATION_PRIMARY && !temp_vent.welded)
var/datum/pipeline/temp_vent_parent = temp_vent.PARENT1
var/datum/pipeline/temp_vent_parent = temp_vent.parents[1]
if(temp_vent_parent.other_atmosmch.len > 20)
vents += temp_vent

View File

@@ -133,7 +133,7 @@
else if(entry_vent)
if(get_dist(src, entry_vent) <= 1)
var/list/vents = list()
var/datum/pipeline/entry_vent_parent = entry_vent.PARENT1
var/datum/pipeline/entry_vent_parent = entry_vent.parents[1]
for(var/obj/machinery/atmospherics/components/unary/vent_pump/temp_vent in entry_vent_parent.other_atmosmch)
vents.Add(temp_vent)
if(!vents.len)

View File

@@ -13,12 +13,12 @@
//Manifolds
for (var/obj/machinery/atmospherics/pipe/manifold/pipe in GLOB.machines)
if (!pipe.NODE1 || !pipe.NODE2 || !pipe.NODE3)
if (!pipe.nodes[1] || !pipe.nodes[2] || !pipe.nodes[3])
to_chat(usr, "Unconnected [pipe.name] located at [pipe.x],[pipe.y],[pipe.z] ([get_area(pipe.loc)])")
//Pipes
for (var/obj/machinery/atmospherics/pipe/simple/pipe in GLOB.machines)
if (!pipe.NODE1 || !pipe.NODE2)
if (!pipe.nodes[1] || !pipe.nodes[2])
to_chat(usr, "Unconnected [pipe.name] located at [pipe.x],[pipe.y],[pipe.z] ([get_area(pipe.loc)])")
/client/proc/powerdebug()

View File

@@ -60,8 +60,8 @@ Pipelines + Other Objects -> Pipe network
SetInitDirections()
/obj/machinery/atmospherics/Destroy()
for(DEVICE_TYPE_LOOP)
nullifyNode(I)
for(var/i in 1 to device_type)
nullifyNode(i)
SSair.atmos_machinery -= src
@@ -79,22 +79,22 @@ Pipelines + Other Objects -> Pipe network
// Called to build a network from this node
return
/obj/machinery/atmospherics/proc/nullifyNode(I)
if(NODE_I)
var/obj/machinery/atmospherics/N = NODE_I
/obj/machinery/atmospherics/proc/nullifyNode(i)
if(nodes[i])
var/obj/machinery/atmospherics/N = nodes[i]
N.disconnect(src)
NODE_I = null
nodes[i] = null
/obj/machinery/atmospherics/proc/getNodeConnects()
var/list/node_connects = list()
node_connects.len = device_type
for(DEVICE_TYPE_LOOP)
for(var/i in 1 to device_type)
for(var/D in GLOB.cardinals)
if(D & GetInitDirections())
if(D in node_connects)
continue
node_connects[I] = D
node_connects[i] = D
break
return node_connects
@@ -109,10 +109,10 @@ Pipelines + Other Objects -> Pipe network
if(!node_connects) //for pipes where order of nodes doesn't matter
node_connects = getNodeConnects()
for(DEVICE_TYPE_LOOP)
for(var/obj/machinery/atmospherics/target in get_step(src,node_connects[I]))
if(can_be_node(target, I))
NODE_I = target
for(var/i in 1 to device_type)
for(var/obj/machinery/atmospherics/target in get_step(src,node_connects[i]))
if(can_be_node(target, i))
nodes[i] = target
break
update_icon()
@@ -171,8 +171,7 @@ Pipelines + Other Objects -> Pipe network
if(istype(reference, /obj/machinery/atmospherics/pipe))
var/obj/machinery/atmospherics/pipe/P = reference
P.destroy_network()
var/I = nodes.Find(reference)
NODE_I = null
nodes[nodes.Find(reference)] = null
update_icon()
/obj/machinery/atmospherics/update_icon()

View File

@@ -21,8 +21,8 @@
/obj/machinery/atmospherics/components/binary/circulator/proc/return_transfer_air()
var/datum/gas_mixture/air1 = AIR1
var/datum/gas_mixture/air2 = AIR2
var/datum/gas_mixture/air1 = airs[1]
var/datum/gas_mixture/air2 = airs[2]
var/output_starting_pressure = air1.return_pressure()
var/input_starting_pressure = air2.return_pressure()

View File

@@ -49,8 +49,8 @@ Acts like a normal vent, but has an input AND output.
/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/New()
..()
var/datum/gas_mixture/air1 = AIR1
var/datum/gas_mixture/air2 = AIR2
var/datum/gas_mixture/air1 = airs[1]
var/datum/gas_mixture/air2 = airs[2]
air1.volume = 1000
air2.volume = 1000
@@ -73,8 +73,8 @@ Acts like a normal vent, but has an input AND output.
if(!on)
return
var/datum/gas_mixture/air1 = AIR1
var/datum/gas_mixture/air2 = AIR2
var/datum/gas_mixture/air1 = airs[1]
var/datum/gas_mixture/air2 = airs[2]
var/datum/gas_mixture/environment = loc.return_air()
var/environment_pressure = environment.return_pressure()
@@ -99,7 +99,7 @@ Acts like a normal vent, but has an input AND output.
loc.assume_air(removed)
air_update_turf()
var/datum/pipeline/parent1 = PARENT1
var/datum/pipeline/parent1 = parents[1]
parent1.update = 1
else //external -> output
@@ -122,7 +122,7 @@ Acts like a normal vent, but has an input AND output.
air2.merge(removed)
air_update_turf()
var/datum/pipeline/parent2 = PARENT2
var/datum/pipeline/parent2 = parents[2]
parent2.update = 1
//Radio remote control

View File

@@ -41,8 +41,8 @@ Passive gate is similar to the regular pump except:
if(!on)
return
var/datum/gas_mixture/air1 = AIR1
var/datum/gas_mixture/air2 = AIR2
var/datum/gas_mixture/air1 = airs[1]
var/datum/gas_mixture/air2 = airs[2]
var/output_starting_pressure = air2.return_pressure()
var/input_starting_pressure = air1.return_pressure()

View File

@@ -50,8 +50,8 @@ Thus, the two variables affect pump operation are set in New():
if(!on || !is_operational())
return
var/datum/gas_mixture/air1 = AIR1
var/datum/gas_mixture/air2 = AIR2
var/datum/gas_mixture/air1 = airs[1]
var/datum/gas_mixture/air2 = airs[2]
var/output_starting_pressure = air2.return_pressure()

View File

@@ -31,7 +31,7 @@ It's like a regular ol' straight pipe, but you can turn it on and off.
open = TRUE
update_icon_nopipes()
update_parents()
var/datum/pipeline/parent1 = PARENT1
var/datum/pipeline/parent1 = parents[1]
parent1.reconcile_air()
investigate_log("was opened by [usr ? key_name(usr) : "a remote signal"]", INVESTIGATE_ATMOS)

View File

@@ -48,8 +48,8 @@ Thus, the two variables affect pump operation are set in New():
if(!on || !is_operational())
return
var/datum/gas_mixture/air1 = AIR1
var/datum/gas_mixture/air2 = AIR2
var/datum/gas_mixture/air1 = airs[1]
var/datum/gas_mixture/air2 = airs[2]
// Pump mechanism just won't do anything if the pressure is too high/too low
@@ -150,7 +150,7 @@ Thus, the two variables affect pump operation are set in New():
on = !on
if("set_transfer_rate" in signal.data)
var/datum/gas_mixture/air1 = AIR1
var/datum/gas_mixture/air1 = airs[1]
transfer_rate = CLAMP(text2num(signal.data["set_transfer_rate"]),0,air1.volume)
if(on != old_on)

View File

@@ -15,10 +15,10 @@ On top of that, now people can add component-speciic procs/vars if they want!
airs = new(device_type)
..()
for(DEVICE_TYPE_LOOP)
for(var/i in 1 to device_type)
var/datum/gas_mixture/A = new
A.volume = 200
AIR_I = A
airs[i] = A
/*
Iconnery
*/
@@ -42,9 +42,9 @@ Iconnery
var/connected = 0 //Direction bitset
for(DEVICE_TYPE_LOOP) //adds intact pieces
if(NODE_I)
connected |= icon_addintact(NODE_I)
for(var/i in 1 to device_type) //adds intact pieces
if(nodes[i])
connected |= icon_addintact(nodes[i])
icon_addbroken(connected) //adds broken pieces
@@ -53,52 +53,45 @@ Iconnery
Pipenet stuff; housekeeping
*/
/obj/machinery/atmospherics/components/nullifyNode(I)
/obj/machinery/atmospherics/components/nullifyNode(i)
..()
if(NODE_I)
nullifyPipenet(PARENT_I)
qdel(AIR_I)
AIR_I = null
if(nodes[i])
nullifyPipenet(parents[i])
QDEL_NULL(airs[i])
/obj/machinery/atmospherics/components/on_construction()
..()
update_parents()
/obj/machinery/atmospherics/components/build_network()
for(DEVICE_TYPE_LOOP)
if(!PARENT_I)
PARENT_I = new /datum/pipeline()
var/datum/pipeline/P = PARENT_I
for(var/i in 1 to device_type)
if(!parents[i])
parents[i] = new /datum/pipeline()
var/datum/pipeline/P = parents[i]
P.build_pipeline(src)
/obj/machinery/atmospherics/components/proc/nullifyPipenet(datum/pipeline/reference)
var/I = parents.Find(reference)
reference.other_airs -= AIR_I
var/i = parents.Find(reference)
reference.other_airs -= airs[i]
reference.other_atmosmch -= src
PARENT_I = null
parents[i] = null
/obj/machinery/atmospherics/components/returnPipenetAir(datum/pipeline/reference)
var/I = parents.Find(reference)
return AIR_I
return airs[parents.Find(reference)]
/obj/machinery/atmospherics/components/pipeline_expansion(datum/pipeline/reference)
if(reference)
var/I = parents.Find(reference)
return list(NODE_I)
else
return list(nodes[parents.Find(reference)])
return ..()
/obj/machinery/atmospherics/components/setPipenet(datum/pipeline/reference, obj/machinery/atmospherics/A)
var/I = nodes.Find(A)
PARENT_I = reference
parents[nodes.Find(A)] = reference
/obj/machinery/atmospherics/components/returnPipenet(obj/machinery/atmospherics/A = NODE1) //returns PARENT1 if called without argument
var/I = nodes.Find(A)
return PARENT_I
/obj/machinery/atmospherics/components/returnPipenet(obj/machinery/atmospherics/A = nodes[1]) //returns parents[1] if called without argument
return parents[nodes.Find(A)]
/obj/machinery/atmospherics/components/replacePipenet(datum/pipeline/Old, datum/pipeline/New)
var/I = parents.Find(Old)
PARENT_I = New
parents[parents.Find(Old)] = New
/obj/machinery/atmospherics/components/unsafe_pressure_release(var/mob/user, var/pressures)
..()
@@ -109,15 +102,15 @@ Pipenet stuff; housekeeping
var/datum/gas_mixture/environment = T.return_air()
var/lost = null
var/times_lost = 0
for(DEVICE_TYPE_LOOP)
var/datum/gas_mixture/air = AIR_I
for(var/i in 1 to device_type)
var/datum/gas_mixture/air = airs[i]
lost += pressures*environment.volume/(air.temperature * R_IDEAL_GAS_EQUATION)
times_lost++
var/shared_loss = lost/times_lost
var/datum/gas_mixture/to_release
for(DEVICE_TYPE_LOOP)
var/datum/gas_mixture/air = AIR_I
for(var/i in 1 to device_type)
var/datum/gas_mixture/air = airs[i]
if(!to_release)
to_release = air.remove(shared_loss)
continue
@@ -136,8 +129,8 @@ Helpers
*/
/obj/machinery/atmospherics/components/proc/update_parents()
for(DEVICE_TYPE_LOOP)
var/datum/pipeline/parent = PARENT_I
for(var/i in 1 to device_type)
var/datum/pipeline/parent = parents[i]
if(!parent)
throw EXCEPTION("Component is missing a pipenet! Rebuilding...")
build_network()
@@ -145,8 +138,8 @@ Helpers
/obj/machinery/atmospherics/components/returnPipenets()
. = list()
for(DEVICE_TYPE_LOOP)
. += returnPipenet(NODE_I)
for(var/i in 1 to device_type)
. += returnPipenet(nodes[i])
/*
UI Stuff
@@ -157,4 +150,3 @@ UI Stuff
return ..()
to_chat(user, "<span class='danger'>Access denied.</span>")
return UI_CLOSE

View File

@@ -50,7 +50,7 @@
..()
/obj/machinery/atmospherics/components/trinary/filter/update_icon_nopipes()
if(on && NODE1 && NODE2 && NODE3 && is_operational())
if(on && nodes[1] && nodes[2] && nodes[3] && is_operational())
icon_state = "filter_on[flipped?"_f":""]"
return
icon_state = "filter_off[flipped?"_f":""]"
@@ -63,12 +63,12 @@
/obj/machinery/atmospherics/components/trinary/filter/process_atmos()
..()
if(!on || !(NODE1 && NODE2 && NODE3) || !is_operational())
if(!on || !(nodes[1] && nodes[2] && nodes[3]) || !is_operational())
return
var/datum/gas_mixture/air1 = AIR1
var/datum/gas_mixture/air2 = AIR2
var/datum/gas_mixture/air3 = AIR3
var/datum/gas_mixture/air1 = airs[1]
var/datum/gas_mixture/air2 = airs[2]
var/datum/gas_mixture/air3 = airs[3]
var/output_starting_pressure = air3.return_pressure()

View File

@@ -33,7 +33,7 @@
return ..()
/obj/machinery/atmospherics/components/trinary/mixer/update_icon_nopipes()
if(on && NODE1 && NODE2 && NODE3 && is_operational())
if(on && nodes[1] && nodes[2] && nodes[3] && is_operational())
icon_state = "mixer_on[flipped?"_f":""]"
return
icon_state = "mixer_off[flipped?"_f":""]"
@@ -46,18 +46,18 @@
/obj/machinery/atmospherics/components/trinary/mixer/New()
..()
var/datum/gas_mixture/air3 = AIR3
var/datum/gas_mixture/air3 = airs[3]
air3.volume = 300
AIR3 = air3
airs[3] = air3
/obj/machinery/atmospherics/components/trinary/mixer/process_atmos()
..()
if(!on || !(NODE1 && NODE2 && NODE3) && !is_operational())
if(!on || !(nodes[1] && nodes[2] && nodes[3]) && !is_operational())
return
var/datum/gas_mixture/air1 = AIR1
var/datum/gas_mixture/air2 = AIR2
var/datum/gas_mixture/air3 = AIR3
var/datum/gas_mixture/air1 = airs[1]
var/datum/gas_mixture/air2 = airs[2]
var/datum/gas_mixture/air3 = airs[3]
var/output_starting_pressure = air3.return_pressure()
@@ -103,14 +103,14 @@
air3.merge(removed2)
if(transfer_moles1)
var/datum/pipeline/parent1 = PARENT1
var/datum/pipeline/parent1 = parents[1]
parent1.update = TRUE
if(transfer_moles2)
var/datum/pipeline/parent2 = PARENT2
var/datum/pipeline/parent2 = parents[2]
parent2.update = TRUE
var/datum/pipeline/parent3 = PARENT3
var/datum/pipeline/parent3 = parents[3]
parent3.update = TRUE
return

View File

@@ -174,7 +174,7 @@
open_machine()
return
var/datum/gas_mixture/air1 = AIR1
var/datum/gas_mixture/air1 = airs[1]
if(air1.gases.len)
if(mob_occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic.
@@ -196,9 +196,9 @@
if(!on)
return
var/datum/gas_mixture/air1 = AIR1
var/datum/gas_mixture/air1 = airs[1]
if(!NODE1 || !AIR1 || !air1.gases.len || air1.gases[/datum/gas/oxygen][MOLES] < 5) // Turn off if the machine won't work.
if(!nodes[1] || !airs[1] || !air1.gases.len || air1.gases[/datum/gas/oxygen][MOLES] < 5) // Turn off if the machine won't work.
on = FALSE
update_icon()
return
@@ -348,8 +348,7 @@
else
data["occupant"]["temperaturestatus"] = "bad"
var/datum/gas_mixture/air1 = AIR1
var/datum/gas_mixture/air1 = airs[1]
data["cellTemperature"] = round(air1.temperature, 1)
data["isBeakerLoaded"] = beaker ? TRUE : FALSE
@@ -401,7 +400,7 @@
return 0 // you can't see the pipe network when inside a cryo cell.
/obj/machinery/atmospherics/components/unary/cryo_cell/return_temperature()
var/datum/gas_mixture/G = AIR1
var/datum/gas_mixture/G = airs[1]
if(G.total_moles() > 10)
return G.temperature
@@ -411,13 +410,13 @@
. = ..()
if(.)
SetInitDirections()
var/obj/machinery/atmospherics/node = NODE1
var/obj/machinery/atmospherics/node = nodes[1]
if(node)
node.disconnect(src)
NODE1 = null
nullifyPipenet(PARENT1)
nodes[1] = null
nullifyPipenet(parents[1])
atmosinit()
node = NODE1
node = nodes[1]
if(node)
node.atmosinit()
node.addMember(src)

View File

@@ -15,9 +15,9 @@
pipe_state = "heunary"
/obj/machinery/atmospherics/components/unary/heat_exchanger/update_icon()
if(NODE1)
if(nodes[1])
icon_state = "he_intact"
var/obj/machinery/atmospherics/node = NODE1
var/obj/machinery/atmospherics/node = nodes[1]
add_atom_colour(node.color, FIXED_COLOUR_PRIORITY)
else
icon_state = "he_exposed"
@@ -42,8 +42,8 @@
update_cycle = SSair.times_fired
partner.update_cycle = SSair.times_fired
var/datum/gas_mixture/air_contents = AIR1
var/datum/gas_mixture/partner_air_contents = partner.AIR1
var/datum/gas_mixture/air_contents = airs[1]
var/datum/gas_mixture/partner_air_contents = partner.airs[1]
var/air_heat_capacity = air_contents.heat_capacity()
var/other_air_heat_capacity = partner_air_contents.heat_capacity()

View File

@@ -32,7 +32,7 @@
if(showpipe)
add_overlay(getpipeimage(icon, "inje_cap", initialize_directions))
if(!NODE1 || !on || !is_operational())
if(!nodes[1] || !on || !is_operational())
icon_state = "inje_off"
return
@@ -53,7 +53,7 @@
if(!on || !is_operational())
return
var/datum/gas_mixture/air_contents = AIR1
var/datum/gas_mixture/air_contents = airs[1]
if(air_contents.temperature > 0)
var/transfer_moles = (air_contents.return_pressure())*volume_rate/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
@@ -70,7 +70,7 @@
if(on || injecting || !is_operational())
return
var/datum/gas_mixture/air_contents = AIR1
var/datum/gas_mixture/air_contents = airs[1]
injecting = 1
@@ -130,7 +130,7 @@
if("set_volume_rate" in signal.data)
var/number = text2num(signal.data["set_volume_rate"])
var/datum/gas_mixture/air_contents = AIR1
var/datum/gas_mixture/air_contents = airs[1]
volume_rate = CLAMP(number, 0, air_contents.volume)
if("status" in signal.data)

View File

@@ -13,7 +13,7 @@
/obj/machinery/atmospherics/components/unary/portables_connector/New()
..()
var/datum/gas_mixture/air_contents = AIR1
var/datum/gas_mixture/air_contents = airs[1]
air_contents.volume = 0

View File

@@ -13,7 +13,7 @@
/obj/machinery/atmospherics/components/unary/tank/New()
..()
var/datum/gas_mixture/air_contents = AIR1
var/datum/gas_mixture/air_contents = airs[1]
air_contents.volume = volume
air_contents.temperature = T20C
if(gas_type)
@@ -43,7 +43,7 @@
/obj/machinery/atmospherics/components/unary/tank/air/New()
..()
var/datum/gas_mixture/air_contents = AIR1
var/datum/gas_mixture/air_contents = airs[1]
air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrogen)
air_contents.gases[/datum/gas/oxygen][MOLES] = AIR_CONTENTS * 0.2
air_contents.gases[/datum/gas/nitrogen][MOLES] = AIR_CONTENTS * 0.8

View File

@@ -48,9 +48,9 @@
/obj/machinery/atmospherics/components/unary/thermomachine/process_atmos()
..()
if(!on || !NODE1)
if(!on || !nodes[1])
return
var/datum/gas_mixture/air_contents = AIR1
var/datum/gas_mixture/air_contents = airs[1]
var/air_heat_capacity = air_contents.heat_capacity()
var/combined_heat_capacity = heat_capacity + air_heat_capacity
@@ -88,14 +88,14 @@
if(!..())
return 0
SetInitDirections()
var/obj/machinery/atmospherics/node = NODE1
var/obj/machinery/atmospherics/node = nodes[1]
if(node)
node.disconnect(src)
NODE1 = null
nullifyPipenet(PARENT1)
nodes[1] = null
nullifyPipenet(parents[1])
atmosinit()
node = NODE1
node = nodes[1]
if(node)
node.atmosinit()
node.addMember(src)
@@ -123,7 +123,7 @@
data["target"] = target_temperature
data["initial"] = initial(target_temperature)
var/datum/gas_mixture/air1 = AIR1
var/datum/gas_mixture/air1 = airs[1]
data["temperature"] = air1.temperature
data["pressure"] = air1.return_pressure()
return data

View File

@@ -81,7 +81,7 @@
/obj/machinery/atmospherics/components/unary/vent_pump/high_volume/New()
..()
var/datum/gas_mixture/air_contents = AIR1
var/datum/gas_mixture/air_contents = airs[1]
air_contents.volume = 1000
/obj/machinery/atmospherics/components/unary/vent_pump/update_icon_nopipes()
@@ -93,7 +93,7 @@
icon_state = "vent_welded"
return
if(!NODE1 || !on || !is_operational())
if(!nodes[1] || !on || !is_operational())
if(icon_state == "vent_welded")
icon_state = "vent_off"
return
@@ -122,12 +122,12 @@
..()
if(!is_operational())
return
if(!NODE1)
if(!nodes[1])
on = FALSE
if(!on || welded)
return
var/datum/gas_mixture/air_contents = AIR1
var/datum/gas_mixture/air_contents = airs[1]
var/datum/gas_mixture/environment = loc.return_air()
var/environment_pressure = environment.return_pressure()

View File

@@ -77,7 +77,7 @@
icon_state = "scrub_welded"
return
if(!NODE1 || !on || !is_operational())
if(!nodes[1] || !on || !is_operational())
icon_state = "scrub_off"
return
@@ -142,7 +142,7 @@
..()
if(welded || !is_operational())
return FALSE
if(!NODE1 || !on)
if(!nodes[1] || !on)
on = FALSE
return FALSE
scrub(loc)
@@ -156,7 +156,7 @@
return FALSE
var/datum/gas_mixture/environment = tile.return_air()
var/datum/gas_mixture/air_contents = AIR1
var/datum/gas_mixture/air_contents = airs[1]
var/list/env_gases = environment.gases
if(air_contents.return_pressure() >= 50*ONE_ATMOSPHERE)

View File

@@ -216,8 +216,8 @@
GL += P.return_air()
for(var/obj/machinery/atmospherics/components/binary/valve/V in P.other_atmosmch)
if(V.open)
PL |= V.PARENT1
PL |= V.PARENT2
PL |= V.parents[1]
PL |= V.parents[2]
for(var/obj/machinery/atmospherics/components/unary/portables_connector/C in P.other_atmosmch)
if(C.connected_device)
GL += C.portableConnectorReturnAir()

View File

@@ -32,9 +32,9 @@
cut_overlays()
//Add non-broken pieces
for(DEVICE_TYPE_LOOP)
if(NODE_I)
add_overlay(getpipeimage('icons/obj/atmospherics/pipes/heat.dmi', "manifold_intact[invis]", get_dir(src, NODE_I)))
for(var/i in 1 to device_type)
if(nodes[i])
add_overlay(getpipeimage('icons/obj/atmospherics/pipes/heat.dmi', "manifold_intact[invis]", get_dir(src, nodes[i])))
//4-way manifold
/obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w
@@ -61,6 +61,6 @@
cut_overlays()
//Add non-broken pieces
for(DEVICE_TYPE_LOOP)
if(NODE_I)
add_overlay(getpipeimage('icons/obj/atmospherics/pipes/heat.dmi', "manifold_intact[invis]", get_dir(src, NODE_I)))
for(var/i in 1 to device_type)
if(nodes[i])
add_overlay(getpipeimage('icons/obj/atmospherics/pipes/heat.dmi', "manifold_intact[invis]", get_dir(src, nodes[i])))

View File

@@ -107,14 +107,14 @@
P.destroy_network()
while(reference in get_all_connected_nodes())
if(reference in nodes)
var/I = nodes.Find(reference)
NODE_I = null
var/i = nodes.Find(reference)
nodes[i] = null
if(reference in front_nodes)
var/I = front_nodes.Find(reference)
front_nodes[I] = null
var/i = front_nodes.Find(reference)
front_nodes[i] = null
if(reference in back_nodes)
var/I = back_nodes.Find(reference)
back_nodes[I] = null
var/i = back_nodes.Find(reference)
back_nodes[i] = null
update_icon()
/obj/machinery/atmospherics/pipe/layer_manifold/relaymove(mob/living/user, dir)

View File

@@ -35,9 +35,9 @@
cut_overlays()
//Add non-broken pieces
for(DEVICE_TYPE_LOOP)
if(NODE_I)
add_overlay(getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full[invis]", get_dir(src, NODE_I)))
for(var/i in 1 to device_type)
if(nodes[i])
add_overlay(getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full[invis]", get_dir(src, nodes[i])))
//Colored pipes, use these for mapping
/obj/machinery/atmospherics/pipe/manifold/general

View File

@@ -26,9 +26,9 @@
cut_overlays()
//Add non-broken pieces
for(DEVICE_TYPE_LOOP)
if(NODE_I)
add_overlay(getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full[invis]", get_dir(src, NODE_I)))
for(var/i in 1 to device_type)
if(nodes[i])
add_overlay(getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full[invis]", get_dir(src, nodes[i])))
//Colored pipes, use these for mapping
/obj/machinery/atmospherics/pipe/manifold4w/general

View File

@@ -18,8 +18,8 @@
volume = 35 * device_type
..()
/obj/machinery/atmospherics/pipe/nullifyNode(I)
var/obj/machinery/atmospherics/oldN = NODE_I
/obj/machinery/atmospherics/pipe/nullifyNode(i)
var/obj/machinery/atmospherics/oldN = nodes[i]
..()
if(oldN)
oldN.build_network()
@@ -33,11 +33,11 @@
parent.build_pipeline(src)
/obj/machinery/atmospherics/pipe/update_icon() //overridden by manifolds
if(NODE1&&NODE2)
if(nodes[1] && nodes[2])
icon_state = "intact[invisibility ? "-f" : "" ]"
else
var/have_node1 = NODE1?1:0
var/have_node2 = NODE2?1:0
var/have_node1 = nodes[1] ? TRUE : FALSE
var/have_node2 = nodes[2] ? TRUE : FALSE
icon_state = "exposed[have_node1][have_node2][invisibility ? "-f" : "" ]"
/obj/machinery/atmospherics/pipe/atmosinit()
@@ -91,9 +91,9 @@
QDEL_NULL(parent)
/obj/machinery/atmospherics/pipe/proc/update_node_icon()
for(DEVICE_TYPE_LOOP)
if(NODE_I)
var/obj/machinery/atmospherics/N = NODE_I
for(var/i in 1 to device_type)
if(nodes[i])
var/obj/machinery/atmospherics/N = nodes[i]
N.update_icon()
/obj/machinery/atmospherics/pipe/returnPipenets()
@@ -109,4 +109,3 @@
pipe_color = paint_color
update_node_icon()
return TRUE

View File

@@ -324,13 +324,13 @@
valve_open = !valve_open
timing = FALSE
if(!valve_open)
pump.AIR1 = null
pump.AIR2 = null
pump.airs[1] = null
pump.airs[2] = null
return
var/turf/T = get_turf(src)
pump.AIR1 = air_contents
pump.AIR2 = holding ? holding.air_contents : T.return_air()
pump.airs[1] = air_contents
pump.airs[2] = holding ? holding.air_contents : T.return_air()
pump.target_pressure = release_pressure
pump.process_atmos() // Pump gas.

View File

@@ -54,7 +54,7 @@
//Perform the connection
connected_port = new_port
connected_port.connected_device = src
var/datum/pipeline/connected_port_parent = connected_port.PARENT1
var/datum/pipeline/connected_port_parent = connected_port.parents[1]
connected_port_parent.reconcile_air()
anchored = TRUE //Prevent movement

View File

@@ -41,17 +41,17 @@
/obj/machinery/portable_atmospherics/pump/process_atmos()
..()
if(!on)
pump.AIR1 = null
pump.AIR2 = null
pump.airs[1] = null
pump.airs[2] = null
return
var/turf/T = get_turf(src)
if(direction == PUMP_OUT) // Hook up the internal pump.
pump.AIR1 = holding ? holding.air_contents : air_contents
pump.AIR2 = holding ? air_contents : T.return_air()
pump.airs[1] = holding ? holding.air_contents : air_contents
pump.airs[2] = holding ? air_contents : T.return_air()
else
pump.AIR1 = holding ? air_contents : T.return_air()
pump.AIR2 = holding ? holding.air_contents : air_contents
pump.airs[1] = holding ? air_contents : T.return_air()
pump.airs[2] = holding ? holding.air_contents : air_contents
pump.process_atmos() // Pump gas.
if(!holding)

View File

@@ -2,9 +2,8 @@
name = "Alien Infestation"
typepath = /datum/round_event/ghost_role/alien_infestation
weight = 5
earliest_start = 24000 //40 min
min_players = 20 //Avoid lowpop rounds
min_players = 10
max_occurrences = 1
/datum/round_event/ghost_role/alien_infestation
@@ -16,6 +15,7 @@
// 50% chance of being incremented by one
var/spawncount = 1
var/successSpawn = 0 //So we don't make a command report if nothing gets spawned.
fakeable = TRUE
/datum/round_event/ghost_role/alien_infestation/setup()
@@ -74,3 +74,4 @@
else
// Like how did we get here?
return FALSE

View File

@@ -35,3 +35,4 @@
spawn_atom_to_turf(spawn_type, vent, 1, FALSE)
vents -= vent
spawncount--

View File

@@ -47,3 +47,4 @@
while(cockroaches)
new /mob/living/simple_animal/cockroach(get_turf(vent))
cockroaches--

View File

@@ -1058,6 +1058,13 @@
if (client)
if (new_z)
SSmobs.clients_by_zlevel[new_z] += src
for (var/I in length(SSidlenpcpool.idle_mobs_by_zlevel[new_z]) to 1 step -1) //Backwards loop because we're removing (guarantees optimal rather than worst-case performance), it's fine to use .len here but doesn't compile on 511
var/mob/living/simple_animal/SA = SSidlenpcpool.idle_mobs_by_zlevel[new_z][I]
if (SA)
SA.toggle_ai(AI_ON) // Guarantees responsiveness for when appearing right next to mobs
else
SSidlenpcpool.idle_mobs_by_zlevel[new_z] -= SA
registered_z = new_z
else
registered_z = null

View File

@@ -28,9 +28,6 @@
var/ranged_message = "fires" //Fluff text for ranged mobs
var/ranged_cooldown = 0 //What the current cooldown on ranged attacks is, generally world.time + ranged_cooldown_time
var/ranged_cooldown_time = 30 //How long, in deciseconds, the cooldown of ranged attacks is
var/ranged_telegraph = "prepares to fire at *TARGET*!" //A message shown when the mob prepares to fire; use *TARGET* if you want to show the target's name
var/ranged_telegraph_sound //A sound played when the mob prepares to fire
var/ranged_telegraph_time = 0 //In deciseconds, how long between the telegraph and ranged shot
var/ranged_ignores_vision = FALSE //if it'll fire ranged attacks even if it lacks vision on its target, only works with environment smash
var/check_friendly_fire = 0 // Should the ranged mob check for friendlies when shooting
var/retreat_distance = null //If our mob runs from players when they're too close, set in tile distance. By default, mobs do not retreat.
@@ -231,9 +228,6 @@
if(!target || !CanAttack(target))
LoseTarget()
return 0
if(ismob(target.loc))
LoseTarget()
return 0
if(target in possible_targets)
var/turf/T = get_turf(src)
if(target.z != T.z)
@@ -242,14 +236,7 @@
var/target_distance = get_dist(targets_from,target)
if(ranged) //We ranged? Shoot at em
if(!target.Adjacent(targets_from) && ranged_cooldown <= world.time) //But make sure they're not in range for a melee attack and our range attack is off cooldown
if(!ranged_telegraph_time || client)
OpenFire(target)
else
if(ranged_telegraph)
visible_message("<span class='danger'>[src] [replacetext(ranged_telegraph, "*TARGET*", "[target]")]</span>")
if(ranged_telegraph_sound)
playsound(src, ranged_telegraph_sound, 75, FALSE)
addtimer(CALLBACK(src, .proc/OpenFire, target), ranged_telegraph_time)
if(!Process_Spacemove()) //Drifting
walk(src,0)
return 1
@@ -289,7 +276,7 @@
if(search_objects)//Turn off item searching and ignore whatever item we were looking at, we're more concerned with fight or flight
target = null
LoseSearchObjects()
if(AIStatus == AI_IDLE)
if(AIStatus != AI_ON && AIStatus != AI_OFF)
toggle_ai(AI_ON)
FindTarget()
else if(target != null && prob(40))//No more pulling a mob forever and having a second player attack it, it can switch targets now if it finds a more suitable one
@@ -413,7 +400,6 @@ mob/living/simple_animal/hostile/proc/DestroySurroundings() // for use with mega
DestroyObjectsInDirection(dir)
/mob/living/simple_animal/hostile/proc/EscapeConfinement()
if(buckled)
buckled.attack_animal(src)
@@ -498,3 +484,14 @@ mob/living/simple_animal/hostile/proc/DestroySurroundings() // for use with mega
if(AIStatus == AI_IDLE && FindTarget(tlist, 1))
toggle_ai(AI_ON)
/mob/living/simple_animal/hostile/proc/ListTargetsLazy(var/_Z)//Step 1, find out what we can see
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/destructible/clockwork/ocular_warden))
. = list()
for (var/I in SSmobs.clients_by_zlevel[_Z])
var/mob/M = I
if (get_dist(M, src) < vision_range)
if (isturf(M.loc))
. += M
else if (M.loc.type in hostile_machines)
. += M.loc

View File

@@ -82,14 +82,14 @@
var/dextrous_hud_type = /datum/hud/dextrous
var/datum/personal_crafting/handcrafting
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever)
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever), AI_Z_OFF (Temporarily off due to nonpresence of players)
var/shouldwakeup = FALSE //convenience var for forcibly waking up an idling AI on next check.
//domestication
var/tame = 0
no_vore = TRUE
var/my_z // I don't want to confuse this with client registered_z
/mob/living/simple_animal/Initialize()
. = ..()
@@ -544,7 +544,13 @@
/mob/living/simple_animal/proc/toggle_ai(togglestatus)
if (AIStatus != togglestatus)
if (togglestatus > 0 && togglestatus < 4)
if (togglestatus > 0 && togglestatus < 5)
if (togglestatus == AI_Z_OFF || AIStatus == AI_Z_OFF)
var/turf/T = get_turf(src)
if (AIStatus == AI_Z_OFF)
SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src
else
SSidlenpcpool.idle_mobs_by_zlevel[T.z] += src
GLOB.simple_animals[AIStatus] -= src
GLOB.simple_animals[togglestatus] += src
AIStatus = togglestatus
@@ -560,3 +566,10 @@
if(!ckey && !stat)//Not unconscious
if(AIStatus == AI_IDLE)
toggle_ai(AI_ON)
/mob/living/simple_animal/onTransitZ(old_z, new_z)
..()
if (AIStatus == AI_Z_OFF)
SSidlenpcpool[old_z] -= src
toggle_ai(initial(AIStatus))

View File

@@ -45,7 +45,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
if(vent_found)
var/datum/pipeline/vent_found_parent = vent_found.PARENT1
var/datum/pipeline/vent_found_parent = vent_found.parents[1]
if(vent_found_parent && (vent_found_parent.members.len || vent_found_parent.other_atmosmch))
visible_message("<span class='notice'>[src] begins climbing into the ventilation system...</span>" ,"<span class='notice'>You begin climbing into the ventilation system...</span>")

View File

@@ -99,11 +99,11 @@
// update icon overlays only if displayed level has changed
if(hot_air)
var/datum/gas_mixture/hot_circ_air1 = hot_circ.AIR1
var/datum/gas_mixture/hot_circ_air1 = hot_circ.airs[1]
hot_circ_air1.merge(hot_air)
if(cold_air)
var/datum/gas_mixture/cold_circ_air1 = cold_circ.AIR1
var/datum/gas_mixture/cold_circ_air1 = cold_circ.airs[1]
cold_circ_air1.merge(cold_air)
update_icon()
@@ -134,10 +134,10 @@
if(!powernet)
t += "<span class='bad'>Unable to connect to the power network!</span>"
else if(cold_circ && hot_circ)
var/datum/gas_mixture/cold_circ_air1 = cold_circ.AIR1
var/datum/gas_mixture/cold_circ_air2 = cold_circ.AIR2
var/datum/gas_mixture/hot_circ_air1 = hot_circ.AIR1
var/datum/gas_mixture/hot_circ_air2 = hot_circ.AIR2
var/datum/gas_mixture/cold_circ_air1 = cold_circ.airs[1]
var/datum/gas_mixture/cold_circ_air2 = cold_circ.airs[2]
var/datum/gas_mixture/hot_circ_air1 = hot_circ.airs[1]
var/datum/gas_mixture/hot_circ_air2 = hot_circ.airs[2]
t += "<div class='statusDisplay'>"

View File

@@ -213,9 +213,9 @@ All ShuttleMove procs go here
/obj/machinery/atmospherics/afterShuttleMove(turf/oldT, list/movement_force, shuttle_dir, shuttle_preferred_direction, move_dir, rotation)
. = ..()
var/missing_nodes = FALSE
for(DEVICE_TYPE_LOOP)
if(src.nodes[I])
var/obj/machinery/atmospherics/node = src.nodes[I]
for(var/i in 1 to device_type)
if(nodes[i])
var/obj/machinery/atmospherics/node = nodes[i]
var/connected = FALSE
for(var/D in GLOB.cardinals)
if(node in get_step(src, D))
@@ -223,9 +223,9 @@ All ShuttleMove procs go here
break
if(!connected)
nullifyNode(I)
nullifyNode(i)
if(!src.nodes[I])
if(!nodes[i])
missing_nodes = TRUE
if(missing_nodes)

View File

@@ -84,17 +84,17 @@ If ever any of these procs are useful for non-shuttles, rename it to proc/rotate
/obj/machinery/atmospherics/shuttleRotate(rotation, params)
var/list/real_node_connect = getNodeConnects()
for(DEVICE_TYPE_LOOP)
real_node_connect[I] = angle2dir(rotation+dir2angle(real_node_connect[I]))
for(var/i in 1 to device_type)
real_node_connect[i] = angle2dir(rotation+dir2angle(real_node_connect[i]))
. = ..()
SetInitDirections()
var/list/supposed_node_connect = getNodeConnects()
var/list/nodes_copy = nodes.Copy()
for(DEVICE_TYPE_LOOP)
var/new_pos = supposed_node_connect.Find(real_node_connect[I])
nodes[new_pos] = nodes_copy[I]
for(var/i in 1 to device_type)
var/new_pos = supposed_node_connect.Find(real_node_connect[i])
nodes[new_pos] = nodes_copy[i]
//prevents shuttles attempting to rotate this since it messes up sprites
/obj/machinery/gateway/shuttleRotate(rotation, params)

View File

@@ -0,0 +1,4 @@
author: "Naksu"
delete-after: True
changes:
- tweak: "Hostile mobs on z-levels without living players will now conserve their efforts and simply not run AI routines at all. Also, idling mob routines should be significantly cheaper on non-station Z-levels."

View File

@@ -0,0 +1,4 @@
author: "deathride58"
delete-after: True
changes:
- bugfix: "Vore is now actually fixed. Fuck."

View File

@@ -1,4 +1,4 @@
/mob/living/human/grabbedby(mob/living/carbon/user, supress_message = 0)
/mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0)
if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && isliving(pulling))
vore_attack(user, pulling)
else