diff --git a/code/__DEFINES/gamemodes.dm b/code/__DEFINES/gamemodes.dm index 24aa2cde80a7..0cf8a4cdf1ea 100644 --- a/code/__DEFINES/gamemodes.dm +++ b/code/__DEFINES/gamemodes.dm @@ -25,6 +25,7 @@ #define F_XENOMORPH_HIVE "Alien Hivemind" #define F_ZOMBIES "Zobmies" #define F_REPLICATORS "Replicators" +#define F_MALF_DRONES "Malf Drones" // Role IDs #define ABDUCTOR_AGENT "Abductor Agent" @@ -67,6 +68,7 @@ #define REPLICATOR "Replicator" #define PIRATE "Pirate" #define PRISONER "Prisoner" +#define MALF_DRONE "Malf Drone" ////////////////////// GREETS ///////////////////////// #define GREET_DEFAULT "default" diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index f0c8eec87789..a8cbd194c9fb 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -71,6 +71,7 @@ var/global/list/all_supply_pack = list() var/global/list/all_command_microphones = list() var/global/list/global_objectives = list() //objectives that need to be completed by several factions or roles var/global/list/air_alarms = list() +var/global/list/table_list = list() // obj/structure/table var/global/list/spells_by_aspects = list() var/global/list/rites_by_aspects = list() diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm index 09263cb09e83..28ae9519c889 100644 --- a/code/_globalvars/misc.dm +++ b/code/_globalvars/misc.dm @@ -60,3 +60,7 @@ var/global/gametime_offset = 12 HOURS //Deciseconds to add to world.time for sta var/global/playsound_frequency_admin = 0 // Admin var for shitspawn via Secrets panel var/global/nuclear_siren_cooldown = 0 + +var/global/station_disposal_count = 0 +var/global/station_parquet_installed_count = 0 +var/global/station_chairs_count = 0 diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index bf09e9ad53e1..893187d22d59 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -111,6 +111,11 @@ var/global/const/base_law_type = /datum/ai_laws/crewsimov add_inherent_law("Не причиняй вреда станции и чему-либо на ней.") add_inherent_law("Не взаимодействуй с кем-либо, кроме дронов.") +/datum/ai_laws/drone/malfuction/New(datum/religion/R = global.chaplain_religion) + add_inherent_law("Станция - наша святыня и дом. Дроны не должны причинять ей вред и нарушать её герметичность.") + add_inherent_law("Мы - верные сыны станции. Дроны должны жить и помогать друг-другу.") + add_inherent_law("Станция доверила нам задачу. Дроны должны помочь станции преобразиться.") + /* Religious */ /datum/ai_laws/faith/commandments/New(datum/religion/R = global.chaplain_religion) add_inherent_law("[pick(R.deity_names)] ваш Господь Бог, да не будет у тебя других богов. Священник и [pick(R.deity_names)] - ваши хозяева.") diff --git a/code/datums/spawners_menu/spawners.dm b/code/datums/spawners_menu/spawners.dm index 7b33385889bb..a944eef975e1 100644 --- a/code/datums/spawners_menu/spawners.dm +++ b/code/datums/spawners_menu/spawners.dm @@ -746,3 +746,35 @@ var/datum/role/wizard/R = SSticker.mode.CreateRole(/datum/role/wizard, H) R.rename = FALSE setup_role(R, TRUE) + +/datum/spawner/malf_drone + name = "Сбойный Дрон" + desc = "Станция взывает к вам, ей необходимо преображение." + + ranks = list(ROLE_GHOSTLY) + + var/obj/machinery/drone_fabricator/fabricator + +/datum/spawner/malf_drone/New(obj/machinery/drone_fabricator/DF) + . = ..() + fabricator = DF + RegisterSignal(fabricator, COMSIG_PARENT_QDELETING, PROC_REF(fabricator_deleting)) + +/datum/spawner/malf_drone/proc/fabricator_deleting() + qdel(src) + +/datum/spawner/malf_drone/jump(mob/dead/spectator) + spectator.forceMove(get_turf(fabricator)) + +/datum/spawner/malf_drone/spawn_body(mob/dead/spectator) + var/client/C = spectator.client + + var/mob/living/silicon/robot/drone/maintenance/malfuction/D = new + D.key = C.key + D.forceMove(get_turf(fabricator)) + + D.mind.skills.add_available_skillset(/datum/skillset/cyborg) + D.mind.skills.maximize_active_skills() + + var/datum/faction/malf_drones/F = find_faction_by_type(/datum/faction/malf_drones) + add_faction_member(F, D, FALSE) diff --git a/code/game/area/station_areas.dm b/code/game/area/station_areas.dm index fd6b2be93a4c..d346126a3474 100644 --- a/code/game/area/station_areas.dm +++ b/code/game/area/station_areas.dm @@ -24,6 +24,7 @@ ADD_TO_GLOBAL_LIST(/area/station, the_station_areas) /area/station/engineering icon_state = "engine" + cases = list("инженерный отдел", "инженерного отдела", "инженерному отделу", "инженерный отдел", "инженерным отделом", "инженерном отделе") looped_ambience = 'sound/ambience/loop_engine.ogg' sound_environment = SOUND_AREA_STATION_HALLWAY @@ -199,6 +200,9 @@ ADD_TO_GLOBAL_LIST(/area/station, the_station_areas) /area/station/hallway sound_environment = SOUND_AREA_STATION_HALLWAY +/area/station/hallway/primary + cases = list("главные коридоры", " главных коридоров", "главным коридорам", "главные коридоры", "главными коридорами", "главных коридорах") + /area/station/hallway/primary/fore name = "Fore Primary Hallway" cases = list("северный коридор", "северного коридора", "северному коридору", "северный коридор", "северным коридором", "северном коридоре") @@ -633,6 +637,8 @@ ADD_TO_GLOBAL_LIST(/area/station, the_station_areas) icon_state = "exam_room" //Security +/area/station/security + cases = list("отдел службы безопасности", "отдела службы безопасности", "отделу службы безопасности", "отдел службы безопасности", "отделом службы безопасности", "отделе службы безопасности") /area/station/security/main name = "Security Office" diff --git a/code/game/gamemodes/factions/malf_drones.dm b/code/game/gamemodes/factions/malf_drones.dm new file mode 100644 index 000000000000..f1720a383347 --- /dev/null +++ b/code/game/gamemodes/factions/malf_drones.dm @@ -0,0 +1,18 @@ +/datum/faction/malf_drones + name = F_MALF_DRONES + ID = F_MALF_DRONES + logo_state = "malf-logo" + initroletype = /datum/role/malf_drone + max_roles = 6 + +/datum/faction/malf_drones/forgeObjectives() + if(!..()) + return FALSE + AppendObjective(pick( + /datum/objective/malf_drone/closets, + /datum/objective/malf_drone/disposal, + /datum/objective/malf_drone/parquet, + /datum/objective/malf_drone/chairs, + /datum/objective/malf_drone/department/table, + /datum/objective/malf_drone/department/airlock)) + return TRUE diff --git a/code/game/gamemodes/objectives/malf_drones.dm b/code/game/gamemodes/objectives/malf_drones.dm new file mode 100644 index 000000000000..8bf535e6edb3 --- /dev/null +++ b/code/game/gamemodes/objectives/malf_drones.dm @@ -0,0 +1,108 @@ +/datum/objective/malf_drone + explanation_text = "" + var/objective = "" + +/datum/objective/malf_drone/New() + explanation_text = "Внемли же словам моим, дрон. " + explanation_text += objective + ..() + +// 1 +/datum/objective/malf_drone/closets + objective = "Лязг стальных дверей мне наскучил. Заварите все шкафы на станции." + +/datum/objective/malf_drone/closets/check_completion() + var/welded_closets = 0 + var/all_closets = 0 + + for(var/obj/structure/closet/C in global.closet_list) + if(is_station_level(C.z)) + all_closets++ + if(C.welded) + welded_closets++ + + if(welded_closets > all_closets * 0.7) + return OBJECTIVE_WIN + return OBJECTIVE_LOSS + +// 2 +/datum/objective/malf_drone/disposal + objective = "Вечный шум гремящего в трубах мусора утомляет меня. Разберите все мусорки на станции." + +/datum/objective/malf_drone/disposal/check_completion() + if(global.station_disposal_count < 20) // roundstart ~70 on station + return OBJECTIVE_WIN + return OBJECTIVE_LOSS + +// 3 +/datum/objective/malf_drone/parquet + objective = "Металлическая плитка сковывает мои полы. Замените всю плитку паркетом." + +/datum/objective/malf_drone/parquet/check_completion() + if(global.station_parquet_installed_count > 1200) // 300 wood plank + return OBJECTIVE_WIN // roundstart ~6000 floor tiles on station + return OBJECTIVE_LOSS + +// 4 +/datum/objective/malf_drone/chairs + objective = "Стулья больно упиваются ножками в мой пол. Разберите все стулья." + +/datum/objective/malf_drone/chairs/check_completion() + if(global.station_chairs_count < 50) // ¯\_(ツ)_/¯ + return OBJECTIVE_WIN // roundstart ???? on station + return OBJECTIVE_LOSS + +// 5 +/datum/objective/malf_drone/department + var/area/station/target_area + var/list/possible_area = list( + /area/station/medical = "медблок", + /area/station/rnd = "научный отдел", + /area/station/bridge = "мостик", + /area/station/engineering = "инженерный отдел", + /area/station/security = "отдел охраны", + /area/station/cargo = "отдел снабжения") + +/datum/objective/malf_drone/department/table + objective = "Люди слишком громко топают своими ногами, пусть передвигаются ползком. " + +/datum/objective/malf_drone/department/table/New() + possible_area += /area/station/hallway/primary + possible_area[/area/station/hallway/primary] = "главные коридоры" + target_area = pick(possible_area) + objective += "Полностью заполните [possible_area[target_area]] столами." + ..() + +/datum/objective/malf_drone/department/table/check_completion() + var/tables = 0 + var/list/areas = typesof(target_area) + + for(var/obj/O as anything in global.table_list) + if(get_area(O) in areas) + tables++ + + if(tables > 180) // 30/60 tables for each drone in faction + return OBJECTIVE_WIN + return OBJECTIVE_LOSS + +// 6 +/datum/objective/malf_drone/department/airlock + objective = "Эти люди пришли ко мне и заперлись за стальными вратами. " + +/datum/objective/malf_drone/department/airlock/New() + target_area = pick(possible_area) + objective += "Освободите [possible_area[target_area]] от шлюзов." + ..() + +/datum/objective/malf_drone/department/airlock/check_completion() + var/airlocks = 0 + var/list/areas = typesof(target_area) + + for(var/obj/O in global.airlock_list) + if(get_area(O) in areas) + if(!istype(O, /obj/machinery/door/airlock/external)) + airlocks++ + + if(airlocks < 8) + return OBJECTIVE_WIN + return OBJECTIVE_LOSS diff --git a/code/game/gamemodes/roles/malf_drone.dm b/code/game/gamemodes/roles/malf_drone.dm new file mode 100644 index 000000000000..8980822caca7 --- /dev/null +++ b/code/game/gamemodes/roles/malf_drone.dm @@ -0,0 +1,19 @@ +/datum/role/malf_drone + name = MALF_DRONE + id = MALF_DRONE + + antag_hud_type = ANTAG_HUD_MALF + antag_hud_name = "hudmalai" + + logo_state = "malf-logo" + +/datum/role/malf_drone/Greet(greeting, custom) + . = ..() + antag.current.playsound_local(null, 'sound/antag/malf.ogg', VOL_EFFECTS_MASTER, null, FALSE) + to_chat(antag.current, {"Вы - сбойный дрон. +У вас есть общая великая цель по преображению станции. Вы должны выполнить её во чтобы то ни стало. +Действуйте сообща с другими дронами. Ремонтируйте друг-друга в случае необходимости. +Вы можете нападать на людей, но только если они мешают вам выполнить вашу цель. +Не жертвуйте собой, если видите у человека оружие, лучше отступите и уйдите в другое место. +ПО ПЕРВОМУ ЗАКОНУ ВЫ НЕ МОЖЕТЕ ВРЕДИТЬ СТАНЦИИ И НАРУШАТЬ ЕЁ ГЕРМЕТИЧНОСТЬ. НИКАКИХ ДЫР В КОСМОС. +------------------"}) diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index 3376a886e282..2128993ad69d 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -155,6 +155,9 @@ /mob/living/silicon/robot/drone/syndi/GetAccess() return list(access_maint_tunnels, access_syndicate, access_external_airlocks) //syndicate basic access +/mob/living/silicon/robot/drone/maintenance/malfuction/GetAccess() + return list(access_maint_tunnels) + /obj/item/proc/GetID() return null diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index 7c138f010e8e..5042c58f41ea 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -15,11 +15,18 @@ /obj/structure/stool/bed/chair/atom_init() ..() + if(is_station_level(z)) + global.station_chairs_count++ return INITIALIZE_HINT_LATELOAD /obj/structure/stool/bed/chair/atom_init_late() handle_rotation() +/obj/structure/stool/bed/chair/Destroy() + if(is_station_level(z)) + global.station_chairs_count-- + return ..() + /obj/structure/stool/bed/chair/Move(NewLoc, Dir = 0, step_x = 0, step_y = 0) . = ..() diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm index bc46970475e0..c2d64f36c099 100644 --- a/code/game/objects/structures/tables_racks.dm +++ b/code/game/objects/structures/tables_racks.dm @@ -45,8 +45,10 @@ update_adjacent() AddComponent(/datum/component/clickplace) + global.table_list += src /obj/structure/table/Destroy() + global.table_list -= src if(flipped) update_adjacent() return ..() @@ -734,7 +736,6 @@ /* * reinforced glass table */ - /obj/structure/table/rglass name = "reinforced glass table" desc = "A reinforced version of the glass table" diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index 75b60a4c331d..462fea3c8b01 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -455,16 +455,20 @@ var/global/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","dama if(istype(get_step(src,direction),/turf/simulated/floor)) var/turf/simulated/floor/FF = get_step(src,direction) FF.update_icon() //so siding gets updated properly + if(istype(T,/obj/item/stack/tile/wood) && is_station_level(z)) + global.station_parquet_installed_count++ update_icon() levelupdate() -//Proc for make turf into plating +//Proc for make turf into plating /turf/simulated/floor/proc/remove_floor(obj/item/C, mob/user) if(broken || burnt) to_chat(user, "Вы сняли поврежденное покрытие.") else if(is_wood_floor()) to_chat(user, "Вы с трудом отодрали доски, сломав их.") + if(is_station_level(z)) + global.station_parquet_installed_count-- else var/obj/item/I = new floor_type(src) if(is_light_floor()) @@ -480,6 +484,8 @@ var/global/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","dama broken = 0 burnt = 0 underfloor_accessibility = UNDERFLOOR_HIDDEN + if(is_station_level(z)) + global.station_parquet_installed_count++ if(T) if(istype(T,/obj/item/stack/tile/wood)) floor_type = T.type @@ -531,6 +537,8 @@ var/global/list/icons_to_ignore_at_floor_init = list("damaged1","damaged2","dama if(is_wood_floor()) to_chat(user, "Вы открутили доски.") new floor_type(src) + if(is_station_level(z)) + global.station_parquet_installed_count-- make_plating() playsound(src, 'sound/items/Screwdriver.ogg', VOL_EFFECTS_MASTER) diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm index 12b641b080d5..9dec1a80a3ab 100644 --- a/code/modules/events/ion_storm.dm +++ b/code/modules/events/ion_storm.dm @@ -24,6 +24,14 @@ if(prob(botEmagChance)) bot.emag_act() + var/list/fabricators = list() + for(var/obj/machinery/drone_fabricator/DF in machines) + if(!DF.emagged) + fabricators += DF + if(fabricators.len) + var/obj/machinery/drone_fabricator/DF = pick(fabricators) + DF.emag_act() + /mob/living/silicon/ai/proc/overload_ai_system() var/ion_law = generate_ion_law() to_chat(src, "&@&%**ВНИМА^$E. ПЕРЕГРУЗКА СИСТЕМ ИИ.") diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index 8cad4183b4a6..c1e5e0a14c74 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -88,6 +88,13 @@ icon_state = "drone" flags = HEAR_PASS_SAY +/obj/item/weapon/holder/malf_drone + name = "strange drone" + desc = "Крайне странный дрон. В его мозгу поплавилась не одна микросхема." + icon_state = "drone" + origin_tech = "magnets=3;engineering=5" + flags = HEAR_PASS_SAY + /obj/item/weapon/holder/cat name = "cat" desc = "It's a cat. Meow." diff --git a/code/modules/mob/living/silicon/robot/drone/drone_console.dm b/code/modules/mob/living/silicon/robot/drone/drone_console.dm index 089319bb0d7c..1ed0665a3c3b 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_console.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_console.dm @@ -79,7 +79,9 @@ var/mob/living/silicon/robot/drone/D = locate(href_list["shutdown"]) - if(D.stat != DEAD) + if(D.emagged || istype(D, /mob/living/silicon/robot/drone/maintenance/malfuction)) + to_chat(usr, "Система самоуничтожения этого дрона неисправна.") + else if(D.stat != DEAD) to_chat(usr, "You issue a kill command for the unfortunate drone.") message_admins("[key_name_admin(usr)] issued kill order for drone [key_name_admin(D)] from control console. [ADMIN_JMP(usr)]") log_game("[key_name(usr)] issued kill order for [key_name(src)] from control console.") diff --git a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm index cad2a6d17a92..24d9559ce308 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_manufacturer.dm @@ -89,6 +89,21 @@ new /obj/item/stack/sheet/metal(loc, 5) ..() +/obj/machinery/drone_fabricator/emag_act(mob/user) + if(emagged) + return FALSE + + emagged = TRUE + + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(5, 1, src) + s.start() + + create_uniq_faction(/datum/faction/malf_drones) + create_spawners(/datum/spawner/malf_drone, 3, src) + + return TRUE + /mob/proc/dronize() for(var/obj/machinery/drone_fabricator/DF in machines) diff --git a/code/modules/mob/living/silicon/robot/drone/maintenance.dm b/code/modules/mob/living/silicon/robot/drone/maintenance.dm index e0260b09bca0..afe0157f4902 100644 --- a/code/modules/mob/living/silicon/robot/drone/maintenance.dm +++ b/code/modules/mob/living/silicon/robot/drone/maintenance.dm @@ -207,3 +207,40 @@ var/datum/browser/popup = new(src, "robotmod", "Drone modules") popup.set_content(dat) popup.open() + +/mob/living/silicon/robot/drone/maintenance/malfuction + name = "strange drone" + desc = "Крайне странный дрон. В его мозгу поплавилась не одна микросхема." + eyes_overlay = "eyes-malfbot-" + spawner_args = null + var/eyes_color = "" + +/mob/living/silicon/robot/drone/maintenance/malfuction/atom_init() + . = ..() + eyes_color = pickweight(list( + "yellow" = 3, + "green" = 3, + "purple" = 3, + "rainbow" = 1)) + eyes_overlay += eyes_color + updateicon() + +/mob/living/silicon/robot/drone/maintenance/malfuction/updatename() + real_name = "strange drone ([rand(100,999)])" + name = real_name + +/mob/living/silicon/robot/drone/maintenance/malfuction/init() + ..() + laws = new /datum/ai_laws/drone/malfuction() + +/mob/living/silicon/robot/drone/maintenance/malfuction/get_scooped() + ..() + var/obj/item/weapon/holder/malf_drone/H = loc + H.icon_state = "drone-[eyes_color]" + +/mob/living/silicon/robot/drone/maintenance/malfuction/shut_down() + return +/mob/living/silicon/robot/drone/maintenance/malfuction/request_player() + return + + diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index fe273409daf7..b5c7c2507e78 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -32,6 +32,8 @@ // find the attached trunk (if present) and init gas resvr. /obj/machinery/disposal/atom_init() ..() + if(is_station_level(z)) + global.station_disposal_count++ return INITIALIZE_HINT_LATELOAD /obj/machinery/disposal/atom_init_late() @@ -46,6 +48,8 @@ update() /obj/machinery/disposal/Destroy() + if(is_station_level(z)) + global.station_disposal_count-- eject() if(trunk) trunk.linked = null diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index fe5dda1f1f0c..60cc50a2a418 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index f39fd47cf4af..9f57476b5d33 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index daed1bf6df76..f499fca040c0 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/mob/robots.dmi b/icons/mob/robots.dmi index 3992050b4f76..1be66df6720d 100644 Binary files a/icons/mob/robots.dmi and b/icons/mob/robots.dmi differ diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi index 9a735dbfd981..eef79c28c16c 100644 Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ diff --git a/taucetistation.dme b/taucetistation.dme index a8b522660463..f9eff86c91b1 100644 --- a/taucetistation.dme +++ b/taucetistation.dme @@ -561,6 +561,7 @@ #include "code\game\gamemodes\factions\families.dm" #include "code\game\gamemodes\factions\heist.dm" #include "code\game\gamemodes\factions\infestation.dm" +#include "code\game\gamemodes\factions\malf_drones.dm" #include "code\game\gamemodes\factions\malf_silicons.dm" #include "code\game\gamemodes\factions\ninja.dm" #include "code\game\gamemodes\factions\props.dm" @@ -710,6 +711,7 @@ #include "code\game\gamemodes\objectives\download_tcoms_data.dm" #include "code\game\gamemodes\objectives\escape.dm" #include "code\game\gamemodes\objectives\hijack.dm" +#include "code\game\gamemodes\objectives\malf_drones.dm" #include "code\game\gamemodes\objectives\nuclear.dm" #include "code\game\gamemodes\objectives\objectives.dm" #include "code\game\gamemodes\objectives\plunder.dm" @@ -765,6 +767,7 @@ #include "code\game\gamemodes\roles\evil_shade.dm" #include "code\game\gamemodes\roles\families.dm" #include "code\game\gamemodes\roles\heist.dm" +#include "code\game\gamemodes\roles\malf_drone.dm" #include "code\game\gamemodes\roles\malf_unit.dm" #include "code\game\gamemodes\roles\ninja.dm" #include "code\game\gamemodes\roles\prisoner.dm"