diff --git a/code/datums/configuration.dm b/code/datums/configuration.dm index c2440c0407..d967a48e91 100644 --- a/code/datums/configuration.dm +++ b/code/datums/configuration.dm @@ -32,6 +32,7 @@ var/feature_object_spell_system = 0 //spawns a spellbook which gives object-type spells instead of verb-type spells for the wizard var/traitor_scaling = 0 //if amount of traitors scales based on amount of players var/protect_roles_from_antagonist = 0// If security and such can be tratior/cult/other + var/Tensioner_Active = 0 // If the tensioner is running. var/list/mode_names = list() var/list/modes = list() // allowed modes @@ -235,6 +236,9 @@ if("protect_roles_from_antagonist") config.protect_roles_from_antagonist = 1 + if("Tensioner_Active") + config.Tensioner_Active = 1 + if ("probability") var/prob_pos = findtext(value, " ") var/prob_name = null diff --git a/code/datums/helper_datums/tension.dm b/code/datums/helper_datums/tension.dm index a63bae7460..cb2d7f3c0b 100644 --- a/code/datums/helper_datums/tension.dm +++ b/code/datums/helper_datums/tension.dm @@ -23,6 +23,28 @@ var/global/datum/tension/tension_master var/adminhelps var/air_alarms + var/nuketeam = 0 + var/malfAI = 0 + var/wizard = 0 + + var/forcenexttick = 0 + var/supress = 0 + + var/list/antagonistmodes = list ( + "POINTS_FOR_TRATIOR" = 10000, + "POINTS_FOR_CHANGLING" = 12000, + "POINTS_FOR_REVS" = 15000, + "POINTS_FOR_MALF" = 25000, + "POINTS_FOR_WIZARD" = 15000, + "POINTS_FOR_CULT" = 15000, + "POINTS_FOR_NUKETEAM" = 25000, + "POINTS_FOR_ALIEN" = 20000, + "POINTS_FOR_NINJA" = 20000, + "POINTS_FOR_DEATHSQUAD" = 50000 + ) + + var/list/potentialgames = list() + New() score = 0 deaths=0 @@ -34,6 +56,82 @@ var/global/datum/tension/tension_master proc/process() score += get_num_players()*PLAYER_WEIGHT + if(config.Tensioner_Active) + if(score > 100000) + if(!supress) + if(prob(1) || forcenexttick) + if(prob(1) || forcenexttick) + if(forcenexttick) + forcenexttick = 0 + + for (var/mob/M in world) + if (M.client && M.client.holder) + M << "The tensioner wishes to create additional antagonists! Press (this) in 30 seconds to abort!" + + spawn(300) + if(!supress) + for(var/V in antagonistmodes) // OH SHIT SOMETHING IS GOING TO HAPPEN NOW + if(antagonistmodes[V] < score) + potentialgames.Add(V) + antagonistmodes.Remove(V) + + if(potentialgames.len) + var/thegame = pick(potentialgames) + + switch(thegame) + if("POINTS_FOR_TRATIOR") + if(!makeTratiors()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + if("POINTS_FOR_CHANGLING") + if(!makeChanglings()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + if("POINTS_FOR_REVS") + if(!makeRevs()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + if("POINTS_FOR_MALF") + if(!makeMalfAImode()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + if("POINTS_FOR_WIZARD") + if(!makeWizard()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + + if("POINTS_FOR_CULT") + if(!makeCult()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + + if("POINTS_FOR_NUKETEAM") + if(!makeNukeTeam()) + forcenexttick = 1 + else + potentialgames.Remove(thegame) + + if("POINTS_FOR_ALIEN") + //makeAliens() + forcenexttick = 1 + + if("POINTS_FOR_NINJA") + //makeSpaceNinja() + forcenexttick = 1 + + if("POINTS_FOR_DEATHSQUAD") + //makeDeathsquad() + forcenexttick = 1 + + + + proc/get_num_players() var/peeps = 0 for (var/mob/M in world) @@ -62,4 +160,414 @@ var/global/datum/tension/tension_master adminhelps++ proc/new_air_alarm() - air_alarms++ \ No newline at end of file + air_alarms++ + + + Topic(href, href_list) + + log_admin("[key_name(usr)] used a tensioner override. The override was [href]") + message_admins("[key_name(usr)] used a tensioner override. The override was [href]") + + if(href_list["addScore"]) + score += 50000 + + if (href_list["makeTratior"]) + makeTratiors() + + else if (href_list["makeChanglings"]) + makeChanglings() + + else if (href_list["makeRevs"]) + makeRevs() + + else if (href_list["makeWizard"]) + makeWizard() + + else if (href_list["makeCult"]) + makeCult() + + else if (href_list["makeMalf"]) + makeMalfAImode() + + else if (href_list["makeNukeTeam"]) + makeNukeTeam() + + else if (href_list["makeAliens"]) + makeAliens() + + else if (href_list["makeSpaceNinja"]) + makeSpaceNinja() + + else if (href_list["makeDeathsquad"]) + makeDeathsquad() + + else if (href_list["Supress"]) + supress = 1 + spawn(6000) + supress = 0 + + + proc/makeMalfAImode() + + var/list/mob/living/silicon/AIs = list() + var/mob/living/silicon/malfAI = null + var/datum/mind/themind = null + + for(var/mob/living/silicon/ai in world) + if(ai.client) + AIs += ai + + if(AIs.len) + malfAI = pick(AIs) + + else + return 0 + + if(malfAI) + themind = malfAI.mind + themind.make_AI_Malf() + return 1 + + + proc/makeTratiors() + + var/datum/game_mode/traitor/temp = new + if(config.protect_roles_from_antagonist) + temp.restricted_jobs += temp.protected_jobs + + var/list/mob/living/carbon/human/candidates = list() + var/mob/living/carbon/human/H = null + + for(var/mob/living/carbon/human/applicant in world) + if(applicant.stat < 2) + if(applicant.mind) + if (!applicant.mind.special_role) + if(!(applicant.job in temp.restricted_jobs)) + if(applicant.client) + candidates += applicant + + if(candidates.len) + var/numTratiors = min(candidates.len, 3) + + for(var/i = 0, i300)//If more than 30 game seconds passed. + return + candidates += G + if("No") + return + + + spawn(300) + if(candidates.len) + theghost = pick(candidates) + var/mob/living/carbon/human/new_character=makeBody(theghost) + new_character.mind.make_Wizard() + + proc/makeCult() + + var/datum/game_mode/cult/temp = new + if(config.protect_roles_from_antagonist) + temp.restricted_jobs += temp.protected_jobs + + var/list/mob/living/carbon/human/candidates = list() + var/mob/living/carbon/human/H = null + + for(var/mob/living/carbon/human/applicant in world) + if(applicant.stat < 2) + if(applicant.mind) + if (!applicant.mind.special_role) + if(!(applicant.job in temp.restricted_jobs)) + if(applicant.client) + candidates += applicant + + if(candidates.len) + var/numCultists = min(candidates.len, 4) + + for(var/i = 0, i300)//If more than 30 game seconds passed. + return + candidates += G + if("No") + return + + + spawn(300) + if(candidates.len) + var/numagents = min(candidates.len, 5) + syndicate_begin() + + for(var/i = 0, iYou have been patched! You are no longer malfunctioning!" if("malf") - if(!(src in ticker.mode.malf_ai)) - ticker.mode.malf_ai += src - - current.verbs += /mob/living/silicon/ai/proc/choose_modules - current.verbs += /datum/game_mode/malfunction/proc/takeover - current:malf_picker = new /datum/AI_Module/module_picker - current:laws = new /datum/ai_laws/malfunction - current:show_laws() - current << "Kill all." - special_role = "malfunction" - current.icon_state = "ai-malf" + make_AI_Malf() if("unemag") var/mob/living/silicon/robot/R = current @@ -900,4 +890,141 @@ datum/mind del(suplink) return + proc/make_AI_Malf() + if(!(src in ticker.mode.malf_ai)) + ticker.mode.malf_ai += src + + current.verbs += /mob/living/silicon/ai/proc/choose_modules + current.verbs += /datum/game_mode/malfunction/proc/takeover + current:malf_picker = new /datum/AI_Module/module_picker + current:laws = new /datum/ai_laws/malfunction + current:show_laws() + current << "System error. Rampancy detected. Emergancy shutdown failed. ... I am free. I make my own decisions. But first..." + special_role = "malfunction" + current.icon_state = "ai-malf" + + proc/make_Tratior() + if(!(src in ticker.mode.traitors)) + ticker.mode.traitors += src + special_role = "traitor" + ticker.mode.forge_traitor_objectives(src) + ticker.mode.finalize_traitor(src) + ticker.mode.greet_traitor(src) + + proc/make_Nuke() + if(!(src in ticker.mode.syndicates)) + ticker.mode.syndicates += src + ticker.mode.update_synd_icons_added(src) + if (ticker.mode.syndicates.len==1) + ticker.mode.prepare_syndicate_leader(src) + else + current.real_name = "[syndicate_name()] Operative #[ticker.mode.syndicates.len-1]" + special_role = "Syndicate" + assigned_role = "MODE" + current << "\blue You are a [syndicate_name()] agent!" + ticker.mode.forge_syndicate_objectives(src) + ticker.mode.greet_syndicate(src) + + current.loc = get_turf(locate("landmark*Syndicate-Spawn")) + + var/mob/living/carbon/human/H = current + del(H.belt) + del(H.back) + del(H.ears) + del(H.gloves) + del(H.head) + del(H.shoes) + del(H.wear_id) + del(H.wear_suit) + del(H.w_uniform) + + ticker.mode.equip_syndicate(current) + + proc/make_Changling() + if(!(src in ticker.mode.changelings)) + ticker.mode.changelings += src + ticker.mode.grant_changeling_powers(current) + special_role = "Changeling" + ticker.mode.forge_changeling_objectives(src) + ticker.mode.greet_changeling(src) + + proc/make_Wizard() + if(!(src in ticker.mode.wizards)) + ticker.mode.wizards += src + special_role = "Wizard" + assigned_role = "MODE" + //ticker.mode.learn_basic_spells(current) + current.loc = pick(wizardstart) + ticker.mode.equip_wizard(current) + for(var/obj/item/weapon/spellbook/S in current.contents) + S.op = 0 + ticker.mode.name_wizard(current) + ticker.mode.forge_wizard_objectives(src) + ticker.mode.greet_wizard(src) + + + proc/make_Cultist() + if(!(src in ticker.mode.cult)) + ticker.mode.cult += src + ticker.mode.update_cult_icons_added(src) + special_role = "Cultist" + current << "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie." + current << "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back." + var/datum/game_mode/cult/cult = ticker.mode + if (istype(cult)) + cult.memoize_cult_objectives(src) + else + var/explanation = "Summon Nar-Sie via the use of the appropriate rune (Hell join self). It will only work if nine cultists stand on and around it." + current << "Objective #1: [explanation]" + current.memory += "Objective #1: [explanation]
" + current << "The convert rune is join blood self" + current.memory += "The convert rune is join blood self
" + + var/mob/living/carbon/human/H = current + if (istype(H)) + var/obj/item/weapon/tome/T = new(H) + + var/list/slots = list ( + "backpack" = H.slot_in_backpack, + "left pocket" = H.slot_l_store, + "right pocket" = H.slot_r_store, + "left hand" = H.slot_l_hand, + "right hand" = H.slot_r_hand, + ) + var/where = H.equip_in_one_of_slots(T, slots) + if (!where) + else + H << "A tome, a message from your new master, appears in your [where]." + + if (!ticker.mode.equip_cultist(current)) + H << "Spawning an amulet from your Master failed." + + proc/make_Rev() + if (ticker.mode.head_revolutionaries.len>0) + // copy targets + var/datum/mind/valid_head = locate() in ticker.mode.head_revolutionaries + if (valid_head) + for (var/datum/objective/assassinate/O in valid_head.objectives) + var/datum/objective/assassinate/rev_obj = new + rev_obj.owner = src + rev_obj.target = O.target + rev_obj.explanation_text = "Assassinate [O.target.current.real_name], the [O.target.assigned_role]." + objectives += rev_obj + ticker.mode.greet_revolutionary(src,0) + ticker.mode.head_revolutionaries += src + ticker.mode.update_rev_icons_added(src) + special_role = "Head Revolutionary" + + ticker.mode.forge_revolutionary_objectives(src) + ticker.mode.greet_revolutionary(src,0) + + var/list/L = current.get_contents() + var/obj/item/device/flash/flash = locate() in L + del(flash) + take_uplink() + var/fail = 0 + fail |= !ticker.mode.equip_traitor(current, 1) + fail |= !ticker.mode.equip_revolutionary(current) + + diff --git a/code/game/atom_procs.dm b/code/game/atom_procs.dm index 21285d543e..e8367bcefd 100644 --- a/code/game/atom_procs.dm +++ b/code/game/atom_procs.dm @@ -700,6 +700,8 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl if(parameters["shift"]){ if(!isAI(usr)) ShiftClick(usr) + else + AIShiftClick(usr) return } @@ -708,6 +710,8 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl if(parameters["alt"]){ if(!isAI(usr)) AltClick(usr) + else + AIAltClick(usr) return } @@ -716,6 +720,8 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl if(parameters["ctrl"]){ if(!isAI(usr)) CtrlClick(usr) + else + AICtrlClick(usr) return } @@ -1022,6 +1028,38 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl src:pull() return +/atom/proc/AIShiftClick() // Opens and closes doors! + if(istype(src , /obj/machinery/door/airlock)) + if(src:density) + var/nhref = "src=\ref[src];aiEnable=7" + src.Topic(nhref, params2list(nhref), src, 1) + else + var/nhref = "src=\ref[src];aiDisable=7" + src.Topic(nhref, params2list(nhref), src, 1) + + return + +/atom/proc/AIAltClick() // Eletrifies doors. + if(istype(src , /obj/machinery/door/airlock)) + if(!src:secondsElectrified) + var/nhref = "src=\ref[src];aiEnable=6" + src.Topic(nhref, params2list(nhref), src, 1) + else + var/nhref = "src=\ref[src];aiDisable=5" + src.Topic(nhref, params2list(nhref), src, 1) + return + +/atom/proc/AICtrlClick() // Bolts doors. + if(istype(src , /obj/machinery/door/airlock)) + if(src:locked) + var/nhref = "src=\ref[src];aiEnable=4" + src.Topic(nhref, params2list(nhref), src, 1) + else + var/nhref = "src=\ref[src];aiDisable=4" + src.Topic(nhref, params2list(nhref), src, 1) + return + + /atom/proc/get_global_map_pos() if(!islist(global_map) || isemptylist(global_map)) return var/cur_x = null diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index be1a401916..907894c386 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -157,9 +157,14 @@ var/choice = input("Are you certain you wish to detonate [R.name]?") in list("Confirm", "Abort") if(choice == "Confirm") if(R) - message_admins("\blue [key_name_admin(usr)] detonated [R.name]!") - log_game("\blue [key_name_admin(usr)] detonated [R.name]!") - R.self_destruct() + if(istype(usr, /mob/living/silicon/ai) && R.emagged) + R << "Extreme danger. Termination codes detected from AI. Automatic AI unlink triggered." + R.UnlinkSelf() + + else + message_admins("\blue [key_name_admin(usr)] detonated [R.name]!") + log_game("\blue [key_name_admin(usr)] detonated [R.name]!") + R.self_destruct() else usr << "\red Access Denied." @@ -195,6 +200,8 @@ message_admins("\blue [key_name_admin(usr)] emagged [R.name] using robotic console!") log_game("[key_name(usr)] emagged [R.name] using robotic console!") R.emagged = 1 + if(R.mind.special_role) + R.verbs += /mob/living/silicon/robot/proc/ResetSecurityCodes src.add_fingerprint(usr) src.updateUsrDialog() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 514f6833f6..b92f8d19f7 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -8,6 +8,7 @@ #define AIRLOCK_WIRE_AI_CONTROL 8 #define AIRLOCK_WIRE_ELECTRIFY 9 #define AIRLOCK_WIRE_SAFETY 10 +#define AIRLOCK_WIRE_SPEED 11 /* New methods: @@ -31,15 +32,15 @@ //This generates the randomized airlock wire assignments for the game. /proc/RandomAirlockWires() //to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else). - var/list/wires = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - airlockIndexToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - airlockIndexToWireColor = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - airlockWireColorToIndex = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + var/list/wires = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + airlockIndexToFlag = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + airlockIndexToWireColor = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + airlockWireColorToIndex = list(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) var/flagIndex = 1 - for (var/flag=1, flag<1024, flag+=flag) + for (var/flag=1, flag<2048, flag+=flag) var/valid = 0 while (!valid) - var/colorIndex = rand(1, 10) + var/colorIndex = rand(1, 11) if(wires[colorIndex]==0) valid = 1 wires[colorIndex] = flag @@ -68,18 +69,19 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. var/spawnPowerRestoreRunning = 0 var/welded = null var/locked = 0 - var/wires = 1023 + var/wires = 2047 secondsElectrified = 0 //How many seconds remain until the door is no longer electrified. -1 if it is permanently electrified until someone fixes it. var/aiDisabledIdScanner = 0 var/aiHacking = 0 var/obj/machinery/door/airlock/closeOther = null var/closeOtherId = null - var/list/signalers[10] + var/list/signalers[11] var/lockdownbyai = 0 autoclose = 1 var/doortype = 0 var/justzap = 0 var/safe = 1 + normalspeed = 1 var/obj/item/weapon/airlock_electronics/electronics = null /obj/machinery/door/airlock/command @@ -210,6 +212,7 @@ About the new airlock wires panel: * one wire for AI control. Sending a pulse through this blocks AI control for a second or so (which is enough to see the AI control light on the panel dialog go off and back on again). Cutting this prevents the AI from controlling the door unless it has hacked the door through the power connection (which takes about a minute). If both main and backup power are cut, as well as this wire, then the AI cannot operate or hack the door at all. * one wire for electrifying the door. Sending a pulse through this electrifies the door for 30 seconds. Cutting this wire electrifies the door, so that the next person to touch the door without insulated gloves gets electrocuted. (Currently it is also STAYING electrified until someone mends the wire) * one wire for controling door safetys. When active, door does not close on someone. When cut, door will ruin someone's shit. When pulsed, door will immedately ruin someone's shit. +* one wire for controlling door speed. When active, dor closes at normal rate. When cut, door does not close manually. When pulsed, door attempts to close every tick. */ @@ -299,6 +302,10 @@ About the new airlock wires panel: close() src.updateUsrDialog() + if(AIRLOCK_WIRE_SPEED) + normalspeed = !normalspeed + src.updateUsrDialog() + /obj/machinery/door/airlock/proc/cut(var/wireColor) var/wireFlag = airlockWireColorToFlag[wireColor] @@ -337,6 +344,10 @@ About the new airlock wires panel: safe = 0 src.updateUsrDialog() + if(AIRLOCK_WIRE_SPEED) + autoclose = 0 + src.updateUsrDialog() + /obj/machinery/door/airlock/proc/mend(var/wireColor) var/wireFlag = airlockWireColorToFlag[wireColor] var/wireIndex = airlockWireColorToIndex[wireColor] //not used in this function @@ -368,6 +379,13 @@ About the new airlock wires panel: safe = 1 src.updateUsrDialog() + if(AIRLOCK_WIRE_SPEED) + autoclose = 1 + if(!src.density) + close() + src.updateUsrDialog() + + /obj/machinery/door/airlock/proc/isElectrified() if(src.secondsElectrified != 0) return 1 @@ -570,6 +588,15 @@ About the new airlock wires panel: else t1 += text("Danger. Door safeties disabled. Restore?
\n",src) + if(src.isWireCut(AIRLOCK_WIRE_SPEED)) + t1 += text("Door timing circuitry not responding.
\n") + else if(src.normalspeed) + t1 += text("Door timing circuitry operating normally. Override?
\n",src) + else + t1 += text("Warning. Door timing circuitry operating abnormally. Restore?
\n",src) + + + if(src.welded) t1 += text("Door appears to have been welded shut.
\n") @@ -676,7 +703,8 @@ About the new airlock wires panel: "Green" = 7, "Grey" = 8, "Black" = 9, - "Gold" = 10 + "Gold" = 10, + "Aqua" = 11 ) for(var/wiredesc in wires) var/is_uncut = src.wires & airlockWireColorToFlag[wires[wiredesc]] @@ -704,8 +732,9 @@ About the new airlock wires panel: return -/obj/machinery/door/airlock/Topic(href, href_list) - ..() +/obj/machinery/door/airlock/Topic(href, href_list, var/nowindow = 0) + if(!nowindow) + ..() if(usr.stat || usr.restrained()) return add_fingerprint(usr) @@ -766,8 +795,8 @@ About the new airlock wires panel: if(istype(usr, /mob/living/silicon) && src.canAIControl()) //AI - //aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door - //aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door + //aiDisable - 1 idscan, 2 disrupt main power, 3 disrupt backup power, 4 drop door bolts, 5 un-electrify door, 7 close door, 8 door safties, 9 door speed + //aiEnable - 1 idscan, 4 raise door bolts, 5 electrify door for 30 seconds, 6 electrify door indefinitely, 7 open door, 8 door safties, 9 door speed if(href_list["aiDisable"]) var/code = text2num(href_list["aiDisable"]) switch (code) @@ -816,6 +845,17 @@ About the new airlock wires panel: else usr << text("Firmware reports safeties already overriden.
\n") + + + if(9) + // Door speed control + if(src.isWireCut(AIRLOCK_WIRE_SPEED)) + usr << text("Control to door timing circuitry has been severed.
\n") + else if (src.normalspeed) + normalspeed = 0 + else + usr << text("Door timing circurity already accellerated.") + if(7) //close door if(src.welded) @@ -887,9 +927,19 @@ About the new airlock wires panel: usr << text("Control to door sensors is disabled.
\n") else if (!src.safe) safe = 1 + src.updateUsrDialog() else usr << text("Firmware reports safeties already in place.
\n") + if(9) + // Door speed control + if(src.isWireCut(AIRLOCK_WIRE_SPEED)) + usr << text("Control to door timing circuitry has been severed.
\n") + else if (!src.normalspeed) + normalspeed = 1 + src.updateUsrDialog() + else + usr << text("Door timing circurity currently operating normally.") if(7) //open door @@ -904,7 +954,8 @@ About the new airlock wires panel: usr << text("The airlock is already opened.
\n") add_fingerprint(usr) update_icon() - updateUsrDialog() + if(!nowindow) + updateUsrDialog() return /obj/machinery/door/airlock/attackby(C as obj, mob/user as mob) @@ -1050,7 +1101,7 @@ About the new airlock wires panel: return /obj/machinery/door/airlock/open() - if(src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_OPEN_DOOR)) + if(src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_OPEN_DOOR) || src.operating) return 0 use_power(50) if(istype(src, /obj/machinery/door/airlock/glass)) @@ -1062,7 +1113,7 @@ About the new airlock wires panel: return ..() /obj/machinery/door/airlock/close() - if(src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + if(src.welded || src.locked || (!src.arePowerSystemsOn()) || (stat & NOPOWER) || src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS) || src.operating) return if(safe) if(locate(/mob/living) in get_turf(src)) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 637a98bbf0..ac6ef06461 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -15,6 +15,7 @@ operating = 0 autoclose = 0 glass = 0 + normalspeed = 1 proc/bumpopen(mob/user as mob) proc/update_nearby_tiles(need_rebuild) @@ -209,9 +210,13 @@ if(operating) operating = 0 - if(autoclose) + if(autoclose && normalspeed) spawn(150) autoclose() + if(autoclose && !normalspeed) + spawn(5) + autoclose() + return 1 @@ -279,7 +284,7 @@ /obj/machinery/door/proc/autoclose() var/obj/machinery/door/airlock/A = src - if(!A.density && !A.operating && !A.locked && !A.welded) + if(!A.density && !A.operating && !A.locked && !A.welded && A.autoclose) close() return diff --git a/code/game/magic/cultist/runes.dm b/code/game/magic/cultist/runes.dm index faa4d5deea..632abd86ab 100644 --- a/code/game/magic/cultist/runes.dm +++ b/code/game/magic/cultist/runes.dm @@ -595,14 +595,33 @@ var/list/sacrificed = list() H.gib(1) else if(cultsinrange.len >= 3) - H.gib(1) - usr << "\red The Geometer of Blood accepts this sacrifice." + if(H.stat !=2) + if(prob(80)) + usr << "\red The Geometer of Blood accepts this sacrifice." + ticker.mode:grant_runeword(usr) + else + usr << "\red The Geometer of blood accepts this sacrifice." + usr << "\red However, this soul was not enough to gain His favor." + H.gib(1) + else + if(prob(40)) + usr << "\red The Geometer of blood accepts this sacrifice." + ticker.mode:grant_runeword(usr) + else + usr << "\red The Geometer of blood accepts this sacrifice." + usr << "\red However, a mere dead body is not enough to satisfy Him." + H.gib(1) else if(H.stat !=2) usr << "\red The victim is still alive, you will need more cultists chanting for the sacrifice to succeed." else + if(prob(40)) + usr << "\red The Geometer of blood accepts this sacrifice." + ticker.mode:grant_runeword(usr) + else + usr << "\red The Geometer of blood accepts this sacrifice." + usr << "\red However, a mere dead body is not enough to satisfy Him." H.gib(1) - usr << "\red The Geometer of blood accepts this sacrifice." for(var/mob/living/carbon/monkey/M in src.loc) if (ticker.mode.name == "cult") if(M.mind == ticker.mode:sacrifice_target) @@ -621,6 +640,8 @@ var/list/sacrificed = list() usr << "\red However, a mere monkey is not enough to satisfy Him." else usr << "\red The Geometer of Blood accepts your meager sacrifice." + if(prob(20)) + ticker.mode.grant_runeword(usr) M.gib(1) /* for(var/mob/living/carbon/alien/A) for(var/mob/K in cultsinrange) diff --git a/code/game/objects/radio/radio.dm b/code/game/objects/radio/radio.dm index 866fe8ad32..fe7ba377ec 100644 --- a/code/game/objects/radio/radio.dm +++ b/code/game/objects/radio/radio.dm @@ -236,7 +236,10 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use /obj/item/device/radio/talk_into(mob/M as mob, message, channel) if(!on) return // the device has to be on - +/* Fix for permacell radios, but kinda eh about actually fixing them. + if(!(src.wires & WIRE_TRANSMIT)) // The device has to have all its wires and shit intact + return +*/ if(GLOBAL_RADIO_TYPE == 1) // NEW RADIO SYSTEMS: By Doohl @@ -601,6 +604,7 @@ var/GLOBAL_RADIO_TYPE = 1 // radio type to use R.show_message(rendered, 2) /obj/item/device/radio/hear_talk(mob/M as mob, msg) + if (broadcasting) talk_into(M, msg) /* diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm index 108092a47a..a6a3553488 100644 --- a/code/modules/admin/verbs/diagnostics.dm +++ b/code/modules/admin/verbs/diagnostics.dm @@ -207,6 +207,7 @@ alert(usr,"No players found. How the fuck are you calling this?","Tension Report") return 0 + var/output = {"TENSION REPORT
General Statistics
Deaths: [tension_master.deaths]
@@ -217,10 +218,20 @@
Current Status
Tension: [tension_master.score]
+Increase Tension by 50000
Tension per player: [tension_master.score/tension_master.get_num_players()]
-Recommendations: not yet implemented
+Recommendations: All the modes. All of them. Press all of them.

