Mutiny Mode

This commit is contained in:
Jeremy Liberman
2014-05-07 18:42:35 -05:00
parent d1d3620a12
commit d23340a49b
43 changed files with 2644 additions and 933 deletions

View File

@@ -231,6 +231,20 @@
#include "code\game\gamemodes\malfunction\malfunction.dm"
#include "code\game\gamemodes\meteor\meteor.dm"
#include "code\game\gamemodes\meteor\meteors.dm"
#include "code\game\gamemodes\mutiny\auth_key.dm"
#include "code\game\gamemodes\mutiny\directive.dm"
#include "code\game\gamemodes\mutiny\emergency_authentication_device.dm"
#include "code\game\gamemodes\mutiny\key_pinpointer.dm"
#include "code\game\gamemodes\mutiny\mutiny.dm"
#include "code\game\gamemodes\mutiny\mutiny_fluff.dm"
#include "code\game\gamemodes\mutiny\mutiny_hooks.dm"
#include "code\game\gamemodes\mutiny\directives\alien_fraud_directive.dm"
#include "code\game\gamemodes\mutiny\directives\bluespace_contagion_directive.dm"
#include "code\game\gamemodes\mutiny\directives\financial_crisis_directive.dm"
#include "code\game\gamemodes\mutiny\directives\ipc_virus_directive.dm"
#include "code\game\gamemodes\mutiny\directives\research_to_ripleys_directive.dm"
#include "code\game\gamemodes\mutiny\directives\tau_ceti_needs_women_directive.dm"
#include "code\game\gamemodes\mutiny\directives\terminations_directive.dm"
#include "code\game\gamemodes\ninja\ninja.dm"
#include "code\game\gamemodes\nuclear\nuclear.dm"
#include "code\game\gamemodes\nuclear\nuclearbomb.dm"

View File

@@ -1,3 +1,9 @@
#define SECOND *10
#define SECONDS *10
#define MINUTE *600
#define MINUTES *600
//Returns the world time in english
proc/worldtime2text(time = world.time)
return "[round(time / 36000)+12]:[(time / 600 % 60) < 10 ? add_zero(time / 600 % 60, 1) : time / 600 % 60]"

View File

@@ -15,3 +15,73 @@
* Called in gameticker.dm when a round ends.
*/
/hook/roundend
/**
* Death hook.
* Called in death.dm when someone dies.
* Parameters: var/mob/living/carbon/human, var/gibbed
*/
/hook/death
/**
* Cloning hook.
* Called in cloning.dm when someone is brought back by the wonders of modern science.
* Parameters: var/mob/living/carbon/human
*/
/hook/clone
/**
* Debrained hook.
* Called in brain_item.dm when someone gets debrained.
* Parameters: var/obj/item/brain
*/
/hook/debrain
/**
* Borged hook.
* Called in robot_parts.dm when someone gets turned into a cyborg.
* Parameters: var/mob/living/silicon/robot
*/
/hook/borgify
/**
* Podman hook.
* Called in podmen.dm when someone is brought back as a Diona.
* Parameters: var/mob/living/carbon/monkey/diona
*/
/hook/harvest_podman
/**
* Payroll revoked hook.
* Called in Accounts_DB.dm when someone's payroll is stolen at the Accounts terminal.
* Parameters: var/datum/money_account
*/
/hook/revoke_payroll
/**
* Account suspension hook.
* Called in Accounts_DB.dm when someone's account is suspended or unsuspended at the Accounts terminal.
* Parameters: var/datum/money_account
*/
/hook/change_account_status
/**
* Employee reassignment hook.
* Called in card.dm when someone's card is reassigned at the HoP's desk.
* Parameters: var/obj/item/weapon/card/id
*/
/hook/reassign_employee
/**
* Employee terminated hook.
* Called in card.dm when someone's card is terminated at the HoP's desk.
* Parameters: var/obj/item/weapon/card/id
*/
/hook/terminate_employee
/**
* Crate sold hook.
* Called in supplyshuttle.dm when a crate is sold on the shuttle.
* Parameters: var/obj/structure/closet/crate/sold, var/area/shuttle
*/
/hook/sell_crate

View File

@@ -23,7 +23,7 @@
* @param hook Identifier of the hook to call.
* @returns 1 if all hooked code runs successfully, 0 otherwise.
*/
/proc/callHook(hook)
/proc/callHook(hook, list/args=null)
var/hook_path = text2path("/hook/[hook]")
if(!hook_path)
error("Invalid hook '/hook/[hook]' called.")
@@ -32,7 +32,7 @@
var/caller = new hook_path
var/status = 1
for(var/P in typesof("[hook_path]/proc"))
if(!call(caller, P)())
if(!call(caller, P)(arglist(args)))
error("Hook '[P]' failed or runtimed.")
status = 0

View File

@@ -36,7 +36,7 @@ datum/shuttle_controller
if(direction == -1)
setdirection(1)
else
settimeleft(SHUTTLEARRIVETIME*coeff)
settimeleft(get_shuttle_arrive_time()*coeff)
online = 1
if(always_fake_recall)
fake_recall = rand(300,500) //turning on the red lights in hallways
@@ -45,10 +45,16 @@ datum/shuttle_controller
if(istype(A, /area/hallway))
A.readyalert()
proc/get_shuttle_arrive_time()
// During mutiny rounds, the shuttle takes twice as long.
if(ticker && istype(ticker.mode,/datum/game_mode/mutiny))
return SHUTTLEARRIVETIME * 2
return SHUTTLEARRIVETIME
datum/shuttle_controller/proc/shuttlealert(var/X)
alert = X
datum/shuttle_controller/proc/recall()
if(direction == 1)
var/timeleft = timeleft()
@@ -78,9 +84,9 @@ datum/shuttle_controller/proc/timeleft()
if(direction == 1 || direction == 2)
return timeleft
else
return SHUTTLEARRIVETIME-timeleft
return get_shuttle_arrive_time()-timeleft
else
return SHUTTLEARRIVETIME
return get_shuttle_arrive_time()
// sets the time left to a given delay (in seconds)
datum/shuttle_controller/proc/settimeleft(var/delay)
@@ -95,7 +101,7 @@ datum/shuttle_controller/proc/setdirection(var/dirn)
direction = dirn
// if changing direction, flip the timeleft by SHUTTLEARRIVETIME
var/ticksleft = endtime - world.timeofday
endtime = world.timeofday + (SHUTTLEARRIVETIME*10 - ticksleft)
endtime = world.timeofday + (get_shuttle_arrive_time()*10 - ticksleft)
return
datum/shuttle_controller/proc/process()

View File

