diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index 1472a045d2d..a8b240c4743 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -29,3 +29,4 @@ #define BE_BLOB 512 #define BE_NINJA 1024 #define BE_MONKEY 2048 +#define BE_GANG 4096 diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 440a907e527..256aee3b322 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -143,17 +143,17 @@ if(A.flags & HEAR) found_mobs |= A - + for(var/atom/B in A) if(!processed_list[B]) processing_list |= B processing_list.Cut(1, 2) processed_list[A] = A - + return found_mobs // Better recursive loop, technically sort of not actually recursive cause that shit is retarded, enjoy. -//No need for a recursive limit either +//No need for a recursive limit either /proc/recursive_mob_check(var/atom/O,var/client_check=1,var/sight_check=1,var/include_radio=1) var/list/processing_list = list(O) @@ -193,7 +193,7 @@ return found_mobs - + /proc/get_hearers_in_view(var/R, var/atom/source) // Returns a list of hearers in range of R from source. Used in saycode. var/turf/T = get_turf(source) @@ -269,7 +269,7 @@ return 1 #undef SIGN - + /proc/isInSight(var/atom/A, var/atom/B) var/turf/Aturf = get_turf(A) var/turf/Bturf = get_turf(B) diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm index f7caa812336..810db1dd6c5 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -139,6 +139,20 @@ var/syndicate_name = null syndicate_name = name return name +var/gang_A_name = null +var/gang_B_name = null +/proc/gang_name(var/gang) + if(!gang_A_name || !gang_B_name) + var/gang_name_pool = list("Clandestine", "Prima", "Blue", "Zero-G", "Max", "Blasto", "Waffle", "North", "Omni", "Newton", "Cyber", "Donk", "Gene", "Gib", "Tunnel") + gang_A_name = pick(gang_name_pool) + gang_name_pool -= gang_A_name + gang_B_name = pick(gang_name_pool) + + if(gang == "A") + return gang_A_name + if(gang == "B") + return gang_B_name + //Traitors and traitor silicons will get these. Revs will not. var/syndicate_code_phrase//Code phrase for traitors. @@ -305,4 +319,4 @@ var/syndicate_code_response//Code response for traitors. if(5) return -*/ \ No newline at end of file +*/ diff --git a/code/_globalvars/configuration.dm b/code/_globalvars/configuration.dm index 5d3a5f8030b..062be18c68d 100644 --- a/code/_globalvars/configuration.dm +++ b/code/_globalvars/configuration.dm @@ -45,5 +45,6 @@ var/list/be_special_flags = list( "Cultist" = BE_CULTIST, "Blob" = BE_BLOB, "Ninja" = BE_NINJA, - "Monkey" = BE_MONKEY + "Monkey" = BE_MONKEY, + "Gang" = BE_GANG ) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index ce9d2325ad2..af3e024b5e9 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -161,6 +161,11 @@ remove_objectives() remove_antag_equip() + +/datum/mind/proc/remove_gang() + ticker.mode.remove_gangster(src,0,1) + remove_objectives() + /datum/mind/proc/remove_malf() if(src in ticker.mode.malf_ai) ticker.mode.malf_ai -= src @@ -196,6 +201,7 @@ remove_cultist() remove_rev() remove_malf() + remove_gang() /datum/mind/proc/show_memory(mob/recipient, window=1) if(!recipient) @@ -224,6 +230,7 @@ var/list/sections = list( "revolution", + "gang", "cult", "wizard", "changeling", @@ -256,16 +263,54 @@ else text += "." - text += " Reequip (gives traitor uplink)." + /** GANG ***/ + text = "gang" + if (ticker.mode.config_tag=="gang") + text = uppertext(text) + text = "[text]: " + if (src in ticker.mode.A_bosses) + text += "loyal|none|(A) gangster BOSS|(B) gangster boss" + text += "
Flash & Recaller: give" + + var/list/L = current.get_contents() + var/obj/item/device/flash/flash = locate() in L + if (flash) + if(!flash.broken) + text += "|take equipment." + else + text += "|take equipment|repair flash." + else + text += "." + if (objectives.len==0) - text += "
Objectives are empty! Set to kill all heads." + text += "
Objectives are empty! Set to kill all rival gang leaders." + + else if (src in ticker.mode.B_bosses) + text += "loyal|none|(A) gangster boss|(B) gangster BOSS" + text += "
Flash & Recaller: give" + + var/list/L = current.get_contents() + var/obj/item/device/flash/flash = locate() in L + if (flash) + if(!flash.broken) + text += "
take equipment." + else + text += "
take equipment|repair flash." + else + text += "." + + if (objectives.len==0) + text += "
Objectives are empty! Set to kill all rival gang leaders." + + else if (src in ticker.mode.A_gangsters) + text += "loyal|none|(A) GANGSTER boss|(B) gangster boss" + else if (src in ticker.mode.B_gangsters) + text += "loyal|none|(A) gangster boss|(B) GANGSTER boss" else if(isloyal(current)) - text += "head|LOYAL|employee|headrev|rev" - else if (src in ticker.mode.revolutionaries) - text += "head|loyal|employee|headrev|REV" + text += "LOYAL|none|(A) gangster boss|(B) gangster boss" else - text += "head|loyal|EMPLOYEE|headrev|rev" - sections["revolution"] = text + text += "loyal|NONE|(A) gangster boss|(B) gangster boss" + sections["gang"] = text /** CULT ***/ text = "cult" @@ -448,7 +493,7 @@ out += "Announce objectives