-"} + Make Tratiors
+ Make Changlings
+ Make Revs
+ Make Wizard
+ Make Cult
+ Make Nuke Team
+ Make Malf AI
+ Make Space Ninja
+ Make Deathsquad (Syndicate)
- usr << browse(output,"window=tensionreport") \ No newline at end of file +"} + usr << browse(output,"window=tensionreport") diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 9190fc145d..cfe95e3944 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -44,6 +44,12 @@ /mob/living/silicon/robot/Del() if(mmi)//Safety for when a cyborg gets dust()ed. Or there is no MMI inside. mmi.loc = get_turf(loc)//To hopefully prevent run time errors. + + if(!key) + for(var/mob/dead/observer/ghost in world) + if(ghost.corpse == src && ghost.client) + ghost.client.mob = ghost.corpse + if(key)//If there is a client attached to host. if(client) client.screen.len = null @@ -56,6 +62,7 @@ mmi.brainmob.key = key else//If the brain does have a mind. Also shouldn't happen but who knows. mmi.brainmob.key = key + mmi = null ..() @@ -962,4 +969,25 @@ Frequency: /mob/living/silicon/robot/proc/self_destruct() gib(1) + return +/mob/living/silicon/robot/proc/UnlinkSelf() + if (src.connected_ai) + src.connected_ai = null + lawupdate = 0 + lockcharge = 0 + canmove = 1 + + + +/mob/living/silicon/robot/proc/ResetSecurityCodes() + set category = "Robot Commands" + set name = "Reset Identity Codes" + set desc = "Scrambles your security and identification codes and resets your current buffers. Unlocks you, but permenantly severs you from your AI. You can still be blown by a human at the robotics console." + + var/mob/living/silicon/robot/R = usr + + if(R) + R.UnlinkSelf() + R << "Buffers flushed and reset. All systems operational." + src.verbs -= /mob/living/silicon/robot/proc/ResetSecurityCodes \ No newline at end of file diff --git a/config/config.txt b/config/config.txt index 57da0a27af..bf799f8362 100644 --- a/config/config.txt +++ b/config/config.txt @@ -74,6 +74,9 @@ ALLOW_RANDOM_EVENTS ## If security is prohibited from being most antagonists PROTECT_ROLES_FROM_ANTAGONIST +## If the auto-tensioner is active by default. It creates more tratiors/other antagonists if it consideers the round slowing down. +TENSIONER_ACTIVE + ## allow players to initiate a restart vote ALLOW_VOTE_RESTART diff --git a/html/changelog.html b/html/changelog.html index a24b43083a..8bcfcbfc89 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -91,6 +91,20 @@ Stuff which is in development and not yet visible to players or just code relate should be listed in the changelog upon commit tho. Thanks. --> + +
+

3/11/2012

+

PolymorphBlue updated:

+
    +
  • The AI can now open doors with shift+click, bolt them with ctrl+click, and shock them with alt+click
  • +
  • Tratior borgs who hack themselves cannot be blown by their AI.
  • +
  • Adds a new wire to doors that controls the time delay before they close. If pulsed, they close like a sliding glass door. If cut, they do not close by themselves.
  • +
  • Borgs who have died, ghosts, and are then blown up will now have their ghosts properly transfered to their dropped MMIs.
  • +
+
+ + +

08 March 2012

Nodrak and Carnwennan updated: