Files
VOREStation/code/modules/admin/verbs/lightning_strike.dm
Cameron Lennox 84dc5535dc var/global/list -> GLOB. conversion (#17928)
* These two are easy

* !!!runlevel_flags

the fact it was global.runlevel_flags.len has me a bit...iffy on this.

* !!!json_cache

Same as above. used global.

* player_list & observer_mob_list

* mechas_list

* this wasn't even used

* surgery_steps

* event_triggers

* landmarks_list

* dead_mob_list

* living_mob_list

* ai_list

* cable_list

* cleanbot_reserved_turfs

* listening_objects

* silicon_mob_list

* human_mob_list

* Update global_lists.dm

* joblist

* mob_list

* Update global_lists.dm

* holomap_markers

* mapping_units

* mapping_beacons

* hair_styles_list

* facial_hair_styles_list

* Update global_lists.dm

* facial_hair_styles_male_list

* facial_hair_styles_female_list

* body_marking_styles_list

* body_marking_nopersist_list

* ear_styles_list

* hair_styles_male_list

* tail_styles_list

* wing_styles_list

* escape_list & rune_list & endgame_exits

these were all really small

* endgame_safespawns

* stool_cache

* emotes_by_key

* random_maps & map_count

* item_tf_spawnpoints

* narsie_list

* active_radio_jammers

* unused

* paikeys

* pai_software_by_key & default_pai_software

* plant_seed_sprites

* magazine_icondata_keys  & magazine_icondata_states

* unused

* ashtray_cache

* light_type_cache

* HOLIDAY!!!

this one was annoying

* faction stuff (red?!)

* Update preferences_factions.dm

* vs edit removal

* backbaglist, pdachoicelist, exclude_jobs

* item_digestion_blacklist, edible_tech, blacklisted_artifact_effect, selectable_footstep, hexNums, syndicate_access

* string_slot_flags and hexdigits->hexNums

* possible_changeling_IDs

* vr_mob_tf_options

* vr_mob_spawner_options

* pipe_colors

* vr_mob_spawner_options

* common_tools

* newscaster_standard_feeds

* Update periodic_news.dm

* changeling_fabricated_clothing

* semirandom_mob_spawner_decisions

* id_card_states

* Update syndicate_ids.dm

* overlay_cache & gear_distributed_to

* more

* radio_channels_by_freq

* Update global_lists.dm

* proper

* default_medbay_channels & default_internal_channels

default_internal_channels is weird as it has a mapbased proc() but that proc is never called...

* valid_ringtones

* move this

* possible_plants

* more

* separate these

moves xeno2chemlist from a hook to a new global list.

* tube_dir_list

* valid_bloodreagents & monitor_states

* Junk

* valid_bloodtypes

* breach_burn_descriptors & burn

* more!!

appliance_available_recipes seems uber cursed, re-look at later

* Appliance code is cursed

* wide_chassis & flying_chassis

* allows_eye_color

* all_tooltip_styles

* direction_table

* gun_choices

* severity_to_string

* old event_viruses

* description_icons

* MOVE_KEY_MAPPINGS

* more more

* pai & robot modules

* Update global_lists.dm

* GEOSAMPLES

Also swaps a .len to LAZYLEN()

* shieldgens

* reagent recipies

* global ammo types

* rad collector

* old file and unused global

* nif_look_messages

* FESH

* nifsoft

* chamelion

* the death of sortAtom

* globulins

* lazylen that

* Update global_lists.dm

* LAZY

* Theese too

* quick fix

---------

Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
2025-07-14 20:14:31 +02:00

101 lines
4.2 KiB
Plaintext

/client/proc/admin_lightning_strike()
set name = "Lightning Strike"
set desc = "Causes lightning to strike on your tile. This can be made to hurt things on or nearby it severely."
set category = "Fun.Do Not"
if(!check_rights(R_FUN))
return
var/result = tgui_alert(src, "Really strike your tile with lightning?", "Confirm Badmin" , list("No", "Yes (Cosmetic)", "Yes (Real)"))
if(!result || result == "No")
return
var/fake_lightning = result == "Yes (Cosmetic)"
lightning_strike(get_turf(usr), fake_lightning)
log_and_message_admins("has caused [fake_lightning ? "cosmetic":"harmful"] lightning to strike at their position ([src.mob.x], [src.mob.y], [src.mob.z]). \
(<A href='byond://?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[src.mob.x];Y=[src.mob.y];Z=[src.mob.z]'>JMP</a>)", src)
#define LIGHTNING_REDIRECT_RANGE 28 // How far in tiles certain things draw lightning from.
#define LIGHTNING_ZAP_RANGE 1 // How far the tesla effect zaps, as well as the bad effects from a direct strike.
#define LIGHTNING_POWER 20000 // How much 'zap' is in a strike, used for tesla_zap().
// The real lightning proc.
// This is global until I can figure out a better place for it.
// T is the turf that is being struck. If cosmetic is true, the lightning won't actually hurt anything.
/proc/lightning_strike(turf/T, cosmetic = FALSE)
// First, visuals.
// Do a lightning flash for the whole planet, if the turf belongs to a planet.
var/datum/planet/P = null
P = LAZYACCESS(SSplanets.z_to_planet, T.z)
if(P)
var/datum/weather_holder/holder = P.weather_holder
flick("lightning_flash", holder.special_visuals)
// Before we do the other visuals, we need to see if something is going to hijack our intended target.
var/obj/machinery/power/grounding_rod/ground = null // Most of the bad effects of lightning will get negated if a grounding rod is nearby.
var/obj/machinery/power/tesla_coil/coil = null // However a tesla coil has higher priority and the strike will bounce.
for(var/obj/machinery/power/thing in range(LIGHTNING_REDIRECT_RANGE, T))
if(istype(thing, /obj/machinery/power/tesla_coil))
var/turf/simulated/coil_turf = get_turf(thing)
if(istype(coil_turf) && thing.anchored && coil_turf.is_outdoors())
coil = thing
break
if(istype(thing, /obj/machinery/power/grounding_rod))
var/turf/simulated/rod_turf = get_turf(thing)
if(istype(rod_turf) && thing.anchored && rod_turf.is_outdoors())
ground = thing
if(coil) // Coil gets highest priority.
T = coil.loc
else if(ground)
T = ground.loc
// Now make the lightning strike sprite. It will fade and delete itself in a second.
new /obj/effect/temporary_effect/lightning_strike(T)
// For those close up.
playsound(T, 'sound/effects/lightningbolt.ogg', 100, 1)
// And for those far away. If the strike happens on a planet, everyone on the planet will hear it.
// Otherwise only those on the current z-level will hear it.
var/sound = get_sfx("thunder")
for(var/mob/M in GLOB.player_list)
if( (P && (M.z in P.expected_z_levels)) || M.z == T.z)
if(M.check_sound_preference(/datum/preference/toggle/weather_sounds))
M.playsound_local(get_turf(M), soundin = sound, vol = 70, vary = FALSE, is_global = TRUE)
if(cosmetic) // Everything beyond here involves potentially damaging things. If we don't want to do that, stop now.
return
if(ground) // All is well.
ground.tesla_act(LIGHTNING_POWER, FALSE)
return
else if(coil) // Otherwise lets bounce off the tesla coil.
coil.tesla_act(LIGHTNING_POWER, TRUE)
else // Striking the turf directly.
tesla_zap(T, zap_range = LIGHTNING_ZAP_RANGE, power = LIGHTNING_POWER, explosive = FALSE, stun_mobs = TRUE)
// Some extra effects.
// Some apply to those within zap range, others if they were a bit farther away.
for(var/mob/living/L in view(5, T))
if(get_dist(L, T) <= LIGHTNING_ZAP_RANGE) // They probably got zapped.
L.lightning_act()
// Deafen them.
if(L.get_ear_protection() < 2)
L.AdjustSleeping(-100)
if(iscarbon(L))
var/mob/living/carbon/C = L
C.ear_deaf += 10
to_chat(L, span_danger("Lightning struck nearby, and the thunderclap is deafening!"))
#undef LIGHTNING_REDIRECT_RANGE
#undef LIGHTNING_ZAP_RANGE
#undef LIGHTNING_POWER