diff --git a/baystation12.dme b/baystation12.dme index 05c88022914..7703467c4e0 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -217,6 +217,7 @@ #include "code\game\gamemodes\blob\blobs\node.dm" #include "code\game\gamemodes\blob\blobs\resource.dm" #include "code\game\gamemodes\blob\blobs\shield.dm" +#include "code\game\gamemodes\borer\borer.dm" #include "code\game\gamemodes\changeling\changeling.dm" #include "code\game\gamemodes\changeling\changeling_powers.dm" #include "code\game\gamemodes\changeling\modularchangling.dm" diff --git a/code/game/gamemodes/borer/borer.dm b/code/game/gamemodes/borer/borer.dm new file mode 100644 index 00000000000..bc09d35808d --- /dev/null +++ b/code/game/gamemodes/borer/borer.dm @@ -0,0 +1,151 @@ +//This file was auto-corrected by findeclaration.exe on 29/05/2012 15:03:04 +// TOTALLY NOT COPY-PASTA FROM meme.dm + +/datum/game_mode/var/list/borers = list() + +/datum/game_mode/borer + name = "Cortical Borers" + config_tag = "borer" + required_players = 3 + required_players_secret = 10 + restricted_jobs = list("AI", "Cyborg", "Mobile MMI") + recommended_enemies = 2 // need at least a borer and a host + votable = 0 // temporarily disable this mode for voting + + var/var/list/datum/mind/first_hosts = list() + var/var/list/assigned_hosts = list() + + var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds) + var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds) + +/datum/game_mode/borer/announce() + world << "The current game mode is - Cortical Borer!" + world << "An unknown creature has infested the mind of a crew member. Find and destroy it by any means necessary." + +/datum/game_mode/borer/can_start() + if(!..()) + return 0 + + // for every 10 players, get 1 borer, and for each borer, get a host + // also make sure that there's at least one borer and one host + recommended_enemies = max(src.num_players() / 20 * 2, 2) + + var/list/datum/mind/possible_borers = get_players_for_role(BE_ALIEN) + + if(possible_borers.len < 2) + log_admin("MODE FAILURE: BORER. NOT ENOUGH BORER CANDIDATES.") + return 0 // not enough candidates for borer + + // for each 2 possible borers, add one borer and one host + while(possible_borers.len >= 2) + var/datum/mind/borer = pick(possible_borers) + possible_borers.Remove(borer) + + var/datum/mind/first_host = pick(possible_borers) + possible_borers.Remove(first_host) + + modePlayer += borer + modePlayer += first_host + borers += borer + first_hosts += first_host + + // so that we can later know which host belongs to which borer + assigned_hosts[borer.key] = first_host + + borer.assigned_role = "MODE" //So they aren't chosen for other jobs. + borer.special_role = "Borer" + + return 1 + +/datum/game_mode/borer/pre_setup() + return 1 + + +/datum/game_mode/borer/post_setup() + // create a borer and enter it + for(var/datum/mind/borer in borers) + var/mob/living/simple_animal/borer/M = new(null,1) // loc, by_gamemode=0 + var/mob/original = borer.current + borer.transfer_to(M) + //M.clearHUD() + + // get the host for this borer + var/datum/mind/first_host = assigned_hosts[borer.key] + // this is a redundant check, but I don't think the above works.. + // if picking hosts works with this method, remove the method above + if(!first_host) + first_host = pick(first_hosts) + first_hosts.Remove(first_host) + M.perform_infestation(first_host.current) + forge_borer_objectives(borer, first_host) + + del original + + log_admin("Created [borers.len] borers.") + + spawn (rand(waittime_l, waittime_h)) + send_intercept() + ..() + return + +/datum/game_mode/proc/greet_borer(var/datum/mind/borer, var/you_are=1) + if (you_are) + borer.current << "\red You are a Cortical Borer!" + + var/obj_count = 1 + for(var/datum/objective/objective in borer.objectives) + borer.current << "Objective #[obj_count]: [objective.explanation_text]" + obj_count++ + return + +/datum/game_mode/borer/check_finished() + var/borers_alive = 0 + for(var/datum/mind/borer in borers) + if(!istype(borer.current,/mob/living)) + continue + if(borer.current.stat==2) + continue + borers_alive++ + + if (borers_alive) + return ..() + else + return 1 + +/datum/game_mode/proc/auto_declare_completion_borer() + for(var/datum/mind/borer in borers) + var/borerwin = 1 + if((borer.current) && istype(borer.current,/mob/living/simple_animal/borer)) + world << "The borer was [borer.current.key]." + world << "The last host was [borer.current:host.key]." + + var/count = 1 + for(var/datum/objective/objective in borer.objectives) + if(objective.check_completion()) + world << "Objective #[count]: [objective.explanation_text] \green Success" + feedback_add_details("borer_objective","[objective.type]|SUCCESS") + else + world << "Objective #[count]: [objective.explanation_text] \red Failed" + feedback_add_details("borer_objective","[objective.type]|FAIL") + borerwin = 0 + count++ + + else + borerwin = 0 + + if(borerwin) + world << "The borer was successful!" + feedback_add_details("borer_success","SUCCESS") + else + world << "The borer has failed!" + feedback_add_details("borer_success","FAIL") + return 1 + +/datum/game_mode/proc/forge_borer_objectives(var/datum/mind/borer, var/datum/mind/first_host) + var/datum/objective/survive/survive_objective = new + survive_objective.owner = borer + borer.objectives += survive_objective + + greet_borer(borer) + + return \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/borer.dm b/code/modules/mob/living/simple_animal/borer.dm index 4bb00a415a7..970ddb27d77 100644 --- a/code/modules/mob/living/simple_animal/borer.dm +++ b/code/modules/mob/living/simple_animal/borer.dm @@ -16,11 +16,9 @@ src << "You whisper silently, \"[message]\"" B.host << "The captive mind of [src] whispers, \"[message]\"" - for (var/mob/M in player_list) - if (istype(M, /mob/new_player)) - continue - else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS) - M << "The captive mind of [src] whispers, \"[message]\"" + for(var/mob/M in mob_list) + if(M.mind && (istype(M, /mob/dead/observer))) + M << "Thought-speech, [src] -> [B.truename]: [message]" /mob/living/captive_brain/emote(var/message) return @@ -94,12 +92,13 @@ if(prob(host.brainloss/20)) host.say("*[pick(list("blink","blink_r","choke","aflap","drool","twitch","twitch_s","gasp"))]") -/mob/living/simple_animal/borer/New() +/mob/living/simple_animal/borer/New(var/by_gamemode=0) ..() truename = "[pick("Primary","Secondary","Tertiary","Quaternary")] [rand(1000,9999)]" host_brain = new/mob/living/captive_brain(src) - request_player() + if(!by_gamemode) + request_player() /mob/living/simple_animal/borer/say(var/message) @@ -136,11 +135,9 @@ src << "You drop words into [host]'s mind: \"[message]\"" host << "Your own thoughts speak: \"[message]\"" - for (var/mob/M in player_list) - if (istype(M, /mob/new_player)) - continue - else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS) - M << "[src.truename] whispers to [host], \"[message]\"" + for(var/mob/M in mob_list) + if(M.mind && (istype(M, /mob/dead/observer))) + M << "Thought-speech, [truename] -> [host]: [copytext(message, 2)]" /mob/living/simple_animal/borer/Stat() @@ -397,22 +394,25 @@ mob/living/simple_animal/borer/proc/detatch() if(!M.stat) M << "Something disgusting and slimy wiggles into your ear!" - src.host = M - src.loc = M - - if(istype(M,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - var/datum/organ/external/head = H.get_organ("head") - head.implants += src - - host_brain.name = M.name - host_brain.real_name = M.real_name + src.perform_infestation(M) return else src << "They are no longer in range!" return +/mob/living/simple_animal/borer/proc/perform_infestation(var/mob/living/carbon/M) + src.host = M + src.loc = M + + if(istype(M,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + var/datum/organ/external/head = H.get_organ("head") + head.implants += src + + host_brain.name = M.name + host_brain.real_name = M.real_name + /mob/living/simple_animal/borer/verb/ventcrawl() set name = "Crawl through Vent" set desc = "Enter an air vent and crawl through the pipe system."