Merge branch 'master' into the-p-o-o-l
@@ -26,6 +26,7 @@ matrix:
|
||||
- find . -name "*.json" -not -path "./tgui/node_modules/*" -print0 | xargs -0 python3 ./tools/json_verifier.py
|
||||
- tools/travis/build_tgui.sh
|
||||
- tools/travis/check_grep.sh
|
||||
- python3 tools/travis/check_line_endings.py
|
||||
- ~/dreamchecker
|
||||
|
||||
- name: "Compile All Maps"
|
||||
|
||||
@@ -341,7 +341,7 @@
|
||||
if(probabilities[M.config_tag]<=0)
|
||||
qdel(M)
|
||||
continue
|
||||
if(M.config_tag in SSvote.stored_modetier_results && SSvote.stored_modetier_results[M.config_tag] < Get(/datum/config_entry/number/dropped_modes))
|
||||
if(CONFIG_GET(flag/modetier_voting) && !(M.config_tag in SSvote.stored_modetier_results))
|
||||
qdel(M)
|
||||
continue
|
||||
if(min_pop[M.config_tag])
|
||||
|
||||
@@ -396,7 +396,6 @@
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/flag/modetier_voting
|
||||
config_entry_value = TRUE
|
||||
|
||||
/datum/config_entry/number/dropped_modes
|
||||
config_entry_value = 3
|
||||
|
||||
@@ -188,6 +188,12 @@ SUBSYSTEM_DEF(ticker)
|
||||
tipped = TRUE
|
||||
|
||||
if(timeLeft <= 0)
|
||||
if(SSvote.mode && (SSvote.mode == "roundtype" || SSvote.mode == "dynamic" || SSvote.mode == "mode tiers"))
|
||||
SSvote.result()
|
||||
SSpersistence.SaveSavedVotes()
|
||||
for(var/client/C in SSvote.voting)
|
||||
C << browse(null, "window=vote;can_close=0")
|
||||
SSvote.reset()
|
||||
current_state = GAME_STATE_SETTING_UP
|
||||
Master.SetRunLevel(RUNLEVEL_SETUP)
|
||||
if(start_immediately)
|
||||
@@ -221,12 +227,6 @@ SUBSYSTEM_DEF(ticker)
|
||||
var/init_start = world.timeofday
|
||||
//Create and announce mode
|
||||
var/list/datum/game_mode/runnable_modes
|
||||
if(SSvote.mode && (SSvote.mode == "roundtype" || SSvote.mode == "dynamic" || SSvote.mode == "mode tiers"))
|
||||
SSvote.result()
|
||||
SSpersistence.SaveSavedVotes()
|
||||
for(var/client/C in SSvote.voting)
|
||||
C << browse(null, "window=vote;can_close=0")
|
||||
SSvote.reset()
|
||||
if(GLOB.master_mode == "random" || GLOB.master_mode == "secret")
|
||||
runnable_modes = config.get_runnable_modes()
|
||||
|
||||
|
||||
@@ -102,17 +102,18 @@ SUBSYSTEM_DEF(vote)
|
||||
var/list/d[][] = new/list(choices.len,choices.len) // the basic vote matrix, how many times a beats b
|
||||
for(var/ckey in voted)
|
||||
var/list/this_vote = voted[ckey]
|
||||
for(var/a in 1 to choices.len)
|
||||
for(var/b in a+1 to choices.len)
|
||||
var/a_rank = this_vote.Find(a)
|
||||
var/b_rank = this_vote.Find(b)
|
||||
a_rank = a_rank ? a_rank : choices.len+1
|
||||
b_rank = b_rank ? b_rank : choices.len+1
|
||||
if(a_rank<b_rank)
|
||||
d[a][b]++
|
||||
else if(b_rank<a_rank)
|
||||
d[b][a]++
|
||||
//if equal, do nothing
|
||||
if(islist(this_vote))
|
||||
for(var/a in 1 to choices.len)
|
||||
for(var/b in a+1 to choices.len)
|
||||
var/a_rank = this_vote.Find(a)
|
||||
var/b_rank = this_vote.Find(b)
|
||||
a_rank = a_rank ? a_rank : choices.len+1
|
||||
b_rank = b_rank ? b_rank : choices.len+1
|
||||
if(a_rank<b_rank)
|
||||
d[a][b]++
|
||||
else if(b_rank<a_rank)
|
||||
d[b][a]++
|
||||
//if equal, do nothing
|
||||
var/list/p[][] = new/list(choices.len,choices.len) //matrix of shortest path from a to b
|
||||
for(var/i in 1 to choices.len)
|
||||
for(var/j in 1 to choices.len)
|
||||
@@ -142,15 +143,18 @@ SUBSYSTEM_DEF(vote)
|
||||
// https://en.wikipedia.org/wiki/Majority_judgment
|
||||
var/list/scores_by_choice = list()
|
||||
for(var/choice in choices)
|
||||
scores_by_choice[choice] = list()
|
||||
scores_by_choice += "[choice]"
|
||||
scores_by_choice["[choice]"] = list()
|
||||
for(var/ckey in voted)
|
||||
var/list/this_vote = voted[ckey]
|
||||
var/list/pretty_vote = list()
|
||||
for(var/choice in this_vote)
|
||||
sorted_insert(scores_by_choice[choice],this_vote[choice],/proc/cmp_numeric_asc)
|
||||
// START BALLOT GATHERING
|
||||
pretty_vote += choice
|
||||
pretty_vote[choice] = GLOB.vote_score_options[this_vote[choice]]
|
||||
for(var/choice in choices)
|
||||
if("[choice]" in this_vote && "[choice]" in scores_by_choice)
|
||||
sorted_insert(scores_by_choice["[choice]"],this_vote["[choice]"],/proc/cmp_numeric_asc)
|
||||
// START BALLOT GATHERING
|
||||
pretty_vote += "[choice]"
|
||||
if(this_vote["[choice]"] in GLOB.vote_score_options)
|
||||
pretty_vote["[choice]"] = GLOB.vote_score_options[this_vote["[choice]"]]
|
||||
SSblackbox.record_feedback("associative","voting_ballots",1,pretty_vote)
|
||||
// END BALLOT GATHERING
|
||||
for(var/score_name in scores_by_choice)
|
||||
@@ -186,11 +190,13 @@ SUBSYSTEM_DEF(vote)
|
||||
/datum/controller/subsystem/vote/proc/calculate_scores(var/blackbox_text)
|
||||
var/list/scores_by_choice = list()
|
||||
for(var/choice in choices)
|
||||
scores_by_choice[choice] = list()
|
||||
scores_by_choice += "[choice]"
|
||||
scores_by_choice["[choice]"] = list()
|
||||
for(var/ckey in voted)
|
||||
var/list/this_vote = voted[ckey]
|
||||
for(var/choice in this_vote)
|
||||
sorted_insert(scores_by_choice[choice],this_vote[choice],/proc/cmp_numeric_asc)
|
||||
for(var/choice in choices)
|
||||
if("[choice]" in this_vote && "[choice]" in scores_by_choice)
|
||||
sorted_insert(scores_by_choice["[choice]"],this_vote["[choice]"],/proc/cmp_numeric_asc)
|
||||
var/middle_score = round(GLOB.vote_score_options.len/2,1)
|
||||
for(var/score_name in scores_by_choice)
|
||||
var/list/score = scores_by_choice[score_name]
|
||||
@@ -212,6 +218,7 @@ SUBSYSTEM_DEF(vote)
|
||||
calculate_condorcet_votes(vote_title_text)
|
||||
if(vote_system == SCORE_VOTING)
|
||||
calculate_majority_judgement_vote(vote_title_text)
|
||||
calculate_scores(vote_title_text)
|
||||
var/list/winners = get_result()
|
||||
var/was_roundtype_vote = mode == "roundtype" || mode == "dynamic"
|
||||
if(winners.len > 0)
|
||||
@@ -219,13 +226,20 @@ SUBSYSTEM_DEF(vote)
|
||||
stored_gamemode_votes = list()
|
||||
if(!obfuscated && vote_system == RANKED_CHOICE_VOTING)
|
||||
text += "\nIt should be noted that this is not a raw tally of votes (impossible in ranked choice) but the score determined by the schulze method of voting, so the numbers will look weird!"
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
var/votes = choices[choices[i]]
|
||||
if(!votes)
|
||||
votes = 0
|
||||
if(was_roundtype_vote)
|
||||
stored_gamemode_votes[choices[i]] = votes
|
||||
text += "\n<b>[choices[i]]:</b> [obfuscated ? "???" : votes]" //CIT CHANGE - adds obfuscated votes
|
||||
if(mode == "mode tiers")
|
||||
for(var/score_name in scores)
|
||||
var/score = scores[score_name]
|
||||
if(!score)
|
||||
score = 0
|
||||
text = "\n<b>[score_name]:</b> [obfuscated ? "???" : score]"
|
||||
else
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
var/votes = choices[choices[i]]
|
||||
if(!votes)
|
||||
votes = 0
|
||||
if(was_roundtype_vote)
|
||||
stored_gamemode_votes[choices[i]] = votes
|
||||
text += "\n<b>[choices[i]]:</b> [obfuscated ? "???" : votes]" //CIT CHANGE - adds obfuscated votes
|
||||
if(mode != "custom")
|
||||
if(winners.len > 1 && !obfuscated) //CIT CHANGE - adds obfuscated votes
|
||||
text = "\n<b>Vote Tied Between:</b>"
|
||||
@@ -247,8 +261,9 @@ SUBSYSTEM_DEF(vote)
|
||||
if(RANKED_CHOICE_VOTING)
|
||||
for(var/i=1,i<=voted.len,i++)
|
||||
var/list/myvote = voted[voted[i]]
|
||||
for(var/j=1,j<=myvote.len,j++)
|
||||
SSblackbox.record_feedback("nested tally","voting",1,list(vote_title_text,"[j]\th",choices[myvote[j]]))
|
||||
if(islist(myvote))
|
||||
for(var/j=1,j<=myvote.len,j++)
|
||||
SSblackbox.record_feedback("nested tally","voting",1,list(vote_title_text,"[j]\th",choices[myvote[j]]))
|
||||
if(obfuscated) //CIT CHANGE - adds obfuscated votes. this messages admins with the vote's true results
|
||||
var/admintext = "Obfuscated results"
|
||||
if(vote_system == RANKED_CHOICE_VOTING)
|
||||
@@ -276,7 +291,7 @@ SUBSYSTEM_DEF(vote)
|
||||
if(CONFIG_GET(flag/modetier_voting))
|
||||
reset()
|
||||
started_time = 0
|
||||
initiate_vote("mode tiers","server",hideresults=FALSE,votesystem=RANKED_CHOICE_VOTING,forced=TRUE, vote_time = 30 MINUTES)
|
||||
initiate_vote("mode tiers","server",hideresults=FALSE,votesystem=SCORE_VOTING,forced=TRUE, vote_time = 30 MINUTES)
|
||||
to_chat(world,"<b>The vote will end right as the round starts.</b>")
|
||||
return .
|
||||
if("restart")
|
||||
@@ -290,7 +305,14 @@ SUBSYSTEM_DEF(vote)
|
||||
else
|
||||
GLOB.master_mode = .
|
||||
if("mode tiers")
|
||||
stored_modetier_results = choices.Copy()
|
||||
var/list/raw_score_numbers = list()
|
||||
for(var/score_name in scores)
|
||||
sorted_insert(raw_score_numbers,scores[score_name],/proc/cmp_numeric_asc)
|
||||
stored_modetier_results = scores.Copy()
|
||||
for(var/score_name in stored_modetier_results)
|
||||
if(stored_modetier_results[score_name] <= raw_score_numbers[CONFIG_GET(number/dropped_modes)])
|
||||
stored_modetier_results -= score_name
|
||||
stored_modetier_results += "traitor"
|
||||
if("dynamic")
|
||||
if(SSticker.current_state > GAME_STATE_PREGAME)//Don't change the mode if the round already started.
|
||||
return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.")
|
||||
@@ -417,6 +439,7 @@ SUBSYSTEM_DEF(vote)
|
||||
for(var/tag in modes_to_add)
|
||||
if(probabilities[tag] <= 0)
|
||||
modes_to_add -= tag
|
||||
modes_to_add -= "traitor" // makes it so that traitor is always available
|
||||
choices.Add(modes_to_add)
|
||||
if("dynamic")
|
||||
for(var/T in config.storyteller_cache)
|
||||
@@ -516,7 +539,7 @@ SUBSYSTEM_DEF(vote)
|
||||
if(RANKED_CHOICE_VOTING)
|
||||
var/list/myvote = voted[C.ckey]
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
var/vote = (myvote ? (myvote.Find(i)) : 0)
|
||||
var/vote = (islist(myvote) ? (myvote.Find(i)) : 0)
|
||||
if(vote)
|
||||
. += "<li><b><a href='?src=[REF(src)];vote=[i]'>[choices[i]]</a> ([vote])</b></li>"
|
||||
else
|
||||
@@ -615,8 +638,12 @@ SUBSYSTEM_DEF(vote)
|
||||
if(usr.ckey in voted)
|
||||
if(!(usr.ckey in SSpersistence.saved_votes))
|
||||
SSpersistence.saved_votes[usr.ckey] = list()
|
||||
SSpersistence.saved_votes[usr.ckey][mode] = voted[usr.ckey]
|
||||
saved += usr.ckey
|
||||
if(islist(voted[usr.ckey]))
|
||||
SSpersistence.saved_votes[usr.ckey][mode] = voted[usr.ckey]
|
||||
saved += usr.ckey
|
||||
else
|
||||
voted[usr.ckey] = list()
|
||||
to_chat(usr,"Your vote was malformed! Start over!")
|
||||
if("load")
|
||||
if(!(usr.ckey in SSpersistence.saved_votes))
|
||||
SSpersistence.LoadSavedVote(usr.ckey)
|
||||
@@ -627,7 +654,21 @@ SUBSYSTEM_DEF(vote)
|
||||
else
|
||||
SSpersistence.saved_votes[usr.ckey][mode] = list()
|
||||
voted[usr.ckey] = SSpersistence.saved_votes[usr.ckey][mode]
|
||||
saved += usr.ckey
|
||||
if(islist(voted[usr.ckey]))
|
||||
var/malformed = FALSE
|
||||
if(vote_system == SCORE_VOTING)
|
||||
for(var/thing in voted[usr.ckey])
|
||||
if(!(thing in choices))
|
||||
malformed = TRUE
|
||||
if(!malformed)
|
||||
saved += usr.ckey
|
||||
else
|
||||
to_chat(usr,"Your saved vote was malformed! Start over!")
|
||||
SSpersistence.saved_votes[usr.ckey] -= mode
|
||||
voted -= usr.ckey
|
||||
else
|
||||
to_chat(usr,"Your saved vote was malformed! Start over!")
|
||||
voted -= usr.ckey
|
||||
else
|
||||
if(vote_system == SCORE_VOTING)
|
||||
submit_vote(round(text2num(href_list["vote"])),round(text2num(href_list["score"])))
|
||||
|
||||
@@ -380,9 +380,14 @@
|
||||
/datum/map_template/shuttle/emergency/gorilla
|
||||
suffix = "gorilla"
|
||||
name = "Gorilla Cargo Freighter"
|
||||
description = "A rustic, barely excuseable shuttle transporting important cargo. Not for crew who are about to go ape."
|
||||
description = "(Emag only) A rustic, barely excuseable shuttle transporting important cargo. Not for crew who are about to go ape."
|
||||
credit_cost = 2000
|
||||
|
||||
/datum/map_template/shuttle/emergency/gorilla/prerequisites_met()
|
||||
if("emagged" in SSshuttle.shuttle_purchase_requirements_met)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/map_template/shuttle/ferry/base
|
||||
suffix = "base"
|
||||
name = "transport ferry"
|
||||
|
||||
@@ -99,10 +99,12 @@
|
||||
id = "Mesmerize"
|
||||
alert_type = /obj/screen/alert/status_effect/mesmerized
|
||||
|
||||
/datum/status_effect/no_combat_mode/mesmerize/on_apply()
|
||||
/datum/status_effect/no_combat_mode/mesmerize/on_creation(mob/living/new_owner, set_duration)
|
||||
. = ..()
|
||||
ADD_TRAIT(owner, TRAIT_MUTE, "mesmerize")
|
||||
|
||||
/datum/status_effect/no_combat_mode/mesmerize/on_remove()
|
||||
. = ..()
|
||||
REMOVE_TRAIT(owner, TRAIT_MUTE, "mesmerize")
|
||||
|
||||
/obj/screen/alert/status_effect/mesmerized
|
||||
|
||||
@@ -139,9 +139,9 @@
|
||||
|
||||
/datum/world_topic/status/Run(list/input, addr)
|
||||
if(!key_valid) //If we have a key, then it's safe to trust that this isn't a malicious packet. Also prevents the extra info from leaking
|
||||
if(GLOB.topic_status_lastcache <= world.time + 5)
|
||||
if(GLOB.topic_status_lastcache >= world.time)
|
||||
return GLOB.topic_status_cache
|
||||
GLOB.topic_status_lastcache = world.time
|
||||
GLOB.topic_status_lastcache = world.time + 5
|
||||
. = list()
|
||||
.["version"] = GLOB.game_version
|
||||
.["mode"] = "hidden" //CIT CHANGE - hides the gamemode in topic() calls to prevent meta'ing the gamemode
|
||||
|
||||
@@ -101,13 +101,23 @@
|
||||
item_state = "synth"
|
||||
instrumentId = "piano"
|
||||
instrumentExt = "ogg"
|
||||
var/static/list/insTypes = list("accordion" = "mid", "bikehorn" = "ogg", "glockenspiel" = "mid", "guitar" = "ogg", "harmonica" = "mid", "piano" = "ogg", "recorder" = "mid", "saxophone" = "mid", "trombone" = "mid", "violin" = "mid", "xylophone" = "mid") //No eguitar you ear-rapey fuckers.
|
||||
var/static/list/insTypes = list("accordion" = "mid", "bikehorn" = "ogg", "glockenspiel" = "mid", "banjo" = "ogg", "guitar" = "ogg", "harmonica" = "mid", "piano" = "ogg", "recorder" = "mid", "saxophone" = "mid", "trombone" = "mid", "violin" = "mid", "xylophone" = "mid") //No eguitar you ear-rapey fuckers.
|
||||
actions_types = list(/datum/action/item_action/synthswitch)
|
||||
|
||||
/obj/item/instrument/piano_synth/proc/changeInstrument(name = "piano")
|
||||
song.instrumentDir = name
|
||||
song.instrumentExt = insTypes[name]
|
||||
|
||||
/obj/item/instrument/banjo
|
||||
name = "banjo"
|
||||
desc = "A 'Mura' brand banjo. It's pretty much just a drum with a neck and strings."
|
||||
icon_state = "banjo"
|
||||
item_state = "banjo"
|
||||
instrumentExt = "ogg"
|
||||
attack_verb = list("scruggs-styled", "hum-diggitied", "shin-digged", "clawhammered")
|
||||
hitsound = 'sound/weapons/banjoslap.ogg'
|
||||
instrumentId = "banjo"
|
||||
|
||||
/obj/item/instrument/guitar
|
||||
name = "guitar"
|
||||
desc = "It's made of wood and has bronze strings."
|
||||
@@ -263,8 +273,6 @@
|
||||
throw_range = 15
|
||||
hitsound = 'sound/items/bikehorn.ogg'
|
||||
|
||||
///
|
||||
|
||||
/obj/item/musicaltuner
|
||||
name = "musical tuner"
|
||||
desc = "A device for tuning musical instruments both manual and electronic alike."
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
new /obj/item/radio/headset/heads/captain(src)
|
||||
new /obj/item/clothing/glasses/sunglasses/gar/supergar(src)
|
||||
new /obj/item/clothing/gloves/color/captain(src)
|
||||
new /obj/item/restraints/handcuffs/cable/zipties(src)
|
||||
new /obj/item/storage/belt/sabre(src)
|
||||
new /obj/item/gun/energy/e_gun(src)
|
||||
new /obj/item/door_remote/captain(src)
|
||||
|
||||
@@ -7,22 +7,33 @@
|
||||
#define STICKYBAN_MAX_ADMIN_MATCHES 2
|
||||
|
||||
/world/IsBanned(key,address,computer_id,type,real_bans_only=FALSE)
|
||||
var/static/key_cache = list()
|
||||
if(!real_bans_only)
|
||||
if(key_cache[key])
|
||||
return list("reason"="concurrent connection attempts", "desc"="You are attempting to connect too fast. Try again.")
|
||||
key_cache[key] = 1
|
||||
|
||||
if (!key || !address || !computer_id)
|
||||
if(real_bans_only)
|
||||
key_cache[key] = 0
|
||||
return FALSE
|
||||
log_access("Failed Login (invalid data): [key] [address]-[computer_id]")
|
||||
key_cache[key] = 0
|
||||
return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided invalid or blank information to the server on connection (byond username, IP, and Computer ID.) Provided information for reference: Username:'[key]' IP:'[address]' Computer ID:'[computer_id]'. (If you continue to get this error, please restart byond or contact byond support.)")
|
||||
|
||||
if (text2num(computer_id) == 2147483647) //this cid causes stickybans to go haywire
|
||||
log_access("Failed Login (invalid cid): [key] [address]-[computer_id]")
|
||||
key_cache[key] = 0
|
||||
return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided an invalid Computer ID.)")
|
||||
|
||||
if (type == "world")
|
||||
key_cache[key] = 0
|
||||
return ..() //shunt world topic banchecks to purely to byond's internal ban system
|
||||
|
||||
var/ckey = ckey(key)
|
||||
var/client/C = GLOB.directory[ckey]
|
||||
if (C && ckey == C.ckey && computer_id == C.computer_id && address == C.address)
|
||||
key_cache[key] = 0
|
||||
return //don't recheck connected clients.
|
||||
|
||||
var/admin = FALSE
|
||||
@@ -38,21 +49,25 @@
|
||||
addclientmessage(ckey,"<span class='adminnotice'>You have been allowed to bypass the whitelist</span>")
|
||||
else
|
||||
log_access("Failed Login: [key] - Not on whitelist")
|
||||
key_cache[key] = 0
|
||||
return list("reason"="whitelist", "desc" = "\nReason: You are not on the white list for this server")
|
||||
|
||||
//Guest Checking
|
||||
if(!real_bans_only && IsGuestKey(key))
|
||||
if (CONFIG_GET(flag/guest_ban))
|
||||
log_access("Failed Login: [key] - Guests not allowed")
|
||||
key_cache[key] = 0
|
||||
return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a byond account.")
|
||||
if (CONFIG_GET(flag/panic_bunker) && SSdbcore.Connect())
|
||||
log_access("Failed Login: [key] - Guests not allowed during panic bunker")
|
||||
key_cache[key] = 0
|
||||
return list("reason"="guest", "desc"="\nReason: Sorry but the server is currently not accepting connections from never before seen players or guests. If you have played on this server with a byond account before, please log in to the byond account you have played from.")
|
||||
|
||||
//Population Cap Checking
|
||||
var/extreme_popcap = CONFIG_GET(number/extreme_popcap)
|
||||
if(!real_bans_only && extreme_popcap && living_player_count() >= extreme_popcap && !admin)
|
||||
log_access("Failed Login: [key] - Population cap reached")
|
||||
key_cache[key] = 0
|
||||
return list("reason"="popcap", "desc"= "\nReason: [CONFIG_GET(string/extreme_popcap_message)]")
|
||||
|
||||
if(CONFIG_GET(flag/ban_legacy_system))
|
||||
@@ -66,6 +81,7 @@
|
||||
addclientmessage(ckey,"<span class='adminnotice'>You have been allowed to bypass a matching ban on [.["key"]]</span>")
|
||||
else
|
||||
log_access("Failed Login: [key] [computer_id] [address] - Banned [.["reason"]]")
|
||||
key_cache[key] = 0
|
||||
return .
|
||||
|
||||
else
|
||||
@@ -73,6 +89,7 @@
|
||||
var/msg = "Ban database connection failure. Key [ckey] not checked"
|
||||
log_world(msg)
|
||||
message_admins(msg)
|
||||
key_cache[key] = 0
|
||||
return
|
||||
|
||||
var/ipquery = ""
|
||||
@@ -86,6 +103,7 @@
|
||||
var/datum/DBQuery/query_ban_check = SSdbcore.NewQuery("SELECT IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), a_ckey), reason, expiration_time, duration, bantime, bantype, id, round_id FROM [format_table_name("ban")] WHERE (ckey = '[ckey]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR bantype = 'ADMIN_PERMABAN' OR ((bantype = 'TEMPBAN' OR bantype = 'ADMIN_TEMPBAN') AND expiration_time > Now())) AND isnull(unbanned)")
|
||||
if(!query_ban_check.Execute(async = TRUE))
|
||||
qdel(query_ban_check)
|
||||
key_cache[key] = 0
|
||||
return
|
||||
while(query_ban_check.NextRow())
|
||||
var/pkey = query_ban_check.item[1]
|
||||
@@ -124,6 +142,7 @@
|
||||
|
||||
log_access("Failed Login: [key] [computer_id] [address] - Banned (#[banid]) [.["reason"]]")
|
||||
qdel(query_ban_check)
|
||||
key_cache[key] = 0
|
||||
return .
|
||||
qdel(query_ban_check)
|
||||
|
||||
@@ -138,6 +157,7 @@
|
||||
|
||||
//rogue ban in the process of being reverted.
|
||||
if (cachedban && cachedban["reverting"])
|
||||
key_cache[key] = 0
|
||||
return null
|
||||
|
||||
if (cachedban && ckey != bannedckey)
|
||||
@@ -165,6 +185,7 @@
|
||||
newmatches_admin.len > STICKYBAN_MAX_ADMIN_MATCHES \
|
||||
)
|
||||
if (cachedban["reverting"])
|
||||
key_cache[key] = 0
|
||||
return null
|
||||
cachedban["reverting"] = TRUE
|
||||
|
||||
@@ -182,6 +203,7 @@
|
||||
cachedban["admin_matches_this_round"] = list()
|
||||
cachedban -= "reverting"
|
||||
world.SetConfig("ban", bannedckey, list2stickyban(cachedban))
|
||||
key_cache[key] = 0
|
||||
return null
|
||||
|
||||
//byond will not trigger isbanned() for "global" host bans,
|
||||
@@ -191,6 +213,7 @@
|
||||
log_admin("The admin [key] has been allowed to bypass a matching host/sticky ban on [bannedckey]")
|
||||
message_admins("<span class='adminnotice'>The admin [key] has been allowed to bypass a matching host/sticky ban on [bannedckey]</span>")
|
||||
addclientmessage(ckey,"<span class='adminnotice'>You have been allowed to bypass a matching host/sticky ban on [bannedckey]</span>")
|
||||
key_cache[key] = 0
|
||||
return null
|
||||
|
||||
if (C) //user is already connected!.
|
||||
@@ -200,6 +223,7 @@
|
||||
. = list("reason" = "Stickyban", "desc" = desc)
|
||||
log_access("Failed Login: [key] [computer_id] [address] - StickyBanned [ban["message"]] Target Username: [bannedckey] Placed by [ban["admin"]]")
|
||||
|
||||
key_cache[key] = 0
|
||||
return .
|
||||
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
target.Stun(40) //Utterly useless without this, its okay since there are so many checks to go through
|
||||
target.apply_status_effect(STATUS_EFFECT_MESMERIZE, 45) //So you cant rotate with combat mode, plus fancy status alert
|
||||
|
||||
if(do_mob(user, target, 40, 0, TRUE, extra_checks=CALLBACK(src, .proc/ContinueActive, user, target)))
|
||||
if(do_mob(user, target, 40, 0, TRUE, extra_checks = CALLBACK(src, .proc/ContinueActive, user, target)))
|
||||
PowerActivatedSuccessfully() // PAY COST! BEGIN COOLDOWN!
|
||||
var/power_time = 90 + level_current * 12
|
||||
target.apply_status_effect(STATUS_EFFECT_MESMERIZE, power_time + 80)
|
||||
|
||||
@@ -2,8 +2,9 @@ GLOBAL_LIST_EMPTY(clientmessages)
|
||||
|
||||
/proc/addclientmessage(var/ckey, var/message)
|
||||
ckey = ckey(ckey)
|
||||
if (!ckey || !message)
|
||||
if(!ckey || !message)
|
||||
return
|
||||
if (!(ckey in GLOB.clientmessages))
|
||||
GLOB.clientmessages[ckey] = list()
|
||||
GLOB.clientmessages[ckey] += message
|
||||
var/list/L = GLOB.clientmessages[ckey]
|
||||
if(!L)
|
||||
GLOB.clientmessages[ckey] = L = list()
|
||||
L += message
|
||||
@@ -25,7 +25,7 @@
|
||||
else
|
||||
log_admin("Client [ckey] was just autokicked for flooding keysends; likely abuse but potentially lagspike.")
|
||||
message_admins("Client [ckey] was just autokicked for flooding keysends; likely abuse but potentially lagspike.")
|
||||
QDEL_IN(src, 1)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
///Check if the key is short enough to even be a real key
|
||||
|
||||
@@ -244,6 +244,10 @@
|
||||
name = "Shark"
|
||||
icon_state = "shark"
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/hshark
|
||||
name = "hShark"
|
||||
icon_state = "hshark"
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/toucan
|
||||
name = "Toucan"
|
||||
icon_state = "toucan"
|
||||
|
||||
@@ -833,8 +833,8 @@ Nothing else in the console has ID requirements.
|
||||
for(var/i in 1 to length(ui))
|
||||
if(!findtextEx(ui[i], RDSCREEN_NOBREAK))
|
||||
ui[i] += "<br>"
|
||||
ui[i] = replacetextEx(ui[i], RDSCREEN_NOBREAK, "")
|
||||
return ui.Join("")
|
||||
. = ui.Join("")
|
||||
return replacetextEx(., RDSCREEN_NOBREAK, "")
|
||||
|
||||
/obj/machinery/computer/rdconsole/Topic(raw, ls)
|
||||
if(..())
|
||||
|
||||
@@ -131,6 +131,12 @@
|
||||
/obj/item/clothing/suit/drfreeze_coat = 1,
|
||||
/obj/item/clothing/suit/gothcoat = 2,
|
||||
/obj/item/clothing/under/draculass = 1,
|
||||
/obj/item/clothing/under/christmas/christmasmaler = 3,
|
||||
/obj/item/clothing/under/christmas/christmasmaleg = 3,
|
||||
/obj/item/clothing/under/christmas/christmasfemaler = 3,
|
||||
/obj/item/clothing/under/christmas/christmasfemaleg = 3,
|
||||
/obj/item/clothing/head/christmashat = 3,
|
||||
/obj/item/clothing/head/christmashatg = 3,
|
||||
/obj/item/clothing/under/drfreeze = 1) //End of Cit Changes
|
||||
refill_canister = /obj/item/vending_refill/autodrobe
|
||||
|
||||
|
||||
@@ -123,15 +123,19 @@
|
||||
/obj/item/clothing/ears/headphones = 10,
|
||||
/obj/item/clothing/suit/apron/purple_bartender = 4,
|
||||
/obj/item/clothing/under/rank/bartender/purple = 4,
|
||||
/* Commenting out until next Christmas or made automatic
|
||||
/obj/item/clothing/under/christmas/christmasmaler = 3,
|
||||
/obj/item/clothing/under/christmas/christmasmaleg = 3,
|
||||
/obj/item/clothing/under/christmas/christmasfemaler = 3,
|
||||
/obj/item/clothing/under/christmas/christmasfemaleg = 3,
|
||||
*/
|
||||
/obj/item/clothing/suit/hooded/wintercoat/christmascoatr = 3,
|
||||
/obj/item/clothing/suit/hooded/wintercoat/christmascoatg = 3,
|
||||
/obj/item/clothing/suit/hooded/wintercoat/christmascoatrg = 3,
|
||||
/*Commenting out until next Christmas or made automatic
|
||||
/obj/item/clothing/head/christmashat = 3,
|
||||
/obj/item/clothing/head/christmashatg = 3,
|
||||
*/
|
||||
/obj/item/clothing/shoes/winterboots/christmasbootsr = 3,
|
||||
/obj/item/clothing/shoes/winterboots/christmasbootsg = 3,
|
||||
/obj/item/clothing/shoes/winterboots/santaboots = 3,
|
||||
|
||||
4
html/changelogs/AutoChangeLog-pr-10287.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
author: "Ghommie"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscdel: "Removed an old pair of zipties from the captain closet."
|
||||
4
html/changelogs/AutoChangeLog-pr-10404.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
author: "Xantholne"
|
||||
delete-after: True
|
||||
changes:
|
||||
- tweak: "Christmas clothes moved from clothesmate and loadout to premium autodrobe, hoodies and boots remain."
|
||||
4
html/changelogs/AutoChangeLog-pr-10478.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
author: "Seris02"
|
||||
delete-after: True
|
||||
changes:
|
||||
- tweak: "makes gorilla shuttle emag only"
|
||||
4
html/changelogs/AutoChangeLog-pr-10493.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
author: "Putnam3145"
|
||||
delete-after: True
|
||||
changes:
|
||||
- tweak: "Score instead of ranked choice for mode tiers"
|
||||
4
html/changelogs/AutoChangeLog-pr-10507.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
author: "LetterN"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "Adds banjo"
|
||||
5
html/changelogs/AutoChangeLog-pr-10539.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
author: "Savotta"
|
||||
delete-after: True
|
||||
changes:
|
||||
- rscadd: "snout"
|
||||
- imageadd: "snout"
|
||||
4
html/changelogs/AutoChangeLog-pr-10556.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
author: "AffectedArc07"
|
||||
delete-after: True
|
||||
changes:
|
||||
- tweak: "Added CI step to check for CRLF files"
|
||||
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
@@ -93,6 +93,7 @@
|
||||
restricted_desc = "Engineering, Security, and Cargo"
|
||||
restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster")
|
||||
|
||||
/*Commenting out Until next Christmas or made automatic
|
||||
/datum/gear/santahatr
|
||||
name = "Red Santa Hat"
|
||||
category = SLOT_HEAD
|
||||
@@ -102,6 +103,7 @@
|
||||
name = "Green Santa Hat"
|
||||
category = SLOT_HEAD
|
||||
path = /obj/item/clothing/head/christmashatg
|
||||
*/
|
||||
|
||||
/datum/gear/cowboyhat
|
||||
name = "Cowboy Hat, Brown"
|
||||
@@ -129,6 +131,3 @@
|
||||
path = /obj/item/clothing/head/cowboyhat/sec
|
||||
restricted_desc = "Security"
|
||||
restricted_roles = list("Warden","Detective","Security Officer","Head of Security")
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -390,6 +390,7 @@
|
||||
path = /obj/item/clothing/under/gear_harness
|
||||
|
||||
//Christmas
|
||||
/*Commenting out Until next Christmas or made automatic
|
||||
/datum/gear/christmasmaler
|
||||
name = "Red Masculine Christmas Suit"
|
||||
category = SLOT_W_UNIFORM
|
||||
@@ -415,6 +416,7 @@
|
||||
category = SLOT_W_UNIFORM
|
||||
path = /obj/item/clothing/under/stripper_pink
|
||||
cost = 3
|
||||
*/
|
||||
|
||||
/datum/gear/greenstripper
|
||||
name = "Green stripper outfit"
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |