Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Makes revolution objectives softer #11107

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 0 additions & 76 deletions code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm
Original file line number Diff line number Diff line change
Expand Up @@ -77,82 +77,6 @@
/datum/dynamic_ruleset/roundstart/hivemind
)

//////////////////////////////////////////////
// //
// REVOLUTIONARY PROVOCATEUR //
// //
//////////////////////////////////////////////

/datum/dynamic_ruleset/latejoin/provocateur
name = "Provocateur"
persistent = TRUE
antag_datum = /datum/antagonist/rev/head
role_preference = /datum/role_preference/antagonist/revolutionary
restricted_roles = list(JOB_NAME_AI, JOB_NAME_CYBORG, JOB_NAME_SECURITYOFFICER, JOB_NAME_WARDEN, JOB_NAME_DETECTIVE, JOB_NAME_HEADOFSECURITY, JOB_NAME_CAPTAIN, JOB_NAME_HEADOFPERSONNEL, JOB_NAME_CHIEFENGINEER, JOB_NAME_CHIEFMEDICALOFFICER, JOB_NAME_RESEARCHDIRECTOR)
enemy_roles = list(JOB_NAME_AI, JOB_NAME_CYBORG, JOB_NAME_SECURITYOFFICER,JOB_NAME_DETECTIVE,JOB_NAME_HEADOFSECURITY, JOB_NAME_CAPTAIN, JOB_NAME_WARDEN)
required_enemies = list(2,2,1,1,1,1,1,0,0,0)
required_candidates = 1
weight = 2
delay = 1 MINUTES // Prevents rule start while head is offstation.
cost = 13
requirements = list(101,101,70,40,30,20,20,20,20,20)
flags = HIGH_IMPACT_RULESET|INTACT_STATION_RULESET
blocking_rules = list(/datum/dynamic_ruleset/roundstart/revs)
var/required_heads_of_staff = 3
var/finished = FALSE
/// How much threat should be injected when the revolution wins?
var/revs_win_threat_injection = 20
var/datum/team/revolution/revolution

/datum/dynamic_ruleset/latejoin/provocateur/ready(forced=FALSE)
if (forced)
required_heads_of_staff = 1
if(!..())
return FALSE
var/head_check = 0
for(var/mob/player in mode.current_players[CURRENT_LIVING_PLAYERS])
if (player.mind.assigned_role in GLOB.command_positions)
head_check++
return (head_check >= required_heads_of_staff)

/datum/dynamic_ruleset/latejoin/provocateur/execute(forced = FALSE)
var/mob/M = pick(candidates) // This should contain a single player, but in case.
if(check_eligible(M.mind)) // Didnt die/run off z-level/get implanted since leaving shuttle.
assigned += M.mind
M.mind.special_role = ROLE_REV_HEAD
revolution = new()
var/datum/antagonist/rev/head/new_head = new()
new_head.give_flash = TRUE
new_head.give_hud = TRUE
new_head.remove_clumsy = TRUE
new_head = M.mind.add_antag_datum(new_head, revolution)
revolution.update_objectives()
revolution.update_heads()
SSshuttle.registerHostileEnvironment(revolution)
return DYNAMIC_EXECUTE_SUCCESS
else
log_game("DYNAMIC: [ruletype] [name] discarded [M.name] from head revolutionary due to ineligibility.")
log_game("DYNAMIC: [ruletype] [name] failed to get any eligible headrevs. Refunding [cost] threat.")
return DYNAMIC_EXECUTE_NOT_ENOUGH_PLAYERS

/datum/dynamic_ruleset/latejoin/provocateur/rule_process()
var/winner = revolution.process_victory(revs_win_threat_injection)
if (isnull(winner))
return

finished = winner
return RULESET_STOP_PROCESSING

/// Checks for revhead loss conditions and other antag datums.
/datum/dynamic_ruleset/latejoin/provocateur/proc/check_eligible(var/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))
return TRUE
return FALSE

/datum/dynamic_ruleset/latejoin/provocateur/round_result()
revolution.round_result(finished)

