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 66225c4c577..057d8db01c4 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 fc002e1d0b5..b934c62ecd6 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -680,12 +680,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 1120dc2ad81..95661a8082c 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -2184,9 +2184,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 9776b1cf5d4..0392dfd068b 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -744,7 +744,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 92959c71c62..ce7b7794823 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -1018,15 +1018,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 415f0bf497a..501749c3bc3 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 ###