mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-18 03:26:31 +01:00
The Spectre-Meter App, also a bootleg data disk item for the black market. (#80188)
## About The Pull Request This PR adds in a new app that scans the nearby area for "spookiness" (e.g. presence of ghosts, mobs with the spirit biotype, objects made with hauntium or containing hauntium). A bit clunky by all means. It's a maintenance app, and as such is more often found in the rare maintenance computer disks, or downloadable from emagged PDAs (IIRC), or perhaps the black market item which I've also added here as well, that might contain it amongst other things. Oh, if you also have the camera app, it'll let you take pictures of ghosts like the 'camera obscura' does. Oh, and there's also a maintenance version of the arcade program too; just , like, lazier and easier. ## Why It's Good For The Game Mostly a shower thought, 'cause I felt the idea maintenance disks to be quite interesting yet lackluster, almost too niche. As for the remote thought of using the app for validhunting, it isn't something you can reliably get every and every other round, and if someone's got enough ghosts circling them, chances are they're some big, loud antag or doing something so cheeky, that they kinda deserve it. Also, yeah, more black market stuff. Except for the misc section, it's pretty lacking in uniqueness. Screenshot of the UI, taken at the distance of one tile from a revenant:  ## Changelog 🆑 add: The Spectre-Meter modular computer app. A little, amatuerishly coded app that, as the name implies, scan an area for spectral presence. It can be found amongst other apps in maintenance computer disks. add: An easier, lazier version of the Arcade app, also found in maintenance. add: Black market computer disks, which contains programs not readily available to the average assistant. /🆑 --------- Co-authored-by: Jacquerel <hnevard@gmail.com>
This commit is contained in:
@@ -23,6 +23,20 @@
|
||||
///Determines which boss image to use on the UI.
|
||||
var/boss_id = 1
|
||||
|
||||
///Lazy version of the arade that can be found in maintenance disks
|
||||
/datum/computer_file/program/arcade/eazy
|
||||
filename = "dsarcadeez"
|
||||
filedesc = "Donksoft Micro Arcade Ez"
|
||||
filetype = "MNT"
|
||||
program_flags = PROGRAM_UNIQUE_COPY
|
||||
extended_desc = "Some sort of fan-made conversion of the classic game 'Outbomb Cuban Pete'. This one has you fight the weaker 'George Melon' instead."
|
||||
boss_hp = 40
|
||||
boss_mp = 10
|
||||
player_hp = 35
|
||||
player_mp = 15
|
||||
heads_up = "Are you a bad enough dude to grief the station?"
|
||||
boss_name = "George Melon"
|
||||
|
||||
/datum/computer_file/program/arcade/proc/game_check(mob/user)
|
||||
sleep(0.5 SECONDS)
|
||||
user?.mind?.adjust_experience(/datum/skill/gaming, 1)
|
||||
@@ -159,9 +173,9 @@
|
||||
return TRUE
|
||||
if("Start_Game")
|
||||
game_active = TRUE
|
||||
boss_hp = 45
|
||||
player_hp = 30
|
||||
player_mp = 10
|
||||
boss_hp = initial(boss_hp)
|
||||
player_hp = initial(player_hp)
|
||||
player_mp = initial(player_mp)
|
||||
heads_up = "You stand before [boss_name]! Prepare for battle!"
|
||||
program_open_overlay = "arcade"
|
||||
boss_id = rand(1,6)
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
if(internal_picture)
|
||||
QDEL_NULL(internal_picture)
|
||||
var/turf/our_turf = get_turf(tapped_atom)
|
||||
var/spooky_camera = locate(/datum/computer_file/program/maintenance/spectre_meter) in computer.stored_files
|
||||
internal_camera.see_ghosts = spooky_camera ? CAMERA_SEE_GHOSTS_BASIC : CAMERA_NO_GHOSTS
|
||||
internal_picture = internal_camera.captureimage(our_turf, user, internal_camera.picture_size_x + 1, internal_camera.picture_size_y + 1)
|
||||
picture_number++
|
||||
computer.save_photo(internal_picture.picture_image)
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/maintenance/modsuit_control/proc/unsync_modsuit(atom/source)
|
||||
SIGNAL_HANDLER
|
||||
UnregisterSignal(controlled_suit, COMSIG_QDELETING)
|
||||
controlled_suit = null
|
||||
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
|
||||
#define SPOOK_VALUE_SAME_TURF_MULT 1.5
|
||||
#define SPOOK_VALUE_LIVING_MULT 6
|
||||
#define SPOOK_VALUE_DEF_MOB 10
|
||||
#define SPOOK_VALUE_ICON_STATE_MAX 120
|
||||
#define SPOOK_VALUE_SEGMENT 15
|
||||
|
||||
/datum/computer_file/program/maintenance/spectre_meter
|
||||
filename = "spectre_meter"
|
||||
filedesc = "Spectre-Meter"
|
||||
power_cell_use = PROGRAM_BASIC_CELL_USE * 2
|
||||
downloader_category = PROGRAM_CATEGORY_EQUIPMENT
|
||||
extended_desc = "A program used to somehow detect nearby spectral presence. Combine with the camera app to take photos of ghosts."
|
||||
size = 7
|
||||
can_run_on_flags = PROGRAM_LAPTOP|PROGRAM_PDA
|
||||
tgui_id = "NtosSpectreMeter"
|
||||
program_icon = "ghost"
|
||||
program_open_overlay = "spectre_meter_0"
|
||||
/// The cooldown for manual scans
|
||||
COOLDOWN_DECLARE(manual_scan_cd)
|
||||
/// Whether the automatic scan mode is active or not
|
||||
var/auto_mode = FALSE
|
||||
/// The value reported by the last scan.
|
||||
var/last_spook_value = 0
|
||||
var/datum/looping_sound/spectre_meter/soundloop
|
||||
|
||||
/datum/computer_file/program/maintenance/spectre_meter/on_start(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
soundloop = new()
|
||||
|
||||
/datum/computer_file/program/maintenance/spectre_meter/kill_program()
|
||||
QDEL_NULL(soundloop)
|
||||
auto_mode = FALSE
|
||||
last_spook_value = 0
|
||||
program_open_overlay = "spectre_meter_0"
|
||||
power_cell_use = PROGRAM_BASIC_CELL_USE
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
return ..()
|
||||
|
||||
/datum/computer_file/program/maintenance/spectre_meter/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["spook_value"] = last_spook_value
|
||||
data["auto_mode"] = auto_mode
|
||||
data["on_cooldown"] = !COOLDOWN_FINISHED(src, manual_scan_cd)
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/maintenance/spectre_meter/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
switch(action)
|
||||
if("manual_scan")
|
||||
if(COOLDOWN_FINISHED(src, manual_scan_cd))
|
||||
INVOKE_ASYNC(src, PROC_REF(scan_surroundings))
|
||||
COOLDOWN_START(src, manual_scan_cd, 2 SECONDS)
|
||||
playsound(computer, 'sound/effects/ping_hit.ogg', vol = 40, vary = TRUE)
|
||||
return TRUE
|
||||
if("toggle_mode")
|
||||
auto_mode = !auto_mode
|
||||
if(auto_mode)
|
||||
///We want SSprocess. It fires twice as fast than the standard SSobjs used by [computer_file/program/process_tick]
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
soundloop.start(computer)
|
||||
else
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
soundloop.stop(TRUE)
|
||||
power_cell_use = auto_mode ? PROGRAM_BASIC_CELL_USE * 3 : PROGRAM_BASIC_CELL_USE
|
||||
return TRUE
|
||||
|
||||
/datum/computer_file/program/maintenance/spectre_meter/process(seconds_per_tick)
|
||||
if(auto_mode)
|
||||
INVOKE_ASYNC(src, PROC_REF(scan_surroundings))
|
||||
|
||||
///Return the "spook level" of the area the computer is in.
|
||||
/datum/computer_file/program/maintenance/spectre_meter/proc/scan_surroundings()
|
||||
var/spook_value = 0
|
||||
var/turf/turf = get_turf(computer)
|
||||
|
||||
for(var/atom/atom as anything in range(5, turf))
|
||||
var/spook_amount = 0
|
||||
if(ismob(atom))
|
||||
///ghastly mobs count toward spookiness more than observers.
|
||||
var/spook_value_mult = 0
|
||||
if(isliving(atom))
|
||||
var/mob/living/living = atom
|
||||
if(living.mob_biotypes & MOB_SPIRIT)
|
||||
spook_value_mult = SPOOK_VALUE_LIVING_MULT
|
||||
else if(isobserver(atom))
|
||||
spook_value_mult = 1
|
||||
spook_amount += SPOOK_VALUE_DEF_MOB * spook_value_mult
|
||||
var/list/materials = atom.has_material_type(/datum/material/hauntium)
|
||||
if(materials)
|
||||
spook_amount += materials[/datum/material/hauntium]/SHEET_MATERIAL_AMOUNT
|
||||
spook_amount += atom.reagents?.get_reagent_amount(/datum/reagent/hauntium)/20
|
||||
if(!spook_amount)
|
||||
continue
|
||||
if(atom.loc == turf)
|
||||
spook_amount *= SPOOK_VALUE_SAME_TURF_MULT
|
||||
spook_value += spook_amount/max(get_dist(turf, atom), 1)
|
||||
CHECK_TICK
|
||||
|
||||
soundloop.last_spook_value = last_spook_value = round(spook_value)
|
||||
var/old_open_overlay = program_open_overlay
|
||||
program_open_overlay = "spectre_meter_[min(FLOOR(last_spook_value, SPOOK_VALUE_SEGMENT), SPOOK_VALUE_ICON_STATE_MAX)]"
|
||||
if(program_open_overlay != old_open_overlay)
|
||||
computer.update_appearance(UPDATE_OVERLAYS)
|
||||
|
||||
/datum/looping_sound/spectre_meter
|
||||
mid_sounds = /datum/looping_sound/geiger::mid_sounds
|
||||
mid_length = 2
|
||||
volume = 12
|
||||
var/last_spook_value = 0
|
||||
|
||||
/datum/looping_sound/spectre_meter/get_sound()
|
||||
var/index = 1
|
||||
switch(last_spook_value)
|
||||
if(0 to 14)
|
||||
return null
|
||||
if(14 to 40)
|
||||
index = 1
|
||||
if(40 to 65)
|
||||
index = 2
|
||||
if(65 to 90)
|
||||
index = 3
|
||||
else
|
||||
index = 4
|
||||
return ..(mid_sounds[index])
|
||||
|
||||
/datum/looping_sound/spectre_meter/stop(null_parent = FALSE)
|
||||
last_spook_value = 0
|
||||
return ..()
|
||||
|
||||
#undef SPOOK_VALUE_SAME_TURF_MULT
|
||||
#undef SPOOK_VALUE_LIVING_MULT
|
||||
#undef SPOOK_VALUE_DEF_MOB
|
||||
#undef SPOOK_VALUE_ICON_STATE_MAX
|
||||
#undef SPOOK_VALUE_SEGMENT
|
||||
Reference in New Issue
Block a user