//////////////////////////////////////////////
// //
// HERETIC SMUGGLER //
Expand Down
2 changes: 0 additions & 2 deletions code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,6 @@
requirements = list(101,101,70,40,30,20,10,10,10,10)
antag_cap = 3
flags = HIGH_IMPACT_RULESET | NO_OTHER_ROUNDSTARTS_RULESET | PERSISTENT_RULESET
blocking_rules = list(/datum/dynamic_ruleset/latejoin/provocateur)
// I give up, just there should be enough heads with 35 players...
minimum_players = 35
/// How much threat should be injected when the revolution wins?
Expand Down Expand Up @@ -395,7 +394,6 @@
if(revolution.members.len)
revolution.update_objectives()
revolution.update_heads()
SSshuttle.registerHostileEnvironment(revolution)
return DYNAMIC_EXECUTE_SUCCESS
log_game("DYNAMIC: [ruletype] [name] failed to get any eligible headrevs. Refunding [cost] threat.")
return DYNAMIC_EXECUTE_NOT_ENOUGH_PLAYERS
Expand Down
10 changes: 6 additions & 4 deletions code/game/gamemodes/revolution/revolution.dm
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
antag_datum = /datum/antagonist/rev/head
false_report_weight = 10
restricted_jobs = list(JOB_NAME_SECURITYOFFICER, JOB_NAME_WARDEN, JOB_NAME_DETECTIVE, JOB_NAME_AI, JOB_NAME_CYBORG,JOB_NAME_CAPTAIN, JOB_NAME_HEADOFPERSONNEL, JOB_NAME_HEADOFSECURITY, JOB_NAME_CHIEFENGINEER, JOB_NAME_RESEARCHDIRECTOR, JOB_NAME_CHIEFMEDICALOFFICER)
required_jobs = list(list(JOB_NAME_CAPTAIN=1),list(JOB_NAME_HEADOFPERSONNEL=1),list(JOB_NAME_HEADOFSECURITY=1),list(JOB_NAME_CHIEFENGINEER=1),list(JOB_NAME_RESEARCHDIRECTOR=1),list(JOB_NAME_CHIEFMEDICALOFFICER=1)) //Any head present
required_jobs = list(list(JOB_NAME_CAPTAIN=1, JOB_NAME_LAWYER=1),list(JOB_NAME_HEADOFPERSONNEL=1),list(JOB_NAME_HEADOFSECURITY=1, JOB_NAME_LAWYER=1),list(JOB_NAME_CHIEFENGINEER=1, JOB_NAME_LAWYER=1),list(JOB_NAME_RESEARCHDIRECTOR=1, JOB_NAME_LAWYER=1),list(JOB_NAME_CHIEFMEDICALOFFICER=1, JOB_NAME_LAWYER=1)) //Any head present and a deconverter present
required_players = 30
required_enemies = 2
recommended_enemies = 3
Expand Down Expand Up @@ -159,9 +159,11 @@
//Checks for rev victory//
//////////////////////////
/datum/game_mode/revolution/proc/check_rev_victory()
for(var/datum/objective/mutiny/objective in revolution.objectives)
if(!(objective.check_completion()))
return FALSE
for(var/datum/mind/staff_mind in SSjob.get_all_heads())
var/turf/location = get_turf(staff_mind.current)
if(!considered_afk(staff_mind) && considered_alive(staff_mind) && is_station_level(location.z))
if(ishuman(staff_mind.current))
return FALSE
return TRUE

/////////////////////////////
Expand Down
47 changes: 47 additions & 0 deletions code/game/objects/items/manuals.dm
PowerfulBacon marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,53 @@
user.visible_message("<span class='suicide'>[user] pretends to read \the [src] intently... then promptly dies of laughter!</span>")
return OXYLOSS

/obj/item/book/manual/wiki/security_space_law/afterattack(atom/target, mob/living/user, proximity_flag, click_parameters)
. = ..()
if (target != user && isliving(target) && (user.mind.assigned_role == JOB_NAME_LAWYER || user.mind.assigned_role == JOB_NAME_HEADOFPERSONNEL))
INVOKE_ASYNC(src, PROC_REF(deconvert_target), user, target)

