mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-14 08:34:16 +01:00
Merge branch 'master' into admin-additions
This commit is contained in:
@@ -59,7 +59,7 @@ GLOBAL_DATUM_INIT(pipe_icon_manager, /datum/pipe_icon_manager, new())
|
||||
for(var/mob/living/L in src) //ventcrawling is serious business
|
||||
L.remove_ventcrawl()
|
||||
L.forceMove(get_turf(src))
|
||||
QDEL_NULL(pipe_image) //we have to del it, or it might keep a ref somewhere else
|
||||
QDEL_NULL(pipe_image) //we have to qdel it, or it might keep a ref somewhere else
|
||||
return ..()
|
||||
|
||||
// Icons/overlays/underlays
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
var/frequency = ATMOS_VENTSCRUB
|
||||
var/id_tag = null
|
||||
var/datum/radio_frequency/radio_connection
|
||||
var/advcontrol = 0//does this device listen to the AAC
|
||||
|
||||
settagwhitelist = list("id_tag")
|
||||
|
||||
@@ -75,7 +74,7 @@
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump/update_icon(var/safety = 0)
|
||||
..()
|
||||
|
||||
|
||||
if(!check_icon_cache())
|
||||
return
|
||||
|
||||
@@ -192,7 +191,7 @@
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump/receive_signal(datum/signal/signal)
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command") || (signal.data["advcontrol"] && !advcontrol))
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command"))
|
||||
return 0
|
||||
if(signal.data["power"] != null)
|
||||
on = text2num(signal.data["power"])
|
||||
@@ -256,14 +255,5 @@
|
||||
<ul>
|
||||
<li><b>Frequency:</b> <a href="?src=[UID()];set_freq=-1">[format_frequency(frequency)] GHz</a> (<a href="?src=[UID()];set_freq=[ATMOS_VENTSCRUB]">Reset</a>)</li>
|
||||
<li><b>ID Tag:</b> <a href="?src=[UID()];set_id=1">[id_tag]</a></li>
|
||||
<li><b>AAC Acces:</b> <a href="?src=[UID()];toggleadvcontrol=1">[advcontrol ? "Allowed" : "Blocked"]</a></li>
|
||||
</ul>
|
||||
"}
|
||||
|
||||
/obj/machinery/atmospherics/binary/dp_vent_pump/multitool_topic(var/mob/user, var/list/href_list, var/obj/O)
|
||||
. = ..()
|
||||
if(.)
|
||||
return .
|
||||
if("toggleadvcontrol" in href_list)
|
||||
advcontrol = !advcontrol
|
||||
return TRUE
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
target_pressure = clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
|
||||
update_icon()
|
||||
|
||||
@@ -232,7 +232,7 @@ Thus, the two variables affect pump operation are set in New():
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
target_pressure = clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
|
||||
update_icon()
|
||||
|
||||
@@ -228,7 +228,7 @@ Thus, the two variables affect pump operation are set in New():
|
||||
rate = text2num(rate)
|
||||
. = TRUE
|
||||
if(.)
|
||||
transfer_rate = Clamp(rate, 0, MAX_TRANSFER_RATE)
|
||||
transfer_rate = clamp(rate, 0, MAX_TRANSFER_RATE)
|
||||
investigate_log("was set to [transfer_rate] L/s by [key_name(usr)]", "atmos")
|
||||
|
||||
update_icon()
|
||||
|
||||
@@ -89,12 +89,12 @@
|
||||
if(ATM_P)
|
||||
filtered_out.toxins = removed.toxins
|
||||
removed.toxins = 0
|
||||
|
||||
filtered_out.agent_b = removed.agent_b
|
||||
removed.agent_b = 0
|
||||
if(ATM_N2O)
|
||||
if(removed.trace_gases.len>0)
|
||||
for(var/datum/gas/sleeping_agent/trace_gas in removed.trace_gases)
|
||||
if(istype(trace_gas))
|
||||
removed.trace_gases -= trace_gas
|
||||
filtered_out.trace_gases += trace_gas
|
||||
filtered_out.sleeping_agent = removed.sleeping_agent
|
||||
removed.sleeping_agent = 0
|
||||
else
|
||||
filtered_out = null
|
||||
|
||||
|
||||
@@ -150,11 +150,8 @@ Filter types:
|
||||
filtered_out.toxins = removed.toxins
|
||||
removed.toxins = 0
|
||||
|
||||
if(removed.trace_gases.len>0)
|
||||
for(var/datum/gas/trace_gas in removed.trace_gases)
|
||||
if(istype(trace_gas, /datum/gas/oxygen_agent_b))
|
||||
removed.trace_gases -= trace_gas
|
||||
filtered_out.trace_gases += trace_gas
|
||||
filtered_out.agent_b = removed.agent_b
|
||||
removed.agent_b = 0
|
||||
|
||||
if(1) //removing O2
|
||||
filtered_out.oxygen = removed.oxygen
|
||||
@@ -169,12 +166,8 @@ Filter types:
|
||||
removed.carbon_dioxide = 0
|
||||
|
||||
if(4)//removing N2O
|
||||
if(removed.trace_gases.len>0)
|
||||
for(var/datum/gas/trace_gas in removed.trace_gases)
|
||||
if(istype(trace_gas, /datum/gas/sleeping_agent))
|
||||
removed.trace_gases -= trace_gas
|
||||
filtered_out.trace_gases += trace_gas
|
||||
|
||||
filtered_out.sleeping_agent = removed.sleeping_agent
|
||||
removed.sleeping_agent = 0
|
||||
else
|
||||
filtered_out = null
|
||||
|
||||
@@ -244,7 +237,7 @@ Filter types:
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
target_pressure = clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
if(href_list["filter"])
|
||||
filter_type = text2num(href_list["filter"])
|
||||
|
||||
@@ -202,7 +202,7 @@
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = Clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
target_pressure = clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
if(href_list["node1"])
|
||||
var/value = text2num(href_list["node1"])
|
||||
|
||||
@@ -92,10 +92,7 @@
|
||||
air_contents.volume = volume
|
||||
air_contents.temperature = T20C
|
||||
|
||||
var/datum/gas/sleeping_agent/trace_gas = new
|
||||
trace_gas.moles = (25*ONE_ATMOSPHERE)*(air_contents.volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
|
||||
|
||||
air_contents.trace_gases += trace_gas
|
||||
air_contents.sleeping_agent = (25 * ONE_ATMOSPHERE) * (air_contents.volume) / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
|
||||
|
||||
/obj/machinery/atmospherics/unary/tank/oxygen_agent_b
|
||||
name = "Unidentified Gas Tank"
|
||||
@@ -108,6 +105,4 @@
|
||||
air_contents.volume = volume
|
||||
air_contents.temperature = T20C
|
||||
|
||||
var/datum/gas/oxygen_agent_b/trace_gas = new
|
||||
trace_gas.moles = (50 * ONE_ATMOSPHERE) * (air_contents.volume) / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
|
||||
air_contents.trace_gases += trace_gas
|
||||
air_contents.agent_b = (50 * ONE_ATMOSPHERE) * (air_contents.volume) / (R_IDEAL_GAS_EQUATION * air_contents.temperature)
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
var/frequency = ATMOS_VENTSCRUB
|
||||
var/datum/radio_frequency/radio_connection
|
||||
Mtoollink = 1
|
||||
var/advcontrol = 0//does this device listen to the AAC
|
||||
|
||||
var/radio_filter_out
|
||||
var/radio_filter_in
|
||||
@@ -250,7 +249,7 @@
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
//log_admin("DEBUG \[[world.timeofday]\]: /obj/machinery/atmospherics/unary/vent_pump/receive_signal([signal.debug_print()])")
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command") || (signal.data["advcontrol"] && !advcontrol))
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command"))
|
||||
return 0
|
||||
|
||||
if(signal.data["purge"] != null)
|
||||
@@ -425,15 +424,10 @@
|
||||
<ul>
|
||||
<li><b>Frequency:</b> <a href="?src=[UID()];set_freq=-1">[format_frequency(frequency)] GHz</a> (<a href="?src=[UID()];set_freq=[ATMOS_VENTSCRUB]">Reset</a>)</li>
|
||||
<li>[format_tag("ID Tag","id_tag","set_id")]</li>
|
||||
<li><b>AAC Acces:</b> <a href="?src=[UID()];toggleadvcontrol=1">[advcontrol ? "Allowed" : "Blocked"]</a>
|
||||
</ul>
|
||||
"}
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/multitool_topic(var/mob/user, var/list/href_list, var/obj/O)
|
||||
if("toggleadvcontrol" in href_list)
|
||||
advcontrol = !advcontrol
|
||||
return TRUE
|
||||
|
||||
if("set_id" in href_list)
|
||||
var/newid = copytext(reject_bad_text(input(usr, "Specify the new ID tag for this machine", src, src.id_tag) as null|text), 1, MAX_MESSAGE_LEN)
|
||||
if(!newid)
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
var/id_tag = null
|
||||
var/frequency = ATMOS_VENTSCRUB
|
||||
var/datum/radio_frequency/radio_connection
|
||||
var/advcontrol = 0//does this device listen to the AAC?
|
||||
|
||||
var/list/turf/simulated/adjacent_turfs = list()
|
||||
|
||||
@@ -226,7 +225,7 @@
|
||||
var/datum/gas_mixture/environment = tile.return_air()
|
||||
|
||||
if(scrubbing)
|
||||
if((scrub_O2 && environment.oxygen>0.001) || (scrub_N2 && environment.nitrogen>0.001) || (scrub_CO2 && environment.carbon_dioxide>0.001) || (scrub_Toxins && environment.toxins>0.001) || (environment.trace_gases.len>0))
|
||||
if((scrub_O2 && environment.oxygen>0.001) || (scrub_N2 && environment.nitrogen>0.001) || (scrub_CO2 && environment.carbon_dioxide>0.001) || (scrub_Toxins && environment.toxins>0.001) || (environment.sleeping_agent) || (environment.agent_b))
|
||||
var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles()
|
||||
|
||||
//Take a gas sample
|
||||
@@ -250,14 +249,13 @@
|
||||
filtered_out.carbon_dioxide = removed.carbon_dioxide
|
||||
removed.carbon_dioxide = 0
|
||||
|
||||
if(removed.trace_gases.len>0)
|
||||
for(var/datum/gas/trace_gas in removed.trace_gases)
|
||||
if(istype(trace_gas, /datum/gas/oxygen_agent_b))
|
||||
removed.trace_gases -= trace_gas
|
||||
filtered_out.trace_gases += trace_gas
|
||||
else if(istype(trace_gas, /datum/gas/sleeping_agent) && scrub_N2O)
|
||||
removed.trace_gases -= trace_gas
|
||||
filtered_out.trace_gases += trace_gas
|
||||
if(removed.agent_b)
|
||||
filtered_out.agent_b = removed.agent_b
|
||||
removed.agent_b = 0
|
||||
|
||||
if(scrub_N2O)
|
||||
filtered_out.sleeping_agent = removed.sleeping_agent
|
||||
removed.sleeping_agent = 0
|
||||
|
||||
//Remix the resulting gases
|
||||
air_contents.merge(filtered_out)
|
||||
@@ -286,7 +284,7 @@
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/receive_signal(datum/signal/signal)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command") || (signal.data["advcontrol"] && !advcontrol))
|
||||
if(!signal.data["tag"] || (signal.data["tag"] != id_tag) || (signal.data["sigtype"]!="command"))
|
||||
return 0
|
||||
|
||||
if(signal.data["power"] != null)
|
||||
@@ -354,15 +352,10 @@
|
||||
<ul>
|
||||
<li><b>Frequency:</b> <a href="?src=[UID()];set_freq=-1">[format_frequency(frequency)] GHz</a> (<a href="?src=[UID()];set_freq=[ATMOS_VENTSCRUB]">Reset</a>)</li>
|
||||
<li>[format_tag("ID Tag","id_tag", "set_id")]</li>
|
||||
<li><b>AAC Acces:</b> <a href="?src=[UID()];toggleadvcontrol=1">[advcontrol ? "Allowed" : "Blocked"]</a>
|
||||
</ul>
|
||||
"}
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/multitool_topic(var/mob/user, var/list/href_list, var/obj/O)
|
||||
if("toggleadvcontrol" in href_list)
|
||||
advcontrol = !advcontrol
|
||||
return TRUE
|
||||
|
||||
if("set_id" in href_list)
|
||||
var/newid = copytext(reject_bad_text(input(usr, "Specify the new ID tag for this machine", src, src:id_tag) as null|text),1,MAX_MESSAGE_LEN)
|
||||
if(!newid)
|
||||
|
||||
@@ -127,20 +127,15 @@ GLOBAL_VAR_INIT(pipenetwarnings, 10)
|
||||
member.air_temporary = new
|
||||
member.air_temporary.volume = member.volume
|
||||
|
||||
member.air_temporary.oxygen = air.oxygen*member.volume/air.volume
|
||||
member.air_temporary.nitrogen = air.nitrogen*member.volume/air.volume
|
||||
member.air_temporary.toxins = air.toxins*member.volume/air.volume
|
||||
member.air_temporary.carbon_dioxide = air.carbon_dioxide*member.volume/air.volume
|
||||
member.air_temporary.oxygen = air.oxygen * member.volume / air.volume
|
||||
member.air_temporary.nitrogen = air.nitrogen * member.volume / air.volume
|
||||
member.air_temporary.toxins = air.toxins * member.volume / air.volume
|
||||
member.air_temporary.carbon_dioxide = air.carbon_dioxide * member.volume / air.volume
|
||||
member.air_temporary.sleeping_agent = air.sleeping_agent * member.volume / air.volume
|
||||
member.air_temporary.agent_b = air.agent_b * member.volume / air.volume
|
||||
|
||||
member.air_temporary.temperature = air.temperature
|
||||
|
||||
if(air.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in air.trace_gases)
|
||||
var/datum/gas/corresponding = new trace_gas.type()
|
||||
member.air_temporary.trace_gases += corresponding
|
||||
|
||||
corresponding.moles = trace_gas.moles*member.volume/air.volume
|
||||
|
||||
/datum/pipeline/proc/temperature_interact(turf/target, share_volume, thermal_conductivity)
|
||||
var/total_heat_capacity = air.heat_capacity()
|
||||
var/partial_heat_capacity = total_heat_capacity*(share_volume/air.volume)
|
||||
@@ -228,7 +223,8 @@ GLOBAL_VAR_INIT(pipenetwarnings, 10)
|
||||
var/total_nitrogen = 0
|
||||
var/total_toxins = 0
|
||||
var/total_carbon_dioxide = 0
|
||||
var/list/total_trace_gases = list()
|
||||
var/total_sleeping_agent = 0
|
||||
var/total_agent_b = 0
|
||||
|
||||
for(var/datum/gas_mixture/G in GL)
|
||||
total_volume += G.volume
|
||||
@@ -239,15 +235,8 @@ GLOBAL_VAR_INIT(pipenetwarnings, 10)
|
||||
total_nitrogen += G.nitrogen
|
||||
total_toxins += G.toxins
|
||||
total_carbon_dioxide += G.carbon_dioxide
|
||||
|
||||
if(G.trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in G.trace_gases)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in total_trace_gases
|
||||
if(!corresponding)
|
||||
corresponding = new trace_gas.type()
|
||||
total_trace_gases += corresponding
|
||||
|
||||
corresponding.moles += trace_gas.moles
|
||||
total_sleeping_agent += G.sleeping_agent
|
||||
total_agent_b += G.agent_b
|
||||
|
||||
if(total_volume > 0)
|
||||
|
||||
@@ -259,18 +248,11 @@ GLOBAL_VAR_INIT(pipenetwarnings, 10)
|
||||
|
||||
//Update individual gas_mixtures by volume ratio
|
||||
for(var/datum/gas_mixture/G in GL)
|
||||
G.oxygen = total_oxygen*G.volume/total_volume
|
||||
G.nitrogen = total_nitrogen*G.volume/total_volume
|
||||
G.toxins = total_toxins*G.volume/total_volume
|
||||
G.carbon_dioxide = total_carbon_dioxide*G.volume/total_volume
|
||||
G.oxygen = total_oxygen * G.volume / total_volume
|
||||
G.nitrogen = total_nitrogen * G.volume / total_volume
|
||||
G.toxins = total_toxins * G.volume / total_volume
|
||||
G.carbon_dioxide = total_carbon_dioxide * G.volume / total_volume
|
||||
G.sleeping_agent = total_sleeping_agent * G.volume / total_volume
|
||||
G.agent_b = total_agent_b * G.volume / total_volume
|
||||
|
||||
G.temperature = temperature
|
||||
|
||||
if(total_trace_gases.len)
|
||||
for(var/datum/gas/trace_gas in total_trace_gases)
|
||||
var/datum/gas/corresponding = locate(trace_gas.type) in G.trace_gases
|
||||
if(!corresponding)
|
||||
corresponding = new trace_gas.type()
|
||||
G.trace_gases += corresponding
|
||||
|
||||
corresponding.moles = trace_gas.moles*G.volume/total_volume
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
else return 1
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/proc/burst()
|
||||
src.visible_message("<span class='danger'>\The [src] bursts!</span>");
|
||||
src.visible_message("<span class='danger'>\The [src] bursts!</span>")
|
||||
playsound(src.loc, 'sound/effects/bang.ogg', 25, 1)
|
||||
var/datum/effect_system/smoke_spread/smoke = new
|
||||
smoke.set_up(1,0, src.loc, 0)
|
||||
|
||||
@@ -176,7 +176,7 @@
|
||||
|
||||
if(istype(loc, /turf/simulated))
|
||||
var/turf/simulated/T = loc
|
||||
if(T.to_be_destroyed)
|
||||
if(T.to_be_destroyed && !T.changing_turf)
|
||||
var/chance_of_deletion
|
||||
if(T.heat_capacity) //beware of division by zero
|
||||
chance_of_deletion = T.max_fire_temperature_sustained / T.heat_capacity * 8 //there is no problem with prob(23456), min() was redundant --rastaf0
|
||||
|
||||
@@ -142,7 +142,7 @@ turf/CanPass(atom/movable/mover, turf/target, height=1.5)
|
||||
return
|
||||
T.atmos_spawn_air(text, amount)
|
||||
|
||||
/turf/simulated/proc/atmos_spawn_air(var/flag, var/amount)
|
||||
/turf/simulated/proc/atmos_spawn_air(flag, amount)
|
||||
if(!text || !amount || !air)
|
||||
return
|
||||
|
||||
@@ -156,17 +156,21 @@ turf/CanPass(atom/movable/mover, turf/target, height=1.5)
|
||||
|
||||
if(flag & LINDA_SPAWN_TOXINS)
|
||||
G.toxins += amount
|
||||
|
||||
if(flag & LINDA_SPAWN_OXYGEN)
|
||||
G.oxygen += amount
|
||||
|
||||
if(flag & LINDA_SPAWN_CO2)
|
||||
G.carbon_dioxide += amount
|
||||
|
||||
if(flag & LINDA_SPAWN_NITROGEN)
|
||||
G.nitrogen += amount
|
||||
|
||||
if(flag & LINDA_SPAWN_N2O)
|
||||
var/datum/gas/sleeping_agent/T = new
|
||||
T.moles += amount
|
||||
G.trace_gases += T
|
||||
G.sleeping_agent += amount
|
||||
|
||||
if(flag & LINDA_SPAWN_AGENT_B)
|
||||
G.agent_b += amount
|
||||
|
||||
if(flag & LINDA_SPAWN_AIR)
|
||||
G.oxygen += MOLES_O2STANDARD * amount
|
||||
|
||||
@@ -19,20 +19,24 @@
|
||||
GM.carbon_dioxide = carbon_dioxide
|
||||
GM.nitrogen = nitrogen
|
||||
GM.toxins = toxins
|
||||
GM.sleeping_agent = sleeping_agent
|
||||
GM.agent_b = agent_b
|
||||
|
||||
GM.temperature = temperature
|
||||
|
||||
return GM
|
||||
|
||||
/turf/remove_air(amount as num)
|
||||
/turf/remove_air(amount)
|
||||
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
|
||||
var/sum = oxygen + carbon_dioxide + nitrogen + toxins + sleeping_agent + agent_b
|
||||
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.sleeping_agent = (sleeping_agent / sum) * amount
|
||||
GM.agent_b = (agent_b / sum) * amount
|
||||
|
||||
GM.temperature = temperature
|
||||
|
||||
@@ -53,7 +57,7 @@
|
||||
|
||||
var/temperature_archived //USED ONLY FOR SOLIDS
|
||||
|
||||
var/atmos_overlay_type = "" //current active overlay
|
||||
var/atmos_overlay_type = null //current active overlay
|
||||
|
||||
/turf/simulated/New()
|
||||
..()
|
||||
@@ -64,12 +68,14 @@
|
||||
air.carbon_dioxide = carbon_dioxide
|
||||
air.nitrogen = nitrogen
|
||||
air.toxins = toxins
|
||||
air.sleeping_agent = sleeping_agent
|
||||
air.agent_b = agent_b
|
||||
|
||||
air.temperature = temperature
|
||||
|
||||
/turf/simulated/Destroy()
|
||||
visibilityChanged()
|
||||
QDEL_NULL(active_hotspot)
|
||||
QDEL_NULL(wet_overlay)
|
||||
return ..()
|
||||
|
||||
/turf/simulated/assume_air(datum/gas_mixture/giver)
|
||||
@@ -100,7 +106,7 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/turf/simulated/remove_air(amount as num)
|
||||
/turf/simulated/remove_air(amount)
|
||||
if(air)
|
||||
var/datum/gas_mixture/removed = null
|
||||
|
||||
@@ -155,7 +161,7 @@
|
||||
|
||||
var/turf/enemy_tile = get_step(src, direction)
|
||||
|
||||
if(istype(enemy_tile,/turf/simulated))
|
||||
if(istype(enemy_tile, /turf/simulated))
|
||||
var/turf/simulated/enemy_simulated = enemy_tile
|
||||
|
||||
if(current_cycle > enemy_simulated.current_cycle)
|
||||
@@ -211,7 +217,13 @@
|
||||
|
||||
if(planet_atmos) //share our air with the "atmosphere" "above" the turf
|
||||
var/datum/gas_mixture/G = new
|
||||
G.copy_from_turf(src)
|
||||
G.oxygen = oxygen
|
||||
G.carbon_dioxide = carbon_dioxide
|
||||
G.nitrogen = nitrogen
|
||||
G.toxins = toxins
|
||||
G.sleeping_agent = sleeping_agent
|
||||
G.agent_b = agent_b
|
||||
G.temperature = initial(temperature) // Temperature is modified at runtime; we only care about the turf's initial temperature
|
||||
G.archive()
|
||||
if(!air.compare(G))
|
||||
if(!excited_group)
|
||||
@@ -271,8 +283,7 @@
|
||||
if(air.toxins > MOLES_PLASMA_VISIBLE)
|
||||
return "plasma"
|
||||
|
||||
var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in air.trace_gases
|
||||
if(sleeping_agent && (sleeping_agent.moles > 1))
|
||||
if(air.sleeping_agent > 1)
|
||||
return "sleeping_agent"
|
||||
return null
|
||||
|
||||
@@ -340,7 +351,7 @@
|
||||
reset_cooldowns()
|
||||
|
||||
/datum/excited_group/proc/merge_groups(var/datum/excited_group/E)
|
||||
if(turf_list.len > E.turf_list.len)
|
||||
if(length(turf_list) > length(E.turf_list))
|
||||
SSair.excited_groups -= E
|
||||
for(var/turf/simulated/T in E.turf_list)
|
||||
T.excited_group = src
|
||||
@@ -358,32 +369,26 @@
|
||||
|
||||
/datum/excited_group/proc/self_breakdown()
|
||||
var/datum/gas_mixture/A = new
|
||||
var/datum/gas/sleeping_agent/S = new
|
||||
A.trace_gases += S
|
||||
for(var/turf/simulated/T in turf_list)
|
||||
A.oxygen += T.air.oxygen
|
||||
A.carbon_dioxide+= T.air.carbon_dioxide
|
||||
A.nitrogen += T.air.nitrogen
|
||||
A.toxins += T.air.toxins
|
||||
|
||||
if(T.air.trace_gases.len)
|
||||
for(var/datum/gas/N in T.air.trace_gases)
|
||||
S.moles += N.moles
|
||||
var/list/cached_turf_list = turf_list // cache for super speed
|
||||
|
||||
for(var/turf/simulated/T in turf_list)
|
||||
T.air.oxygen = A.oxygen/turf_list.len
|
||||
T.air.carbon_dioxide= A.carbon_dioxide/turf_list.len
|
||||
T.air.nitrogen = A.nitrogen/turf_list.len
|
||||
T.air.toxins = A.toxins/turf_list.len
|
||||
for(var/turf/simulated/T in cached_turf_list)
|
||||
A.oxygen += T.air.oxygen
|
||||
A.carbon_dioxide += T.air.carbon_dioxide
|
||||
A.nitrogen += T.air.nitrogen
|
||||
A.toxins += T.air.toxins
|
||||
A.sleeping_agent += T.air.sleeping_agent
|
||||
A.agent_b += T.air.agent_b
|
||||
|
||||
if(S.moles > 0)
|
||||
if(T.air.trace_gases.len)
|
||||
for(var/datum/gas/G in T.air.trace_gases)
|
||||
G.moles = S.moles/turf_list.len
|
||||
else
|
||||
var/datum/gas/sleeping_agent/G = new
|
||||
G.moles = S.moles/turf_list.len
|
||||
T.air.trace_gases += G
|
||||
var/turflen = length(cached_turf_list)
|
||||
|
||||
for(var/turf/simulated/T in cached_turf_list)
|
||||
T.air.oxygen = A.oxygen / turflen
|
||||
T.air.carbon_dioxide = A.carbon_dioxide / turflen
|
||||
T.air.nitrogen = A.nitrogen / turflen
|
||||
T.air.toxins = A.toxins / turflen
|
||||
T.air.sleeping_agent = A.sleeping_agent / turflen
|
||||
T.air.agent_b = A.agent_b / turflen
|
||||
|
||||
T.update_visuals()
|
||||
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/datum/stack
|
||||
var/list/stack = list()
|
||||
var/max_elements = 0
|
||||
|
||||
/datum/stack/New(list/elements,max)
|
||||
..()
|
||||
if(elements)
|
||||
stack = elements.Copy()
|
||||
if(max)
|
||||
max_elements = max
|
||||
|
||||
/datum/stack/proc/Pop()
|
||||
if(is_empty())
|
||||
return null
|
||||
. = stack[stack.len]
|
||||
stack.Cut(stack.len,0)
|
||||
|
||||
/datum/stack/proc/Push(element)
|
||||
if(max_elements && (stack.len+1 > max_elements))
|
||||
return null
|
||||
stack += element
|
||||
|
||||
/datum/stack/proc/Top()
|
||||
if(is_empty())
|
||||
return null
|
||||
. = stack[stack.len]
|
||||
|
||||
/datum/stack/proc/is_empty()
|
||||
. = stack.len ? 0 : 1
|
||||
|
||||
//Rotate entire stack left with the leftmost looping around to the right
|
||||
/datum/stack/proc/RotateLeft()
|
||||
if(is_empty())
|
||||
return 0
|
||||
. = stack[1]
|
||||
stack.Cut(1,2)
|
||||
Push(.)
|
||||
|
||||
//Rotate entire stack to the right with the rightmost looping around to the left
|
||||
/datum/stack/proc/RotateRight()
|
||||
if(is_empty())
|
||||
return 0
|
||||
. = stack[stack.len]
|
||||
stack.Cut(stack.len,0)
|
||||
stack.Insert(1,.)
|
||||
|
||||
|
||||
/datum/stack/proc/Copy()
|
||||
var/datum/stack/S=new()
|
||||
S.stack = stack.Copy()
|
||||
S.max_elements = max_elements
|
||||
return S
|
||||
|
||||
|
||||
/datum/stack/proc/Clear()
|
||||
stack.Cut()
|
||||
@@ -32,17 +32,16 @@
|
||||
// (Requires a MC restart to change)
|
||||
#define SS_NO_FIRE 2
|
||||
|
||||
//subsystem only runs on spare cpu (after all non-background subsystems have ran that tick)
|
||||
// SS_BACKGROUND has its own priority bracket
|
||||
/** Subsystem only runs on spare cpu (after all non-background subsystems have ran that tick) */
|
||||
/// SS_BACKGROUND has its own priority bracket, this overrides SS_TICKER's priority bump
|
||||
#define SS_BACKGROUND 4
|
||||
|
||||
//subsystem does not tick check, and should not run unless there is enough time (or its running behind (unless background))
|
||||
#define SS_NO_TICK_CHECK 8
|
||||
|
||||
//Treat wait as a tick count, not DS, run every wait ticks.
|
||||
// (also forces it to run first in the tick, above even SS_NO_TICK_CHECK subsystems)
|
||||
/// (also forces it to run first in the tick (unless SS_BACKGROUND))
|
||||
// (implies all runlevels because of how it works)
|
||||
// (overrides SS_BACKGROUND)
|
||||
// This is designed for basically anything that works as a mini-mc (like SStimer)
|
||||
#define SS_TICKER 16
|
||||
|
||||
|
||||
@@ -1,291 +0,0 @@
|
||||
#define SEND_SIGNAL(target, sigtype, arguments...) ( !target.comp_lookup || !target.comp_lookup[sigtype] ? NONE : target._SendSignal(sigtype, list(target, ##arguments)) )
|
||||
|
||||
#define SEND_GLOBAL_SIGNAL(sigtype, arguments...) ( SEND_SIGNAL(SSdcs, sigtype, ##arguments) )
|
||||
|
||||
//shorthand
|
||||
#define GET_COMPONENT_FROM(varname, path, target) var##path/##varname = ##target.GetComponent(##path)
|
||||
#define GET_COMPONENT(varname, path) GET_COMPONENT_FROM(varname, path, src)
|
||||
|
||||
#define COMPONENT_INCOMPATIBLE 1
|
||||
|
||||
// How multiple components of the exact same type are handled in the same datum
|
||||
|
||||
#define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default)
|
||||
#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed
|
||||
#define COMPONENT_DUPE_UNIQUE 2 //new component is deleted
|
||||
#define COMPONENT_DUPE_UNIQUE_PASSARGS 4 //old component is given the initialization args of the new
|
||||
|
||||
// All signals. Format:
|
||||
// When the signal is called: (signal arguments)
|
||||
// All signals send the source datum of the signal as the first argument
|
||||
|
||||
// global signals
|
||||
// These are signals which can be listened to by any component on any parent
|
||||
// start global signals with "!", this used to be necessary but now it's just a formatting choice
|
||||
#define COMSIG_GLOB_NEW_Z "!new_z" //from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args)
|
||||
#define COMSIG_GLOB_VAR_EDIT "!var_edit" //called after a successful var edit somewhere in the world: (list/args)
|
||||
#define COMSIG_GLOB_MOB_CREATED "!mob_created" //mob was created somewhere : (mob)
|
||||
#define COMSIG_GLOB_MOB_DEATH "!mob_death" //mob died somewhere : (mob , gibbed)
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// /datum signals
|
||||
#define COMSIG_COMPONENT_ADDED "component_added" //when a component is added to a datum: (/datum/component)
|
||||
#define COMSIG_COMPONENT_REMOVING "component_removing" //before a component is removed from a datum because of RemoveComponent: (/datum/component)
|
||||
#define COMSIG_PARENT_PREQDELETED "parent_preqdeleted" //before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation
|
||||
#define COMSIG_PARENT_QDELETING "parent_qdeleting" //just before a datum's Destroy() is called: (force), at this point none of the other components chose to interrupt qdel and Destroy will be called
|
||||
#define COMSIG_TOPIC "handle_topic" //generic topic handler (usr, href_list)
|
||||
|
||||
// /atom signals
|
||||
#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params)
|
||||
#define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called
|
||||
#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human)
|
||||
#define COMSIG_PARENT_EXAMINE "atom_examine" //from base of atom/examine(): (/mob, result)
|
||||
#define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name" //from base of atom/get_examine_name(): (/mob, list/overrides)
|
||||
//Positions for overrides list
|
||||
#define EXAMINE_POSITION_ARTICLE 1
|
||||
#define EXAMINE_POSITION_BEFORE 2
|
||||
//End positions
|
||||
#define COMPONENT_EXNAME_CHANGED 1
|
||||
#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable/entering, /atom)
|
||||
#define COMSIG_ATOM_EXITED "atom_exited" //from base of atom/Exited(): (atom/movable/exiting, atom/newloc)
|
||||
#define COMSIG_ATOM_EXIT "atom_exit" //from base of atom/Exit(): (/atom/movable/exiting, /atom/newloc)
|
||||
#define COMPONENT_ATOM_BLOCK_EXIT 1
|
||||
#define COMSIG_ATOM_EX_ACT "atom_ex_act" //from base of atom/ex_act(): (severity, target)
|
||||
#define COMSIG_ATOM_EMP_ACT "atom_emp_act" //from base of atom/emp_act(): (severity)
|
||||
#define COMSIG_ATOM_FIRE_ACT "atom_fire_act" //from base of atom/fire_act(): (exposed_temperature, exposed_volume)
|
||||
#define COMSIG_ATOM_BULLET_ACT "atom_bullet_act" //from base of atom/bullet_act(): (/obj/item/projectile, def_zone)
|
||||
#define COMSIG_ATOM_BLOB_ACT "atom_blob_act" //from base of atom/blob_act(): (/obj/structure/blob)
|
||||
#define COMSIG_ATOM_ACID_ACT "atom_acid_act" //from base of atom/acid_act(): (acidpwr, acid_volume)
|
||||
#define COMSIG_ATOM_EMAG_ACT "atom_emag_act" //from base of atom/emag_act(): ()
|
||||
#define COMSIG_ATOM_RAD_ACT "atom_rad_act" //from base of atom/rad_act(intensity)
|
||||
#define COMSIG_ATOM_NARSIE_ACT "atom_narsie_act" //from base of atom/narsie_act(): ()
|
||||
#define COMSIG_ATOM_RATVAR_ACT "atom_ratvar_act" //from base of atom/ratvar_act(): ()
|
||||
#define COMSIG_ATOM_RCD_ACT "atom_rcd_act" //from base of atom/rcd_act(): (/mob, /obj/item/construction/rcd, passed_mode)
|
||||
#define COMSIG_ATOM_SING_PULL "atom_sing_pull" //from base of atom/singularity_pull(): (S, current_size)
|
||||
#define COMSIG_ATOM_SET_LIGHT "atom_set_light" //from base of atom/set_light(): (l_range, l_power, l_color)
|
||||
#define COMSIG_ATOM_DIR_CHANGE "atom_dir_change" //from base of atom/setDir(): (old_dir, new_dir)
|
||||
#define COMSIG_ATOM_CONTENTS_DEL "atom_contents_del" //from base of atom/handle_atom_del(): (atom/deleted)
|
||||
#define COMSIG_ATOM_HAS_GRAVITY "atom_has_gravity" //from base of atom/has_gravity(): (turf/location, list/forced_gravities)
|
||||
#define COMSIG_ATOM_RAD_PROBE "atom_rad_probe" //from proc/get_rad_contents(): ()
|
||||
#define COMPONENT_BLOCK_RADIATION 1
|
||||
#define COMSIG_ATOM_RAD_CONTAMINATING "atom_rad_contam" //from base of datum/radiation_wave/radiate(): (strength)
|
||||
#define COMPONENT_BLOCK_CONTAMINATION 1
|
||||
#define COMSIG_ATOM_RAD_WAVE_PASSING "atom_rad_wave_pass" //from base of datum/radiation_wave/check_obstructions(): (datum/radiation_wave, width)
|
||||
#define COMPONENT_RAD_WAVE_HANDLED 1
|
||||
#define COMSIG_ATOM_CANREACH "atom_can_reach" //from internal loop in atom/movable/proc/CanReach(): (list/next)
|
||||
#define COMPONENT_BLOCK_REACH 1
|
||||
#define COMSIG_ATOM_SCREWDRIVER_ACT "atom_screwdriver_act" //from base of atom/screwdriver_act(): (mob/living/user, obj/item/I)
|
||||
/////////////////
|
||||
#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost" //from base of atom/attack_ghost(): (mob/dead/observer/ghost)
|
||||
#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand" //from base of atom/attack_hand(): (mob/user)
|
||||
#define COMSIG_ATOM_ATTACK_PAW "atom_attack_paw" //from base of atom/attack_paw(): (mob/user)
|
||||
#define COMPONENT_NO_ATTACK_HAND 1 //works on all 3.
|
||||
/////////////////
|
||||
|
||||
#define COMSIG_ENTER_AREA "enter_area" //from base of area/Entered(): (/area)
|
||||
#define COMSIG_EXIT_AREA "exit_area" //from base of area/Exited(): (/area)
|
||||
|
||||
#define COMSIG_CLICK "atom_click" //from base of atom/Click(): (location, control, params, mob/user)
|
||||
#define COMSIG_CLICK_SHIFT "shift_click" //from base of atom/ShiftClick(): (/mob)
|
||||
#define COMSIG_CLICK_CTRL "ctrl_click" //from base of atom/CtrlClickOn(): (/mob)
|
||||
#define COMSIG_CLICK_ALT "alt_click" //from base of atom/AltClick(): (/mob)
|
||||
#define COMSIG_CLICK_CTRL_SHIFT "ctrl_shift_click" //from base of atom/CtrlShiftClick(/mob)
|
||||
#define COMSIG_MOUSEDROP_ONTO "mousedrop_onto" //from base of atom/MouseDrop(): (/atom/over, /mob/user)
|
||||
#define COMPONENT_NO_MOUSEDROP 1
|
||||
#define COMSIG_MOUSEDROPPED_ONTO "mousedropped_onto" //from base of atom/MouseDrop_T: (/atom/from, /mob/user)
|
||||
|
||||
// /area signals
|
||||
#define COMSIG_AREA_ENTERED "area_entered" //from base of area/Entered(): (atom/movable/M)
|
||||
#define COMSIG_AREA_EXITED "area_exited" //from base of area/Exited(): (atom/movable/M)
|
||||
|
||||
// /turf signals
|
||||
#define COMSIG_TURF_CHANGE "turf_change" //from base of turf/ChangeTurf(): (path, list/new_baseturfs, flags, list/transferring_comps)
|
||||
#define COMSIG_TURF_HAS_GRAVITY "turf_has_gravity" //from base of atom/has_gravity(): (atom/asker, list/forced_gravities)
|
||||
|
||||
// /atom/movable signals
|
||||
#define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (/atom, dir)
|
||||
#define COMSIG_MOVABLE_CROSS "movable_cross" //from base of atom/movable/Cross(): (/atom/movable)
|
||||
#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (/atom/movable)
|
||||
#define COMSIG_CROSSED_MOVABLE "crossed_movable" //when we cross over something (calling Crossed() on that atom)
|
||||
#define COMSIG_MOVABLE_UNCROSSED "movable_uncrossed" //from base of atom/movable/Uncrossed(): (/atom/movable)
|
||||
#define COMSIG_MOVABLE_UNCROSS "movable_uncross" //from base of atom/movable/Uncross(): (/atom/movable)
|
||||
#define COMPONENT_MOVABLE_BLOCK_UNCROSS 1
|
||||
#define COMSIG_MOVABLE_BUMP "movable_bump" //from base of atom/movable/Bump(): (/atom)
|
||||
#define COMSIG_MOVABLE_IMPACT "movable_impact" //from base of atom/movable/throw_impact(): (/atom/hit_atom, /datum/thrownthing/throwingdatum)
|
||||
#define COMSIG_MOVABLE_IMPACT_ZONE "item_impact_zone" //from base of mob/living/hitby(): (mob/living/target, hit_zone)
|
||||
#define COMSIG_MOVABLE_BUCKLE "buckle" //from base of atom/movable/buckle_mob(): (mob, force)
|
||||
#define COMSIG_MOVABLE_UNBUCKLE "unbuckle" //from base of atom/movable/unbuckle_mob(): (mob, force)
|
||||
#define COMSIG_MOVABLE_PRE_THROW "movable_pre_throw" //from base of atom/movable/throw_at(): (list/args)
|
||||
#define COMPONENT_CANCEL_THROW 1
|
||||
#define COMSIG_MOVABLE_POST_THROW "movable_post_throw" //from base of atom/movable/throw_at(): (datum/thrownthing, spin)
|
||||
#define COMSIG_MOVABLE_Z_CHANGED "movable_ztransit" //from base of atom/movable/onTransitZ(): (old_z, new_z)
|
||||
#define COMSIG_MOVABLE_HEAR "movable_hear" //from base of atom/movable/Hear(): (message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||
#define COMSIG_MOVABLE_DISPOSING "movable_disposing" //called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source)
|
||||
|
||||
// /mob signals
|
||||
#define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed)
|
||||
#define COMSIG_MOB_CLICKON "mob_clickon" //from base of mob/clickon(): (atom/A, params)
|
||||
#define COMSIG_MOB_CANCEL_CLICKON 1
|
||||
#define COMSIG_MOB_ALLOWED "mob_allowed" //from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj
|
||||
#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" //from base of mob/anti_magic_check(): (magic, holy, protection_sources)
|
||||
#define COMPONENT_BLOCK_MAGIC 1
|
||||
#define COMSIG_MOB_HUD_CREATED "mob_hud_created" //from base of mob/create_mob_hud(): ()
|
||||
#define COMSIG_MOB_ATTACK_HAND "mob_attack_hand" //from base of
|
||||
#define COMSIG_MOB_ITEM_ATTACK "mob_item_attack" //from base of /obj/item/attack(): (mob/M, mob/user)
|
||||
#define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters)
|
||||
#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //from base of mob/RangedAttack(): (atom/A, params)
|
||||
#define COMSIG_MOB_THROW "mob_throw" //from base of /mob/throw_item(): (atom/target)
|
||||
#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): ()
|
||||
|
||||
// /mob/living signals
|
||||
#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living)
|
||||
#define COMSIG_LIVING_IGNITED "living_ignite" //from base of mob/living/IgniteMob() (/mob/living)
|
||||
#define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //from base of mob/living/ExtinguishMob() (/mob/living)
|
||||
#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage)
|
||||
#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: ()
|
||||
|
||||
//ALL OF THESE DO NOT TAKE INTO ACCOUNT WHETHER AMOUNT IS 0 OR LOWER AND ARE SENT REGARDLESS!
|
||||
#define COMSIG_LIVING_STATUS_STUN "living_stun" //from base of mob/living/Stun() (amount, update, ignore)
|
||||
#define COMSIG_LIVING_STATUS_KNOCKDOWN "living_knockdown" //from base of mob/living/Knockdown() (amount, update, ignore)
|
||||
#define COMSIG_LIVING_STATUS_PARALYZE "living_paralyze" //from base of mob/living/Paralyze() (amount, update, ignore)
|
||||
#define COMSIG_LIVING_STATUS_IMMOBILIZE "living_immobilize" //from base of mob/living/Immobilize() (amount, update, ignore)
|
||||
#define COMSIG_LIVING_STATUS_UNCONSCIOUS "living_unconscious" //from base of mob/living/Unconscious() (amount, update, ignore)
|
||||
#define COMSIG_LIVING_STATUS_SLEEP "living_sleeping" //from base of mob/living/Sleeping() (amount, update, ignore)
|
||||
#define COMPONENT_NO_STUN 1 //For all of them
|
||||
|
||||
// /mob/living/carbon signals
|
||||
#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity))
|
||||
|
||||
// /mob/living/simple_animal/hostile signals
|
||||
#define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget"
|
||||
#define COMPONENT_HOSTILE_NO_ATTACK 1
|
||||
|
||||
// /obj signals
|
||||
#define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct" //from base of obj/deconstruct(): (disassembled)
|
||||
#define COMSIG_OBJ_SETANCHORED "obj_setanchored" //called in /obj/structure/setAnchored(): (value)
|
||||
#define COMSIG_OBJ_UPDATE_ICON "obj_update_icon" //called in /obj/update_icon()
|
||||
|
||||
|
||||
// /obj/item signals
|
||||
#define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user)
|
||||
#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob)
|
||||
#define COMPONENT_NO_INTERACT 1
|
||||
#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //from base of obj/item/attack_obj(): (/obj, /mob)
|
||||
#define COMPONENT_NO_ATTACK_OBJ 1
|
||||
#define COMSIG_ITEM_PRE_ATTACK "item_pre_attack" //from base of obj/item/pre_attack(): (atom/target, mob/user, params)
|
||||
#define COMPONENT_NO_ATTACK 1
|
||||
#define COMSIG_ITEM_AFTERATTACK "item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, params)
|
||||
#define COMSIG_ITEM_EQUIPPED "item_equip" //from base of obj/item/equipped(): (/mob/equipper, slot)
|
||||
#define COMSIG_ITEM_DROPPED "item_drop" //from base of obj/item/dropped(): (mob/user)
|
||||
#define COMSIG_ITEM_PICKUP "item_pickup" //from base of obj/item/pickup(): (/mob/taker)
|
||||
#define COMSIG_ITEM_ATTACK_ZONE "item_attack_zone" //from base of mob/living/carbon/attacked_by(): (mob/living/carbon/target, mob/living/user, hit_zone)
|
||||
#define COMSIG_ITEM_IMBUE_SOUL "item_imbue_soul" //return a truthy value to prevent ensouling, checked in /obj/effect/proc_holder/spell/targeted/lichdom/cast(): (mob/user)
|
||||
#define COMSIG_ITEM_HIT_REACT "item_hit_react" //from base of obj/item/hit_reaction(): (list/args)
|
||||
|
||||
// /obj/item/clothing signals
|
||||
#define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): ()
|
||||
|
||||
// /obj/item/implant signals
|
||||
#define COMSIG_IMPLANT_ACTIVATED "implant_activated" //from base of /obj/item/implant/proc/activate(): ()
|
||||
#define COMSIG_IMPLANT_IMPLANTING "implant_implanting" //from base of /obj/item/implant/proc/implant(): (list/args)
|
||||
#define COMPONENT_STOP_IMPLANTING 1
|
||||
#define COMSIG_IMPLANT_OTHER "implant_other" //called on already installed implants when a new one is being added in /obj/item/implant/proc/implant(): (list/args, obj/item/implant/new_implant)
|
||||
//#define COMPONENT_STOP_IMPLANTING 1 //The name makes sense for both
|
||||
#define COMPONENT_DELETE_NEW_IMPLANT 2
|
||||
#define COMPONENT_DELETE_OLD_IMPLANT 4
|
||||
#define COMSIG_IMPLANT_EXISTING_UPLINK "implant_uplink_exists" //called on implants being implanted into someone with an uplink implant: (datum/component/uplink)
|
||||
//This uses all return values of COMSIG_IMPLANT_OTHER
|
||||
|
||||
// /obj/item/pda signals
|
||||
#define COMSIG_PDA_CHANGE_RINGTONE "pda_change_ringtone" //called on pda when the user changes the ringtone: (mob/living/user, new_ringtone)
|
||||
#define COMPONENT_STOP_RINGTONE_CHANGE 1
|
||||
|
||||
// /obj/item/radio signals
|
||||
#define COMSIG_RADIO_NEW_FREQUENCY "radio_new_frequency" //called from base of /obj/item/radio/proc/set_frequency(): (list/args)
|
||||
|
||||
// /obj/item/pen signals
|
||||
#define COMSIG_PEN_ROTATED "pen_rotated" //called after rotation in /obj/item/pen/attack_self(): (rotation, mob/living/carbon/user)
|
||||
|
||||
|
||||
// /mob/living/carbon/human signals
|
||||
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target)
|
||||
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker)
|
||||
#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit" //Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted)
|
||||
|
||||
// /datum/species signals
|
||||
#define COMSIG_SPECIES_GAIN "species_gain" //from datum/species/on_species_gain(): (datum/species/new_species, datum/species/old_species)
|
||||
#define COMSIG_SPECIES_LOSS "species_loss" //from datum/species/on_species_loss(): (datum/species/lost_species)
|
||||
|
||||
/*******Component Specific Signals*******/
|
||||
//Janitor
|
||||
#define COMSIG_TURF_IS_WET "check_turf_wet" //(): Returns bitflags of wet values.
|
||||
#define COMSIG_TURF_MAKE_DRY "make_turf_try" //(max_strength, immediate, duration_decrease = INFINITY): Returns bool.
|
||||
#define COMSIG_COMPONENT_CLEAN_ACT "clean_act" //called on an object to clean it of cleanables. Usualy with soap: (num/strength)
|
||||
|
||||
//Food
|
||||
#define COMSIG_FOOD_EATEN "food_eaten" //from base of obj/item/reagent_containers/food/snacks/attack(): (mob/living/eater, mob/feeder)
|
||||
|
||||
//Mood
|
||||
#define COMSIG_ADD_MOOD_EVENT "add_mood" //Called when you send a mood event from anywhere in the code.
|
||||
#define COMSIG_CLEAR_MOOD_EVENT "clear_mood" //Called when you clear a mood event from anywhere in the code.
|
||||
|
||||
//NTnet
|
||||
#define COMSIG_COMPONENT_NTNET_RECEIVE "ntnet_receive" //called on an object by its NTNET connection component on receive. (sending_id(number), sending_netname(text), data(datum/netdata))
|
||||
|
||||
//Nanites
|
||||
#define COMSIG_HAS_NANITES "has_nanites" //() returns TRUE if nanites are found
|
||||
#define COMSIG_NANITE_GET_PROGRAMS "nanite_get_programs" //(list/nanite_programs) - makes the input list a copy the nanites' program list
|
||||
#define COMSIG_NANITE_SET_VOLUME "nanite_set_volume" //(amount) Sets current nanite volume to the given amount
|
||||
#define COMSIG_NANITE_ADJUST_VOLUME "nanite_adjust" //(amount) Adjusts nanite volume by the given amount
|
||||
#define COMSIG_NANITE_SET_MAX_VOLUME "nanite_set_max_volume" //(amount) Sets maximum nanite volume to the given amount
|
||||
#define COMSIG_NANITE_SET_CLOUD "nanite_set_cloud" //(amount(0-100)) Sets cloud ID to the given amount
|
||||
#define COMSIG_NANITE_SET_SAFETY "nanite_set_safety" //(amount) Sets safety threshold to the given amount
|
||||
#define COMSIG_NANITE_SET_REGEN "nanite_set_regen" //(amount) Sets regeneration rate to the given amount
|
||||
#define COMSIG_NANITE_SIGNAL "nanite_signal" //(code(1-9999)) Called when sending a nanite signal to a mob.
|
||||
#define COMSIG_NANITE_SCAN "nanite_scan" //(mob/user, full_scan) - sends to chat a scan of the nanites to the user, returns TRUE if nanites are detected
|
||||
#define COMSIG_NANITE_UI_DATA "nanite_ui_data" //(list/data, scan_level) - adds nanite data to the given data list - made for ui_data procs
|
||||
#define COMSIG_NANITE_ADD_PROGRAM "nanite_add_program" //(datum/nanite_program/new_program, datum/nanite_program/source_program) Called when adding a program to a nanite component
|
||||
#define COMPONENT_PROGRAM_INSTALLED 1 //Installation successful
|
||||
#define COMPONENT_PROGRAM_NOT_INSTALLED 2 //Installation failed, but there are still nanites
|
||||
#define COMSIG_NANITE_SYNC "nanite_sync" //(datum/component/nanites, full_overwrite, copy_activation) Called to sync the target's nanites to a given nanite component
|
||||
|
||||
// /datum/component/storage signals
|
||||
#define COMSIG_CONTAINS_STORAGE "is_storage" //() - returns bool.
|
||||
#define COMSIG_TRY_STORAGE_INSERT "storage_try_insert" //(obj/item/inserting, mob/user, silent, force) - returns bool
|
||||
#define COMSIG_TRY_STORAGE_SHOW "storage_show_to" //(mob/show_to, force) - returns bool.
|
||||
#define COMSIG_TRY_STORAGE_HIDE_FROM "storage_hide_from" //(mob/hide_from) - returns bool
|
||||
#define COMSIG_TRY_STORAGE_HIDE_ALL "storage_hide_all" //returns bool
|
||||
#define COMSIG_TRY_STORAGE_SET_LOCKSTATE "storage_lock_set_state" //(newstate)
|
||||
#define COMSIG_IS_STORAGE_LOCKED "storage_get_lockstate" //() - returns bool. MUST CHECK IF STORAGE IS THERE FIRST!
|
||||
#define COMSIG_TRY_STORAGE_TAKE_TYPE "storage_take_type" //(type, atom/destination, amount = INFINITY, check_adjacent, force, mob/user, list/inserted) - returns bool - type can be a list of types.
|
||||
#define COMSIG_TRY_STORAGE_FILL_TYPE "storage_fill_type" //(type, amount = INFINITY, force = FALSE) //don't fuck this up. Force will ignore max_items, and amount is normally clamped to max_items.
|
||||
#define COMSIG_TRY_STORAGE_TAKE "storage_take_obj" //(obj, new_loc, force = FALSE) - returns bool
|
||||
#define COMSIG_TRY_STORAGE_QUICK_EMPTY "storage_quick_empty" //(loc) - returns bool - if loc is null it will dump at parent location.
|
||||
#define COMSIG_TRY_STORAGE_RETURN_INVENTORY "storage_return_inventory" //(list/list_to_inject_results_into, recursively_search_inside_storages = TRUE)
|
||||
#define COMSIG_TRY_STORAGE_CAN_INSERT "storage_can_equip" //(obj/item/insertion_candidate, mob/user, silent) - returns bool
|
||||
|
||||
// /datum/action signals
|
||||
#define COMSIG_ACTION_TRIGGER "action_trigger" //from base of datum/action/proc/Trigger(): (datum/action)
|
||||
#define COMPONENT_ACTION_BLOCK_TRIGGER 1
|
||||
|
||||
/*******Non-Signal Component Related Defines*******/
|
||||
|
||||
//Redirection component init flags
|
||||
#define REDIRECT_TRANSFER_WITH_TURF 1
|
||||
|
||||
//Arch
|
||||
#define ARCH_PROB "probability" //Probability for each item
|
||||
#define ARCH_MAXDROP "max_drop_amount" //each item's max drop amount
|
||||
|
||||
//Ouch my toes!
|
||||
#define CALTROP_BYPASS_SHOES 1
|
||||
#define CALTROP_IGNORE_WALKERS 2
|
||||
|
||||
//Xenobio hotkeys
|
||||
#define COMSIG_XENO_SLIME_CLICK_CTRL "xeno_slime_click_ctrl" //from slime CtrlClickOn(): (/mob)
|
||||
#define COMSIG_XENO_SLIME_CLICK_ALT "xeno_slime_click_alt" //from slime AltClickOn(): (/mob)
|
||||
#define COMSIG_XENO_SLIME_CLICK_SHIFT "xeno_slime_click_shift" //from slime ShiftClickOn(): (/mob)
|
||||
#define COMSIG_XENO_TURF_CLICK_SHIFT "xeno_turf_click_shift" //from turf ShiftClickOn(): (/mob)
|
||||
#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt" //from turf AltClickOn(): (/mob)
|
||||
#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" //from monkey CtrlClickOn(): (/mob)
|
||||
@@ -0,0 +1,41 @@
|
||||
/// Return this from `/datum/component/Initialize` or `datum/component/OnTransfer` to have the component be deleted if it's applied to an incorrect type.
|
||||
/// `parent` must not be modified if this is to be returned.
|
||||
/// This will be noted in the runtime logs
|
||||
#define COMPONENT_INCOMPATIBLE 1
|
||||
/// Returned in PostTransfer to prevent transfer, similar to `COMPONENT_INCOMPATIBLE`
|
||||
#define COMPONENT_NOTRANSFER 2
|
||||
|
||||
/// Return value to cancel attaching
|
||||
#define ELEMENT_INCOMPATIBLE 1
|
||||
|
||||
// /datum/element flags
|
||||
/// Causes the detach proc to be called when the host object is being deleted
|
||||
#define ELEMENT_DETACH (1 << 0)
|
||||
/**
|
||||
* Only elements created with the same arguments given after `id_arg_index` share an element instance
|
||||
* The arguments are the same when the text and number values are the same and all other values have the same ref
|
||||
*/
|
||||
#define ELEMENT_BESPOKE (1 << 1)
|
||||
|
||||
// How multiple components of the exact same type are handled in the same datum
|
||||
/// old component is deleted (default)
|
||||
#define COMPONENT_DUPE_HIGHLANDER 0
|
||||
/// duplicates allowed
|
||||
#define COMPONENT_DUPE_ALLOWED 1
|
||||
/// new component is deleted
|
||||
#define COMPONENT_DUPE_UNIQUE 2
|
||||
/// old component is given the initialization args of the new
|
||||
#define COMPONENT_DUPE_UNIQUE_PASSARGS 4
|
||||
/// each component of the same type is consulted as to whether the duplicate should be allowed
|
||||
#define COMPONENT_DUPE_SELECTIVE 5
|
||||
|
||||
//Redirection component init flags
|
||||
#define REDIRECT_TRANSFER_WITH_TURF 1
|
||||
|
||||
//Arch
|
||||
#define ARCH_PROB "probability" //Probability for each item
|
||||
#define ARCH_MAXDROP "max_drop_amount" //each item's max drop amount
|
||||
|
||||
//Ouch my toes!
|
||||
#define CALTROP_BYPASS_SHOES 1
|
||||
#define CALTROP_IGNORE_WALKERS 2
|
||||
@@ -0,0 +1,15 @@
|
||||
/// Used to trigger signals and call procs registered for that signal
|
||||
/// The datum hosting the signal is automaticaly added as the first argument
|
||||
/// Returns a bitfield gathered from all registered procs
|
||||
/// Arguments given here are packaged in a list and given to _SendSignal
|
||||
#define SEND_SIGNAL(target, sigtype, arguments...) ( !target.comp_lookup || !target.comp_lookup[sigtype] ? NONE : target._SendSignal(sigtype, list(target, ##arguments)) )
|
||||
|
||||
#define SEND_GLOBAL_SIGNAL(sigtype, arguments...) ( SEND_SIGNAL(SSdcs, sigtype, ##arguments) )
|
||||
|
||||
/// A wrapper for _AddElement that allows us to pretend we're using normal named arguments
|
||||
#define AddElement(arguments...) _AddElement(list(##arguments))
|
||||
/// A wrapper for _RemoveElement that allows us to pretend we're using normal named arguments
|
||||
#define RemoveElement(arguments...) _RemoveElement(list(##arguments))
|
||||
|
||||
/// A wrapper for _AddComponent that allows us to pretend we're using normal named arguments
|
||||
#define AddComponent(arguments...) _AddComponent(list(##arguments))
|
||||
@@ -0,0 +1,728 @@
|
||||
// All signals. Format:
|
||||
// When the signal is called: (signal arguments)
|
||||
// All signals send the source datum of the signal as the first argument
|
||||
|
||||
// global signals
|
||||
// These are signals which can be listened to by any component on any parent
|
||||
// start global signals with "!", this used to be necessary but now it's just a formatting choice
|
||||
|
||||
///from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args)
|
||||
#define COMSIG_GLOB_NEW_Z "!new_z"
|
||||
/// called after a successful var edit somewhere in the world: (list/args)
|
||||
#define COMSIG_GLOB_VAR_EDIT "!var_edit"
|
||||
/// called after an explosion happened : (epicenter, devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range)
|
||||
#define COMSIG_GLOB_EXPLOSION "!explosion"
|
||||
/// mob was created somewhere : (mob)
|
||||
#define COMSIG_GLOB_MOB_CREATED "!mob_created"
|
||||
/// mob died somewhere : (mob , gibbed)
|
||||
#define COMSIG_GLOB_MOB_DEATH "!mob_death"
|
||||
/// global living say plug - use sparingly: (mob/speaker , message)
|
||||
#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special"
|
||||
/// called by datum/cinematic/play() : (datum/cinematic/new_cinematic)
|
||||
#define COMSIG_GLOB_PLAY_CINEMATIC "!play_cinematic"
|
||||
#define COMPONENT_GLOB_BLOCK_CINEMATIC (1<<0)
|
||||
/// ingame button pressed (/obj/machinery/button/button)
|
||||
#define COMSIG_GLOB_BUTTON_PRESSED "!button_pressed"
|
||||
|
||||
/// signals from globally accessible objects
|
||||
|
||||
///from SSsun when the sun changes position : (azimuth)
|
||||
#define COMSIG_SUN_MOVED "sun_moved"
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// /datum signals
|
||||
/// when a component is added to a datum: (/datum/component)
|
||||
#define COMSIG_COMPONENT_ADDED "component_added"
|
||||
/// before a component is removed from a datum because of RemoveComponent: (/datum/component)
|
||||
#define COMSIG_COMPONENT_REMOVING "component_removing"
|
||||
/// before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation
|
||||
#define COMSIG_PARENT_PREQDELETED "parent_preqdeleted"
|
||||
/// just before a datum's Destroy() is called: (force), at this point none of the other components chose to interrupt qdel and Destroy will be called
|
||||
#define COMSIG_PARENT_QDELETING "parent_qdeleting"
|
||||
/// generic topic handler (usr, href_list)
|
||||
#define COMSIG_TOPIC "handle_topic"
|
||||
|
||||
/// fires on the target datum when an element is attached to it (/datum/element)
|
||||
#define COMSIG_ELEMENT_ATTACH "element_attach"
|
||||
/// fires on the target datum when an element is attached to it (/datum/element)
|
||||
#define COMSIG_ELEMENT_DETACH "element_detach"
|
||||
|
||||
// /atom signals
|
||||
///from base of atom/proc/Initialize(): sent any time a new atom is created
|
||||
#define COMSIG_ATOM_CREATED "atom_created"
|
||||
//from SSatoms InitAtom - Only if the atom was not deleted or failed initialization
|
||||
#define COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE "atom_init_success"
|
||||
///from base of atom/attackby(): (/obj/item, /mob/living, params)
|
||||
#define COMSIG_PARENT_ATTACKBY "atom_attackby"
|
||||
///Return this in response if you don't want afterattack to be called
|
||||
#define COMPONENT_NO_AFTERATTACK (1<<0)
|
||||
///from base of atom/attack_hulk(): (/mob/living/carbon/human)
|
||||
#define COMSIG_ATOM_HULK_ATTACK "hulk_attack"
|
||||
///from base of atom/animal_attack(): (/mob/user)
|
||||
#define COMSIG_ATOM_ATTACK_ANIMAL "attack_animal"
|
||||
///from base of atom/examine(): (/mob)
|
||||
#define COMSIG_PARENT_EXAMINE "atom_examine"
|
||||
///from base of atom/get_examine_name(): (/mob, list/overrides)
|
||||
#define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name"
|
||||
//Positions for overrides list
|
||||
#define EXAMINE_POSITION_ARTICLE (1<<0)
|
||||
#define EXAMINE_POSITION_BEFORE (1<<1)
|
||||
//End positions
|
||||
#define COMPONENT_EXNAME_CHANGED (1<<0)
|
||||
///from base of atom/update_icon(): ()
|
||||
#define COMSIG_ATOM_UPDATE_ICON "atom_update_icon"
|
||||
#define COMSIG_ATOM_NO_UPDATE_ICON_STATE (1<<0)
|
||||
#define COMSIG_ATOM_NO_UPDATE_OVERLAYS (1<<1)
|
||||
///from base of atom/update_overlays(): (list/new_overlays)
|
||||
#define COMSIG_ATOM_UPDATE_OVERLAYS "atom_update_overlays"
|
||||
///from base of atom/update_icon(): (signalOut, did_anything)
|
||||
#define COMSIG_ATOM_UPDATED_ICON "atom_updated_icon"
|
||||
///from base of atom/Entered(): (atom/movable/entering, /atom)
|
||||
#define COMSIG_ATOM_ENTERED "atom_entered"
|
||||
///from base of atom/Exit(): (/atom/movable/exiting, /atom/newloc)
|
||||
#define COMSIG_ATOM_EXIT "atom_exit"
|
||||
#define COMPONENT_ATOM_BLOCK_EXIT (1<<0)
|
||||
///from base of atom/Exited(): (atom/movable/exiting, atom/newloc)
|
||||
#define COMSIG_ATOM_EXITED "atom_exited"
|
||||
///from base of atom/Bumped(): (/atom/movable)
|
||||
#define COMSIG_ATOM_BUMPED "atom_bumped"
|
||||
///from base of atom/ex_act(): (severity, target)
|
||||
#define COMSIG_ATOM_EX_ACT "atom_ex_act"
|
||||
///from base of atom/emp_act(): (severity)
|
||||
#define COMSIG_ATOM_EMP_ACT "atom_emp_act"
|
||||
///from base of atom/fire_act(): (exposed_temperature, exposed_volume)
|
||||
#define COMSIG_ATOM_FIRE_ACT "atom_fire_act"
|
||||
///from base of atom/bullet_act(): (/obj/projectile, def_zone)
|
||||
#define COMSIG_ATOM_BULLET_ACT "atom_bullet_act"
|
||||
///from base of atom/blob_act(): (/obj/structure/blob)
|
||||
#define COMSIG_ATOM_BLOB_ACT "atom_blob_act"
|
||||
///from base of atom/acid_act(): (acidpwr, acid_volume)
|
||||
#define COMSIG_ATOM_ACID_ACT "atom_acid_act"
|
||||
///from base of atom/emag_act(): (/mob/user)
|
||||
#define COMSIG_ATOM_EMAG_ACT "atom_emag_act"
|
||||
///from base of atom/rad_act(intensity)
|
||||
#define COMSIG_ATOM_RAD_ACT "atom_rad_act"
|
||||
///from base of atom/narsie_act(): ()
|
||||
#define COMSIG_ATOM_NARSIE_ACT "atom_narsie_act"
|
||||
///from base of atom/rcd_act(): (/mob, /obj/item/construction/rcd, passed_mode)
|
||||
#define COMSIG_ATOM_RCD_ACT "atom_rcd_act"
|
||||
///from base of atom/singularity_pull(): (S, current_size)
|
||||
#define COMSIG_ATOM_SING_PULL "atom_sing_pull"
|
||||
///from obj/machinery/bsa/full/proc/fire(): ()
|
||||
#define COMSIG_ATOM_BSA_BEAM "atom_bsa_beam_pass"
|
||||
#define COMSIG_ATOM_BLOCKS_BSA_BEAM (1<<0)
|
||||
///from base of atom/set_light(): (l_range, l_power, l_color)
|
||||
#define COMSIG_ATOM_SET_LIGHT "atom_set_light"
|
||||
///from base of atom/setDir(): (old_dir, new_dir)
|
||||
#define COMSIG_ATOM_DIR_CHANGE "atom_dir_change"
|
||||
///from base of atom/handle_atom_del(): (atom/deleted)
|
||||
#define COMSIG_ATOM_CONTENTS_DEL "atom_contents_del"
|
||||
///from base of atom/has_gravity(): (turf/location, list/forced_gravities)
|
||||
#define COMSIG_ATOM_HAS_GRAVITY "atom_has_gravity"
|
||||
///from proc/get_rad_contents(): ()
|
||||
#define COMSIG_ATOM_RAD_PROBE "atom_rad_probe"
|
||||
#define COMPONENT_BLOCK_RADIATION (1<<0)
|
||||
///from base of datum/radiation_wave/radiate(): (strength)
|
||||
#define COMSIG_ATOM_RAD_CONTAMINATING "atom_rad_contam"
|
||||
#define COMPONENT_BLOCK_CONTAMINATION (1<<0)
|
||||
///from base of datum/radiation_wave/check_obstructions(): (datum/radiation_wave, width)
|
||||
#define COMSIG_ATOM_RAD_WAVE_PASSING "atom_rad_wave_pass"
|
||||
#define COMPONENT_RAD_WAVE_HANDLED (1<<0)
|
||||
///from internal loop in atom/movable/proc/CanReach(): (list/next)
|
||||
#define COMSIG_ATOM_CANREACH "atom_can_reach"
|
||||
#define COMPONENT_BLOCK_REACH (1<<0)
|
||||
///from base of atom/screwdriver_act(): (mob/living/user, obj/item/I)
|
||||
#define COMSIG_ATOM_SCREWDRIVER_ACT "atom_screwdriver_act"
|
||||
///from base of atom/wrench_act(): (mob/living/user, obj/item/I)
|
||||
#define COMSIG_ATOM_WRENCH_ACT "atom_wrench_act"
|
||||
///from base of atom/multitool_act(): (mob/living/user, obj/item/I)
|
||||
#define COMSIG_ATOM_MULTITOOL_ACT "atom_multitool_act"
|
||||
///from base of atom/welder_act(): (mob/living/user, obj/item/I)
|
||||
#define COMSIG_ATOM_WELDER_ACT "atom_welder_act"
|
||||
///from base of atom/wirecutter_act(): (mob/living/user, obj/item/I)
|
||||
#define COMSIG_ATOM_WIRECUTTER_ACT "atom_wirecutter_act"
|
||||
///from base of atom/crowbar_act(): (mob/living/user, obj/item/I)
|
||||
#define COMSIG_ATOM_CROWBAR_ACT "atom_crowbar_act"
|
||||
///from base of atom/analyser_act(): (mob/living/user, obj/item/I)
|
||||
#define COMSIG_ATOM_ANALYSER_ACT "atom_analyser_act"
|
||||
#define COMPONENT_BLOCK_TOOL_ATTACK (1<<0)
|
||||
///called when teleporting into a protected turf: (channel, turf/origin)
|
||||
#define COMSIG_ATOM_INTERCEPT_TELEPORT "intercept_teleport"
|
||||
#define COMPONENT_BLOCK_TELEPORT (1<<0)
|
||||
///called when an atom is added to the hearers on get_hearers_in_view(): (list/processing_list, list/hearers)
|
||||
#define COMSIG_ATOM_HEARER_IN_VIEW "atom_hearer_in_view"
|
||||
///called when an atom starts orbiting another atom: (atom)
|
||||
#define COMSIG_ATOM_ORBIT_BEGIN "atom_orbit_begin"
|
||||
///called when an atom stops orbiting another atom: (atom)
|
||||
#define COMSIG_ATOM_ORBIT_STOP "atom_orbit_stop"
|
||||
/////////////////
|
||||
///from base of atom/attack_ghost(): (mob/dead/observer/ghost)
|
||||
#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost"
|
||||
///from base of atom/attack_hand(): (mob/user)
|
||||
#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand"
|
||||
///from base of atom/attack_paw(): (mob/user)
|
||||
#define COMSIG_ATOM_ATTACK_PAW "atom_attack_paw"
|
||||
#define COMPONENT_NO_ATTACK_HAND (1<<0) //works on all 3.
|
||||
//This signal return value bitflags can be found in __DEFINES/misc.dm
|
||||
|
||||
///called for each movable in a turf contents on /turf/zImpact(): (atom/movable/A, levels)
|
||||
#define COMSIG_ATOM_INTERCEPT_Z_FALL "movable_intercept_z_impact"
|
||||
///called on a movable (NOT living) when someone starts pulling it (atom/movable/puller, state, force)
|
||||
#define COMSIG_ATOM_START_PULL "movable_start_pull"
|
||||
///called on /living when someone starts pulling it (atom/movable/puller, state, force)
|
||||
#define COMSIG_LIVING_START_PULL "living_start_pull"
|
||||
|
||||
/////////////////
|
||||
|
||||
///from base of area/Entered(): (/area)
|
||||
#define COMSIG_ENTER_AREA "enter_area"
|
||||
///from base of area/Exited(): (/area)
|
||||
#define COMSIG_EXIT_AREA "exit_area"
|
||||
///from base of atom/Click(): (location, control, params, mob/user)
|
||||
#define COMSIG_CLICK "atom_click"
|
||||
///from base of atom/ShiftClick(): (/mob)
|
||||
#define COMSIG_CLICK_SHIFT "shift_click"
|
||||
#define COMPONENT_ALLOW_EXAMINATE (1<<0) //Allows the user to examinate regardless of client.eye.
|
||||
///from base of atom/CtrlClickOn(): (/mob)
|
||||
#define COMSIG_CLICK_CTRL "ctrl_click"
|
||||
///from base of atom/AltClick(): (/mob)
|
||||
#define COMSIG_CLICK_ALT "alt_click"
|
||||
///from base of atom/CtrlShiftClick(/mob)
|
||||
#define COMSIG_CLICK_CTRL_SHIFT "ctrl_shift_click"
|
||||
///from base of atom/MouseDrop(): (/atom/over, /mob/user)
|
||||
#define COMSIG_MOUSEDROP_ONTO "mousedrop_onto"
|
||||
#define COMPONENT_NO_MOUSEDROP (1<<0)
|
||||
///from base of atom/MouseDrop_T: (/atom/from, /mob/user)
|
||||
#define COMSIG_MOUSEDROPPED_ONTO "mousedropped_onto"
|
||||
|
||||
// /area signals
|
||||
|
||||
///from base of area/Entered(): (atom/movable/M)
|
||||
#define COMSIG_AREA_ENTERED "area_entered"
|
||||
///from base of area/Exited(): (atom/movable/M)
|
||||
#define COMSIG_AREA_EXITED "area_exited"
|
||||
|
||||
// /turf signals
|
||||
|
||||
///from base of turf/ChangeTurf(): (path, list/new_baseturfs, flags, list/transferring_comps)
|
||||
#define COMSIG_TURF_CHANGE "turf_change"
|
||||
///from base of atom/has_gravity(): (atom/asker, list/forced_gravities)
|
||||
#define COMSIG_TURF_HAS_GRAVITY "turf_has_gravity"
|
||||
///from base of turf/New(): (turf/source, direction)
|
||||
#define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new"
|
||||
|
||||
// /atom/movable signals
|
||||
|
||||
///from base of atom/movable/Moved(): (/atom)
|
||||
#define COMSIG_MOVABLE_PRE_MOVE "movable_pre_move"
|
||||
#define COMPONENT_MOVABLE_BLOCK_PRE_MOVE (1<<0)
|
||||
///from base of atom/movable/Moved(): (/atom, dir)
|
||||
#define COMSIG_MOVABLE_MOVED "movable_moved"
|
||||
///from base of atom/movable/Cross(): (/atom/movable)
|
||||
#define COMSIG_MOVABLE_CROSS "movable_cross"
|
||||
///from base of atom/movable/Crossed(): (/atom/movable)
|
||||
#define COMSIG_MOVABLE_CROSSED "movable_crossed"
|
||||
///when we cross over something (calling Crossed() on that atom)
|
||||
#define COMSIG_CROSSED_MOVABLE "crossed_movable"
|
||||
///from base of atom/movable/Uncross(): (/atom/movable)
|
||||
#define COMSIG_MOVABLE_UNCROSS "movable_uncross"
|
||||
#define COMPONENT_MOVABLE_BLOCK_UNCROSS (1<<0)
|
||||
///from base of atom/movable/Uncrossed(): (/atom/movable)
|
||||
#define COMSIG_MOVABLE_UNCROSSED "movable_uncrossed"
|
||||
///from base of atom/movable/Bump(): (/atom)
|
||||
#define COMSIG_MOVABLE_BUMP "movable_bump"
|
||||
///from base of atom/movable/throw_impact(): (/atom/hit_atom, /datum/thrownthing/throwingdatum)
|
||||
#define COMSIG_MOVABLE_IMPACT "movable_impact"
|
||||
#define COMPONENT_MOVABLE_IMPACT_FLIP_HITPUSH (1<<0) //if true, flip if the impact will push what it hits
|
||||
#define COMPONENT_MOVABLE_IMPACT_NEVERMIND (1<<1) //return true if you destroyed whatever it was you're impacting and there won't be anything for hitby() to run on
|
||||
///from base of mob/living/hitby(): (mob/living/target, hit_zone)
|
||||
#define COMSIG_MOVABLE_IMPACT_ZONE "item_impact_zone"
|
||||
///from base of atom/movable/buckle_mob(): (mob, force)
|
||||
#define COMSIG_MOVABLE_BUCKLE "buckle"
|
||||
///from base of atom/movable/unbuckle_mob(): (mob, force)
|
||||
#define COMSIG_MOVABLE_UNBUCKLE "unbuckle"
|
||||
///from base of atom/movable/throw_at(): (list/args)
|
||||
#define COMSIG_MOVABLE_PRE_THROW "movable_pre_throw"
|
||||
#define COMPONENT_CANCEL_THROW (1<<0)
|
||||
///from base of atom/movable/throw_at(): (datum/thrownthing, spin)
|
||||
#define COMSIG_MOVABLE_POST_THROW "movable_post_throw"
|
||||
///from base of atom/movable/onTransitZ(): (old_z, new_z)
|
||||
#define COMSIG_MOVABLE_Z_CHANGED "movable_ztransit"
|
||||
///called when the movable is placed in an unaccessible area, used for stationloving: ()
|
||||
#define COMSIG_MOVABLE_SECLUDED_LOCATION "movable_secluded"
|
||||
///from base of atom/movable/Hear(): (proc args list(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode))
|
||||
#define COMSIG_MOVABLE_HEAR "movable_hear"
|
||||
#define HEARING_MESSAGE 1
|
||||
#define HEARING_SPEAKER 2
|
||||
// #define HEARING_LANGUAGE 3
|
||||
#define HEARING_RAW_MESSAGE 4
|
||||
/* #define HEARING_RADIO_FREQ 5
|
||||
#define HEARING_SPANS 6
|
||||
#define HEARING_MESSAGE_MODE 7 */
|
||||
|
||||
///called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source)
|
||||
#define COMSIG_MOVABLE_DISPOSING "movable_disposing"
|
||||
|
||||
// /mob signals
|
||||
|
||||
///from base of /mob/Login(): ()
|
||||
#define COMSIG_MOB_LOGIN "mob_login"
|
||||
///from base of /mob/Logout(): ()
|
||||
#define COMSIG_MOB_LOGOUT "mob_logout"
|
||||
///from base of mob/death(): (gibbed)
|
||||
#define COMSIG_MOB_DEATH "mob_death"
|
||||
///from base of mob/set_stat(): (new_stat)
|
||||
#define COMSIG_MOB_STATCHANGE "mob_statchange"
|
||||
///from base of mob/clickon(): (atom/A, params)
|
||||
#define COMSIG_MOB_CLICKON "mob_clickon"
|
||||
///from base of mob/MiddleClickOn(): (atom/A)
|
||||
#define COMSIG_MOB_MIDDLECLICKON "mob_middleclickon"
|
||||
///from base of mob/AltClickOn(): (atom/A)
|
||||
#define COMSIG_MOB_ALTCLICKON "mob_altclickon"
|
||||
#define COMSIG_MOB_CANCEL_CLICKON (1<<0)
|
||||
|
||||
///from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj
|
||||
#define COMSIG_MOB_ALLOWED "mob_allowed"
|
||||
///from base of mob/anti_magic_check(): (mob/user, magic, holy, tinfoil, chargecost, self, protection_sources)
|
||||
#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic"
|
||||
#define COMPONENT_BLOCK_MAGIC (1<<0)
|
||||
///from base of mob/create_mob_hud(): ()
|
||||
#define COMSIG_MOB_HUD_CREATED "mob_hud_created"
|
||||
///from base of atom/attack_hand(): (mob/user)
|
||||
#define COMSIG_MOB_ATTACK_HAND "mob_attack_hand"
|
||||
///from base of /obj/item/attack(): (mob/M, mob/user)
|
||||
#define COMSIG_MOB_ITEM_ATTACK "mob_item_attack"
|
||||
#define COMPONENT_ITEM_NO_ATTACK (1<<0)
|
||||
///from base of /mob/living/proc/apply_damage(): (damage, damagetype, def_zone)
|
||||
#define COMSIG_MOB_APPLY_DAMGE "mob_apply_damage"
|
||||
///from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters)
|
||||
#define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack"
|
||||
///from base of obj/item/attack_qdeleted(): (atom/target, mob/user, proxiumity_flag, click_parameters)
|
||||
#define COMSIG_MOB_ITEM_ATTACK_QDELETED "mob_item_attack_qdeleted"
|
||||
///from base of mob/RangedAttack(): (atom/A, params)
|
||||
#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged"
|
||||
///from base of /mob/throw_item(): (atom/target)
|
||||
#define COMSIG_MOB_THROW "mob_throw"
|
||||
///from base of /mob/verb/examinate(): (atom/target)
|
||||
#define COMSIG_MOB_EXAMINATE "mob_examinate"
|
||||
///from base of /mob/update_sight(): ()
|
||||
#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight"
|
||||
////from /mob/living/say(): ()
|
||||
#define COMSIG_MOB_SAY "mob_say"
|
||||
#define COMPONENT_UPPERCASE_SPEECH (1<<0)
|
||||
// used to access COMSIG_MOB_SAY argslist
|
||||
#define SPEECH_MESSAGE 1
|
||||
// #define SPEECH_BUBBLE_TYPE 2
|
||||
#define SPEECH_SPANS 3
|
||||
/* #define SPEECH_SANITIZE 4
|
||||
#define SPEECH_LANGUAGE 5
|
||||
#define SPEECH_IGNORE_SPAM 6
|
||||
#define SPEECH_FORCED 7 */
|
||||
|
||||
///from /mob/say_dead(): (mob/speaker, message)
|
||||
#define COMSIG_MOB_DEADSAY "mob_deadsay"
|
||||
#define MOB_DEADSAY_SIGNAL_INTERCEPT (1<<0)
|
||||
///from /mob/living/emote(): ()
|
||||
#define COMSIG_MOB_EMOTE "mob_emote"
|
||||
///from base of mob/swap_hand(): (obj/item)
|
||||
#define COMSIG_MOB_SWAP_HANDS "mob_swap_hands"
|
||||
#define COMPONENT_BLOCK_SWAP (1<<0)
|
||||
|
||||
// /mob/living signals
|
||||
|
||||
///from base of mob/living/resist() (/mob/living)
|
||||
#define COMSIG_LIVING_RESIST "living_resist"
|
||||
///from base of mob/living/IgniteMob() (/mob/living)
|
||||
#define COMSIG_LIVING_IGNITED "living_ignite"
|
||||
///from base of mob/living/ExtinguishMob() (/mob/living)
|
||||
#define COMSIG_LIVING_EXTINGUISHED "living_extinguished"
|
||||
///from base of mob/living/electrocute_act(): (shock_damage, source, siemens_coeff, flags)
|
||||
#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act"
|
||||
///sent when items with siemen coeff. of 0 block a shock: (power_source, source, siemens_coeff, dist_check)
|
||||
#define COMSIG_LIVING_SHOCK_PREVENTED "living_shock_prevented"
|
||||
///sent by stuff like stunbatons and tasers: ()
|
||||
#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock"
|
||||
///from base of mob/living/revive() (full_heal, admin_revive)
|
||||
#define COMSIG_LIVING_REVIVE "living_revive"
|
||||
///from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs)
|
||||
#define COMSIG_LIVING_REGENERATE_LIMBS "living_regen_limbs"
|
||||
///from base of /obj/item/bodypart/proc/attach_limb(): (new_limb, special) allows you to fail limb attachment
|
||||
#define COMSIG_LIVING_ATTACH_LIMB "living_attach_limb"
|
||||
#define COMPONENT_NO_ATTACH (1<<0)
|
||||
///sent from borg recharge stations: (amount, repairs)
|
||||
#define COMSIG_PROCESS_BORGCHARGER_OCCUPANT "living_charge"
|
||||
///sent when a mob/login() finishes: (client)
|
||||
#define COMSIG_MOB_CLIENT_LOGIN "comsig_mob_client_login"
|
||||
///sent from borg mobs to itself, for tools to catch an upcoming destroy() due to safe decon (rather than detonation)
|
||||
#define COMSIG_BORG_SAFE_DECONSTRUCT "borg_safe_decon"
|
||||
|
||||
//ALL OF THESE DO NOT TAKE INTO ACCOUNT WHETHER AMOUNT IS 0 OR LOWER AND ARE SENT REGARDLESS!
|
||||
|
||||
///from base of mob/living/Stun() (amount, update, ignore)
|
||||
#define COMSIG_LIVING_STATUS_STUN "living_stun"
|
||||
///from base of mob/living/Knockdown() (amount, update, ignore)
|
||||
#define COMSIG_LIVING_STATUS_KNOCKDOWN "living_knockdown"
|
||||
///from base of mob/living/Paralyze() (amount, update, ignore)
|
||||
#define COMSIG_LIVING_STATUS_PARALYZE "living_paralyze"
|
||||
///from base of mob/living/Immobilize() (amount, update, ignore)
|
||||
#define COMSIG_LIVING_STATUS_IMMOBILIZE "living_immobilize"
|
||||
///from base of mob/living/Unconscious() (amount, update, ignore)
|
||||
#define COMSIG_LIVING_STATUS_UNCONSCIOUS "living_unconscious"
|
||||
///from base of mob/living/Sleeping() (amount, update, ignore)
|
||||
#define COMSIG_LIVING_STATUS_SLEEP "living_sleeping"
|
||||
#define COMPONENT_NO_STUN (1<<0) //For all of them
|
||||
///from base of /mob/living/can_track(): (mob/user)
|
||||
#define COMSIG_LIVING_CAN_TRACK "mob_cantrack"
|
||||
#define COMPONENT_CANT_TRACK (1<<0)
|
||||
|
||||
// /mob/living/carbon signals
|
||||
|
||||
///from base of mob/living/carbon/soundbang_act(): (list(intensity))
|
||||
#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang"
|
||||
///from /item/organ/proc/Insert() (/obj/item/organ/)
|
||||
#define COMSIG_CARBON_GAIN_ORGAN "carbon_gain_organ"
|
||||
///from /item/organ/proc/Remove() (/obj/item/organ/)
|
||||
#define COMSIG_CARBON_LOSE_ORGAN "carbon_lose_organ"
|
||||
///from /mob/living/carbon/doUnEquip(obj/item/I, force, newloc, no_move, invdrop, silent)
|
||||
#define COMSIG_CARBON_EQUIP_HAT "carbon_equip_hat"
|
||||
///from /mob/living/carbon/doUnEquip(obj/item/I, force, newloc, no_move, invdrop, silent)
|
||||
#define COMSIG_CARBON_UNEQUIP_HAT "carbon_unequip_hat"
|
||||
///defined twice, in carbon and human's topics, fired when interacting with a valid embedded_object to pull it out (mob/living/carbon/target, /obj/item, /obj/item/bodypart/L)
|
||||
#define COMSIG_CARBON_EMBED_RIP "item_embed_start_rip"
|
||||
///called when removing a given item from a mob, from mob/living/carbon/remove_embedded_object(mob/living/carbon/target, /obj/item)
|
||||
#define COMSIG_CARBON_EMBED_REMOVAL "item_embed_remove_safe"
|
||||
|
||||
// /mob/living/simple_animal/hostile signals
|
||||
#define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget"
|
||||
#define COMPONENT_HOSTILE_NO_ATTACK (1<<0)
|
||||
|
||||
// /obj signals
|
||||
|
||||
///from base of obj/deconstruct(): (disassembled)
|
||||
#define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct"
|
||||
///called in /obj/structure/setAnchored(): (value)
|
||||
#define COMSIG_OBJ_SETANCHORED "obj_setanchored"
|
||||
///from base of code/game/machinery
|
||||
#define COMSIG_OBJ_DEFAULT_UNFASTEN_WRENCH "obj_default_unfasten_wrench"
|
||||
///from base of /turf/proc/levelupdate(). (intact) true to hide and false to unhide
|
||||
#define COMSIG_OBJ_HIDE "obj_hide"
|
||||
///called in /obj/update_icon()
|
||||
#define COMSIG_OBJ_UPDATE_ICON "obj_update_icon"
|
||||
|
||||
// /obj/machinery signals
|
||||
|
||||
///from /obj/machinery/obj_break(damage_flag): (damage_flag)
|
||||
#define COMSIG_MACHINERY_BROKEN "machinery_broken"
|
||||
///from base power_change() when power is lost
|
||||
#define COMSIG_MACHINERY_POWER_LOST "machinery_power_lost"
|
||||
///from base power_change() when power is restored
|
||||
#define COMSIG_MACHINERY_POWER_RESTORED "machinery_power_restored"
|
||||
|
||||
// /obj/item signals
|
||||
|
||||
///from base of obj/item/attack(): (/mob/living/target, /mob/living/user)
|
||||
#define COMSIG_ITEM_ATTACK "item_attack"
|
||||
///from base of obj/item/attack_self(): (/mob)
|
||||
#define COMSIG_ITEM_ATTACK_SELF "item_attack_self"
|
||||
#define COMPONENT_NO_INTERACT (1<<0)
|
||||
///from base of obj/item/attack_obj(): (/obj, /mob)
|
||||
#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj"
|
||||
#define COMPONENT_NO_ATTACK_OBJ (1<<0)
|
||||
///from base of obj/item/pre_attack(): (atom/target, mob/user, params)
|
||||
#define COMSIG_ITEM_PRE_ATTACK "item_pre_attack"
|
||||
#define COMPONENT_NO_ATTACK (1<<0)
|
||||
///from base of obj/item/afterattack(): (atom/target, mob/user, params)
|
||||
#define COMSIG_ITEM_AFTERATTACK "item_afterattack"
|
||||
///from base of obj/item/attack_qdeleted(): (atom/target, mob/user, params)
|
||||
#define COMSIG_ITEM_ATTACK_QDELETED "item_attack_qdeleted"
|
||||
///from base of obj/item/equipped(): (/mob/equipper, slot)
|
||||
#define COMSIG_ITEM_EQUIPPED "item_equip"
|
||||
///from base of obj/item/dropped(): (mob/user)
|
||||
#define COMSIG_ITEM_DROPPED "item_drop"
|
||||
///from base of obj/item/pickup(): (/mob/taker)
|
||||
#define COMSIG_ITEM_PICKUP "item_pickup"
|
||||
///from base of mob/living/carbon/attacked_by(): (mob/living/carbon/target, mob/living/user, hit_zone)
|
||||
#define COMSIG_ITEM_ATTACK_ZONE "item_attack_zone"
|
||||
///return a truthy value to prevent ensouling, checked in /obj/effect/proc_holder/spell/targeted/lichdom/cast(): (mob/user)
|
||||
#define COMSIG_ITEM_IMBUE_SOUL "item_imbue_soul"
|
||||
///called before marking an object for retrieval, checked in /obj/effect/proc_holder/spell/targeted/summonitem/cast() : (mob/user)
|
||||
#define COMSIG_ITEM_MARK_RETRIEVAL "item_mark_retrieval"
|
||||
#define COMPONENT_BLOCK_MARK_RETRIEVAL (1<<0)
|
||||
///from base of obj/item/hit_reaction(): (list/args)
|
||||
#define COMSIG_ITEM_HIT_REACT "item_hit_react"
|
||||
///called on item when crossed by something (): (/atom/movable, mob/living/crossed)
|
||||
#define COMSIG_ITEM_WEARERCROSSED "wearer_crossed"
|
||||
///called on item when microwaved (): (obj/machinery/microwave/M)
|
||||
#define COMSIG_ITEM_MICROWAVE_ACT "microwave_act"
|
||||
///from base of item/sharpener/attackby(): (amount, max)
|
||||
#define COMSIG_ITEM_SHARPEN_ACT "sharpen_act"
|
||||
#define COMPONENT_BLOCK_SHARPEN_APPLIED (1<<0)
|
||||
#define COMPONENT_BLOCK_SHARPEN_BLOCKED (1<<1)
|
||||
#define COMPONENT_BLOCK_SHARPEN_ALREADY (1<<2)
|
||||
#define COMPONENT_BLOCK_SHARPEN_MAXED (1<<3)
|
||||
///from base of [/obj/item/proc/tool_check_callback]: (mob/living/user)
|
||||
#define COMSIG_TOOL_IN_USE "tool_in_use"
|
||||
///from base of [/obj/item/proc/tool_start_check]: (mob/living/user)
|
||||
#define COMSIG_TOOL_START_USE "tool_start_use"
|
||||
///from [/obj/item/proc/disableEmbedding]:
|
||||
#define COMSIG_ITEM_DISABLE_EMBED "item_disable_embed"
|
||||
///from [/obj/effect/mine/proc/triggermine]:
|
||||
#define COMSIG_MINE_TRIGGERED "minegoboom"
|
||||
|
||||
// /obj/item signals for economy
|
||||
///called when an item is sold by the exports subsystem
|
||||
#define COMSIG_ITEM_SOLD "item_sold"
|
||||
///called when a wrapped up structure is opened by hand
|
||||
#define COMSIG_STRUCTURE_UNWRAPPED "structure_unwrapped"
|
||||
#define COMSIG_ITEM_UNWRAPPED "item_unwrapped"
|
||||
///called when a wrapped up item is opened by hand
|
||||
#define COMSIG_ITEM_SPLIT_VALUE (1<<0)
|
||||
///called when getting the item's exact ratio for cargo's profit.
|
||||
#define COMSIG_ITEM_SPLIT_PROFIT "item_split_profits"
|
||||
///called when getting the item's exact ratio for cargo's profit, without selling the item.
|
||||
#define COMSIG_ITEM_SPLIT_PROFIT_DRY "item_split_profits_dry"
|
||||
|
||||
// /obj/item/clothing signals
|
||||
|
||||
///from base of obj/item/clothing/shoes/proc/step_action(): ()
|
||||
#define COMSIG_SHOES_STEP_ACTION "shoes_step_action"
|
||||
///from base of /obj/item/clothing/suit/space/proc/toggle_spacesuit(): (obj/item/clothing/suit/space/suit)
|
||||
#define COMSIG_SUIT_SPACE_TOGGLE "suit_space_toggle"
|
||||
|
||||
// /obj/item/implant signals
|
||||
///from base of /obj/item/implant/proc/activate(): ()
|
||||
#define COMSIG_IMPLANT_ACTIVATED "implant_activated"
|
||||
///from base of /obj/item/implant/proc/implant(): (list/args)
|
||||
#define COMSIG_IMPLANT_IMPLANTING "implant_implanting"
|
||||
#define COMPONENT_STOP_IMPLANTING (1<<0)
|
||||
///called on already installed implants when a new one is being added in /obj/item/implant/proc/implant(): (list/args, obj/item/implant/new_implant)
|
||||
#define COMSIG_IMPLANT_OTHER "implant_other"
|
||||
//#define COMPONENT_STOP_IMPLANTING (1<<0) //The name makes sense for both
|
||||
#define COMPONENT_DELETE_NEW_IMPLANT (1<<1)
|
||||
#define COMPONENT_DELETE_OLD_IMPLANT (1<<2)
|
||||
///called on implants being implanted into someone with an uplink implant: (datum/component/uplink)
|
||||
#define COMSIG_IMPLANT_EXISTING_UPLINK "implant_uplink_exists"
|
||||
//This uses all return values of COMSIG_IMPLANT_OTHER
|
||||
|
||||
// /obj/item/pda signals
|
||||
|
||||
///called on pda when the user changes the ringtone: (mob/living/user, new_ringtone)
|
||||
#define COMSIG_PDA_CHANGE_RINGTONE "pda_change_ringtone"
|
||||
#define COMPONENT_STOP_RINGTONE_CHANGE (1<<0)
|
||||
#define COMSIG_PDA_CHECK_DETONATE "pda_check_detonate"
|
||||
#define COMPONENT_PDA_NO_DETONATE (1<<0)
|
||||
|
||||
// /obj/item/radio signals
|
||||
|
||||
///called from base of /obj/item/radio/proc/set_frequency(): (list/args)
|
||||
#define COMSIG_RADIO_NEW_FREQUENCY "radio_new_frequency"
|
||||
|
||||
// /obj/item/pen signals
|
||||
|
||||
///called after rotation in /obj/item/pen/attack_self(): (rotation, mob/living/carbon/user)
|
||||
#define COMSIG_PEN_ROTATED "pen_rotated"
|
||||
|
||||
// /obj/item/gun signals
|
||||
|
||||
///called in /obj/item/gun/process_fire (user, target, params, zone_override)
|
||||
#define COMSIG_MOB_FIRED_GUN "mob_fired_gun"
|
||||
|
||||
// /obj/item/grenade signals
|
||||
|
||||
///called in /obj/item/gun/process_fire (user, target, params, zone_override)
|
||||
#define COMSIG_GRENADE_PRIME "grenade_prime"
|
||||
///called in /obj/item/gun/process_fire (user, target, params, zone_override)
|
||||
#define COMSIG_GRENADE_ARMED "grenade_armed"
|
||||
|
||||
// /obj/projectile signals (sent to the firer)
|
||||
|
||||
///from base of /obj/projectile/proc/on_hit(): (atom/movable/firer, atom/target, Angle)
|
||||
#define COMSIG_PROJECTILE_SELF_ON_HIT "projectile_self_on_hit"
|
||||
///from base of /obj/projectile/proc/on_hit(): (atom/movable/firer, atom/target, Angle)
|
||||
#define COMSIG_PROJECTILE_ON_HIT "projectile_on_hit"
|
||||
///from base of /obj/projectile/proc/fire(): (obj/projectile, atom/original_target)
|
||||
#define COMSIG_PROJECTILE_BEFORE_FIRE "projectile_before_fire"
|
||||
///from the base of /obj/projectile/proc/fire(): ()
|
||||
#define COMSIG_PROJECTILE_FIRE "projectile_fire"
|
||||
///sent to targets during the process_hit proc of projectiles
|
||||
#define COMSIG_PROJECTILE_PREHIT "com_proj_prehit"
|
||||
///sent to targets during the process_hit proc of projectiles
|
||||
#define COMSIG_PROJECTILE_RANGE_OUT "projectile_range_out"
|
||||
///sent when trying to force an embed (mainly for projectiles, only used in the embed element)
|
||||
#define COMSIG_EMBED_TRY_FORCE "item_try_embed"
|
||||
|
||||
///sent to targets during the process_hit proc of projectiles
|
||||
#define COMSIG_PELLET_CLOUD_INIT "pellet_cloud_init"
|
||||
|
||||
// /obj/mecha signals
|
||||
|
||||
///sent from mecha action buttons to the mecha they're linked to
|
||||
#define COMSIG_MECHA_ACTION_ACTIVATE "mecha_action_activate"
|
||||
|
||||
// /mob/living/carbon/human signals
|
||||
|
||||
///from mob/living/carbon/human/UnarmedAttack(): (atom/target, proximity)
|
||||
#define COMSIG_HUMAN_EARLY_UNARMED_ATTACK "human_early_unarmed_attack"
|
||||
///from mob/living/carbon/human/UnarmedAttack(): (atom/target, proximity)
|
||||
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack"
|
||||
///from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker)
|
||||
#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby"
|
||||
///Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted)
|
||||
#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit"
|
||||
///Whenever EquipRanked is called, called after job is set
|
||||
#define COMSIG_JOB_RECEIVED "job_received"
|
||||
|
||||
// /datum/species signals
|
||||
|
||||
///from datum/species/on_species_gain(): (datum/species/new_species, datum/species/old_species)
|
||||
#define COMSIG_SPECIES_GAIN "species_gain"
|
||||
///from datum/species/on_species_loss(): (datum/species/lost_species)
|
||||
#define COMSIG_SPECIES_LOSS "species_loss"
|
||||
|
||||
// /datum/song signals
|
||||
|
||||
///sent to the instrument when a song starts playing
|
||||
#define COMSIG_SONG_START "song_start"
|
||||
///sent to the instrument when a song stops playing
|
||||
#define COMSIG_SONG_END "song_end"
|
||||
|
||||
/*******Component Specific Signals*******/
|
||||
//Janitor
|
||||
|
||||
///(): Returns bitflags of wet values.
|
||||
#define COMSIG_TURF_IS_WET "check_turf_wet"
|
||||
///(max_strength, immediate, duration_decrease = INFINITY): Returns bool.
|
||||
#define COMSIG_TURF_MAKE_DRY "make_turf_try"
|
||||
///called on an object to clean it of cleanables. Usualy with soap: (num/strength)
|
||||
#define COMSIG_COMPONENT_CLEAN_ACT "clean_act"
|
||||
|
||||
//Creamed
|
||||
|
||||
///called when you wash your face at a sink: (num/strength)
|
||||
#define COMSIG_COMPONENT_CLEAN_FACE_ACT "clean_face_act"
|
||||
|
||||
//Food
|
||||
|
||||
///from base of obj/item/reagent_containers/food/snacks/attack(): (mob/living/eater, mob/feeder)
|
||||
#define COMSIG_FOOD_EATEN "food_eaten"
|
||||
|
||||
//Gibs
|
||||
|
||||
///from base of /obj/effect/decal/cleanable/blood/gibs/streak(): (list/directions, list/diseases)
|
||||
#define COMSIG_GIBS_STREAK "gibs_streak"
|
||||
|
||||
//Mood
|
||||
|
||||
///called when you send a mood event from anywhere in the code.
|
||||
#define COMSIG_ADD_MOOD_EVENT "add_mood"
|
||||
///Mood event that only RnD members listen for
|
||||
#define COMSIG_ADD_MOOD_EVENT_RND "RND_add_mood"
|
||||
///called when you clear a mood event from anywhere in the code.
|
||||
#define COMSIG_CLEAR_MOOD_EVENT "clear_mood"
|
||||
|
||||
//NTnet
|
||||
|
||||
///called on an object by its NTNET connection component on receive. (sending_id(number), sending_netname(text), data(datum/netdata))
|
||||
#define COMSIG_COMPONENT_NTNET_RECEIVE "ntnet_receive"
|
||||
|
||||
//Nanites
|
||||
|
||||
///() returns TRUE if nanites are found
|
||||
#define COMSIG_HAS_NANITES "has_nanites"
|
||||
///() returns TRUE if nanites have stealth
|
||||
#define COMSIG_NANITE_IS_STEALTHY "nanite_is_stealthy"
|
||||
///() deletes the nanite component
|
||||
#define COMSIG_NANITE_DELETE "nanite_delete"
|
||||
///(list/nanite_programs) - makes the input list a copy the nanites' program list
|
||||
#define COMSIG_NANITE_GET_PROGRAMS "nanite_get_programs"
|
||||
///(amount) Returns nanite amount
|
||||
#define COMSIG_NANITE_GET_VOLUME "nanite_get_volume"
|
||||
///(amount) Sets current nanite volume to the given amount
|
||||
#define COMSIG_NANITE_SET_VOLUME "nanite_set_volume"
|
||||
///(amount) Adjusts nanite volume by the given amount
|
||||
#define COMSIG_NANITE_ADJUST_VOLUME "nanite_adjust"
|
||||
///(amount) Sets maximum nanite volume to the given amount
|
||||
#define COMSIG_NANITE_SET_MAX_VOLUME "nanite_set_max_volume"
|
||||
///(amount(0-100)) Sets cloud ID to the given amount
|
||||
#define COMSIG_NANITE_SET_CLOUD "nanite_set_cloud"
|
||||
///(method) Modify cloud sync status. Method can be toggle, enable or disable
|
||||
#define COMSIG_NANITE_SET_CLOUD_SYNC "nanite_set_cloud_sync"
|
||||
///(amount) Sets safety threshold to the given amount
|
||||
#define COMSIG_NANITE_SET_SAFETY "nanite_set_safety"
|
||||
///(amount) Sets regeneration rate to the given amount
|
||||
#define COMSIG_NANITE_SET_REGEN "nanite_set_regen"
|
||||
///(code(1-9999)) Called when sending a nanite signal to a mob.
|
||||
#define COMSIG_NANITE_SIGNAL "nanite_signal"
|
||||
///(comm_code(1-9999), comm_message) Called when sending a nanite comm signal to a mob.
|
||||
#define COMSIG_NANITE_COMM_SIGNAL "nanite_comm_signal"
|
||||
///(mob/user, full_scan) - sends to chat a scan of the nanites to the user, returns TRUE if nanites are detected
|
||||
#define COMSIG_NANITE_SCAN "nanite_scan"
|
||||
///(list/data, scan_level) - adds nanite data to the given data list - made for ui_data procs
|
||||
#define COMSIG_NANITE_UI_DATA "nanite_ui_data"
|
||||
///(datum/nanite_program/new_program, datum/nanite_program/source_program) Called when adding a program to a nanite component
|
||||
#define COMSIG_NANITE_ADD_PROGRAM "nanite_add_program"
|
||||
///Installation successful
|
||||
#define COMPONENT_PROGRAM_INSTALLED (1<<0)
|
||||
///Installation failed, but there are still nanites
|
||||
#define COMPONENT_PROGRAM_NOT_INSTALLED (1<<1)
|
||||
///(datum/component/nanites, full_overwrite, copy_activation) Called to sync the target's nanites to a given nanite component
|
||||
#define COMSIG_NANITE_SYNC "nanite_sync"
|
||||
|
||||
// /datum/component/storage signals
|
||||
|
||||
///() - returns bool.
|
||||
#define COMSIG_CONTAINS_STORAGE "is_storage"
|
||||
///(obj/item/inserting, mob/user, silent, force) - returns bool
|
||||
#define COMSIG_TRY_STORAGE_INSERT "storage_try_insert"
|
||||
///(mob/show_to, force) - returns bool.
|
||||
#define COMSIG_TRY_STORAGE_SHOW "storage_show_to"
|
||||
///(mob/hide_from) - returns bool
|
||||
#define COMSIG_TRY_STORAGE_HIDE_FROM "storage_hide_from"
|
||||
///returns bool
|
||||
#define COMSIG_TRY_STORAGE_HIDE_ALL "storage_hide_all"
|
||||
///(newstate)
|
||||
#define COMSIG_TRY_STORAGE_SET_LOCKSTATE "storage_lock_set_state"
|
||||
///() - returns bool. MUST CHECK IF STORAGE IS THERE FIRST!
|
||||
#define COMSIG_IS_STORAGE_LOCKED "storage_get_lockstate"
|
||||
///(type, atom/destination, amount = INFINITY, check_adjacent, force, mob/user, list/inserted) - returns bool - type can be a list of types.
|
||||
#define COMSIG_TRY_STORAGE_TAKE_TYPE "storage_take_type"
|
||||
///(type, amount = INFINITY, force = FALSE). Force will ignore max_items, and amount is normally clamped to max_items.
|
||||
#define COMSIG_TRY_STORAGE_FILL_TYPE "storage_fill_type"
|
||||
///(obj, new_loc, force = FALSE) - returns bool
|
||||
#define COMSIG_TRY_STORAGE_TAKE "storage_take_obj"
|
||||
///(loc) - returns bool - if loc is null it will dump at parent location.
|
||||
#define COMSIG_TRY_STORAGE_QUICK_EMPTY "storage_quick_empty"
|
||||
///(list/list_to_inject_results_into, recursively_search_inside_storages = TRUE)
|
||||
#define COMSIG_TRY_STORAGE_RETURN_INVENTORY "storage_return_inventory"
|
||||
///(obj/item/insertion_candidate, mob/user, silent) - returns bool
|
||||
#define COMSIG_TRY_STORAGE_CAN_INSERT "storage_can_equip"
|
||||
|
||||
// /datum/component/two_handed signals
|
||||
|
||||
///from base of datum/component/two_handed/proc/wield(mob/living/carbon/user): (/mob/user)
|
||||
#define COMSIG_TWOHANDED_WIELD "twohanded_wield"
|
||||
#define COMPONENT_TWOHANDED_BLOCK_WIELD (1<<0)
|
||||
///from base of datum/component/two_handed/proc/unwield(mob/living/carbon/user): (/mob/user)
|
||||
#define COMSIG_TWOHANDED_UNWIELD "twohanded_unwield"
|
||||
|
||||
// /datum/action signals
|
||||
|
||||
///from base of datum/action/proc/Trigger(): (datum/action)
|
||||
#define COMSIG_ACTION_TRIGGER "action_trigger"
|
||||
#define COMPONENT_ACTION_BLOCK_TRIGGER (1<<0)
|
||||
|
||||
//Xenobio hotkeys
|
||||
|
||||
///from slime CtrlClickOn(): (/mob)
|
||||
#define COMSIG_XENO_SLIME_CLICK_CTRL "xeno_slime_click_ctrl"
|
||||
///from slime AltClickOn(): (/mob)
|
||||
#define COMSIG_XENO_SLIME_CLICK_ALT "xeno_slime_click_alt"
|
||||
///from slime ShiftClickOn(): (/mob)
|
||||
#define COMSIG_XENO_SLIME_CLICK_SHIFT "xeno_slime_click_shift"
|
||||
///from turf ShiftClickOn(): (/mob)
|
||||
#define COMSIG_XENO_TURF_CLICK_SHIFT "xeno_turf_click_shift"
|
||||
///from turf AltClickOn(): (/mob)
|
||||
#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt"
|
||||
///from monkey CtrlClickOn(): (/mob)
|
||||
#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl"
|
||||
@@ -15,6 +15,7 @@
|
||||
#define GAMEMODE_IS_NUCLEAR (SSticker && istype(SSticker.mode, /datum/game_mode/nuclear))
|
||||
#define GAMEMODE_IS_REVOLUTION (SSticker && istype(SSticker.mode, /datum/game_mode/revolution))
|
||||
#define GAMEMODE_IS_WIZARD (SSticker && istype(SSticker.mode, /datum/game_mode/wizard))
|
||||
#define GAMEMODE_IS_RAGIN_MAGES (SSticker && istype(SSticker.mode, /datum/game_mode/wizard/raginmages))
|
||||
|
||||
//special roles
|
||||
// Distinct from the ROLE_X defines because some antags have multiple special roles but only one ban type
|
||||
|
||||
@@ -145,7 +145,6 @@
|
||||
#define RESISTCOLD "resist_cold"
|
||||
#define NO_EXAMINE "no_examine"
|
||||
#define CAN_WINGDINGS "can_wingdings"
|
||||
#define NOZOMBIE "no_zombie"
|
||||
#define NO_GERMS "no_germs"
|
||||
#define NO_DECAY "no_decay"
|
||||
#define PIERCEIMMUNE "pierce_immunity"
|
||||
|
||||
@@ -5,6 +5,3 @@
|
||||
#define WEIGHT_CLASS_BULKY 4 //Items that can be weilded or equipped but not stored in an inventory, ex: Defibrillator, Backpack, Space Suits
|
||||
#define WEIGHT_CLASS_HUGE 5 //Usually represents objects that require two hands to operate, ex: Shotgun, Two Handed Melee Weapons
|
||||
#define WEIGHT_CLASS_GIGANTIC 6 //Essentially means it cannot be picked up or placed in an inventory, ex: Mech Parts, Safe
|
||||
|
||||
#define TV_TRIP "trip"
|
||||
#define TV_SLIP "slip"
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// Atoms
|
||||
#define isatom(A) istype(A, /atom)
|
||||
#define ismovableatom(A) istype(A, /atom/movable)
|
||||
#define isatom(A) (isloc(A))
|
||||
|
||||
// Mobs
|
||||
#define ismegafauna(A) istype(A, /mob/living/simple_animal/hostile/megafauna)
|
||||
#define iszombie(A) (is_species(A, /datum/species/zombie))
|
||||
|
||||
//Simple animals
|
||||
#define isshade(A) (istype(A, /mob/living/simple_animal/shade))
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
#define JOB_CLOWN (1<<11)
|
||||
#define JOB_MIME (1<<12)
|
||||
#define JOB_CIVILIAN (1<<13)
|
||||
|
||||
#define JOB_EXPLORER (1<<14)
|
||||
|
||||
#define JOBCAT_KARMA (1<<3)
|
||||
|
||||
|
||||
+211
-32
@@ -1,59 +1,238 @@
|
||||
#define NUM_E 2.71828183
|
||||
|
||||
#define PI 3.1415
|
||||
#define SPEED_OF_LIGHT 3e8 //not exact but hey!
|
||||
#define SPEED_OF_LIGHT_SQ 9e+16
|
||||
#define INFINITY 1e31 //closer than enough
|
||||
|
||||
#define Clamp(x, y, z) ((x) <= (y) ? (y) : ((x) >= (z) ? (z) : (x)))
|
||||
#define CLAMP01(x) (Clamp((x), 0, 1))
|
||||
|
||||
// Similar to clamp but the bottom rolls around to the top and vice versa. min is inclusive, max is exclusive
|
||||
#define WRAP(val, min, max) ( min == max ? min : (val) - (round(((val) - (min))/((max) - (min))) * ((max) - (min))) )
|
||||
|
||||
#define SIMPLE_SIGN(X) ((X) < 0 ? -1 : 1)
|
||||
#define SIGN(X) ((X) ? SIMPLE_SIGN(X) : 0)
|
||||
#define hypotenuse(Ax, Ay, Bx, By) (sqrt(((Ax) - (Bx))**2 + ((Ay) - (By))**2))
|
||||
#define Ceiling(x) (-round(-(x)))
|
||||
#define Tan(x) (sin(x) / cos(x))
|
||||
#define Cot(x) (1 / Tan(x))
|
||||
#define Csc(x) (1 / sin(x))
|
||||
#define Sec(x) (1 / cos(x))
|
||||
#define Floor(x) (round(x))
|
||||
#define Inverse(x) (1 / (x))
|
||||
#define IsEven(x) ((x) % 2 == 0)
|
||||
#define IsOdd(x) ((x) % 2 == 1)
|
||||
#define IsInRange(val, min, max) ((min) <= (val) && (val) <= (max))
|
||||
#define IsInteger(x) (Floor(x) == (x))
|
||||
#define IsMultiple(x, y) ((x) % (y) == 0)
|
||||
#define Lcm(a, b) (abs(a) / Gcd((a), (b)) * abs(b))
|
||||
#define Root(n, x) ((x) ** (1 / (n)))
|
||||
#define ToDegrees(radians) ((radians) * 57.2957795) // 180 / Pi
|
||||
#define ToRadians(degrees) ((degrees) * 0.0174532925) // Pi / 180
|
||||
|
||||
#define SHORT_REAL_LIMIT 16777216
|
||||
|
||||
// Real modulus that handles decimals
|
||||
#define MODULUS(x, y) ( (x) - (y) * round((x) / (y)) )
|
||||
|
||||
|
||||
//"fancy" math for calculating time in ms from tick_usage percentage and the length of ticks
|
||||
//percent_of_tick_used * (ticklag * 100(to convert to ms)) / 100(percent ratio)
|
||||
//collapsed to percent_of_tick_used * tick_lag
|
||||
#define TICK_DELTA_TO_MS(percent_of_tick_used) ((percent_of_tick_used) * world.tick_lag)
|
||||
#define TICK_USAGE_TO_MS(starting_tickusage) (TICK_DELTA_TO_MS(TICK_USAGE_REAL - starting_tickusage))
|
||||
|
||||
#define PERCENT(val) (round((val)*100, 0.1))
|
||||
#define CLAMP01(x) (clamp(x, 0, 1))
|
||||
|
||||
//time of day but automatically adjusts to the server going into the next day within the same round.
|
||||
//for when you need a reliable time number that doesn't depend on byond time.
|
||||
#define REALTIMEOFDAY (world.timeofday + (MIDNIGHT_ROLLOVER * MIDNIGHT_ROLLOVER_CHECK))
|
||||
#define MIDNIGHT_ROLLOVER_CHECK ( GLOB.rollovercheck_last_timeofday != world.timeofday ? update_midnight_rollover() : GLOB.midnight_rollovers )
|
||||
|
||||
#define SIMPLE_SIGN(X) ((X) < 0 ? -1 : 1)
|
||||
|
||||
#define SIGN(x) ( (x)!=0 ? (x) / abs(x) : 0 )
|
||||
|
||||
#define CEILING(x, y) ( -round(-(x) / (y)) * (y) )
|
||||
|
||||
// round() acts like floor(x, 1) by default but can't handle other values
|
||||
#define FLOOR(x, y) ( round((x) / (y)) * (y) )
|
||||
|
||||
// Similar to clamp but the bottom rolls around to the top and vice versa. min is inclusive, max is exclusive
|
||||
#define WRAP(val, min, max) clamp(( min == max ? min : (val) - (round(((val) - (min))/((max) - (min))) * ((max) - (min))) ),min,max)
|
||||
|
||||
// Real modulus that handles decimals
|
||||
#define MODULUS(x, y) ( (x) - (y) * round((x) / (y)) )
|
||||
|
||||
// Cotangent
|
||||
#define COT(x) (1 / tan(x))
|
||||
|
||||
// Secant
|
||||
#define SEC(x) (1 / cos(x))
|
||||
|
||||
// Cosecant
|
||||
#define CSC(x) (1 / sin(x))
|
||||
|
||||
#define ATAN2(x, y) ( !(x) && !(y) ? 0 : (y) >= 0 ? arccos((x) / sqrt((x)*(x) + (y)*(y))) : -arccos((x) / sqrt((x)*(x) + (y)*(y))) )
|
||||
|
||||
#define HYPOTENUSE(Ax, Ay, Bx, By) (sqrt(((Ax) - (Bx))**2 + ((Ay) - (By))**2))
|
||||
|
||||
// Greatest Common Divisor - Euclid's algorithm
|
||||
/proc/Gcd(a, b)
|
||||
return b ? Gcd(b, (a) % (b)) : a
|
||||
|
||||
// Least Common Multiple
|
||||
#define Lcm(a, b) (abs(a) / Gcd(a, b) * abs(b))
|
||||
|
||||
#define INVERSE(x) ( 1/(x) )
|
||||
|
||||
// Used for calculating the radioactive strength falloff
|
||||
#define INVERSE_SQUARE(initial_strength,cur_distance,initial_distance) ( (initial_strength)*((initial_distance)**2/(cur_distance)**2) )
|
||||
|
||||
#define ISABOUTEQUAL(a, b, deviation) (deviation ? abs((a) - (b)) <= deviation : abs((a) - (b)) <= 0.1)
|
||||
|
||||
#define ISEVEN(x) (x % 2 == 0)
|
||||
|
||||
#define ISODD(x) (x % 2 != 0)
|
||||
|
||||
// Returns true if val is from min to max, inclusive.
|
||||
#define ISINRANGE(val, min, max) (min <= val && val <= max)
|
||||
|
||||
// Same as above, exclusive.
|
||||
#define ISINRANGE_EX(val, min, max) (min < val && val < max)
|
||||
|
||||
#define ISINTEGER(x) (round(x) == x)
|
||||
|
||||
#define ISMULTIPLE(x, y) ((x) % (y) == 0)
|
||||
|
||||
// Performs a linear interpolation between a and b.
|
||||
// Note that amount=0 returns a, amount=1 returns b, and
|
||||
// amount=0.5 returns the mean of a and b.
|
||||
#define LERP(a, b, amount) ( amount ? ((a) + ((b) - (a)) * (amount)) : a )
|
||||
|
||||
// Returns the nth root of x.
|
||||
#define ROOT(n, x) ((x) ** (1 / (n)))
|
||||
|
||||
// The quadratic formula. Returns a list with the solutions, or an empty list
|
||||
// if they are imaginary.
|
||||
/proc/SolveQuadratic(a, b, c)
|
||||
ASSERT(a)
|
||||
. = list()
|
||||
var/d = b*b - 4 * a * c
|
||||
var/bottom = 2 * a
|
||||
if(d < 0)
|
||||
return
|
||||
var/root = sqrt(d)
|
||||
. += (-b + root) / bottom
|
||||
if(!d)
|
||||
return
|
||||
. += (-b - root) / bottom
|
||||
|
||||
#define TODEGREES(radians) ((radians) * 57.2957795)
|
||||
|
||||
#define TORADIANS(degrees) ((degrees) * 0.0174532925)
|
||||
|
||||
/// Gets shift x that would be required the bitflag (1<<x)
|
||||
#define TOBITSHIFT(bit) ( log(2, bit) )
|
||||
|
||||
// Will filter out extra rotations and negative rotations
|
||||
// E.g: 540 becomes 180. -180 becomes 180.
|
||||
#define SIMPLIFY_DEGREES(degrees) (MODULUS((degrees), 360))
|
||||
|
||||
#define GET_ANGLE_OF_INCIDENCE(face, input) (MODULUS((face) - (input), 360))
|
||||
|
||||
//Finds the shortest angle that angle A has to change to get to angle B. Aka, whether to move clock or counterclockwise.
|
||||
/proc/closer_angle_difference(a, b)
|
||||
if(!isnum(a) || !isnum(b))
|
||||
return
|
||||
a = SIMPLIFY_DEGREES(a)
|
||||
b = SIMPLIFY_DEGREES(b)
|
||||
var/inc = b - a
|
||||
if(inc < 0)
|
||||
inc += 360
|
||||
var/dec = a - b
|
||||
if(dec < 0)
|
||||
dec += 360
|
||||
. = inc > dec? -dec : inc
|
||||
|
||||
//A logarithm that converts an integer to a number scaled between 0 and 1.
|
||||
//Currently, this is used for hydroponics-produce sprite transforming, but could be useful for other transform functions.
|
||||
#define TRANSFORM_USING_VARIABLE(input, max) ( sin((90*(input))/(max))**2 )
|
||||
|
||||
//converts a uniform distributed random number into a normal distributed one
|
||||
//since this method produces two random numbers, one is saved for subsequent calls
|
||||
//(making the cost negligble for every second call)
|
||||
//This will return +/- decimals, situated about mean with standard deviation stddev
|
||||
//68% chance that the number is within 1stddev
|
||||
//95% chance that the number is within 2stddev
|
||||
//98% chance that the number is within 3stddev...etc
|
||||
#define ACCURACY 10000
|
||||
/proc/gaussian(mean, stddev)
|
||||
var/static/gaussian_next
|
||||
var/R1;var/R2;var/working
|
||||
if(gaussian_next != null)
|
||||
R1 = gaussian_next
|
||||
gaussian_next = null
|
||||
else
|
||||
do
|
||||
R1 = rand(-ACCURACY,ACCURACY)/ACCURACY
|
||||
R2 = rand(-ACCURACY,ACCURACY)/ACCURACY
|
||||
working = R1*R1 + R2*R2
|
||||
while(working >= 1 || working==0)
|
||||
working = sqrt(-2 * log(working) / working)
|
||||
R1 *= working
|
||||
gaussian_next = R2 * working
|
||||
return (mean + stddev * R1)
|
||||
#undef ACCURACY
|
||||
|
||||
/proc/get_turf_in_angle(angle, turf/starting, increments)
|
||||
var/pixel_x = 0
|
||||
var/pixel_y = 0
|
||||
for(var/i in 1 to increments)
|
||||
pixel_x += sin(angle)+16*sin(angle)*2
|
||||
pixel_y += cos(angle)+16*cos(angle)*2
|
||||
var/new_x = starting.x
|
||||
var/new_y = starting.y
|
||||
while(pixel_x > 16)
|
||||
pixel_x -= 32
|
||||
new_x++
|
||||
while(pixel_x < -16)
|
||||
pixel_x += 32
|
||||
new_x--
|
||||
while(pixel_y > 16)
|
||||
pixel_y -= 32
|
||||
new_y++
|
||||
while(pixel_y < -16)
|
||||
pixel_y += 32
|
||||
new_y--
|
||||
new_x = clamp(new_x, 0, world.maxx)
|
||||
new_y = clamp(new_y, 0, world.maxy)
|
||||
return locate(new_x, new_y, starting.z)
|
||||
|
||||
// Returns a list where [1] is all x values and [2] is all y values that overlap between the given pair of rectangles
|
||||
/proc/get_overlap(x1, y1, x2, y2, x3, y3, x4, y4)
|
||||
var/list/region_x1 = list()
|
||||
var/list/region_y1 = list()
|
||||
var/list/region_x2 = list()
|
||||
var/list/region_y2 = list()
|
||||
|
||||
// These loops create loops filled with x/y values that the boundaries inhabit
|
||||
// ex: list(5, 6, 7, 8, 9)
|
||||
for(var/i in min(x1, x2) to max(x1, x2))
|
||||
region_x1["[i]"] = TRUE
|
||||
for(var/i in min(y1, y2) to max(y1, y2))
|
||||
region_y1["[i]"] = TRUE
|
||||
for(var/i in min(x3, x4) to max(x3, x4))
|
||||
region_x2["[i]"] = TRUE
|
||||
for(var/i in min(y3, y4) to max(y3, y4))
|
||||
region_y2["[i]"] = TRUE
|
||||
|
||||
return list(region_x1 & region_x2, region_y1 & region_y2)
|
||||
|
||||
#define EXP_DISTRIBUTION(desired_mean) ( -(1/(1/desired_mean)) * log(rand(1, 1000) * 0.001) )
|
||||
|
||||
#define LORENTZ_DISTRIBUTION(x, s) ( s*tan(TODEGREES(PI*(rand()-0.5))) + x )
|
||||
#define LORENTZ_CUMULATIVE_DISTRIBUTION(x, y, s) ( (1/PI)*TORADIANS(arctan((x-y)/s)) + 1/2 )
|
||||
|
||||
#define RULE_OF_THREE(a, b, x) ((a*x)/b)
|
||||
// )
|
||||
|
||||
/proc/RaiseToPower(num, power)
|
||||
if(!power)
|
||||
return 1
|
||||
return (power-- > 1 ? num * RaiseToPower(num, power) : num)
|
||||
|
||||
// oof, what a mouthful
|
||||
// Used in status_procs' "adjust" to let them modify a status effect by a given
|
||||
// amount, without inadverdently increasing it in the wrong direction
|
||||
/proc/directional_bounded_sum(orig_val, modifier, bound_lower, bound_upper)
|
||||
var/new_val = orig_val + modifier
|
||||
if(modifier > 0)
|
||||
if(new_val > bound_upper)
|
||||
new_val = max(orig_val, bound_upper)
|
||||
else if(modifier < 0)
|
||||
if(new_val < bound_lower)
|
||||
new_val = min(orig_val, bound_lower)
|
||||
return new_val
|
||||
|
||||
// sqrt, but if you give it a negative number, you get 0 instead of a runtime
|
||||
/proc/sqrtor0(num)
|
||||
if(num < 0)
|
||||
return 0
|
||||
return sqrt(num)
|
||||
|
||||
/proc/round_down(num)
|
||||
if(round(num) != num)
|
||||
return round(num--)
|
||||
else
|
||||
return num
|
||||
|
||||
@@ -431,7 +431,6 @@
|
||||
#define LINDA_SPAWN_OXYGEN 8
|
||||
#define LINDA_SPAWN_CO2 16
|
||||
#define LINDA_SPAWN_NITROGEN 32
|
||||
|
||||
#define LINDA_SPAWN_N2O 64
|
||||
|
||||
#define LINDA_SPAWN_AGENT_B 128
|
||||
#define LINDA_SPAWN_AIR 256
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
#define isslimeperson(A) (is_species(A, /datum/species/slime))
|
||||
#define isgrey(A) (is_species(A, /datum/species/grey))
|
||||
#define isdiona(A) (is_species(A, /datum/species/diona))
|
||||
#define ismachine(A) (is_species(A, /datum/species/machine))
|
||||
#define ismachineperson(A) (is_species(A, /datum/species/machine))
|
||||
#define isdrask(A) (is_species(A, /datum/species/drask))
|
||||
|
||||
#define isanimal(A) (istype((A), /mob/living/simple_animal))
|
||||
|
||||
@@ -15,3 +15,57 @@
|
||||
|
||||
#define SOUND_MINIMUM_PRESSURE 10
|
||||
#define FALLOFF_SOUNDS 0.5
|
||||
|
||||
//Ambience types
|
||||
|
||||
#define GENERIC_SOUNDS list('sound/ambience/ambigen1.ogg', 'sound/ambience/ambigen3.ogg',\
|
||||
'sound/ambience/ambigen4.ogg', 'sound/ambience/ambigen5.ogg',\
|
||||
'sound/ambience/ambigen6.ogg', 'sound/ambience/ambigen7.ogg',\
|
||||
'sound/ambience/ambigen8.ogg', 'sound/ambience/ambigen9.ogg',\
|
||||
'sound/ambience/ambigen10.ogg', 'sound/ambience/ambigen11.ogg',\
|
||||
'sound/ambience/ambigen12.ogg', 'sound/ambience/ambigen14.ogg', 'sound/ambience/ambigen15.ogg')
|
||||
|
||||
#define HOLY_SOUNDS list('sound/ambience/ambicha1.ogg', 'sound/ambience/ambicha2.ogg', 'sound/ambience/ambicha3.ogg',\
|
||||
'sound/ambience/ambicha4.ogg', 'sound/ambience/ambiholy.ogg', 'sound/ambience/ambiholy2.ogg',\
|
||||
'sound/ambience/ambiholy3.ogg')
|
||||
|
||||
#define HIGHSEC_SOUNDS list('sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg')
|
||||
|
||||
#define RUINS_SOUNDS list('sound/ambience/ambimine.ogg', 'sound/ambience/ambicave.ogg', 'sound/ambience/ambiruin.ogg',\
|
||||
'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\
|
||||
'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\
|
||||
'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambitech3.ogg',\
|
||||
'sound/ambience/ambimystery.ogg', 'sound/ambience/ambimaint1.ogg')
|
||||
|
||||
#define ENGINEERING_SOUNDS list('sound/ambience/ambisin1.ogg', 'sound/ambience/ambisin2.ogg', 'sound/ambience/ambisin3.ogg', 'sound/ambience/ambisin4.ogg',\
|
||||
'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg', 'sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambitech3.ogg')
|
||||
|
||||
#define MINING_SOUNDS list('sound/ambience/ambimine.ogg', 'sound/ambience/ambicave.ogg', 'sound/ambience/ambiruin.ogg',\
|
||||
'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\
|
||||
'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\
|
||||
'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambimaint1.ogg',\
|
||||
'sound/ambience/ambilava1.ogg', 'sound/ambience/ambilava2.ogg', 'sound/ambience/ambilava3.ogg')
|
||||
|
||||
#define MEDICAL_SOUNDS list('sound/ambience/ambinice.ogg')
|
||||
|
||||
#define SPOOKY_SOUNDS list('sound/ambience/ambimo1.ogg','sound/ambience/ambimo2.ogg','sound/ambience/ambiruin7.ogg','sound/ambience/ambiruin6.ogg',\
|
||||
'sound/ambience/ambiodd.ogg', 'sound/ambience/ambimystery.ogg')
|
||||
|
||||
#define SPACE_SOUNDS list('sound/ambience/ambispace.ogg', 'sound/ambience/ambispace2.ogg', 'sound/music/title2.ogg', 'sound/ambience/ambiatmos.ogg')
|
||||
|
||||
#define MAINTENANCE_SOUNDS list('sound/ambience/ambimaint1.ogg', 'sound/ambience/ambimaint2.ogg', 'sound/ambience/ambimaint3.ogg', 'sound/ambience/ambimaint4.ogg',\
|
||||
'sound/ambience/ambimaint5.ogg', 'sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg', 'sound/ambience/ambitech2.ogg' )
|
||||
|
||||
#define AWAY_MISSION_SOUNDS list('sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambiruin.ogg',\
|
||||
'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\
|
||||
'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\
|
||||
'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambimaint.ogg',\
|
||||
'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg', 'sound/ambience/ambiodd.ogg')
|
||||
|
||||
|
||||
|
||||
#define CREEPY_SOUNDS list('sound/effects/ghost.ogg', 'sound/effects/ghost2.ogg', 'sound/effects/heart_beat.ogg', 'sound/effects/screech.ogg',\
|
||||
'sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/behind_you2.ogg', 'sound/hallucinations/far_noise.ogg', 'sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg',\
|
||||
'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\
|
||||
'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\
|
||||
'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg')
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#define UNCONSCIOUS 1
|
||||
#define DEAD 2
|
||||
|
||||
// NanoUI flags
|
||||
// NanoUI & TGUI flags
|
||||
#define STATUS_INTERACTIVE 2 // GREEN Visability
|
||||
#define STATUS_UPDATE 1 // ORANGE Visability
|
||||
#define STATUS_DISABLED 0 // RED Visability
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
// Subsystem init_order, from highest priority to lowest priority
|
||||
// Subsystems shutdown in the reverse of the order they initialize in
|
||||
// The numbers just define the ordering, they are meaningless otherwise.
|
||||
|
||||
#define INIT_ORDER_TITLE 100 // This **MUST** load first or people will se blank lobby screens
|
||||
#define INIT_ORDER_GARBAGE 19
|
||||
#define INIT_ORDER_DBCORE 18
|
||||
#define INIT_ORDER_BLACKBOX 17
|
||||
|
||||
@@ -143,6 +143,9 @@ GLOBAL_VAR_INIT(log_end, (world.system_type == UNIX ? ascii2text(13) : ""))
|
||||
/proc/log_runtime_summary(text)
|
||||
WRITE_LOG(GLOB.runtime_summary_log, "[text]")
|
||||
|
||||
/proc/log_tgui(text)
|
||||
WRITE_LOG(GLOB.tgui_log, "[text]")
|
||||
|
||||
/**
|
||||
* Standardized method for tracking startup times.
|
||||
*/
|
||||
|
||||
+1
-10
@@ -183,9 +183,6 @@
|
||||
|
||||
|
||||
/proc/get_mobs_in_radio_ranges(var/list/obj/item/radio/radios)
|
||||
|
||||
set background = 1
|
||||
|
||||
. = list()
|
||||
// Returns a list of mobs who can hear any of the radios given in @radios
|
||||
var/list/speaker_coverage = list()
|
||||
@@ -347,7 +344,7 @@
|
||||
for(var/i = 1; i <= GLOB.player_list.len; i++)
|
||||
var/mob/M = GLOB.player_list[i]
|
||||
if(M && M.client)
|
||||
if(istype(M, /mob/new_player)) // exclude people in the lobby
|
||||
if(isnewplayer(M)) // exclude people in the lobby
|
||||
continue
|
||||
else if(isobserver(M)) // Ghosts are fine if they were playing once (didn't start as observers)
|
||||
var/mob/dead/observer/O = M
|
||||
@@ -428,12 +425,6 @@
|
||||
if(pressure <= LAVALAND_EQUIPMENT_EFFECT_PRESSURE)
|
||||
. = TRUE
|
||||
|
||||
/proc/MinutesToTicks(var/minutes as num)
|
||||
return minutes * 60 * 10
|
||||
|
||||
/proc/SecondsToTicks(var/seconds)
|
||||
return seconds * 10
|
||||
|
||||
proc/pollCandidates(Question, be_special_type, antag_age_check = FALSE, poll_time = 300, ignore_respawnability = FALSE, min_hours = 0, flashwindow = TRUE, check_antaghud = TRUE)
|
||||
var/roletext = be_special_type ? get_roletext(be_special_type) : null
|
||||
var/list/mob/dead/observer/candidates = list()
|
||||
|
||||
@@ -23,6 +23,14 @@
|
||||
|
||||
init_subtypes(/datum/surgery_step, GLOB.surgery_steps)
|
||||
|
||||
// Different bodies
|
||||
__init_body_accessory(/datum/body_accessory/body)
|
||||
// Different tails
|
||||
__init_body_accessory(/datum/body_accessory/tail)
|
||||
|
||||
// Setup species:accessory relations
|
||||
initialize_body_accessory_by_species()
|
||||
|
||||
for(var/path in (subtypesof(/datum/surgery)))
|
||||
GLOB.surgeries_list += new path()
|
||||
|
||||
@@ -30,6 +38,7 @@
|
||||
init_datum_subtypes(/datum/superheroes, GLOB.all_superheroes, null, "name")
|
||||
init_datum_subtypes(/datum/language, GLOB.all_languages, null, "name")
|
||||
|
||||
// Setup languages
|
||||
for(var/language_name in GLOB.all_languages)
|
||||
var/datum/language/L = GLOB.all_languages[language_name]
|
||||
if(!(L.flags & NONGLOBAL))
|
||||
@@ -54,7 +63,61 @@
|
||||
var/datum/pipes/P = D
|
||||
if(P.rpd_dispensable)
|
||||
GLOB.rpd_pipe_list += list(list("pipe_name" = P.pipe_name, "pipe_id" = P.pipe_id, "pipe_type" = P.pipe_type, "pipe_category" = P.pipe_category, "orientations" = P.orientations, "pipe_icon" = P.pipe_icon, "bendy" = P.bendy))
|
||||
return 1
|
||||
|
||||
// Setup PAI software
|
||||
for(var/type in subtypesof(/datum/pai_software))
|
||||
var/datum/pai_software/P = new type()
|
||||
if(GLOB.pai_software_by_key[P.id])
|
||||
var/datum/pai_software/O = GLOB.pai_software_by_key[P.id]
|
||||
to_chat(world, "<span class='warning'>pAI software module [P.name] has the same key as [O.name]!</span>")
|
||||
continue
|
||||
GLOB.pai_software_by_key[P.id] = P
|
||||
if(P.default)
|
||||
GLOB.default_pai_software[P.id] = P
|
||||
|
||||
// Setup loadout gear
|
||||
for(var/geartype in subtypesof(/datum/gear))
|
||||
var/datum/gear/G = geartype
|
||||
|
||||
var/use_name = initial(G.display_name)
|
||||
var/use_category = initial(G.sort_category)
|
||||
|
||||
if(G == initial(G.subtype_path))
|
||||
continue
|
||||
|
||||
if(!use_name)
|
||||
error("Loadout - Missing display name: [G]")
|
||||
continue
|
||||
if(!initial(G.cost))
|
||||
error("Loadout - Missing cost: [G]")
|
||||
continue
|
||||
if(!initial(G.path))
|
||||
error("Loadout - Missing path definition: [G]")
|
||||
continue
|
||||
|
||||
if(!GLOB.loadout_categories[use_category])
|
||||
GLOB.loadout_categories[use_category] = new /datum/loadout_category(use_category)
|
||||
var/datum/loadout_category/LC = GLOB.loadout_categories[use_category]
|
||||
GLOB.gear_datums[use_name] = new geartype
|
||||
LC.gear[use_name] = GLOB.gear_datums[use_name]
|
||||
|
||||
GLOB.loadout_categories = sortAssoc(GLOB.loadout_categories)
|
||||
for(var/loadout_category in GLOB.loadout_categories)
|
||||
var/datum/loadout_category/LC = GLOB.loadout_categories[loadout_category]
|
||||
LC.gear = sortAssoc(LC.gear)
|
||||
|
||||
|
||||
// Setup a list of robolimbs
|
||||
GLOB.basic_robolimb = new()
|
||||
for(var/limb_type in typesof(/datum/robolimb))
|
||||
var/datum/robolimb/R = new limb_type()
|
||||
GLOB.all_robolimbs[R.company] = R
|
||||
if(!R.unavailable_at_chargen)
|
||||
if(R != "head" && R != "chest" && R != "groin" ) //Part of the method that ensures only IPCs can access head, chest and groin prosthetics.
|
||||
if(R.has_subtypes) //Ensures solos get added to the list as well be incorporating has_subtypes == 1 and has_subtypes == 2.
|
||||
GLOB.chargen_robolimbs[R.company] = R //List only main brands and solo parts.
|
||||
if(R.selectable)
|
||||
GLOB.selectable_robolimbs[R.company] = R
|
||||
|
||||
/* // Uncomment to debug chemical reaction list.
|
||||
/client/verb/debug_chemical_list()
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
|
||||
//////////////////////
|
||||
//Heap object
|
||||
//datum/heap object
|
||||
//////////////////////
|
||||
|
||||
/Heap
|
||||
/datum/heap
|
||||
var/list/L
|
||||
var/cmp
|
||||
|
||||
/Heap/New(compare)
|
||||
/datum/heap/New(compare)
|
||||
L = new()
|
||||
cmp = compare
|
||||
|
||||
/Heap/proc/IsEmpty()
|
||||
/datum/heap/proc/IsEmpty()
|
||||
return !L.len
|
||||
|
||||
//Insert and place at its position a new node in the heap
|
||||
/Heap/proc/Insert(atom/A)
|
||||
/datum/heap/proc/Insert(atom/A)
|
||||
|
||||
L.Add(A)
|
||||
Swim(L.len)
|
||||
|
||||
//removes and returns the first element of the heap
|
||||
//(i.e the max or the min dependant on the comparison function)
|
||||
/Heap/proc/Pop()
|
||||
/datum/heap/proc/Pop()
|
||||
if(!L.len)
|
||||
return 0
|
||||
. = L[1]
|
||||
@@ -33,7 +33,7 @@
|
||||
Sink(1)
|
||||
|
||||
//Get a node up to its right position in the heap
|
||||
/Heap/proc/Swim(var/index)
|
||||
/datum/heap/proc/Swim(var/index)
|
||||
var/parent = round(index * 0.5)
|
||||
|
||||
while(parent > 0 && (call(cmp)(L[index],L[parent]) > 0))
|
||||
@@ -42,7 +42,7 @@
|
||||
parent = round(index * 0.5)
|
||||
|
||||
//Get a node down to its right position in the heap
|
||||
/Heap/proc/Sink(var/index)
|
||||
/datum/heap/proc/Sink(var/index)
|
||||
var/g_child = GetGreaterChild(index)
|
||||
|
||||
while(g_child > 0 && (call(cmp)(L[index],L[g_child]) < 0))
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
//Returns the greater (relative to the comparison proc) of a node children
|
||||
//or 0 if there's no child
|
||||
/Heap/proc/GetGreaterChild(var/index)
|
||||
/datum/heap/proc/GetGreaterChild(var/index)
|
||||
if(index * 2 > L.len)
|
||||
return 0
|
||||
|
||||
@@ -65,11 +65,11 @@
|
||||
return index * 2
|
||||
|
||||
//Replaces a given node so it verify the heap condition
|
||||
/Heap/proc/ReSort(atom/A)
|
||||
/datum/heap/proc/ReSort(atom/A)
|
||||
var/index = L.Find(A)
|
||||
|
||||
Swim(index)
|
||||
Sink(index)
|
||||
|
||||
/Heap/proc/List()
|
||||
/datum/heap/proc/List()
|
||||
. = L.Copy()
|
||||
@@ -61,7 +61,7 @@
|
||||
var/adjacencies = 0
|
||||
|
||||
var/atom/movable/AM
|
||||
if(ismovableatom(A))
|
||||
if(ismovable(A))
|
||||
AM = A
|
||||
if(AM.can_be_unanchored && !AM.anchored)
|
||||
return 0
|
||||
|
||||
@@ -580,7 +580,7 @@ world
|
||||
var/B = RGB[2]
|
||||
|
||||
var/Y = (0.2126 * R) + (0.7152 * G) + (0.0722 * B)
|
||||
return Clamp((Y * 0.01), 0, 1) //Returns the brightness of a color in decimal percentage format. Can multiply light_power by this to receive 100% brightness or a lower brightness. Not a higher brightness.
|
||||
return clamp((Y * 0.01), 0, 1) //Returns the brightness of a color in decimal percentage format. Can multiply light_power by this to receive 100% brightness or a lower brightness. Not a higher brightness.
|
||||
|
||||
/proc/HueToAngle(hue)
|
||||
// normalize hsv in case anything is screwy
|
||||
@@ -899,9 +899,9 @@ The _flatIcons list is a cache for generated icon files.
|
||||
if(!value) return color
|
||||
|
||||
var/list/RGB = ReadRGB(color)
|
||||
RGB[1] = Clamp(RGB[1]+value,0,255)
|
||||
RGB[2] = Clamp(RGB[2]+value,0,255)
|
||||
RGB[3] = Clamp(RGB[3]+value,0,255)
|
||||
RGB[1] = clamp(RGB[1]+value,0,255)
|
||||
RGB[2] = clamp(RGB[2]+value,0,255)
|
||||
RGB[3] = clamp(RGB[3]+value,0,255)
|
||||
return rgb(RGB[1],RGB[2],RGB[3])
|
||||
|
||||
/proc/sort_atoms_by_layer(var/list/atoms)
|
||||
|
||||
@@ -690,6 +690,8 @@ proc/dd_sortedObjectList(list/incoming)
|
||||
// LAZYING PT 2: THE LAZENING
|
||||
#define LAZYREINITLIST(L) LAZYCLEARLIST(L); LAZYINITLIST(L);
|
||||
|
||||
// Lazying Episode 3
|
||||
#define LAZYSET(L, K, V) LAZYINITLIST(L); L[K] = V;
|
||||
|
||||
//same, but returns nothing and acts on list in place
|
||||
/proc/shuffle_inplace(list/L)
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
// Credits to Nickr5 for the useful procs I've taken from his library resource.
|
||||
|
||||
#define MATH_E 2.71828183
|
||||
#define SQRT2 1.41421356
|
||||
|
||||
/proc/Atan2(x, y)
|
||||
if(!x && !y) return 0
|
||||
var/a = arccos(x / sqrt(x*x + y*y))
|
||||
return y >= 0 ? a : -a
|
||||
|
||||
// Greatest Common Divisor - Euclid's algorithm
|
||||
/proc/Gcd(a, b)
|
||||
return b ? Gcd(b, a % b) : a
|
||||
|
||||
/proc/IsAboutEqual(a, b, deviation = 0.1)
|
||||
return abs(a - b) <= deviation
|
||||
|
||||
// Performs a linear interpolation between a and b.
|
||||
// Note that amount=0 returns a, amount=1 returns b, and
|
||||
// amount=0.5 returns the mean of a and b.
|
||||
/proc/Lerp(a, b, amount = 0.5)
|
||||
return a + (b - a) * amount
|
||||
|
||||
/proc/Mean(...)
|
||||
var/values = 0
|
||||
var/sum = 0
|
||||
for(var/val in args)
|
||||
values++
|
||||
sum += val
|
||||
return sum / values
|
||||
|
||||
// The quadratic formula. Returns a list with the solutions, or an empty list
|
||||
// if they are imaginary.
|
||||
/proc/SolveQuadratic(a, b, c)
|
||||
ASSERT(a)
|
||||
. = list()
|
||||
var/d = b*b - 4 * a * c
|
||||
var/bottom = 2 * a
|
||||
if(d < 0) return
|
||||
var/root = sqrt(d)
|
||||
. += (-b + root) / bottom
|
||||
if(!d) return
|
||||
. += (-b - root) / bottom
|
||||
|
||||
// Will filter out extra rotations and negative rotations
|
||||
// E.g: 540 becomes 180. -180 becomes 180.
|
||||
/proc/SimplifyDegrees(degrees)
|
||||
degrees = degrees % 360
|
||||
if(degrees < 0)
|
||||
degrees += 360
|
||||
return degrees
|
||||
|
||||
// min is inclusive, max is exclusive
|
||||
/proc/Wrap(val, min, max)
|
||||
var/d = max - min
|
||||
var/t = Floor((val - min) / d)
|
||||
return val - (t * d)
|
||||
|
||||
//A logarithm that converts an integer to a number scaled between 0 and 1 (can be tweaked to be higher).
|
||||
//Currently, this is used for hydroponics-produce sprite transforming, but could be useful for other transform functions.
|
||||
/proc/TransformUsingVariable(input, inputmaximum, scaling_modifier = 0)
|
||||
|
||||
var/inputToDegrees = (input/inputmaximum)*180 //Converting from a 0 -> 100 scale to a 0 -> 180 scale. The 0 -> 180 scale corresponds to degrees
|
||||
var/size_factor = ((-cos(inputToDegrees) +1) /2) //returns a value from 0 to 1
|
||||
|
||||
return size_factor + scaling_modifier //scale mod of 0 results in a number from 0 to 1. A scale modifier of +0.5 returns 0.5 to 1.5
|
||||
//world<< "Transform multiplier of [src] is [size_factor + scaling_modifer]"
|
||||
|
||||
/proc/RaiseToPower(num, power)
|
||||
if(!power) return 1
|
||||
return (power-- > 1 ? num * RaiseToPower(num, power) : num)
|
||||
|
||||
//converts a uniform distributed random number into a normal distributed one
|
||||
//since this method produces two random numbers, one is saved for subsequent calls
|
||||
//(making the cost negligble for every second call)
|
||||
//This will return +/- decimals, situated about mean with standard deviation stddev
|
||||
//68% chance that the number is within 1stddev
|
||||
//95% chance that the number is within 2stddev
|
||||
//98% chance that the number is within 3stddev...etc
|
||||
GLOBAL_VAR(gaussian_next)
|
||||
#define ACCURACY 10000
|
||||
/proc/gaussian(mean, stddev)
|
||||
var/R1;var/R2;var/working
|
||||
if(GLOB.gaussian_next != null)
|
||||
R1 = GLOB.gaussian_next
|
||||
GLOB.gaussian_next = null
|
||||
else
|
||||
do
|
||||
R1 = rand(-ACCURACY,ACCURACY)/ACCURACY
|
||||
R2 = rand(-ACCURACY,ACCURACY)/ACCURACY
|
||||
working = R1*R1 + R2*R2
|
||||
while(working >= 1 || working==0)
|
||||
working = sqrt(-2 * log(working) / working)
|
||||
R1 *= working
|
||||
GLOB.gaussian_next = R2 * working
|
||||
return (mean + stddev * R1)
|
||||
#undef ACCURACY
|
||||
|
||||
|
||||
|
||||
// oof, what a mouthful
|
||||
// Used in status_procs' "adjust" to let them modify a status effect by a given
|
||||
// amount, without inadverdently increasing it in the wrong direction
|
||||
/proc/directional_bounded_sum(orig_val, modifier, bound_lower, bound_upper)
|
||||
var/new_val = orig_val + modifier
|
||||
if(modifier > 0)
|
||||
if(new_val > bound_upper)
|
||||
new_val = max(orig_val, bound_upper)
|
||||
else if(modifier < 0)
|
||||
if(new_val < bound_lower)
|
||||
new_val = min(orig_val, bound_lower)
|
||||
return new_val
|
||||
|
||||
// sqrt, but if you give it a negative number, you get 0 instead of a runtime
|
||||
/proc/sqrtor0(num)
|
||||
if(num < 0)
|
||||
return 0
|
||||
return sqrt(num)
|
||||
|
||||
/proc/round_down(num)
|
||||
if(round(num) != num)
|
||||
return round(num--)
|
||||
else return num
|
||||
|
||||
// Returns a list where [1] is all x values and [2] is all y values that overlap between the given pair of rectangles
|
||||
/proc/get_overlap(x1, y1, x2, y2, x3, y3, x4, y4)
|
||||
var/list/region_x1 = list()
|
||||
var/list/region_y1 = list()
|
||||
var/list/region_x2 = list()
|
||||
var/list/region_y2 = list()
|
||||
|
||||
// These loops create loops filled with x/y values that the boundaries inhabit
|
||||
// ex: list(5, 6, 7, 8, 9)
|
||||
for(var/i in min(x1, x2) to max(x1, x2))
|
||||
region_x1["[i]"] = TRUE
|
||||
for(var/i in min(y1, y2) to max(y1, y2))
|
||||
region_y1["[i]"] = TRUE
|
||||
for(var/i in min(x3, x4) to max(x3, x4))
|
||||
region_x2["[i]"] = TRUE
|
||||
for(var/i in min(y3, y4) to max(y3, y4))
|
||||
region_y2["[i]"] = TRUE
|
||||
|
||||
return list(region_x1 & region_x2, region_y1 & region_y2)
|
||||
+40
-2
@@ -289,11 +289,14 @@ This is always put in the attack log.
|
||||
|
||||
var/user_str = key_name_log(user) + COORD(user)
|
||||
var/target_str
|
||||
var/target_info
|
||||
if(isatom(target))
|
||||
var/atom/AT = target
|
||||
target_str = key_name_log(AT) + COORD(AT)
|
||||
target_info = key_name_admin(target)
|
||||
else
|
||||
target_str = target
|
||||
target_info = target
|
||||
var/mob/MU = user
|
||||
var/mob/MT = target
|
||||
if(istype(MU))
|
||||
@@ -317,10 +320,13 @@ This is always put in the attack log.
|
||||
var/area/A = get_area(MT)
|
||||
if(A && A.hide_attacklogs)
|
||||
loglevel = ATKLOG_ALMOSTALL
|
||||
else
|
||||
loglevel = ATKLOG_ALL // Hitting an object. Not a mob
|
||||
if(isLivingSSD(target)) // Attacks on SSDs are shown to admins with any log level except ATKLOG_NONE. Overrides custom level
|
||||
loglevel = ATKLOG_FEW
|
||||
|
||||
msg_admin_attack("[key_name_admin(user)] vs [key_name_admin(target)]: [what_done]", loglevel)
|
||||
|
||||
msg_admin_attack("[key_name_admin(user)] vs [target_info]: [what_done]", loglevel)
|
||||
|
||||
/proc/do_mob(mob/user, mob/target, time = 30, uninterruptible = 0, progress = 1, list/extra_checks = list())
|
||||
if(!user || !target)
|
||||
@@ -579,7 +585,8 @@ GLOBAL_LIST_INIT(do_after_once_tracker, list())
|
||||
LogMouseMacro(".mouse", params)
|
||||
|
||||
/proc/update_all_mob_security_hud()
|
||||
for(var/mob/living/carbon/human/H in GLOB.mob_list)
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
H.sec_hud_set_security_status()
|
||||
|
||||
/proc/getviewsize(view)
|
||||
@@ -616,3 +623,34 @@ GLOBAL_LIST_INIT(do_after_once_tracker, list())
|
||||
chosen = pick(mob_spawn_meancritters)
|
||||
var/mob/living/simple_animal/C = new chosen(spawn_location)
|
||||
return C
|
||||
|
||||
//determines the job of a mob, taking into account job transfers
|
||||
/proc/determine_role(mob/living/P)
|
||||
var/datum/mind/M = P.mind
|
||||
if(!M)
|
||||
return
|
||||
return M.playtime_role ? M.playtime_role : M.assigned_role //returns current role
|
||||
|
||||
/** checks the security force on station and returns a list of numbers, of the form:
|
||||
* total, active, dead, antag
|
||||
* where active is defined as conscious (STAT = 0) and not an antag
|
||||
*/
|
||||
/proc/check_active_security_force()
|
||||
var/sec_positions = GLOB.security_positions - "Magistrate" - "Brig Physician"
|
||||
var/total = 0
|
||||
var/active = 0
|
||||
var/dead = 0
|
||||
var/antag = 0
|
||||
for(var/p in GLOB.human_list) //contains only human mobs, so no type check needed
|
||||
var/mob/living/carbon/human/player = p //need to tell it what type it is or we can't access stat without the dreaded :
|
||||
if(determine_role(player) in sec_positions)
|
||||
total++
|
||||
if(player.stat == DEAD)
|
||||
dead++
|
||||
continue
|
||||
if(isAntag(player))
|
||||
antag++
|
||||
continue
|
||||
if(player.stat == CONSCIOUS)
|
||||
active++
|
||||
return list(total, active, dead, antag)
|
||||
|
||||
@@ -533,7 +533,7 @@ proc/checkhtml(var/t)
|
||||
text = replacetext(text, "\[/grid\]", "</td></tr></table>")
|
||||
text = replacetext(text, "\[row\]", "</td><tr>")
|
||||
text = replacetext(text, "\[cell\]", "<td>")
|
||||
text = replacetext(text, "\[logo\]", "<img src = ntlogo.png>")
|
||||
text = replacetext(text, "\[logo\]", "​<img src = ntlogo.png>")
|
||||
text = replacetext(text, "\[time\]", "[station_time_timestamp()]") // TO DO
|
||||
if(!no_font)
|
||||
if(P)
|
||||
|
||||
+2
-21
@@ -11,25 +11,6 @@
|
||||
|
||||
#define TICKS2DS(T) ((T) TICKS)
|
||||
|
||||
#define TimeOfGame (get_game_time())
|
||||
#define TimeOfTick (world.tick_usage*0.01*world.tick_lag)
|
||||
|
||||
/proc/get_game_time()
|
||||
var/global/time_offset = 0
|
||||
var/global/last_time = 0
|
||||
var/global/last_usage = 0
|
||||
|
||||
var/wtime = world.time
|
||||
var/wusage = world.tick_usage * 0.01
|
||||
|
||||
if(last_time < wtime && last_usage > 1)
|
||||
time_offset += last_usage - 1
|
||||
|
||||
last_time = wtime
|
||||
last_usage = wusage
|
||||
|
||||
return wtime + (time_offset + wusage) * world.tick_lag
|
||||
|
||||
/* This proc should only be used for world/Topic.
|
||||
* If you want to display the time for which dream daemon has been running ("round time") use worldtime2text.
|
||||
* If you want to display the canonical station "time" (aka the in-character time of the station) use station_time_timestamp
|
||||
@@ -98,14 +79,14 @@ proc/isDay(var/month, var/day)
|
||||
* Returns "watch handle" (really just a timestamp :V)
|
||||
*/
|
||||
/proc/start_watch()
|
||||
return TimeOfGame
|
||||
return REALTIMEOFDAY
|
||||
|
||||
/**
|
||||
* Returns number of seconds elapsed.
|
||||
* @param wh number The "Watch Handle" from start_watch(). (timestamp)
|
||||
*/
|
||||
/proc/stop_watch(wh)
|
||||
return round(0.1 * (TimeOfGame - wh), 0.1)
|
||||
return round(0.1 * (REALTIMEOFDAY - wh), 0.1)
|
||||
|
||||
/proc/numberToMonthName(number)
|
||||
return GLOB.month_names.Find(number)
|
||||
|
||||
@@ -65,6 +65,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_WATERBREATH "waterbreathing"
|
||||
#define TRAIT_BLOODCRAWL "bloodcrawl"
|
||||
#define TRAIT_BLOODCRAWL_EAT "bloodcrawl_eat"
|
||||
#define TRAIT_JESTER "jester"
|
||||
|
||||
// common trait sources
|
||||
#define ROUNDSTART_TRAIT "roundstart" //cannot be removed without admin intervention
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
GLOBAL_VAR_INIT(next_unique_datum_id, 1)
|
||||
|
||||
// /client/var/tmp/unique_datum_id = null
|
||||
|
||||
/datum/proc/UID()
|
||||
if(!unique_datum_id)
|
||||
var/tag_backup = tag
|
||||
@@ -37,8 +35,6 @@ GLOBAL_VAR_INIT(next_unique_datum_id, 1)
|
||||
|
||||
var/datum/D = locate(copytext(uid, 1, splitat))
|
||||
|
||||
// We might locate a client instead of a datum, but just using : is easier
|
||||
// than actually checking and typecasting
|
||||
if(D && D:unique_datum_id == uid)
|
||||
if(D && D.unique_datum_id == uid)
|
||||
return D
|
||||
return null
|
||||
|
||||
+27
-36
@@ -25,11 +25,9 @@
|
||||
|
||||
if(!( istext(HTMLstring) ))
|
||||
CRASH("Given non-text argument!")
|
||||
return
|
||||
else
|
||||
if(length(HTMLstring) != 7)
|
||||
CRASH("Given non-HTML argument!")
|
||||
return
|
||||
var/textr = copytext(HTMLstring, 2, 4)
|
||||
var/textg = copytext(HTMLstring, 4, 6)
|
||||
var/textb = copytext(HTMLstring, 6, 8)
|
||||
@@ -46,7 +44,6 @@
|
||||
if(length(textb) < 2)
|
||||
textr = text("0[]", textb)
|
||||
return text("#[][][]", textr, textg, textb)
|
||||
return
|
||||
|
||||
//Returns the middle-most value
|
||||
/proc/dd_range(var/low, var/high, var/num)
|
||||
@@ -332,8 +329,9 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
/proc/select_active_ai_with_fewest_borgs()
|
||||
var/mob/living/silicon/ai/selected
|
||||
var/list/active = active_ais()
|
||||
for(var/mob/living/silicon/ai/A in active)
|
||||
if(!selected || (selected.connected_robots > A.connected_robots))
|
||||
for(var/thing in active)
|
||||
var/mob/living/silicon/ai/A = thing
|
||||
if(!selected || (length(selected.connected_robots) > length(A.connected_robots)))
|
||||
selected = A
|
||||
|
||||
return selected
|
||||
@@ -437,16 +435,6 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
return "[round((powerused * 0.000001), 0.001)] MW"
|
||||
return "[round((powerused * 0.000000001), 0.0001)] GW"
|
||||
|
||||
//E = MC^2
|
||||
/proc/convert2energy(var/M)
|
||||
var/E = M*(SPEED_OF_LIGHT_SQ)
|
||||
return E
|
||||
|
||||
//M = E/C^2
|
||||
/proc/convert2mass(var/E)
|
||||
var/M = E/(SPEED_OF_LIGHT_SQ)
|
||||
return M
|
||||
|
||||
//Forces a variable to be posative
|
||||
/proc/modulus(var/M)
|
||||
if(M >= 0)
|
||||
@@ -540,21 +528,6 @@ Returns 1 if the chain up to the area contains the given typepath
|
||||
/proc/between(var/low, var/middle, var/high)
|
||||
return max(min(middle, high), low)
|
||||
|
||||
|
||||
|
||||
#if DM_VERSION > 513
|
||||
#warn 513 is definitely stable now, remove this
|
||||
#endif
|
||||
#if DM_VERSION < 513
|
||||
/proc/arctan(x)
|
||||
var/y=arcsin(x/sqrt(1+x*x))
|
||||
return y
|
||||
/proc/islist(list/list)
|
||||
if(istype(list))
|
||||
return 1
|
||||
return 0
|
||||
#endif
|
||||
|
||||
//returns random gauss number
|
||||
proc/GaussRand(var/sigma)
|
||||
var/x,y,rsq
|
||||
@@ -1520,7 +1493,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
//orbit() can run without it (swap orbiting for A)
|
||||
//but then you can never stop it and that's just silly.
|
||||
/atom/movable/var/atom/orbiting = null
|
||||
|
||||
/atom/movable/var/cached_transform = null
|
||||
//A: atom to orbit
|
||||
//radius: range to orbit at, radius of the circle formed by orbiting
|
||||
//clockwise: whether you orbit clockwise or anti clockwise
|
||||
@@ -1538,6 +1511,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
|
||||
orbiting = A
|
||||
var/matrix/initial_transform = matrix(transform)
|
||||
cached_transform = initial_transform
|
||||
var/lastloc = loc
|
||||
|
||||
//Head first!
|
||||
@@ -1555,8 +1529,6 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
|
||||
SpinAnimation(rotation_speed, -1, clockwise, rotation_segments)
|
||||
|
||||
//we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit
|
||||
transform = initial_transform
|
||||
while(orbiting && orbiting == A && A.loc)
|
||||
var/targetloc = get_turf(A)
|
||||
if(!lockinorbit && loc != lastloc && loc != targetloc)
|
||||
@@ -1570,12 +1542,14 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
|
||||
if(orbiting == A) //make sure we haven't started orbiting something else.
|
||||
orbiting = null
|
||||
SpinAnimation(0,0)
|
||||
SpinAnimation(0, 0)
|
||||
transform = cached_transform
|
||||
|
||||
|
||||
|
||||
/atom/movable/proc/stop_orbit()
|
||||
orbiting = null
|
||||
transform = cached_transform
|
||||
|
||||
//Centers an image.
|
||||
//Requires:
|
||||
@@ -1945,6 +1919,16 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
|
||||
return pois
|
||||
|
||||
/*
|
||||
* Returns all player mobs in an assoc list with ckey as key and the mob as value
|
||||
*/
|
||||
/proc/get_assoc_mob_list_by_ckey()
|
||||
var/list/mob/mobs = list()
|
||||
for(var/i in GLOB.player_list)
|
||||
var/mob/M = i
|
||||
mobs[M.ckey] = M
|
||||
return mobs
|
||||
|
||||
/proc/flash_color(mob_or_client, flash_color="#960000", flash_time=20)
|
||||
var/client/C
|
||||
if(istype(mob_or_client, /mob))
|
||||
@@ -2035,6 +2019,13 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
tX = splittext(tX[1], ":")
|
||||
tX = tX[1]
|
||||
var/list/actual_view = getviewsize(C ? C.view : world.view)
|
||||
tX = Clamp(origin.x + text2num(tX) - round(actual_view[1] / 2) - 1, 1, world.maxx)
|
||||
tY = Clamp(origin.y + text2num(tY) - round(actual_view[2] / 2) - 1, 1, world.maxy)
|
||||
tX = clamp(origin.x + text2num(tX) - round(actual_view[1] / 2) - 1, 1, world.maxx)
|
||||
tY = clamp(origin.y + text2num(tY) - round(actual_view[2] / 2) - 1, 1, world.maxy)
|
||||
return locate(tX, tY, tZ)
|
||||
|
||||
/proc/CallAsync(datum/source, proctype, list/arguments)
|
||||
set waitfor = FALSE
|
||||
return call(source, proctype)(arglist(arguments))
|
||||
|
||||
/// Waits at a line of code until X is true
|
||||
#define UNTIL(X) while(!(X)) stoplag()
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
#define DEBUG
|
||||
//#define TESTING
|
||||
|
||||
// Uncomment the following line to compile unit tests.
|
||||
// #define UNIT_TESTS
|
||||
|
||||
|
||||
#ifdef TRAVISBUILDING
|
||||
#define UNIT_TESTS
|
||||
#endif
|
||||
|
||||
#ifdef TESTING
|
||||
//#define GC_FAILURE_HARD_LOOKUP //makes paths that fail to GC call find_references before del'ing.
|
||||
//implies FIND_REF_NO_CHECK_TICK
|
||||
@@ -11,8 +19,6 @@
|
||||
|
||||
#define IS_MODE_COMPILED(MODE) (ispath(text2path("/datum/game_mode/"+(MODE))))
|
||||
|
||||
#define BACKGROUND_ENABLED 0 // The default value for all uses of set background. Set background can cause gradual lag and is recommended you only turn this on if necessary.
|
||||
|
||||
//Don't set this very much higher then 1024 unless you like inviting people in to dos your server with message spam
|
||||
#define MAX_MESSAGE_LEN 1024
|
||||
#define MAX_PAPER_MESSAGE_LEN 3072
|
||||
@@ -20,11 +26,13 @@
|
||||
#define MAX_BOOK_MESSAGE_LEN 9216
|
||||
#define MAX_NAME_LEN 50 //diona names can get loooooooong
|
||||
|
||||
// Version check, terminates compilation if someone is using a version of BYOND that's too old
|
||||
#if DM_VERSION < 510
|
||||
#error OUTDATED VERSION ERROR - \
|
||||
Due to BYOND features used in this codebase, you must update to version 510 or later to compile. \
|
||||
This may require updating to a beta release.
|
||||
//Update this whenever you need to take advantage of more recent byond features
|
||||
#define MIN_COMPILER_VERSION 513
|
||||
#define MIN_COMPILER_BUILD 1514
|
||||
#if DM_VERSION < MIN_COMPILER_VERSION || DM_BUILD < MIN_COMPILER_BUILD
|
||||
//Don't forget to update this part
|
||||
#error Your version of BYOND is too out-of-date to compile this project. Go to https://secure.byond.com/download and update.
|
||||
#error You need version 513.1514 or higher
|
||||
#endif
|
||||
|
||||
// Macros that must exist before world.dm
|
||||
|
||||
@@ -18,6 +18,8 @@ GLOBAL_LIST_EMPTY(player_list) //List of all mobs **with clients attached**.
|
||||
GLOBAL_LIST_EMPTY(mob_list) //List of all mobs, including clientless
|
||||
GLOBAL_LIST_EMPTY(silicon_mob_list) //List of all silicon mobs, including clientless
|
||||
GLOBAL_LIST_EMPTY(mob_living_list) //all instances of /mob/living and subtypes
|
||||
GLOBAL_LIST_EMPTY(carbon_list) //all instances of /mob/living/carbon and subtypes, notably does not contain simple animals
|
||||
GLOBAL_LIST_EMPTY(human_list) //all instances of /mob/living/carbon/human and subtypes
|
||||
GLOBAL_LIST_EMPTY(spirits) //List of all the spirits, including Masks
|
||||
GLOBAL_LIST_EMPTY(alive_mob_list) //List of all alive mobs, including clientless. Excludes /mob/new_player
|
||||
GLOBAL_LIST_EMPTY(dead_mob_list) //List of all dead mobs, including clientless. Excludes /mob/new_player
|
||||
|
||||
@@ -16,7 +16,6 @@ GLOBAL_LIST_INIT(prisoncomputer_list, list())
|
||||
GLOBAL_LIST_INIT(celltimers_list, list()) // list of all cell timers
|
||||
GLOBAL_LIST_INIT(cell_logs, list())
|
||||
GLOBAL_LIST_INIT(navigation_computers, list())
|
||||
GLOBAL_LIST_INIT(zombie_infection_list, list())
|
||||
|
||||
GLOBAL_LIST_INIT(all_areas, list())
|
||||
GLOBAL_LIST_INIT(machines, list())
|
||||
|
||||
@@ -15,6 +15,8 @@ GLOBAL_VAR(world_asset_log)
|
||||
GLOBAL_PROTECT(world_asset_log)
|
||||
GLOBAL_VAR(runtime_summary_log)
|
||||
GLOBAL_PROTECT(runtime_summary_log)
|
||||
GLOBAL_VAR(tgui_log)
|
||||
GLOBAL_PROTECT(tgui_log)
|
||||
|
||||
GLOBAL_LIST_EMPTY(jobMax)
|
||||
GLOBAL_PROTECT(jobMax)
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
#define Z_SOUTH 3
|
||||
#define Z_WEST 4
|
||||
|
||||
GLOBAL_LIST_INIT(cardinal, list( NORTH, SOUTH, EAST, WEST ))
|
||||
GLOBAL_LIST_INIT(cardinal, list(NORTH, SOUTH, EAST, WEST))
|
||||
GLOBAL_LIST_INIT(alldirs, list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
|
||||
GLOBAL_LIST_INIT(alldirs2, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST, NORTH, SOUTH, EAST, WEST))
|
||||
GLOBAL_LIST_INIT(diagonals, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST))
|
||||
|
||||
// This must exist early on or shit breaks bad
|
||||
@@ -54,3 +55,7 @@ GLOBAL_LIST_EMPTY(space_ruins_templates)
|
||||
GLOBAL_LIST_EMPTY(lava_ruins_templates)
|
||||
GLOBAL_LIST_EMPTY(shelter_templates)
|
||||
GLOBAL_LIST_EMPTY(shuttle_templates)
|
||||
|
||||
// Teleport locations
|
||||
GLOBAL_LIST_EMPTY(teleportlocs)
|
||||
GLOBAL_LIST_EMPTY(ghostteleportlocs)
|
||||
|
||||
@@ -4,7 +4,7 @@ GLOBAL_DATUM(slmaster, /obj/effect/overlay)
|
||||
GLOBAL_VAR_INIT(CELLRATE, 0.002) // conversion ratio between a watt-tick and kilojoule
|
||||
GLOBAL_VAR_INIT(CHARGELEVEL, 0.001) // Cap for how fast cells charge, as a percentage-per-tick (.001 means cellcharge is capped to 1% per second)
|
||||
|
||||
// Announcer intercom, because too much stuff creates an intercom for one message then hard del()s it.
|
||||
// Announcer intercom, because too much stuff creates an intercom for one message then qdel()s it.
|
||||
GLOBAL_DATUM_INIT(global_announcer, /obj/item/radio/intercom, create_global_announcer())
|
||||
GLOBAL_DATUM_INIT(command_announcer, /obj/item/radio/intercom/command, create_command_announcer())
|
||||
|
||||
@@ -89,7 +89,7 @@ GLOBAL_VAR_INIT(copier_items_printed_logged, FALSE)
|
||||
|
||||
GLOBAL_VAR(map_name) // Self explanatory
|
||||
|
||||
GLOBAL_DATUM(data_core, /datum/datacore) // Station datacore, manifest, etc
|
||||
GLOBAL_DATUM_INIT(data_core, /datum/datacore, new) // Station datacore, manifest, etc
|
||||
|
||||
GLOBAL_VAR_INIT(panic_bunker_enabled, FALSE) // Is the panic bunker enabled
|
||||
|
||||
@@ -101,3 +101,4 @@ GLOBAL_PROTECT(dbcon)
|
||||
|
||||
GLOBAL_LIST_EMPTY(ability_verbs) // Create-level abilities
|
||||
GLOBAL_LIST_INIT(pipe_colors, list("grey" = PIPE_COLOR_GREY, "red" = PIPE_COLOR_RED, "blue" = PIPE_COLOR_BLUE, "cyan" = PIPE_COLOR_CYAN, "green" = PIPE_COLOR_GREEN, "yellow" = PIPE_COLOR_YELLOW, "purple" = PIPE_COLOR_PURPLE))
|
||||
|
||||
|
||||
@@ -9,4 +9,4 @@ GLOBAL_REAL_VAR(sqlfdbkdb) = "test"
|
||||
GLOBAL_REAL_VAR(sqlfdbklogin) = "root"
|
||||
GLOBAL_REAL_VAR(sqlfdbkpass) = ""
|
||||
GLOBAL_REAL_VAR(sqlfdbktableprefix) = "erro_"
|
||||
|
||||
GLOBAL_REAL_VAR(sql_version) = 0
|
||||
|
||||
@@ -161,10 +161,13 @@
|
||||
#define ui_bot_pull "EAST-2:26,SOUTH:7"
|
||||
|
||||
//Ghosts
|
||||
#define ui_ghost_jumptomob "SOUTH:6,CENTER-2:24"
|
||||
#define ui_ghost_orbit "SOUTH:6,CENTER-1:24"
|
||||
#define ui_ghost_reenter_corpse "SOUTH:6,CENTER:24"
|
||||
#define ui_ghost_teleport "SOUTH:6,CENTER+1:24"
|
||||
#define ui_ghost_jumptomob "SOUTH:6,CENTER-2"
|
||||
#define ui_ghost_orbit "SOUTH:6,CENTER-1"
|
||||
#define ui_ghost_reenter_corpse "SOUTH:6,CENTER"
|
||||
#define ui_ghost_teleport "SOUTH:6,CENTER+1"
|
||||
#define ui_ghost_respawn_list "SOUTH:6,CENTER+2"
|
||||
#define ui_ghost_respawn_mob "SOUTH:6+1,CENTER+2"
|
||||
#define ui_ghost_respawn_pai "SOUTH:6+2,CENTER+2"
|
||||
|
||||
//HUD styles. Please ensure HUD_VERSIONS is the same as the maximum index. Index order defines how they are cycled in F12.
|
||||
#define HUD_STYLE_STANDARD 1
|
||||
|
||||
+11
-10
@@ -19,9 +19,8 @@
|
||||
if(!category)
|
||||
return
|
||||
|
||||
var/obj/screen/alert/alert
|
||||
if(alerts[category])
|
||||
alert = alerts[category]
|
||||
var/obj/screen/alert/alert = LAZYACCESS(alerts, category)
|
||||
if(alert)
|
||||
if(alert.override_alerts)
|
||||
return 0
|
||||
if(new_master && new_master != alert.master)
|
||||
@@ -57,7 +56,7 @@
|
||||
alert.icon_state = "[initial(alert.icon_state)][severity]"
|
||||
alert.severity = severity
|
||||
|
||||
alerts[category] = alert
|
||||
LAZYSET(alerts, category, alert) // This also creates the list if it doesn't exist
|
||||
if(client && hud_used)
|
||||
hud_used.reorganize_alerts()
|
||||
alert.transform = matrix(32, 6, MATRIX_TRANSLATE)
|
||||
@@ -72,7 +71,7 @@
|
||||
|
||||
// Proc to clear an existing alert.
|
||||
/mob/proc/clear_alert(category, clear_override = FALSE)
|
||||
var/obj/screen/alert/alert = alerts[category]
|
||||
var/obj/screen/alert/alert = LAZYACCESS(alerts, category)
|
||||
if(!alert)
|
||||
return 0
|
||||
if(alert.override_alerts && !clear_override)
|
||||
@@ -585,12 +584,14 @@ so as to remain in compliance with the most up-to-date laws."
|
||||
// Re-render all alerts - also called in /datum/hud/show_hud() because it's needed there
|
||||
/datum/hud/proc/reorganize_alerts()
|
||||
var/list/alerts = mymob.alerts
|
||||
if(!alerts)
|
||||
return FALSE
|
||||
var/icon_pref
|
||||
if(!hud_shown)
|
||||
for(var/i = 1, i <= alerts.len, i++)
|
||||
for(var/i in 1 to alerts.len)
|
||||
mymob.client.screen -= alerts[alerts[i]]
|
||||
return 1
|
||||
for(var/i = 1, i <= alerts.len, i++)
|
||||
return TRUE
|
||||
for(var/i in 1 to alerts.len)
|
||||
var/obj/screen/alert/alert = alerts[alerts[i]]
|
||||
if(alert.icon_state == "template")
|
||||
if(!icon_pref)
|
||||
@@ -611,10 +612,10 @@ so as to remain in compliance with the most up-to-date laws."
|
||||
. = ""
|
||||
alert.screen_loc = .
|
||||
mymob.client.screen |= alert
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob
|
||||
var/list/alerts = list() // contains /obj/screen/alert only // On /mob so clientless mobs will throw alerts properly
|
||||
var/list/alerts // lazy list. contains /obj/screen/alert only // On /mob so clientless mobs will throw alerts properly
|
||||
|
||||
/obj/screen/alert/Click(location, control, params)
|
||||
if(!usr || !usr.client)
|
||||
|
||||
@@ -40,6 +40,52 @@
|
||||
var/mob/dead/observer/G = usr
|
||||
G.dead_tele()
|
||||
|
||||
/obj/screen/ghost/respawn_list
|
||||
name = "Ghost spawns"
|
||||
icon = 'icons/mob/screen_midnight.dmi'
|
||||
icon_state = "template"
|
||||
|
||||
/obj/screen/ghost/respawn_list/Initialize(mapload)
|
||||
. = ..()
|
||||
update_hidden_state()
|
||||
|
||||
/obj/screen/ghost/respawn_list/Click()
|
||||
var/client/C = hud.mymob.client
|
||||
hud.inventory_shown = !hud.inventory_shown
|
||||
if(hud.inventory_shown)
|
||||
C.screen += hud.toggleable_inventory
|
||||
else
|
||||
C.screen -= hud.toggleable_inventory
|
||||
update_hidden_state()
|
||||
|
||||
/obj/screen/ghost/respawn_list/proc/update_hidden_state()
|
||||
var/matrix/M = matrix(transform)
|
||||
M.Turn(-90)
|
||||
|
||||
overlays.Cut()
|
||||
var/image/img = image('icons/mob/actions/actions.dmi', src, (hud && hud.inventory_shown) ? "hide" : "show")
|
||||
img.transform = M
|
||||
overlays += img
|
||||
|
||||
/obj/screen/ghost/respawn_mob
|
||||
name = "Mob spawners"
|
||||
icon_state = "mob_spawner"
|
||||
|
||||
/obj/screen/ghost/respawn_mob/Click()
|
||||
var/mob/dead/observer/G = usr
|
||||
G.open_spawners_menu()
|
||||
|
||||
/obj/screen/ghost/respawn_pai
|
||||
name = "Configure pAI"
|
||||
icon_state = "pai"
|
||||
|
||||
/obj/screen/ghost/respawn_pai/Click()
|
||||
var/mob/dead/observer/G = usr
|
||||
GLOB.paiController.recruitWindow(G)
|
||||
|
||||
/datum/hud/ghost
|
||||
inventory_shown = FALSE
|
||||
|
||||
/datum/hud/ghost/New(mob/owner)
|
||||
..()
|
||||
var/obj/screen/using
|
||||
@@ -59,6 +105,22 @@
|
||||
using = new /obj/screen/ghost/teleport()
|
||||
using.screen_loc = ui_ghost_teleport
|
||||
static_inventory += using
|
||||
static_inventory += using
|
||||
|
||||
using = new /obj/screen/ghost/respawn_list()
|
||||
using.screen_loc = ui_ghost_respawn_list
|
||||
static_inventory += using
|
||||
|
||||
using = new /obj/screen/ghost/respawn_mob()
|
||||
using.screen_loc = ui_ghost_respawn_mob
|
||||
toggleable_inventory += using
|
||||
|
||||
using = new /obj/screen/ghost/respawn_pai()
|
||||
using.screen_loc = ui_ghost_respawn_pai
|
||||
toggleable_inventory += using
|
||||
|
||||
for(var/obj/screen/S in (static_inventory + toggleable_inventory))
|
||||
S.hud = src
|
||||
|
||||
/datum/hud/ghost/show_hud()
|
||||
mymob.client.screen = list()
|
||||
|
||||
@@ -246,7 +246,7 @@
|
||||
if(!view)
|
||||
view = world.view
|
||||
var/list/new_overlays = list()
|
||||
var/count = Ceiling(view/(480/world.icon_size))+1
|
||||
var/count = CEILING(view/(480/world.icon_size), 1)+1
|
||||
for(var/x in -count to count)
|
||||
for(var/y in -count to count)
|
||||
if(x == 0 && y == 0)
|
||||
|
||||
@@ -102,8 +102,8 @@
|
||||
overlays += standard_background
|
||||
|
||||
/obj/screen/movable/pic_in_pic/proc/set_view_size(width, height, do_refresh = TRUE)
|
||||
width = Clamp(width, 0, max_dimensions)
|
||||
height = Clamp(height, 0, max_dimensions)
|
||||
width = clamp(width, 0, max_dimensions)
|
||||
height = clamp(height, 0, max_dimensions)
|
||||
src.width = width
|
||||
src.height = height
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@
|
||||
if(!R.robot_modules_background)
|
||||
return
|
||||
|
||||
var/display_rows = Ceiling(R.module.modules.len / 8)
|
||||
var/display_rows = CEILING(R.module.modules.len / 8, 1)
|
||||
R.robot_modules_background.screen_loc = "CENTER-4:16,SOUTH+1:7 to CENTER+3:16,SOUTH+[display_rows]:7"
|
||||
R.client.screen += R.robot_modules_background
|
||||
|
||||
|
||||
@@ -75,13 +75,13 @@
|
||||
if(hitsound)
|
||||
playsound(loc, hitsound, get_clamped_volume(), 1, -1)
|
||||
|
||||
user.lastattacked = M
|
||||
M.lastattacker = user
|
||||
M.lastattacker = user.real_name
|
||||
M.lastattackerckey = user.ckey
|
||||
|
||||
user.do_attack_animation(M)
|
||||
. = M.attacked_by(src, user, def_zone)
|
||||
|
||||
add_attack_logs(user, M, "Attacked with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])", (M.ckey && force > 0 && damtype != STAMINA) ? null : ATKLOG_ALMOSTALL)
|
||||
add_attack_logs(user, M, "Attacked with [name] ([uppertext(user.a_intent)]) ([uppertext(damtype)])", (M.ckey && force > 0 && damtype != STAMINA) ? null : ATKLOG_ALMOSTALL)
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
@@ -135,9 +135,9 @@
|
||||
/obj/item/proc/get_clamped_volume()
|
||||
if(w_class)
|
||||
if(force)
|
||||
return Clamp((force + w_class) * 4, 30, 100)// Add the item's force to its weight class and multiply by 4, then clamp the value between 30 and 100
|
||||
return clamp((force + w_class) * 4, 30, 100)// Add the item's force to its weight class and multiply by 4, then clamp the value between 30 and 100
|
||||
else
|
||||
return Clamp(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100
|
||||
return clamp(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100
|
||||
|
||||
/mob/living/proc/send_item_attack_message(obj/item/I, mob/living/user, hit_area)
|
||||
if(I.discrete)
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
// Otherwise jump
|
||||
else
|
||||
following = null
|
||||
forceMove(get_turf(A))
|
||||
update_parallax_contents()
|
||||
|
||||
@@ -64,7 +63,7 @@
|
||||
if(!istype(user)) // Make sure user is actually an observer. Revenents also use attack_ghost, but do not have the health_scan var.
|
||||
return
|
||||
if(user.client && user.health_scan)
|
||||
if(issilicon(src) || ismachine(src))
|
||||
if(issilicon(src) || ismachineperson(src))
|
||||
robot_healthscan(user, src)
|
||||
else if(ishuman(src))
|
||||
healthscan(user, src, 1, TRUE)
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
|
||||
#define MIDDLE_CLICK 0
|
||||
#define ALT_CLICK 1
|
||||
#define CTRL_CLICK 2
|
||||
#define MAX_HARDSUIT_CLICK_MODE 2
|
||||
|
||||
/client
|
||||
var/hardsuit_click_mode = MIDDLE_CLICK
|
||||
|
||||
/client/verb/toggle_hardsuit_mode()
|
||||
set name = "Toggle Hardsuit Activation Mode"
|
||||
set desc = "Switch between hardsuit activation modes."
|
||||
set category = "OOC"
|
||||
|
||||
hardsuit_click_mode++
|
||||
if(hardsuit_click_mode > MAX_HARDSUIT_CLICK_MODE)
|
||||
hardsuit_click_mode = 0
|
||||
|
||||
switch(hardsuit_click_mode)
|
||||
if(MIDDLE_CLICK)
|
||||
to_chat(src, "Hardsuit activation mode set to middle-click.")
|
||||
if(ALT_CLICK)
|
||||
to_chat(src, "Hardsuit activation mode set to alt-click.")
|
||||
if(CTRL_CLICK)
|
||||
to_chat(src, "Hardsuit activation mode set to control-click.")
|
||||
else
|
||||
// should never get here, but just in case:
|
||||
log_runtime(EXCEPTION("Bad hardsuit click mode: [hardsuit_click_mode] - expected 0 to [MAX_HARDSUIT_CLICK_MODE]"), src)
|
||||
to_chat(src, "Somehow you bugged the system. Setting your hardsuit mode to middle-click.")
|
||||
hardsuit_click_mode = MIDDLE_CLICK
|
||||
|
||||
/mob/living/MiddleClickOn(atom/A)
|
||||
if(client && client.hardsuit_click_mode == MIDDLE_CLICK)
|
||||
if(HardsuitClickOn(A))
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/AltClickOn(atom/A)
|
||||
if(client && client.hardsuit_click_mode == ALT_CLICK)
|
||||
if(HardsuitClickOn(A))
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/CtrlClickOn(atom/A)
|
||||
if(client && client.hardsuit_click_mode == CTRL_CLICK)
|
||||
if(HardsuitClickOn(A))
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/proc/can_use_rig()
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/can_use_rig()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/brain/can_use_rig()
|
||||
return istype(loc, /obj/item/mmi)
|
||||
|
||||
/mob/living/silicon/ai/can_use_rig()
|
||||
return istype(loc, /obj/item/aicard)
|
||||
|
||||
/mob/living/silicon/pai/can_use_rig()
|
||||
return loc == card
|
||||
|
||||
/mob/living/proc/HardsuitClickOn(var/atom/A, var/alert_ai = 0)
|
||||
if(!can_use_rig() || (next_move > world.time))
|
||||
return 0
|
||||
var/obj/item/rig/rig = get_rig()
|
||||
if(istype(rig) && !rig.offline && rig.selected_module)
|
||||
if(src != rig.wearer)
|
||||
if(rig.ai_can_move_suit(src, check_user_module = 1))
|
||||
message_admins("[key_name_admin(src)] is trying to force \the [key_name_admin(rig.wearer)] to use a hardsuit module.")
|
||||
else
|
||||
return 0
|
||||
rig.selected_module.engage(A, alert_ai)
|
||||
if(ismob(A)) // No instant mob attacking - though modules have their own cooldowns
|
||||
changeNext_move(CLICK_CD_MELEE)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
#undef MIDDLE_CLICK
|
||||
#undef ALT_CLICK
|
||||
#undef CTRL_CLICK
|
||||
#undef MAX_HARDSUIT_CLICK_MODE
|
||||
@@ -36,7 +36,7 @@
|
||||
var/vote_no_default = 0 // vote does not default to nochange/norestart (tbi)
|
||||
var/vote_no_dead = 0 // dead people can't vote (tbi)
|
||||
// var/enable_authentication = 0 // goon authentication
|
||||
var/del_new_on_log = 1 // del's new players if they log before they spawn in
|
||||
var/del_new_on_log = 1 // qdel's new players if they log before they spawn in
|
||||
var/feature_object_spell_system = 0 //spawns a spellbook which gives object-type spells instead of verb-type spells for the wizard
|
||||
var/traitor_scaling = 0 //if amount of traitors scales based on amount of players
|
||||
var/protect_roles_from_antagonist = 0// If security and such can be tratior/cult/other
|
||||
@@ -61,7 +61,6 @@
|
||||
var/usewhitelist = 0
|
||||
var/mods_are_mentors = 0
|
||||
var/load_jobs_from_txt = 0
|
||||
var/ToRban = 0
|
||||
var/automute_on = 0 //enables automuting/spam prevention
|
||||
var/jobs_have_minimal_access = 0 //determines whether jobs use minimal access or expanded access.
|
||||
var/round_abandon_penalty_period = 30 MINUTES // Time from round start during which ghosting out is penalized
|
||||
@@ -200,8 +199,8 @@
|
||||
var/disable_away_missions = 0 // disable away missions
|
||||
var/disable_space_ruins = 0 //disable space ruins
|
||||
|
||||
var/extra_space_ruin_levels_min = 2
|
||||
var/extra_space_ruin_levels_max = 4
|
||||
var/extra_space_ruin_levels_min = 4
|
||||
var/extra_space_ruin_levels_max = 8
|
||||
|
||||
var/ooc_allowed = 1
|
||||
var/looc_allowed = 1
|
||||
@@ -265,6 +264,11 @@
|
||||
src.votable_modes += "secret"
|
||||
|
||||
/datum/configuration/proc/load(filename, type = "config") //the type can also be game_options, in which case it uses a different switch. not making it separate to not copypaste code - Urist
|
||||
if(IsAdminAdvancedProcCall())
|
||||
to_chat(usr, "<span class='boldannounce'>Config reload blocked: Advanced ProcCall detected.</span>")
|
||||
message_admins("[key_name(usr)] attempted to reload configuration via advanced proc-call")
|
||||
log_admin("[key_name(usr)] attempted to reload configuration via advanced proc-call")
|
||||
return
|
||||
var/list/Lines = file2list(filename)
|
||||
|
||||
for(var/t in Lines)
|
||||
@@ -573,9 +577,6 @@
|
||||
if("humans_need_surnames")
|
||||
humans_need_surnames = 1
|
||||
|
||||
if("tor_ban")
|
||||
ToRban = 1
|
||||
|
||||
if("automute_on")
|
||||
automute_on = 1
|
||||
|
||||
@@ -641,31 +642,31 @@
|
||||
config.max_maint_drones = text2num(value)
|
||||
|
||||
if("expected_round_length")
|
||||
config.expected_round_length = MinutesToTicks(text2num(value))
|
||||
config.expected_round_length = text2num(value) MINUTES
|
||||
|
||||
if("event_custom_start_mundane")
|
||||
var/values = text2numlist(value, ";")
|
||||
config.event_first_run[EVENT_LEVEL_MUNDANE] = list("lower" = MinutesToTicks(values[1]), "upper" = MinutesToTicks(values[2]))
|
||||
config.event_first_run[EVENT_LEVEL_MUNDANE] = list("lower" = values[1] MINUTES, "upper" = values[2] MINUTES)
|
||||
|
||||
if("event_custom_start_moderate")
|
||||
var/values = text2numlist(value, ";")
|
||||
config.event_first_run[EVENT_LEVEL_MODERATE] = list("lower" = MinutesToTicks(values[1]), "upper" = MinutesToTicks(values[2]))
|
||||
config.event_first_run[EVENT_LEVEL_MODERATE] = list("lower" = values[1] MINUTES, "upper" = values[2] MINUTES)
|
||||
|
||||
if("event_custom_start_major")
|
||||
var/values = text2numlist(value, ";")
|
||||
config.event_first_run[EVENT_LEVEL_MAJOR] = list("lower" = MinutesToTicks(values[1]), "upper" = MinutesToTicks(values[2]))
|
||||
config.event_first_run[EVENT_LEVEL_MAJOR] = list("lower" = values[1] MINUTES, "upper" = values[2] MINUTES)
|
||||
|
||||
if("event_delay_lower")
|
||||
var/values = text2numlist(value, ";")
|
||||
config.event_delay_lower[EVENT_LEVEL_MUNDANE] = MinutesToTicks(values[1])
|
||||
config.event_delay_lower[EVENT_LEVEL_MODERATE] = MinutesToTicks(values[2])
|
||||
config.event_delay_lower[EVENT_LEVEL_MAJOR] = MinutesToTicks(values[3])
|
||||
config.event_delay_lower[EVENT_LEVEL_MUNDANE] = values[1] MINUTES
|
||||
config.event_delay_lower[EVENT_LEVEL_MODERATE] = values[2] MINUTES
|
||||
config.event_delay_lower[EVENT_LEVEL_MAJOR] = values[3] MINUTES
|
||||
|
||||
if("event_delay_upper")
|
||||
var/values = text2numlist(value, ";")
|
||||
config.event_delay_upper[EVENT_LEVEL_MUNDANE] = MinutesToTicks(values[1])
|
||||
config.event_delay_upper[EVENT_LEVEL_MODERATE] = MinutesToTicks(values[2])
|
||||
config.event_delay_upper[EVENT_LEVEL_MAJOR] = MinutesToTicks(values[3])
|
||||
config.event_delay_upper[EVENT_LEVEL_MUNDANE] = values[1] MINUTES
|
||||
config.event_delay_upper[EVENT_LEVEL_MODERATE] = values[2] MINUTES
|
||||
config.event_delay_upper[EVENT_LEVEL_MAJOR] = values[3] MINUTES
|
||||
|
||||
if("starlight")
|
||||
config.starlight = 1
|
||||
@@ -701,7 +702,7 @@
|
||||
config.max_loadout_points = text2num(value)
|
||||
|
||||
if("round_abandon_penalty_period")
|
||||
config.round_abandon_penalty_period = MinutesToTicks(text2num(value))
|
||||
config.round_abandon_penalty_period = text2num(value) MINUTES
|
||||
|
||||
if("medal_hub_address")
|
||||
config.medal_hub_address = value
|
||||
@@ -808,8 +809,12 @@
|
||||
log_config("Unknown setting in configuration: '[name]'")
|
||||
|
||||
/datum/configuration/proc/loadsql(filename) // -- TLE
|
||||
if(IsAdminAdvancedProcCall())
|
||||
to_chat(usr, "<span class='boldannounce'>SQL configuration reload blocked: Advanced ProcCall detected.</span>")
|
||||
message_admins("[key_name(usr)] attempted to reload SQL configuration via advanced proc-call")
|
||||
log_admin("[key_name(usr)] attempted to reload SQL configuration via advanced proc-call")
|
||||
return
|
||||
var/list/Lines = file2list(filename)
|
||||
var/db_version = 0
|
||||
for(var/t in Lines)
|
||||
if(!t) continue
|
||||
|
||||
@@ -848,10 +853,13 @@
|
||||
if("feedback_tableprefix")
|
||||
sqlfdbktableprefix = value
|
||||
if("db_version")
|
||||
db_version = text2num(value)
|
||||
sql_version = text2num(value)
|
||||
else
|
||||
log_config("Unknown setting in configuration: '[name]'")
|
||||
if(config.sql_enabled && db_version != SQL_VERSION)
|
||||
|
||||
// The unit tests have their own version of this check, which wont hold the server up infinitely, so this is disabled if we are running unit tests
|
||||
#ifndef UNIT_TESTS
|
||||
if(config.sql_enabled && sql_version != SQL_VERSION)
|
||||
config.sql_enabled = 0
|
||||
log_config("WARNING: DB_CONFIG DEFINITION MISMATCH!")
|
||||
spawn(60)
|
||||
@@ -859,6 +867,7 @@
|
||||
SSticker.ticker_going = FALSE
|
||||
spawn(600)
|
||||
to_chat(world, "<span class='alert'>DB_CONFIG MISMATCH, ROUND START DELAYED. <BR>Please check database version for recent upstream changes!</span>")
|
||||
#endif
|
||||
|
||||
/datum/configuration/proc/loadoverflowwhitelist(filename)
|
||||
var/list/Lines = file2list(filename)
|
||||
|
||||
@@ -14,7 +14,7 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
|
||||
|
||||
var/datum/controller/exclude_these = new
|
||||
gvars_datum_in_built_vars = exclude_these.vars + list("gvars_datum_protected_varlist", "gvars_datum_in_built_vars", "gvars_datum_init_order")
|
||||
qdel(exclude_these)
|
||||
QDEL_IN(exclude_these, 0) //signal logging isn't ready
|
||||
|
||||
Initialize()
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* Startup hook.
|
||||
* Called in world.dm when the server starts.
|
||||
*/
|
||||
/hook/startup
|
||||
|
||||
/**
|
||||
* Roundstart hook.
|
||||
* Called in gameticker.dm when a round starts.
|
||||
*/
|
||||
/hook/roundstart
|
||||
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* @file hooks.dm
|
||||
* Implements hooks, a simple way to run code on pre-defined events.
|
||||
*/
|
||||
|
||||
/** @page hooks Code hooks
|
||||
* @section hooks Hooks
|
||||
* A hook is defined under /hook in the type tree.
|
||||
*
|
||||
* To add some code to be called by the hook, define a proc under the type, as so:
|
||||
* @code
|
||||
/hook/foo/proc/bar()
|
||||
if(1)
|
||||
return 1 //Sucessful
|
||||
else
|
||||
return 0 //Error, or runtime.
|
||||
* @endcode
|
||||
* All hooks must return nonzero on success, as runtimes will force return null.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Calls a hook, executing every piece of code that's attached to it.
|
||||
* @param hook Identifier of the hook to call.
|
||||
* @returns 1 if all hooked code runs successfully, 0 otherwise.
|
||||
*/
|
||||
/proc/callHook(hook, list/args=null)
|
||||
var/hook_path = text2path("/hook/[hook]")
|
||||
if(!hook_path)
|
||||
error("Invalid hook '/hook/[hook]' called.")
|
||||
return 0
|
||||
|
||||
var/caller = new hook_path
|
||||
var/status = 1
|
||||
for(var/P in typesof("[hook_path]/proc"))
|
||||
if(!call(caller, P)(arglist(args)))
|
||||
error("Hook '[P]' failed or runtimed.")
|
||||
status = 0
|
||||
|
||||
return status
|
||||
@@ -451,14 +451,15 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
// in those cases, so we just let them run)
|
||||
if(queue_node_flags & SS_NO_TICK_CHECK)
|
||||
if(queue_node.tick_usage > TICK_LIMIT_RUNNING - TICK_USAGE && ran_non_ticker)
|
||||
queue_node.queued_priority += queue_priority_count * 0.1
|
||||
queue_priority_count -= queue_node_priority
|
||||
queue_priority_count += queue_node.queued_priority
|
||||
current_tick_budget -= queue_node_priority
|
||||
queue_node = queue_node.queue_next
|
||||
if(!(queue_node_flags & SS_BACKGROUND))
|
||||
queue_node.queued_priority += queue_priority_count * 0.1
|
||||
queue_priority_count -= queue_node_priority
|
||||
queue_priority_count += queue_node.queued_priority
|
||||
current_tick_budget -= queue_node_priority
|
||||
queue_node = queue_node.queue_next
|
||||
continue
|
||||
|
||||
if((queue_node_flags & SS_BACKGROUND) && !bg_calc)
|
||||
if(!bg_calc && (queue_node_flags & SS_BACKGROUND))
|
||||
current_tick_budget = queue_priority_count_bg
|
||||
bg_calc = TRUE
|
||||
|
||||
@@ -511,7 +512,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
|
||||
queue_node.paused_ticks = 0
|
||||
queue_node.paused_tick_usage = 0
|
||||
|
||||
if(queue_node_flags & SS_BACKGROUND) //update our running total
|
||||
if(bg_calc) //update our running total
|
||||
queue_priority_count_bg -= queue_node_priority
|
||||
else
|
||||
queue_priority_count -= queue_node_priority
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
/datum/controller/subsystem
|
||||
// Metadata; you should define these.
|
||||
name = "fire coderbus" //name of the subsystem
|
||||
name = "fire codertrain" //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 = 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
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
var/static/list/failure_strikes //How many times we suspect a subsystem type has crashed the MC, 3 strikes and you're out!
|
||||
|
||||
var/offline_implications = "None" // What are the implications of this SS being offlined?
|
||||
var/offline_implications = "None. No immediate action is needed." // What are the implications of this SS being offlined?
|
||||
|
||||
//Do not override
|
||||
///datum/controller/subsystem/New()
|
||||
@@ -89,7 +89,7 @@
|
||||
queue_node_flags = queue_node.flags
|
||||
|
||||
if(queue_node_flags & SS_TICKER)
|
||||
if(!(SS_flags & SS_TICKER))
|
||||
if((SS_flags & (SS_TICKER|SS_BACKGROUND)) != SS_TICKER)
|
||||
continue
|
||||
if(queue_node_priority < SS_priority)
|
||||
break
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#define AFK_WARNED 1
|
||||
#define AFK_CRYOD 2
|
||||
#define AFK_WARNED 1
|
||||
#define AFK_CRYOD 2
|
||||
#define AFK_ADMINS_WARNED 3
|
||||
|
||||
SUBSYSTEM_DEF(afk)
|
||||
name = "AFK Watcher"
|
||||
@@ -7,24 +8,29 @@ SUBSYSTEM_DEF(afk)
|
||||
flags = SS_BACKGROUND
|
||||
offline_implications = "Players will no longer be marked as AFK. No immediate action is needed."
|
||||
var/list/afk_players = list() // Associative list. ckey as key and AFK state as value
|
||||
var/list/non_cryo_antags
|
||||
|
||||
|
||||
/datum/controller/subsystem/afk/Initialize()
|
||||
if(config.warn_afk_minimum <= 0 || config.auto_cryo_afk <= 0 || config.auto_despawn_afk <= 0)
|
||||
flags |= SS_NO_FIRE
|
||||
if(config.warn_afk_minimum <= 0 || config.auto_cryo_afk <= 0 || config.auto_despawn_afk <= 0)
|
||||
flags |= SS_NO_FIRE
|
||||
else
|
||||
non_cryo_antags = list(SPECIAL_ROLE_ABDUCTOR_AGENT, SPECIAL_ROLE_ABDUCTOR_SCIENTIST, \
|
||||
SPECIAL_ROLE_SHADOWLING, SPECIAL_ROLE_WIZARD, SPECIAL_ROLE_WIZARD_APPRENTICE, SPECIAL_ROLE_NUKEOPS)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/afk/fire()
|
||||
var/list/toRemove = list()
|
||||
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
|
||||
if(!H.ckey) // Useless non ckey creatures
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
if(!H?.ckey) // Useless non ckey creatures
|
||||
continue
|
||||
|
||||
var/turf/T
|
||||
// Only players and players with the AFK watch enabled
|
||||
// No dead, unconcious, restrained, people without jobs, people on other Z levels than the station or antags
|
||||
// No dead, unconcious, restrained, people without jobs or people on other Z levels than the station
|
||||
if(!H.client || !H.client.prefs.afk_watch || !H.mind || \
|
||||
H.stat || H.restrained() || !H.job || H.mind.special_role || \
|
||||
!is_station_level((T = get_turf(H)).z)) // Assign the turf as last. Small optimization
|
||||
H.stat || H.restrained() || !H.job || !is_station_level((T = get_turf(H)).z)) // Assign the turf as last. Small optimization
|
||||
if(afk_players[H.ckey])
|
||||
toRemove += H.ckey
|
||||
continue
|
||||
@@ -44,20 +50,27 @@ SUBSYSTEM_DEF(afk)
|
||||
if(mins_afk >= config.auto_cryo_afk && A.can_get_auto_cryod)
|
||||
if(A.fast_despawn)
|
||||
toRemove += H.ckey
|
||||
warn(H, "<span class='danger'>You are have been despawned after being AFK for [mins_afk] minutes. You have been despawned instantly due to you being in a secure area.</span>")
|
||||
msg_admins(H, mins_afk, T, "forcefully despawned", "AFK in a fast despawn area")
|
||||
warn(H, "<span class='danger'>You have been despawned after being AFK for [mins_afk] minutes. You have been despawned instantly due to you being in a secure area.</span>")
|
||||
log_afk_action(H, mins_afk, T, "despawned", "AFK in a fast despawn area")
|
||||
force_cryo_human(H)
|
||||
else if(cryo_ssd(H))
|
||||
afk_players[H.ckey] = AFK_CRYOD
|
||||
msg_admins(H, mins_afk, T, "put into cryostorage")
|
||||
warn(H, "<span class='danger'>You are AFK for [mins_afk] minutes and have been moved to cryostorage. After being AFK for [config.auto_despawn_afk] total minutes you will be fully despawned. Please eject yourself (right click, eject) out of the cryostorage if you want to avoid being despawned.</span>")
|
||||
else
|
||||
if(!(H.mind.special_role in non_cryo_antags))
|
||||
if(cryo_ssd(H))
|
||||
H.create_log(MISC_LOG, "Put into cryostorage by the AFK subsystem")
|
||||
afk_players[H.ckey] = AFK_CRYOD
|
||||
log_afk_action(H, mins_afk, T, "put into cryostorage")
|
||||
warn(H, "<span class='danger'>You are AFK for [mins_afk] minutes and have been moved to cryostorage. \
|
||||
After being AFK for another [config.auto_despawn_afk] minutes you will be fully despawned. \
|
||||
Please eject yourself (right click, eject) out of the cryostorage if you want to avoid being despawned.</span>")
|
||||
else
|
||||
message_admins("[key_name_admin(H)] at ([get_area(T).name] [ADMIN_JMP(T)]) is AFK for [mins_afk] and can't be automatically cryod due to it's antag status: ([H.mind.special_role]).")
|
||||
afk_players[H.ckey] = AFK_ADMINS_WARNED
|
||||
|
||||
else if(mins_afk >= config.auto_despawn_afk)
|
||||
var/obj/machinery/cryopod/P = H.loc
|
||||
msg_admins(H, mins_afk, T, "forcefully despawned")
|
||||
warn(H, "<span class='danger'>You are have been despawned after being AFK for [mins_afk] minutes.</span>")
|
||||
else if(afk_players[H.ckey] != AFK_ADMINS_WARNED && mins_afk >= config.auto_despawn_afk)
|
||||
log_afk_action(H, mins_afk, T, "despawned")
|
||||
warn(H, "<span class='danger'>You have been despawned after being AFK for [mins_afk] minutes.</span>")
|
||||
toRemove += H.ckey
|
||||
P.despawn_occupant()
|
||||
force_cryo_human(H)
|
||||
|
||||
removeFromWatchList(toRemove)
|
||||
|
||||
@@ -67,9 +80,8 @@ SUBSYSTEM_DEF(afk)
|
||||
if(H.client)
|
||||
window_flash(H.client)
|
||||
|
||||
/datum/controller/subsystem/afk/proc/msg_admins(mob/living/carbon/human/H, mins_afk, turf/location, action, info)
|
||||
/datum/controller/subsystem/afk/proc/log_afk_action(mob/living/carbon/human/H, mins_afk, turf/location, action, info)
|
||||
log_admin("[key_name(H)] has been [action] by the AFK Watcher subsystem after being AFK for [mins_afk] minutes.[info ? " Extra info:" + info : ""]")
|
||||
message_admins("[key_name_admin(H)] at ([get_area(location).name] [ADMIN_JMP(location)]) has been [action] by the AFK Watcher subsystem after being AFK for [mins_afk] minutes.[info ? " Extra info:" + info : ""]")
|
||||
|
||||
/datum/controller/subsystem/afk/proc/removeFromWatchList(list/toRemove)
|
||||
for(var/C in toRemove)
|
||||
@@ -80,3 +92,4 @@ SUBSYSTEM_DEF(afk)
|
||||
|
||||
#undef AFK_WARNED
|
||||
#undef AFK_CRYOD
|
||||
#undef AFK_ADMINS_WARNED
|
||||
|
||||
@@ -90,7 +90,7 @@ SUBSYSTEM_DEF(events)
|
||||
if(E.isRunning)
|
||||
message += "and is still running."
|
||||
else
|
||||
if(E.endedAt - E.startedAt > MinutesToTicks(5)) // Only mention end time if the entire duration was more than 5 minutes
|
||||
if(E.endedAt - E.startedAt > 5 MINUTES) // Only mention end time if the entire duration was more than 5 minutes
|
||||
message += "and ended at [station_time_timestamp("hh:mm:ss", E.endedAt)]."
|
||||
else
|
||||
message += "and ran to completion."
|
||||
@@ -212,38 +212,38 @@ SUBSYSTEM_DEF(events)
|
||||
|
||||
if(href_list["toggle_report"])
|
||||
report_at_round_end = !report_at_round_end
|
||||
admin_log_and_message_admins("has [report_at_round_end ? "enabled" : "disabled"] the round end event report.")
|
||||
log_and_message_admins("has [report_at_round_end ? "enabled" : "disabled"] the round end event report.")
|
||||
else if(href_list["dec_timer"])
|
||||
var/datum/event_container/EC = locate(href_list["event"])
|
||||
var/decrease = (60 * RaiseToPower(10, text2num(href_list["dec_timer"])))
|
||||
EC.next_event_time -= decrease
|
||||
admin_log_and_message_admins("decreased timer for [GLOB.severity_to_string[EC.severity]] events by [decrease/600] minute(s).")
|
||||
log_and_message_admins("decreased timer for [GLOB.severity_to_string[EC.severity]] events by [decrease/600] minute(s).")
|
||||
else if(href_list["inc_timer"])
|
||||
var/datum/event_container/EC = locate(href_list["event"])
|
||||
var/increase = (60 * RaiseToPower(10, text2num(href_list["inc_timer"])))
|
||||
EC.next_event_time += increase
|
||||
admin_log_and_message_admins("increased timer for [GLOB.severity_to_string[EC.severity]] events by [increase/600] minute(s).")
|
||||
log_and_message_admins("increased timer for [GLOB.severity_to_string[EC.severity]] events by [increase/600] minute(s).")
|
||||
else if(href_list["select_event"])
|
||||
var/datum/event_container/EC = locate(href_list["select_event"])
|
||||
var/datum/event_meta/EM = EC.SelectEvent()
|
||||
if(EM)
|
||||
admin_log_and_message_admins("has queued the [GLOB.severity_to_string[EC.severity]] event '[EM.name]'.")
|
||||
log_and_message_admins("has queued the [GLOB.severity_to_string[EC.severity]] event '[EM.name]'.")
|
||||
else if(href_list["pause"])
|
||||
var/datum/event_container/EC = locate(href_list["pause"])
|
||||
EC.delayed = !EC.delayed
|
||||
admin_log_and_message_admins("has [EC.delayed ? "paused" : "resumed"] countdown for [GLOB.severity_to_string[EC.severity]] events.")
|
||||
log_and_message_admins("has [EC.delayed ? "paused" : "resumed"] countdown for [GLOB.severity_to_string[EC.severity]] events.")
|
||||
else if(href_list["interval"])
|
||||
var/delay = input("Enter delay modifier. A value less than one means events fire more often, higher than one less often.", "Set Interval Modifier") as num|null
|
||||
if(delay && delay > 0)
|
||||
var/datum/event_container/EC = locate(href_list["interval"])
|
||||
EC.delay_modifier = delay
|
||||
admin_log_and_message_admins("has set the interval modifier for [GLOB.severity_to_string[EC.severity]] events to [EC.delay_modifier].")
|
||||
log_and_message_admins("has set the interval modifier for [GLOB.severity_to_string[EC.severity]] events to [EC.delay_modifier].")
|
||||
else if(href_list["stop"])
|
||||
if(alert("Stopping an event may have unintended side-effects. Continue?","Stopping Event!","Yes","No") != "Yes")
|
||||
return
|
||||
var/datum/event/E = locate(href_list["stop"])
|
||||
var/datum/event_meta/EM = E.event_meta
|
||||
admin_log_and_message_admins("has stopped the [GLOB.severity_to_string[EM.severity]] event '[EM.name]'.")
|
||||
log_and_message_admins("has stopped the [GLOB.severity_to_string[EM.severity]] event '[EM.name]'.")
|
||||
E.kill()
|
||||
else if(href_list["view_events"])
|
||||
selected_event_container = locate(href_list["view_events"])
|
||||
@@ -265,23 +265,23 @@ SUBSYSTEM_DEF(events)
|
||||
var/datum/event_meta/EM = locate(href_list["set_weight"])
|
||||
EM.weight = weight
|
||||
if(EM != new_event)
|
||||
admin_log_and_message_admins("has changed the weight of the [GLOB.severity_to_string[EM.severity]] event '[EM.name]' to [EM.weight].")
|
||||
log_and_message_admins("has changed the weight of the [GLOB.severity_to_string[EM.severity]] event '[EM.name]' to [EM.weight].")
|
||||
else if(href_list["toggle_oneshot"])
|
||||
var/datum/event_meta/EM = locate(href_list["toggle_oneshot"])
|
||||
EM.one_shot = !EM.one_shot
|
||||
if(EM != new_event)
|
||||
admin_log_and_message_admins("has [EM.one_shot ? "set" : "unset"] the oneshot flag for the [GLOB.severity_to_string[EM.severity]] event '[EM.name]'.")
|
||||
log_and_message_admins("has [EM.one_shot ? "set" : "unset"] the oneshot flag for the [GLOB.severity_to_string[EM.severity]] event '[EM.name]'.")
|
||||
else if(href_list["toggle_enabled"])
|
||||
var/datum/event_meta/EM = locate(href_list["toggle_enabled"])
|
||||
EM.enabled = !EM.enabled
|
||||
admin_log_and_message_admins("has [EM.enabled ? "enabled" : "disabled"] the [GLOB.severity_to_string[EM.severity]] event '[EM.name]'.")
|
||||
log_and_message_admins("has [EM.enabled ? "enabled" : "disabled"] the [GLOB.severity_to_string[EM.severity]] event '[EM.name]'.")
|
||||
else if(href_list["remove"])
|
||||
if(alert("This will remove the event from rotation. Continue?","Removing Event!","Yes","No") != "Yes")
|
||||
return
|
||||
var/datum/event_meta/EM = locate(href_list["remove"])
|
||||
var/datum/event_container/EC = locate(href_list["EC"])
|
||||
EC.available_events -= EM
|
||||
admin_log_and_message_admins("has removed the [GLOB.severity_to_string[EM.severity]] event '[EM.name]'.")
|
||||
log_and_message_admins("has removed the [GLOB.severity_to_string[EM.severity]] event '[EM.name]'.")
|
||||
else if(href_list["add"])
|
||||
if(!new_event.name || !new_event.event_type)
|
||||
return
|
||||
@@ -289,12 +289,12 @@ SUBSYSTEM_DEF(events)
|
||||
return
|
||||
new_event.severity = selected_event_container.severity
|
||||
selected_event_container.available_events += new_event
|
||||
admin_log_and_message_admins("has added \a [GLOB.severity_to_string[new_event.severity]] event '[new_event.name]' of type [new_event.event_type] with weight [new_event.weight].")
|
||||
log_and_message_admins("has added \a [GLOB.severity_to_string[new_event.severity]] event '[new_event.name]' of type [new_event.event_type] with weight [new_event.weight].")
|
||||
new_event = new
|
||||
else if(href_list["clear"])
|
||||
var/datum/event_container/EC = locate(href_list["clear"])
|
||||
if(EC.next_event)
|
||||
admin_log_and_message_admins("has dequeued the [GLOB.severity_to_string[EC.severity]] event '[EC.next_event.name]'.")
|
||||
log_and_message_admins("has dequeued the [GLOB.severity_to_string[EC.severity]] event '[EC.next_event.name]'.")
|
||||
EC.next_event = null
|
||||
|
||||
Interact(usr)
|
||||
|
||||
@@ -4,10 +4,10 @@ SUBSYSTEM_DEF(garbage)
|
||||
wait = 2 SECONDS
|
||||
flags = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT
|
||||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
|
||||
init_order = INIT_ORDER_GARBAGE
|
||||
init_order = INIT_ORDER_GARBAGE // Why does this have an init order if it has SS_NO_INIT?
|
||||
offline_implications = "Garbage collection is no longer functional, and objects will not be qdel'd. Immediate server restart recommended."
|
||||
|
||||
var/list/collection_timeout = list(0, 2 MINUTES, 10 SECONDS) // deciseconds to wait before moving something up in the queue to the next level
|
||||
var/list/collection_timeout = list(2 MINUTES, 10 SECONDS) // deciseconds to wait before moving something up in the queue to the next level
|
||||
|
||||
//Stat tracking
|
||||
var/delslasttick = 0 // number of del()'s we've done this tick
|
||||
|
||||
@@ -19,8 +19,18 @@ SUBSYSTEM_DEF(icon_smooth)
|
||||
can_fire = 0
|
||||
|
||||
/datum/controller/subsystem/icon_smooth/Initialize()
|
||||
smooth_zlevel(1,TRUE)
|
||||
smooth_zlevel(2,TRUE)
|
||||
log_startup_progress("Smoothing atoms...")
|
||||
// Smooth EVERYTHING in the world
|
||||
for(var/turf/T in world)
|
||||
if(T.smooth)
|
||||
smooth_icon(T)
|
||||
for(var/A in T)
|
||||
var/atom/AA = A
|
||||
if(AA.smooth)
|
||||
smooth_icon(AA)
|
||||
CHECK_TICK
|
||||
|
||||
// Incase any new atoms were added to the smoothing queue for whatever reason
|
||||
var/queue = smooth_queue
|
||||
smooth_queue = list()
|
||||
for(var/V in queue)
|
||||
|
||||
@@ -121,3 +121,8 @@ SUBSYSTEM_DEF(input)
|
||||
for(var/i in 1 to clients.len)
|
||||
var/client/C = clients[i]
|
||||
C.keyLoop()
|
||||
|
||||
/datum/controller/subsystem/input/Recover()
|
||||
macro_sets = SSinput.macro_sets
|
||||
movement_keys = SSinput.movement_keys
|
||||
alt_movement_keys = SSinput.alt_movement_keys
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
GLOBAL_LIST_EMPTY(lighting_update_lights) // List of lighting sources queued for update.
|
||||
GLOBAL_LIST_EMPTY(lighting_update_corners) // List of lighting corners queued for update.
|
||||
GLOBAL_LIST_EMPTY(lighting_update_objects) // List of lighting objects queued for update.
|
||||
|
||||
SUBSYSTEM_DEF(lighting)
|
||||
name = "Lighting"
|
||||
wait = 2
|
||||
init_order = INIT_ORDER_LIGHTING
|
||||
flags = SS_TICKER
|
||||
offline_implications = "Lighting will no longer update. Shuttle call recommended."
|
||||
var/static/list/sources_queue = list() // List of lighting sources queued for update.
|
||||
var/static/list/corners_queue = list() // List of lighting corners queued for update.
|
||||
var/static/list/objects_queue = list() // List of lighting objects queued for update.
|
||||
|
||||
/datum/controller/subsystem/lighting/stat_entry()
|
||||
..("L:[GLOB.lighting_update_lights.len]|C:[GLOB.lighting_update_corners.len]|O:[GLOB.lighting_update_objects.len]")
|
||||
..("L:[length(sources_queue)]|C:[length(corners_queue)]|O:[length(objects_queue)]")
|
||||
|
||||
/datum/controller/subsystem/lighting/Initialize(timeofday)
|
||||
if(!initialized)
|
||||
@@ -31,9 +30,10 @@ SUBSYSTEM_DEF(lighting)
|
||||
MC_SPLIT_TICK_INIT(3)
|
||||
if(!init_tick_checks)
|
||||
MC_SPLIT_TICK
|
||||
var/list/queue = sources_queue
|
||||
var/i = 0
|
||||
for(i in 1 to GLOB.lighting_update_lights.len)
|
||||
var/datum/light_source/L = GLOB.lighting_update_lights[i]
|
||||
for(i in 1 to length(queue))
|
||||
var/datum/light_source/L = queue[i]
|
||||
|
||||
L.update_corners()
|
||||
|
||||
@@ -44,14 +44,15 @@ SUBSYSTEM_DEF(lighting)
|
||||
else if(MC_TICK_CHECK)
|
||||
break
|
||||
if(i)
|
||||
GLOB.lighting_update_lights.Cut(1, i+1)
|
||||
queue.Cut(1, i + 1)
|
||||
i = 0
|
||||
|
||||
if(!init_tick_checks)
|
||||
MC_SPLIT_TICK
|
||||
|
||||
for (i in 1 to GLOB.lighting_update_corners.len)
|
||||
var/datum/lighting_corner/C = GLOB.lighting_update_corners[i]
|
||||
queue = corners_queue
|
||||
for(i in 1 to length(queue))
|
||||
var/datum/lighting_corner/C = queue[i]
|
||||
|
||||
C.update_objects()
|
||||
C.needs_update = FALSE
|
||||
@@ -60,15 +61,16 @@ SUBSYSTEM_DEF(lighting)
|
||||
else if(MC_TICK_CHECK)
|
||||
break
|
||||
if(i)
|
||||
GLOB.lighting_update_corners.Cut(1, i+1)
|
||||
queue.Cut(1, i + 1)
|
||||
i = 0
|
||||
|
||||
|
||||
if(!init_tick_checks)
|
||||
MC_SPLIT_TICK
|
||||
|
||||
for (i in 1 to GLOB.lighting_update_objects.len)
|
||||
var/atom/movable/lighting_object/O = GLOB.lighting_update_objects[i]
|
||||
queue = objects_queue
|
||||
for(i in 1 to length(queue))
|
||||
var/atom/movable/lighting_object/O = queue[i]
|
||||
|
||||
if(QDELETED(O))
|
||||
continue
|
||||
@@ -80,7 +82,7 @@ SUBSYSTEM_DEF(lighting)
|
||||
else if(MC_TICK_CHECK)
|
||||
break
|
||||
if(i)
|
||||
GLOB.lighting_update_objects.Cut(1, i+1)
|
||||
queue.Cut(1, i + 1)
|
||||
|
||||
|
||||
/datum/controller/subsystem/lighting/Recover()
|
||||
|
||||
@@ -42,7 +42,7 @@ SUBSYSTEM_DEF(machines)
|
||||
while(currentrun.len)
|
||||
var/obj/O = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(O)
|
||||
if(O && !QDELETED(O))
|
||||
var/datum/powernet/newPN = new() // create a new powernet...
|
||||
propagate_network(O, newPN)//... and propagate it to the other side of the cable
|
||||
|
||||
|
||||
@@ -11,24 +11,57 @@ SUBSYSTEM_DEF(mapping)
|
||||
createRandomZlevel()
|
||||
// Seed space ruins
|
||||
if(!config.disable_space_ruins)
|
||||
var/timer = start_watch()
|
||||
log_startup_progress("Creating random space levels...")
|
||||
seedRuins(list(level_name_to_num(EMPTY_AREA)), rand(0, 3), /area/space, GLOB.space_ruins_templates)
|
||||
log_startup_progress("Loaded random space levels in [stop_watch(timer)]s.")
|
||||
|
||||
// load in extra levels of space ruins
|
||||
|
||||
var/load_zlevels_timer = start_watch()
|
||||
log_startup_progress("Creating random space levels...")
|
||||
var/num_extra_space = rand(config.extra_space_ruin_levels_min, config.extra_space_ruin_levels_max)
|
||||
for(var/i = 1, i <= num_extra_space, i++)
|
||||
var/zlev = GLOB.space_manager.add_new_zlevel("[EMPTY_AREA] #[i]", linkage = CROSSLINKED, traits = list(REACHABLE))
|
||||
seedRuins(list(zlev), rand(0, 3), /area/space, GLOB.space_ruins_templates)
|
||||
GLOB.space_manager.add_new_zlevel("Ruin Area #[i]", linkage = CROSSLINKED, traits = list(REACHABLE, SPAWN_RUINS))
|
||||
log_startup_progress("Loaded random space levels in [stop_watch(load_zlevels_timer)]s.")
|
||||
|
||||
// Now spawn ruins, random budget between 20 and 30 for all zlevels combined.
|
||||
// While this may seem like a high number, the amount of ruin Z levels can be anywhere between 3 and 7.
|
||||
// Note that this budget is not split evenly accross all zlevels
|
||||
log_startup_progress("Seeding ruins...")
|
||||
var/seed_ruins_timer = start_watch()
|
||||
seedRuins(levels_by_trait(SPAWN_RUINS), rand(20, 30), /area/space, GLOB.space_ruins_templates)
|
||||
log_startup_progress("Successfully seeded ruins in [stop_watch(seed_ruins_timer)]s.")
|
||||
|
||||
// Makes a blank space level for the sake of randomness
|
||||
GLOB.space_manager.add_new_zlevel("Empty Area", linkage = CROSSLINKED, traits = list(REACHABLE))
|
||||
|
||||
|
||||
// Setup the Z-level linkage
|
||||
GLOB.space_manager.do_transition_setup()
|
||||
|
||||
// Spawn Lavaland ruins and rivers.
|
||||
log_startup_progress("Populating lavaland...")
|
||||
var/lavaland_setup_timer = start_watch()
|
||||
seedRuins(list(level_name_to_num(MINING)), config.lavaland_budget, /area/lavaland/surface/outdoors/unexplored, GLOB.lava_ruins_templates)
|
||||
spawn_rivers(list(level_name_to_num(MINING)))
|
||||
log_startup_progress("Successfully populated lavaland in [stop_watch(lavaland_setup_timer)]s.")
|
||||
|
||||
// Now we make a list of areas for teleport locs
|
||||
// TOOD: Make these locs into lists on the SS itself, not globs
|
||||
for(var/area/AR in world)
|
||||
if(AR.no_teleportlocs)
|
||||
continue
|
||||
if(GLOB.teleportlocs[AR.name])
|
||||
continue
|
||||
var/turf/picked = safepick(get_area_turfs(AR.type))
|
||||
if(picked && is_station_level(picked.z))
|
||||
GLOB.teleportlocs[AR.name] = AR
|
||||
|
||||
GLOB.teleportlocs = sortAssoc(GLOB.teleportlocs)
|
||||
|
||||
for(var/area/AR in world)
|
||||
if(GLOB.ghostteleportlocs[AR.name])
|
||||
continue
|
||||
var/list/turfs = get_area_turfs(AR.type)
|
||||
if(turfs.len)
|
||||
GLOB.ghostteleportlocs[AR.name] = AR
|
||||
|
||||
GLOB.ghostteleportlocs = sortAssoc(GLOB.ghostteleportlocs)
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ SUBSYSTEM_DEF(mob_hunt)
|
||||
name = "Nano-Mob Hunter GO Server"
|
||||
init_order = INIT_ORDER_NANOMOB
|
||||
priority = FIRE_PRIORITY_NANOMOB // Low priority, no need for MC_TICK_CHECK due to extremely low performance impact.
|
||||
flags = SS_NO_INIT
|
||||
offline_implications = "Nano-Mob Hunter will no longer spawn mobs. No immediate action is needed."
|
||||
var/max_normal_spawns = 15 //change this to adjust the number of normal spawns that can exist at one time. trapped spawns (from traitors) don't count towards this
|
||||
var/list/normal_spawns = list()
|
||||
@@ -103,12 +104,12 @@ SUBSYSTEM_DEF(mob_hunt)
|
||||
return
|
||||
if(red_terminal && red_terminal.ready && blue_terminal && blue_terminal.ready)
|
||||
battle_turn = pick("Red", "Blue")
|
||||
red_terminal.audible_message("Battle starting!", null, 5)
|
||||
blue_terminal.audible_message("Battle starting!", null, 5)
|
||||
red_terminal.atom_say("Battle starting!")
|
||||
blue_terminal.atom_say("Battle starting!")
|
||||
if(battle_turn == "Red")
|
||||
red_terminal.audible_message("Red Player's Turn!", null, 5)
|
||||
red_terminal.atom_say("Red Player's Turn!")
|
||||
else if(battle_turn == "Blue")
|
||||
blue_terminal.audible_message("Blue Player's Turn!", null, 5)
|
||||
blue_terminal.atom_say("Blue Player's Turn!")
|
||||
|
||||
/datum/controller/subsystem/mob_hunt/proc/launch_attack(team, raw_damage, datum/mob_type/attack_type)
|
||||
if(!team || !raw_damage)
|
||||
@@ -135,11 +136,11 @@ SUBSYSTEM_DEF(mob_hunt)
|
||||
winner_terminal.ready = 0
|
||||
loser_terminal.ready = 0
|
||||
if(surrender) //surrender doesn't give exp, to avoid people just farming exp without actually doing a battle
|
||||
winner_terminal.audible_message("Your rival surrendered!", null, 2)
|
||||
winner_terminal.atom_say("Your rival surrendered!")
|
||||
else
|
||||
var/progress_message = winner_terminal.mob_info.gain_exp()
|
||||
winner_terminal.audible_message("[winner_terminal.team] Player wins!", null, 5)
|
||||
winner_terminal.audible_message(progress_message, null, 2)
|
||||
winner_terminal.atom_say("[winner_terminal.team] Player wins!")
|
||||
winner_terminal.atom_say(progress_message)
|
||||
|
||||
/datum/controller/subsystem/mob_hunt/proc/end_turn()
|
||||
red_terminal.updateUsrDialog()
|
||||
@@ -148,7 +149,7 @@ SUBSYSTEM_DEF(mob_hunt)
|
||||
return
|
||||
if(battle_turn == "Red")
|
||||
battle_turn = "Blue"
|
||||
blue_terminal.audible_message("Blue's turn.", null, 5)
|
||||
blue_terminal.atom_say("Blue's turn.")
|
||||
else if(battle_turn == "Blue")
|
||||
battle_turn = "Red"
|
||||
blue_terminal.audible_message("Red's turn.", null, 5)
|
||||
blue_terminal.atom_say("Red's turn.")
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(dcs)
|
||||
name = "Datum Component System"
|
||||
flags = SS_NO_INIT
|
||||
|
||||
var/list/elements_by_type = list()
|
||||
// Update this if you add in components which actually use this as a processor
|
||||
offline_implications = "This SS doesnt actually process anything yet. No immediate action is needed."
|
||||
|
||||
/datum/controller/subsystem/processing/dcs/Recover()
|
||||
comp_lookup = SSdcs.comp_lookup
|
||||
|
||||
/datum/controller/subsystem/processing/dcs/proc/GetElement(list/arguments)
|
||||
var/datum/element/eletype = arguments[1]
|
||||
var/element_id = eletype
|
||||
|
||||
if(!ispath(eletype, /datum/element))
|
||||
CRASH("Attempted to instantiate [eletype] as a /datum/element")
|
||||
|
||||
if(initial(eletype.element_flags) & ELEMENT_BESPOKE)
|
||||
element_id = GetIdFromArguments(arguments)
|
||||
|
||||
. = elements_by_type[element_id]
|
||||
if(.)
|
||||
return
|
||||
. = elements_by_type[element_id] = new eletype
|
||||
|
||||
/****
|
||||
* Generates an id for bespoke elements when given the argument list
|
||||
* Generating the id here is a bit complex because we need to support named arguments
|
||||
* Named arguments can appear in any order and we need them to appear after ordered arguments
|
||||
* We assume that no one will pass in a named argument with a value of null
|
||||
**/
|
||||
/datum/controller/subsystem/processing/dcs/proc/GetIdFromArguments(list/arguments)
|
||||
var/datum/element/eletype = arguments[1]
|
||||
var/list/fullid = list("[eletype]")
|
||||
var/list/named_arguments = list()
|
||||
for(var/i in initial(eletype.id_arg_index) to length(arguments))
|
||||
var/key = arguments[i]
|
||||
var/value
|
||||
if(istext(key))
|
||||
value = arguments[key]
|
||||
if(!(istext(key) || isnum(key)))
|
||||
key = "\ref[key]"
|
||||
key = "[key]" // Key is stringified so numbers dont break things
|
||||
if(!isnull(value))
|
||||
if(!(istext(value) || isnum(value)))
|
||||
value = "\ref[value]"
|
||||
named_arguments["[key]"] = value
|
||||
else
|
||||
fullid += "[key]"
|
||||
|
||||
if(length(named_arguments))
|
||||
named_arguments = sortList(named_arguments)
|
||||
fullid += named_arguments
|
||||
return list2params(fullid)
|
||||
@@ -4,3 +4,4 @@ PROCESSING_SUBSYSTEM_DEF(fastprocess)
|
||||
name = "Fast Processing"
|
||||
wait = 2
|
||||
stat_tag = "FP"
|
||||
offline_implications = "Objects using the 'Fast Processing' processor will no longer process. Shuttle call recommended."
|
||||
|
||||
@@ -3,3 +3,4 @@ PROCESSING_SUBSYSTEM_DEF(obj)
|
||||
priority = FIRE_PRIORITY_OBJ
|
||||
flags = SS_NO_INIT
|
||||
wait = 20
|
||||
offline_implications = "Objects using the 'Objects' processor will no longer process. Shuttle call recommended."
|
||||
|
||||
@@ -9,6 +9,7 @@ SUBSYSTEM_DEF(processing)
|
||||
var/stat_tag = "P" //Used for logging
|
||||
var/list/processing = list()
|
||||
var/list/currentrun = list()
|
||||
offline_implications = "Objects using the default processor will no longer process. Shuttle call recommended."
|
||||
|
||||
/datum/controller/subsystem/processing/stat_entry()
|
||||
..("[stat_tag]:[processing.len]")
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
/**
|
||||
* tgui subsystem
|
||||
*
|
||||
* Contains all tgui state and subsystem code.
|
||||
**/
|
||||
|
||||
|
||||
SUBSYSTEM_DEF(tgui)
|
||||
name = "TGUI"
|
||||
wait = 9
|
||||
flags = SS_NO_INIT
|
||||
priority = FIRE_PRIORITY_NANOUI // Yes I am aware that this is TGUI and I used the nanoUI fire priority. Dont @ me.
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
offline_implications = "All TGUIs will no longer process. Shuttle call recommended."
|
||||
|
||||
var/list/currentrun = list()
|
||||
var/list/open_uis = list() // A list of open UIs, grouped by src_object and ui_key.
|
||||
var/list/processing_uis = list() // A list of processing UIs, ungrouped.
|
||||
var/basehtml // The HTML base used for all UIs.
|
||||
|
||||
/datum/controller/subsystem/tgui/PreInit()
|
||||
basehtml = file2text('tgui/packages/tgui/public/tgui.html')
|
||||
|
||||
/datum/controller/subsystem/tgui/Shutdown()
|
||||
close_all_uis()
|
||||
|
||||
/datum/controller/subsystem/tgui/stat_entry()
|
||||
..("P:[processing_uis.len]")
|
||||
|
||||
/datum/controller/subsystem/tgui/fire(resumed = 0)
|
||||
if (!resumed)
|
||||
src.currentrun = processing_uis.Copy()
|
||||
//cache for sanic speed (lists are references anyways)
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
while(currentrun.len)
|
||||
var/datum/tgui/ui = currentrun[currentrun.len]
|
||||
currentrun.len--
|
||||
if(ui && ui.user && ui.src_object)
|
||||
ui.process()
|
||||
else
|
||||
processing_uis.Remove(ui)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Get a open UI given a user, src_object, and ui_key and try to update it with data.
|
||||
*
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* required src_object datum The object/datum which owns the UI.
|
||||
* required ui_key string The ui_key of the UI.
|
||||
* optional ui datum/tgui The UI to be updated, if it exists.
|
||||
* optional force_open bool If the UI should be re-opened instead of updated.
|
||||
*
|
||||
* return datum/tgui The found UI.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/try_update_ui(mob/user, datum/src_object, ui_key, datum/tgui/ui, force_open = FALSE)
|
||||
if(isnull(ui)) // No UI was passed, so look for one.
|
||||
ui = get_open_ui(user, src_object, ui_key)
|
||||
|
||||
if(!isnull(ui))
|
||||
var/data = src_object.tgui_data(user) // Get data from the src_object.
|
||||
if(!force_open) // UI is already open; update it.
|
||||
ui.push_data(data)
|
||||
else // Re-open it anyways.
|
||||
ui.reinitialize(null, data)
|
||||
return ui // We found the UI, return it.
|
||||
else
|
||||
return null // We couldn't find a UI.
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Get a open UI given a user, src_object, and ui_key.
|
||||
*
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* required src_object datum The object/datum which owns the UI.
|
||||
* required ui_key string The ui_key of the UI.
|
||||
*
|
||||
* return datum/tgui The found UI.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/get_open_ui(mob/user, datum/src_object, ui_key)
|
||||
var/src_object_key = "[src_object.UID()]"
|
||||
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return null // No UIs open.
|
||||
else if(isnull(open_uis[src_object_key][ui_key]) || !istype(open_uis[src_object_key][ui_key], /list))
|
||||
return null // No UIs open for this object.
|
||||
|
||||
for(var/datum/tgui/ui in open_uis[src_object_key][ui_key]) // Find UIs for this object.
|
||||
if(ui.user == user) // Make sure we have the right user
|
||||
return ui
|
||||
|
||||
return null // Couldn't find a UI!
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Update all UIs attached to src_object.
|
||||
*
|
||||
* required src_object datum The object/datum which owns the UIs.
|
||||
*
|
||||
* return int The number of UIs updated.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/update_uis(datum/src_object)
|
||||
var/src_object_key = "[src_object.UID()]"
|
||||
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return 0 // Couldn't find any UIs for this object.
|
||||
|
||||
var/update_count = 0
|
||||
for(var/ui_key in open_uis[src_object_key])
|
||||
for(var/datum/tgui/ui in open_uis[src_object_key][ui_key])
|
||||
if(ui && ui.src_object && ui.user && ui.src_object.tgui_host(ui.user)) // Check the UI is valid.
|
||||
ui.process(force = 1) // Update the UI.
|
||||
update_count++ // Count each UI we update.
|
||||
return update_count
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Close all UIs attached to src_object.
|
||||
*
|
||||
* required src_object datum The object/datum which owns the UIs.
|
||||
*
|
||||
* return int The number of UIs closed.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/close_uis(datum/src_object)
|
||||
var/src_object_key = "[src_object.UID()]"
|
||||
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return 0 // Couldn't find any UIs for this object.
|
||||
|
||||
var/close_count = 0
|
||||
for(var/ui_key in open_uis[src_object_key])
|
||||
for(var/datum/tgui/ui in open_uis[src_object_key][ui_key])
|
||||
if(ui && ui.src_object && ui.user && ui.src_object.tgui_host(ui.user)) // Check the UI is valid.
|
||||
ui.close() // Close the UI.
|
||||
close_count++ // Count each UI we close.
|
||||
return close_count
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Close *ALL* UIs
|
||||
*
|
||||
* return int The number of UIs closed.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/close_all_uis()
|
||||
var/close_count = 0
|
||||
for(var/src_object_key in open_uis)
|
||||
for(var/ui_key in open_uis[src_object_key])
|
||||
for(var/datum/tgui/ui in open_uis[src_object_key][ui_key])
|
||||
if(ui && ui.src_object && ui.user && ui.src_object.tgui_host(ui.user)) // Check the UI is valid.
|
||||
ui.close() // Close the UI.
|
||||
close_count++ // Count each UI we close.
|
||||
return close_count
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Update all UIs belonging to a user.
|
||||
*
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* optional src_object datum If provided, only update UIs belonging this src_object.
|
||||
* optional ui_key string If provided, only update UIs with this UI key.
|
||||
*
|
||||
* return int The number of UIs updated.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/update_user_uis(mob/user, datum/src_object = null, ui_key = null)
|
||||
if(isnull(user.open_tguis) || !istype(user.open_tguis, /list) || open_uis.len == 0)
|
||||
return 0 // Couldn't find any UIs for this user.
|
||||
|
||||
var/update_count = 0
|
||||
for(var/datum/tgui/ui in user.open_tguis)
|
||||
if((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key))
|
||||
ui.process(force = 1) // Update the UI.
|
||||
update_count++ // Count each UI we upadte.
|
||||
return update_count
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Close all UIs belonging to a user.
|
||||
*
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* optional src_object datum If provided, only close UIs belonging this src_object.
|
||||
* optional ui_key string If provided, only close UIs with this UI key.
|
||||
*
|
||||
* return int The number of UIs closed.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/close_user_uis(mob/user, datum/src_object = null, ui_key = null)
|
||||
if(isnull(user.open_tguis) || !istype(user.open_tguis, /list) || open_uis.len == 0)
|
||||
return 0 // Couldn't find any UIs for this user.
|
||||
|
||||
var/close_count = 0
|
||||
for(var/datum/tgui/ui in user.open_tguis)
|
||||
if((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key))
|
||||
ui.close() // Close the UI.
|
||||
close_count++ // Count each UI we close.
|
||||
return close_count
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Add a UI to the list of open UIs.
|
||||
*
|
||||
* required ui datum/tgui The UI to be added.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/on_open(datum/tgui/ui)
|
||||
var/src_object_key = "[ui.src_object.UID()]"
|
||||
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
open_uis[src_object_key] = list(ui.ui_key = list()) // Make a list for the ui_key and src_object.
|
||||
else if(isnull(open_uis[src_object_key][ui.ui_key]) || !istype(open_uis[src_object_key][ui.ui_key], /list))
|
||||
open_uis[src_object_key][ui.ui_key] = list() // Make a list for the ui_key.
|
||||
|
||||
// Append the UI to all the lists.
|
||||
ui.user.open_tguis |= ui
|
||||
var/list/uis = open_uis[src_object_key][ui.ui_key]
|
||||
uis |= ui
|
||||
processing_uis |= ui
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Remove a UI from the list of open UIs.
|
||||
*
|
||||
* required ui datum/tgui The UI to be removed.
|
||||
*
|
||||
* return bool If the UI was removed or not.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/on_close(datum/tgui/ui)
|
||||
var/src_object_key = "[ui.src_object.UID()]"
|
||||
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
|
||||
return FALSE // It wasn't open.
|
||||
else if(isnull(open_uis[src_object_key][ui.ui_key]) || !istype(open_uis[src_object_key][ui.ui_key], /list))
|
||||
return FALSE // It wasn't open.
|
||||
|
||||
processing_uis.Remove(ui) // Remove it from the list of processing UIs.
|
||||
if(ui.user) // If the user exists, remove it from them too.
|
||||
ui.user.open_tguis.Remove(ui)
|
||||
var/Ukey = ui.ui_key
|
||||
var/list/uis = open_uis[src_object_key][Ukey] // Remove it from the list of open UIs.
|
||||
uis.Remove(ui)
|
||||
if(!uis.len)
|
||||
var/list/uiobj = open_uis[src_object_key]
|
||||
uiobj.Remove(Ukey)
|
||||
if(!uiobj.len)
|
||||
open_uis.Remove(src_object_key)
|
||||
|
||||
return TRUE // Let the caller know we did it.
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Handle client logout, by closing all their UIs.
|
||||
*
|
||||
* required user mob The mob which logged out.
|
||||
*
|
||||
* return int The number of UIs closed.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/on_logout(mob/user)
|
||||
return close_user_uis(user)
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Handle clients switching mobs, by transferring their UIs.
|
||||
*
|
||||
* required user source The client's original mob.
|
||||
* required user target The client's new mob.
|
||||
*
|
||||
* return bool If the UIs were transferred.
|
||||
**/
|
||||
/datum/controller/subsystem/tgui/proc/on_transfer(mob/source, mob/target)
|
||||
if(!source || isnull(source.open_tguis) || !istype(source.open_tguis, /list) || open_uis.len == 0)
|
||||
return FALSE // The old mob had no open UIs.
|
||||
|
||||
if(isnull(target.open_tguis) || !istype(target.open_tguis, /list))
|
||||
target.open_tguis = list() // Create a list for the new mob if needed.
|
||||
|
||||
for(var/datum/tgui/ui in source.open_tguis)
|
||||
ui.user = target // Inform the UIs of their new owner.
|
||||
target.open_tguis.Add(ui) // Transfer all the UIs.
|
||||
|
||||
source.open_tguis.Cut() // Clear the old list.
|
||||
return TRUE // Let the caller know we did it.
|
||||
@@ -180,7 +180,14 @@ SUBSYSTEM_DEF(ticker)
|
||||
current_state = GAME_STATE_PLAYING
|
||||
Master.SetRunLevel(RUNLEVEL_GAME)
|
||||
|
||||
callHook("roundstart")
|
||||
// Generate the list of playable AI cores in the world
|
||||
for(var/obj/effect/landmark/start/S in GLOB.landmarks_list)
|
||||
if(S.name != "AI")
|
||||
continue
|
||||
if(locate(/mob/living) in S.loc)
|
||||
continue
|
||||
GLOB.empty_playable_ai_cores += new /obj/structure/AIcore/deactivated(get_turf(S))
|
||||
|
||||
|
||||
//here to initialize the random events nicely at round start
|
||||
setup_economy()
|
||||
@@ -280,7 +287,21 @@ SUBSYSTEM_DEF(ticker)
|
||||
if(N.client)
|
||||
N.new_player_panel_proc()
|
||||
|
||||
return 1
|
||||
// Now that every other piece of the round has initialized, lets setup player job scaling
|
||||
var/playercount = length(GLOB.clients)
|
||||
var/highpop_trigger = 80
|
||||
|
||||
if(playercount >= highpop_trigger)
|
||||
log_debug("Playercount: [playercount] versus trigger: [highpop_trigger] - loading highpop job config")
|
||||
SSjobs.LoadJobs("config/jobs_highpop.txt")
|
||||
else
|
||||
log_debug("Playercount: [playercount] versus trigger: [highpop_trigger] - keeping standard job config")
|
||||
|
||||
#ifdef UNIT_TESTS
|
||||
RunUnitTests()
|
||||
#endif
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/station_explosion_cinematic(station_missed = 0, override = null)
|
||||
if(cinematic)
|
||||
@@ -405,7 +426,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
EquipCustomItems(player)
|
||||
if(captainless)
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!istype(M,/mob/new_player))
|
||||
if(!isnewplayer(M))
|
||||
to_chat(M, "Captainship not forced on anyone.")
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/send_tip_of_the_round()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
GLOBAL_REAL(SSmentor_tickets, /datum/controller/subsystem/tickets/mentor_tickets)
|
||||
|
||||
/datum/controller/subsystem/tickets/mentor_tickets/New()
|
||||
NEW_SS_GLOBAL(SSmentor_tickets);
|
||||
PreInit();
|
||||
NEW_SS_GLOBAL(SSmentor_tickets)
|
||||
PreInit()
|
||||
|
||||
/datum/controller/subsystem/tickets/mentor_tickets
|
||||
name = "Mentor Tickets"
|
||||
@@ -10,12 +10,13 @@ GLOBAL_REAL(SSmentor_tickets, /datum/controller/subsystem/tickets/mentor_tickets
|
||||
ticket_name = "Mentor Ticket"
|
||||
span_class = "mentorhelp"
|
||||
close_rights = R_MENTOR | R_ADMIN
|
||||
offline_implications = "Mentor tickets will no longer be marked as stale. No immediate action is needed."
|
||||
|
||||
/datum/controller/subsystem/tickets/mentor_tickets/message_staff(var/msg)
|
||||
message_mentorTicket(msg)
|
||||
|
||||
/datum/controller/subsystem/tickets/mentor_tickets/Initialize()
|
||||
close_messages = list("<font color='red' size='3'><b>- [ticket_name] Closed -</b></font>",
|
||||
"<span class='boldmessage'>Please try to be as descriptive as possible in mentor helps. Mentors do not know the full situation you're in and need more information to give you a helpful response.</span>",
|
||||
close_messages = list("<font color='red' size='3'><b>- [ticket_name] Closed -</b></font>",
|
||||
"<span class='boldmessage'>Please try to be as descriptive as possible in mentor helps. Mentors do not know the full situation you're in and need more information to give you a helpful response.</span>",
|
||||
"<span class='[span_class]'>Your [ticket_name] has now been closed.</span>")
|
||||
return ..()
|
||||
|
||||
@@ -20,16 +20,17 @@ SUBSYSTEM_DEF(tickets)
|
||||
init_order = INIT_ORDER_TICKETS
|
||||
wait = 300
|
||||
priority = FIRE_PRIORITY_TICKETS
|
||||
|
||||
offline_implications = "Admin tickets will no longer be marked as stale. No immediate action is needed."
|
||||
|
||||
flags = SS_BACKGROUND
|
||||
|
||||
|
||||
var/list/allTickets = list() //make it here because someone might ahelp before the system has initialized
|
||||
|
||||
var/ticketCounter = 1
|
||||
|
||||
/datum/controller/subsystem/tickets/Initialize()
|
||||
close_messages = list("<font color='red' size='4'><b>- [ticket_name] Rejected! -</b></font>",
|
||||
"<span class='boldmessage'>Please try to be calm, clear, and descriptive in admin helps, do not assume the staff member has seen any related events, and clearly state the names of anybody you are reporting. If you asked a question, please ensure it was clear what you were asking.</span>",
|
||||
"<span class='boldmessage'>Please try to be calm, clear, and descriptive in admin helps, do not assume the staff member has seen any related events, and clearly state the names of anybody you are reporting. If you asked a question, please ensure it was clear what you were asking.</span>",
|
||||
"<span class='[span_class]'>Your [ticket_name] has now been closed.</span>")
|
||||
return ..()
|
||||
|
||||
@@ -112,7 +113,7 @@ SUBSYSTEM_DEF(tickets)
|
||||
message_staff("<span class='[span_class]'>[usr.client] / ([usr]) resolved [ticket_name] number [N]</span>")
|
||||
to_chat_safe(returnClient(N), "<span class='[span_class]'>Your [ticket_name] has now been resolved.</span>")
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
/datum/controller/subsystem/tickets/proc/autoRespond(N)
|
||||
if(!check_rights(R_ADMIN|R_MOD))
|
||||
@@ -124,19 +125,19 @@ SUBSYSTEM_DEF(tickets)
|
||||
if(alert(usr, "[T.ticketState == TICKET_OPEN ? "Another admin appears to already be handling this." : "This ticket is already marked as closed or resolved"] Are you sure you want to continue?", "Confirmation", "Yes", "No") != "Yes")
|
||||
return
|
||||
T.assignStaff(C)
|
||||
|
||||
var/response_phrases = list("Thanks" = "Thanks, have a Paradise day!",
|
||||
|
||||
var/response_phrases = list("Thanks" = "Thanks, have a Paradise day!",
|
||||
"Handling It" = "The issue is being looked into, thanks.",
|
||||
"Already Resolved" = "The problem has been resolved already.",
|
||||
"Mentorhelp" = "Please redirect your question to Mentorhelp, as they are better experienced with these types of questions.",
|
||||
"Happens Again" = "Thanks, let us know if it continues to happen.",
|
||||
"Clear Cache" = "To fix a blank screen, please leave the game and clear your Byond Cache. To clear your Byond Cache, there is a Settings icon in the top right of the launcher. After you click that, go into the Games tab and hit the Clear Cache button. If the issue persists a few minutes after rejoining and doing this, please adminhelp again and state you cleared your cache." ,
|
||||
"Clear Cache" = "To fix a blank screen, go to the 'Special Verbs' tab and press 'Reload UI Resources'. If that fails, clear your BYOND cache (instructions provided with 'Reload UI Resources'). If that still fails, please adminhelp again, stating you have already done the following." ,
|
||||
"IC Issue" = "This is an In Character (IC) issue and will not be handled by admins. You could speak to Security, Internal Affairs, a Departmental Head, Nanotrasen Representetive, or any other relevant authority currently on station.",
|
||||
"Reject" = "Reject",
|
||||
"Man Up" = "Man Up",
|
||||
"Appeal on the Forums" = "Appealing a ban must occur on the forums. Privately messaging, or adminhelping about your ban will not resolve it. To appeal your ban, please head to <a href='[config.banappeals]'>[config.banappeals]</a>"
|
||||
)
|
||||
|
||||
|
||||
var/sorted_responses = list()
|
||||
for(var/key in response_phrases) //build a new list based on the short descriptive keys of the master list so we can send this as the input instead of the full paragraphs to the admin choosing which autoresponse
|
||||
sorted_responses += key
|
||||
@@ -351,7 +352,7 @@ UI STUFF
|
||||
dat += "<tr><td>[T.content[i]]</td></tr>"
|
||||
|
||||
dat += "</table><br /><br />"
|
||||
dat += "<a href='?src=[UID()];detailreopen=[T.ticketNum]'>Re-Open</a>[check_rights(R_ADMIN|R_MOD, 0) ? "<a href='?src=[UID()];autorespond=[T.ticketNum]'>Auto</a>": ""]<a href='?src=[UID()];detailresolve=[T.ticketNum]'>Resolve</a><br /><br />"
|
||||
dat += "<a href='?src=[UID()];detailreopen=[T.ticketNum]'>Re-Open</a>[check_rights(R_ADMIN|R_MOD, 0) ? "<a href='?src=[UID()];autorespond=[T.ticketNum]'>Auto</a>": ""]<a href='?src=[UID()];detailresolve=[T.ticketNum]'>Resolve</a><br /><br />"
|
||||
|
||||
if(!T.staffAssigned)
|
||||
dat += "No staff member assigned to this [ticket_name] - <a href='?src=[UID()];assignstaff=[T.ticketNum]'>Take Ticket</a><br />"
|
||||
@@ -447,7 +448,7 @@ UI STUFF
|
||||
return
|
||||
if(closeTicket(indexNum))
|
||||
showDetailUI(usr, indexNum)
|
||||
|
||||
|
||||
|
||||
if(href_list["detailreopen"])
|
||||
var/indexNum = text2num(href_list["detailreopen"])
|
||||
|
||||
@@ -160,7 +160,7 @@ SUBSYSTEM_DEF(timer)
|
||||
|
||||
if(timer.timeToRun < head_offset)
|
||||
bucket_resolution = null //force bucket recreation
|
||||
CRASH("[i] Invalid timer state: Timer in long run queue with a time to run less then head_offset. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
stack_trace("[i] Invalid timer state: Timer in long run queue with a time to run less then head_offset. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
|
||||
if(timer.callBack && !timer.spent)
|
||||
timer.callBack.InvokeAsync()
|
||||
@@ -172,7 +172,7 @@ SUBSYSTEM_DEF(timer)
|
||||
|
||||
if(timer.timeToRun < head_offset + TICKS2DS(practical_offset-1))
|
||||
bucket_resolution = null //force bucket recreation
|
||||
CRASH("[i] Invalid timer state: Timer in long run queue that would require a backtrack to transfer to short run queue. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
stack_trace("[i] Invalid timer state: Timer in long run queue that would require a backtrack to transfer to short run queue. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]")
|
||||
if(timer.callBack && !timer.spent)
|
||||
timer.callBack.InvokeAsync()
|
||||
spent += timer
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/hook/startup/proc/setup_title_screen()
|
||||
SUBSYSTEM_DEF(title)
|
||||
name = "Title Screen"
|
||||
flags = SS_NO_FIRE
|
||||
init_order = INIT_ORDER_TITLE
|
||||
|
||||
/datum/controller/subsystem/title/Initialize()
|
||||
var/list/provisional_title_screens = flist("config/title_screens/images/")
|
||||
var/list/title_screens = list()
|
||||
var/use_rare_screens = prob(1)
|
||||
@@ -29,5 +34,5 @@
|
||||
|
||||
for(var/turf/unsimulated/wall/splashscreen/splash in world)
|
||||
splash.icon = icon
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
return ..()
|
||||
@@ -367,7 +367,7 @@ SUBSYSTEM_DEF(vote)
|
||||
var/votedesc = capitalize(mode)
|
||||
if(mode == "custom")
|
||||
votedesc += " ([question])"
|
||||
admin_log_and_message_admins("cancelled the running [votedesc] vote.")
|
||||
log_and_message_admins("cancelled the running [votedesc] vote.")
|
||||
reset()
|
||||
if("toggle_restart")
|
||||
if(admin)
|
||||
|
||||
@@ -57,7 +57,6 @@ SUBSYSTEM_DEF(weather)
|
||||
break
|
||||
if(!ispath(weather_datum_type, /datum/weather))
|
||||
CRASH("run_weather called with invalid weather_datum_type: [weather_datum_type || "null"]")
|
||||
return
|
||||
|
||||
if(isnull(z_levels))
|
||||
z_levels = levels_by_trait(initial(weather_datum_type.target_trait))
|
||||
@@ -65,7 +64,6 @@ SUBSYSTEM_DEF(weather)
|
||||
z_levels = list(z_levels)
|
||||
else if(!islist(z_levels))
|
||||
CRASH("run_weather called with invalid z_levels: [z_levels || "null"]")
|
||||
return
|
||||
|
||||
var/datum/weather/W = new weather_datum_type(z_levels)
|
||||
W.telegraph()
|
||||
|
||||
@@ -339,7 +339,7 @@
|
||||
|
||||
/datum/action/item_action/remove_tape/Trigger(attack_self = FALSE)
|
||||
if(..())
|
||||
GET_COMPONENT_FROM(DT, /datum/component/ducttape, target)
|
||||
var/datum/component/ducttape/DT = target.GetComponent(/datum/component/ducttape)
|
||||
DT.remove_tape(target, usr)
|
||||
|
||||
/datum/action/item_action/toggle_jetpack
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
#define ARMORID "armor-[melee]-[bullet]-[laser]-[energy]-[bomb]-[bio]-[rad]-[fire]-[acid]-[magic]"
|
||||
|
||||
/proc/getArmor(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0, magic = 0)
|
||||
. = locate(ARMORID)
|
||||
if (!.)
|
||||
. = new /datum/armor(melee, bullet, laser, energy, bomb, bio, rad, fire, acid, magic)
|
||||
|
||||
/datum/armor
|
||||
var/melee
|
||||
var/bullet
|
||||
var/laser
|
||||
var/energy
|
||||
var/bomb
|
||||
var/bio
|
||||
var/rad
|
||||
var/fire
|
||||
var/acid
|
||||
var/magic
|
||||
|
||||
/datum/armor/New(melee_value = 0, bullet_value = 0, laser_value = 0, energy_value = 0, bomb_value = 0, bio_value = 0, rad_value = 0, fire_value = 0, acid_value = 0, magic_value = 0)
|
||||
melee = melee_value
|
||||
bullet = bullet_value
|
||||
laser = laser_value
|
||||
energy = energy_value
|
||||
bomb = bomb_value
|
||||
bio = bio_value
|
||||
rad = rad_value
|
||||
fire = fire_value
|
||||
acid = acid_value
|
||||
magic = magic_value
|
||||
tag = ARMORID
|
||||
|
||||
/datum/armor/proc/modifyRating(melee_value = 0, bullet_value = 0, laser_value = 0, energy_value = 0, bomb_value = 0, bio_value = 0, rad_value = 0, fire_value = 0, acid_value = 0, magic_value = 0)
|
||||
return getArmor(melee + melee_value, bullet + bullet_value, laser + laser_value, energy + energy_value, bomb + bomb_value, bio + bio_value, rad + rad_value, fire + fire_value, acid + acid_value, magic + magic_value)
|
||||
|
||||
/datum/armor/proc/modifyAllRatings(modifier = 0)
|
||||
return getArmor(melee + modifier, bullet + modifier, laser + modifier, energy + modifier, bomb + modifier, bio + modifier, rad + modifier, fire + modifier, acid + modifier, magic + modifier)
|
||||
|
||||
/datum/armor/proc/setRating(melee_value, bullet_value, laser_value, energy_value, bomb_value, bio_value, rad_value, fire_value, acid_value, magic_value)
|
||||
return getArmor((isnull(melee_value) ? melee : melee_value),\
|
||||
(isnull(bullet_value) ? bullet : bullet_value),\
|
||||
(isnull(laser_value) ? laser : laser_value),\
|
||||
(isnull(energy_value) ? energy : energy_value),\
|
||||
(isnull(bomb_value) ? bomb : bomb_value),\
|
||||
(isnull(bio_value) ? bio : bio_value),\
|
||||
(isnull(rad_value) ? rad : rad_value),\
|
||||
(isnull(fire_value) ? fire : fire_value),\
|
||||
(isnull(acid_value) ? acid : acid_value),\
|
||||
(isnull(magic_value) ? magic : magic_value))
|
||||
|
||||
/datum/armor/proc/getRating(rating)
|
||||
return vars[rating]
|
||||
|
||||
/datum/armor/proc/getList()
|
||||
return list("melee" = melee, "bullet" = bullet, "laser" = laser, "energy" = energy, "bomb" = bomb, "bio" = bio, "rad" = rad, "fire" = fire, "acid" = acid, "magic" = magic)
|
||||
|
||||
/datum/armor/proc/attachArmor(datum/armor/AA)
|
||||
return getArmor(melee + AA.melee, bullet + AA.bullet, laser + AA.laser, energy + AA.energy, bomb + AA.bomb, bio + AA.bio, rad + AA.rad, fire + AA.fire, acid + AA.acid, magic + AA.magic)
|
||||
|
||||
/datum/armor/proc/detachArmor(datum/armor/AA)
|
||||
return getArmor(melee - AA.melee, bullet - AA.bullet, laser - AA.laser, energy - AA.energy, bomb - AA.bomb, bio - AA.bio, rad - AA.rad, fire - AA.fire, acid - AA.acid, magic - AA.magic)
|
||||
|
||||
/datum/armor/vv_edit_var(var_name, var_value)
|
||||
if (var_name == NAMEOF(src, tag))
|
||||
return FALSE
|
||||
. = ..()
|
||||
tag = ARMORID // update tag in case armor values were edited
|
||||
|
||||
#undef ARMORID
|
||||
+3
-4
@@ -99,11 +99,11 @@
|
||||
//Position the effect so the beam is one continous line
|
||||
var/a
|
||||
if(abs(Pixel_x)>32)
|
||||
a = Pixel_x > 0 ? round(Pixel_x/32) : Ceiling(Pixel_x/32)
|
||||
a = Pixel_x > 0 ? round(Pixel_x/32) : CEILING(Pixel_x/32, 1)
|
||||
X.x += a
|
||||
Pixel_x %= 32
|
||||
if(abs(Pixel_y)>32)
|
||||
a = Pixel_y > 0 ? round(Pixel_y/32) : Ceiling(Pixel_y/32)
|
||||
a = Pixel_y > 0 ? round(Pixel_y/32) : CEILING(Pixel_y/32, 1)
|
||||
X.y += a
|
||||
Pixel_y %= 32
|
||||
|
||||
@@ -131,6 +131,5 @@
|
||||
|
||||
/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=3)
|
||||
var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type,beam_sleep_time)
|
||||
spawn(0)
|
||||
newbeam.Start()
|
||||
INVOKE_ASYNC(newbeam, /datum/beam.proc/Start)
|
||||
return newbeam
|
||||
|
||||
Vendored
+26
-36
@@ -4,7 +4,7 @@ GLOBAL_DATUM_INIT(crew_repository, /datum/repository/crew, new())
|
||||
cache_data = list()
|
||||
..()
|
||||
|
||||
/datum/repository/crew/proc/health_data(var/turf/T)
|
||||
/datum/repository/crew/proc/health_data(turf/T)
|
||||
var/list/crewmembers = list()
|
||||
if(!T)
|
||||
return crewmembers
|
||||
@@ -18,50 +18,40 @@ GLOBAL_DATUM_INIT(crew_repository, /datum/repository/crew, new())
|
||||
if(world.time < cache_entry.timestamp)
|
||||
return cache_entry.data
|
||||
|
||||
var/tracked = scan()
|
||||
for(var/obj/item/clothing/under/C in tracked)
|
||||
for(var/thing in GLOB.human_list)
|
||||
var/mob/living/carbon/human/H = thing
|
||||
var/obj/item/clothing/under/C = H.w_uniform
|
||||
if(!C || C.sensor_mode == SUIT_SENSOR_OFF || !C.has_sensor)
|
||||
continue
|
||||
var/turf/pos = get_turf(C)
|
||||
if((C) && (C.has_sensor) && (pos) && (T && pos.z == T.z) && (C.sensor_mode != SUIT_SENSOR_OFF))
|
||||
if(istype(C.loc, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = C.loc
|
||||
if(H.w_uniform != C)
|
||||
continue
|
||||
if(!T || pos.z != T.z)
|
||||
continue
|
||||
var/list/crewmemberData = list("dead"=0, "oxy"=-1, "tox"=-1, "fire"=-1, "brute"=-1, "area"="", "x"=-1, "y"=-1, "ref" = "\ref[H]")
|
||||
|
||||
var/list/crewmemberData = list("dead"=0, "oxy"=-1, "tox"=-1, "fire"=-1, "brute"=-1, "area"="", "x"=-1, "y"=-1, "ref" = "\ref[H]")
|
||||
crewmemberData["sensor_type"] = C.sensor_mode
|
||||
crewmemberData["name"] = H.get_authentification_name(if_no_id="Unknown")
|
||||
crewmemberData["rank"] = H.get_authentification_rank(if_no_id="Unknown", if_no_job="No Job")
|
||||
crewmemberData["assignment"] = H.get_assignment(if_no_id="Unknown", if_no_job="No Job")
|
||||
|
||||
crewmemberData["sensor_type"] = C.sensor_mode
|
||||
crewmemberData["name"] = H.get_authentification_name(if_no_id="Unknown")
|
||||
crewmemberData["rank"] = H.get_authentification_rank(if_no_id="Unknown", if_no_job="No Job")
|
||||
crewmemberData["assignment"] = H.get_assignment(if_no_id="Unknown", if_no_job="No Job")
|
||||
if(C.sensor_mode >= SUIT_SENSOR_BINARY)
|
||||
crewmemberData["dead"] = H.stat > UNCONSCIOUS
|
||||
|
||||
if(C.sensor_mode >= SUIT_SENSOR_BINARY)
|
||||
crewmemberData["dead"] = H.stat > UNCONSCIOUS
|
||||
if(C.sensor_mode >= SUIT_SENSOR_VITAL)
|
||||
crewmemberData["oxy"] = round(H.getOxyLoss(), 1)
|
||||
crewmemberData["tox"] = round(H.getToxLoss(), 1)
|
||||
crewmemberData["fire"] = round(H.getFireLoss(), 1)
|
||||
crewmemberData["brute"] = round(H.getBruteLoss(), 1)
|
||||
|
||||
if(C.sensor_mode >= SUIT_SENSOR_VITAL)
|
||||
crewmemberData["oxy"] = round(H.getOxyLoss(), 1)
|
||||
crewmemberData["tox"] = round(H.getToxLoss(), 1)
|
||||
crewmemberData["fire"] = round(H.getFireLoss(), 1)
|
||||
crewmemberData["brute"] = round(H.getBruteLoss(), 1)
|
||||
if(C.sensor_mode >= SUIT_SENSOR_TRACKING)
|
||||
var/area/A = get_area(H)
|
||||
crewmemberData["area"] = sanitize(A.name)
|
||||
crewmemberData["x"] = pos.x
|
||||
crewmemberData["y"] = pos.y
|
||||
|
||||
if(C.sensor_mode >= SUIT_SENSOR_TRACKING)
|
||||
var/area/A = get_area(H)
|
||||
crewmemberData["area"] = sanitize(A.name)
|
||||
crewmemberData["x"] = pos.x
|
||||
crewmemberData["y"] = pos.y
|
||||
|
||||
crewmembers[++crewmembers.len] = crewmemberData
|
||||
crewmembers[++crewmembers.len] = crewmemberData
|
||||
|
||||
crewmembers = sortByKey(crewmembers, "name")
|
||||
cache_entry.timestamp = world.time + 5 SECONDS
|
||||
cache_entry.data = crewmembers
|
||||
|
||||
return crewmembers
|
||||
|
||||
/datum/repository/crew/proc/scan()
|
||||
var/list/tracked = list()
|
||||
for(var/mob/living/carbon/human/H in GLOB.mob_list)
|
||||
if(istype(H.w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/C = H.w_uniform
|
||||
if(C.has_sensor)
|
||||
tracked |= C
|
||||
return tracked
|
||||
|
||||
@@ -2,134 +2,8 @@
|
||||
|
||||
## Concept
|
||||
|
||||
Loosely adapted from /vg/. This is an entity component system for adding behaviours to datums when inheritance doesn't quite cut it. By using signals and events instead of direct inheritance, you can inject behaviours without hacky overloads. It requires a different method of thinking, but is not hard to use correctly. If a behaviour can have application across more than one thing. Make it generic, make it a component. Atom/mob/obj event? Give it a signal, and forward it's arguments with a `SEND_SIGNAL` call. Now every component that want's to can also know about this happening.
|
||||
Loosely adapted from /vg/. This is an entity component system for adding behaviours to datums when inheritance doesn't quite cut it. By using signals and events instead of direct inheritance, you can inject behaviours without hacky overloads. It requires a different method of thinking, but is not hard to use correctly. If a behaviour can have application across more than one thing. Make it generic, make it a component. Atom/mob/obj event? Give it a signal, and forward it's arguments with a `SendSignal()` call. Now every component that want's to can also know about this happening.
|
||||
|
||||
### In the code
|
||||
See [this thread](https://tgstation13.org/phpBB/viewtopic.php?f=5&t=22674) for an introduction to the system as a whole.
|
||||
|
||||
#### Slippery things
|
||||
|
||||
At the time of this writing, every object that is slippery overrides atom/Crossed does some checks, then slips the mob. Instead of all those Crossed overrides they could add a slippery component to all these objects. And have the checks in one proc that is run by the Crossed event
|
||||
|
||||
#### Powercells
|
||||
|
||||
A lot of objects have powercells. The `get_cell()` proc was added to give generic access to the cell var if it had one. This is just a specific use case of `GetComponent()`
|
||||
|
||||
#### Radios
|
||||
|
||||
The radio object as it is should not exist, given that more things use the _concept_ of radios rather than the object itself. The actual function of the radio can exist in a component which all the things that use it (Request consoles, actual radios, the SM shard) can add to themselves.
|
||||
|
||||
#### Standos
|
||||
|
||||
Stands have a lot of procs which mimic mob procs. Rather than inserting hooks for all these procs in overrides, the same can be accomplished with signals
|
||||
|
||||
## API
|
||||
|
||||
### Defines
|
||||
|
||||
1. `COMPONENT_INCOMPATIBLE` Return this from `/datum/component/Initialize` or `datum/component/OnTransfer` to have the component be deleted if it's applied to an incorrect type. `parent` must not be modified if this is to be returned. This will be noted in the runtime logs
|
||||
|
||||
### Vars
|
||||
|
||||
1. `/datum/var/list/datum_components` (private)
|
||||
* Lazy associated list of type -> component/list of components.
|
||||
1. `/datum/var/list/comp_lookup` (private)
|
||||
* Lazy associated list of signal -> registree/list of registrees
|
||||
1. `/datum/var/list/signal_procs` (private)
|
||||
* Associated lazy list of signals -> `/datum/callback`s that will be run when the parent datum receives that signal
|
||||
1. `/datum/var/signal_enabled` (protected, boolean)
|
||||
* If the datum is signal enabled. If not, it will not react to signals
|
||||
* `FALSE` by default, set to `TRUE` when a signal is registered
|
||||
1. `/datum/component/var/dupe_mode` (protected, enum)
|
||||
* How duplicate component types are handled when added to the datum.
|
||||
* `COMPONENT_DUPE_HIGHLANDER` (default): Old component will be deleted, new component will first have `/datum/component/proc/InheritComponent(datum/component/old, FALSE)` on it
|
||||
* `COMPONENT_DUPE_ALLOWED`: The components will be treated as separate, `GetComponent()` will return the first added
|
||||
* `COMPONENT_DUPE_UNIQUE`: New component will be deleted, old component will first have `/datum/component/proc/InheritComponent(datum/component/new, TRUE)` on it
|
||||
* `COMPONENT_DUPE_UNIQUE_PASSARGS`: New component will never exist and instead its initialization arguments will be passed on to the old component.
|
||||
1. `/datum/component/var/dupe_type` (protected, type)
|
||||
* Definition of a duplicate component type
|
||||
* `null` means exact match on `type` (default)
|
||||
* Any other type means that and all subtypes
|
||||
1. `/datum/component/var/datum/parent` (protected, read-only)
|
||||
* The datum this component belongs to
|
||||
* Never `null` in child procs
|
||||
1. `report_signal_origin` (protected, boolean)
|
||||
* If `TRUE`, will invoke the callback when signalled with the signal type as the first argument.
|
||||
* `FALSE` by default.
|
||||
|
||||
### Procs
|
||||
|
||||
1. `/datum/proc/GetComponent(component_type(type)) -> datum/component?` (public, final)
|
||||
* Returns a reference to a component of component_type if it exists in the datum, null otherwise
|
||||
1. `/datum/proc/GetComponents(component_type(type)) -> list` (public, final)
|
||||
* Returns a list of references to all components of component_type that exist in the datum
|
||||
1. `/datum/proc/GetExactComponent(component_type(type)) -> datum/component?` (public, final)
|
||||
* Returns a reference to a component whose type MATCHES component_type if that component exists in the datum, null otherwise
|
||||
1. `GET_COMPONENT(varname, component_type)` OR `GET_COMPONENT_FROM(varname, component_type, src)`
|
||||
* Shorthand for `var/component_type/varname = src.GetComponent(component_type)`
|
||||
1. `SEND_SIGNAL(target, sigtype, ...)` (public, final)
|
||||
* Use to send signals to target datum
|
||||
* Extra arguments are to be specified in the signal definition
|
||||
* Returns a bitflag with signal specific information assembled from all activated components
|
||||
* Arguments are packaged in a list and handed off to _SendSignal()
|
||||
1. `/datum/proc/AddComponent(component_type(type), ...) -> datum/component` (public, final)
|
||||
* Creates an instance of `component_type` in the datum and passes `...` to its `Initialize()` call
|
||||
* Sends the `COMSIG_COMPONENT_ADDED` signal to the datum
|
||||
* All components a datum owns are deleted with the datum
|
||||
* Returns the component that was created. Or the old component in a dupe situation where `COMPONENT_DUPE_UNIQUE` was set
|
||||
* If this tries to add an component to an incompatible type, the component will be deleted and the result will be `null`. This is very unperformant, try not to do it
|
||||
* Properly handles duplicate situations based on the `dupe_mode` var
|
||||
1. `/datum/proc/LoadComponent(component_type(type), ...) -> datum/component` (public, final)
|
||||
* Equivalent to calling `GetComponent(component_type)` where, if the result would be `null`, returns `AddComponent(component_type, ...)` instead
|
||||
1. `/datum/proc/ComponentActivated(datum/component/C)` (abstract, async)
|
||||
* Called on a component's `parent` after a signal received causes it to activate. `src` is the parameter
|
||||
* Will only be called if a component's callback returns `TRUE`
|
||||
1. `/datum/proc/TakeComponent(datum/component/C)` (public, final)
|
||||
* Properly transfers ownership of a component from one datum to another
|
||||
* Signals `COMSIG_COMPONENT_REMOVING` on the parent
|
||||
* Called on the datum you want to own the component with another datum's component
|
||||
1. `/datum/proc/_SendSignal(signal, list/arguments)` (private, final)
|
||||
* Handles most of the actual signaling procedure
|
||||
* Will runtime if used on datums with an empty component list
|
||||
1. `/datum/proc/RegisterSignal(datum/target, signal(string/list of strings), proc_ref(type), override(boolean))` (protected, final)
|
||||
* If signal is a list it will be as if RegisterSignal was called for each of the entries with the same following arguments
|
||||
* Makes the datum listen for the specified `signal` on it's `parent` datum.
|
||||
* When that signal is received `proc_ref` will be called on the component, along with associated arguments
|
||||
* Example proc ref: `.proc/OnEvent`
|
||||
* If a previous registration is overwritten by the call, a runtime occurs. Setting `override` to TRUE prevents this
|
||||
* These callbacks run asyncronously
|
||||
* Returning `TRUE` from these callbacks will trigger a `TRUE` return from the `SendSignal()` that initiated it
|
||||
1. `/datum/component/New(datum/parent, ...)` (private, final)
|
||||
* Runs internal setup for the component
|
||||
* Extra arguments are passed to `Initialize()`
|
||||
1. `/datum/component/Initialize(...)` (abstract, no-sleep)
|
||||
* Called by `New()` with the same argments excluding `parent`
|
||||
* Component does not exist in `parent`'s `datum_components` list yet, although `parent` is set and may be used
|
||||
* Signals will not be received while this function is running
|
||||
* Component may be deleted after this function completes without being attached
|
||||
* Do not call `qdel(src)` from this function
|
||||
1. `/datum/component/Destroy(force(bool), silent(bool))` (virtual, no-sleep)
|
||||
* Sends the `COMSIG_COMPONENT_REMOVING` signal to the parent datum if the `parent` isn't being qdeleted
|
||||
* Properly removes the component from `parent` and cleans up references
|
||||
* Setting `force` makes it not check for and remove the component from the parent
|
||||
* Setting `silent` deletes the component without sending a `COMSIG_COMPONENT_REMOVING` signal
|
||||
1. `/datum/component/proc/InheritComponent(datum/component/C, i_am_original(boolean))` (abstract, no-sleep)
|
||||
* Called on a component when a component of the same type was added to the same parent
|
||||
* See `/datum/component/var/dupe_mode`
|
||||
* `C`'s type will always be the same of the called component
|
||||
1. `/datum/component/proc/AfterComponentActivated()` (abstract, async)
|
||||
* Called on a component that was activated after it's `parent`'s `ComponentActivated()` is called
|
||||
1. `/datum/component/proc/OnTransfer(datum/new_parent)` (abstract, no-sleep)
|
||||
* Called before `new_parent` is assigned to `parent` in `TakeComponent()`
|
||||
* Allows the component to react to ownership transfers
|
||||
1. `/datum/component/proc/_RemoveFromParent()` (private, final)
|
||||
* Clears `parent` and removes the component from it's component list
|
||||
1. `/datum/component/proc/_JoinParent` (private, final)
|
||||
* Tries to add the component to it's `parent`s `datum_components` list
|
||||
1. `/datum/component/proc/RegisterWithParent` (abstract, no-sleep)
|
||||
* Used to register the signals that should be on the `parent` object
|
||||
* Use this if you plan on the component transfering between parents
|
||||
1. `/datum/component/proc/UnregisterFromParent` (abstract, no-sleep)
|
||||
* Counterpart to `RegisterWithParent()`
|
||||
* Used to unregister the signals that should only be on the `parent` object
|
||||
|
||||
### See/Define signals and their arguments in __DEFINES\components.dm
|
||||
### See/Define signals and their arguments in [__DEFINES\dcs\signals.dm](../../__DEFINES/dcs/signals.dm)
|
||||
|
||||
@@ -1,21 +1,87 @@
|
||||
/**
|
||||
* # Component
|
||||
*
|
||||
* The component datum
|
||||
*
|
||||
* A component should be a single standalone unit
|
||||
* of functionality, that works by receiving signals from it's parent
|
||||
* object to provide some single functionality (i.e a slippery component)
|
||||
* that makes the object it's attached to cause people to slip over.
|
||||
* Useful when you want shared behaviour independent of type inheritance
|
||||
*/
|
||||
/datum/component
|
||||
/**
|
||||
* Defines how duplicate existing components are handled when added to a datum
|
||||
*
|
||||
* See [COMPONENT_DUPE_*][COMPONENT_DUPE_ALLOWED] definitions for available options
|
||||
*/
|
||||
var/dupe_mode = COMPONENT_DUPE_HIGHLANDER
|
||||
|
||||
/**
|
||||
* The type to check for duplication
|
||||
*
|
||||
* `null` means exact match on `type` (default)
|
||||
*
|
||||
* Any other type means that and all subtypes
|
||||
*/
|
||||
var/dupe_type
|
||||
|
||||
/// The datum this components belongs to
|
||||
var/datum/parent
|
||||
//only set to true if you are able to properly transfer this component
|
||||
//At a minimum RegisterWithParent and UnregisterFromParent should be used
|
||||
//Make sure you also implement PostTransfer for any post transfer handling
|
||||
|
||||
/**
|
||||
* Only set to true if you are able to properly transfer this component
|
||||
*
|
||||
* At a minimum [RegisterWithParent][/datum/component/proc/RegisterWithParent] and [UnregisterFromParent][/datum/component/proc/UnregisterFromParent] should be used
|
||||
*
|
||||
* Make sure you also implement [PostTransfer][/datum/component/proc/PostTransfer] for any post transfer handling
|
||||
*/
|
||||
var/can_transfer = FALSE
|
||||
|
||||
/datum/component/New(datum/P, ...)
|
||||
parent = P
|
||||
var/list/arguments = args.Copy(2)
|
||||
/**
|
||||
* Create a new component.
|
||||
*
|
||||
* Additional arguments are passed to [Initialize()][/datum/component/proc/Initialize]
|
||||
*
|
||||
* Arguments:
|
||||
* * datum/P the parent datum this component reacts to signals from
|
||||
*/
|
||||
/datum/component/New(list/raw_args)
|
||||
parent = raw_args[1]
|
||||
var/list/arguments = raw_args.Copy(2)
|
||||
if(Initialize(arglist(arguments)) == COMPONENT_INCOMPATIBLE)
|
||||
stack_trace("Incompatible [type] assigned to a [parent.type]! args: [json_encode(arguments)]")
|
||||
qdel(src, TRUE, TRUE)
|
||||
CRASH("Incompatible [type] assigned to a [P.type]! args: [json_encode(arguments)]")
|
||||
return
|
||||
|
||||
_JoinParent(P)
|
||||
_JoinParent(parent)
|
||||
|
||||
/**
|
||||
* Called during component creation with the same arguments as in new excluding parent.
|
||||
*
|
||||
* Do not call `qdel(src)` from this function, `return COMPONENT_INCOMPATIBLE` instead
|
||||
*/
|
||||
/datum/component/proc/Initialize(...)
|
||||
return
|
||||
|
||||
/**
|
||||
* Properly removes the component from `parent` and cleans up references
|
||||
*
|
||||
* Arguments:
|
||||
* * force - makes it not check for and remove the component from the parent
|
||||
* * silent - deletes the component without sending a [COMSIG_COMPONENT_REMOVING] signal
|
||||
*/
|
||||
/datum/component/Destroy(force=FALSE, silent=FALSE)
|
||||
if(!force && parent)
|
||||
_RemoveFromParent()
|
||||
if(!silent)
|
||||
SEND_SIGNAL(parent, COMSIG_COMPONENT_REMOVING, src)
|
||||
parent = null
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Internal proc to handle behaviour of components when joining a parent
|
||||
*/
|
||||
/datum/component/proc/_JoinParent()
|
||||
var/datum/P = parent
|
||||
//lazy init the parent's dc list
|
||||
@@ -51,21 +117,9 @@
|
||||
|
||||
RegisterWithParent()
|
||||
|
||||
// If you want/expect to be moving the component around between parents, use this to register on the parent for signals
|
||||
/datum/component/proc/RegisterWithParent()
|
||||
return
|
||||
|
||||
/datum/component/proc/Initialize(...)
|
||||
return
|
||||
|
||||
/datum/component/Destroy(force=FALSE, silent=FALSE)
|
||||
if(!force && parent)
|
||||
_RemoveFromParent()
|
||||
if(!silent)
|
||||
SEND_SIGNAL(parent, COMSIG_COMPONENT_REMOVING, src)
|
||||
parent = null
|
||||
return ..()
|
||||
|
||||
/**
|
||||
* Internal proc to handle behaviour when being removed from a parent
|
||||
*/
|
||||
/datum/component/proc/_RemoveFromParent()
|
||||
var/datum/P = parent
|
||||
var/list/dc = P.datum_components
|
||||
@@ -84,10 +138,41 @@
|
||||
|
||||
UnregisterFromParent()
|
||||
|
||||
/**
|
||||
* Register the component with the parent object
|
||||
*
|
||||
* Use this proc to register with your parent object
|
||||
*
|
||||
* Overridable proc that's called when added to a new parent
|
||||
*/
|
||||
/datum/component/proc/RegisterWithParent()
|
||||
return
|
||||
|
||||
/**
|
||||
* Unregister from our parent object
|
||||
*
|
||||
* Use this proc to unregister from your parent object
|
||||
*
|
||||
* Overridable proc that's called when removed from a parent
|
||||
* *
|
||||
*/
|
||||
/datum/component/proc/UnregisterFromParent()
|
||||
return
|
||||
|
||||
/datum/proc/RegisterSignal(datum/target, sig_type_or_types, proc_or_callback, override = FALSE)
|
||||
/**
|
||||
* Register to listen for a signal from the passed in target
|
||||
*
|
||||
* This sets up a listening relationship such that when the target object emits a signal
|
||||
* the source datum this proc is called upon, will recieve a callback to the given proctype
|
||||
* Return values from procs registered must be a bitfield
|
||||
*
|
||||
* Arguments:
|
||||
* * datum/target The target to listen for signals from
|
||||
* * sig_type_or_types Either a string signal name, or a list of signal names (strings)
|
||||
* * proctype The proc to call back when the signal is emitted
|
||||
* * override If a previous registration exists you must explicitly set this
|
||||
*/
|
||||
/datum/proc/RegisterSignal(datum/target, sig_type_or_types, proctype, override = FALSE)
|
||||
if(QDELETED(src) || QDELETED(target))
|
||||
return
|
||||
|
||||
@@ -100,15 +185,12 @@
|
||||
if(!lookup)
|
||||
target.comp_lookup = lookup = list()
|
||||
|
||||
if(!istype(proc_or_callback, /datum/callback)) //if it wasnt a callback before, it is now
|
||||
proc_or_callback = CALLBACK(src, proc_or_callback)
|
||||
|
||||
var/list/sig_types = islist(sig_type_or_types) ? sig_type_or_types : list(sig_type_or_types)
|
||||
for(var/sig_type in sig_types)
|
||||
if(!override && procs[target][sig_type])
|
||||
stack_trace("[sig_type] overridden. Use override = TRUE to suppress this warning")
|
||||
|
||||
procs[target][sig_type] = proc_or_callback
|
||||
procs[target][sig_type] = proctype
|
||||
|
||||
if(!lookup[sig_type]) // Nothing has registered here yet
|
||||
lookup[sig_type] = src
|
||||
@@ -122,6 +204,17 @@
|
||||
|
||||
signal_enabled = TRUE
|
||||
|
||||
/**
|
||||
* Stop listening to a given signal from target
|
||||
*
|
||||
* Breaks the relationship between target and source datum, removing the callback when the signal fires
|
||||
*
|
||||
* Doesn't care if a registration exists or not
|
||||
*
|
||||
* Arguments:
|
||||
* * datum/target Datum to stop listening to signals from
|
||||
* * sig_typeor_types Signal string key or list of signal keys to stop listening to specifically
|
||||
*/
|
||||
/datum/proc/UnregisterSignal(datum/target, sig_type_or_types)
|
||||
var/list/lookup = target.comp_lookup
|
||||
if(!signal_procs || !signal_procs[target] || !lookup)
|
||||
@@ -129,6 +222,8 @@
|
||||
if(!islist(sig_type_or_types))
|
||||
sig_type_or_types = list(sig_type_or_types)
|
||||
for(var/sig in sig_type_or_types)
|
||||
if(!signal_procs[target][sig])
|
||||
continue
|
||||
switch(length(lookup[sig]))
|
||||
if(2)
|
||||
lookup[sig] = (lookup[sig]-src)[1]
|
||||
@@ -151,41 +246,96 @@
|
||||
if(!signal_procs[target].len)
|
||||
signal_procs -= target
|
||||
|
||||
/**
|
||||
* Called on a component when a component of the same type was added to the same parent
|
||||
*
|
||||
* See [/datum/component/var/dupe_mode]
|
||||
*
|
||||
* `C`'s type will always be the same of the called component
|
||||
*/
|
||||
/datum/component/proc/InheritComponent(datum/component/C, i_am_original)
|
||||
return
|
||||
|
||||
|
||||
/**
|
||||
* Called on a component when a component of the same type was added to the same parent with [COMPONENT_DUPE_SELECTIVE]
|
||||
*
|
||||
* See [/datum/component/var/dupe_mode]
|
||||
*
|
||||
* `C`'s type will always be the same of the called component
|
||||
*
|
||||
* return TRUE if you are absorbing the component, otherwise FALSE if you are fine having it exist as a duplicate component
|
||||
*/
|
||||
/datum/component/proc/CheckDupeComponent(datum/component/C, ...)
|
||||
return
|
||||
|
||||
|
||||
/**
|
||||
* Callback Just before this component is transferred
|
||||
*
|
||||
* Use this to do any special cleanup you might need to do before being deregged from an object
|
||||
*/
|
||||
/datum/component/proc/PreTransfer()
|
||||
return
|
||||
|
||||
/**
|
||||
* Callback Just after a component is transferred
|
||||
*
|
||||
* Use this to do any special setup you need to do after being moved to a new object
|
||||
*
|
||||
* Do not call `qdel(src)` from this function, `return COMPONENT_INCOMPATIBLE` instead
|
||||
*/
|
||||
/datum/component/proc/PostTransfer()
|
||||
return COMPONENT_INCOMPATIBLE //Do not support transfer by default as you must properly support it
|
||||
|
||||
/**
|
||||
* Internal proc to create a list of our type and all parent types
|
||||
*/
|
||||
/datum/component/proc/_GetInverseTypeList(our_type = type)
|
||||
//we can do this one simple trick
|
||||
var/current_type = parent_type
|
||||
. = list(our_type, current_type)
|
||||
//and since most components are root level + 1, this won't even have to run
|
||||
while(current_type != /datum/component)
|
||||
while (current_type != /datum/component)
|
||||
current_type = type2parent(current_type)
|
||||
. += current_type
|
||||
|
||||
/**
|
||||
* Internal proc to handle most all of the signaling procedure
|
||||
*
|
||||
* Will runtime if used on datums with an empty component list
|
||||
*
|
||||
* Use the [SEND_SIGNAL] define instead
|
||||
*/
|
||||
/datum/proc/_SendSignal(sigtype, list/arguments)
|
||||
var/target = comp_lookup[sigtype]
|
||||
if(!length(target))
|
||||
var/datum/C = target
|
||||
if(!C.signal_enabled)
|
||||
return NONE
|
||||
var/datum/callback/CB = C.signal_procs[src][sigtype]
|
||||
return CB.InvokeAsync(arglist(arguments))
|
||||
var/proctype = C.signal_procs[src][sigtype]
|
||||
return NONE | CallAsync(C, proctype, arguments)
|
||||
. = NONE
|
||||
for(var/I in target)
|
||||
var/datum/C = I
|
||||
if(!C.signal_enabled)
|
||||
continue
|
||||
var/datum/callback/CB = C.signal_procs[src][sigtype]
|
||||
. |= CB.InvokeAsync(arglist(arguments))
|
||||
var/proctype = C.signal_procs[src][sigtype]
|
||||
. |= CallAsync(C, proctype, arguments)
|
||||
|
||||
/datum/proc/GetComponent(c_type)
|
||||
// The type arg is casted so initial works, you shouldn't be passing a real instance into this
|
||||
/**
|
||||
* Return any component assigned to this datum of the given type
|
||||
*
|
||||
* This will throw an error if it's possible to have more than one component of that type on the parent
|
||||
*
|
||||
* Arguments:
|
||||
* * datum/component/c_type The typepath of the component you want to get a reference to
|
||||
*/
|
||||
/datum/proc/GetComponent(datum/component/c_type)
|
||||
RETURN_TYPE(c_type)
|
||||
if(initial(c_type.dupe_mode) == COMPONENT_DUPE_ALLOWED || initial(c_type.dupe_mode) == COMPONENT_DUPE_SELECTIVE)
|
||||
stack_trace("GetComponent was called to get a component of which multiple copies could be on an object. This can easily break and should be changed. Type: \[[c_type]\]")
|
||||
var/list/dc = datum_components
|
||||
if(!dc)
|
||||
return null
|
||||
@@ -193,7 +343,19 @@
|
||||
if(length(.))
|
||||
return .[1]
|
||||
|
||||
/datum/proc/GetExactComponent(c_type)
|
||||
// The type arg is casted so initial works, you shouldn't be passing a real instance into this
|
||||
/**
|
||||
* Return any component assigned to this datum of the exact given type
|
||||
*
|
||||
* This will throw an error if it's possible to have more than one component of that type on the parent
|
||||
*
|
||||
* Arguments:
|
||||
* * datum/component/c_type The typepath of the component you want to get a reference to
|
||||
*/
|
||||
/datum/proc/GetExactComponent(datum/component/c_type)
|
||||
RETURN_TYPE(c_type)
|
||||
if(initial(c_type.dupe_mode) == COMPONENT_DUPE_ALLOWED || initial(c_type.dupe_mode) == COMPONENT_DUPE_SELECTIVE)
|
||||
stack_trace("GetComponent was called to get a component of which multiple copies could be on an object. This can easily break and should be changed. Type: \[[c_type]\]")
|
||||
var/list/dc = datum_components
|
||||
if(!dc)
|
||||
return null
|
||||
@@ -205,6 +367,12 @@
|
||||
return C
|
||||
return null
|
||||
|
||||
/**
|
||||
* Get all components of a given type that are attached to this datum
|
||||
*
|
||||
* Arguments:
|
||||
* * c_type The component type path
|
||||
*/
|
||||
/datum/proc/GetComponents(c_type)
|
||||
var/list/dc = datum_components
|
||||
if(!dc)
|
||||
@@ -213,7 +381,19 @@
|
||||
if(!length(.))
|
||||
return list(.)
|
||||
|
||||
/datum/proc/AddComponent(new_type, ...)
|
||||
/**
|
||||
* Creates an instance of `new_type` in the datum and attaches to it as parent
|
||||
*
|
||||
* Sends the [COMSIG_COMPONENT_ADDED] signal to the datum
|
||||
*
|
||||
* Returns the component that was created. Or the old component in a dupe situation where [COMPONENT_DUPE_UNIQUE] was set
|
||||
*
|
||||
* If this tries to add a component to an incompatible type, the component will be deleted and the result will be `null`. This is very unperformant, try not to do it
|
||||
*
|
||||
* Properly handles duplicate situations based on the `dupe_mode` var
|
||||
*/
|
||||
/datum/proc/_AddComponent(list/raw_args)
|
||||
var/new_type = raw_args[1]
|
||||
var/datum/component/nt = new_type
|
||||
var/dm = initial(nt.dupe_mode)
|
||||
var/dt = initial(nt.dupe_type)
|
||||
@@ -228,7 +408,7 @@
|
||||
new_comp = nt
|
||||
nt = new_comp.type
|
||||
|
||||
args[1] = src
|
||||
raw_args[1] = src
|
||||
|
||||
if(dm != COMPONENT_DUPE_ALLOWED)
|
||||
if(!dt)
|
||||
@@ -239,37 +419,62 @@
|
||||
switch(dm)
|
||||
if(COMPONENT_DUPE_UNIQUE)
|
||||
if(!new_comp)
|
||||
new_comp = new nt(arglist(args))
|
||||
new_comp = new nt(raw_args)
|
||||
if(!QDELETED(new_comp))
|
||||
old_comp.InheritComponent(new_comp, TRUE)
|
||||
QDEL_NULL(new_comp)
|
||||
if(COMPONENT_DUPE_HIGHLANDER)
|
||||
if(!new_comp)
|
||||
new_comp = new nt(arglist(args))
|
||||
new_comp = new nt(raw_args)
|
||||
if(!QDELETED(new_comp))
|
||||
new_comp.InheritComponent(old_comp, FALSE)
|
||||
QDEL_NULL(old_comp)
|
||||
if(COMPONENT_DUPE_UNIQUE_PASSARGS)
|
||||
if(!new_comp)
|
||||
var/list/arguments = args.Copy(2)
|
||||
old_comp.InheritComponent(null, TRUE, arguments)
|
||||
var/list/arguments = raw_args.Copy(2)
|
||||
arguments.Insert(1, null, TRUE)
|
||||
old_comp.InheritComponent(arglist(arguments))
|
||||
else
|
||||
old_comp.InheritComponent(new_comp, TRUE)
|
||||
if(COMPONENT_DUPE_SELECTIVE)
|
||||
var/list/arguments = raw_args.Copy()
|
||||
arguments[1] = new_comp
|
||||
var/make_new_component = TRUE
|
||||
for(var/i in GetComponents(new_type))
|
||||
var/datum/component/C = i
|
||||
if(C.CheckDupeComponent(arglist(arguments)))
|
||||
make_new_component = FALSE
|
||||
QDEL_NULL(new_comp)
|
||||
break
|
||||
if(!new_comp && make_new_component)
|
||||
new_comp = new nt(raw_args)
|
||||
else if(!new_comp)
|
||||
new_comp = new nt(arglist(args)) // There's a valid dupe mode but there's no old component, act like normal
|
||||
new_comp = new nt(raw_args) // There's a valid dupe mode but there's no old component, act like normal
|
||||
else if(!new_comp)
|
||||
new_comp = new nt(arglist(args)) // Dupes are allowed, act like normal
|
||||
new_comp = new nt(raw_args) // Dupes are allowed, act like normal
|
||||
|
||||
if(!old_comp && !QDELETED(new_comp)) // Nothing related to duplicate components happened and the new component is healthy
|
||||
SEND_SIGNAL(src, COMSIG_COMPONENT_ADDED, new_comp)
|
||||
return new_comp
|
||||
return old_comp
|
||||
|
||||
/**
|
||||
* Get existing component of type, or create it and return a reference to it
|
||||
*
|
||||
* Use this if the item needs to exist at the time of this call, but may not have been created before now
|
||||
*
|
||||
* Arguments:
|
||||
* * component_type The typepath of the component to create or return
|
||||
* * ... additional arguments to be passed when creating the component if it does not exist
|
||||
*/
|
||||
/datum/proc/LoadComponent(component_type, ...)
|
||||
. = GetComponent(component_type)
|
||||
if(!.)
|
||||
return AddComponent(arglist(args))
|
||||
return _AddComponent(args)
|
||||
|
||||
/**
|
||||
* Removes the component from parent, ends up with a null parent
|
||||
*/
|
||||
/datum/component/proc/RemoveComponent()
|
||||
if(!parent)
|
||||
return
|
||||
@@ -279,6 +484,14 @@
|
||||
parent = null
|
||||
SEND_SIGNAL(old_parent, COMSIG_COMPONENT_REMOVING, src)
|
||||
|
||||
/**
|
||||
* Transfer this component to another parent
|
||||
*
|
||||
* Component is taken from source datum
|
||||
*
|
||||
* Arguments:
|
||||
* * datum/component/target Target datum to transfer to
|
||||
*/
|
||||
/datum/proc/TakeComponent(datum/component/target)
|
||||
if(!target || target.parent == src)
|
||||
return
|
||||
@@ -295,6 +508,14 @@
|
||||
if(target == AddComponent(target))
|
||||
target._JoinParent()
|
||||
|
||||
/**
|
||||
* Transfer all components to target
|
||||
*
|
||||
* All components from source datum are taken
|
||||
*
|
||||
* Arguments:
|
||||
* * /datum/target the target to move the components to
|
||||
*/
|
||||
/datum/proc/TransferComponents(datum/target)
|
||||
var/list/dc = datum_components
|
||||
if(!dc)
|
||||
@@ -309,5 +530,8 @@
|
||||
if(C.can_transfer)
|
||||
target.TakeComponent(comps)
|
||||
|
||||
/**
|
||||
* Return the object that is the host of any UI's that this component has
|
||||
*/
|
||||
/datum/component/nano_host()
|
||||
return parent
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
var/first_dir // This only stores the dir arg from init
|
||||
|
||||
/datum/component/decal/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description, _alpha=255)
|
||||
/datum/component/decal/Initialize(_icon, _icon_state, _dir, _cleanable = CLEAN_GOD, _color, _layer = TURF_LAYER, _description, _alpha = 255)
|
||||
if(!isatom(parent) || !generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
first_dir = _dir
|
||||
|
||||
@@ -37,10 +37,10 @@
|
||||
I.anchored = initial(I.anchored)
|
||||
for(var/datum/action/item_action/remove_tape/RT in I.actions)
|
||||
RT.Remove(user)
|
||||
RT.Destroy()
|
||||
qdel(RT)
|
||||
I.overlays.Cut(tape_overlay)
|
||||
user.transfer_fingerprints_to(I)
|
||||
Destroy()
|
||||
qdel(src)
|
||||
|
||||
/datum/component/ducttape/proc/afterattack(obj/item/I, atom/target, mob/user, proximity, params)
|
||||
if(!proximity)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// This is just a bit of fun while making an example for global signal
|
||||
/datum/component/edit_complainer
|
||||
var/list/say_lines
|
||||
|
||||
/datum/component/edit_complainer/Initialize(list/text)
|
||||
if(!ismovable(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
var/static/list/default_lines = list(
|
||||
"CentComm's profligacy frays another thread.",
|
||||
"Another tug at the weave.",
|
||||
"Who knows when the stresses will finally shatter the form?",
|
||||
"Even now a light shines through the cracks.",
|
||||
"CentComm once more twists knowledge beyond its authority.",
|
||||
"There is an uncertain air in the mansus.",
|
||||
)
|
||||
say_lines = text || default_lines
|
||||
|
||||
RegisterSignal(SSdcs, COMSIG_GLOB_VAR_EDIT, .proc/var_edit_react)
|
||||
|
||||
/datum/component/edit_complainer/proc/var_edit_react(datum/source, list/arguments)
|
||||
var/atom/movable/master = parent
|
||||
master.atom_say(pick(say_lines))
|
||||
@@ -1,5 +0,0 @@
|
||||
/datum/component/jestosterone
|
||||
var/mind_type //Is the affected mob a clown / mime?
|
||||
|
||||
/datum/component/jestosterone/Initialize(mind_type_arg)
|
||||
mind_type = mind_type_arg
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user