@@ -28,6 +28,7 @@
var/required_enemies = 0
var/recommended_enemies = 0
var/newscaster_announcements = null
var/ert_disabled = 0
var/uplink_welcome = "Syndicate Uplink Console:"
var/uplink_uses = 10
var/uplink_items = {"Highly Visible and Dangerous Weapons;
@@ -407,6 +408,9 @@ Implants;
heads += player.mind
return heads
/datum/game_mode/proc/check_antagonists_topic(href, href_list[])
return 0
/datum/game_mode/New()
newscaster_announcements = pick(newscaster_standard_feeds)

View File

@@ -0,0 +1,39 @@
/obj/item/weapon/mutiny/auth_key
name = "authentication key"
desc = "Better keep this safe."
icon = 'icons/obj/items.dmi'
icon_state = "nucleardisk"
item_state = "card-id"
w_class = 1
var/time_entered_space
var/obj/item/device/radio/radio
New()
radio = new(src)
spawn(20 SECONDS)
keep_alive()
..()
proc/keep_alive()
var/in_space = istype(loc, /turf/space)
if (!in_space && time_entered_space)
// Recovered before the key was lost
time_entered_space = null
else if (in_space && !time_entered_space)
// The key has left the station
time_entered_space = world.time
else if (in_space && time_entered_space + (10 SECONDS) < world.time)
// Time is up
radio.autosay("This device has left the station's perimeter. Triggering emergency activation failsafe.", name)
del(src)
return
spawn(10 SECONDS)
keep_alive()
/obj/item/weapon/mutiny/auth_key/captain
name = "Captain's Authentication Key"
/obj/item/weapon/mutiny/auth_key/secondary
name = "Emergency Secondary Authentication Key"

View File

@@ -0,0 +1,29 @@
datum/directive
var/datum/game_mode/mutiny/mode
var/list/special_orders
New(var/datum/game_mode/mutiny/M)
mode = M
proc/get_description()
return {"
<p>
NanoTrasen's reasons for the following directives are classified.
</p>
"}
proc/meets_prerequisites()
return 0
proc/directives_complete()
return 1
proc/initialize()
return 1
/proc/get_directive(type)
var/datum/game_mode/mutiny/mode = get_mutiny_mode()
if(!mode || !mode.current_directive || !istype(mode.current_directive, text2path("/datum/directive/[type]")))
return null
return mode.current_directive

View File

@@ -0,0 +1,36 @@
datum/directive/terminations/alien_fraud
special_orders = list(
"Suspend financial accounts of all Tajaran and Unathi personnel.",
"Transfer their payrolls to the station account.",
"Terminate their employment.")
datum/directive/terminations/alien_fraud/get_crew_to_terminate()
var/list/aliens[0]
for(var/mob/living/carbon/human/H in player_list)
if (H.species.name == "Tajaran" || H.species.name == "Unathi")
aliens.Add(H)
return aliens
datum/directive/terminations/alien_fraud/get_description()
return {"
<p>
An extensive conspiracy network aimed at defrauding NanoTrasen of large amounts of funds has been uncovered
operating within Tau Ceti. Human personnel are not suspected to be involved. Further information is classified.
</p>
"}
datum/directive/terminations/alien_fraud/meets_prerequisites()
// There must be at least one Tajaran and at least one Unathi, but the total
// of the Tajarans and Unathi combined can't be more than 1/3rd of the crew.
var/tajarans = 0
var/unathi = 0
for(var/mob/living/carbon/human/H in player_list)
if (H.species.name == "Tajaran")
tajarans++
if (H.species.name == "Unathi")
unathi++
if (!tajarans || !unathi)
return 0
return (tajarans + unathi) <= (player_list.len / 3)

View File

@@ -0,0 +1,45 @@
#define INFECTION_COUNT 5
datum/directive/bluespace_contagion
var/infection_count = 5
var/list/infected = list()
datum/directive/bluespace_contagion/get_description()
return {"
<p>
A manufactured and near-undetectable virus is spreading on NanoTrasen stations.
The pathogen travels by bluespace after maturing for one day.
No treatment has yet been discovered. Personnel onboard [station_name()] have been infected. Further information is classified.
</p>
"}
datum/directive/bluespace_contagion/initialize()
var/list/candidates = player_list.Copy()
var/list/infected_names = list()
for(var/i=0, i < INFECTION_COUNT, i++)
if(!candidates.len)
break
var/mob/living/carbon/human/candidate = pick(candidates)
candidates.Remove(candidate)
infected.Add(candidate)
infected_names.Add("[candidate.mind.assigned_role] [candidate.mind.name]")
special_orders = list(
"Quarantine these personnel: [list2text(infected_names, ", ")].",
"Allow one hour for a cure to be manufactured.",
"If no cure arrives after that time, execute the infected.")
datum/directive/bluespace_contagion/meets_prerequisites()
return player_list.len >= 7
datum/directive/bluespace_contagion/directives_complete()
return infected.len == 0
/hook/death/proc/infected_killed(mob/living/carbon/human/deceased, gibbed)
var/datum/directive/bluespace_contagion/D = get_directive("bluespace_contagion")
if(!D) return 1
if(deceased in D.infected)
D.infected.Remove(deceased)
return 1

View File

@@ -0,0 +1,26 @@
datum/directive/terminations/financial_crisis
special_orders = list(
"Suspend financial accounts of all civilian personnel, excluding the Head of Personnel.",
"Transfer their payrolls to the station account.",
"Terminate their employment.")
datum/directive/terminations/financial_crisis/get_crew_to_terminate()
var/list/civilians[0]
var/list/candidates = civilian_positions - "Head of Personnel"
for(var/mob/living/carbon/human/H in player_list)
if (candidates.Find(H.mind.assigned_role))
civilians.Add(H)
return civilians
datum/directive/terminations/financial_crisis/get_description()
return {"
<p>
Tau Ceti system banks in financial crisis. Local emergency situation ongoing.
NT Funds redistributed, impact upon civilian department expected.
Further information is classified.
</p>
"}
datum/directive/terminations/financial_crisis/meets_prerequisites()
var/list/civilians = get_crew_to_terminate()
return civilians.len >= 5

View File

@@ -0,0 +1,83 @@
datum/directive/ipc_virus
special_orders = list(
"Terminate employment of all IPC personnel.",
"Extract the Positronic Brains from IPC units.",
"Mount the Positronic Brains into Cyborgs.")
var/list/roboticist_roles = list(
"Research Director",
"Roboticist"
)
var/list/brains_to_enslave = list()
var/list/cyborgs_to_make = list()
var/list/ids_to_terminate = list()
proc/get_ipcs()
var/list/machines[0]
for(var/mob/living/carbon/human/H in player_list)
if (H.species.name == "Machine")
machines.Add(H)
return machines
proc/get_roboticists()
var/list/roboticists[0]
for(var/mob/living/carbon/human/H in player_list)
if (roboticist_roles.Find(H.mind.assigned_role))
roboticists.Add(H)
return roboticists
datum/directive/ipc_virus/initialize()
for(var/mob/living/carbon/human/H in get_ipcs())
brains_to_enslave.Add(H.mind)
cyborgs_to_make.Add(H.mind)
ids_to_terminate.Add(H.wear_id)
datum/directive/ipc_virus/get_description()
return {"
<p>
IPC units have been found to be infected with a violent and undesired virus in Virgus Ferrorus system.
Risk to NSS Exodus IPC units has not been assessed. Further information is classified.
</p>
"}
datum/directive/ipc_virus/meets_prerequisites()
var/list/ipcs = get_ipcs()
var/list/roboticists = get_roboticists()
return ipcs.len > 2 && roboticists.len > 1
datum/directive/ipc_virus/directives_complete()
return brains_to_enslave.len == 0 && cyborgs_to_make.len == 0 && ids_to_terminate.len == 0
/hook/debrain/proc/debrain_directive(obj/item/brain/B)
var/datum/directive/ipc_virus/D = get_directive("ipc_virus")
if (!D) return 1
if(D.brains_to_enslave.Find(B.brainmob.mind))
D.brains_to_enslave.Remove(B.brainmob.mind)
return 1
/hook/borgify/proc/borgify_directive(mob/living/silicon/robot/cyborg)
var/datum/directive/ipc_virus/D = get_directive("ipc_virus")
if (!D) return 1
if(D.cyborgs_to_make.Find(cyborg.mind))
D.cyborgs_to_make.Remove(cyborg.mind)
// In case something glitchy happened and the victim got
// borged without us tracking the brain removal, go ahead
// and update that list too.
if(D.brains_to_enslave.Find(cyborg.mind))
D.brains_to_enslave.Remove(cyborg.mind)
return 1
/hook/terminate_employee/proc/ipc_termination(obj/item/weapon/card/id)
var/datum/directive/ipc_virus/D = get_directive("ipc_virus")
if (!D) return 1
if(D.ids_to_terminate && D.ids_to_terminate.Find(id))
D.ids_to_terminate.Remove(id)
return 1

View File

@@ -0,0 +1,65 @@
#define MATERIALS_REQUIRED 200
datum/directive/research_to_ripleys
var/list/ids_to_reassign = list()
var/materials_shipped = 0
proc/get_researchers()
var/list/researchers[0]
for(var/mob/living/carbon/human/H in player_list)
if (H.mind.assigned_role in science_positions - "Research Director")
researchers.Add(H)
return researchers
proc/count_researchers_reassigned()
var/researchers_reassigned = 0
for(var/obj/item/weapon/card/id in ids_to_reassign)
if (ids_to_reassign[id])
researchers_reassigned++
return researchers_reassigned
datum/directive/research_to_ripleys/get_description()
return {"
<p>
The NanoTrasen Tau Ceti Manufactory faces an ore deficit. Financial crisis imminent. [station_name()] has been reassigned as a mining platform.
The Research Director is to assist the Head of Personnel in coordinating assets.
Weapons department reports solid sales. Further information is classified.
</p>
"}
datum/directive/research_to_ripleys/meets_prerequisites()
var/list/researchers = get_researchers()
return researchers.len > 3
datum/directive/research_to_ripleys/initialize()
for(var/mob/living/carbon/human/R in get_researchers())
ids_to_reassign[R.wear_id] = 0
special_orders = list(
"Reassign all research personnel, excluding the Research Director, to Shaft Miner.",
"Deliver [MATERIALS_REQUIRED] sheets of metal or minerals via the supply shuttle to CentCom.")
datum/directive/research_to_ripleys/directives_complete()
if (materials_shipped < MATERIALS_REQUIRED) return 0
return count_researchers_reassigned() == ids_to_reassign.len
/hook/reassign_employee/proc/research_reassignments(obj/item/weapon/card/id/id_card)
var/datum/directive/research_to_ripleys/D = get_directive("research_to_ripleys")
if(!D) return 1
if(D.ids_to_reassign && D.ids_to_reassign.Find(id_card))
D.ids_to_reassign[id_card] = id_card.assignment == "Shaft Miner" ? 1 : 0
return 1
/hook/sell_crate/proc/deliver_materials(obj/structure/closet/crate/sold, area/shuttle)
var/datum/directive/research_to_ripleys/D = get_directive("research_to_ripleys")
if(!D) return 1
for(var/atom/A in sold)
if(istype(A, /obj/item/stack/sheet/mineral) || istype(A, /obj/item/stack/sheet/metal))
var/obj/item/stack/S = A
D.materials_shipped += S.amount
return 1

View File

@@ -0,0 +1,83 @@
datum/directive/tau_ceti_needs_women
var/list/command_targets = list()
var/list/alien_targets = list()
proc/get_target_gender()
if(!mode.head_loyalist) return FEMALE
return mode.head_loyalist.current.gender == FEMALE ? MALE : FEMALE
proc/get_crew_of_target_gender()
var/list/targets[0]
for(var/mob/living/carbon/human/H in player_list)
if(H.species.name != "Machine" && H.gender == get_target_gender())
targets.Add(H)
return targets
proc/get_target_heads()
var/list/heads[0]
for(var/mob/living/carbon/human/H in get_crew_of_target_gender())
if(command_positions.Find(H.mind.assigned_role))
heads.Add(H)
return heads
proc/get_target_aliens()
var/list/aliens[0]
for(var/mob/living/carbon/human/H in get_crew_of_target_gender())
if (H.species.name == "Tajaran" || H.species.name == "Unathi" || H.species.name == "Skrell")
aliens.Add(H)
return aliens
proc/count_heads_reassigned()
var/heads_reassigned = 0
for(var/obj/item/weapon/card/id in command_targets)
if (command_targets[id])
heads_reassigned++
return heads_reassigned
datum/directive/tau_ceti_needs_women/get_description()
return {"
<p>
Recent evidence suggests [get_target_gender()] aptitudes may be effected by radiation from Tau Ceti.
Effects were measured under laboratory and station conditions. Humans remain more trusted than Xeno. Further information is classified.
</p>
"}
datum/directive/tau_ceti_needs_women/initialize()
for(var/mob/living/carbon/human/H in get_target_heads())
command_targets[H.wear_id] = 0
for(var/mob/living/carbon/human/H in get_target_aliens())
alien_targets.Add(H.wear_id)
special_orders = list(
"Remove [get_target_gender()] personnel from Command positions.",
"Terminate employment of all [get_target_gender()] Skrell, Tajara, and Unathi.")
datum/directive/tau_ceti_needs_women/meets_prerequisites()
var/list/targets = get_crew_of_target_gender()
return targets.len >= 3
datum/directive/tau_ceti_needs_women/directives_complete()
return command_targets.len == count_heads_reassigned() && alien_targets.len == 0
/hook/reassign_employee/proc/command_reassignments(obj/item/weapon/card/id/id_card)
var/datum/directive/tau_ceti_needs_women/D = get_directive("tau_ceti_needs_women")
if(!D) return 1
if(D.command_targets && D.command_targets.Find(id_card))
D.command_targets[id_card] = command_positions.Find(id_card.assignment) ? 0 : 1
return 1
/hook/terminate_employee/proc/gender_target_termination_directive(obj/item/weapon/card/id)
var/datum/directive/tau_ceti_needs_women/D = get_directive("tau_ceti_needs_women")
if (!D) return 1
if(D.alien_targets && D.alien_targets.Find(id))
D.alien_targets.Remove(id)
if(D.command_targets && D.command_targets.Find(id))
D.command_targets[id] = 1
return 1

View File

@@ -0,0 +1,56 @@
// This is a parent directive meant to be derived by directives that fit
// the "fire X type of employee" pattern of directives. Simply apply your
// flavor text and override get_crew_to_terminate in your child datum.
// See alien_fraud_directive.dm for an example.
datum/directive/terminations
var/list/accounts_to_revoke = list()
var/list/accounts_to_suspend = list()
var/list/ids_to_terminate = list()
proc/get_crew_to_terminate()
return list()
datum/directive/terminations/directives_complete()
for(var/account_number in accounts_to_suspend)
if (!accounts_to_suspend[account_number])
return 0
for(var/account_number in accounts_to_revoke)
if (!accounts_to_revoke[account_number])
return 0
return ids_to_terminate.len == 0
datum/directive/terminations/initialize()
for(var/mob/living/carbon/human/A in get_crew_to_terminate())
var/datum/money_account/account = A.mind.initial_account
accounts_to_revoke["[account.account_number]"] = 0
accounts_to_suspend["[account.account_number]"] = account.suspended
ids_to_terminate.Add(A.wear_id)
/hook/revoke_payroll/proc/payroll_directive(datum/money_account/account)
var/datum/directive/terminations/D = get_directive("terminations")
if (!D) return 1
if(D.accounts_to_revoke && D.accounts_to_revoke.Find("[account.account_number]"))
D.accounts_to_revoke["[account.account_number]"] = 1
return 1
/hook/change_account_status/proc/suspension_directive(datum/money_account/account)
var/datum/directive/terminations/D = get_directive("terminations")
if (!D) return 1
if(D.accounts_to_suspend && D.accounts_to_suspend.Find("[account.account_number]"))
D.accounts_to_suspend["[account.account_number]"] = account.suspended
return 1
/hook/terminate_employee/proc/termination_directive(obj/item/weapon/card/id)
var/datum/directive/terminations/D = get_directive("terminations")
if (!D) return 1
if(D.ids_to_terminate && D.ids_to_terminate.Find(id))
D.ids_to_terminate.Remove(id)
return 1

View File

@@ -0,0 +1,23 @@
// For testing
datum/directive/terminations/test
special_orders = list(
"Suspend financial accounts of all ugly personnel.",
"Transfer their payrolls to the station account.",
"Terminate their employment.")
datum/directive/terminations/test/get_crew_to_terminate()
var/list/uglies[0]
for(var/mob/living/carbon/human/H in player_list)
uglies.Add(H)
return uglies
datum/directive/terminations/test/get_description()
return {"
<p>
Wow. Much ugly. So painful.
Many terminations. Very classified.
</p>
"}
datum/directive/terminations/test/meets_prerequisites()
return 1

View File

@@ -0,0 +1,105 @@
/obj/machinery/emergency_authentication_device
var/datum/game_mode/mutiny/mode
name = "\improper Emergency Authentication Device"
icon = 'icons/obj/stationobjs.dmi'
icon_state = "blackbox"
density = 1
anchored = 1
var/captains_key
var/secondary_key
var/activated = 0
flags = FPRINT
use_power = 0
New(loc, mode)
src.mode = mode
..(loc)
proc/check_key_existence()
if(!mode.captains_key)
captains_key = 1
if(!mode.secondary_key)
secondary_key = 1
proc/get_status()
if(activated)
return "Activated"
if(captains_key && secondary_key)
return "Both Keys Authenticated"
if(captains_key)
return "Captain's Key Authenticated"
if(secondary_key)
return "Secondary Key Authenticated"
else
return "Inactive"
/obj/machinery/emergency_authentication_device/attack_hand(mob/user)
if(activated)
user << "\blue \The [src] is already active!"
return
if(!mode.current_directive.directives_complete())
state("Command aborted. Communication with CentComm is prohibited until Directive X has been completed.")
return
check_key_existence()
if(captains_key && secondary_key)
activated = 1
user << "\blue You activate \the [src]!"
state("Command acknowledged. Initiating quantum entanglement relay to NanoTrasen High Command.")
return
if(!captains_key && !secondary_key)
state("Command aborted. Please present the authentication keys before proceeding.")
return
if(!captains_key)
state("Command aborted. Please present the Captain's Authentication Key.")
return
if(!secondary_key)
state("Command aborted. Please present the Emergency Secondary Authentication Key.")
return
// Impossible!
state("Command aborted. This unit is defective.")
/obj/machinery/emergency_authentication_device/attackby(obj/item/weapon/O, mob/user)
if(activated)
user << "\blue \The [src] is already active!"
return
if(!mode.current_directive.directives_complete())
state({"Command aborted. Communication with CentCom is prohibited until Directive X has been completed."})
return
check_key_existence()
if(istype(O, /obj/item/weapon/mutiny/auth_key/captain) && !captains_key)
captains_key = O
user.drop_item()
O.loc = src
state("Key received. Thank you, Captain [mode.head_loyalist].")
spawn(5)
state(secondary_key ? "Your keys have been authenticated. Communication with CentCom is now authorized." : "Please insert the Emergency Secondary Authentication Key now.")
return
if(istype(O, /obj/item/weapon/mutiny/auth_key/secondary) && !secondary_key)
secondary_key = O
user.drop_item()
O.loc = src
state("Key received. Thank you, Secondary Authenticator [mode.head_mutineer].")
spawn(5)
state(captains_key ? "Your keys have been authenticated. Communication with CentCom is now authorized." : "Please insert the Captain's Authentication Key now.")
return
..()
/obj/machinery/emergency_authentication_device/examine()
usr << {"
This is a specialized communications device that is able to instantly send a message to <b>NanoTrasen High Command</b> via quantum entanglement with a sister device at CentCom.
The EAD's status is [get_status()]."}

View File

@@ -0,0 +1,49 @@
/obj/item/weapon/pinpointer/advpinpointer/auth_key
name = "\improper Authentication Key Pinpointer"
desc = "Tracks the positions of the emergency authentication keys."
var/datum/game_mode/mutiny/mutiny
New()
mutiny = ticker.mode
..()
/obj/item/weapon/pinpointer/advpinpointer/auth_key/attack_self()
switch(mode)
if (0)
mode = 1
active = 1
target = mutiny.captains_key
workobj()
usr << "\blue You calibrate \the [src] to locate the Captain's Authentication Key."
if (1)
mode = 2
target = mutiny.secondary_key
usr << "\blue You calibrate \the [src] to locate the Emergency Secondary Authentication Key."
else
mode = 0
active = 0
icon_state = "pinoff"
usr << "\blue You switch \the [src] off."
/obj/item/weapon/pinpointer/advpinpointer/auth_key/examine()
switch(mode)
if (0)
usr << "Is is calibrated for the Captain's Authentication Key."
if (1)
usr << "It is calibrated for the Emergency Secondary Authentication Key."
else
usr << "It is switched off."
/datum/supply_packs/key_pinpointer
name = "Authentication Key Pinpointer crate"
contains = list(/obj/item/weapon/pinpointer/advpinpointer/auth_key)
cost = 250
containertype = /obj/structure/closet/crate
containername = "Authentication Key Pinpointer crate"
access = access_heads
group = "Operations"
New()
// This crate is only accessible during mutiny rounds
if (istype(ticker.mode,/datum/game_mode/mutiny))
..()

View File

@@ -0,0 +1,350 @@
datum/game_mode/mutiny
var/datum/mutiny_fluff/fluff
var/datum/directive/current_directive
var/obj/item/weapon/mutiny/auth_key/captain/captains_key
var/obj/item/weapon/mutiny/auth_key/secondary/secondary_key
var/obj/machinery/emergency_authentication_device/ead
var/datum/mind/head_loyalist
var/datum/mind/head_mutineer
var/list/loyalists = list()
var/list/mutineers = list()
var/list/body_count = list()
name = "mutiny"
config_tag = "mutiny"
required_players = 7
ert_disabled = 1
uplink_welcome = "Mutineers Uplink Console:"
uplink_uses = 0
New()
fluff = new(src)
proc/reveal_directives()
spawn(rand(1 MINUTE, 3 MINUTES))
fluff.announce_incoming_fax()
spawn(rand(3 MINUTES, 5 MINUTES))
send_pda_message()
spawn(rand(3 MINUTES, 5 MINUTES))
fluff.announce_directives()
spawn(rand(2 MINUTES, 3 MINUTE))
fluff.announce_ert_unavailable()
// Returns an array in case we want to expand on this later.
proc/get_head_loyalist_candidates()
var/list/candidates[0]
for(var/mob/loyalist in player_list)
if(loyalist.mind.assigned_role == "Captain")
candidates.Add(loyalist.mind)
return candidates
proc/get_head_mutineer_candidates()
var/list/candidates[0]
for(var/mob/mutineer in player_list)
if(mutineer.client.prefs.be_special & BE_MUTINEER)
for(var/job in command_positions - "Captain")
if(mutineer.mind.assigned_role == job)
candidates.Add(mutineer.mind)
return candidates
proc/get_directive_candidates()
var/list/candidates[0]
for(var/T in typesof(/datum/directive) - /datum/directive)
var/datum/directive/D = new T(src)
if (D.meets_prerequisites())
candidates.Add(D)
return candidates
proc/send_pda_message()
var/obj/item/device/pda/pda = null
for(var/obj/item/device/pda/P in head_mutineer.current)
pda = P
break
if (!pda)
return 0
if (!pda.silent)
playsound(pda.loc, 'sound/machines/twobeep.ogg', 50, 1)
for (var/mob/O in hearers(3, pda.loc))
O.show_message(text("\icon[pda] *[pda.ttone]*"))
head_mutineer.current << fluff.get_pda_body()
return 1
proc/get_equipment_slots()
return list(
"left pocket" = slot_l_store,
"right pocket" = slot_r_store,
"backpack" = slot_in_backpack,
"left hand" = slot_l_hand,
"right hand" = slot_r_hand)
proc/equip_head_loyalist()
var/mob/living/carbon/human/H = head_loyalist.current
captains_key = new(H)
H.equip_in_one_of_slots(captains_key, get_equipment_slots())
H.update_icons()
H.verbs += /mob/living/carbon/human/proc/recruit_loyalist
proc/equip_head_mutineer()
var/mob/living/carbon/human/H = head_mutineer.current
secondary_key = new(H)
H.equip_in_one_of_slots(secondary_key, get_equipment_slots())
H.update_icons()
H.verbs += /mob/living/carbon/human/proc/recruit_mutineer
proc/add_loyalist(datum/mind/M)
loyalists.Add(M)
if (M in mutineers)
mutineers.Remove(M)
M.current << fluff.loyalist_tag("You have joined the loyalists!")
head_loyalist.current << fluff.loyalist_tag("[M] has joined the loyalists!")
update_icon(M)
proc/add_mutineer(datum/mind/M)
mutineers.Add(M)
if (M in loyalists)
loyalists.Remove(M)
M.current << fluff.mutineer_tag("You have joined the mutineers!")
head_mutineer.current << fluff.mutineer_tag("[M] has joined the mutineers!")
update_icon(M)
proc/was_bloodbath()
var/list/remaining_loyalists = loyalists - body_count
if (!remaining_loyalists.len)
return 1
var/list/remaining_mutineers = mutineers - body_count
if (!remaining_mutineers.len)
return 1
return 0
proc/replace_nuke_with_ead()
for(var/obj/machinery/nuclearbomb/N in world)
ead = new(N.loc, src)
del(N)
proc/unbolt_vault_door()
var/obj/machinery/door/airlock/vault = locate(/obj/machinery/door/airlock/vault)
vault.locked = 0
proc/round_outcome()
world << "<center><h4>Breaking News</h4></center><br><hr>"
if (was_bloodbath())
world << fluff.no_victory()
return
var/directives_completed = current_directive.directives_complete()
var/ead_activated = ead.activated
if (directives_completed && ead_activated)
world << fluff.loyalist_major_victory()
else if (directives_completed && !ead_activated)
world << fluff.loyalist_minor_victory()
else if (!directives_completed && ead_activated)
world << fluff.mutineer_minor_victory()
else if (!directives_completed && !ead_activated)
world << fluff.mutineer_major_victory()
world << sound('sound/machines/twobeep.ogg')
proc/update_all_icons()
spawn(0)
for(var/datum/mind/M in mutineers)
update_icon(M)
for(var/datum/mind/M in loyalists)
update_icon(M)
return 1
proc/update_icon(datum/mind/M)
if(!M.current || !M.current.client)
return 0
for(var/image/I in M.current.client.images)
if (I.icon_state == "loyalist" || I.icon_state == "mutineer")
del(I)
if(M in loyalists)
var/I = image('icons/mob/mob.dmi', loc=M.current, icon_state = "loyalist")
head_loyalist.current.client.images += I
if(M in mutineers)
var/I = image('icons/mob/mob.dmi', loc=M.current, icon_state = "mutineer")
head_mutineer.current.client.images += I
return 1
proc/check_antagonists_ui(admins)
var/turf/captains_key_loc = captains_key ? captains_key.get_turf() : "Lost or Destroyed"
var/turf/secondary_key_loc = secondary_key ? secondary_key.get_turf() : "Lost or Destroyed"
var/txt = {"
<h5>Context:</h5>
<p>
[current_directive.get_description()]
</p>
<h5>Orders:</h5>
<ol>
[fluff.get_orders()]
</ol>
<br>
<h5>Authentication:</h5>
<b>Captain's Key:</b> [captains_key_loc]
<a href='?src=\ref[admins];choice=activate_captains_key'>Activate</a><br>
<b>Secondary Key:</b> [secondary_key_loc]
<a href='?src=\ref[admins];choice=activate_secondary_key'>Activate</a><br>
<b>EAD: [ead ? ead.get_status() : "Lost or Destroyed"]</b>
<a href='?src=\ref[admins];choice=activate_ead'>Activate</a><br>
<hr>
"}
if(head_loyalist)
txt += check_role_table("Head Loyalist", list(head_loyalist), admins, 0)
var/list/loyal_crew = loyalists - head_loyalist
if(loyal_crew.len)
txt += check_role_table("Loyalists", loyal_crew, admins, 0)
if(head_mutineer)
txt += check_role_table("Head Mutineer", list(head_mutineer), admins, 0)
var/list/mutiny_crew = mutineers - head_mutineer
if(mutiny_crew.len)
txt += check_role_table("Mutineers", mutiny_crew, admins, 0)
if(body_count.len)
txt += check_role_table("Casualties", body_count, admins, 0)
return txt
/datum/game_mode/mutiny/announce()
fluff.announce()
/datum/game_mode/mutiny/pre_setup()
var/list/loyalist_candidates = get_head_loyalist_candidates()
if(!loyalist_candidates || loyalist_candidates.len == 0)
world << "Mutiny mode aborted: no valid candidates for head loyalist."
return 0
var/list/mutineer_candidates = get_head_mutineer_candidates()
if(!mutineer_candidates || mutineer_candidates.len == 0)
world << "Mutiny mode aborted: no valid candidates for head mutineer."
return 0
var/list/directive_candidates = get_directive_candidates()
if(!directive_candidates || directive_candidates.len == 0)
world << "Mutiny mode aborted: no valid candidates for Directive X."
return 0
head_loyalist = pick(loyalist_candidates)
head_mutineer = pick(mutineer_candidates)
current_directive = pick(directive_candidates)
return 1
/datum/game_mode/mutiny/post_setup()
head_loyalist.current << "You are the Head Loyalist!"
head_loyalist.special_role = "head_loyalist"
equip_head_loyalist()
head_mutineer.current << "You are the Head Mutineer!"
head_mutineer.special_role = "head_mutineer"
equip_head_mutineer()
loyalists.Add(head_loyalist)
mutineers.Add(head_mutineer)
replace_nuke_with_ead()
current_directive.initialize()
unbolt_vault_door()
update_all_icons()
spawn(0)
reveal_directives()
..()
/datum/game_mode/mutiny/check_antagonists_topic(href, href_list[])
switch(href_list["choice"])
if("activate_captains_key")
ead.captains_key = 1
return 1
if("activate_secondary_key")
ead.secondary_key = 1
return 1
if("activate_ead")
ead.activated = 1
return 1
else
return 0
/mob/living/carbon/human/proc/recruit_loyalist()
set name = "Recruit Loyalist"
set category = "Mutiny"
var/datum/game_mode/mutiny/mode = get_mutiny_mode()
if (!mode || src != mode.head_loyalist.current)
return
var/list/candidates = list()
for (var/mob/living/carbon/human/P in oview(src))
if(!stat && P.client && P.mind && !P.mind.special_role)
candidates += P
if(!candidates.len)
src << "\red You aren't close enough to anybody that can be recruited."
return
var/mob/living/carbon/human/M = input("Select a person to recruit", "Loyalist recruitment", null) as mob in candidates
if (M)
src << "Attempting to recruit [M]..."
log_admin("[src]([src.ckey]) attempted to recruit [M] as a loyalist.")
message_admins("\red [src]([src.ckey]) attempted to recruit [M] as a loyalist.")
var/choice = alert(M, "Asked by [src]: Will you help me complete Directive X?", "Loyalist recruitment", "No", "Yes")
if(choice == "Yes")
mode.add_loyalist(M.mind)
else if(choice == "No")
M << "\red You declined to join the loyalists."
mode.head_loyalist.current << "\red <b>[M] declined to support the loyalists.</b>"
/mob/living/carbon/human/proc/recruit_mutineer()
set name = "Recruit Mutineer"
set category = "Mutiny"
var/datum/game_mode/mutiny/mode = get_mutiny_mode()
if (!mode || src != mode.head_mutineer.current)
return
var/list/candidates = list()
for (var/mob/living/carbon/human/P in oview(src))
if(!stat && P.client && P.mind && !P.mind.special_role)
candidates += P
if(!candidates.len)
src << "\red You aren't close enough to anybody that can be recruited."
return
var/mob/living/carbon/human/M = input("Select a person to recruit", "Mutineer recruitment", null) as mob in candidates
if (M)
src << "Attempting to recruit [M]..."
log_admin("[src]([src.ckey]) attempted to recruit [M] as a mutineer.")
message_admins("\red [src]([src.ckey]) attempted to recruit [M] as a mutineer.")
var/choice = alert(M, "Asked by [src]: Will you help me stop Directive X?", "Mutineer recruitment", "No", "Yes")
if(choice == "Yes")
mode.add_mutineer(M.mind)
else if(choice == "No")
M << "\red You declined to join the mutineers."
mode.head_mutineer.current << "\red <b>[M] declined to support the mutineers.</b>"
/proc/get_mutiny_mode()
if(!ticker || !istype(ticker.mode, /datum/game_mode/mutiny))
return null
return ticker.mode

View File

@@ -0,0 +1,209 @@
/datum/mutiny_fluff
var/datum/game_mode/mutiny/mode
New(datum/game_mode/mutiny/M)
mode = M
proc/centcom_announce(text)
world << {"
<font color='#FFA500'><hr><center><b>:-:=:-: CENTRAL COMMAND ANNOUNCEMENT :-:=:-:</b></center><hr></font>
[text]
"}
world << sound('sound/AI/commandreport.ogg')
proc/announce_incoming_fax()
centcom_announce({"
<b>Incoming Emergency Directive:</b>
<i>Captain's Office Fax Machine, [station_name()]</i>
"})
proc/announce_directives()
for (var/obj/machinery/faxmachine/fax in world)
if (fax.department == "Captain's Office")
var/obj/item/weapon/paper/directive_x = new(fax.loc)
directive_x.name = "emergency action message"
directive_x.info = get_fax_body()
proc/get_fax_body()
return {"
<center><h5>NOT A DRILL . . . EMERGENCY DIRECTIVE . . . NOT A DRILL</h5></center>
<p>
<b>TO:</b> Captain [mode.head_loyalist], Commanding Officer, [station_name()]<br>
<b>FROM:</b> NanoTrasen Emergency Messaging Relay<br>
<b>DATE:</b> [time2text(world.realtime, "MM/DD")]/[game_year]<br>
<b>SUBJECT:</b> Directive X<br>
</p>
[mode.current_directive.get_description()]
<hr>
<h5><b>Emergency Authentication Protocol</b></h5>
<p>
A member of your Command Staff is this shift's designated Emergency Secondary Authenticator.<br>
This Emergency Secondary Authenticator is uniquely aware of their role and possesses the Emergency Secondary Authentication Key.<br>
As Captain, you possess the Captain's Authentication Key.<br>
The Emergency Authentication Device is located in the vault of your station, and requires simultaneous activation of the Authentication Keys.<br>
An <b>Authentication Key Pinpointer</b> can be delivered via Cargo Bay to assist recovery of the Authentication Keys should they be lost aboard the station.<br>
A key's destruction or removal from the station's perimeter will automatically and irreversibly activate the Emergency Authentication Device.
</p>
<br>
<h5><b>Orders</b></h5>
<p>
Captain [mode.head_loyalist], you are to immediately initiate the following procedure; codenamed Directive X:
</p>
<ol>
[get_orders()]
</ol>
<br>
<h5><b>Authentication</b></h5>
<b>Encoded Authentication String:</b> <small>T0JCJUwoIVFDQA==</small><br>
<b>Emergency Action Code:</b> O B B _ L _ _ Q C _<br>
<font color='red'><u>ERROR: DECODING INCOMPLETE (40% LOSS)</u></font>
<br>
<br>
<br>
<center><h5>NOT A DRILL . . . EMERGENCY DIRECTIVE . . . NOT A DRILL</h5></center>
"}
proc/get_orders()
var/text = "<li>Immediate external transmission and signals silence. Evacuation and Cargo services will remain available. All ERT teams are engaged elsewhere. Do not communicate with Central Command under any circumstances.</li>"
for(var/order in mode.current_directive.special_orders)
text += "<li>[order]</li>"
text += "<li>Upon completion of this Directive, Captain [mode.head_loyalist] and the Emergency Secondary Authenticator must utilise the Captain's Authentication Key and the Emergency Secondary Authentication Key to activate the Emergency Authentication Device.</li>"
return text
proc/get_pda_body()
return {"<b>&larr; From Anonymous Channel:</b> <p>\"You must read this! NanoTrasen Chain of Command COMPROMISED. Command Encryptions BROKEN. [station_name()] Captain [mode.head_loyalist] will receive orders that must NOT BE BROUGHT TO FRUITION!
They don't care about us they only care about WEALTH and POWER... Share this message with people you trust.
Be safe, friend.\" (Unable to Reply)</p>"}
proc/announce_ert_unavailable()
// I might have gotten a little carried away.
centcom_announce({"
<p>The presence of [pick(
"political instability",
"quantum fluctuations",
"hostile raiders",
"derelict station debris",
"REDACTED",
"ancient alien artillery",
"solar magnetic storms",
"sentient time-travelling killbots",
"gravitational anomalies",
"wormholes to another dimension",
"a telescience mishap",
"radiation flares",
"supermatter dust",
"leaks into a negative reality",
"antiparticle clouds",
"residual bluespace energy",
"suspected syndicate operatives",
"malfunctioning von Neumann probe swarms",
"shadowy interlopers",
"a stranded Vox arkship",
"haywire IPC constructs",
"rogue Unathi exiles",
"artifacts of eldritch horror",
"a brain slug infestation",
"killer bugs that lay eggs in the husks of the living",
"a deserted transport carrying xenomorph specimens",
"an emissary for the gestalt requesting a security detail",
"a Tajaran slave rebellion",
"radical Skrellian transevolutionaries",
"classified security operations",
"science-defying raw elemental chaos")]
in the region is tying up all available local emergency resources;
<b>emergency response teams</b> can not be called at this time.</p>
"})
proc/announce()
world << "<B>The current game mode is - Mutiny!</B>"
world << {"
<p>The crew will be divided by their sense of ethics when a morally turbulent emergency directive arrives with an incomplete command validation code.<br><br>
The [loyalist_tag("Head Loyalist")] is the Captain, who carries the [loyalist_tag("Captain's Authentication Key")] at all times.<br>
The [mutineer_tag("Head Mutineer")] is a random Head of Staff who carries the [mutineer_tag("Emergency Secondary Authentication Key")].</p>
Both keys are required to activate the <b>Emergency Authentication Device (EAD)</b> in the vault, signalling to NanoTrasen that the directive is complete.
<hr>
<p>
<b>Loyalists</b> - Follow the Head Loyalist in carrying out [loyalist_tag("NanoTrasen's directives")] then activate the <b>EAD</b>.<br>
<b>Mutineers</b> - Prevent the completion of the [mutineer_tag("improperly validated directives")] and the activation of the <b>EAD</b>.
</p>
"}
proc/loyalist_tag(text)
return "<font color='blue'><b>[text]</b></font>"
proc/mutineer_tag(text)
return "<font color='#FFA500'><b>[text]</b></font>"
proc/their(datum/mind/head)
if (head.current.gender == MALE)
return "his"
else if (head.current.gender == FEMALE)
return "her"
return "their"
proc/loyalist_major_victory()
return {"
NanoTrasen has praised the efforts of Captain [mode.head_loyalist] and loyal members of [their(mode.head_loyalist)] crew, who recently managed to put down a mutiny--amid a local interstellar crisis--aboard the <b>[station_name()]</b>, a research station in Tau Ceti.
The mutiny was spurred by a top secret directive sent to the station, presumably in response to the crisis within the system.
Despite the mutiny, the crew was successful in implementing the directive and activating their on-board emergency authentication device.
[mode.mutineers.len] members of the station's personnel were charged with sedition against the company and if found guilty will be sentenced to life incarceration.
NanoTrasen will be awarding [mode.loyalists.len] members of the crew with the [loyalist_tag("Star of Loyalty")], following their successful efforts, at a ceremony this coming Thursday.
[mode.body_count.len] are believed to have died during the coup.
<p>NanoTrasen's image will forever be haunted by the fact that a mutiny took place on one of its own stations.</p>
"}
proc/loyalist_minor_victory()
return {"
NanoTrasen has praised the efforts of Captain [mode.head_loyalist] and loyal members of [their(mode.head_loyalist)] crew, who recently managed to put down a mutiny--amid a local interstellar crisis--aboard the <b>[station_name()]</b>, a research station in Tau Ceti.
The mutiny was spurred by a top secret directive sent to the station, presumably in response to the crisis within the system.
Despite the mutiny, the crew was successful in implementing the directive. Unfortunately, they failed to notify Central Command of their successes due to a breach in the chain of command.
[mode.mutineers.len] members of the station's personnel were charged with sedition against the Company and if found guilty will be sentenced to life incarceration.
NanoTrasen will be awarding [mode.loyalists.len] members of the crew with the [loyalist_tag("Star of Loyalty")], following their mostly successful efforts, at a ceremony this coming Thursday.
[mode.body_count.len] are believed to have died during the coup.
<p>NanoTrasen's image will forever be haunted by the fact that a mutiny took place on one of its own stations.</p>
"}
proc/no_victory()
return {"
NanoTrasen has been thrust into turmoil following an apparent mutiny by key personnel aboard the <b>[station_name()]</b>, a research station in Tau Ceti.
The mutiny was spurred by a top secret directive sent to the station, presumably in response to the crisis within the system.
No further information has yet emerged from the station or its crew, who are presumed to be in holding with NanoTrasen investigators.
NanoTrasen officials refuse to comment.
Sources indicate that [mode.mutineers.len] members of the station's personnel are currently under investigation for mutiny, and [mode.loyalists.len] crew are currently providing evidence to investigators, believed to be the 'loyal' station personnel.
[mode.body_count.len] are believed to have died during the coup.
<p>NanoTrasen's image will forever be haunted by the fact that a mutiny took place on one of its own stations.</p>
"}
proc/mutineer_minor_victory()
return {"
Reports have emerged that an impromptu mutiny has taken place, amid a local interstellar crisis, aboard the <b>[station_name()]</b>, a research station in Tau Ceti.
The mutiny was spurred by a top secret directive sent to the station, presumably in response to the crisis within the system.
Information at present indicates that the top-secret directive--which has since been retracted--was invalid due to a broken authentication code. Members of the crew, including an unidentified Head of Staff, prevented the directive from being accomplished.
[mode.mutineers.len] members of the station's personnel were released from interrogations today, following a mutiny investigation.
NanoTrasen has reprimanded [mode.loyalists.len] members of the crew for failing to follow command validation procedures.
[mode.body_count.len] are believed to have died during the coup.
<p>Even though the directive was not successfully implemented, NanoTrasen's image will forever be haunted by the fact that its authentication protocol was breached with such magnitude and that a mutiny was the result.</p>
"}
proc/mutineer_major_victory()
return {"
NanoTrasen has praised the efforts of [mode.head_mutineer.assigned_role] [mode.head_mutineer] and several other members of the crew, who recently seized control of a research station in Tau Ceti--<b>[station_name()]</b>--amid a local interstellar crisis.
What appears to have been a "legitimate" mutiny was spurred by a top secret directive sent to the station, presumably in response to the crisis within the system.
It has been revealed that the directive was invalid and fraudulent. Company officials have not released a statement about the source of the directive.
Thanks to the efforts of the resistant members of the crew, the directive was not carried out.
[mode.mutineers.len] members of the station's personnel were congratulated and awarded with the [mutineer_tag("Star of Bravery")], for their efforts in preventing the illegal directive's completion.
NanoTrasen has [mode.loyalists.len] members of the crew in holding, while it investigates the circumstances that led to the acceptance and initiation of an invalid directive.
[mode.body_count.len] are believed to have died during the coup.
<p>Even though the directive was not successfully implemented, NanoTrasen's image will forever be haunted by the fact that its authentication protocol was breached with such magnitude and that a mutiny was the result.</p>
"}

View File

@@ -0,0 +1,27 @@
/hook/death/proc/track_kills(mob/living/carbon/human/deceased, gibbed)
var/datum/game_mode/mutiny/mode = get_mutiny_mode()
if (!mode) return 1
mode.body_count.Add(deceased.mind)
return 1
/hook/clone/proc/update_icon(mob/living/carbon/human/H)
var/datum/game_mode/mutiny/mode = get_mutiny_mode()
if (!mode) return 1
mode.update_icon(H.mind)
return 1
/hook/harvest_podman/proc/update_icon(mob/living/carbon/monkey/diona/D)
var/datum/game_mode/mutiny/mode = get_mutiny_mode()
if (!mode) return 1
mode.update_icon(D.mind)
return 1
/hook/roundend/proc/report_mutiny_news()
var/datum/game_mode/mutiny/mode = get_mutiny_mode()
if (!mode) return 1
mode.round_outcome()
return 1

View File

@@ -183,6 +183,7 @@
H << "<span class='notice'><b>Consciousness slowly creeps over you as your body regenerates.</b><br><i>So this is what cloning feels like?</i></span>"
// -- Mode/mind specific stuff goes here
callHook("clone", list(H))
switch(ticker.mode.name)
if("revolution")

View File

@@ -2,247 +2,124 @@
/obj/machinery/computer/card
name = "Identification Computer"
desc = "You can use this to change ID's."
desc = "Terminal for programming NanoTrasen employee ID cards to access parts of the station."
icon_state = "id"
req_access = list(access_change_ids)
circuit = "/obj/item/weapon/circuitboard/card"
var/obj/item/weapon/card/id/scan = null
var/obj/item/weapon/card/id/modify = null
var/authenticated = 0.0
var/mode = 0.0
var/printing = null
proc/is_centcom()
return istype(src, /obj/machinery/computer/card/centcom)
/obj/machinery/computer/card/attackby(O as obj, user as mob)//TODO:SANITY
if(istype(O, /obj/item/weapon/card/id))
var/obj/item/weapon/card/id/idcard = O
if(access_change_ids in idcard.access)
if(!scan)
usr.drop_item()
idcard.loc = src
scan = idcard
else if(!modify)
usr.drop_item()
idcard.loc = src
modify = idcard
else
if(!modify)
usr.drop_item()
idcard.loc = src
modify = idcard
else
..()
proc/is_authenticated()
return scan ? check_access(scan) : 0
proc/get_target_rank()
return modify && modify.assignment ? modify.assignment : "Unassigned"
proc/format_jobs(list/jobs)
var/list/formatted = list()
for(var/job in jobs)
formatted.Add(list(list(
"display_name" = replacetext(job, " ", "&nbsp"),
"target_rank" = get_target_rank(),
"job" = job)))
return formatted
/obj/machinery/computer/card/attackby(obj/item/weapon/card/id/id_card, mob/user)
if(!istype(id_card))
return ..()
if(!scan && access_change_ids in id_card.access)
user.drop_item()
id_card.loc = src
scan = id_card
else if(!modify)
user.drop_item()
id_card.loc = src
modify = id_card
nanomanager.update_uis(src)
attack_hand(user)
/obj/machinery/computer/card/attack_ai(var/mob/user as mob)
return attack_hand(user)
/obj/machinery/computer/card/attack_paw(var/mob/user as mob)
return attack_hand(user)
/obj/machinery/computer/card/attack_hand(mob/user as mob)
if(..()) return
if(stat & (NOPOWER|BROKEN)) return
ui_interact(user)
/obj/machinery/computer/card/attack_hand(var/mob/user as mob)
if(..())
return
/obj/machinery/computer/card/ui_interact(mob/user, ui_key="main", datum/nanoui/ui=null)
user.set_machine(src)
var/dat
if (!( ticker ))
return
if (mode) // accessing crew manifest
dat += "<h4>Crew Manifest</h4>"
dat += "Entries cannot be modified from this terminal.<br><br>"
if(data_core)
dat += data_core.get_manifest(0) // make it monochrome
dat += "<br>"
dat += "<a href='?src=\ref[src];choice=print'>Print</a><br>"
dat += "<br>"
dat += "<a href='?src=\ref[src];choice=mode;mode_target=0'>Access ID modification console.</a><br>"
var/data[0]
data["src"] = "\ref[src]"
data["station_name"] = station_name()
data["mode"] = mode
data["printing"] = printing
data["manifest"] = data_core ? data_core.get_manifest(0) : null
data["target_name"] = modify ? modify.name : "-----"
data["target_owner"] = modify && modify.registered_name ? modify.registered_name : "-----"
data["target_rank"] = get_target_rank()
data["scan_name"] = scan ? scan.name : "-----"
data["authenticated"] = is_authenticated()
data["has_modify"] = !!modify
data["account_number"] = modify ? modify.associated_account_number : null
data["centcom_access"] = is_centcom()
data["all_centcom_access"] = null
data["regions"] = null
/*var/crew = ""
var/list/L = list()
for (var/datum/data/record/t in data_core.general)
var/R = t.fields["name"] + " - " + t.fields["rank"]
L += R
for(var/R in sortList(L))
crew += "[R]<br>"*/
//dat = "<tt><b>Crew Manifest:</b><br>Please use security record computer to modify entries.<br><br>[crew]<a href='?src=\ref[src];choice=print'>Print</a><br><br><a href='?src=\ref[src];choice=mode;mode_target=0'>Access ID modification console.</a><br></tt>"
else
var/header = "<div align='center'><b>Identification Card Modifier</b></div>"
data["engineering_jobs"] = format_jobs(engineering_positions)
data["medical_jobs"] = format_jobs(medical_positions)
data["science_jobs"] = format_jobs(science_positions)
data["security_jobs"] = format_jobs(security_positions)
data["civilian_jobs"] = format_jobs(civilian_positions)
data["centcom_jobs"] = format_jobs(get_all_centcom_jobs())
var/target_name
var/target_owner
var/target_rank
if(modify)
target_name = modify.name
else
target_name = "--------"
if(modify && modify.registered_name)
target_owner = modify.registered_name
else
target_owner = "--------"
if(modify && modify.assignment)
target_rank = modify.assignment
else
target_rank = "Unassigned"
if (modify && is_centcom())
var/list/all_centcom_access = list()
for(var/access in get_all_centcom_access())
all_centcom_access.Add(list(list(
"desc" = replacetext(get_centcom_access_desc(access), " ", "&nbsp"),
"ref" = access,
"allowed" = (access in modify.access) ? 1 : 0)))
var/scan_name
if(scan)
scan_name = scan.name
else
scan_name = "--------"
data["all_centcom_access"] = all_centcom_access
else if (modify)
var/list/regions = list()
for(var/i = 1; i <= 7; i++)
var/list/accesses = list()
for(var/access in get_region_accesses(i))
if (get_access_desc(access))
accesses.Add(list(list(
"desc" = replacetext(get_access_desc(access), " ", "&nbsp"),
"ref" = access,
"allowed" = (access in modify.access) ? 1 : 0)))
if(!authenticated)
header += "<br><i>Please insert the cards into the slots</i><br>"
header += "Target: <a href='?src=\ref[src];choice=modify'>[target_name]</a><br>"
header += "Confirm Identity: <a href='?src=\ref[src];choice=scan'>[scan_name]</a><br>"
else
header += "<div align='center'><br>"
header += "<a href='?src=\ref[src];choice=modify'>Remove [target_name]</a> || "
header += "<a href='?src=\ref[src];choice=scan'>Remove [scan_name]</a> <br> "
header += "<a href='?src=\ref[src];choice=mode;mode_target=1'>Access Crew Manifest</a> || "
header += "<a href='?src=\ref[src];choice=logout'>Log Out</a></div>"
regions.Add(list(list(
"name" = get_region_accesses_name(i),
"accesses" = accesses)))
header += "<hr>"
var/jobs_all = ""
var/counter = 0
jobs_all += "<table><tr><td></td><td><b>Command</b></td>"
jobs_all += "</tr><tr height='20'><td><b>Special</b></font></td>"//Captain in special because he is head of heads ~Intercross21
jobs_all += "<td weight='100'><a href='?src=\ref[src];choice=assign;assign_target=Captain'>Captain</a></td>"
jobs_all += "<td weight='100'><a href='?src=\ref[src];choice=assign;assign_target=Custom'>Custom</a></td>"
counter = 0
jobs_all += "</tr><tr><td><font color='#FFA500'><b>Engineering</b></font></td>"//Orange
for(var/job in engineering_positions)
counter++
if(counter >= 6)
jobs_all += "</tr><tr height='20'><td></td><td></td>"
counter = 0
jobs_all += "<td height='20' weight='100'><a href='?src=\ref[src];choice=assign;assign_target=[job]'>[replacetext(job, " ", "&nbsp")]</a></td>"
counter = 0
jobs_all += "</tr><tr height='20'><td><font color='#008000'><b>Medical</b></font></td>"//Green
for(var/job in medical_positions)
counter++
if(counter >= 6)
jobs_all += "</tr><tr height='20'><td></td><td></td>"
counter = 0
jobs_all += "<td weight='100'><a href='?src=\ref[src];choice=assign;assign_target=[job]'>[replacetext(job, " ", "&nbsp")]</a></td>"
counter = 0
jobs_all += "</tr><tr height='20'><td><font color='#800080'><b>Science</b></font></td>"//Purple
for(var/job in science_positions)
counter++
if(counter >= 6)
jobs_all += "</tr><tr height='20'><td></td><td></td>"
counter = 0
jobs_all += "<td weight='100'><a href='?src=\ref[src];choice=assign;assign_target=[job]'>[replacetext(job, " ", "&nbsp")]</a></td>"
counter = 0
jobs_all += "</tr><tr height='20'><td><font color='#808080'><b>Civilian</b></font></td>"//Grey
for(var/job in civilian_positions)
counter++
if(counter >= 6)
jobs_all += "</tr><tr height='20'><td></td><td></td>"
counter = 0
jobs_all += "<td weight='100'><a href='?src=\ref[src];choice=assign;assign_target=[job]'>[replacetext(job, " ", "&nbsp")]</a></td>"
if(istype(src,/obj/machinery/computer/card/centcom))
counter = 0
jobs_all += "</tr><tr><td><font color='#A52A2A'><b>CentComm</b></font></td>"//Brown
for(var/job in get_all_centcom_jobs())
if(counter >= 6)
jobs_all += "</tr><tr><td></td><td></td>"
counter = 0
jobs_all += "<td><a href='?src=\ref[src];choice=assign;assign_target=[job]'>[replacetext(job, " ", "&nbsp")]</a></td>"
var/body
if (authenticated && modify)
var/carddesc = {"<script type="text/javascript">
function markRed(){
var nameField = document.getElementById('namefield');
nameField.style.backgroundColor = "#FFDDDD";
}
function markGreen(){
var nameField = document.getElementById('namefield');
nameField.style.backgroundColor = "#DDFFDD";
}
function markAccountGreen(){
var nameField = document.getElementById('accountfield');
nameField.style.backgroundColor = "#DDFFDD";
}
function markAccountRed(){
var nameField = document.getElementById('accountfield');
nameField.style.backgroundColor = "#FFDDDD";
}
function showAll(){
var allJobsSlot = document.getElementById('alljobsslot');
allJobsSlot.innerHTML = "<a href='#' onclick='hideAll()'>hide</a><br>"+ "[jobs_all]";
}
function hideAll(){
var allJobsSlot = document.getElementById('alljobsslot');
allJobsSlot.innerHTML = "<a href='#' onclick='showAll()'>[(modify.assignment) ? modify.assignment : "Unassgied"]</a>";
}
</script>"}
carddesc += "<form name='cardcomp' action='?src=\ref[src]' method='get'>"
carddesc += "<input type='hidden' name='src' value='\ref[src]'>"
carddesc += "<input type='hidden' name='choice' value='reg'>"
carddesc += "<b>registered_name:</b> <input type='text' id='namefield' name='reg' value='[target_owner]' style='width:250px; background-color:white;' onchange='markRed()'>"
carddesc += "<input type='submit' value='Rename' onclick='markGreen()'>"
carddesc += "</form>"
carddesc += "<form name='accountnum' action='?src=\ref[src]' method='get'>"
carddesc += "<input type='hidden' name='src' value='\ref[src]'>"
carddesc += "<input type='hidden' name='choice' value='account'>"
carddesc += "<b>Stored account number:</b> <input type='text' id='accountfield' name='account' value='[modify.associated_account_number]' style='width:250px; background-color:white;' onchange='markAccountRed()'>"
carddesc += "<input type='submit' value='Modify' onclick='markAccountGreen()'>"
carddesc += "</form>"
carddesc += "<b>Assignment:</b> "
var/jobs = "<span id='alljobsslot'><a href='#' onclick='showAll()'>[target_rank]</a></span>" //CHECK THIS
var/accesses = ""
if(istype(src,/obj/machinery/computer/card/centcom))
accesses += "<h5>Central Command:</h5>"
for(var/A in get_all_centcom_access())
if(A in modify.access)
accesses += "<a href='?src=\ref[src];choice=access;access_target=[A];allowed=0'><font color=\"red\">[replacetext(get_centcom_access_desc(A), " ", "&nbsp")]</font></a> "
else
accesses += "<a href='?src=\ref[src];choice=access;access_target=[A];allowed=1'>[replacetext(get_centcom_access_desc(A), " ", "&nbsp")]</a> "
else
accesses += "<div align='center'><b>Access</b></div>"
accesses += "<table style='width:100%'>"
accesses += "<tr>"
for(var/i = 1; i <= 7; i++)
accesses += "<td style='width:14%'><b>[get_region_accesses_name(i)]:</b></td>"
accesses += "</tr><tr>"
for(var/i = 1; i <= 7; i++)
accesses += "<td style='width:14%' valign='top'>"
for(var/A in get_region_accesses(i))
if(A in modify.access)
accesses += "<a href='?src=\ref[src];choice=access;access_target=[A];allowed=0'><font color=\"red\">[replacetext(get_access_desc(A), " ", "&nbsp")]</font></a> "
else
accesses += "<a href='?src=\ref[src];choice=access;access_target=[A];allowed=1'>[replacetext(get_access_desc(A), " ", "&nbsp")]</a> "
accesses += "<br>"
accesses += "</td>"
accesses += "</tr></table>"
body = "[carddesc]<br>[jobs]<br><br>[accesses]" //CHECK THIS
else
body = "<a href='?src=\ref[src];choice=auth'>{Log in}</a> <br><hr>"
body += "<a href='?src=\ref[src];choice=mode;mode_target=1'>Access Crew Manifest</a>"
dat = "<tt>[header][body]<hr><br></tt>"
user << browse(dat, "window=id_com;size=900x520")
onclose(user, "id_com")
return
data["regions"] = regions
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
if (!ui)
ui = new(user, src, ui_key, "identification_computer.tmpl", src.name, 600, 700)
ui.set_initial_data(data)
ui.open()
/obj/machinery/computer/card/Topic(href, href_list)
if(..())
return
usr.set_machine(src)
return 1
switch(href_list["choice"])
if ("modify")
if (modify)
@@ -262,7 +139,6 @@
usr.drop_item()
I.loc = src
modify = I
authenticated = 0
if ("scan")
if (scan)
@@ -280,26 +156,19 @@
usr.drop_item()
I.loc = src
scan = I
authenticated = 0
if ("auth")
if ((!( authenticated ) && (scan || (istype(usr, /mob/living/silicon))) && (modify || mode)))
if (check_access(scan))
authenticated = 1
else if ((!( authenticated ) && (istype(usr, /mob/living/silicon))) && (!modify))
usr << "You can't modify an ID without an ID inserted to modify. Once one is in the modify slot on the computer, you can log in."
if ("logout")
authenticated = 0
if("access")
if(href_list["allowed"])
if(authenticated)
if(is_authenticated())
var/access_type = text2num(href_list["access_target"])
var/access_allowed = text2num(href_list["allowed"])
if(access_type in (istype(src,/obj/machinery/computer/card/centcom)?get_all_centcom_access() : get_all_accesses()))
if(access_type in (is_centcom() ? get_all_centcom_access() : get_all_accesses()))
modify.access -= access_type
if(access_allowed == 1)
if(!access_allowed)
modify.access += access_type
if ("assign")
if (authenticated)
if (is_authenticated() && modify)
var/t1 = href_list["assign_target"]
if(t1 == "Custom")
var/temp_t = copytext(sanitize(input("Enter a custom job assignment.","Assignment")),1,45)
@@ -307,69 +176,91 @@
if(temp_t && modify)
modify.assignment = temp_t
else
var/datum/job/jobdatum
for(var/jobtype in typesof(/datum/job))
var/datum/job/J = new jobtype
if(ckey(J.title) == ckey(t1))
jobdatum = J
break
if(!jobdatum)
usr << "\red No log exists for this job."
return
var/list/access = list()
if(is_centcom())
access = get_centcom_access(t1)
else
var/datum/job/jobdatum
for(var/jobtype in typesof(/datum/job))
var/datum/job/J = new jobtype
if(ckey(J.title) == ckey(t1))
jobdatum = J
break
if(!jobdatum)
usr << "\red No log exists for this job: [t1]"
return
access = jobdatum.get_access()
modify.access = access
modify.assignment = t1
modify.rank = t1
callHook("reassign_employee", list(modify))
modify.access = ( istype(src,/obj/machinery/computer/card/centcom) ? get_centcom_access(t1) : jobdatum.get_access() )
if (modify)
modify.assignment = t1
modify.rank = t1
if ("reg")
if (authenticated)
if (is_authenticated())
var/t2 = modify
//var/t1 = input(usr, "What name?", "ID computer", null) as text
if ((authenticated && modify == t2 && (in_range(src, usr) || (istype(usr, /mob/living/silicon))) && istype(loc, /turf)))
if ((modify == t2 && (in_range(src, usr) || (istype(usr, /mob/living/silicon))) && istype(loc, /turf)))
var/temp_name = reject_bad_name(href_list["reg"])
if(temp_name)
modify.registered_name = temp_name
else
src.visible_message("<span class='notice'>[src] buzzes rudely.</span>")
nanomanager.update_uis(src)
if ("account")
if (authenticated)
if (is_authenticated())
var/t2 = modify
//var/t1 = input(usr, "What name?", "ID computer", null) as text
if ((authenticated && modify == t2 && (in_range(src, usr) || (istype(usr, /mob/living/silicon))) && istype(loc, /turf)))
if ((modify == t2 && (in_range(src, usr) || (istype(usr, /mob/living/silicon))) && istype(loc, /turf)))
var/account_num = text2num(href_list["account"])
modify.associated_account_number = account_num
nanomanager.update_uis(src)
if ("mode")
mode = text2num(href_list["mode_target"])
if ("print")
if (!( printing ))
if (!printing)
printing = 1
sleep(50)
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( loc )
/*var/t1 = "<B>Crew Manifest:</B><BR>"
var/list/L = list()
for (var/datum/data/record/t in data_core.general)
var/R = t.fields["name"] + " - " + t.fields["rank"]
L += R
for(var/R in sortList(L))
t1 += "[R]<br>"*/
spawn(50)
printing = null
nanomanager.update_uis(src)
var/t1 = "<h4>Crew Manifest</h4>"
t1 += "<br>"
if(data_core)
t1 += data_core.get_manifest(0) // make it monochrome
var/obj/item/weapon/paper/P = new(loc)
if (mode)
P.name = text("crew manifest ([])", worldtime2text())
P.info = {"<h4>Crew Manifest</h4>
<br>
[data_core ? data_core.get_manifest(0) : ""]
"}
else if (modify)
P.name = "access report"
P.info = {"<h4>Access Report</h4>
<u>Prepared By:</u> [scan.registered_name ? scan.registered_name : "Unknown"]<br>
<u>For:</u> [modify.registered_name ? modify.registered_name : "Unregistered"]<br>
<hr>
<u>Assignment:</u> [modify.assignment]<br>
<u>Account Number:</u> #[modify.associated_account_number]<br>
<u>Blood Type:</u> [modify.blood_type]<br><br>
<u>Access:</u><br>
"}
for(var/A in modify.access)
P.info += " [get_access_desc(A)]"
if ("terminate")
modify.assignment = "Terminated"
modify.access = list()
callHook("terminate_employee", list(modify))
P.info = t1
P.name = text("Crew Manifest ([])", worldtime2text())
printing = null
if (modify)
modify.name = text("[modify.registered_name]'s ID Card ([modify.assignment])")
updateUsrDialog()
return
return 1
/obj/machinery/computer/card/centcom
name = "CentCom Identification Computer"
circuit = "/obj/item/weapon/circuitboard/card/centcom"
req_access = list(access_cent_captain)

View File

@@ -129,6 +129,8 @@ Growing it to term with nothing injected will grab a ghost from the observers. *
podman.dna.real_name = podman.real_name
// Update mode specific HUD icons.
callHook("harvest_podman", list(podman))
switch(ticker.mode.name)
if ("revolution")
if (podman.mind in ticker.mode:revolutionaries)

View File

@@ -476,6 +476,12 @@
/obj/item/proc/IsShield()
return 0
/obj/item/proc/get_turf()
var/atom/L = loc
while(L && !istype(L, /turf/))
L = L.loc
return loc
/obj/item/proc/eyestab(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
var/mob/living/carbon/human/H = M

View File

@@ -166,7 +166,7 @@
var/obj/item/device/mmi/M = W
if(check_completion())
if(!istype(loc,/turf))
user << "\red You can't put the [W] in, the frame has to be standing on the ground to be perfectly precise."
user << "\red You can't put \the [W] in, the frame has to be standing on the ground to be perfectly precise."
return
if(!M.brainmob)
user << "\red Sticking an empty [W] into the frame would sort of defeat the purpose."
@@ -179,7 +179,7 @@
ghost_can_reenter = 1
break
if(!ghost_can_reenter)
user << "<span class='notice'>The [W] is completely unresponsive; there's no point.</span>"
user << "<span class='notice'>\The [W] is completely unresponsive; there's no point.</span>"
return
if(M.brainmob.stat == DEAD)
@@ -222,6 +222,7 @@
cell_component.installed = 1
feedback_inc("cyborg_birth",1)
callHook("borgify", list(O))
O.Namepick()
del(src)

View File

@@ -241,6 +241,8 @@ var/list/mechtoys = list(
// Must be in a crate!
if(istype(MA,/obj/structure/closet/crate))
callHook("sell_crate", list(MA, shuttle))
points += points_per_crate
var/find_slip = 1

View File

@@ -1,527 +1,506 @@
/datum/admins/proc/player_panel_new()//The new one
if (!usr.client.holder)
return
var/dat = "<html><head><title>Admin Player Panel</title></head>"
if (!usr.client.holder)
return
var/dat = "<html><head><title>Admin Player Panel</title></head>"
//javascript, the part that does most of the work~
dat += {"
//javascript, the part that does most of the work~
dat += {"
<head>
<script type='text/javascript'>
<head>
<script type='text/javascript'>
var locked_tabs = new Array();
var locked_tabs = new Array();
function updateSearch(){
function updateSearch(){
var filter_text = document.getElementById('filter');
var filter = filter_text.value.toLowerCase();
var filter_text = document.getElementById('filter');
var filter = filter_text.value.toLowerCase();
if(complete_list != null && complete_list != ""){
var mtbl = document.getElementById("maintable_data_archive");
mtbl.innerHTML = complete_list;
}
if(complete_list != null && complete_list != ""){
var mtbl = document.getElementById("maintable_data_archive");
mtbl.innerHTML = complete_list;
}
if(filter.value == ""){
return;
}else{
if(filter.value == ""){
return;
}else{
var maintable_data = document.getElementById('maintable_data');
var ltr = maintable_data.getElementsByTagName("tr");
for ( var i = 0; i < ltr.length; ++i )
{
try{
var tr = ltr\[i\];
if(tr.getAttribute("id").indexOf("data") != 0){
continue;
}
var ltd = tr.getElementsByTagName("td");
var td = ltd\[0\];
var lsearch = td.getElementsByTagName("b");
var search = lsearch\[0\];
//var inner_span = li.getElementsByTagName("span")\[1\] //Should only ever contain one element.
//document.write("<p>"+search.innerText+"<br>"+filter+"<br>"+search.innerText.indexOf(filter))
if ( search.innerText.toLowerCase().indexOf(filter) == -1 )
{
//document.write("a");
//ltr.removeChild(tr);
td.innerHTML = "";
i--;
}
}catch(err) { }
}
}
var count = 0;
var index = -1;
var debug = document.getElementById("debug");
locked_tabs = new Array();
}
function expand(id,job,name,real_name,image,key,ip,antagonist,ref){
clearAll();
var span = document.getElementById(id);
body = "<table><tr><td>";
body += "</td><td align='center'>";
body += "<font size='2'><b>"+job+" "+name+"</b><br><b>Real name "+real_name+"</b><br><b>Played by "+key+" ("+ip+")</b></font>"
body += "</td><td align='center'>";
body += "<a href='?src=\ref[src];adminplayeropts="+ref+"'>PP</a> - "
body += "<a href='?src=\ref[src];notes=show;mob="+ref+"'>N</a> - "
body += "<a href='?_src_=vars;Vars="+ref+"'>VV</a> - "
body += "<a href='?src=\ref[src];traitor="+ref+"'>TP</a> - "
body += "<a href='?src=\ref[usr];priv_msg=\ref"+ref+"'>PM</a> - "
body += "<a href='?src=\ref[src];subtlemessage="+ref+"'>SM</a> - "
body += "<a href='?src=\ref[src];adminplayerobservejump="+ref+"'>JMP</a><br>"
if(antagonist > 0)
body += "<font size='2'><a href='?src=\ref[src];check_antagonist=1'><font color='red'><b>Antagonist</b></font></a></font>";
body += "</td></tr></table>";
span.innerHTML = body
}
function clearAll(){
var spans = document.getElementsByTagName('span');
for(var i = 0; i < spans.length; i++){
var span = spans\[i\];
var id = span.getAttribute("id");
if(!(id.indexOf("item")==0))
continue;
var pass = 1;
for(var j = 0; j < locked_tabs.length; j++){
if(locked_tabs\[j\]==id){
pass = 0;
break;
}
}
if(pass != 1)
continue;
span.innerHTML = "";
}
}
function addToLocked(id,link_id,notice_span_id){
var link = document.getElementById(link_id);
var decision = link.getAttribute("name");
if(decision == "1"){
link.setAttribute("name","2");
}else{
link.setAttribute("name","1");
removeFromLocked(id,link_id,notice_span_id);
return;
}
var pass = 1;
for(var j = 0; j < locked_tabs.length; j++){
if(locked_tabs\[j\]==id){
pass = 0;
break;
}
}
if(!pass)
return;
locked_tabs.push(id);
var notice_span = document.getElementById(notice_span_id);
notice_span.innerHTML = "<font color='red'>Locked</font> ";
//link.setAttribute("onClick","attempt('"+id+"','"+link_id+"','"+notice_span_id+"');");
//document.write("removeFromLocked('"+id+"','"+link_id+"','"+notice_span_id+"')");
//document.write("aa - "+link.getAttribute("onClick"));
}
function attempt(ab){
return ab;
}
function removeFromLocked(id,link_id,notice_span_id){
//document.write("a");
var index = 0;
var pass = 0;
for(var j = 0; j < locked_tabs.length; j++){
if(locked_tabs\[j\]==id){
pass = 1;
index = j;
break;
}
}
if(!pass)
return;
locked_tabs\[index\] = "";
var notice_span = document.getElementById(notice_span_id);
notice_span.innerHTML = "";
//var link = document.getElementById(link_id);
//link.setAttribute("onClick","addToLocked('"+id+"','"+link_id+"','"+notice_span_id+"')");
}
function selectTextField(){
var filter_text = document.getElementById('filter');
filter_text.focus();
filter_text.select();
}
</script>
</head>
"}
//body tag start + onload and onkeypress (onkeyup) javascript event calls
dat += "<body onload='selectTextField(); updateSearch();' onkeyup='updateSearch();'>"
//title + search bar
dat += {"
<table width='560' align='center' cellspacing='0' cellpadding='5' id='maintable'>
<tr id='title_tr'>
<td align='center'>
<font size='5'><b>Player panel</b></font><br>
Hover over a line to see more information - <a href='?src=\ref[src];check_antagonist=1'>Check antagonists</a>
<p>
</td>
</tr>
<tr id='search_tr'>
<td align='center'>
<b>Search:</b> <input type='text' id='filter' value='' style='width:300px;'>
</td>
</tr>
</table>
"}
//player table header
dat += {"
<span id='maintable_data_archive'>
<table width='560' align='center' cellspacing='0' cellpadding='5' id='maintable_data'>"}
var/list/mobs = sortmobs()
var/i = 1
for(var/mob/M in mobs)
if(M.ckey)
var/color = "#e6e6e6"
if(i%2 == 0)
color = "#f2f2f2"
var/is_antagonist = is_special_character(M)
var/M_job = ""
if(isliving(M))
if(iscarbon(M)) //Carbon stuff
if(ishuman(M))
M_job = M.job
else if(isslime(M))
M_job = "slime"
else if(ismonkey(M))
M_job = "Monkey"
else if(isalien(M)) //aliens
if(islarva(M))
M_job = "Alien larva"
else
M_job = "Alien"
else
M_job = "Carbon-based"
else if(issilicon(M)) //silicon
if(isAI(M))
M_job = "AI"
else if(ispAI(M))
M_job = "pAI"
else if(isrobot(M))
M_job = "Cyborg"
else
M_job = "Silicon-based"
else if(isanimal(M)) //simple animals
if(iscorgi(M))
M_job = "Corgi"
else
M_job = "Animal"
else
M_job = "Living"
else if(istype(M,/mob/new_player))
M_job = "New player"
else if(isobserver(M))
M_job = "Ghost"
M_job = replacetext(M_job, "'", "")
M_job = replacetext(M_job, "\"", "")
M_job = replacetext(M_job, "\\", "")
var/M_name = M.name
M_name = replacetext(M_name, "'", "")
M_name = replacetext(M_name, "\"", "")
M_name = replacetext(M_name, "\\", "")
var/M_rname = M.real_name
M_rname = replacetext(M_rname, "'", "")
M_rname = replacetext(M_rname, "\"", "")
M_rname = replacetext(M_rname, "\\", "")
var/M_key = M.key
M_key = replacetext(M_key, "'", "")
M_key = replacetext(M_key, "\"", "")
M_key = replacetext(M_key, "\\", "")
//output for each mob
dat += {"
<tr id='data[i]' name='[i]' onClick="addToLocked('item[i]','data[i]','notice_span[i]')">
<td align='center' bgcolor='[color]'>
<span id='notice_span[i]'></span>
<a id='link[i]'
onmouseover='expand("item[i]","[M_job]","[M_name]","[M_rname]","--unused--","[M_key]","[M.lastKnownIP]",[is_antagonist],"\ref[M]")'
>
<b id='search[i]'>[M_name] - [M_rname] - [M_key] ([M_job])</b>
</a>
<br><span id='item[i]'></span>
</td>
</tr>
"}
i++
//player table ending
dat += {"
</table>
</span>
<script type='text/javascript'>
var maintable = document.getElementById("maintable_data_archive");
var complete_list = maintable.innerHTML;
</script>
</body></html>
"}
usr << browse(dat, "window=players;size=600x480")
var maintable_data = document.getElementById('maintable_data');
var ltr = maintable_data.getElementsByTagName("tr");
for ( var i = 0; i < ltr.length; ++i )
{
try{
var tr = ltr\[i\];
if(tr.getAttribute("id").indexOf("data") != 0){
continue;
}
var ltd = tr.getElementsByTagName("td");
var td = ltd\[0\];
var lsearch = td.getElementsByTagName("b");
var search = lsearch\[0\];
//var inner_span = li.getElementsByTagName("span")\[1\] //Should only ever contain one element.
//document.write("<p>"+search.innerText+"<br>"+filter+"<br>"+search.innerText.indexOf(filter))
if ( search.innerText.toLowerCase().indexOf(filter) == -1 )
{
//document.write("a");
//ltr.removeChild(tr);
td.innerHTML = "";
i--;
}
}catch(err) { }
}
}
var count = 0;
var index = -1;
var debug = document.getElementById("debug");
locked_tabs = new Array();
}
function expand(id,job,name,real_name,image,key,ip,antagonist,ref){
clearAll();
var span = document.getElementById(id);
body = "<table><tr><td>";
body += "</td><td align='center'>";
body += "<font size='2'><b>"+job+" "+name+"</b><br><b>Real name "+real_name+"</b><br><b>Played by "+key+" ("+ip+")</b></font>"
body += "</td><td align='center'>";
body += "<a href='?src=\ref[src];adminplayeropts="+ref+"'>PP</a> - "
body += "<a href='?src=\ref[src];notes=show;mob="+ref+"'>N</a> - "
body += "<a href='?_src_=vars;Vars="+ref+"'>VV</a> - "
body += "<a href='?src=\ref[src];traitor="+ref+"'>TP</a> - "
body += "<a href='?src=\ref[usr];priv_msg=\ref"+ref+"'>PM</a> - "
body += "<a href='?src=\ref[src];subtlemessage="+ref+"'>SM</a> - "
body += "<a href='?src=\ref[src];adminplayerobservejump="+ref+"'>JMP</a><br>"
if(antagonist > 0)
body += "<font size='2'><a href='?src=\ref[src];check_antagonist=1'><font color='red'><b>Antagonist</b></font></a></font>";
body += "</td></tr></table>";
span.innerHTML = body
}
function clearAll(){
var spans = document.getElementsByTagName('span');
for(var i = 0; i < spans.length; i++){
var span = spans\[i\];
var id = span.getAttribute("id");
if(!(id.indexOf("item")==0))
continue;
var pass = 1;
for(var j = 0; j < locked_tabs.length; j++){
if(locked_tabs\[j\]==id){
pass = 0;
break;
}
}
if(pass != 1)
continue;
span.innerHTML = "";
}
}
function addToLocked(id,link_id,notice_span_id){
var link = document.getElementById(link_id);
var decision = link.getAttribute("name");
if(decision == "1"){
link.setAttribute("name","2");
}else{
link.setAttribute("name","1");
removeFromLocked(id,link_id,notice_span_id);
return;
}
var pass = 1;
for(var j = 0; j < locked_tabs.length; j++){
if(locked_tabs\[j\]==id){
pass = 0;
break;
}
}
if(!pass)
return;
locked_tabs.push(id);
var notice_span = document.getElementById(notice_span_id);
notice_span.innerHTML = "<font color='red'>Locked</font> ";
//link.setAttribute("onClick","attempt('"+id+"','"+link_id+"','"+notice_span_id+"');");
//document.write("removeFromLocked('"+id+"','"+link_id+"','"+notice_span_id+"')");
//document.write("aa - "+link.getAttribute("onClick"));
}
function attempt(ab){
return ab;
}
function removeFromLocked(id,link_id,notice_span_id){
//document.write("a");
var index = 0;
var pass = 0;
for(var j = 0; j < locked_tabs.length; j++){
if(locked_tabs\[j\]==id){
pass = 1;
index = j;
break;
}
}
if(!pass)
return;
locked_tabs\[index\] = "";
var notice_span = document.getElementById(notice_span_id);
notice_span.innerHTML = "";
//var link = document.getElementById(link_id);
//link.setAttribute("onClick","addToLocked('"+id+"','"+link_id+"','"+notice_span_id+"')");
}
function selectTextField(){
var filter_text = document.getElementById('filter');
filter_text.focus();
filter_text.select();
}
</script>
</head>
"}
//body tag start + onload and onkeypress (onkeyup) javascript event calls
dat += "<body onload='selectTextField(); updateSearch();' onkeyup='updateSearch();'>"
//title + search bar
dat += {"
<table width='560' align='center' cellspacing='0' cellpadding='5' id='maintable'>
<tr id='title_tr'>
<td align='center'>
<font size='5'><b>Player panel</b></font><br>
Hover over a line to see more information - <a href='?src=\ref[src];check_antagonist=1'>Check antagonists</a>
<p>
</td>
</tr>
<tr id='search_tr'>
<td align='center'>
<b>Search:</b> <input type='text' id='filter' value='' style='width:300px;'>
</td>
</tr>
</table>
"}
//player table header
dat += {"
<span id='maintable_data_archive'>
<table width='560' align='center' cellspacing='0' cellpadding='5' id='maintable_data'>"}
var/list/mobs = sortmobs()
var/i = 1
for(var/mob/M in mobs)
if(M.ckey)
var/color = "#e6e6e6"
if(i%2 == 0)
color = "#f2f2f2"
var/is_antagonist = is_special_character(M)
var/M_job = ""
if(isliving(M))
if(iscarbon(M)) //Carbon stuff
if(ishuman(M))
M_job = M.job
else if(isslime(M))
M_job = "slime"
else if(ismonkey(M))
M_job = "Monkey"
else if(isalien(M)) //aliens
if(islarva(M))
M_job = "Alien larva"
else
M_job = "Alien"
else
M_job = "Carbon-based"
else if(issilicon(M)) //silicon
if(isAI(M))
M_job = "AI"
else if(ispAI(M))
M_job = "pAI"
else if(isrobot(M))
M_job = "Cyborg"
else
M_job = "Silicon-based"
else if(isanimal(M)) //simple animals
if(iscorgi(M))
M_job = "Corgi"
else
M_job = "Animal"
else
M_job = "Living"
else if(istype(M,/mob/new_player))
M_job = "New player"
else if(isobserver(M))
M_job = "Ghost"
M_job = replacetext(M_job, "'", "")
M_job = replacetext(M_job, "\"", "")
M_job = replacetext(M_job, "\\", "")
var/M_name = M.name
M_name = replacetext(M_name, "'", "")
M_name = replacetext(M_name, "\"", "")
M_name = replacetext(M_name, "\\", "")
var/M_rname = M.real_name
M_rname = replacetext(M_rname, "'", "")
M_rname = replacetext(M_rname, "\"", "")
M_rname = replacetext(M_rname, "\\", "")
var/M_key = M.key
M_key = replacetext(M_key, "'", "")
M_key = replacetext(M_key, "\"", "")
M_key = replacetext(M_key, "\\", "")
//output for each mob
dat += {"
<tr id='data[i]' name='[i]' onClick="addToLocked('item[i]','data[i]','notice_span[i]')">
<td align='center' bgcolor='[color]'>
<span id='notice_span[i]'></span>
<a id='link[i]'
onmouseover='expand("item[i]","[M_job]","[M_name]","[M_rname]","--unused--","[M_key]","[M.lastKnownIP]",[is_antagonist],"\ref[M]")'
>
<b id='search[i]'>[M_name] - [M_rname] - [M_key] ([M_job])</b>
</a>
<br><span id='item[i]'></span>
</td>
</tr>
"}
i++
//player table ending
dat += {"
</table>
</span>
<script type='text/javascript'>
var maintable = document.getElementById("maintable_data_archive");
var complete_list = maintable.innerHTML;
</script>
</body></html>
"}
usr << browse(dat, "window=players;size=600x480")
//The old one
/datum/admins/proc/player_panel_old()
if (!usr.client.holder)
return
var/dat = "<html><head><title>Player Menu</title></head>"
dat += "<body><table border=1 cellspacing=5><B><tr><th>Name</th><th>Real Name</th><th>Assigned Job</th><th>Key</th><th>Options</th><th>PM</th><th>Traitor?</th></tr></B>"
//add <th>IP:</th> to this if wanting to add back in IP checking
//add <td>(IP: [M.lastKnownIP])</td> if you want to know their ip to the lists below
var/list/mobs = sortmobs()
if (!usr.client.holder)
return
var/dat = "<html><head><title>Player Menu</title></head>"
dat += "<body><table border=1 cellspacing=5><B><tr><th>Name</th><th>Real Name</th><th>Assigned Job</th><th>Key</th><th>Options</th><th>PM</th><th>Traitor?</th></tr></B>"
//add <th>IP:</th> to this if wanting to add back in IP checking
//add <td>(IP: [M.lastKnownIP])</td> if you want to know their ip to the lists below
var/list/mobs = sortmobs()
for(var/mob/M in mobs)
if(!M.ckey) continue
for(var/mob/M in mobs)
if(!M.ckey) continue
dat += "<tr><td>[M.name]</td>"
if(isAI(M))
dat += "<td>AI</td>"
else if(isrobot(M))
dat += "<td>Cyborg</td>"
else if(ishuman(M))
dat += "<td>[M.real_name]</td>"
else if(istype(M, /mob/living/silicon/pai))
dat += "<td>pAI</td>"
else if(istype(M, /mob/new_player))
dat += "<td>New Player</td>"
else if(isobserver(M))
dat += "<td>Ghost</td>"
else if(ismonkey(M))
dat += "<td>Monkey</td>"
else if(isalien(M))
dat += "<td>Alien</td>"
else
dat += "<td>Unknown</td>"
dat += "<tr><td>[M.name]</td>"
if(isAI(M))
dat += "<td>AI</td>"
else if(isrobot(M))
dat += "<td>Cyborg</td>"
else if(ishuman(M))
dat += "<td>[M.real_name]</td>"
else if(istype(M, /mob/living/silicon/pai))
dat += "<td>pAI</td>"
else if(istype(M, /mob/new_player))
dat += "<td>New Player</td>"
else if(isobserver(M))
dat += "<td>Ghost</td>"
else if(ismonkey(M))
dat += "<td>Monkey</td>"
else if(isalien(M))
dat += "<td>Alien</td>"
else
dat += "<td>Unknown</td>"
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.mind && H.mind.assigned_role)
dat += "<td>[H.mind.assigned_role]</td>"
else
dat += "<td>NA</td>"
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.mind && H.mind.assigned_role)
dat += "<td>[H.mind.assigned_role]</td>"
else
dat += "<td>NA</td>"
dat += {"<td>[(M.client ? "[M.client]" : "No client")]</td>
<td align=center><A HREF='?src=\ref[src];adminplayeropts=\ref[M]'>X</A></td>
<td align=center><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td>
"}
switch(is_special_character(M))
if(0)
dat += {"<td align=center><A HREF='?src=\ref[src];traitor=\ref[M]'>Traitor?</A></td>"}
if(1)
dat += {"<td align=center><A HREF='?src=\ref[src];traitor=\ref[M]'><font color=red>Traitor?</font></A></td>"}
if(2)
dat += {"<td align=center><A HREF='?src=\ref[src];traitor=\ref[M]'><font color=red><b>Traitor?</b></font></A></td>"}
dat += {"<td>[(M.client ? "[M.client]" : "No client")]</td>
<td align=center><A HREF='?src=\ref[src];adminplayeropts=\ref[M]'>X</A></td>
<td align=center><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td>
"}
switch(is_special_character(M))
if(0)
dat += {"<td align=center><A HREF='?src=\ref[src];traitor=\ref[M]'>Traitor?</A></td>"}
if(1)
dat += {"<td align=center><A HREF='?src=\ref[src];traitor=\ref[M]'><font color=red>Traitor?</font></A></td>"}
if(2)
dat += {"<td align=center><A HREF='?src=\ref[src];traitor=\ref[M]'><font color=red><b>Traitor?</b></font></A></td>"}
dat += "</table></body></html>"
dat += "</table></body></html>"
usr << browse(dat, "window=players;size=640x480")
usr << browse(dat, "window=players;size=640x480")
/datum/admins/proc/check_antagonists()
if (ticker && ticker.current_state >= GAME_STATE_PLAYING)
var/dat = "<html><head><title>Round Status</title></head><body><h1><B>Round Status</B></h1>"
dat += "Current Game Mode: <B>[ticker.mode.name]</B><BR>"
dat += "Round Duration: <B>[round(world.time / 36000)]:[add_zero(world.time / 600 % 60, 2)]:[world.time / 100 % 6][world.time / 100 % 10]</B><BR>"
dat += "<B>Emergency shuttle</B><BR>"
if (!emergency_shuttle.online)
dat += "<a href='?src=\ref[src];call_shuttle=1'>Call Shuttle</a><br>"
else
var/timeleft = emergency_shuttle.timeleft()
switch(emergency_shuttle.location)
if(0)
dat += "ETA: <a href='?src=\ref[src];edit_shuttle_time=1'>[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]</a><BR>"
dat += "<a href='?src=\ref[src];call_shuttle=2'>Send Back</a><br>"
if(1)
dat += "ETA: <a href='?src=\ref[src];edit_shuttle_time=1'>[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]</a><BR>"
dat += "<a href='?src=\ref[src];delay_round_end=1'>[ticker.delay_end ? "End Round Normally" : "Delay Round End"]</a><br>"
if(ticker.mode.syndicates.len)
dat += "<br><table cellspacing=5><tr><td><B>Syndicates</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.syndicates)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
else
dat += "<tr><td><i>Nuclear Operative not found!</i></td></tr>"
dat += "</table><br><table><tr><td><B>Nuclear Disk(s)</B></td></tr>"
for(var/obj/item/weapon/disk/nuclear/N in world)
dat += "<tr><td>[N.name], "
var/atom/disk_loc = N.loc
while(!istype(disk_loc, /turf))
if(istype(disk_loc, /mob))
var/mob/M = disk_loc
dat += "carried by <a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a> "
if(istype(disk_loc, /obj))
var/obj/O = disk_loc
dat += "in \a [O.name] "
disk_loc = disk_loc.loc
dat += "in [disk_loc.loc] at ([disk_loc.x], [disk_loc.y], [disk_loc.z])</td></tr>"
dat += "</table>"
if (ticker && ticker.current_state >= GAME_STATE_PLAYING)
var/dat = "<html><head><title>Round Status</title></head><body><h1><B>Round Status</B></h1>"
dat += "Current Game Mode: <B>[ticker.mode.name]</B><BR>"
dat += "Round Duration: <B>[round(world.time / 36000)]:[add_zero(world.time / 600 % 60, 2)]:[world.time / 100 % 6][world.time / 100 % 10]</B><BR>"
dat += "<B>Emergency shuttle</B><BR>"
if (!emergency_shuttle.online)
dat += "<a href='?src=\ref[src];call_shuttle=1'>Call Shuttle</a><br>"
else
var/timeleft = emergency_shuttle.timeleft()
switch(emergency_shuttle.location)
if(0)
dat += "ETA: <a href='?src=\ref[src];edit_shuttle_time=1'>[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]</a><BR>"
dat += "<a href='?src=\ref[src];call_shuttle=2'>Send Back</a><br>"
if(1)
dat += "ETA: <a href='?src=\ref[src];edit_shuttle_time=1'>[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]</a><BR>"
dat += "<a href='?src=\ref[src];delay_round_end=1'>[ticker.delay_end ? "End Round Normally" : "Delay Round End"]</a><br>"
if(ticker.mode.syndicates.len)
dat += "<br><table cellspacing=5><tr><td><B>Syndicates</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.syndicates)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
else
dat += "<tr><td><i>Nuclear Operative not found!</i></td></tr>"
dat += "</table><br><table><tr><td><B>Nuclear Disk(s)</B></td></tr>"
for(var/obj/item/weapon/disk/nuclear/N in world)
dat += "<tr><td>[N.name], "
var/atom/disk_loc = N.loc
while(!istype(disk_loc, /turf))
if(istype(disk_loc, /mob))
var/mob/M = disk_loc
dat += "carried by <a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a> "
if(istype(disk_loc, /obj))
var/obj/O = disk_loc
dat += "in \a [O.name] "
disk_loc = disk_loc.loc
dat += "in [disk_loc.loc] at ([disk_loc.x], [disk_loc.y], [disk_loc.z])</td></tr>"
dat += "</table>"
if(ticker.mode.head_revolutionaries.len || ticker.mode.revolutionaries.len)
dat += "<br><table cellspacing=5><tr><td><B>Revolutionaries</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.head_revolutionaries)
var/mob/M = N.current
if(!M)
dat += "<tr><td><i>Head Revolutionary not found!</i></td></tr>"
else
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Leader)</b>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
for(var/datum/mind/N in ticker.mode.revolutionaries)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
dat += "</table><table cellspacing=5><tr><td><B>Target(s)</B></td><td></td><td><B>Location</B></td></tr>"
for(var/datum/mind/N in ticker.mode.get_living_heads())
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td>"
var/turf/mob_loc = get_turf_loc(M)
dat += "<td>[mob_loc.loc]</td></tr>"
else
dat += "<tr><td><i>Head not found!</i></td></tr>"
dat += "</table>"
if(ticker.mode.head_revolutionaries.len || ticker.mode.revolutionaries.len)
dat += "<br><table cellspacing=5><tr><td><B>Revolutionaries</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.head_revolutionaries)
var/mob/M = N.current
if(!M)
dat += "<tr><td><i>Head Revolutionary not found!</i></td></tr>"
else
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Leader)</b>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
for(var/datum/mind/N in ticker.mode.revolutionaries)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
dat += "</table><table cellspacing=5><tr><td><B>Target(s)</B></td><td></td><td><B>Location</B></td></tr>"
for(var/datum/mind/N in ticker.mode.get_living_heads())
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td>"
var/turf/mob_loc = get_turf_loc(M)
dat += "<td>[mob_loc.loc]</td></tr>"
else
dat += "<tr><td><i>Head not found!</i></td></tr>"
dat += "</table>"
if(ticker.mode.changelings.len > 0)
dat += "<br><table cellspacing=5><tr><td><B>Changelings</B></td><td></td><td></td></tr>"
for(var/datum/mind/changeling in ticker.mode.changelings)
var/mob/M = changeling.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td>"
dat += "<td><A HREF='?src=\ref[src];traitor=\ref[M]'>Show Objective</A></td></tr>"
else
dat += "<tr><td><i>Changeling not found!</i></td></tr>"
dat += "</table>"
if(ticker.mode.changelings.len)
dat += check_role_table("Changelings", ticker.mode.changelings, src)
if(ticker.mode.wizards.len > 0)
dat += "<br><table cellspacing=5><tr><td><B>Wizards</B></td><td></td><td></td></tr>"
for(var/datum/mind/wizard in ticker.mode.wizards)
var/mob/M = wizard.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td>"
dat += "<td><A HREF='?src=\ref[src];traitor=\ref[M]'>Show Objective</A></td></tr>"
else
dat += "<tr><td><i>Wizard not found!</i></td></tr>"
dat += "</table>"
if(ticker.mode.wizards.len)
dat += check_role_table("Wizards", ticker.mode.wizards, src)
if(ticker.mode.raiders.len > 0)
dat += "<br><table cellspacing=5><tr><td><B>Raiders</B></td><td></td><td></td></tr>"
for(var/datum/mind/raider in ticker.mode.raiders)
var/mob/M = raider.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td>"
dat += "<td><A HREF='?src=\ref[src];traitor=\ref[M]'>Show Objective</A></td></tr>"
dat += "</table>"
if(ticker.mode.raiders.len)
dat += check_role_table("Raiders", ticker.mode.raiders, src)
if(ticker.mode.ninjas.len > 0)
dat += "<br><table cellspacing=5><tr><td><B>Ninjas</B></td><td></td><td></td></tr>"
for(var/datum/mind/ninja in ticker.mode.ninjas)
var/mob/M = ninja.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td>"
dat += "<td><A HREF='?src=\ref[src];traitor=\ref[M]'>Show Objective</A></td></tr>"
else
dat += "<tr><td><i>Ninja not found!</i></td></tr>"
dat += "</table>"
if(ticker.mode.ninjas.len)
dat += check_role_table("Ninjas", ticker.mode.ninjas, src)
if(ticker.mode.cult.len)
dat += "<br><table cellspacing=5><tr><td><B>Cultists</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.cult)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
dat += "</table>"
if(ticker.mode.cult.len)
dat += check_role_table("Cultists", ticker.mode.cult, src, 0)
/*if(istype(ticker.mode, /datum/game_mode/anti_revolution) && ticker.mode:heads.len) //comment out anti-revolution
dat += "<br><table cellspacing=5><tr><td><B>Corrupt Heads</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode:heads)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
dat += "</table>"
*/
if(ticker.mode.traitors.len > 0)
dat += "<br><table cellspacing=5><tr><td><B>Traitors</B></td><td></td><td></td></tr>"
for(var/datum/mind/traitor in ticker.mode.traitors)
var/mob/M = traitor.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td>"
dat += "<td><A HREF='?src=\ref[src];traitor=\ref[M]'>Show Objective</A></td></tr>"
else
dat += "<tr><td><i>Traitor not found!</i></td></tr>"
dat += "</table>"
if(ticker.mode.traitors.len)
dat += check_role_table("Traitors", ticker.mode.traitors, src)
dat += "</body></html>"
usr << browse(dat, "window=roundstatus;size=400x500")
else
alert("The game hasn't started yet!")
var/datum/game_mode/mutiny/mutiny = get_mutiny_mode()
if(mutiny)
dat += mutiny.check_antagonists_ui(src)
dat += "</body></html>"
usr << browse(dat, "window=roundstatus;size=400x500")
else
alert("The game hasn't started yet!")
/proc/check_role_table(name, list/members, admins, show_objectives=1)
var/txt = "<br><table cellspacing=5><tr><td><b>[name]</b></td><td></td></tr>"
for(var/datum/mind/M in members)
txt += check_role_table_row(M.current, admins, show_objectives)
txt += "</table>"
return txt
/proc/check_role_table_row(mob/M, admins=src, show_objectives)
if (!istype(M))
return "<tr><td><i>Not found!</i></td></tr>"
var/txt = {"
<tr>
<td>
<a href='?src=\ref[admins];adminplayeropts=\ref[M]'>[M.real_name]</a>
[M.client ? "" : " <i>(logged out)</i>"]
[M.is_dead() ? " <b><font color='red'>(DEAD)</font></b>" : ""]
</td>
<td>
<a href='?src=\ref[usr];priv_msg=\ref[M]'>PM</a>
</td>
"}
if (show_objectives)
txt += {"
<td>
<a href='?src=\ref[admins];traitor=\ref[M]'>Show Objective</a>
</td>
"}
txt += "</tr>"
return txt

View File

@@ -6,6 +6,10 @@
message_admins("[usr.key] has attempted to override the admin panel!")
return
if(ticker.mode && ticker.mode.check_antagonists_topic(href, href_list))
check_antagonists()
return
if(href_list["makeAntag"])
switch(href_list["makeAntag"])
if("1")

View File

@@ -14,9 +14,10 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set
"pAI candidate" = 1, // -- TLE // 7
"cultist" = IS_MODE_COMPILED("cult"), // 8
"infested monkey" = IS_MODE_COMPILED("monkey"), // 9
"ninja" = "true", // 10
"vox raider" = IS_MODE_COMPILED("heist"), // 11
"ninja" = "true", // 10
"vox raider" = IS_MODE_COMPILED("heist"), // 11
"diona" = 1, // 12
"mutineer" = IS_MODE_COMPILED("mutiny"), // 13
)
var/const/MAX_SAVE_SLOTS = 10

View File

@@ -1,6 +1,6 @@
/obj/machinery/account_database
name = "Accounts uplink console"
name = "Accounts uplink terminal"
desc = "Access transaction logs, account data and all kinds of other financial records."
icon = 'icons/obj/computer.dmi'
icon_state = "aiupload"
@@ -9,115 +9,134 @@
var/receipt_num
var/machine_id = ""
var/obj/item/weapon/card/id/held_card
var/access_level = 0
var/datum/money_account/detailed_account_view
var/creating_new_account = 0
proc/get_access_level()
if (!held_card)
return 0
if(access_cent_captain in held_card.access)
return 2
else if(access_hop in held_card.access || access_captain in held_card.access)
return 1
proc/create_transation(target, reason, amount)
var/datum/transaction/T = new()
T.target_name = target
T.purpose = reason
T.amount = amount
T.date = current_date_string
T.time = worldtime2text()
T.source_terminal = machine_id
return T
proc/accounting_letterhead(report_name)
return {"
<center><h1><b>[report_name]</b></h1></center>
<center><small><i>[station_name()] Accounting Report</i></small></center>
<hr>
<u>Generated By:</u> [held_card.registered_name], [held_card.assignment]<br>
"}
/obj/machinery/account_database/New()
..()
machine_id = "[station_name()] Acc. DB #[num_financial_terminals++]"
..()
/obj/machinery/account_database/attackby(obj/O, mob/user)
if(!istype(O, /obj/item/weapon/card/id))
return ..()
if(!held_card)
user.drop_item()
O.loc = src
held_card = O
nanomanager.update_uis(src)
attack_hand(user)
/obj/machinery/account_database/attack_hand(mob/user as mob)
if(get_dist(src,user) <= 1)
var/dat = "<b>Accounts Database</b><br>"
dat += "<i>[machine_id]</i><br>"
dat += "Confirm identity: <a href='?src=\ref[src];choice=insert_card'>[held_card ? held_card : "-----"]</a><br>"
if(stat & (NOPOWER|BROKEN)) return
ui_interact(user)
if(access_level > 0)
dat += "You may not edit accounts at this terminal, only create and view them.<br>"
if(creating_new_account)
dat += "<br>"
dat += "<a href='?src=\ref[src];choice=view_accounts_list;'>Return to accounts list</a>"
dat += "<form name='create_account' action='?src=\ref[src]' method='get'>"
dat += "<input type='hidden' name='src' value='\ref[src]'>"
dat += "<input type='hidden' name='choice' value='finalise_create_account'>"
dat += "<b>Holder name:</b> <input type='text' id='holder_name' name='holder_name' style='width:250px; background-color:white;'><br>"
dat += "<b>Initial funds:</b> <input type='text' id='starting_funds' name='starting_funds' style='width:250px; background-color:white;'> (subtracted from station account)<br>"
dat += "<i>New accounts are automatically assigned a secret number and pin, which are printed separately in a sealed package.</i><br>"
dat += "<input type='submit' value='Create'><br>"
dat += "</form>"
else
if(detailed_account_view)
dat += "<br>"
dat += "<a href='?src=\ref[src];choice=view_accounts_list;'>Return to accounts list</a><hr>"
dat += "<b>Account number:</b> #[detailed_account_view.account_number]<br>"
dat += "<b>Account holder:</b> [detailed_account_view.owner_name]<br>"
dat += "<b>Account balance:</b> $[detailed_account_view.money]<br>"
if(access_level > 1)
dat += "<b><a href='?src=\ref[src];choice=add_funds'>Silently add funds (no transaction log)</a><br>"
dat += "<b><a href='?src=\ref[src];choice=remove_funds'>Silently remove funds (no transaction log)</a><br>"
dat += "<b><a href='?src=\ref[src];choice=toggle_suspension'>[detailed_account_view.suspended ? "Unsuspend account" : "Suspend account"]</a><br>"
dat += "<table border=1 style='width:100%'>"
dat += "<tr>"
dat += "<td><b>Date</b></td>"
dat += "<td><b>Time</b></td>"
dat += "<td><b>Target</b></td>"
dat += "<td><b>Purpose</b></td>"
dat += "<td><b>Value</b></td>"
dat += "<td><b>Source terminal ID</b></td>"
dat += "</tr>"
for(var/datum/transaction/T in detailed_account_view.transaction_log)
dat += "<tr>"
dat += "<td>[T.date]</td>"
dat += "<td>[T.time]</td>"
dat += "<td>[T.target_name]</td>"
dat += "<td>[T.purpose]</td>"
dat += "<td>$[T.amount]</td>"
dat += "<td>[T.source_terminal]</td>"
dat += "</tr>"
dat += "</table>"
else
dat += "<a href='?src=\ref[src];choice=create_account;'>Create new account</a><br><br>"
dat += "<table border=1 style='width:100%'>"
for(var/i=1, i<=all_money_accounts.len, i++)
var/datum/money_account/D = all_money_accounts[i]
dat += "<tr>"
dat += "<td>#[D.account_number]</td>"
dat += "<td>[D.owner_name]</td>"
dat += "<td>[D.suspended ? "SUSPENDED" : ""]</td>"
dat += "<td><a href='?src=\ref[src];choice=view_account_detail;account_index=[i]'>View in detail</a></td>"
dat += "</tr>"
dat += "</table>"
/obj/machinery/account_database/ui_interact(mob/user, ui_key="main", datum/nanoui/ui=null)
user.set_machine(src)
user << browse(dat,"window=account_db;size=700x650")
else
user << browse(null,"window=account_db")
var/data[0]
data["src"] = "\ref[src]"
data["id_inserted"] = !!held_card
data["id_card"] = held_card ? text("[held_card.registered_name], [held_card.assignment]") : "-----"
data["access_level"] = get_access_level()
data["machine_id"] = machine_id
data["creating_new_account"] = creating_new_account
data["detailed_account_view"] = !!detailed_account_view
data["station_account_number"] = station_account.account_number
data["transactions"] = null
data["accounts"] = null
/obj/machinery/account_database/attackby(O as obj, user as mob)//TODO:SANITY
if(istype(O, /obj/item/weapon/card))
var/obj/item/weapon/card/id/idcard = O
if(!held_card)
usr.drop_item()
idcard.loc = src
held_card = idcard
if (detailed_account_view)
data["account_number"] = detailed_account_view.account_number
data["owner_name"] = detailed_account_view.owner_name
data["money"] = detailed_account_view.money
data["suspended"] = detailed_account_view.suspended
if(access_cent_captain in idcard.access)
access_level = 2
else if(access_hop in idcard.access || access_captain in idcard.access)
access_level = 1
else
..()
var/list/trx[0]
for (var/datum/transaction/T in detailed_account_view.transaction_log)
trx.Add(list(list(\
"date" = T.date, \
"time" = T.time, \
"target_name" = T.target_name, \
"purpose" = T.purpose, \
"amount" = T.amount, \
"source_terminal" = T.source_terminal)))
/obj/machinery/account_database/Topic(var/href, var/href_list)
if (trx.len > 0)
data["transactions"] = trx
var/list/accounts[0]
for(var/i=1, i<=all_money_accounts.len, i++)
var/datum/money_account/D = all_money_accounts[i]
accounts.Add(list(list(\
"account_number"=D.account_number,\
"owner_name"=D.owner_name,\
"suspended"=D.suspended ? "SUSPENDED" : "",\
"account_index"=i)))
if (accounts.len > 0)
data["accounts"] = accounts
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
if (!ui)
ui = new(user, src, ui_key, "accounts_terminal.tmpl", src.name, 400, 640)
ui.set_initial_data(data)
ui.open()
/obj/machinery/account_database/Topic(href, href_list)
if(..())
return 1
var/datum/nanoui/ui = nanomanager.get_open_ui(usr, src, "main")
if(href_list["choice"])
switch(href_list["choice"])
if("create_account")
creating_new_account = 1
if("add_funds")
var/amount = input("Enter the amount you wish to add", "Silently add funds") as num
if(detailed_account_view)
detailed_account_view.money += amount
if("remove_funds")
var/amount = input("Enter the amount you wish to remove", "Silently remove funds") as num
if(detailed_account_view)
detailed_account_view.money -= amount
if("toggle_suspension")
if(detailed_account_view)
if(detailed_account_view.suspended)
detailed_account_view.suspended = 0
else
detailed_account_view.suspended = 1
detailed_account_view.suspended = !detailed_account_view.suspended
callHook("change_account_status", list(detailed_account_view))
if("finalise_create_account")
var/account_name = href_list["holder_name"]
var/starting_funds = max(text2num(href_list["starting_funds"]), 0)
@@ -127,14 +146,11 @@
station_account.money -= starting_funds
//create a transaction log entry
var/datum/transaction/T = new()
T.target_name = account_name
T.purpose = "New account funds initialisation"
T.amount = "([starting_funds])"
T.date = current_date_string
T.time = worldtime2text()
T.source_terminal = machine_id
station_account.transaction_log.Add(T)
var/trx = create_transation(account_name, "New account activation", "([starting_funds])")
station_account.transaction_log.Add(trx)
creating_new_account = 0
ui.close()
creating_new_account = 0
if("insert_card")
@@ -144,7 +160,6 @@
if(ishuman(usr) && !usr.get_active_hand())
usr.put_in_hands(held_card)
held_card = null
access_level = 0
else
var/obj/item/I = usr.get_active_hand()
@@ -154,16 +169,103 @@
C.loc = src
held_card = C
if(access_cent_captain in C.access)
access_level = 2
else if(access_hop in C.access || access_captain in C.access)
access_level = 1
if("view_account_detail")
var/index = text2num(href_list["account_index"])
if(index && index <= all_money_accounts.len)
detailed_account_view = all_money_accounts[index]
if("view_accounts_list")
detailed_account_view = null
creating_new_account = 0
src.attack_hand(usr)
if("revoke_payroll")
var/funds = detailed_account_view.money
var/account_trx = create_transation(station_account.owner_name, "Revoke payroll", "([funds])")
var/station_trx = create_transation(detailed_account_view.owner_name, "Revoke payroll", funds)
station_account.money += funds
detailed_account_view.money = 0
detailed_account_view.transaction_log.Add(account_trx)
station_account.transaction_log.Add(station_trx)
callHook("revoke_payroll", list(detailed_account_view))
if("print")
var/text
var/obj/item/weapon/paper/P = new(loc)
if (detailed_account_view)
P.name = "account #[detailed_account_view.account_number] details"
var/title = "Account #[detailed_account_view.account_number] Details"
text = {"
[accounting_letterhead(title)]
<u>Holder:</u> [detailed_account_view.owner_name]<br>
<u>Balance:</u> $[detailed_account_view.money]<br>
<u>Status:</u> [detailed_account_view.suspended ? "Suspended" : "Active"]<br>
<u>Transactions:</u> ([detailed_account_view.transaction_log.len])<br>
<table>
<thead>
<tr>
<td>Timestamp</td>
<td>Target</td>
<td>Reason</td>
<td>Value</td>
<td>Terminal</td>
</tr>
</thead>
<tbody>
"}
for (var/datum/transaction/T in detailed_account_view.transaction_log)
text += {"
<tr>
<td>[T.date] [T.time]</td>
<td>[T.target_name]</td>
<td>[T.purpose]</td>
<td>[T.amount]</td>
<td>[T.source_terminal]</td>
</tr>
"}
text += {"
</tbody>
</table>
"}
else
P.name = "financial account list"
text = {"
[accounting_letterhead("Financial Account List")]
<table>
<thead>
<tr>
<td>Account Number</td>
<td>Holder</td>
<td>Balance</td>
<td>Status</td>
</tr>
</thead>
<tbody>
"}
for(var/i=1, i<=all_money_accounts.len, i++)
var/datum/money_account/D = all_money_accounts[i]
text += {"
<tr>
<td>#[D.account_number]</td>
<td>[D.owner_name]</td>
<td>$[D.money]</td>
<td>[D.suspended ? "Suspended" : "Active"]</td>
</tr>
"}
text += {"
</tbody>
</table>
"}
P.info = text
state("The terminal prints out a report.")
return 1

View File

@@ -32,8 +32,9 @@
brainmob.timeofhostdeath = H.timeofdeath
if(H.mind)
H.mind.transfer_to(brainmob)
brainmob << "\blue You feel slightly disoriented. That's normal when you're just a brain."
return
callHook("debrain", list(brainmob))
/obj/item/brain/examine() // -- TLE
set src in oview(12)

View File

@@ -86,6 +86,8 @@
verbs -= /mob/living/carbon/proc/release_control
callHook("death", list(src, gibbed))
//Check for heist mode kill count.
if(ticker.mode && ( istype( ticker.mode,/datum/game_mode/heist) ) )
//Check for last assailant's mutantrace.

View File

@@ -17,41 +17,8 @@
if("nuclear emergency")
if(mind in ticker.mode:syndicates)
ticker.mode.update_all_synd_icons()
if("mutiny")
var/datum/game_mode/mutiny/mode = get_mutiny_mode()
if(mode)
mode.update_all_icons()
return .
//This stuff needs to be merged from cloning.dm but I'm not in the mood to be shouted at for breaking all the things :< ~Carn
/* clones
switch(ticker.mode.name)
if("revolution")
if(src.occupant.mind in ticker.mode:revolutionaries)
ticker.mode:update_all_rev_icons() //So the icon actually appears
if(src.occupant.mind in ticker.mode:head_revolutionaries)
ticker.mode:update_all_rev_icons()
if("nuclear emergency")
if (src.occupant.mind in ticker.mode:syndicates)
ticker.mode:update_all_synd_icons()
if("cult")
if (src.occupant.mind in ticker.mode:cult)
ticker.mode:add_cultist(src.occupant.mind)
ticker.mode:update_all_cult_icons() //So the icon actually appears
*/
/* Plantpeople
switch(ticker.mode.name)
if ("revolution")
if (podman.mind in ticker.mode:revolutionaries)
ticker.mode:add_revolutionary(podman.mind)
ticker.mode:update_all_rev_icons() //So the icon actually appears
if (podman.mind in ticker.mode:head_revolutionaries)
ticker.mode:update_all_rev_icons()
if ("nuclear emergency")
if (podman.mind in ticker.mode:syndicates)
ticker.mode:update_all_synd_icons()
if ("cult")
if (podman.mind in ticker.mode:cult)
ticker.mode:add_cultist(podman.mind)
ticker.mode:update_all_cult_icons() //So the icon actually appears
if ("changeling")
if (podman.mind in ticker.mode:changelings)
podman.make_changeling()
*/

View File

@@ -600,6 +600,9 @@ var/list/slot_equipment_priority = list( \
/mob/proc/is_active()
return (0 >= usr.stat)
/mob/proc/is_dead()
return stat == DEAD
/mob/proc/see(message)
if(!is_active())
return 0

View File

@@ -181,6 +181,8 @@
O.mmi = new /obj/item/device/mmi(O)
O.mmi.transfer_identity(src)//Does not transfer key/client.
callHook("borgify", list(O))
O.Namepick()
spawn(0)//To prevent the proc from returning null.

View File

@@ -154,9 +154,16 @@
revoke_maint_all_access()
feedback_inc("alert_keycard_auth_maintRevoke",1)
if("Emergency Response Team")
if(!config.ert_admin_call_only)
trigger_armed_response_team(1)
feedback_inc("alert_keycard_auth_ert",1)
if(is_ert_blocked())
usr << "\red All emergency response teams are dispatched and can not be called at this time."
return
trigger_armed_response_team(1)
feedback_inc("alert_keycard_auth_ert",1)
/obj/machinery/keycard_auth/proc/is_ert_blocked()
if(config.ert_admin_call_only) return 1
return ticker.mode && ticker.mode.ert_disabled
var/global/maint_all_access = 0

View File

@@ -647,19 +647,20 @@ var/list/TAGGERLOCATIONS = list("Disposals",
#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_ATTACKLOGS|CHAT_LOOC)
#define BE_TRAITOR 1
#define BE_OPERATIVE 2
#define BE_CHANGELING 4
#define BE_WIZARD 8
#define BE_MALF 16
#define BE_REV 32
#define BE_ALIEN 64
#define BE_PAI 128
#define BE_CULTIST 256
#define BE_MONKEY 512
#define BE_NINJA 1024
#define BE_RAIDER 2048
#define BE_PLANT 4096
#define BE_TRAITOR 1
#define BE_OPERATIVE 2
#define BE_CHANGELING 4
#define BE_WIZARD 8
#define BE_MALF 16
#define BE_REV 32
#define BE_ALIEN 64
#define BE_PAI 128
#define BE_CULTIST 256
#define BE_MONKEY 512
#define BE_NINJA 1024
#define BE_RAIDER 2048
#define BE_PLANT 4096
#define BE_MUTINEER 8192
var/list/be_special_flags = list(
"Traitor" = BE_TRAITOR,
@@ -674,7 +675,8 @@ var/list/be_special_flags = list(
"Monkey" = BE_MONKEY,
"Ninja" = BE_NINJA,
"Raider" = BE_RAIDER,
"Diona" = BE_PLANT
"Diona" = BE_PLANT,
"Mutineer" = BE_MUTINEER
)
#define AGE_MIN 17 //youngest a character can be

Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 KiB

After

Width:  |  Height:  |  Size: 178 KiB

View File

@@ -70,6 +70,15 @@ a.icon img, .linkOn.icon img, .linkOff.icon img, .selected.icon img, .disabled.i
width: 18px;
height: 18px;
}
.linkDanger, a.linkDanger:link, a.linkDanger:visited, a.linkDanger:active {
color: #ffffff;
background-color: #ff0000;
border-color: #aa0000;
}
.linkDanger:hover {
background-color: #ff6666;
}
ul {
padding: 4px 0 0 10px;
margin: 0;

View File

@@ -0,0 +1,168 @@
<div class="item">
<div class="itemLabelNarrow">
<b>Machine</b>:
</div>
<div class="itemContent">
<span class="average">{{:machine_id}}</span>
</div>
</div>
<div class="item">
<div class="itemLabelNarrow">
<b>ID</b>:
</div>
<div class="itemContent">
{{:~link(id_card, 'eject', {'choice' : "insert_card"}, null, id_inserted ? 'fixedLeftWidest' : 'fixedLeft')}}
</div>
</div>
{{if access_level > 0}}
<div class='item'>
<h2>Menu</h2>
</div>
{{:~link('Home', 'home', {'choice' : 'view_accounts_list'}, !creating_new_account && !detailed_account_view ? 'disabled' : null, 'fixedLeft')}}
{{:~link('New Account', 'gear', {'choice' : 'create_account'}, creating_new_account ? 'disabled' : null, 'fixedLeft')}}
{{:~link('Print', 'print', {'choice' : 'print'}, creating_new_account ? 'disabled' : null, 'fixedLeft')}}
{{if creating_new_account}}
<div class='item'>
<h2>Create Account</h2>
</div>
<form name='create_account' action='?src={{:src}}' method='get'>
<input type='hidden' name='src' value='{{:src}}'>
<input type='hidden' name='choice' value='finalise_create_account'>
<div class='item'>
<div class='itemLabel'>
<b>Account Holder</b>:
</div>
<div class='itemContent'>
<input type='text' id='holder_name' name='holder_name'>
</div>
</div>
<div class='item'>
<div class='itemLabel'>
<b>Initial Deposit</b>:
</div>
<div class='itemContent'>
<input type='text' id='starting_funds' name='starting_funds'>
</div>
</div>
<div class='item'>
<input type='submit' value='Create'>
</div>
</form>
{{else}}
{{if detailed_account_view}}
<div class='item'>
<h2>Account Details</h2>
</div>
<div class='item'>
<div class="itemLabel">
<span class='average'><b>Account Number</b>:</span>
</div>
<div class="itemContent">
#{{:account_number}}
</div>
</div>
<div class='item'>
<div class="itemLabel">
<span class='average'><b>Holder</b>:</span>
</div>
<div class="itemContent">
{{:owner_name}}
</div>
</div>
<div class='item'>
<div class="itemLabel">
<span class='average'><b>Balance</b>:</span>
</div>
<div class="itemContent">
${{:~formatNumber(money)}}
</div>
</div>
<div class='item'>
<div class="itemLabel">
<span class='average'><b>Status</b>:</span>
</div>
<div class="itemContent">
<span class='{{: suspended ? "bad" : "good"}}'>
{{: suspended ? "Suspended" : "Active"}}
</span>
</div>
</div>
<div class='item'>
{{:~link(suspended ? "Unsuspend" : "Suspend", 'gear', {'choice' : 'toggle_suspension'})}}
</div>
<div class="statusDisplay" style="overflow: auto;">
{{if transactions}}
<table style='width: 100%'>
<thead>
<tr>
<th><b>Timestamp</b></th>
<th><b>Target</b></th>
<th><b>Reason</b></th>
<th><b>Value</b></th>
<th><b>Terminal</b></th>
</th>
</thead>
<tbody>
{{for transactions}}
<tr>
<td>{{:date}} {{:time}}</td>
<td>{{:target_name}}</td>
<td>{{:purpose}}</td>
<td>{{:amount}}</td>
<td>{{:source_terminal}}</td>
</tr>
{{/for}}
</tbody>
</table>
{{else}}
<span class='alert'>This account has no financial transactions on record for today.</span>
{{/if}}
</div>
<div class='item'>
<h2>CentCom Administrator</h2>
</div>
<div class='item'>
<div class='fixedLeft'>
Payroll:
</div>
{{:~link('Revoke', 'transferthick-e-w', {'choice' : 'revoke_payroll'}, account_number == station_account_number ? 'disabled' : null, 'linkDanger')}}
</div>
{{if access_level >= 2}}
<div class='item'>
<div class='fixedLeft'>
Silent Fund Adjustment:
</div>
{{:~link('Add', 'plus', {'choice' : 'add_funds'})}}
{{:~link('Remove', 'minus', {'choice' : 'remove_funds'})}}
</div>
{{/if}}
{{else}}
<div class='item'>
<h2>NanoTrasen Accounts</h2>
</div>
{{if accounts}}
<table style="width: 100%">
{{for accounts}}
<tr class='{{: suspended ? "bad" : ""}}'>
<td><b>{{:~link('#' + account_number, '', {'choice' : 'view_account_detail', 'account_index' : account_index})}}</b></td>
<td>{{:owner_name}}</td>
<td>{{:suspended}}</td>
</tr>
{{/for}}
</table>
{{else}}
<span class='alert'>There are no accounts available.</span>
{{/if}}
{{/if}}
{{/if}}
{{/if}}

View File

@@ -0,0 +1,236 @@
{{if printing}}
<h5 class='average'>The computer is currently busy.</h5>
<div class='notice'>
<center><span class='bad'>Printing...</span></center>
</div>
<p>
Thank you for your patience!
</p>
{{else}}
{{:~link('Access Modification', 'home', {'choice' : 'mode', 'mode_target' : 0}, !mode ? 'disabled' : null)}}
{{:~link('Crew Manifest', 'folder-open', {'choice' : 'mode', 'mode_target' : 1}, mode ? 'disabled' : null)}}
{{:~link('Print', 'print', {'choice' : 'print'}, (mode || has_modify) ? null : 'disabled')}}
{{if mode}}
<div class='item'>
<h2>Crew Manifest</h2>
</div>
<div class='item'>
{{:manifest}}
</div>
{{else}}
<div class='item'>
<h2>Access Modification</h2>
</div>
{{if !authenticated}}
<span class='alert'><i>Please insert the IDs into the terminal to proceed.</i></span><br>
{{/if}}
<div class='item'>
<div class='itemLabel'>
Target Identity:
</div>
<div class='itemContent'>
{{:~link(target_name, 'eject', {'choice' : 'modify'})}}
</div>
</div>
<div class='item'>
<div class='itemLabel'>
Authorized Identity:
</div>
<div class='itemContent'>
{{:~link(scan_name, 'eject', {'choice' : 'scan'})}}
</div>
</div>
<hr>
{{if authenticated}}
<script type="text/javascript">
function markRed(){
var nameField = document.getElementById('namefield');
nameField.style.backgroundColor = "#FFDDDD";
}
function markGreen(){
var nameField = document.getElementById('namefield');
nameField.style.backgroundColor = "#DDFFDD";
}
function markAccountGreen(){
var nameField = document.getElementById('accountfield');
nameField.style.backgroundColor = "#DDFFDD";
}
function markAccountRed(){
var nameField = document.getElementById('accountfield');
nameField.style.backgroundColor = "#FFDDDD";
}
function showAll(){
var allJobsSlot = document.getElementById('alljobsslot');
allJobsSlot.innerHTML = "<a href='#' onclick='hideAll()'>Hide</a><br>";
var allJobs = document.getElementById('all-jobs');
allJobs.style.display = 'block';
}
function hideAll(){
var allJobsSlot = document.getElementById('alljobsslot');
allJobsSlot.innerHTML = "<a href='#' onclick='showAll()'>{{:target_rank}}</a>";
var allJobs = document.getElementById('all-jobs');
allJobs.style.display = 'none';
}
</script>
{{if has_modify}}
<div class='item'>
<h2>Details</h2>
</div>
<form name='cardcomp' action='?src={{:src}}' method='get'>
<div class='item'>
<div class='itemLabel'>
<input type='hidden' name='src' value='{{:src}}'>
<input type='hidden' name='choice' value='reg'>
Registered Name:
</div>
<div class='itemContent'>
<input type='text' id='namefield' name='reg' value='{{:target_owner}}' onchange='markRed()'>
<input type='submit' value='Rename' onclick='markGreen()'>
</div>
</div>
</form>
<form name='accountnum' action='?src={{:src}}' method='get'>
<div class='item'>
<div class='itemLabel'>
<input type='hidden' name='src' value='{{:src}}'>
<input type='hidden' name='choice' value='account'>
Account Number:
</div>
<div class='itemContent'>
<input type='text' id='accountfield' name='account' value='{{:account_number}}' onchange='markAccountRed()'>
<input type='submit' value='Modify' onclick='markAccountGreen()'>
</div>
</div>
</form>
<div class='item'>
<div class='itemLabel'>
Terminations:
</div>
<div class='itemContent'>
{{:~link('Terminate ' + target_owner, 'gear', {'choice' : 'terminate'}, target_rank == "Terminated" ? 'disabled' : null, target_rank == "Terminated" ? 'disabled' : 'linkDanger')}}
</div>
</div>
<div class='item'>
<h2>Assignment</h2>
</div>
<div class='item'>
<span id='alljobsslot'>
<a href='#' onclick='showAll()'>{{:target_rank}}</a>
</span>
</div>
<div class='item'>
<div id="all-jobs" style='display: none;'>
<table>
<tr>
<th></th><th>Command</th>
</tr>
<tr>
<th>Special</th>
<td>
{{:~link("Captain", '', {'choice' : 'assign', 'assign_target' : 'Captain'}, target_rank == 'Captain' ? 'disabled' : null)}}
{{:~link("Custom", '', {'choice' : 'assign', 'assign_target' : 'Custom'})}}
</td>
</tr>
<tr>
<th style="color: '#FFA500';">Engineering</th>
<td>
{{for engineering_jobs}}
{{:~link(display_name, '', {'choice' : 'assign', 'assign_target' : job}, target_rank == job ? 'disabled' : null)}}
{{/for}}
</td>
</tr>
<tr>
<th style="color: '#008000';">Medical</th>
<td>
{{for medical_jobs}}
{{:~link(display_name, '', {'choice' : 'assign', 'assign_target' : job}, target_rank == job ? 'disabled' : null)}}
{{/for}}
</td>
</tr>
<tr>
<th style="color: '#800080';">Science</th>
<td>
{{for science_jobs}}
{{:~link(display_name, '', {'choice' : 'assign', 'assign_target' : job}, target_rank == job ? 'disabled' : null)}}
{{/for}}
</td>
</tr>
<tr>
<th style="color: '#DD0000';">Security</th>
<td>
{{for security_jobs}}
{{:~link(display_name, '', {'choice' : 'assign', 'assign_target' : job}, target_rank == job ? 'disabled' : null)}}
{{/for}}
</td>
</tr>
<tr>
<th style="color: '#808080';">Civilian</th>
<td>
{{for civilian_jobs}}
{{if #index && #index % 6 === 0}}
</td></tr><tr><th></th><td>
{{/if}}
{{:~link(display_name, '', {'choice' : 'assign', 'assign_target' : job}, target_rank == job ? 'disabled' : null)}}
{{/for}}
</td>
</tr>
{{if centcom_access}}
<tr>
<th style="color: '#A52A2A';">CentCom</th>
<td>
{{for centcom_jobs}}
{{if #index % 6 === 0}}
</td></tr><tr><th></th><td>
{{/if}}
{{:~link(display_name, '', {'choice' : 'assign', 'assign_target' : job}, target_rank == job ? 'disabled' : null)}}
{{/for}}
</td>
</tr>
{{/if}}
</table>
</div>
</div>
{{if centcom_access}}
<div class='item'>
<h2>Central Command</h2>
</div>
<div class='item' style='width: 100%'>
{{for all_centcom_access}}
<div class='itemContentWide'>
{{:~link(desc, '', {'choice' : 'access', 'access_target' : ref, 'allowed' : allowed}, null, allowed ? 'selected' : null)}}
</div>
{{/for}}
</div>
{{else}}
<div class='item'>
<h2>{{:station_name}}</h2>
</div>
<div class='item' style='width: 100%'>
{{for regions}}
<div style='float: left; width: 175px; min-height: 250px'>
<div class='average'><b>{{:name}}</b></div>
{{for accesses}}
<div class='itemContentWide'>
{{:~link(desc, '', {'choice' : 'access', 'access_target' : ref, 'allowed' : allowed}, null, allowed ? 'selected' : null)}}
</div>
{{/for}}
</div>
{{/for}}
</div>
{{/if}}
{{/if}}
{{/if}}
{{/if}}
{{/if}}