Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Upstream 16.01.2025 #1750

Merged
merged 6 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
553 changes: 268 additions & 285 deletions _maps/map_files/generic/centcomm.dmm

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions code/_onclick/hud/follow_alert.dm
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@
/atom/movable/screen/alert/augury/meteor/process()
var/overridden = FALSE
for(var/obj/effect/meteor/M in GLOB.meteor_list)
if(istype(M, /obj/effect/meteor/fake))
continue // Meteor? What meteor?
if(!is_station_level(M.z))
continue // don't worry about endlessly looping
if(istype(M, /obj/effect/meteor/tunguska) && !overridden)
Expand Down
46 changes: 46 additions & 0 deletions code/game/objects/effects/meteors.dm
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,52 @@ GLOBAL_LIST_INIT(meteors_gore, list(/obj/effect/meteor/meaty = 5, /obj/effect/me
//Meteor types
///////////////////////

//Fake
/obj/effect/meteor/fake
name = "simulated meteor"
desc = "A simulated meteor for testing shield satellites. How did you see this, anyway?"
invisibility = INVISIBILITY_MAXIMUM
density = FALSE
pass_flags = NONE
/// The station goal that is simulating this meteor.
var/datum/station_goal/station_shield/goal
/// Did we crash into something? Used to avoid falsely reporting success when qdeleted.
var/failed = FALSE

/obj/effect/meteor/fake/Initialize(mapload)
. = ..()
for(var/datum/station_goal/station_shield/found_goal in SSticker.mode.station_goals)
goal = found_goal
return

/obj/effect/meteor/fake/Destroy()
if(!failed)
succeed()
goal = null
return ..()

/obj/effect/meteor/fake/ram_turf(turf/T)
if(!isspaceturf(T))
fail()
return
for(var/thing in T)
if(isobj(thing) && !iseffect(thing))
fail()
return

/obj/effect/meteor/fake/get_hit()
return

/obj/effect/meteor/fake/proc/succeed()
if(istype(goal))
goal.update_coverage(TRUE, get_turf(src))

/obj/effect/meteor/fake/proc/fail()
if(istype(goal))
goal.update_coverage(FALSE, get_turf(src))
failed = TRUE
qdel(src)

//Dust
/obj/effect/meteor/dust
name = "space dust"
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/devices/scanners.dm
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ SLIME SCANNER
msgs += "Damage Specifics: <span class='healthscan_oxy'>[OX]</span> - <font color='green'>[TX]</font> - <font color='#FFA500'>[BU]</font> - <font color='red'>[BR]</font>"

if(H.timeofdeath && (H.stat == DEAD || (HAS_TRAIT(H, TRAIT_FAKEDEATH)) || probably_dead))
var/tod = probably_dead || (HAS_TRAIT(user, TRAIT_MED_MACHINE_HALLUCINATING) && prob(10)) ? world.time - rand(10, 5000) : H.timeofdeath // Sure let's blow it out
var/tod = probably_dead && (HAS_TRAIT(user, TRAIT_MED_MACHINE_HALLUCINATING) && prob(10)) ? world.time - rand(10, 5000) : H.timeofdeath // Sure let's blow it out
msgs += "<span class='notice'>Time of Death: [station_time_timestamp("hh:mm:ss", tod)]</span>"
var/tdelta = round(world.time - tod)
if(H.is_revivable() && !DNR)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
var/canister_burn_duration = 10 SECONDS
/// How many firestacks will our reagent apply
var/canister_fire_applications = 1
/// Does our chemical have any special color?
var/canister_fire_color
/// How much ammo do we use per tile?
var/ammo_usage = 1
/// Is this a syndicate flamethrower
Expand Down Expand Up @@ -90,23 +92,28 @@
canister_burn_temp = null
canister_burn_duration = null
canister_fire_applications = null
canister_fire_color = null
return

var/burn_temp
var/burn_duration
var/fire_applications
var/how_many_canisters = length(canisters)
var/list/colors = list()

for(var/obj/item/chemical_canister/canister as anything in canisters)
if(!canister.ammo)
continue
burn_temp += canister.chem_burn_temp
burn_duration += canister.chem_burn_duration
fire_applications += canister.fire_applications
colors += canister.chem_color

canister_burn_temp = round(burn_temp / how_many_canisters, 1)
canister_burn_duration = round(burn_duration / how_many_canisters, 1)
canister_fire_applications = round(fire_applications / how_many_canisters, 1)
if(length(colors))
canister_fire_color = pick(colors)
update_icon(UPDATE_OVERLAYS)

/obj/item/chemical_flamethrower/afterattack__legacy__attackchain(atom/target, mob/user, flag)
Expand Down Expand Up @@ -159,7 +166,8 @@
previousturf = T

/obj/item/chemical_flamethrower/proc/make_flame(turf/spawn_turf)
new /obj/effect/fire(spawn_turf, canister_burn_temp, (canister_burn_duration + rand(1, 3) SECONDS), canister_fire_applications) // For that spicy randomness (and to save your ears from all fires extinguishing at the same time)
// For that spicy randomness (and to save your ears from all fires extinguishing at the same time)
new /obj/effect/fire(spawn_turf, canister_burn_temp, (canister_burn_duration + rand(1, 3) SECONDS), canister_fire_applications, canister_fire_color)

/*
* Uses `amount` ammo from the flamethrower.
Expand Down Expand Up @@ -232,6 +240,8 @@
var/first_time_silent = FALSE // The reason for this is so we can have canisters that spawn with reagents but don't announce it on `Initialize()`
/// What chemical do we have? This will be the chemical ID, so a string
var/stored_chemical
/// What color will our fire burn
var/chem_color

/obj/item/chemical_canister/Initialize(mapload)
. = ..()
Expand Down Expand Up @@ -273,6 +283,8 @@
chem_burn_duration = reagent_to_burn.burn_duration
chem_burn_temp = reagent_to_burn.burn_temperature
fire_applications = reagent_to_burn.fire_stack_applications
if(reagent_to_burn.burn_color)
chem_color = reagent_to_burn.burn_color
ammo = initial(ammo)
has_filled_reagent = TRUE
reagents.clear_reagents()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ GLOBAL_LIST_EMPTY(flame_effects)
name = "fire"
desc = "You don't think you should touch this."
icon = 'icons/effects/chemical_fire.dmi'
icon_state = "fire1"

icon_state = "red_small"
base_icon_state = "red"
/// How hot is our fire?
var/temperature
/// How long will our fire last
var/duration = 10 SECONDS
/// How many firestacks does the fire give to mobs
var/application_stacks = 1

/obj/effect/fire/Initialize(mapload, reagent_temperature, reagent_duration, fire_applications)
/obj/effect/fire/Initialize(mapload, reagent_temperature, reagent_duration, fire_applications, color)
. = ..()

if(reagent_duration < 0 || reagent_temperature <= 0) // There is no reason for this thing to exist
Expand All @@ -24,6 +24,9 @@ GLOBAL_LIST_EMPTY(flame_effects)
duration = reagent_duration
temperature = reagent_temperature
application_stacks = max(application_stacks, fire_applications)
if(color)
base_icon_state = color
update_icon()

for(var/obj/effect/fire/flame in get_turf(src))
if(!istype(flame) || flame == src)
Expand All @@ -48,6 +51,7 @@ GLOBAL_LIST_EMPTY(flame_effects)
fizzle()
return
duration -= 2 SECONDS
update_icon(UPDATE_ICON_STATE)

for(var/atom/movable/thing_to_burn in get_turf(src))
if(isliving(thing_to_burn))
Expand All @@ -68,6 +72,14 @@ GLOBAL_LIST_EMPTY(flame_effects)
var/datum/milla_safe/fire_heat_air/milla = new()
milla.invoke_async(src, location)

/obj/effect/fire/update_icon_state()
var/suffix = "small"
if(duration >= 30 SECONDS)
suffix = "big"
else if(duration >= 10 SECONDS)
suffix = "medium"
icon_state = "[base_icon_state]_[suffix]"

/datum/milla_safe/fire_heat_air

/datum/milla_safe/fire_heat_air/on_run(obj/effect/fire/fire, turf/T)
Expand All @@ -79,6 +91,7 @@ GLOBAL_LIST_EMPTY(flame_effects)
duration -= 10 SECONDS
if(duration <= 0)
fizzle()
update_icon(UPDATE_ICON_STATE)

/obj/effect/fire/proc/on_atom_entered(datum/source, atom/movable/entered, old_loc)
SIGNAL_HANDLER // COMSIG_ATOM_ENTERED
Expand Down
49 changes: 43 additions & 6 deletions code/modules/atmospherics/machinery/portable/portable_pump.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

/// The maximum `target_pressure` you can set on the pump. Equates to about 1013.25 kPa.
#define MAX_TARGET_PRESSURE 10 * ONE_ATMOSPHERE
/// The maximum `target_pressure` you can set on the pump.
#define MAX_TARGET_PRESSURE 45 * ONE_ATMOSPHERE
/// The pump will be siphoning gas.
#define DIRECTION_IN 0
/// The pump will be pumping gas out.
Expand All @@ -9,7 +9,9 @@
/obj/machinery/atmospherics/portable/pump
name = "portable air pump"
icon = 'icons/obj/atmos.dmi'
icon_state = "psiphon:0"
icon_state = "ppump:0"
base_icon_state = "ppump"
var/base_attachment_icon_state = "ppump"
density = TRUE
volume = 1000
/// The direction the pump is operating in. This should be either `DIRECTION_IN` or `DIRECTION_OUT`.
Expand All @@ -18,6 +20,12 @@
target_pressure = 101.325
resistance_flags = NONE

/obj/machinery/atmospherics/portable/pump/Initialize(mapload)
. = ..()
// Fill with normal air.
air_contents.set_oxygen(MAX_TARGET_PRESSURE * O2STANDARD * volume / (T20C * R_IDEAL_GAS_EQUATION))
air_contents.set_nitrogen(MAX_TARGET_PRESSURE * N2STANDARD * volume / (T20C * R_IDEAL_GAS_EQUATION))

/obj/machinery/atmospherics/portable/pump/examine(mob/user)
. = ..()
. += "<span class='notice'>Invaluable for filling air in a room rapidly after a breach repair. The internal gas container can be filled by \
Expand All @@ -26,14 +34,14 @@
A tank of gas can also be attached to the air pump, allowing you to fill or empty the tank, via the internal one.</span>"

/obj/machinery/atmospherics/portable/pump/update_icon_state()
icon_state = "psiphon:[on]"
icon_state = "[base_icon_state]:[on]"

/obj/machinery/atmospherics/portable/pump/update_overlays()
. = ..()
if(holding_tank)
. += "siphon-open"
. += "[base_attachment_icon_state]-open"
if(connected_port)
. += "siphon-connector"
. += "[base_attachment_icon_state]-connector"

/obj/machinery/atmospherics/portable/pump/emp_act(severity)
if(stat & (BROKEN|NOPOWER))
Expand Down Expand Up @@ -166,6 +174,7 @@
direction = DIRECTION_OUT
if(on && holding_tank)
investigate_log("[key_name(usr)] started a transfer into [holding_tank].<br>", "atmos")
update_icon()
return TRUE

if("remove_tank")
Expand All @@ -179,6 +188,34 @@

add_fingerprint(usr)

/obj/machinery/atmospherics/portable/pump/big
name = "large portable air pump"
icon_state = "ppump_big:0"
base_icon_state = "ppump_big"
base_attachment_icon_state = "ppump_big"
volume = 5000

/obj/machinery/atmospherics/portable/pump/big/examine(mob/user)
. = ..()
. += "<br><span class='notice'>This one is quite large, enabling it to hold more air.</span>"

/obj/machinery/atmospherics/portable/pump/bluespace
name = "bluespace portable air pump"
icon_state = "ppump_bs:0"
base_icon_state = "ppump_bs"
base_attachment_icon_state = "ppump_big"
volume = 25000

/obj/machinery/atmospherics/portable/pump/bluespace/examine(mob/user)
. = ..()
. += "<br><span class='notice'>This one is not only large, but made of exotic materials, and uses bluespace technology to hold even more air.</span>"

/obj/machinery/atmospherics/portable/pump/bluespace/update_icon_state()
if(on && direction == DIRECTION_IN)
icon_state = "[base_icon_state]:[on]-r"
else
icon_state = "[base_icon_state]:[on]"

#undef MAX_TARGET_PRESSURE
#undef DIRECTION_IN
#undef DIRECTION_OUT
4 changes: 2 additions & 2 deletions code/modules/atmospherics/machinery/portable/scrubber.dm
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@
/obj/machinery/atmospherics/portable/scrubber/update_overlays()
. = ..()
if(holding_tank)
. += "scrubber-open"
. += "pscrubber-open"
if(connected_port)
. += "scrubber-connector"
. += "pscrubber-connector"

/obj/machinery/atmospherics/portable/scrubber/process_atmos()
..()
Expand Down
4 changes: 4 additions & 0 deletions code/modules/reagents/chemistry/reagents/pyrotechnic.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
taste_description = "burning"
burn_temperature = T0C + 500
burn_duration = 20 SECONDS
burn_color = "white"
var/temp_fire = 4000
var/temp_deviance = 1000
var/size_divisor = 40
Expand Down Expand Up @@ -46,6 +47,7 @@
size_divisor = 80
mob_burning = 3 // 15
burn_temperature = T0C + 700
burn_color = "white"

/datum/reagent/napalm
name = "Napalm"
Expand Down Expand Up @@ -198,6 +200,7 @@
taste_description = "rust"
burn_temperature = T0C + 1500 // hahahahHAHAHAHAH LET IT BURN
burn_duration = 5 SECONDS // Not for long though
burn_color = "blue" // too hot!

/datum/reagent/thermite/reaction_mob(mob/living/M, method= REAGENT_TOUCH, volume)
if(method == REAGENT_TOUCH)
Expand Down Expand Up @@ -253,6 +256,7 @@
burn_temperature = T0C + 700
burn_duration = 15 SECONDS
fire_stack_applications = 3
burn_color = "green"

/datum/reagent/clf3/on_mob_life(mob/living/M)
if(M.on_fire)
Expand Down
2 changes: 2 additions & 0 deletions code/modules/reagents/chemistry/reagents_datum.dm
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
var/burn_duration = 30 SECONDS
/// How many firestacks will the reagent apply when it is burning? Currently only used for chemical flamethrowers
var/fire_stack_applications = 1
/// If we burn in a fire, what color do we have?
var/burn_color

/datum/reagent/Destroy()
. = ..()
Expand Down
Loading
Loading