Files
Paradise/code/game/machinery/firealarm.dm
PollardTheDragonandGitHub 8f654dfcc7 Adds Kidan Ship Ruin (#32081)
* Kidan Warriors

* Linters

* Kidan mob AI adjustments and stat adjustments. Kidan Princess Megafauna

* Bug spray vulnerability

* Ragnarok props and kidan spear update

* The ship

* Fixes and adjustments

* Map update

* Linters
2026-06-24 21:49:27 +00:00

365 lines
11 KiB
Plaintext

/*
FIRE ALARM
*/
#define FIRE_ALARM_FRAME 0
#define FIRE_ALARM_UNWIRED 1
#define FIRE_ALARM_READY 2
/obj/machinery/firealarm
name = "fire alarm"
desc = "<i>\"Pull this in case of emergency\"</i>. Thus, keep pulling it forever."
icon = 'icons/obj/wallbumps/firealarm.dmi'
icon_state = "firealarm_off"
/// Whether or not the fire alarm will sound the alarm if its temperature rises above 200C
var/detecting = TRUE
var/working = TRUE
var/time = 10.0
var/timing = 0.0
anchored = TRUE
max_integrity = 250
integrity_failure = 100
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 100, FIRE = 90, ACID = 30)
idle_power_consumption = 2
active_power_consumption = 6
power_channel = PW_CHANNEL_ENVIRONMENT
resistance_flags = FIRE_PROOF
cares_about_temperature = TRUE
light_power = LIGHTING_MINIMUM_POWER
light_range = 7
light_color = "#ff3232"
var/wiresexposed = FALSE
var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone
var/report_fire_alarms = TRUE // Should triggered fire alarms also trigger an actual alarm?
var/show_alert_level = TRUE // Should fire alarms display the current alert level?
var/last_time_pulled //used to prevent pulling spam by same persons
/obj/machinery/firealarm/Initialize(mapload, direction, building)
. = ..()
if(building)
buildstage = 0
wiresexposed = TRUE
setDir(direction)
set_pixel_offsets_from_dir(26, -26, 26, -26)
var/area/our_area = get_area(src)
LAZYADD(our_area.firealarms, src)
if(is_station_contact(z))
RegisterSignal(SSsecurity_level, COMSIG_SECURITY_LEVEL_CHANGED, PROC_REF(on_security_level_update))
name = "fire alarm"
set_light(1, LIGHTING_MINIMUM_POWER) //for emissives
update_icon()
/obj/machinery/firealarm/no_alarm
report_fire_alarms = FALSE
/obj/machinery/firealarm/syndicate
report_fire_alarms = FALSE
show_alert_level = FALSE
/obj/machinery/firealarm/update_icon_state()
if(wiresexposed)
icon_state = "firealarm_b[buildstage]"
return
if(stat & BROKEN)
icon_state = "firealarm_broken"
return
if(stat & NOPOWER)
icon_state = "firealarm_off"
return
if(!detecting)
icon_state = "firealarm_detect"
return
else
icon_state = "firealarm_off"
/obj/machinery/firealarm/update_overlays()
. = ..()
underlays.Cut()
if(stat & (NOPOWER|BROKEN))
return
if(is_station_contact(z) && show_alert_level)
. += "overlay_[SSsecurity_level.get_current_level_as_text()]"
underlays += emissive_appearance(icon, "firealarm_overlay_lightmask")
if(!wiresexposed)
underlays += emissive_appearance(icon, "firealarm_detect")
var/area/area = get_area(src)
if(area.fire)
. += "firealarm_alarming"
return
/obj/machinery/firealarm/emag_act(mob/user)
if(!emagged)
emagged = TRUE
if(user)
user.visible_message(SPAN_WARNING("Sparks fly out of [src]!"),
SPAN_NOTICE("You emag [src], disabling its thermal sensors."))
playsound(loc, 'sound/effects/sparks4.ogg', 50, TRUE)
return TRUE
/obj/machinery/firealarm/temperature_expose(exposed_temperature, exposed_volume)
..()
if(!emagged && detecting && exposed_temperature > T0C + 200)
alarm() // added check of detector status here
/obj/machinery/firealarm/attack_ai(mob/user)
add_hiddenprint(user)
return attack_hand(user)
/obj/machinery/firealarm/attack_ghost(mob/user)
if(user.can_advanced_admin_interact())
toggle_alarm(user)
/obj/machinery/firealarm/emp_act(severity)
if(prob(50/severity))
alarm(rand(30/severity, 60/severity))
..()
/obj/machinery/firealarm/item_interaction(mob/living/user, obj/item/used, list/modifiers)
add_fingerprint(user)
if(!wiresexposed)
return ..()
if(buildstage == FIRE_ALARM_UNWIRED && istype(used, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/coil = used
if(!coil.use(5))
to_chat(user, SPAN_WARNING("You need a total of five cables to wire [src]!"))
return ITEM_INTERACT_COMPLETE
buildstage = FIRE_ALARM_READY
playsound(get_turf(src), used.usesound, 50, TRUE)
to_chat(user, SPAN_NOTICE("You wire [src]!"))
update_icon()
return ITEM_INTERACT_COMPLETE
if(buildstage == FIRE_ALARM_FRAME && istype(used, /obj/item/firealarm_electronics))
to_chat(user, SPAN_NOTICE("You insert the circuit!"))
qdel(used)
buildstage = FIRE_ALARM_UNWIRED
update_icon()
return ITEM_INTERACT_COMPLETE
return ..()
/obj/machinery/firealarm/crowbar_act(mob/user, obj/item/I)
if(buildstage != FIRE_ALARM_UNWIRED)
return
. = TRUE
if(!I.tool_use_check(user, 0))
return
CROWBAR_ATTEMPT_PRY_CIRCUIT_MESSAGE
if(!I.use_tool(src, user, 20, volume = I.tool_volume) || buildstage != FIRE_ALARM_UNWIRED)
return
new /obj/item/firealarm_electronics(drop_location())
buildstage = FIRE_ALARM_FRAME
update_icon()
CROWBAR_PRY_CIRCUIT_SUCCESS_MESSAGE
/obj/machinery/firealarm/multitool_act(mob/user, obj/item/I)
if(buildstage != FIRE_ALARM_READY)
return
. = TRUE
if(!wiresexposed)
to_chat(user, SPAN_WARNING("You need to expose the wires first!"))
return
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
detecting = !detecting
if(detecting)
user.visible_message(SPAN_WARNING("[user] has reconnected [src]'s detecting unit!"), "You have reconnected [src]'s detecting unit.")
else
user.visible_message(SPAN_WARNING("[user] has disconnected [src]'s detecting unit!"), "You have disconnected [src]'s detecting unit.")
/obj/machinery/firealarm/screwdriver_act(mob/user, obj/item/I)
if(buildstage != FIRE_ALARM_READY)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
wiresexposed = !wiresexposed
if(wiresexposed)
SCREWDRIVER_OPEN_PANEL_MESSAGE
else
SCREWDRIVER_CLOSE_PANEL_MESSAGE
update_icon()
/obj/machinery/firealarm/wirecutter_act(mob/user, obj/item/I)
if(buildstage != FIRE_ALARM_READY)
return
. = TRUE
if(!wiresexposed)
to_chat(user, SPAN_WARNING("You need to expose the wires first!"))
return
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
update_icon()
WIRECUTTER_SNIP_MESSAGE
var/obj/item/stack/cable_coil/new_coil = new /obj/item/stack/cable_coil(drop_location())
new_coil.amount = 5
buildstage = FIRE_ALARM_UNWIRED
/obj/machinery/firealarm/wrench_act(mob/user, obj/item/I)
if(buildstage != FIRE_ALARM_FRAME)
return
. = TRUE
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
return
WRENCH_UNANCHOR_WALL_MESSAGE
new /obj/item/mounted/frame/firealarm(get_turf(user))
qdel(src)
/obj/machinery/firealarm/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
if(.) //damage received
if(obj_integrity > 0 && !(stat & BROKEN) && buildstage != 0 && !emagged)
if(prob(33))
alarm()
/obj/machinery/firealarm/singularity_pull(S, current_size)
if(current_size >= STAGE_FIVE) // If the singulo is strong enough to pull anchored objects, the fire alarm experiences integrity failure
deconstruct()
..()
/obj/machinery/firealarm/obj_break(damage_flag)
if(!(stat & BROKEN) && !(flags & NODECONSTRUCT) && buildstage != 0) //can't break the electronics if there isn't any inside.
stat |= BROKEN
var/area/our_area = get_area(src)
LAZYREMOVE(our_area.firealarms, src)
update_icon()
/obj/machinery/firealarm/deconstruct(disassembled = TRUE)
if(!(flags & NODECONSTRUCT))
new /obj/item/stack/sheet/metal(loc, 1)
if(!(stat & BROKEN))
var/obj/item/I = new /obj/item/firealarm_electronics(loc)
if(!disassembled)
I.obj_integrity = I.max_integrity * 0.5
new /obj/item/stack/cable_coil(loc, 3)
qdel(src)
/obj/machinery/firealarm/proc/update_fire_light(fire)
if(stat & NOPOWER)
set_light(0)
return
else if(SSsecurity_level.get_current_level_as_number() == SEC_LEVEL_EPSILON)
set_light(2, 1, COLOR_WHITE)
return
else if(fire == !!light_power || fire == !!(light_power - 0.1))
return // do nothing if we're already active
if(fire)
set_light(l_power = 0.8)
else
set_light(l_power = LIGHTING_MINIMUM_POWER)
/obj/machinery/firealarm/proc/update_fire_sound(fire)
var/area/A = get_area(src)
if(stat & NOPOWER)
GLOB.firealarm_soundloop.stop(src, TRUE)
else if(A.fire)
GLOB.firealarm_soundloop.start(src)
/obj/machinery/firealarm/proc/on_security_level_update(datum/source, previous_level_number, new_level_number)
SIGNAL_HANDLER
update_icon()
update_fire_light()
/obj/machinery/firealarm/power_change()
if(!..())
return
update_fire_light()
update_icon()
update_fire_sound()
/obj/machinery/firealarm/attack_hand(mob/user)
if(stat & (NOPOWER|BROKEN) || buildstage != 2)
return 1
if(user.incapacitated())
return 1
if(fingerprintslast == user.ckey && world.time < last_time_pulled + 2 SECONDS) //no spamming >:C
to_chat(user, SPAN_WARNING("[src] is still processing your earlier command."))
return
toggle_alarm(user)
/obj/machinery/firealarm/proc/toggle_alarm(mob/user)
var/area/A = get_area(src)
if(istype(A))
add_fingerprint(user)
last_time_pulled = world.time
if(A.fire)
reset()
else
alarm()
/obj/machinery/firealarm/examine(mob/user)
. = ..()
switch(buildstage)
if(FIRE_ALARM_FRAME)
. += SPAN_NOTICE("It's missing a <i>circuit board<i> and the <b>bolts</b> are exposed.")
if(FIRE_ALARM_UNWIRED)
. += SPAN_NOTICE("The control board needs <i>wiring</i> and can be <b>pried out</b>.")
if(FIRE_ALARM_READY)
if(wiresexposed)
. += SPAN_NOTICE("The fire alarm's <b>wires</b> are exposed by the <i>unscrewed</i> panel.")
. += SPAN_NOTICE("The detection circuitry can be turned <b>[detecting ? "off" : "on"]</b> by <i>pulsing</i> the board.")
. += "It shows the alert level as: <B><U>[capitalize(SSsecurity_level.get_current_level_as_text())]</U></B>."
/obj/machinery/firealarm/proc/reset()
if(!working || !report_fire_alarms)
return
var/area/A = get_area(src)
A.firereset(src)
/obj/machinery/firealarm/proc/alarm()
if(!working || !report_fire_alarms)
return
var/area/A = get_area(src)
if(!A)
return
A.firealert(src) // Manually trigger alarms if the alarm isn't reported
/obj/machinery/firealarm/Destroy()
LAZYREMOVE(GLOB.firealarm_soundloop.output_atoms, src)
var/area/our_area = get_area(src)
LAZYREMOVE(our_area.firealarms, src)
return ..()
MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/firealarm, 32, 32)
MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/firealarm/no_alarm, 32, 32)
/*
FIRE ALARM CIRCUIT
Just a object used in constructing fire alarms
*/
/obj/item/firealarm_electronics
name = "fire alarm electronics"
icon = 'icons/obj/doors/door_assembly.dmi'
icon_state = "door_electronics"
desc = "A circuit. It has a label on it, it says \"Can handle heat levels up to 40 degrees celsius!\""
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL = 100, MAT_GLASS = 100)
origin_tech = "engineering=2;programming=1"
usesound = 'sound/items/deconstruct.ogg'
#undef FIRE_ALARM_FRAME
#undef FIRE_ALARM_UNWIRED
#undef FIRE_ALARM_READY