" - usr << browse(out, "window=edit_memory[src]") + usr << browse(out, "window=edit_memory[src];size=400x500") /datum/mind/Topic(href, href_list) if(!check_rights(R_ADMIN)) return @@ -679,16 +724,83 @@ else flash.broken = 0 - if("reequip") + else if (href_list["gang"]) + switch(href_list["gang"]) + if("clear") + remove_gang() + message_admins("[key_name_admin(usr)] has de-gang'ed [current].") + log_admin("[key_name(usr)] has de-gang'ed [current].") + + if("agang") + if(src in ticker.mode.A_gangsters) + return + ticker.mode.remove_gangster(src, 0, 2) + ticker.mode.add_gangster(src,"A",0) + message_admins("[key_name_admin(usr)] has added [current] to the [gang_name("A")] Gang (A).") + log_admin("[key_name(usr)] has added [current] to the [gang_name("A")] Gang (A).") + + if("aboss") + if(src in ticker.mode.A_bosses) + return + ticker.mode.remove_gangster(src, 0, 2) + ticker.mode.A_bosses += src + src.special_role = "[gang_name("A")] Gang (A) Boss" + ticker.mode.update_gang_icons_added(src, "A") + current << "You are a [gang_name("A")] Gang Boss!" + message_admins("[key_name_admin(usr)] has added [current] to the [gang_name("A")] Gang (A) leadership.") + log_admin("[key_name(usr)] has added [current] to the [gang_name("A")] Gang (A) leadership.") + + if("bgang") + if(src in ticker.mode.B_gangsters) + return + ticker.mode.remove_gangster(src, 0, 2) + ticker.mode.add_gangster(src,"B",0) + message_admins("[key_name_admin(usr)] has added [current] to the [gang_name("B")] Gang (B).") + log_admin("[key_name(usr)] has added [current] to the [gang_name("B")] Gang (B).") + + if("bboss") + if(src in ticker.mode.B_bosses) + return + ticker.mode.remove_gangster(src, 0, 2) + ticker.mode.B_bosses += src + src.special_role = "[gang_name("B")] Gang (B) Boss" + ticker.mode.update_gang_icons_added(src, "B") + current << "You are a [gang_name("B")] Gang Boss!" + message_admins("[key_name_admin(usr)] has added [current] to the [gang_name("B")] Gang (B) leadership.") + log_admin("[key_name(usr)] has added [current] to the [gang_name("B")] Gang (B) leadership.") + + if("autoobjective") + ticker.mode.forge_gang_objectives(src) + ticker.mode.greet_gang(src,0) + usr << "Unable to equip flash!" + if(1) + usr << "Unable to equip recaller!" + if(0) + usr << "Unable to equip both flash and recaller!" + + if("takeequip") var/list/L = current.get_contents() var/obj/item/device/flash/flash = locate() in L + if (!flash) + usr << "Deleting flash failed!" qdel(flash) - take_uplink() - var/fail = 0 - fail |= !ticker.mode.equip_traitor(current, 1) - fail |= !ticker.mode.equip_revolutionary(current) - if (fail) - usr << "Reequipping revolutionary goes wrong!" + var/obj/item/device/recaller/recaller = locate() in L + if (!recaller) + usr << "Deleting recaller failed!" + qdel(recaller) + + if("repairflash") + var/list/L = current.get_contents() + var/obj/item/device/flash/flash = locate() in L + if (!flash) + usr << "Repairing flash failed!" + else + flash.broken = 0 else if (href_list["cult"]) switch(href_list["cult"]) @@ -1119,6 +1231,13 @@ fail |= !ticker.mode.equip_revolutionary(current) +/datum/mind/proc/make_Gang(var/gang) + special_role = "[(gang=="A") ? "[gang_name("A")] Gang (A)" : "[gang_name("B")] Gang (B)"] Boss" + ticker.mode.update_gang_icons_added(src, gang) + ticker.mode.forge_gang_objectives(src, gang) + ticker.mode.greet_gang(src) + ticker.mode.equip_gang(current) + /mob/proc/sync_mind() mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist) mind.active = 1 //indicates that the mind is currently synced with a client diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 517ccae3a06..7974819cefb 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -218,6 +218,7 @@ if(BE_OPERATIVE) roletext="operative" if(BE_WIZARD) roletext="wizard" if(BE_REV) roletext="revolutionary" + if(BE_GANG) roletext="gangster" if(BE_CULTIST) roletext="cultist" if(BE_MONKEY) roletext="monkey" @@ -400,4 +401,4 @@ proc/display_roundstart_logout_report() text += "body destroyed" text += ")" - return text + return text diff --git a/code/game/gamemodes/gang/gang.dm b/code/game/gamemodes/gang/gang.dm new file mode 100644 index 00000000000..11fa69970ec --- /dev/null +++ b/code/game/gamemodes/gang/gang.dm @@ -0,0 +1,442 @@ +//gang.dm +//Gang War Game Mode + +/datum/game_mode + var/list/datum/mind/A_bosses = list() //gang A bosses + var/list/datum/mind/A_gangsters = list() //gang A Members + var/list/datum/mind/B_bosses = list() //gang B bosses + var/list/datum/mind/B_gangsters = list() //gang B Members + +/datum/game_mode/gang + name = "gang war" + config_tag = "gang" + antag_flag = BE_GANG + restricted_jobs = list("Security Officer", "Warden", "Detective", "AI", "Cyborg","Captain", "Head of Personnel", "Head of Security", "Chief Engineer", "Research Director", "Chief Medical Officer") + required_players = 20 + required_enemies = 2 + recommended_enemies = 4 + + var/finished = 0 + var/checkwin_counter = 0 +/////////////////////////// +//Announces the game type// +/////////////////////////// +/datum/game_mode/gang/announce() + world << "The current game mode is - Gang War!" + world << "A violent turf war has erupted on the station!
Gangsters - Take over the station by killing the rival gang's bosses! Recruit gangsters by flashing them!
Security - Protect the Crew! Identify and stop the mob bosses!
" + + +/////////////////////////////////////////////////////////////////////////////// +//Gets the round setup, cancelling if there's not enough players at the start// +/////////////////////////////////////////////////////////////////////////////// +/datum/game_mode/gang/pre_setup() + if(config.protect_roles_from_antagonist) + restricted_jobs += protected_jobs + + for(var/datum/mind/player in antag_candidates) + for(var/job in restricted_jobs)//Removing heads and such from the list + if(player.assigned_role == job) + antag_candidates -= player + + if(antag_candidates.len > 2) + assign_bosses() + if(antag_candidates.len > 20) + assign_bosses() + + if(!A_bosses.len || !B_bosses.len) + return 0 + + return 1 + + +/datum/game_mode/gang/post_setup() + spawn(rand(10,100)) + for(var/datum/mind/boss_mind in A_bosses) + update_gang_icons_added(boss_mind, "A") + forge_gang_objectives(boss_mind, "A") + greet_gang(boss_mind) + equip_gang(boss_mind.current) + + for(var/datum/mind/boss_mind in B_bosses) + update_gang_icons_added(boss_mind, "B") + forge_gang_objectives(boss_mind, "B") + greet_gang(boss_mind) + equip_gang(boss_mind.current) + + modePlayer += A_bosses + modePlayer += B_bosses + ..() + + +/datum/game_mode/gang/process() + checkwin_counter++ + if(checkwin_counter >= 5) + if(!finished) + ticker.mode.check_win() + checkwin_counter = 0 + return 0 + +/datum/game_mode/gang/proc/assign_bosses() + var/datum/mind/boss = pick(antag_candidates) + A_bosses += boss + antag_candidates -= boss + boss.special_role = "[gang_name("A")] Gang (A) Boss" + log_game("[boss.key] has been selected as a boss for the [gang_name("A")] Gang (A)") + + boss = pick(antag_candidates) + B_bosses += boss + antag_candidates -= boss + boss.special_role = "[gang_name("B")] Gang (B) Boss" + log_game("[boss.key] has been selected as a boss for the [gang_name("B")] Gang (B)") + +/datum/game_mode/proc/forge_gang_objectives(var/datum/mind/boss_mind) + var/datum/objective/rival_obj = new + rival_obj.owner = boss_mind + rival_obj.explanation_text = "Assassinate or exile the [(boss_mind in A_bosses) ? gang_name("B") : gang_name("A")] Gang's bosses." + boss_mind.objectives += rival_obj + + +/datum/game_mode/proc/greet_gang(var/datum/mind/boss_mind, var/you_are=1) + var/obj_count = 1 + if (you_are) + boss_mind.current << "You are a [(boss_mind in A_bosses) ? gang_name("A") : gang_name("B")] Gang Boss!" + for(var/datum/objective/objective in boss_mind.objectives) + boss_mind.current << "Objective #[obj_count]: [objective.explanation_text]" + obj_count++ + +/////////////////////////////////////////////////////////////////////////// +//This equips the bosses with their gear, and makes the clown not clumsy// +/////////////////////////////////////////////////////////////////////////// +/datum/game_mode/proc/equip_gang(mob/living/carbon/human/mob) + if(!istype(mob)) + return + + if (mob.mind) + if (mob.mind.assigned_role == "Clown") + mob << "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself." + mob.mutations.Remove(CLUMSY) + + + var/obj/item/device/flash/T = new(mob) + var/obj/item/device/recaller/recaller = new(mob) + + var/list/slots = list ( + "backpack" = slot_in_backpack, + "left pocket" = slot_l_store, + "right pocket" = slot_r_store, + "left hand" = slot_l_hand, + "right hand" = slot_r_hand, + ) + + . = 0 + + var/where2 = mob.equip_in_one_of_slots(recaller, slots) + if (!where2) + mob << "Your Syndicate benefactors were unfortunately unable to get you a Recaller." + else + mob << "The Recaller in your [where2] will allow you to prevent the station from prematurely evacuating. Use it to recall the emergency shuttle from anywhere on the station." + . += 2 + + var/where = mob.equip_in_one_of_slots(T, slots) + if (!where) + mob << "Your Syndicate benefactors were unfortunately unable to get you a flash." + else + mob << "The flash in your [where] will help you to persuade the crew to work for you. Keep in mind that your underlings can only identify their bosses, but not each other." + . += 1 + + mob.update_icons() + + return . + +///////////////////////////////////////////// +//Checks if the either gang have won or not// +///////////////////////////////////////////// +/datum/game_mode/gang/check_win() + var/A_victory = check_gang_victory(B_bosses) //Check if B bosses are dead or exiled + var/B_victory = check_gang_victory(A_bosses) //Check if A bosses are dead or exiled + + if(A_victory && B_victory) + finished = "Draw" //Both teams fail. Allow for draws in case they're all incapacitated at the same time. + + else if(A_victory) + finished = "A" //Gang A wins + + else if(B_victory) + finished = "B" //Gang B wins + +/////////////////////////////// +//Checks if the round is over// +/////////////////////////////// +/datum/game_mode/gang/check_finished() + if(finished) //Check for Gang Boss death + return 1 + return ..() //Check for evacuation/nuke + +/////////////////////////////////////////// +//Deals with converting players to a gang// +/////////////////////////////////////////// +/datum/game_mode/proc/add_gangster(datum/mind/gangster_mind, var/gang, var/check = 1) + if(check && isloyal(gangster_mind.current)) //Check to see if the potential gangster is implanted + return 0 + if((gangster_mind in A_bosses) || (gangster_mind in A_gangsters) || (gangster_mind in B_bosses) || (gangster_mind in B_gangsters)) + return 0 + if(gang == "A") + A_gangsters += gangster_mind + else + B_gangsters += gangster_mind + gangster_mind.current << "You are now a member of the [gang=="A" ? gang_name("A") : gang_name("B")] Gang!" + gangster_mind.current << "Help your bosses take over the station by defeating their rivals. You can identify your bosses by the brown \"B\" icons, but only they know who is in your gang! Work with your boss to avoid attacking your own gang." + gangster_mind.current.attack_log += "\[[time_stamp()]\] Has been converted to the [gang=="A" ? "[gang_name("A")] Gang (A)" : "[gang_name("B")] Gang (B)"]!" + gangster_mind.special_role = "[gang=="A" ? "[gang_name("A")] Gang (A)" : "[gang_name("B")] Gang (B)"]" + update_gang_icons_added(gangster_mind,gang) + return 1 +////////////////////////////////////////////////////////////// +//Deals with players going straight (Not a gangster anymore)// +////////////////////////////////////////////////////////////// +/datum/game_mode/proc/remove_gangster(datum/mind/gangster_mind, var/beingborged, var/silent) + var/gang + + if(gangster_mind in A_bosses) + A_bosses -= gangster_mind + gang = "A" + + else if(gangster_mind in A_gangsters) + A_gangsters -= gangster_mind + gang = "A" + + else if(gangster_mind in B_bosses) + B_bosses -= gangster_mind + gang = "B" + + else if(gangster_mind in B_gangsters) + B_gangsters -= gangster_mind + gang = "B" + + if(!gang) //not a valid gangster + return + + gangster_mind.special_role = null + if(silent < 2) + gangster_mind.current.attack_log += "\[[time_stamp()]\] Has reformed and defected from the [gang=="A" ? "[gang_name("A")] Gang (A)" : "[gang_name("B")] Gang (B)"]!" + + if(beingborged) + if(!silent) + gangster_mind.current.visible_message("The frame beeps contentedly from the MMI before initalizing it.") + gangster_mind.current << "The frame's firmware detects and deletes your criminal behavior! You are no longer a gangster!" + message_admins("[key_name_admin(gangster_mind.current)] ? has been borged while being a member of the [gang=="A" ? "[gang_name("A")] Gang (A)" : "[gang_name("B")] Gang (B)"] Gang. They are no longer a gangster.") + else + if(!silent) + gangster_mind.current.visible_message("[gangster_mind.current] looks like they've given up the life of crime!") + gangster_mind.current << "You have been reformed! You are no longer a gangster!" + + update_gang_icons_removed(gangster_mind) + + +///////////////////////////////////////////////////////////////////////////////////////////////// +//Keeps track of players having the correct icons//////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////// +/datum/game_mode/proc/update_all_gang_icons() + spawn(0) + var/list/all_gangsters = A_bosses + B_bosses + A_gangsters + B_gangsters + + //Delete all gang icons + for(var/datum/mind/gang_mind in all_gangsters) + if(gang_mind.current) + if(gang_mind.current.client) + for(var/image/I in gang_mind.current.client.images) + if(I.icon_state == "gangster" || I.icon_state == "gang_boss") + del(I) + + update_gang_icons("A") + update_gang_icons("B") + +/datum/game_mode/proc/update_gang_icons(var/gang) + var/list/bosses + var/list/gangsters + if(gang == "A") + bosses = A_bosses + gangsters = A_gangsters + else if(gang == "B") + bosses = B_bosses + gangsters = B_gangsters + else + world << "ERROR: Invalid gang in update_gang_icons()" + + //Update gang icons for boss' visions + for(var/datum/mind/boss_mind in bosses) + if(boss_mind.current) + if(boss_mind.current.client) + for(var/datum/mind/gangster_mind in gangsters) + if(gangster_mind.current) + var/I = image('icons/mob/mob.dmi', loc = gangster_mind.current, icon_state = "gangster") + boss_mind.current.client.images += I + for(var/datum/mind/boss2_mind in bosses) + if(boss2_mind.current) + var/I = image('icons/mob/mob.dmi', loc = boss2_mind.current, icon_state = "gang_boss") + boss_mind.current.client.images += I + + //Update boss and self icons for gangsters' visions + for(var/datum/mind/gangster_mind in gangsters) + if(gangster_mind.current) + if(gangster_mind.current.client) + for(var/datum/mind/boss_mind in bosses) + if(boss_mind.current) + var/I = image('icons/mob/mob.dmi', loc = boss_mind.current, icon_state = "gang_boss") + gangster_mind.current.client.images += I + //Tag themselves to see + var/K + if(gangster_mind in bosses) //If the new gangster is a boss himself + K = image('icons/mob/mob.dmi', loc = gangster_mind.current, icon_state = "gang_boss") + else + K = image('icons/mob/mob.dmi', loc = gangster_mind.current, icon_state = "gangster") + gangster_mind.current.client.images += K + +///////////////////////////////////////////////// +//Assigns icons when a new gangster is recruited// +///////////////////////////////////////////////// +/datum/game_mode/proc/update_gang_icons_added(datum/mind/recruit_mind, var/gang) + var/list/bosses + if(gang == "A") + bosses = A_bosses + else if(gang == "B") + bosses = B_bosses + if(!gang) + world << "ERROR: Invalid gang in update_gang_icons_added()" + + spawn(0) + for(var/datum/mind/boss_mind in bosses) + //Tagging the new gangster for the bosses to see + if(boss_mind.current) + if(boss_mind.current.client) + var/I + if(recruit_mind in bosses) //If the new gangster is a boss himself + I = image('icons/mob/mob.dmi', loc = recruit_mind.current, icon_state = "gang_boss") + else + I = image('icons/mob/mob.dmi', loc = recruit_mind.current, icon_state = "gangster") + boss_mind.current.client.images += I + //Tagging every boss for the new gangster to see + if(recruit_mind.current) + if(recruit_mind.current.client) + var/image/J = image('icons/mob/mob.dmi', loc = boss_mind.current, icon_state = "gang_boss") + recruit_mind.current.client.images += J + //Tag themselves to see + if(recruit_mind.current) + if(recruit_mind.current.client) + var/K + if(recruit_mind in bosses) //If the new gangster is a boss himself + K = image('icons/mob/mob.dmi', loc = recruit_mind.current, icon_state = "gang_boss") + else + K = image('icons/mob/mob.dmi', loc = recruit_mind.current, icon_state = "gangster") + recruit_mind.current.client.images += K + +//////////////////////////////////////// +//Keeps track of deconverted gangsters// +//////////////////////////////////////// +/datum/game_mode/proc/update_gang_icons_removed(datum/mind/defector_mind) + var/list/all_gangsters = A_bosses + B_bosses + A_gangsters + B_gangsters + + spawn(0) + //Remove defector's icon from gangsters' visions + for(var/datum/mind/boss_mind in all_gangsters) + if(boss_mind.current) + if(boss_mind.current.client) + for(var/image/I in boss_mind.current.client.images) + if((I.icon_state == "gangster" || I.icon_state == "gang_boss") && I.loc == defector_mind.current) + del(I) + + //Remove gang icons from defector's vision + if(defector_mind.current) + if(defector_mind.current.client) + for(var/image/I in defector_mind.current.client.images) + if(I.icon_state == "gangster" || I.icon_state == "gang_boss") + del(I) + +/////////////////////////// +//Checks for gang victory// +/////////////////////////// +/datum/game_mode/gang/proc/check_gang_victory(var/list/boss_list) + if(!boss_list.len) + return 0 + for(var/datum/mind/boss_mind in boss_list) + if(boss_mind.current) + if(boss_mind.current.stat == DEAD || !ishuman(boss_mind.current) || !boss_mind.current.ckey || !boss_mind.current.client) + return 1 + var/turf/T = get_turf(boss_mind.current) + if(T && (T.z != 1)) //If they leave the station they count as dead for this + return 1 + return 0 + return 1 + +////////////////////////////////////////////////////////////////////// +//Announces the end of the game with all relavent information stated// +////////////////////////////////////////////////////////////////////// +/datum/game_mode/gang/declare_completion() + if(!finished) + world << "The station was [station_was_nuked ? "destroyed!" : "evacuated before either gang could claim it!"]" + if(finished == "Draw") + world << "All gang bosses have been killed or exiled!" + else + world << "The [finished=="A" ? gang_name("A") : gang_name("B")] Gang defeated their rivals!" + ..() + return 1 + +/datum/game_mode/proc/auto_declare_completion_gang() + var/winner + var/datum/game_mode/gang/game_mode = ticker.mode + if(istype(game_mode)) + winner = game_mode.finished + + var/num_ganga = 0 + var/list/agang = A_gangsters + A_bosses + for(var/datum/mind/agangster in agang) + if(agangster.current) + if(agangster.current in living_mob_list) + num_ganga++ + + var/num_gangb = 0 + var/list/bgang = B_gangsters + B_bosses + for(var/datum/mind/bgangster in bgang) + if(bgangster.current) + if(bgangster.current in living_mob_list) + num_gangb++ + + var/num_survivors = 0 + for(var/mob/living/carbon/survivor in living_mob_list) + if(survivor.key) + num_survivors++ + + if(A_bosses.len || A_gangsters.len) + if(winner == "A" || winner == "B") + world << "
The [gang_name("A")] Gang was [winner=="A" ? "victorious" : "defeated"] with [round((num_ganga/num_survivors)*100, 0.1)]% strength." + world << "
The [gang_name("A")] Gang bosses were:" + gang_membership_report(A_bosses) + world << "
The [gang_name("A")] Gangsters were:" + gang_membership_report(A_gangsters) + + if(B_bosses.len || B_gangsters.len) + if(winner == "A" || winner == "B") + world << "
The [gang_name("B")] Gang was [winner=="B" ? "victorious" : "defeated"] with [round((num_gangb/num_survivors)*100, 0.1)]% strength" + world << "
The [gang_name("B")] Gang bosses were:" + gang_membership_report(B_bosses) + world << "
The [gang_name("B")] Gangsters were:" + gang_membership_report(B_gangsters) + +/datum/game_mode/proc/gang_membership_report(var/list/membership) + var/text = "" + for(var/datum/mind/gang_mind in membership) + text += "
[gang_mind.key] was [gang_mind.name] (" + if(gang_mind.current) + if(gang_mind.current.stat == DEAD || isbrain(gang_mind.current)) + text += "died" + else if(gang_mind.current.z != 1) + text += "fled the station" + else + text += "survived" + if(gang_mind.current.real_name != gang_mind.name) + text += " as [gang_mind.current.real_name]" + else + text += "body destroyed" + text += ")" + text += "
" + + world << text diff --git a/code/game/gamemodes/intercept_report.dm b/code/game/gamemodes/intercept_report.dm index 05ab6f49f63..2be2b45d984 100644 --- a/code/game/gamemodes/intercept_report.dm +++ b/code/game/gamemodes/intercept_report.dm @@ -61,6 +61,10 @@ src.text = "" src.build_rev(correct_person) return src.text + if("gang") + src.text = "" + src.build_gang(correct_person) + return src.text if("cult") src.text = "" src.build_cult(correct_person) @@ -220,6 +224,10 @@ src.text += "
However, if this information is acted on without substantial evidence, those responsible will face severe repercussions." */ +/datum/intercept_text/proc/build_gang(datum/mind/correct_person) + src.text += "

