From 6c077758c64fa9273591d1de7cc7559c7ff05fc6 Mon Sep 17 00:00:00 2001 From: JTGSZ <46565256+JTGSZ@users.noreply.github.com> Date: Sat, 18 May 2019 05:06:22 -0400 Subject: [PATCH] ports gang --- code/__DEFINES/antagonists.dm | 5 + code/__DEFINES/role_preferences.dm | 6 +- code/modules/admin/topic.dm | 9 +- icons/effects/crayondecal.dmi | Bin 29115 -> 34780 bytes icons/mob/hud.dmi | Bin 14773 -> 14934 bytes icons/obj/device.dmi | Bin 43527 -> 43562 bytes .../code/game/gamemodes/gangs/dominator.dm | 241 +++++++++ .../gamemodes/gangs/dominator_countdown.dm | 13 + .../code/game/gamemodes/gangs/gang.dm | 475 ++++++++++++++++++ .../code/game/gamemodes/gangs/gang_crayon.dm | 236 +++++++++ .../code/game/gamemodes/gangs/gang_datums.dm | 139 +++++ .../code/game/gamemodes/gangs/gang_decals.dm | 38 ++ .../code/game/gamemodes/gangs/gang_hud.dm | 34 ++ .../code/game/gamemodes/gangs/gang_items.dm | 404 +++++++++++++++ .../code/game/gamemodes/gangs/gang_pen.dm | 58 +++ .../code/game/gamemodes/gangs/gangs.dm | 59 +++ .../code/game/gamemodes/gangs/gangtool.dm | 259 ++++++++++ .../code/game/gamemodes/gangs/implant_gang.dm | 61 +++ tgstation.dme | 12 + 19 files changed, 2046 insertions(+), 3 deletions(-) create mode 100644 modular_citadel/code/game/gamemodes/gangs/dominator.dm create mode 100644 modular_citadel/code/game/gamemodes/gangs/dominator_countdown.dm create mode 100644 modular_citadel/code/game/gamemodes/gangs/gang.dm create mode 100644 modular_citadel/code/game/gamemodes/gangs/gang_crayon.dm create mode 100644 modular_citadel/code/game/gamemodes/gangs/gang_datums.dm create mode 100644 modular_citadel/code/game/gamemodes/gangs/gang_decals.dm create mode 100644 modular_citadel/code/game/gamemodes/gangs/gang_hud.dm create mode 100644 modular_citadel/code/game/gamemodes/gangs/gang_items.dm create mode 100644 modular_citadel/code/game/gamemodes/gangs/gang_pen.dm create mode 100644 modular_citadel/code/game/gamemodes/gangs/gangs.dm create mode 100644 modular_citadel/code/game/gamemodes/gangs/gangtool.dm create mode 100644 modular_citadel/code/game/gamemodes/gangs/implant_gang.dm diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index 4c454aa61a..e35defd485 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -35,3 +35,8 @@ //Overthrow time to update heads obj #define OBJECTIVE_UPDATING_TIME 300 + +//Gangshit +#define NOT_DOMINATING -1 +#define MAX_LEADERS_GANG 3 +#define INITIAL_DOM_ATTEMPTS 3 diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 6773d55e53..b316c003a9 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -33,7 +33,8 @@ #define ROLE_DRONE "drone" #define ROLE_DEATHSQUAD "deathsquad" #define ROLE_LAVALAND "lavaland" -#define ROLE_INTERNAL_AFFAIRS "internal affairs agent" +#define ROLE_INTERNAL_AFFAIRS "internal affairs agent" +#define ROLE_GANG "gangster" //Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR. //The gamemode specific ones are just so the gamemodes can query whether a player is old enough @@ -58,7 +59,8 @@ GLOBAL_LIST_INIT(special_roles, list( ROLE_SERVANT_OF_RATVAR = /datum/game_mode/clockwork_cult, ROLE_OVERTHROW = /datum/game_mode/overthrow, ROLE_INTERNAL_AFFAIRS = /datum/game_mode/traitor/internal_affairs, - ROLE_SENTIENCE + ROLE_SENTIENCE, + ROLE_GANG = /datum/game_mode/gang )) //Job defines for what happens when you fail to qualify for any job during job selection diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 226f2a5456..6fa118ab7f 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -903,6 +903,13 @@ else dat += "Alien" + //Gang + if(jobban_isbanned(M, ROLE_GANG) || isbanned_dept) + dat += "Gang" + else + dat += "Gang" + + //Other Roles (black) dat += "" dat += "" @@ -974,7 +981,7 @@ if("ghostroles") joblist += list(ROLE_PAI, ROLE_POSIBRAIN, ROLE_DRONE , ROLE_DEATHSQUAD, ROLE_LAVALAND, ROLE_SENTIENCE) if("teamantags") - joblist += list(ROLE_OPERATIVE, ROLE_REV, ROLE_CULTIST, ROLE_SERVANT_OF_RATVAR, ROLE_ABDUCTOR, ROLE_ALIEN) + joblist += list(ROLE_OPERATIVE, ROLE_REV, ROLE_CULTIST, ROLE_SERVANT_OF_RATVAR, ROLE_ABDUCTOR, ROLE_ALIEN, ROLE_GANG) if("convertantags") joblist += list(ROLE_REV, ROLE_CULTIST, ROLE_SERVANT_OF_RATVAR, ROLE_ALIEN) if("otherroles") diff --git a/icons/effects/crayondecal.dmi b/icons/effects/crayondecal.dmi index bb48832025c0b6e4e7c3850a6d5020b72da517b9..fcd27698e7e1b286291a7eb0cfeb211fd1081683 100644 GIT binary patch delta 10004 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 PfyXoX=TA%I%!2+0Aq1Ru delta 4310 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 diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 047f08094662b38053bdae13b3d87a530d485cac..10474f94da8c8e6a2667411520ebb65c5f18d096 100644 GIT binary patch literal 14934 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 diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index becb58568ff14b0a8d215f10a556f805b1a920ee..55c33e5e832f86f5fcc95aad40486aab775056bd 100644 GIT binary patch delta 23479 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 z world.time) + to_chat(user, "Hostile Takeover in progress. Estimated [gang.domination_time_remaining()] seconds remain.") + else + to_chat(user, "Hostile Takeover of [station_name()] successful. Have a great day.") + else + to_chat(user, "System on standby.") + to_chat(user, "System Integrity: [round((obj_integrity/max_integrity)*100,1)]%") + +/obj/machinery/dominator/process() + ..() + if(gang && gang.domination_time != NOT_DOMINATING) + var/time_remaining = gang.domination_time_remaining() + if(time_remaining > 0) + if(excessive_walls_check()) + gang.domination_time += 20 + playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0) + if(spam_prevention < DOM_BLOCKED_SPAM_CAP) + spam_prevention++ + else + gang.message_gangtools("Warning: There are too many walls around your gang's dominator, its signal is being blocked!") + say("Error: Takeover signal is currently blocked! There are too many walls within 3 standard units of this device.") + spam_prevention = 0 + return + . = TRUE + playsound(loc, 'sound/items/timer.ogg', 10, 0) + if(!warned && (time_remaining < 180)) + warned = TRUE + var/area/domloc = get_area(loc) + gang.message_gangtools("Less than 3 minutes remains in hostile takeover. Defend your dominator at [domloc.map_name]!") + for(var/G in GLOB.gangs) + var/datum/team/gang/tempgang = G + if(tempgang != gang) + tempgang.message_gangtools("WARNING: [gang.name] Gang takeover imminent. Their dominator at [domloc.map_name] must be destroyed!",1,1) + else + Cinematic(CINEMATIC_MALF,world) //Here is the gang victory trigger on the dominator ending. + gang.winner = TRUE + SSticker.force_ending = TRUE + + if(!.) + STOP_PROCESSING(SSmachines, src) + +/obj/machinery/dominator/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) + switch(damage_type) + if(BRUTE) + if(damage_amount) + playsound(src, 'sound/effects/bang.ogg', 50, 1) + else + playsound(loc, 'sound/weapons/tap.ogg', 50, 1) + if(BURN) + playsound(src.loc, 'sound/items/welder.ogg', 100, 1) + +/obj/machinery/dominator/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1) + . = ..() + if(.) + if(obj_integrity/max_integrity > 0.66) + if(prob(damage_amount*2)) + spark_system.start() + else if(!(stat & BROKEN)) + spark_system.start() + update_icon() + + +/obj/machinery/dominator/obj_break(damage_flag) + if(!(stat & BROKEN) && !(flags_1 & NODECONSTRUCT_1)) + set_broken() + +/obj/machinery/dominator/deconstruct(disassembled = TRUE) + if(!(flags_1 & NODECONSTRUCT_1)) + if(!(stat & BROKEN)) + set_broken() + new /obj/item/stack/sheet/plasteel(src.loc) + qdel(src) + +/obj/machinery/dominator/attacked_by(obj/item/I, mob/living/user) + add_fingerprint(user) + ..() + +/obj/machinery/dominator/attack_hand(mob/user) + if(operating || (stat & BROKEN)) + examine(user) + return + + var/datum/team/gang/tempgang + + var/datum/antagonist/gang/GA = user.mind.has_antag_datum(/datum/antagonist/gang) + if(GA) + tempgang = GA.gang + if(!tempgang) + examine(user) + return + + if(tempgang.domination_time != NOT_DOMINATING) + to_chat(user, "Error: Hostile Takeover is already in progress.") + return + + if(!tempgang.dom_attempts) + to_chat(user, "Error: Unable to breach station network. Firewall has logged our signature and is blocking all further attempts.") + return + + var/time = round(tempgang.determine_domination_time()/60,0.1) + if(alert(user,"A takeover will require [time] minutes.\nYour gang will be unable to gain influence while it is active.\nThe entire station will likely be alerted to it once it starts.\nYou have [tempgang.dom_attempts] attempt(s) remaining. Are you ready?","Confirm","Ready","Later") == "Ready") + if((tempgang.domination_time != NOT_DOMINATING) || !tempgang.dom_attempts || !in_range(src, user) || !isturf(loc)) + return 0 + + var/area/A = get_area(loc) + var/locname = A.map_name + + gang = tempgang + gang.dom_attempts -- + priority_announce("Network breach detected in [locname]. The [gang.name] Gang is attempting to seize control of the station!","Network Alert") + gang.domination() + SSshuttle.registerHostileEnvironment(src) + name = "[gang.name] Gang [name]" + operating = TRUE + update_icon() + + countdown.start() + countdown.color = gang.color + + set_light(3) + START_PROCESSING(SSmachines, src) + + gang.message_gangtools("Hostile takeover in progress: Estimated [time] minutes until victory.[gang.dom_attempts ? "" : " This is your final attempt."]") + for(var/G in GLOB.gangs) + var/datum/team/gang/vagos = G + if(vagos != gang) + vagos.message_gangtools("Enemy takeover attempt detected in [locname]: Estimated [time] minutes until our defeat.",1,1) + +/obj/machinery/dominator/proc/excessive_walls_check() // why the fuck was this even a global proc... + var/open = FALSE + for(var/turf/T in view(3, src)) + if(!isclosedturf(T)) + open++ + if(open < DOM_REQUIRED_TURFS) + return TRUE + else + return FALSE + +/obj/machinery/dominator/proc/set_broken() + if(gang) + gang.domination_time = NOT_DOMINATING + + var/takeover_in_progress = FALSE + for(var/G in GLOB.gangs) + var/datum/team/gang/ballas = G + if(ballas.domination_time != NOT_DOMINATING) + takeover_in_progress = TRUE + break + if(!takeover_in_progress) + var/was_stranded = SSshuttle.emergency.mode == SHUTTLE_STRANDED + if(!was_stranded) + priority_announce("All hostile activity within station systems has ceased.","Network Alert") + + if(get_security_level() == "delta") + set_security_level("red") + + SSshuttle.clearHostileEnvironment(src) + gang.message_gangtools("Hostile takeover cancelled: Dominator is no longer operational.[gang.dom_attempts ? " You have [gang.dom_attempts] attempt remaining." : " The station network will have likely blocked any more attempts by us."]",1,1) + + set_light(0) + operating = FALSE + stat |= BROKEN + update_icon() + STOP_PROCESSING(SSmachines, src) + +#undef DOM_BLOCKED_SPAM_CAP +#undef DOM_REQUIRED_TURFS +#undef DOM_HULK_HITS_REQUIRED \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/dominator_countdown.dm b/modular_citadel/code/game/gamemodes/gangs/dominator_countdown.dm new file mode 100644 index 0000000000..c6ae610e37 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/dominator_countdown.dm @@ -0,0 +1,13 @@ +/obj/effect/countdown/dominator + name = "dominator countdown" + text_size = 1 + color = "#e5e5e5" // Overwritten when the dominator starts + +/obj/effect/countdown/dominator/get_value() + var/obj/machinery/dominator/D = attached_to + if(!istype(D)) + return + else if(D.gang && D.gang.domination_time != NOT_DOMINATING) + return D.gang.domination_time_remaining() + else + return "OFFLINE" \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/gang.dm b/modular_citadel/code/game/gamemodes/gangs/gang.dm new file mode 100644 index 0000000000..5b93cf0cb7 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gang.dm @@ -0,0 +1,475 @@ +/datum/antagonist/gang + name = "Gangster" + roundend_category = "gangsters" + can_coexist_with_others = FALSE + job_rank = ROLE_GANG + antagpanel_category = "Gang" + var/hud_type = "gangster" + var/message_name = "Gangster" + var/datum/team/gang/gang + +/datum/antagonist/gang/can_be_owned(datum/mind/new_owner) + . = ..() + if(.) + if(new_owner.unconvertable) + return FALSE + +/datum/antagonist/gang/apply_innate_effects(mob/living/mob_override) + var/mob/living/M = mob_override || owner.current + update_gang_icons_added(M) + +/datum/antagonist/gang/remove_innate_effects(mob/living/mob_override) + var/mob/living/M = mob_override || owner.current + update_gang_icons_removed(M) + +/datum/antagonist/gang/get_team() + return gang + +/datum/antagonist/gang/greet() + gang.greet_gangster(owner) + +/datum/antagonist/gang/farewell() + if(ishuman(owner.current)) + owner.current.visible_message("[owner.current] looks like [owner.current.p_theyve()] just remembered [owner.current.p_their()] real allegiance!", null, null, null, owner.current) + to_chat(owner, "You are no longer a gangster!") + +/datum/antagonist/gang/on_gain() + if(!gang) + create_team() + ..() + var/mob/living/carbon/human/H = owner.current + if(istype(H)) + if(owner.assigned_role == "Clown") + to_chat(owner, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") + H.dna.remove_mutation(CLOWNMUT) + add_to_gang() + +/datum/antagonist/gang/on_removal() + remove_from_gang() + ..() + +/datum/antagonist/gang/create_team(team) + if(!gang) // add_antag_datum calls create_team, so we need to avoid generating two gangs in that case + if(team) + gang = team + return + var/datum/team/gang/gangteam = pick_n_take(GLOB.possible_gangs) + if(gangteam) + gang = new gangteam + +/datum/antagonist/gang/proc/equip_gang() // Bosses get equipped with their tools + return + +/datum/antagonist/gang/proc/update_gang_icons_added(mob/living/M) + var/datum/atom_hud/antag/gang/ganghud = GLOB.huds[gang.hud_entry_num] + if(!ganghud) + ganghud = new/datum/atom_hud/antag/gang() + gang.hud_entry_num = GLOB.huds.len+1 // this is the index the gang hud will be added at + GLOB.huds += ganghud + ganghud.color = gang.color + ganghud.join_hud(M) + set_antag_hud(M,hud_type) + +/datum/antagonist/gang/proc/update_gang_icons_removed(mob/living/M) + var/datum/atom_hud/antag/gang/ganghud = GLOB.huds[gang.hud_entry_num] + if(ganghud) + ganghud.leave_hud(M) + set_antag_hud(M, null) + +/datum/antagonist/gang/proc/can_be_converted(mob/living/candidate) + if(!candidate.mind) + return FALSE + if(!can_be_owned(candidate.mind)) + return FALSE + var/mob/living/carbon/human/H = candidate + if(!istype(H)) //Can't nonhumans + return FALSE + return TRUE + +/datum/antagonist/gang/proc/promote() // Bump up to boss + var/datum/team/gang/old_gang = gang + var/datum/mind/old_owner = owner + owner.remove_antag_datum(/datum/antagonist/gang) + var/datum/antagonist/gang/boss/lieutenant/new_boss = new + new_boss.silent = TRUE + old_owner.add_antag_datum(new_boss,old_gang) + new_boss.silent = FALSE + log_game("[key_name(old_owner)] has been promoted to Lieutenant in the [old_gang.name] Gang") + to_chat(old_owner, "You have been promoted to Lieutenant!") + + +// Admin commands +/datum/antagonist/gang/get_admin_commands() + . = ..() + .["Promote"] = CALLBACK(src,.proc/admin_promote) + .["Set Influence"] = CALLBACK(src, .proc/admin_adjust_influence) + if(gang.domination_time != NOT_DOMINATING) + .["Set domination time left"] = CALLBACK(src, .proc/set_dom_time_left) + +/datum/antagonist/gang/admin_add(datum/mind/new_owner,mob/admin) + var/new_or_existing = input(admin, "Which gang do you want to be assigned to the user?", "Gangs") as null|anything in list("New","Existing") + if(isnull(new_or_existing)) + return + else if(new_or_existing == "New") + var/newgang = input(admin, "Select a gang, or select random to pick a random one.", "New gang") as null|anything in GLOB.possible_gangs + "Random" + if(isnull(newgang)) + return + else if(newgang == "Random") + var/datum/team/gang/G = pick_n_take(GLOB.possible_gangs) + gang = new G + else + GLOB.possible_gangs -= newgang + gang = new newgang + else + if(!GLOB.gangs.len) // no gangs exist + to_chat(admin, "No gangs exist, please create a new one instead.") + return + var/existinggang = input(admin, "Select a gang, or select random to pick a random one.", "Existing gang") as null|anything in GLOB.gangs + "Random" + if(isnull(existinggang)) + return + else if(existinggang == "Random") + gang = pick(GLOB.gangs) + else + gang = existinggang + ..() + return TRUE + +/datum/antagonist/gang/proc/admin_promote(mob/admin) + message_admins("[key_name_admin(admin)] has promoted [owner] to gang boss.") + log_admin("[key_name(admin)] has promoted [owner] to boss.") + promote() + +/datum/antagonist/gang/proc/admin_adjust_influence() + var/inf = input("Influence for [gang.name]","Gang influence", gang.influence) as null | num + if(!isnull(inf)) + gang.influence = inf + message_admins("[key_name_admin(usr)] changed [gang.name]'s influence to [inf].") + log_admin("[key_name(usr)] changed [gang.name]'s influence to [inf].") + +/datum/antagonist/gang/proc/add_to_gang() + gang.add_member(owner) + owner.current.log_message("Has been converted to the [gang.name] gang!", INDIVIDUAL_ATTACK_LOG) + +/datum/antagonist/gang/proc/remove_from_gang() + gang.remove_member(owner) + owner.current.log_message("Has been deconverted from the [gang.name] gang!", INDIVIDUAL_ATTACK_LOG) + +/datum/antagonist/gang/proc/set_dom_time_left(mob/admin) + if(gang.domination_time == NOT_DOMINATING) + return // an admin shouldn't need this + var/seconds = input(admin, "Set the time left for the gang to win, in seconds", "Domination time left") as null|num + if(seconds && seconds > 0) + gang.domination_time = world.time + seconds*10 + gang.message_gangtools("Takeover shortened to [gang.domination_time_remaining()] seconds by your Syndicate benefactors.") + +// Boss type. Those can use gang tools to buy items for their gang, in particular the Dominator, used to win the gamemode, along with more gang tools to promote fellow gangsters to boss status. +/datum/antagonist/gang/boss + name = "Gang boss" + hud_type = "gang_boss" + message_name = "Leader" + +/datum/antagonist/gang/boss/on_gain() + ..() + if(gang) + gang.leaders += owner + +/datum/antagonist/gang/boss/on_removal() + if(gang) + gang.leaders -= owner + ..() + +/datum/antagonist/gang/boss/antag_listing_name() + return ..() + "(Boss)" + +/datum/antagonist/gang/boss/equip_gang(gangtool = TRUE, pen = TRUE, spraycan = TRUE, hud = TRUE) // usually has to be called separately + var/mob/living/carbon/human/H = owner.current + if(!istype(H)) + return + + var/list/slots = list ( + "backpack" = SLOT_IN_BACKPACK, + "left pocket" = SLOT_L_STORE, + "right pocket" = SLOT_R_STORE, + "hands" = SLOT_HANDS + ) + + if(gangtool) + var/obj/item/device/gangtool/G = new() + var/where = H.equip_in_one_of_slots(G, slots) + if (!where) + to_chat(H, "Your Syndicate benefactors were unfortunately unable to get you a Gangtool.") + else + G.register_device(H) + to_chat(H, "The Gangtool in your [where] will allow you to purchase weapons and equipment, send messages to your gang, and recall the emergency shuttle from anywhere on the station.") + to_chat(H, "As the gang boss, you can also promote your gang members to lieutenant. Unlike regular gangsters, Lieutenants cannot be deconverted and are able to use recruitment pens and gangtools.") + + if(pen) + var/obj/item/pen/gang/T = new() + var/where2 = H.equip_in_one_of_slots(T, slots) + if (!where2) + to_chat(H, "Your Syndicate benefactors were unfortunately unable to get you a recruitment pen to start.") + else + to_chat(H, "The recruitment pen in your [where2] will help you get your gang started. Stab unsuspecting crew members with it to recruit them.") + + if(spraycan) + var/obj/item/toy/crayon/spraycan/gang/SC = new(null,gang) + var/where3 = H.equip_in_one_of_slots(SC, slots) + if (!where3) + to_chat(H, "Your Syndicate benefactors were unfortunately unable to get you a territory spraycan to start.") + else + to_chat(H, "The territory spraycan in your [where3] can be used to claim areas of the station for your gang. The more territory your gang controls, the more influence you get. All gangsters can use these, so distribute them to grow your influence faster.") + + if(hud) + var/obj/item/clothing/glasses/hud/security/chameleon/C = new(null,gang) + var/where4 = H.equip_in_one_of_slots(C, slots) + if (!where4) + to_chat(H, "Your Syndicate benefactors were unfortunately unable to get you a chameleon security HUD.") + else + to_chat(H, "The chameleon security HUD in your [where4] will help you keep track of who is mindshield-implanted, and unable to be recruited.") + +// Admin commands for bosses +/datum/antagonist/gang/boss/admin_add(datum/mind/new_owner,mob/admin) + if(!new_owner.has_antag_datum(parent_type)) + ..() + to_chat(new_owner.current, "You are a member of the [gang.name] Gang leadership now!") + return + promote() + message_admins("[key_name_admin(admin)] has made [new_owner.current] a boss of the [gang.name] gang.") + log_admin("[key_name(admin)] has made [new_owner.current] a boss of the [gang.name] gang.") + to_chat(new_owner.current, "You are a member of the [gang.name] Gang leadership now!") + +/datum/antagonist/gang/boss/get_admin_commands() + . = ..() + . -= "Promote" + .["Take gangtool"] = CALLBACK(src,.proc/admin_take_gangtool) + .["Give gangtool"] = CALLBACK(src,.proc/admin_give_gangtool) + .["Demote"] = CALLBACK(src,.proc/admin_demote) + +/datum/antagonist/gang/boss/proc/demote() + var/old_gang = gang + var/datum/mind/old_owner = owner + silent = TRUE + owner.remove_antag_datum(/datum/antagonist/gang/boss) + var/datum/antagonist/gang/new_gangster = new /datum/antagonist/gang() + new_gangster.silent = TRUE + old_owner.add_antag_datum(new_gangster,old_gang) + new_gangster.silent = FALSE + log_game("[key_name(old_owner)] has been demoted to Gangster in the [gang.name] Gang") + to_chat(old_owner, "The gang has been disappointed of your leader traits! You are a regular gangster now!") + +/datum/antagonist/gang/boss/proc/admin_take_gangtool(mob/admin) + var/list/L = owner.current.get_contents() + var/obj/item/device/gangtool/gangtool = locate() in L + if (!gangtool) + to_chat(admin, "Deleting gangtool failed!") + return + qdel(gangtool) + +/datum/antagonist/gang/boss/proc/admin_give_gangtool(mob/admin) + equip_gang(TRUE, FALSE, FALSE, FALSE) + +/datum/antagonist/gang/boss/proc/admin_demote(datum/mind/target,mob/user) + message_admins("[key_name_admin(user)] has demoted [owner.current] from gang boss.") + log_admin("[key_name(user)] has demoted [owner.current] from gang boss.") + admin_take_gangtool(user) + demote() + +/datum/antagonist/gang/boss/lieutenant + name = "Gang Lieutenant" + message_name = "Lieutenant" + hud_type = "gang_lt" + +#define MAXIMUM_RECALLS 3 +#define INFLUENCE_INTERVAL 1200 //This handles the interval between each count of influence. +// Gang team datum. This handles the gang itself. +/datum/team/gang + name = "Gang" + member_name = "gangster" + var/hud_entry_num // because if you put something other than a number in GLOB.huds, god have mercy on your fucking soul friend + var/list/leaders = list() // bosses + var/max_leaders = MAX_LEADERS_GANG + var/list/territories = list() // territories owned by the gang. + var/list/lost_territories = list() // territories lost by the gang. + var/list/new_territories = list() // territories captured by the gang. + var/list/gangtools = list() + var/domination_time = NOT_DOMINATING + var/dom_attempts = INITIAL_DOM_ATTEMPTS + var/color + var/influence = 0 // influence of the gang, based on how many territories they own. Can be used to buy weapons and tools from a gang uplink. + var/winner // Once the gang wins with a dominator, this becomes true. For roundend credits purposes. + var/list/inner_outfits = list() + var/list/outer_outfits = list() + var/next_point_time + var/recalls = MAXIMUM_RECALLS // Once this reaches 0, this gang cannot force recall the shuttle with their gangtool anymore + +/datum/team/gang/New(starting_members) + . = ..() + GLOB.gangs += src + if(starting_members) + if(islist(starting_members)) + for(var/datum/mind/groveboss in starting_members) + leaders += groveboss + var/datum/antagonist/gang/boss/gb = new + groveboss.add_antag_datum(gb, src) + gb.equip_gang() + + else + var/datum/mind/CJ = starting_members + if(istype(CJ)) + leaders += CJ + var/datum/antagonist/gang/boss/bossdatum = new + CJ.add_antag_datum(bossdatum, src) + bossdatum.equip_gang() + next_point_time = world.time + INFLUENCE_INTERVAL + addtimer(CALLBACK(src, .proc/handle_territories), INFLUENCE_INTERVAL) + +/datum/team/gang/Destroy() + GLOB.gangs -= src + ..() + +/datum/team/gang/roundend_report() + var/list/report = list() + report += "[name]:" + if(winner) + report += "The [name] gang was successful!" + else + report += "The [name] gang has failed!" + + report += "The [name] gang bosses were:" + report += printplayerlist(leaders) + report += "The [name] [member_name]s were:" + report += printplayerlist(members-leaders) + + return "

[report.Join("
")]
" + +/datum/team/gang/proc/greet_gangster(datum/mind/gangster) + to_chat(gangster, "You are now a member of the [name] Gang!") + to_chat(gangster, "Help your bosses take over the station by claiming territory with special spraycans only they can provide. Simply spray on any unclaimed area of the station.") + to_chat(gangster, "Their ultimate objective is to take over the station with a Dominator machine.") + to_chat(gangster, "You can identify your mates by their large, \[G\] icon.") + gangster.store_memory("You are a member of the [name] Gang!") + +/datum/team/gang/proc/handle_territories() + next_point_time = world.time + INFLUENCE_INTERVAL + if(!leaders.len) + return + var/added_names = "" + var/lost_names = "" + + //Re-add territories that were reclaimed, so if they got tagged over, they can still earn income if they tag it back before the next status report + var/list/reclaimed_territories = new_territories & lost_territories + territories |= reclaimed_territories + new_territories -= reclaimed_territories + lost_territories -= reclaimed_territories + + //Process lost territories + for(var/area in lost_territories) + if(lost_names != "") + lost_names += ", " + lost_names += "[lost_territories[area]]" + territories -= area + + //Calculate and report influence growth + + //Process new territories + for(var/area in new_territories) + if(added_names != "") + added_names += ", " + added_names += "[new_territories[area]]" + territories += area + + //Report territory changes + var/message = "[src] Gang Status Report:.
*---------*
" + message += "[new_territories.len] new territories:
[added_names]
" + message += "[lost_territories.len] territories lost:
[lost_names]
" + //Clear the lists + new_territories = list() + lost_territories = list() + var/total_territories = total_claimable_territories() + var/control = round((territories.len/total_territories)*100, 1) + var/uniformed = check_clothing() + message += "Your gang now has [control]% control of the station.
*---------*
" + if(domination_time != NOT_DOMINATING) + var/new_time = max(world.time, domination_time - (uniformed * 4) - (territories.len * 2)) + if(new_time < domination_time) + message += "Takeover shortened by [(domination_time - new_time)*0.1] seconds for defending [territories.len] territories.
" + domination_time = new_time + message += "[domination_time_remaining()] seconds remain in hostile takeover.
" + else + var/new_influence = check_territory_income() + if(new_influence != influence) + message += "Gang influence has increased by [new_influence - influence] for defending [territories.len] territories and [uniformed] uniformed gangsters.
" + influence = new_influence + message += "Your gang now has [influence] influence.
" + message_gangtools(message) + addtimer(CALLBACK(src, .proc/handle_territories), INFLUENCE_INTERVAL) + +/datum/team/gang/proc/total_claimable_territories() + var/list/valid_territories = list() + for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION)) //First, collect all area types on the station zlevel + for(var/ar in SSmapping.areas_in_z["[z]"]) + var/area/A = ar + if(!(A.type in valid_territories) && A.valid_territory) + valid_territories |= A.type + return valid_territories.len + +/datum/team/gang/proc/check_territory_income() + var/new_influence = min(999,influence + 15 + (check_clothing() * 2) + territories.len) + return new_influence + +/datum/team/gang/proc/check_clothing() + //Count uniformed gangsters + var/uniformed = 0 + for(var/datum/mind/gangmind in members) + if(ishuman(gangmind.current)) + var/mob/living/carbon/human/gangster = gangmind.current + //Gangster must be alive and should return 0 not continue if conditions are met. + if(!istype(gangster) || gangster.stat == DEAD) + return 0 + + var/obj/item/clothing/outfit + var/obj/item/clothing/gang_outfit + if(gangster.w_uniform) + outfit = gangster.w_uniform + if(outfit.type in inner_outfits) + gang_outfit = outfit + if(gangster.wear_suit) + outfit = gangster.wear_suit + if(outfit.type in outer_outfits) + gang_outfit = outfit + + if(gang_outfit) + uniformed++ + return uniformed + +/datum/team/gang/proc/adjust_influence(value) + influence = max(0, influence + value) + +/datum/team/gang/proc/message_gangtools(message) + if(!gangtools.len || !message) + return + for(var/i in gangtools) + var/obj/item/device/gangtool/tool = i + var/mob/living/mob = get(tool.loc, /mob/living) + if(mob && mob.mind && mob.stat == CONSCIOUS) + var/datum/antagonist/gang/gangster = mob.mind.has_antag_datum(/datum/antagonist/gang) + if(gangster.gang == src) + to_chat(mob, "[icon2html(tool, mob)] [message]") + playsound(mob.loc, 'sound/machines/twobeep.ogg', 50, 1) + return + +/datum/team/gang/proc/domination() + domination_time = world.time + determine_domination_time()*10 + set_security_level("delta") + +/datum/team/gang/proc/determine_domination_time() // calculates the value in seconds (this is the initial domination time!) + var/total_territories = total_claimable_territories() + return max(180,480 - (round((territories.len/total_territories)*100, 1) * 9)) + +/datum/team/gang/proc/domination_time_remaining() // retrieves the value from world.time based deciseconds to seconds + var/diff = domination_time - world.time + return round(diff * 0.1) + + +#undef MAXIMUM_RECALLS +#undef INFLUENCE_INTERVAL \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/gang_crayon.dm b/modular_citadel/code/game/gamemodes/gangs/gang_crayon.dm new file mode 100644 index 0000000000..2edc2ba945 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gang_crayon.dm @@ -0,0 +1,236 @@ +#define RANDOM_GRAFFITI "Random Graffiti" +#define RANDOM_LETTER "Random Letter" +#define RANDOM_NUMBER "Random Number" +#define RANDOM_ORIENTED "Random Oriented" +#define RANDOM_RUNE "Random Rune" +#define RANDOM_ANY "Random Anything" + +/obj/item/toy/crayon + var/datum/team/gang/gang //For marking territory, spraycans are gang-locked to their initial gang due to colors + +/obj/item/toy/crayon/afterattack(atom/target, mob/user, proximity, params) + if(!proximity || !check_allowed_items(target)) + return + + var/cost = 1 + if(paint_mode == PAINT_LARGE_HORIZONTAL) + cost = 5 + if(istype(target, /obj/item/canvas)) + cost = 0 + + if(istype(target, /obj/effect/decal/cleanable)) + target = target.loc + + if(!is_type_in_list(target,validSurfaces)) + return + + var/drawing = drawtype + switch(drawtype) + if(RANDOM_LETTER) + drawing = pick(letters) + if(RANDOM_GRAFFITI) + drawing = pick(graffiti) + if(RANDOM_RUNE) + drawing = pick(runes) + if(RANDOM_ORIENTED) + drawing = pick(oriented) + if(RANDOM_NUMBER) + drawing = pick(numerals) + if(RANDOM_ANY) + drawing = pick(all_drawables) + + var/temp = "rune" + if(drawing in letters) + temp = "letter" + else if(drawing in graffiti) + temp = "graffiti" + else if(drawing in numerals) + temp = "number" + + temp = gang_check(user,target) + if(!temp) return // hippie + var/graf_rot + if(drawing in oriented) + switch(user.dir) + if(EAST) + graf_rot = 90 + if(SOUTH) + graf_rot = 180 + if(WEST) + graf_rot = 270 + else + graf_rot = 0 + + var/list/click_params = params2list(params) + var/clickx + var/clicky + + if(click_params && click_params["icon-x"] && click_params["icon-y"]) + clickx = CLAMP(text2num(click_params["icon-x"]) - 16, -(world.icon_size/2), world.icon_size/2) + clicky = CLAMP(text2num(click_params["icon-y"]) - 16, -(world.icon_size/2), world.icon_size/2) + + if(!instant) + to_chat(user, "You start drawing a [temp] on the [target.name]...") + + if(pre_noise) + audible_message("You hear spraying.") + playsound(user.loc, 'sound/effects/spray.ogg', 5, 1, 5) + + var/takes_time = !instant + + var/wait_time = 50 + if(paint_mode == PAINT_LARGE_HORIZONTAL) + wait_time *= 3 + if(gang) takes_time = TRUE // hippie + if(takes_time) + if(!do_after(user, 50, target = target)) + return + + if(length(text_buffer)) + drawing = copytext(text_buffer,1,2) + + + var/list/turf/affected_turfs = list() + + if(!gang) // hippie - drawing is done in gang_final() if it's a gang type + if(actually_paints) + switch(paint_mode) + if(PAINT_NORMAL) + var/obj/effect/decal/cleanable/crayon/C = new(target, paint_color, drawing, temp, graf_rot) + C.add_hiddenprint(user) + C.pixel_x = clickx + C.pixel_y = clicky + affected_turfs += target + if(PAINT_LARGE_HORIZONTAL) + var/turf/left = locate(target.x-1,target.y,target.z) + var/turf/right = locate(target.x+1,target.y,target.z) + if(is_type_in_list(left, validSurfaces) && is_type_in_list(right, validSurfaces)) + var/obj/effect/decal/cleanable/crayon/C = new(left, paint_color, drawing, temp, graf_rot, PAINT_LARGE_HORIZONTAL_ICON) + C.add_hiddenprint(user) + affected_turfs += left + affected_turfs += right + affected_turfs += target + else + to_chat(user, "There isn't enough space to paint!") + return + else // hippie + if(gang_final(user, target, affected_turfs)) return // hippie + + if(!instant) + to_chat(user, "You finish drawing \the [temp].") + else + to_chat(user, "You spray a [temp] on \the [target.name]") + + var/charges_used = use_charges(user, cost) + if(!charges_used) + return + . = charges_used + + if(length(text_buffer)) + text_buffer = copytext(text_buffer,2) + + if(post_noise) + audible_message("You hear spraying.") + playsound(user.loc, 'sound/effects/spray.ogg', 5, 1, 5) + + var/fraction = min(1, . / reagents.maximum_volume) + if(affected_turfs.len) + fraction /= affected_turfs.len + for(var/t in affected_turfs) + reagents.reaction(t, TOUCH, fraction * volume_multiplier) + reagents.trans_to(t, ., volume_multiplier) + check_empty(user) + +/obj/item/toy/crayon/proc/gang_check(mob/user, atom/target) // hooked into afterattack + var/gang_mode = FALSE + if(gang && user.mind) + var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang) + if(G.gang != gang) + to_chat(user, "This spraycan's color isn't your gang's one! You cannot use it.") + return FALSE + gang_mode = TRUE + instant = FALSE + . = "graffiti" + // discontinue if the area isn't valid for tagging because gang "honour" + if(gang_mode && (!can_claim_for_gang(user, target))) + return FALSE + +/obj/item/toy/crayon/proc/gang_final(mob/user, atom/target, list/affected_turfs) // hooked into afterattack + // Double check it wasn't tagged in the meanwhile + if(!can_claim_for_gang(user, target)) + return TRUE + tag_for_gang(user, target) + affected_turfs += target + +/obj/item/toy/crayon/proc/can_claim_for_gang(mob/user, atom/target) + // Check area validity. + // Reject space, player-created areas, and non-station z-levels. + var/area/A = get_area(target) + if(!A || (!is_station_level(A.z)) || !A.valid_territory) + to_chat(user, "[A] is unsuitable for tagging.") + return FALSE + + var/spraying_over = FALSE + for(var/G in target) + var/obj/effect/decal/cleanable/crayon/gang/gangtag = G + if(istype(gangtag)) + var/datum/antagonist/gang/GA = user.mind.has_antag_datum(/datum/antagonist/gang) + if(gangtag.gang != GA.gang) + spraying_over = TRUE + break + + for(var/obj/machinery/power/apc in target) + to_chat(user, "You can't tag an APC.") + return FALSE + + var/occupying_gang = territory_claimed(A, user) + if(occupying_gang && !spraying_over) + to_chat(user, "[A] has already been tagged by the [occupying_gang] gang! You must get rid of or spray over the old tag first!") + return FALSE + + // If you pass the gaunlet of checks, you're good to proceed + return TRUE + +/obj/item/toy/crayon/proc/territory_claimed(area/territory, mob/user) + for(var/datum/team/gang/G in GLOB.gangs) + if(territory.type in (G.territories|G.new_territories)) + . = G.name + break + +/obj/item/toy/crayon/proc/tag_for_gang(mob/user, atom/target) + //Delete any old markings on this tile, including other gang tags + for(var/obj/effect/decal/cleanable/crayon/old_marking in target) + qdel(old_marking) + + var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang) + var/area/territory = get_area(target) + + new /obj/effect/decal/cleanable/crayon/gang(target,G.gang,"graffiti",0,user) + to_chat(user, "You tagged [territory] for your gang!") + +/obj/item/toy/crayon/spraycan/gang + //desc = "A modified container containing suspicious paint." + charges = 20 + gang = TRUE + + pre_noise = FALSE + post_noise = TRUE + +/obj/item/toy/crayon/spraycan/gang/Initialize(loc, datum/team/gang/G) + ..() + if(G) + gang = G + paint_color = G.color + update_icon() + +/obj/item/toy/crayon/spraycan/gang/examine(mob/user) + . = ..() + if(user.mind && user.mind.has_antag_datum(/datum/antagonist/gang) || isobserver(user)) + to_chat(user, "This spraycan has been specially modified for tagging territory.") + +#undef RANDOM_GRAFFITI +#undef RANDOM_LETTER +#undef RANDOM_NUMBER +#undef RANDOM_ORIENTED +#undef RANDOM_RUNE +#undef RANDOM_ANY \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/gang_datums.dm b/modular_citadel/code/game/gamemodes/gangs/gang_datums.dm new file mode 100644 index 0000000000..66dfdd0ca3 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gang_datums.dm @@ -0,0 +1,139 @@ +// Gang datums go here. If you want to create a new gang, you must be sure to edit: +// name +// color (must be a hex, "blue" isn't acceptable due to how spraycans are handled) +// inner_outfits (must be a list() with typepaths of the clothes in it. One is fine, but there is support for multiple: one will be picked at random when bought) +// outer_outfits (same as above) +// You also need to make a gang graffiti, that will go in crayondecal.dmi inside our icons(not tg's), with the same name of the gang it's assigned to. Nothing else,just the icon. +// Those are all required. If one is missed, stuff could break. + +/datum/team/gang/clandestine + name = "Clandestine" + color = "#FF0000" + inner_outfits = list(/obj/item/clothing/under/syndicate/combat) + outer_outfits = list(/obj/item/clothing/suit/jacket) + +/datum/team/gang/prima + name = "Prima" + color = "#FFFF00" + inner_outfits = list(/obj/item/clothing/under/color/yellow) + outer_outfits = list(/obj/item/clothing/suit/hastur) + +/datum/team/gang/zerog + name = "Zero-G" + color = "#C0C0C0" + inner_outfits = list(/obj/item/clothing/under/suit_jacket/white) + outer_outfits = list(/obj/item/clothing/suit/hooded/wintercoat) + +/datum/team/gang/max + name = "Max" + color = "#800000" + inner_outfits = list(/obj/item/clothing/under/color/maroon) + outer_outfits = list(/obj/item/clothing/suit/poncho/red) + +/datum/team/gang/blasto + name = "Blasto" + color = "#000080" + inner_outfits = list(/obj/item/clothing/under/suit_jacket/navy) + outer_outfits = list(/obj/item/clothing/suit/jacket/miljacket) + +/datum/team/gang/waffle + name = "Waffle" + color = "#808000" + inner_outfits = list(/obj/item/clothing/under/suit_jacket/green) + outer_outfits = list(/obj/item/clothing/suit/poncho) + +/datum/team/gang/north + name = "North" + color = "#00FF00" + inner_outfits = list(/obj/item/clothing/under/color/green) + outer_outfits = list(/obj/item/clothing/suit/poncho/green) + +/datum/team/gang/omni + name = "Omni" + color = "#008080" + inner_outfits = list(/obj/item/clothing/under/color/teal) + outer_outfits = list(/obj/item/clothing/suit/studentuni) + +/datum/team/gang/newton + name = "Newton" + color = "#A52A2A" + inner_outfits = list(/obj/item/clothing/under/color/brown) + outer_outfits = list(/obj/item/clothing/suit/toggle/owlwings) + +/datum/team/gang/cyber + name = "Cyber" + color = "#808000" + inner_outfits = list(/obj/item/clothing/under/color/lightbrown) + outer_outfits = list(/obj/item/clothing/suit/nemes) + +/datum/team/gang/donk + name = "Donk" + color = "#0000FF" + inner_outfits = list(/obj/item/clothing/under/color/darkblue) + outer_outfits = list(/obj/item/clothing/suit/apron/overalls) + +/datum/team/gang/gene + name = "Gene" + color = "#00FFFF" + inner_outfits = list(/obj/item/clothing/under/color/blue) + outer_outfits = list(/obj/item/clothing/suit/apron) + +/datum/team/gang/gib + name = "Gib" + color = "#636060" //Applying black to grayscale... Zero-G is already grey too. + inner_outfits = list(/obj/item/clothing/under/color/black) + outer_outfits = list(/obj/item/clothing/suit/jacket/leather/overcoat) + +/datum/team/gang/tunnel + name = "Tunnel" + color = "#FF00FF" + inner_outfits = list(/obj/item/clothing/under/villain) + outer_outfits = list(/obj/item/clothing/suit/poncho/ponchoshame) + +/datum/team/gang/diablo + name = "Diablo" + color = "#FF0000" + inner_outfits = list(/obj/item/clothing/under/color/red) + outer_outfits = list(/obj/item/clothing/suit/jacket/leather) + +/datum/team/gang/psyke + name = "Psyke" + color = "#808080" + inner_outfits = list(/obj/item/clothing/under/color/grey) + outer_outfits = list(/obj/item/clothing/suit/toggle/owlwings/griffinwings) + +/datum/team/gang/osiron + name = "Osiron" + color = "#FFFFFF" + inner_outfits = list(/obj/item/clothing/under/color/white) + outer_outfits = list(/obj/item/clothing/suit/toggle/labcoat) + +/datum/team/gang/sirius + name = "Sirius" + color = "#FFC0CB" + inner_outfits = list(/obj/item/clothing/under/color/pink) + outer_outfits = list(/obj/item/clothing/suit/jacket/puffer/vest) + +/datum/team/gang/sleepingcarp + name = "Sleeping Carp" + color = "#800080" + inner_outfits = list(/obj/item/clothing/under/color/lightpurple) + outer_outfits = list(/obj/item/clothing/suit/hooded/carp_costume) + +/datum/team/gang/h + name = "H" + color = "#993333" + inner_outfits = list(/obj/item/clothing/under/jabroni) //Why not? + outer_outfits = list(/obj/item/clothing/suit/toggle/owlwings) + +/datum/team/gang/rigatonifamily + name = "Rigatoni family" + color = "#cc9900" // p a s t a colored + inner_outfits = list(/obj/item/clothing/under/rank/chef) + outer_outfits = list(/obj/item/clothing/suit/apron/chef) + +/datum/team/gang/weed + name = "Weed" + color = "#66ff33" + inner_outfits = list(/obj/item/clothing/under/color/darkgreen) + outer_outfits = list(/obj/item/clothing/suit/vapeshirt) \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/gang_decals.dm b/modular_citadel/code/game/gamemodes/gangs/gang_decals.dm new file mode 100644 index 0000000000..6e5cb58891 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gang_decals.dm @@ -0,0 +1,38 @@ +/obj/effect/decal/cleanable/crayon/Initialize(mapload, main, type, e_name, graf_rot, alt_icon = null) + . = ..() + if(type == "poseur tag") + var/datum/team/gang/gang = pick(subtypesof(/datum/team/gang)) + var/gangname = initial(gang.name) + icon = 'icons/effects/crayondecal.dmi' + icon_state = "[gangname]" + type = null + +/obj/effect/decal/cleanable/crayon/gang + icon = 'icons/effects/crayondecal.dmi' + layer = ABOVE_NORMAL_TURF_LAYER //Harder to hide + plane = GAME_PLANE + do_icon_rotate = FALSE //These are designed to always face south, so no rotation please. + var/datum/team/gang/gang + +/obj/effect/decal/cleanable/crayon/gang/Initialize(mapload, datum/team/gang/G, e_name = "gang tag", rotation = 0, mob/user) + if(!G) + return INITIALIZE_HINT_QDEL + gang = G + var/newcolor = G.color + var/area/territory = get_area(src) + icon_state = G.name + G.new_territories |= list(territory.type = territory.name) + //If this isn't tagged by a specific gangster there's no bonus income. + .=..(mapload, newcolor, icon_state, e_name, rotation) + +/obj/effect/decal/cleanable/crayon/gang/Destroy() + if(gang) + var/area/territory = get_area(src) + gang.territories -= territory.type + gang.new_territories -= territory.type + gang.lost_territories |= list(territory.type = territory.name) + gang = null + return ..() + +/obj/effect/decal/cleanable/crayon/NeverShouldHaveComeHere(turf/T) + return isspaceturf(T) || islava(T) || istype(T, /turf/open/water) || ischasm(T) \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/gang_hud.dm b/modular_citadel/code/game/gamemodes/gangs/gang_hud.dm new file mode 100644 index 0000000000..3fde6d4123 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gang_hud.dm @@ -0,0 +1,34 @@ +/datum/atom_hud/antag/gang + var/color = null + +/datum/atom_hud/antag/gang/add_to_hud(atom/A) + if(!A) + return + var/image/holder = A.hud_list[ANTAG_HUD] + if(holder) + holder.color = color + ..() + +/datum/atom_hud/antag/gang/remove_from_hud(atom/A) + if(!A) + return + var/image/holder = A.hud_list[ANTAG_HUD] + if(holder) + holder.color = null + ..() + +/datum/atom_hud/antag/gang/join_hud(mob/M) + if(!istype(M)) + CRASH("join_hud(): [M] ([M.type]) is not a mob!") + var/image/holder = M.hud_list[ANTAG_HUD] + if(holder) + holder.color = color + ..() + +/datum/atom_hud/antag/gang/leave_hud(mob/M) + if(!istype(M)) + CRASH("leave_hud(): [M] ([M.type]) is not a mob!") + var/image/holder = M.hud_list[ANTAG_HUD] + if(holder) + holder.color = null + ..() \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/gang_items.dm b/modular_citadel/code/game/gamemodes/gangs/gang_items.dm new file mode 100644 index 0000000000..ceb08b3da3 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gang_items.dm @@ -0,0 +1,404 @@ +/datum/gang_item + var/name + var/item_path + var/cost + var/spawn_msg + var/category + var/list/gang_whitelist = list() + var/list/gang_blacklist = list() + var/id + +/datum/gang_item/proc/purchase(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool, check_canbuy = TRUE) + if(check_canbuy && !can_buy(user, gang, gangtool)) + return FALSE + var/real_cost = get_cost(user, gang, gangtool) + if(!spawn_item(user, gang, gangtool)) + gang.adjust_influence(-real_cost) + to_chat(user, "You bought \the [name].") + return TRUE + +/datum/gang_item/proc/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) // If this returns anything other than null, something fucked up and influence won't lower. + if(item_path) + var/obj/item/O = new item_path(user.loc) + user.put_in_hands(O) + else + return TRUE + if(spawn_msg) + to_chat(user, "[spawn_msg]") + +/datum/gang_item/proc/can_buy(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + return gang && (gang.influence >= get_cost(user, gang, gangtool)) && can_see(user, gang, gangtool) + +/datum/gang_item/proc/can_see(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + return TRUE + +/datum/gang_item/proc/get_cost(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + return cost + +/datum/gang_item/proc/get_cost_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + return "([get_cost(user, gang, gangtool)] Influence)" + +/datum/gang_item/proc/get_name_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + return name + +/datum/gang_item/proc/get_extra_info(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + return + +/////////////////// +//CLOTHING +/////////////////// + +/datum/gang_item/clothing + category = "Purchase Gang Clothes (Only the jumpsuit and suit give you added influence):" + +/datum/gang_item/clothing/under + name = "Gang Uniform" + id = "under" + cost = 1 + +/datum/gang_item/clothing/under/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(gang.inner_outfits.len) + var/outfit = pick(gang.inner_outfits) + if(outfit) + var/obj/item/O = new outfit(user.loc) + user.put_in_hands(O) + to_chat(user, " This is your gang's official uniform, wearing it will increase your influence") + return + return TRUE + +/datum/gang_item/clothing/suit + name = "Gang Armored Outerwear" + id = "suit" + cost = 1 + +/datum/gang_item/clothing/suit/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(gang.outer_outfits.len) + var/outfit = pick(gang.outer_outfits) + if(outfit) + var/obj/item/O = new outfit(user.loc) + O.armor = O.armor.setRating(melee = 20, bullet = 35, laser = 10, energy = 10, bomb = 30, bio = 0, rad = 0, fire = 30, acid = 30) + O.desc += " Tailored for the [gang.name] Gang to offer the wearer moderate protection against ballistics and physical trauma." + user.put_in_hands(O) + to_chat(user, " This is your gang's official outerwear, wearing it will increase your influence") + return + return TRUE + + +/datum/gang_item/clothing/hat + name = "Pimp Hat" + id = "hat" + cost = 16 + item_path = /obj/item/clothing/head/collectable/petehat/gang + + +/obj/item/clothing/head/collectable/petehat/gang + name = "pimpin' hat" + desc = "The undisputed king of style." + +/datum/gang_item/clothing/mask + name = "Golden Death Mask" + id = "mask" + cost = 18 + item_path = /obj/item/clothing/mask/gskull + +/obj/item/clothing/mask/gskull + name = "golden death mask" + icon_state = "gskull" + desc = "Strike terror, and envy, into the hearts of your enemies." + +/datum/gang_item/clothing/shoes + name = "Bling Boots" + id = "boots" + cost = 22 + item_path = /obj/item/clothing/shoes/gang + +/obj/item/clothing/shoes/gang + name = "blinged-out boots" + desc = "Stand aside peasants." + icon_state = "bling" + +/datum/gang_item/clothing/neck + name = "Gold Necklace" + id = "necklace" + cost = 9 + item_path = /obj/item/clothing/neck/necklace/dope + +/datum/gang_item/clothing/hands + name = "Decorative Brass Knuckles" + id = "hand" + cost = 11 + item_path = /obj/item/clothing/gloves/gang + +/obj/item/clothing/gloves/gang + name = "braggadocio's brass knuckles" + desc = "Purely decorative, don't find out the hard way." + icon_state = "knuckles" + w_class = 3 + +/datum/gang_item/clothing/belt + name = "Badass Belt" + id = "belt" + cost = 13 + item_path = /obj/item/storage/belt/military/gang + +/obj/item/storage/belt/military/gang + name = "badass belt" + icon_state = "gangbelt" + item_state = "gang" + desc = "The belt buckle simply reads 'BAMF'." + +/////////////////// +//WEAPONS +/////////////////// + +/datum/gang_item/weapon + category = "Purchase Weapons:" + +/datum/gang_item/weapon/ammo + +/datum/gang_item/weapon/shuriken + name = "Shuriken" + id = "shuriken" + cost = 2 + item_path = /obj/item/throwing_star + +/datum/gang_item/weapon/switchblade + name = "Switchblade" + id = "switchblade" + cost = 5 + item_path = /obj/item/switchblade + +/datum/gang_item/weapon/surplus + name = "Surplus Rifle" + id = "surplus" + cost = 7 + item_path = /obj/item/gun/ballistic/automatic/surplus + +/datum/gang_item/weapon/ammo/surplus_ammo + name = "Surplus Rifle Ammo" + id = "surplus_ammo" + cost = 5 + item_path = /obj/item/ammo_box/magazine/m10mm/rifle + +/datum/gang_item/weapon/improvised + name = "Sawn-Off Improvised Shotgun" + id = "sawn" + cost = 6 + item_path = /obj/item/gun/ballistic/revolver/doublebarrel/improvised/sawn + +/datum/gang_item/weapon/ammo/improvised_ammo + name = "Box of Buckshot" + id = "buckshot" + cost = 5 + item_path = /obj/item/storage/box/lethalshot + +/datum/gang_item/weapon/pistol + name = "10mm Pistol" + id = "pistol" + cost = 25 + item_path = /obj/item/gun/ballistic/automatic/pistol + +/datum/gang_item/weapon/ammo/pistol_ammo + name = "10mm Ammo" + id = "pistol_ammo" + cost = 10 + item_path = /obj/item/ammo_box/magazine/m10mm + +/datum/gang_item/weapon/sniper + name = "Black Market .50cal Sniper Rifle" + id = "sniper" + cost = 40 + item_path = /obj/item/gun/ballistic/automatic/sniper_rifle + +/datum/gang_item/weapon/ammo/sniper_ammo + name = "Smuggled .50cal Sniper Rounds" + id = "sniper_ammo" + cost = 15 + item_path = /obj/item/ammo_box/magazine/sniper_rounds + +/datum/gang_item/weapon/ammo/sleeper_ammo + name = "Illicit Soporific Cartridges" + id = "sniper_ammo" + cost = 15 + item_path = /obj/item/ammo_box/magazine/sniper_rounds/soporific + +/datum/gang_item/weapon/machinegun + name = "Mounted Machine Gun" + id = "MG" + cost = 50 + item_path = /obj/machinery/manned_turret + spawn_msg = "The mounted machine gun features enhanced responsiveness. Hold down on the trigger while firing to control where you're shooting." + +/datum/gang_item/weapon/machinegun/spawn_item(mob/living/carbon/user, obj/item/device/gangtool/gangtool) + new item_path(user.loc) + to_chat(user, spawn_msg) + +/datum/gang_item/weapon/uzi + name = "Uzi SMG" + id = "uzi" + cost = 60 + item_path = /obj/item/gun/ballistic/automatic/mini_uzi + +/datum/gang_item/weapon/ammo/uzi_ammo + name = "Uzi Ammo" + id = "uzi_ammo" + cost = 30 + item_path = /obj/item/ammo_box/magazine/uzim9mm + +/////////////////// +//EQUIPMENT +/////////////////// + +/datum/gang_item/equipment + category = "Purchase Equipment:" + + +/datum/gang_item/equipment/spraycan + name = "Territory Spraycan" + id = "spraycan" + cost = 5 + item_path = /obj/item/toy/crayon/spraycan/gang + +/datum/gang_item/equipment/spraycan/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + var/obj/item/O = new item_path(user.loc, gang) + user.put_in_hands(O) + +/datum/gang_item/equipment/sharpener + name = "Sharpener" + id = "whetstone" + cost = 3 + item_path = /obj/item/sharpener + + +/datum/gang_item/equipment/emp + name = "EMP Grenade" + id = "EMP" + cost = 7 + item_path = /obj/item/grenade/empgrenade + +/datum/gang_item/equipment/c4 + name = "C4 Explosive" + id = "c4" + cost = 7 + item_path = /obj/item/grenade/plastic/c4 + +/datum/gang_item/equipment/frag + name = "Fragmentation Grenade" + id = "frag nade" + cost = 7 + item_path = /obj/item/grenade/syndieminibomb/concussion/frag + +/datum/gang_item/equipment/stimpack + name = "Black Market Stimulants" + id = "stimpack" + cost = 12 + item_path = /obj/item/reagent_containers/syringe/stimulants + +/datum/gang_item/equipment/implant_breaker + name = "Implant Breaker" + id = "implant_breaker" + cost = 10 + item_path = /obj/item/implanter/gang + +/datum/gang_item/equipment/implant_breaker/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + var/obj/item/O = new item_path(user.loc, gang) + user.put_in_hands(O) + to_chat(user, "The implant breaker is a single-use device that destroys all implants within the target before trying to recruit them to your gang. Also works on enemy gangsters.") + +/datum/gang_item/equipment/wetwork_boots + name = "Wetwork boots" + id = "wetwork" + cost = 12 + item_path = /obj/item/clothing/shoes/combat/gang + +/obj/item/clothing/shoes/combat/gang + name = "Wetwork boots" + desc = "A gang's best hitmen are prepared for anything." + permeability_coefficient = 0.01 + clothing_flags = NOSLIP + +/datum/gang_item/equipment/pen + name = "Recruitment Pen" + id = "pen" + cost = 25 + item_path = /obj/item/pen/gang + spawn_msg = "More recruitment pens will allow you to recruit gangsters faster. Only gang leaders can recruit with pens." + +/datum/gang_item/equipment/pen/purchase(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(..()) + gangtool.free_pen = FALSE + return TRUE + return FALSE + +/datum/gang_item/equipment/pen/get_cost(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(gangtool && gangtool.free_pen) + return 0 + return ..() + +/datum/gang_item/equipment/pen/get_cost_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(gangtool && gangtool.free_pen) + return "(GET ONE FREE)" + return ..() + + +/datum/gang_item/equipment/gangtool + id = "gangtool" + cost = 10 + +/datum/gang_item/equipment/gangtool/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + var/item_type + if(gang) + item_type = /obj/item/device/gangtool/spare/lt + if(gang.leaders.len < MAX_LEADERS_GANG) + to_chat(user, "Gangtools allow you to promote a gangster to be your Lieutenant, enabling them to recruit and purchase items like you. Simply have them register the gangtool. You may promote up to [MAX_LEADERS_GANG-gang.leaders.len] more Lieutenants") + else + item_type = /obj/item/device/gangtool/spare + var/obj/item/device/gangtool/spare/tool = new item_type(user.loc) + user.put_in_hands(tool) + +/datum/gang_item/equipment/gangtool/get_name_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(gang && (gang.leaders.len < gang.max_leaders)) + return "Promote a Gangster" + return "Spare Gangtool" + +/datum/gang_item/equipment/dominator + name = "Station Dominator" + id = "dominator" + cost = 30 + item_path = /obj/machinery/dominator + spawn_msg = "The dominator will secure your gang's dominance over the station. Turn it on when you are ready to defend it." + +/datum/gang_item/equipment/dominator/can_buy(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(!gang || !gang.dom_attempts) + return FALSE + return ..() + +/datum/gang_item/equipment/dominator/get_name_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(!gang || !gang.dom_attempts) + return ..() + return "[..()]" + +/datum/gang_item/equipment/dominator/get_cost_display(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(!gang || !gang.dom_attempts) + return "(Out of stock)" + return ..() + +/datum/gang_item/equipment/dominator/get_extra_info(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + if(gang) + return "This device requires a 5x5 area clear of walls to work. (Estimated Takeover Time: [round(gang.determine_domination_time()/60,0.1)] minutes)" + +/datum/gang_item/equipment/dominator/purchase(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + var/area/userarea = get_area(user) + if(!(userarea.type in gang.territories|gang.new_territories)) + to_chat(user,"The dominator can be spawned only on territory controlled by your gang!") + return FALSE + for(var/obj/obj in get_turf(user)) + if(obj.density) + to_chat(user, "There's not enough room here!") + return FALSE + + return ..() + +/datum/gang_item/equipment/dominator/spawn_item(mob/living/carbon/user, datum/team/gang/gang, obj/item/device/gangtool/gangtool) + new item_path(user.loc) + to_chat(user, spawn_msg) \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/gang_pen.dm b/modular_citadel/code/game/gamemodes/gangs/gang_pen.dm new file mode 100644 index 0000000000..ceb780a8c5 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gang_pen.dm @@ -0,0 +1,58 @@ +/* + * Gang Boss Pens + */ +/obj/item/pen/gang + var/cooldown + var/last_used + +/obj/item/pen/gang/Initialize() + . = ..() + last_used = world.time + +/obj/item/pen/gang/attack(mob/living/M, mob/user, stealth = TRUE) + if(!istype(M)) + return + if(!ishuman(M) || !ishuman(user) || M.stat == DEAD) + return ..() + var/datum/antagonist/gang/boss/L = user.mind.has_antag_datum(/datum/antagonist/gang/boss) + if(!L) + return ..() + if(!..()) + return + if(cooldown) + to_chat(user, "[src] needs more time to recharge before it can be used.") + return + if(!M.client || !M.mind) + to_chat(user, "A braindead gangster is an useless gangster!") + return + var/datum/team/gang/gang = L.gang + if(!add_gangster(user, gang, M.mind)) + return + cooldown = TRUE + icon_state = "pen_blink" + var/cooldown_time = 600/gang.leaders.len + addtimer(CALLBACK(src, .proc/cooldown), cooldown_time) + +/obj/item/pen/gang/proc/cooldown() + cooldown = FALSE + icon_state = "pen" + var/mob/M = loc + if(istype(M)) + to_chat(M, "[icon2html(src, M)] [src][(loc == M)?(""):(" in your [loc]")] vibrates softly. It is ready to be used again.") + +/obj/item/pen/gang/proc/add_gangster(mob/user, datum/team/gang/gang, datum/mind/gangster_mind, check = TRUE) // Basically a wrapper to add_antag_datum. + var/datum/antagonist/dudegang = gangster_mind.has_antag_datum(/datum/antagonist/gang) + if(dudegang) + if(dudegang == gang) + to_chat(user, "This mind is already controlled by your gang!") + return + to_chat(user, "This mind is already controlled by someone else!") + return + if(check && gangster_mind.current.has_trait(TRAIT_MINDSHIELD)) //Check to see if the potential gangster is implanted + to_chat(user, "This mind is too strong to control!") + return + var/mob/living/carbon/human/H = gangster_mind.current // we are sure the dude's human cause it's checked in attack() + H.silent = max(H.silent, 5) + H.Knockdown(100) + gangster_mind.add_antag_datum(/datum/antagonist/gang, gang) + return TRUE \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/gangs.dm b/modular_citadel/code/game/gamemodes/gangs/gangs.dm new file mode 100644 index 0000000000..639296c628 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gangs.dm @@ -0,0 +1,59 @@ +//gang.dm +//Gang War Game Mode +GLOBAL_LIST_INIT(possible_gangs, subtypesof(/datum/team/gang)) +GLOBAL_LIST_EMPTY(gangs) +/datum/game_mode/gang + name = "gang war" + config_tag = "gang" + antag_flag = ROLE_GANG + restricted_jobs = list("Security Officer", "Warden", "Detective", "AI", "Cyborg","Captain", "Head of Personnel", "Head of Security") + required_players = 1 + required_enemies = 0 + recommended_enemies = 2 + enemy_minimum_age = 14 + + announce_span = "danger" + announce_text = "A violent turf war has erupted on the station!\n\ + Gangsters: Take over the station with a dominator.\n\ + Crew: Prevent the gangs from expanding and initiating takeover." + + var/list/datum/mind/gangboss_candidates = list() + +/datum/game_mode/gang/pre_setup() + if(CONFIG_GET(flag/protect_roles_from_antagonist)) + restricted_jobs += protected_jobs + + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) + restricted_jobs += "Assistant" + + //Spawn more bosses depending on server population + var/gangs_to_create = 2 + if(prob(num_players()) && num_players() > 1.5*required_players) + gangs_to_create++ + if(prob(num_players()) && num_players() > 2*required_players) + gangs_to_create++ + gangs_to_create = min(gangs_to_create, GLOB.possible_gangs.len) + + for(var/i in 1 to gangs_to_create) + if(!antag_candidates.len) + break + + //Now assign a boss for the gang + var/datum/mind/boss = pick_n_take(antag_candidates) + antag_candidates -= boss + gangboss_candidates += boss + boss.restricted_roles = restricted_jobs + + if(gangboss_candidates.len < 1) //Need at least one gangs + return + + return TRUE + +/datum/game_mode/gang/post_setup() + set waitfor = FALSE + ..() + for(var/i in gangboss_candidates) + var/datum/mind/M = i + var/datum/antagonist/gang/boss/B = new() + M.add_antag_datum(B) + B.equip_gang() diff --git a/modular_citadel/code/game/gamemodes/gangs/gangtool.dm b/modular_citadel/code/game/gamemodes/gangs/gangtool.dm new file mode 100644 index 0000000000..9e828a7042 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/gangtool.dm @@ -0,0 +1,259 @@ +//gangtool device +/obj/item/device/gangtool + name = "suspicious device" + desc = "A strange device of sorts. Hard to really make out what it actually does if you don't know how to operate it." + icon = 'icons/obj/device.dmi' + icon_state = "gangtool" + item_state = "radio" + lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' + throwforce = 0 + w_class = WEIGHT_CLASS_TINY + throw_speed = 3 + throw_range = 7 + flags_1 = CONDUCT_1 + var/datum/team/gang/gang //Which gang uses this? + var/recalling = 0 + var/outfits = 2 + var/free_pen = 0 + var/promotable = FALSE + var/static/list/buyable_items = list() + var/list/tags = list() + +/obj/item/device/gangtool/Initialize() + . = ..() + update_icon() + for(var/i in subtypesof(/datum/gang_item)) + var/datum/gang_item/G = i + var/id = initial(G.id) + var/cat = initial(G.category) + if(id) + if(!islist(buyable_items[cat])) + buyable_items[cat] = list() + buyable_items[cat][id] = new G +/obj/item/device/gangtool/Destroy() + if(gang) + gang.gangtools -= src + return ..() + +/obj/item/device/gangtool/attack_self(mob/user) + ..() + if (!can_use(user)) + return + var/datum/antagonist/gang/boss/L = user.mind.has_antag_datum(/datum/antagonist/gang/boss) + var/dat + if(!gang) + dat += "This device is not registered.

" + if(L) + if(promotable && L.gang.leaders.len < L.gang.max_leaders) + dat += "Give this device to another member of your organization to use to promote them to Lieutenant.

" + dat += "If this is meant as a spare device for yourself:
" + dat += "Register Device as Spare
" + else if(promotable) + var/datum/antagonist/gang/sweet = user.mind.has_antag_datum(/datum/antagonist/gang) + if(sweet.gang.leaders.len < sweet.gang.max_leaders) + dat += "You have been selected for a promotion!
" + dat += "Accept Promotion
" + else + dat += "No promotions available: All positions filled.
" + else + dat += "This device is not authorized to promote.
" + else + if(gang.domination_time != NOT_DOMINATING) + dat += "
Takeover In Progress:
[DisplayTimeText(gang.domination_time_remaining() * 10)] remain
" + + dat += "Registration: [gang.name] Gang Boss
" + dat += "Organization Size: [gang.members.len] | Station Control: [gang.territories.len] territories under control. | Influence: [gang.influence]
" + dat += "Time until Influence grows: [time2text(gang.next_point_time - world.time, "mm:ss")]
" + dat += "Send message to Gang
" + dat += "Recall shuttle
" + dat += "
" + for(var/cat in buyable_items) + dat += "[cat]
" + for(var/id in buyable_items[cat]) + var/datum/gang_item/G = buyable_items[cat][id] + if(!G.can_see(user, gang, src)) + continue + + var/cost = G.get_cost_display(user, gang, src) + if(cost) + dat += cost + " " + + var/toAdd = G.get_name_display(user, gang, src) + if(G.can_buy(user, gang, src)) + toAdd = "[toAdd]" + dat += toAdd + var/extra = G.get_extra_info(user, gang, src) + if(extra) + dat += "
[extra]" + dat += "
" + dat += "
" + + dat += "Refresh
" + + var/datum/browser/popup = new(user, "gangtool", "Welcome to GangTool v4.0", 340, 625) + popup.set_content(dat) + popup.open() + +/obj/item/device/gangtool/Topic(href, href_list) + if(!can_use(usr)) + return + + add_fingerprint(usr) + + if(href_list["register"]) + register_device(usr) + + else if(!gang) //Gangtool must be registered before you can use the functions below + return + + if(href_list["purchase"]) + if(islist(buyable_items[href_list["cat"]])) + var/list/L = buyable_items[href_list["cat"]] + var/datum/gang_item/G = L[href_list["id"]] + if(G && G.can_buy(usr, gang, src)) + G.purchase(usr, gang, src, FALSE) + + if(href_list["commute"]) + ping_gang(usr) + if(href_list["recall"]) + recall(usr) + attack_self(usr) + +/obj/item/device/gangtool/update_icon() + overlays.Cut() + var/image/I = new(icon, "[icon_state]-overlay") + if(gang) + I.color = gang.color + overlays.Add(I) + +/obj/item/device/gangtool/proc/ping_gang(mob/user) + if(!can_use(user)) + return + var/message = stripped_input(user,"Discreetly send a gang-wide message.","Send Message") as null|text + if(!message || !can_use(user)) + return + if(!is_station_level(user.z)) + to_chat(user, "[icon2html(src, user)]Error: Station out of range.") + return + if(gang.members.len) + var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang) + if(!G) + return + var/ping = "[gang.name] [G.message_name] [user.real_name]: [message]" + for(var/datum/mind/ganger in gang.members) + if(ganger.current && is_station_level(ganger.current.z) && (ganger.current.stat == CONSCIOUS)) + to_chat(ganger.current, ping) + for(var/mob/M in GLOB.dead_mob_list) + var/link = FOLLOW_LINK(M, user) + to_chat(M, "[link] [ping]") + user.log_talk(message,LOG_SAY, tag="[gang.name] gangster") + +/obj/item/device/gangtool/proc/register_device(mob/user) + if(gang) //It's already been registered! + return + var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang) + if(G) + gang = G.gang + gang.gangtools += src + update_icon() + if(!(user.mind in gang.leaders) && promotable) + G.promote() + free_pen = TRUE + gang.message_gangtools("[user] has been promoted to Lieutenant.") + to_chat(user, "The Gangtool you registered will allow you to purchase weapons and equipment, and send messages to your gang.") + to_chat(user, "Unlike regular gangsters, you may use recruitment pens to add recruits to your gang. Use them on unsuspecting crew members to recruit them. Don't forget to get your one free pen from the gangtool.") + else + to_chat(user, "ACCESS DENIED: Unauthorized user.") + +/obj/item/device/gangtool/proc/recall(mob/user) + if(!recallchecks(user)) + return + if(recalling) + to_chat(user, "Error: Recall already in progress.") + return + gang.message_gangtools("[user] is attempting to recall the emergency shuttle.") + recalling = TRUE + to_chat(user, "[icon2html(src, loc)]Generating shuttle recall order with codes retrieved from last call signal...") + addtimer(CALLBACK(src, .proc/recall2, user), rand(100,300)) + +/obj/item/device/gangtool/proc/recall2(mob/user) + if(!recallchecks(user)) + return + to_chat(user, "[icon2html(src, loc)]Shuttle recall order generated. Accessing station long-range communication arrays...") + addtimer(CALLBACK(src, .proc/recall3, user), rand(100,300)) + +/obj/item/device/gangtool/proc/recall3(mob/user) + if(!recallchecks(user)) + return + var/list/living_crew = list()//shamelessly copied from mulligan code, there should be a helper for this + for(var/mob/Player in GLOB.mob_list) + if(Player.mind && Player.stat != DEAD && !isnewplayer(Player) && !isbrain(Player) && Player.client) + living_crew += Player + var/malc = CONFIG_GET(number/midround_antag_life_check) + if(living_crew.len / GLOB.joined_player_list.len <= malc) //Shuttle cannot be recalled if too many people died + to_chat(user, "[icon2html(src, user)]Error: Station communication systems compromised. Unable to establish connection.") + recalling = FALSE + return + to_chat(user, "[icon2html(src, loc)]Comm arrays accessed. Broadcasting recall signal...") + addtimer(CALLBACK(src, .proc/recallfinal, user), rand(100,300)) + +/obj/item/device/gangtool/proc/recallfinal(mob/user) + if(!recallchecks(user)) + return + recalling = FALSE + log_game("[key_name(user)] has tried to recall the shuttle with a gangtool.") + message_admins("[key_name_admin(user)] has tried to recall the shuttle with a gangtool.", 1) + if(SSshuttle.cancelEvac(user)) + gang.recalls-- + return TRUE + + to_chat(user, "[icon2html(src, loc)]No response recieved. Emergency shuttle cannot be recalled at this time.") + return + +/obj/item/device/gangtool/proc/recallchecks(mob/user) + if(!can_use(user)) + return + if(SSshuttle.emergencyNoRecall) + return + if(!gang.recalls) + to_chat(user, "Error: Unable to access communication arrays. Firewall has logged our signature and is blocking all further attempts.") + return + if(SSshuttle.emergency.mode != SHUTTLE_CALL) //Shuttle can only be recalled when it's moving to the station + to_chat(user, "[icon2html(src, user)]Emergency shuttle cannot be recalled at this time.") + recalling = FALSE + return + if(!gang.dom_attempts) + to_chat(user, "[icon2html(src, user)]Error: Unable to access communication arrays. Firewall has logged our signature and is blocking all further attempts.") + recalling = FALSE + return + if(!is_station_level(user.z)) //Shuttle can only be recalled while on station + to_chat(user, "[icon2html(src, user)]Error: Device out of range of station communication arrays.") + recalling = FALSE + return + return TRUE + +/obj/item/device/gangtool/proc/can_use(mob/living/carbon/human/user) + if(!istype(user)) + return + if(user.incapacitated()) + return + if(!(src in user.contents)) + return + if(!user.mind) + return + var/datum/antagonist/gang/G = user.mind.has_antag_datum(/datum/antagonist/gang) + if(!G) + to_chat(user, "Huh, what's this?") + return + if(!isnull(gang) && G.gang != gang) + to_chat(user, "You cannot use gang tools owned by enemy gangs!") + return + return TRUE + + +/obj/item/device/gangtool/spare + outfits = TRUE + +/obj/item/device/gangtool/spare/lt + promotable = TRUE \ No newline at end of file diff --git a/modular_citadel/code/game/gamemodes/gangs/implant_gang.dm b/modular_citadel/code/game/gamemodes/gangs/implant_gang.dm new file mode 100644 index 0000000000..ee91928845 --- /dev/null +++ b/modular_citadel/code/game/gamemodes/gangs/implant_gang.dm @@ -0,0 +1,61 @@ +/obj/item/implant/gang + name = "gang implant" + desc = "Makes you a gangster or such." + activated = 0 + var/datum/team/gang/gang + +/obj/item/implant/gang/Initialize(loc, setgang) + .=..() + gang = setgang + +/obj/item/implant/gang/Destroy() + gang = null + return ..() + +/obj/item/implant/gang/get_data() + var/dat = {"Implant Specifications:
+ Name: Criminal brainwash implant
+ Life: A few seconds after injection.
+ Important Notes: Illegal
+
+ Implant Details:
+ Function: Contains a small pod of nanobots that change the host's brain to be loyal to a certain organization.
+ Special Features: This device will also emit a small EMP pulse, destroying any other implants within the host's brain.
+ Integrity: Implant's EMP function will destroy itself in the process."} + return dat + +/obj/item/implant/gang/implant(mob/living/target, mob/user, silent = 0) + if(!target || !target.mind || target.stat == DEAD) + return 0 + var/datum/antagonist/gang/G = target.mind.has_antag_datum(/datum/antagonist/gang) + if(G && G.gang == G) + return 0 // it's pointless + if(..()) + for(var/obj/item/implant/I in target.implants) + if(I != src) + qdel(I) + + if(ishuman(target)) + var/success + if(G) + if(!istype(G, /datum/antagonist/gang/boss)) + success = TRUE //Was not a gang boss, convert as usual + target.mind.remove_antag_datum(/datum/antagonist/gang) + else + success = TRUE + if(!success) + target.visible_message("[target] seems to resist the implant!", "You feel the influence of your enemies try to invade your mind!") + return FALSE + target.mind.add_antag_datum(/datum/antagonist/gang, gang) + qdel(src) + return TRUE + +/obj/item/implanter/gang + name = "implanter (gang)" + +/obj/item/implanter/gang/Initialize(loc, gang) + if(!gang) + qdel(src) + return + imp = new /obj/item/implant/gang(src,gang) + .=..() \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index 12a91dfaa9..7c9185699a 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -2810,6 +2810,18 @@ #include "modular_citadel\code\datums\wires\airlock.dm" #include "modular_citadel\code\datums\wires\autoylathe.dm" #include "modular_citadel\code\game\area\cit_areas.dm" +#include "modular_citadel\code\game\gamemodes\gangs\dominator.dm" +#include "modular_citadel\code\game\gamemodes\gangs\dominator_countdown.dm" +#include "modular_citadel\code\game\gamemodes\gangs\gang.dm" +#include "modular_citadel\code\game\gamemodes\gangs\gang_crayon.dm" +#include "modular_citadel\code\game\gamemodes\gangs\gang_datums.dm" +#include "modular_citadel\code\game\gamemodes\gangs\gang_decals.dm" +#include "modular_citadel\code\game\gamemodes\gangs\gang_hud.dm" +#include "modular_citadel\code\game\gamemodes\gangs\gang_items.dm" +#include "modular_citadel\code\game\gamemodes\gangs\gang_pen.dm" +#include "modular_citadel\code\game\gamemodes\gangs\gangs.dm" +#include "modular_citadel\code\game\gamemodes\gangs\gangtool.dm" +#include "modular_citadel\code\game\gamemodes\gangs\implant_gang.dm" #include "modular_citadel\code\game\gamemodes\miniantags\bot_swarm\swarmer_event.dm" #include "modular_citadel\code\game\gamemodes\revolution\revolution.dm" #include "modular_citadel\code\game\machinery\cryopod.dm"
Other Roles