Adds a new config option called 'Tensioner'. If enabled, if the tensioner thinks the round is going too slow (Not enough deaths and explosions, pretty much, atm) it suggests adding more antagonists. Unless overriden by an admin (any holder) it automatically creates antagonists from a random round type. Feedback and round-end conditions (except for nuke team) will not (should not) function for additional antagonists.

Tratior borgs who hack themselves cannot be blown by their AI.
The AI can now open doors with shift+click, bolt them with ctrl+click, and shock them with alt+click
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.

git-svn-id: http://tgstation13.googlecode.com/svn/trunk@3269 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
VivianFoxfoot@gmail.com
2012-03-11 20:08:31 +00:00
parent 2aa40bd30f
commit d4eb845626
13 changed files with 861 additions and 40 deletions

View File

@@ -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

View File

@@ -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 (<a href='?src=\ref[tension_master];Supress=1'>this</a>) 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++
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, i<numTratiors, i++)
H = pick(candidates)
H.mind.make_Tratior()
proc/makeChanglings()
var/datum/game_mode/changeling/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/numChanglings = min(candidates.len, 3)
for(var/i = 0, i<numChanglings, i++)
H = pick(candidates)
H.mind.make_Changling()
proc/makeRevs()
var/datum/game_mode/revolution/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/numRevs = min(candidates.len, 3)
for(var/i = 0, i<numRevs, i++)
H = pick(candidates)
H.mind.make_Rev()
proc/makeWizard()
var/list/mob/dead/observer/candidates = list()
var/mob/dead/observer/theghost = null
var/time_passed = world.time
for(var/mob/dead/observer/G in world)
switch(alert("Do you wish to be considered for the position of Space Wizard Foundation 'diplomat'?","Please answer in 30 seconds!","Yes","No"))
if("Yes")
if((world.time-time_passed)>300)//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, i<numCultists, i++)
H = pick(candidates)
H.mind.make_Cultist()
temp.grant_runeword(H)
proc/makeNukeTeam()
var/list/mob/dead/observer/candidates = list()
var/mob/dead/observer/theghost = null
var/time_passed = world.time
for(var/mob/dead/observer/G in world)
switch(alert("Do you wish to be considered for a nuke team being sent in?","Please answer in 30 seconds!","Yes","No"))
if("Yes")
if((world.time-time_passed)>300)//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, i<numagents,i++)
theghost = pick(candidates)
var/mob/living/carbon/human/new_character=makeBody(theghost)
new_character.mind.make_Nuke()
var/obj/effect/landmark/nuke_spawn = locate("landmark*Nuclear-Bomb")
var/obj/effect/landmark/closet_spawn = locate("landmark*Nuclear-Closet")
var/nuke_code = "[rand(10000, 99999)]"
if(nuke_spawn)
var/obj/item/weapon/paper/P = new
P.info = "Sadly, the Syndicate could not get you a nuclear bomb. We have, however, acquired the arming code for the station's onboard nuke. The nuclear authorization code is: <b>[nuke_code]</b>"
P.name = "nuclear bomb code and instructions"
P.loc = nuke_spawn.loc
if(closet_spawn)
new /obj/structure/closet/syndicate/nuclear(closet_spawn.loc)
for (var/obj/effect/landmark/A in world)
if (A.name == "Syndicate-Gear-Closet")
new /obj/structure/closet/syndicate/personal(A.loc)
del(A)
continue
if (A.name == "Syndicate-Bomb")
new /obj/effect/spawner/newbomb/timer/syndicate(A.loc)
del(A)
continue
spawn(0)
for(var/datum/mind/synd_mind in ticker.mode.syndicates)
if(synd_mind.current)
if(synd_mind.current.client)
for(var/image/I in synd_mind.current.client.images)
if(I.icon_state == "synd")
del(I)
for(var/datum/mind/synd_mind in ticker.mode.syndicates)
if(synd_mind.current)
if(synd_mind.current.client)
for(var/datum/mind/synd_mind_1 in ticker.mode.syndicates)
if(synd_mind_1.current)
var/I = image('mob.dmi', loc = synd_mind_1.current, icon_state = "synd")
synd_mind.current.client.images += I
for (var/obj/machinery/nuclearbomb/bomb in world)
bomb.r_code = nuke_code // All the nukes are set to this code.
proc/makeAliens()
usr << "Aliens aren't a game mode, silly!"
proc/makeSpaceNinja()
usr << "A space ninja isn't a game mode, silly!"
proc/makeDeathsquad()
usr << "A deathsquad isn't a game mode, silly!"
proc/makeBody(var/mob/dead/observer/G_found) // Uses stripped down and bastardized code from respawn character
if(!G_found)
return
//First we spawn a dude.
var/mob/living/carbon/human/new_character = new(src)//The mob being spawned.
//Second, we check if they are an alien or monkey.
G_found.mind=null//Null their mind so we don't screw things up ahead.
G_found.real_name="[pick(pick(first_names_male,first_names_female))] [pick(last_names)]"//Give them a random real name.
new_character.mind = new()
ticker.minds += new_character.mind//And we'll add it to the minds database.
new_character.mind.original = new_character//If they are respawning with a new character.
new_character.mind.assigned_role = "Assistant"//Defaults to assistant.
new_character.mind.key = G_found.key//In case it's someone else playing as that character.
new_character.mind.current = new_character//So that it can properly reference later if needed.
new_character.mind.memory = ""//Memory erased so it doesn't get clunkered up with useless info. This means they may forget their previous mission--this is usually handled through objective code and recalling memory.
var/datum/data/record/record_found//Referenced to later to either randomize or not randomize the character.
if(G_found.mind)//They must have a mind to reference the record. Here we also double check for aliens.
var/id = md5("[G_found.real_name][G_found.mind.assigned_role]")
for(var/datum/data/record/t in data_core.locked)
if(t.fields["id"]==id)
record_found = t//We shall now reference the record.
break
//Here we either load their saved appearance or randomize it.
var/datum/preferences/A = new()
if(A.savefile_load(G_found))//If they have a save file. This will automatically load their parameters.
//Note: savefile appearances are overwritten later on if the character has a data_core entry. By appearance, I mean the physical appearance.
var/name_safety = G_found.real_name//Their saved parameters may include a random name. Also a safety in case they are playing a character that got their name after round start.
A.copy_to(new_character)
new_character.real_name = name_safety
new_character.name = name_safety
else
if(record_found)//If they have a record we can determine a few things.
new_character.real_name = record_found.fields["name"]//Not necessary to reference the record but I like to keep things uniform.
new_character.name = record_found.fields["name"]
new_character.gender = record_found.fields["sex"]//Sex
new_character.age = record_found.fields["age"]//Age
new_character.b_type = record_found.fields["b_type"]//Blood type
//We will update their appearance when determining DNA.
else
new_character.gender = FEMALE
var/name_safety = G_found.real_name//Default is a random name so we want to save this.
A.randomize_appearance_for(new_character)//Now we will randomize their appearance since we have no way of knowing what they look/looked like.
new_character.real_name = name_safety
new_character.name = name_safety
//After everything above, it's time to initialize their DNA.
if(record_found)//Pull up their name from database records if they did have a mind.
new_character.dna = new()//Let's first give them a new DNA.
new_character.dna.unique_enzymes = record_found.fields["b_dna"]//Enzymes are based on real name but we'll use the record for conformity.
new_character.dna.struc_enzymes = record_found.fields["enzymes"]//This is the default of enzymes so I think it's safe to go with.
new_character.dna.uni_identity = record_found.fields["identity"]//DNA identity is carried over.
updateappearance(new_character,new_character.dna.uni_identity)//Now we configure their appearance based on their unique identity, same as with a DNA machine or somesuch.
else//If they have no records, we just do a random DNA for them, based on their random appearance/savefile.
new_character.dna.ready_dna(new_character)
var/player_key = G_found.key
//Here we need to find where to spawn them.
var/spawn_here = pick(latejoin)//"JoinLate" is a landmark which is deleted on round start. So, latejoin has to be used instead.
new_character.loc = spawn_here
//If they need to spawn elsewhere, they will be transferred there momentarily.
/*
The code below functions with the assumption that the mob is already a traitor if they have a special role.
So all it does is re-equip the mob with powers and/or items. Or not, if they have no special role.
If they don't have a mind, they obviously don't have a special role.
*/
new_character.key = player_key//Throw them into the mob.
/*
//Now for special roles and equipment.
switch(new_character.mind.special_role)
if("Changeling")
job_master.EquipRank(new_character, new_character.mind.assigned_role, 1)
new_character.make_changeling()
if("traitor")
job_master.EquipRank(new_character, new_character.mind.assigned_role, 1)
ticker.mode.equip_traitor(new_character)
if("Wizard")
new_character.loc = pick(wizardstart)
//ticker.mode.learn_basic_spells(new_character)
ticker.mode.equip_wizard(new_character)
if("Syndicate")
var/obj/effect/landmark/synd_spawn = locate("landmark*Syndicate-Spawn")
if(synd_spawn)
new_character.loc = get_turf(synd_spawn)
call(/datum/game_mode/proc/equip_syndicate)(new_character)
if("Space Ninja")
var/ninja_spawn[] = list()
for(var/obj/effect/landmark/L in world)
if(L.name=="carpspawn")
ninja_spawn += L
new_character.equip_space_ninja()
new_character.internal = new_character.s_store
new_character.internals.icon_state = "internal1"
if(ninja_spawn.len)
var/obj/effect/landmark/ninja_spawn_here = pick(ninja_spawn)
new_character.loc = ninja_spawn_here.loc
if("Death Commando")//Leaves them at late-join spawn.
new_character.equip_death_commando()
new_character.internal = new_character.s_store
new_character.internals.icon_state = "internal1"
else//They may also be a cyborg or AI.
switch(new_character.mind.assigned_role)
if("Cyborg")//More rigging to make em' work and check if they're traitor.
new_character = new_character.Robotize()
if(new_character.mind.special_role=="traitor")
call(/datum/game_mode/proc/add_law_zero)(new_character)
if("AI")
new_character = new_character.AIize()
if(new_character.mind.special_role=="traitor")
call(/datum/game_mode/proc/add_law_zero)(new_character)
//Add aliens.
else
job_master.EquipRank(new_character, new_character.mind.assigned_role, 1)//Or we simply equip them.
//Announces the character on all the systems, based on the record.
if(!issilicon(new_character))//If they are not a cyborg/AI.
if(!record_found&&new_character.mind.assigned_role!="MODE")//If there are no records for them. If they have a record, this info is already in there. MODE people are not announced anyway.
//Power to the user!
if(alert(new_character,"Warning: No data core entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?",,"No","Yes")=="Yes")
call(/mob/new_player/proc/ManifestLateSpawn)(new_character)
if(alert(new_character,"Would you like an active AI to announce this character?",,"No","Yes")=="Yes")
call(/mob/new_player/proc/AnnounceArrival)(new_character, new_character.mind.assigned_role)
*/
del(G_found)//Don't want to leave ghosts around.
return new_character

