Files
2020-02-19 19:48:29 -08:00

505 lines
17 KiB
Plaintext

// To add a rev to the list of revolutionaries, make sure it's rev (with if(istype(ticker.mode, /datum/game_mode/revolution))),
// then call ticker.mode:add_revolutionary(_THE_PLAYERS_MIND_)
// nothing else needs to be done, as that proc will check if they are a valid target.
// Just make sure the converter is a head before you call it!
// To remove a rev (from brainwashing or w/e), call ticker.mode:remove_revolutionary(_THE_PLAYERS_MIND_),
// this will also check they're not a head, so it can just be called freely
// If the rev icons start going wrong for some reason, ticker.mode:update_all_rev_icons() can be called to correct them.
// If the game somtimes isn't registering a win properly, then ticker.mode.check_win() isn't being called somewhere.
/datum/game_mode/revolution
name = "revolution"
config_tag = "revolution"
shuttle_available = 0
var/list/datum/mind/head_revolutionaries = list()
var/list/datum/mind/revolutionaries = list()
var/finished = 0
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)
var/win_check_freq = 30 SECONDS //frequency of checks on the win conditions
var/round_limit = 21000 // 35 minutes (see post_setup)
var/endthisshit = 0
/datum/game_mode/revolution/extended
name = "extended revolution"
config_tag = "revolution_extended"
round_limit = 0 //Do not end prematurely
/datum/game_mode/revolution/announce()
boutput(world, "<B>The current game mode is - Revolution!</B>")
boutput(world, "<B>Some crewmembers are attempting to start a revolution!<BR><br>Revolutionaries - Kill the heads of staff. Convert other crewmembers (excluding synthetics and security) to your cause by flashing them. Protect your leaders.<BR><br>Personnel - Protect the heads of staff. Kill the leaders of the revolution, and brainwash the other revolutionaries (by using an electropack, electric chair or beating them in the head).</B>")
/datum/game_mode/revolution/pre_setup()
var/list/revs_possible = get_possible_revolutionaries()
if (!revs_possible.len)
return 0
var/rev_number = 0
if(revs_possible.len >= 3)
rev_number = 3
else
rev_number = revs_possible.len
var/list/chosen_revolutionaries = antagWeighter.choose(pool = revs_possible, role = "head_rev", amount = rev_number, recordChosen = 1)
for (var/datum/mind/rev in chosen_revolutionaries)
head_revolutionaries += rev
rev.special_role = "head_rev"
revs_possible.Remove(rev)
return 1
/datum/game_mode/revolution/post_setup()
var/list/heads = get_living_heads()
if(!head_revolutionaries || !heads)
boutput(world, "<B><span style=\"color:red\">Not enough players for revolution game mode. Restarting world in 5 seconds.</span></B>")
sleep(50)
Reboot_server()
return
for(var/datum/mind/rev_mind in head_revolutionaries)
for(var/datum/mind/head_mind in heads)
var/datum/objective/regular/assassinate/rev_obj = new
rev_obj.owner = rev_mind
rev_obj.find_target_by_role(head_mind.assigned_role)
rev_mind.objectives += rev_obj
equip_revolutionary(rev_mind.current)
SHOW_REVHEAD_TIPS(rev_mind.current)
update_rev_icons_added(rev_mind)
for(var/datum/mind/rev_mind in head_revolutionaries)
var/obj_count = 1
boutput(rev_mind.current, "<span style=\"color:blue\">You are a member of the revolutionaries' leadership!</span>")
for(var/datum/objective/objective in rev_mind.objectives)
boutput(rev_mind.current, "<B>Objective #[obj_count]</B>: [objective.explanation_text]")
obj_count++
SPAWN_DBG (rand(waittime_l, waittime_h))
send_intercept()
if(round_limit > 0)
SPAWN_DBG (round_limit) // this has got to end soon
command_alert("A revolution has been detected on [station_name(1)]. All loyal members of the crew are to ensure the revolution is quelled.","Emergency Riot Update")
SPAWN_DBG(6000) // 10 minutes to clean up shop
command_alert("Revolution heads have been identified. Please stand by for hostile employee termination.", "Emergency Riot Update")
SPAWN_DBG(3000) // 5 minutes until everyone dies
command_alert("You may feel a slight burning sensation.", "Emergency Riot Update")
SPAWN_DBG(10 SECONDS) // welp
for(var/mob/living/carbon/M in mobs)
M.gib()
endthisshit = 1
/datum/game_mode/revolution/proc/equip_revolutionary(mob/living/carbon/human/rev_mob)
equip_traitor(rev_mob)
//var/the_slot = ""
/*
if (!rev_mob.w_uniform)
var/obj/F = new /obj/item/device/flash/revolution(get_turf(rev_mob))
rev_mob.put_in_hand_or_drop(F)
the_slot = "hand"
else
if (!rev_mob.r_store)
rev_mob.equip_if_possible(new /obj/item/device/flash/revolution(rev_mob), rev_mob.slot_r_store)
the_slot = "right pocket"
else if (!rev_mob.l_store)
rev_mob.equip_if_possible(new /obj/item/device/flash/revolution(rev_mob), rev_mob.slot_l_store)
the_slot = "left pocket"
else if (istype(rev_mob.back, /obj/item/storage/) && rev_mob.back.contents.len < 7)
rev_mob.equip_if_possible(new /obj/item/device/flash/revolution(rev_mob), rev_mob.slot_in_backpack)
the_slot = "backpack"
else
var/obj/F2 = new /obj/item/device/flash/revolution(get_turf(rev_mob))
rev_mob.put_in_hand_or_drop(F2)
the_slot = "hand"
*/
rev_mob.show_text("You can use any <b>flash</b> or order items on your Uplink to convert others to the cause!", "blue")
return
/datum/game_mode/revolution/send_intercept()
var/intercepttext = "Cent. Com. Update Requested staus information:<BR>"
intercepttext += " Cent. Com has recently been contacted by the following syndicate affiliated organisations in your area, please investigate any information you may have:"
var/list/possible_modes = list()
possible_modes.Add("revolution", "wizard", "nuke", "traitor", "changeling")
possible_modes -= "[ticker.mode]"
var/number = pick(2, 3)
var/i = 0
for(i = 0, i < number, i++)
possible_modes.Remove(pick(possible_modes))
possible_modes.Insert(rand(possible_modes.len), "[ticker.mode]")
var/datum/intercept_text/i_text = new /datum/intercept_text
for(var/A in possible_modes)
intercepttext += i_text.build(A, pick(head_revolutionaries))
/*
for (var/obj/machinery/computer/communications/comm in machines)
if (!(comm.status & (BROKEN | NOPOWER)) && comm.prints_intercept)
var/obj/item/paper/intercept = new /obj/item/paper( comm.loc )
intercept.name = "paper- 'Cent. Com. Status Summary'"
intercept.info = intercepttext
comm.messagetitle.Add("Cent. Com. Status Summary")
comm.messagetext.Add(intercepttext)
*/
for (var/obj/machinery/communications_dish/C in comm_dishes)
C.add_centcom_report("Cent. Com. Status Summary", intercepttext)
command_alert("Summary downloaded and printed out at all communications consoles.", "Enemy communication intercept. Security Level Elevated.")
/datum/game_mode/revolution/process()
..()
if (world.time > win_check_freq)
win_check_freq += win_check_freq
check_win()
/datum/game_mode/revolution/check_win()
if(check_rev_victory())
finished = 1
else if(check_heads_victory())
finished = 2
else if(check_centcom_victory())
finished = 3
return
/datum/game_mode/revolution/check_finished()
if(finished != 0)
return 1
else
return 0
/datum/game_mode/revolution/proc/add_revolutionary(datum/mind/rev_mind)
.= 0
if (!rev_mind.current || (rev_mind.current && !rev_mind.current.client))
return 0
var/list/uncons = src.get_unconvertables()
if (!(rev_mind in src.revolutionaries) && !(rev_mind in src.head_revolutionaries) && !(rev_mind in uncons))
SHOW_REVVED_TIPS(rev_mind.current)
rev_mind.current.show_text("<h2><font color=red>You are now a revolutionary! Kill the heads of staff and don't harm your fellow freedom fighters. You can identify your comrades by the R icons (blue = rev leader, red = regular member).</font></h2>")
src.revolutionaries += rev_mind
src.update_rev_icons_added(rev_mind)
logTheThing("combat", rev_mind.current, null, "was made a member of the revolution.")
. = 1
var/obj/itemspecialeffect/derev/E = unpool(/obj/itemspecialeffect/derev)
E.color = "#FF5555"
E.setup(rev_mind.current.loc)
/datum/game_mode/revolution/proc/remove_revolutionary(datum/mind/rev_mind)
.= 0
if (!rev_mind.current)
return 0
if (rev_mind in revolutionaries)
SHOW_DEREVVED_TIPS(rev_mind.current)
rev_mind.current.show_text("<h2><font color=blue>You are no longer a revolutionary! Protect the heads of staff and help them kill the leaders of the revolution.</font></h2>", "blue")
src.revolutionaries -= rev_mind
src.update_rev_icons_removed(rev_mind)
logTheThing("combat", rev_mind.current, null, "is no longer a member of the revolution.")
for (var/mob/living/M in view(rev_mind.current))
M.show_text("<b>[rev_mind.current] looks like they just remembered their real allegiance!</b>", "blue")
.= 1
var/obj/itemspecialeffect/derev/E = unpool(/obj/itemspecialeffect/derev)
E.color = "#5555FF"
E.setup(rev_mind.current.loc)
/datum/game_mode/revolution/proc/update_all_rev_icons()
var/list/update_me = list()
update_me.Add(src.head_revolutionaries)
update_me.Add(src.revolutionaries)
for (var/datum/mind/M in update_me)
if (M.current)
M.current.antagonist_overlay_refresh(1, 0)
return
/datum/game_mode/revolution/proc/update_rev_icons_added(datum/mind/rev_mind)
var/list/update_me = list()
update_me.Add(src.head_revolutionaries)
update_me.Add(src.revolutionaries) // Includes rev_mind.
for (var/datum/mind/M in update_me)
if (M.current)
M.current.antagonist_overlay_refresh(1, 0)
return
/datum/game_mode/revolution/proc/update_rev_icons_removed(datum/mind/rev_mind)
if (rev_mind && istype(rev_mind) && rev_mind.current)
rev_mind.current.antagonist_overlay_refresh(1, 1)
var/list/update_me = list()
update_me.Add(src.head_revolutionaries)
update_me.Add(src.revolutionaries)
for (var/datum/mind/M in update_me)
if (M.current)
M.current.antagonist_overlay_refresh(1, 0)
return
/datum/game_mode/revolution/proc/get_possible_revolutionaries()
var/list/candidates = list()
for(var/mob/new_player/player in mobs)
if (ishellbanned(player)) continue //No treason for you
if ((player.client) && (player.ready) && !(player.mind in head_revolutionaries) && !(player.mind in token_players) && !candidates.Find(player.mind))
if(player.client.preferences.be_revhead)
candidates += player.mind
if(candidates.len < 1)
logTheThing("debug", null, null, "<b>Enemy Assignment</b>: Not enough players with be_revhead set to yes, so we're adding players who don't want to be rev leaders to the pool.")
for(var/mob/new_player/player in mobs)
if (ishellbanned(player)) continue //No treason for you
if ((player.client) && (player.ready) && !(player.mind in head_revolutionaries) && !(player.mind in token_players) && !candidates.Find(player.mind))
candidates += player.mind
if(candidates.len < 1)
return list()
else
return candidates
/datum/game_mode/revolution/proc/get_living_heads()
var/list/heads = list()
for(var/mob/living/carbon/human/player in mobs)
if(player.mind)
var/role = player.mind.assigned_role
if(role in list("Captain", "Head of Security", "Head of Personnel", "Chief Engineer", "Research Director", "Medical Director","Communications Officer"))
heads += player.mind
if(heads.len < 1)
return null
else
return heads
/datum/game_mode/revolution/proc/get_all_heads()
var/list/heads = list()
for(var/mob/player in mobs)
if(player.mind)
var/role = player.mind.assigned_role
if(role in list("Captain", "Head of Security", "Head of Personnel", "Chief Engineer", "Research Director", "Medical Director","Communications Officer"))
heads += player.mind
return heads
/datum/game_mode/revolution/proc/get_unconvertables()
var/list/ucs = list()
for(var/mob/living/silicon/robot/player in mobs)
if(player.mind)
var/rol = player.mind.assigned_role
if(rol in list("Cyborg"))
ucs += player.mind
for(var/mob/living/critter/small_animal/player in mobs)
if(player.mind)
if (player.ghost_spawned)
ucs += player.mind
for(var/mob/living/carbon/human/player in mobs)
if(player.mind)
if (locate(/obj/item/implant/antirev) in player.implant)
ucs += player.mind
else
var/role = player.mind.assigned_role
if(role in list("Captain", "Head of Security", "Head of Personnel", "Chief Engineer", "Research Director", "Medical Director", "Head Surgeon", "Head of Mining", "Security Officer", "Vice Officer", "Detective", "AI", "Cyborg", "Nanotrasen Special Operative", "Nanotrasen Security Operative","Communications Officer"))
ucs += player.mind
//for(var/mob/living/carbon/human/player in mobs)
return ucs
/datum/game_mode/revolution/proc/check_rev_victory()
var/list/head_check = get_all_heads()
if(endthisshit == 1) // don't count gibbed dudes on centcom win
return 0
// Run through all the heads
for(var/datum/mind/head_mind in head_check)
// If they exist, have a mob and aren't dead
if(head_mind && head_mind.current && !isdead(head_mind.current))
// Check to see if they're a robot
if(issilicon(head_mind.current))
// If they're a robot don't count them
continue
if(isghostcritter(head_mind.current) || isVRghost(head_mind.current))
continue
// Check if they're on the current z-level
var/turf/T = get_turf_loc(head_mind.current)
if(T.z != 1)
continue
// If they are then don't end the round
// This return means that they're alive and on the first z level and are not a robot
return 0
return 1
/*
for(var/datum/mind/rev_mind in head_revolutionaries)
for(var/datum/objective/objective in rev_mind.objectives)
#ifdef CREW_OBJECTIVES
if (istype(objective, /datum/objective/crew)) continue
#endif
if(!(objective.check_completion()))
return 0
return 1
*/
/datum/game_mode/revolution/proc/check_heads_victory()
if(endthisshit == 1)
return 0
for(var/datum/mind/rev_mind in head_revolutionaries)
if(rev_mind && rev_mind.current && !isdead(rev_mind.current))
// Check to see if they're a robot
if(issilicon(rev_mind.current))
// If they're a robot don't count them
continue
if(isghostcritter(rev_mind.current) || isVRghost(rev_mind.current))
continue
var/turf/T = get_turf_loc(rev_mind.current)
if(T.z != 1)
continue
if(istype(T.loc, /area/station/security/brig) && !rev_mind.current.canmove)
continue
return 0
return 1
/datum/game_mode/revolution/proc/check_centcom_victory()
if (!endthisshit)
return 0
return 1
/datum/game_mode/revolution/declare_completion()
var/text = ""
if(finished == 1)
boutput(world, "<span style=\"color:red\"><FONT size = 3><B> The heads of staff were killed or abandoned the [station_or_ship()]! The revolutionaries win!</B></FONT></span>")
else if(finished == 2)
boutput(world, "<span style=\"color:red\"><FONT size = 3><B> The heads of staff managed to stop the revolution!</B></FONT></span>")
else if(finished == 3)
boutput(world, "<span style=\"color:red\"><FONT size = 3><B> Everyone was terminated! CentCom wins!</B></FONT></span>")
#ifdef DATALOGGER
switch(finished)
if(1)
game_stats.Increment("traitorwin")
if(2)
game_stats.Increment("traitorloss")
#endif
boutput(world, "<FONT size = 2><B>The head revolutionaries were: </B></FONT>")
for(var/datum/mind/rev_mind in head_revolutionaries)
text = ""
if(rev_mind.current)
text += "[rev_mind.current.real_name]"
var/turf/T = get_turf_loc(rev_mind.current)
if(isdead(rev_mind.current))
text += " (Dead)"
else if(T.z == 2)
text += " (Imprisoned!)"
else if(T.z != 1)
text += " (Abandoned the cause!)"
else
text += " (Survived!)"
else
text += "[rev_mind.key] (character destroyed)"
boutput(world, text)
text = ""
boutput(world, "<FONT size = 2><B>The converted revolutionaries were: </B></FONT>")
for(var/datum/mind/rev_nh_mind in revolutionaries)
if(rev_nh_mind.current)
text += "[rev_nh_mind.current.real_name]"
var/turf/T = get_turf_loc(rev_nh_mind.current)
if(T.z == 2)
text += " (Imprisoned!)"
else if(isdead(rev_nh_mind.current))
text += " (Dead)"
else if(T.z != 1)
text += " (Abandoned the cause!)"
else
text += " (Survived!)"
else
text += "[rev_nh_mind.key] (character destroyed)"
text += ", "
boutput(world, text)
boutput(world, "<FONT size = 2><B>The heads of staff were: </B></FONT>")
var/list/heads = list()
heads = get_all_heads()
for(var/datum/mind/head_mind in heads)
text = ""
if(head_mind.current)
text += "[head_mind.current.real_name]"
if(isdead(head_mind.current))
text += " (Dead)"
else
var/turf/T = get_turf_loc(head_mind.current)
if(T.z != 1)
text += " (Abandoned the [station_or_ship()]!)"
else
text += " (Survived!)"
else
text += "[head_mind.key] (character destroyed)"
boutput(world, text)
..() // Admin-assigned antagonists or whatever.
/obj/item/revolutionary_sign
name = "revolutionary sign"
desc = "A sign bearing revolutionary propaganda. Good for picketing."
icon = 'icons/obj/weapons.dmi'
icon_state = "revsign"
inhand_image_icon = 'icons/mob/inhand/hand_weapons.dmi'
item_state = "revsign"
w_class = 4.0
throwforce = 8
flags = FPRINT | TABLEPASS | CONDUCT
force = 7
stamina_damage = 25
stamina_cost = 14
stamina_crit_chance = 10
hitsound = 'sound/impact_sounds/Wood_Hit_1.ogg'
New()
..()
src.setItemSpecial(/datum/item_special/swipe)