/obj/item/book/manual/wiki/security_space_law/proc/deconvert_target(mob/living/user, mob/living/target)
if (user.do_afters)
return
for (var/i in 1 to 4)
if (user.do_afters)
return
if (!do_after(user, 2 SECONDS, target))
return
if (user.mind?.has_antag_datum(/datum/antagonist/rev))
switch (i)
if (1)
user.say("Number One: In 1945, corporations paid 50% of federal taxes; now they pay about 5%.", forced="space law")
if (2)
user.say("Number Two: In 1900, 90% of people were self employed; now it's about 2%... It's called consolidation; strengthen governments and corporations, weaken individuals. With taxes, this can be done imperceptibly over time.", forced="space law")
if (3)
user.say("Number Three: In the 2030s, there were strict regulations to prevent monopolies; now those regulations have been dismantled, allowing a few companies to control entire industries. This concentration of power stifles competition and innovation.")
if (4)
user.say("Number Four: In the past, media outlets were independent; now a handful of conglomerates control the majority of information. Control the narrative, control the minds of the masses.")
else
var/datum/crime/chosen = pick(subtypesof(/datum/crime) - /datum/crime/minor - /datum/crime/capital - /datum/crime/major - /datum/crime/misdemeanour)
user.say("[initial(chosen.tooltip)]", forced = "space law")
if (user.do_afters)
return
if (!do_after(user, 2 SECONDS, target))
return
if (user.mind?.has_antag_datum(/datum/antagonist/rev))
var/datum/antagonist/rev/rev = user.mind.has_antag_datum(/datum/antagonist/rev)
user.say("Isn't it obvious, Nanotrasen, the governments; everyone around us has been tricking us, playing us like we are pawns...", forced = "space law")
if (rev.add_revolutionary(target.mind, FALSE))
target.visible_message("<span class='notice'>[target] nods in approval, taking in the information!</span>", "<span class='notice'>That all makes perfect sense, the truth washes over you!</span>")
else
target.visible_message("<span class='userdanger'>[target] spits on the floor, disrespecting [user]'s authority!</span>", "<span class='notice'>You finish listening to [user]'s waffling. What a knobhead, you think to yourself...</span>")
else
user.say("These shall all be considered acts which are in violation of your contract of employment, and you are contractually obliged to not commit them.", forced = "space law")
if(target.mind?.has_antag_datum(/datum/antagonist/rev/head) || target.mind?.unconvertable)
target.visible_message("<span class='userdanger'>[target] spits on the floor, disrespecting [user]'s authority!</span>", "<span class='notice'>You finish listening to [user]'s waffling. What a knobhead, you think to yourself...</span>")
return
var/datum/antagonist/rev/rev = target.mind?.has_antag_datum(/datum/antagonist/rev)
if(rev)
rev.remove_revolutionary(FALSE, user)
target.visible_message("<span class='notice'>[target] nods in approval, taking in the information!</span>", "<span class='notice'>That all makes perfect sense, you feel a sense of pride to be working for Nanotrasen!</span>")

/obj/item/book/manual/wiki/infections
name = "Infections - Making your own pandemic!"
icon_state = "bookInfections"
Expand Down
139 changes: 21 additions & 118 deletions code/modules/antagonists/revolution/revolution.dm
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
var/hud_type = "rev"
var/datum/team/revolution/rev_team

/// What message should the player receive when they are being demoted, and the revolution has won?
var/victory_message = "The revolution has overpowered the command staff! Viva la revolution! Execute any head of staff and security should you find them alive."

/datum/antagonist/rev/can_be_owned(datum/mind/new_owner)
. = ..()
if(.)
Expand Down Expand Up @@ -49,10 +46,10 @@
. = ..()

/datum/antagonist/rev/greet()
to_chat(owner, "<span class='userdanger'>You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Help them kill the heads to win the revolution!</span>")
to_chat(owner, "<span class='userdanger'>You are now a revolutionary! Help your cause. Do not harm your fellow freedom fighters. You can identify your comrades by the red \"R\" icons, and your leaders by the blue \"R\" icons. Establish a new command structure for the station that will bring fairness to all.</span>")
owner.announce_objectives()
owner.current.client?.tgui_panel?.give_antagonist_popup("Revolution",
"Eliminate the heads of staff. Viva la revolution!")
"Establish a new command structure to live a better life. Viva la revolution!")

/datum/antagonist/rev/create_team(datum/team/revolution/new_team)
if(!new_team)
Expand Down Expand Up @@ -212,38 +209,19 @@
new_rev.silent = FALSE
to_chat(old_owner, "<span class='userdanger'>Revolution has been disappointed of your leader traits! You are a regular revolutionary now!</span>")

/// Checks if the revolution succeeded, and lets them know.
/datum/antagonist/rev/proc/announce_victorious()
. = rev_team.check_rev_victory()

