HELPERS
This commit is contained in:
@@ -101,7 +101,10 @@ Actual Adjacent procs :
|
||||
//sanitation
|
||||
var/turf/end = get_turf(_end)
|
||||
var/turf/start = get_turf(caller)
|
||||
if((!start)||(start.z != end.z)||(start == end)) //no pathfinding between z levels
|
||||
if(!start || !end)
|
||||
stack_trace("Invalid A* start or destination")
|
||||
return 0
|
||||
if( start.z != end.z || start == end ) //no pathfinding between z levels
|
||||
return 0
|
||||
if(maxnodes)
|
||||
//if start turf is farther than maxnodes from end turf, no need to do anything
|
||||
|
||||
@@ -20,6 +20,35 @@
|
||||
#define LAZYLEN(L) length(L)
|
||||
#define LAZYCLEARLIST(L) if(L) L.Cut()
|
||||
#define SANITIZE_LIST(L) ( islist(L) ? L : list() )
|
||||
#define reverseList(L) reverseRange(L.Copy())
|
||||
|
||||
// binary search sorted insert
|
||||
// IN: Object to be inserted
|
||||
// LIST: List to insert object into
|
||||
// TYPECONT: The typepath of the contents of the list
|
||||
// COMPARE: The variable on the objects to compare
|
||||
#define BINARY_INSERT(IN, LIST, TYPECONT, COMPARE) \
|
||||
var/__BIN_CTTL = length(LIST);\
|
||||
if(!__BIN_CTTL) {\
|
||||
LIST += IN;\
|
||||
} else {\
|
||||
var/__BIN_LEFT = 1;\
|
||||
var/__BIN_RIGHT = __BIN_CTTL;\
|
||||
var/__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\
|
||||
var/##TYPECONT/__BIN_ITEM;\
|
||||
while(__BIN_LEFT < __BIN_RIGHT) {\
|
||||
__BIN_ITEM = LIST[__BIN_MID];\
|
||||
if(__BIN_ITEM.##COMPARE <= IN.##COMPARE) {\
|
||||
__BIN_LEFT = __BIN_MID + 1;\
|
||||
} else {\
|
||||
__BIN_RIGHT = __BIN_MID;\
|
||||
};\
|
||||
__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\
|
||||
};\
|
||||
__BIN_ITEM = LIST[__BIN_MID];\
|
||||
__BIN_MID = __BIN_ITEM.##COMPARE > IN.##COMPARE ? __BIN_MID : __BIN_MID + 1;\
|
||||
LIST.Insert(__BIN_MID, IN);\
|
||||
}
|
||||
|
||||
//Returns a list in plain english as a string
|
||||
/proc/english_list(list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" )
|
||||
@@ -460,8 +489,18 @@
|
||||
return l
|
||||
. = l.Copy()
|
||||
for(var/i = 1 to l.len)
|
||||
if(islist(.[i]))
|
||||
.[i] = .(.[i])
|
||||
var/key = .[i]
|
||||
if(isnum(key))
|
||||
// numbers cannot ever be associative keys
|
||||
continue
|
||||
var/value = .[key]
|
||||
if(islist(value))
|
||||
value = deepCopyList(value)
|
||||
.[key] = value
|
||||
if(islist(key))
|
||||
key = deepCopyList(key)
|
||||
.[i] = key
|
||||
.[key] = value
|
||||
|
||||
//takes an input_key, as text, and the list of keys already used, outputting a replacement key in the format of "[input_key] ([number_of_duplicates])" if it finds a duplicate
|
||||
//use this for lists of things that might have the same name, like mobs or objects, that you plan on giving to a player as input
|
||||
|
||||
+100
-12
@@ -44,6 +44,7 @@
|
||||
WRITE_LOG(GLOB.world_game_log, "ADMINPRIVATE: [text]")
|
||||
|
||||
/proc/log_adminsay(text)
|
||||
GLOB.admin_log.Add(text)
|
||||
if (CONFIG_GET(flag/log_adminchat))
|
||||
WRITE_LOG(GLOB.world_game_log, "ADMINPRIVATE: ASAY: [text]")
|
||||
|
||||
@@ -103,6 +104,10 @@
|
||||
//reusing the PDA option because I really don't think news comments are worth a config option
|
||||
WRITE_LOG(GLOB.world_pda_log, "COMMENT: [text]")
|
||||
|
||||
/proc/log_telecomms(text)
|
||||
if (CONFIG_GET(flag/log_telecomms))
|
||||
WRITE_LOG(GLOB.world_telecomms_log, "TCOMMS: [text]")
|
||||
|
||||
/proc/log_chat(text)
|
||||
if (CONFIG_GET(flag/log_pda))
|
||||
//same thing here
|
||||
@@ -134,7 +139,9 @@
|
||||
|
||||
/* Log to both DD and the logfile. */
|
||||
/proc/log_world(text)
|
||||
#ifdef USE_CUSTOM_ERROR_HANDLER
|
||||
WRITE_LOG(GLOB.world_runtime_log, text)
|
||||
#endif
|
||||
SEND_TEXT(world.log, text)
|
||||
|
||||
/* Log to the logfile only. */
|
||||
@@ -157,19 +164,100 @@
|
||||
|
||||
|
||||
/* Helper procs for building detailed log lines */
|
||||
/proc/datum_info_line(datum/D)
|
||||
if(!istype(D))
|
||||
return
|
||||
if(!ismob(D))
|
||||
return "[D] ([D.type])"
|
||||
var/mob/M = D
|
||||
return "[M] ([M.ckey]) ([M.type])"
|
||||
/proc/key_name(whom, include_link = null, include_name = TRUE)
|
||||
var/mob/M
|
||||
var/client/C
|
||||
var/key
|
||||
var/ckey
|
||||
var/fallback_name
|
||||
|
||||
/proc/atom_loc_line(atom/A)
|
||||
if(!whom)
|
||||
return "*null*"
|
||||
if(istype(whom, /client))
|
||||
C = whom
|
||||
M = C.mob
|
||||
key = C.key
|
||||
ckey = C.ckey
|
||||
else if(ismob(whom))
|
||||
M = whom
|
||||
C = M.client
|
||||
key = M.key
|
||||
ckey = M.ckey
|
||||
else if(istext(whom))
|
||||
key = whom
|
||||
ckey = ckey(whom)
|
||||
C = GLOB.directory[ckey]
|
||||
if(C)
|
||||
M = C.mob
|
||||
else if(istype(whom,/datum/mind))
|
||||
var/datum/mind/mind = whom
|
||||
key = mind.key
|
||||
ckey = ckey(key)
|
||||
if(mind.current)
|
||||
M = mind.current
|
||||
if(M.client)
|
||||
C = M.client
|
||||
else
|
||||
fallback_name = mind.name
|
||||
else // Catch-all cases if none of the types above match
|
||||
var/swhom = null
|
||||
|
||||
if(istype(whom, /atom))
|
||||
var/atom/A = whom
|
||||
swhom = "[A.name]"
|
||||
else if(istype(whom, /datum))
|
||||
swhom = "[whom]"
|
||||
|
||||
if(!swhom)
|
||||
swhom = "*invalid*"
|
||||
|
||||
return "\[[swhom]\]"
|
||||
|
||||
. = ""
|
||||
|
||||
if(!ckey)
|
||||
include_link = FALSE
|
||||
|
||||
if(key)
|
||||
if(C && C.holder && C.holder.fakekey && !include_name)
|
||||
if(include_link)
|
||||
. += "<a href='?priv_msg=[C.findStealthKey()]'>"
|
||||
. += "Administrator"
|
||||
else
|
||||
if(include_link)
|
||||
. += "<a href='?priv_msg=[ckey]'>"
|
||||
. += key
|
||||
if(!C)
|
||||
. += "\[DC\]"
|
||||
|
||||
if(include_link)
|
||||
. += "</a>"
|
||||
else
|
||||
. += "*no key*"
|
||||
|
||||
if(include_name)
|
||||
if(M)
|
||||
if(M.real_name)
|
||||
. += "/([M.real_name])"
|
||||
else if(M.name)
|
||||
. += "/([M.name])"
|
||||
else if(fallback_name)
|
||||
. += "/([fallback_name])"
|
||||
|
||||
return .
|
||||
|
||||
/proc/key_name_admin(whom, include_name = TRUE)
|
||||
return key_name(whom, TRUE, include_name)
|
||||
|
||||
/proc/loc_name(atom/A)
|
||||
if(!istype(A))
|
||||
return
|
||||
var/turf/T = get_turf(A)
|
||||
return "(INVALID LOCATION)"
|
||||
|
||||
var/turf/T = A
|
||||
if (!istype(T))
|
||||
T = get_turf(A)
|
||||
|
||||
if(istype(T))
|
||||
return "[A.loc] [COORD(T)] ([A.loc.type])"
|
||||
return "([AREACOORD(T)])"
|
||||
else if(A.loc)
|
||||
return "[A.loc] (0, 0, 0) ([A.loc.type])"
|
||||
return "(UNKNOWN (?, ?, ?))"
|
||||
|
||||
+13
-10
@@ -3,7 +3,8 @@
|
||||
// Gets an atmos isolated contained space
|
||||
// Returns an associative list of turf|dirs pairs
|
||||
// The dirs are connected turfs in the same space
|
||||
// break_if_found is a typecache of turf types to return false if found
|
||||
// break_if_found is a typecache of turf/area types to return false if found
|
||||
// Please keep this proc type agnostic. If you need to restrict it do it elsewhere or add an arg.
|
||||
/proc/detect_room(turf/origin, list/break_if_found)
|
||||
if(origin.blocks_air)
|
||||
return list(origin)
|
||||
@@ -13,10 +14,6 @@
|
||||
var/list/found_turfs = list(origin)
|
||||
while(found_turfs.len)
|
||||
var/turf/sourceT = found_turfs[1]
|
||||
if(break_if_found[sourceT.type])
|
||||
return FALSE
|
||||
if (istype(sourceT.loc, /area/shuttle))
|
||||
return FALSE
|
||||
found_turfs.Cut(1, 2)
|
||||
var/dir_flags = checked_turfs[sourceT]
|
||||
for(var/dir in GLOB.alldirs)
|
||||
@@ -29,18 +26,24 @@
|
||||
checked_turfs[checkT] |= turn(dir, 180)
|
||||
.[sourceT] |= dir
|
||||
.[checkT] |= turn(dir, 180)
|
||||
if(break_if_found[checkT.type] || break_if_found[checkT.loc.type])
|
||||
return FALSE
|
||||
var/static/list/cardinal_cache = list("[NORTH]"=TRUE, "[EAST]"=TRUE, "[SOUTH]"=TRUE, "[WEST]"=TRUE)
|
||||
if(!cardinal_cache["[dir]"] || checkT.blocks_air || !CANATMOSPASS(sourceT, checkT))
|
||||
continue
|
||||
found_turfs += checkT // Since checkT is connected, add it to the list to be processed
|
||||
|
||||
/proc/create_area(mob/creator)
|
||||
var/static/blacklisted_turfs = typecacheof(/turf/open/space)
|
||||
var/static/blacklisted_areas = typecacheof(list(
|
||||
/area/space,
|
||||
// Passed into the above proc as list/break_if_found
|
||||
var/static/area_or_turf_fail_types = typecacheof(list(
|
||||
/turf/open/space,
|
||||
/area/shuttle,
|
||||
))
|
||||
var/list/turfs = detect_room(get_turf(creator), blacklisted_turfs)
|
||||
// Ignore these areas and dont let people expand them. They can expand into them though
|
||||
var/static/blacklisted_areas = typecacheof(list(
|
||||
/area/space,
|
||||
))
|
||||
var/list/turfs = detect_room(get_turf(creator), area_or_turf_fail_types)
|
||||
if(!turfs)
|
||||
to_chat(creator, "<span class='warning'>The new area must be completely airtight and not a part of a shuttle.</span>")
|
||||
return
|
||||
@@ -50,7 +53,7 @@
|
||||
var/list/areas = list("New Area" = /area)
|
||||
for(var/i in 1 to turfs.len)
|
||||
var/area/place = get_area(turfs[i])
|
||||
if(blacklisted_areas[place.type] || istype(place, /area/shuttle))
|
||||
if(blacklisted_areas[place.type])
|
||||
continue
|
||||
if(!place.requires_power || place.noteleport || place.hidden)
|
||||
continue // No expanding powerless rooms etc
|
||||
|
||||
@@ -350,7 +350,7 @@
|
||||
/proc/flick_overlay(image/I, list/show_to, duration)
|
||||
for(var/client/C in show_to)
|
||||
C.images += I
|
||||
addtimer(CALLBACK(GLOBAL_PROC, /.proc/remove_images_from_clients, I, show_to), duration, TIMER_CLIENT_TIME)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, /proc/remove_images_from_clients, I, show_to), duration, TIMER_CLIENT_TIME)
|
||||
|
||||
/proc/flick_overlay_view(image/I, atom/target, duration) //wrapper for the above, flicks to everyone who can see the target atom
|
||||
var/list/viewing = list()
|
||||
|
||||
@@ -1027,15 +1027,17 @@ GLOBAL_LIST_EMPTY(friendly_animal_types)
|
||||
return 0
|
||||
|
||||
//For creating consistent icons for human looking simple animals
|
||||
/proc/get_flat_human_icon(icon_id, datum/job/J, datum/preferences/prefs, dummy_key, showDirs = GLOB.cardinals)
|
||||
/proc/get_flat_human_icon(icon_id, datum/job/J, datum/preferences/prefs, dummy_key, showDirs = GLOB.cardinals, outfit_override = null)
|
||||
var/static/list/humanoid_icon_cache = list()
|
||||
if(!icon_id || !humanoid_icon_cache[icon_id])
|
||||
var/mob/living/carbon/human/dummy/body = generate_or_wait_for_human_dummy(dummy_key)
|
||||
|
||||
if(prefs)
|
||||
prefs.copy_to(body)
|
||||
prefs.copy_to(body,TRUE,FALSE)
|
||||
if(J)
|
||||
J.equip(body, TRUE, FALSE)
|
||||
J.equip(body, TRUE, FALSE, outfit_override = outfit_override)
|
||||
else if (outfit_override)
|
||||
body.equipOutfit(outfit_override,visualsOnly = TRUE)
|
||||
|
||||
|
||||
var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing")
|
||||
|
||||
@@ -14,4 +14,4 @@
|
||||
#define is_away_level(z) SSmapping.level_trait(z, ZTRAIT_AWAY)
|
||||
|
||||
// If true, the singularity cannot strip away asteroid turf on this Z
|
||||
#define is_planet_level(z) (GLOB.z_is_planet["z"])
|
||||
#define is_planet_level(z) SSmapping.level_trait(z, ZTRAIT_PLANET)
|
||||
|
||||
@@ -266,65 +266,6 @@ GLOBAL_LIST_EMPTY(species_list)
|
||||
else
|
||||
return "unknown"
|
||||
|
||||
/*
|
||||
Proc for attack log creation, because really why not
|
||||
1 argument is the actor
|
||||
2 argument is the target of action
|
||||
3 is the description of action(like punched, throwed, or any other verb)
|
||||
4 is the tool with which the action was made(usually item) 4 and 5 are very similar(5 have "by " before it, that it) and are separated just to keep things in a bit more in order
|
||||
5 is additional information, anything that needs to be added
|
||||
*/
|
||||
|
||||
/proc/add_logs(mob/user, mob/target, what_done, object=null, addition=null)
|
||||
var/turf/attack_location = get_turf(target)
|
||||
|
||||
var/is_mob_user = user && ismob(user)
|
||||
var/is_mob_target = target && ismob(target)
|
||||
|
||||
var/mob/living/living_target
|
||||
|
||||
if(target && isliving(target))
|
||||
living_target = target
|
||||
|
||||
var/hp =" "
|
||||
if(living_target)
|
||||
hp = " (NEWHP: [living_target.health]) "
|
||||
|
||||
var/starget = "NON-EXISTENT SUBJECT"
|
||||
if(target)
|
||||
if(is_mob_target && target.key)
|
||||
starget = "[target.name]([target.key])"
|
||||
else
|
||||
starget = "[target.name]"
|
||||
|
||||
var/ssource = "NON-EXISTENT USER" //How!?
|
||||
if(user)
|
||||
if(is_mob_user && user.key)
|
||||
ssource = "[user.name]([user.key])"
|
||||
else
|
||||
ssource = "[user.name]"
|
||||
|
||||
var/sobject = ""
|
||||
if(object)
|
||||
sobject = "[object]"
|
||||
if(addition)
|
||||
addition = " [addition]"
|
||||
|
||||
var/sattackloc = ""
|
||||
if(attack_location)
|
||||
sattackloc = "([attack_location.x],[attack_location.y],[attack_location.z])"
|
||||
|
||||
if(is_mob_user)
|
||||
var/message = "<font color='red'>has [what_done] [starget][(sobject||addition) ? " with ":""][sobject][addition][hp][sattackloc]</font>"
|
||||
user.log_message(message, INDIVIDUAL_ATTACK_LOG)
|
||||
|
||||
if(is_mob_target)
|
||||
var/message = "<font color='orange'>has been [what_done] by [ssource][(sobject||addition) ? " with ":""][sobject][addition][hp][sattackloc]</font>"
|
||||
target.log_message(message, INDIVIDUAL_ATTACK_LOG)
|
||||
|
||||
log_attack("[ssource] [what_done] [starget][(sobject||addition) ? " with ":""][sobject][addition][hp][sattackloc]")
|
||||
|
||||
|
||||
/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks = null)
|
||||
if(!user || !target)
|
||||
return 0
|
||||
@@ -573,42 +514,6 @@ Proc for attack log creation, because really why not
|
||||
else
|
||||
to_chat(M, message)
|
||||
|
||||
|
||||
/proc/log_talk(mob/user,message,logtype)
|
||||
var/turf/say_turf = get_turf(user)
|
||||
|
||||
var/sayloc = ""
|
||||
if(say_turf)
|
||||
sayloc = "([say_turf.x],[say_turf.y],[say_turf.z])"
|
||||
|
||||
|
||||
var/logmessage = "[message] [sayloc]"
|
||||
|
||||
switch(logtype)
|
||||
|
||||
if(LOGDSAY)
|
||||
log_dsay(logmessage)
|
||||
if(LOGSAY)
|
||||
log_say(logmessage)
|
||||
if(LOGWHISPER)
|
||||
log_whisper(logmessage)
|
||||
if(LOGEMOTE)
|
||||
log_emote(logmessage)
|
||||
if(LOGPDA)
|
||||
log_pda(logmessage)
|
||||
if(LOGCHAT)
|
||||
log_chat(logmessage)
|
||||
if(LOGCOMMENT)
|
||||
log_comment(logmessage)
|
||||
if(LOGASAY)
|
||||
log_adminsay(logmessage)
|
||||
if(LOGOOC)
|
||||
log_ooc(logmessage)
|
||||
log_looc(logmessage) //CITADEL EDIT, logging LOOC because why not
|
||||
else
|
||||
warning("Invalid speech logging type detected. [logtype]. Defaulting to say")
|
||||
log_say(logmessage)
|
||||
|
||||
//Used in chemical_mob_spawn. Generates a random mob based on a given gold_core_spawnable value.
|
||||
/proc/create_random_mob(spawn_location, mob_class = HOSTILE_SPAWN)
|
||||
var/static/list/mob_spawn_meancritters = list() // list of possible hostile mobs
|
||||
|
||||
+11
-13
@@ -1,26 +1,24 @@
|
||||
// A special GetAllContents that doesn't search past things with rad insulation
|
||||
// The protection var only protects the things inside from being affected.
|
||||
// The protecting object itself will get returned still.
|
||||
// Components which return COMPONENT_BLOCK_RADIATION prevent further searching into that object's contents. The object itself will get returned still.
|
||||
// The ignore list makes those objects never return at all
|
||||
/proc/get_rad_contents(atom/location)
|
||||
var/static/list/ignored_things = typecacheof(list(
|
||||
/mob/dead,
|
||||
/mob/camera,
|
||||
/obj/effect,
|
||||
/obj/docking_port,
|
||||
/atom/movable/lighting_object,
|
||||
/obj/item/projectile,
|
||||
))
|
||||
var/list/processing_list = list(location)
|
||||
. = list()
|
||||
while(processing_list.len)
|
||||
var/static/list/ignored_things = typecacheof(list(
|
||||
/mob/dead,
|
||||
/mob/camera,
|
||||
/obj/effect,
|
||||
/obj/docking_port,
|
||||
/atom/movable/lighting_object,
|
||||
/obj/item/projectile
|
||||
))
|
||||
var/atom/thing = processing_list[1]
|
||||
processing_list -= thing
|
||||
if(ignored_things[thing.type])
|
||||
continue
|
||||
. += thing
|
||||
var/datum/component/rad_insulation/insulation = thing.GetComponent(/datum/component/rad_insulation)
|
||||
if(insulation && insulation.protects)
|
||||
if(SEND_SIGNAL(thing, COMSIG_ATOM_RAD_PROBE) & COMPONENT_BLOCK_RADIATION)
|
||||
continue
|
||||
processing_list += thing.contents
|
||||
|
||||
@@ -43,5 +41,5 @@
|
||||
log = TRUE
|
||||
if(log)
|
||||
var/turf/_source_T = isturf(source) ? source : get_turf(source)
|
||||
log_game("Radiation pulse with intensity: [intensity] and range modifier: [range_modifier] in [AREACOORD(_source_T)] ")
|
||||
log_game("Radiation pulse with intensity: [intensity] and range modifier: [range_modifier] in [loc_name(_source_T)] ")
|
||||
return TRUE
|
||||
@@ -194,7 +194,7 @@
|
||||
|
||||
send2irc("Server", "Round just ended.")
|
||||
|
||||
if(length(CONFIG_GET(keyed_string_list/cross_server)))
|
||||
if(length(CONFIG_GET(keyed_list/cross_server)))
|
||||
send_news_report()
|
||||
|
||||
CHECK_TICK
|
||||
@@ -271,6 +271,10 @@
|
||||
var/list/parts = list()
|
||||
var/station_evacuated = EMERGENCY_ESCAPED_OR_ENDGAMED
|
||||
|
||||
if(GLOB.round_id)
|
||||
var/statspage = CONFIG_GET(string/roundstatsurl)
|
||||
var/info = statspage ? "<a href='?action=openLink&link=[url_encode(statspage)][GLOB.round_id]'>[GLOB.round_id]</a>" : GLOB.round_id
|
||||
parts += "[GLOB.TAB]Round ID: <b>[info]</b>"
|
||||
parts += "[GLOB.TAB]Shift Duration: <B>[DisplayTimeText(world.time - SSticker.round_start_time)]</B>"
|
||||
parts += "[GLOB.TAB]Station Integrity: <B>[mode.station_was_nuked ? "<span class='redtext'>Destroyed</span>" : "[popcount["station_integrity"]]%"]</B>"
|
||||
var/total_players = GLOB.joined_player_list.len
|
||||
@@ -518,10 +522,20 @@
|
||||
return objective_parts.Join("<br>")
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/save_admin_data()
|
||||
if(IsAdminAdvancedProcCall())
|
||||
to_chat(usr, "<span class='admin prefix'>Admin rank DB Sync blocked: Advanced ProcCall detected.</span>")
|
||||
return
|
||||
if(CONFIG_GET(flag/admin_legacy_system)) //we're already using legacy system so there's nothing to save
|
||||
return
|
||||
else if(load_admins(TRUE)) //returns true if there was a database failure and the backup was loaded from
|
||||
return
|
||||
sync_ranks_with_db()
|
||||
var/list/sql_admins = list()
|
||||
for(var/datum/admins/A in GLOB.protected_admins)
|
||||
var/sql_ckey = sanitizeSQL(A.owner.ckey)
|
||||
var/sql_rank = sanitizeSQL(A.rank.name)
|
||||
sql_admins = list(list("ckey" = "'[sql_ckey]'", "rank" = "'[sql_rank]'"))
|
||||
SSdbcore.MassInsert(format_table_name("admin"), sql_admins, duplicate_key = TRUE)
|
||||
var/datum/DBQuery/query_admin_rank_update = SSdbcore.NewQuery("UPDATE [format_table_name("player")] p INNER JOIN [format_table_name("admin")] a ON p.ckey = a.ckey SET p.lastadminrank = a.rank")
|
||||
query_admin_rank_update.Execute()
|
||||
qdel(query_admin_rank_update)
|
||||
@@ -543,3 +557,29 @@
|
||||
file_data["admins"]["[i]"] = A.rank.name
|
||||
fdel(json_file)
|
||||
WRITE_FILE(json_file, json_encode(file_data))
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/update_everything_flag_in_db()
|
||||
for(var/datum/admin_rank/R in GLOB.admin_ranks)
|
||||
var/list/flags = list()
|
||||
if(R.include_rights == R_EVERYTHING)
|
||||
flags += "flags"
|
||||
if(R.exclude_rights == R_EVERYTHING)
|
||||
flags += "exclude_flags"
|
||||
if(R.can_edit_rights == R_EVERYTHING)
|
||||
flags += "can_edit_flags"
|
||||
if(!flags.len)
|
||||
continue
|
||||
var/sql_rank = sanitizeSQL(R.name)
|
||||
var/flags_to_check = flags.Join(" != [R_EVERYTHING] AND ") + " != [R_EVERYTHING]"
|
||||
var/datum/DBQuery/query_check_everything_ranks = SSdbcore.NewQuery("SELECT flags, exclude_flags, can_edit_flags FROM [format_table_name("admin_ranks")] WHERE rank = '[sql_rank]' AND ([flags_to_check])")
|
||||
if(!query_check_everything_ranks.Execute())
|
||||
qdel(query_check_everything_ranks)
|
||||
return
|
||||
if(query_check_everything_ranks.NextRow()) //no row is returned if the rank already has the correct flag value
|
||||
var/flags_to_update = flags.Join(" = [R_EVERYTHING], ") + " = [R_EVERYTHING]"
|
||||
var/datum/DBQuery/query_update_everything_ranks = SSdbcore.NewQuery("UPDATE [format_table_name("admin_ranks")] SET [flags_to_update] WHERE rank = '[sql_rank]'")
|
||||
if(!query_update_everything_ranks.Execute())
|
||||
qdel(query_update_everything_ranks)
|
||||
return
|
||||
qdel(query_update_everything_ranks)
|
||||
qdel(query_check_everything_ranks)
|
||||
|
||||
@@ -372,80 +372,6 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
return "[round(units * 0.000001, 0.001)] MJ"
|
||||
return "[round(units * 0.000000001, 0.0001)] GJ"
|
||||
|
||||
/proc/key_name(whom, include_link = null, include_name = 1)
|
||||
var/mob/M
|
||||
var/client/C
|
||||
var/key
|
||||
var/ckey
|
||||
var/fallback_name
|
||||
|
||||
if(!whom)
|
||||
return "*null*"
|
||||
if(istype(whom, /client))
|
||||
C = whom
|
||||
M = C.mob
|
||||
key = C.key
|
||||
ckey = C.ckey
|
||||
else if(ismob(whom))
|
||||
M = whom
|
||||
C = M.client
|
||||
key = M.key
|
||||
ckey = M.ckey
|
||||
else if(istext(whom))
|
||||
key = whom
|
||||
ckey = ckey(whom)
|
||||
C = GLOB.directory[ckey]
|
||||
if(C)
|
||||
M = C.mob
|
||||
else if(istype(whom,/datum/mind))
|
||||
var/datum/mind/mind = whom
|
||||
key = mind.key
|
||||
ckey = ckey(key)
|
||||
if(mind.current)
|
||||
M = mind.current
|
||||
if(M.client)
|
||||
C = M.client
|
||||
else
|
||||
fallback_name = mind.name
|
||||
else
|
||||
return "*invalid*"
|
||||
|
||||
. = ""
|
||||
|
||||
if(!ckey)
|
||||
include_link = 0
|
||||
|
||||
if(key)
|
||||
if(C && C.holder && C.holder.fakekey && !include_name)
|
||||
if(include_link)
|
||||
. += "<a href='?priv_msg=[C.findStealthKey()]'>"
|
||||
. += "Administrator"
|
||||
else
|
||||
if(include_link)
|
||||
. += "<a href='?priv_msg=[ckey]'>"
|
||||
. += key
|
||||
if(!C)
|
||||
. += "\[DC\]"
|
||||
|
||||
if(include_link)
|
||||
. += "</a>"
|
||||
else
|
||||
. += "*no key*"
|
||||
|
||||
if(include_name)
|
||||
if(M)
|
||||
if(M.real_name)
|
||||
. += "/([M.real_name])"
|
||||
else if(M.name)
|
||||
. += "/([M.name])"
|
||||
else if(fallback_name)
|
||||
. += "/([fallback_name])"
|
||||
|
||||
return .
|
||||
|
||||
/proc/key_name_admin(whom, include_name = 1)
|
||||
return key_name(whom, 1, include_name)
|
||||
|
||||
/proc/get_mob_by_ckey(key)
|
||||
if(!key)
|
||||
return
|
||||
@@ -651,14 +577,9 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
//Takes: Area type as a text string from a variable.
|
||||
//Returns: Instance for the area in the world.
|
||||
/proc/get_area_instance_from_text(areatext)
|
||||
var/areainstance = null
|
||||
if(istext(areatext))
|
||||
areatext = text2path(areatext)
|
||||
for(var/V in GLOB.sortedAreas)
|
||||
var/area/A = V
|
||||
if(A.type == areatext)
|
||||
areainstance = V
|
||||
return areainstance
|
||||
return GLOB.areas_by_type[areatext]
|
||||
|
||||
//Takes: Area type as text string or as typepath OR an instance of the area.
|
||||
//Returns: A list of all areas of that type in the world.
|
||||
@@ -1349,7 +1270,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
var/ready_to_die = FALSE
|
||||
|
||||
/mob/dview/Initialize() //Properly prevents this mob from gaining huds or joining any global lists
|
||||
return
|
||||
return INITIALIZE_HINT_NORMAL
|
||||
|
||||
/mob/dview/Destroy(force = FALSE)
|
||||
if(!ready_to_die)
|
||||
@@ -1538,6 +1459,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
/obj/item/reagent_containers/food/snacks/soup,
|
||||
/obj/item/reagent_containers/food/snacks/grown,
|
||||
/obj/item/reagent_containers/food/snacks/grown/mushroom,
|
||||
/obj/item/reagent_containers/food/snacks/grown/nettle, // base type
|
||||
/obj/item/reagent_containers/food/snacks/deepfryholder
|
||||
)
|
||||
blocked |= typesof(/obj/item/reagent_containers/food/snacks/customizable)
|
||||
@@ -1545,7 +1467,10 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
||||
return pick(typesof(/obj/item/reagent_containers/food/snacks) - blocked)
|
||||
|
||||
/proc/get_random_drink()
|
||||
return pick(subtypesof(/obj/item/reagent_containers/food/drinks))
|
||||
var/list/blocked = list(/obj/item/reagent_containers/food/drinks/soda_cans,
|
||||
/obj/item/reagent_containers/food/drinks/bottle
|
||||
)
|
||||
return pick(subtypesof(/obj/item/reagent_containers/food/drinks) - blocked)
|
||||
|
||||
//For these two procs refs MUST be ref = TRUE format like typecaches!
|
||||
/proc/weakref_filter_list(list/things, list/refs)
|
||||
|
||||
Reference in New Issue
Block a user