diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 113818f6a68..69c68d9c114 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -53,6 +53,8 @@ datum/mind var/datum/faction/faction //associated faction var/datum/changeling/changeling //changeling holder + var/rev_cooldown = 0 + New(var/key) src.key = key diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index c35c48bcd94..424c822d5ae 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -86,6 +86,39 @@ datum/objective/mutiny return 0 return 1 +datum/objective/mutiny/rp + find_target() + ..() + if(target && target.current) + explanation_text = "Assassinate, capture or convert [target.current.real_name], the [target.assigned_role]." + else + explanation_text = "Free Objective" + return target + + + find_target_by_role(role, role_type=0) + ..(role, role_type) + if(target && target.current) + explanation_text = "Assassinate, capture or convert [target.current.real_name], the [!role_type ? target.assigned_role : target.special_role]." + else + explanation_text = "Free Objective" + return target + + // less violent rev objectives + check_completion() + if(target && target.current) + if(target.current.stat == DEAD || target.current.handcuffed || !ishuman(target.current)) + return 1 + // Check if they're converted + if(istype(ticker.mode, /datum/game_mode/revolution)) + if(target in ticker.mode:head_revolutionaries) + return 1 + var/turf/T = get_turf(target.current) + if(T && (T.z != 1)) //If they leave the station they count as dead for this + return 2 + return 0 + return 1 + datum/objective/debrain//I want braaaainssss find_target() diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index fe03323c86b..a210d856cde 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -25,7 +25,7 @@ var/finished = 0 var/checkwin_counter = 0 - var/const/max_headrevs = 3 + var/max_headrevs = 3 var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) /////////////////////////// diff --git a/code/game/gamemodes/revolution/rp-revolution.dm b/code/game/gamemodes/revolution/rp-revolution.dm index 1c8d2367eeb..7456e73403b 100644 --- a/code/game/gamemodes/revolution/rp-revolution.dm +++ b/code/game/gamemodes/revolution/rp-revolution.dm @@ -280,46 +280,6 @@ return 1 -/*obj/item/weapon/paper/communist_manifesto - name = "Communist Manifesto" - icon = 'books.dmi' - icon_state = "redcommunist" - info = "Supporters of the Revolution:

