Merge branch 'master' into revenant_TK
This commit is contained in:
@@ -69,7 +69,7 @@ GLOBAL_LIST_EMPTY(actionspeed_modification_cache)
|
||||
return TRUE
|
||||
remove_actionspeed_modifier(existing, FALSE)
|
||||
if(length(actionspeed_modification))
|
||||
BINARY_INSERT(type_or_datum.id, actionspeed_modification, datum/actionspeed_modifier, type_or_datum, priority, COMPARE_VALUE)
|
||||
BINARY_INSERT(type_or_datum.id, actionspeed_modification, /datum/actionspeed_modifier, type_or_datum, priority, COMPARE_VALUE)
|
||||
LAZYSET(actionspeed_modification, type_or_datum.id, type_or_datum)
|
||||
if(update)
|
||||
update_actionspeed()
|
||||
|
||||
@@ -226,6 +226,14 @@
|
||||
key_cache[key] = 0
|
||||
return .
|
||||
|
||||
/proc/restore_stickybans()
|
||||
for (var/banned_ckey in GLOB.stickybanadmintexts)
|
||||
world.SetConfig("ban", banned_ckey, GLOB.stickybanadmintexts[banned_ckey])
|
||||
GLOB.stickybanadminexemptions = list()
|
||||
GLOB.stickybanadmintexts = list()
|
||||
if (GLOB.stickbanadminexemptiontimerid)
|
||||
deltimer(GLOB.stickbanadminexemptiontimerid)
|
||||
GLOB.stickbanadminexemptiontimerid = null
|
||||
|
||||
#undef STICKYBAN_MAX_MATCHES
|
||||
#undef STICKYBAN_MAX_EXISTING_USER_MATCHES
|
||||
|
||||
@@ -52,11 +52,9 @@
|
||||
edit_emitter(user)
|
||||
|
||||
/obj/effect/sound_emitter/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(check_rights_for(user.client, R_SOUNDS))
|
||||
activate(user)
|
||||
to_chat(user, "<span class='notice'>Sound emitter activated.</span>")
|
||||
return TRUE
|
||||
to_chat(user, "<span class='notice'>Sound emitter activated.</span>", confidential = TRUE)
|
||||
|
||||
/obj/effect/sound_emitter/proc/edit_emitter(mob/user)
|
||||
var/dat = ""
|
||||
@@ -84,20 +82,20 @@
|
||||
if(!new_label)
|
||||
return
|
||||
maptext = new_label
|
||||
to_chat(user, "<span class='notice'>Label set to [maptext].</span>")
|
||||
to_chat(user, "<span class='notice'>Label set to [maptext].</span>", confidential = TRUE)
|
||||
if(href_list["edit_sound_file"])
|
||||
var/new_file = input(user, "Choose a sound file.", "Sound Emitter") as null|sound
|
||||
if(!new_file)
|
||||
return
|
||||
sound_file = new_file
|
||||
to_chat(user, "<span class='notice'>New sound file set to [sound_file].</span>")
|
||||
to_chat(user, "<span class='notice'>New sound file set to [sound_file].</span>", confidential = TRUE)
|
||||
if(href_list["edit_volume"])
|
||||
var/new_volume = input(user, "Choose a volume.", "Sound Emitter", sound_volume) as null|num
|
||||
if(isnull(new_volume))
|
||||
return
|
||||
new_volume = clamp(new_volume, 0, 100)
|
||||
sound_volume = new_volume
|
||||
to_chat(user, "<span class='notice'>Volume set to [sound_volume]%.</span>")
|
||||
to_chat(user, "<span class='notice'>Volume set to [sound_volume]%.</span>", confidential = TRUE)
|
||||
if(href_list["edit_mode"])
|
||||
var/new_mode
|
||||
var/mode_list = list("Local (normal sound)" = SOUND_EMITTER_LOCAL, "Direct (not affected by environment/location)" = SOUND_EMITTER_DIRECT)
|
||||
@@ -105,7 +103,7 @@
|
||||
if(!new_mode)
|
||||
return
|
||||
motus_operandi = mode_list[new_mode]
|
||||
to_chat(user, "<span class='notice'>Mode set to [motus_operandi].</span>")
|
||||
to_chat(user, "<span class='notice'>Mode set to [motus_operandi].</span>", confidential = TRUE)
|
||||
if(href_list["edit_range"])
|
||||
var/new_range
|
||||
var/range_list = list("Radius (all mobs within a radius)" = SOUND_EMITTER_RADIUS, "Z-Level (all mobs on the same z)" = SOUND_EMITTER_ZLEVEL, "Global (all players)" = SOUND_EMITTER_GLOBAL)
|
||||
@@ -113,14 +111,14 @@
|
||||
if(!new_range)
|
||||
return
|
||||
emitter_range = range_list[new_range]
|
||||
to_chat(user, "<span class='notice'>Range set to [emitter_range].</span>")
|
||||
to_chat(user, "<span class='notice'>Range set to [emitter_range].</span>", confidential = TRUE)
|
||||
if(href_list["edit_radius"])
|
||||
var/new_radius = input(user, "Choose a radius.", "Sound Emitter", sound_volume) as null|num
|
||||
if(isnull(new_radius))
|
||||
return
|
||||
new_radius = clamp(new_radius, 0, 127)
|
||||
play_radius = new_radius
|
||||
to_chat(user, "<span class='notice'>Audible radius set to [play_radius].</span>")
|
||||
to_chat(user, "<span class='notice'>Audible radius set to [play_radius].</span>", confidential = TRUE)
|
||||
if(href_list["play"])
|
||||
activate(user)
|
||||
edit_emitter(user) //Refresh the UI to see our changes
|
||||
|
||||
+318
-55
@@ -7,7 +7,7 @@
|
||||
if ("add")
|
||||
var/list/ban = list()
|
||||
var/ckey
|
||||
ban["admin"] = usr.key
|
||||
ban["admin"] = usr.ckey
|
||||
ban["type"] = list("sticky")
|
||||
ban["reason"] = "(InGameBan)([usr.key])" //this will be displayed in dd only
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
ban["ckey"] = ckey
|
||||
|
||||
if (get_stickyban_from_ckey(ckey))
|
||||
to_chat(usr, "<span class='adminnotice'>Error: Can not add a stickyban: User already has a current sticky ban</span>")
|
||||
to_chat(usr, "<span class='adminnotice'>Error: Can not add a stickyban: User already has a current sticky ban</span>", confidential = TRUE)
|
||||
return
|
||||
|
||||
if (data["reason"])
|
||||
ban["message"] = data["reason"]
|
||||
@@ -31,7 +32,26 @@
|
||||
return
|
||||
ban["message"] = "[reason]"
|
||||
|
||||
if(SSdbcore.Connect()) // todo: second wave
|
||||
// var/datum/db_query/query_create_stickyban = SSdbcore.NewQuery({"
|
||||
// INSERT INTO [format_table_name("stickyban")] (ckey, reason, banning_admin)
|
||||
// VALUES (:ckey, :message, :banning_admin)
|
||||
// "}, list("ckey" = ckey, "message" = ban["message"], "banning_admin" = usr.ckey))
|
||||
var/datum/DBQuery/query_create_stickyban = SSdbcore.NewQuery({"
|
||||
INSERT INTO [format_table_name("stickyban")] (ckey, reason, banning_admin)
|
||||
VALUES ([ckey], [ban["message"]], [usr.ckey])
|
||||
"})
|
||||
if (query_create_stickyban.warn_execute())
|
||||
ban["fromdb"] = TRUE
|
||||
qdel(query_create_stickyban)
|
||||
|
||||
world.SetConfig("ban",ckey,list2stickyban(ban))
|
||||
ban = stickyban2list(list2stickyban(ban))
|
||||
ban["matches_this_round"] = list()
|
||||
ban["existing_user_matches_this_round"] = list()
|
||||
ban["admin_matches_this_round"] = list()
|
||||
ban["pending_matches_this_round"] = list()
|
||||
SSstickyban.cache[ckey] = ban
|
||||
|
||||
log_admin_private("[key_name(usr)] has stickybanned [ckey].\nReason: [ban["message"]]")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has stickybanned [ckey].\nReason: [ban["message"]]</span>")
|
||||
@@ -43,14 +63,29 @@
|
||||
|
||||
var/ban = get_stickyban_from_ckey(ckey)
|
||||
if (!ban)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>")
|
||||
to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>", confidential = TRUE)
|
||||
return
|
||||
if (alert("Are you sure you want to remove the sticky ban on [ckey]?","Are you sure","Yes","No") == "No")
|
||||
return
|
||||
if (!get_stickyban_from_ckey(ckey))
|
||||
to_chat(usr, "<span class='adminnotice'>Error: The ban disappeared.</span>")
|
||||
to_chat(usr, "<span class='adminnotice'>Error: The ban disappeared.</span>", confidential = TRUE)
|
||||
return
|
||||
world.SetConfig("ban",ckey, null)
|
||||
SSstickyban.cache -= ckey
|
||||
|
||||
if (SSdbcore.Connect())
|
||||
// SSdbcore.QuerySelect(list(
|
||||
// SSdbcore.NewQuery("DELETE FROM [format_table_name("stickyban")] WHERE ckey = :ckey", list("ckey" = ckey)),
|
||||
// SSdbcore.NewQuery("DELETE FROM [format_table_name("stickyban_matched_ckey")] WHERE stickyban = :ckey", list("ckey" = ckey)),
|
||||
// SSdbcore.NewQuery("DELETE FROM [format_table_name("stickyban_matched_cid")] WHERE stickyban = :ckey", list("ckey" = ckey)),
|
||||
// SSdbcore.NewQuery("DELETE FROM [format_table_name("stickyban_matched_ip")] WHERE stickyban = :ckey", list("ckey" = ckey))
|
||||
// ), warn = TRUE, qdel = TRUE)
|
||||
SSdbcore.QuerySelect(list(
|
||||
SSdbcore.NewQuery("DELETE FROM [format_table_name("stickyban")] WHERE ckey = [ckey]"),
|
||||
SSdbcore.NewQuery("DELETE FROM [format_table_name("stickyban_matched_ckey")] WHERE stickyban = [ckey]"),
|
||||
SSdbcore.NewQuery("DELETE FROM [format_table_name("stickyban_matched_cid")] WHERE stickyban = [ckey]"),
|
||||
SSdbcore.NewQuery("DELETE FROM [format_table_name("stickyban_matched_ip")] WHERE stickyban = [ckey]")
|
||||
), warn = TRUE, qdel = TRUE)
|
||||
|
||||
log_admin_private("[key_name(usr)] removed [ckey]'s stickyban")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] removed [ckey]'s stickyban</span>")
|
||||
@@ -64,42 +99,45 @@
|
||||
var/alt = ckey(data["alt"])
|
||||
var/ban = get_stickyban_from_ckey(ckey)
|
||||
if (!ban)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>")
|
||||
to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>", confidential = TRUE)
|
||||
return
|
||||
|
||||
var/found = 0
|
||||
//we have to do it this way because byond keeps the case in its sticky ban matches WHY!!!
|
||||
for (var/key in ban["keys"])
|
||||
if (ckey(key) == alt)
|
||||
found = 1
|
||||
break
|
||||
|
||||
if (!found)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: [alt] is not linked to [ckey]'s sticky ban!</span>")
|
||||
var/key = LAZYACCESS(ban["keys"], alt)
|
||||
if (!key)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: [alt] is not linked to [ckey]'s sticky ban!</span>", confidential = TRUE)
|
||||
return
|
||||
|
||||
if (alert("Are you sure you want to disassociate [alt] from [ckey]'s sticky ban? \nNote: Nothing stops byond from re-linking them","Are you sure","Yes","No") == "No")
|
||||
if (alert("Are you sure you want to disassociate [alt] from [ckey]'s sticky ban? \nNote: Nothing stops byond from re-linking them, Use \[E] to exempt them","Are you sure","Yes","No") == "No")
|
||||
return
|
||||
|
||||
//we have to do this again incase something changes
|
||||
ban = get_stickyban_from_ckey(ckey)
|
||||
if (!ban)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: The ban disappeared.</span>")
|
||||
to_chat(usr, "<span class='adminnotice'>Error: The ban disappeared.</span>", confidential = TRUE)
|
||||
return
|
||||
|
||||
found = 0
|
||||
for (var/key in ban["keys"])
|
||||
if (ckey(key) == alt)
|
||||
ban["keys"] -= key
|
||||
found = 1
|
||||
break
|
||||
key = LAZYACCESS(ban["keys"], alt)
|
||||
|
||||
if (!found)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: [alt] link to [ckey]'s sticky ban disappeared.</span>")
|
||||
if (!key)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: [alt] link to [ckey]'s sticky ban disappeared.</span>", confidential = TRUE)
|
||||
return
|
||||
|
||||
LAZYREMOVE(ban["keys"], alt)
|
||||
world.SetConfig("ban",ckey,list2stickyban(ban))
|
||||
|
||||
SSstickyban.cache[ckey] = ban
|
||||
|
||||
if (SSdbcore.Connect())
|
||||
// var/datum/db_query/query_remove_stickyban_alt = SSdbcore.NewQuery(
|
||||
// "DELETE FROM [format_table_name("stickyban_matched_ckey")] WHERE stickyban = :ckey AND matched_ckey = :alt",
|
||||
// list("ckey" = ckey, "alt" = alt)
|
||||
// )
|
||||
var/datum/DBQuery/query_remove_stickyban_alt = SSdbcore.NewQuery(
|
||||
"DELETE FROM [format_table_name("stickyban_matched_ckey")] WHERE stickyban = [ckey] AND matched_ckey = [alt]"
|
||||
)
|
||||
query_remove_stickyban_alt.warn_execute()
|
||||
qdel(query_remove_stickyban_alt)
|
||||
|
||||
log_admin_private("[key_name(usr)] has disassociated [alt] from [ckey]'s sticky ban")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has disassociated [alt] from [ckey]'s sticky ban</span>")
|
||||
|
||||
@@ -109,7 +147,7 @@
|
||||
var/ckey = data["ckey"]
|
||||
var/ban = get_stickyban_from_ckey(ckey)
|
||||
if (!ban)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>")
|
||||
to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>", confidential = TRUE)
|
||||
return
|
||||
var/oldreason = ban["message"]
|
||||
var/reason = input(usr,"Reason","Reason","[ban["message"]]") as text|null
|
||||
@@ -118,28 +156,203 @@
|
||||
//we have to do this again incase something changed while we waited for input
|
||||
ban = get_stickyban_from_ckey(ckey)
|
||||
if (!ban)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: The ban disappeared.</span>")
|
||||
to_chat(usr, "<span class='adminnotice'>Error: The ban disappeared.</span>", confidential = TRUE)
|
||||
return
|
||||
ban["message"] = "[reason]"
|
||||
|
||||
world.SetConfig("ban",ckey,list2stickyban(ban))
|
||||
|
||||
SSstickyban.cache[ckey] = ban
|
||||
|
||||
if (SSdbcore.Connect())
|
||||
// var/datum/db_query/query_edit_stickyban = SSdbcore.NewQuery(
|
||||
// "UPDATE [format_table_name("stickyban")] SET reason = :reason WHERE ckey = :ckey",
|
||||
// list("reason" = reason, "ckey" = ckey)
|
||||
// )
|
||||
var/datum/DBQuery/query_edit_stickyban = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("stickyban")] SET reason = [reason] WHERE ckey = [ckey]"
|
||||
)
|
||||
query_edit_stickyban.warn_execute()
|
||||
qdel(query_edit_stickyban)
|
||||
|
||||
log_admin_private("[key_name(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]</span>")
|
||||
|
||||
if ("exempt")
|
||||
if (!data["ckey"])
|
||||
return
|
||||
var/ckey = data["ckey"]
|
||||
if (!data["alt"])
|
||||
return
|
||||
var/alt = ckey(data["alt"])
|
||||
var/ban = get_stickyban_from_ckey(ckey)
|
||||
if (!ban)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>", confidential = TRUE)
|
||||
return
|
||||
|
||||
var/key = LAZYACCESS(ban["keys"], alt)
|
||||
if (!key)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: [alt] is not linked to [ckey]'s sticky ban!</span>", confidential = TRUE)
|
||||
return
|
||||
|
||||
if (alert("Are you sure you want to exempt [alt] from [ckey]'s sticky ban?","Are you sure","Yes","No") == "No")
|
||||
return
|
||||
|
||||
//we have to do this again incase something changes
|
||||
ban = get_stickyban_from_ckey(ckey)
|
||||
if (!ban)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: The ban disappeared.</span>", confidential = TRUE)
|
||||
return
|
||||
|
||||
key = LAZYACCESS(ban["keys"], alt)
|
||||
|
||||
if (!key)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: [alt]'s link to [ckey]'s sticky ban disappeared.</span>", confidential = TRUE)
|
||||
return
|
||||
LAZYREMOVE(ban["keys"], alt)
|
||||
key["exempt"] = TRUE
|
||||
LAZYSET(ban["whitelist"], alt, key)
|
||||
|
||||
world.SetConfig("ban",ckey,list2stickyban(ban))
|
||||
|
||||
SSstickyban.cache[ckey] = ban
|
||||
|
||||
if (SSdbcore.Connect())
|
||||
// var/datum/db_query/query_exempt_stickyban_alt = SSdbcore.NewQuery(
|
||||
// "UPDATE [format_table_name("stickyban_matched_ckey")] SET exempt = 1 WHERE stickyban = :ckey AND matched_ckey = :alt",
|
||||
// list("ckey" = ckey, "alt" = alt)
|
||||
// )
|
||||
var/datum/DBQuery/query_exempt_stickyban_alt = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("stickyban_matched_ckey")] SET exempt = 1 WHERE stickyban = [ckey] AND matched_ckey = [alt]"
|
||||
)
|
||||
query_exempt_stickyban_alt.warn_execute()
|
||||
qdel(query_exempt_stickyban_alt)
|
||||
|
||||
log_admin_private("[key_name(usr)] has exempted [alt] from [ckey]'s sticky ban")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has exempted [alt] from [ckey]'s sticky ban</span>")
|
||||
|
||||
if ("unexempt")
|
||||
if (!data["ckey"])
|
||||
return
|
||||
var/ckey = data["ckey"]
|
||||
if (!data["alt"])
|
||||
return
|
||||
var/alt = ckey(data["alt"])
|
||||
var/ban = get_stickyban_from_ckey(ckey)
|
||||
if (!ban)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>", confidential = TRUE)
|
||||
return
|
||||
|
||||
var/key = LAZYACCESS(ban["whitelist"], alt)
|
||||
if (!key)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: [alt] is not exempt from [ckey]'s sticky ban!</span>", confidential = TRUE)
|
||||
return
|
||||
|
||||
if (alert("Are you sure you want to unexempt [alt] from [ckey]'s sticky ban?","Are you sure","Yes","No") == "No")
|
||||
return
|
||||
|
||||
//we have to do this again incase something changes
|
||||
ban = get_stickyban_from_ckey(ckey)
|
||||
if (!ban)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: The ban disappeared.</span>", confidential = TRUE)
|
||||
return
|
||||
|
||||
key = LAZYACCESS(ban["whitelist"], alt)
|
||||
if (!key)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: [alt]'s exemption from [ckey]'s sticky ban disappeared.</span>", confidential = TRUE)
|
||||
return
|
||||
|
||||
LAZYREMOVE(ban["whitelist"], alt)
|
||||
key["exempt"] = FALSE
|
||||
LAZYSET(ban["keys"], alt, key)
|
||||
|
||||
world.SetConfig("ban",ckey,list2stickyban(ban))
|
||||
|
||||
SSstickyban.cache[ckey] = ban
|
||||
|
||||
if (SSdbcore.Connect())
|
||||
// var/datum/db_query/query_unexempt_stickyban_alt = SSdbcore.NewQuery(
|
||||
// "UPDATE [format_table_name("stickyban_matched_ckey")] SET exempt = 0 WHERE stickyban = :ckey AND matched_ckey = :alt",
|
||||
// list("ckey" = ckey, "alt" = alt)
|
||||
// )
|
||||
var/datum/DBQuery/query_unexempt_stickyban_alt = SSdbcore.NewQuery(
|
||||
"UPDATE [format_table_name("stickyban_matched_ckey")] SET exempt = 0 WHERE stickyban = [ckey] AND matched_ckey = [alt]"
|
||||
)
|
||||
query_unexempt_stickyban_alt.warn_execute()
|
||||
qdel(query_unexempt_stickyban_alt)
|
||||
|
||||
log_admin_private("[key_name(usr)] has unexempted [alt] from [ckey]'s sticky ban")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has unexempted [alt] from [ckey]'s sticky ban</span>")
|
||||
|
||||
if ("timeout")
|
||||
if (!data["ckey"])
|
||||
return
|
||||
if (!SSdbcore.Connect())
|
||||
to_chat(usr, "<span class='adminnotice'>No database connection!</span>", confidential = TRUE)
|
||||
return
|
||||
|
||||
var/ckey = data["ckey"]
|
||||
|
||||
if (alert("Are you sure you want to put [ckey]'s stickyban on timeout until next round (or removed)?","Are you sure","Yes","No") == "No")
|
||||
return
|
||||
var/ban = get_stickyban_from_ckey(ckey)
|
||||
if (!ban)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>", confidential = TRUE)
|
||||
return
|
||||
|
||||
ban["timeout"] = TRUE
|
||||
|
||||
world.SetConfig("ban", ckey, null)
|
||||
|
||||
var/cachedban = SSstickyban.cache[ckey]
|
||||
if (cachedban)
|
||||
cachedban["timeout"] = TRUE
|
||||
|
||||
log_admin_private("[key_name(usr)] has put [ckey]'s sticky ban on timeout.")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has put [ckey]'s sticky ban on timeout.</span>")
|
||||
|
||||
if ("untimeout")
|
||||
if (!data["ckey"])
|
||||
return
|
||||
if (!SSdbcore.Connect())
|
||||
to_chat(usr, "<span class='adminnotice'>No database connection!</span>", confidential = TRUE)
|
||||
return
|
||||
var/ckey = data["ckey"]
|
||||
|
||||
if (alert("Are you sure you want to lift the timeout on [ckey]'s stickyban?","Are you sure","Yes","No") == "No")
|
||||
return
|
||||
|
||||
var/ban = get_stickyban_from_ckey(ckey)
|
||||
var/cachedban = SSstickyban.cache[ckey]
|
||||
if (cachedban)
|
||||
cachedban["timeout"] = FALSE
|
||||
if (!ban)
|
||||
if (!cachedban)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>", confidential = TRUE)
|
||||
return
|
||||
ban = cachedban
|
||||
|
||||
ban["timeout"] = FALSE
|
||||
|
||||
world.SetConfig("ban",ckey,list2stickyban(ban))
|
||||
|
||||
log_admin_private("[key_name(usr)] has taken [ckey]'s sticky ban off of timeout.")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has taken [ckey]'s sticky ban off of timeout.</span>")
|
||||
|
||||
|
||||
if ("revert")
|
||||
if (!data["ckey"])
|
||||
return
|
||||
var/ckey = data["ckey"]
|
||||
if (alert("Are you sure you want to revert the sticky ban on [ckey] to its state at round start?","Are you sure","Yes","No") == "No")
|
||||
if (alert("Are you sure you want to revert the sticky ban on [ckey] to its state at round start (or last edit)?","Are you sure","Yes","No") == "No")
|
||||
return
|
||||
var/ban = get_stickyban_from_ckey(ckey)
|
||||
if (!ban)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>")
|
||||
to_chat(usr, "<span class='adminnotice'>Error: No sticky ban for [ckey] found!</span>", confidential = TRUE)
|
||||
return
|
||||
var/cached_ban = SSstickyban.cache[ckey]
|
||||
if (!cached_ban)
|
||||
to_chat(usr, "<span class='adminnotice'>Error: No cached sticky ban for [ckey] found!</span>")
|
||||
to_chat(usr, "<span class='adminnotice'>Error: No cached sticky ban for [ckey] found!</span>", confidential = TRUE)
|
||||
world.SetConfig("ban",ckey,null)
|
||||
|
||||
log_admin_private("[key_name(usr)] has reverted [ckey]'s sticky ban to its state at round start.")
|
||||
@@ -150,14 +363,22 @@
|
||||
world.SetConfig("ban",ckey,list2stickyban(cached_ban))
|
||||
|
||||
|
||||
/datum/admins/proc/stickyban_gethtml(ckey, ban)
|
||||
. = {"
|
||||
/datum/admins/proc/stickyban_gethtml(ckey)
|
||||
var/ban = get_stickyban_from_ckey(ckey)
|
||||
if (!ban)
|
||||
return
|
||||
var/timeout
|
||||
if (SSdbcore.Connect())
|
||||
timeout = "<a href='?_src_=holder;[HrefToken()];stickyban=[(ban["timeout"] ? "untimeout" : "timeout")]&ckey=[ckey]'>\[[(ban["timeout"] ? "untimeout" : "timeout" )]\]</a>"
|
||||
else
|
||||
timeout = "<a href='?_src_=holder;[HrefToken()];stickyban=revert&ckey=[ckey]'>\[revert\]</a>"
|
||||
. = list({"
|
||||
<a href='?_src_=holder;[HrefToken()];stickyban=remove&ckey=[ckey]'>\[-\]</a>
|
||||
<a href='?_src_=holder;[HrefToken()];stickyban=revert&ckey=[ckey]'>\[revert\]</a>
|
||||
[timeout]
|
||||
<b>[ckey]</b>
|
||||
<br />"
|
||||
[ban["message"]] <b><a href='?_src_=holder;[HrefToken()];stickyban=edit&ckey=[ckey]'>\[Edit\]</a></b><br />
|
||||
"}
|
||||
"})
|
||||
if (ban["admin"])
|
||||
. += "[ban["admin"]]<br />"
|
||||
else
|
||||
@@ -166,19 +387,24 @@
|
||||
for (var/key in ban["keys"])
|
||||
if (ckey(key) == ckey)
|
||||
continue
|
||||
. += "<li><a href='?_src_=holder;[HrefToken()];stickyban=remove_alt&ckey=[ckey]&alt=[ckey(key)]'>\[-\]</a>[key]</li>"
|
||||
. += "<li><a href='?_src_=holder;[HrefToken()];stickyban=remove_alt&ckey=[ckey]&alt=[ckey(key)]'>\[-\]</a>[key]<a href='?_src_=holder;[HrefToken()];stickyban=exempt&ckey=[ckey]&alt=[ckey(key)]'>\[E\]</a></li>"
|
||||
|
||||
for (var/key in ban["whitelist"])
|
||||
if (ckey(key) == ckey)
|
||||
continue
|
||||
. += "<li><a href='?_src_=holder;[HrefToken()];stickyban=remove_alt&ckey=[ckey]&alt=[ckey(key)]'>\[-\]</a>[key]<a href='?_src_=holder;[HrefToken()];stickyban=unexempt&ckey=[ckey]&alt=[ckey(key)]'>\[UE\]</a></li>"
|
||||
|
||||
. += "</ol>\n"
|
||||
|
||||
/datum/admins/proc/stickyban_show()
|
||||
if(!check_rights(R_BAN))
|
||||
return
|
||||
var/list/bans = sortList(world.GetConfig("ban"))
|
||||
var/banhtml = ""
|
||||
var/list/bans = sticky_banned_ckeys()
|
||||
var/list/banhtml = list()
|
||||
for(var/key in bans)
|
||||
var/ckey = ckey(key)
|
||||
var/ban = stickyban2list(world.GetConfig("ban",key))
|
||||
banhtml += "<br /><hr />\n"
|
||||
banhtml += stickyban_gethtml(ckey,ban)
|
||||
banhtml += stickyban_gethtml(ckey)
|
||||
|
||||
var/html = {"
|
||||
<head>
|
||||
@@ -186,22 +412,49 @@
|
||||
</head>
|
||||
<body>
|
||||
<h2>All Sticky Bans:</h2> <a href='?_src_=holder;[HrefToken()];stickyban=add'>\[+\]</a><br>
|
||||
[banhtml]
|
||||
[banhtml.Join("")]
|
||||
</body>
|
||||
"}
|
||||
usr << browse(html,"window=stickybans;size=700x400")
|
||||
|
||||
/proc/get_stickyban_from_ckey(var/ckey)
|
||||
/proc/sticky_banned_ckeys()
|
||||
if (SSdbcore.Connect() || length(SSstickyban.dbcache))
|
||||
if (SSstickyban.dbcacheexpire < world.time)
|
||||
SSstickyban.Populatedbcache()
|
||||
if (SSstickyban.dbcacheexpire)
|
||||
return SSstickyban.dbcache.Copy()
|
||||
|
||||
return sortList(world.GetConfig("ban"))
|
||||
|
||||
|
||||
/proc/get_stickyban_from_ckey(ckey)
|
||||
. = list()
|
||||
if (!ckey)
|
||||
return null
|
||||
ckey = ckey(ckey)
|
||||
. = null
|
||||
for (var/key in world.GetConfig("ban"))
|
||||
if (ckey(key) == ckey)
|
||||
. = stickyban2list(world.GetConfig("ban",key))
|
||||
break
|
||||
if (SSdbcore.Connect() || length(SSstickyban.dbcache))
|
||||
if (SSstickyban.dbcacheexpire < world.time)
|
||||
SSstickyban.Populatedbcache()
|
||||
if (SSstickyban.dbcacheexpire)
|
||||
. = SSstickyban.dbcache[ckey]
|
||||
//reset the cache incase its a newer ban (but only if we didn't update the cache recently)
|
||||
if (!. && SSstickyban.dbcacheexpire != world.time+STICKYBAN_DB_CACHE_TIME)
|
||||
SSstickyban.dbcacheexpire = 1
|
||||
SSstickyban.Populatedbcache()
|
||||
. = SSstickyban.dbcache[ckey]
|
||||
if (.)
|
||||
var/list/cachedban = SSstickyban.cache["[ckey]"]
|
||||
if (cachedban)
|
||||
.["timeout"] = cachedban["timeout"]
|
||||
|
||||
/proc/stickyban2list(var/ban)
|
||||
.["fromdb"] = TRUE
|
||||
return
|
||||
|
||||
. = stickyban2list(world.GetConfig("ban", ckey)) || stickyban2list(world.GetConfig("ban", ckey(ckey))) || list()
|
||||
|
||||
if (!length(.))
|
||||
return null
|
||||
|
||||
/proc/stickyban2list(ban, strictdb = TRUE)
|
||||
if (!ban)
|
||||
return null
|
||||
. = params2list(ban)
|
||||
@@ -212,30 +465,40 @@
|
||||
var/ckey = ckey(key)
|
||||
ckeys[ckey] = ckey //to make searching faster.
|
||||
.["keys"] = ckeys
|
||||
if (.["whitelist"])
|
||||
var/keys = splittext(.["whitelist"], ",")
|
||||
var/ckeys = list()
|
||||
for (var/key in keys)
|
||||
var/ckey = ckey(key)
|
||||
ckeys[ckey] = ckey //to make searching faster.
|
||||
.["whitelist"] = ckeys
|
||||
.["type"] = splittext(.["type"], ",")
|
||||
.["IP"] = splittext(.["IP"], ",")
|
||||
.["computer_id"] = splittext(.["computer_id"], ",")
|
||||
. -= "fromdb"
|
||||
|
||||
|
||||
/proc/list2stickyban(var/list/ban)
|
||||
/proc/list2stickyban(list/ban)
|
||||
if (!ban || !islist(ban))
|
||||
return null
|
||||
. = ban.Copy()
|
||||
if (.["keys"])
|
||||
.["keys"] = jointext(.["keys"], ",")
|
||||
if (.["IP"])
|
||||
.["IP"] = jointext(.["IP"], ",")
|
||||
if (.["computer_id"])
|
||||
.["computer_id"] = jointext(.["computer_id"], ",")
|
||||
if (.["whitelist"])
|
||||
.["whitelist"] = jointext(.["whitelist"], ",")
|
||||
if (.["type"])
|
||||
.["type"] = jointext(.["type"], ",")
|
||||
|
||||
//internal tracking only, shouldn't be stored
|
||||
. -= "reverting"
|
||||
. -= "matches_this_round"
|
||||
. -= "existing_user_matches_this_round"
|
||||
. -= "admin_matches_this_round"
|
||||
. -= "matches_this_round"
|
||||
. -= "reverting"
|
||||
. -= "pending_matches_this_round"
|
||||
|
||||
//storing these can sometimes cause sticky bans to start matching everybody
|
||||
// and isn't even needed for sticky ban matching, as the hub tracks these separately
|
||||
. -= "IP"
|
||||
. -= "computer_id"
|
||||
|
||||
. = list2params(.)
|
||||
|
||||
|
||||
@@ -782,7 +782,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null
|
||||
if(temp.vars.Find(v))
|
||||
temp.vars[v] = SDQL_expression(d, set_list[sets])
|
||||
else
|
||||
temp.vv_edit_var(v, SDQL_expression(d, set_list[sets]))
|
||||
temp.vv_edit_var(v, SDQL_expression(d, set_list[sets]), TRUE)
|
||||
break
|
||||
if(temp.vars.Find(v) && (istype(temp.vars[v], /datum) || istype(temp.vars[v], /client)))
|
||||
temp = temp.vars[v]
|
||||
|
||||
@@ -158,3 +158,19 @@
|
||||
else
|
||||
to_chat(src, "Failed to move mob to a valid location.", confidential = TRUE)
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Send Mob") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/// Proc to hook user-enacted teleporting behavior and keep logging of the event.
|
||||
/atom/movable/proc/admin_teleport(atom/new_location, message = TRUE)
|
||||
if(isnull(new_location))
|
||||
log_admin("[key_name(usr)] teleported [key_name(src)] to nullspace")
|
||||
moveToNullspace()
|
||||
else
|
||||
log_admin("[key_name(usr)] teleported [key_name(src)] to [AREACOORD(loc)]")
|
||||
forceMove(new_location)
|
||||
|
||||
/mob/admin_teleport(atom/new_location, message = TRUE)
|
||||
var/msg = "[key_name_admin(usr)] teleported [ADMIN_LOOKUPFLW(src)] to [isnull(new_location) ? "nullspace" : ADMIN_VERBOSEJMP(loc)]"
|
||||
if(message)
|
||||
message_admins(msg)
|
||||
admin_ticket_log(src, msg)
|
||||
return ..()
|
||||
|
||||
@@ -4,12 +4,10 @@
|
||||
if(!check_rights(R_SOUNDS))
|
||||
return
|
||||
|
||||
var/freq = 1
|
||||
var/vol = input(usr, "What volume would you like the sound to play at?",, 100) as null|num
|
||||
if(!vol)
|
||||
return
|
||||
var/freq = input(usr, "What frequency would you like the sound to play at?",, 1) as null|num
|
||||
if(!freq)
|
||||
freq = 1
|
||||
vol = clamp(vol, 1, 100)
|
||||
|
||||
var/sound/admin_sound = new()
|
||||
@@ -18,14 +16,14 @@
|
||||
admin_sound.channel = CHANNEL_ADMIN
|
||||
admin_sound.frequency = freq
|
||||
admin_sound.wait = 1
|
||||
admin_sound.repeat = 0
|
||||
admin_sound.repeat = FALSE
|
||||
admin_sound.status = SOUND_STREAM
|
||||
admin_sound.volume = vol
|
||||
|
||||
var/res = alert(usr, "Show the title of this song to the players?",, "Yes","No", "Cancel")
|
||||
switch(res)
|
||||
if("Yes")
|
||||
to_chat(world, "<span class='boldannounce'>An admin played: [S]</span>")
|
||||
to_chat(world, "<span class='boldannounce'>An admin played: [S]</span>", confidential = TRUE)
|
||||
if("Cancel")
|
||||
return
|
||||
|
||||
@@ -49,7 +47,7 @@
|
||||
|
||||
log_admin("[key_name(src)] played a local sound [S]")
|
||||
message_admins("[key_name_admin(src)] played a local sound [S]")
|
||||
playsound(get_turf(src.mob), S, 50, 0, 0)
|
||||
playsound(get_turf(src.mob), S, 50, FALSE, FALSE)
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Local Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/play_web_sound()
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
if (!thing)
|
||||
continue
|
||||
var/datum/D = thing
|
||||
if (D.vv_edit_var(variable, initial(D.vars[variable])) != FALSE)
|
||||
if (D.vv_edit_var(variable, initial(D.vars[variable]), TRUE) != FALSE)
|
||||
accepted++
|
||||
else
|
||||
rejected++
|
||||
@@ -135,7 +135,7 @@
|
||||
for(var/V in varsvars)
|
||||
new_value = replacetext(new_value,"\[[V]]","[D.vars[V]]")
|
||||
|
||||
if (D.vv_edit_var(variable, new_value) != FALSE)
|
||||
if (D.vv_edit_var(variable, new_value, TRUE) != FALSE)
|
||||
accepted++
|
||||
else
|
||||
rejected++
|
||||
@@ -161,7 +161,7 @@
|
||||
if(many && !new_value)
|
||||
new_value = new type()
|
||||
|
||||
if (D.vv_edit_var(variable, new_value) != FALSE)
|
||||
if (D.vv_edit_var(variable, new_value, TRUE) != FALSE)
|
||||
accepted++
|
||||
else
|
||||
rejected++
|
||||
@@ -176,7 +176,7 @@
|
||||
if (!thing)
|
||||
continue
|
||||
var/datum/D = thing
|
||||
if (D.vv_edit_var(variable, new_value) != FALSE)
|
||||
if (D.vv_edit_var(variable, new_value, TRUE) != FALSE)
|
||||
accepted++
|
||||
else
|
||||
rejected++
|
||||
|
||||
@@ -109,7 +109,7 @@ GLOBAL_LIST_EMPTY(deletion_failures)
|
||||
set name = "Find References"
|
||||
set src in world
|
||||
|
||||
find_references(FALSE)
|
||||
find_references_legacy(FALSE)
|
||||
|
||||
|
||||
/datum/proc/find_references_legacy(skip_alert)
|
||||
@@ -164,7 +164,7 @@ GLOBAL_LIST_EMPTY(deletion_failures)
|
||||
|
||||
qdel(src, TRUE) //force a qdel
|
||||
if(!running_find_references)
|
||||
find_references(TRUE)
|
||||
find_references_legacy(TRUE)
|
||||
|
||||
|
||||
/datum/verb/qdel_then_if_fail_find_references()
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
dat += "<A href='byond://?src=[REF(src)];school=[APPRENTICE_ROBELESS]'>Robeless</A><BR>"
|
||||
dat += "<I>Your apprentice is training to cast spells without their robes. They know Knock and Mindswap.</I><BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];school=[APPRENTICE_MARTIAL]'>Martial Artist</a><BR>"
|
||||
dat += "<I>Your apprentice is training in ancient martial arts. They know the Plasmafist and Nuclear Fist.</I><BR>"
|
||||
dat += "<I>Your apprentice is training in ancient martial arts. They know an Inner Mantra and the Nuclear Fist technique.</I><BR>"
|
||||
user << browse(dat, "window=radio")
|
||||
onclose(user, "radio")
|
||||
return
|
||||
|
||||
@@ -69,6 +69,7 @@ GLOBAL_LIST_INIT(abductor_gear, subtypesof(/datum/abductor_gear))
|
||||
build_path = /obj/item/abductor_machine_beacon/chem_dispenser
|
||||
category = "Advanced Gear"
|
||||
|
||||
/*
|
||||
/datum/abductor_gear/shrink_ray
|
||||
name = "Shrink Ray Blaster"
|
||||
description = "This is a piece of frightening alien tech that enhances the magnetic pull of atoms in a localized space to temporarily make an object shrink. \
|
||||
@@ -77,3 +78,4 @@ GLOBAL_LIST_INIT(abductor_gear, subtypesof(/datum/abductor_gear))
|
||||
cost = 2
|
||||
build_path = /obj/item/gun/energy/shrink_ray
|
||||
category = "Advanced Gear"
|
||||
*/
|
||||
|
||||
@@ -13,8 +13,9 @@
|
||||
var/nightime_duration = 900 //15 Minutes
|
||||
|
||||
/obj/effect/sunlight/Initialize()
|
||||
countdown()
|
||||
hud_tick()
|
||||
. = ..()
|
||||
INVOKE_ASYNC(src, .proc/countdown)
|
||||
INVOKE_ASYNC(src, .proc/hud_tick)
|
||||
|
||||
/obj/effect/sunlight/proc/countdown()
|
||||
set waitfor = FALSE
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
/datum/antagonist/vassal/greet()
|
||||
to_chat(owner, "<span class='userdanger'>You are now the mortal servant of [master.owner.current], a bloodsucking vampire!</span>")
|
||||
to_chat(owner, "<span class='boldannounce'>The power of [master.owner.current.p_their()] immortal blood compells you to obey [master.owner.current.p_them()] in all things, even offering your own life to prolong theirs.<br>\
|
||||
You are not required to obey any other Bloodsucker, for only [master.owner.current] is your master. The laws of Nanotransen do not apply to you now; only your vampiric master's word must be obeyed.<span>")
|
||||
You are not required to obey any other Bloodsucker, for only [master.owner.current] is your master. The laws of Nanotrasen do not apply to you now; only your vampiric master's word must be obeyed.<span>")
|
||||
// Effects...
|
||||
owner.current.playsound_local(null, 'sound/magic/mutate.ogg', 100, FALSE, pressure_affected = FALSE)
|
||||
//owner.store_memory("You became the mortal servant of [master.owner.current], a bloodsucking vampire!")
|
||||
|
||||
@@ -213,7 +213,7 @@
|
||||
if(canrespec)
|
||||
to_chat(owner.current, "<span class='notice'>We have removed our evolutions from this form, and are now ready to readapt.</span>")
|
||||
reset_powers()
|
||||
playsound(get_turf(owner.current), 'sound/effects/lingreadapt.ogg', 75, TRUE, 5, soundenvwet = 0)
|
||||
playsound(get_turf(owner.current), 'sound/effects/lingreadapt.ogg', 75, TRUE, 5)
|
||||
canrespec = 0
|
||||
SSblackbox.record_feedback("tally", "changeling_power_purchase", 1, "Readapt")
|
||||
return 1
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
for(var/obj/machinery/light/L in range(4, user))
|
||||
L.on = 1
|
||||
L.break_light_tube()
|
||||
playsound(get_turf(user), 'sound/effects/lingscreech.ogg', 75, TRUE, 5, soundenvwet = 0)
|
||||
playsound(get_turf(user), 'sound/effects/lingscreech.ogg', 75, TRUE, 5)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/changeling/dissonant_shriek
|
||||
@@ -49,5 +49,5 @@
|
||||
L.on = 1
|
||||
L.break_light_tube()
|
||||
empulse_using_range(get_turf(user), 8, TRUE)
|
||||
playsound(get_turf(user), 'sound/effects/lingempscreech.ogg', 75, TRUE, 5, soundenvwet = 0)
|
||||
playsound(get_turf(user), 'sound/effects/lingempscreech.ogg', 75, TRUE, 5)
|
||||
return TRUE
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.z == z)
|
||||
if(get_dist(src, M) >= 7)
|
||||
M.playsound_local(src, 'sound/magic/blink.ogg', 10, FALSE, falloff = 10)
|
||||
M.playsound_local(src, 'sound/magic/blink.ogg', 10, FALSE)
|
||||
else
|
||||
M.playsound_local(src, 'sound/magic/blink.ogg', 50, FALSE)
|
||||
|
||||
|
||||
@@ -348,9 +348,9 @@
|
||||
L.dust()
|
||||
else if(L.health > min_drain_health)
|
||||
if(!GLOB.ratvar_awakens && L.stat == CONSCIOUS)
|
||||
vitality_drained = L.adjustToxLoss(1, forced = TRUE)
|
||||
vitality_drained = L.adjustToxLoss(1, forced = TRUE, toxins_type = TOX_OMNI)
|
||||
else
|
||||
vitality_drained = L.adjustToxLoss(1.5, forced = TRUE)
|
||||
vitality_drained = L.adjustToxLoss(1.5, forced = TRUE, toxins_type = TOX_OMNI)
|
||||
if(vitality_drained)
|
||||
GLOB.clockwork_vitality += vitality_drained
|
||||
else
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
if(totaldamage)
|
||||
L.heal_overall_damage(brutedamage, burndamage, only_organic = FALSE) //Maybe a machine god shouldn't murder augmented followers instead of healing them
|
||||
L.adjustOxyLoss(-oxydamage)
|
||||
L.adjustToxLoss(totaldamage * 0.5, TRUE, TRUE)
|
||||
L.adjustToxLoss(totaldamage * 0.5, TRUE, TRUE, toxins_type = TOX_OMNI)
|
||||
clockwork_say(ranged_ability_user, text2ratvar("[has_holy_water ? "Heal tainted" : "Mend wounded"] flesh!"))
|
||||
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>", \
|
||||
|
||||
@@ -15,3 +15,5 @@
|
||||
audible_message("<i>*click*</i>")
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50, TRUE)
|
||||
activate()
|
||||
|
||||
. = ..()
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
alpha = 75
|
||||
|
||||
/obj/structure/destructible/clockwork/trap/trigger/pressure_sensor/mech/Crossed(atom/movable/AM)
|
||||
|
||||
. = ..()
|
||||
if(!istype(AM,/obj/mecha/))
|
||||
return
|
||||
|
||||
|
||||
@@ -21,3 +21,5 @@
|
||||
if(isliving(AM) && opacity)
|
||||
var/mob/living/L = AM
|
||||
L.adjust_fire_stacks(-1) //It's wet!
|
||||
return
|
||||
. = ..()
|
||||
|
||||
@@ -717,9 +717,9 @@
|
||||
uses = 0
|
||||
ratio *= -1
|
||||
H.adjustOxyLoss((overall_damage*ratio) * (H.getOxyLoss() / overall_damage), 0)
|
||||
H.adjustToxLoss((overall_damage*ratio) * (H.getToxLoss() / overall_damage), 0)
|
||||
H.adjustFireLoss((overall_damage*ratio) * (H.getFireLoss() / overall_damage), 0)
|
||||
H.adjustBruteLoss((overall_damage*ratio) * (H.getBruteLoss() / overall_damage), 0)
|
||||
H.adjustToxLoss((overall_damage*ratio) * (H.getToxLoss() / overall_damage), 0, toxins_type = TOX_OMNI)
|
||||
H.adjustFireLoss((overall_damage*ratio) * (H.getFireLoss() / overall_damage), 0, only_organic = FALSE)
|
||||
H.adjustBruteLoss((overall_damage*ratio) * (H.getBruteLoss() / overall_damage), 0, only_organic = FALSE)
|
||||
H.updatehealth()
|
||||
playsound(get_turf(H), 'sound/magic/staff_healing.ogg', 25)
|
||||
new /obj/effect/temp_visual/cult/sparks(get_turf(H))
|
||||
|
||||
@@ -214,8 +214,8 @@
|
||||
if(L.health != L.maxHealth)
|
||||
new /obj/effect/temp_visual/heal(get_turf(src), "#960000")
|
||||
if(ishuman(L))
|
||||
L.adjustBruteLoss(-1, 0)
|
||||
L.adjustFireLoss(-1, 0)
|
||||
L.adjustBruteLoss(-1, 0, only_organic = FALSE)
|
||||
L.adjustFireLoss(-1, 0, only_organic = FALSE)
|
||||
L.updatehealth()
|
||||
if(isshade(L) || isconstruct(L))
|
||||
var/mob/living/simple_animal/M = L
|
||||
|
||||
@@ -189,6 +189,10 @@
|
||||
name = "Mutate"
|
||||
spell_type = /obj/effect/proc_holder/spell/targeted/genetic/mutate
|
||||
|
||||
/datum/spellbook_entry/mantra
|
||||
name = "Inner Mantra"
|
||||
spell_type = /obj/effect/proc_holder/spell/self/mantra
|
||||
|
||||
/datum/spellbook_entry/jaunt
|
||||
name = "Ethereal Jaunt"
|
||||
spell_type = /obj/effect/proc_holder/spell/targeted/ethereal_jaunt
|
||||
|
||||
@@ -181,8 +181,8 @@
|
||||
to_chat(owner, "<B>Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned stealthy, robeless spells. You are able to cast knock and mindswap.")
|
||||
if(APPRENTICE_MARTIAL)
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/targeted/touch/nuclear_fist(null))
|
||||
H.put_in_hands(new /obj/item/book/granter/martial/plasma_fist(H))
|
||||
to_chat(owner, "<B>Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned mystical martial abilities. You are also able to use the Nuclear Fist at will.")
|
||||
owner.AddSpell(new /obj/effect/proc_holder/spell/self/mantra(null))
|
||||
to_chat(owner, "<B>Your service has not gone unrewarded, however. Studying under [master.current.real_name], you have learned to control your Inner Mantra. You are also able to use the Nuclear Fist at will.")
|
||||
|
||||
/datum/antagonist/wizard/apprentice/create_objectives()
|
||||
var/datum/objective/protect/new_objective = new /datum/objective/protect
|
||||
|
||||
@@ -123,6 +123,7 @@ obj/item/dildo/flared/huge
|
||||
desc = "THIS THING IS HUGE!"
|
||||
dildo_size = 4
|
||||
force = 10
|
||||
hitsound = 'sound/weapons/klonk.ogg'
|
||||
|
||||
obj/item/dildo/custom
|
||||
name = "customizable dildo"
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
master.update_icon()
|
||||
|
||||
/obj/item/assembly_holder/Crossed(atom/movable/AM as mob|obj)
|
||||
. = ..()
|
||||
if(a_left)
|
||||
a_left.Crossed(AM)
|
||||
if(a_right)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
/// Process asset cache client topic calls for "asset_cache_confirm_arrival=[INT]"
|
||||
/// Process asset cache client topic calls for `"asset_cache_confirm_arrival=[INT]"`
|
||||
/client/proc/asset_cache_confirm_arrival(job_id)
|
||||
var/asset_cache_job = round(text2num(job_id))
|
||||
//because we skip the limiter, we have to make sure this is a valid arrival and not somebody tricking us into letting them append to a list without limit.
|
||||
@@ -10,7 +10,7 @@
|
||||
return asset_cache_job || TRUE
|
||||
|
||||
|
||||
/// Process asset cache client topic calls for "asset_cache_preload_data=[HTML+JSON_STRING]
|
||||
/// Process asset cache client topic calls for `"asset_cache_preload_data=[HTML+JSON_STRING]"`
|
||||
/client/proc/asset_cache_preload_data(data)
|
||||
var/json = data
|
||||
var/list/preloaded_assets = json_decode(json)
|
||||
|
||||
@@ -47,8 +47,9 @@
|
||||
"smmon_3.gif" = 'icons/program_icons/smmon_3.gif',
|
||||
"smmon_4.gif" = 'icons/program_icons/smmon_4.gif',
|
||||
"smmon_5.gif" = 'icons/program_icons/smmon_5.gif',
|
||||
"smmon_6.gif" = 'icons/program_icons/smmon_6.gif',
|
||||
"borg_mon.gif" = 'icons/program_icons/borg_mon.gif'
|
||||
"smmon_6.gif" = 'icons/program_icons/smmon_6.gif'
|
||||
// "borg_mon.gif" = 'icons/program_icons/borg_mon.gif',
|
||||
// "robotact.gif" = 'icons/program_icons/robotact.gif'
|
||||
)
|
||||
|
||||
/datum/asset/simple/radar_assets
|
||||
@@ -156,7 +157,6 @@
|
||||
)
|
||||
|
||||
/datum/asset/simple/namespaced/fontawesome
|
||||
legacy = TRUE
|
||||
assets = list(
|
||||
"fa-regular-400.eot" = 'html/font-awesome/webfonts/fa-regular-400.eot',
|
||||
"fa-regular-400.woff" = 'html/font-awesome/webfonts/fa-regular-400.woff',
|
||||
@@ -248,6 +248,10 @@
|
||||
"rule8" = 'icons/UI_Icons/Achievements/Misc/rule8.png',
|
||||
"snail" = 'icons/UI_Icons/Achievements/Misc/snail.png',
|
||||
"ascension" = 'icons/UI_Icons/Achievements/Misc/ascension.png',
|
||||
"ashascend" = 'icons/UI_Icons/Achievements/Misc/ashascend.png',
|
||||
"fleshascend" = 'icons/UI_Icons/Achievements/Misc/fleshascend.png',
|
||||
"rustascend" = 'icons/UI_Icons/Achievements/Misc/rustascend.png',
|
||||
"voidascend" = 'icons/UI_Icons/Achievements/Misc/voidascend.png',
|
||||
"mining" = 'icons/UI_Icons/Achievements/Skills/mining.png',
|
||||
"assistant" = 'icons/UI_Icons/Achievements/Mafia/assistant.png',
|
||||
"changeling" = 'icons/UI_Icons/Achievements/Mafia/changeling.png',
|
||||
@@ -288,7 +292,7 @@
|
||||
)
|
||||
|
||||
/datum/asset/spritesheet/simple/pills
|
||||
name ="pills"
|
||||
name = "pills"
|
||||
assets = list(
|
||||
"pill1" = 'icons/UI_Icons/Pills/pill1.png',
|
||||
"pill2" = 'icons/UI_Icons/Pills/pill2.png',
|
||||
@@ -313,7 +317,28 @@
|
||||
"pill21" = 'icons/UI_Icons/Pills/pill21.png',
|
||||
"pill22" = 'icons/UI_Icons/Pills/pill22.png',
|
||||
)
|
||||
|
||||
/*
|
||||
/datum/asset/spritesheet/simple/condiments
|
||||
name = "condiments"
|
||||
assets = list(
|
||||
CONDIMASTER_STYLE_FALLBACK = 'icons/UI_Icons/Condiments/emptycondiment.png',
|
||||
"enzyme" = 'icons/UI_Icons/Condiments/enzyme.png',
|
||||
"flour" = 'icons/UI_Icons/Condiments/flour.png',
|
||||
"mayonnaise" = 'icons/UI_Icons/Condiments/mayonnaise.png',
|
||||
"milk" = 'icons/UI_Icons/Condiments/milk.png',
|
||||
"blackpepper" = 'icons/UI_Icons/Condiments/peppermillsmall.png',
|
||||
"rice" = 'icons/UI_Icons/Condiments/rice.png',
|
||||
"sodiumchloride" = 'icons/UI_Icons/Condiments/saltshakersmall.png',
|
||||
"soymilk" = 'icons/UI_Icons/Condiments/soymilk.png',
|
||||
"soysauce" = 'icons/UI_Icons/Condiments/soysauce.png',
|
||||
"sugar" = 'icons/UI_Icons/Condiments/sugar.png',
|
||||
"ketchup" = 'icons/UI_Icons/Condiments/ketchup.png',
|
||||
"capsaicin" = 'icons/UI_Icons/Condiments/hotsauce.png',
|
||||
"frostoil" = 'icons/UI_Icons/Condiments/coldsauce.png',
|
||||
"bbqsauce" = 'icons/UI_Icons/Condiments/bbqsauce.png',
|
||||
"cornoil" = 'icons/UI_Icons/Condiments/oliveoil.png',
|
||||
)
|
||||
*/
|
||||
//this exists purely to avoid meta by pre-loading all language icons.
|
||||
/datum/asset/language/register()
|
||||
for(var/path in typesof(/datum/language))
|
||||
@@ -484,3 +509,31 @@
|
||||
/datum/asset/spritesheet/mafia/register()
|
||||
InsertAll("", 'icons/obj/mafia.dmi')
|
||||
..()
|
||||
|
||||
/datum/asset/simple/portraits
|
||||
var/tab = "use subtypes of this please"
|
||||
assets = list()
|
||||
|
||||
/datum/asset/simple/portraits/New()
|
||||
if(!SSpersistence.paintings || !SSpersistence.paintings[tab] || !length(SSpersistence.paintings[tab]))
|
||||
return
|
||||
for(var/p in SSpersistence.paintings[tab])
|
||||
var/list/portrait = p
|
||||
var/png = "data/paintings/[tab]/[portrait["md5"]].png"
|
||||
if(fexists(png))
|
||||
assets[portrait["title"]] = png
|
||||
..() //this is where it registers all these assets we added to the list
|
||||
|
||||
/datum/asset/simple/portraits/library
|
||||
tab = "library"
|
||||
|
||||
/datum/asset/simple/portraits/library_secure
|
||||
tab = "library_secure"
|
||||
|
||||
/datum/asset/simple/portraits/library_private
|
||||
tab = "library_private"
|
||||
|
||||
/datum/asset/simple/safe
|
||||
assets = list(
|
||||
"safe_dial.png" = 'html/safe_dial.png'
|
||||
)
|
||||
|
||||
@@ -24,7 +24,7 @@ Call .get_url_mappings() to get an associated list with the urls your assets can
|
||||
|
||||
See the documentation for `/datum/asset_transport` for the backend api the asset datums utilize.
|
||||
|
||||
The global variable `SSassets.transport` contains the currently configured transport.
|
||||
The global variable `SSassets.transport` contains the currently configured transport.
|
||||
|
||||
|
||||
|
||||
@@ -32,6 +32,6 @@ The global variable `SSassets.transport` contains the currently configured trans
|
||||
|
||||
Because byond browse() calls use non-blocking queues, if your code uses output() (which bypasses all of these queues) to invoke javascript functions you will need to first have the javascript announce to the server it has loaded before trying to invoke js functions.
|
||||
|
||||
To make your code work with any CDNs configured by the server, you must make sure assets are referenced from the url returned by `get_url_mappings()` or by asset_transport's `get_asset_url()`. (TGUI also has helpers for this.) If this can not be easily done, you can bypass the cdn using legacy assets, see the simple asset datum for details.
|
||||
To make your code work with any CDNs configured by the server, you must make sure assets are referenced from the url returned by `get_url_mappings()` or by asset_transport's `get_asset_url()`. (TGUI also has helpers for this.) If this can not be easily done, you can bypass the cdn using legacy assets, see the simple asset datum for details.
|
||||
|
||||
CSS files that use url() can be made to use the CDN without needing to rewrite all url() calls in code by using the namespaced helper datum. See the documentation for `/datum/asset/simple/namespaced` for details.
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
SSair.add_to_active(T)
|
||||
return ..()
|
||||
|
||||
/// Function for Extools Atmos
|
||||
/turf/proc/update_air_ref()
|
||||
|
||||
/////////////////GAS MIXTURE PROCS///////////////////
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#define AMMO_DROP_LIFETIME 300
|
||||
#define CTF_REQUIRED_PLAYERS 4
|
||||
|
||||
|
||||
|
||||
/obj/item/ctf
|
||||
name = "banner"
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
@@ -16,13 +18,13 @@
|
||||
righthand_file = 'icons/mob/inhands/equipment/banners_righthand.dmi'
|
||||
desc = "A banner with Nanotrasen's logo on it."
|
||||
slowdown = 2
|
||||
item_flags = SLOWS_WHILE_IN_HAND
|
||||
throw_speed = 0
|
||||
throw_range = 1
|
||||
force = 200
|
||||
armour_penetration = 1000
|
||||
resistance_flags = INDESTRUCTIBLE
|
||||
anchored = TRUE
|
||||
item_flags = SLOWS_WHILE_IN_HAND
|
||||
var/team = WHITE_TEAM
|
||||
var/reset_cooldown = 0
|
||||
var/anyonecanpickup = TRUE
|
||||
@@ -53,12 +55,13 @@
|
||||
to_chat(M, "<span class='userdanger'>\The [src] has been returned to base!</span>")
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/ctf/on_attack_hand(mob/living/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
//ATTACK HAND IGNORING PARENT RETURN VALUE
|
||||
/obj/item/ctf/on_attack_hand(mob/living/user)
|
||||
if(!is_ctf_target(user) && !anyonecanpickup)
|
||||
to_chat(user, "Non players shouldn't be moving the flag!")
|
||||
to_chat(user, "<span class='warning'>Non-players shouldn't be moving the flag!</span>")
|
||||
return
|
||||
if(team in user.faction)
|
||||
to_chat(user, "You can't move your own flag!")
|
||||
to_chat(user, "<span class='warning'>You can't move your own flag!</span>")
|
||||
return
|
||||
if(loc == user)
|
||||
if(!user.dropItemToGround(src))
|
||||
@@ -68,7 +71,7 @@
|
||||
if(!user.put_in_active_hand(src))
|
||||
dropped(user)
|
||||
return
|
||||
user.anchored = TRUE
|
||||
user.set_anchored(TRUE)
|
||||
user.status_flags &= ~CANPUSH
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
var/area/mob_area = get_area(M)
|
||||
@@ -79,7 +82,7 @@
|
||||
|
||||
/obj/item/ctf/dropped(mob/user)
|
||||
..()
|
||||
user.anchored = FALSE
|
||||
user.set_anchored(FALSE)
|
||||
user.status_flags |= CANPUSH
|
||||
reset_cooldown = world.time + 200 //20 seconds
|
||||
START_PROCESSING(SSobj, src)
|
||||
@@ -172,20 +175,20 @@
|
||||
GLOB.poi_list.Remove(src)
|
||||
..()
|
||||
|
||||
/obj/machinery/capture_the_flag/process()
|
||||
/obj/machinery/capture_the_flag/process(delta_time)
|
||||
for(var/i in spawned_mobs)
|
||||
if(!i)
|
||||
spawned_mobs -= i
|
||||
continue
|
||||
// Anyone in crit, automatically reap
|
||||
var/mob/living/M = i
|
||||
if(M.InCritical() || M.stat == DEAD)
|
||||
ctf_dust_old(M)
|
||||
var/mob/living/living_participant = i
|
||||
if(living_participant.InCritical() || living_participant.stat == DEAD)
|
||||
ctf_dust_old(living_participant)
|
||||
else
|
||||
// The changes that you've been hit with no shield but not
|
||||
// instantly critted are low, but have some healing.
|
||||
M.adjustBruteLoss(-5)
|
||||
M.adjustFireLoss(-5)
|
||||
living_participant.adjustBruteLoss(-2.5 * delta_time)
|
||||
living_participant.adjustFireLoss(-2.5 * delta_time)
|
||||
|
||||
/obj/machinery/capture_the_flag/red
|
||||
name = "Red CTF Controller"
|
||||
@@ -212,6 +215,10 @@
|
||||
toggle_all_ctf(user)
|
||||
return
|
||||
|
||||
|
||||
// if(!(GLOB.ghost_role_flags & GHOSTROLE_MINIGAME))
|
||||
// to_chat(user, "<span class='warning'>CTF has been temporarily disabled by admins.</span>")
|
||||
// return
|
||||
people_who_want_to_play |= user.ckey
|
||||
var/num = people_who_want_to_play.len
|
||||
var/remaining = CTF_REQUIRED_PLAYERS - num
|
||||
@@ -227,7 +234,7 @@
|
||||
return
|
||||
if(user.ckey in team_members)
|
||||
if(user.ckey in recently_dead_ckeys)
|
||||
to_chat(user, "It must be more than [DisplayTimeText(respawn_cooldown)] from your last death to respawn!")
|
||||
to_chat(user, "<span class='warning'>It must be more than [DisplayTimeText(respawn_cooldown)] from your last death to respawn!</span>")
|
||||
return
|
||||
var/client/new_team_member = user.client
|
||||
if(user.mind && user.mind.current)
|
||||
@@ -239,10 +246,10 @@
|
||||
if(CTF == src || CTF.ctf_enabled == FALSE)
|
||||
continue
|
||||
if(user.ckey in CTF.team_members)
|
||||
to_chat(user, "No switching teams while the round is going!")
|
||||
to_chat(user, "<span class='warning'>No switching teams while the round is going!</span>")
|
||||
return
|
||||
if(CTF.team_members.len < src.team_members.len)
|
||||
to_chat(user, "[src.team] has more team members than [CTF.team]. Try joining [CTF.team] team to even things up.")
|
||||
to_chat(user, "<span class='warning'>[src.team] has more team members than [CTF.team]! Try joining [CTF.team] team to even things up.</span>")
|
||||
return
|
||||
team_members |= user.ckey
|
||||
var/client/new_team_member = user.client
|
||||
@@ -258,7 +265,7 @@
|
||||
addtimer(CALLBACK(src, .proc/clear_cooldown, body.ckey), respawn_cooldown, TIMER_UNIQUE)
|
||||
body.dust()
|
||||
|
||||
/obj/machinery/capture_the_flag/proc/clear_cooldown(var/ckey)
|
||||
/obj/machinery/capture_the_flag/proc/clear_cooldown(ckey)
|
||||
recently_dead_ckeys -= ckey
|
||||
|
||||
/obj/machinery/capture_the_flag/proc/spawn_team_member(client/new_team_member)
|
||||
@@ -270,7 +277,7 @@
|
||||
M.equipOutfit(ctf_gear)
|
||||
M.dna.species.punchdamagehigh = 25
|
||||
M.dna.species.punchdamagelow = 25
|
||||
M.AddElement(/datum/element/ghost_role_eligibility)
|
||||
M.AddElement(/datum/element/ghost_role_eligibility) //??
|
||||
spawned_mobs += M
|
||||
|
||||
/obj/machinery/capture_the_flag/Topic(href, href_list)
|
||||
@@ -293,14 +300,15 @@
|
||||
victory()
|
||||
|
||||
/obj/machinery/capture_the_flag/proc/victory()
|
||||
for(var/mob/M in GLOB.mob_list)
|
||||
var/area/mob_area = get_area(M)
|
||||
for(var/mob/_competitor in GLOB.mob_living_list)
|
||||
var/mob/living/competitor = _competitor
|
||||
var/area/mob_area = get_area(competitor)
|
||||
if(istype(mob_area, /area/ctf))
|
||||
to_chat(M, "<span class='narsie [team_span]'>[team] team wins!</span>")
|
||||
to_chat(M, "<span class='userdanger'>Teams have been cleared. Click on the machines to vote to begin another round.</span>")
|
||||
for(var/obj/item/ctf/W in M)
|
||||
M.dropItemToGround(W)
|
||||
M.dust()
|
||||
to_chat(competitor, "<span class='narsie [team_span]'>[team] team wins!</span>")
|
||||
to_chat(competitor, "<span class='userdanger'>Teams have been cleared. Click on the machines to vote to begin another round.</span>")
|
||||
for(var/obj/item/ctf/W in competitor)
|
||||
competitor.dropItemToGround(W)
|
||||
competitor.dust()
|
||||
for(var/obj/machinery/control_point/control in GLOB.machines)
|
||||
control.icon_state = "dominator"
|
||||
control.controlling = null
|
||||
@@ -328,7 +336,7 @@
|
||||
|
||||
dead_barricades.Cut()
|
||||
|
||||
notify_ghosts("[name] has been activated!", enter_link="<a href=?src=[REF(src)];join=1>(Click to join the [team] team!)</a> or click on the controller directly!", source = src, action=NOTIFY_ATTACK)
|
||||
notify_ghosts("[name] has been activated!", enter_link="<a href=?src=[REF(src)];join=1>(Click to join the [team] team!)</a> or click on the controller directly!", source = src, action=NOTIFY_ATTACK, header = "CTF has been activated")
|
||||
|
||||
if(!arena_reset)
|
||||
reset_the_arena()
|
||||
@@ -355,10 +363,10 @@
|
||||
ctf_enabled = FALSE
|
||||
arena_reset = FALSE
|
||||
var/area/A = get_area(src)
|
||||
for(var/i in GLOB.mob_list)
|
||||
var/mob/M = i
|
||||
if((get_area(A) == A) && (M.ckey in team_members))
|
||||
M.dust()
|
||||
for(var/_competitor in GLOB.mob_living_list)
|
||||
var/mob/living/competitor = _competitor
|
||||
if((get_area(A) == A) && (competitor.ckey in team_members))
|
||||
competitor.dust()
|
||||
team_members.Cut()
|
||||
spawned_mobs.Cut()
|
||||
recently_dead_ckeys.Cut()
|
||||
@@ -375,18 +383,18 @@
|
||||
CTF.ctf_gear = initial(ctf_gear)
|
||||
CTF.respawn_cooldown = DEFAULT_RESPAWN
|
||||
|
||||
/proc/ctf_floor_vanish(atom/target)
|
||||
if(isturf(target.loc))
|
||||
qdel(target)
|
||||
|
||||
/obj/item/gun/ballistic/automatic/pistol/deagle/ctf
|
||||
desc = "This looks like it could really hurt in melee."
|
||||
force = 75
|
||||
mag_type = /obj/item/ammo_box/magazine/m50/ctf
|
||||
|
||||
/obj/item/gun/ballistic/automatic/pistol/deagle/ctf/dropped(mob/user)
|
||||
/obj/item/gun/ballistic/automatic/pistol/deagle/ctf/dropped()
|
||||
. = ..()
|
||||
addtimer(CALLBACK(GLOBAL_PROC, /proc/ctf_floor_vanish, src), 1)
|
||||
addtimer(CALLBACK(src, .proc/floor_vanish), 1)
|
||||
|
||||
/obj/item/gun/ballistic/automatic/pistol/deagle/ctf/proc/floor_vanish()
|
||||
if(isturf(loc))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/ammo_box/magazine/m50/ctf
|
||||
ammo_type = /obj/item/ammo_casing/a50/ctf
|
||||
@@ -400,6 +408,7 @@
|
||||
/obj/item/projectile/bullet/ctf/prehit(atom/target)
|
||||
if(is_ctf_target(target))
|
||||
damage = 60
|
||||
return //PROJECTILE_PIERCE_NONE /// hey uhh don't hit anyone behind them
|
||||
. = ..()
|
||||
|
||||
/obj/item/gun/ballistic/automatic/laser/ctf
|
||||
@@ -407,16 +416,24 @@
|
||||
desc = "This looks like it could really hurt in melee."
|
||||
force = 50
|
||||
|
||||
/obj/item/gun/ballistic/automatic/laser/ctf/dropped(mob/user)
|
||||
/obj/item/gun/ballistic/automatic/laser/ctf/dropped()
|
||||
. = ..()
|
||||
addtimer(CALLBACK(GLOBAL_PROC, /proc/ctf_floor_vanish, src), 1)
|
||||
addtimer(CALLBACK(src, .proc/floor_vanish), 1)
|
||||
|
||||
/obj/item/gun/ballistic/automatic/laser/ctf/proc/floor_vanish()
|
||||
if(isturf(loc))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/ammo_box/magazine/recharge/ctf
|
||||
ammo_type = /obj/item/ammo_casing/caseless/laser/ctf
|
||||
|
||||
/obj/item/ammo_box/magazine/recharge/ctf/dropped(mob/user)
|
||||
/obj/item/ammo_box/magazine/recharge/ctf/dropped()
|
||||
. = ..()
|
||||
addtimer(CALLBACK(GLOBAL_PROC, /proc/ctf_floor_vanish, src), 1)
|
||||
addtimer(CALLBACK(src, .proc/floor_vanish), 1)
|
||||
|
||||
/obj/item/ammo_box/magazine/recharge/ctf/proc/floor_vanish()
|
||||
if(isturf(loc))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/ammo_casing/caseless/laser/ctf
|
||||
projectile_type = /obj/item/projectile/beam/ctf
|
||||
@@ -428,15 +445,16 @@
|
||||
/obj/item/projectile/beam/ctf/prehit(atom/target)
|
||||
if(is_ctf_target(target))
|
||||
damage = 150
|
||||
return //PROJECTILE_PIERCE_NONE /// hey uhhh don't hit anyone behind them
|
||||
. = ..()
|
||||
|
||||
/proc/is_ctf_target(atom/target)
|
||||
. = FALSE
|
||||
if(istype(target, /obj/structure/barricade/security/ctf))
|
||||
. = TRUE
|
||||
if(isliving(target))
|
||||
var/mob/living/H = target
|
||||
if((RED_TEAM in H.faction) || (BLUE_TEAM in H.faction))
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit/shielded/ctf))
|
||||
. = TRUE
|
||||
|
||||
// RED TEAM GUNS
|
||||
@@ -482,7 +500,11 @@
|
||||
|
||||
/obj/item/claymore/ctf/dropped(mob/user)
|
||||
. = ..()
|
||||
addtimer(CALLBACK(GLOBAL_PROC, /proc/ctf_floor_vanish, src), 1)
|
||||
addtimer(CALLBACK(src, .proc/floor_vanish), 1)
|
||||
|
||||
/obj/item/claymore/ctf/proc/floor_vanish()
|
||||
if(isturf(loc))
|
||||
qdel(src)
|
||||
|
||||
/datum/outfit/ctf
|
||||
name = "CTF"
|
||||
@@ -491,27 +513,28 @@
|
||||
suit = /obj/item/clothing/suit/space/hardsuit/shielded/ctf
|
||||
toggle_helmet = FALSE // see the whites of their eyes
|
||||
shoes = /obj/item/clothing/shoes/combat
|
||||
gloves = /obj/item/clothing/gloves/tackler/combat
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
id = /obj/item/card/id/away
|
||||
belt = /obj/item/gun/ballistic/automatic/pistol/deagle/ctf
|
||||
l_pocket = /obj/item/ammo_box/magazine/recharge/ctf
|
||||
r_pocket = /obj/item/ammo_box/magazine/recharge/ctf
|
||||
r_hand = /obj/item/gun/ballistic/automatic/laser/ctf
|
||||
back = /obj/item/claymore/ctf
|
||||
|
||||
/datum/outfit/ctf/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source)
|
||||
/datum/outfit/ctf/post_equip(mob/living/carbon/human/H, visualsOnly=FALSE)
|
||||
if(visualsOnly)
|
||||
return
|
||||
var/list/no_drops = list()
|
||||
var/obj/item/card/id/W = H.wear_id
|
||||
no_drops += W
|
||||
W.registered_name = H.real_name
|
||||
W.update_label(W.registered_name, W.assignment)
|
||||
W.update_label()
|
||||
|
||||
// The shielded hardsuit is already TRAIT_NODROP
|
||||
no_drops += H.get_item_by_slot(SLOT_GLOVES)
|
||||
no_drops += H.get_item_by_slot(SLOT_SHOES)
|
||||
no_drops += H.get_item_by_slot(SLOT_W_UNIFORM)
|
||||
no_drops += H.get_item_by_slot(SLOT_EARS)
|
||||
no_drops += H.get_item_by_slot(ITEM_SLOT_OCLOTHING)
|
||||
no_drops += H.get_item_by_slot(ITEM_SLOT_GLOVES)
|
||||
no_drops += H.get_item_by_slot(ITEM_SLOT_FEET)
|
||||
no_drops += H.get_item_by_slot(ITEM_SLOT_ICLOTHING)
|
||||
no_drops += H.get_item_by_slot(ITEM_SLOT_EARS)
|
||||
for(var/i in no_drops)
|
||||
var/obj/item/I = i
|
||||
ADD_TRAIT(I, TRAIT_NODROP, CAPTURE_THE_FLAG_TRAIT)
|
||||
@@ -525,6 +548,7 @@
|
||||
r_hand = /obj/item/gun/ballistic/automatic/laser/ctf/red
|
||||
l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/red
|
||||
r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/red
|
||||
id = /obj/item/card/id/syndicate_command //it's red
|
||||
|
||||
/datum/outfit/ctf/red/instagib
|
||||
r_hand = /obj/item/gun/energy/laser/instakill/red
|
||||
@@ -535,12 +559,13 @@
|
||||
r_hand = /obj/item/gun/ballistic/automatic/laser/ctf/blue
|
||||
l_pocket = /obj/item/ammo_box/magazine/recharge/ctf/blue
|
||||
r_pocket = /obj/item/ammo_box/magazine/recharge/ctf/blue
|
||||
id = /obj/item/card/id/centcom //it's blue
|
||||
|
||||
/datum/outfit/ctf/blue/instagib
|
||||
r_hand = /obj/item/gun/energy/laser/instakill/blue
|
||||
shoes = /obj/item/clothing/shoes/jackboots/fast
|
||||
|
||||
/datum/outfit/ctf/red/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source)
|
||||
/datum/outfit/ctf/red/post_equip(mob/living/carbon/human/H)
|
||||
..()
|
||||
var/obj/item/radio/R = H.ears
|
||||
R.set_frequency(FREQ_CTF_RED)
|
||||
@@ -548,7 +573,7 @@
|
||||
R.independent = TRUE
|
||||
H.dna.species.stunmod = 0
|
||||
|
||||
/datum/outfit/ctf/blue/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source)
|
||||
/datum/outfit/ctf/blue/post_equip(mob/living/carbon/human/H)
|
||||
..()
|
||||
var/obj/item/radio/R = H.ears
|
||||
R.set_frequency(FREQ_CTF_BLUE)
|
||||
@@ -595,6 +620,10 @@
|
||||
/obj/structure/barricade/security/ctf/make_debris()
|
||||
new /obj/effect/ctf/dead_barricade(get_turf(src))
|
||||
|
||||
/obj/structure/table/reinforced/ctf
|
||||
resistance_flags = INDESTRUCTIBLE
|
||||
flags_1 = NODECONSTRUCT_1
|
||||
|
||||
/obj/effect/ctf
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
@@ -617,10 +646,11 @@
|
||||
QDEL_IN(src, AMMO_DROP_LIFETIME)
|
||||
|
||||
/obj/effect/ctf/ammo/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
reload(AM)
|
||||
|
||||
/obj/effect/ctf/ammo/Bump(atom/movable/AM)
|
||||
reload(AM)
|
||||
/obj/effect/ctf/ammo/Bump(atom/A)
|
||||
reload(A)
|
||||
|
||||
/obj/effect/ctf/ammo/Bumped(atom/movable/AM)
|
||||
reload(AM)
|
||||
@@ -636,7 +666,7 @@
|
||||
qdel(G)
|
||||
O.equip(M)
|
||||
to_chat(M, "<span class='notice'>Ammunition reloaded!</span>")
|
||||
playsound(get_turf(M), 'sound/weapons/shotgunpump.ogg', 50, 1, -1)
|
||||
playsound(get_turf(M), 'sound/weapons/shotgunpump.ogg', 50, TRUE, -1)
|
||||
qdel(src)
|
||||
break
|
||||
|
||||
@@ -667,18 +697,18 @@
|
||||
resistance_flags = INDESTRUCTIBLE
|
||||
var/obj/machinery/capture_the_flag/controlling
|
||||
var/team = "none"
|
||||
var/point_rate = 1
|
||||
var/point_rate = 0.5
|
||||
|
||||
/obj/machinery/control_point/process()
|
||||
/obj/machinery/control_point/process(delta_time)
|
||||
if(controlling)
|
||||
controlling.control_points += point_rate
|
||||
controlling.control_points += point_rate * delta_time
|
||||
if(controlling.control_points >= controlling.control_points_to_win)
|
||||
controlling.victory()
|
||||
|
||||
/obj/machinery/control_point/attackby(mob/user, params)
|
||||
capture(user)
|
||||
|
||||
/obj/machinery/control_point/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
|
||||
/obj/machinery/control_point/on_attack_hand(mob/user)
|
||||
capture(user)
|
||||
|
||||
/obj/machinery/control_point/proc/capture(mob/user)
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
/obj/effect/mob_spawn/Initialize(mapload)
|
||||
. = ..()
|
||||
if(instant || (roundstart && (mapload || (SSticker && SSticker.current_state > GAME_STATE_SETTING_UP))))
|
||||
create()
|
||||
INVOKE_ASYNC(src, .proc/create)
|
||||
else if(ghost_usable)
|
||||
GLOB.poi_list |= src
|
||||
LAZYADD(GLOB.mob_spawners[job_description ? job_description : name], src)
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
/obj/item/dice/d20/fate/proc/effect(var/mob/living/carbon/human/user,roll)
|
||||
if(!reusable)
|
||||
used = 1
|
||||
visible_message("<span class='userdanger'>The die flare briefly.</span>")
|
||||
visible_message("<span class='userdanger'>The die flares briefly.</span>")
|
||||
switch(roll)
|
||||
if(1)
|
||||
//Dust
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
var/triggered = 0
|
||||
|
||||
/obj/effect/meatgrinder/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
Bumped(AM)
|
||||
|
||||
/obj/effect/meatgrinder/Bumped(atom/movable/AM)
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
var/path = "sound/chatter/[phomeme]_[length].ogg"
|
||||
|
||||
playsound(loc, path,
|
||||
vol = 40, vary = 0, extrarange = 3, falloff = FALSE)
|
||||
vol = 40, vary = 0, extrarange = 3)
|
||||
|
||||
sleep((length + 1) * chatter_get_sleep_multiplier(phomeme))
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
var/datum/preferences/prefs = null
|
||||
var/last_turn = 0
|
||||
var/move_delay = 0
|
||||
var/last_move = 0
|
||||
var/area = null
|
||||
|
||||
/// Last time we Click()ed. No clicking twice in one tick!
|
||||
|
||||
@@ -147,6 +147,8 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
|
||||
/client/proc/handle_statpanel_click(list/href_list)
|
||||
var/atom/target = locate(href_list["statpanel_item_target"])
|
||||
if(!target)
|
||||
return
|
||||
Click(target, target.loc, null, "[href_list["statpanel_item_shiftclick"]?"shift=1;":null][href_list["statpanel_item_ctrlclick"]?"ctrl=1;":null]&alt=[href_list["statpanel_item_altclick"]?"alt=1;":null]", FALSE, "statpanel")
|
||||
|
||||
/client/proc/is_content_unlocked()
|
||||
@@ -496,7 +498,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
GLOB.directory -= ckey
|
||||
log_access("Logout: [key_name(src)]")
|
||||
GLOB.ahelp_tickets.ClientLogout(src)
|
||||
// SSserver_maint.UpdateHubStatus()
|
||||
SSserver_maint.UpdateHubStatus()
|
||||
if(credits)
|
||||
QDEL_LIST(credits)
|
||||
if(holder)
|
||||
@@ -642,7 +644,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
query_log_connection.Execute()
|
||||
qdel(query_log_connection)
|
||||
|
||||
// SSserver_maint.UpdateHubStatus()
|
||||
SSserver_maint.UpdateHubStatus()
|
||||
|
||||
if(new_player)
|
||||
player_age = -1
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
/obj/item/clothing/gloves/fingerless/pugilist/equipped(mob/user, slot)
|
||||
. = ..()
|
||||
if(current_equipped_slot == SLOT_GLOVES)
|
||||
if(slot == SLOT_GLOVES)
|
||||
use_buffs(user, TRUE)
|
||||
wornonce = TRUE
|
||||
|
||||
|
||||
@@ -510,12 +510,12 @@ Contains:
|
||||
name = "paramedic EVA suit"
|
||||
icon_state = "paramedic-eva"
|
||||
item_state = "paramedic-eva"
|
||||
desc = "A deep blue space suit decorated with red and white crosses to indicate that the wearer is trained emergency medical personnel."
|
||||
desc = "A deep blue space suit decorated with medical insignia to indicate that the wearer is trained emergency medical personnel."
|
||||
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/roller)
|
||||
|
||||
/obj/item/clothing/head/helmet/space/eva/paramedic
|
||||
name = "paramedic EVA helmet"
|
||||
desc = "A deep blue space helmet with a large red cross on the faceplate to designate the wearer as trained emergency medical personnel."
|
||||
desc = "A deep blue space helmet decorated with medical insignia to designate the wearer as trained emergency medical personnel."
|
||||
icon_state = "paramedic-eva-helmet"
|
||||
item_state = "paramedic-eva-helmet"
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/virologist
|
||||
name = "virologist labcoat"
|
||||
desc = "A suit that protects against minor chemical spills. Offers slightly more protection against biohazards than the standard model. Has a green stripe on the shoulder."
|
||||
desc = "A suit that protects against minor chemical spills. Has a green stripe on the shoulder."
|
||||
icon_state = "labcoat_vir"
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/science
|
||||
@@ -63,6 +63,11 @@
|
||||
desc = "A suit that protects against minor chemical spills. Has a purple stripe on the shoulder."
|
||||
icon_state = "labcoat_tox"
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/roboticist
|
||||
name = "roboticist labcoat"
|
||||
desc = "More like an eccentric coat than a labcoat. Helps pass off bloodstains as part of the aesthetic. Comes with red shoulder pads."
|
||||
icon_state = "labcoat_robo"
|
||||
|
||||
// Departmental Jackets
|
||||
/obj/item/clothing/suit/toggle/labcoat/depjacket
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
|
||||
|
||||
@@ -58,6 +58,12 @@
|
||||
RemoveHood()
|
||||
|
||||
/obj/item/clothing/suit/hooded/proc/ToggleHood()
|
||||
if(!hood)
|
||||
to_chat(loc, "<span class='warning'>[src] seems to be missing its hood..</span>")
|
||||
return
|
||||
if(atom_colours)
|
||||
hood.atom_colours = atom_colours.Copy()
|
||||
hood.update_atom_colour()
|
||||
if(!suittoggled)
|
||||
if(ishuman(src.loc))
|
||||
var/mob/living/carbon/human/H = src.loc
|
||||
@@ -191,7 +197,11 @@
|
||||
if(!helmettype)
|
||||
return
|
||||
if(!helmet)
|
||||
to_chat(H, "<span class='warning'>[src] seems to be missing its helmet..</span>")
|
||||
return
|
||||
if(atom_colours)
|
||||
helmet.atom_colours = atom_colours.Copy()
|
||||
helmet.update_atom_colour()
|
||||
if(!suittoggled)
|
||||
if(ishuman(src.loc))
|
||||
if(H.wear_suit != src)
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
log_admin_private("[key_name(usr)] cancelled event [name].")
|
||||
SSblackbox.record_feedback("tally", "event_admin_cancelled", 1, typepath)
|
||||
|
||||
/datum/round_event_control/proc/runEvent()
|
||||
/datum/round_event_control/proc/runEvent(random = FALSE)
|
||||
var/datum/round_event/E = new typepath()
|
||||
E.current_players = get_active_player_count(alive_check = 1, afk_check = 1, human_check = 1)
|
||||
E.control = src
|
||||
|
||||
@@ -340,6 +340,7 @@
|
||||
playsound(src.loc, 'sound/items/welder.ogg', 100, TRUE)
|
||||
|
||||
/obj/structure/spacevine/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
if(!isliving(AM))
|
||||
return
|
||||
for(var/datum/spacevine_mutation/SM in mutations)
|
||||
|
||||
@@ -99,7 +99,7 @@
|
||||
new reward(get_turf(src))
|
||||
|
||||
/mob/living/carbon/human/dummy/travelling_trader/Initialize()
|
||||
..()
|
||||
. = ..() // return a hint you fuck
|
||||
add_atom_colour("#570d6b", FIXED_COLOUR_PRIORITY) //make them purple (otherworldly!)
|
||||
set_light(1, -0.7, "#AAD84B")
|
||||
ADD_TRAIT(src,TRAIT_PIERCEIMMUNE, "trader_pierce_immune") //don't let people take their blood
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
if(!F.check_variables() && !override_checks)
|
||||
QDEL_NULL(F)
|
||||
if(start_field && (F || override_checks))
|
||||
F.Initialize()
|
||||
F.begin_field()
|
||||
return F
|
||||
|
||||
/datum/proximity_monitor/advanced
|
||||
@@ -78,11 +78,11 @@
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/process_edge_turf(turf/T)
|
||||
|
||||
/datum/proximity_monitor/advanced/New()
|
||||
/datum/proximity_monitor/advanced/New(atom/_host, range, _ignore_if_not_on_turf = TRUE)
|
||||
if(requires_processing)
|
||||
START_PROCESSING(SSfields, src)
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/Initialize()
|
||||
/datum/proximity_monitor/advanced/proc/begin_field()
|
||||
setup_field()
|
||||
post_setup_field()
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
var/atom/_host = host
|
||||
var/atom/new_host_loc = _host.loc
|
||||
if(last_host_loc != new_host_loc)
|
||||
recalculate_field()
|
||||
INVOKE_ASYNC(src, .proc/recalculate_field)
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/post_setup_field()
|
||||
|
||||
@@ -302,7 +302,7 @@
|
||||
|
||||
/obj/item/multitool/field_debug/attack_self(mob/user)
|
||||
operating = !operating
|
||||
to_chat(user, "You turn [src] [operating? "on":"off"].")
|
||||
to_chat(user, "<span class='notice'>You turn [src] [operating? "on":"off"].</span>")
|
||||
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
|
||||
listeningTo = null
|
||||
if(!istype(current) && operating)
|
||||
@@ -312,13 +312,15 @@
|
||||
else if(!operating)
|
||||
QDEL_NULL(current)
|
||||
|
||||
/obj/item/multitool/field_debug/dropped(mob/user)
|
||||
/obj/item/multitool/field_debug/dropped()
|
||||
. = ..()
|
||||
if(listeningTo)
|
||||
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
|
||||
listeningTo = null
|
||||
|
||||
/obj/item/multitool/field_debug/proc/on_mob_move()
|
||||
SIGNAL_HANDLER
|
||||
|
||||
check_turf(get_turf(src))
|
||||
|
||||
/obj/item/multitool/field_debug/process()
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
if(G.summoner && locate(/obj/effect/proc_holder/spell/aoe_turf/timestop) in G.summoner.mind.spell_list) //It would only make sense that a person's stand would also be immune.
|
||||
immune[G] = TRUE
|
||||
if(start)
|
||||
timestop()
|
||||
INVOKE_ASYNC(src, .proc/timestop)
|
||||
|
||||
/obj/effect/timestop/Destroy()
|
||||
qdel(chronofield)
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
/obj/effect/timestop/proc/timestop()
|
||||
target = get_turf(src)
|
||||
playsound(src, 'sound/magic/timeparadox2.ogg', 75, 1, -1)
|
||||
playsound(src, 'sound/magic/timeparadox2.ogg', 75, TRUE, -1)
|
||||
chronofield = make_field(/datum/proximity_monitor/advanced/timestop, list("current_range" = freezerange, "host" = src, "immune" = immune, "check_anti_magic" = check_anti_magic, "check_holy" = check_holy))
|
||||
QDEL_IN(src, duration)
|
||||
|
||||
@@ -112,6 +112,8 @@
|
||||
unfreeze_turf(T)
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_atom(atom/movable/A)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(A.throwing)
|
||||
unfreeze_throwing(A)
|
||||
if(isliving(A))
|
||||
@@ -128,12 +130,14 @@
|
||||
frozen_things -= A
|
||||
global_frozen_atoms -= A
|
||||
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/freeze_mecha(obj/mecha/M)
|
||||
M.completely_disabled = TRUE
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_mecha(obj/mecha/M)
|
||||
M.completely_disabled = FALSE
|
||||
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/freeze_throwing(atom/movable/AM)
|
||||
var/datum/thrownthing/T = AM.throwing
|
||||
T.paused = TRUE
|
||||
@@ -160,7 +164,7 @@
|
||||
/datum/proximity_monitor/advanced/timestop/process()
|
||||
for(var/i in frozen_mobs)
|
||||
var/mob/living/m = i
|
||||
m.Stun(20, 1, 1)
|
||||
m.Stun(20, ignore_canstun = TRUE)
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/setup_field_turf(turf/T)
|
||||
for(var/i in T.contents)
|
||||
@@ -168,6 +172,7 @@
|
||||
freeze_turf(T)
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/freeze_projectile(obj/item/projectile/P)
|
||||
P.paused = TRUE
|
||||
|
||||
@@ -176,18 +181,18 @@
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/freeze_mob(mob/living/L)
|
||||
frozen_mobs += L
|
||||
L.Stun(20, 1, 1)
|
||||
L.Stun(20, ignore_canstun = TRUE)
|
||||
ADD_TRAIT(L, TRAIT_MUTE, TIMESTOP_TRAIT)
|
||||
walk(L, 0) //stops them mid pathing even if they're stunimmune
|
||||
if(isanimal(L))
|
||||
var/mob/living/simple_animal/S = L
|
||||
S.toggle_ai(AI_OFF)
|
||||
if(ishostile(L))
|
||||
var/mob/living/simple_animal/hostile/H = L
|
||||
H.LoseTarget()
|
||||
if(ishostile(L))
|
||||
var/mob/living/simple_animal/hostile/H = L
|
||||
H.LoseTarget()
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_mob(mob/living/L)
|
||||
L.AdjustStun(-20, 1, 1)
|
||||
L.AdjustStun(-20, ignore_canstun = TRUE)
|
||||
REMOVE_TRAIT(L, TRAIT_MUTE, TIMESTOP_TRAIT)
|
||||
frozen_mobs -= L
|
||||
if(isanimal(L))
|
||||
|
||||
@@ -24,11 +24,12 @@
|
||||
desc = "Get off my turf!"
|
||||
|
||||
/obj/effect/abstract/proximity_checker/advanced/field_turf/CanPass(atom/movable/AM, turf/target)
|
||||
. = ..()
|
||||
if(parent)
|
||||
return parent.field_turf_canpass(AM, src, target)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/abstract/proximity_checker/advanced/field_turf/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
if(parent)
|
||||
return parent.field_turf_crossed(AM, src)
|
||||
return TRUE
|
||||
@@ -48,11 +49,12 @@
|
||||
desc = "Edgy description here."
|
||||
|
||||
/obj/effect/abstract/proximity_checker/advanced/field_edge/CanPass(atom/movable/AM, turf/target)
|
||||
. = ..()
|
||||
if(parent)
|
||||
return parent.field_edge_canpass(AM, src, target)
|
||||
return TRUE
|
||||
|
||||
/obj/effect/abstract/proximity_checker/advanced/field_edge/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
if(parent)
|
||||
return parent.field_edge_crossed(AM, src)
|
||||
return TRUE
|
||||
|
||||
@@ -139,10 +139,11 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
Show()
|
||||
|
||||
/obj/effect/hallucination/simple/Moved(atom/OldLoc, Dir)
|
||||
. = ..()
|
||||
Show()
|
||||
|
||||
/obj/effect/hallucination/simple/Destroy()
|
||||
if(target && target.client)
|
||||
if(target?.client)
|
||||
target.client.images.Remove(current_image)
|
||||
active = FALSE
|
||||
return ..()
|
||||
@@ -1093,6 +1094,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
|
||||
target.client.images += image
|
||||
|
||||
/obj/effect/hallucination/danger/lava/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
if(AM == target)
|
||||
target.adjustStaminaLoss(20)
|
||||
new /datum/hallucination/fire(target)
|
||||
|
||||
@@ -596,7 +596,7 @@
|
||||
name = "Buzz Fuzz"
|
||||
desc = "The sister drink of Shambler's Juice! Uses real honey, making it a sweet tooth's dream drink. The slogan reads ''A Hive of Flavour'', there's also a label about how it is adddicting."
|
||||
icon_state = "honeysoda_can"
|
||||
list_reagents = list(/datum/reagent/consumable/buzz_fuzz = 25, /datum/reagent/consumable/honey = 5)
|
||||
list_reagents = list(/datum/reagent/consumable/buzz_fuzz = 30)
|
||||
foodtype = SUGAR | JUNKFOOD
|
||||
|
||||
/obj/item/reagent_containers/food/drinks/soda_cans/grey_bull
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
/obj/item/weldingtool = 3,
|
||||
/obj/item/wirecutters = 2,
|
||||
/obj/item/wrench = 4,
|
||||
/obj/item/weaponcrafting/improvised_parts/shotgun_receiver = 1,
|
||||
/obj/item/weaponcrafting/receiver = 1,
|
||||
/obj/item/geiger_counter = 3,
|
||||
/obj/item/reagent_containers/food/snacks/grown/citrus/orange = 5,
|
||||
/obj/item/assembly/infra = 1,
|
||||
|
||||
@@ -50,16 +50,18 @@
|
||||
var/cached_z
|
||||
/// I'm busy, don't move.
|
||||
var/busy = FALSE
|
||||
|
||||
var/static/blacklisted_items = typecacheof(list(
|
||||
/obj/effect,
|
||||
/obj/belly,
|
||||
/obj/mafia_game_board,
|
||||
/obj/docking_port,
|
||||
/obj/shapeshift_holder,
|
||||
/obj/screen))
|
||||
/obj/effect,
|
||||
/obj/belly,
|
||||
/obj/mafia_game_board,
|
||||
/obj/docking_port,
|
||||
/obj/shapeshift_holder,
|
||||
/obj/screen
|
||||
))
|
||||
|
||||
/mob/living/simple_animal/jacq/Initialize()
|
||||
..()
|
||||
. = ..() //fuck you jacq, return a hint you shit
|
||||
cached_z = z
|
||||
poof()
|
||||
|
||||
@@ -158,23 +160,18 @@
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/jacq/proc/gender_check(mob/living/carbon/C)
|
||||
var/gender = "lamb"
|
||||
if(C)
|
||||
if(C.gender == MALE)
|
||||
gender = "laddie"
|
||||
if(C.gender == FEMALE)
|
||||
gender = "lassie"
|
||||
return gender
|
||||
. = "lamb"
|
||||
switch(C)
|
||||
if(MALE)
|
||||
. = "laddie"
|
||||
if(FEMALE)
|
||||
. = "lassie"
|
||||
|
||||
//Ye wee bugger, gerrout of it. Ye've nae tae enjoy reading the code fer mae secrets like.
|
||||
/mob/living/simple_animal/jacq/proc/chit_chat(mob/living/carbon/C)
|
||||
//Very important
|
||||
var/gender = gender_check(C)
|
||||
if(C)
|
||||
if(C.gender == MALE)
|
||||
gender = "laddie"
|
||||
if(C.gender == FEMALE)
|
||||
gender = "lassie"
|
||||
// it physicaly cannot fail*. Why is there a fucking dupe
|
||||
|
||||
if(!progression["[C.real_name]"] || !(progression["[C.real_name]"] & JACQ_HELLO))
|
||||
visible_message("<b>[src]</b> smiles ominously at [C], <span class='spooky'>\"Well halo there [gender]! Ah'm Jacqueline, tae great Pumpqueen, great tae meet ye.\"</span>")
|
||||
|
||||
@@ -82,5 +82,5 @@
|
||||
var/sound/music_played = sound(soundfile)
|
||||
for(var/i in hearing_mobs)
|
||||
var/mob/M = i
|
||||
M.playsound_local(source, null, volume * using_instrument.volume_multiplier, falloff = 5, S = music_played)
|
||||
M.playsound_local(source, null, volume * using_instrument.volume_multiplier, S = music_played)
|
||||
// Could do environment and echo later but not for now
|
||||
|
||||
@@ -578,6 +578,7 @@
|
||||
return FALSE
|
||||
|
||||
/obj/item/electronic_assembly/Moved(oldLoc, dir)
|
||||
. = ..()
|
||||
for(var/I in assembly_components)
|
||||
var/obj/item/integrated_circuit/IC = I
|
||||
IC.ext_moved(oldLoc, dir)
|
||||
|
||||
@@ -187,7 +187,7 @@
|
||||
/datum/job/proc/announce_head(var/mob/living/carbon/human/H, var/channels) //tells the given channel that the given mob is the new department head. See communications.dm for valid channels.
|
||||
if(H && GLOB.announcement_systems.len)
|
||||
//timer because these should come after the captain announcement
|
||||
SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, .proc/addtimer, CALLBACK(pick(GLOB.announcement_systems), /obj/machinery/announcement_system/proc/announce, "NEWHEAD", H.real_name, H.job, channels), 1))
|
||||
SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, .proc/_addtimer, CALLBACK(pick(GLOB.announcement_systems), /obj/machinery/announcement_system/proc/announce, "NEWHEAD", H.real_name, H.job, channels), 1))
|
||||
|
||||
//If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1
|
||||
/datum/job/proc/player_old_enough(client/C)
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
l_pocket = /obj/item/pda/roboticist
|
||||
ears = /obj/item/radio/headset/headset_sci
|
||||
uniform = /obj/item/clothing/under/rank/rnd/roboticist
|
||||
suit = /obj/item/clothing/suit/toggle/labcoat
|
||||
suit = /obj/item/clothing/suit/toggle/labcoat/roboticist
|
||||
|
||||
backpack = /obj/item/storage/backpack/science
|
||||
satchel = /obj/item/storage/backpack/satchel/tox
|
||||
|
||||
@@ -135,7 +135,7 @@
|
||||
var/curr_z = text2num(dmmRegex.group[5])
|
||||
if(curr_z < z_lower || curr_z > z_upper)
|
||||
continue
|
||||
|
||||
|
||||
var/curr_x = text2num(dmmRegex.group[3])
|
||||
var/curr_y = text2num(dmmRegex.group[4])
|
||||
|
||||
@@ -171,7 +171,7 @@
|
||||
if(width > right_width)
|
||||
for(var/i in 1 to lines)
|
||||
gridLines[i] = copytext(gridLines[i], 1, key_len * right_width)
|
||||
|
||||
|
||||
// during the actual load we're starting at the top and working our way down
|
||||
gridSet.ycrd += lines - 1
|
||||
|
||||
@@ -300,14 +300,14 @@
|
||||
//we do this after we load everything in. if we don't; we'll have weird atmos bugs regarding atmos adjacent turfs
|
||||
T.AfterChange(CHANGETURF_IGNORE_AIR)
|
||||
|
||||
if(did_expand)
|
||||
world.refresh_atmos_grid()
|
||||
|
||||
#ifdef TESTING
|
||||
if(turfsSkipped)
|
||||
testing("Skipped loading [turfsSkipped] default turfs")
|
||||
#endif
|
||||
|
||||
if(did_expand)
|
||||
world.refresh_atmos_grid()
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/parsed_map/proc/build_cache(no_changeturf, bad_paths=null)
|
||||
|
||||
@@ -1104,7 +1104,7 @@
|
||||
if(1)
|
||||
new /obj/item/mayhem(src)
|
||||
if(2)
|
||||
new /obj/item/gun/ballistic/revolver/doublebarrel/super(src)
|
||||
new /obj/item/book/granter/spell/asura(src)
|
||||
if(3)
|
||||
new /obj/item/guardiancreator(src)
|
||||
|
||||
@@ -1187,6 +1187,13 @@
|
||||
unique_reskin = null
|
||||
sawn_off = TRUE
|
||||
|
||||
/obj/item/book/granter/spell/asura
|
||||
spell = /obj/effect/proc_holder/spell/self/asura
|
||||
spellname = "asuras wrath"
|
||||
icon_state = "bookasura"
|
||||
desc = "This crimson novel emanates rage incarnate."
|
||||
remarks = list("Kaio-What?", "It can only be sustained for a short time...", "It's like a massive upsurge of energy...", "Takes a heavy toll on the user's body...?", "Extra arms not included...", "There's stronger levels? Why aren't they in the book...")
|
||||
|
||||
//Colossus
|
||||
/obj/structure/closet/crate/necropolis/colossus
|
||||
name = "colossus chest"
|
||||
|
||||
@@ -8,6 +8,7 @@ INITIALIZE_IMMEDIATE(/mob/dead)
|
||||
throwforce = 0
|
||||
|
||||
/mob/dead/Initialize()
|
||||
SHOULD_CALL_PARENT(FALSE)
|
||||
if(flags_1 & INITIALIZED_1)
|
||||
stack_trace("Warning: [src]([type]) initialized multiple times!")
|
||||
flags_1 |= INITIALIZED_1
|
||||
@@ -68,14 +69,15 @@ INITIALIZE_IMMEDIATE(/mob/dead)
|
||||
set desc= "Jump to the other server"
|
||||
if(mob_transforming)
|
||||
return
|
||||
var/list/csa = CONFIG_GET(keyed_list/cross_server)
|
||||
var/list/our_id = CONFIG_GET(string/cross_comms_name)
|
||||
var/list/csa = CONFIG_GET(keyed_list/cross_server) - our_id
|
||||
var/pick
|
||||
switch(csa.len)
|
||||
if(0)
|
||||
remove_verb(src, /mob/dead/proc/server_hop)
|
||||
to_chat(src, "<span class='notice'>Server Hop has been disabled.</span>")
|
||||
if(1)
|
||||
pick = csa[0]
|
||||
pick = csa[1]
|
||||
else
|
||||
pick = input(src, "Pick a server to jump to", "Server Hop") as null|anything in csa
|
||||
|
||||
@@ -100,7 +102,7 @@ INITIALIZE_IMMEDIATE(/mob/dead)
|
||||
|
||||
winset(src, null, "command=.options") //other wise the user never knows if byond is downloading resources
|
||||
|
||||
C << link("[addr]?server_hop=[key]")
|
||||
C << link("[addr]")
|
||||
|
||||
/mob/dead/proc/update_z(new_z) // 1+ to register, null to unregister
|
||||
if (registered_z != new_z)
|
||||
|
||||
@@ -243,6 +243,10 @@
|
||||
icon_state = "none"
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/brown
|
||||
name = "Brown"
|
||||
icon_state = "brown"
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/punished
|
||||
name = "Burnt Off"
|
||||
icon_state = "punished"
|
||||
@@ -271,6 +275,10 @@
|
||||
name = "Deathshead"
|
||||
icon_state = "deathhead"
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/featherymoth
|
||||
name = "Feathery Moth"
|
||||
icon_state = "featherymoth"
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/firewatch
|
||||
name = "Firewatch"
|
||||
icon_state = "firewatch"
|
||||
@@ -291,18 +299,22 @@
|
||||
name = "Moon Fly"
|
||||
icon_state = "moonfly"
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/oakworm
|
||||
name = "Oak Worm"
|
||||
icon_state = "oakworm"
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/plain
|
||||
name = "Plain"
|
||||
icon_state = "plain"
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/plasmafire
|
||||
name = "Plasma Fire"
|
||||
icon_state = "plasmafire"
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/poison
|
||||
name = "Poison"
|
||||
icon_state = "poison"
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/oakworm
|
||||
name = "Oak Worm"
|
||||
icon_state = "oakworm"
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/ragged
|
||||
name = "Ragged"
|
||||
icon_state = "ragged"
|
||||
@@ -311,6 +323,10 @@
|
||||
name = "Reddish"
|
||||
icon_state = "redish"
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/rosy
|
||||
name = "Rosy"
|
||||
icon_state = "rosy"
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/royal
|
||||
name = "Royal"
|
||||
icon_state = "royal"
|
||||
|
||||
@@ -58,9 +58,7 @@
|
||||
dimension_y = 34
|
||||
relevant_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
/datum/sprite_accessory/deco_wings/atlas
|
||||
name = "Atlas"
|
||||
icon_state = "atlas"
|
||||
//nonmoth wings
|
||||
|
||||
/datum/sprite_accessory/deco_wings/bat
|
||||
name = "Bat"
|
||||
@@ -70,18 +68,76 @@
|
||||
name = "Bee"
|
||||
icon_state = "bee"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/deathhead
|
||||
name = "Deathshead"
|
||||
icon_state = "deathhead"
|
||||
/datum/sprite_accessory/deco_wings/bee2
|
||||
name = "Small Bee"
|
||||
icon_state = "beewings"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/dragon
|
||||
name = "Dragon"
|
||||
icon_state = "dragon"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/dragonfly
|
||||
name = "Dragonfly"
|
||||
icon_state = "dragonfly"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/fairy
|
||||
name = "Fairy"
|
||||
icon_state = "fairy"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/feathery
|
||||
/datum/sprite_accessory/deco_wings/featheredwing
|
||||
name = "Feathery"
|
||||
icon_state = "feathery"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/featheredwingmedium
|
||||
name = "Medium Feathered"
|
||||
icon_state = "feathered3"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/featheredwinglarge
|
||||
name = "Large Feathered"
|
||||
icon_state = "feathered2"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/harpywings
|
||||
name = "Harpy"
|
||||
icon_state = "harpywings"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/roboticwing
|
||||
name = "Robotic"
|
||||
icon_state = "drago"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/succubusblack
|
||||
name = "Succubus Black"
|
||||
icon_state = "succubusblack"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/succubuspurple
|
||||
name = "Succubus Purple"
|
||||
icon_state = "succubuspurple"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/succubusred
|
||||
name = "Succubus Red"
|
||||
icon_state = "succubusred"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/xenobackplate
|
||||
name = "Xenomorph Backplate"
|
||||
icon_state = "snagbackplate"
|
||||
|
||||
//moth wings
|
||||
|
||||
/datum/sprite_accessory/deco_wings/atlas
|
||||
name = "Atlas"
|
||||
icon_state = "atlas"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/brown
|
||||
name = "Brown"
|
||||
icon_state = "brown"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/deathhead
|
||||
name = "Deathshead"
|
||||
icon_state = "deathhead"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/featherymoth
|
||||
name = "Feathery Moth Wings"
|
||||
icon_state = "featherymoth"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/firewatch
|
||||
name = "Firewatch"
|
||||
icon_state = "firewatch"
|
||||
@@ -90,6 +146,10 @@
|
||||
name = "Gothic"
|
||||
icon_state = "gothic"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/jungle
|
||||
name = "Jungle"
|
||||
icon_state = "jungle"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/lovers
|
||||
name = "Lovers"
|
||||
icon_state = "lovers"
|
||||
@@ -106,10 +166,18 @@
|
||||
name = "Moon Fly"
|
||||
icon_state = "moonfly"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/oakworm
|
||||
name = "Oak Worm"
|
||||
icon_state = "oakworm"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/plain
|
||||
name = "Plain"
|
||||
icon_state = "plain"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/plasmafire
|
||||
name = "Plasma Fire"
|
||||
icon_state = "plasmafire"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/poison
|
||||
name = "Poison"
|
||||
icon_state = "poison"
|
||||
@@ -126,6 +194,10 @@
|
||||
name = "Reddish"
|
||||
icon_state = "redish"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/rosy
|
||||
name = "Rosy"
|
||||
icon_state = "rosy"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/royal
|
||||
name = "Royal"
|
||||
icon_state = "royal"
|
||||
@@ -138,18 +210,10 @@
|
||||
name = "White Fly"
|
||||
icon_state = "whitefly"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/oakworm
|
||||
name = "Oak Worm"
|
||||
icon_state = "oakworm"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/witchwing
|
||||
name = "Witch Wing"
|
||||
icon_state = "witchwing"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/jungle
|
||||
name = "Jungle"
|
||||
icon_state = "jungle"
|
||||
|
||||
//INSECT WINGS
|
||||
|
||||
/datum/sprite_accessory/insect_wings
|
||||
@@ -157,6 +221,69 @@
|
||||
color_src = WINGCOLOR
|
||||
relevant_layers = list(BODY_BEHIND_LAYER, BODY_FRONT_LAYER)
|
||||
|
||||
//non insect wings
|
||||
/datum/sprite_accessory/deco_wings/bat
|
||||
name = "Bat"
|
||||
icon_state = "bat"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/bee
|
||||
name = "Bee"
|
||||
icon_state = "bee"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/bee2
|
||||
name = "Small Bee"
|
||||
icon_state = "beewings"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/dragon
|
||||
name = "Dragon"
|
||||
icon_state = "dragon"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/dragonfly
|
||||
name = "Dragonfly"
|
||||
icon_state = "dragonfly"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/fairy
|
||||
name = "Fairy"
|
||||
icon_state = "fairy"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/featheredwing
|
||||
name = "Feathery"
|
||||
icon_state = "feathery"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/featheredwingmedium
|
||||
name = "Medium Feathered"
|
||||
icon_state = "feathered3"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/featheredwinglarge
|
||||
name = "Large Feathered"
|
||||
icon_state = "feathered2"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/harpywings
|
||||
name = "Harpy"
|
||||
icon_state = "harpywings"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/roboticwing
|
||||
name = "Robotic"
|
||||
icon_state = "drago"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/succubusblack
|
||||
name = "Succubus Black"
|
||||
icon_state = "succubusblack"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/succubuspurple
|
||||
name = "Succubus Purple"
|
||||
icon_state = "succubuspurple"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/succubusred
|
||||
name = "Succubus Red"
|
||||
icon_state = "succubusred"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/xenobackplate
|
||||
name = "Xenomorph Backplate"
|
||||
icon_state = "snagbackplate"
|
||||
|
||||
//moth wings
|
||||
|
||||
/datum/sprite_accessory/insect_wings/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
@@ -166,25 +293,17 @@
|
||||
name = "Atlas"
|
||||
icon_state = "atlas"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/bat
|
||||
name = "Bat"
|
||||
icon_state = "bat"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/bee
|
||||
name = "Bee"
|
||||
icon_state = "bee"
|
||||
/datum/sprite_accessory/insect_wings/brown
|
||||
name = "Brown"
|
||||
icon_state = "brown"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/deathhead
|
||||
name = "Deathshead"
|
||||
icon_state = "deathhead"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/fairy
|
||||
name = "Fairy"
|
||||
icon_state = "fairy"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/feathery
|
||||
name = "Feathery"
|
||||
icon_state = "feathery"
|
||||
/datum/sprite_accessory/insect_wings/featherymoth
|
||||
name = "Feathery Moth Wings"
|
||||
icon_state = "featherymoth"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/firewatch
|
||||
name = "Firewatch"
|
||||
@@ -222,6 +341,10 @@
|
||||
name = "Plain"
|
||||
icon_state = "plain"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/plasmafire
|
||||
name = "Plasma Fire"
|
||||
icon_state = "plasmafire"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/poison
|
||||
name = "Poison"
|
||||
icon_state = "poison"
|
||||
@@ -238,6 +361,10 @@
|
||||
name = "Reddish"
|
||||
icon_state = "redish"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/rosy
|
||||
name = "Rosy"
|
||||
icon_state = "rosy"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/royal
|
||||
name = "Royal"
|
||||
icon_state = "royal"
|
||||
@@ -265,45 +392,25 @@
|
||||
icon_state = "none"
|
||||
relevant_layers = null
|
||||
|
||||
/datum/sprite_accessory/insect_markings/reddish
|
||||
name = "Reddish"
|
||||
icon_state = "reddish"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/royal
|
||||
name = "Royal"
|
||||
icon_state = "royal"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/gothic
|
||||
name = "Gothic"
|
||||
icon_state = "gothic"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/whitefly
|
||||
name = "White Fly"
|
||||
icon_state = "whitefly"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/lovers
|
||||
name = "Lovers"
|
||||
icon_state = "lovers"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/punished
|
||||
name = "Punished"
|
||||
icon_state = "punished"
|
||||
/datum/sprite_accessory/insect_markings/deathhead
|
||||
name = "Deathshead"
|
||||
icon_state = "deathhead"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/firewatch
|
||||
name = "Firewatch"
|
||||
icon_state = "firewatch"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/deathhead
|
||||
name = "Deathshead"
|
||||
icon_state = "deathhead"
|
||||
/datum/sprite_accessory/insect_markings/gothic
|
||||
name = "Gothic"
|
||||
icon_state = "gothic"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/poison
|
||||
name = "Poison"
|
||||
icon_state = "poison"
|
||||
/datum/sprite_accessory/insect_markings/jungle
|
||||
name = "Jungle"
|
||||
icon_state = "jungle"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/ragged
|
||||
name = "Ragged"
|
||||
icon_state = "ragged"
|
||||
/datum/sprite_accessory/insect_markings/lovers
|
||||
name = "Lovers"
|
||||
icon_state = "lovers"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/moonfly
|
||||
name = "Moon Fly"
|
||||
@@ -313,10 +420,42 @@
|
||||
name = "Oak Worm"
|
||||
icon_state = "oakworm"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/jungle
|
||||
name = "Jungle"
|
||||
icon_state = "jungle"
|
||||
/datum/sprite_accessory/insect_markings/poison
|
||||
name = "Poison"
|
||||
icon_state = "poison"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/punished
|
||||
name = "Punished"
|
||||
icon_state = "punished"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/ragged
|
||||
name = "Ragged"
|
||||
icon_state = "ragged"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/reddish
|
||||
name = "Reddish"
|
||||
icon_state = "reddish"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/royal
|
||||
name = "Royal"
|
||||
icon_state = "royal"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/whitefly
|
||||
name = "White Fly"
|
||||
icon_state = "whitefly"
|
||||
|
||||
/datum/sprite_accessory/insect_markings/witchwing
|
||||
name = "Witch Wing"
|
||||
icon_state = "witchwing"
|
||||
|
||||
//DONATOR WINGS
|
||||
|
||||
/datum/sprite_accessory/deco_wings/eyestalks
|
||||
name = "gazer eyestalks"
|
||||
icon_state = "eyestalks"
|
||||
//ckeys_allowed = list("liquidfirefly","seiga") //At request.
|
||||
|
||||
/datum/sprite_accessory/insect_wings/eyestalks
|
||||
name = "gazer eyestalks"
|
||||
icon_state = "eyestalks"
|
||||
//ckeys_allowed = list("liquidfirefly","seiga") //At request.
|
||||
|
||||
@@ -91,8 +91,8 @@
|
||||
Attach(M)
|
||||
|
||||
/obj/item/clothing/mask/facehugger/Crossed(atom/target)
|
||||
. = ..()
|
||||
HasProximity(target)
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/on_found(mob/finder)
|
||||
if(stat == CONSCIOUS)
|
||||
|
||||
@@ -304,10 +304,16 @@
|
||||
emote("wag")
|
||||
|
||||
else if(check_zone(M.zone_selected) == BODY_ZONE_R_ARM || check_zone(M.zone_selected) == BODY_ZONE_L_ARM)
|
||||
M.visible_message( \
|
||||
"<span class='notice'>[M] shakes [src]'s hand.</span>", \
|
||||
"<span class='notice'>You shake [src]'s hand.</span>", target = src,
|
||||
target_message = "<span class='notice'>[M] shakes your hand.</span>")
|
||||
if((pulling == M) && (grab_state == GRAB_PASSIVE))
|
||||
M.visible_message( \
|
||||
"<span class='notice'>[M] squeezes [src]'s hand.</span>", \
|
||||
"<span class='notice'>You squeeze [src]'s hand.</span>", target = src,
|
||||
target_message = "<span class='notice'>[M] squeezes your hand.</span>")
|
||||
else
|
||||
M.visible_message( \
|
||||
"<span class='notice'>[M] shakes [src]'s hand.</span>", \
|
||||
"<span class='notice'>You shake [src]'s hand.</span>", target = src,
|
||||
target_message = "<span class='notice'>[M] shakes your hand.</span>")
|
||||
|
||||
else
|
||||
M.visible_message("<span class='notice'>[M] hugs [src] to make [p_them()] feel better!</span>", \
|
||||
|
||||
@@ -62,8 +62,8 @@
|
||||
amount += BP.burn_dam
|
||||
return amount
|
||||
|
||||
|
||||
/mob/living/carbon/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
//In both these procs, only_organic / only_robotic are only used for healing, not for damaging. For now at least.
|
||||
/mob/living/carbon/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE, only_robotic = FALSE, only_organic = TRUE)
|
||||
if(!forced && amount < 0 && HAS_TRAIT(src,TRAIT_NONATURALHEAL))
|
||||
return FALSE
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
@@ -71,10 +71,10 @@
|
||||
if(amount > 0)
|
||||
take_overall_damage(amount, 0, 0, updating_health)
|
||||
else
|
||||
heal_overall_damage(abs(amount), 0, 0, FALSE, TRUE, updating_health)
|
||||
heal_overall_damage(abs(amount), 0, 0, only_robotic, only_organic, updating_health)
|
||||
return amount
|
||||
|
||||
/mob/living/carbon/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
/mob/living/carbon/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE, only_robotic = FALSE, only_organic = TRUE)
|
||||
if(!forced && amount < 0 && HAS_TRAIT(src,TRAIT_NONATURALHEAL)) //Vamps don't heal naturally.
|
||||
return FALSE
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
@@ -82,7 +82,7 @@
|
||||
if(amount > 0)
|
||||
take_overall_damage(0, amount, 0, updating_health)
|
||||
else
|
||||
heal_overall_damage(0, abs(amount), 0, FALSE, TRUE, updating_health)
|
||||
heal_overall_damage(0, abs(amount), 0, only_robotic, only_organic, updating_health)
|
||||
return amount
|
||||
|
||||
|
||||
|
||||
@@ -80,10 +80,11 @@
|
||||
if("shortlimbdisable")
|
||||
var/disabled_type = pick(list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_R_ARM, TRAIT_PARALYSIS_L_LEG, TRAIT_PARALYSIS_R_LEG))
|
||||
ADD_TRAIT(src, disabled_type, CORRUPTED_SYSTEM)
|
||||
update_disabled_bodyparts()
|
||||
addtimer(CALLBACK(src, .proc/reenable_limb, disabled_type), 5 SECONDS)
|
||||
to_chat(src, "<span class='warning'>Error - Limb control subsystem partially shutdown, rebooting.</span>")
|
||||
if("shortblind")
|
||||
ADD_TRAIT(src, TRAIT_BLIND, CORRUPTED_SYSTEM)
|
||||
become_blind(CORRUPTED_SYSTEM)
|
||||
addtimer(CALLBACK(src, .proc/reenable_vision), 5 SECONDS)
|
||||
to_chat(src, "<span class='warning'>Visual receptor shutdown detected - Initiating reboot.</span>")
|
||||
if("shortstun")
|
||||
@@ -105,10 +106,11 @@
|
||||
if("longlimbdisable")
|
||||
var/disabled_type = pick(list(TRAIT_PARALYSIS_L_ARM, TRAIT_PARALYSIS_R_ARM, TRAIT_PARALYSIS_L_LEG, TRAIT_PARALYSIS_R_LEG))
|
||||
ADD_TRAIT(src, disabled_type, CORRUPTED_SYSTEM)
|
||||
update_disabled_bodyparts()
|
||||
addtimer(CALLBACK(src, .proc/reenable_limb, disabled_type), 25 SECONDS)
|
||||
to_chat(src, "<span class='warning'>Fatal error in limb control subsystem - rebooting.</span>")
|
||||
if("blindmutedeaf")
|
||||
ADD_TRAIT(src, TRAIT_BLIND, CORRUPTED_SYSTEM)
|
||||
become_blind(CORRUPTED_SYSTEM)
|
||||
addtimer(CALLBACK(src, .proc/reenable_vision), (rand(10, 25)) SECONDS)
|
||||
ADD_TRAIT(src, TRAIT_DEAF, CORRUPTED_SYSTEM)
|
||||
addtimer(CALLBACK(src, .proc/reenable_hearing), (rand(15, 35)) SECONDS)
|
||||
@@ -140,6 +142,7 @@
|
||||
|
||||
/mob/living/carbon/proc/reenable_limb(disabled_limb)
|
||||
REMOVE_TRAIT(src, disabled_limb, CORRUPTED_SYSTEM)
|
||||
update_disabled_bodyparts()
|
||||
to_chat(src, "<span class='notice'>Limb control subsystem successfully rebooted.</span>")
|
||||
|
||||
/mob/living/carbon/proc/reenable_hearing()
|
||||
@@ -147,7 +150,7 @@
|
||||
to_chat(src, "<span class='notice'>Hearing restored.</span>")
|
||||
|
||||
/mob/living/carbon/proc/reenable_vision()
|
||||
REMOVE_TRAIT(src, TRAIT_BLIND, CORRUPTED_SYSTEM)
|
||||
cure_blind(CORRUPTED_SYSTEM)
|
||||
to_chat(src, "<span class='notice'>Visual receptors back online.</span>")
|
||||
|
||||
/mob/living/carbon/proc/reenable_speech()
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
real_name = "Unknown"
|
||||
icon = 'icons/mob/human.dmi'
|
||||
icon_state = "caucasian_m"
|
||||
appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE
|
||||
SET_APPEARANCE_FLAGS(KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE)
|
||||
|
||||
/mob/living/carbon/human/Initialize()
|
||||
add_verb(src, /mob/living/proc/mob_sleep)
|
||||
@@ -1028,7 +1028,7 @@
|
||||
return
|
||||
|
||||
stop_pulling()
|
||||
riding_datum.handle_vehicle_layer()
|
||||
riding_datum.handle_vehicle_layer(dir)
|
||||
riding_datum.fireman_carrying = fireman
|
||||
. = ..(target, force, check_loc)
|
||||
|
||||
|
||||
@@ -411,15 +411,18 @@
|
||||
if(isrobotic(src))
|
||||
apply_status_effect(/datum/status_effect/no_combat_mode/robotic_emp, severity / 20)
|
||||
severity *= 0.5
|
||||
var/do_not_stun = FALSE
|
||||
if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
|
||||
severity *= 0.5 //Robotpeople take less limb damage, but instead suffer system corruption (see carbon emp_act)
|
||||
do_not_stun = TRUE
|
||||
for(var/obj/item/bodypart/L in src.bodyparts)
|
||||
if(L.is_robotic_limb())
|
||||
if(!informed)
|
||||
to_chat(src, "<span class='userdanger'>You feel a sharp pain as your robotic limbs overload.</span>")
|
||||
informed = TRUE
|
||||
L.receive_damage(0,severity/10)
|
||||
Stun(severity*2)
|
||||
if(!do_not_stun) //Tiny bit better than checking for the trait another six times in succession
|
||||
Stun(severity*2)
|
||||
|
||||
/mob/living/carbon/human/acid_act(acidpwr, acid_volume, bodyzone_hit)
|
||||
var/list/damaged = list()
|
||||
|
||||
@@ -9,11 +9,6 @@
|
||||
return
|
||||
return considering
|
||||
|
||||
/mob/living/carbon/human/movement_delay()
|
||||
. = ..()
|
||||
if (m_intent == MOVE_INTENT_WALK && HAS_TRAIT(src, TRAIT_SPEEDY_STEP))
|
||||
. -= 1.5
|
||||
|
||||
/mob/living/carbon/human/slip(knockdown_amount, obj/O, lube)
|
||||
if(HAS_TRAIT(src, TRAIT_NOSLIPALL))
|
||||
return 0
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
override_bp_icon = 'icons/mob/arachnid_parts.dmi'
|
||||
say_mod = "chitters"
|
||||
default_color = "00FF00"
|
||||
species_traits = list(LIPS, NOEYES, NO_UNDERWEAR)
|
||||
species_traits = list(LIPS, NOEYES, NO_UNDERWEAR, HAS_FLESH, HAS_BONE)
|
||||
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG
|
||||
mutant_bodyparts = list("arachnid_legs" = "Plain", "arachnid_spinneret" = "Plain", "arachnid_mandibles" = "Plain")
|
||||
attack_verb = "slash"
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
name = "Xenobiological Slime Entity"
|
||||
id = SPECIES_SLIME
|
||||
default_color = "00FFFF"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,HAS_FLESH)
|
||||
say_mod = "says"
|
||||
hair_color = "mutcolor"
|
||||
hair_alpha = 150
|
||||
@@ -404,7 +404,7 @@
|
||||
id = SPECIES_SLIME_HYBRID
|
||||
limbs_id = SPECIES_SLIME
|
||||
default_color = "00FFFF"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,HAS_FLESH)
|
||||
inherent_traits = list(TRAIT_TOXINLOVER)
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF", "mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None", "legs" = "Plantigrade")
|
||||
say_mod = "says"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
id = SPECIES_LIZARD
|
||||
say_mod = "hisses"
|
||||
default_color = "00FF00"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR,WINGCOLOR,HAS_FLESH,HAS_BONE)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR,WINGCOLOR,CAN_SCAR,HAS_FLESH,HAS_BONE)
|
||||
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_REPTILE
|
||||
mutanttongue = /obj/item/organ/tongue/lizard
|
||||
mutanttail = /obj/item/organ/tail/lizard
|
||||
@@ -48,7 +48,7 @@
|
||||
name = "Ash Walker"
|
||||
id = SPECIES_ASHWALKER
|
||||
limbs_id = SPECIES_LIZARD
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,DIGITIGRADE)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,DIGITIGRADE,CAN_SCAR,HAS_FLESH,HAS_BONE)
|
||||
inherent_traits = list(TRAIT_CHUNKYFINGERS)
|
||||
mutantlungs = /obj/item/organ/lungs/ashwalker
|
||||
mutanteyes = /obj/item/organ/eyes/night_vision
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
/datum/species/pod/pseudo_weak
|
||||
name = "Anthromorphic Plant"
|
||||
id = SPECIES_POD_WEAK
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS)
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS,CAN_SCAR,HAS_FLESH,HAS_BONE)
|
||||
mutant_bodyparts = list("mcolor" = "FFFFFF","mcolor2" = "FFFFFF","mcolor3" = "FFFFFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "mam_body_markings" = "Husky", "taur" = "None", "legs" = "Normal Legs")
|
||||
limbs_id = SPECIES_POD
|
||||
light_nutrition_gain_factor = 3
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
id = SPECIES_XENOHYBRID
|
||||
say_mod = "hisses"
|
||||
default_color = "00FF00"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,CAN_SCAR)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,CAN_SCAR,HAS_FLESH,HAS_BONE)
|
||||
mutant_bodyparts = list("xenotail"="Xenomorph Tail","xenohead"="Standard","xenodorsal"="Standard", "mam_body_markings" = "Xeno","mcolor" = "0F0","mcolor2" = "0F0","mcolor3" = "0F0","taur" = "None", "legs" = "Digitigrade","deco_wings"= "None")
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
|
||||
@@ -594,10 +594,18 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
drunkenness = max(drunkenness - (drunkenness * 0.04), 0)
|
||||
if(drunkenness >= 6)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "drunk", /datum/mood_event/drunk)
|
||||
if(prob(25))
|
||||
slurring += 2
|
||||
jitteriness = max(jitteriness - 3, 0)
|
||||
// throw_alert("drunk", /atom/movable/screen/alert/drunk)
|
||||
if(HAS_TRAIT(src, TRAIT_DRUNK_HEALING))
|
||||
adjustBruteLoss(-0.12, FALSE)
|
||||
adjustFireLoss(-0.06, FALSE)
|
||||
sound_environment_override = SOUND_ENVIRONMENT_PSYCHOTIC
|
||||
else
|
||||
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "drunk")
|
||||
clear_alert("drunk")
|
||||
sound_environment_override = SOUND_ENVIRONMENT_NONE
|
||||
|
||||
if(mind && (mind.assigned_role == "Scientist" || mind.assigned_role == "Research Director"))
|
||||
if(SSresearch.science_tech)
|
||||
|
||||
@@ -8,10 +8,12 @@
|
||||
overlay_fullscreen("high", /obj/screen/fullscreen/high)
|
||||
throw_alert("high", /obj/screen/alert/high)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "high", /datum/mood_event/high)
|
||||
sound_environment_override = SOUND_ENVIRONMENT_DRUGGED
|
||||
else
|
||||
clear_fullscreen("high")
|
||||
clear_alert("high")
|
||||
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "high")
|
||||
sound_environment_override = SOUND_ENVIRONMENT_NONE
|
||||
|
||||
/mob/living/carbon/set_drugginess(amount)
|
||||
druggy = max(amount, 0)
|
||||
|
||||
@@ -141,7 +141,8 @@
|
||||
/mob/living/proc/getBruteLoss()
|
||||
return bruteloss
|
||||
|
||||
/mob/living/proc/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
//only_robotic and only_organic arg only relevant for carbons
|
||||
/mob/living/proc/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE, only_robotic = FALSE, only_organic = TRUE)
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
return FALSE
|
||||
bruteloss = clamp((bruteloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
@@ -215,7 +216,8 @@
|
||||
/mob/living/proc/getFireLoss()
|
||||
return fireloss
|
||||
|
||||
/mob/living/proc/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
//only_robotic and only_organic arg only relevant for carbons
|
||||
/mob/living/proc/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE, only_robotic = FALSE, only_organic = TRUE)
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
return FALSE
|
||||
fireloss = clamp((fireloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2)
|
||||
|
||||
@@ -101,6 +101,7 @@
|
||||
|
||||
if(lying && !buckled && prob(getBruteLoss()*200/maxHealth))
|
||||
makeTrail(newloc, T, old_direction)
|
||||
|
||||
if(causes_dirt_buildup_on_floor && (movement_type & GROUND))
|
||||
dirt_buildup()
|
||||
|
||||
|
||||
@@ -911,10 +911,10 @@
|
||||
|
||||
if(!istype(apc) || QDELETED(apc) || apc.stat & BROKEN)
|
||||
to_chat(src, "<span class='danger'>Hack aborted. The designated APC no longer exists on the power network.</span>")
|
||||
playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, 1)
|
||||
playsound(get_turf(src), 'sound/machines/buzz-two.ogg', 50, TRUE, ignore_walls = FALSE)
|
||||
else if(apc.aidisabled)
|
||||
to_chat(src, "<span class='danger'>Hack aborted. \The [apc] is no longer responding to our systems.</span>")
|
||||
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, 1)
|
||||
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 50, TRUE, ignore_walls = FALSE)
|
||||
else
|
||||
malf_picker.processing_time += 10
|
||||
|
||||
@@ -923,7 +923,7 @@
|
||||
apc.locked = TRUE
|
||||
apc.coverlocked = TRUE
|
||||
|
||||
playsound(get_turf(src), 'sound/machines/ding.ogg', 50, 1)
|
||||
playsound(get_turf(src), 'sound/machines/ding.ogg', 50, TRUE, ignore_walls = FALSE)
|
||||
to_chat(src, "Hack complete. \The [apc] is now under your exclusive control.")
|
||||
apc.update_icon()
|
||||
|
||||
|
||||
@@ -426,6 +426,10 @@
|
||||
//Misc
|
||||
.["Cyborg - Misc (dog - blade)"] = process_holoform_icon_filter(icon('modular_citadel/icons/mob/widerobot.dmi', "blade"), HOLOFORM_FILTER_PAI, FALSE)
|
||||
|
||||
// Gorillas
|
||||
.["Gorilla (standing)"] = process_holoform_icon_filter(icon('icons/mob/gorilla.dmi', "standing"), HOLOFORM_FILTER_PAI, FALSE)
|
||||
.["Gorilla (crawling)"] = process_holoform_icon_filter(icon('icons/mob/gorilla.dmi', "crawling"), HOLOFORM_FILTER_PAI, FALSE)
|
||||
|
||||
/mob/living/silicon/pai/proc/default_chassis_pixel_offsets_x()
|
||||
. = list()
|
||||
//Engi
|
||||
|
||||
@@ -81,10 +81,10 @@
|
||||
to_chat(src, "<span class='userdanger'>The impact degrades your holochassis!</span>")
|
||||
return amount
|
||||
|
||||
/mob/living/silicon/pai/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
/mob/living/silicon/pai/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE, only_robotic = FALSE, only_organic = TRUE)
|
||||
return take_holo_damage(amount)
|
||||
|
||||
/mob/living/silicon/pai/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
/mob/living/silicon/pai/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE, only_robotic = FALSE, only_organic = TRUE)
|
||||
return take_holo_damage(amount)
|
||||
|
||||
/mob/living/silicon/pai/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, toxins_type = TOX_DEFAULT)
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
updatehealth()
|
||||
return amount
|
||||
|
||||
/mob/living/simple_animal/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
/mob/living/simple_animal/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE, only_robotic = FALSE, only_organic = TRUE)
|
||||
if(forced)
|
||||
. = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced)
|
||||
else if(damage_coeff[BRUTE])
|
||||
. = adjustHealth(amount * damage_coeff[BRUTE] * CONFIG_GET(number/damage_multiplier), updating_health, forced)
|
||||
|
||||
/mob/living/simple_animal/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
/mob/living/simple_animal/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE, only_robotic = FALSE, only_organic = TRUE)
|
||||
if(forced)
|
||||
. = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced)
|
||||
else if(damage_coeff[BURN])
|
||||
|
||||
@@ -37,23 +37,25 @@
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/cockroach/Crossed(var/atom/movable/AM)
|
||||
if(ismob(AM))
|
||||
if(isliving(AM))
|
||||
var/mob/living/A = AM
|
||||
if(A.mob_size > MOB_SIZE_SMALL && !(A.movement_type & FLYING))
|
||||
if(prob(squish_chance))
|
||||
A.visible_message("<span class='notice'>[A] squashed [src].</span>", "<span class='notice'>You squashed [src].</span>")
|
||||
adjustBruteLoss(1) //kills a normal cockroach
|
||||
else
|
||||
visible_message("<span class='notice'>[src] avoids getting crushed.</span>")
|
||||
else
|
||||
if(isstructure(AM))
|
||||
/mob/living/simple_animal/cockroach/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
if(isliving(AM))
|
||||
var/mob/living/A = AM
|
||||
if(A.mob_size > MOB_SIZE_SMALL && !(A.movement_type & FLYING))
|
||||
if(HAS_TRAIT(A, TRAIT_PACIFISM))
|
||||
A.visible_message("<span class='notice'>[A] carefully steps over [src].</span>", "<span class='notice'>You carefully step over [src] to avoid hurting it.</span>")
|
||||
return
|
||||
if(prob(squish_chance))
|
||||
AM.visible_message("<span class='notice'>[src] was crushed under [AM].</span>")
|
||||
adjustBruteLoss(1)
|
||||
A.visible_message("<span class='notice'>[A] squashed [src].</span>", "<span class='notice'>You squashed [src].</span>")
|
||||
adjustBruteLoss(1) //kills a normal cockroach
|
||||
else
|
||||
visible_message("<span class='notice'>[src] avoids getting crushed.</span>")
|
||||
else if(isstructure(AM))
|
||||
if(prob(squish_chance))
|
||||
AM.visible_message("<span class='notice'>[src] is crushed under [AM].</span>")
|
||||
adjustBruteLoss(1)
|
||||
else
|
||||
visible_message("<span class='notice'>[src] avoids getting crushed.</span>")
|
||||
|
||||
/mob/living/simple_animal/cockroach/ex_act() //Explosions are a terrible way to handle a cockroach.
|
||||
return
|
||||
|
||||
@@ -263,7 +263,7 @@
|
||||
/mob/living/simple_animal/pet/dog/corgi/proc/place_on_head(obj/item/item_to_add, mob/user)
|
||||
|
||||
if(istype(item_to_add, /obj/item/grenade/plastic)) // last thing he ever wears, I guess
|
||||
item_to_add.afterattack(src,user,1)
|
||||
INVOKE_ASYNC(item_to_add, /obj/item.proc/afterattack, src, user, 1)
|
||||
return
|
||||
|
||||
if(inventory_head)
|
||||
@@ -271,13 +271,15 @@
|
||||
to_chat(user, "<span class='warning'>You can't put more than one hat on [src]!</span>")
|
||||
return
|
||||
if(!item_to_add)
|
||||
user.visible_message("[user] pets [src].","<span class='notice'>You rest your hand on [src]'s head for a moment.</span>")
|
||||
user.visible_message("<span class='notice'>[user] pets [src].</span>", "<span class='notice'>You rest your hand on [src]'s head for a moment.</span>")
|
||||
if(flags_1 & HOLOGRAM_1)
|
||||
return
|
||||
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, src, /datum/mood_event/pet_animal, src)
|
||||
return
|
||||
|
||||
if(user && !user.temporarilyRemoveItemFromInventory(item_to_add))
|
||||
to_chat(user, "<span class='warning'>\The [item_to_add] is stuck to your hand, you cannot put it on [src]'s head!</span>")
|
||||
return 0
|
||||
return
|
||||
|
||||
var/valid = FALSE
|
||||
if(ispath(item_to_add.dog_fashion, /datum/dog_fashion/head))
|
||||
@@ -287,11 +289,11 @@
|
||||
|
||||
if(valid)
|
||||
if(health <= 0)
|
||||
to_chat(user, "<span class ='notice'>There is merely a dull, lifeless look in [real_name]'s eyes as you put the [item_to_add] on [p_them()].</span>")
|
||||
to_chat(user, "<span class='notice'>There is merely a dull, lifeless look in [real_name]'s eyes as you put the [item_to_add] on [p_them()].</span>")
|
||||
else if(user)
|
||||
user.visible_message("[user] puts [item_to_add] on [real_name]'s head. [src] looks at [user] and barks once.",
|
||||
"<span class='notice'>You put [item_to_add] on [real_name]'s head. [src] gives you a peculiar look, then wags [p_their()] tail once and barks.</span>",
|
||||
"<span class='italics'>You hear a friendly-sounding bark.</span>")
|
||||
user.visible_message("<span class='notice'>[user] puts [item_to_add] on [real_name]'s head. [src] looks at [user] and barks once.</span>",
|
||||
"<span class='notice'>You put [item_to_add] on [real_name]'s head. [src] gives you a peculiar look, then wags [p_their()] tail once and barks.</span>",
|
||||
"<span class='hear'>You hear a friendly-sounding bark.</span>")
|
||||
item_to_add.forceMove(src)
|
||||
src.inventory_head = item_to_add
|
||||
update_corgi_fluff()
|
||||
@@ -361,7 +363,7 @@
|
||||
icon_state = "old_corgi"
|
||||
icon_living = "old_corgi"
|
||||
icon_dead = "old_corgi_dead"
|
||||
desc = "At a ripe old age of [record_age] Ian's not as spry as he used to be, but he'll always be the HoP's beloved corgi." //RIP
|
||||
desc = "At a ripe old age of [record_age], Ian's not as spry as he used to be, but he'll always be the HoP's beloved corgi." //RIP
|
||||
turns_per_move = 20
|
||||
RemoveElement(/datum/element/mob_holder, held_icon)
|
||||
AddElement(/datum/element/mob_holder, "old_corgi")
|
||||
|
||||
@@ -110,6 +110,7 @@
|
||||
|
||||
|
||||
/obj/effect/snare/Crossed(AM as mob|obj)
|
||||
. = ..()
|
||||
if(isliving(AM) && spawner && spawner.summoner && AM != spawner && !spawner.hasmatchingsummoner(AM))
|
||||
to_chat(spawner.summoner, "<span class='danger'><B>[AM] has crossed surveillance snare, [name].</span></B>")
|
||||
var/list/guardians = spawner.summoner.hasparasites()
|
||||
|
||||
@@ -94,16 +94,17 @@
|
||||
consume_bait()
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/proc/consume_bait()
|
||||
var/obj/item/stack/ore/diamond/diamonds = locate(/obj/item/stack/ore/diamond) in oview(src, 9)
|
||||
var/obj/item/pen/survival/bait = locate(/obj/item/pen/survival) in oview(src, 9)
|
||||
if(!diamonds && !bait)
|
||||
return
|
||||
var/list/L = list()
|
||||
for(var/obj/O in view(src, 9))
|
||||
L += O
|
||||
var/obj/item/stack/ore/diamond/diamonds = locate(/obj/item/stack/ore/diamond) in L
|
||||
if(diamonds)
|
||||
var/distanced = 0
|
||||
distanced = get_dist(loc,diamonds.loc)
|
||||
if(distanced <= 1 && diamonds)
|
||||
qdel(diamonds)
|
||||
src.visible_message("<span class='notice'>[src] consumes [diamonds], and it disappears! ...At least, you think.</span>")
|
||||
var/obj/item/pen/survival/bait = locate(/obj/item/pen/survival) in L
|
||||
if(bait)
|
||||
var/distanceb = 0
|
||||
distanceb = get_dist(loc,bait.loc)
|
||||
|
||||
+3
@@ -219,6 +219,9 @@
|
||||
|
||||
/obj/effect/temp_visual/goliath_tentacle/broodmother/patch/Initialize(mapload, new_spawner)
|
||||
. = ..()
|
||||
INVOKE_ASYNC(src, .proc/createpatch)
|
||||
|
||||
/obj/effect/temp_visual/goliath_tentacle/broodmother/patch/proc/createpatch()
|
||||
var/tentacle_locs = spiral_range_turfs(1, get_turf(src))
|
||||
for(var/T in tentacle_locs)
|
||||
new /obj/effect/temp_visual/goliath_tentacle/broodmother(T, spawner)
|
||||
|
||||
@@ -42,7 +42,8 @@
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/nugget = 5)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/frog/Crossed(AM as mob|obj)
|
||||
. = ..()
|
||||
if(!stat && isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(L.mob_size > MOB_SIZE_TINY)
|
||||
playsound(src, stepped_sound, 50, 1)
|
||||
playsound(src, stepped_sound, 50, TRUE)
|
||||
|
||||
@@ -1189,4 +1189,4 @@
|
||||
icon_state = "mtoo-flap"
|
||||
icon_living = "mtoo-flap"
|
||||
icon_dead = "mtoo-dead"
|
||||
icon_sit = "mtoo_sit"
|
||||
icon_sit = "mtoo_sit"
|
||||
|
||||
@@ -225,7 +225,7 @@
|
||||
. += "Power Level: [powerlevel]"
|
||||
|
||||
|
||||
/mob/living/simple_animal/slime/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
/mob/living/simple_animal/slime/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE, only_robotic = FALSE, only_organic = TRUE)
|
||||
if(!forced)
|
||||
amount = -abs(amount)
|
||||
return ..() //Heals them
|
||||
|
||||
@@ -177,3 +177,6 @@
|
||||
var/list/ability_actions
|
||||
/// ability = list(data). see __DEFINES/mobs/innate_abilities.dm
|
||||
var/list/ability_properties
|
||||
|
||||
///Override for sound_environments. If this is set the user will always hear a specific type of reverb (Instead of the area defined reverb)
|
||||
var/sound_environment_override = SOUND_ENVIRONMENT_NONE
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
return FALSE
|
||||
//We are now going to move
|
||||
var/add_delay = mob.movement_delay()
|
||||
mob.set_glide_size(DELAY_TO_GLIDE_SIZE(add_delay * ( (NSCOMPONENT(direction) && EWCOMPONENT(direction)) ? 2 : 1 ) ), FALSE) // set it now in case of pulled objects
|
||||
if(old_move_delay + (add_delay*MOVEMENT_DELAY_BUFFER_DELTA) + MOVEMENT_DELAY_BUFFER > world.time)
|
||||
move_delay = old_move_delay
|
||||
else
|
||||
@@ -95,6 +96,7 @@
|
||||
|
||||
if((direction & (direction - 1)) && mob.loc == n) //moved diagonally successfully
|
||||
add_delay *= 2
|
||||
mob.set_glide_size(DELAY_TO_GLIDE_SIZE(add_delay), FALSE)
|
||||
move_delay += add_delay
|
||||
if(.) // If mob is null here, we deserve the runtime
|
||||
if(mob.throwing)
|
||||
@@ -104,6 +106,8 @@
|
||||
if(AM && AM.density && !SEND_SIGNAL(L, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_ACTIVE) && !ismob(AM))
|
||||
L.setDir(turn(L.dir, 180))
|
||||
|
||||
last_move = world.time
|
||||
|
||||
SEND_SIGNAL(mob, COMSIG_MOB_CLIENT_MOVE, src, direction, n, oldloc, add_delay)
|
||||
|
||||
/// Process_Grab(): checks for grab, attempts to break if so. Return TRUE to prevent movement.
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
// user?.mind?.adjust_experience(/datum/skill/gaming, 1)
|
||||
if(boss_hp <= 0)
|
||||
heads_up = "You have crushed [boss_name]! Rejoice!"
|
||||
playsound(computer.loc, 'sound/arcade/win.ogg', 50, TRUE, extrarange = -3, falloff = 10)
|
||||
playsound(computer.loc, 'sound/arcade/win.ogg', 50, TRUE, extrarange = -3)
|
||||
game_active = FALSE
|
||||
program_icon_state = "arcade_off"
|
||||
if(istype(computer))
|
||||
@@ -37,7 +37,7 @@
|
||||
sleep(10)
|
||||
else if(player_hp <= 0 || player_mp <= 0)
|
||||
heads_up = "You have been defeated... how will the station survive?"
|
||||
playsound(computer.loc, 'sound/arcade/lose.ogg', 50, TRUE, extrarange = -3, falloff = 10)
|
||||
playsound(computer.loc, 'sound/arcade/lose.ogg', 50, TRUE, extrarange = -3)
|
||||
game_active = FALSE
|
||||
program_icon_state = "arcade_off"
|
||||
if(istype(computer))
|
||||
@@ -57,17 +57,17 @@
|
||||
return
|
||||
if (boss_mp <= 5)
|
||||
heads_up = "[boss_mpamt] magic power has been stolen from you!"
|
||||
playsound(computer.loc, 'sound/arcade/steal.ogg', 50, TRUE, extrarange = -3, falloff = 10)
|
||||
playsound(computer.loc, 'sound/arcade/steal.ogg', 50, TRUE, extrarange = -3)
|
||||
player_mp -= boss_mpamt
|
||||
boss_mp += boss_mpamt
|
||||
else if(boss_mp > 5 && boss_hp <12)
|
||||
heads_up = "[boss_name] heals for [bossheal] health!"
|
||||
playsound(computer.loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3, falloff = 10)
|
||||
playsound(computer.loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3)
|
||||
boss_hp += bossheal
|
||||
boss_mp -= boss_mpamt
|
||||
else
|
||||
heads_up = "[boss_name] attacks you for [boss_attackamt] damage!"
|
||||
playsound(computer.loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3, falloff = 10)
|
||||
playsound(computer.loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3)
|
||||
player_hp -= boss_attackamt
|
||||
|
||||
pause_state = FALSE
|
||||
@@ -106,7 +106,7 @@
|
||||
attackamt = rand(2,6)// + rand(0, gamerSkill)
|
||||
pause_state = TRUE
|
||||
heads_up = "You attack for [attackamt] damage."
|
||||
playsound(computer.loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3, falloff = 10)
|
||||
playsound(computer.loc, 'sound/arcade/hit.ogg', 50, TRUE, extrarange = -3)
|
||||
boss_hp -= attackamt
|
||||
sleep(10)
|
||||
game_check()
|
||||
@@ -123,7 +123,7 @@
|
||||
healcost = rand(1, maxPointCost)
|
||||
pause_state = TRUE
|
||||
heads_up = "You heal for [healamt] damage."
|
||||
playsound(computer.loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3, falloff = 10)
|
||||
playsound(computer.loc, 'sound/arcade/heal.ogg', 50, TRUE, extrarange = -3)
|
||||
player_hp += healamt
|
||||
player_mp -= healcost
|
||||
sleep(10)
|
||||
@@ -136,7 +136,7 @@
|
||||
rechargeamt = rand(4,7)// + rand(0, gamerSkill)
|
||||
pause_state = TRUE
|
||||
heads_up = "You regain [rechargeamt] magic power."
|
||||
playsound(computer.loc, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3, falloff = 10)
|
||||
playsound(computer.loc, 'sound/arcade/mana.ogg', 50, TRUE, extrarange = -3)
|
||||
player_mp += rechargeamt
|
||||
sleep(10)
|
||||
game_check()
|
||||
@@ -153,7 +153,7 @@
|
||||
computer.visible_message("<span class='notice'>\The [computer] prints out paper.</span>")
|
||||
if(ticket_count >= 1)
|
||||
new /obj/item/stack/arcadeticket((get_turf(computer)), 1)
|
||||
to_chat(usr, "<span class='notice'>[src] dispenses a ticket!</span>")
|
||||
to_chat(usr, "<span class='notice'>[computer] dispenses a ticket!</span>")
|
||||
ticket_count -= 1
|
||||
printer.stored_paper -= 1
|
||||
else
|
||||
|
||||
@@ -96,7 +96,7 @@ GLOBAL_LIST_EMPTY(movespeed_modification_cache)
|
||||
return TRUE
|
||||
remove_movespeed_modifier(existing, FALSE)
|
||||
if(length(movespeed_modification))
|
||||
BINARY_INSERT(type_or_datum.id, movespeed_modification, datum/movespeed_modifier, type_or_datum, priority, COMPARE_VALUE)
|
||||
BINARY_INSERT(type_or_datum.id, movespeed_modification, /datum/movespeed_modifier, type_or_datum, priority, COMPARE_VALUE)
|
||||
LAZYSET(movespeed_modification, type_or_datum.id, type_or_datum)
|
||||
if(update)
|
||||
update_movespeed()
|
||||
@@ -217,13 +217,25 @@ GLOBAL_LIST_EMPTY(movespeed_modification_cache)
|
||||
else
|
||||
continue
|
||||
. = M.apply_multiplicative(., src)
|
||||
var/old = cached_multiplicative_slowdown // CITAEDL EDIT - To make things a bit less jarring, when in situations where
|
||||
// your delay decreases, "give" the delay back to the client
|
||||
cached_multiplicative_slowdown = .
|
||||
var/diff = old - cached_multiplicative_slowdown
|
||||
if((diff > 0) && client)
|
||||
if(!client)
|
||||
return
|
||||
var/diff = (client.last_move - client.move_delay) - cached_multiplicative_slowdown
|
||||
if(diff > 0)
|
||||
if(client.move_delay > world.time + 1.5)
|
||||
client.move_delay -= diff
|
||||
var/timeleft = world.time - client.move_delay
|
||||
var/elapsed = world.time - client.last_move
|
||||
var/glide_size_current = glide_size
|
||||
if((timeleft <= 0) || (elapsed > 20))
|
||||
set_glide_size(16, TRUE)
|
||||
return
|
||||
var/pixels_moved = glide_size_current * elapsed * (1 / world.tick_lag)
|
||||
// calculate glidesize needed to move to the next tile within timeleft deciseconds
|
||||
var/ticks_allowed = timeleft / world.tick_lag
|
||||
var/pixels_per_tick = pixels_moved / ticks_allowed
|
||||
set_glide_size(pixels_per_tick * GLOB.glide_size_multiplier, TRUE)
|
||||
|
||||
/// Get the move speed modifiers list of the mob
|
||||
/mob/proc/get_movespeed_modifiers()
|
||||
|
||||
@@ -62,6 +62,11 @@
|
||||
var/mod = CONFIG_GET(number/movedelay/walk_delay)
|
||||
multiplicative_slowdown = isnum(mod)? mod : initial(multiplicative_slowdown)
|
||||
|
||||
/datum/movespeed_modifier/config_wak_run/walk/apply_multiplicative(existing, mob/target)
|
||||
. = ..()
|
||||
if(HAS_TRAIT(target, TRAIT_SPEEDY_STEP))
|
||||
. -= 1.25
|
||||
|
||||
/datum/movespeed_modifier/config_walk_run/run/sync()
|
||||
var/mod = CONFIG_GET(number/movedelay/run_delay)
|
||||
multiplicative_slowdown = isnum(mod)? mod : initial(multiplicative_slowdown)
|
||||
|
||||
@@ -150,7 +150,8 @@
|
||||
H.DefaultCombatKnockdown(40)
|
||||
playsound(src, 'sound/effects/woodhit.ogg', 60, TRUE, 1)
|
||||
else if(filled)
|
||||
victim.adjustStaminaLoss(1)
|
||||
if(iscarbon(victim))
|
||||
victim.adjustStaminaLoss(1)
|
||||
playsound(src, "water_wade", 20, TRUE)
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -56,12 +56,14 @@
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/machinery/field/containment/Crossed(mob/mover)
|
||||
if(isliving(mover))
|
||||
shock(mover)
|
||||
/obj/machinery/field/containment/Crossed(atom/movable/AM)
|
||||
. = ..()
|
||||
if(isliving(AM))
|
||||
shock(AM)
|
||||
|
||||
if(ismachinery(AM) || isstructure(AM) || ismecha(AM))
|
||||
bump_field(AM)
|
||||
|
||||
if(ismachinery(mover) || isstructure(mover) || ismecha(mover))
|
||||
bump_field(mover)
|
||||
|
||||
/obj/machinery/field/containment/proc/set_master(master1,master2)
|
||||
if(!master1 || !master2)
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
movement_range = 0
|
||||
|
||||
/obj/effect/accelerated_particle/Crossed(atom/A)
|
||||
. = ..()
|
||||
if(isliving(A))
|
||||
toxmob(A)
|
||||
|
||||
|
||||
@@ -348,11 +348,11 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
|
||||
/obj/machinery/power/supermatter_crystal/proc/alarm()
|
||||
switch(get_status())
|
||||
if(SUPERMATTER_DELAMINATING)
|
||||
playsound(src, 'sound/misc/bloblarm.ogg', 100)
|
||||
playsound(src, 'sound/misc/bloblarm.ogg', 100, FALSE, 40, 30, falloff_distance = 10)
|
||||
if(SUPERMATTER_EMERGENCY)
|
||||
playsound(src, 'sound/machines/engine_alert1.ogg', 100)
|
||||
playsound(src, 'sound/machines/engine_alert1.ogg', 100, FALSE, 30, 30, falloff_distance = 10)
|
||||
if(SUPERMATTER_DANGER)
|
||||
playsound(src, 'sound/machines/engine_alert2.ogg', 100)
|
||||
playsound(src, 'sound/machines/engine_alert2.ogg', 100, FALSE, 30, 30, falloff_distance = 10)
|
||||
if(SUPERMATTER_WARNING)
|
||||
playsound(src, 'sound/machines/terminal_alert.ogg', 75)
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
item_flags = NEEDS_PERMIT
|
||||
attack_verb = list("struck", "hit", "bashed")
|
||||
attack_speed = CLICK_CD_RANGE
|
||||
var/ranged_attack_speed = CLICK_CD_RANGE
|
||||
var/melee_attack_speed = CLICK_CD_MELEE
|
||||
|
||||
var/fire_sound = "gunshot"
|
||||
var/suppressed = null //whether or not a message is displayed when fired
|
||||
@@ -159,7 +161,7 @@
|
||||
user.UseStaminaBuffer(safe_cost)
|
||||
|
||||
if(suppressed)
|
||||
playsound(user, fire_sound, 10, 1)
|
||||
playsound(user, fire_sound, 10, TRUE, ignore_walls = FALSE, extrarange = SILENCED_SOUND_EXTRARANGE, falloff_distance = 0)
|
||||
else
|
||||
playsound(user, fire_sound, 50, 1)
|
||||
if(message)
|
||||
@@ -174,12 +176,25 @@
|
||||
for(var/obj/O in contents)
|
||||
O.emp_act(severity)
|
||||
|
||||
/obj/item/gun/attack(mob/living/M, mob/user)
|
||||
. = ..()
|
||||
if(!(. & DISCARD_LAST_ACTION))
|
||||
user.DelayNextAction(melee_attack_speed)
|
||||
|
||||
/obj/item/gun/attack_obj(obj/O, mob/user)
|
||||
. = ..()
|
||||
if(!(. & DISCARD_LAST_ACTION))
|
||||
user.DelayNextAction(melee_attack_speed)
|
||||
|
||||
/obj/item/gun/afterattack(atom/target, mob/living/user, flag, params)
|
||||
. = ..()
|
||||
if(user && !CheckAttackCooldown(user, target))
|
||||
if(user && !CheckAttackCooldown(user, target, TRUE))
|
||||
return
|
||||
process_afterattack(target, user, flag, params)
|
||||
|
||||
/obj/item/gun/CheckAttackCooldown(mob/user, atom/target, shooting = FALSE)
|
||||
return user.CheckActionCooldown(shooting? ranged_attack_speed : attack_speed, clickdelay_from_next_action, clickdelay_mod_bypass, clickdelay_ignores_next_action)
|
||||
|
||||
/obj/item/gun/proc/process_afterattack(atom/target, mob/living/user, flag, params)
|
||||
if(!target)
|
||||
return
|
||||
|
||||
@@ -373,7 +373,6 @@
|
||||
sawn_off = TRUE
|
||||
slot_flags = ITEM_SLOT_BELT
|
||||
|
||||
|
||||
/obj/item/gun/ballistic/revolver/reverse //Fires directly at its user... unless the user is a clown, of course.
|
||||
clumsy_check = 0
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user