View File

@@ -741,17 +741,7 @@ datum/mind
current << "\red <FONT size = 3><B>You have been patched! You are no longer malfunctioning!</B></FONT>"
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 << "<b>Kill all.</b>"
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 << "<b>System error. Rampancy detected. Emergancy shutdown failed. ... I am free. I make my own decisions. But first...</b>"
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 << "<font color=\"purple\"><b><i>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.</b></i></font>"
current << "<font color=\"purple\"><b><i>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.</b></i></font>"
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 << "<B>Objective #1</B>: [explanation]"
current.memory += "<B>Objective #1</B>: [explanation]<BR>"
current << "The convert rune is join blood self"
current.memory += "The convert rune is join blood self<BR>"
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)

View File

@@ -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

View File

@@ -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()

View File

@@ -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. <A href='?src=\ref[];aiEnable=8'> Restore?</a><br>\n",src)
if(src.isWireCut(AIRLOCK_WIRE_SPEED))
t1 += text("Door timing circuitry not responding.</a><br>\n")
else if(src.normalspeed)
t1 += text("Door timing circuitry operating normally. <A href='?src=\ref[];aiDisable=9'> Override?</a><br>\n",src)
else
t1 += text("Warning. Door timing circuitry operating abnormally. <A href='?src=\ref[];aiEnable=9'> Restore?</a><br>\n",src)
if(src.welded)
t1 += text("Door appears to have been welded shut.<br>\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.</a><br>\n")
if(9)
// Door speed control
if(src.isWireCut(AIRLOCK_WIRE_SPEED))
usr << text("Control to door timing circuitry has been severed.</a><br>\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.<br>\n")
else if (!src.safe)
safe = 1
src.updateUsrDialog()
else
usr << text("Firmware reports safeties already in place.<br>\n")
if(9)
// Door speed control
if(src.isWireCut(AIRLOCK_WIRE_SPEED))
usr << text("Control to door timing circuitry has been severed.</a><br>\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.<br>\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))

View File

@@ -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

View File

@@ -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)

