# Conflicts:
#	code/modules/ninja/suit/ninjaDrainAct.dm
This commit is contained in:
zerothebigboy
2021-05-02 22:47:39 -04:00
448 changed files with 310031 additions and 306315 deletions
+29 -48
View File
@@ -308,10 +308,10 @@
var/list/areas_with_LS = list()
var/list/areas_with_intercom = list()
var/list/areas_with_camera = list()
var/list/station_areas_blacklist = typecacheof(list(/area/holodeck/rec_center, /area/shuttle, /area/engine/supermatter, /area/science/test_area, /area/space, /area/solar, /area/mine, /area/ruin, /area/asteroid))
var/list/station_areas_blacklist = typecacheof(list(/area/holodeck/rec_center, /area/shuttle, /area/engineering/supermatter, /area/science/test_area, /area/space, /area/solars, /area/mine, /area/ruin, /area/asteroid))
if(SSticker.current_state == GAME_STATE_STARTUP)
to_chat(usr, "Game still loading, please hold!")
to_chat(usr, "Game still loading, please hold!", confidential = TRUE)
return
var/log_message
@@ -326,8 +326,11 @@
for(var/area/A in world)
if(on_station)
var/turf/picked = safepick(get_area_turfs(A.type))
if(picked && is_station_level(picked.z))
var/list/area_turfs = get_area_turfs(A.type)
if (!length(area_turfs))
continue
var/turf/picked = pick(area_turfs)
if(is_station_level(picked.z))
if(!(A.type in areas_all) && !is_type_in_typecache(A, station_areas_blacklist))
areas_all.Add(A.type)
else if(!(A.type in areas_all))
@@ -481,74 +484,52 @@
set name = "Test Areas (ALL)"
cmd_admin_areatest(FALSE)
/client/proc/cmd_admin_dress(mob/M in GLOB.mob_list)
set category = "Admin.Events"
set name = "Select equipment"
if(!(ishuman(M) || isobserver(M)))
alert("Invalid mob")
return
var/dresscode = robust_dress_shop()
if(!dresscode)
return
var/delete_pocket
var/mob/living/carbon/human/H
if(isobserver(M))
H = M.change_mob_type(/mob/living/carbon/human, null, null, TRUE)
else
H = M
if(alert("Drop Items in Pockets? No will delete them.", "Robust quick dress shop", "Yes", "No") == "No")
delete_pocket = TRUE
SSblackbox.record_feedback("tally", "admin_verb", 1, "Select Equipment") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
for (var/obj/item/I in H.get_equipped_items(delete_pocket))
qdel(I)
if(dresscode != "Naked")
H.equipOutfit(dresscode)
H.regenerate_icons()
log_admin("[key_name(usr)] changed the equipment of [key_name(H)] to [dresscode].")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] changed the equipment of [ADMIN_LOOKUPFLW(H)] to [dresscode].</span>")
/client/proc/robust_dress_shop()
var/list/outfits = list("Cancel","Naked","Custom","As Job...")
var/list/paths = subtypesof(/datum/outfit) - typesof(/datum/outfit/job)
var/list/baseoutfits = list("Naked","Custom","As Job...", "As Plasmaman...")
var/list/outfits = list()
var/list/paths = subtypesof(/datum/outfit) - typesof(/datum/outfit/job) - typesof(/datum/outfit/plasmaman)
for(var/path in paths)
var/datum/outfit/O = path //not much to initalize here but whatever
if(initial(O.can_be_admin_equipped))
outfits[initial(O.name)] = path
outfits[initial(O.name)] = path
var/dresscode = input("Select outfit", "Robust quick dress shop") as null|anything in outfits
var/dresscode = input("Select outfit", "Robust quick dress shop") as null|anything in baseoutfits + sortList(outfits)
if (isnull(dresscode))
return
if (outfits[dresscode])
dresscode = outfits[dresscode]
if(dresscode == "Cancel")
return
if (dresscode == "As Job...")
var/list/job_paths = subtypesof(/datum/outfit/job)
var/list/job_outfits = list()
for(var/path in job_paths)
var/datum/outfit/O = path
if(initial(O.can_be_admin_equipped))
job_outfits[initial(O.name)] = path
job_outfits[initial(O.name)] = path
dresscode = input("Select job equipment", "Robust quick dress shop") as null|anything in job_outfits
dresscode = input("Select job equipment", "Robust quick dress shop") as null|anything in sortList(job_outfits)
dresscode = job_outfits[dresscode]
if(isnull(dresscode))
return
if (dresscode == "As Plasmaman...")
var/list/plasmaman_paths = typesof(/datum/outfit/plasmaman)
var/list/plasmaman_outfits = list()
for(var/path in plasmaman_paths)
var/datum/outfit/O = path
plasmaman_outfits[initial(O.name)] = path
dresscode = input("Select plasmeme equipment", "Robust quick dress shop") as null|anything in sortList(plasmaman_outfits)
dresscode = plasmaman_outfits[dresscode]
if(isnull(dresscode))
return
if (dresscode == "Custom")
var/list/custom_names = list()
for(var/datum/outfit/D in GLOB.custom_outfits)
custom_names[D.name] = D
var/selected_name = input("Select outfit", "Robust quick dress shop") as null|anything in custom_names
var/selected_name = input("Select outfit", "Robust quick dress shop") as null|anything in sortList(custom_names)
dresscode = custom_names[selected_name]
if(isnull(dresscode))
return
+2
View File
@@ -48,6 +48,8 @@
if(C.prefs.toggles & SOUND_PRAYERS)
if(usr.job == "Chaplain")
SEND_SOUND(C, sound('sound/effects/pray.ogg'))
else
SEND_SOUND(C, sound('sound/effects/ding.ogg'))
to_chat(usr, "<span class='info'>You pray to the gods: \"[msg_tmp]\"</span>", confidential = TRUE)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Prayer") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+49 -2
View File
@@ -879,8 +879,6 @@ Traitors and the like can also be revived with the previous role mostly intact.
message_admins("[ADMIN_LOOKUPFLW(usr)] [N.timing ? "activated" : "deactivated"] a nuke at [ADMIN_VERBOSEJMP(N)].")
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Nuke", "[N.timing]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
/client/proc/create_outfits()
set category = "Debug"
set name = "Create Custom Outfit"
@@ -1547,6 +1545,55 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
msg += "</UL></BODY></HTML>"
src << browse(msg.Join(), "window=Player_playtime_check")
/obj/effect/temp_visual/fireball
icon = 'icons/obj/wizard.dmi'
icon_state = "fireball"
name = "fireball"
desc = "Get out of the way!"
layer = FLY_LAYER
randomdir = FALSE
duration = 9
pixel_z = 270
/obj/effect/temp_visual/fireball/Initialize()
. = ..()
animate(src, pixel_z = 0, time = duration)
/obj/effect/temp_visual/target
icon = 'icons/mob/actions/actions_items.dmi'
icon_state = "sniper_zoom"
layer = BELOW_MOB_LAYER
light_range = 2
duration = 9
/obj/effect/temp_visual/target/ex_act()
return
/obj/effect/temp_visual/target/Initialize(mapload, list/flame_hit)
. = ..()
INVOKE_ASYNC(src, .proc/fall, flame_hit)
/obj/effect/temp_visual/target/proc/fall(list/flame_hit)
var/turf/T = get_turf(src)
playsound(T,'sound/magic/fleshtostone.ogg', 80, 1)
new /obj/effect/temp_visual/fireball(T)
sleep(duration)
if(ismineralturf(T))
var/turf/closed/mineral/M = T
M.gets_drilled()
playsound(T, "explosion", 80, 1)
new /obj/effect/hotspot(T)
T.hotspot_expose(700, 50, 1)
for(var/mob/living/L in T.contents)
if(istype(L, /mob/living/simple_animal/hostile/megafauna/dragon))
continue
if(islist(flame_hit) && !flame_hit[L])
L.adjustFireLoss(40)
to_chat(L, "<span class='userdanger'>You're hit by the drake's fire breath!</span>")
flame_hit[L] = TRUE
else
L.adjustFireLoss(10) //if we've already hit them, do way less damage
/datum/admins/proc/cmd_show_exp_panel(client/client_to_check)
if(!check_rights(R_ADMIN))
return
+1 -1
View File
@@ -349,7 +349,7 @@
return
SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Egalitarian Station"))
for(var/obj/machinery/door/airlock/W in GLOB.machines)
if(is_station_level(W.z) && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison))
if(is_station_level(W.z) && !istype(get_area(W), /area/command) && !istype(get_area(W), /area/commons) && !istype(get_area(W), /area/service) && !istype(get_area(W), /area/command/heads_quarters) && !istype(get_area(W), /area/security/prison))
W.req_access = list()
message_admins("[key_name_admin(holder)] activated Egalitarian Station mode")
priority_announce("CentCom airlock control override activated. Please take this time to get acquainted with your coworkers.", null, "commandreport")
+227
View File
@@ -0,0 +1,227 @@
/client/proc/cmd_select_equipment(mob/target in GLOB.mob_list)
set category = "Admin.Events"
set name = "Select equipment"
var/datum/select_equipment/ui = new(usr, target)
ui.ui_interact(usr)
/*
* This is the datum housing the select equipment UI.
*
* You may notice some oddities about the way outfits are passed to the UI and vice versa here.
* That's because it handles both outfit typepaths (for normal outfits) *and* outfit objects (for custom outfits).
*
* Custom outfits need to be objects as they're created in runtime.
* "Then just handle the normal outfits as objects too and simplify the handling" - you may say.
* There are about 300 outfit types at the time of writing this. Initializing all of these to objects would be a huge waste.
*
*/
/datum/select_equipment
var/client/user
var/mob/target_mob
var/dummy_key
//static list to share all the outfit typepaths between all instances of this datum.
var/static/list/cached_outfits
//a typepath if the selected outfit is a normal outfit;
//an object if the selected outfit is a custom outfit
var/datum/outfit/selected_outfit = /datum/outfit
//serializable string for the UI to keep track of which outfit is selected
var/selected_identifier = "/datum/outfit"
/datum/select_equipment/New(_user, mob/target)
user = CLIENT_FROM_VAR(_user)
if(!ishuman(target) && !isobserver(target))
alert("Invalid mob")
return
target_mob = target
/datum/select_equipment/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "SelectEquipment", "Select Equipment")
ui.open()
ui.set_autoupdate(FALSE)
/datum/select_equipment/ui_state(mob/user)
return GLOB.admin_state
/datum/select_equipment/ui_status(mob/user, datum/ui_state/state)
if(QDELETED(target_mob))
return UI_CLOSE
return ..()
/datum/select_equipment/ui_close(mob/user)
clear_human_dummy(dummy_key)
qdel(src)
/datum/select_equipment/proc/init_dummy()
dummy_key = "selectequipmentUI_[target_mob]"
generate_dummy_lookalike(dummy_key, target_mob)
unset_busy_human_dummy(dummy_key)
return
/**
* Packs up data about an outfit as an assoc list to send to the UI as an outfit entry.
*
* Args:
* * category (string) - The tab it will be under
*
* * identifier (typepath or ref) - This will sent this back to ui_act to preview or spawn in an outfit.
* * Must be unique between all entries.
*
* * name (string) - Will be the text on the button
*
* * priority (bool)(optional) - If True, the UI will sort the entry to the top, right below favorites.
*
* * custom_entry (bool)(optional) - Send the identifier with a "ref" keyword instead of "path",
* * for the UI to tell apart custom outfits from normal ones.
*
* Returns (list) An outfit entry
*/
/datum/select_equipment/proc/outfit_entry(category, identifier, name, priority=FALSE, custom_entry=FALSE)
if(custom_entry)
return list("category" = category, "ref" = identifier, "name" = name, "priority" = priority)
return list("category" = category, "path" = identifier, "name" = name, "priority" = priority)
/datum/select_equipment/proc/make_outfit_entries(category="General", list/outfit_list)
var/list/entries = list()
for(var/path as anything in outfit_list)
var/datum/outfit/outfit = path
entries += list(outfit_entry(category, path, initial(outfit.name)))
return entries
//GLOB.custom_outfits lists outfit *objects* so we'll need to do some custom handling for it
/datum/select_equipment/proc/make_custom_outfit_entries(list/outfit_list)
var/list/entries = list()
for(var/datum/outfit/outfit as anything in outfit_list)
entries += list(outfit_entry("Custom", REF(outfit), outfit.name, custom_entry=TRUE)) //it's either this or special handling on the UI side
return entries
/datum/select_equipment/ui_data(mob/user)
var/list/data = list()
if(!dummy_key)
init_dummy()
var/icon/dummysprite = get_flat_human_icon(null,
dummy_key = dummy_key,
outfit_override = selected_outfit,
no_anim = TRUE)
data["icon64"] = icon2base64(dummysprite)
data["name"] = target_mob
var/datum/preferences/prefs = user?.client?.prefs
data["favorites"] = list()
if(prefs)
data["favorites"] = prefs.favorite_outfits
var/list/custom
custom += make_custom_outfit_entries(GLOB.custom_outfits)
data["custom_outfits"] = custom
data["current_outfit"] = selected_identifier
return data
/datum/select_equipment/ui_static_data(mob/user)
var/list/data = list()
if(!cached_outfits)
cached_outfits = list()
cached_outfits += list(outfit_entry("General", /datum/outfit, "Naked", priority=TRUE))
cached_outfits += make_outfit_entries("General", subtypesof(/datum/outfit) - typesof(/datum/outfit/job) - typesof(/datum/outfit/plasmaman))
cached_outfits += make_outfit_entries("Jobs", typesof(/datum/outfit/job))
cached_outfits += make_outfit_entries("Plasmamen Outfits", typesof(/datum/outfit/plasmaman))
data["outfits"] = cached_outfits
return data
/datum/select_equipment/proc/resolve_outfit(text)
var/path = text2path(text)
if(ispath(path, /datum/outfit))
return path
else //don't bail yet - could be a custom outfit
var/datum/outfit/custom_outfit = locate(text)
if(istype(custom_outfit))
return custom_outfit
/datum/select_equipment/ui_act(action, params)
if(..())
return
. = TRUE
switch(action)
if("preview")
var/datum/outfit/new_outfit = resolve_outfit(params["path"])
if(ispath(new_outfit)) //got a typepath - that means we're dealing with a normal outfit
selected_identifier = new_outfit //these are keyed by type
//by the way, no, they can't be keyed by name because many of them have duplicate names
else if(istype(new_outfit)) //got an initialized object - means it's a custom outfit
selected_identifier = REF(new_outfit) //and the outfit will be keyed by its ref (cause its type will always be /datum/outfit)
else //we got nothing and should bail
return
selected_outfit = new_outfit
if("applyoutfit")
var/datum/outfit/new_outfit = resolve_outfit(params["path"])
if(new_outfit && ispath(new_outfit)) //initialize it
new_outfit = new new_outfit
if(!istype(new_outfit))
return
user.admin_apply_outfit(target_mob, new_outfit)
if("customoutfit")
user.outfit_manager()
if("togglefavorite")
var/datum/outfit/outfit_path = resolve_outfit(params["path"])
if(!ispath(outfit_path)) //we do *not* want custom outfits (i.e objects) here, they're not even persistent
return
if(user.prefs.favorite_outfits.Find(outfit_path)) //already there, remove it
user.prefs.favorite_outfits -= outfit_path
else //not there, add it
user.prefs.favorite_outfits += outfit_path
user.prefs.save_preferences()
/client/proc/admin_apply_outfit(mob/target, dresscode)
if(!ishuman(target) && !isobserver(target))
alert("Invalid mob")
return
if(!dresscode)
return
var/delete_pocket
var/mob/living/carbon/human/human_target
if(isobserver(target))
human_target = target.change_mob_type(/mob/living/carbon/human, delete_old_mob = TRUE)
else
human_target = target
if(human_target.l_store || human_target.r_store || human_target.s_store) //saves a lot of time for admins and coders alike
if(alert("Drop Items in Pockets? No will delete them.", "Robust quick dress shop", "Yes", "No") == "No")
delete_pocket = TRUE
SSblackbox.record_feedback("tally", "admin_verb", 1, "Select Equipment") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
for(var/obj/item/item in human_target.get_equipped_items(delete_pocket))
qdel(item)
if(dresscode != "Naked")
human_target.equipOutfit(dresscode)
human_target.regenerate_icons()
log_admin("[key_name(usr)] changed the equipment of [key_name(human_target)] to [dresscode].")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] changed the equipment of [ADMIN_LOOKUPFLW(human_target)] to [dresscode].</span>")
return dresscode