" - attack(mob/living/carbon/M as mob, mob/user as mob) - if(user.mind in ticker.mode:head_revolutionaries) - if(RevConvert(M,user)) - for(var/mob/O in viewers(user, null)) - O.show_message(text("\red [] converts [] with the Communist Manifesto!", user, M)) - info += "[M.real_name]
" - else - for(var/mob/O in viewers(user, null)) - O.show_message(text("\red [] fails to convert [] with the Communist Manifesto!", user, M)) - else - usr << "\red You are completely confounded as to the operation of this tome." - return - -proc/RevConvert(mob/living/carbon/M,mob/user) - if(!istype(M)) return 0 - if((M.mind in ticker.mode:head_revolutionaries) || (M.mind in ticker.mode:revolutionaries)) - user << "\red [M] is already a revolutionary!" - return 0 - else if(M.mind in ticker.mode:get_unconvertables()) - user << "\red [M] cannot be a revolutionary!" - return 0 - else - if(world.time < M.mind.rev_cooldown) - user << "\red Wait five seconds before reconversion attempt." - return 0 - user << "\red Attempting to convert [M]..." - var/choice = alert(M,"Asked by [user]: Do you want to join the revolution?","Align Thyself with the Revolution!","No!","Yes!") - if(choice == "Yes!") - ticker.mode:add_revolutionary(M.mind) - user << "\blue [M] joins the revolution!" - . = 1 - else if(choice == "No!") - user << "\red [M] does not support the revolution!" - . = 0 - M.mind.rev_cooldown = world.time+50*/ mob/living/carbon/human/proc RevConvert(mob/M as mob in oview(src)) diff --git a/code/game/gamemodes/revolution/rp_revolution.dm b/code/game/gamemodes/revolution/rp_revolution.dm new file mode 100644 index 00000000000..07e04d6b2c5 --- /dev/null +++ b/code/game/gamemodes/revolution/rp_revolution.dm @@ -0,0 +1,192 @@ +// BS12's less violent revolution mode + +/datum/game_mode/revolution/rp_revolution + name = "rp-revolution" + config_tag = "rp-revolution" + required_players = 12 + required_enemies = 3 + recommended_enemies = 3 + + var/list/heads = list() + var/tried_to_add_revheads = 0 + +/////////////////////////////////////////////////////////////////////////////// +//Gets the round setup, cancelling if there's not enough players at the start// +/////////////////////////////////////////////////////////////////////////////// +/datum/game_mode/revolution/rp_revolution/pre_setup() + + if(config.protect_roles_from_antagonist) + restricted_jobs += protected_jobs + + var/num_players = num_players() + max_headrevs = max(num_players / 4, 3) + recommended_enemies = max_headrevs + + var/list/datum/mind/possible_headrevs = get_players_for_role(BE_REV) + + var/head_check = 0 + for(var/mob/new_player/player in player_list) + if(player.mind.assigned_role in command_positions) + head_check = 1 + break + + for(var/datum/mind/player in possible_headrevs) + for(var/job in restricted_jobs)//Removing heads and such from the list + if(player.assigned_role == job) + possible_headrevs -= player + + for (var/i=1 to max_headrevs) + if (possible_headrevs.len==0) + break + var/datum/mind/lenin = pick(possible_headrevs) + possible_headrevs -= lenin + head_revolutionaries += lenin + + if((head_revolutionaries.len==0)||(!head_check)) + return 0 + + return 1 + + +/datum/game_mode/revolution/rp_revolution/post_setup() + heads = get_living_heads() + + for(var/datum/mind/rev_mind in head_revolutionaries) + for(var/datum/mind/head_mind in heads) + var/datum/objective/mutiny/rp/rev_obj = new + rev_obj.owner = rev_mind + rev_obj.target = head_mind + rev_obj.explanation_text = "Assassinate or capture [head_mind.name], the [head_mind.assigned_role]." + rev_mind.objectives += rev_obj + + update_rev_icons_added(rev_mind) + + for(var/datum/mind/rev_mind in head_revolutionaries) + greet_revolutionary(rev_mind) + rev_mind.current.verbs += /mob/living/carbon/human/proc/RevConvert + modePlayer += head_revolutionaries + spawn (rand(waittime_l, waittime_h)) + send_intercept() + ..() + +/datum/game_mode/revolution/rp_revolution/greet_revolutionary(var/datum/mind/rev_mind, var/you_are=1) + var/obj_count = 1 + if (you_are) + rev_mind.current << "\blue You are a member of the revolutionaries' leadership!" + for(var/datum/objective/objective in rev_mind.objectives) + rev_mind.current << "Objective #[obj_count]: [objective.explanation_text]" + rev_mind.special_role = "Head Revolutionary" + obj_count++ + +/////////////////////////////////////////////////// +//Deals with converting players to the revolution// +/////////////////////////////////////////////////// +/datum/game_mode/revolution/rp_revolution/add_revolutionary(datum/mind/rev_mind) + // overwrite this func to make it so even heads can be converted + var/mob/living/carbon/human/H = rev_mind.current//Check to see if the potential rev is implanted + if(!is_convertible(H)) + return 0 + if((rev_mind in revolutionaries) || (rev_mind in head_revolutionaries)) + return 0 + revolutionaries += rev_mind + rev_mind.current << "\red 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, capture or convert the heads to win the revolution!" + rev_mind.special_role = "Revolutionary" + update_rev_icons_added(rev_mind) + return 1 + +///////////////////////////// +//Checks for a head victory// +///////////////////////////// +/datum/game_mode/revolution/rp_revolution/check_heads_victory() + for(var/datum/mind/rev_mind in head_revolutionaries) + var/turf/T = get_turf(rev_mind.current) + if(rev_mind.current.stat != 2) + // TODO: add a similar check that also checks whether they're without ID in the brig.. + // probably wanna export this stuff into a separate function for use by both + // revs and heads + if(!rev_mind.current.handcuffed && T && T.z == 1) + return 0 + return 1 + +////////////////////////////////////////////////////////////////////// +//Announces the end of the game with all relavent information stated// +////////////////////////////////////////////////////////////////////// +/datum/game_mode/revolution/rp_revolution/declare_completion() + if(finished == 1) + feedback_set_details("round_end_result","win - heads overthrown") + world << "\red The heads of staff were overthrown! The revolutionaries win!" + else if(finished == 2) + feedback_set_details("round_end_result","loss - revolution stopped") + world << "\red The heads of staff managed to stop the revolution!" + ..() + return 1 + +/datum/game_mode/revolution/proc/is_convertible(mob/M) + for(var/obj/item/weapon/implant/loyalty/L in M)//Checking that there is a loyalty implant in the contents + if(L.imp_in == M)//Checking that it's actually implanted + return 0 + + return 1 + +/mob/living/carbon/human/proc/RevConvert(mob/M as mob in oview(src)) + set name = "Rev-Convert" + if(((src.mind in ticker.mode:head_revolutionaries) || (src.mind in ticker.mode:revolutionaries))) + if((M.mind in ticker.mode:head_revolutionaries) || (M.mind in ticker.mode:revolutionaries)) + src << "\red [M] is already be a revolutionary!" + else if(ticker.mode:is_convertible(M)) + src << "\red [M] is implanted with a loyalty implant - Remove it first!" + else + if(world.time < M.mind.rev_cooldown) + src << "\red Wait five seconds before reconversion attempt." + return + src << "\red Attempting to convert [M]..." + log_admin("[src]([src.ckey]) attempted to convert [M].") + message_admins("\red [src]([src.ckey]) attempted to convert [M].") + var/choice = alert(M,"Asked by [src]: Do you want to join the revolution?","Align Thyself with the Revolution!","No!","Yes!") + if(choice == "Yes!") + ticker.mode:add_revolutionary(M.mind) + M << "\blue You join the revolution!" + src << "\blue [M] joins the revolution!" + else if(choice == "No!") + M << "\red You reject this traitorous cause!" + src << "\red [M] does not support the revolution!" + M.mind.rev_cooldown = world.time+50 + +/datum/game_mode/revolution/rp_revolution/process() + // only perform rev checks once in a while + if(tried_to_add_revheads < world.time) + tried_to_add_revheads = world.time+50 + for(var/datum/mind/rev_mind in head_revolutionaries) + var/active_revs = 0 + if(rev_mind.current.client && rev_mind.current.client.inactivity <= 10*60*20) // 20 minutes inactivity are OK + active_revs++ + + if(active_revs == 0) + log_admin("There are zero active head revolutionists, trying to add some..") + message_admins("There are zero active head revolutionists, trying to add some..") + var/added_heads = 0 + for(var/mob/living/carbon/human/H in world) if(H.client && H.mind && H.client.inactivity <= 10*60*20) + head_revolutionaries += H.mind + for(var/datum/mind/head_mind in heads) + var/datum/objective/mutiny/rp/rev_obj = new + rev_obj.owner = H.mind + rev_obj.target = head_mind + rev_obj.explanation_text = "Assassinate or capture [head_mind.name], the [head_mind.assigned_role]." + H.mind.objectives += rev_obj + + update_rev_icons_added(H.mind) + H.verbs += /mob/living/carbon/human/proc/RevConvert + + H << "\red Congratulations, yer heads of revolution are all gone now, so yer earned yourself a promotion." + added_heads = 1 + break + + if(added_heads) + log_admin("Managed to add new heads of revolution.") + message_admins("Managed to add new heads of revolution.") + else + log_admin("Unable to add new heads of revolution.") + message_admins("Unable to add new heads of revolution.") + tried_to_add_revheads = world.time + 6000 // wait 10 minutes + + return ..() \ No newline at end of file