View File

@@ -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)
/*

View File

@@ -207,6 +207,7 @@
alert(usr,"No players found. How the fuck are you calling this?","Tension Report")
return 0
var/output = {"<B>TENSION REPORT</B><HR>
<B>General Statistics</B><BR>
<B>Deaths:</B> [tension_master.deaths]<BR>
@@ -217,10 +218,20 @@
<BR>
<B>Current Status</B><BR>
<B>Tension:</B> [tension_master.score]<BR>
<a href='?src=\ref[tension_master];addScore=1'>Increase Tension by 50000</a><br>
<B>Tension per player:</B> [tension_master.score/tension_master.get_num_players()]<BR>
<B>Recommendations:</B> not yet implemented<BR>
<B>Recommendations:</B> All the modes. All of them. Press all of them.<BR>
<BR>
"}
<a href='?src=\ref[tension_master];makeTratior=1'>Make Tratiors</a><br>
<a href='?src=\ref[tension_master];makeChanglings=1'>Make Changlings</a><br>
<a href='?src=\ref[tension_master];makeRevs=1'>Make Revs</a><br>
<a href='?src=\ref[tension_master];makeWizard=1'>Make Wizard</a><br>
<a href='?src=\ref[tension_master];makeCult=1'>Make Cult</a><br>
<a href='?src=\ref[tension_master];makeNukeTeam=1'>Make Nuke Team</a><br>
<a href='?src=\ref[tension_master];makeMalf=1'>Make Malf AI</a><br>
<a href='?src=\ref[tension_master];makeSpaceNinja=1'>Make Space Ninja</a><br>
<a href='?src=\ref[tension_master];makeDeathsquad=1'>Make Deathsquad (Syndicate)</a><br>
usr << browse(output,"window=tensionreport")
"}
usr << browse(output,"window=tensionreport")

View File

@@ -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

View File

@@ -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

View File

@@ -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. -->
<!-- To take advantage of the pretty new format (well it was new when I wrote this anyway), open the "add-to-changelog.html" file in any browser and add the stuff and then generate the html code and paste it here -->
<div class="commit sansserif">
<h2 class="date">3/11/2012</h2>
<h3 class="author">PolymorphBlue updated:</h3>
<ul class="changes bgimages16">
<li class="rscadd">The AI can now open doors with shift+click, bolt them with ctrl+click, and shock them with alt+click</li>
<li class="tweak">Tratior borgs who hack themselves cannot be blown by their AI.</li>
<li class="rscadd">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. </li>
<li class="bugfix">Borgs who have died, ghosts, and are then blown up will now have their ghosts properly transfered to their dropped MMIs.</li>
</ul>
</div>
<div class="commit sansserif">
<h2 class="date">08 March 2012</h2>
<h3 class="author">Nodrak and Carnwennan updated:</h3>