mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 04:30:44 +01:00
Merge remote-tracking branch 'tgstation/master' into disposal_destinations_v3
This commit is contained in:
@@ -80,8 +80,8 @@
|
||||
var/client/banned_client = banned_mob?.client
|
||||
var/banned_mob_guest_key = had_banned_mob && IsGuestKey(banned_mob.key)
|
||||
banned_mob = null
|
||||
|
||||
var/datum/DBQuery/query_add_ban_get_ckey = SSdbcore.NewQuery("SELECT 1 FROM [format_table_name("player")] WHERE ckey = '[ckey]'")
|
||||
var/sql_ckey = sanitizeSQL(ckey)
|
||||
var/datum/DBQuery/query_add_ban_get_ckey = SSdbcore.NewQuery("SELECT 1 FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'")
|
||||
if(!query_add_ban_get_ckey.warn_execute())
|
||||
qdel(query_add_ban_get_ckey)
|
||||
return
|
||||
@@ -123,9 +123,9 @@
|
||||
adminwho += ", [C]"
|
||||
|
||||
reason = sanitizeSQL(reason)
|
||||
|
||||
var/sql_a_ckey = sanitizeSQL(a_ckey)
|
||||
if(maxadminbancheck)
|
||||
var/datum/DBQuery/query_check_adminban_amt = SSdbcore.NewQuery("SELECT count(id) AS num FROM [format_table_name("ban")] WHERE (a_ckey = '[a_ckey]') AND (bantype = 'ADMIN_PERMABAN' OR (bantype = 'ADMIN_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
|
||||
var/datum/DBQuery/query_check_adminban_amt = SSdbcore.NewQuery("SELECT count(id) AS num FROM [format_table_name("ban")] WHERE (a_ckey = '[sql_a_ckey]') AND (bantype = 'ADMIN_PERMABAN' OR (bantype = 'ADMIN_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)")
|
||||
if(!query_check_adminban_amt.warn_execute())
|
||||
qdel(query_check_adminban_amt)
|
||||
return
|
||||
@@ -143,7 +143,12 @@
|
||||
computerid = "0"
|
||||
if(!ip)
|
||||
ip = "0.0.0.0"
|
||||
var/sql = "INSERT INTO [format_table_name("ban")] (`bantime`,`server_ip`,`server_port`,`round_id`,`bantype`,`reason`,`job`,`duration`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`) VALUES (Now(), INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]', '[bantype_str]', '[reason]', '[job]', [(duration)?"[duration]":"0"], Now() + INTERVAL [(duration>0) ? duration : 0] MINUTE, '[ckey]', '[computerid]', INET_ATON('[ip]'), '[a_ckey]', '[a_computerid]', INET_ATON('[a_ip]'), '[who]', '[adminwho]')"
|
||||
var/sql_job = sanitizeSQL(job)
|
||||
var/sql_computerid = sanitizeSQL(computerid)
|
||||
var/sql_ip = sanitizeSQL(ip)
|
||||
var/sql_a_computerid = sanitizeSQL(a_computerid)
|
||||
var/sql_a_ip = sanitizeSQL(a_ip)
|
||||
var/sql = "INSERT INTO [format_table_name("ban")] (`bantime`,`server_ip`,`server_port`,`round_id`,`bantype`,`reason`,`job`,`duration`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`) VALUES (Now(), INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]', '[bantype_str]', '[reason]', '[sql_job]', [(duration)?"[duration]":"0"], Now() + INTERVAL [(duration>0) ? duration : 0] MINUTE, '[sql_ckey]', '[sql_computerid]', INET_ATON('[sql_ip]'), '[sql_a_ckey]', '[sql_a_computerid]', INET_ATON('[sql_a_ip]'), '[who]', '[adminwho]')"
|
||||
var/datum/DBQuery/query_add_ban = SSdbcore.NewQuery(sql)
|
||||
if(!query_add_ban.warn_execute())
|
||||
qdel(query_add_ban)
|
||||
@@ -207,10 +212,11 @@
|
||||
bantype_sql = "(bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now() ) )"
|
||||
else
|
||||
bantype_sql = "bantype = '[bantype_str]'"
|
||||
|
||||
var/sql = "SELECT id FROM [format_table_name("ban")] WHERE ckey = '[ckey]' AND [bantype_sql] AND (unbanned is null OR unbanned = false)"
|
||||
var/sql_ckey = sanitizeSQL(ckey)
|
||||
var/sql = "SELECT id FROM [format_table_name("ban")] WHERE ckey = '[sql_ckey]' AND [bantype_sql] AND (unbanned is null OR unbanned = false)"
|
||||
if(job)
|
||||
sql += " AND job = '[job]'"
|
||||
var/sql_job = sanitizeSQL(job)
|
||||
sql += " AND job = '[sql_job]'"
|
||||
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
var/F = file("[GLOB.log_directory]/[subject].html")
|
||||
WRITE_FILE(F, "<small>[time_stamp()] [REF(src)] ([x],[y],[z])</small> || [src] [message]<br>")
|
||||
|
||||
/client/proc/investigate_show(subject in list("notes, memos, watchlist", INVESTIGATE_RESEARCH, INVESTIGATE_EXONET, INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS, INVESTIGATE_RADIATION, INVESTIGATE_CIRCUIT) )
|
||||
/client/proc/investigate_show(subject in list("notes, memos, watchlist", INVESTIGATE_RESEARCH, INVESTIGATE_EXONET, INVESTIGATE_PORTAL, INVESTIGATE_SINGULO, INVESTIGATE_WIRES, INVESTIGATE_TELESCI, INVESTIGATE_GRAVITY, INVESTIGATE_RECORDS, INVESTIGATE_CARGO, INVESTIGATE_SUPERMATTER, INVESTIGATE_ATMOS, INVESTIGATE_EXPERIMENTOR, INVESTIGATE_BOTANY, INVESTIGATE_HALLUCINATIONS, INVESTIGATE_RADIATION, INVESTIGATE_CIRCUIT, INVESTIGATE_NANITES) )
|
||||
set name = "Investigate"
|
||||
set category = "Admin"
|
||||
if(!holder)
|
||||
|
||||
@@ -35,9 +35,9 @@ GLOBAL_VAR(antag_prototypes)
|
||||
var/data_part = antag_panel_data()
|
||||
var/objective_part = antag_panel_objectives()
|
||||
var/memory_part = antag_panel_memory()
|
||||
|
||||
|
||||
var/list/parts = listtrim(list(command_part,data_part,objective_part,memory_part))
|
||||
|
||||
|
||||
return parts.Join("<br>")
|
||||
|
||||
/datum/antagonist/proc/antag_panel_objectives()
|
||||
@@ -80,7 +80,7 @@ GLOBAL_VAR(antag_prototypes)
|
||||
var/list/result = list()
|
||||
if(!current)
|
||||
result += "<span class='bad'>No body!</span>"
|
||||
if(current && current.isloyal())
|
||||
if(current && current.has_trait(TRAIT_MINDSHIELD))
|
||||
result += "<span class='good'>Mindshielded</span>"
|
||||
//Move these to mob
|
||||
if(iscyborg(current))
|
||||
@@ -155,8 +155,8 @@ GLOBAL_VAR(antag_prototypes)
|
||||
priority_sections |= antag_category
|
||||
antag_header_parts += "<span class='bad'>[current_antag.name]</span>"
|
||||
antag_header_parts += "<a href='?src=[REF(src)];remove_antag=[REF(current_antag)]'>Remove</a>"
|
||||
|
||||
|
||||
|
||||
|
||||
//We aren't antag of this category, grab first prototype to check the prefs (This is pretty vague but really not sure how else to do this)
|
||||
var/datum/antagonist/pref_source = current_antag
|
||||
if(!pref_source)
|
||||
@@ -167,7 +167,7 @@ GLOBAL_VAR(antag_prototypes)
|
||||
break
|
||||
if(pref_source.job_rank)
|
||||
antag_header_parts += pref_source.enabled_in_preferences(src) ? "Enabled in Prefs" : "Disabled in Prefs"
|
||||
|
||||
|
||||
//Traitor : None | Traitor | IAA
|
||||
// Command1 | Command2 | Command3
|
||||
// Secret Word : Banana
|
||||
@@ -180,12 +180,12 @@ GLOBAL_VAR(antag_prototypes)
|
||||
if(current_antag)
|
||||
cat_section += current_antag.antag_panel()
|
||||
sections[antag_category] = cat_section
|
||||
|
||||
|
||||
for(var/s in priority_sections)
|
||||
out += sections[s]
|
||||
for(var/s in sections - priority_sections)
|
||||
out += sections[s]
|
||||
|
||||
|
||||
out += "<br>"
|
||||
|
||||
//Uplink
|
||||
@@ -201,7 +201,7 @@ GLOBAL_VAR(antag_prototypes)
|
||||
else
|
||||
uplink_info += "<a href='?src=[REF(src)];common=uplink'>give</a>"
|
||||
uplink_info += "." //hiel grammar
|
||||
|
||||
|
||||
out += uplink_info + "<br>"
|
||||
//Common Memory
|
||||
var/common_memory = "<span>Common Memory:</span>"
|
||||
@@ -210,7 +210,7 @@ GLOBAL_VAR(antag_prototypes)
|
||||
out += common_memory + "<br>"
|
||||
//Other stuff
|
||||
out += get_common_admin_commands()
|
||||
|
||||
|
||||
var/datum/browser/panel = new(usr, "traitorpanel", "", 600, 600)
|
||||
panel.set_content(out)
|
||||
panel.open()
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
var/checktime = text2num(query_validate_time.item[1])
|
||||
if(!checktime)
|
||||
to_chat(src, "Datetime entered is improperly formatted or not later than current server time.")
|
||||
qdel(query_validate_time)
|
||||
return
|
||||
endtime = query_validate_time.item[1]
|
||||
qdel(query_validate_time)
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
var/checktime = text2num(query_validate_expire_time.item[1])
|
||||
if(!checktime)
|
||||
to_chat(usr, "Datetime entered is improperly formatted or not later than current server time.")
|
||||
qdel(query_validate_expire_time)
|
||||
return
|
||||
expiry = query_validate_expire_time.item[1]
|
||||
qdel(query_validate_expire_time)
|
||||
@@ -170,16 +171,19 @@
|
||||
message_id = text2num(message_id)
|
||||
if(!message_id)
|
||||
return
|
||||
var/datum/DBQuery/query_find_edit_expiry_message = SSdbcore.NewQuery("SELECT type, targetckey, adminckey, expire_timestamp FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
|
||||
var/editor_ckey = sanitizeSQL(usr.ckey)
|
||||
var/editor_key = sanitizeSQL(usr.key)
|
||||
var/kn = key_name(usr)
|
||||
var/kna = key_name_admin(usr)
|
||||
var/datum/DBQuery/query_find_edit_expiry_message = SSdbcore.NewQuery("SELECT type, (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = targetckey), (SELECT byond_key FROM [format_table_name("player")] WHERE ckey = adminckey), expire_timestamp FROM [format_table_name("messages")] WHERE id = [message_id] AND deleted = 0")
|
||||
if(!query_find_edit_expiry_message.warn_execute())
|
||||
qdel(query_find_edit_expiry_message)
|
||||
return
|
||||
if(query_find_edit_expiry_message.NextRow())
|
||||
var/type = query_find_edit_expiry_message.item[1]
|
||||
var/target_ckey = query_find_edit_expiry_message.item[2]
|
||||
var/admin_ckey = query_find_edit_expiry_message.item[3]
|
||||
var/target_key = query_find_edit_expiry_message.item[2]
|
||||
var/admin_key = query_find_edit_expiry_message.item[3]
|
||||
var/old_expiry = query_find_edit_expiry_message.item[4]
|
||||
var/editor_ckey = sanitizeSQL(usr.ckey)
|
||||
var/new_expiry
|
||||
var/expire_time = input("Set expiry time for [type] as format YYYY-MM-DD HH:MM:SS. All times in server time. HH:MM:SS is optional and 24-hour. Must be later than current time for obvious reasons. Enter -1 to remove expiry time.", "Set expiry time", old_expiry) as null|text
|
||||
if(!expire_time)
|
||||
@@ -192,26 +196,30 @@
|
||||
var/datum/DBQuery/query_validate_expire_time_edit = SSdbcore.NewQuery("SELECT IF(STR_TO_DATE('[expire_time]','%Y-%c-%d %T') > NOW(), STR_TO_DATE('[expire_time]','%Y-%c-%d %T'), 0)")
|
||||
if(!query_validate_expire_time_edit.warn_execute())
|
||||
qdel(query_validate_expire_time_edit)
|
||||
qdel(query_find_edit_expiry_message)
|
||||
return
|
||||
if(query_validate_expire_time_edit.NextRow())
|
||||
var/checktime = text2num(query_validate_expire_time_edit.item[1])
|
||||
if(!checktime)
|
||||
to_chat(usr, "Datetime entered is improperly formatted or not later than current server time.")
|
||||
qdel(query_validate_expire_time_edit)
|
||||
qdel(query_find_edit_expiry_message)
|
||||
return
|
||||
new_expiry = query_validate_expire_time_edit.item[1]
|
||||
qdel(query_validate_expire_time_edit)
|
||||
var/edit_text = sanitizeSQL("Expiration time edited by [editor_ckey] on [SQLtime()] from [old_expiry] to [new_expiry]<hr>")
|
||||
var/edit_text = sanitizeSQL("Expiration time edited by [editor_key] on [SQLtime()] from [old_expiry] to [new_expiry]<hr>")
|
||||
var/datum/DBQuery/query_edit_message_expiry = SSdbcore.NewQuery("UPDATE [format_table_name("messages")] SET expire_timestamp = [expire_time == "-1" ? "NULL" : "'[new_expiry]'"], lasteditor = '[editor_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [message_id] AND deleted = 0")
|
||||
if(!query_edit_message_expiry.warn_execute())
|
||||
qdel(query_edit_message_expiry)
|
||||
qdel(query_find_edit_expiry_message)
|
||||
return
|
||||
qdel(query_edit_message_expiry)
|
||||
log_admin_private("[key_name(usr)] has edited the expiration time of a [type] [(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_ckey]" : ""] made by [admin_ckey] from [old_expiry] to [new_expiry]")
|
||||
message_admins("[key_name_admin(usr)] has edited the expiration time of a [type] [(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_ckey]" : ""] made by [admin_ckey] from [old_expiry] to [new_expiry]")
|
||||
log_admin_private("[kn] has edited the expiration time of a [type] [(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""] made by [admin_key] from [old_expiry] to [new_expiry]")
|
||||
message_admins("[kna] has edited the expiration time of a [type] [(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_key]" : ""] made by [admin_key] from [old_expiry] to [new_expiry]")
|
||||
if(browse)
|
||||
browse_messages("[type]")
|
||||
else
|
||||
browse_messages(target_ckey = target_ckey, agegate = TRUE)
|
||||
browse_messages(target_ckey = ckey(target_key), agegate = TRUE)
|
||||
qdel(query_find_edit_expiry_message)
|
||||
|
||||
/proc/toggle_message_secrecy(message_id)
|
||||
@@ -378,6 +386,14 @@
|
||||
if("note")
|
||||
notedata += data
|
||||
qdel(query_get_messages)
|
||||
if(!target_key)
|
||||
var/datum/DBQuery/query_get_message_key = SSdbcore.NewQuery("SELECT byond_key FROM [format_table_name("player")] WHERE ckey = '[target_ckey]'")
|
||||
if(!query_get_message_key.warn_execute())
|
||||
qdel(query_get_message_key)
|
||||
return
|
||||
if(query_get_message_key.NextRow())
|
||||
target_key = query_get_message_key.item[1]
|
||||
qdel(query_get_message_key)
|
||||
output += "<h2><center>[target_key]</center></h2><center>"
|
||||
if(!linkless)
|
||||
output += "<a href='?_src_=holder;[HrefToken()];addnote=[target_key]'>\[Add note\]</a>"
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
if(!msg)
|
||||
return
|
||||
|
||||
log_talk(mob,"[key_name(src)] : [msg]",LOGASAY)
|
||||
mob.log_talk(msg, LOG_ADMIN_PRIVATE)
|
||||
|
||||
msg = keywords_lookup(msg)
|
||||
msg = "<span class='adminsay'><span class='prefix'>ADMIN:</span> <EM>[key_name(usr, 1)]</EM> [ADMIN_FLW(mob)]: <span class='message linkify'>[msg]</span></span>"
|
||||
to_chat(GLOB.admins, msg)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
return
|
||||
|
||||
msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)
|
||||
log_talk(mob,"[key_name(src)] : [msg]",LOGDSAY)
|
||||
mob.log_talk(msg, LOG_DSAY)
|
||||
|
||||
if (!msg)
|
||||
return
|
||||
|
||||
@@ -1,29 +1,45 @@
|
||||
/proc/show_individual_logging_panel(mob/M, source = LOGSRC_CLIENT, type = INDIVIDUAL_ATTACK_LOG)
|
||||
if(!M || !ismob(M))
|
||||
return
|
||||
|
||||
|
||||
var/ntype = text2num(type)
|
||||
|
||||
//Add client links
|
||||
var/dat = ""
|
||||
if(M.client)
|
||||
dat += "<center><p>Client</p></center>"
|
||||
dat += "<center><a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_ATTACK_LOG];log_src=[LOGSRC_CLIENT]'>Attack log</a> | "
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_SAY_LOG];log_src=[LOGSRC_CLIENT]'>Say log</a> | "
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_EMOTE_LOG];log_src=[LOGSRC_CLIENT]'>Emote log</a> | "
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_OOC_LOG];log_src=[LOGSRC_CLIENT]'>OOC log</a> | "
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_SHOW_ALL_LOG];log_src=[LOGSRC_CLIENT]'>Show all</a> | "
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[type];log_src=[LOGSRC_CLIENT]'>Refresh</a></center>"
|
||||
if(M.client)
|
||||
dat += "<center><p>Client</p></center>"
|
||||
dat += "<center>"
|
||||
dat += individual_logging_panel_link(M, INDIVIDUAL_ATTACK_LOG, LOGSRC_CLIENT, "Attack Log", source, ntype)
|
||||
dat += " | "
|
||||
dat += individual_logging_panel_link(M, INDIVIDUAL_SAY_LOG, LOGSRC_CLIENT, "Say Log", source, ntype)
|
||||
dat += " | "
|
||||
dat += individual_logging_panel_link(M, INDIVIDUAL_EMOTE_LOG, LOGSRC_CLIENT, "Emote Log", source, ntype)
|
||||
dat += " | "
|
||||
dat += individual_logging_panel_link(M, INDIVIDUAL_COMMS_LOG, LOGSRC_CLIENT, "Comms Log", source, ntype)
|
||||
dat += " | "
|
||||
dat += individual_logging_panel_link(M, INDIVIDUAL_OOC_LOG, LOGSRC_CLIENT, "OOC Log", source, ntype)
|
||||
dat += " | "
|
||||
dat += individual_logging_panel_link(M, INDIVIDUAL_SHOW_ALL_LOG, LOGSRC_CLIENT, "Show All", source, ntype)
|
||||
dat += "</center>"
|
||||
else
|
||||
dat += "<p> No client attached to mob </p>"
|
||||
|
||||
dat += "<hr style='background:#000000; border:0; height:1px'>"
|
||||
dat += "<center><p>Mob</p></center>"
|
||||
dat += "<center><p>Mob</p></center>"
|
||||
//Add the links for the mob specific log
|
||||
dat += "<center><a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_ATTACK_LOG];log_src=[LOGSRC_MOB]'>Attack log</a> | "
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_SAY_LOG];log_src=[LOGSRC_MOB]'>Say log</a> | "
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_EMOTE_LOG];log_src=[LOGSRC_MOB]'>Emote log</a> | "
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_OOC_LOG];log_src=[LOGSRC_MOB]'>OOC log</a> | "
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[INDIVIDUAL_SHOW_ALL_LOG];log_src=[LOGSRC_MOB]'>Show all</a> | "
|
||||
dat += "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[type];log_src=[LOGSRC_MOB]'>Refresh</a></center>"
|
||||
dat += "<center>"
|
||||
dat += individual_logging_panel_link(M, INDIVIDUAL_ATTACK_LOG, LOGSRC_MOB, "Attack Log", source, ntype)
|
||||
dat += " | "
|
||||
dat += individual_logging_panel_link(M, INDIVIDUAL_SAY_LOG, LOGSRC_MOB, "Say Log", source, ntype)
|
||||
dat += " | "
|
||||
dat += individual_logging_panel_link(M, INDIVIDUAL_EMOTE_LOG, LOGSRC_MOB, "Emote Log", source, ntype)
|
||||
dat += " | "
|
||||
dat += individual_logging_panel_link(M, INDIVIDUAL_COMMS_LOG, LOGSRC_MOB, "Comms Log", source, ntype)
|
||||
dat += " | "
|
||||
dat += individual_logging_panel_link(M, INDIVIDUAL_OOC_LOG, LOGSRC_MOB, "OOC Log", source, ntype)
|
||||
dat += " | "
|
||||
dat += individual_logging_panel_link(M, INDIVIDUAL_SHOW_ALL_LOG, LOGSRC_MOB, "Show All", source, ntype)
|
||||
dat += "</center>"
|
||||
|
||||
dat += "<hr style='background:#000000; border:0; height:1px'>"
|
||||
|
||||
@@ -31,22 +47,21 @@
|
||||
if(source == LOGSRC_CLIENT && M.client) //if client doesn't exist just fall back to the mob log
|
||||
log_source = M.client.player_details.logging //should exist, if it doesn't that's a bug, don't check for it not existing
|
||||
|
||||
if(type == INDIVIDUAL_SHOW_ALL_LOG)
|
||||
dat += "<center>Displaying all [source] logs of [key_name(M)]</center><br><hr>"
|
||||
for(var/log_type in log_source)
|
||||
dat += "<center><b>[log_type]</b></center><br>"
|
||||
for(var/log_type in log_source)
|
||||
var/nlog_type = text2num(log_type)
|
||||
if(nlog_type & ntype)
|
||||
var/list/reversed = log_source[log_type]
|
||||
if(islist(reversed))
|
||||
reversed = reverseRange(reversed.Copy())
|
||||
for(var/entry in reversed)
|
||||
dat += "<font size=2px>[entry]: [reversed[entry]]</font><br>"
|
||||
dat += "<font size=2px><b>[entry]</b><br>[reversed[entry]]</font><br>"
|
||||
dat += "<hr>"
|
||||
else
|
||||
dat += "<center>[source] [type] of [key_name(M)]</center><br>"
|
||||
var/list/reversed = log_source[type]
|
||||
if(reversed)
|
||||
reversed = reverseRange(reversed.Copy())
|
||||
for(var/entry in reversed)
|
||||
dat += "<font size=2px>[entry]: [reversed[entry]]</font><hr>"
|
||||
|
||||
usr << browse(dat, "window=invidual_logging_[key_name(M)];size=600x480")
|
||||
|
||||
/proc/individual_logging_panel_link(mob/M, log_type, log_src, label, selected_src, selected_type)
|
||||
var/slabel = label
|
||||
if(selected_type == log_type && selected_src == log_src)
|
||||
slabel = "<b>\[[label]\]</b>"
|
||||
|
||||
return "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[log_type];log_src=[log_src]'>[slabel]</a>"
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
var/datum/map_template/template
|
||||
|
||||
var/map = input(usr, "Choose a Map Template to place at your CURRENT LOCATION","Place Map Template") as null|anything in SSmapping.map_templates
|
||||
var/map = input(src, "Choose a Map Template to place at your CURRENT LOCATION","Place Map Template") as null|anything in SSmapping.map_templates
|
||||
if(!map)
|
||||
return
|
||||
template = SSmapping.map_templates[map]
|
||||
@@ -18,35 +18,50 @@
|
||||
var/image/item = image('icons/turf/overlays.dmi',S,"greenOverlay")
|
||||
item.plane = ABOVE_LIGHTING_PLANE
|
||||
preview += item
|
||||
usr.client.images += preview
|
||||
if(alert(usr,"Confirm location.","Template Confirm","Yes","No") == "Yes")
|
||||
images += preview
|
||||
if(alert(src,"Confirm location.","Template Confirm","Yes","No") == "Yes")
|
||||
if(template.load(T, centered = TRUE))
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has placed a map template ([template.name]) at [ADMIN_COORDJMP(T)]</span>")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(src)] has placed a map template ([template.name]) at [ADMIN_COORDJMP(T)]</span>")
|
||||
else
|
||||
to_chat(usr, "Failed to place map")
|
||||
usr.client.images -= preview
|
||||
to_chat(src, "Failed to place map")
|
||||
images -= preview
|
||||
|
||||
/client/proc/map_template_upload()
|
||||
set category = "Debug"
|
||||
set name = "Map Template - Upload"
|
||||
|
||||
var/map = input(usr, "Choose a Map Template to upload to template storage","Upload Map Template") as null|file
|
||||
var/map = input(src, "Choose a Map Template to upload to template storage","Upload Map Template") as null|file
|
||||
if(!map)
|
||||
return
|
||||
if(copytext("[map]",-4) != ".dmm")
|
||||
to_chat(usr, "Bad map file: [map]")
|
||||
to_chat(src, "<span class='warning'>Filename must end in '.dmm': [map]</span>")
|
||||
return
|
||||
var/datum/map_template/M
|
||||
switch(alert(usr, "What kind of map is this?", "Map type", "Normal", "Shuttle", "Cancel"))
|
||||
switch(alert(src, "What kind of map is this?", "Map type", "Normal", "Shuttle", "Cancel"))
|
||||
if("Normal")
|
||||
M = new /datum/map_template(map, "[map]")
|
||||
M = new /datum/map_template(map, "[map]", TRUE)
|
||||
if("Shuttle")
|
||||
M = new /datum/map_template/shuttle(map, "[map]")
|
||||
M = new /datum/map_template/shuttle(map, "[map]", TRUE)
|
||||
else
|
||||
return
|
||||
if(M.preload_size(map))
|
||||
to_chat(usr, "Map template '[map]' ready to place ([M.width]x[M.height])")
|
||||
SSmapping.map_templates[M.name] = M
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has uploaded a map template ([map])</span>")
|
||||
else
|
||||
to_chat(usr, "Map template '[map]' failed to load properly")
|
||||
if(!M.cached_map)
|
||||
to_chat(src, "<span class='warning'>Map template '[map]' failed to parse properly.</span>")
|
||||
return
|
||||
|
||||
var/datum/map_report/report = M.cached_map.check_for_errors()
|
||||
var/report_link
|
||||
if(report)
|
||||
report.show_to(src)
|
||||
report_link = " - <a href='?src=[REF(report)];[HrefToken(TRUE)];show=1'>validation report</a>"
|
||||
to_chat(src, "<span class='warning'>Map template '[map]' <a href='?src=[REF(report)];[HrefToken()];show=1'>failed validation</a>.</span>")
|
||||
if(report.loadable)
|
||||
var/response = alert(src, "The map failed validation, would you like to load it anyways?", "Map Errors", "Cancel", "Upload Anyways")
|
||||
if(response != "Upload Anyways")
|
||||
return
|
||||
else
|
||||
alert(src, "The map failed validation and cannot be loaded.", "Map Errors", "Oh Darn")
|
||||
return
|
||||
|
||||
SSmapping.map_templates[M.name] = M
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(src)] has uploaded a map template '[map]' ([M.width]x[M.height])[report_link].</span>")
|
||||
to_chat(src, "<span class='notice'>Map template '[map]' ready to place ([M.width]x[M.height])</span>")
|
||||
|
||||
@@ -629,9 +629,11 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
if (O.vv_edit_var(variable, var_new) == FALSE)
|
||||
to_chat(src, "Your edit was rejected by the object.")
|
||||
return
|
||||
vv_update_display(O, "varedited", VV_MSG_EDITED)
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_VAR_EDIT, args)
|
||||
log_world("### VarEdit by [key_name(src)]: [O.type] [variable]=[var_value] => [var_new]")
|
||||
log_admin("[key_name(src)] modified [original_name]'s [variable] from [html_encode("[var_value]")] to [html_encode("[var_new]")]")
|
||||
var/msg = "[key_name_admin(src)] modified [original_name]'s [variable] from [var_value] to [var_new]"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(O, msg)
|
||||
return TRUE
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
message_admins("[key_name_admin(src)] decided not to answer [key_name_admin(H)]'s [sender] request.")
|
||||
return
|
||||
|
||||
log_admin("[key_name(src)] replied to [key_name(H)]'s [sender] message with the message [input].")
|
||||
log_directed_talk(src, H, input, LOG_ADMIN, "reply")
|
||||
message_admins("[key_name_admin(src)] replied to [key_name_admin(H)]'s [sender] message with: \"[input]\"")
|
||||
to_chat(H, "You hear something crackle in your ears for a moment before a voice speaks. \"Please stand by for a message from [sender == "Syndicate" ? "your benefactor" : "Central Command"]. Message as follows[sender == "Syndicate" ? ", agent." : ":"] <span class='bold'>[input].</span> Message ends.\"")
|
||||
|
||||
@@ -596,16 +596,28 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
|
||||
/client/proc/admin_delete(datum/D)
|
||||
var/atom/A = D
|
||||
var/coords = istype(A) ? " at ([A.x], [A.y], [A.z])" : ""
|
||||
if (alert(src, "Are you sure you want to delete:\n[D]\nat[coords]?", "Confirmation", "Yes", "No") == "Yes")
|
||||
log_admin("[key_name(usr)] deleted [D][coords]")
|
||||
message_admins("[key_name_admin(usr)] deleted [D][coords]")
|
||||
var/coords = ""
|
||||
var/jmp_coords = ""
|
||||
if(istype(A))
|
||||
var/turf/T = get_turf(A)
|
||||
if(T)
|
||||
coords = "at [COORD(T)]"
|
||||
jmp_coords = "at [ADMIN_COORDJMP(T)]"
|
||||
else
|
||||
jmp_coords = coords = "in nullspace"
|
||||
|
||||
if (alert(src, "Are you sure you want to delete:\n[D]\n[coords]?", "Confirmation", "Yes", "No") == "Yes")
|
||||
log_admin("[key_name(usr)] deleted [D] [coords]")
|
||||
message_admins("[key_name_admin(usr)] deleted [D] [jmp_coords]")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Delete") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
if(isturf(D))
|
||||
var/turf/T = D
|
||||
T.ScrapeAway()
|
||||
else
|
||||
vv_update_display(D, "deleted", VV_MSG_DELETED)
|
||||
qdel(D)
|
||||
if(!QDELETED(D))
|
||||
vv_update_display(D, "deleted", "")
|
||||
|
||||
/client/proc/cmd_admin_list_open_jobs()
|
||||
set category = "Admin"
|
||||
@@ -1117,7 +1129,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
return
|
||||
|
||||
for(var/mob/living/carbon/human/H in GLOB.carbon_list)
|
||||
new /obj/item/organ/zombie_infection(H)
|
||||
new /obj/item/organ/zombie_infection/nodamage(H)
|
||||
|
||||
message_admins("[key_name_admin(usr)] added a latent zombie infection to all humans.")
|
||||
log_admin("[key_name(usr)] added a latent zombie infection to all humans.")
|
||||
@@ -1134,7 +1146,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
if(confirm != "Yes")
|
||||
return
|
||||
|
||||
for(var/obj/item/organ/zombie_infection/I in GLOB.zombie_infection_list)
|
||||
for(var/obj/item/organ/zombie_infection/nodamage/I in GLOB.zombie_infection_list)
|
||||
qdel(I)
|
||||
|
||||
message_admins("[key_name_admin(usr)] cured all zombies.")
|
||||
|
||||
@@ -362,7 +362,7 @@
|
||||
|
||||
to_chat(L, "<span class='italics'>You hear a voice in your head saying: </span><span class='abductor'>[message]</span>")
|
||||
to_chat(user, "<span class='notice'>You send the message to your target.</span>")
|
||||
log_talk(user,"[key_name(user)] sent an abductor mind message to [key_name(L)]: '[message]'", LOGSAY)
|
||||
log_directed_talk(user, L, message, LOG_SAY, "abductor whisper")
|
||||
|
||||
|
||||
/obj/item/firing_pin/abductor
|
||||
@@ -505,6 +505,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
|
||||
|
||||
L.Knockdown(140)
|
||||
L.apply_effect(EFFECT_STUTTER, 7)
|
||||
SEND_SIGNAL(L, COMSIG_LIVING_MINOR_SHOCK)
|
||||
|
||||
L.visible_message("<span class='danger'>[user] has stunned [L] with [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has stunned you with [src]!</span>")
|
||||
@@ -514,7 +515,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
|
||||
var/mob/living/carbon/human/H = L
|
||||
H.forcesay(GLOB.hit_appends)
|
||||
|
||||
add_logs(user, L, "stunned")
|
||||
log_combat(user, L, "stunned")
|
||||
|
||||
/obj/item/abductor_baton/proc/SleepAttack(mob/living/L,mob/living/user)
|
||||
if(L.incapacitated(TRUE, TRUE))
|
||||
@@ -528,7 +529,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
|
||||
"<span class='userdanger'>You suddenly feel very drowsy!</span>")
|
||||
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
|
||||
L.Sleeping(1200)
|
||||
add_logs(user, L, "put to sleep")
|
||||
log_combat(user, L, "put to sleep")
|
||||
else
|
||||
if(istype(L.get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/foilhat))
|
||||
to_chat(user, "<span class='warning'>The specimen's protective headgear is completely blocking our sleep inducement methods!</span>")
|
||||
@@ -554,7 +555,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
|
||||
C.handcuffed = new /obj/item/restraints/handcuffs/energy/used(C)
|
||||
C.update_handcuffed()
|
||||
to_chat(user, "<span class='notice'>You restrain [C].</span>")
|
||||
add_logs(user, C, "handcuffed")
|
||||
log_combat(user, C, "handcuffed")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You fail to restrain [C].</span>")
|
||||
else
|
||||
|
||||
@@ -208,7 +208,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
if (!message)
|
||||
return
|
||||
|
||||
log_talk(src,"[key_name(src)] : [message]",LOGSAY)
|
||||
src.log_talk(message, LOG_SAY)
|
||||
|
||||
var/message_a = say_quote(message, get_spans())
|
||||
var/rendered = "<span class='big'><font color=\"#EE4000\"><b>\[Blob Telepathy\] [name](<font color=\"[blob_reagent_datum.color]\">[blob_reagent_datum.name]</font>)</b> [message_a]</font></span>"
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
//Recent as opposed to all because rounds tend to have a LOT of text.
|
||||
var/list/recent_speech = list()
|
||||
|
||||
var/list/say_log = target.logging[INDIVIDUAL_SAY_LOG]
|
||||
var/list/say_log = target.logging[LOG_SAY]
|
||||
|
||||
if(LAZYLEN(say_log) > LING_ABSORB_RECENT_SPEECH)
|
||||
recent_speech = say_log.Copy(say_log.len-LING_ABSORB_RECENT_SPEECH+1,0) //0 so len-LING_ARS+1 to end of list
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/transformation/sting_action(mob/user, mob/target)
|
||||
add_logs(user, target, "stung", "transformation sting", " new identity is [selected_dna.dna.real_name]")
|
||||
log_combat(user, target, "stung", "transformation sting", " new identity is '[selected_dna.dna.real_name]'")
|
||||
var/datum/dna/NewDNA = selected_dna.dna
|
||||
if(ismonkey(target))
|
||||
to_chat(user, "<span class='notice'>Our genes cry out as we sting [target.name]!</span>")
|
||||
@@ -132,7 +132,7 @@
|
||||
return 1
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/false_armblade/sting_action(mob/user, mob/target)
|
||||
add_logs(user, target, "stung", object="false armblade sting")
|
||||
log_combat(user, target, "stung", object="false armblade sting")
|
||||
|
||||
var/obj/item/held = target.get_active_held_item()
|
||||
if(held && !target.dropItemToGround(held))
|
||||
@@ -174,7 +174,7 @@
|
||||
return changeling.can_absorb_dna(target)
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/extract_dna/sting_action(mob/user, mob/living/carbon/human/target)
|
||||
add_logs(user, target, "stung", "extraction sting")
|
||||
log_combat(user, target, "stung", "extraction sting")
|
||||
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(!(changeling.has_dna(target.dna)))
|
||||
changeling.add_new_profile(target)
|
||||
@@ -189,7 +189,7 @@
|
||||
dna_cost = 2
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/mute/sting_action(mob/user, mob/living/carbon/target)
|
||||
add_logs(user, target, "stung", "mute sting")
|
||||
log_combat(user, target, "stung", "mute sting")
|
||||
target.silent += 30
|
||||
return TRUE
|
||||
|
||||
@@ -202,7 +202,7 @@
|
||||
dna_cost = 1
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/blind/sting_action(mob/user, mob/living/carbon/target)
|
||||
add_logs(user, target, "stung", "blind sting")
|
||||
log_combat(user, target, "stung", "blind sting")
|
||||
to_chat(target, "<span class='danger'>Your eyes burn horrifically!</span>")
|
||||
target.become_nearsighted(EYE_DAMAGE)
|
||||
target.blind_eyes(20)
|
||||
@@ -218,7 +218,7 @@
|
||||
dna_cost = 1
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/LSD/sting_action(mob/user, mob/living/carbon/target)
|
||||
add_logs(user, target, "stung", "LSD sting")
|
||||
log_combat(user, target, "stung", "LSD sting")
|
||||
addtimer(CALLBACK(src, .proc/hallucination_time, target), rand(100,200))
|
||||
return TRUE
|
||||
|
||||
@@ -235,7 +235,7 @@
|
||||
dna_cost = 2
|
||||
|
||||
/obj/effect/proc_holder/changeling/sting/cryo/sting_action(mob/user, mob/target)
|
||||
add_logs(user, target, "stung", "cryo sting")
|
||||
log_combat(user, target, "stung", "cryo sting")
|
||||
if(target.reagents)
|
||||
target.reagents.add_reagent("frostoil", 30)
|
||||
return TRUE
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
GLOB.application_scripture_unlocked = TRUE
|
||||
hierophant_message("<span class='large_brass bold'>With the conversion of a new servant the Ark's power grows. Application scriptures are now available.</span>")
|
||||
if(add_servant_of_ratvar(L))
|
||||
L.log_message("<font color=#BE8700>Conversion was done with a [sigil_name].</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
L.log_message("conversion was done with a [sigil_name]", LOG_ATTACK, color="BE8700")
|
||||
if(iscarbon(L))
|
||||
var/mob/living/carbon/M = L
|
||||
M.uncuff()
|
||||
|
||||
@@ -46,5 +46,5 @@
|
||||
return
|
||||
if(ishuman(owner))
|
||||
clockwork_say(owner, "[text2ratvar("Servants, hear my words: [input]")]", TRUE)
|
||||
log_talk(owner,"CLOCK:[key_name(owner)] : [input]",LOGSAY)
|
||||
owner.log_talk(input, LOG_SAY, tag="clockwork")
|
||||
titled_hierophant_message(owner, input, span_for_name, span_for_message, title)
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
L.handcuffed = new/obj/item/restraints/handcuffs/clockwork(L)
|
||||
L.update_handcuffed()
|
||||
to_chat(ranged_ability_user, "<span class='neovgre_small'>You shackle [L].</span>")
|
||||
add_logs(ranged_ability_user, L, "handcuffed")
|
||||
log_combat(ranged_ability_user, L, "handcuffed")
|
||||
else
|
||||
to_chat(ranged_ability_user, "<span class='warning'>You fail to shackle [L].</span>")
|
||||
|
||||
@@ -117,12 +117,12 @@
|
||||
L.adjustOxyLoss(-oxydamage)
|
||||
L.adjustToxLoss(totaldamage * 0.5, TRUE, TRUE)
|
||||
clockwork_say(ranged_ability_user, text2ratvar("[has_holy_water ? "Heal tainted" : "Mend wounded"] flesh!"))
|
||||
add_logs(ranged_ability_user, L, "healed with Sentinel's Compromise")
|
||||
log_combat(ranged_ability_user, L, "healed with Sentinel's Compromise")
|
||||
L.visible_message("<span class='warning'>A blue light washes over [L], [has_holy_water ? "causing [L.p_them()] to briefly glow as it mends" : " mending"] [L.p_their()] bruises and burns!</span>", \
|
||||
"<span class='heavy_brass'>You feel Inath-neq's power healing your wounds[has_holy_water ? " and purging the darkness within you" : ""], but a deep nausea overcomes you!</span>")
|
||||
else
|
||||
clockwork_say(ranged_ability_user, text2ratvar("Purge foul darkness!"))
|
||||
add_logs(ranged_ability_user, L, "purged of holy water with Sentinel's Compromise")
|
||||
log_combat(ranged_ability_user, L, "purged of holy water with Sentinel's Compromise")
|
||||
L.visible_message("<span class='warning'>A blue light washes over [L], causing [L.p_them()] to briefly glow!</span>", \
|
||||
"<span class='heavy_brass'>You feel Inath-neq's power purging the darkness within you!</span>")
|
||||
playsound(targetturf, 'sound/magic/staff_healing.ogg', 50, 1)
|
||||
@@ -153,7 +153,7 @@
|
||||
var/turf/U = get_turf(target)
|
||||
to_chat(ranged_ability_user, "<span class='brass'>You release the light of Ratvar!</span>")
|
||||
clockwork_say(ranged_ability_user, text2ratvar("Purge all untruths and honor Engine!"))
|
||||
add_logs(ranged_ability_user, U, "fired at with Kindle")
|
||||
log_combat(ranged_ability_user, U, "fired at with Kindle")
|
||||
playsound(ranged_ability_user, 'sound/magic/blink.ogg', 50, TRUE, frequency = 0.5)
|
||||
var/obj/item/projectile/kindle/A = new(T)
|
||||
A.preparePixelProjectile(target, caller, params)
|
||||
@@ -265,7 +265,7 @@
|
||||
"<span class='heavy_brass'>You direct the judicial force to [target].</span>")
|
||||
var/turf/targetturf = get_turf(target)
|
||||
new/obj/effect/clockwork/judicial_marker(targetturf, ranged_ability_user)
|
||||
add_logs(ranged_ability_user, targetturf, "created a judicial marker")
|
||||
log_combat(ranged_ability_user, targetturf, "created a judicial marker")
|
||||
remove_ranged_ability()
|
||||
|
||||
return TRUE
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
ranged_ability_user.visible_message("<span class='warning'>[ranged_ability_user]'s judicial visor fires a stream of energy at [target], creating a strange mark!</span>", "<span class='heavy_brass'>You direct [visor]'s power to [target]. You must wait for some time before doing this again.</span>")
|
||||
var/turf/targetturf = get_turf(target)
|
||||
new/obj/effect/clockwork/judicial_marker(targetturf, ranged_ability_user)
|
||||
add_logs(ranged_ability_user, targetturf, "created a judicial marker")
|
||||
log_combat(ranged_ability_user, targetturf, "created a judicial marker")
|
||||
ranged_ability_user.update_action_buttons_icon()
|
||||
ranged_ability_user.update_inv_glasses()
|
||||
addtimer(CALLBACK(visor, /obj/item/clothing/glasses/judicial_visor.proc/recharge_visor, ranged_ability_user), GLOB.ratvar_awakens ? visor.recharge_cooldown*0.1 : visor.recharge_cooldown)//Cooldown is reduced by 10x if Ratvar is up
|
||||
@@ -209,7 +209,7 @@
|
||||
targetsjudged++
|
||||
if(!QDELETED(L))
|
||||
L.adjustBruteLoss(20) //does a decent amount of damage
|
||||
add_logs(user, L, "struck with a judicial blast")
|
||||
log_combat(user, L, "struck with a judicial blast")
|
||||
to_chat(user, "<span class='brass'><b>[targetsjudged ? "Successfully judged <span class='neovgre'>[targetsjudged]</span>":"Judged no"] heretic[targetsjudged == 1 ? "":"s"].</b></span>")
|
||||
sleep(3) //so the animation completes properly
|
||||
qdel(src)
|
||||
|
||||
@@ -33,12 +33,12 @@
|
||||
T.visible_message("<span class='warning'>[T] suddenly emits a ringing sound!</span>", null, null, null, src)
|
||||
playsound(T, 'sound/machines/clockcult/ark_damage.ogg', 75, FALSE)
|
||||
last_failed_turf = T
|
||||
if((world.time - lastWarning) >= 30)
|
||||
if((world.time - lastWarning) >= 30)
|
||||
lastWarning = world.time
|
||||
to_chat(src, "<span class='warning'>This turf is consecrated and can't be crossed!</span>")
|
||||
return
|
||||
if(istype(get_area(T), /area/chapel))
|
||||
if((world.time - lastWarning) >= 30)
|
||||
if((world.time - lastWarning) >= 30)
|
||||
lastWarning = world.time
|
||||
to_chat(src, "<span class='warning'>The Chapel is hallowed ground under a heretical deity, and can't be accessed!</span>")
|
||||
return
|
||||
@@ -86,7 +86,7 @@
|
||||
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
|
||||
if(!message)
|
||||
return
|
||||
log_talk(src, "[key_name(src)] : [message]", LOGSAY)
|
||||
src.log_talk(message, LOG_SAY, tag="clockwork eminence")
|
||||
if(GLOB.ratvar_awakens)
|
||||
visible_message("<span class='brass'><b>You feel light slam into your mind and form words:</b> \"[capitalize(message)]\"</span>")
|
||||
playsound(src, 'sound/machines/clockcult/ark_scream.ogg', 50, FALSE)
|
||||
@@ -99,6 +99,7 @@
|
||||
to_chat(M, message)
|
||||
|
||||
/mob/camera/eminence/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||
. = ..()
|
||||
if(is_reebe(z) || is_servant_of_ratvar(speaker) || GLOB.ratvar_approaches || GLOB.ratvar_awakens) //Away from Reebe, the Eminence can't hear anything
|
||||
to_chat(src, message)
|
||||
return
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
SSticker.mode.servants_of_ratvar += owner
|
||||
SSticker.mode.update_servant_icons_added(owner)
|
||||
owner.special_role = ROLE_SERVANT_OF_RATVAR
|
||||
owner.current.log_message("<font color=#BE8700>Has been converted to the cult of Ratvar!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
owner.current.log_message("has been converted to the cult of Ratvar!", LOG_ATTACK, color="#BE8700")
|
||||
if(issilicon(current))
|
||||
if(iscyborg(current) && !silent)
|
||||
var/mob/living/silicon/robot/R = current
|
||||
@@ -161,7 +161,7 @@
|
||||
if(!silent)
|
||||
owner.current.visible_message("<span class='deconversion_message'>[owner.current] seems to have remembered [owner.current.p_their()] true allegiance!</span>", null, null, null, owner.current)
|
||||
to_chat(owner, "<span class='userdanger'>A cold, cold darkness flows through your mind, extinguishing the Justiciar's light and all of your memories as his servant.</span>")
|
||||
owner.current.log_message("<font color=#BE8700>Has renounced the cult of Ratvar!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
owner.current.log_message("has renounced the cult of Ratvar!", LOG_ATTACK, color="#BE8700")
|
||||
owner.special_role = null
|
||||
if(iscyborg(owner.current))
|
||||
to_chat(owner.current, "<span class='warning'>Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking.</span>")
|
||||
|
||||
@@ -378,7 +378,7 @@
|
||||
uses = 0
|
||||
qdel(src)
|
||||
return
|
||||
add_logs(user, M, "used a cult spell on", source.name, "")
|
||||
log_combat(user, M, "used a cult spell on", source.name, "")
|
||||
M.lastattacker = user.real_name
|
||||
M.lastattackerckey = user.ckey
|
||||
|
||||
@@ -507,7 +507,7 @@
|
||||
C.update_handcuffed()
|
||||
C.silent += 5
|
||||
to_chat(user, "<span class='notice'>You shackle [C].</span>")
|
||||
add_logs(user, C, "shackled")
|
||||
log_combat(user, C, "shackled")
|
||||
uses--
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[C] is already bound.</span>")
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
equip_cultist(TRUE)
|
||||
SSticker.mode.cult += owner // Only add after they've been given objectives
|
||||
SSticker.mode.update_cult_icons_added(owner)
|
||||
current.log_message("<font color=#960000>Has been converted to the cult of Nar'Sie!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
current.log_message("has been converted to the cult of Nar'Sie!", LOG_ATTACK, color="#960000")
|
||||
|
||||
if(cult_team.blood_target && cult_team.blood_target_image && current.client)
|
||||
current.client.images += cult_team.blood_target_image
|
||||
@@ -130,7 +130,7 @@
|
||||
if(!silent)
|
||||
owner.current.visible_message("<span class='deconversion_message'>[owner.current] looks like [owner.current.p_theyve()] just reverted to [owner.current.p_their()] old faith!</span>", null, null, null, owner.current)
|
||||
to_chat(owner.current, "<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of the Geometer and all your memories as her servant.</span>")
|
||||
owner.current.log_message("<font color=#960000>Has renounced the cult of Nar'Sie!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
owner.current.log_message("has renounced the cult of Nar'Sie!", LOG_ATTACK, color="#960000")
|
||||
if(cult_team.blood_target && cult_team.blood_target_image && owner.current.client)
|
||||
owner.current.client.images -= cult_team.blood_target_image
|
||||
. = ..()
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
var/link = FOLLOW_LINK(M, user)
|
||||
to_chat(M, "[link] [my_message]")
|
||||
|
||||
log_talk(user,"CULT:[key_name(user)] : [message]",LOGSAY)
|
||||
user.log_talk(message, LOG_SAY, tag="cult")
|
||||
|
||||
/datum/action/innate/cult/comm/spirit
|
||||
name = "Spiritual Communion"
|
||||
|
||||
@@ -29,7 +29,7 @@ This file contains the cult dagger and rune list code
|
||||
var/holy2unholy = M.reagents.get_reagent_amount("holywater")
|
||||
M.reagents.del_reagent("holywater")
|
||||
M.reagents.add_reagent("unholywater",holy2unholy)
|
||||
add_logs(user, M, "smacked", src, " removing the holy water from them")
|
||||
log_combat(user, M, "smacked", src, " removing the holy water from them")
|
||||
return FALSE
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -173,14 +173,14 @@
|
||||
visible_message("<span class='danger'>[M] has punched [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has punched [src]!</span>")
|
||||
adjustBruteLoss(damage)
|
||||
add_logs(M, src, "attacked")
|
||||
log_combat(M, src, "attacked")
|
||||
updatehealth()
|
||||
if ("disarm")
|
||||
if (!lying && !ascended) //No stealing the arch devil's pitchfork.
|
||||
if (prob(5))
|
||||
Unconscious(40)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
add_logs(M, src, "pushed")
|
||||
log_combat(M, src, "pushed")
|
||||
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has pushed down [src]!</span>")
|
||||
else
|
||||
|
||||
@@ -246,8 +246,18 @@
|
||||
|
||||
/datum/team/nuclear/proc/disk_rescued()
|
||||
for(var/obj/item/disk/nuclear/D in GLOB.poi_list)
|
||||
if(!D.onCentCom())
|
||||
return FALSE
|
||||
//If emergency shuttle is in transit disk is only safe on it
|
||||
if(SSshuttle.emergency.mode == SHUTTLE_ESCAPE)
|
||||
if(!SSshuttle.emergency.is_in_shuttle_bounds(D))
|
||||
return FALSE
|
||||
//If shuttle escaped check if it's on centcom side
|
||||
else if(SSshuttle.emergency.mode == SHUTTLE_ENDGAME)
|
||||
if(!D.onCentCom())
|
||||
return FALSE
|
||||
else //Otherwise disk is safe when on station
|
||||
var/turf/T = get_turf(D)
|
||||
if(!T || !is_station_level(T.z))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/team/nuclear/proc/operatives_dead()
|
||||
@@ -263,7 +273,7 @@
|
||||
return S && (is_centcom_level(S.z) || T)
|
||||
|
||||
/datum/team/nuclear/proc/get_result()
|
||||
var/evacuation = SSshuttle.emergency.mode == SHUTTLE_ENDGAME
|
||||
var/evacuation = EMERGENCY_ESCAPED_OR_ENDGAMED
|
||||
var/disk_rescued = disk_rescued()
|
||||
var/syndies_didnt_escape = !syndies_escaped()
|
||||
var/station_was_nuked = SSticker.mode.station_was_nuked
|
||||
@@ -285,7 +295,7 @@
|
||||
return NUKE_RESULT_CREW_WIN
|
||||
else if (!disk_rescued && operatives_dead())
|
||||
return NUKE_RESULT_DISK_LOST
|
||||
else if (!disk_rescued && evacuation)
|
||||
else if (!disk_rescued && evacuation)
|
||||
return NUKE_RESULT_DISK_STOLEN
|
||||
else
|
||||
return //Undefined result
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
/mob/living/simple_animal/revenant/say(message)
|
||||
if(!message)
|
||||
return
|
||||
log_talk(src,"[key_name(src)] : [message]",LOGSAY)
|
||||
src.log_talk(message, LOG_SAY)
|
||||
var/rendered = "<span class='revennotice'><b>[src]</b> says, \"[message]\"</span>"
|
||||
for(var/mob/M in GLOB.mob_list)
|
||||
if(isrevenant(M))
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
if(!msg)
|
||||
charge_counter = charge_max
|
||||
return
|
||||
log_talk(user,"RevenantTransmit: [key_name(user)]->[key_name(M)] : [msg]",LOGSAY)
|
||||
log_directed_talk(user, M, msg, LOG_SAY, "revenant whisper")
|
||||
to_chat(user, "<span class='revenboldnotice'>You transmit to [M]:</span> <span class='revennotice'>[msg]</span>")
|
||||
if(!M.anti_magic_check(FALSE, TRUE)) //hear no evil
|
||||
to_chat(M, "<span class='revenboldnotice'>You hear something behind you talking...</span> <span class='revennotice'>[msg]</span>")
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
return FALSE
|
||||
if(new_owner.unconvertable)
|
||||
return FALSE
|
||||
if(new_owner.current && new_owner.current.isloyal())
|
||||
if(new_owner.current && new_owner.current.has_trait(TRAIT_MINDSHIELD))
|
||||
return FALSE
|
||||
|
||||
/datum/antagonist/rev/apply_innate_effects(mob/living/mob_override)
|
||||
@@ -35,7 +35,7 @@
|
||||
. = ..()
|
||||
create_objectives()
|
||||
equip_rev()
|
||||
owner.current.log_message("<font color='red'>Has been converted to the revolution!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
owner.current.log_message("has been converted to the revolution!", LOG_ATTACK, color="red")
|
||||
|
||||
/datum/antagonist/rev/on_removal()
|
||||
remove_objectives()
|
||||
@@ -209,7 +209,7 @@
|
||||
|
||||
//blunt trauma deconversions call this through species.dm spec_attacked_by()
|
||||
/datum/antagonist/rev/proc/remove_revolutionary(borged, deconverter)
|
||||
log_attack("[owner.current] (Key: [key_name(owner.current)]) has been deconverted from the revolution by [deconverter] (Key: [key_name(deconverter)])!")
|
||||
log_attack("[key_name(owner.current)] has been deconverted from the revolution by [key_name(deconverter)]!")
|
||||
if(borged)
|
||||
message_admins("[ADMIN_LOOKUPFLW(owner.current)] has been borged while being a [name]")
|
||||
owner.special_role = null
|
||||
|
||||
@@ -483,7 +483,7 @@
|
||||
if(ishuman(target) && (!H.handcuffed))
|
||||
H.handcuffed = new /obj/item/restraints/handcuffs/energy/used(H)
|
||||
H.update_handcuffed()
|
||||
add_logs(src, H, "handcuffed")
|
||||
log_combat(src, H, "handcuffed")
|
||||
|
||||
var/datum/effect_system/spark_spread/S = new
|
||||
S.set_up(4,0,get_turf(target))
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
if(iscultist(user))
|
||||
to_chat(user, "<span class='cultlarge'>\"Come now, do not capture your bretheren's soul.\"</span>")
|
||||
return
|
||||
add_logs(user, M, "captured [M.name]'s soul", src)
|
||||
log_combat(user, M, "captured [M.name]'s soul", src)
|
||||
transfer_soul("VICTIM", M, user)
|
||||
|
||||
///////////////////Options for using captured souls///////////////////////////////////////
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
if(D.secondsElectrified)
|
||||
D.secondsElectrified = -1
|
||||
LAZYADD(D.shockedby, "\[[time_stamp()]\] [key_name(usr)]")
|
||||
add_logs(usr, D, "electrified")
|
||||
log_combat(usr, D, "electrified")
|
||||
else
|
||||
D.secondsElectrified = 0
|
||||
if(specialfunctions & SAFE)
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
/obj/item/assembly/flash/proc/flash_carbon(mob/living/carbon/M, mob/user, power = 15, targeted = TRUE, generic_message = FALSE)
|
||||
if(!istype(M))
|
||||
return
|
||||
add_logs(user, M, "[targeted? "flashed(targeted)" : "flashed(AOE)"]", src)
|
||||
log_combat(user, M, "[targeted? "flashed(targeted)" : "flashed(AOE)"]", src)
|
||||
if(generic_message && M != user)
|
||||
to_chat(M, "<span class='disarm'>[src] emits a blinding light!</span>")
|
||||
if(targeted)
|
||||
@@ -139,7 +139,7 @@
|
||||
return TRUE
|
||||
else if(issilicon(M))
|
||||
var/mob/living/silicon/robot/R = M
|
||||
add_logs(user, R, "flashed", src)
|
||||
log_combat(user, R, "flashed", src)
|
||||
update_icon(1)
|
||||
R.Knockdown(rand(80,120))
|
||||
var/diff = 5 * CONFUSION_STACK_MAX_MULTIPLIER - M.confused
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
to_chat(user, "<span class='notice'>Use a multitool to swap between \"inclusive\", \"exclusive\", \"recognizer\", and \"voice sensor\" mode.</span>")
|
||||
|
||||
/obj/item/assembly/voice/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||
. = ..()
|
||||
if(speaker == src)
|
||||
return
|
||||
|
||||
|
||||
@@ -1,66 +1,4 @@
|
||||
//Plasma fire properties
|
||||
#define OXYGEN_BURN_RATE_BASE 1.4
|
||||
#define PLASMA_BURN_RATE_DELTA 9
|
||||
#define PLASMA_MINIMUM_OXYGEN_NEEDED 2
|
||||
#define PLASMA_MINIMUM_OXYGEN_PLASMA_RATIO 30
|
||||
#define FIRE_CARBON_ENERGY_RELEASED 100000 //Amount of heat released per mole of burnt carbon into the tile
|
||||
#define FIRE_HYDROGEN_ENERGY_RELEASED 280000 //Amount of heat released per mole of burnt hydrogen and/or tritium(hydrogen isotope)
|
||||
#define FIRE_PLASMA_ENERGY_RELEASED 3000000 //Amount of heat released per mole of burnt plasma into the tile
|
||||
//General assmos defines.
|
||||
#define WATER_VAPOR_FREEZE 200
|
||||
#define NITRYL_FORMATION_ENERGY 100000
|
||||
#define TRITIUM_BURN_OXY_FACTOR 100
|
||||
#define TRITIUM_BURN_TRIT_FACTOR 10
|
||||
#define TRITIUM_BURN_RADIOACTIVITY_FACTOR 50000 //The neutrons gotta go somewhere. Completely arbitrary number.
|
||||
#define TRITIUM_MINIMUM_RADIATION_ENERGY 0.1 //minimum 0.01 moles trit or 10 moles oxygen to start producing rads
|
||||
#define SUPER_SATURATION_THRESHOLD 96
|
||||
#define STIMULUM_HEAT_SCALE 100000
|
||||
#define STIMULUM_FIRST_RISE 0.65
|
||||
#define STIMULUM_FIRST_DROP 0.065
|
||||
#define STIMULUM_SECOND_RISE 0.0009
|
||||
#define STIMULUM_ABSOLUTE_DROP 0.00000335
|
||||
#define REACTION_OPPRESSION_THRESHOLD 5
|
||||
#define NOBLIUM_FORMATION_ENERGY 2e9 //1 Mole of Noblium takes the planck energy to condense.
|
||||
//Plasma fusion properties
|
||||
#define FUSION_ENERGY_THRESHOLD 3e9 //Amount of energy it takes to start a fusion reaction
|
||||
#define FUSION_TEMPERATURE_THRESHOLD 1000 //Temperature required to start a fusion reaction
|
||||
#define FUSION_MOLE_THRESHOLD 250 //Mole count required (tritium/plasma) to start a fusion reaction
|
||||
#define FUSION_RELEASE_ENERGY_SUPER 3e9 //Amount of energy released in the fusion process, super tier
|
||||
#define FUSION_RELEASE_ENERGY_HIGH 1e9 //Amount of energy released in the fusion process, high tier
|
||||
#define FUSION_RELEASE_ENERGY_MID 5e8 //Amount of energy released in the fusion process, mid tier
|
||||
#define FUSION_RELEASE_ENERGY_LOW 1e8 //Amount of energy released in the fusion process, low tier
|
||||
#define FUSION_MEDIATION_FACTOR 80 //Arbitrary
|
||||
#define FUSION_SUPER_TIER_THRESHOLD 50 //anything above this is super tier
|
||||
#define FUSION_HIGH_TIER_THRESHOLD 20 //anything above this and below 50 is high tier
|
||||
#define FUSION_MID_TIER_THRESHOLD 5 //anything above this and below 20 is mid tier - below this is low tier, but that doesnt need a define
|
||||
#define FUSION_ENERGY_DIVISOR_SUPER 25 //power_ratio is divided by this during energy calculations
|
||||
#define FUSION_ENERGY_DIVISOR_HIGH 20
|
||||
#define FUSION_ENERGY_DIVISOR_MID 10
|
||||
#define FUSION_ENERGY_DIVISOR_LOW 2
|
||||
#define FUSION_GAS_CREATION_FACTOR_TRITIUM 0.40 //trit - one gas rather than two, so think about that when calculating stuff - 40% in total
|
||||
#define FUSION_GAS_CREATION_FACTOR_STIM 0.05 //stim percentage creation from high tier - 5%, 60% in total with pluox
|
||||
#define FUSION_GAS_CREATION_FACTOR_PLUOX 0.55 //pluox percentage creation from high tier - 55%, 60% in total with stim
|
||||
#define FUSION_GAS_CREATION_FACTOR_NITRYL 0.20 //nitryl and N2O - 80% in total
|
||||
#define FUSION_GAS_CREATION_FACTOR_N2O 0.60 //nitryl and N2O - 80% in total
|
||||
#define FUSION_GAS_CREATION_FACTOR_BZ 0.05 //BZ - 5% - 90% in total with CO2
|
||||
#define FUSION_GAS_CREATION_FACTOR_CO2 0.85 //CO2 - 85% - 90% in total with BZ
|
||||
#define FUSION_MID_TIER_RAD_PROB_FACTOR 2 //probability of radpulse is power ratio * this for whatever tier
|
||||
#define FUSION_LOW_TIER_RAD_PROB_FACTOR 5
|
||||
#define FUSION_EFFICIENCY_BASE 60 //used in the fusion efficiency calculations
|
||||
#define FUSION_EFFICIENCY_DIVISOR 0.6 //ditto
|
||||
#define FUSION_RADIATION_FACTOR 15000 //horizontal asymptote
|
||||
#define FUSION_RADIATION_CONSTANT 30 //equation is form of (ax) / (x + b), where a = radiation factor and b = radiation constant and x = power ratio (https://www.desmos.com/calculator/4i1f296phl)
|
||||
#define FUSION_ZAP_POWER_ASYMPTOTE 50000 //maximum value - not enough to instacrit but it'll still hurt like shit
|
||||
#define FUSION_ZAP_POWER_CONSTANT 75 //equation is of from [ax / (x + b)] + c, where a = zap power asymptote, b = zap power constant, c = zap power base and x = power ratio
|
||||
#define FUSION_ZAP_POWER_BASE 1000 //(https://www.desmos.com/calculator/vvbmhf4unm)
|
||||
#define FUSION_ZAP_RANGE_SUPER 9 //range of the tesla zaps that occur from fusion
|
||||
#define FUSION_ZAP_RANGE_HIGH 7
|
||||
#define FUSION_ZAP_RANGE_MID 5
|
||||
#define FUSION_ZAP_RANGE_LOW 3
|
||||
#define FUSION_PARTICLE_FACTOR_SUPER 4 //# of particles fired out is equal to rand(3,6) * this for whatever tier
|
||||
#define FUSION_PARTICLE_FACTOR_HIGH 3
|
||||
#define FUSION_PARTICLE_FACTOR_MID 2
|
||||
#define FUSION_PARTICLE_FACTOR_LOW 1
|
||||
//All defines used in reactions are located in ..\__DEFINES\reactions.dm
|
||||
|
||||
/proc/init_gas_reactions()
|
||||
var/list/reaction_types = list()
|
||||
@@ -495,21 +433,4 @@
|
||||
var/new_heat_capacity = air.heat_capacity()
|
||||
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
|
||||
air.temperature = max(((air.temperature*old_heat_capacity - energy_taken)/new_heat_capacity),TCMB)
|
||||
|
||||
#undef OXYGEN_BURN_RATE_BASE
|
||||
#undef PLASMA_BURN_RATE_DELTA
|
||||
#undef PLASMA_MINIMUM_OXYGEN_NEEDED
|
||||
#undef PLASMA_MINIMUM_OXYGEN_PLASMA_RATIO
|
||||
#undef FIRE_CARBON_ENERGY_RELEASED
|
||||
#undef FIRE_PLASMA_ENERGY_RELEASED
|
||||
#undef WATER_VAPOR_FREEZE
|
||||
#undef NITRYL_FORMATION_ENERGY
|
||||
#undef TRITIUM_BURN_OXY_FACTOR
|
||||
#undef SUPER_SATURATION_THRESHOLD
|
||||
#undef STIMULUM_HEAT_SCALE
|
||||
#undef STIMULUM_FIRST_RISE
|
||||
#undef STIMULUM_FIRST_DROP
|
||||
#undef STIMULUM_SECOND_RISE
|
||||
#undef STIMULUM_ABSOLUTE_DROP
|
||||
#undef REACTION_OPPRESSION_THRESHOLD
|
||||
#undef NOBLIUM_FORMATION_ENERGY
|
||||
|
||||
@@ -26,10 +26,11 @@
|
||||
var/assignedrole
|
||||
var/show_flavour = TRUE
|
||||
var/banType = "lavaland"
|
||||
var/ghost_usable = TRUE
|
||||
|
||||
//ATTACK GHOST IGNORING PARENT RETURN VALUE
|
||||
/obj/effect/mob_spawn/attack_ghost(mob/user)
|
||||
if(!SSticker.HasRoundStarted() || !loc)
|
||||
if(!SSticker.HasRoundStarted() || !loc || !ghost_usable)
|
||||
return
|
||||
if(!uses)
|
||||
to_chat(user, "<span class='warning'>This spawner is out of charges!</span>")
|
||||
@@ -49,7 +50,7 @@
|
||||
. = ..()
|
||||
if(instant || (roundstart && (mapload || (SSticker && SSticker.current_state > GAME_STATE_SETTING_UP))))
|
||||
create()
|
||||
else
|
||||
else if(ghost_usable)
|
||||
GLOB.poi_list |= src
|
||||
LAZYADD(GLOB.mob_spawners[name], src)
|
||||
|
||||
@@ -225,6 +226,7 @@
|
||||
roundstart = FALSE //you could use these for alive fake humans on roundstart but this is more common scenario
|
||||
|
||||
/obj/effect/mob_spawn/human/corpse/delayed
|
||||
ghost_usable = FALSE //These are just not-yet-set corpses.
|
||||
instant = FALSE
|
||||
|
||||
//Non-human spawners
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
description = "Central Command will be holding a business convention this year. Ship a few briefcases in support."
|
||||
reward = 2500
|
||||
required_count = 5
|
||||
wanted_types = list(/obj/item/storage/briefcase)
|
||||
wanted_types = list(/obj/item/storage/briefcase, /obj/item/storage/secure/briefcase)
|
||||
|
||||
/datum/bounty/item/assistant/sunglasses
|
||||
name = "Sunglasses"
|
||||
@@ -104,55 +104,12 @@
|
||||
required_count = 2
|
||||
wanted_types = list(/obj/item/clothing/glasses/sunglasses)
|
||||
|
||||
/datum/bounty/item/assistant/gondola_hide
|
||||
name = "Gondola Hide"
|
||||
description = "Central Command has recently learned of strange creatures called Gondolas. If you catch one, ship its hide back to CentCom."
|
||||
reward = 5000
|
||||
wanted_types = list(/obj/item/stack/sheet/animalhide/gondola)
|
||||
|
||||
/datum/bounty/item/assistant/monkey_hide
|
||||
name = "Monkey Hide"
|
||||
description = "One of the scientists at CentCom is interested in testing products on monkey skin. Your mission is to acquire monkey's hide and ship it."
|
||||
reward = 1500
|
||||
wanted_types = list(/obj/item/stack/sheet/animalhide/monkey)
|
||||
|
||||
/datum/bounty/item/assistant/heart
|
||||
name = "Heart"
|
||||
description = "Commander Johnson is in critical condition after suffering a heart attack. Doctors say he needs a new heart fast. Ship one, pronto!"
|
||||
reward = 3000
|
||||
wanted_types = list(/obj/item/organ/heart)
|
||||
|
||||
/datum/bounty/item/assistant/lung
|
||||
name = "Lungs"
|
||||
description = "A recent explosion at Central Command has left multiple staff with punctured lungs. Ship spare lungs to be rewarded."
|
||||
reward = 3000
|
||||
required_count = 1
|
||||
wanted_types = list(/obj/item/organ/lungs)
|
||||
|
||||
/datum/bounty/item/assistant/appendix
|
||||
name = "Appendix"
|
||||
description = "Chef Gibb of Central Command wants to prepare a meal using a very special delicacy: an appendix. If you ship one, he'll pay."
|
||||
reward = 3000
|
||||
wanted_types = list(/obj/item/organ/appendix)
|
||||
|
||||
/datum/bounty/item/assistant/lizard_tail
|
||||
name = "Lizard Tail"
|
||||
description = "The Wizard Federation has made off with Nanotrasen's supply of lizard tails. While CentCom is dealing with the wizards, can the station spare a tail of their own?"
|
||||
reward = 3000
|
||||
wanted_types = list(/obj/item/organ/tail/lizard)
|
||||
|
||||
/datum/bounty/item/assistant/cat_tail
|
||||
name = "Cat Tail"
|
||||
description = "Central Command has run out of heavy duty pipe cleaners. Can you ship over a cat tail to help us out?"
|
||||
reward = 3000
|
||||
wanted_types = list(/obj/item/organ/tail/cat)
|
||||
|
||||
/datum/bounty/item/assistant/tail_whip
|
||||
name = "Nine Tails whip"
|
||||
description = "Commander Jackson is looking for a fine addition to her exotic weapons collection. She will reward you handsomely for either a Cat or Liz o' Nine Tails."
|
||||
reward = 4000
|
||||
wanted_types = list(/obj/item/melee/chainofcommand/tailwhip)
|
||||
|
||||
/datum/bounty/item/assistant/shard
|
||||
name = "Shards"
|
||||
description = "A killer clown has been stalking CentCom, and staff have been unable to catch her because she's not wearing shoes. Please ship some shards so that a booby trap can be constructed."
|
||||
@@ -246,10 +203,15 @@
|
||||
reward = 3000
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/meat/slab/corgi)
|
||||
|
||||
/datum/bounty/item/chef/action_figures
|
||||
/datum/bounty/item/assistant/action_figures
|
||||
name = "Action Figures"
|
||||
description = "The vice president's son saw an ad for action figures on the telescreen and now he won't shut up about them. Ship some to ease his complaints."
|
||||
reward = 4000
|
||||
required_count = 5
|
||||
wanted_types = list(/obj/item/toy/figure)
|
||||
|
||||
/datum/bounty/item/assistant/tail_whip
|
||||
name = "Nine Tails whip"
|
||||
description = "Commander Jackson is looking for a fine addition to her exotic weapons collection. She will reward you handsomely for either a Cat or Liz o' Nine Tails."
|
||||
reward = 4000
|
||||
wanted_types = list(/obj/item/melee/chainofcommand/tailwhip)
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
/datum/bounty/item/botany
|
||||
reward = 5000
|
||||
var/datum/bounty/item/botany/multiplier = 0 //adds bonus reward money; increased for higher tier or rare mutations
|
||||
var/datum/bounty/item/botany/bonus_desc //for adding extra flavor text to bounty descriptions
|
||||
var/datum/bounty/item/botany/foodtype = "meal" //same here
|
||||
|
||||
/datum/bounty/item/botany/New()
|
||||
..()
|
||||
description = "Central Command's head chef is looking to prepare a fine [foodtype] with [name]. [bonus_desc]"
|
||||
reward += multiplier * 1000
|
||||
required_count = rand(5, 10)
|
||||
|
||||
/datum/bounty/item/botany/ambrosia_vulgaris
|
||||
name = "Ambrosia Vulgaris Leaves"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/ambrosia/vulgaris)
|
||||
foodtype = "stew"
|
||||
|
||||
/datum/bounty/item/botany/ambrosia_gaia
|
||||
name = "Ambrosia Gaia Leaves"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/ambrosia/gaia)
|
||||
multiplier = 4
|
||||
foodtype = "stew"
|
||||
|
||||
/datum/bounty/item/botany/apple_golden
|
||||
name = "Golden Apples"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/apple/gold)
|
||||
multiplier = 4
|
||||
foodtype = "dessert"
|
||||
|
||||
/datum/bounty/item/botany/banana
|
||||
name = "Bananas"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/banana)
|
||||
exclude_types = list(/obj/item/reagent_containers/food/snacks/grown/banana/bluespace)
|
||||
foodtype = "banana split"
|
||||
|
||||
/datum/bounty/item/botany/banana_bluespace
|
||||
name = "Bluespace Bananas"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/banana/bluespace)
|
||||
multiplier = 2
|
||||
foodtype = "banana split"
|
||||
|
||||
/datum/bounty/item/botany/beans_koi
|
||||
name = "Koi Beans"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/koibeans)
|
||||
multiplier = 2
|
||||
|
||||
/datum/bounty/item/botany/berries_death
|
||||
name = "Death Berries"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/berries/death)
|
||||
multiplier = 2
|
||||
bonus_desc = "He insists that \"he knows what he's doing\"."
|
||||
foodtype = "sorbet"
|
||||
|
||||
/datum/bounty/item/botany/berries_glow
|
||||
name = "Glow-Berries"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/berries/glow)
|
||||
multiplier = 2
|
||||
foodtype = "sorbet"
|
||||
|
||||
/datum/bounty/item/botany/cannabis
|
||||
name = "Cannabis Leaves"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/cannabis)
|
||||
exclude_types = list(/obj/item/reagent_containers/food/snacks/grown/cannabis/white, /obj/item/reagent_containers/food/snacks/grown/cannabis/death, /obj/item/reagent_containers/food/snacks/grown/cannabis/ultimate)
|
||||
multiplier = 4 //hush money
|
||||
bonus_desc = "Do not mention this shipment to security."
|
||||
foodtype = "\"meal\""
|
||||
|
||||
/datum/bounty/item/botany/cannabis_white
|
||||
name = "Lifeweed Leaves"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/cannabis/white)
|
||||
multiplier = 6
|
||||
bonus_desc = "Do not mention this shipment to security."
|
||||
foodtype = "\"meal\""
|
||||
|
||||
/datum/bounty/item/botany/cannabis_death
|
||||
name = "Deathweed Leaves"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/cannabis/death)
|
||||
multiplier = 6
|
||||
bonus_desc = "Do not mention this shipment to security."
|
||||
foodtype = "\"meal\""
|
||||
|
||||
/datum/bounty/item/botany/cannabis_ultimate
|
||||
name = "Omega Weed Leaves"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/cannabis/ultimate)
|
||||
multiplier = 6
|
||||
bonus_desc = "Under no circumstances mention this shipment to security."
|
||||
foodtype = "\"meal\""
|
||||
|
||||
/datum/bounty/item/botany/wheat
|
||||
name = "Wheat Grains"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/wheat)
|
||||
|
||||
/datum/bounty/item/botany/rice
|
||||
name = "Rice Grains"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/rice)
|
||||
|
||||
/datum/bounty/item/botany/chili
|
||||
name = "Chili Peppers"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/chili)
|
||||
|
||||
/datum/bounty/item/botany/chili
|
||||
name = "Ice Chili Peppers"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/icepepper)
|
||||
multiplier = 2
|
||||
|
||||
/datum/bounty/item/botany/chili
|
||||
name = "Ghost Chili Peppers"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/ghost_chili)
|
||||
multiplier = 2
|
||||
|
||||
/datum/bounty/item/botany/citrus_lime
|
||||
name = "Limes"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/citrus/lime)
|
||||
foodtype = "sorbet"
|
||||
|
||||
/datum/bounty/item/botany/citrus_lemon
|
||||
name = "Lemons"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/citrus/lemon)
|
||||
foodtype = "sorbet"
|
||||
|
||||
/datum/bounty/item/botany/citrus_oranges
|
||||
name = "Oranges"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/citrus/orange)
|
||||
bonus_desc = "Do not ship lemons or limes." //I vanted orahnge!
|
||||
foodtype = "sorbet"
|
||||
|
||||
/datum/bounty/item/botany/eggplant
|
||||
name = "Eggplants"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/eggplant)
|
||||
bonus_desc = "Not to be confused with egg-plants."
|
||||
|
||||
/datum/bounty/item/botany/eggplant_eggy
|
||||
name = "Egg-plants"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/shell/eggy)
|
||||
bonus_desc = "Not to be confused with eggplants."
|
||||
multiplier = 2
|
||||
|
||||
/datum/bounty/item/botany/kudzu
|
||||
name = "Kudzu Pods"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/kudzupod)
|
||||
bonus_desc = "Store in a dry, dark place."
|
||||
multiplier = 4
|
||||
|
||||
/datum/bounty/item/botany/watermelon
|
||||
name = "Watermelons"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/watermelon)
|
||||
foodtype = "dessert"
|
||||
|
||||
/datum/bounty/item/botany/watermelon_holy
|
||||
name = "Holy Melons"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/holymelon)
|
||||
multiplier = 2
|
||||
foodtype = "dessert"
|
||||
|
||||
/datum/bounty/item/botany/glowshroom
|
||||
name = "Glowshrooms"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom)
|
||||
exclude_types = list(/obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom/glowcap, /obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom/shadowshroom)
|
||||
foodtype = "omelet"
|
||||
|
||||
/datum/bounty/item/botany/glowshroom_cap
|
||||
name = "Glowcaps"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom/glowcap)
|
||||
multiplier = 2
|
||||
foodtype = "omelet"
|
||||
|
||||
/datum/bounty/item/botany/glowshroom_shadow
|
||||
name = "Shadowshrooms"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom/shadowshroom)
|
||||
multiplier = 2
|
||||
foodtype = "omelet"
|
||||
|
||||
/datum/bounty/item/botany/nettles_death
|
||||
name = "Death Nettles"
|
||||
wanted_types = list(/obj/item/grown/nettle/death)
|
||||
multiplier = 2
|
||||
bonus_desc = "Wear protection when handling them."
|
||||
foodtype = "cheese"
|
||||
|
||||
/datum/bounty/item/botany/pineapples
|
||||
name = "Pineapples"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/pineapple)
|
||||
bonus_desc = "Not for human consumption."
|
||||
foodtype = "ashtray"
|
||||
|
||||
/datum/bounty/item/botany/tomato
|
||||
name = "Tomatoes"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/tomato)
|
||||
exclude_types = list(/obj/item/reagent_containers/food/snacks/grown/tomato/blue)
|
||||
|
||||
/datum/bounty/item/botany/tomato_bluespace
|
||||
name = "Bluespace Tomatoes"
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/tomato/blue/bluespace)
|
||||
multiplier = 4
|
||||
@@ -82,13 +82,6 @@
|
||||
reward = 8000
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/hotdog)
|
||||
|
||||
/datum/bounty/item/chef/lemon
|
||||
name = "Lemons"
|
||||
description = "A commander claims he can turn lemons into money. Ship him a few and he'll deposit the money into the station's account."
|
||||
reward = 4444
|
||||
required_count = 10
|
||||
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/citrus/lemon)
|
||||
|
||||
/datum/bounty/item/chef/eggplantparm
|
||||
name = "Eggplant Parmigianas"
|
||||
description = "A famous singer will be arriving at CentCom, and their contract demands that they only be served Eggplant Parmigiana. Ship some, please!"
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/datum/bounty/item/medical/heart
|
||||
name = "Heart"
|
||||
description = "Commander Johnson is in critical condition after suffering yet another heart attack. Doctors say he needs a new heart fast. Ship one, pronto!"
|
||||
reward = 3000
|
||||
wanted_types = list(/obj/item/organ/heart)
|
||||
|
||||
/datum/bounty/item/medical/lung
|
||||
name = "Lungs"
|
||||
description = "A recent explosion at Central Command has left multiple staff with punctured lungs. Ship spare lungs to be rewarded."
|
||||
reward = 10000
|
||||
required_count = 3
|
||||
wanted_types = list(/obj/item/organ/lungs)
|
||||
|
||||
/datum/bounty/item/medical/appendix
|
||||
name = "Appendix"
|
||||
description = "Chef Gibb of Central Command wants to prepare a meal using a very special delicacy: an appendix. If you ship one, he'll pay."
|
||||
reward = 5000 //there are no synthetic appendixes
|
||||
wanted_types = list(/obj/item/organ/appendix)
|
||||
|
||||
/datum/bounty/item/medical/ears
|
||||
name = "Ears"
|
||||
description = "Multiple staff at Station 12 have been left deaf due to unauthorized clowning. Ship them new ears."
|
||||
reward = 10000
|
||||
required_count = 3
|
||||
wanted_types = list(/obj/item/organ/ears)
|
||||
|
||||
/datum/bounty/item/medical/liver
|
||||
name = "Livers"
|
||||
description = "Multiple high-ranking CentCom diplomats have been hospitalized with liver failure after a recent meeting with Third Soviet Union ambassadors. Help us out, will you?"
|
||||
reward = 10000
|
||||
required_count = 3
|
||||
wanted_types = list(/obj/item/organ/liver)
|
||||
|
||||
/datum/bounty/item/medical/eye
|
||||
name = "Organic Eyes"
|
||||
description = "Station 5's Research Director Willem is requesting a few pairs of non-robotic eyes. Don't ask questions, just ship them."
|
||||
reward = 10000
|
||||
required_count = 3
|
||||
wanted_types = list(/obj/item/organ/eyes)
|
||||
exclude_types = list(/obj/item/organ/eyes/robotic)
|
||||
|
||||
/datum/bounty/item/medical/tongue
|
||||
name = "Tongues"
|
||||
description = "A recent attack by Mime extremists has left staff at Station 23 speechless. Ship some spare tongues."
|
||||
reward = 10000
|
||||
required_count = 3
|
||||
wanted_types = list(/obj/item/organ/tongue)
|
||||
|
||||
/datum/bounty/item/medical/lizard_tail
|
||||
name = "Lizard Tail"
|
||||
description = "The Wizard Federation has made off with Nanotrasen's supply of lizard tails. While CentCom is dealing with the wizards, can the station spare a tail of their own?"
|
||||
reward = 3000
|
||||
wanted_types = list(/obj/item/organ/tail/lizard)
|
||||
|
||||
/datum/bounty/item/medical/cat_tail
|
||||
name = "Cat Tail"
|
||||
description = "Central Command has run out of heavy duty pipe cleaners. Can you ship over a cat tail to help us out?"
|
||||
reward = 3000
|
||||
wanted_types = list(/obj/item/organ/tail/cat)
|
||||
@@ -45,7 +45,7 @@
|
||||
name = "Diamond Mining Drill"
|
||||
description = "Central Command is willing to pay three months salary in exchange for one diamond mining drill."
|
||||
reward = 15000
|
||||
wanted_types = list(/obj/item/mecha_parts/mecha_equipment/drill/diamonddrill)
|
||||
wanted_types = list(/obj/item/pickaxe/drill/diamonddrill, /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill)
|
||||
|
||||
/datum/bounty/item/science/floor_buffer
|
||||
name = "Floor Buffer Upgrade"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/datum/bounty/item/syndicate_documents
|
||||
name = "Syndicate Documents"
|
||||
description = "Intel regarding the syndicate is highly prized at CentCom. If you find syndicate documents, ship them. You could save lives."
|
||||
reward = 10000
|
||||
reward = 15000
|
||||
wanted_types = list(/obj/item/documents/syndicate, /obj/item/documents/photocopy)
|
||||
|
||||
/datum/bounty/item/syndicate_documents/applies_to(obj/O)
|
||||
@@ -19,6 +19,13 @@
|
||||
return (Copy.copy_type && ispath(Copy.copy_type, /obj/item/documents/syndicate))
|
||||
return TRUE
|
||||
|
||||
/datum/bounty/item/adamantine
|
||||
name = "Adamantine"
|
||||
description = "Nanotrasen's anomalous materials division is in desparate need for Adamantine. Send them a large shipment and we'll make it worth your while."
|
||||
reward = 35000
|
||||
required_count = 10
|
||||
wanted_types = list(/obj/item/stack/sheet/mineral/adamantine)
|
||||
|
||||
/datum/bounty/more_bounties
|
||||
name = "More Bounties"
|
||||
description = "Complete enough bounties and CentCom will issue new ones!"
|
||||
|
||||
@@ -75,7 +75,7 @@ GLOBAL_LIST_EMPTY(bounties_list)
|
||||
|
||||
// Returns a new bounty of random type, but does not add it to GLOB.bounties_list.
|
||||
/proc/random_bounty()
|
||||
switch(rand(1, 11))
|
||||
switch(rand(1, 13))
|
||||
if(1)
|
||||
var/subtype = pick(subtypesof(/datum/bounty/item/assistant))
|
||||
return new subtype
|
||||
@@ -109,6 +109,12 @@ GLOBAL_LIST_EMPTY(bounties_list)
|
||||
if(11)
|
||||
var/subtype = pick(subtypesof(/datum/bounty/item/mining))
|
||||
return new subtype
|
||||
if(12)
|
||||
var/subtype = pick(subtypesof(/datum/bounty/item/medical))
|
||||
return new subtype
|
||||
if(13)
|
||||
var/subtype = pick(subtypesof(/datum/bounty/item/botany))
|
||||
return new subtype
|
||||
|
||||
// Called lazily at startup to populate GLOB.bounties_list with random bounties.
|
||||
/proc/setup_bounties()
|
||||
@@ -122,7 +128,9 @@ GLOBAL_LIST_EMPTY(bounties_list)
|
||||
/datum/bounty/item/security = 1,
|
||||
/datum/bounty/virus = 1,
|
||||
/datum/bounty/item/engineering = 1,
|
||||
/datum/bounty/item/mining = 2)
|
||||
/datum/bounty/item/mining = 2,
|
||||
/datum/bounty/item/medical = 2,
|
||||
/datum/bounty/item/botany = 2)
|
||||
|
||||
for(var/the_type in easy_add_list_subtypes)
|
||||
for(var/i in 1 to easy_add_list_subtypes[the_type])
|
||||
@@ -154,6 +162,7 @@ GLOBAL_LIST_EMPTY(bounties_list)
|
||||
/********************************Low Priority Gens********************************/
|
||||
var/list/low_priority_strict_type_list = list( /datum/bounty/item/alien_organs,
|
||||
/datum/bounty/item/syndicate_documents,
|
||||
/datum/bounty/item/adamantine,
|
||||
/datum/bounty/more_bounties)
|
||||
|
||||
for(var/low_priority_bounty in low_priority_strict_type_list)
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
export_types = list(/obj/item/stack/sheet/animalhide/lizard)
|
||||
|
||||
/datum/export/stack/skin/gondola
|
||||
cost = 500
|
||||
cost = 5000
|
||||
unit_name = "gondola hide"
|
||||
export_types = list(/obj/item/stack/sheet/animalhide/gondola)
|
||||
|
||||
|
||||
@@ -448,6 +448,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
|
||||
qdel(query_get_related_ip)
|
||||
var/datum/DBQuery/query_get_related_cid = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE computerid = '[computer_id]' AND ckey != '[sql_ckey]'")
|
||||
if(!query_get_related_cid.Execute())
|
||||
qdel(query_get_related_cid)
|
||||
return
|
||||
related_accounts_cid = ""
|
||||
while (query_get_related_cid.NextRow())
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/datum/player_details
|
||||
var/list/player_actions = list()
|
||||
var/list/logging = list(INDIVIDUAL_ATTACK_LOG, INDIVIDUAL_SAY_LOG, INDIVIDUAL_EMOTE_LOG, INDIVIDUAL_OOC_LOG)
|
||||
var/list/logging = list()
|
||||
var/byond_version = "Unknown"
|
||||
@@ -1102,11 +1102,13 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
ghost_others = GHOST_OTHERS_SIMPLE
|
||||
|
||||
if("name")
|
||||
var/new_name = reject_bad_name( input(user, "Choose your character's name:", "Character Preference") as text|null )
|
||||
var/new_name = input(user, "Choose your character's name:", "Character Preference") as text|null
|
||||
if(new_name)
|
||||
real_name = new_name
|
||||
else
|
||||
to_chat(user, "<font color='red'>Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .</font>")
|
||||
new_name = reject_bad_name(new_name)
|
||||
if(new_name)
|
||||
real_name = new_name
|
||||
else
|
||||
to_chat(user, "<font color='red'>Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .</font>")
|
||||
|
||||
if("age")
|
||||
var/new_age = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX])", "Character Preference") as num|null
|
||||
|
||||
@@ -50,9 +50,7 @@
|
||||
to_chat(src, "<span class='danger'>You have OOC muted.</span>")
|
||||
return
|
||||
|
||||
|
||||
log_talk(mob,"[key_name(src)] : [raw_msg]",LOGOOC)
|
||||
mob.log_message("[key]: [raw_msg]", INDIVIDUAL_OOC_LOG)
|
||||
mob.log_talk(raw_msg, LOG_OOC)
|
||||
|
||||
var/keyname = key
|
||||
if(prefs.unlock_content)
|
||||
|
||||
@@ -205,18 +205,24 @@
|
||||
log_game("[key_name(src)] (job: [src.job ? "[src.job]" : "None"]) committed suicide at [AREACOORD(src)].")
|
||||
|
||||
/mob/living/proc/canSuicide()
|
||||
if(stat == CONSCIOUS)
|
||||
return TRUE
|
||||
else if(stat == DEAD)
|
||||
to_chat(src, "You're already dead!")
|
||||
else if(stat == UNCONSCIOUS)
|
||||
to_chat(src, "You need to be conscious to suicide!")
|
||||
switch(stat)
|
||||
if(CONSCIOUS)
|
||||
return TRUE
|
||||
if(SOFT_CRIT)
|
||||
to_chat(src, "You can't commit suicide while in a critical condition!")
|
||||
if(UNCONSCIOUS)
|
||||
to_chat(src, "You need to be conscious to commit suicide!")
|
||||
if(DEAD)
|
||||
to_chat(src, "You're already dead!")
|
||||
return
|
||||
|
||||
/mob/living/carbon/canSuicide()
|
||||
if(!..())
|
||||
return
|
||||
if(!canmove || restrained()) //just while I finish up the new 'fun' suiciding verb. This is to prevent metagaming via suicide
|
||||
to_chat(src, "You can't commit suicide whilst restrained! ((You can type Ghost instead however.))")
|
||||
if(IsStun() || IsKnockdown()) //just while I finish up the new 'fun' suiciding verb. This is to prevent metagaming via suicide
|
||||
to_chat(src, "You can't commit suicide while stunned! ((You can type Ghost instead however.))")
|
||||
return
|
||||
if(restrained())
|
||||
to_chat(src, "You can't commit suicide while restrained! ((You can type Ghost instead however.))")
|
||||
return
|
||||
return TRUE
|
||||
|
||||
@@ -237,6 +237,7 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
attack_verb = list("warned", "cautioned", "smashed")
|
||||
resistance_flags = NONE
|
||||
dynamic_hair_suffix = ""
|
||||
|
||||
/obj/item/clothing/head/santa
|
||||
name = "santa hat"
|
||||
@@ -327,6 +328,7 @@
|
||||
name = "french beret"
|
||||
desc = "A quality beret, infused with the aroma of chain-smoking, wine-swilling Parisians. You feel less inclined to engage military conflict, for some reason."
|
||||
icon_state = "beretblack"
|
||||
dynamic_hair_suffix = ""
|
||||
|
||||
/obj/item/clothing/head/frenchberet/speechModification(M)
|
||||
if(copytext(M, 1, 2) != "*")
|
||||
|
||||
@@ -272,3 +272,24 @@
|
||||
icon_state = "scarecrow_sack"
|
||||
item_state = "scarecrow_sack"
|
||||
flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
|
||||
|
||||
/obj/item/clothing/mask/gondola
|
||||
name = "gondola mask"
|
||||
desc = "Genuine gondola fur."
|
||||
icon_state = "gondola"
|
||||
item_state = "gondola"
|
||||
flags_inv = HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/clothing/mask/gondola/speechModification(M)
|
||||
if(copytext(M, 1, 2) != "*")
|
||||
M = " [M]"
|
||||
var/list/spurdo_words = strings("spurdo_replacement.json", "spurdo")
|
||||
for(var/key in spurdo_words)
|
||||
var/value = spurdo_words[key]
|
||||
if(islist(value))
|
||||
value = pick(value)
|
||||
M = replacetextEx(M,regex(uppertext(key),"g"), "[uppertext(value)]")
|
||||
M = replacetextEx(M,regex(capitalize(key),"g"), "[capitalize(value)]")
|
||||
M = replacetextEx(M,regex(key,"g"), "[value]")
|
||||
return trim(M)
|
||||
|
||||
@@ -727,6 +727,14 @@
|
||||
fitted = NO_FEMALE_UNIFORM
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/gondola
|
||||
name = "gondola hide suit"
|
||||
desc = "Now you're cooking."
|
||||
icon_state = "gondola"
|
||||
item_state = "lb_suit"
|
||||
item_color = "gondola"
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/skeleton
|
||||
name = "skeleton jumpsuit"
|
||||
desc = "A black jumpsuit with a white bone pattern printed on it. Spooky!"
|
||||
|
||||
@@ -30,18 +30,17 @@
|
||||
if(iscarbon(A) && A.reagents && reagents.total_volume)
|
||||
var/mob/living/carbon/C = A
|
||||
var/reagentlist = pretty_string_from_reagent_list(reagents)
|
||||
var/log_object = "a damp rag containing [reagentlist]"
|
||||
if(user.a_intent == INTENT_HARM && !C.is_mouth_covered())
|
||||
reagents.reaction(C, INGEST)
|
||||
reagents.trans_to(C, reagents.total_volume)
|
||||
C.visible_message("<span class='danger'>[user] has smothered \the [C] with \the [src]!</span>", "<span class='userdanger'>[user] has smothered you with \the [src]!</span>", "<span class='italics'>You hear some struggling and muffled cries of surprise.</span>")
|
||||
log_game("[key_name(user)] smothered [key_name(A)] with a damp rag containing [reagentlist]")
|
||||
log_attack("[key_name(user)] smothered [key_name(A)] with a damp rag containing [reagentlist]")
|
||||
log_combat(user, C, "smothered", log_object)
|
||||
else
|
||||
reagents.reaction(C, TOUCH)
|
||||
reagents.clear_reagents()
|
||||
log_game("[key_name(user)] touched [key_name(A)] with a damp rag containing [reagentlist]")
|
||||
log_attack("[key_name(user)] touched [key_name(A)] with a damp rag containing [reagentlist]")
|
||||
C.visible_message("<span class='notice'>[user] has touched \the [C] with \the [src].</span>")
|
||||
log_combat(user, C, "touched", log_object)
|
||||
|
||||
else if(istype(A) && src in user)
|
||||
user.visible_message("[user] starts to wipe down [A] with [src]!", "<span class='notice'>You start to wipe down [A] with [src]...</span>")
|
||||
|
||||
@@ -7,11 +7,11 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0)
|
||||
|
||||
/world/Error(exception/E, datum/e_src)
|
||||
GLOB.total_runtimes++
|
||||
|
||||
|
||||
if(!istype(E)) //Something threw an unusual exception
|
||||
log_world("uncaught runtime error: [E]")
|
||||
return ..()
|
||||
|
||||
|
||||
//this is snowflake because of a byond bug (ID:2306577), do not attempt to call non-builtin procs in this if
|
||||
if(copytext(E.name,1,32) == "Maximum recursion level reached")
|
||||
//log to world while intentionally triggering the byond bug.
|
||||
@@ -86,8 +86,8 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0)
|
||||
var/list/usrinfo = null
|
||||
var/locinfo
|
||||
if(istype(usr))
|
||||
usrinfo = list(" usr: [datum_info_line(usr)]")
|
||||
locinfo = atom_loc_line(usr)
|
||||
usrinfo = list(" usr: [key_name(usr)]")
|
||||
locinfo = loc_name(usr)
|
||||
if(locinfo)
|
||||
usrinfo += " usr.loc: [locinfo]"
|
||||
// The proceeding mess will almost definitely break if error messages are ever changed
|
||||
|
||||
@@ -46,8 +46,8 @@
|
||||
if(M.assigned_role == job)
|
||||
citizens += H
|
||||
M.add_antag_datum(/datum/antagonist/separatist,nation)
|
||||
H.log_message("<font color='red'>Was made into a separatist, long live [nation_name]!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
|
||||
H.log_message("Was made into a separatist, long live [nation_name]!", LOG_ATTACK, color="red")
|
||||
|
||||
if(citizens.len)
|
||||
var/message
|
||||
for(var/job in jobs_to_revolt)
|
||||
|
||||
@@ -63,11 +63,11 @@
|
||||
/obj/item/greentext/proc/check_winner()
|
||||
if(!new_holder)
|
||||
return
|
||||
|
||||
|
||||
if(is_centcom_level(new_holder.z))//you're winner!
|
||||
to_chat(new_holder, "<font color='green'>At last it feels like victory is assured!</font>")
|
||||
new_holder.mind.add_antag_datum(/datum/antagonist/greentext)
|
||||
new_holder.log_message("<font color='green'>Won with greentext!!!</font>", INDIVIDUAL_ATTACK_LOG)
|
||||
new_holder.log_message("won with greentext!!!", LOG_ATTACK, color="green")
|
||||
color_altered_mobs -= new_holder
|
||||
resistance_flags |= ON_FIRE
|
||||
qdel(src)
|
||||
|
||||
@@ -36,5 +36,5 @@
|
||||
SSticker.mode.apprentices += I.mind
|
||||
I.mind.special_role = "imposter"
|
||||
//
|
||||
I.log_message("<font color='red'>Is an imposter!</font>", INDIVIDUAL_ATTACK_LOG) //?
|
||||
I.log_message("is an imposter!", LOG_ATTACK, color="red") //?
|
||||
SEND_SOUND(I, sound('sound/effects/magic.ogg'))
|
||||
|
||||
@@ -771,13 +771,13 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
..()
|
||||
var/turf/source = random_far_turf()
|
||||
if(!sound_type)
|
||||
sound_type = pick("airlock","airlock_pry","console","explosion","far_explosion","mech","glass","alarm","beepsky","mech","wall_decon","door_hack","tesla")
|
||||
sound_type = pick("airlock","airlock pry","console","explosion","far explosion","mech","glass","alarm","beepsky","mech","wall decon","door hack")
|
||||
feedback_details += "Type: [sound_type]"
|
||||
//Strange audio
|
||||
switch(sound_type)
|
||||
if("airlock")
|
||||
target.playsound_local(source,'sound/machines/airlock.ogg', 30, 1)
|
||||
if("airlock_pry")
|
||||
if("airlock pry")
|
||||
target.playsound_local(source,'sound/machines/airlock_alien_prying.ogg', 100, 1)
|
||||
sleep(50)
|
||||
target.playsound_local(source, 'sound/machines/airlockforced.ogg', 30, 1)
|
||||
@@ -788,7 +788,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
target.playsound_local(source,'sound/effects/explosion1.ogg', 50, 1)
|
||||
else
|
||||
target.playsound_local(source, 'sound/effects/explosion2.ogg', 50, 1)
|
||||
if("far_explosion")
|
||||
if("far explosion")
|
||||
target.playsound_local(source, 'sound/effects/explosionfar.ogg', 50, 1)
|
||||
if("glass")
|
||||
target.playsound_local(source, pick('sound/effects/glassbr1.ogg','sound/effects/glassbr2.ogg','sound/effects/glassbr3.ogg'), 50, 1)
|
||||
@@ -807,14 +807,14 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
mech_dir = pick(GLOB.cardinals)
|
||||
sleep(10)
|
||||
//Deconstructing a wall
|
||||
if("wall_decon")
|
||||
if("wall decon")
|
||||
target.playsound_local(source, 'sound/items/welder.ogg', 50, 1)
|
||||
sleep(105)
|
||||
target.playsound_local(source, 'sound/items/welder2.ogg', 50, 1)
|
||||
sleep(15)
|
||||
target.playsound_local(source, 'sound/items/ratchet.ogg', 50, 1)
|
||||
//Hacking a door
|
||||
if("door_hack")
|
||||
if("door hack")
|
||||
target.playsound_local(source, 'sound/items/screwdriver.ogg', 50, 1)
|
||||
sleep(rand(40,80))
|
||||
target.playsound_local(source, 'sound/machines/airlockforced.ogg', 30, 1)
|
||||
@@ -827,7 +827,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
..()
|
||||
var/turf/source = random_far_turf()
|
||||
if(!sound_type)
|
||||
sound_type = pick("phone","hallelujah","highlander","hyperspace","game_over","creepy","tesla")
|
||||
sound_type = pick("phone","hallelujah","highlander","laughter","hyperspace","game over","creepy","tesla")
|
||||
feedback_details += "Type: [sound_type]"
|
||||
//Strange audio
|
||||
switch(sound_type)
|
||||
@@ -845,7 +845,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
target.playsound_local(source, 'sound/effects/pray_chaplain.ogg', 50)
|
||||
if("highlander")
|
||||
target.playsound_local(null, 'sound/misc/highlander.ogg', 50)
|
||||
if("game_over")
|
||||
if("game over")
|
||||
target.playsound_local(source, 'sound/misc/compiler-failure.ogg', 50)
|
||||
if("laughter")
|
||||
if(prob(50))
|
||||
@@ -870,10 +870,10 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
set waitfor = FALSE
|
||||
..()
|
||||
if(!message)
|
||||
message = pick("ratvar","shuttle_dock","blob_alert","malf_ai","meteors","supermatter")
|
||||
message = pick("ratvar","shuttle dock","blob alert","malf ai","meteors","supermatter")
|
||||
feedback_details += "Type: [message]"
|
||||
switch(message)
|
||||
if("blob_alert")
|
||||
if("blob alert")
|
||||
to_chat(target, "<h1 class='alert'>Biohazard Alert</h1>")
|
||||
to_chat(target, "<br><br><span class='alert'>Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.</span><br><br>")
|
||||
SEND_SOUND(target, 'sound/ai/outbreak5.ogg')
|
||||
@@ -882,11 +882,11 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
target.playsound_local(target, 'sound/effects/clockcult_gateway_disrupted.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
sleep(27)
|
||||
target.playsound_local(target, 'sound/effects/explosion_distant.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
if("shuttle_dock")
|
||||
if("shuttle dock")
|
||||
to_chat(target, "<h1 class='alert'>Priority Announcement</h1>")
|
||||
to_chat(target, "<br><br><span class='alert'>The Emergency Shuttle has docked with the station. You have 3 minutes to board the Emergency Shuttle.</span><br><br>")
|
||||
SEND_SOUND(target, 'sound/ai/shuttledock.ogg')
|
||||
if("malf_ai") //AI is doomsdaying!
|
||||
if("malf ai") //AI is doomsdaying!
|
||||
to_chat(target, "<h1 class='alert'>Anomaly Alert</h1>")
|
||||
to_chat(target, "<br><br><span class='alert'>Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.</span><br><br>")
|
||||
SEND_SOUND(target, 'sound/ai/aimalf.ogg')
|
||||
@@ -900,11 +900,14 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
|
||||
/datum/hallucination/hudscrew
|
||||
|
||||
/datum/hallucination/hudscrew/New(mob/living/carbon/C, forced = TRUE)
|
||||
/datum/hallucination/hudscrew/New(mob/living/carbon/C, forced = TRUE, screwyhud_type)
|
||||
set waitfor = FALSE
|
||||
..()
|
||||
//Screwy HUD
|
||||
target.set_screwyhud(pick(SCREWYHUD_CRIT,SCREWYHUD_DEAD,SCREWYHUD_HEALTHY))
|
||||
var/chosen_screwyhud = screwyhud_type
|
||||
if(!chosen_screwyhud)
|
||||
chosen_screwyhud = pick(SCREWYHUD_CRIT,SCREWYHUD_DEAD,SCREWYHUD_HEALTHY)
|
||||
target.set_screwyhud(chosen_screwyhud)
|
||||
feedback_details += "Type: [target.hal_screwyhud]"
|
||||
sleep(rand(100,250))
|
||||
target.set_screwyhud(SCREWYHUD_NONE)
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
if(!reagents || !reagents.total_volume)
|
||||
return // The drink might be empty after the delay, such as by spam-feeding
|
||||
M.visible_message("<span class='danger'>[user] feeds the contents of [src] to [M].</span>", "<span class='userdanger'>[user] feeds the contents of [src] to [M].</span>")
|
||||
add_logs(user, M, "fed", reagents.log_list())
|
||||
log_combat(user, M, "fed", reagents.log_list())
|
||||
|
||||
var/fraction = min(gulp_size/reagents.total_volume, 1)
|
||||
checkLiked(fraction, M)
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
"<span class='userdanger'>[target] hits [target.p_them()]self with a bottle of [src.name][head_attack_message]!</span>")
|
||||
|
||||
//Attack logs
|
||||
add_logs(user, target, "attacked", src)
|
||||
log_combat(user, target, "attacked", src)
|
||||
|
||||
//The reagents in the bottle splash all over the target, thanks for the idea Nodrak
|
||||
SplashReagents(target)
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
if(user.a_intent == INTENT_HARM && ismob(target) && target.reagents && reagents.total_volume)
|
||||
target.visible_message("<span class='danger'>[user] splashes the contents of [src] onto [target]!</span>", \
|
||||
"<span class='userdanger'>[user] splashes the contents of [src] onto [target]!</span>")
|
||||
add_logs(user, target, "splashed", src)
|
||||
log_combat(user, target, "splashed", src)
|
||||
reagents.reaction(target, TOUCH)
|
||||
reagents.clear_reagents()
|
||||
return
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
if(!reagents || !reagents.total_volume)
|
||||
return // The condiment might be empty after the delay.
|
||||
user.visible_message("<span class='warning'>[user] feeds [M] from [src].</span>")
|
||||
add_logs(user, M, "fed", reagents.log_list())
|
||||
log_combat(user, M, "fed", reagents.log_list())
|
||||
|
||||
var/fraction = min(10/reagents.total_volume, 1)
|
||||
reagents.reaction(M, INGEST, fraction)
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
|
||||
if(!do_mob(user, M))
|
||||
return
|
||||
add_logs(user, M, "fed", reagents.log_list())
|
||||
log_combat(user, M, "fed", reagents.log_list())
|
||||
M.visible_message("<span class='danger'>[user] forces [M] to eat [src].</span>", \
|
||||
"<span class='userdanger'>[user] forces [M] to eat [src].</span>")
|
||||
|
||||
|
||||
@@ -316,7 +316,7 @@
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/meat/steak/gondola
|
||||
name = "gondola steak"
|
||||
tastes = list("meat = 1", "tranquility" = 1)
|
||||
tastes = list("meat" = 1, "tranquility" = 1)
|
||||
|
||||
//////////////////////////////// MEAT CUTLETS ///////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -189,7 +189,7 @@
|
||||
var/mob/living/carbon/monkey/bananas = new(drop_location(), TRUE, spammer)
|
||||
if (!QDELETED(bananas))
|
||||
visible_message("<span class='notice'>[src] expands!</span>")
|
||||
bananas.log_message("Spawned via [src] at [AREACOORD(src)], Last attached mob: [key_name(spammer)].", INDIVIDUAL_ATTACK_LOG)
|
||||
bananas.log_message("Spawned via [src] at [AREACOORD(src)], Last attached mob: [key_name(spammer)].", LOG_ATTACK)
|
||||
else if (!spammer) // Visible message in case there are no fingerprints
|
||||
visible_message("<span class='notice'>[src] fails to expand!</span>")
|
||||
qdel(src)
|
||||
|
||||
@@ -160,8 +160,59 @@
|
||||
tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "pineapple" = 2, "ham" = 2)
|
||||
foodtype = GRAIN | VEGETABLES | DAIRY | MEAT | FRUIT | PINEAPPLE
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/pizza/arnold
|
||||
name = "\improper Arnold pizza"
|
||||
desc = "Hello, you've reached Arnold's pizza shop. I'm not here now, I'm out killing pepperoni."
|
||||
icon_state = "arnoldpizza"
|
||||
slice_path = /obj/item/reagent_containers/food/snacks/pizzaslice/arnold
|
||||
bonus_reagents = list("nutriment" = 30, "vitamin" = 6, "iron" = 10, "omnizine" = 30)
|
||||
tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "pepperoni" = 2, "9 millimeter bullets" = 2)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/proc/try_break_off(mob/living/M, mob/living/user) //maybe i give you a pizza maybe i break off your arm
|
||||
var/obj/item/bodypart/l_arm = user.get_bodypart(BODY_ZONE_L_ARM)
|
||||
var/obj/item/bodypart/r_arm = user.get_bodypart(BODY_ZONE_R_ARM)
|
||||
if(prob(50) && iscarbon(user) && M == user && (r_arm || l_arm))
|
||||
user.visible_message("<span class='warning'>\The [src] breaks off [user]'s arm!!</span>", "<span class='warning'>\The [src] breaks off your arm!</span>")
|
||||
if(l_arm)
|
||||
l_arm.dismember()
|
||||
else
|
||||
r_arm.dismember()
|
||||
playsound(user,pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg') ,50, TRUE, -1)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/proc/i_kill_you(obj/item/I, mob/user)
|
||||
if(istype(I, /obj/item/reagent_containers/food/snacks/pineappleslice))
|
||||
to_chat(user, "<font color='red' size='7'>If you want something crazy like pineapple, I kill you.</font>")
|
||||
user.gib() //if you want something crazy like pineapple, i kill you
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/pizza/arnold/attack(mob/living/M, mob/living/user)
|
||||
. = ..()
|
||||
try_break_off(M, user)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/pizza/arnold/attackby(obj/item/I, mob/user)
|
||||
i_kill_you(I, user)
|
||||
. = ..()
|
||||
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/pizzaslice/arnold
|
||||
name = "\improper Arnold pizza slice"
|
||||
desc = "I come over, maybe I give you a pizza, maybe I break off your arm."
|
||||
icon_state = "arnoldpizzaslice"
|
||||
filling_color = "#A52A2A"
|
||||
tastes = list("crust" = 1, "tomato" = 1, "cheese" = 1, "pineapple" = 2, "ham" = 2)
|
||||
foodtype = GRAIN | VEGETABLES | DAIRY | MEAT
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/pizzaslice/arnold/attack(mob/living/M, mob/living/user)
|
||||
. =..()
|
||||
try_break_off(M, user)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/pizzaslice/arnold/attackby(obj/item/I, mob/user)
|
||||
i_kill_you(I, user)
|
||||
. = ..()
|
||||
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/pizzaslice/custom
|
||||
name = "pizza slice"
|
||||
icon_state = "pizzamargheritaslice"
|
||||
filling_color = "#FFFFFF"
|
||||
foodtype = GRAIN | VEGETABLES
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
/obj/machinery/gibber/attackby(obj/item/P, mob/user, params)
|
||||
if(default_deconstruction_screwdriver(user, "grinder_open", "grinder", P))
|
||||
return
|
||||
|
||||
|
||||
else if(default_pry_open(P))
|
||||
return
|
||||
|
||||
@@ -184,7 +184,7 @@
|
||||
if(typeofskin)
|
||||
skin = new typeofskin
|
||||
|
||||
add_logs(user, occupant, "gibbed")
|
||||
log_combat(user, occupant, "gibbed")
|
||||
mob_occupant.death(1)
|
||||
mob_occupant.ghostize()
|
||||
qdel(src.occupant)
|
||||
|
||||
@@ -24,6 +24,18 @@
|
||||
result = /obj/item/reagent_containers/food/snacks/pizza/meat
|
||||
subcategory = CAT_PIZZA
|
||||
|
||||
/datum/crafting_recipe/food/arnold
|
||||
name = "Arnold pizza"
|
||||
reqs = list(
|
||||
/obj/item/reagent_containers/food/snacks/pizzabread = 1,
|
||||
/obj/item/reagent_containers/food/snacks/meat/cutlet = 3,
|
||||
/obj/item/ammo_casing/c9mm = 8,
|
||||
/obj/item/reagent_containers/food/snacks/cheesewedge = 1,
|
||||
/obj/item/reagent_containers/food/snacks/grown/tomato = 1
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/pizza/arnold
|
||||
subcategory = CAT_PIZZA
|
||||
|
||||
/datum/crafting_recipe/food/mushroompizza
|
||||
name = "Mushroom pizza"
|
||||
reqs = list(
|
||||
@@ -45,7 +57,7 @@
|
||||
result = /obj/item/reagent_containers/food/snacks/pizza/vegetable
|
||||
subcategory = CAT_PIZZA
|
||||
|
||||
/datum/crafting_recipe/food/donpocketpizza
|
||||
/datum/crafting_recipe/food/donkpocketpizza
|
||||
name = "Donkpocket pizza"
|
||||
reqs = list(
|
||||
/obj/item/reagent_containers/food/snacks/pizzabread = 1,
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
name = "lush grass"
|
||||
icon_state = "grass"
|
||||
bullet_bounce_sound = null
|
||||
tiled_dirt = FALSE
|
||||
|
||||
/turf/open/floor/holofloor/beach
|
||||
gender = PLURAL
|
||||
@@ -35,6 +36,7 @@
|
||||
icon = 'icons/misc/beach.dmi'
|
||||
icon_state = "sand"
|
||||
bullet_bounce_sound = null
|
||||
tiled_dirt = FALSE
|
||||
|
||||
/turf/open/floor/holofloor/beach/coast_t
|
||||
gender = NEUTER
|
||||
@@ -54,6 +56,7 @@
|
||||
/turf/open/floor/holofloor/asteroid
|
||||
name = "asteroid"
|
||||
icon_state = "asteroid0"
|
||||
tiled_dirt = FALSE
|
||||
|
||||
/turf/open/floor/holofloor/asteroid/Initialize()
|
||||
icon_state = "asteroid[rand(0, 12)]"
|
||||
@@ -63,6 +66,7 @@
|
||||
gender = PLURAL
|
||||
name = "basalt"
|
||||
icon_state = "basalt0"
|
||||
tiled_dirt = FALSE
|
||||
|
||||
/turf/open/floor/holofloor/basalt/Initialize()
|
||||
. = ..()
|
||||
@@ -84,6 +88,7 @@
|
||||
icon = 'icons/turf/space.dmi'
|
||||
icon_state = "speedspace_ns_1"
|
||||
bullet_bounce_sound = null
|
||||
tiled_dirt = FALSE
|
||||
|
||||
/turf/open/floor/holofloor/hyperspace/Initialize()
|
||||
icon_state = "speedspace_ns_[(x + 5*y + (y%2+1)*7)%15+1]"
|
||||
@@ -102,6 +107,7 @@
|
||||
smooth = SMOOTH_TRUE
|
||||
canSmoothWith = null
|
||||
bullet_bounce_sound = null
|
||||
tiled_dirt = FALSE
|
||||
|
||||
/turf/open/floor/holofloor/carpet/Initialize()
|
||||
. = ..()
|
||||
@@ -122,6 +128,7 @@
|
||||
slowdown = 2
|
||||
bullet_sizzle = TRUE
|
||||
bullet_bounce_sound = null
|
||||
tiled_dirt = FALSE
|
||||
|
||||
/turf/open/floor/holofloor/snow/cold
|
||||
initial_gas_mix = "nob=7500;TEMP=2.7"
|
||||
@@ -131,3 +138,4 @@
|
||||
name = "asteroid sand"
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "asteroid"
|
||||
tiled_dirt = FALSE
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
return
|
||||
if(isliving(M))
|
||||
to_chat(M, "<span class='danger'>You are stunned by the powerful acid of the Deathnettle!</span>")
|
||||
add_logs(user, M, "attacked", src)
|
||||
log_combat(user, M, "attacked", src)
|
||||
|
||||
M.adjust_blurriness(force/7)
|
||||
if(prob(20))
|
||||
|
||||
@@ -75,7 +75,13 @@
|
||||
to_chat(user, "<span class='notice'>The maintenance panel [opened ? "can be" : "is"] <b>screwed</b> in place.</span>")
|
||||
|
||||
if((isobserver(user) && ckeys_allowed_to_scan[user.ckey]) || IsAdminGhost(user))
|
||||
to_chat(user, "You can <a href='?src=[REF(src)];ghostscan=1'>scan</a> this circuit.");
|
||||
to_chat(user, "You can <a href='?src=[REF(src)];ghostscan=1'>scan</a> this circuit.")
|
||||
|
||||
for(var/I in assembly_components)
|
||||
var/obj/item/integrated_circuit/IC = I
|
||||
IC.external_examine(user)
|
||||
if(opened)
|
||||
interact(user)
|
||||
|
||||
/obj/item/electronic_assembly/proc/check_interactivity(mob/user)
|
||||
return user.canUseTopic(src, BE_CLOSE)
|
||||
@@ -311,14 +317,6 @@
|
||||
detail_overlay.color = detail_color
|
||||
add_overlay(detail_overlay)
|
||||
|
||||
/obj/item/electronic_assembly/examine(mob/user)
|
||||
..()
|
||||
for(var/I in assembly_components)
|
||||
var/obj/item/integrated_circuit/IC = I
|
||||
IC.external_examine(user)
|
||||
if(opened)
|
||||
interact(user)
|
||||
|
||||
/obj/item/electronic_assembly/proc/return_total_complexity()
|
||||
. = 0
|
||||
var/obj/item/integrated_circuit/part
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
var/passkey = strtohex(XorEncrypt(json_encode(access), SScircuit.cipherkey))
|
||||
|
||||
if(assembly)
|
||||
assembly.access_card.access = access
|
||||
assembly.access_card.access |= access
|
||||
|
||||
if(card) // An ID card.
|
||||
set_pin_data(IC_OUTPUT, 1, card.registered_name)
|
||||
|
||||
@@ -859,6 +859,7 @@
|
||||
power_draw_per_use = 5
|
||||
|
||||
/obj/item/integrated_circuit/input/microphone/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode)
|
||||
. = ..()
|
||||
var/translated = FALSE
|
||||
if(speaker && message)
|
||||
if(raw_message)
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
//Shooting Code:
|
||||
A.preparePixelProjectile(target, src)
|
||||
A.fire()
|
||||
log_attack("[assembly] [REF(assembly)] has fired [installed_gun].")
|
||||
return A
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/locomotion
|
||||
@@ -350,7 +351,7 @@
|
||||
name = "grabber"
|
||||
desc = "A circuit with its own inventory for items. Used to grab and store things."
|
||||
icon_state = "grabber"
|
||||
extended_desc = "This circuit accepts a reference to an object to be grabbed, and can store up to 10 objects. Modes: 1 to grab, 0 to eject the first object, and -1 to eject all objects. If you throw something from a grabber's inventory with a thrower, the grabber will update its outputs accordingly."
|
||||
extended_desc = "This circuit accepts a reference to an object to be grabbed, and can store up to 10 objects. Modes: 1 to grab, 0 to eject the first object, -1 to eject all objects, and -2 to eject the target. If you throw something from a grabber's inventory with a thrower, the grabber will update its outputs accordingly."
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
size = 3
|
||||
cooldown_per_use = 5
|
||||
@@ -364,33 +365,42 @@
|
||||
var/max_items = 10
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grabber/do_work()
|
||||
var/max_w_class = assembly.w_class
|
||||
var/atom/movable/acting_object = get_object()
|
||||
var/turf/T = get_turf(acting_object)
|
||||
var/obj/item/AM = get_pin_data_as_type(IC_INPUT, 1, /obj/item)
|
||||
if(!QDELETED(AM) && !istype(AM, /obj/item/electronic_assembly) && !istype(AM, /obj/item/transfer_valve) && !istype(AM, /obj/item/twohanded) && !istype(assembly.loc, /obj/item/implant/storage))
|
||||
var/mode = get_pin_data(IC_INPUT, 2)
|
||||
if(mode == 1)
|
||||
if(check_target(AM))
|
||||
var/weightcheck = FALSE
|
||||
if (AM.w_class <= max_w_class)
|
||||
weightcheck = TRUE
|
||||
else
|
||||
weightcheck = FALSE
|
||||
if((contents.len < max_items) && (weightcheck))
|
||||
AM.forceMove(src)
|
||||
if(mode == 0)
|
||||
if(contents.len)
|
||||
var/obj/item/U = contents[1]
|
||||
U.forceMove(T)
|
||||
if(mode == -1)
|
||||
if(contents.len)
|
||||
var/obj/item/U
|
||||
for(U in contents)
|
||||
U.forceMove(T)
|
||||
switch(mode)
|
||||
if(1)
|
||||
grab(AM)
|
||||
if(0)
|
||||
if(contents.len)
|
||||
drop(contents[1])
|
||||
if(-1)
|
||||
drop_all()
|
||||
if(-2)
|
||||
drop(AM)
|
||||
update_outputs()
|
||||
activate_pin(2)
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grabber/proc/grab(obj/item/AM)
|
||||
var/max_w_class = assembly.w_class
|
||||
if(check_target(AM))
|
||||
if(contents.len < max_items && AM.w_class <= max_w_class)
|
||||
var/atom/A = get_object()
|
||||
A.investigate_log("picked up ([AM]) with [src].", INVESTIGATE_CIRCUIT)
|
||||
AM.forceMove(src)
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grabber/proc/drop(obj/item/AM, turf/T = drop_location())
|
||||
var/atom/A = get_object()
|
||||
A.investigate_log("dropped ([AM]) from [src].", INVESTIGATE_CIRCUIT)
|
||||
AM.forceMove(T)
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grabber/proc/drop_all()
|
||||
if(contents.len)
|
||||
var/turf/T = drop_location()
|
||||
var/obj/item/U
|
||||
for(U in src)
|
||||
drop(U, T)
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grabber/proc/update_outputs()
|
||||
if(contents.len)
|
||||
set_pin_data(IC_OUTPUT, 1, WEAKREF(contents[1]))
|
||||
@@ -403,11 +413,7 @@
|
||||
push_data()
|
||||
|
||||
/obj/item/integrated_circuit/manipulation/grabber/attack_self(var/mob/user)
|
||||
if(contents.len)
|
||||
var/turf/T = get_turf(src)
|
||||
var/obj/item/U
|
||||
for(U in contents)
|
||||
U.forceMove(T)
|
||||
drop_all()
|
||||
update_outputs()
|
||||
push_data()
|
||||
|
||||
@@ -437,6 +443,7 @@
|
||||
mode = CLAMP(mode, GRAB_PASSIVE, max_grab)
|
||||
if(AM)
|
||||
if(check_target(AM, exclude_contents = TRUE))
|
||||
acting_object.investigate_log("grabbed ([AM]) using [src].", INVESTIGATE_CIRCUIT)
|
||||
acting_object.start_pulling(AM,mode)
|
||||
if(acting_object.pulling)
|
||||
set_pin_data(IC_OUTPUT, 1, TRUE)
|
||||
|
||||
@@ -126,10 +126,8 @@
|
||||
return
|
||||
vol = CLAMP(vol ,0 , 100)
|
||||
playsound(get_turf(src), selected_sound, vol, freq, -1)
|
||||
if(assembly)
|
||||
assembly.investigate_log("played a sound ([selected_sound]) with [type].", INVESTIGATE_CIRCUIT)
|
||||
else
|
||||
investigate_log("played a sound ([selected_sound]) as [type].", INVESTIGATE_CIRCUIT)
|
||||
var/atom/A = get_object()
|
||||
A.investigate_log("played a sound ([selected_sound]) as [type].", INVESTIGATE_CIRCUIT)
|
||||
|
||||
/obj/item/integrated_circuit/output/sound/on_data_written()
|
||||
power_draw_per_use = get_pin_data(IC_INPUT, 2) * 15
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
|
||||
//Always log attemped injections for admins
|
||||
var/contained = reagents.log_list()
|
||||
add_logs(src, L, "attempted to inject", addition="which had [contained]")
|
||||
log_combat(src, L, "attempted to inject", addition="which had [contained]")
|
||||
L.visible_message("<span class='danger'>[acting_object] is trying to inject [L]!</span>", \
|
||||
"<span class='userdanger'>[acting_object] is trying to inject you!</span>")
|
||||
busy = TRUE
|
||||
@@ -141,7 +141,7 @@
|
||||
var/fraction = min(transfer_amount/reagents.total_volume, 1)
|
||||
reagents.reaction(L, INJECT, fraction)
|
||||
reagents.trans_to(L, transfer_amount)
|
||||
add_logs(src, L, "injected", addition="which had [contained]")
|
||||
log_combat(src, L, "injected", addition="which had [contained]")
|
||||
L.visible_message("<span class='danger'>[acting_object] injects [L] with its needle!</span>", \
|
||||
"<span class='userdanger'>[acting_object] injects you with its needle!</span>")
|
||||
else
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
if(IsAdminGhost(M))
|
||||
//Access can't stop the abuse
|
||||
return TRUE
|
||||
else if(SEND_SIGNAL(M, COMSIG_MOB_ALLOWED, src))
|
||||
return TRUE
|
||||
else if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
//if they are holding or wearing a card that has access, that works
|
||||
@@ -59,7 +61,6 @@
|
||||
/obj/proc/check_access(obj/item/I)
|
||||
return check_access_list(I ? I.GetAccess() : null)
|
||||
|
||||
|
||||
/obj/proc/check_access_list(list/access_list)
|
||||
gen_access()
|
||||
|
||||
|
||||
@@ -4,21 +4,25 @@
|
||||
var/height = 0
|
||||
var/mappath = null
|
||||
var/loaded = 0 // Times loaded this round
|
||||
var/datum/parsed_map/cached_map
|
||||
var/keep_cached_map = FALSE
|
||||
|
||||
/datum/map_template/New(path = null, rename = null)
|
||||
/datum/map_template/New(path = null, rename = null, cache = FALSE)
|
||||
if(path)
|
||||
mappath = path
|
||||
if(mappath)
|
||||
preload_size(mappath)
|
||||
preload_size(mappath, cache)
|
||||
if(rename)
|
||||
name = rename
|
||||
|
||||
/datum/map_template/proc/preload_size(path)
|
||||
var/datum/parsed_map/parsed = load_map(file(path), 1, 1, 1, cropMap=FALSE, measureOnly=TRUE)
|
||||
/datum/map_template/proc/preload_size(path, cache = FALSE)
|
||||
var/datum/parsed_map/parsed = new(file(path))
|
||||
var/bounds = parsed?.bounds
|
||||
if(bounds)
|
||||
width = bounds[MAP_MAXX] // Assumes all templates are rectangular, have a single Z level, and begin at 1,1,1
|
||||
height = bounds[MAP_MAXY]
|
||||
if(cache)
|
||||
cached_map = parsed
|
||||
return bounds
|
||||
|
||||
/datum/parsed_map/proc/initTemplateBounds()
|
||||
@@ -77,8 +81,13 @@
|
||||
if(T.y+height > world.maxy)
|
||||
return
|
||||
|
||||
var/datum/parsed_map/parsed = load_map(file(mappath), T.x, T.y, T.z, cropMap=TRUE, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=TRUE)
|
||||
var/list/bounds = parsed?.bounds
|
||||
// Accept cached maps, but don't save them automatically - we don't want
|
||||
// ruins clogging up memory for the whole round.
|
||||
var/datum/parsed_map/parsed = cached_map || new(file(mappath))
|
||||
cached_map = keep_cached_map ? parsed : null
|
||||
if(!parsed.load(T.x, T.y, T.z, cropMap=TRUE, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=TRUE))
|
||||
return
|
||||
var/list/bounds = parsed.bounds
|
||||
if(!bounds)
|
||||
return
|
||||
|
||||
|
||||
@@ -133,6 +133,21 @@
|
||||
else
|
||||
log_world("### MAP WARNING, [src] failed to find an airlock at [AREACOORD(src)]")
|
||||
|
||||
/obj/effect/mapping_helpers/airlock/unres
|
||||
name = "airlock unresctricted side helper"
|
||||
icon_state = "airlock_unres_helper"
|
||||
|
||||
/obj/effect/mapping_helpers/airlock/unres/Initialize(mapload)
|
||||
. = ..()
|
||||
if(!mapload)
|
||||
log_world("### MAP WARNING, [src] spawned outside of mapload!")
|
||||
return
|
||||
var/obj/machinery/door/airlock/airlock = locate(/obj/machinery/door/airlock) in loc
|
||||
if(airlock)
|
||||
airlock.unres_sides ^= dir
|
||||
else
|
||||
log_world("### MAP WARNING, [src] failed to find an airlock at [AREACOORD(src)]")
|
||||
|
||||
|
||||
//needs to do its thing before spawn_rivers() is called
|
||||
INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// global datum that will preload variables on atoms instanciation
|
||||
GLOBAL_VAR_INIT(use_preloader, FALSE)
|
||||
GLOBAL_DATUM_INIT(_preloader, /datum/map_preloader, new)
|
||||
|
||||
/// Preloader datum
|
||||
/datum/map_preloader
|
||||
parent_type = /datum
|
||||
var/list/attributes
|
||||
var/target_path
|
||||
|
||||
/datum/map_preloader/proc/setup(list/the_attributes, path)
|
||||
if(the_attributes.len)
|
||||
GLOB.use_preloader = TRUE
|
||||
attributes = the_attributes
|
||||
target_path = path
|
||||
|
||||
/datum/map_preloader/proc/load(atom/what)
|
||||
GLOB.use_preloader = FALSE
|
||||
for(var/attribute in attributes)
|
||||
var/value = attributes[attribute]
|
||||
if(islist(value))
|
||||
value = deepCopyList(value)
|
||||
what.vars[attribute] = value
|
||||
|
||||
/area/template_noop
|
||||
name = "Area Passthrough"
|
||||
|
||||
/turf/template_noop
|
||||
name = "Turf Passthrough"
|
||||
icon_state = "noop"
|
||||
bullet_bounce_sound = null
|
||||
@@ -2,9 +2,6 @@
|
||||
//SS13 Optimized Map loader
|
||||
//////////////////////////////////////////////////////////////
|
||||
#define SPACE_KEY "space"
|
||||
//global datum that will preload variables on atoms instanciation
|
||||
GLOBAL_VAR_INIT(use_preloader, FALSE)
|
||||
GLOBAL_DATUM_INIT(_preloader, /datum/map_preloader, new)
|
||||
|
||||
/datum/grid_set
|
||||
var/xcrd
|
||||
@@ -19,7 +16,6 @@ GLOBAL_DATUM_INIT(_preloader, /datum/map_preloader, new)
|
||||
var/list/gridSets = list()
|
||||
|
||||
var/list/modelCache
|
||||
var/list/bad_paths
|
||||
|
||||
/// Unoffset bounds. Null on parse failure.
|
||||
var/list/parsed_bounds
|
||||
@@ -38,13 +34,13 @@ GLOBAL_DATUM_INIT(_preloader, /datum/map_preloader, new)
|
||||
|
||||
/// Shortcut function to parse a map and apply it to the world.
|
||||
///
|
||||
/// - dmm_file: A .dmm file to load (Required).
|
||||
/// - x_offset, y_offset, z_offset: Positions representign where to load the map (Optional).
|
||||
/// - cropMap: When true, the map will be cropped to fit the existing world dimensions (Optional).
|
||||
/// - measureOnly: When true, no changes will be made to the world (Optional).
|
||||
/// - no_changeturf: When true, turf/AfterChange won't be called on loaded turfs
|
||||
/// - x_lower, x_upper, y_lower, y_upper: Coordinates (relative to the map) to crop to (Optional).
|
||||
/// - placeOnTop: Whether to use turf/PlaceOnTop rather than turf/ChangeTurf (Optional).
|
||||
/// - `dmm_file`: A .dmm file to load (Required).
|
||||
/// - `x_offset`, `y_offset`, `z_offset`: Positions representign where to load the map (Optional).
|
||||
/// - `cropMap`: When true, the map will be cropped to fit the existing world dimensions (Optional).
|
||||
/// - `measureOnly`: When true, no changes will be made to the world (Optional).
|
||||
/// - `no_changeturf`: When true, [turf/AfterChange] won't be called on loaded turfs
|
||||
/// - `x_lower`, `x_upper`, `y_lower`, `y_upper`: Coordinates (relative to the map) to crop to (Optional).
|
||||
/// - `placeOnTop`: Whether to use [turf/PlaceOnTop] rather than [turf/ChangeTurf] (Optional).
|
||||
/proc/load_map(dmm_file as file, x_offset as num, y_offset as num, z_offset as num, cropMap as num, measureOnly as num, no_changeturf as num, x_lower = -INFINITY as num, x_upper = INFINITY as num, y_lower = -INFINITY as num, y_upper = INFINITY as num, placeOnTop = FALSE as num)
|
||||
var/datum/parsed_map/parsed = new(dmm_file, x_lower, x_upper, y_lower, y_upper, measureOnly)
|
||||
if(parsed.bounds && !measureOnly)
|
||||
@@ -133,7 +129,7 @@ GLOBAL_DATUM_INIT(_preloader, /datum/map_preloader, new)
|
||||
bounds = null
|
||||
parsed_bounds = bounds
|
||||
|
||||
/// Load the parsed map into the world. See /proc/load_map for arguments.
|
||||
/// Load the parsed map into the world. See [/proc/load_map] for arguments.
|
||||
/datum/parsed_map/proc/load(x_offset, y_offset, z_offset, cropMap, no_changeturf, x_lower, x_upper, y_lower, y_upper, placeOnTop)
|
||||
//How I wish for RAII
|
||||
Master.StartLoadingMap()
|
||||
@@ -218,8 +214,8 @@ GLOBAL_DATUM_INIT(_preloader, /datum/map_preloader, new)
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/parsed_map/proc/build_cache(no_changeturf)
|
||||
if(modelCache)
|
||||
/datum/parsed_map/proc/build_cache(no_changeturf, bad_paths=null)
|
||||
if(modelCache && !bad_paths)
|
||||
return modelCache
|
||||
. = modelCache = list()
|
||||
var/list/grid_models = src.grid_models
|
||||
@@ -246,8 +242,9 @@ GLOBAL_DATUM_INIT(_preloader, /datum/map_preloader, new)
|
||||
var/atom_def = text2path(path_text) //path definition, e.g /obj/foo/bar
|
||||
old_position = dpos + 1
|
||||
|
||||
if(!atom_def) // Skip the item if the path does not exist. Fix your crap, mappers!
|
||||
LAZYADD(bad_paths, path_text)
|
||||
if(!ispath(atom_def, /atom)) // Skip the item if the path does not exist. Fix your crap, mappers!
|
||||
if(bad_paths)
|
||||
LAZYOR(bad_paths[path_text], model_key)
|
||||
continue
|
||||
members.Add(atom_def)
|
||||
|
||||
@@ -467,34 +464,3 @@ GLOBAL_DATUM_INIT(_preloader, /datum/map_preloader, new)
|
||||
/datum/parsed_map/Destroy()
|
||||
..()
|
||||
return QDEL_HINT_HARDDEL_NOW
|
||||
|
||||
//////////////////
|
||||
//Preloader datum
|
||||
//////////////////
|
||||
|
||||
/datum/map_preloader
|
||||
parent_type = /datum
|
||||
var/list/attributes
|
||||
var/target_path
|
||||
|
||||
/datum/map_preloader/proc/setup(list/the_attributes, path)
|
||||
if(the_attributes.len)
|
||||
GLOB.use_preloader = TRUE
|
||||
attributes = the_attributes
|
||||
target_path = path
|
||||
|
||||
/datum/map_preloader/proc/load(atom/what)
|
||||
GLOB.use_preloader = FALSE
|
||||
for(var/attribute in attributes)
|
||||
var/value = attributes[attribute]
|
||||
if(islist(value))
|
||||
value = deepCopyList(value)
|
||||
what.vars[attribute] = value
|
||||
|
||||
/area/template_noop
|
||||
name = "Area Passthrough"
|
||||
|
||||
/turf/template_noop
|
||||
name = "Turf Passthrough"
|
||||
icon_state = "noop"
|
||||
bullet_bounce_sound = null
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/// An error report generated by [parsed_map/check_for_errors].
|
||||
/datum/map_report
|
||||
var/original_path
|
||||
var/list/bad_paths = list()
|
||||
var/list/bad_keys = list()
|
||||
/// Whether this map can be loaded safely despite the errors.
|
||||
var/loadable = TRUE
|
||||
var/crashed = TRUE
|
||||
|
||||
var/static/tag_number = 0
|
||||
|
||||
/datum/map_report/New(datum/parsed_map/map)
|
||||
original_path = map.original_path || "Untitled"
|
||||
|
||||
/// Show a rendered version of this report to a client.
|
||||
/datum/map_report/proc/show_to(client/C)
|
||||
var/list/html = list()
|
||||
html += "<p>Report for map file <tt>[original_path]</tt></p>"
|
||||
if(crashed)
|
||||
html += "<p><b>Validation crashed</b>: check the runtime logs.</p>"
|
||||
if(!loadable)
|
||||
html += "<p><b>Not loadable</b>: some tiles are missing their turfs or areas.</p>"
|
||||
|
||||
if(bad_paths.len)
|
||||
html += "<p>Bad paths: <ol>"
|
||||
for(var/path in bad_paths)
|
||||
var/list/keys = bad_paths[path]
|
||||
html += "<li><tt>[path]</tt>: used in ([keys.len]): <tt>[keys.Join("</tt>, <tt>")]</tt>"
|
||||
html += "</ol></p>"
|
||||
|
||||
if(bad_keys.len)
|
||||
html += "<p>Bad keys: <ul>"
|
||||
for(var/key in bad_keys)
|
||||
var/list/messages = bad_keys[key]
|
||||
html += "<li><tt>[key]</tt>"
|
||||
if(messages.len == 1)
|
||||
html += ": [bad_keys[key][1]]"
|
||||
else
|
||||
html += "<ul><li>[messages.Join("</li><li>")]</li></ul>"
|
||||
html += "</li>"
|
||||
html += "</ul></p>"
|
||||
C << browse(html.Join(), "window=[tag];size=600x400")
|
||||
|
||||
/datum/map_report/Topic(href, href_list)
|
||||
. = ..()
|
||||
if(. || !check_rights(R_ADMIN, FALSE) || !usr.client.holder.CheckAdminHref(href, href_list))
|
||||
return
|
||||
|
||||
if (href_list["show"])
|
||||
show_to(usr)
|
||||
|
||||
|
||||
/// Check a parsed but not yet loaded map for errors.
|
||||
///
|
||||
/// Returns a [/datum/map_report] if there are errors or `FALSE` otherwise.
|
||||
/datum/parsed_map/proc/check_for_errors()
|
||||
var/datum/map_report/report = new(src)
|
||||
. = report
|
||||
|
||||
// build_cache will check bad paths for us
|
||||
var/list/modelCache = build_cache(TRUE, report.bad_paths)
|
||||
|
||||
for(var/path in report.bad_paths)
|
||||
if(copytext(path, 1, 7) == "/turf/" || copytext(path, 1, 7) == "/area/")
|
||||
report.loadable = FALSE
|
||||
|
||||
// check for tiles with the wrong number of turfs or areas
|
||||
for(var/key in modelCache)
|
||||
if(key == SPACE_KEY)
|
||||
continue
|
||||
var/model = modelCache[key]
|
||||
var/list/members = model[1]
|
||||
|
||||
var/turfs = 0
|
||||
var/areas = 0
|
||||
for(var/i in 1 to members.len)
|
||||
var/atom/path = members[i]
|
||||
|
||||
turfs += ispath(path, /turf)
|
||||
areas += ispath(path, /area)
|
||||
|
||||
if(turfs == 0)
|
||||
report.loadable = FALSE
|
||||
LAZYADD(report.bad_keys[key], "no turf")
|
||||
else if(turfs > 1)
|
||||
LAZYADD(report.bad_keys[key], "[turfs] stacked turfs")
|
||||
|
||||
if(areas != 1)
|
||||
report.loadable = FALSE
|
||||
LAZYADD(report.bad_keys[key], "[areas] areas instead of 1")
|
||||
|
||||
// return the report
|
||||
if(report.bad_paths.len || report.bad_keys.len || !report.loadable)
|
||||
// keep the report around so it can be referenced later
|
||||
report.tag = "mapreport_[++report.tag_number]"
|
||||
report.crashed = FALSE
|
||||
else
|
||||
return FALSE
|
||||
@@ -100,7 +100,7 @@
|
||||
playsound(T,'sound/weapons/resonator_blast.ogg',50,1)
|
||||
for(var/mob/living/L in T)
|
||||
if(creator)
|
||||
add_logs(creator, L, "used a resonator field on", "resonator")
|
||||
log_combat(creator, L, "used a resonator field on", "resonator")
|
||||
to_chat(L, "<span class='userdanger'>[src] ruptured with you in it!</span>")
|
||||
L.apply_damage(resonance_damage, BRUTE)
|
||||
qdel(src)
|
||||
|
||||
@@ -975,7 +975,7 @@
|
||||
to_chat(user, "<span class='notice'>You shatter the bottle!</span>")
|
||||
playsound(user.loc, 'sound/effects/glassbr1.ogg', 100, 1)
|
||||
message_admins("<span class='adminnotice'>[ADMIN_LOOKUPFLW(user)] has activated a bottle of mayhem!</span>")
|
||||
add_logs(user, null, "activated a bottle of mayhem", src)
|
||||
log_combat(user, null, "activated a bottle of mayhem", src)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/blood_contract
|
||||
@@ -1019,7 +1019,7 @@
|
||||
var/datum/objective/survive/survive = new
|
||||
survive.owner = L.mind
|
||||
L.mind.objectives += survive
|
||||
add_logs(user, L, "took out a blood contract on", src)
|
||||
log_combat(user, L, "took out a blood contract on", src)
|
||||
to_chat(L, "<span class='userdanger'>You've been marked for death! Don't let the demons get you! KILL THEM ALL!</span>")
|
||||
L.add_atom_colour("#FF0000", ADMIN_COLOUR_PRIORITY)
|
||||
var/obj/effect/mine/pickup/bloodbath/B = new(L)
|
||||
@@ -1105,7 +1105,7 @@
|
||||
timer = world.time + CLICK_CD_MELEE //by default, melee attacks only cause melee blasts, and have an accordingly short cooldown
|
||||
if(proximity_flag)
|
||||
INVOKE_ASYNC(src, .proc/aoe_burst, T, user)
|
||||
add_logs(user, target, "fired 3x3 blast at", src)
|
||||
log_combat(user, target, "fired 3x3 blast at", src)
|
||||
else
|
||||
if(ismineralturf(target) && get_dist(user, target) < 6) //target is minerals, we can hit it(even if we can't see it)
|
||||
INVOKE_ASYNC(src, .proc/cardinal_blasts, T, user)
|
||||
@@ -1117,10 +1117,10 @@
|
||||
var/obj/effect/temp_visual/hierophant/chaser/C = new(get_turf(user), user, target, chaser_speed, friendly_fire_check)
|
||||
C.damage = 30
|
||||
C.monster_damage_boost = FALSE
|
||||
add_logs(user, target, "fired a chaser at", src)
|
||||
log_combat(user, target, "fired a chaser at", src)
|
||||
else
|
||||
INVOKE_ASYNC(src, .proc/cardinal_blasts, T, user) //otherwise, just do cardinal blast
|
||||
add_logs(user, target, "fired cardinal blast at", src)
|
||||
log_combat(user, target, "fired cardinal blast at", src)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>That target is out of range!</span>" )
|
||||
timer = world.time
|
||||
@@ -1232,7 +1232,7 @@
|
||||
INVOKE_ASYNC(src, .proc/prepare_icon_update)
|
||||
beacon.icon_state = "hierophant_tele_off"
|
||||
return
|
||||
add_logs(user, beacon, "teleported self from [AREACOORD(source)] to")
|
||||
user.log_message("teleported self from [AREACOORD(source)] to [beacon]")
|
||||
new /obj/effect/temp_visual/hierophant/telegraph/teleport(T, user)
|
||||
new /obj/effect/temp_visual/hierophant/telegraph/teleport(source, user)
|
||||
for(var/t in RANGE_TURFS(1, T))
|
||||
@@ -1279,7 +1279,7 @@
|
||||
return
|
||||
M.visible_message("<span class='hierophant_warning'>[M] fades in!</span>")
|
||||
if(user != M)
|
||||
add_logs(user, M, "teleported", null, "from [AREACOORD(source)]")
|
||||
log_combat(user, M, "teleported", null, "from [AREACOORD(source)]")
|
||||
|
||||
/obj/item/hierophant_club/proc/cardinal_blasts(turf/T, mob/living/user) //fire cardinal cross blasts with a delay
|
||||
if(!T)
|
||||
|
||||
@@ -5,7 +5,7 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
|
||||
name = "ore silo"
|
||||
desc = "An all-in-one bluespace storage and transmission system for the station's mineral distribution needs."
|
||||
icon = 'icons/obj/mining.dmi'
|
||||
icon_state = "bin"
|
||||
icon_state = "silo"
|
||||
density = TRUE
|
||||
circuit = /obj/item/circuitboard/machine/ore_silo
|
||||
|
||||
@@ -178,10 +178,7 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
|
||||
logs.Insert(1, entry)
|
||||
|
||||
updateUsrDialog()
|
||||
animate(src, icon_state = "bin_partial", time = 2)
|
||||
animate(icon_state = "bin_full", time = 1)
|
||||
animate(icon_state = "bin_partial", time = 2)
|
||||
animate(icon_state = "bin")
|
||||
flick("silo_active", src)
|
||||
|
||||
/datum/ore_silo_log
|
||||
var/name // for VV
|
||||
|
||||
@@ -335,7 +335,6 @@ GLOBAL_LIST_INIT(sand_recipes, list(\
|
||||
|
||||
/obj/item/coin/proc/manual_suicide(mob/living/user)
|
||||
var/index = sideslist.Find(coinflip)
|
||||
message_admins("coinflip landed on [coinflip] which is [index] in sideslist")
|
||||
if (index==2)//tails
|
||||
user.visible_message("<span class='suicide'>\the [src] lands on [coinflip]! [user] promptly falls over, dead!</span>")
|
||||
user.adjustOxyLoss(200)
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
var/isadmin = 0
|
||||
if(src.client && src.client.holder)
|
||||
isadmin = 1
|
||||
var/datum/DBQuery/query_get_new_polls = SSdbcore.NewQuery("SELECT id FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM [format_table_name("poll_vote")] WHERE ckey = \"[ckey]\") AND id NOT IN (SELECT pollid FROM [format_table_name("poll_textreply")] WHERE ckey = \"[ckey]\")")
|
||||
var/datum/DBQuery/query_get_new_polls = SSdbcore.NewQuery("SELECT id FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM [format_table_name("poll_vote")] WHERE ckey = \"[sanitizeSQL(ckey)]\") AND id NOT IN (SELECT pollid FROM [format_table_name("poll_textreply")] WHERE ckey = \"[sanitizeSQL(ckey)]\")")
|
||||
var/rs = REF(src)
|
||||
if(query_get_new_polls.Execute())
|
||||
var/newpoll = 0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@
|
||||
client.dsay(message)
|
||||
return
|
||||
|
||||
log_talk(src,"Ghost/[src.key] : [message]", LOGSAY)
|
||||
src.log_talk(message, LOG_SAY, tag="ghost")
|
||||
|
||||
if(check_emote(message))
|
||||
return
|
||||
@@ -23,6 +23,7 @@
|
||||
. = say_dead(message)
|
||||
|
||||
/mob/dead/observer/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||
. = ..()
|
||||
var/atom/movable/to_follow = speaker
|
||||
if(radio_freq)
|
||||
var/atom/movable/virtualspeaker/V = speaker
|
||||
|
||||
@@ -10,4 +10,5 @@
|
||||
return
|
||||
|
||||
/mob/proc/death(gibbed)
|
||||
SEND_SIGNAL(src, COMSIG_MOB_DEATH, gibbed)
|
||||
return
|
||||
@@ -38,7 +38,7 @@ In all, this is a lot like the monkey code. /N
|
||||
visible_message("<span class='danger'>[M.name] bites [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
adjustBruteLoss(1)
|
||||
add_logs(M, src, "attacked")
|
||||
log_combat(M, src, "attacked")
|
||||
updatehealth()
|
||||
else
|
||||
to_chat(M, "<span class='warning'>[name] is too injured for that.</span>")
|
||||
@@ -97,7 +97,7 @@ In all, this is a lot like the monkey code. /N
|
||||
if(M.is_adult)
|
||||
damage = rand(10, 40)
|
||||
adjustBruteLoss(damage)
|
||||
add_logs(M, src, "attacked")
|
||||
log_combat(M, src, "attacked")
|
||||
updatehealth()
|
||||
|
||||
/mob/living/carbon/alien/ex_act(severity, target, origin)
|
||||
|
||||
@@ -97,7 +97,7 @@ Doesn't work on other aliens/AI.*/
|
||||
return 0
|
||||
var/msg = sanitize(input("Message:", "Alien Whisper") as text|null)
|
||||
if(msg)
|
||||
log_talk(user,"AlienWhisper: [key_name(user)]->[key_name(M)] : [msg]",LOGSAY)
|
||||
log_directed_talk(user, M, msg, LOG_SAY, tag="alien whisper")
|
||||
to_chat(M, "<span class='noticealien'>You hear a strange, alien voice in your head...</span>[msg]")
|
||||
to_chat(user, "<span class='noticealien'>You said: \"[msg]\" to [M]</span>")
|
||||
for(var/ded in GLOB.dead_mob_list)
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"<span class='userdanger'>[M] has knocked [src] down!</span>")
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
apply_damage(damage, BRUTE, affecting)
|
||||
add_logs(M, src, "attacked")
|
||||
log_combat(M, src, "attacked")
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='userdanger'>[M] has attempted to punch [src]!</span>", \
|
||||
@@ -46,7 +46,7 @@
|
||||
if (prob(5))
|
||||
Unconscious(40)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
add_logs(M, src, "pushed")
|
||||
log_combat(M, src, "pushed")
|
||||
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has pushed down [src]!</span>")
|
||||
else
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
var/damage = rand(1, 9)
|
||||
if (prob(90))
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
add_logs(M, src, "attacked")
|
||||
log_combat(M, src, "attacked")
|
||||
visible_message("<span class='danger'>[M] has kicked [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has kicked [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
if ((stat != DEAD) && (damage > 4.9))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/living/proc/alien_talk(message, shown_name = real_name)
|
||||
log_talk(src,"[key_name(src)] : [message]",LOGSAY)
|
||||
src.log_talk(message, LOG_SAY)
|
||||
message = trim(message)
|
||||
if(!message)
|
||||
return
|
||||
|
||||
@@ -162,7 +162,7 @@
|
||||
var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors
|
||||
var/turf/end_T = get_turf(target)
|
||||
if(start_T && end_T)
|
||||
add_logs(src, throwable_mob, "thrown", addition="grab from tile in [AREACOORD(start_T)] towards tile at [AREACOORD(end_T)]")
|
||||
log_combat(src, throwable_mob, "thrown", addition="grab from tile in [AREACOORD(start_T)] towards tile at [AREACOORD(end_T)]")
|
||||
|
||||
else if(!(I.item_flags & (NODROP | ABSTRACT)))
|
||||
thrown_thing = I
|
||||
@@ -174,7 +174,7 @@
|
||||
|
||||
if(thrown_thing)
|
||||
visible_message("<span class='danger'>[src] has thrown [thrown_thing].</span>")
|
||||
add_logs(src, thrown_thing, "thrown")
|
||||
src.log_message("has thrown [thrown_thing]", LOG_ATTACK)
|
||||
newtonian_move(get_dir(target, src))
|
||||
thrown_thing.throw_at(target, thrown_thing.throw_range, thrown_thing.throw_speed, src)
|
||||
|
||||
@@ -508,9 +508,9 @@
|
||||
var/obj/item/bodypart/BP = X
|
||||
total_brute += (BP.brute_dam * BP.body_damage_coeff)
|
||||
total_burn += (BP.burn_dam * BP.body_damage_coeff)
|
||||
total_stamina += (BP.stamina_dam * BP.body_damage_coeff)
|
||||
health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
|
||||
staminaloss = total_stamina
|
||||
total_stamina += (BP.stamina_dam * BP.stam_damage_coeff)
|
||||
health = round(maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute, DAMAGE_PRECISION)
|
||||
staminaloss = round(total_stamina, DAMAGE_PRECISION)
|
||||
update_stat()
|
||||
if(((maxHealth - total_burn) < HEALTH_THRESHOLD_DEAD) && stat == DEAD )
|
||||
become_husk("burn")
|
||||
@@ -520,6 +520,16 @@
|
||||
else
|
||||
remove_movespeed_modifier(MOVESPEED_ID_CARBON_SOFTCRIT, TRUE)
|
||||
|
||||
/mob/living/carbon/update_stamina()
|
||||
var/stam = getStaminaLoss()
|
||||
if(stam > DAMAGE_PRECISION)
|
||||
var/total_health = (health - stam)
|
||||
if(total_health <= crit_threshold && !stat)
|
||||
if(!IsKnockdown())
|
||||
to_chat(src, "<span class='notice'>You're too exhausted to keep going...</span>")
|
||||
Knockdown(70)
|
||||
update_health_hud()
|
||||
|
||||
/mob/living/carbon/update_sight()
|
||||
if(!client)
|
||||
return
|
||||
@@ -826,7 +836,7 @@
|
||||
"<span class='userdanger'>[src] devours you!</span>")
|
||||
C.forceMove(src)
|
||||
stomach_contents.Add(C)
|
||||
add_logs(src, C, "devoured")
|
||||
log_combat(src, C, "devoured")
|
||||
|
||||
/mob/living/carbon/proc/create_bodyparts()
|
||||
var/l_arm_index_next = -1
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
gender = MALE
|
||||
pressure_resistance = 15
|
||||
possible_a_intents = list(INTENT_HELP, INTENT_HARM)
|
||||
hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,GLAND_HUD)
|
||||
hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,GLAND_HUD,NANITE_HUD,DIAG_NANITE_FULL_HUD)
|
||||
has_limbs = 1
|
||||
held_items = list(null, null)
|
||||
var/list/stomach_contents = list()
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
if(movement_type & FLYING)
|
||||
return 0
|
||||
if(!(lube&SLIDE_ICE))
|
||||
add_logs(src, (O ? O : get_turf(src)), "slipped on the", null, ((lube & SLIDE) ? "(LUBE)" : null))
|
||||
log_combat(src, (O ? O : get_turf(src)), "slipped on the", null, ((lube & SLIDE) ? "(LUBE)" : null))
|
||||
return loc.handle_slip(src, knockdown_amount, O, lube)
|
||||
|
||||
/mob/living/carbon/Process_Spacemove(movement_dir = 0)
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
. = 0
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
. += BP.stamina_dam
|
||||
. += round(BP.stamina_dam * BP.stam_damage_coeff, DAMAGE_PRECISION)
|
||||
|
||||
/mob/living/carbon/adjustStaminaLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
@@ -113,10 +113,12 @@
|
||||
////////////////////////////////////////////
|
||||
|
||||
//Returns a list of damaged bodyparts
|
||||
/mob/living/carbon/proc/get_damaged_bodyparts(brute = FALSE, burn = FALSE, stamina = FALSE)
|
||||
/mob/living/carbon/proc/get_damaged_bodyparts(brute = FALSE, burn = FALSE, stamina = FALSE, status)
|
||||
var/list/obj/item/bodypart/parts = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(status && BP.status != status)
|
||||
continue
|
||||
if((brute && BP.brute_dam) || (burn && BP.burn_dam) || (stamina && BP.stamina_dam))
|
||||
parts += BP
|
||||
return parts
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user