if (!.)
return

to_chat(owner, "<span class='deconversion_message bold'>[victory_message]</span>")

/datum/antagonist/rev/farewell()
if (announce_victorious())
return

if(ishuman(owner.current))
owner.current.visible_message("<span class='deconversion_message'>[owner.current] looks like [owner.current.p_theyve()] just remembered [owner.current.p_their()] real allegiance!</span>", null, null, null, owner.current)
to_chat(owner, "<span class='userdanger'>You are no longer a brainwashed revolutionary! Your memory is hazy from the time you were a rebel...the only thing you remember is the name of the one who brainwashed you...</span>")
else if(issilicon(owner.current))
owner.current.visible_message("<span class='deconversion_message'>The frame beeps contentedly, purging the hostile memory engram from the MMI before initalizing it.</span>", null, null, null, owner.current)
to_chat(owner, "<span class='userdanger'>The frame's firmware detects and deletes your neural reprogramming! You remember nothing but the name of the one who flashed you.</span>")

/datum/antagonist/rev/head/farewell()
if (announce_victorious())
return

if((ishuman(owner.current)))
if(owner.current.stat != DEAD)
owner.current.visible_message("<span class='deconversion_message'>[owner.current] looks like [owner.current.p_theyve()] just remembered [owner.current.p_their()] real allegiance!</span>", null, null, null, owner.current)
to_chat(owner, "<span class ='deconversion_message bold'>You have given up your cause of overthrowing the command staff. You are no longer a Head Revolutionary.</span>")
else
to_chat(owner, "<span class ='deconversion_message bold'>The sweet release of death. You are no longer a Head Revolutionary.</span>")
else if(issilicon(owner.current))
owner.current.visible_message("<span class='deconversion_message'>The frame beeps contentedly, suppressing the disloyal personality traits from the MMI before initalizing it.</span>", null, null, null, owner.current)
to_chat(owner, "<span class='userdanger'>The frame's firmware detects and suppresses your unwanted personality traits! You feel more content with the leadership around these parts.</span>")

//blunt trauma deconversions call this through species.dm spec_attacked_by()
Expand Down Expand Up @@ -287,38 +265,15 @@
S.Insert(H, special = FALSE, drop_if_replaced = FALSE)
to_chat(H, "Your eyes have been implanted with a cybernetic security HUD which will help you keep track of who is mindshield-implanted, and therefore unable to be recruited.")

/// "Enemy of the Revolutionary", given to heads and security when the revolution wins
/datum/antagonist/revolution_enemy
name = "Enemy of the Revolution"
show_in_antagpanel = FALSE
banning_key = UNBANNABLE_ANTAGONIST

/datum/antagonist/revolution_enemy/on_gain()
owner.special_role = "revolution enemy"

var/datum/objective/survive/survive = new /datum/objective/survive
survive.owner = owner
survive.explanation_text = "The station has been overrun by revolutionaries, stay alive until the end."
objectives += survive

return ..()

/datum/team/revolution
name = "Revolution"
var/max_headrevs = 3
var/list/ex_headrevs = list() // Dynamic removes revs on loss, used to keep a list for the roundend report.
var/list/ex_revs = list()

/datum/team/revolution/proc/update_objectives(initial = FALSE)
var/untracked_heads = SSjob.get_all_heads()
for(var/datum/objective/mutiny/O in objectives)
untracked_heads -= O.target
for(var/datum/mind/M in untracked_heads)
var/datum/objective/mutiny/new_target = new()
new_target.team = src
new_target.set_target(M)
new_target.update_explanation_text()
objectives += new_target
if (!objectives)
objectives += new /datum/objective/revolution()
for(var/datum/mind/M in members)
var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev)
R.objectives |= objectives
Expand Down Expand Up @@ -359,15 +314,13 @@

addtimer(CALLBACK(src,PROC_REF(update_heads)),HEAD_UPDATE_PERIOD,TIMER_UNIQUE)

/datum/team/revolution/proc/save_members()
ex_headrevs = get_antag_minds(/datum/antagonist/rev/head, TRUE)
ex_revs = get_antag_minds(/datum/antagonist/rev, TRUE)

