diff --git a/code/__HELPERS/hearted.dm b/code/__HELPERS/hearted.dm index 18d45abc18a..860022a2a85 100644 --- a/code/__HELPERS/hearted.dm +++ b/code/__HELPERS/hearted.dm @@ -1,8 +1,10 @@ /// Called when the shuttle starts launching back to centcom, polls a few random players who joined the round for commendations /datum/controller/subsystem/ticker/proc/poll_hearts() - if(!CONFIG_GET(number/commendations)) + if(!CONFIG_GET(number/commendation_percent_poll)) return - var/number_to_ask = round(LAZYLEN(GLOB.joined_player_list) * CONFIG_GET(number/commendations)) + rand(0,1) + + var/number_to_ask = round(LAZYLEN(GLOB.joined_player_list) * CONFIG_GET(number/commendation_percent_poll)) + rand(0,1) + message_admins("Polling [number_to_ask] players for commendations.") for(var/i in GLOB.joined_player_list) var/mob/check_mob = get_mob_by_ckey(i) @@ -11,24 +13,21 @@ // maybe some other filters like bans or whatever INVOKE_ASYNC(check_mob, /mob.proc/query_heart, 1) number_to_ask-- - if(number_to_ask == 0) + if(number_to_ask <= 0) break -/// Once the round is actually over, cycle through the commendations in the hearts list and give them the hearted status +/// Once the round is actually over, cycle through the ckeys in the hearts list and give them the hearted status /datum/controller/subsystem/ticker/proc/handle_hearts() - for(var/i in hearts) - var/mob/heart_winner = i - if(!heart_winner.mind || !heart_winner.client) + var/list/message = list("The following players were commended this round: ") + var/i = 0 + for(var/hearted_ckey in hearts) + i++ + var/mob/hearted_mob = get_mob_by_ckey(hearted_ckey) + if(!hearted_mob?.client) continue - heart_winner.client.prefs.hearted_until = world.realtime + 24 HOURS // make configable - if(!heart_winner.client) - return - - heart_winner.client.prefs.hearted = TRUE // so they get it right away - if(!heart_winner.client) - return - heart_winner.client.prefs.save_preferences() - tgui_alert(heart_winner, "Someone anonymously thanked you for being kind during the last round!", "<3!", list("Okay")) + hearted_mob.client.adjust_heart() + message += "[hearted_ckey][i==hearts.len ? "" : ", "]" + message_admins(message.Join()) /// Ask someone if they'd like to award a commendation for the round, 3 tries to get the name they want before we give up /mob/proc/query_heart(attempt=1) @@ -67,16 +66,26 @@ return if("Nope") continue - if("Cancel") + else return query_heart(attempt + 1) -/// Once we've confirmed who we're commendating, log it and add them to the hearts list -/mob/proc/nominate_heart(mob/heart_recepient) - if(!mind || !client) +/* +* Once we've confirmed who we're commending, either set their status now or log it for the end of the round +* +* Arguments: +* * heart_recepient: The reference to the mob who we want to commend. Note that if we delay to the end of the round, we log the mob's current ckey in case they change bodies +* * duration: How long from the moment it's applied the heart will last +* * instant: If TRUE (or if the round is already over), we'll give them the heart status now, if FALSE, we wait until the end of the round (which is the standard behavior) +*/ +/mob/proc/nominate_heart(mob/heart_recepient, duration = 24 HOURS, instant = FALSE) + if(!mind || !client || !heart_recepient?.client) return to_chat(src, "Commendation sent!") - message_admins("[key_name(src)] commended [key_name(heart_recepient)] (CANCEL)") // cancel is probably unnecessary without messages - log_admin("[key_name(src)] commended [key_name(heart_recepient)]") - LAZYADD(SSticker.hearts, heart_recepient) + message_admins("[key_name(src)] commended [key_name(heart_recepient)] [instant ? "" : "(roundend)"]") + log_admin("[key_name(src)] commended [key_name(heart_recepient)] [instant ? "" : "(roundend)"]") + if(instant || SSticker.current_state == GAME_STATE_FINISHED) + heart_recepient.client?.adjust_heart(duration) + else + LAZYADD(SSticker.hearts, heart_recepient.ckey) diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index 38bd3174d62..37948ccada6 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -200,8 +200,13 @@ /datum/config_entry/flag/ooc_during_round +// deprecated for unclear name /datum/config_entry/number/commendations integer = FALSE + deprecated_by = /datum/config_entry/number/commendation_percent_poll + +/datum/config_entry/number/commendation_percent_poll + integer = FALSE /datum/config_entry/flag/emojis diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 0729e3e1fba..e08f15c97b1 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -699,12 +699,3 @@ SUBSYSTEM_DEF(ticker) SEND_SOUND(M.client, end_of_round_sound_ref) text2file(login_music, "data/last_round_lobby_music.txt") - -/datum/controller/subsystem/ticker/Topic(href, list/href_list) - . = ..() - if(href_list["cancel_heart"] && usr.client.holder) - var/mob/heart_sender = locate(href_list["heart_source"]) - var/mob/intended_recepient = locate(href_list["heart_target"]) - log_admin("[usr.ckey] blocked commendation from [heart_sender] ([heart_sender.ckey]) to [intended_recepient] ([intended_recepient.ckey])") - message_admins("[usr.ckey] blocked commendation from [heart_sender] ([heart_sender.ckey]) to [intended_recepient] ([intended_recepient.ckey])") - hearts[intended_recepient] = null diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index b30e59ee79a..e0c4f3f7804 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -2200,9 +2200,17 @@ to_chat(usr, "The round must be in progress to use this!") return var/mob/heart_recepient = locate(href_list["admincommend"]) - if(tgui_alert(usr, "Are you sure you'd like to anonymously commend [heart_recepient.ckey]? NOTE: This is logged, please use this sparingly and only for actual kind behavior, not as a reward for your friends.", "<3?", list("Yes", "No")) == "No") + if(!heart_recepient?.ckey) + to_chat(usr, "This mob either no longer exists or no longer is being controlled by someone!") return - usr.nominate_heart(heart_recepient) + + switch(tgui_alert(usr, "Would you like the effects to apply immediately or at the end of the round? Applying them now will make it clear it was an admin commendation.", "<3?", list("Apply now", "Apply at round end", "Cancel"))) + if("Apply now") + usr.nominate_heart(heart_recepient, instant = TRUE) + if("Apply at round end") + usr.nominate_heart(heart_recepient) + else + return else if(href_list["force_war"]) if(!check_rights(R_ADMIN)) diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 754daeea263..56c85e9440b 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -809,7 +809,6 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) nameWords += string for(var/string in nameWords) - testing("Name word [string]") if(string in msglist) potential_hits += M break diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index ce2f5aa5091..4764ca63f19 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -1048,15 +1048,14 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( /client/proc/get_award_status(achievement_type, mob/user, value = 1) return player_details.achievements.get_achievement_status(achievement_type) -///Redirect proc that makes it easier to get the status of an achievement. Achievement type is the typepath to the award. -/client/proc/award_heart(heart_reason) - to_chat(src, "Someone awarded you a heart![heart_reason ? " They said: [heart_reason]!" : ""]") - if(!src) +///Gives someone hearted status for OOC, from behavior commendations +/client/proc/adjust_heart(duration = 24 HOURS) + var/new_duration = world.realtime + duration + if(prefs.hearted_until > new_duration) return - prefs.hearted_until = world.realtime + (24 HOURS) + to_chat(src, "Someone awarded you a heart!") + prefs.hearted_until = new_duration prefs.hearted = TRUE - if(!src) - return prefs.save_preferences() /// compiles a full list of verbs and sends it to the browser diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm index 25269a4d330..3e591487a9d 100644 --- a/code/modules/client/verbs/ooc.dm +++ b/code/modules/client/verbs/ooc.dm @@ -56,12 +56,12 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8") mob.log_talk(raw_msg, LOG_OOC) var/keyname = key - if(prefs.hearted) - var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/chat) - keyname = "[sheet.icon_tag("emoji-heart")][keyname]" if(prefs.unlock_content) if(prefs.toggles & MEMBER_PUBLIC) keyname = "[icon2html('icons/member_content.dmi', world, "blag")][keyname]" + if(prefs.hearted) + var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/chat) + keyname = "[sheet.icon_tag("emoji-heart")][keyname]" //The linkify span classes and linkify=TRUE below make ooc text get clickable chat href links if you pass in something resembling a url for(var/client/C in GLOB.clients) if(C.prefs.chat_toggles & CHAT_OOC) diff --git a/config/game_options.txt b/config/game_options.txt index b27b045fef0..17d3f0a512c 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -20,8 +20,8 @@ OOC_DURING_ROUND EMOJIS ## HEART COMMENDATIONS ### -## Uncomment this if you'd like to enable commendation pollings for this percentage of players near the end of the round (5% default) -## COMMENDATIONS 0.05 +## Uncomment this if you'd like to enable commendation pollings for this percentage of players near the end of the round (5% suggested) +COMMENDATION_PERCENT_POLL 0.05 ## MOB MOVEMENT ###