[MIRROR] Abductors can no longer be converted by conversion antags (#29310)

* Abductors can no longer be converted by conversion antags (#84766)

## About The Pull Request

Basically what the title says. Abductors cannot be converted by
bloodbrother/revs/cult. They will NOT show up as having a mindshield,
however.
## Why It's Good For The Game

Abductors are, by design, incredibly strong. You are not meant to be
able to win against them, and this is reflected policy-wise by the fact
that they're a restricted antagonist. However, this is still a problem
when conversion antags get involved. If an abductor becomes a cultist or
a revolutionary, then suddenly every other player who isn't also
converted has to deal with an abductor without the normal restrictions.
It's not fun to play against and in general just shouldn't happen.
## Changelog
🆑
balance: Abductors (the antag, not the species) can no longer be
converted by any antagonist.
/🆑

* Abductors can no longer be converted by conversion antags

---------

Co-authored-by: GPeckman <21979502+GPeckman@users.noreply.github.com>
This commit is contained in:
SkyratBot
2024-08-15 11:50:44 +02:00
committed by GitHub
parent 80bf0d1971
commit c9e8162a8a
18 changed files with 35 additions and 32 deletions
+3
View File
@@ -263,7 +263,10 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_NODEATH "nodeath"
#define TRAIT_NOHARDCRIT "nohardcrit"
#define TRAIT_NOSOFTCRIT "nosoftcrit"
/// Makes someone show up as mindshielded on sechuds. Does NOT actually make them unconvertable - See TRAIT_UNCONVERTABLE for that
#define TRAIT_MINDSHIELD "mindshield"
/// Makes it impossible for someone to be converted by cult/revs/etc.
#define TRAIT_UNCONVERTABLE "unconvertable"
#define TRAIT_DISSECTED "dissected"
#define TRAIT_SURGICALLY_ANALYZED "surgically_analyzed"
/// Lets the user succumb even if they got NODEATH
+1
View File
@@ -506,6 +506,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_TUMOR_SUPPRESSION" = TRAIT_TUMOR_SUPPRESSED,
"TRAIT_UI_BLOCKED" = TRAIT_UI_BLOCKED,
"TRAIT_UNBREAKABLE" = TRAIT_UNBREAKABLE,
"TRAIT_UNCONVERTABLE" = TRAIT_UNCONVERTABLE,
"TRAIT_UNDENSE" = TRAIT_UNDENSE,
"TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE" = TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE,
"TRAIT_UNHUSKABLE" = TRAIT_UNHUSKABLE,
+1
View File
@@ -289,6 +289,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list(
"TRAIT_TRAIT_MEDIBOTCOMINGTHROUGH" = TRAIT_MEDIBOTCOMINGTHROUGH,
"TRAIT_TUMOR_SUPPRESSION" = TRAIT_TUMOR_SUPPRESSED,
"TRAIT_UI_BLOCKED" = TRAIT_UI_BLOCKED,
"TRAIT_UNCONVERTABLE" = TRAIT_UNCONVERTABLE,
"TRAIT_UNDENSE" = TRAIT_UNDENSE,
"TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE" = TRAIT_UNDERWATER_BASKETWEAVING_KNOWLEDGE,
"TRAIT_UNHUSKABLE" = TRAIT_UNHUSKABLE,
@@ -175,7 +175,7 @@
/// Checks for revhead loss conditions and other antag datums.
/datum/dynamic_ruleset/latejoin/provocateur/proc/check_eligible(datum/mind/M)
var/turf/T = get_turf(M.current)
if(!considered_afk(M) && considered_alive(M) && is_station_level(T.z) && !M.antag_datums?.len && !HAS_TRAIT(M, TRAIT_MINDSHIELD))
if(!considered_afk(M) && considered_alive(M) && is_station_level(T.z) && !M.antag_datums?.len && !HAS_MIND_TRAIT(M.current, TRAIT_UNCONVERTABLE))
return TRUE
return FALSE
@@ -574,7 +574,7 @@ GLOBAL_VAR_INIT(revolutionary_win, FALSE)
/// Checks for revhead loss conditions and other antag datums.
/datum/dynamic_ruleset/roundstart/revs/proc/check_eligible(datum/mind/M)
var/turf/T = get_turf(M.current)
if(!considered_afk(M) && considered_alive(M) && is_station_level(T.z) && !M.antag_datums?.len && !HAS_TRAIT(M, TRAIT_MINDSHIELD))
if(!considered_afk(M) && considered_alive(M) && is_station_level(T.z) && !M.antag_datums?.len && !HAS_MIND_TRAIT(M.current, TRAIT_UNCONVERTABLE))
return TRUE
return FALSE
+1 -1
View File
@@ -209,7 +209,7 @@
return ..()
/datum/component/mind_linker/active_linking/link_mob(mob/living/to_link)
if(HAS_TRAIT(to_link, TRAIT_MINDSHIELD)) // Mindshield implant - no dice
if(HAS_MIND_TRAIT(to_link, TRAIT_UNCONVERTABLE)) // Protected mind, so they can't be added to the mindlink
return FALSE
if(to_link.can_block_magic(MAGIC_RESISTANCE_MIND, charge_cost = 0))
return FALSE
-1
View File
@@ -64,7 +64,6 @@
///If this mind's master is another mob (i.e. adamantine golems). Weakref of a /living.
var/datum/weakref/enslaved_to
var/unconvertable = FALSE
var/late_joiner = FALSE
/// has this mind ever been an AI
var/has_ever_been_ai = FALSE
@@ -20,7 +20,7 @@
if(!.)
return FALSE
if(target.mind)
if((SEND_SIGNAL(target.mind, COMSIG_PRE_MINDSHIELD_IMPLANT, user) & COMPONENT_MINDSHIELD_RESISTED) || target.mind.unconvertable)
if((SEND_SIGNAL(target.mind, COMSIG_PRE_MINDSHIELD_IMPLANT, user) & COMPONENT_MINDSHIELD_RESISTED))
if(!silent)
target.visible_message(span_warning("[target] seems to resist the implant!"), span_warning("You feel something interfering with your mental conditioning, but you resist it!"))
removed(target, TRUE)
@@ -30,7 +30,7 @@
if(prob(1) || check_holidays(APRIL_FOOLS))
target.say("I'm out! I quit! Whose kidneys are these?", forced = "They're out! They quit! Whose kidneys do they have?")
ADD_TRAIT(target, TRAIT_MINDSHIELD, IMPLANT_TRAIT)
target.add_traits(list(TRAIT_MINDSHIELD, TRAIT_UNCONVERTABLE), IMPLANT_TRAIT)
target.sec_hud_set_implants()
if(!silent)
to_chat(target, span_notice("You feel a sense of peace and security. You are now protected from brainwashing."))
@@ -42,7 +42,7 @@
return FALSE
if(isliving(target))
var/mob/living/L = target
REMOVE_TRAIT(L, TRAIT_MINDSHIELD, IMPLANT_TRAIT)
target.remove_traits(list(TRAIT_MINDSHIELD, TRAIT_UNCONVERTABLE), IMPLANT_TRAIT)
L.sec_hud_set_implants()
if(target.stat != DEAD && !silent)
to_chat(target, span_boldnotice("Your mind suddenly feels terribly vulnerable. You are no longer safe from brainwashing."))
@@ -191,7 +191,7 @@
objective = tgui_input_text(user, "What order do you want to imprint on [C]?", "Brainwashing", max_length = 120)
message_admins("[ADMIN_LOOKUPFLW(user)] set brainwash machine objective to '[objective]'.")
user.log_message("set brainwash machine objective to '[objective]'.", LOG_GAME)
if(HAS_TRAIT(C, TRAIT_MINDSHIELD))
if(HAS_MIND_TRAIT(C, TRAIT_UNCONVERTABLE))
return FALSE
brainwash(C, objective)
message_admins("[ADMIN_LOOKUPFLW(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
+2
View File
@@ -81,6 +81,8 @@ GLOBAL_VAR(antag_prototypes)
result += "<span class='bad'>No body!</span>"
if(current && HAS_TRAIT(current, TRAIT_MINDSHIELD))
result += "<span class='good'>Mindshielded</span>"
if(current && HAS_MIND_TRAIT(current, TRAIT_UNCONVERTABLE))
result += "<span class='good'>Unconvertable</span>"
//Move these to mob
if(iscyborg(current))
var/mob/living/silicon/robot/robot = current
+13 -12
View File
@@ -79,12 +79,13 @@
owner.special_role = ROLE_ABDUCTOR
objectives += team.objectives
finalize_abductor()
ADD_TRAIT(owner, TRAIT_ABDUCTOR_TRAINING, ABDUCTOR_ANTAGONIST)
// We don't want abductors to be converted by other antagonists
owner.add_traits(list(TRAIT_ABDUCTOR_TRAINING, TRAIT_UNCONVERTABLE), ABDUCTOR_ANTAGONIST)
return ..()
/datum/antagonist/abductor/on_removal()
owner.special_role = null
REMOVE_TRAIT(owner, TRAIT_ABDUCTOR_TRAINING, ABDUCTOR_ANTAGONIST)
owner.remove_traits(list(TRAIT_ABDUCTOR_TRAINING, TRAIT_UNCONVERTABLE), ABDUCTOR_ANTAGONIST)
return ..()
/datum/antagonist/abductor/greet()
@@ -95,20 +96,20 @@
/datum/antagonist/abductor/proc/finalize_abductor()
//Equip
var/mob/living/carbon/human/H = owner.current
H.set_species(/datum/species/abductor)
var/obj/item/organ/internal/tongue/abductor/T = H.get_organ_slot(ORGAN_SLOT_TONGUE)
T.mothership = "[team.name]"
var/mob/living/carbon/human/new_abductor = owner.current
new_abductor.set_species(/datum/species/abductor)
var/obj/item/organ/internal/tongue/abductor/abductor_tongue = new_abductor.get_organ_slot(ORGAN_SLOT_TONGUE)
abductor_tongue.mothership = "[team.name]"
H.real_name = "[team.name] [sub_role]"
H.equipOutfit(outfit)
new_abductor.real_name = "[team.name] [sub_role]"
new_abductor.equipOutfit(outfit)
// We require that the template be loaded here, so call it in a blocking manner, if its already done loading, this won't block
SSmapping.lazy_load_template(LAZY_TEMPLATE_KEY_ABDUCTOR_SHIPS)
//Teleport to ship
for(var/obj/effect/landmark/abductor/LM in GLOB.landmarks_list)
if(istype(LM, landmark_type) && LM.team_number == team.team_number)
H.forceMove(LM.loc)
new_abductor.forceMove(LM.loc)
break
/datum/antagonist/abductor/scientist/on_gain()
@@ -142,13 +143,13 @@
if(!ishuman(owner.current))
to_chat(admin, span_warning("This only works on humans!"))
return
var/mob/living/carbon/human/H = owner.current
var/mob/living/carbon/human/new_abductor = owner.current
var/gear = tgui_alert(admin,"Agent or Scientist Gear", "Gear", list("Agent", "Scientist"))
if(gear)
if(gear == "Agent")
H.equipOutfit(/datum/outfit/abductor/agent)
new_abductor.equipOutfit(/datum/outfit/abductor/agent)
else
H.equipOutfit(/datum/outfit/abductor/scientist)
new_abductor.equipOutfit(/datum/outfit/abductor/scientist)
/datum/team/abductor_team
member_name = "\improper Abductor"
@@ -15,7 +15,7 @@
for(var/mob/living/carbon/target in orange(4,owner_turf))
if(target == owner)
continue
if(HAS_TRAIT(target, TRAIT_MINDSHIELD))
if(HAS_MIND_TRAIT(target, TRAIT_MINDSHIELD))
to_chat(target, span_notice("You hear a faint hum fill your ears, which quickly dies down."))
continue
@@ -41,7 +41,7 @@
if(target_human.stat)
continue
if(HAS_TRAIT(target_human, TRAIT_MINDSHIELD))
if(HAS_MIND_TRAIT(target_human, TRAIT_UNCONVERTABLE))
to_chat(target_human, span_notice("You hear a low drone as something foreign attempts to enter your mind, but the noise fades after a few moments."))
continue
+1 -1
View File
@@ -94,7 +94,7 @@
flashed.balloon_alert(source, "[flashed.p_theyre()] loyal to someone else!")
return
if (HAS_TRAIT(flashed, TRAIT_MINDSHIELD))
if (HAS_TRAIT(flashed, TRAIT_UNCONVERTABLE))
flashed.balloon_alert(source, "[flashed.p_they()] resist!")
return
+1 -3
View File
@@ -25,8 +25,6 @@
return FALSE
#endif
if(target.mind.unconvertable)
return FALSE
if(ishuman(target) && target.mind.holy_role)
return FALSE
if(specific_cult?.is_sacrifice_target(target.mind))
@@ -36,6 +34,6 @@
return FALSE
if(IS_HERETIC_OR_MONSTER(target))
return FALSE
if(HAS_TRAIT(target, TRAIT_MINDSHIELD) || issilicon(target) || isbot(target) || isdrone(target))
if(HAS_MIND_TRAIT(target, TRAIT_UNCONVERTABLE) || issilicon(target) || isbot(target) || isdrone(target))
return FALSE //can't convert machines, shielded, or braindead
return TRUE
@@ -234,7 +234,7 @@
to_chat(crewmate, span_boldwarning("[user]'s rise is influencing those who are weak willed. Their minds shall rend." ))
continue
// Mindshielded and anti-magic folks are immune against this effect because this is a magical mind effect
if(HAS_TRAIT(crewmate, TRAIT_MINDSHIELD) || crewmate.can_block_magic(MAGIC_RESISTANCE))
if(HAS_MIND_TRAIT(crewmate, TRAIT_UNCONVERTABLE) || crewmate.can_block_magic(MAGIC_RESISTANCE))
to_chat(crewmate, span_boldwarning("You feel shielded from something." ))
continue
if(amount_of_lunatics > length(GLOB.human_list) * 0.2)
@@ -15,9 +15,7 @@
/datum/antagonist/rev/can_be_owned(datum/mind/new_owner)
if(new_owner.assigned_role.job_flags & JOB_HEAD_OF_STAFF)
return FALSE
if(new_owner.unconvertable)
return FALSE
if(new_owner.current && HAS_TRAIT(new_owner.current, TRAIT_MINDSHIELD))
if(new_owner.current && HAS_MIND_TRAIT(new_owner.current, TRAIT_UNCONVERTABLE))
return FALSE
return ..()
+1 -1
View File
@@ -1221,7 +1221,7 @@
return bodyparts.len > 2 && ..()
/mob/living/carbon/proc/hypnosis_vulnerable()
if(HAS_TRAIT(src, TRAIT_MINDSHIELD))
if(HAS_MIND_TRAIT(src, TRAIT_UNCONVERTABLE))
return FALSE
if(has_status_effect(/datum/status_effect/hallucination) || has_status_effect(/datum/status_effect/drugginess))
return TRUE
@@ -86,7 +86,7 @@
if(!target.mind)
to_chat(user, span_warning("[target] doesn't respond to the brainwashing, as if [target.p_they()] lacked a mind..."))
return FALSE
if(HAS_TRAIT(target, TRAIT_MINDSHIELD))
if(HAS_MIND_TRAIT(target, TRAIT_UNCONVERTABLE))
to_chat(user, span_warning("You hear a faint buzzing from a device inside [target]'s brain, and the brainwashing is erased."))
return FALSE
display_results(