From 9976fab42b7af6feb4a05155dd31603cac9916c0 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 18 Apr 2020 14:40:41 -0700 Subject: [PATCH] Made traitor classes rerollable, reassignable by admins --- code/datums/mind.dm | 13 +++++ code/modules/admin/antag_panel.dm | 2 +- .../antagonists/traitor/classes/hijack.dm | 3 + .../traitor/classes/traitor_class.dm | 4 ++ .../antagonists/traitor/datum_traitor.dm | 56 ++++++++++++------- .../uplink/uplink_items/uplink_bundles.dm | 17 ++++++ 6 files changed, 75 insertions(+), 20 deletions(-) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 45a0f86a98..31704d5451 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -511,6 +511,19 @@ message_admins("[key_name_admin(usr)] edited [current]'s objective to [new_objective.explanation_text]") log_admin("[key_name(usr)] edited [current]'s objective to [new_objective.explanation_text]") + else if(href_list["traitor_class"]) + var/static/list/choices + if(!choices) + choices = list() + for(var/C in GLOB.traitor_classes) + var/datum/traitor_class/t = C + choices[initial(t.employer)] = C + var/datum/antagonist/traitor/T = locate(href_list["target_antag"]) in antag_datums + if(T) + var/selected_type = input("Select traitor class:", "Traitor class", T.traitor_kind.employer) as null|anything in choices + selected_type = choices[selected_type] + T.set_traitor_kind(selected_type) + else if (href_list["obj_delete"]) var/datum/objective/objective diff --git a/code/modules/admin/antag_panel.dm b/code/modules/admin/antag_panel.dm index 19e53b09b4..88aab2c4ce 100644 --- a/code/modules/admin/antag_panel.dm +++ b/code/modules/admin/antag_panel.dm @@ -104,7 +104,7 @@ GLOBAL_VAR(antag_prototypes) var/special_statuses = get_special_statuses() if(length(special_statuses)) - out += get_special_statuses() + "
" + out += special_statuses + "
" if(!GLOB.antag_prototypes) GLOB.antag_prototypes = list() diff --git a/code/modules/antagonists/traitor/classes/hijack.dm b/code/modules/antagonists/traitor/classes/hijack.dm index 59e0591600..dbfa78eb96 100644 --- a/code/modules/antagonists/traitor/classes/hijack.dm +++ b/code/modules/antagonists/traitor/classes/hijack.dm @@ -16,3 +16,6 @@ /datum/traitor_class/human/hijack/finalize_traitor(datum/antagonist/traitor/T) T.hijack_speed=1 return TRUE + +/datum/traitor_class/human/hijack/clean_up_traitor(datum/antagonist/traitor/T) + T.hijack_speed = 0.5 diff --git a/code/modules/antagonists/traitor/classes/traitor_class.dm b/code/modules/antagonists/traitor/classes/traitor_class.dm index 012a269572..260e978bec 100644 --- a/code/modules/antagonists/traitor/classes/traitor_class.dm +++ b/code/modules/antagonists/traitor/classes/traitor_class.dm @@ -38,3 +38,7 @@ GLOBAL_LIST_EMPTY(traitor_classes) /datum/traitor_class/proc/finalize_traitor(datum/antagonist/traitor/T) // Finalization. Return TRUE if should play standard traitor sound/equip, return FALSE if both are special case return TRUE + +/datum/traitor_class/proc/clean_up_traitor(datum/antagonist/traitor/T) + // Any effects that need to be cleaned up if traitor class is being swapped. + \ No newline at end of file diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index f7dc7ad6d1..cf10f87bf8 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -15,36 +15,53 @@ threat = 5 /datum/antagonist/traitor/New() - ..() if(!GLOB.traitor_classes.len)//Only need to fill the list when it's needed. for(var/I in subtypesof(/datum/traitor_class)) new I + ..() -/datum/antagonist/traitor/proc/set_traitor_kind(var/kind) +/datum/antagonist/traitor/proc/set_traitor_kind(kind) + var/swap_from_old = FALSE + if(traitor_kind) + traitor_kind.remove_innate_effects(owner.current) + traitor_kind.clean_up_traitor(src) + swap_from_old = TRUE traitor_kind = GLOB.traitor_classes[kind] + traitor_kind.apply_innate_effects(owner.current) + if(give_objectives) + for(var/O in objectives) + qdel(O) + traitor_kind.forge_objectives(src) + if(swap_from_old) + traitor_kind.finalize_traitor(src) + traitor_kind.greet(src) + owner.announce_objectives() + +/proc/get_random_traitor_kind(var/list/blacklist = list()) + var/chaos_weight = 0 + if(istype(SSticker.mode,/datum/game_mode/dynamic)) + var/datum/game_mode/dynamic/mode = SSticker.mode + chaos_weight = (mode.threat - 50)/50 + var/list/weights = list() + for(var/C in GLOB.traitor_classes) + if(!(C in blacklist)) + var/datum/traitor_class/class = GLOB.traitor_classes[C] + var/weight = LOGISTIC_FUNCTION(1.5*class.weight,chaos_weight,class.chaos,0) + weights[C] = weight * 1000 + var/choice = pickweightAllowZero(weights) + if(!choice) + choice = TRAITOR_HUMAN // it's an "easter egg" + var/datum/traitor_class/actual_class = GLOB.traitor_classes[choice] + actual_class.weight *= 0.8 // less likely this round + return choice /datum/antagonist/traitor/on_gain() if(owner.current && isAI(owner.current)) set_traitor_kind(TRAITOR_AI) else - var/chaos_weight = 0 - if(istype(SSticker.mode,/datum/game_mode/dynamic)) - var/datum/game_mode/dynamic/mode = SSticker.mode - chaos_weight = (mode.threat - 50)/50 - var/list/weights = list() - for(var/C in GLOB.traitor_classes) - var/datum/traitor_class/class = GLOB.traitor_classes[C] - var/weight = LOGISTIC_FUNCTION(1.5*class.weight,chaos_weight,class.chaos,0) - weights[C] = weight - var/choice = pickweightAllowZero(weights) - if(!choice) - choice = GLOB.traitor_classes[TRAITOR_HUMAN] // it's an "easter egg" - set_traitor_kind(choice) - traitor_kind.weight *= 0.8 // less likely this round + set_traitor_kind(get_random_traitor_kind()) SSticker.mode.traitors += owner owner.special_role = special_role - if(give_objectives) - traitor_kind.forge_objectives(src) finalize_traitor() ..() @@ -97,7 +114,8 @@ owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/tatoralert.ogg', 100, FALSE, pressure_affected = FALSE) /datum/antagonist/traitor/antag_panel_objectives() - . = ..() + . += "Traitor class: [traitor_kind.employer]
" + . += ..() if(contractor_hub?.assigned_targets && length(contractor_hub.assigned_targets)) . += "Contract Targets:
" for(var/datum/mind/M in contractor_hub.assigned_targets) diff --git a/code/modules/uplink/uplink_items/uplink_bundles.dm b/code/modules/uplink/uplink_items/uplink_bundles.dm index 7d0e52947a..f3e95fa61c 100644 --- a/code/modules/uplink/uplink_items/uplink_bundles.dm +++ b/code/modules/uplink/uplink_items/uplink_bundles.dm @@ -150,6 +150,23 @@ U.purchase_log.LogPurchase(goods, I, 0) return C +/datum/uplink_item/bundles_TC/reroll + name = "Renegotiate Contract" + desc = "Selecting this will inform the syndicate that you wish to change employers. Can only be done once; no take-backs." + item = /obj/effect/gibspawner/generic + cost = 0 + cant_discount = TRUE + restricted = TRUE + limited_stock = 1 + +/datum/uplink_item/bundles_TC/reroll/purchase(mob/user, datum/component/uplink/U) + var/datum/antagonist/traitor/T = user?.mind?.has_antag_datum(/datum/antagonist/traitor) + if(istype(T)) + var/new_traitor_kind = get_random_traitor_kind(list(T.traitor_kind.type)) + T.set_traitor_kind(new_traitor_kind) + else + to_chat(user,"Invalid user for contract renegotiation.") + /datum/uplink_item/bundles_TC/random name = "Random Item" desc = "Picking this will purchase a random item. Useful if you have some TC to spare or if you haven't decided on a strategy yet."