/// Checks if revs have won
/datum/team/revolution/proc/check_rev_victory()
for(var/datum/objective/mutiny/objective in objectives)
if(!(objective.check_completion()))
return FALSE
for(var/datum/mind/staff_mind in SSjob.get_all_heads())
var/turf/location = get_turf(staff_mind.current)
if(!considered_afk(staff_mind) && considered_alive(staff_mind) && is_station_level(location.z))
if(ishuman(staff_mind.current))
return FALSE
return TRUE

/// Checks if heads have won
Expand All @@ -384,69 +337,9 @@
/// If revs_win_injection_amount is passed, then that amount of threat will be added if the revs win.
/datum/team/revolution/proc/process_victory(revs_win_injection_amount)
if (check_rev_victory())
. = REVOLUTION_VICTORY
return REVOLUTION_VICTORY
else if (check_heads_victory())
. = STATION_VICTORY
else
return

SSshuttle.clearHostileEnvironment(src)
save_members()

// Remove everyone as a revolutionary
for (var/_rev_mind in members)
var/datum/mind/rev_mind = _rev_mind
if (rev_mind.has_antag_datum(/datum/antagonist/rev))
var/datum/antagonist/rev/rev_antag = rev_mind.has_antag_datum(/datum/antagonist/rev)
rev_antag.remove_revolutionary(FALSE, . == STATION_VICTORY ? DECONVERTER_STATION_WIN : DECONVERTER_REVS_WIN)
LAZYADD(rev_mind.special_statuses, "<span class='bad'>Former [(rev_mind in ex_headrevs) ? "head revolutionary" : "revolutionary"]</span>")

if (. == STATION_VICTORY)
// If the revolution was quelled, make rev heads unable to be revived through pods
for (var/_rev_head_mind in ex_revs)
var/datum/mind/rev_head_mind = _rev_head_mind
var/mob/living/carbon/rev_head_body = rev_head_mind.current
if(istype(rev_head_body) && rev_head_body.stat == DEAD)
rev_head_body.makeUncloneable()

priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \
We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, SSstation.announcer.get_rand_report_sound(), null, "Central Command Loyalty Monitoring Division")
else
for (var/_player in GLOB.player_list)
var/mob/player = _player
var/datum/mind/mind = player.mind

if (isnull(mind))
continue

if (!(mind.assigned_role in GLOB.command_positions + GLOB.security_positions))
continue

var/mob/living/carbon/target_body = mind.current

mind.add_antag_datum(/datum/antagonist/revolution_enemy)

if (!istype(target_body))
continue

if (target_body.stat == DEAD)
target_body.makeUncloneable()
else
mind.announce_objectives()

for (var/job_name in GLOB.command_positions + GLOB.security_positions)
var/datum/job/job = SSjob.GetJob(job_name)
job.allow_bureaucratic_error = FALSE
job.total_positions = 0

if (revs_win_injection_amount)
var/datum/game_mode/dynamic/dynamic = SSticker.mode
dynamic.unfavorable_situation()

priority_announce("A recent assessment of your station has marked your station as a severe risk area for high ranking Nanotrasen officials. \
For the safety of our staff, we have blacklisted your station for new employment of security and command. \
[pick(world.file2list("strings/anti_union_propaganda.txt"))]", null, SSstation.announcer.get_rand_report_sound(), null, "Central Command Loyalty Monitoring Division")
addtimer(CALLBACK(SSshuttle.emergency, TYPE_PROC_REF(/obj/docking_port/mobile/emergency, request), null, 1), 50)
return STATION_VICTORY

/// Mutates the ticker to report that the revs have won
/datum/team/revolution/proc/round_result(finished)
Expand All @@ -456,6 +349,9 @@
else if (finished == STATION_VICTORY)
SSticker.mode_result = "loss - rev heads killed"
SSticker.news_report = REVS_LOSE
else
SSticker.mode_result = "minor win - station forced to be abandoned"
SSticker.news_report = STATION_EVACUATED

/datum/team/revolution/roundend_report()
if(!members.len && !ex_headrevs.len)
Expand Down Expand Up @@ -552,5 +448,12 @@
/datum/team/revolution/is_gamemode_hero()
return SSticker.mode.name == "revolution"

/datum/objective/revolution
name = "revolution"
explanation_text = "Establish a new chain of command by throwing out the old heads of staff and promoting new ones."

/datum/objective/revolution/get_completion_message()
return "[explanation_text]"

#undef DECONVERTER_STATION_WIN
#undef DECONVERTER_REVS_WIN
Loading