Merge branch 'master' of https://github.com/Skyrat-SS13/Skyrat-tg into upstream-2405a

This commit is contained in:
Waterpig
2024-05-04 14:24:25 +02:00
154 changed files with 1499 additions and 952 deletions
+1 -1
View File
@@ -5,4 +5,4 @@
# (Requiring clients update to connect to the game server is not something we like to spring on them with no notice,
# especially for beta builds where the pager/updater won't let them update without additional configuration.)
514
515
+127 -123
View File
@@ -668,23 +668,6 @@
},
/turf/open/floor/iron/cafeteria,
/area/station/medical/medbay)
"cK" = (
/obj/machinery/light/directional/south,
/obj/structure/table/glass,
/obj/item/disk/surgery/debug,
/obj/item/storage/box/monkeycubes{
pixel_x = 6;
pixel_y = 1
},
/obj/item/storage/box/monkeycubes{
pixel_x = -6;
pixel_y = 2
},
/obj/effect/turf_decal/tile/blue{
dir = 8
},
/turf/open/floor/iron/white/corner,
/area/station/medical/medbay)
"cL" = (
/obj/item/surgery_tray/full/advanced,
/obj/structure/table/glass,
@@ -1751,16 +1734,19 @@
/obj/effect/mapping_helpers/airalarm/unlocked,
/turf/open/floor/plating,
/area/station/engineering/atmos)
"hv" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on{
dir = 4
},
/obj/item/storage/part_replacer/bluespace/tier4,
/turf/open/floor/iron,
/area/station/cargo/bitrunning/den)
"hD" = (
/obj/structure/closet/secure_closet/chemical/heisenberg{
locked = 0
},
/turf/open/floor/iron,
/area/station/medical/chemistry)
"ib" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/cargo/bitrunning/den)
"ii" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -1819,13 +1805,6 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/engineering/main)
"lE" = (
/obj/machinery/power/apc/auto_name/directional/north,
/obj/structure/cable,
/obj/machinery/airalarm/directional/east,
/obj/machinery/computer/quantum_console,
/turf/open/floor/iron,
/area/station/cargo/bitrunning/den)
"lH" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
dir = 6
@@ -1849,11 +1828,6 @@
/obj/machinery/chem_mass_spec,
/turf/open/floor/iron,
/area/station/medical/chemistry)
"mV" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
/turf/open/floor/iron,
/area/station/cargo/bitrunning/den)
"nn" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on{
dir = 8
@@ -1871,6 +1845,12 @@
/obj/item/storage/toolbox/syndicate,
/turf/open/floor/iron,
/area/station/commons/storage/primary)
"nI" = (
/obj/machinery/door/airlock,
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
/turf/open/floor/iron,
/area/station/cargo/bitrunning/den)
"od" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -1899,9 +1879,6 @@
/obj/machinery/door/airlock/external/glass/ruin,
/turf/open/floor/plating,
/area/station/medical/medbay)
"pK" = (
/turf/open/floor/iron,
/area/station/cargo/bitrunning/den)
"qb" = (
/obj/machinery/door/airlock,
/turf/open/floor/plating,
@@ -1932,23 +1909,34 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
"rM" = (
/obj/machinery/quantum_server,
/turf/open/floor/iron,
/area/station/cargo/bitrunning/den)
"rS" = (
"rT" = (
/turf/open/floor/circuit/green,
/area/station/cargo/bitrunning/den)
"sr" = (
/obj/machinery/door/airlock/shell,
/turf/open/floor/iron/dark,
/area/station/construction)
"sH" = (
/obj/structure/table,
/obj/item/storage/box/shipping,
/obj/item/boulder_beacon,
/turf/open/floor/iron,
/area/station/commons/storage/primary)
"tz" = (
/obj/machinery/light/directional/south,
/obj/structure/table/glass,
/obj/item/disk/surgery/debug,
/obj/item/storage/box/monkeycubes{
pixel_x = 6;
pixel_y = 1
},
/obj/item/storage/box/monkeycubes{
pixel_x = -6;
pixel_y = 2
},
/obj/effect/turf_decal/tile/blue{
dir = 8
},
/obj/item/disk/data/debug{
pixel_y = 9;
pixel_x = 7
},
/turf/open/floor/iron/white/corner,
/area/station/medical/medbay)
"tE" = (
/obj/machinery/door/airlock/research,
/turf/open/floor/iron/dark,
@@ -2006,6 +1994,11 @@
},
/turf/open/floor/iron/dark,
/area/station/science/explab)
"vb" = (
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
/turf/open/floor/iron,
/area/station/cargo/bitrunning/den)
"vm" = (
/mob/living/circuit_drone,
/turf/open/floor/iron/dark,
@@ -2079,16 +2072,16 @@
/obj/machinery/airalarm/directional/north,
/turf/open/floor/iron,
/area/station/science)
"Aj" = (
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/cargo/bitrunning/den)
"AP" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
dir = 8
},
/turf/open/floor/iron,
/area/station/science)
"Ba" = (
/obj/machinery/netpod,
/turf/open/floor/iron,
/area/station/cargo/bitrunning/den)
"BD" = (
/obj/structure/closet/secure_closet/chief_medical{
locked = 0
@@ -2109,10 +2102,6 @@
/obj/structure/closet/syndicate/resources/everything,
/turf/open/floor/iron,
/area/station/science)
"Cz" = (
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/cargo/bitrunning/den)
"CQ" = (
/obj/machinery/light/directional/south,
/obj/effect/turf_decal/stripes/line{
@@ -2230,6 +2219,13 @@
/obj/effect/turf_decal/tile/blue/half/contrasted,
/turf/open/floor/iron,
/area/station/command/bridge)
"IF" = (
/obj/machinery/power/apc/auto_name/directional/north,
/obj/structure/cable,
/obj/machinery/airalarm/directional/east,
/obj/machinery/computer/quantum_console,
/turf/open/floor/iron,
/area/station/cargo/bitrunning/den)
"IH" = (
/obj/structure/closet/secure_closet/engineering_welding{
locked = 0
@@ -2263,13 +2259,6 @@
/obj/effect/mapping_helpers/airalarm/unlocked,
/turf/open/floor/iron,
/area/station/hallway/primary/central)
"Kf" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on{
dir = 4
},
/obj/item/storage/part_replacer/bluespace/tier4,
/turf/open/floor/iron,
/area/station/cargo/bitrunning/den)
"Kx" = (
/obj/structure/table,
/obj/item/analyzer,
@@ -2277,15 +2266,6 @@
/obj/machinery/light/directional/south,
/turf/open/floor/plating,
/area/station/engineering/atmos)
"Lb" = (
/obj/structure/table/reinforced,
/obj/machinery/light/directional/south,
/obj/item/bitrunning_debug,
/turf/open/floor/iron,
/area/station/cargo/bitrunning/den)
"Le" = (
/turf/closed/wall/r_wall,
/area/station/cargo/bitrunning/den)
"Ly" = (
/obj/machinery/chem_dispenser/chem_synthesizer,
/turf/open/floor/iron/dark,
@@ -2298,6 +2278,10 @@
/obj/machinery/door/airlock/research,
/turf/open/floor/iron/dark,
/area/station/science/explab)
"LS" = (
/obj/machinery/quantum_server,
/turf/open/floor/iron,
/area/station/cargo/bitrunning/den)
"LW" = (
/obj/effect/turf_decal/stripes/line,
/turf/open/floor/iron,
@@ -2329,10 +2313,6 @@
/obj/machinery/chem_recipe_debug,
/turf/open/floor/iron,
/area/station/medical/chemistry)
"Nj" = (
/obj/machinery/byteforge,
/turf/open/floor/circuit/green,
/area/station/cargo/bitrunning/den)
"Ns" = (
/obj/machinery/door/airlock/public/glass,
/obj/structure/cable,
@@ -2404,11 +2384,9 @@
},
/turf/open/floor/engine,
/area/station/cargo/miningoffice)
"QU" = (
/obj/machinery/door/airlock,
/obj/structure/cable,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
/turf/open/floor/iron,
"QY" = (
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/station/cargo/bitrunning/den)
"Rb" = (
/obj/effect/spawner/structure/window/reinforced,
@@ -2420,6 +2398,10 @@
},
/turf/open/floor/plating,
/area/station/hallway/secondary/entry)
"Rp" = (
/obj/machinery/byteforge,
/turf/open/floor/circuit/green,
/area/station/cargo/bitrunning/den)
"RM" = (
/obj/structure/closet/secure_closet/hop{
locked = 0
@@ -2442,6 +2424,12 @@
},
/turf/open/floor/iron/white/corner,
/area/station/medical/medbay)
"SC" = (
/obj/structure/table/reinforced,
/obj/machinery/light/directional/south,
/obj/item/bitrunning_debug,
/turf/open/floor/iron,
/area/station/cargo/bitrunning/den)
"Td" = (
/obj/machinery/light/directional/east,
/obj/effect/turf_decal/stripes/line{
@@ -2456,11 +2444,18 @@
"Tt" = (
/turf/open/floor/plating,
/area/station/maintenance/aft)
"TR" = (
/obj/machinery/netpod,
/turf/open/floor/iron,
/area/station/cargo/bitrunning/den)
"TV" = (
/obj/machinery/door/airlock,
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/construction)
"Ue" = (
/turf/closed/wall/r_wall,
/area/station/cargo/bitrunning/den)
"Ut" = (
/obj/structure/closet/secure_closet/medical3{
locked = 0
@@ -2468,6 +2463,16 @@
/obj/item/healthanalyzer/advanced,
/turf/open/floor/iron,
/area/station/medical/medbay)
"Va" = (
/obj/machinery/power/smes/full,
/obj/effect/turf_decal/stripes/line{
dir = 9
},
/obj/structure/cable,
/obj/machinery/airalarm/directional/north,
/obj/effect/mapping_helpers/airalarm/unlocked,
/turf/open/floor/iron,
/area/station/engineering/gravity_generator)
"Vg" = (
/obj/machinery/light/directional/south,
/obj/structure/cable,
@@ -2512,16 +2517,6 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/station/engineering/gravity_generator)
"Wy" = (
/obj/machinery/power/smes/full,
/obj/effect/turf_decal/stripes/line{
dir = 9
},
/obj/structure/cable,
/obj/machinery/airalarm/directional/north,
/obj/effect/mapping_helpers/airalarm/unlocked,
/turf/open/floor/iron,
/area/station/engineering/gravity_generator)
"WK" = (
/obj/structure/money_bot,
/turf/open/floor/iron/dark,
@@ -2581,6 +2576,9 @@
/obj/effect/landmark/blobstart,
/turf/open/floor/iron,
/area/station/commons/storage/primary)
"Yd" = (
/turf/open/floor/iron,
/area/station/cargo/bitrunning/den)
"Ym" = (
/obj/structure/table,
/obj/item/storage/toolbox/electrical,
@@ -2623,6 +2621,12 @@
/obj/machinery/suit_storage_unit/ce,
/turf/open/floor/iron,
/area/station/engineering/atmos)
"ZK" = (
/obj/structure/table,
/obj/item/storage/box/shipping,
/obj/item/boulder_beacon,
/turf/open/floor/iron,
/area/station/commons/storage/primary)
"ZP" = (
/turf/open/floor/iron/dark,
/area/station/science/explab)
@@ -3200,12 +3204,12 @@ aa
aa
aa
aa
Le
Le
Le
Le
Le
Le
Ue
Ue
Ue
Ue
Ue
Ue
aa
aa
aa
@@ -3292,12 +3296,12 @@ aa
aa
aa
aa
Le
rS
Nj
pK
Ba
Le
Ue
rT
Rp
Yd
TR
Ue
aa
aa
aa
@@ -3384,12 +3388,12 @@ aa
aa
aa
aa
Le
rM
pK
Kf
Ba
Le
Ue
LS
Yd
hv
TR
Ue
aa
aa
aa
@@ -3476,12 +3480,12 @@ aa
aa
aa
aa
Le
lE
Cz
mV
Lb
Le
Ue
IF
Aj
vb
SC
Ue
aa
aa
aa
@@ -3568,12 +3572,12 @@ em
em
em
em
Le
Le
Le
QU
ib
Le
Ue
Ue
Ue
nI
QY
Ue
Tj
Tj
Tj
@@ -7611,7 +7615,7 @@ aa
ad
af
ak
Wy
Va
aG
aV
bg
@@ -7820,7 +7824,7 @@ dJ
dJ
dJ
dJ
sH
ZK
cS
fP
fO
@@ -8267,7 +8271,7 @@ is
cy
Ut
cm
cK
tz
by
dB
dx
@@ -218,6 +218,7 @@
/area/shuttle/arrival)
"U" = (
/obj/machinery/door/airlock/external,
/obj/structure/fans/tiny,
/turf/open/floor/iron/shuttle/arrivals,
/area/shuttle/arrival)
"V" = (
+3 -1
View File
@@ -48,9 +48,11 @@
#define AIRLOCK_ASSEMBLY_NEEDS_ELECTRONICS 1
#define AIRLOCK_ASSEMBLY_NEEDS_SCREWDRIVER 2
//blast door (de)construction states
///The blast door is missing wires, first step of construction.
#define BLASTDOOR_NEEDS_WIRES 0
///The blast door needs electronics, second step of construction.
#define BLASTDOOR_NEEDS_ELECTRONICS 1
///The blast door is fully constructed.
#define BLASTDOOR_FINISHED 2
//floodlights because apparently we use defines now
@@ -146,6 +146,8 @@
#define COMPONENT_LIVING_BLOCK_PRE_MOB_BUMP (1<<0)
///From base of mob/living/MobBump() (mob/living)
#define COMSIG_LIVING_MOB_BUMP "living_mob_bump"
///From base of mob/living/MobBump() (mob/living)
#define COMSIG_LIVING_MOB_BUMPED "living_mob_bumped"
///From base of mob/living/Bump() (turf/closed)
#define COMSIG_LIVING_WALL_BUMP "living_wall_bump"
///From base of turf/closed/Exited() (turf/closed)
@@ -448,7 +448,10 @@
/// Prevents click from happening.
#define COMPONENT_CANCEL_EQUIPMENT_CLICK (1<<0)
///from base of /obj/item/attack(): (mob/living, mob/living, params)
#define COMSIG_ITEM_ATTACK "item_attack"
///from base of /obj/item/attack(): (mob/living, mob/living, params)
#define COMSIG_ITEM_POST_ATTACK "item_post_attack" // called only if the attack was executed
///from base of obj/item/attack_self(): (/mob)
#define COMSIG_ITEM_ATTACK_SELF "item_attack_self"
//from base of obj/item/attack_self_secondary(): (/mob)
@@ -19,8 +19,8 @@
///from base of [/datum/reagent/proc/expose_atom]: (/turf, reac_volume)
#define COMSIG_REAGENT_EXPOSE_TURF "reagent_expose_turf"
///from base of [/datum/system/materials/proc/InitializeMaterial]: (/datum/material)
#define COMSIG_MATERIALS_INIT_MAT "DSmaterials_init_mat"
///from base of [/datum/materials_controller/proc/InitializeMaterial]: (/datum/material)
#define COMSIG_MATERIALS_INIT_MAT "SSmaterials_init_mat"
///from base of [/datum/component/multiple_lives/proc/respawn]: (mob/respawned_mob, gibbed, lives_left)
#define COMSIG_ON_MULTIPLE_LIVES_RESPAWN "on_multiple_lives_respawn"
+3
View File
@@ -353,3 +353,6 @@
#define VOTE_WINNER_METHOD_WEIGHTED_RANDOM "Weighted Random"
/// There is no winner for this vote.
#define VOTE_WINNER_METHOD_NONE "None"
/// Returned by [/datum/vote/proc/can_be_initiated] to denote the vote is valid and can be initiated.
#define VOTE_AVAILABLE "Vote Available"
+1
View File
@@ -952,6 +952,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define STATION_TRAIT_BIGGER_PODS "station_trait_bigger_pods"
#define STATION_TRAIT_BIRTHDAY "station_trait_birthday"
#define STATION_TRAIT_BOTS_GLITCHED "station_trait_bot_glitch"
#define STATION_TRAIT_BRIGHT_DAY "station_trait_bright_day"
#define STATION_TRAIT_CARP_INFESTATION "station_trait_carp_infestation"
#define STATION_TRAIT_CYBERNETIC_REVOLUTION "station_trait_cybernetic_revolution"
#define STATION_TRAIT_EMPTY_MAINT "station_trait_empty_maint"
+12 -6
View File
@@ -417,7 +417,7 @@
**/
/proc/list_clear_nulls(list/list_to_clear)
return (list_to_clear.RemoveAll(null) > 0)
/**
* Removes any empty weakrefs from the list
@@ -473,17 +473,23 @@
* You should only pass integers in.
*/
/proc/pick_weight(list/list_to_pick)
if(length(list_to_pick) == 0)
return null
var/total = 0
var/item
for(item in list_to_pick)
for(var/item in list_to_pick)
if(!list_to_pick[item])
list_to_pick[item] = 0
total += list_to_pick[item]
total = rand(1, total)
for(item in list_to_pick)
total -= list_to_pick[item]
if(total <= 0 && list_to_pick[item])
for(var/item in list_to_pick)
var/item_weight = list_to_pick[item]
if(item_weight == 0)
continue
total -= item_weight
if(total <= 0)
return item
return null
+1 -1
View File
@@ -2,7 +2,7 @@
#define OPTIMAL_COST(cost)(max(1, round(cost)))
/// Wrapper for fetching material references. Exists exclusively so that people don't need to wrap everything in a list every time.
#define GET_MATERIAL_REF(arguments...) DSmaterials._GetMaterialRef(list(##arguments))
#define GET_MATERIAL_REF(arguments...) SSmaterials._GetMaterialRef(list(##arguments))
// Wrapper to convert material name into its source name
#define MATERIAL_SOURCE(mat) "[mat.name]_material"
+2 -2
View File
@@ -172,8 +172,8 @@
GLOB.crafting_recipes += recipe
var/list/material_stack_recipes = list(
DSmaterials.base_stack_recipes,
DSmaterials.rigid_stack_recipes,
SSmaterials.base_stack_recipes,
SSmaterials.rigid_stack_recipes,
)
for(var/list/recipe_list in material_stack_recipes)
+2 -2
View File
@@ -288,7 +288,7 @@ GLOBAL_LIST_EMPTY(species_list)
var/atom/target_loc = target?.loc
var/drifting = FALSE
if(DSmove_manager.processing_on(user, SSspacedrift))
if(GLOB.move_manager.processing_on(user, SSspacedrift))
drifting = TRUE
var/holding = user.get_active_held_item()
@@ -317,7 +317,7 @@ GLOBAL_LIST_EMPTY(species_list)
if(!QDELETED(progbar))
progbar.update(world.time - starttime)
if(drifting && !DSmove_manager.processing_on(user, SSspacedrift))
if(drifting && !GLOB.move_manager.processing_on(user, SSspacedrift))
drifting = FALSE
user_loc = user.loc
+1 -1
View File
@@ -107,7 +107,7 @@
message.title = title
message.content = text
DScommunications.send_message(message)
GLOB.communications_controller.send_message(message)
/**
* Sends a minor annoucement to players.
+1
View File
@@ -80,6 +80,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"STATION_TRAIT_BIGGER_PODS" = STATION_TRAIT_BIGGER_PODS,
"STATION_TRAIT_BIRTHDAY" = STATION_TRAIT_BIRTHDAY,
"STATION_TRAIT_BOTS_GLITCHED" = STATION_TRAIT_BOTS_GLITCHED,
"STATION_TRAIT_BRIGHT_DAY" = STATION_TRAIT_BRIGHT_DAY,
"STATION_TRAIT_CARP_INFESTATION" = STATION_TRAIT_CARP_INFESTATION,
"STATION_TRAIT_CYBERNETIC_REVOLUTION" = STATION_TRAIT_CYBERNETIC_REVOLUTION,
"STATION_TRAIT_EMPTY_MAINT" = STATION_TRAIT_EMPTY_MAINT,
+2
View File
@@ -236,6 +236,8 @@
user.do_attack_animation(target_mob)
target_mob.attacked_by(src, user)
SEND_SIGNAL(src, COMSIG_ITEM_POST_ATTACK, target_mob, user, params)
log_combat(user, target_mob, "attacked", src.name, "(COMBAT MODE: [uppertext(user.combat_mode)]) (DAMTYPE: [uppertext(damtype)])")
add_fingerprint(user)
@@ -347,6 +347,16 @@
min_val = 0
integer = FALSE
/datum/config_entry/number/events_frequency_lower
default = 2.5 MINUTES
min_val = 0
protection = CONFIG_ENTRY_LOCKED
/datum/config_entry/number/events_frequency_upper
default = 7 MINUTES
min_val = 0
protection = CONFIG_ENTRY_LOCKED
/datum/config_entry/number/mice_roundstart
default = 10
min_val = 0
@@ -188,13 +188,13 @@
/// minimum time between voting sessions (deciseconds, 10 minute default)
/datum/config_entry/number/vote_delay
default = 6000
default = 10 MINUTES
integer = FALSE
min_val = 0
/// length of voting period (deciseconds, default 1 minute)
/datum/config_entry/number/vote_period
default = 600
default = 1 MINUTES
integer = FALSE
min_val = 0
@@ -317,7 +317,7 @@ SUBSYSTEM_DEF(dynamic)
SSticker.news_report = SSshuttle.emergency?.is_hijacked() ? SHUTTLE_HIJACK : STATION_EVACUATED
/datum/controller/subsystem/dynamic/proc/send_intercept()
if(DScommunications.block_command_report) //If we don't want the report to be printed just yet, we put it off until it's ready
if(GLOB.communications_controller.block_command_report) //If we don't want the report to be printed just yet, we put it off until it's ready
addtimer(CALLBACK(src, PROC_REF(send_intercept)), 10 SECONDS)
return
@@ -349,10 +349,10 @@ SUBSYSTEM_DEF(dynamic)
if(trait_list_strings.len > 0)
. += "<hr><b>Identified shift divergencies:</b><BR>" + trait_list_strings.Join()
if(length(DScommunications.command_report_footnotes))
if(length(GLOB.communications_controller.command_report_footnotes))
var/footnote_pile = ""
for(var/datum/command_footnote/footnote in DScommunications.command_report_footnotes)
for(var/datum/command_footnote/footnote in GLOB.communications_controller.command_report_footnotes)
footnote_pile += "[footnote.message]<BR>"
footnote_pile += "<i>[footnote.signature]</i><BR>"
footnote_pile += "<BR>"
+8 -3
View File
@@ -25,6 +25,10 @@ SUBSYSTEM_DEF(events)
if(!event.typepath || !event.valid_for_map())
continue //don't want this one! leave it for the garbage collector
control += event //add it to the list of all events (controls)
frequency_lower = CONFIG_GET(number/events_frequency_lower)
frequency_upper = CONFIG_GET(number/events_frequency_upper)
reschedule()
// Instantiate our holidays list if it hasn't been already
if(isnull(GLOB.holidays))
@@ -91,7 +95,8 @@ SUBSYSTEM_DEF(events)
event_roster[event_to_check] = event_to_check.weight
var/datum/round_event_control/event_to_run = pick_weight(event_roster)
TriggerEvent(event_to_run)
if(event_to_run)
TriggerEvent(event_to_run)
///Does the last pre-flight checks for the passed event, and runs it if the event is ready.
/datum/controller/subsystem/events/proc/TriggerEvent(datum/round_event_control/event_to_trigger)
@@ -109,8 +114,8 @@ SUBSYSTEM_DEF(events)
///Sets the event frequency bounds back to their initial value.
/datum/controller/subsystem/events/proc/resetFrequency()
frequency_lower = initial(frequency_lower)
frequency_upper = initial(frequency_upper)
frequency_lower = CONFIG_GET(number/events_frequency_lower)
frequency_upper = CONFIG_GET(number/events_frequency_upper)
/**
* HOLIDAYS
@@ -1,12 +1,12 @@
/*! How material datums work
Materials are now instanced datums, with an associative list of them being kept in DSmaterials. We only instance the materials once and then re-use these instances for everything.
Materials are now instanced datums, with an associative list of them being kept in SSmaterials. We only instance the materials once and then re-use these instances for everything.
These materials call on_applied() on whatever item they are applied to, common effects are adding components, changing color and changing description. This allows us to differentiate items based on the material they are made out of.area
*/
DATASYSTEM_DEF(materials)
SUBSYSTEM_DEF(materials)
name = "Materials"
flags = SS_NO_FIRE | SS_NO_INIT
///Dictionary of material.id || material ref
var/list/materials
///Dictionary of type || list of material refs
@@ -36,7 +36,7 @@ DATASYSTEM_DEF(materials)
var/list/datum/dimension_theme/dimensional_themes
///Ran on initialize, populated the materials and materials_by_category dictionaries with their appropiate vars (See these variables for more info)
/datum/system/materials/proc/InitializeMaterials()
/datum/controller/subsystem/materials/proc/InitializeMaterials()
materials = list()
materials_by_type = list()
materialids_by_type = list()
@@ -57,7 +57,7 @@ DATASYSTEM_DEF(materials)
* - [arguments][/list]: The arguments to use to create the material datum
* - The first element is the type of material to initialize.
*/
/datum/system/materials/proc/InitializeMaterial(list/arguments)
/datum/controller/subsystem/materials/proc/InitializeMaterial(list/arguments)
var/datum/material/mat_type = arguments[1]
if(initial(mat_type.init_flags) & MATERIAL_INIT_BESPOKE)
arguments[1] = GetIdFromArguments(arguments)
@@ -89,13 +89,13 @@ DATASYSTEM_DEF(materials)
* - If the material type is bespoke a text ID is generated from the arguments list and used to load a material datum from the cache.
* - The following elements are used to generate bespoke IDs
*/
/datum/system/materials/proc/_GetMaterialRef(list/arguments)
/datum/controller/subsystem/materials/proc/_GetMaterialRef(list/arguments)
if(!materials)
InitializeMaterials()
var/datum/material/key = arguments[1]
if(istype(key))
return key // We are assuming here that the only thing allowed to create material datums is [/datum/system/materials/proc/InitializeMaterial]
return key // We are assuming here that the only thing allowed to create material datums is [/datum/controller/subsystem/materials/proc/InitializeMaterial]
if(istext(key)) // Handle text id
. = materials[key]
@@ -123,7 +123,7 @@ DATASYSTEM_DEF(materials)
* 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/system/materials/proc/GetIdFromArguments(list/arguments)
/datum/controller/subsystem/materials/proc/GetIdFromArguments(list/arguments)
var/datum/material/mattype = arguments[1]
var/list/fullid = list("[initial(mattype.id) || mattype]")
var/list/named_arguments = list()
@@ -149,7 +149,7 @@ DATASYSTEM_DEF(materials)
/// Returns a list to be used as an object's custom_materials. Lists will be cached and re-used based on the parameters.
/datum/system/materials/proc/FindOrCreateMaterialCombo(list/materials_declaration, multiplier)
/datum/controller/subsystem/materials/proc/FindOrCreateMaterialCombo(list/materials_declaration, multiplier)
if(!LAZYLEN(materials_declaration))
return null // If we get a null we pass it right back, we don't want to generate stack traces just because something is clearing out its materials list.
@@ -10,7 +10,7 @@ MOVEMENT_SUBSYSTEM_DEF(cliff_falling)
/datum/controller/subsystem/movement/cliff_falling/proc/start_falling(atom/movable/faller, turf/open/cliff/cliff)
// Make them move
var/mover = DSmove_manager.move(moving = faller, direction = cliff.fall_direction, delay = cliff.fall_speed, subsystem = src, priority = MOVEMENT_ABOVE_SPACE_PRIORITY, flags = MOVEMENT_LOOP_OUTSIDE_CONTROL | MOVEMENT_LOOP_NO_DIR_UPDATE)
var/mover = GLOB.move_manager.move(moving = faller, direction = cliff.fall_direction, delay = cliff.fall_speed, subsystem = src, priority = MOVEMENT_ABOVE_SPACE_PRIORITY, flags = MOVEMENT_LOOP_OUTSIDE_CONTROL | MOVEMENT_LOOP_NO_DIR_UPDATE)
cliff_grinders[faller] = mover
@@ -162,7 +162,7 @@
status &= ~MOVELOOP_STATUS_PAUSED
///Removes the atom from some movement subsystem. Defaults to SSmovement
/datum/system/move_manager/proc/stop_looping(atom/movable/moving, datum/controller/subsystem/movement/subsystem = SSmovement)
/datum/move_manager/proc/stop_looping(atom/movable/moving, datum/controller/subsystem/movement/subsystem = SSmovement)
var/datum/movement_packet/our_info = moving.move_packet
if(!our_info)
return FALSE
@@ -183,7 +183,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
/datum/system/move_manager/proc/move(moving, direction, delay, timeout, subsystem, priority, flags, datum/extra_info)
/datum/move_manager/proc/move(moving, direction, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/move, priority, flags, extra_info, delay, timeout, direction)
///Replacement for walk()
@@ -224,7 +224,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
/datum/system/move_manager/proc/force_move_dir(moving, direction, delay, timeout, subsystem, priority, flags, datum/extra_info)
/datum/move_manager/proc/force_move_dir(moving, direction, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/move/force, priority, flags, extra_info, delay, timeout, direction)
/datum/move_loop/move/force
@@ -281,7 +281,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
/datum/system/move_manager/proc/force_move(moving, chasing, delay, timeout, subsystem, priority, flags, datum/extra_info)
/datum/move_manager/proc/force_move(moving, chasing, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/has_target/force_move, priority, flags, extra_info, delay, timeout, chasing)
///Used for force-move loops
@@ -315,7 +315,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
/datum/system/move_manager/proc/jps_move(moving,
/datum/move_manager/proc/jps_move(moving,
chasing,
delay,
timeout,
@@ -493,7 +493,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
/datum/system/move_manager/proc/move_to(moving, chasing, min_dist, delay, timeout, subsystem, priority, flags, datum/extra_info)
/datum/move_manager/proc/move_to(moving, chasing, min_dist, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/has_target/dist_bound/move_to, priority, flags, extra_info, delay, timeout, chasing, min_dist)
///Wrapper around walk_to()
@@ -527,7 +527,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
/datum/system/move_manager/proc/move_away(moving, chasing, max_dist, delay, timeout, subsystem, priority, flags, datum/extra_info)
/datum/move_manager/proc/move_away(moving, chasing, max_dist, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/has_target/dist_bound/move_away, priority, flags, extra_info, delay, timeout, chasing, max_dist)
///Wrapper around walk_away()
@@ -562,7 +562,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
/datum/system/move_manager/proc/move_towards(moving, chasing, delay, home, timeout, subsystem, priority, flags, datum/extra_info)
/datum/move_manager/proc/move_towards(moving, chasing, delay, home, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/has_target/move_towards, priority, flags, extra_info, delay, timeout, chasing, home)
/**
@@ -581,7 +581,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
/datum/system/move_manager/proc/home_onto(moving, chasing, delay, timeout, subsystem, priority, flags, datum/extra_info)
/datum/move_manager/proc/home_onto(moving, chasing, delay, timeout, subsystem, priority, flags, datum/extra_info)
return move_towards(moving, chasing, delay, TRUE, timeout, subsystem, priority, flags, extra_info)
///Used as a alternative to walk_towards
@@ -717,7 +717,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
/datum/system/move_manager/proc/move_towards_legacy(moving, chasing, delay, timeout, subsystem, priority, flags, datum/extra_info)
/datum/move_manager/proc/move_towards_legacy(moving, chasing, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/has_target/move_towards_budget, priority, flags, extra_info, delay, timeout, chasing)
///The actual implementation of walk_towards()
@@ -743,7 +743,7 @@
* priority - Defines how different move loops override each other. Lower numbers beat higher numbers, equal defaults to what currently exists. Defaults to MOVEMENT_DEFAULT_PRIORITY
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*/
/datum/system/move_manager/proc/freeze(moving, halted_turf, delay, timeout, subsystem, priority, flags, datum/extra_info)
/datum/move_manager/proc/freeze(moving, halted_turf, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/freeze, priority, flags, extra_info, delay, timeout, halted_turf)
/// As close as you can get to a "do-nothing" move loop, the pure intention of this is to absolutely resist all and any automated movement until the move loop times out.
@@ -767,7 +767,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
/datum/system/move_manager/proc/move_rand(moving, directions, delay, timeout, subsystem, priority, flags, datum/extra_info)
/datum/move_manager/proc/move_rand(moving, directions, delay, timeout, subsystem, priority, flags, datum/extra_info)
if(!directions)
directions = GLOB.alldirs
return add_to_loop(moving, subsystem, /datum/move_loop/move_rand, priority, flags, extra_info, delay, timeout, directions)
@@ -819,7 +819,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
/datum/system/move_manager/proc/move_to_rand(moving, delay, timeout, subsystem, priority, flags, datum/extra_info)
/datum/move_manager/proc/move_to_rand(moving, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/move_to_rand, priority, flags, extra_info, delay, timeout)
///Wrapper around step_rand
@@ -845,7 +845,7 @@
* flags - Set of bitflags that effect move loop behavior in some way. Check _DEFINES/movement.dm
*
**/
/datum/system/move_manager/proc/move_disposals(moving, delay, timeout, subsystem, priority, flags, datum/extra_info)
/datum/move_manager/proc/move_disposals(moving, delay, timeout, subsystem, priority, flags, datum/extra_info)
return add_to_loop(moving, subsystem, /datum/move_loop/disposal_holder, priority, flags, extra_info, delay, timeout)
/// Disposal holders need to move through a chain of pipes
-1
View File
@@ -192,7 +192,6 @@ SUBSYSTEM_DEF(statpanels)
list("World Time:", "[world.time]"),
list("Globals:", GLOB.stat_entry(), text_ref(GLOB)),
list("[config]:", config.stat_entry(), text_ref(config)),
list("Datasystem Manager:", "Edit", text_ref(SysMgr)),
list("Byond:", "(FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%)) (Internal Tick Usage: [round(MAPTICK_LAST_INTERNAL_TICK_USAGE,0.1)]%)"),
list("Master Controller:", Master.stat_entry(), text_ref(Master)),
list("Failsafe Controller:", Failsafe.stat_entry(), text_ref(Failsafe)),
+94 -25
View File
@@ -18,6 +18,8 @@ SUBSYSTEM_DEF(vote)
var/list/voted = list()
/// A list of all ckeys currently voting for the current vote.
var/list/voting = list()
/// World.time we started our last vote
var/last_vote_time = -INFINITY
/datum/controller/subsystem/vote/Initialize()
for(var/vote_type in subtypesof(/datum/vote))
@@ -30,16 +32,20 @@ SUBSYSTEM_DEF(vote)
return SS_INIT_SUCCESS
// Called by master_controller
/datum/controller/subsystem/vote/fire()
if(!current_vote)
return
current_vote.time_remaining = round((current_vote.started_time + CONFIG_GET(number/vote_period) - world.time) / 10)
if(current_vote.time_remaining < 0)
process_vote_result()
SStgui.close_uis(src)
reset()
end_vote()
/// Ends the current vote.
/datum/controller/subsystem/vote/proc/end_vote()
ASSERT(current_vote)
process_vote_result()
SStgui.close_uis(src)
reset()
/// Resets all of our vars after votes conclude / are cancelled.
/datum/controller/subsystem/vote/proc/reset()
@@ -175,24 +181,10 @@ SUBSYSTEM_DEF(vote)
* * vote_type - The type of vote to initiate. Can be a [/datum/vote] typepath, a [/datum/vote] instance, or the name of a vote datum.
* * vote_initiator_name - The ckey (if player initiated) or name that initiated a vote. Ex: "UristMcAdmin", "the server"
* * vote_initiator - If a person / mob initiated the vote, this is the mob that did it
* * forced - Whether we're forcing the vote to go through regardless of existing votes or other circumstances. Note: If the vote is admin created, forced becomes true regardless.
* * forced - Whether we're forcing the vote to go through regardless of existing votes or other circumstances.
*/
/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, vote_initiator_name, mob/vote_initiator, forced = FALSE)
// Even if it's forced we can't vote before we're set up
if(!MC_RUNNING(init_stage))
if(vote_initiator)
to_chat(vote_initiator, span_warning("You cannot start vote now, the server is not done initializing."))
return FALSE
// Check if we have unlimited voting power.
// Admin started (or forced) voted will go through even if there's an ongoing vote,
// if voting is on cooldown, or regardless if a vote is config disabled (in some cases)
var/unlimited_vote_power = forced || !!GLOB.admin_datums[vote_initiator?.ckey]
if(current_vote && !unlimited_vote_power)
if(vote_initiator)
to_chat(vote_initiator, span_warning("There is already a vote in progress! Please wait for it to finish."))
if(!can_vote_start(vote_initiator, forced))
return FALSE
// Get our actual datum
@@ -219,7 +211,7 @@ SUBSYSTEM_DEF(vote)
return FALSE
// Vote can't be initiated in our circumstances? No vote
if(!to_vote.can_be_initiated(vote_initiator, unlimited_vote_power))
if(to_vote.can_be_initiated(forced) != VOTE_AVAILABLE)
return FALSE
// Okay, we're ready to actually create a vote -
@@ -230,8 +222,12 @@ SUBSYSTEM_DEF(vote)
if(!to_vote.create_vote(vote_initiator))
return FALSE
if(!vote_initiator_name && vote_initiator)
vote_initiator_name = vote_initiator.key
// Okay, the vote's happening now, for real. Set it up.
current_vote = to_vote
last_vote_time = world.time
var/duration = CONFIG_GET(number/vote_period)
var/to_display = current_vote.initiate_vote(vote_initiator_name, duration)
@@ -255,6 +251,36 @@ SUBSYSTEM_DEF(vote)
return TRUE
/**
* Checks if we can start a vote.
*
* * vote_initiator - The mob that initiated the vote.
* * forced - Whether we're forcing the vote to go through regardless of existing votes or other circumstances.
*
* Returns TRUE if we can start a vote, FALSE if we can't.
*/
/datum/controller/subsystem/vote/proc/can_vote_start(mob/vote_initiator, forced)
// Even if it's forced we can't vote before we're set up
if(!MC_RUNNING(init_stage))
if(vote_initiator)
to_chat(vote_initiator, span_warning("You cannot start a vote now, the server is not done initializing."))
return FALSE
if(forced)
return TRUE
var/next_allowed_time = last_vote_time + CONFIG_GET(number/vote_delay)
if(next_allowed_time > world.time)
if(vote_initiator)
to_chat(vote_initiator, span_warning("A vote was initiated recently. You must wait [DisplayTimeText(next_allowed_time - world.time)] before a new vote can be started!"))
return FALSE
if(current_vote)
if(vote_initiator)
to_chat(vote_initiator, span_warning("There is already a vote in progress! Please wait for it to finish."))
return FALSE
return TRUE
/datum/controller/subsystem/vote/ui_state()
return GLOB.always_state
@@ -289,11 +315,12 @@ SUBSYSTEM_DEF(vote)
if(!istype(vote))
continue
var/can_vote = vote.can_be_initiated(is_lower_admin)
var/list/vote_data = list(
"name" = vote_name,
"canBeInitiated" = vote.can_be_initiated(forced = is_lower_admin),
"canBeInitiated" = can_vote == VOTE_AVAILABLE,
"config" = vote.is_config_enabled(),
"message" = vote.message,
"message" = can_vote == VOTE_AVAILABLE ? vote.default_message : can_vote,
)
if(vote == current_vote)
@@ -317,9 +344,15 @@ SUBSYSTEM_DEF(vote)
all_vote_data += list(vote_data)
data["possibleVotes"] = all_vote_data
data["LastVoteTime"] = last_vote_time - world.time
return data
/datum/controller/subsystem/vote/ui_static_data(mob/user)
var/list/data = list()
data["VoteCD"] = CONFIG_GET(number/vote_delay)
return data
/datum/controller/subsystem/vote/ui_act(action, params)
. = ..()
if(.)
@@ -330,19 +363,37 @@ SUBSYSTEM_DEF(vote)
switch(action)
if("cancel")
if(!voter.client?.holder)
message_admins("[key_name(voter)] tried to cancel the current vote while having no admin holder, \
this is potentially a malicious exploit and worth noting.")
return
voter.log_message("cancelled a vote.", LOG_ADMIN)
message_admins("[key_name_admin(voter)] has cancelled the current vote.")
SStgui.close_uis(src)
reset()
return TRUE
if("endNow")
if(!voter.client?.holder)
message_admins("[key_name(voter)] tried to end the current vote while having no admin holder, \
this is potentially a malicious exploit and worth noting.")
return
voter.log_message("ended the current vote early", LOG_ADMIN)
message_admins("[key_name_admin(voter)] has ended the current vote.")
end_vote()
return TRUE
if("toggleVote")
var/datum/vote/selected = possible_votes[params["voteName"]]
if(!istype(selected))
return
if(!check_rights_for(voter.client, R_ADMIN))
message_admins("[key_name(voter)] tried to toggle vote availability while having improper rights, \
this is potentially a malicious exploit and worth noting.")
return
return selected.toggle_votable(voter)
return selected.toggle_votable()
if("callVote")
var/datum/vote/selected = possible_votes[params["voteName"]]
@@ -351,7 +402,12 @@ SUBSYSTEM_DEF(vote)
// Whether the user actually can initiate this vote is checked in initiate_vote,
// meaning you can't spoof initiate a vote you're not supposed to be able to
return initiate_vote(selected, voter.key, voter)
return initiate_vote(
vote_type = selected,
vote_initiator_name = voter.key,
vote_initiator = voter,
forced = !!GLOB.admin_datums[voter.ckey],
)
if("voteSingle")
return submit_single_vote(voter, params["voteOption"])
@@ -359,6 +415,15 @@ SUBSYSTEM_DEF(vote)
if("voteMulti")
return submit_multi_vote(voter, params["voteOption"])
if("resetCooldown")
if(!voter.client.holder)
message_admins("[key_name(voter)] tried to reset the vote cooldown while having no admin holder, \
this is potentially a malicious exploit and worth noting.")
return
last_vote_time = -INFINITY
return TRUE
/datum/controller/subsystem/vote/ui_close(mob/user)
voting -= user.client?.ckey
@@ -367,6 +432,10 @@ SUBSYSTEM_DEF(vote)
set category = "OOC"
set name = "Vote"
if(!SSvote.initialized)
to_chat(usr, span_notice("<i>Voting is not set up yet!</i>"))
return
SSvote.ui_interact(usr)
/// Datum action given to mobs that allows players to vote on the current vote.
+3 -3
View File
@@ -44,7 +44,7 @@
if(charger in charging)
// Stop any existing charging, this'll clean things up properly
DSmove_manager.stop_looping(charger)
GLOB.move_manager.stop_looping(charger)
charging += charger
actively_moving = FALSE
@@ -60,7 +60,7 @@
var/time_to_hit = min(get_dist(charger, target), charge_distance) * charge_speed
var/datum/move_loop/new_loop = DSmove_manager.home_onto(charger, target, delay = charge_speed, timeout = time_to_hit, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
var/datum/move_loop/new_loop = GLOB.move_manager.home_onto(charger, target, delay = charge_speed, timeout = time_to_hit, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
if(!new_loop)
return
RegisterSignal(new_loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move), override = TRUE)
@@ -96,7 +96,7 @@
/datum/action/cooldown/mob_cooldown/charge/update_status_on_signal(mob/source, new_stat, old_stat)
. = ..()
if(new_stat == DEAD)
DSmove_manager.stop_looping(source) //This will cause the loop to qdel, triggering an end to our charging
GLOB.move_manager.stop_looping(source) //This will cause the loop to qdel, triggering an end to our charging
/datum/action/cooldown/mob_cooldown/charge/proc/do_charge_indicator(atom/charger, atom/charge_target)
var/turf/target_turf = get_turf(charge_target)
+7 -3
View File
@@ -172,9 +172,13 @@ multiple modular subtrees with behaviors
return FALSE
return TRUE
/datum/ai_controller/proc/recalculate_idle()
/datum/ai_controller/proc/recalculate_idle(datum/exited)
if(ai_status == AI_STATUS_OFF)
return
if(exited && (get_dist(pawn, (islist(exited) ? exited[1] : exited)) <= interesting_dist)) //is our target in between interesting cells?
return
if(should_idle())
set_ai_status(AI_STATUS_IDLE)
@@ -187,7 +191,7 @@ multiple modular subtrees with behaviors
/datum/ai_controller/proc/on_client_exit(datum/source, datum/exited)
SIGNAL_HANDLER
recalculate_idle()
recalculate_idle(exited)
/// Sets the AI on or off based on current conditions, call to reset after you've manually disabled it somewhere
/datum/ai_controller/proc/reset_ai_status()
@@ -279,7 +283,7 @@ multiple modular subtrees with behaviors
/datum/ai_controller/process(seconds_per_tick)
if(!able_to_run())
DSmove_manager.stop_looping(pawn) //stop moving
GLOB.move_manager.stop_looping(pawn) //stop moving
return //this should remove them from processing in the future through event-based stuff.
if(!LAZYLEN(current_behaviors) && idle_behavior)
@@ -7,6 +7,7 @@ GLOBAL_LIST_INIT(target_interested_atoms, typecacheof(list(/mob, /obj/machinery/
/datum/ai_behavior/find_potential_targets
action_cooldown = 2 SECONDS
behavior_flags = AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION
/// How far can we see stuff?
var/vision_range = 9
/// Blackboard key for aggro range, uses vision range if not specified
@@ -34,7 +35,7 @@ GLOBAL_LIST_INIT(target_interested_atoms, typecacheof(list(/mob, /obj/machinery/
// If we're using a field rn, just don't do anything yeah?
if(controller.blackboard[BB_FIND_TARGETS_FIELD(type)])
return
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/list/potential_targets = hearers(aggro_range, get_turf(controller.pawn)) - living_mob //Remove self, so we don't suicide
@@ -21,6 +21,7 @@
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
pawn.visible_message(span_notice("[pawn] calms down.")) // We can blackboard key this if anyone else actually wants to customise it
controller.clear_blackboard_key(BB_BASIC_MOB_RETALIATE_LIST)
controller.clear_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET)
controller.CancelActions() // Otherwise they will try and get one last kick in
return AI_BEHAVIOR_DELAY
@@ -11,7 +11,6 @@
var/check_faction = FALSE
/datum/ai_planning_subtree/target_retaliate/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
. = ..()
controller.queue_behavior(/datum/ai_behavior/target_from_retaliate_list, BB_BASIC_MOB_RETALIATE_LIST, target_key, targeting_strategy_key, hiding_place_key, check_faction)
/datum/ai_planning_subtree/target_retaliate/check_faction
@@ -35,7 +34,6 @@
var/vision_range = 9
/datum/ai_behavior/target_from_retaliate_list/perform(seconds_per_tick, datum/ai_controller/controller, shitlist_key, target_key, targeting_strategy_key, hiding_location_key, check_faction)
. = ..()
var/mob/living/living_mob = controller.pawn
var/datum/targeting_strategy/targeting_strategy = GET_TARGETING_STRATEGY(controller.blackboard[targeting_strategy_key])
if(!targeting_strategy)
@@ -58,7 +56,6 @@
enemies_list += potential_target
if(!length(enemies_list))
controller.clear_blackboard_key(target_key)
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_FAILED
var/atom/new_target = pick_final_target(controller, enemies_list)
@@ -75,7 +72,7 @@
/datum/ai_behavior/target_from_retaliate_list/proc/pick_final_target(datum/ai_controller/controller, list/enemies_list)
return pick(enemies_list)
/datum/ai_behavior/target_from_retaliate_list/finish_action(datum/ai_controller/controller, succeeded, check_faction)
/datum/ai_behavior/target_from_retaliate_list/finish_action(datum/ai_controller/controller, succeeded, shitlist_key, target_key, targeting_strategy_key, hiding_location_key, check_faction)
. = ..()
if (succeeded || check_faction)
return
+2 -2
View File
@@ -120,7 +120,7 @@
break
if(target)
DSmove_manager.move_away(living_pawn, target, max_dist=MONKEY_ENEMY_VISION, delay=5)
GLOB.move_manager.move_away(living_pawn, target, max_dist=MONKEY_ENEMY_VISION, delay=5)
return AI_BEHAVIOR_DELAY
return AI_BEHAVIOR_DELAY | AI_BEHAVIOR_SUCCEEDED
@@ -161,7 +161,7 @@
controller.clear_blackboard_key(target_key)
if(QDELETED(living_pawn)) // pawn can be null at this point
return
DSmove_manager.stop_looping(living_pawn)
GLOB.move_manager.stop_looping(living_pawn)
/// attack using a held weapon otherwise bite the enemy, then if we are angry there is a chance we might calm down a little
/datum/ai_behavior/monkey_attack_mob/proc/monkey_attack(datum/ai_controller/controller, mob/living/target, seconds_per_tick, disarm)
+1 -1
View File
@@ -17,7 +17,7 @@
moving_controllers -= controller
// We got deleted as we finished an action
if(!QDELETED(controller.pawn))
DSmove_manager.stop_looping(controller.pawn, SSai_movement)
GLOB.move_manager.stop_looping(controller.pawn, SSai_movement)
/datum/ai_movement/proc/increment_pathing_failures(datum/ai_controller/controller)
controller.consecutive_pathing_attempts++
@@ -9,7 +9,7 @@
var/atom/movable/moving = controller.pawn
var/min_dist = controller.blackboard[BB_CURRENT_MIN_MOVE_DISTANCE]
var/delay = controller.movement_delay
var/datum/move_loop/loop = DSmove_manager.move_to(moving, current_movement_target, min_dist, delay, flags = move_flags, subsystem = SSai_movement, extra_info = controller)
var/datum/move_loop/loop = GLOB.move_manager.move_to(moving, current_movement_target, min_dist, delay, flags = move_flags, subsystem = SSai_movement, extra_info = controller)
RegisterSignal(loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move))
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_move))
@@ -8,7 +8,7 @@
var/stopping_time = controller.blackboard[BB_STATIONARY_SECONDS]
var/delay_time = (stopping_time * 0.5) // no real reason to fire any more often than this really
// assume that the current_movement_target is our location
var/datum/move_loop/loop = DSmove_manager.freeze(moving, current_movement_target, delay = delay_time, timeout = stopping_time, subsystem = SSai_movement, extra_info = controller)
var/datum/move_loop/loop = GLOB.move_manager.freeze(moving, current_movement_target, delay = delay_time, timeout = stopping_time, subsystem = SSai_movement, extra_info = controller)
RegisterSignal(loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move))
/datum/ai_movement/complete_stop/allowed_to_move(datum/move_loop/source)
+1 -1
View File
@@ -7,7 +7,7 @@
. = ..()
var/atom/movable/moving = controller.pawn
var/delay = controller.movement_delay
var/datum/move_loop/loop = DSmove_manager.move_towards_legacy(moving, current_movement_target, delay, subsystem = SSai_movement, extra_info = controller)
var/datum/move_loop/loop = GLOB.move_manager.move_towards_legacy(moving, current_movement_target, delay, subsystem = SSai_movement, extra_info = controller)
RegisterSignal(loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move))
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_move))
+1 -1
View File
@@ -12,7 +12,7 @@
var/atom/movable/moving = controller.pawn
var/delay = controller.movement_delay
var/datum/move_loop/has_target/jps/loop = DSmove_manager.jps_move(moving,
var/datum/move_loop/has_target/jps/loop = GLOB.move_manager.jps_move(moving,
current_movement_target,
delay,
repath_delay = 0.5 SECONDS,
@@ -2,9 +2,9 @@
#define COMMUNICATION_COOLDOWN_AI (30 SECONDS)
#define COMMUNICATION_COOLDOWN_MEETING (5 MINUTES)
DATASYSTEM_DEF(communications)
name = "Communications"
GLOBAL_DATUM_INIT(communications_controller, /datum/communciations_controller, new)
/datum/communciations_controller
COOLDOWN_DECLARE(silicon_message_cooldown)
COOLDOWN_DECLARE(nonsilicon_message_cooldown)
@@ -20,7 +20,7 @@ DATASYSTEM_DEF(communications)
/// The location where the special xenomorph egg was planted
var/area/captivity_area
/datum/system/communications/proc/can_announce(mob/living/user, is_silicon)
/datum/communciations_controller/proc/can_announce(mob/living/user, is_silicon)
if(is_silicon && COOLDOWN_FINISHED(src, silicon_message_cooldown))
return TRUE
else if(!is_silicon && COOLDOWN_FINISHED(src, nonsilicon_message_cooldown))
@@ -28,7 +28,7 @@ DATASYSTEM_DEF(communications)
else
return FALSE
/datum/system/communications/proc/make_announcement(mob/living/user, is_silicon, input, syndicate, list/players)
/datum/communciations_controller/proc/make_announcement(mob/living/user, is_silicon, input, syndicate, list/players)
if(!can_announce(user, is_silicon))
return FALSE
if(is_silicon)
@@ -44,7 +44,7 @@ DATASYSTEM_DEF(communications)
user.log_talk(input, LOG_SAY, tag="priority announcement")
message_admins("[ADMIN_LOOKUPFLW(user)] has made a priority announcement.")
/datum/system/communications/proc/send_message(datum/comm_message/sending,print = TRUE,unique = FALSE)
/datum/communciations_controller/proc/send_message(datum/comm_message/sending,print = TRUE,unique = FALSE)
for(var/obj/machinery/computer/communications/C in GLOB.shuttle_caller_list)
if(!(C.machine_stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
if(unique)
+1 -1
View File
@@ -15,7 +15,7 @@
if(!start_delay)
start_delay = speed
var/atom/movable/moving_parent = parent
var/datum/move_loop/loop = DSmove_manager.move(moving_parent, direction, delay = start_delay, subsystem = SSconveyors, flags=MOVEMENT_LOOP_IGNORE_PRIORITY|MOVEMENT_LOOP_OUTSIDE_CONTROL)
var/datum/move_loop/loop = GLOB.move_manager.move(moving_parent, direction, delay = start_delay, subsystem = SSconveyors, flags=MOVEMENT_LOOP_IGNORE_PRIORITY|MOVEMENT_LOOP_OUTSIDE_CONTROL)
RegisterSignal(loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(should_move))
RegisterSignal(loop, COMSIG_QDELETING, PROC_REF(loop_ended))
+1 -1
View File
@@ -23,7 +23,7 @@
if(instant)
flags |= MOVEMENT_LOOP_START_FAST
var/atom/movable/movable_parent = parent
drifting_loop = DSmove_manager.move(moving = parent, direction = direction, delay = movable_parent.inertia_move_delay, subsystem = SSspacedrift, priority = MOVEMENT_SPACE_PRIORITY, flags = flags)
drifting_loop = GLOB.move_manager.move(moving = parent, direction = direction, delay = movable_parent.inertia_move_delay, subsystem = SSspacedrift, priority = MOVEMENT_SPACE_PRIORITY, flags = flags)
if(!drifting_loop) //Really want to qdel here but can't
return COMPONENT_INCOMPATIBLE
+1 -1
View File
@@ -9,7 +9,7 @@
var/mob/mob_parent = parent
var/dist = get_dist(mob_parent, target)
var/datum/move_loop/loop = DSmove_manager.move_towards(mob_parent, target, delay = 1, timeout = dist)
var/datum/move_loop/loop = GLOB.move_manager.move_towards(mob_parent, target, delay = 1, timeout = dist)
RegisterSignal(mob_parent, COMSIG_MOB_CLIENT_PRE_LIVING_MOVE, PROC_REF(stop_move))
RegisterSignal(mob_parent, COMSIG_ATOM_PRE_PRESSURE_PUSH, PROC_REF(stop_pressure))
if(spin)
+3 -3
View File
@@ -44,7 +44,7 @@
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equip))
RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_drop))
RegisterSignal(parent, COMSIG_ITEM_ATTACK, PROC_REF(on_attack))
RegisterSignal(parent, COMSIG_ITEM_POST_ATTACK, PROC_REF(on_successful_attack))
RegisterSignal(parent, COMSIG_TRANSFORMING_ON_TRANSFORM, PROC_REF(on_transform))
/datum/component/jousting/UnregisterFromParent()
@@ -53,7 +53,7 @@
COMSIG_ATOM_EXAMINE,
COMSIG_ITEM_EQUIPPED,
COMSIG_ITEM_DROPPED,
COMSIG_ITEM_ATTACK,
COMSIG_ITEM_POST_ATTACK,
COMSIG_TRANSFORMING_ON_TRANSFORM,
))
@@ -94,7 +94,7 @@
* We deduct the minimum tile charge from the current tile charge to get what will actually be buffed
* So your charge will only get benefits from each extra tile after the minimum (and before the maximum).
*/
/datum/component/jousting/proc/on_attack(datum/source, mob/living/target, mob/user)
/datum/component/jousting/proc/on_successful_attack(datum/source, mob/living/target, mob/user)
SIGNAL_HANDLER
if(user != current_holder || !user.buckled)
return
@@ -86,7 +86,7 @@ handles linking back and forth.
mat_container = parent.AddComponent( \
/datum/component/material_container, \
DSmaterials.materials_by_category[MAT_CATEGORY_SILO], \
SSmaterials.materials_by_category[MAT_CATEGORY_SILO], \
local_size, \
mat_container_flags, \
container_signals = mat_container_signals, \
+1 -1
View File
@@ -51,7 +51,7 @@
update_state(parent) //otherwise we'll get moved 1 tile before we can correct ourselves, which isnt super bad but just looks jank
/datum/component/shuttle_cling/proc/initialize_loop()
hyperloop = DSmove_manager.move(moving = parent, direction = direction, delay = not_clinging_move_delay, subsystem = SShyperspace_drift, priority = MOVEMENT_ABOVE_SPACE_PRIORITY, flags = MOVEMENT_LOOP_NO_DIR_UPDATE|MOVEMENT_LOOP_OUTSIDE_CONTROL)
hyperloop = GLOB.move_manager.move(moving = parent, direction = direction, delay = not_clinging_move_delay, subsystem = SShyperspace_drift, priority = MOVEMENT_ABOVE_SPACE_PRIORITY, flags = MOVEMENT_LOOP_NO_DIR_UPDATE|MOVEMENT_LOOP_OUTSIDE_CONTROL)
update_state()
/datum/component/shuttle_cling/proc/clear_loop()
+1 -1
View File
@@ -286,7 +286,7 @@
if (STAGE_ONE)
steps = 1
if (STAGE_TWO)
steps = 3//Yes this is right
steps = 2
if (STAGE_THREE)
steps = 3
if (STAGE_FOUR)
+1 -1
View File
@@ -266,7 +266,7 @@
/datum/component/uplink/ui_assets(mob/user)
return list(
get_asset_datum(/datum/asset/json/uplink)
get_asset_datum(/datum/asset/json/uplink),
)
/datum/component/uplink/ui_act(action, params, datum/tgui/ui, datum/ui_state/state)
+3
View File
@@ -38,6 +38,9 @@
/// For firing an actual backblast pellet
/datum/element/backblast/proc/pew(obj/item/gun/weapon, mob/living/user, atom/target)
if(HAS_TRAIT(user, TRAIT_PACIFISM))
return
var/turf/origin = get_turf(weapon)
var/backblast_angle = get_angle(target, origin)
explosion(weapon, devastation_range = dev_range, heavy_impact_range = heavy_range, light_impact_range = light_range, flame_range = flame_range, adminlog = FALSE, protect_epicenter = TRUE, explosion_direction = backblast_angle, explosion_arc = blast_angle)
+2 -2
View File
@@ -10,7 +10,7 @@ Simple datum which is instanced once per type and is used for every object of sa
var/name = "material"
/// A short description of the material. Not used anywhere, yet...
var/desc = "its..stuff."
/// What the material is indexed by in the DSmaterials.materials list. Defaults to the type of the material.
/// What the material is indexed by in the SSmaterials.materials list. Defaults to the type of the material.
var/id
///Base color of the material, is used for greyscale. Item isn't changed in color if this is null.
@@ -23,7 +23,7 @@ Simple datum which is instanced once per type and is used for every object of sa
///Starlight color of the material
///This is the color of light it'll emit if its turf is transparent and over space. Defaults to COLOR_STARLIGHT if not set
var/starlight_color
///Bitflags that influence how DSmaterials handles this material.
///Bitflags that influence how SSmaterials handles this material.
var/init_flags = MATERIAL_INIT_MAPLOAD
///Materials "Traits". its a map of key = category | Value = Bool. Used to define what it can be used for
var/list/categories = list()
@@ -17,14 +17,15 @@
*
* You can find the logic for this control in this file
*
* Specifics of how different loops operate can be found in the movement_types.dm file, alongside the [add to loop][/datum/system/move_manager/proc/add_to_loop] helper procs that use them
* Specifics of how different loops operate can be found in the movement_types.dm file, alongside the [add to loop][/datum/move_manager/proc/add_to_loop] helper procs that use them
*
**/
DATASYSTEM_DEF(move_manager)
name = "Movement Handler"
/datum/move_manager
GLOBAL_DATUM_INIT(move_manager, /datum/move_manager, new)
///Adds a movable thing to a movement subsystem. Returns TRUE if it all worked, FALSE if it failed somehow
/datum/system/move_manager/proc/add_to_loop(atom/movable/thing_to_add, datum/controller/subsystem/movement/subsystem = SSmovement, datum/move_loop/loop_type, priority = MOVEMENT_DEFAULT_PRIORITY, flags, datum/extra_info)
/datum/move_manager/proc/add_to_loop(atom/movable/thing_to_add, datum/controller/subsystem/movement/subsystem = SSmovement, datum/move_loop/loop_type, priority = MOVEMENT_DEFAULT_PRIORITY, flags, datum/extra_info)
var/datum/movement_packet/our_data = thing_to_add.move_packet
if(!our_data)
our_data = new(thing_to_add)
@@ -33,7 +34,7 @@ DATASYSTEM_DEF(move_manager)
return our_data.add_loop(arglist(arguments))
///Returns the subsystem's loop if we're processing on it, null otherwise
/datum/system/move_manager/proc/processing_on(atom/movable/packet_owner, datum/controller/subsystem/movement/subsystem)
/datum/move_manager/proc/processing_on(atom/movable/packet_owner, datum/controller/subsystem/movement/subsystem)
var/datum/movement_packet/packet = packet_owner.move_packet
if(!packet)
return
@@ -214,7 +214,7 @@
frozen_mobs += victim
victim.Stun(20, ignore_canstun = TRUE)
victim.add_traits(list(TRAIT_MUTE, TRAIT_EMOTEMUTE), TIMESTOP_TRAIT)
DSmove_manager.stop_looping(victim) //stops them mid pathing even if they're stunimmune //This is really dumb
GLOB.move_manager.stop_looping(victim) //stops them mid pathing even if they're stunimmune //This is really dumb
if(isanimal(victim))
var/mob/living/simple_animal/animal_victim = victim
animal_victim.toggle_ai(AI_OFF)
@@ -304,6 +304,15 @@
weight_multiplier = 3
max_occurrences_modifier = 10 //lotta cows
/datum/station_trait/bright_day
name = "Bright Day"
report_message = "The stars shine bright and the clouds are scarcer than usual. It's a bright day here on the Ice Moon's surface."
trait_type = STATION_TRAIT_POSITIVE
weight = 5
show_in_report = TRUE
trait_flags = STATION_TRAIT_PLANETARY
trait_to_give = STATION_TRAIT_BRIGHT_DAY
/datum/station_trait/shuttle_sale
name = "Shuttle Firesale"
report_message = "The Nanotrasen Emergency Dispatch team is celebrating a record number of shuttle calls in the recent quarter. Some of your emergency shuttle options have been discounted!"
+17 -1
View File
@@ -113,6 +113,10 @@
/// If TRUE, shows the contents of the storage in open_storage
var/display_contents = TRUE
/// Switch this off if you want to handle click_alt in the parent atom
var/click_alt_open = TRUE
/datum/storage/New(
atom/parent,
max_slots = src.max_slots,
@@ -198,7 +202,7 @@
RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, PROC_REF(on_attackby))
RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, PROC_REF(on_preattack))
RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, PROC_REF(mass_empty))
RegisterSignals(parent, list(COMSIG_CLICK_ALT, COMSIG_ATOM_ATTACK_GHOST, COMSIG_ATOM_ATTACK_HAND_SECONDARY), PROC_REF(open_storage_on_signal))
RegisterSignals(parent, list(COMSIG_ATOM_ATTACK_GHOST, COMSIG_ATOM_ATTACK_HAND_SECONDARY), PROC_REF(open_storage_on_signal))
RegisterSignal(parent, COMSIG_ATOM_ATTACKBY_SECONDARY, PROC_REF(open_storage_attackby_secondary))
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(close_distance))
RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(update_actions))
@@ -208,6 +212,7 @@
RegisterSignal(parent, COMSIG_OBJ_DECONSTRUCT, PROC_REF(on_deconstruct))
RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, PROC_REF(on_emp_act))
RegisterSignal(parent, COMSIG_ATOM_CONTENTS_WEIGHT_CLASS_CHANGED, PROC_REF(contents_changed_w_class))
RegisterSignal(parent, COMSIG_CLICK_ALT, PROC_REF(on_click_alt))
/**
* Sets where items are physically being stored in the case it shouldn't be on the parent.
@@ -919,6 +924,17 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches)
if(display_contents)
return COMPONENT_NO_AFTERATTACK
/// Alt click on the storage item. Default: Open the storage.
/datum/storage/proc/on_click_alt(datum/source, mob/user)
SIGNAL_HANDLER
if(!click_alt_open)
return
return open_storage_on_signal(source, user)
/// Opens the storage to the mob, showing them the contents to their UI.
/datum/storage/proc/open_storage(mob/to_show)
if(isobserver(to_show))
+1
View File
@@ -45,6 +45,7 @@
/datum/storage/pockets/small/fedora/detective
attack_hand_interact = TRUE // so the detectives would discover pockets in their hats
click_alt_open = FALSE
/datum/storage/pockets/chefhat
attack_hand_interact = TRUE
-16
View File
@@ -1,16 +0,0 @@
#define NEW_DS_GLOBAL(varname) if(varname != src){if(istype(varname)){qdel(varname);}varname = src;}
#define DATASYSTEM_DEF(X) GLOBAL_REAL(DS##X, /datum/system/##X);\
/datum/system/##X/New(){\
NEW_DS_GLOBAL(DS##X);\
}\
/datum/system/##X
/**
* Global systems which are distinct from subsystems in that they do not process by the MC.
* Data systems or "DS" are used to store round information and procs to interface with that data, if needed.
*/
/datum/system
/// Name of the system
var/name = "Datum System"
-229
View File
@@ -1,229 +0,0 @@
/// Global list of areas which are considered to be inside the same department for our purposes
GLOBAL_LIST_INIT(battle_royale_regions, list(
"Medical Bay" = list(
/area/station/command/heads_quarters/cmo,
/area/station/medical,
/area/station/security/checkpoint/medical,
),
"Research Division" = list(
/area/station/command/heads_quarters/rd,
/area/station/security/checkpoint/science,
/area/station/science,
),
"Engineering Bay" = list(
/area/station/command/heads_quarters/ce,
/area/station/engineering,
/area/station/maintenance/disposal/incinerator,
/area/station/security/checkpoint/engineering,
),
"Cargo Bay" = list(
/area/station/cargo,
/area/station/command/heads_quarters/qm,
/area/station/security/checkpoint/supply,
),
))
/// Basically just exists to hold references to datums so that they don't GC
DATASYSTEM_DEF(battle_royale)
name = "Battle Royale"
/// List of battle royale datums currently running
var/list/active_battles
/// Start a new battle royale using a passed list of implants
/datum/system/battle_royale/proc/start_battle(list/competitors)
var/datum/battle_royale_controller/controller = new()
if (!controller.start(competitors))
return FALSE
LAZYADD(active_battles, controller)
if (LAZYLEN(active_battles) == 1)
start_broadcasting_network(BATTLE_ROYALE_CAMERA_NET)
RegisterSignal(controller, COMSIG_QDELETING, PROC_REF(battle_ended))
return TRUE
/// Drop reference when it kills itself
/datum/system/battle_royale/proc/battle_ended(datum/source)
SIGNAL_HANDLER
LAZYREMOVE(active_battles, source)
if (!LAZYLEN(active_battles))
stop_broadcasting_network(BATTLE_ROYALE_CAMERA_NET)
/// Datum which controls the conflict
/datum/battle_royale_controller
/// Where is our battle taking place?
var/chosen_area
/// Is the battle currently in progress?
var/battle_running = TRUE
/// Should we let everyone know that someone has died?
var/announce_deaths = TRUE
/// List of implants involved
var/list/contestant_implants = list()
/// Ways to describe that someone has died
var/static/list/euphemisms = list(
"cashed their last paycheque.",
"didn't make it...",
"didn't make the cut.",
"had their head blown clean off!",
"has been killed!",
"has failed the challenge!",
"has passed away.",
"has died.",
"is in a better place now.",
"isn't going to be clocking in tomorrow!",
"just flatlined.",
"isn't today's winner.",
"seems to have exploded!",
"was just murdered on live tv!",
"won't be making it to retirement.",
"won't be getting back up after that one.",
)
/// Ways to tell people not to salt in deadchat, surely effective
var/static/list/condolences = list(
"Better luck next time!",
"But stay tuned, there's still everything to play for!",
"Did you catch who did it?",
"It looked like that one really hurt...",
"Let's get that one on action replay!",
"Let's have a moment of silence, please.",
"Let's hope the next one does better.",
"Someone please notify their next of kin.",
"They had a good run.",
"Too bad!",
"What a shame!",
"What an upset!",
"What's going to happen next?",
"Who could have seen that coming?",
"Who will be next?",
)
/datum/battle_royale_controller/Destroy(force)
contestant_implants = null
return ..()
/// Start a battle royale with the list of provided implants
/datum/battle_royale_controller/proc/start(list/implants, battle_time = 10 MINUTES)
chosen_area = pick(GLOB.battle_royale_regions)
for (var/obj/item/implant/explosive/battle_royale/contestant_implant in implants)
contestant_implant.start_battle(chosen_area, GLOB.battle_royale_regions[chosen_area])
if (isnull(contestant_implant))
continue // Might have exploded if it was removed from a person
RegisterSignal(contestant_implant, COMSIG_QDELETING, PROC_REF(implant_destroyed))
contestant_implants |= contestant_implant
if (length(contestant_implants) <= 1)
return FALSE // Well there's not much point is there
priority_announce(
text = "Congratulations [station_name()], you have been chosen as the next site of the Rumble Royale! \n\
Viewers across the sector will watch our [convert_integer_to_words(length(contestant_implants))] lucky contestants battle their way into your [chosen_area] and fight until only one is left standing! \n\
If they don't make it in five minutes, they'll be disqualified. If you see one of our players struggling to get in, do lend them a hand... or don't, if you can live with the consequences! \n\
As a gesture of gratitude, we will be providing our premium broadcast to your entertainment monitors at no cost so that you can watch the excitement. \n\
Bystanders are advised not to intervene... but if you do, make it look good for the camera!",
title = "Rumble Royale Beginning",
sound = 'sound/machines/alarm.ogg',
has_important_message = TRUE,
sender_override = "Rumble Royale Pirate Broadcast Station",
color_override = "red",
)
for (var/obj/item/implant/explosive/battle_royale/contestant_implant as anything in contestant_implants)
contestant_implant.announce()
addtimer(CALLBACK(src, PROC_REF(limit_area)), battle_time / 2, TIMER_DELETE_ME)
addtimer(CALLBACK(src, PROC_REF(finish)), battle_time, TIMER_DELETE_ME)
return TRUE
/// An implant was destroyed, hopefully because it exploded. Count how many competitors remain.
/datum/battle_royale_controller/proc/implant_destroyed(obj/item/implant/implant)
SIGNAL_HANDLER
contestant_implants -= implant
if (!battle_running)
return
if (length(contestant_implants) <= 1)
announce_winner(implant)
else if (announce_deaths)
var/message = ""
if (isnull(implant.imp_in))
message = "Looks like someone removed and destroyed their implant, that's cheating!"
else
message = "[implant.imp_in.real_name] [pick(euphemisms)] [pick(condolences)]"
priority_announce(
text = message,
title = "Rumble Royale Casualty Report",
sound = 'sound/misc/notice1.ogg',
has_important_message = TRUE,
sender_override = "Rumble Royale Pirate Broadcast Station",
color_override = "red",
)
/// There's only one person left, we have a winner!
/datum/battle_royale_controller/proc/announce_winner(obj/item/implant/losing_implant)
battle_running = FALSE
if (length(contestant_implants) > 1)
return
var/message = ""
var/mob/living/loser = losing_implant.imp_in
var/obj/item/implant/winning_implant = pop(contestant_implants)
var/mob/living/winner = winning_implant?.imp_in
if (isnull(winner) && isnull(loser))
message = "Somehow, it seems like there's no winner tonight. What a disappointment!"
else
var/loser_text = isnull(loser) ? "With the disqualification of the other remaining contestant" : "With the death of [loser.real_name]"
var/winner_text = isnull(winner) ? "we must sadly announce that the would-be winner has also been disqualified. Such bad showmanship!" : "only [winner.real_name] remains. Congratulations, we have a winner!"
message = "[loser_text], [winner_text]"
if (!isnull(winner))
podspawn(list(
"target" = get_turf(winner),
"style" = STYLE_SYNDICATE,
"spawn" = /obj/item/food/roast_dinner,
))
priority_announce(
text = message,
title = "Rumble Royale Winner",
sound = 'sound/misc/notice1.ogg',
has_important_message = TRUE,
sender_override = "Rumble Royale Pirate Broadcast Station",
color_override = "red",
)
qdel(winning_implant) // You get to live!
winner?.mind?.remove_antag_datum(/datum/antagonist/survivalist/battle_royale)
qdel(src)
/// Called halfway through the battle, if you've not made it to the designated battle zone we kill you
/datum/battle_royale_controller/proc/limit_area()
priority_announce(
text = "We're halfway done folks! And bad news to anyone who hasn't made it to the [chosen_area]... you're out!",
title = "Rumble Royale Update",
sound = 'sound/misc/notice1.ogg',
has_important_message = TRUE,
sender_override = "Rumble Royale Pirate Broadcast Station",
color_override = "red",
)
for (var/obj/item/implant/explosive/battle_royale/contestant_implant as anything in contestant_implants)
contestant_implant.limit_areas()
/// Well you're out of time, bad luck
/datum/battle_royale_controller/proc/finish()
battle_running = FALSE
priority_announce(
text = "Sorry remaining contestants, your time is up. \
We're sorry to announce that this edition of Royal Rumble has no winner. \n\
Better luck next time!",
title = "Rumble Royale Concluded",
sound = 'sound/misc/notice1.ogg',
has_important_message = TRUE,
sender_override = "Rumble Royale Pirate Broadcast Station",
color_override = "red",
)
for (var/obj/item/implant/explosive/battle_royale/contestant_implant as anything in contestant_implants)
contestant_implant.explode()
qdel(src)
-14
View File
@@ -1,14 +0,0 @@
// See initialization order in /code/game/world.dm
GLOBAL_REAL(SysMgr, /datum/system_manager)
/**
* Initializes all data systems and keeps track of them.
*/
/datum/system_manager
/// List of managed data systems, post initialization.
var/list/datum/system/managed = list()
/datum/system_manager/New()
init_subtypes(/datum/system, managed)
+24 -27
View File
@@ -15,19 +15,8 @@
var/list/default_choices
/// Does the name of this vote contain the word "vote"?
var/contains_vote_in_name = FALSE
/// What message do we want to pass to the player-side vote panel as a tooltip?
var/message = "Click to initiate a vote."
// Internal values used when tracking ongoing votes.
// Don't mess with these, change the above values / override procs for subtypes.
/// An assoc list of [all choices] to [number of votes in the current running vote].
var/list/choices = list()
/// A assoc list of [ckey] to [what they voted for in the current running vote].
var/list/choices_by_ckey = list()
/// The world time this vote was started.
var/started_time
/// The time remaining in this vote's run.
var/time_remaining
/// What message do we show as the tooltip of this vote if the vote can be initiated?
var/default_message = "Click to initiate a vote."
/// The counting method we use for votes.
var/count_method = VOTE_COUNT_METHOD_SINGLE
/// The method for selecting a winner.
@@ -35,6 +24,17 @@
/// Should we show details about the number of votes submitted for each option?
var/display_statistics = TRUE
// Internal values used when tracking ongoing votes.
// Don't mess with these, change the above values / override procs for subtypes.
/// An assoc list of [all choices] to [number of votes in the current running vote].
VAR_FINAL/list/choices = list()
/// A assoc list of [ckey] to [what they voted for in the current running vote].
VAR_FINAL/list/choices_by_ckey = list()
/// The world time this vote was started.
VAR_FINAL/started_time = -1
/// The time remaining in this vote's run.
VAR_FINAL/time_remaining = -1
/**
* Used to determine if this vote is a possible
* vote type for the vote subsystem.
@@ -55,14 +55,13 @@
choices.Cut()
choices_by_ckey.Cut()
started_time = null
time_remaining = null
time_remaining = -1
/**
* If this vote has a config associated, toggles it between enabled and disabled.
* Returns TRUE on a successful toggle, FALSE otherwise
*/
/datum/vote/proc/toggle_votable(mob/toggler)
return FALSE
/datum/vote/proc/toggle_votable()
return
/**
* If this vote has a config associated, returns its value (True or False, usually).
@@ -74,20 +73,18 @@
/**
* Checks if the passed mob can initiate this vote.
*
* Return TRUE if the mob can begin the vote, allowing anyone to actually vote on it.
* Return FALSE if the mob cannot initiate the vote.
* * forced - if being invoked by someone who is an admin
*
* Return VOTE_AVAILABLE if the mob can initiate the vote.
* Return a string with the reason why the mob can't initiate the vote.
*/
/datum/vote/proc/can_be_initiated(mob/by_who, forced = FALSE)
/datum/vote/proc/can_be_initiated(forced = FALSE)
SHOULD_CALL_PARENT(TRUE)
if(started_time)
var/next_allowed_time = (started_time + CONFIG_GET(number/vote_delay))
if(next_allowed_time > world.time && !forced)
message = "A vote was initiated recently. You must wait [DisplayTimeText(next_allowed_time - world.time)] before a new vote can be started!"
return FALSE
if(!forced && !is_config_enabled())
return "This vote is currently disabled by the server configuration."
message = initial(message)
return TRUE
return VOTE_AVAILABLE
/**
* Called prior to the vote being initiated.
+40 -17
View File
@@ -1,14 +1,9 @@
/// The max amount of options someone can have in a custom vote.
#define MAX_CUSTOM_VOTE_OPTIONS 10
/datum/vote/custom_vote/single
name = "Custom Standard"
message = "Click here to start a custom vote (one selection per voter)"
/datum/vote/custom_vote/multi
name = "Custom Multi"
message = "Click here to start a custom multi vote (multiple selections per voter)"
count_method = VOTE_COUNT_METHOD_MULTI
/datum/vote/custom_vote
name = "Custom"
default_message = "Click here to start a custom vote."
// Custom votes ares always accessible.
/datum/vote/custom_vote/is_accessible_vote()
@@ -17,23 +12,45 @@
/datum/vote/custom_vote/reset()
default_choices = null
override_question = null
count_method = VOTE_COUNT_METHOD_SINGLE
return ..()
/datum/vote/custom_vote/can_be_initiated(mob/by_who, forced = FALSE)
/datum/vote/custom_vote/can_be_initiated(forced)
. = ..()
if(!.)
return FALSE
if(. != VOTE_AVAILABLE)
return .
if(forced)
return .
// Custom votes can only be created if they're forced to be made.
// (Either an admin makes it, or otherwise.)
return forced
return "Only admins can create custom votes."
/datum/vote/custom_vote/create_vote(mob/vote_creator)
var/custom_count_method = tgui_input_list(
user = vote_creator,
message = "Single or multiple choice?",
title = "Choice Method",
items = list("Single", "Multiple"),
default = "Single",
)
switch(custom_count_method)
if("Single")
count_method = VOTE_COUNT_METHOD_SINGLE
if("Multiple")
count_method = VOTE_COUNT_METHOD_MULTI
if(null)
return FALSE
else
stack_trace("Got '[custom_count_method]' in create_vote() for custom voting.")
to_chat(vote_creator, span_boldwarning("Unknown choice method. Contact a coder."))
return FALSE
var/custom_win_method = tgui_input_list(
vote_creator,
"How should the vote winner be determined?",
"Winner Method",
list("Simple", "Weighted Random", "No Winner"),
user = vote_creator,
message = "How should the vote winner be determined?",
title = "Winner Method",
items = list("Simple", "Weighted Random", "No Winner"),
default = "Simple",
)
switch(custom_win_method)
@@ -43,7 +60,10 @@
winner_method = VOTE_WINNER_METHOD_WEIGHTED_RANDOM
if("No Winner")
winner_method = VOTE_WINNER_METHOD_NONE
if(null)
return FALSE
else
stack_trace("Got '[custom_win_method]' in create_vote() for custom voting.")
to_chat(vote_creator, span_boldwarning("Unknown winner method. Contact a coder."))
return FALSE
@@ -54,7 +74,7 @@
list("Yes", "No"),
)
if(display_stats == null)
if(isnull(display_stats))
return FALSE
display_statistics = display_stats == "Yes"
@@ -74,6 +94,9 @@
if(!length(default_choices))
return FALSE
// Sanity for all the tgui input stalling we are doing
if(isnull(vote_creator.client?.holder))
return FALSE
return ..()
+10 -28
View File
@@ -1,6 +1,6 @@
/datum/vote/map_vote
name = "Map"
message = "Vote for next round's map!"
default_message = "Vote for next round's map!"
count_method = VOTE_COUNT_METHOD_SINGLE
winner_method = VOTE_WINNER_METHOD_WEIGHTED_RANDOM
display_statistics = FALSE
@@ -30,44 +30,26 @@
SSmapping.map_voted = TRUE // voted by not voting, very sad.
return FALSE
/datum/vote/map_vote/toggle_votable(mob/toggler)
if(!toggler)
CRASH("[type] wasn't passed a \"toggler\" mob to toggle_votable.")
if(!check_rights_for(toggler.client, R_ADMIN))
return FALSE
/datum/vote/map_vote/toggle_votable()
CONFIG_SET(flag/allow_vote_map, !CONFIG_GET(flag/allow_vote_map))
return TRUE
/datum/vote/map_vote/is_config_enabled()
return CONFIG_GET(flag/allow_vote_map)
/datum/vote/map_vote/can_be_initiated(mob/by_who, forced = FALSE)
/datum/vote/map_vote/can_be_initiated(forced)
. = ..()
if(!.)
return FALSE
if(. != VOTE_AVAILABLE)
return .
if(forced)
return TRUE
return VOTE_AVAILABLE
var/number_of_choices = length(check_population())
if(number_of_choices < 2)
message = "There [number_of_choices == 1 ? "is only one map" : "are no maps"] to choose from."
return FALSE
return "There [number_of_choices == 1 ? "is only one map" : "are no maps"] to choose from."
if(SSmapping.map_vote_rocked)
return TRUE
if(!CONFIG_GET(flag/allow_vote_map))
message = "Map voting is disabled by server configuration settings."
return FALSE
return VOTE_AVAILABLE
if(SSmapping.map_voted)
message = "The next map has already been selected."
return FALSE
message = initial(message)
return TRUE
return "The next map has already been selected."
return VOTE_AVAILABLE
/// Before we create a vote, remove all maps from our choices that are outside of our population range.
/// Note that this can result in zero remaining choices for our vote, which is not ideal (but ultimately okay).
+12 -23
View File
@@ -7,7 +7,8 @@
CHOICE_RESTART,
CHOICE_CONTINUE,
)
message = "Vote to restart the ongoing round."
default_message = "Vote to restart the ongoing round. \
Only works if there are no non-AFK admins online."
/// This proc checks to see if any admins are online for the purposes of this vote to see if it can pass. Returns TRUE if there are valid admins online (Has +SERVER and is not AFK), FALSE otherwise.
/datum/vote/restart_vote/proc/admins_present()
@@ -19,36 +20,24 @@
return FALSE
/datum/vote/restart_vote/toggle_votable(mob/toggler)
if(!toggler)
CRASH("[type] wasn't passed a \"toggler\" mob to toggle_votable.")
if(!check_rights_for(toggler.client, R_ADMIN))
return FALSE
/datum/vote/restart_vote/toggle_votable()
CONFIG_SET(flag/allow_vote_restart, !CONFIG_GET(flag/allow_vote_restart))
return TRUE
/datum/vote/restart_vote/is_config_enabled()
return CONFIG_GET(flag/allow_vote_restart)
/datum/vote/restart_vote/can_be_initiated(mob/by_who, forced)
/datum/vote/restart_vote/create_vote(mob/vote_creator)
. = ..()
if(!.)
return FALSE
return
if(!admins_present())
return
async_alert_about_admins(vote_creator)
if(!forced && !CONFIG_GET(flag/allow_vote_restart))
message = "Restart voting is disabled by server configuration settings."
return FALSE
// We still want players to be able to vote to restart even if valid admins are online. Let's update the message just so that the player is aware of this fact.
// We don't want to lock-out the vote though, so we'll return TRUE.
if(admins_present())
message = "Regardless of the results of this vote, the round will not automatically restart because an admin is online."
return TRUE
message = initial(message)
return TRUE
/datum/vote/restart_vote/proc/async_alert_about_admins(mob/vote_creator)
set waitfor = FALSE
tgui_alert(vote_creator, "Note: Regardless of the results of this vote, \
the round will not automatically restart because an active admin is online.")
/datum/vote/restart_vote/get_vote_result(list/non_voters)
if(!CONFIG_GET(flag/default_no_vote))
+12 -30
View File
@@ -10,58 +10,40 @@
CHOICE_TO_ROCK,
CHOICE_NOT_TO_ROCK,
)
message = "Override the current map vote."
default_message = "Override the current map vote."
/// The number of times we have rocked the vote thus far.
var/rocking_votes = 0
/datum/vote/rock_the_vote/toggle_votable(mob/toggler)
if(!toggler)
CRASH("[type] wasn't passed a \"toggler\" mob to toggle_votable.")
if(!check_rights_for(toggler.client, R_ADMIN))
return FALSE
/datum/vote/rock_the_vote/toggle_votable()
CONFIG_SET(flag/allow_rock_the_vote, !CONFIG_GET(flag/allow_rock_the_vote))
return TRUE
/datum/vote/rock_the_vote/is_config_enabled()
return CONFIG_GET(flag/allow_rock_the_vote)
/datum/vote/rock_the_vote/can_be_initiated(mob/by_who, forced)
/datum/vote/rock_the_vote/can_be_initiated(forced)
. = ..()
if(!.)
return FALSE
if(!forced && !CONFIG_GET(flag/allow_rock_the_vote))
message = "Rocking the vote is disabled by this server's configuration settings."
return FALSE
if(. != VOTE_AVAILABLE)
return .
if(SSticker.current_state == GAME_STATE_FINISHED)
message = "The game is finished, no map votes can be initiated."
return FALSE
return "The game is finished, no map votes can be initiated."
if(rocking_votes >= CONFIG_GET(number/max_rocking_votes))
message = "The maximum number of times to rock the vote has been reached."
return FALSE
return "The maximum number of times to rock the vote has been reached."
if(SSmapping.map_vote_rocked)
message = "The vote has already been rocked! Initiate a map vote!"
return FALSE
return "The vote has already been rocked! Initiate a map vote!"
if(!SSmapping.map_voted)
message = "Rocking the vote is disabled because no map has been voted on yet!"
return FALSE
return "Rocking the vote is disabled because no map has been voted on yet!"
if(SSmapping.map_force_chosen)
message = "Rocking the vote is disabled because an admin has forcibly set the map!"
return FALSE
return "Rocking the vote is disabled because an admin has forcibly set the map!"
if(EMERGENCY_ESCAPED_OR_ENDGAMED && SSmapping.map_voted)
message = "The emergency shuttle has already left the station and the next map has already been chosen!"
return FALSE
return "The emergency shuttle has already left the station and the next map has already been chosen!"
message = initial(message)
return TRUE
return VOTE_AVAILABLE
/datum/vote/rock_the_vote/finalize_vote(winning_option)
rocking_votes++
+5
View File
@@ -209,6 +209,11 @@
name = "Icemoon Wastes"
outdoors = TRUE
/area/icemoon/surface/outdoors/Initialize(mapload)
if(HAS_TRAIT(SSstation, STATION_TRAIT_BRIGHT_DAY))
base_lighting_alpha = 145
return ..()
/area/icemoon/surface/outdoors/nospawn // this is the area you use for stuff to not spawn, but if you still want weather.
/area/icemoon/surface/outdoors/nospawn/New() // unless you roll forested trait lol
+1 -1
View File
@@ -23,7 +23,7 @@
var/datum/material/custom_material = GET_MATERIAL_REF(current_material)
custom_material.on_applied(src, OPTIMAL_COST(materials[current_material] * multiplier * material_modifier), material_flags)
custom_materials = DSmaterials.FindOrCreateMaterialCombo(materials, multiplier)
custom_materials = SSmaterials.FindOrCreateMaterialCombo(materials, multiplier)
/**
* Returns the material composition of the atom.
+2 -2
View File
@@ -32,7 +32,7 @@
/obj/machinery/autolathe/Initialize(mapload)
materials = AddComponent( \
/datum/component/material_container, \
DSmaterials.materials_by_category[MAT_CATEGORY_ITEM_MATERIAL], \
SSmaterials.materials_by_category[MAT_CATEGORY_ITEM_MATERIAL], \
0, \
MATCONTAINER_EXAMINE, \
container_signals = list(COMSIG_MATCONTAINER_ITEM_CONSUMED = TYPE_PROC_REF(/obj/machinery/autolathe, AfterMaterialInsert)) \
@@ -252,7 +252,7 @@
var/amount_needed = design.materials[material]
if(istext(material)) // category
var/list/choices = list()
for(var/datum/material/valid_candidate as anything in DSmaterials.materials_by_category[material])
for(var/datum/material/valid_candidate as anything in SSmaterials.materials_by_category[material])
if(materials.get_material_amount(valid_candidate) < amount_needed)
continue
choices[valid_candidate.name] = valid_candidate
+3
View File
@@ -184,6 +184,9 @@
data["id_bounty_names"] = list(inserted_scan_id.registered_account.bounties[1].name,
inserted_scan_id.registered_account.bounties[2].name,
inserted_scan_id.registered_account.bounties[3].name)
data["id_bounty_infos"] = list(inserted_scan_id.registered_account.bounties[1].description,
inserted_scan_id.registered_account.bounties[2].description,
inserted_scan_id.registered_account.bounties[3].description)
data["id_bounty_values"] = list(inserted_scan_id.registered_account.bounties[1].reward * (CIV_BOUNTY_SPLIT/100),
inserted_scan_id.registered_account.bounties[2].reward * (CIV_BOUNTY_SPLIT/100),
inserted_scan_id.registered_account.bounties[3].reward * (CIV_BOUNTY_SPLIT/100))
@@ -531,7 +531,8 @@
return
player_turn = TRUE
ui_panel = UI_PANEL_WORLD_MAP
player_gold /= 2
if(player_gold)
player_gold = max(round(player_gold /= 2, 1), 0)
return TRUE
//they pressed something but it wasn't in the menu, we'll be nice and give them back their turn anyway.
player_turn = TRUE
@@ -339,3 +339,12 @@
to_chat(owner, span_notice("You move downwards."))
else
to_chat(owner, span_notice("You couldn't move downwards!"))
/obj/machinery/computer/camera_advanced/human_ai/screwdriver_act(mob/living/user, obj/item/tool)
balloon_alert(user, "repackaging...")
if(!do_after(user, 5 SECONDS, src))
return ITEM_INTERACT_BLOCKING
tool.play_tool_sound(src, 40)
new /obj/item/secure_camera_console_pod(get_turf(src))
qdel(src)
return ITEM_INTERACT_SUCCESS
@@ -335,7 +335,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
if (!message)
return
DScommunications.soft_filtering = FALSE
GLOB.communications_controller.soft_filtering = FALSE
var/list/hard_filter_result = is_ic_filtered(message)
if(hard_filter_result)
tgui_alert(usr, "Your message contains: (\"[hard_filter_result[CHAT_FILTER_INDEX_WORD]]\"), which is not allowed on this server.")
@@ -347,7 +347,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
return
message_admins("[ADMIN_LOOKUPFLW(usr)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\". They may be using a disallowed term for a cross-station message. Increasing delay time to reject.\n\n Message: \"[html_encode(message)]\"")
log_admin_private("[key_name(usr)] has passed the soft filter for \"[soft_filter_result[CHAT_FILTER_INDEX_WORD]]\". They may be using a disallowed term for a cross-station message. Increasing delay time to reject.\n\n Message: \"[message]\"")
DScommunications.soft_filtering = TRUE
GLOB.communications_controller.soft_filtering = TRUE
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
@@ -358,13 +358,13 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
GLOB.admins,
span_adminnotice( \
"<b color='orange'>CROSS-SECTOR MESSAGE (OUTGOING):</b> [ADMIN_LOOKUPFLW(usr)] is about to send \
the following message to <b>[destination]</b> (will autoapprove in [DScommunications.soft_filtering ? DisplayTimeText(EXTENDED_CROSS_SECTOR_CANCEL_TIME) : DisplayTimeText(CROSS_SECTOR_CANCEL_TIME)]): \
the following message to <b>[destination]</b> (will autoapprove in [GLOB.communications_controller.soft_filtering ? DisplayTimeText(EXTENDED_CROSS_SECTOR_CANCEL_TIME) : DisplayTimeText(CROSS_SECTOR_CANCEL_TIME)]): \
<b><a href='?src=[REF(src)];reject_cross_comms_message=1'>REJECT</a></b><br> \
[html_encode(message)]" \
)
)
send_cross_comms_message_timer = addtimer(CALLBACK(src, PROC_REF(send_cross_comms_message), usr, destination, message), DScommunications.soft_filtering ? EXTENDED_CROSS_SECTOR_CANCEL_TIME : CROSS_SECTOR_CANCEL_TIME, TIMER_STOPPABLE)
send_cross_comms_message_timer = addtimer(CALLBACK(src, PROC_REF(send_cross_comms_message), usr, destination, message), GLOB.communications_controller.soft_filtering ? EXTENDED_CROSS_SECTOR_CANCEL_TIME : CROSS_SECTOR_CANCEL_TIME, TIMER_STOPPABLE)
COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN)
if ("setState")
@@ -552,7 +552,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
var/network_name = CONFIG_GET(string/cross_comms_network)
if(network_name)
payload["network"] = network_name
if(DScommunications.soft_filtering)
if(GLOB.communications_controller.soft_filtering)
payload["is_filtered"] = TRUE
var/name_to_send = "[CONFIG_GET(string/cross_comms_name)]([station_name()])" //SKYRAT EDIT ADDITION
@@ -562,7 +562,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
usr.log_talk(message, LOG_SAY, tag = "message to the other server")
message_admins("[ADMIN_LOOKUPFLW(usr)] has sent a message to the other server\[s].")
deadchat_broadcast(" has sent an outgoing message to the other station(s).</span>", "<span class='bold'>[usr.real_name]", usr, message_type = DEADCHAT_ANNOUNCEMENT)
DScommunications.soft_filtering = FALSE // set it to false at the end of the proc to ensure that everything prior reads as intended
GLOB.communications_controller.soft_filtering = FALSE // set it to false at the end of the proc to ensure that everything prior reads as intended
/obj/machinery/computer/communications/ui_data(mob/user)
var/list/data = list(
@@ -727,7 +727,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
return
deltimer(send_cross_comms_message_timer)
DScommunications.soft_filtering = FALSE
GLOB.communications_controller.soft_filtering = FALSE
send_cross_comms_message_timer = null
log_admin("[key_name(usr)] has cancelled the outgoing cross-comms message.")
@@ -800,7 +800,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
/obj/machinery/computer/communications/proc/make_announcement(mob/living/user)
var/is_ai = HAS_SILICON_ACCESS(user)
if(!DScommunications.can_announce(user, is_ai))
if(!GLOB.communications_controller.can_announce(user, is_ai))
to_chat(user, span_alert("Intercomms recharging. Please stand by."))
return
var/input = tgui_input_text(user, "Message to announce to the station crew", "Announcement")
@@ -821,7 +821,7 @@ GLOBAL_VAR_INIT(cops_arrived, FALSE)
)
var/list/players = get_communication_players()
DScommunications.make_announcement(user, is_ai, input, syndicate || (obj_flags & EMAGGED), players)
GLOB.communications_controller.make_announcement(user, is_ai, input, syndicate || (obj_flags & EMAGGED), players)
deadchat_broadcast(" made a priority announcement from [span_name("[get_area_name(usr, TRUE)]")].", span_name("[user.real_name]"), user, message_type=DEADCHAT_ANNOUNCEMENT)
/obj/machinery/computer/communications/proc/get_communication_players()
+74 -15
View File
@@ -35,6 +35,72 @@
/obj/machinery/door/poddoor/get_save_vars()
return ..() + NAMEOF(src, id)
/obj/machinery/door/poddoor/examine(mob/user)
. = ..()
if(panel_open)
if(deconstruction == BLASTDOOR_FINISHED)
. += span_notice("The maintenance panel is opened and the electronics could be <b>pried</b> out.")
. += span_notice("\The [src] could be calibrated to a blast door controller ID with a <b>multitool</b>.")
else if(deconstruction == BLASTDOOR_NEEDS_ELECTRONICS)
. += span_notice("The <i>electronics</i> are missing and there are some <b>wires</b> sticking out.")
else if(deconstruction == BLASTDOOR_NEEDS_WIRES)
. += span_notice("The <i>wires</i> have been removed and it's ready to be <b>sliced apart</b>.")
/obj/machinery/door/poddoor/add_context(atom/source, list/context, obj/item/held_item, mob/user)
. = ..()
if(isnull(held_item))
return NONE
if(deconstruction == BLASTDOOR_NEEDS_WIRES && istype(held_item, /obj/item/stack/cable_coil))
context[SCREENTIP_CONTEXT_LMB] = "Wire assembly"
return CONTEXTUAL_SCREENTIP_SET
if(deconstruction == BLASTDOOR_NEEDS_ELECTRONICS && istype(held_item, /obj/item/electronics/airlock))
context[SCREENTIP_CONTEXT_LMB] = "Add electronics"
return CONTEXTUAL_SCREENTIP_SET
//we do not check for special effects like if they can actually perform the action because they will be told they can't do it when they try,
//with feedback on what they have to do in order to do so.
switch(held_item.tool_behaviour)
if(TOOL_SCREWDRIVER)
context[SCREENTIP_CONTEXT_LMB] = "Open panel"
return CONTEXTUAL_SCREENTIP_SET
if(TOOL_MULTITOOL)
context[SCREENTIP_CONTEXT_LMB] = "Calibrate ID"
return CONTEXTUAL_SCREENTIP_SET
if(TOOL_CROWBAR)
context[SCREENTIP_CONTEXT_LMB] = "Remove electronics"
return CONTEXTUAL_SCREENTIP_SET
if(TOOL_WIRECUTTER)
context[SCREENTIP_CONTEXT_LMB] = "Remove wires"
return CONTEXTUAL_SCREENTIP_SET
if(TOOL_WELDER)
context[SCREENTIP_CONTEXT_LMB] = "Disassemble"
return CONTEXTUAL_SCREENTIP_SET
/obj/machinery/door/poddoor/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
if(deconstruction == BLASTDOOR_NEEDS_WIRES && istype(tool, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/coil = tool
var/datum/crafting_recipe/recipe = locate(recipe_type) in GLOB.crafting_recipes
var/amount_needed = recipe.reqs[/obj/item/stack/cable_coil]
if(coil.get_amount() < amount_needed)
balloon_alert(user, "not enough cable!")
return ITEM_INTERACT_SUCCESS
balloon_alert(user, "adding cables...")
if(!do_after(user, 5 SECONDS, src))
return ITEM_INTERACT_SUCCESS
coil.use(amount_needed)
deconstruction = BLASTDOOR_NEEDS_ELECTRONICS
balloon_alert(user, "cables added")
return ITEM_INTERACT_SUCCESS
if(deconstruction == BLASTDOOR_NEEDS_ELECTRONICS && istype(tool, /obj/item/electronics/airlock))
balloon_alert(user, "adding electronics...")
if(!do_after(user, 10 SECONDS, src))
return ITEM_INTERACT_SUCCESS
qdel(tool)
balloon_alert(user, "electronics added")
deconstruction = BLASTDOOR_FINISHED
return ITEM_INTERACT_SUCCESS
return NONE
/obj/machinery/door/poddoor/screwdriver_act(mob/living/user, obj/item/tool)
. = ..()
if (density)
@@ -49,7 +115,8 @@
balloon_alert(user, "open the door first!")
return ITEM_INTERACT_SUCCESS
if (!panel_open)
return
balloon_alert(user, "open the panel first!")
return ITEM_INTERACT_SUCCESS
if (deconstruction != BLASTDOOR_FINISHED)
return
var/change_id = tgui_input_number(user, "Set the door controllers ID (Current: [id])", "Door Controller ID", isnum(id) ? id : null, 100)
@@ -69,7 +136,8 @@
balloon_alert(user, "open the door first!")
return ITEM_INTERACT_SUCCESS
if (!panel_open)
return
balloon_alert(user, "open the panel first!")
return ITEM_INTERACT_SUCCESS
if (deconstruction != BLASTDOOR_FINISHED)
return
balloon_alert(user, "removing airlock electronics...")
@@ -86,7 +154,8 @@
balloon_alert(user, "open the door first!")
return ITEM_INTERACT_SUCCESS
if (!panel_open)
return
balloon_alert(user, "open the panel first!")
return ITEM_INTERACT_SUCCESS
if (deconstruction != BLASTDOOR_NEEDS_ELECTRONICS)
return
balloon_alert(user, "removing internal cables...")
@@ -104,7 +173,8 @@
balloon_alert(user, "open the door first!")
return ITEM_INTERACT_SUCCESS
if (!panel_open)
return
balloon_alert(user, "open the panel first!")
return ITEM_INTERACT_SUCCESS
if (deconstruction != BLASTDOOR_NEEDS_WIRES)
return
balloon_alert(user, "tearing apart...") //You're tearing me apart, Lisa!
@@ -116,17 +186,6 @@
qdel(src)
return ITEM_INTERACT_SUCCESS
/obj/machinery/door/poddoor/examine(mob/user)
. = ..()
if(panel_open)
if(deconstruction == BLASTDOOR_FINISHED)
. += span_notice("The maintenance panel is opened and the electronics could be <b>pried</b> out.")
. += span_notice("\The [src] could be calibrated to a blast door controller ID with a <b>multitool</b>.")
else if(deconstruction == BLASTDOOR_NEEDS_ELECTRONICS)
. += span_notice("The <i>electronics</i> are missing and there are some <b>wires</b> sticking out.")
else if(deconstruction == BLASTDOOR_NEEDS_WIRES)
. += span_notice("The <i>wires</i> have been removed and it's ready to be <b>sliced apart</b>.")
/obj/machinery/door/poddoor/connect_to_shuttle(mapload, obj/docking_port/mobile/port, obj/docking_port/stationary/dock)
id = "[port.shuttle_id]_[id]"
+3
View File
@@ -16,6 +16,9 @@
density = FALSE
opacity = FALSE
/obj/machinery/door/poddoor/shutters/preopen/deconstructed
deconstruction = BLASTDOOR_NEEDS_WIRES
/obj/machinery/door/poddoor/shutters/indestructible
name = "hardened shutters"
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
+1 -1
View File
@@ -21,7 +21,7 @@
/obj/machinery/recycler/Initialize(mapload)
materials = AddComponent(
/datum/component/material_container, \
DSmaterials.materials_by_category[MAT_CATEGORY_SILO], \
SSmaterials.materials_by_category[MAT_CATEGORY_SILO], \
INFINITY, \
MATCONTAINER_NO_INSERT \
)
+4 -4
View File
@@ -606,7 +606,7 @@
var/datum/radial_menu_choice/null_choice = new
null_choice.name = DIMENSION_CHOICE_RANDOM
choosable_dimensions[DIMENSION_CHOICE_RANDOM] = null_choice
for(var/datum/dimension_theme/theme as anything in DSmaterials.dimensional_themes)
for(var/datum/dimension_theme/theme as anything in SSmaterials.dimensional_themes)
var/datum/radial_menu_choice/theme_choice = new
theme_choice.image = image(initial(theme.icon), initial(theme.icon_state))
theme_choice.name = initial(theme.name)
@@ -628,14 +628,14 @@
/obj/item/bombcore/dimensional/detonate()
var/list/affected_turfs = circle_range_turfs(src, range_heavy)
var/theme_count = length(DSmaterials.dimensional_themes)
var/theme_count = length(SSmaterials.dimensional_themes)
var/num_affected = 0
for(var/turf/affected as anything in affected_turfs)
var/datum/dimension_theme/theme_to_use
if(isnull(chosen_theme))
theme_to_use = DSmaterials.dimensional_themes[DSmaterials.dimensional_themes[rand(1, theme_count)]]
theme_to_use = SSmaterials.dimensional_themes[SSmaterials.dimensional_themes[rand(1, theme_count)]]
else
theme_to_use = DSmaterials.dimensional_themes[chosen_theme]
theme_to_use = SSmaterials.dimensional_themes[chosen_theme]
if(!theme_to_use.can_convert(affected))
continue
num_affected++
@@ -51,7 +51,7 @@
/obj/effect/anomaly/dimensional/proc/prepare_area(new_theme_path)
if (!new_theme_path)
new_theme_path = pick(subtypesof(/datum/dimension_theme))
theme = DSmaterials.dimensional_themes[new_theme_path]
theme = SSmaterials.dimensional_themes[new_theme_path]
apply_theme_icon()
target_turfs = list()
@@ -47,7 +47,7 @@
break
return
var/datum/move_loop/loop = DSmove_manager.move(src, direction, delay = delay, timeout = range * delay, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
var/datum/move_loop/loop = GLOB.move_manager.move(src, direction, delay = delay, timeout = range * delay, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(spread_movement_effects))
/obj/effect/decal/cleanable/xenoblood/xgibs/proc/spread_movement_effects(datum/move_loop/has_target/source)
@@ -163,7 +163,7 @@
break
return
var/datum/move_loop/loop = DSmove_manager.move_to(src, get_step(src, direction), delay = delay, timeout = range * delay, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
var/datum/move_loop/loop = GLOB.move_manager.move_to(src, get_step(src, direction), delay = delay, timeout = range * delay, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(spread_movement_effects))
/obj/effect/decal/cleanable/blood/gibs/proc/spread_movement_effects(datum/move_loop/has_target/source)
@@ -376,7 +376,7 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache)
/// Set the splatter up to fly through the air until it rounds out of steam or hits something
/obj/effect/decal/cleanable/blood/hitsplatter/proc/fly_towards(turf/target_turf, range)
var/delay = 2
var/datum/move_loop/loop = DSmove_manager.move_towards(src, target_turf, delay, timeout = delay * range, priority = MOVEMENT_ABOVE_SPACE_PRIORITY, flags = MOVEMENT_LOOP_START_FAST)
var/datum/move_loop/loop = GLOB.move_manager.move_towards(src, target_turf, delay, timeout = delay * range, priority = MOVEMENT_ABOVE_SPACE_PRIORITY, flags = MOVEMENT_LOOP_START_FAST)
RegisterSignal(loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move))
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_move))
RegisterSignal(loop, COMSIG_QDELETING, PROC_REF(loop_done))
@@ -412,9 +412,7 @@
. += emissive_appearance(icon, "[icon_state]_light", src, alpha = src.alpha)
/obj/effect/decal/cleanable/ants/fire_act(exposed_temperature, exposed_volume)
var/obj/effect/decal/cleanable/ants/fire/fire_ants = new(loc)
fire_ants.reagents.clear_reagents()
reagents.trans_to(fire_ants, fire_ants.reagents.maximum_volume)
new /obj/effect/decal/cleanable/ants/fire(loc)
qdel(src)
/obj/effect/decal/cleanable/ants/fire
@@ -32,7 +32,7 @@
break
return
var/datum/move_loop/loop = DSmove_manager.move(src, direction, delay = delay, timeout = range * delay, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
var/datum/move_loop/loop = GLOB.move_manager.move(src, direction, delay = delay, timeout = range * delay, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(spread_movement_effects))
/obj/effect/decal/cleanable/robot_debris/proc/spread_movement_effects(datum/move_loop/has_target/source)
@@ -67,7 +67,7 @@ would spawn and follow the beaker, even if it is carried or thrown.
var/step_amt = pick(1,2,3)
var/step_delay = 5
var/datum/move_loop/loop = DSmove_manager.move(effect, direction, step_delay, timeout = step_delay * step_amt, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
var/datum/move_loop/loop = GLOB.move_manager.move(effect, direction, step_delay, timeout = step_delay * step_amt, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(loop, COMSIG_QDELETING, PROC_REF(decrement_total_effect))
/datum/effect_system/proc/decrement_total_effect(datum/source)
@@ -11,7 +11,7 @@
/obj/effect/particle_effect/expl_particles/LateInitialize()
var/step_amt = pick(25;1,50;2,100;3,200;4)
var/datum/move_loop/loop = DSmove_manager.move(src, pick(GLOB.alldirs), 1, timeout = step_amt, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
var/datum/move_loop/loop = GLOB.move_manager.move(src, pick(GLOB.alldirs), 1, timeout = step_amt, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(loop, COMSIG_QDELETING, PROC_REF(end_particle))
/obj/effect/particle_effect/expl_particles/proc/end_particle(datum/source)
@@ -38,7 +38,7 @@
/// Starts the effect moving at a target with a delay in deciseconds, and a lifetime in moves
/// Returns the created loop
/obj/effect/particle_effect/water/extinguisher/proc/move_at(atom/target, delay, lifetime)
var/datum/move_loop/loop = DSmove_manager.move_towards_legacy(src, target, delay, timeout = delay * lifetime, flags = MOVEMENT_LOOP_START_FAST, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
var/datum/move_loop/loop = GLOB.move_manager.move_towards_legacy(src, target, delay, timeout = delay * lifetime, flags = MOVEMENT_LOOP_START_FAST, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_forcemove))
RegisterSignal(loop, COMSIG_QDELETING, PROC_REF(movement_stopped))
return loop
@@ -63,7 +63,7 @@
// Stomach acid doesn't use legacy because it's not "targeted", and we instead want the circular sorta look
/obj/effect/particle_effect/water/extinguisher/stomach_acid/move_at(atom/target, delay, lifetime)
var/datum/move_loop/loop = DSmove_manager.move_towards(src, target, delay, timeout = delay * lifetime, flags = MOVEMENT_LOOP_START_FAST, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
var/datum/move_loop/loop = GLOB.move_manager.move_towards(src, target, delay, timeout = delay * lifetime, flags = MOVEMENT_LOOP_START_FAST, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_forcemove))
RegisterSignal(loop, COMSIG_QDELETING, PROC_REF(movement_stopped))
return loop
@@ -25,5 +25,5 @@
/obj/structure/alien/egg/delivery/Initialize(mapload)
. = ..()
DScommunications.xenomorph_egg_delivered = TRUE
DScommunications.captivity_area = get_area(src)
GLOB.communications_controller.xenomorph_egg_delivered = TRUE
GLOB.communications_controller.captivity_area = get_area(src)
+1 -1
View File
@@ -70,7 +70,7 @@
ADD_TRAIT(AM, TRAIT_IMMOBILIZED, REF(src))
affecting[AM] = AM.dir
var/datum/move_loop/loop = DSmove_manager.move(AM, direction, speed, tiles ? tiles * speed : INFINITY)
var/datum/move_loop/loop = GLOB.move_manager.move(AM, direction, speed, tiles ? tiles * speed : INFINITY)
RegisterSignal(loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move))
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_move))
RegisterSignal(loop, COMSIG_QDELETING, PROC_REF(set_to_normal))
@@ -29,7 +29,7 @@
AddElement(/datum/element/floor_loving)
AddComponent(/datum/component/spawner, spawn_types = list(spawned_effect), max_spawned = max_spawned, spawn_time = spawn_interval)
src.target = target
movement = DSmove_manager.move_towards(src, chasing = target, delay = move_speed, home = homing, timeout = duration, flags = MOVEMENT_LOOP_START_FAST)
movement = GLOB.move_manager.move_towards(src, chasing = target, delay = move_speed, home = homing, timeout = duration, flags = MOVEMENT_LOOP_START_FAST)
RegisterSignal(target, COMSIG_QDELETING, PROC_REF(on_target_invalid))
if (isliving(target))
+5 -6
View File
@@ -14,12 +14,11 @@
else
deploy_bodybag(user, get_turf(src))
/obj/item/bodybag/afterattack(atom/target, mob/user, proximity)
. = ..()
if(proximity)
if(isopenturf(target))
deploy_bodybag(user, target)
/obj/item/bodybag/interact_with_atom(atom/interacting_with, mob/living/user, flags)
if(isopenturf(interacting_with))
deploy_bodybag(user, interacting_with)
return ITEM_INTERACT_SUCCESS
return NONE
/obj/item/bodybag/attempt_pickup(mob/user)
// can't pick ourselves up if we are inside of the bodybag, else very weird things may happen
if(contains(user))
@@ -1,3 +1,28 @@
/// Global list of areas which are considered to be inside the same department for our purposes
GLOBAL_LIST_INIT(battle_royale_regions, list(
"Medical Bay" = list(
/area/station/command/heads_quarters/cmo,
/area/station/medical,
/area/station/security/checkpoint/medical,
),
"Research Division" = list(
/area/station/command/heads_quarters/rd,
/area/station/security/checkpoint/science,
/area/station/science,
),
"Engineering Bay" = list(
/area/station/command/heads_quarters/ce,
/area/station/engineering,
/area/station/maintenance/disposal/incinerator,
/area/station/security/checkpoint/engineering,
),
"Cargo Bay" = list(
/area/station/cargo,
/area/station/command/heads_quarters/qm,
/area/station/security/checkpoint/supply,
),
))
/// Quietly implants people with battle royale implants
/obj/item/royale_implanter
name = "royale implanter"
@@ -78,7 +103,7 @@
balloon_alert(user, "[required_contestants - contestant_count] contestants needed!")
return
DSbattle_royale.start_battle(implanted_implants)
GLOB.battle_royale_master.start_battle(implanted_implants)
for (var/obj/implanter as anything in linked_implanters)
do_sparks(3, cardinal_only = FALSE, source = implanter)
@@ -115,3 +140,208 @@
/obj/item/royale_remote/proc/implant_destroyed(obj/item/implant)
SIGNAL_HANDLER
implanted_implants -= implant
GLOBAL_DATUM_INIT(battle_royale_master, /datum/battle_royale_master, new)
/// Basically just exists to hold references to datums so that they don't GC
/datum/battle_royale_master
/// List of battle royale datums currently running
var/list/active_battles
/// Start a new battle royale using a passed list of implants
/datum/battle_royale_master/proc/start_battle(list/competitors)
var/datum/battle_royale_controller/controller = new()
if (!controller.start(competitors))
return FALSE
LAZYADD(active_battles, controller)
if (LAZYLEN(active_battles) == 1)
start_broadcasting_network(BATTLE_ROYALE_CAMERA_NET)
RegisterSignal(controller, COMSIG_QDELETING, PROC_REF(battle_ended))
return TRUE
/// Drop reference when it kills itself
/datum/battle_royale_master/proc/battle_ended(datum/source)
SIGNAL_HANDLER
LAZYREMOVE(active_battles, source)
if (!LAZYLEN(active_battles))
stop_broadcasting_network(BATTLE_ROYALE_CAMERA_NET)
/// Datum which controls the conflict
/datum/battle_royale_controller
/// Where is our battle taking place?
var/chosen_area
/// Is the battle currently in progress?
var/battle_running = TRUE
/// Should we let everyone know that someone has died?
var/announce_deaths = TRUE
/// List of implants involved
var/list/contestant_implants = list()
/// Ways to describe that someone has died
var/static/list/euphemisms = list(
"cashed their last paycheque.",
"didn't make it...",
"didn't make the cut.",
"had their head blown clean off!",
"has been killed!",
"has failed the challenge!",
"has passed away.",
"has died.",
"is in a better place now.",
"isn't going to be clocking in tomorrow!",
"just flatlined.",
"isn't today's winner.",
"seems to have exploded!",
"was just murdered on live tv!",
"won't be making it to retirement.",
"won't be getting back up after that one.",
)
/// Ways to tell people not to salt in deadchat, surely effective
var/static/list/condolences = list(
"Better luck next time!",
"But stay tuned, there's still everything to play for!",
"Did you catch who did it?",
"It looked like that one really hurt...",
"Let's get that one on action replay!",
"Let's have a moment of silence, please.",
"Let's hope the next one does better.",
"Someone please notify their next of kin.",
"They had a good run.",
"Too bad!",
"What a shame!",
"What an upset!",
"What's going to happen next?",
"Who could have seen that coming?",
"Who will be next?",
)
/datum/battle_royale_controller/Destroy(force)
contestant_implants = null
return ..()
/// Start a battle royale with the list of provided implants
/datum/battle_royale_controller/proc/start(list/implants, battle_time = 10 MINUTES)
chosen_area = pick(GLOB.battle_royale_regions)
for (var/obj/item/implant/explosive/battle_royale/contestant_implant in implants)
contestant_implant.start_battle(chosen_area, GLOB.battle_royale_regions[chosen_area])
if (isnull(contestant_implant))
continue // Might have exploded if it was removed from a person
RegisterSignal(contestant_implant, COMSIG_QDELETING, PROC_REF(implant_destroyed))
contestant_implants |= contestant_implant
if (length(contestant_implants) <= 1)
return FALSE // Well there's not much point is there
priority_announce(
text = "Congratulations [station_name()], you have been chosen as the next site of the Rumble Royale! \n\
Viewers across the sector will watch our [convert_integer_to_words(length(contestant_implants))] lucky contestants battle their way into your [chosen_area] and fight until only one is left standing! \n\
If they don't make it in five minutes, they'll be disqualified. If you see one of our players struggling to get in, do lend them a hand... or don't, if you can live with the consequences! \n\
As a gesture of gratitude, we will be providing our premium broadcast to your entertainment monitors at no cost so that you can watch the excitement. \n\
Bystanders are advised not to intervene... but if you do, make it look good for the camera!",
title = "Rumble Royale Beginning",
sound = 'sound/machines/alarm.ogg',
has_important_message = TRUE,
sender_override = "Rumble Royale Pirate Broadcast Station",
color_override = "red",
)
for (var/obj/item/implant/explosive/battle_royale/contestant_implant as anything in contestant_implants)
contestant_implant.announce()
addtimer(CALLBACK(src, PROC_REF(limit_area)), battle_time / 2, TIMER_DELETE_ME)
addtimer(CALLBACK(src, PROC_REF(finish)), battle_time, TIMER_DELETE_ME)
return TRUE
/// An implant was destroyed, hopefully because it exploded. Count how many competitors remain.
/datum/battle_royale_controller/proc/implant_destroyed(obj/item/implant/implant)
SIGNAL_HANDLER
contestant_implants -= implant
if (!battle_running)
return
if (length(contestant_implants) <= 1)
announce_winner(implant)
else if (announce_deaths)
var/message = ""
if (isnull(implant.imp_in))
message = "Looks like someone removed and destroyed their implant, that's cheating!"
else
message = "[implant.imp_in.real_name] [pick(euphemisms)] [pick(condolences)]"
priority_announce(
text = message,
title = "Rumble Royale Casualty Report",
sound = 'sound/misc/notice1.ogg',
has_important_message = TRUE,
sender_override = "Rumble Royale Pirate Broadcast Station",
color_override = "red",
)
/// There's only one person left, we have a winner!
/datum/battle_royale_controller/proc/announce_winner(obj/item/implant/losing_implant)
battle_running = FALSE
if (length(contestant_implants) > 1)
return
var/message = ""
var/mob/living/loser = losing_implant.imp_in
var/obj/item/implant/winning_implant = pop(contestant_implants)
var/mob/living/winner = winning_implant?.imp_in
if (isnull(winner) && isnull(loser))
message = "Somehow, it seems like there's no winner tonight. What a disappointment!"
else
var/loser_text = isnull(loser) ? "With the disqualification of the other remaining contestant" : "With the death of [loser.real_name]"
var/winner_text = isnull(winner) ? "we must sadly announce that the would-be winner has also been disqualified. Such bad showmanship!" : "only [winner.real_name] remains. Congratulations, we have a winner!"
message = "[loser_text], [winner_text]"
if (!isnull(winner))
podspawn(list(
"target" = get_turf(winner),
"style" = STYLE_SYNDICATE,
"spawn" = /obj/item/food/roast_dinner,
))
priority_announce(
text = message,
title = "Rumble Royale Winner",
sound = 'sound/misc/notice1.ogg',
has_important_message = TRUE,
sender_override = "Rumble Royale Pirate Broadcast Station",
color_override = "red",
)
qdel(winning_implant) // You get to live!
winner?.mind?.remove_antag_datum(/datum/antagonist/survivalist/battle_royale)
qdel(src)
/// Called halfway through the battle, if you've not made it to the designated battle zone we kill you
/datum/battle_royale_controller/proc/limit_area()
priority_announce(
text = "We're halfway done folks! And bad news to anyone who hasn't made it to the [chosen_area]... you're out!",
title = "Rumble Royale Update",
sound = 'sound/misc/notice1.ogg',
has_important_message = TRUE,
sender_override = "Rumble Royale Pirate Broadcast Station",
color_override = "red",
)
for (var/obj/item/implant/explosive/battle_royale/contestant_implant as anything in contestant_implants)
contestant_implant.limit_areas()
/// Well you're out of time, bad luck
/datum/battle_royale_controller/proc/finish()
battle_running = FALSE
priority_announce(
text = "Sorry remaining contestants, your time is up. \
We're sorry to announce that this edition of Royal Rumble has no winner. \n\
Better luck next time!",
title = "Rumble Royale Concluded",
sound = 'sound/misc/notice1.ogg',
has_important_message = TRUE,
sender_override = "Rumble Royale Pirate Broadcast Station",
color_override = "red",
)
for (var/obj/item/implant/explosive/battle_royale/contestant_implant as anything in contestant_implants)
contestant_implant.explode()
qdel(src)
@@ -164,9 +164,13 @@
if(HAS_TRAIT(target, TRAIT_HUSK))
if(advanced)
if(HAS_TRAIT_FROM(target, TRAIT_HUSK, BURN))
render_list += "<span class='alert ml-1'>Subject has been husked by severe burns.</span>\n"
/* SKYRAT EDIT START: More unhusking information */
render_list += "<span class='alert ml-1'>Subject has been husked by severe burns. Proceed by repairing burn damage and following up with \
application of [SYNTHFLESH_UNHUSK_AMOUNT]u synthflesh or injection of rezadone as treatment.</span>\n"
else if (HAS_TRAIT_FROM(target, TRAIT_HUSK, CHANGELING_DRAIN))
render_list += "<span class='alert ml-1'>Subject has been husked by dessication.</span>\n"
render_list += "<span class='alert ml-1'>Subject has been husked by dessication. Use application of [SYNTHFLESH_LING_UNHUSK_AMOUNT]u \
of synthflesh or injection of rezadone as treatment.</span>\n"
/* SKYRAT EDIT END */
else
render_list += "<span class='alert ml-1'>Subject has been husked by mysterious causes.</span>\n"
@@ -225,6 +229,17 @@
render_list += "<span class='alert ml-1'><b>Subject is extremely allergic to the following chemicals:</b></span>\n"
render_list += "<span class='alert ml-2'><b>[allergies]</b></span>\n" // BUBBER EDIT END
// SKYRAT EDIT ADDITION START -- Show increased/decreased brute/burn mods, to "leave a paper trail" for the fragility quirk
if(ishuman(target))
var/mob/living/carbon/human/humantarget = target
var/datum/physiology/physiology = humantarget.physiology
if (physiology.brute_mod != 1)
render_list += "<span class='danger ml-1'>Subject takes [(physiology.brute_mod) * 100]% brute damage.</span>\n"
if (physiology.burn_mod != 1)
render_list += "<span class='danger ml-1'>Subject takes [(physiology.burn_mod) * 100]% burn damage.</span>\n"
// SKYRAT EDIT ADDITION END
if (HAS_TRAIT(target, TRAIT_IRRADIATED))
render_list += "<span class='alert ml-1'>Subject is irradiated. Supply toxin healing.</span>\n"
+1 -1
View File
@@ -258,7 +258,7 @@
//Chair movement loop
/obj/item/extinguisher/proc/move_chair(obj/buckled_object, movementdirection)
var/datum/move_loop/loop = DSmove_manager.move(buckled_object, movementdirection, 1, timeout = 9, flags = MOVEMENT_LOOP_START_FAST, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
var/datum/move_loop/loop = GLOB.move_manager.move(buckled_object, movementdirection, 1, timeout = 9, flags = MOVEMENT_LOOP_START_FAST, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
//This means the chair slowing down is dependant on the extinguisher existing, which is weird
//Couldn't figure out a better way though
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(manage_chair_speed))
+1 -1
View File
@@ -150,7 +150,7 @@
CRASH("a moving bug has been created but isn't moving towards anything!")
src.controller = controller
src.thing_moving_towards = thing_moving_towards
var/datum/move_loop/loop = DSmove_manager.home_onto(src, thing_moving_towards, delay = 5, flags = MOVEMENT_LOOP_NO_DIR_UPDATE)
var/datum/move_loop/loop = GLOB.move_manager.home_onto(src, thing_moving_towards, delay = 5, flags = MOVEMENT_LOOP_NO_DIR_UPDATE)
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(reached_destination_check))
RegisterSignal(thing_moving_towards, COMSIG_QDELETING, PROC_REF(on_machine_del))
@@ -263,6 +263,7 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \
new/datum/stack_recipe("AI core", /obj/structure/ai_core, 4, time = 5 SECONDS, one_per_turf = TRUE, check_density = FALSE, category = CAT_ROBOT),
new/datum/stack_recipe("bomb assembly", /obj/machinery/syndicatebomb/empty, 10, time = 5 SECONDS, check_density = FALSE, category = CAT_CHEMISTRY),
new/datum/stack_recipe("Large Gas Tank", /obj/structure/tank_frame, 4, time=1 SECONDS, one_per_turf=TRUE, check_density = FALSE, category = CAT_ATMOSPHERIC),
new/datum/stack_recipe("shutter assembly", /obj/machinery/door/poddoor/shutters/preopen/deconstructed, 5, time = 5 SECONDS, one_per_turf = TRUE, check_density = FALSE, category = CAT_DOORS),
null,
new /datum/stack_recipe_list("airlock assemblies", list( \
new/datum/stack_recipe("high security airlock assembly", /obj/structure/door_assembly/door_assembly_highsecurity, 4, time = 5 SECONDS, one_per_turf = TRUE, on_solid_ground = TRUE, category = CAT_DOORS),
+3 -3
View File
@@ -110,9 +110,9 @@
for(var/category in what_are_we_made_of.categories)
switch(category)
if(MAT_CATEGORY_BASE_RECIPES)
recipes |= DSmaterials.base_stack_recipes.Copy()
recipes |= SSmaterials.base_stack_recipes.Copy()
if(MAT_CATEGORY_RIGID)
recipes |= DSmaterials.rigid_stack_recipes.Copy()
recipes |= SSmaterials.rigid_stack_recipes.Copy()
update_weight()
update_appearance()
@@ -131,7 +131,7 @@
* - multiplier: The amount to multiply the mats per unit by. Defaults to 1.
*/
/obj/item/stack/proc/set_mats_per_unit(list/mats, multiplier=1)
mats_per_unit = DSmaterials.FindOrCreateMaterialCombo(mats, multiplier)
mats_per_unit = SSmaterials.FindOrCreateMaterialCombo(mats, multiplier)
update_custom_materials()
/** Updates the custom materials list of this stack.
+1 -1
View File
@@ -406,7 +406,7 @@
/obj/item/storage/bag/tray/proc/do_scatter(obj/item/tray_item)
var/delay = rand(2,4)
var/datum/move_loop/loop = DSmove_manager.move_rand(tray_item, list(NORTH,SOUTH,EAST,WEST), delay, timeout = rand(1, 2) * delay, flags = MOVEMENT_LOOP_START_FAST)
var/datum/move_loop/loop = GLOB.move_manager.move_rand(tray_item, list(NORTH,SOUTH,EAST,WEST), delay, timeout = rand(1, 2) * delay, flags = MOVEMENT_LOOP_START_FAST)
//This does mean scattering is tied to the tray. Not sure how better to handle it
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(change_speed))
+1 -1
View File
@@ -309,7 +309,7 @@
user.log_message("used Resin Launcher", LOG_GAME)
playsound(src,'sound/items/syringeproj.ogg',40,TRUE)
var/delay = 2
var/datum/move_loop/loop = DSmove_manager.move_towards(resin, target, delay, timeout = delay * 5, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
var/datum/move_loop/loop = GLOB.move_manager.move_towards(resin, target, delay, timeout = delay * 5, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(resin_stop_check))
RegisterSignal(loop, COMSIG_QDELETING, PROC_REF(resin_landed))
return
@@ -218,13 +218,12 @@
/obj/item/emergency_bed/attack_self(mob/user)
deploy_bed(user, user.loc)
/obj/item/emergency_bed/afterattack(obj/target, mob/user, proximity)
. = ..()
if(!proximity)
return
/obj/item/emergency_bed/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
if(isopenturf(interacting_with))
deploy_bed(user, interacting_with)
return ITEM_INTERACT_SUCCESS
return NONE
if(isopenturf(target))
deploy_bed(user, target)
/obj/item/emergency_bed/proc/deploy_bed(mob/user, atom/location)
var/obj/structure/bed/medical/emergency/deployed = new /obj/structure/bed/medical/emergency(location)
@@ -94,7 +94,7 @@
moving = TRUE
current_tube = tube
var/datum/move_loop/engine = DSmove_manager.force_move_dir(src, dir, 0, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
var/datum/move_loop/engine = GLOB.move_manager.force_move_dir(src, dir, 0, priority = MOVEMENT_ABOVE_SPACE_PRIORITY)
RegisterSignal(engine, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(before_pipe_transfer))
RegisterSignal(engine, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(after_pipe_transfer))
RegisterSignal(engine, COMSIG_QDELETING, PROC_REF(engine_finish))
-4
View File
@@ -17,7 +17,6 @@ GLOBAL_VAR(restart_counter)
* - world.init_byond_tracy()
* - (Start native profiling)
* - world.init_debugger()
* - SysMgr (all data systems)
* - Master =>
* - config *unloaded
* - (all subsystems) PreInit()
@@ -85,9 +84,6 @@ GLOBAL_VAR(restart_counter)
// Create the logger
logger = new
// Initialize all the data systems
SysMgr = new
// THAT'S IT, WE'RE DONE, THE. FUCKING. END.
Master = new
+6 -6
View File
@@ -253,11 +253,11 @@ ADMIN_VERB(run_weather, R_FUN, "Run Weather", "Triggers specific weather on the
ADMIN_VERB(command_report_footnote, R_ADMIN, "Command Report Footnote", "Adds a footnote to the roundstart command report.", ADMIN_CATEGORY_EVENTS)
var/datum/command_footnote/command_report_footnote = new /datum/command_footnote()
DScommunications.block_command_report += 1 //Add a blocking condition to the counter until the inputs are done.
GLOB.communications_controller.block_command_report += 1 //Add a blocking condition to the counter until the inputs are done.
command_report_footnote.message = tgui_input_text(user, "This message will be attached to the bottom of the roundstart threat report. Be sure to delay the roundstart report if you need extra time.", "P.S.")
if(!command_report_footnote.message)
DScommunications.block_command_report -= 1
GLOB.communications_controller.block_command_report -= 1
qdel(command_report_footnote)
return
@@ -266,8 +266,8 @@ ADMIN_VERB(command_report_footnote, R_ADMIN, "Command Report Footnote", "Adds a
if(!command_report_footnote.signature)
command_report_footnote.signature = "Classified"
DScommunications.command_report_footnotes += command_report_footnote
DScommunications.block_command_report--
GLOB.communications_controller.command_report_footnotes += command_report_footnote
GLOB.communications_controller.block_command_report--
message_admins("[user] has added a footnote to the command report: [command_report_footnote.message], signed [command_report_footnote.signature]")
@@ -276,5 +276,5 @@ ADMIN_VERB(command_report_footnote, R_ADMIN, "Command Report Footnote", "Adds a
var/signature
ADMIN_VERB(delay_command_report, R_FUN, "Delay Command Report", "Prevents the roundstart command report from being sent; or forces it to send it delayed.", ADMIN_CATEGORY_EVENTS)
DScommunications.block_command_report = !DScommunications.block_command_report
message_admins("[key_name_admin(user)] has [(DScommunications.block_command_report ? "delayed" : "sent")] the roundstart command report.")
GLOB.communications_controller.block_command_report = !GLOB.communications_controller.block_command_report
message_admins("[key_name_admin(user)] has [(GLOB.communications_controller.block_command_report ? "delayed" : "sent")] the roundstart command report.")
@@ -42,7 +42,7 @@
priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", SSstation.announcer.get_rand_report_sound())
threat.answer_callback = CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(pirates_answered), threat, chosen_gang, payoff, world.time)
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(spawn_pirates), threat, chosen_gang), RESPONSE_MAX_TIME)
DScommunications.send_message(threat, unique = TRUE)
GLOB.communications_controller.send_message(threat, unique = TRUE)
/proc/pirates_answered(datum/comm_message/threat, datum/pirate_gang/chosen_gang, payoff, initial_send_time)
if(world.time > initial_send_time + RESPONSE_MAX_TIME)
@@ -160,7 +160,7 @@
newcarp.faction = dragon.owner.current.faction.Copy()
if(SPT_PROB(1.5, seconds_per_tick))
var/rand_dir = pick(GLOB.cardinals)
DSmove_manager.move_to(src, get_step(src, rand_dir), 1)
GLOB.move_manager.move_to(src, get_step(src, rand_dir), 1)
return
// Increase time trackers and check for any updated states.
@@ -362,7 +362,7 @@
qdel(src)
return
RegisterSignal(src, COMSIG_MOVABLE_CROSS_OVER, PROC_REF(check_teleport))
DSmove_manager.move_towards(src, get_turf(whistle.whistler))
GLOB.move_manager.move_towards(src, get_turf(whistle.whistler))
/// Check if anything the tornado crosses is the creator.
/obj/effect/temp_visual/teleporting_tornado/proc/check_teleport(datum/source, atom/movable/crossed)
+3 -3
View File
@@ -87,7 +87,7 @@
explanation_text = "Escape from captivity."
/datum/objective/escape_captivity/check_completion()
if(!istype(get_area(owner), DScommunications.captivity_area))
if(!istype(get_area(owner), GLOB.communications_controller.captivity_area))
return TRUE
/datum/objective/advance_hive
@@ -146,7 +146,7 @@
if(!captive_alien || captive_alien.stat == DEAD)
return CAPTIVE_XENO_DEAD
if(istype(get_area(captive_alien), DScommunications.captivity_area))
if(istype(get_area(captive_alien), GLOB.communications_controller.captivity_area))
return CAPTIVE_XENO_FAIL
return CAPTIVE_XENO_PASS
@@ -155,7 +155,7 @@
/mob/living/carbon/alien/mind_initialize()
..()
if(!mind.has_antag_datum(/datum/antagonist/xeno))
if(DScommunications.xenomorph_egg_delivered && istype(get_area(src), DScommunications.captivity_area))
if(GLOB.communications_controller.xenomorph_egg_delivered && istype(get_area(src), GLOB.communications_controller.captivity_area))
mind.add_antag_datum(/datum/antagonist/xeno/captive)
else
mind.add_antag_datum(/datum/antagonist/xeno)
@@ -301,8 +301,8 @@
* * given_layer - the piping_layer we are checking
*/
/obj/machinery/atmospherics/proc/connection_check(obj/machinery/atmospherics/target, given_layer)
//check if the target & src connect in the same direction
if(!((initialize_directions & get_dir(src, target)) && (target.initialize_directions & get_dir(target, src))))
//if target is not multiz then we have to check if the target & src connect in the same direction
if(!istype(target, /obj/machinery/atmospherics/pipe/multiz) && !((initialize_directions & get_dir(src, target)) && (target.initialize_directions & get_dir(target, src))))
return FALSE
//both target & src can't be connected either way

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