Syndicate forces may be supplying opposing criminal organizations within your sector in an attempt at destabilizing our operations." + src.text += "Ensure law and order is maintained on the station and be on the lookout for violent confrontations between station factions." + src.text += "Forced labor on the mining asteroid is recommended for anyone convicted of heading a criminal organization." /datum/intercept_text/proc/build_wizard(datum/mind/correct_person) var/SWF_desc = pick(SWF_names) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index e0b45a6fc85..8e8c6a4f021 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -90,7 +90,7 @@ datum/objective/mutiny/check_completion() datum/objective/mutiny/update_explanation_text() ..() if(target && target.current) - explanation_text = "Assassinate [target.current.real_name], the [!target_role_type ? target.assigned_role : target.special_role]." + explanation_text = "Assassinate or exile [target.current.real_name], the [!target_role_type ? target.assigned_role : target.special_role]." else explanation_text = "Free Objective" diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 35dff74d813..b2d075f00e9 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -75,10 +75,11 @@ rev_obj.explanation_text = "Assassinate [head_mind.name], the [head_mind.assigned_role]." rev_mind.objectives += rev_obj - // equip_traitor(rev_mind.current, 1) //changing how revs get assigned their uplink so they can get PDA uplinks. --NEO - // Removing revolutionary uplinks. -Pete - equip_revolutionary(rev_mind.current) - update_rev_icons_added(rev_mind) + spawn(rand(10,100)) + // equip_traitor(rev_mind.current, 1) //changing how revs get assigned their uplink so they can get PDA uplinks. --NEO + // Removing revolutionary uplinks. -Pete + equip_revolutionary(rev_mind.current) + update_rev_icons_added(rev_mind) for(var/datum/mind/rev_mind in head_revolutionaries) greet_revolutionary(rev_mind) @@ -103,7 +104,7 @@ var/datum/objective/mutiny/rev_obj = new rev_obj.owner = rev_mind rev_obj.target = head_mind - rev_obj.explanation_text = "Assassinate [head_mind.name], the [head_mind.assigned_role]." + rev_obj.explanation_text = "Assassinate or exile [head_mind.name], the [head_mind.assigned_role]." rev_mind.objectives += rev_obj /datum/game_mode/proc/greet_revolutionary(var/datum/mind/rev_mind, var/you_are=1) @@ -196,7 +197,8 @@ rev_mind.current.attack_log += "\[[time_stamp()]\] Has renounced the revolution!" if(beingborged) - rev_mind.current << "The frame's firmware detects and deletes your neural reprogramming! You remember nothing from the moment you were flashed until now." + rev_mind.current << "The frame's firmware detects and deletes your neural reprogramming! You remember nothing but the name of the one who flashed you." + message_admins("[key_name_admin(rev_mind.current)] ? has been borged while being a member of the revolution.") else rev_mind.current << "You have been brainwashed! You are no longer a 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..." @@ -264,20 +266,36 @@ /datum/game_mode/proc/update_rev_icons_added(datum/mind/rev_mind) spawn(0) for(var/datum/mind/head_rev_mind in head_revolutionaries) + + //Tagging the new rev for revheads to see if(head_rev_mind.current) if(head_rev_mind.current.client) - var/I = image('icons/mob/mob.dmi', loc = rev_mind.current, icon_state = "rev") + var/I + if(rev_mind in head_revolutionaries) //If the new rev is a head rev + I = image('icons/mob/mob.dmi', loc = rev_mind.current, icon_state = "rev_head") + else + I = image('icons/mob/mob.dmi', loc = rev_mind.current, icon_state = "rev") head_rev_mind.current.client.images += I + + //Tagging the revheads for new rev to see if(rev_mind.current) if(rev_mind.current.client) var/image/J = image('icons/mob/mob.dmi', loc = head_rev_mind.current, icon_state = "rev_head") rev_mind.current.client.images += J for(var/datum/mind/rev_mind_1 in revolutionaries) + + //Tagging the new rev for fellow revs to see if(rev_mind_1.current) if(rev_mind_1.current.client) - var/I = image('icons/mob/mob.dmi', loc = rev_mind.current, icon_state = "rev") + var/I + if(rev_mind in head_revolutionaries) //If the new rev is a head rev + I = image('icons/mob/mob.dmi', loc = rev_mind.current, icon_state = "rev_head") + else + I = image('icons/mob/mob.dmi', loc = rev_mind.current, icon_state = "rev") rev_mind_1.current.client.images += I + + //Tagging fellow revs for the new rev to see if(rev_mind.current) if(rev_mind.current.client) var/image/J = image('icons/mob/mob.dmi', loc = rev_mind_1.current, icon_state = "rev") @@ -336,7 +354,7 @@ /datum/game_mode/revolution/declare_completion() if(finished == 1) feedback_set_details("round_end_result","win - heads killed") - world << "The heads of staff were killed or abandoned the station! The revolutionaries win!" + world << "The heads of staff were killed or exiled! The revolutionaries win!" else if(finished == 2) feedback_set_details("round_end_result","loss - rev heads killed") world << "The heads of staff managed to stop the revolution!" @@ -388,7 +406,7 @@ for(var/datum/mind/rev in revolutionaries) text += "
[rev.key] was [rev.name] (" if(rev.current) - if(rev.current.stat == DEAD) + if(rev.current.stat == DEAD || isbrain(rev.current)) text += "died" else if(rev.current.z != 1) text += "fled the station" @@ -414,7 +432,7 @@ text += "" text += "
[head.key] was [head.name] (" if(head.current) - if(head.current.stat == DEAD) + if(head.current.stat == DEAD || isbrain(head.current)) text += "died" else if(head.current.z != 1) text += "fled the station" @@ -429,10 +447,4 @@ text += "
" text += "
" - world << text - -/proc/is_convertable_to_rev(datum/mind/mind) - return istype(mind) && \ - istype(mind.current, /mob/living/carbon/human) && \ - !(mind.assigned_role in command_positions) && \ - !(mind.assigned_role in list("Security Officer", "Detective", "Warden")) + world << text diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 37922f4529a..dc12c7dec60 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -175,17 +175,15 @@ // -- Mode/mind specific stuff goes here - switch(ticker.mode.name) - if("revolution") - if((H.mind in ticker.mode:revolutionaries) || (H.mind in ticker.mode:head_revolutionaries)) - ticker.mode.update_all_rev_icons() //So the icon actually appears - if("nuclear emergency") - if(H.mind in ticker.mode.syndicates) - ticker.mode.update_all_synd_icons() - if("cult") - if (H.mind in ticker.mode.cult) - ticker.mode.add_cultist(src.occupant.mind) - ticker.mode.update_all_cult_icons() //So the icon actually appears + if((H.mind in ticker.mode.revolutionaries) || (H.mind in ticker.mode.head_revolutionaries)) + ticker.mode.update_all_rev_icons() //So the icon actually appears + if((H.mind in ticker.mode.A_bosses) || ((H.mind in ticker.mode.A_gangsters) || (H.mind in ticker.mode.B_bosses)) || (H.mind in ticker.mode.B_gangsters)) + ticker.mode.update_all_gang_icons() + if(H.mind in ticker.mode.syndicates) + ticker.mode.update_all_synd_icons() + if (H.mind in ticker.mode.cult) + ticker.mode.add_cultist(src.occupant.mind) + ticker.mode.update_all_cult_icons() //So the icon actually appears // -- End mode specific stuff diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index 311cc72910c..959e93bec35 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -143,6 +143,7 @@ ticker.mode.remove_cultist(M.brainmob.mind, 1) ticker.mode.remove_revolutionary(M.brainmob.mind, 1) + ticker.mode.remove_gangster(M.brainmob.mind, 1) user.drop_item() M.loc = src diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index c0f658cb15c..bca82949746 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -622,6 +622,7 @@ var/const/CALL_SHUTTLE_REASON_LENGTH = 12 emergency_shuttle.recall(signal_origin) log_game("[key_name(user)] has recalled the shuttle.") message_admins("[key_name_admin(user)] has recalled the shuttle.", 1) + return 1 return /obj/machinery/computer/communications/proc/post_status(var/command, var/data1, var/data2) diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index c719a49a664..f418c40a72b 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -74,20 +74,26 @@ flick("e_flash", M.flash) if(ishuman(M) && ishuman(user) && M.stat != DEAD) - if(user.mind && user.mind in ticker.mode.head_revolutionaries) + if(user.mind && ((user.mind in ticker.mode.head_revolutionaries) || (user.mind in ticker.mode.A_bosses) || (user.mind in ticker.mode.B_bosses))) if(M.client) if(M.stat == CONSCIOUS) - var/revsafe = 0 - if(isloyal(M)) - revsafe = 1 M.mind_initialize() //give them a mind datum if they don't have one. -// if(M.mind.has_been_rev) -// revsafe = 2 - if(!revsafe) + M.mind.has_been_rev = 1 + var/resisted + if(isloyal(M)) + resisted = 1 + else if(user.mind in ticker.mode.head_revolutionaries) + if(!ticker.mode.add_revolutionary(M.mind)) + resisted = 1 + else if(user.mind in ticker.mode.A_bosses) + if(!ticker.mode.add_gangster(M.mind,"A")) + resisted = 1 + else if(user.mind in ticker.mode.B_bosses) + if(!ticker.mode.add_gangster(M.mind,"B")) + resisted = 1 + if(!resisted) M.mind.has_been_rev = 1 ticker.mode.add_revolutionary(M.mind) - else if(revsafe == 1) - user << "Something seems to be blocking the flash!" else user << "This mind seems resistant to the flash!" else diff --git a/code/game/objects/items/devices/recaller.dm b/code/game/objects/items/devices/recaller.dm new file mode 100644 index 00000000000..72ec1e64b08 --- /dev/null +++ b/code/game/objects/items/devices/recaller.dm @@ -0,0 +1,38 @@ +//Recaller device +//Allows gang leaders to recall the shuttle +/obj/item/device/recaller + name = "suspicious device" + desc = "A strange device of sorts. Hard to really make out what it actually does just by looking." + icon_state = "recaller" + item_state = "walkietalkie" + throwforce = 0 + w_class = 1.0 + throw_speed = 3 + throw_range = 7 + flags = CONDUCT + var/recalling = 0 + +/obj/item/device/recaller/attack_self(mob/user) + if(recalling) + return + if((user.mind in ticker.mode.A_bosses) || (user.mind in ticker.mode.B_bosses)) + var/turf/userturf = get_turf(user) + if(userturf.z != 1) + user << "\icon[src]Error: Device out of range of station communication arrays." + return + + if(emergency_shuttle.location==0) + if (emergency_shuttle.online) + recalling = 1 + loc << "\icon[src]Generating shuttle recall order with codes retrieved from last call signal..." + sleep(rand(10,30)) + loc << "\icon[src]Shuttle recall order generated. Accessing station long-range communication arrays..." + sleep(rand(10,30)) + loc << "\icon[src]Comm arrays accessed. Broadcasting recall signal..." + sleep(rand(10,30)) + recalling = 0 + if(!cancel_call_proc(user)) + loc << "\icon[src]No response recieved. Emergency shuttle cannot be recalled at this time." + return + + user << "\icon[src]Emergency shuttle cannot be recalled at this time." \ No newline at end of file diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 26ad543c980..3deee5d8cdc 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -196,7 +196,7 @@ user << "Sticking a dead brain into the frame would sort of defeat the purpose." return - if(M.brainmob.mind in ticker.mode.head_revolutionaries) + if((M.brainmob.mind in ticker.mode.head_revolutionaries) || (M.brainmob.mind in ticker.mode.A_bosses) || (M.brainmob.mind in ticker.mode.B_bosses)) user << "The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept the MMI." return diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm index db40748eec3..7cdce2e281a 100644 --- a/code/modules/admin/DB ban/functions.dm +++ b/code/modules/admin/DB ban/functions.dm @@ -365,7 +365,7 @@ datum/admins/proc/DB_ban_unban_by_id(var/id) output += "" for(var/j in nonhuman_positions) output += "" - for(var/j in list("traitor","changeling","operative","revolutionary","cultist","wizard")) + for(var/j in list("traitor","changeling","operative","revolutionary", "gangster","cultist","wizard")) output += "" output += "" output += "Reason:

" diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index e5237aba5f5..0c85ba713a6 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -430,6 +430,38 @@ dat += "Head not found!" dat += "" + if(ticker.mode.A_bosses.len || ticker.mode.A_gangsters.len) + dat += "
" + for(var/datum/mind/N in ticker.mode.A_bosses) + var/mob/M = N.current + if(!M) + dat += "" + else + dat += "" + dat += "" + for(var/datum/mind/N in ticker.mode.A_gangsters) + var/mob/M = N.current + if(M) + dat += "" + dat += "" + dat += "
[gang_name("A")] Gang Members
Gang Boss not found!
[M.real_name] (Boss)[M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM
[M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM
" + + if(ticker.mode.B_bosses.len || ticker.mode.B_gangsters.len) + dat += "
" + for(var/datum/mind/N in ticker.mode.B_bosses) + var/mob/M = N.current + if(!M) + dat += "" + else + dat += "" + dat += "" + for(var/datum/mind/N in ticker.mode.B_gangsters) + var/mob/M = N.current + if(M) + dat += "" + dat += "" + dat += "
[gang_name("B")] Gang Members
Gang Boss not found!
[M.real_name] (Boss)[M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM
[M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM
" + if(ticker.mode.changelings.len > 0) dat += "
" for(var/datum/mind/changeling in ticker.mode.changelings) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index a51591a7f15..01687037f7d 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -56,12 +56,17 @@ log_admin("[key_name(usr)] created a death squad.") if(!src.makeDeathsquad()) usr << "Unfortunatly there were not enough candidates available." - if("11") var/strength = input("Set Blob Strength (1=Weak, 2=Strong, 3=Full)","Set Strength",1) as num message_admins("[key_name(usr)] spawned a blob with strength [strength].") log_admin("[key_name(usr)] spawned a blob with strength [strength].") new/datum/round_event/blob(strength) + if("12") + message_admins("[key_name(usr)] started a gang war.") + log_admin("[key_name(usr)] started a gang war.") + if(!src.makeGangsters()) + usr << "Unfortunatly there were not enough candidates available." + else if(href_list["forceevent"]) var/datum/round_event_control/E = locate(href_list["forceevent"]) in events.control @@ -579,6 +584,12 @@ jobs += "" //Breaking it up so it fits nicer on the screen every 5 entries + //Gangster + if(jobban_isbanned(M, "gangster") || isbanned_dept) + jobs += "" + else + jobs += "" + //Cultist if(jobban_isbanned(M, "cultist") || isbanned_dept) jobs += "" diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 21875856b58..5f55666e9de 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -17,6 +17,7 @@ client/proc/one_click_antag() Make Cult
Make Malf AI
Make Blob
+ Make Gangsters
Make Wizard (Requires Ghosts)
Make Nuke Team (Requires Ghosts)
Make Deathsquad (Requires Ghosts)
@@ -382,6 +383,37 @@ client/proc/one_click_antag() return + +/datum/admins/proc/makeGangsters() + + var/datum/game_mode/gang/temp = new + if(config.protect_roles_from_antagonist) + temp.restricted_jobs += temp.protected_jobs + + var/list/mob/living/carbon/human/candidates = list() + var/mob/living/carbon/human/H = null + + for(var/mob/living/carbon/human/applicant in player_list) + if(applicant.client.prefs.be_special & BE_GANG) + if(applicant.stat == CONSCIOUS) + if(applicant.mind) + if(!applicant.mind.special_role) + if(!jobban_isbanned(applicant, "gangster") && !jobban_isbanned(applicant, "Syndicate")) + if(!(applicant.job in temp.restricted_jobs)) + candidates += applicant + + if(candidates.len >= 2) + H = pick(candidates) + H.mind.make_Gang("A") + candidates.Remove(H) + H = pick(candidates) + H.mind.make_Gang("B") + candidates.Remove(H) + return 1 + + return 0 + + /datum/admins/proc/makeBody(var/mob/dead/observer/G_found) // Uses stripped down and bastardized code from respawn character if(!G_found || !G_found.key) return diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 7d3b28c5049..2ad54d17ca7 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -16,7 +16,8 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set "pAI candidate" = 1, // 7 "cultist" = IS_MODE_COMPILED("cult"), // 8 "blob" = IS_MODE_COMPILED("blob"), // 9 - "monkey" = IS_MODE_COMPILED("monkey") // 10 + "monkey" = IS_MODE_COMPILED("monkey"), // 10 + "gangster" = IS_MODE_COMPILED("gang") // 11 ) diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 56c26ec1530..54fb349d79d 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -817,20 +817,19 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob) mind.transfer_to(podman) mind.active = oldactive // -- Mode/mind specific stuff goes here. TODO! Broken :( Should be merged into mob/living/Login - switch(ticker.mode.name) - if("revolution") - if(podman.mind in ticker.mode:revolutionaries) - ticker.mode:add_revolutionary(podman.mind) - ticker.mode:update_all_rev_icons() //So the icon actually appears - if(podman.mind in ticker.mode:head_revolutionaries) - ticker.mode:update_all_rev_icons() - if("nuclear emergency") - if(podman.mind in ticker.mode:syndicates) - ticker.mode:update_all_synd_icons() - if("cult") - if(podman.mind in ticker.mode:cult) - ticker.mode:add_cultist(podman.mind) - ticker.mode:update_all_cult_icons() //So the icon actually appears + if((podman.mind in ticker.mode.A_bosses) || (podman.mind in ticker.mode.A_gangsters) || (podman.mind in ticker.mode.B_bosses) || (podman.mind in ticker.mode.B_gangsters)) + ticker.mode.update_all_gang_icons() + if(podman.mind in ticker.mode:revolutionaries) + ticker.mode.add_revolutionary(podman.mind) + ticker.mode.update_all_rev_icons() //So the icon actually appears + if(podman.mind in ticker.mode:head_revolutionaries) + ticker.mode.add_revolutionary(podman.mind) + ticker.mode.update_all_rev_icons() + if(podman.mind in ticker.mode:syndicates) + ticker.mode:update_all_synd_icons() + if(podman.mind in ticker.mode:cult) + ticker.mode:add_cultist(podman.mind) + ticker.mode:update_all_cult_icons() //So the icon actually appears // -- End mode specific stuff diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 35afcd97f8d..35682a33ed6 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -183,6 +183,7 @@ emp_act apply_effect(20, PARALYZE, armor) if(src != user && I.damtype == BRUTE) ticker.mode.remove_revolutionary(mind) + ticker.mode.remove_gangster(mind) if(bloody) //Apply blood if(wear_mask) wear_mask.add_blood(src) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 9a11c2eebe9..f0c5fe46444 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -853,6 +853,7 @@ H.apply_effect(20, PARALYZE, armor) if(H != user && I.damtype == BRUTE) ticker.mode.remove_revolutionary(H.mind) + ticker.mode.remove_gangster(H.mind) if(bloody) //Apply blood if(H.wear_mask) diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm index d19335d1f3e..0d2e5ad541b 100644 --- a/code/modules/mob/living/login.dm +++ b/code/modules/mob/living/login.dm @@ -12,6 +12,11 @@ if("revolution") if((mind in ticker.mode.revolutionaries) || (src.mind in ticker.mode:head_revolutionaries)) ticker.mode.update_rev_icons_added(src.mind) + if("gang") + if((mind in ticker.mode.A_bosses) || (mind in ticker.mode.A_gangsters)) + ticker.mode.update_gang_icons_added(src.mind,"A") + if((mind in ticker.mode.B_bosses) || (mind in ticker.mode.B_gangsters)) + ticker.mode.update_gang_icons_added(src.mind,"B") if("cult") if(mind in ticker.mode:cult) ticker.mode.update_cult_icons_added(src.mind) diff --git a/code/modules/mob/living/silicon/login.dm b/code/modules/mob/living/silicon/login.dm index 677d8fea567..f8bed180209 100644 --- a/code/modules/mob/living/silicon/login.dm +++ b/code/modules/mob/living/silicon/login.dm @@ -2,4 +2,5 @@ if(mind && ticker && ticker.mode) ticker.mode.remove_cultist(mind, 0) ticker.mode.remove_revolutionary(mind, 0) + ticker.mode.remove_gangster(mind, 0) ..() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/login.dm b/code/modules/mob/living/silicon/robot/login.dm index 99e69a84c53..3a8a144d0eb 100644 --- a/code/modules/mob/living/silicon/robot/login.dm +++ b/code/modules/mob/living/silicon/robot/login.dm @@ -4,6 +4,7 @@ regenerate_icons() show_laws(0) if(mind) ticker.mode.remove_revolutionary(mind) + if(mind) ticker.mode.remove_gangster(mind) /mob/living/silicon/robot/update_hotkey_mode() winset(src, null, "mainwindow.macro=borghotkeymode hotkey_toggle.is-checked=true mapwindow.map.focus=true input.background-color=#F0F0F0") diff --git a/html/changelogs/Ikarrus.yml b/html/changelogs/Ikarrus.yml new file mode 100644 index 00000000000..84834636dc0 --- /dev/null +++ b/html/changelogs/Ikarrus.yml @@ -0,0 +1,7 @@ +author: Ikarrus + +#delete-after: True + +changes: + - wip: Adds Gang War, a new game mode still in alpha development. + - experiment: Developer Note: Gang mode is still in development and is not ready to be played reguarly in secret rotations. Server operators are asked to keep Gang mode's probability at 0, and only run it only as a playtest. \ No newline at end of file diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 5530db7dc60..648866f97d7 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi index 28451ff9fc2..2cfaf2b0015 100644 Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index 45948418d9e..e68aa0b2318 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 859dcada271..5ee02581787 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -283,6 +283,7 @@ #include "code\game\gamemodes\cult\runes.dm" #include "code\game\gamemodes\cult\talisman.dm" #include "code\game\gamemodes\extended\extended.dm" +#include "code\game\gamemodes\gang\gang.dm" #include "code\game\gamemodes\malfunction\Malf_Modules.dm" #include "code\game\gamemodes\malfunction\malfunction.dm" #include "code\game\gamemodes\meteor\meteor.dm" @@ -508,6 +509,7 @@ #include "code\game\objects\items\devices\multitool.dm" #include "code\game\objects\items\devices\paicard.dm" #include "code\game\objects\items\devices\powersink.dm" +#include "code\game\objects\items\devices\recaller.dm" #include "code\game\objects\items\devices\scanners.dm" #include "code\game\objects\items\devices\taperecorder.dm" #include "code\game\objects\items\devices\traitordevices.dm"
Changelings
[replacetext("Gangster", " ", " ")][replacetext("Gangster", " ", " ")][replacetext("Cultist", " ", " ")]