Merge branch 'bleeding-edge-freeze' of https://github.com/Baystation12/Baystation12 into xenoarch

Conflicts:
	baystation12.dme
	code/WorkInProgress/Cael_Aislinn/ShieldGen/energy_field.dm
	icons/obj/storage.dmi

Signed-off-by: Cael_Aislinn <cael_aislinn@yahoo.com.au>
This commit is contained in:
Cael_Aislinn
2013-03-06 19:03:18 +10:00
91 changed files with 11675 additions and 9576 deletions
@@ -1,6 +1,7 @@
var/global/current_date_string
var/global/num_financial_terminals = 1
var/global/datum/money_account/station_account
var/global/list/datum/money_account/department_accounts = list()
var/global/next_account_number = 0
var/global/obj/machinery/account_database/centcomm_account_db
@@ -28,6 +29,31 @@ var/global/obj/machinery/account_database/centcomm_account_db
for(var/obj/machinery/account_database/A in world)
A.accounts.Add(station_account)
/proc/create_department_account(department)
next_account_number = rand(111111, 999999)
var/datum/money_account/department_account = new()
department_account.owner_name = "[department] Account"
department_account.account_number = rand(111111, 999999)
department_account.remote_access_pin = rand(1111, 111111)
department_account.money = 5000
//create an entry in the account transaction log for when it was created
var/datum/transaction/T = new()
T.target_name = department_account.owner_name
T.purpose = "Account creation"
T.amount = department_account.money
T.date = "2nd April, 2555"
T.time = "11:24"
T.source_terminal = "Biesel GalaxyNet Terminal #277"
//add the account
department_account.transaction_log.Add(T)
for(var/obj/machinery/account_database/A in world)
A.accounts.Add(department_account)
department_accounts[department] = department_account
//the current ingame time (hh:mm) can be obtained by calling:
//worldtime2text()
@@ -63,12 +89,17 @@ var/global/obj/machinery/account_database/centcomm_account_db
var/access_level = 0
var/datum/money_account/detailed_account_view
var/creating_new_account = 0
var/activated = 1
/obj/machinery/account_database/New()
..()
if(!station_account)
create_station_account()
if(department_accounts.len == 0)
for(var/department in station_departments)
create_department_account(department)
if(!current_date_string)
current_date_string = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], 2557"
@@ -81,6 +112,7 @@ var/global/obj/machinery/account_database/centcomm_account_db
dat += "Confirm identity: <a href='?src=\ref[src];choice=insert_card'>[held_card ? held_card : "-----"]</a><br>"
if(access_level > 0)
dat += "<a href='?src=\ref[src];toggle_activated=1'>[activated ? "Disable" : "Enable"] remote access</a><br>"
dat += "You may not edit accounts at this terminal, only create and view them.<br>"
if(creating_new_account)
dat += "<br>"
@@ -151,6 +183,10 @@ var/global/obj/machinery/account_database/centcomm_account_db
..()
/obj/machinery/account_database/Topic(var/href, var/href_list)
if(href_list["toggle_activated"])
activated = !activated
if(href_list["choice"])
switch(href_list["choice"])
if("sync_accounts")
@@ -161,7 +197,7 @@ var/global/obj/machinery/account_database/centcomm_account_db
for(var/datum/money_account/M in A.accounts)
if(!src.accounts.Find(M))
src.accounts.Add(M)
usr << "\icon[src] <span class='info'>Accounts synched across all databases in range.</span>"
usr << "\icon[src] <span class='info'>Accounts synched across all NanoTrasen financial databases.</span>"
if("create_account")
creating_new_account = 1
@@ -215,6 +251,15 @@ var/global/obj/machinery/account_database/centcomm_account_db
src.attack_hand(usr)
/obj/machinery/account_database/proc/add_account_across_all(var/new_owner_name = "Default user", var/starting_funds = 0, var/pre_existing = 0)
var/datum/money_account/M = add_account(new_owner_name, starting_funds, pre_existing)
for(var/obj/machinery/account_database/D in world)
if(D == src)
continue
D.accounts.Add(M)
return M
/obj/machinery/account_database/proc/add_account(var/new_owner_name = "Default user", var/starting_funds = 0, var/pre_existing = 0)
//create a new account
@@ -274,6 +319,8 @@ var/global/obj/machinery/account_database/centcomm_account_db
return M
/obj/machinery/account_database/proc/charge_to_account(var/attempt_account_number, var/source_name, var/purpose, var/terminal_id, var/amount)
if(!activated)
return 0
for(var/datum/money_account/D in accounts)
if(D.account_number == attempt_account_number)
D.money += amount
@@ -297,6 +344,8 @@ var/global/obj/machinery/account_database/centcomm_account_db
//this returns the first account datum that matches the supplied accnum/pin combination, it returns null if the combination did not match any account
/obj/machinery/account_database/proc/attempt_account_access(var/attempt_account_number, var/attempt_pin_number, var/security_level_passed = 0)
if(!activated)
return 0
for(var/datum/money_account/D in accounts)
if(D.account_number == attempt_account_number)
if( D.security_level <= security_level_passed && (!D.security_level || D.remote_access_pin == attempt_pin_number) )
@@ -14,6 +14,17 @@
#define ANIMAL_RIGHTS_RAID 13
#define FESTIVAL 14
#define RESEARCH_BREAKTHROUGH 15
#define BARGAINS 16
#define SONG_DEBUT 17
#define MOVIE_RELEASE 18
#define BIG_GAME_HUNTERS 19
#define ELECTION 20
#define GOSSIP 21
#define TOURISM 22
#define CELEBRITY_DEATH 23
#define RESIGNATION 24
#define DEFAULT 1
#define ADMINISTRATIVE 2
@@ -54,10 +65,25 @@
var/setup_economy = 0
/proc/setup_economy()
if(setup_economy)
return
var/datum/feed_channel/newChannel = new /datum/feed_channel
newChannel.channel_name = "Tau Ceti Daily"
newChannel.author = "CentComm Minister of Information"
newChannel.locked = 1
newChannel.is_admin_channel = 1
news_network.network_channels += newChannel
setup_economy = 1
newChannel = new /datum/feed_channel
newChannel.channel_name = "The Gibson Gazette"
newChannel.author = "Editor Mike Hammers"
newChannel.locked = 1
newChannel.is_admin_channel = 1
news_network.network_channels += newChannel
for(var/loc_type in typesof(/datum/trade_destination) - /datum/trade_destination)
var/datum/trade_destination/D = new loc_type
weighted_randomevent_locations[D] = D.viable_random_events.len
weighted_mundaneevent_locations[D] = D.viable_mundane_events.len
setup_economy = 1
@@ -11,11 +11,14 @@
if(!setup_economy)
setup_economy()
var/type = pick(tradeable_destinations)
affected_dest = new type()
affected_dest = pickweight(weighted_randomevent_locations)
if(affected_dest.viable_random_events.len)
endWhen = rand(60,300)
event_type = pick(affected_dest.viable_random_events)
if(!event_type)
return
switch(event_type)
if(RIOTS)
dearer_goods = list(SECURITY)
@@ -54,39 +57,42 @@
/datum/event/economic_event/announce()
//copy-pasted from the admin verbs to submit new newscaster messages
var/datum/feed_message/newMsg = new /datum/feed_message
newMsg.author = "NanoTrasen Editor"
newMsg.author = "Tau Ceti Daily"
newMsg.is_admin_message = 1
switch(event_type)
if(RIOTS)
newMsg.body = "[pick("Riots have","Unrest has")] broken out on planet [affected_dest.name]. Authorities call for calm, as [pick("various parties","rebellious elements","peacekeeping forces","\'REDACTED\'")] begin stockpiling weaponry and armour. Meanwhile, food and mineral prices are dropping as local industries attempt empty their stocks in expectation of looting."
if(WILD_ANIMAL_ATTACK)
newMsg.body = "Local [pick("wildlife","animal life","fauna")] on planet [affected_dest.name] has been increasing in agression and raiding outlying settlements for food. Big game hunters have been called in to help alleviate the problem, but numerous injuries have already occurred."
if(INDUSTRIAL_ACCIDENT)
newMsg.body = "[pick("An industrial accident","A smelting accident","A malfunction","A malfunctioning piece of machinery","Negligent maintenance","A cooleant leak","A ruptured conduit")] at a [pick("factory","installation","power plant","dockyards")] on [affected_dest.name] resulted in severe structural damage and numerous injuries. Repairs are ongoing."
if(BIOHAZARD_OUTBREAK)
newMsg.body = "[pick("A \'REDACTED\'","A biohazard","An outbreak","A virus")] on [affected_dest.name] has resulted in quarantine, stopping much shipping in the area. Although the quarantine is now lifted, authorities are calling for deliveries of medical supplies to treat the infected, and gas to replace contaminated stocks."
if(PIRATES)
newMsg.body = "[pick("Pirates","Criminal elements","A [pick("Syndicate","Donk Co.","Waffle Co.","\'REDACTED\'")] strike force")] have [pick("raided","blockaded","attempted to blackmail","attacked")] [affected_dest.name] today. Security has been tightened, but many valuable minerals were taken."
if(CORPORATE_ATTACK)
newMsg.body = "A small [pick("pirate","Cybersun Industries","Gorlex Marauders","Syndicate")] fleet has precise-jumped into proximity with [affected_dest.name], [pick("for a smash-and-grab operation","in a hit and run attack","in an overt display of hostilities")]. Much damage was done, and security has been tightened since the incident."
if(ALIEN_RAIDERS)
if(prob(20))
newMsg.body = "The Tiger Co-operative have raided [affected_dest.name] today, no doubt on orders from their enigmatic masters. Stealing wildlife, farm animals, medical research materials and kidnapping civilians. NanoTrasen authorities are standing by to counter attempts at bio-terrorism."
else
newMsg.body = "[pick("The alien species designated \'United Exolitics\'","The alien species designated \'REDACTED\'","An unknown alien species")] have raided [affected_dest.name] today, stealing wildlife, farm animals, medical research materials and kidnapping civilians. It seems they desire to learn more about us, so the Navy will be standing by to accomodate them next time they try."
if(AI_LIBERATION)
newMsg.body = "A [pick("\'REDACTED\' was detected on","S.E.L.F operative infiltrated","malignant computer virus was detected on","rogue [pick("slicer","hacker")] was apprehended on")] [affected_dest.name] today, and managed to infect [pick("\'REDACTED\'","a sentient sub-system","a class one AI","a sentient defence installation")] before it could be stopped. Many lives were lost as it systematically begin murdering civilians, and considerable work must be done to repair the affected areas."
if(MOURNING)
newMsg.body = "[pick("The popular","The well-liked","The eminent","The well-known")] [pick("professor","entertainer","singer","researcher","public servant","administrator","ship captain","\'REDACTED\'")], [pick( random_name(pick(MALE,FEMALE)), 40; "\'REDACTED\'" )] has [pick("passed away","committed suicide","been murdered","died in a freakish accident")] on [affected_dest.name] today. The entire planet is in mourning, and prices have dropped for industrial goods as worker morale drops."
if(CULT_CELL_REVEALED)
newMsg.body = "A [pick("dastardly","blood-thirsty","villanous","crazed")] cult of [pick("The Elder Gods","Nar'sie","an apocalyptic sect","\'REDACTED\'")] has [pick("been discovered","been revealed","revealed themselves","gone public")] on [affected_dest.name] earlier today. Public morale has been shaken due to [pick("certain","several","one or two")] [pick("high-profile","well known","popular")] individuals [pick("performing \'REDACTED\' acts","claiming allegiance to the cult","swearing loyalty to the cult leader","promising to aid to the cult")] before those involved could be brought to justice. The editor reminds all personnel that supernatural myths will not be tolerated on NanoTrasen facilities."
if(SECURITY_BREACH)
newMsg.body = "There was [pick("a security breach in","an unauthorised access in","an attempted theft in","an anarchist attack in","violent sabotage of")] a [pick("high-security","restricted access","classified","\'REDACTED\'")] [pick("\'REDACTED\'","section","zone","area")] this morning. Security was tightened on [affected_dest.name] after the incident, and the editor reassures all NanoTrasen personnel that such lapses are rare."
if(ANIMAL_RIGHTS_RAID)
newMsg.body = "[pick("Militant animal rights activists","Members of the terrorist group Animal Rights Consortium","Members of the terrorist group \'REDACTED\'")] have [pick("launched a campaign of terror","unleashed a swathe of destruction","raided farms and pastures","forced entry to \'REDACTED\'")] on [affected_dest.name] earlier today, freeing numerous [pick("farm animals","animals","\'REDACTED\'")]. Prices for tame and breeding animals have spiked as a result."
if(FESTIVAL)
newMsg.body = "A [pick("festival","week long celebration","day of revelry","planet-wide holiday")] has been declared on [affected_dest.name] by [pick("Governor","Commissioner","General","Commandant","Administrator")] [random_name(pick(MALE,FEMALE))] to celebrate [pick("the birth of their [pick("son","daughter")]","coming of age of their [pick("son","daughter")]","the pacification of rogue military cell","the apprehension of a violent criminal who had been terrorising the planet")]. Massive stocks of food and meat have been bought driving up prices across the planet."
//see if our location has custom event info for this event
newMsg.body = affected_dest.get_custom_eventstring()
if(!newMsg.body)
switch(event_type)
if(RIOTS)
newMsg.body = "[pick("Riots have","Unrest has")] broken out on planet [affected_dest.name]. Authorities call for calm, as [pick("various parties","rebellious elements","peacekeeping forces","\'REDACTED\'")] begin stockpiling weaponry and armour. Meanwhile, food and mineral prices are dropping as local industries attempt empty their stocks in expectation of looting."
if(WILD_ANIMAL_ATTACK)
newMsg.body = "Local [pick("wildlife","animal life","fauna")] on planet [affected_dest.name] has been increasing in agression and raiding outlying settlements for food. Big game hunters have been called in to help alleviate the problem, but numerous injuries have already occurred."
if(INDUSTRIAL_ACCIDENT)
newMsg.body = "[pick("An industrial accident","A smelting accident","A malfunction","A malfunctioning piece of machinery","Negligent maintenance","A cooleant leak","A ruptured conduit")] at a [pick("factory","installation","power plant","dockyards")] on [affected_dest.name] resulted in severe structural damage and numerous injuries. Repairs are ongoing."
if(BIOHAZARD_OUTBREAK)
newMsg.body = "[pick("A \'REDACTED\'","A biohazard","An outbreak","A virus")] on [affected_dest.name] has resulted in quarantine, stopping much shipping in the area. Although the quarantine is now lifted, authorities are calling for deliveries of medical supplies to treat the infected, and gas to replace contaminated stocks."
if(PIRATES)
newMsg.body = "[pick("Pirates","Criminal elements","A [pick("Syndicate","Donk Co.","Waffle Co.","\'REDACTED\'")] strike force")] have [pick("raided","blockaded","attempted to blackmail","attacked")] [affected_dest.name] today. Security has been tightened, but many valuable minerals were taken."
if(CORPORATE_ATTACK)
newMsg.body = "A small [pick("pirate","Cybersun Industries","Gorlex Marauders","Syndicate")] fleet has precise-jumped into proximity with [affected_dest.name], [pick("for a smash-and-grab operation","in a hit and run attack","in an overt display of hostilities")]. Much damage was done, and security has been tightened since the incident."
if(ALIEN_RAIDERS)
if(prob(20))
newMsg.body = "The Tiger Co-operative have raided [affected_dest.name] today, no doubt on orders from their enigmatic masters. Stealing wildlife, farm animals, medical research materials and kidnapping civilians. NanoTrasen authorities are standing by to counter attempts at bio-terrorism."
else
newMsg.body = "[pick("The alien species designated \'United Exolitics\'","The alien species designated \'REDACTED\'","An unknown alien species")] have raided [affected_dest.name] today, stealing wildlife, farm animals, medical research materials and kidnapping civilians. It seems they desire to learn more about us, so the Navy will be standing by to accomodate them next time they try."
if(AI_LIBERATION)
newMsg.body = "A [pick("\'REDACTED\' was detected on","S.E.L.F operative infiltrated","malignant computer virus was detected on","rogue [pick("slicer","hacker")] was apprehended on")] [affected_dest.name] today, and managed to infect [pick("\'REDACTED\'","a sentient sub-system","a class one AI","a sentient defence installation")] before it could be stopped. Many lives were lost as it systematically begin murdering civilians, and considerable work must be done to repair the affected areas."
if(MOURNING)
newMsg.body = "[pick("The popular","The well-liked","The eminent","The well-known")] [pick("professor","entertainer","singer","researcher","public servant","administrator","ship captain","\'REDACTED\'")], [pick( random_name(pick(MALE,FEMALE)), 40; "\'REDACTED\'" )] has [pick("passed away","committed suicide","been murdered","died in a freakish accident")] on [affected_dest.name] today. The entire planet is in mourning, and prices have dropped for industrial goods as worker morale drops."
if(CULT_CELL_REVEALED)
newMsg.body = "A [pick("dastardly","blood-thirsty","villanous","crazed")] cult of [pick("The Elder Gods","Nar'sie","an apocalyptic sect","\'REDACTED\'")] has [pick("been discovered","been revealed","revealed themselves","gone public")] on [affected_dest.name] earlier today. Public morale has been shaken due to [pick("certain","several","one or two")] [pick("high-profile","well known","popular")] individuals [pick("performing \'REDACTED\' acts","claiming allegiance to the cult","swearing loyalty to the cult leader","promising to aid to the cult")] before those involved could be brought to justice. The editor reminds all personnel that supernatural myths will not be tolerated on NanoTrasen facilities."
if(SECURITY_BREACH)
newMsg.body = "There was [pick("a security breach in","an unauthorised access in","an attempted theft in","an anarchist attack in","violent sabotage of")] a [pick("high-security","restricted access","classified","\'REDACTED\'")] [pick("\'REDACTED\'","section","zone","area")] this morning. Security was tightened on [affected_dest.name] after the incident, and the editor reassures all NanoTrasen personnel that such lapses are rare."
if(ANIMAL_RIGHTS_RAID)
newMsg.body = "[pick("Militant animal rights activists","Members of the terrorist group Animal Rights Consortium","Members of the terrorist group \'REDACTED\'")] have [pick("launched a campaign of terror","unleashed a swathe of destruction","raided farms and pastures","forced entry to \'REDACTED\'")] on [affected_dest.name] earlier today, freeing numerous [pick("farm animals","animals","\'REDACTED\'")]. Prices for tame and breeding animals have spiked as a result."
if(FESTIVAL)
newMsg.body = "A [pick("festival","week long celebration","day of revelry","planet-wide holiday")] has been declared on [affected_dest.name] by [pick("Governor","Commissioner","General","Commandant","Administrator")] [random_name(pick(MALE,FEMALE))] to celebrate [pick("the birth of their [pick("son","daughter")]","coming of age of their [pick("son","daughter")]","the pacification of rogue military cell","the apprehension of a violent criminal who had been terrorising the planet")]. Massive stocks of food and meat have been bought driving up prices across the planet."
for(var/datum/feed_channel/FC in news_network.network_channels)
if(FC.channel_name == "Tau Ceti Daily")
@@ -0,0 +1,233 @@
/datum/event/mundane_news
endWhen = 10
/datum/event/mundane_news/announce()
var/datum/trade_destination/affected_dest = pickweight(weighted_mundaneevent_locations)
var/event_type = 0
if(affected_dest.viable_mundane_events.len)
event_type = pick(affected_dest.viable_mundane_events)
if(!event_type)
return
//copy-pasted from the admin verbs to submit new newscaster messages
var/datum/feed_message/newMsg = new /datum/feed_message
newMsg.author = "Tau Ceti Daily"
newMsg.is_admin_message = 1
//see if our location has custom event info for this event
newMsg.body = affected_dest.get_custom_eventstring()
if(!newMsg.body)
newMsg.body = ""
switch(event_type)
if(RESEARCH_BREAKTHROUGH)
newMsg.body = "A major breakthough in the field of [pick("plasma research","super-compressed materials","nano-augmentation","bluespace research","volatile power manipulation")] \
was announced [pick("yesterday","a few days ago","last week","earlier this month")] by a private firm on [affected_dest.name]. \
NanoTrasen declined to comment as to whether this could impinge on profits."
if(ELECTION)
newMsg.body = "The pre-selection of an additional candidates was announced for the upcoming [pick("supervisors council","advisory board","governership","board of inquisitors")] \
election on [affected_dest.name] was announced earlier today, \
[pick("media mogul","web celebrity", "industry titan", "superstar", "famed chef", "popular gardener", "ex-army officer", "multi-billionaire")] \
[random_name(pick(MALE,FEMALE))]. In a statement to the media they said '[pick("My only goal is to help the [pick("sick","poor","children")]",\
"I will maintain NanoTrasen's record profits","I believe in our future","We must return to our moral core","Just like... chill out dudes")]'."
if(RESIGNATION)
newMsg.body = "NanoTrasen regretfully announces the resignation of [pick("Sector Admiral","Division Admiral","Ship Admiral","Vice Admiral")] [random_name(pick(MALE,FEMALE))]."
if(prob(25))
var/locstring = pick("Segunda","Salusa","Cepheus","Andromeda","Gruis","Corona","Aquila","Asellus") + " " + pick("I","II","III","IV","V","VI","VII","VIII")
newMsg.body += " In a ceremony on [affected_dest.name] this afternoon, they will be awarded the \
[pick("Red Star of Sacrifice","Purple Heart of Heroism","Blue Eagle of Loyalty","Green Lion of Ingenuity")] for "
if(prob(33))
newMsg.body += "their actions at the Battle of [pick(locstring,"REDACTED")]."
else if(prob(50))
newMsg.body += "their contribution to the colony of [locstring]."
else
newMsg.body += "their loyal service over the years."
else if(prob(33))
newMsg.body += " They are expected to settle down in [affected_dest.name], where they have been granted a handsome pension."
else if(prob(50))
newMsg.body += " The news was broken on [affected_dest.name] earlier today, where they cited reasons of '[pick("health","family","REDACTED")]'"
else
newMsg.body += " Administration Aerospace wishes them the best of luck in their retirement ceremony on [affected_dest.name]."
if(CELEBRITY_DEATH)
newMsg.body = "It is with regret today that we announce the sudden passing of the "
if(prob(33))
newMsg.body += "[pick("distinguished","decorated","veteran","highly respected")] \
[pick("Ship's Captain","Vice Admiral","Colonel","Lieutenant Colonel")] "
else if(prob(50))
newMsg.body += "[pick("award-winning","popular","highly respected","trend-setting")] \
[pick("comedian","singer/songwright","artist","playwright","TV personality","model")] "
else
newMsg.body += "[pick("successful","highly respected","ingenious","esteemed")] \
[pick("academic","Professor","Doctor","Scientist")] "
newMsg.body += "[random_name(pick(MALE,FEMALE))] on [affected_dest.name] [pick("last week","yesterday","this morning","two days ago","three days ago")]\
[pick(". Assassination is suspected, but the perpetrators have not yet been brought to justice",\
" due to Syndicate infiltrators (since captured)",\
" during an industrial accident",\
" due to [pick("heart failure","kidney failure","liver failure","brain hemorrhage")]")]"
if(BARGAINS)
newMsg.body += "BARGAINS! BARGAINS! BARGAINS! Commerce Control on [affected_dest.name] wants you to know that everything must go! Across all retail centres, \
all goods are being slashed, and all retailors are onboard - so come on over for the \[shopping\] time of your life."
if(SONG_DEBUT)
newMsg.body += "[pick("Singer","Singer/songwriter","Saxophonist","Pianist","Guitarist","TV personality","Star")] [random_name(pick(MALE,FEMALE))] \
announced the debut of their new [pick("single","album","EP","label")] '[pick("Everyone's","Look at the","Baby don't eye those","All of those","Dirty nasty")] \
[pick("roses","three stars","starships","nanobots","cyborgs","Skrell","Sren'darr")] \
[pick("on Venus","on Reade","on Moghes","in my hand","slip through my fingers","die for you","sing your heart out","fly away")]' \
with [pick("pre-puchases available","a release tour","cover signings","a launch concert")] on [affected_dest.name]."
if(MOVIE_RELEASE)
newMsg.body += "From the [pick("desk","home town","homeworld","mind")] of [pick("acclaimed","award-winning","popular","stellar")] \
[pick("playwright","author","director","actor","TV star")] [random_name(pick(MALE,FEMALE))] comes the latest sensation: '\
[pick("Deadly","The last","Lost","Dead")] [pick("Starships","Warriors","outcasts","Tajarans","Unathi","Skrell")] \
[pick("of","from","raid","go hunting on","visit","ravage","pillage","destroy")] \
[pick("Moghes","Earth","Biesel","Ahdomai","S'randarr","the Void","the Edge of Space")]'.\
. Own it on webcast today, or visit the galactic premier on [affected_dest.name]!"
if(BIG_GAME_HUNTERS)
newMsg.body += "Game hunters on [affected_dest.name] "
if(prob(33))
newMsg.body += "were surprised when an unusual species experts have since identified as \
[pick("a subclass of mammal","a divergent abhuman species","an intelligent species of lemur","organic/cyborg hybrids")] turned up. Believed to have been brought in by \
[pick("alien smugglers","early colonists","syndicate raiders","unwitting tourists")], this is the first such specimen discovered in the wild."
else if(prob(50))
newMsg.body += "were attacked by a vicious [pick("nas'r","diyaab","samak","predator which has not yet been identified")]\
. Officials urge caution, and locals are advised to stock up on armaments."
else
newMsg.body += "brought in an unusually [pick("valuable","rare","large","vicious","intelligent")] [pick("mammal","predator","farwa","samak")] for inspection \
[pick("today","yesterday","last week")]. Speculators suggest they may be tipped to break several records."
if(GOSSIP)
newMsg.body += "[pick("TV host","Webcast personality","Superstar","Model","Actor","Singer")] [random_name(pick(MALE,FEMALE))] "
if(prob(33))
newMsg.body += "and their partner announced the birth of their [pick("first","second","third")] child on [affected_dest.name] early this morning. \
Doctors say the child is well, and the parents are considering "
if(prob(50))
newMsg.body += capitalize(pick(first_names_female))
else
newMsg.body += capitalize(pick(first_names_male))
newMsg.body += " for the name."
else if(prob(50))
newMsg.body += "announced their [pick("split","break up","marriage","engagement")] with [pick("TV host","webcast personality","superstar","model","actor","singer")] \
[random_name(pick(MALE,FEMALE))] at [pick("a society ball","a new opening","a launch","a club")] on [affected_dest.name] yesterday, pundits are shocked."
else
newMsg.body += "is recovering from plastic surgery in a clinic on [affected_dest.name] for the [pick("second","third","fourth")] time, reportedly having made the decision in response to "
newMsg.body += "[pick("unkind comments by an ex","rumours started by jealous friends",\
"the decision to be dropped by a major sponsor","a disasterous interview on Tau Ceti Tonight")]."
if(TOURISM)
newMsg.body += "Tourists are flocking to [affected_dest.name] after the surprise announcement of [pick("major shopping bargains by a wily retailer",\
"a huge new ARG by a popular entertainment company","a secret tour by popular artiste [random_name(pick(MALE,FEMALE))]")]. \
Tau Ceti Daily is offering discount tickets for two to see [random_name(pick(MALE,FEMALE))] live in return for eyewitness reports and up to the minute coverage."
for(var/datum/feed_channel/FC in news_network.network_channels)
if(FC.channel_name == "Tau Ceti Daily")
FC.messages += newMsg
break
for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
NEWSCASTER.newsAlert("Tau Ceti Daily")
/datum/event/trivial_news
endWhen = 10
/datum/event/trivial_news/announce()
//copy-pasted from the admin verbs to submit new newscaster messages
var/datum/feed_message/newMsg = new /datum/feed_message
newMsg.author = "Editor Mike Hammers"
//newMsg.is_admin_message = 1
var/datum/trade_destination/affected_dest = pick(weighted_mundaneevent_locations)
newMsg.body = pick(
"Tree stuck in tajaran; firefighters baffled.",\
"Armadillos want aardvarks removed from dictionary claims 'here first'.",\
"Angel found dancing on pinhead ordered to stop; cited for public nuisance.",\
"Letters claim they are better than number; 'Always have been'.",\
"Pens proclaim pencils obsolete, 'lead is dead'.",\
"Rock and paper sues scissors for discrimination.",\
"Steak tell-all book reveals he never liked sitting by potato.",\
"Woodchuck stops counting how many times hes chucked 'Never again'.",\
"[affected_dest.name] clerk first person able to pronounce '@*$%!'.",\
"[affected_dest.name] delis serving boiled paperback dictionaries, 'Adjectives chewy' customers declare.",\
"[affected_dest.name] weather deemed 'boring'; meteors and rad storms to be imported.",\
"Most [affected_dest.name] security officers prefer cream over sugar.",\
"Palindrome speakers conference in [affected_dest.name]; 'Wow!' says Otto.",\
"Question mark worshipped as deity by ancient [affected_dest.name] dwellers.",\
"Spilled milk causes whole [affected_dest.name] populace to cry.",\
"World largest carp patty at display on [affected_dest.name].",\
"'Here kitty kitty' no longer preferred tajaran retrieval technique.",\
"Man travels 7000 light years to retrieve lost hankie, 'It was my favourite'.",\
"New bowling lane that shoots mini-meteors at bowlers very popular.",\
"[pick("Unathi","Spacer")] gets tattoo of Tau Ceti on chest '[pick("CentComm","star","starship","asteroid")] tickles most'.",\
"Skrell marries computer; wedding attended by 100 modems.",\
"Chef reports successfully using harmonica as cheese grater.",\
"NanoTrasen invents handkerchief that says 'Bless you' after sneeze.",\
"Clone accused of posing for other cloness school photo.",\
"Clone accused of stealing other cloness employee of the month award.",\
"Woman robs station with hair dryer; crewmen love new style.",\
"This space for rent.",\
"[affected_dest.name] Baker Wins Pickled Crumpet Toss Three Years Running",\
"Skrell Scientist Discovers Abacus Can Be Used To Dry Towels",\
"Survey: 'Cheese Louise' Voted Best Pizza Restaurant In Tau Ceti",\
"I Was Framed, jokes [affected_dest.name] artist",\
"Mysterious Loud Rumbling Noises In [affected_dest.name] Found To Be Mysterious Loud Rumblings",\
"Alien ambassador becomes lost on [affected_dest.name], refuses to ask for directions",\
"Swamp Gas Verified To Be Exhalations Of Stars--Movie Stars--Long Passed",\
"Tainted Broccoli Weapon Of Choice For Syndicate Assassins",\
"Chefs Find Broccoli Effective Tool For Cutting Cheese",\
"Broccoli Found To Cause Grumpiness In Monkeys",\
"Survey: 80% Of People on [affected_dest.name] Love Clog-Dancing",\
"Giant Hairball Has Perfect Grammar But Rolls rr's Too Much, Linguists Say",\
"[affected_dest.name] Phonebooks Print All Wrong Numbers; Results In 15 New Marriages",\
"Tajaran Burglar Spotted on [affected_dest.name], Mistaken For Dalmatian",\
"Gibson Gazette Updates Frequently Absurd, Poll Indicates",\
"Esoteric Verbosity Culminates In Communicative Ennui, [affected_dest.name] Academics Note",\
"Taj Demand Longer Breaks, Cleaner Litter, Slower Mice",\
"Survey: 3 Out Of 5 Skrell Loathe Modern Art",\
"Skrell Scientist Discovers Gravity While Falling Down Stairs",\
"Boy Saves Tajaran From Tree on [affected_dest.name], Thousands Cheer",\
"Shipment Of Apples Overturns, [affected_dest.name] Diner Offers Applesauce Special",\
"Spotted Owl Spotted on [affected_dest.name]",\
"Humans Everywhere Agree: Purring Tajarans Are Happy Tajarans",\
"From The Desk Of Wise Guy Sammy: One Word In This Gazette Is Sdrawkcab",\
"From The Desk Of Wise Guy Sammy: It's Hard To Have Too Much Shelf Space",\
"From The Desk Of Wise Guy Sammy: Wine And Friendships Get Better With Age",\
"From The Desk Of Wise Guy Sammy: The Insides Of Golf Balls Are Mostly Rubber Bands",\
"From The Desk Of Wise Guy Sammy: You Don't Have To Fool All The People, Just The Right Ones",\
"From The Desk Of Wise Guy Sammy: If You Made The Mess, You Clean It Up",\
"From The Desk Of Wise Guy Sammy: It Is Easier To Get Forgiveness Than Permission",\
"From The Desk Of Wise Guy Sammy: Check Your Facts Before Making A Fool Of Yourself",\
"From The Desk Of Wise Guy Sammy: You Can't Outwait A Bureaucracy",\
"From The Desk Of Wise Guy Sammy: It's Better To Yield Right Of Way Than To Demand It",\
"From The Desk Of Wise Guy Sammy: A Person Who Likes Cats Can't Be All Bad",\
"From The Desk Of Wise Guy Sammy: Help Is The Sunny Side Of Control",\
"From The Desk Of Wise Guy Sammy: Two Points Determine A Straight Line",\
"From The Desk Of Wise Guy Sammy: Reading Improves The Mind And Lifts The Spirit",\
"From The Desk Of Wise Guy Sammy: Better To Aim High And Miss Then To Aim Low And Hit",\
"From The Desk Of Wise Guy Sammy: Meteors Often Strike The Same Place More Than Once",\
"Tommy B. Saif Sez: Look Both Ways Before Boarding The Shuttle",\
"Tommy B. Saif Sez: Hold On; Sudden Stops Sometimes Necessary",\
"Tommy B. Saif Sez: Keep Fingers Away From Moving Panels",\
"Tommy B. Saif Sez: No Left Turn, Except Shuttles",\
"Tommy B. Saif Sez: Return Seats And Trays To Their Proper Upright Position",\
"Tommy B. Saif Sez: Eating And Drinking In Docking Bays Is Prohibited",\
"Tommy B. Saif Sez: Accept No Substitutes, And Don't Be Fooled By Imitations",\
"Tommy B. Saif Sez: Do Not Remove This Tag Under Penalty Of Law",\
"Tommy B. Saif Sez: Always Mix Thoroughly When So Instructed",\
"Tommy B. Saif Sez: Try To Keep Six Month's Expenses In Reserve",\
"Tommy B. Saif Sez: Change Not Given Without Purchase",\
"Tommy B. Saif Sez: If You Break It, You Buy It",\
"Tommy B. Saif Sez: Reservations Must Be Cancelled 48 Hours Prior To Event To Obtain Refund",\
"Doughnuts: Is There Anything They Can't Do",\
"If Tin Whistles Are Made Of Tin, What Do They Make Foghorns Out Of?",\
"Broccoli discovered to be colonies of tiny aliens with murder on their minds"\
)
for(var/datum/feed_channel/FC in news_network.network_channels)
if(FC.channel_name == "The Gibson Gazette")
FC.messages += newMsg
break
for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
NEWSCASTER.newsAlert("The Gibson Gazette")
@@ -1,4 +1,7 @@
var/list/weighted_randomevent_locations = list()
var/list/weighted_mundaneevent_locations = list()
/datum/trade_destination
var/name = ""
var/description = ""
@@ -8,6 +11,10 @@
var/can_shuttle_here = 0 //one day crew from the exodus will be able to travel to this destination
var/list/viable_random_events = list()
var/list/temp_price_change[BIOMEDICAL]
var/list/viable_mundane_events = list()
/datum/trade_destination/proc/get_custom_eventstring(var/event_type)
return null
//distance is measured in AU and co-relates to travel time
/datum/trade_destination/centcomm
@@ -17,6 +24,7 @@
willing_to_buy = list()
willing_to_sell = list()
viable_random_events = list(SECURITY_BREACH, CORPORATE_ATTACK, AI_LIBERATION)
viable_mundane_events = list(ELECTION, RESIGNATION, CELEBRITY_DEATH)
/datum/trade_destination/anansi
name = "NSS Anansi"
@@ -25,6 +33,13 @@
willing_to_buy = list()
willing_to_sell = list()
viable_random_events = list(SECURITY_BREACH, CULT_CELL_REVEALED, BIOHAZARD_OUTBREAK, PIRATES, ALIEN_RAIDERS)
viable_mundane_events = list(RESEARCH_BREAKTHROUGH, RESEARCH_BREAKTHROUGH, BARGAINS, GOSSIP)
/datum/trade_destination/anansi/get_custom_eventstring(var/event_type)
if(event_type == RESEARCH_BREAKTHROUGH)
return "Thanks to research conducted on the NSS Anansi, Second Red Cross Society wishes to announce a major breakthough in the field of \
[pick("mind-machine interfacing","neuroscience","nano-augmentation","genetics")]. NanoTrasen is expected to announce a co-exploitation deal within the fortnight."
return null
/datum/trade_destination/icarus
name = "NMV Icarus"
@@ -41,6 +56,13 @@
willing_to_buy = list()
willing_to_sell = list()
viable_random_events = list(INDUSTRIAL_ACCIDENT, PIRATES, CORPORATE_ATTACK)
viable_mundane_events = list(RESEARCH_BREAKTHROUGH, RESEARCH_BREAKTHROUGH)
/datum/trade_destination/redolant/get_custom_eventstring(var/event_type)
if(event_type == RESEARCH_BREAKTHROUGH)
return "Thanks to research conducted on the OAV Redolant, Osiris Atmospherics wishes to announce a major breakthough in the field of \
[pick("plasma research","high energy flux capacitance","super-compressed materials","theoretical particle physics")]. NanoTrasen is expected to announce a co-exploitation deal within the fortnight."
return null
/datum/trade_destination/beltway
name = "Beltway mining chain"
@@ -49,6 +71,7 @@
willing_to_buy = list()
willing_to_sell = list()
viable_random_events = list(PIRATES, INDUSTRIAL_ACCIDENT)
viable_mundane_events = list(TOURISM)
/datum/trade_destination/biesel
name = "Biesel"
@@ -57,6 +80,7 @@
willing_to_buy = list()
willing_to_sell = list()
viable_random_events = list(RIOTS, INDUSTRIAL_ACCIDENT, BIOHAZARD_OUTBREAK, CULT_CELL_REVEALED, FESTIVAL, MOURNING)
viable_mundane_events = list(BARGAINS, GOSSIP, SONG_DEBUT, MOVIE_RELEASE, ELECTION, TOURISM, RESIGNATION, CELEBRITY_DEATH)
/datum/trade_destination/new_gibson
name = "New Gibson"
@@ -65,6 +89,7 @@
willing_to_buy = list()
willing_to_sell = list()
viable_random_events = list(RIOTS, INDUSTRIAL_ACCIDENT, BIOHAZARD_OUTBREAK, CULT_CELL_REVEALED, FESTIVAL, MOURNING)
viable_mundane_events = list(ELECTION, TOURISM, RESIGNATION)
/datum/trade_destination/luthien
name = "Luthien"
@@ -73,6 +98,7 @@
willing_to_buy = list()
willing_to_sell = list()
viable_random_events = list(WILD_ANIMAL_ATTACK, CULT_CELL_REVEALED, FESTIVAL, MOURNING, ANIMAL_RIGHTS_RAID, ALIEN_RAIDERS)
viable_mundane_events = list(ELECTION, TOURISM, BIG_GAME_HUNTERS, RESIGNATION)
/datum/trade_destination/reade
name = "Reade"
@@ -81,5 +107,4 @@
willing_to_buy = list()
willing_to_sell = list()
viable_random_events = list(WILD_ANIMAL_ATTACK, CULT_CELL_REVEALED, FESTIVAL, MOURNING, ANIMAL_RIGHTS_RAID, ALIEN_RAIDERS)
var/list/tradeable_destinations = typesof(/datum/trade_destination) - /datum/trade_destination
viable_mundane_events = list(ELECTION, TOURISM, BIG_GAME_HUNTERS, RESIGNATION)
@@ -0,0 +1,70 @@
var/list/station_departments = list("Command", "Medical", "Engineering", "Science", "Security", "Cargo", "Civilian")
// The department the job belongs to.
/datum/job/var/department = null
// Whether this is a head position
/datum/job/var/head_position = 0
/datum/job/captain/department = "Command"
/datum/job/captain/head_position = 1
/datum/job/hop/department = "Civilian"
/datum/job/hop/head_position = 1
/datum/job/assistant/department = "Civilian"
/datum/job/bartender/department = "Civilian"
/datum/job/chef/department = "Civilian"
/datum/job/hydro/department = "Civilian"
/datum/job/mining/department = "Civilian"
/datum/job/janitor/department = "Civilian"
/datum/job/librarian/department = "Civilian"
/datum/job/lawyer/department = "Civilian"
/datum/job/chaplain/department = "Civilian"
/datum/job/qm/department = "Cargo"
/datum/job/qm/head_position = 1
/datum/job/cargo_tech/department = "Cargo"
/datum/job/chief_engineer/department = "Engineering"
/datum/job/chief_engineer/head_position = 1
/datum/job/engineer/department = "Engineering"
/datum/job/atmos/department = "Engineering"
/datum/job/cmo/department = "Medical"
/datum/job/cmo/head_position = 1
/datum/job/doctor/department = "Medical"
/datum/job/chemist/department = "Medical"
/datum/job/geneticist/department = "Medical"
/datum/job/psychiatrist/department = "Medical"
/datum/job/rd/department = "Science"
/datum/job/rd/head_position = 1
/datum/job/scientist/department = "Science"
/datum/job/roboticist/department = "Science"
/datum/job/hos/department = "Security"
/datum/job/hos/head_position = 1
/datum/job/warden/department = "Security"
/datum/job/detective/department = "Security"
/datum/job/officer/department = "Security"
+26 -10
View File
@@ -2,6 +2,8 @@
//reactor areas
/area/engine
icon_state = "engine"
fore
name = "\improper Fore"
@@ -13,49 +15,63 @@
atmos_storage
name = "\improper Atmos storage"
icon_state = "engine_storage"
control
name = "\improper Control"
icon_state = "engine_control"
electrical_storage
name = "\improper Electrical storage"
engine_monitoring
name = "\improper Electrical storage"
icon_state = "engine_monitoring"
reactor_core
name = "\improper Reactor Core"
icon_state = "engine_core"
//icon_state = "engine_core"
reactor_gas
name = "Reactor Gas Storage"
icon_state = "engine_atmos"
//icon_state = "engine_atmos"
aux_control
name = "Reactor Auxiliary Control"
icon_state = "engine_aux"
//icon_state = "engine_aux"
turbine_control
name = "Turbine Control"
icon_state = "engine_turbine"
//icon_state = "engine_turbine"
reactor_airlock
name = "\improper Reactor Primary Entrance"
icon_state = "engine_airlock"
//icon_state = "engine_airlock"
reactor_fuel_storage
name = "Reactor Fuel Storage"
icon_state = "engine_fuel"
//icon_state = "engine_fuel"
reactor_fuel_ports
name = "\improper Reactor Fuel Ports"
icon_state = "engine_port"
//icon_state = "engine_port"
generators
name = "\improper Generator Room"
icon_state = "engine_generators"
//icon_state = "engine_generators"
port_gyro_bay
name = "\improper Port Gyrotron Bay"
icon_state = "engine_starboardgyro"
//icon_state = "engine_starboardgyro"
starboard_gyro_bay
name = "\improper Starboard Gyrotron Bay"
icon_state = "engine_portgyro"
//icon_state = "engine_portgyro"
storage
name = "\improper Engineering hallway"
icon_state = "engine_storage"
hallway
name = "\improper Engineering storage"
icon_state = "engine_hallway"
@@ -5,13 +5,13 @@
/obj/item/weapon/circuitboard/rust_core_control
name = "Circuit board (RUST core controller)"
build_path = "/obj/machinery/computer/rust_core_control"
origin_tech = "programming=3;engineering=4"
origin_tech = "programming=4;engineering=4"
datum/design/rust_core_control
name = "Circuit Design (RUST core controller)"
desc = "Allows for the construction of circuit boards used to build a core control console for the RUST fusion engine."
id = "rust_core_control"
req_tech = list("programming" = 3, "engineering" = 4)
req_tech = list("programming" = 4, "engineering" = 4)
build_type = IMPRINTER
materials = list("$glass" = 2000, "sacid" = 20)
build_path = "/obj/item/weapon/circuitboard/rust_core_control"
@@ -22,13 +22,13 @@ datum/design/rust_core_control
/obj/item/weapon/circuitboard/rust_fuel_control
name = "Circuit board (RUST fuel controller)"
build_path = "/obj/machinery/computer/rust_fuel_control"
origin_tech = "programming=3;engineering=4"
origin_tech = "programming=4;engineering=4"
datum/design/rust_fuel_control
name = "Circuit Design (RUST fuel controller)"
desc = "Allows for the construction of circuit boards used to build a fuel injector control console for the RUST fusion engine."
id = "rust_fuel_control"
req_tech = list("programming" = 3, "engineering" = 4)
req_tech = list("programming" = 4, "engineering" = 4)
build_type = IMPRINTER
materials = list("$glass" = 2000, "sacid" = 20)
build_path = "/obj/item/weapon/circuitboard/rust_fuel_control"
@@ -56,13 +56,13 @@ datum/design/rust_fuel_port
/obj/item/weapon/module/rust_fuel_compressor
name = "Internal circuitry (RUST fuel compressor)"
icon_state = "card_mod"
origin_tech = "materials=7;plasmatech=4"
origin_tech = "materials=6;plasmatech=4"
datum/design/rust_fuel_compressor
name = "Circuit Design (RUST fuel compressor)"
desc = "Allows for the construction of circuit boards used to build a fuel compressor of the RUST fusion engine."
id = "rust_fuel_compressor"
req_tech = list("materials" = 7, "plasmatech" = 4)
req_tech = list("materials" = 6, "plasmatech" = 4)
build_type = IMPRINTER
materials = list("$glass" = 2000, "sacid" = 20, "$plasma" = 3000, "$diamond" = 1000)
build_path = "/obj/item/weapon/module/rust_fuel_compressor"
@@ -74,7 +74,7 @@ datum/design/rust_fuel_compressor
name = "Internal circuitry (RUST tokamak core)"
build_path = "/obj/machinery/power/rust_core"
board_type = "machine"
origin_tech = "bluespace=3;plasmatech=4;magnets=5;materials=6;powerstorage=6"
origin_tech = "bluespace=3;plasmatech=4;magnets=5;powerstorage=6"
frame_desc = "Requires 2 Pico Manipulators, 1 Ultra Micro-Laser, 5 Pieces of Cable, 1 Subspace Crystal and 1 Console Screen."
req_components = list(
"/obj/item/weapon/stock_parts/manipulator/pico" = 2,
@@ -87,7 +87,7 @@ datum/design/rust_core
name = "Internal circuitry (RUST tokamak core)"
desc = "The circuit board that for a RUST-pattern tokamak fusion core."
id = "pacman"
req_tech = list(bluespace = 3, plasmatech = 4, magnets = 5, materials = 6, powerstorage = 6)
req_tech = list(bluespace = 3, plasmatech = 4, magnets = 5, powerstorage = 6)
build_type = IMPRINTER
reliability_base = 79
materials = list("$glass" = 2000, "sacid" = 20, "$plasma" = 3000, "$diamond" = 2000)
@@ -1,7 +1,8 @@
/obj/machinery/computer/rust_core_control
name = "RUST Core Control"
icon = 'code/WorkInProgress/Cael_Aislinn/Rust/rust.dmi'
icon_state = "core"
icon_state = "core_control"
var/list/connected_devices = list()
var/id_tag = "allan remember to update this before you leave"
var/scan_range = 25
@@ -113,6 +113,8 @@ Deuterium-tritium fusion: 4.5 x 10^7 K
minor_radius = field_strength * 0.2125// max = 8.625
volume_covered = PI * major_radius * minor_radius * 2.5 * 2.5 * 1000
processing_objects.Add(src)
/obj/effect/rust_em_field/process()
//make sure the field generator is still intact
if(!owned_core)
@@ -228,9 +230,9 @@ Deuterium-tritium fusion: 4.5 x 10^7 K
frequency = new_frequency
/obj/effect/rust_em_field/proc/AddEnergy(var/a_energy, var/a_mega_energy, var/a_frequency)
var/energy_loss_ratio = src.frequency / abs(a_frequency - src.frequency)
if(a_frequency == src.frequency)
energy_loss_ratio = 0
var/energy_loss_ratio = 0
if(a_frequency != src.frequency)
energy_loss_ratio = 1 / abs(a_frequency - src.frequency)
energy += a_energy - a_energy * energy_loss_ratio
mega_energy += a_mega_energy - a_mega_energy * energy_loss_ratio
@@ -650,4 +652,5 @@ Deuterium-tritium fusion: 4.5 x 10^7 K
del (catcher)
RadiateAll()
processing_objects.Remove(src)
..()
@@ -64,7 +64,7 @@ max volume of plasma storeable by the field = the total volume of a number of ti
directwired = 1
var/state = 0
var/locked = 0
var/locked = 1
var/remote_access_enabled = 1
/obj/machinery/power/rust_core/process()
@@ -180,7 +180,7 @@ max volume of plasma storeable by the field = the total volume of a number of ti
return
var/dat = ""
if(!powernet || locked)
if(stat & NOPOWER || locked || state != 2)
dat += "<i>The console is dark and nonresponsive.</i>"
else
dat += "<b>RUST Tokamak pattern Electromagnetic Field Generator</b><br>"
@@ -6,7 +6,6 @@
icon_state = "port2"
density = 0
var/obj/item/weapon/fuel_assembly/cur_assembly
layer = 4
var/busy = 0
anchored = 1
@@ -22,26 +21,25 @@
user.drop_item()
I.loc = src
icon_state = "port1"
user << "\blue You insert [I] into [src]. Touch the panel again to insert [I] into the injector."
/obj/machinery/rust_fuel_assembly_port/attack_hand(mob/user)
add_fingerprint(user)
if(stat & (BROKEN|NOPOWER) || opened)
return
if(!busy)
busy = 1
if(cur_assembly)
spawn(30)
if(!try_insert_assembly())
spawn(30)
eject_assembly()
busy = 0
else
busy = 0
if(cur_assembly)
if(try_insert_assembly())
user << "\blue \icon[src] [src] inserts it's fuel rod assembly into an injector."
else
spawn(30)
try_draw_assembly()
busy = 0
if(eject_assembly())
user << "\red \icon[src] [src] ejects it's fuel assembly. Check the fuel injector status."
else if(try_draw_assembly())
user << "\blue \icon[src] [src] draws a fuel rod assembly from an injector."
else if(try_draw_assembly())
user << "\blue \icon[src] [src] draws a fuel rod assembly from an injector."
else
user << "\red \icon[src] [src] was unable to draw a fuel rod assembly from an injector."
/obj/machinery/rust_fuel_assembly_port/proc/try_insert_assembly()
var/success = 0
@@ -53,6 +51,8 @@
break
if(I.cur_assembly)
break
if(I.state != 2)
break
I.cur_assembly = cur_assembly
cur_assembly.loc = I
@@ -60,21 +60,14 @@
icon_state = "port0"
success = 1
if(success)
src.visible_message("\blue \icon[src] a green light flashes on [src] as it inserts it's fuel rod assembly into an injector.")
else
src.visible_message("\red \icon[src] a red light flashes on [src] as it attempts to insert it's fuel rod assembly into an injector.")
return success
/obj/machinery/rust_fuel_assembly_port/proc/eject_assembly()
if(cur_assembly)
var/turf/check_turf = get_step(get_turf(src), src.dir)
cur_assembly.loc = check_turf
cur_assembly.loc = get_step(get_turf(src), src.dir)
cur_assembly = null
icon_state = "port0"
return 1
else
src.visible_message("\red \icon[src] a red light flashes on [src] as it attempts to eject it's fuel rod assembly.")
/obj/machinery/rust_fuel_assembly_port/proc/try_draw_assembly()
var/success = 0
@@ -88,7 +81,7 @@
break
if(I.injecting)
break
if(I.stat != 2)
if(I.state != 2)
break
cur_assembly = I.cur_assembly
@@ -97,10 +90,6 @@
icon_state = "port1"
success = 1
if(success)
src.visible_message("\icon[src] a blue light flashes on [src] as it draws a fuel rod assembly from an injector.")
else
src.visible_message("\red \icon[src] a red light flashes on [src] as it attempts to draw a fuel rod assembly from an injector.")
return success
/*
@@ -42,7 +42,7 @@
dir = ndir
else
has_electronics = 3
opened = 1
opened = 0
icon_state = "port0"
//20% easier to read than apc code
@@ -2,26 +2,17 @@ var/const/max_assembly_amount = 300
/obj/machinery/rust_fuel_compressor
icon = 'code/WorkInProgress/Cael_Aislinn/Rust/rust.dmi'
icon_state = "fuel_compressor0"
icon_state = "fuel_compressor1"
name = "Fuel Compressor"
var/list/new_assembly_quantities
var/list/new_assembly_quantities = list("Deuterium" = 200,"Tritium" = 100,"Helium-3" = 0,"Lithium-6" = 0,"Silver" = 0)
var/compressed_matter = 0
anchored = 1
layer = 2.9
var/opened = 1 //0=closed, 1=opened
var/locked = 0
var/has_electronics = 0 // 0 - none, bit 1 - circuitboard, bit 2 - wires
/obj/machinery/rust_fuel_compressor/New()
new_assembly_quantities = new/list
spawn(0)
new_assembly_quantities["Deuterium"] = 200
new_assembly_quantities["Tritium"] = 100
//
new_assembly_quantities["Helium-3"] = 0
new_assembly_quantities["Lithium-6"] = 0
new_assembly_quantities["Silver"] = 0
/obj/machinery/rust_fuel_compressor/attack_ai(mob/user)
attack_hand(user)
@@ -50,7 +41,7 @@ var/const/max_assembly_amount = 300
if(locked)
t += "Swipe your ID to unlock this console."
else
t += "Compressed matter in storage: [compressed_matter] <A href='?src=\ref[src];eject_matter=1'>\[Eject all\]</a>"
t += "Compressed matter in storage: [compressed_matter] <A href='?src=\ref[src];eject_matter=1'>\[Eject all\]</a><br>"
t += "<A href='?src=\ref[src];activate=1'><b>Activate Fuel Synthesis</b></A><BR> (fuel assemblies require no more than [max_assembly_amount] rods).<br>"
t += "<hr>"
t += "- New fuel assembly constituents:- <br>"
@@ -72,10 +63,15 @@ var/const/max_assembly_amount = 300
usr.machine = null
if( href_list["eject_matter"] )
var/ejected = 0
while(compressed_matter > 10)
new /obj/item/weapon/rcd_ammo(src.loc)
new /obj/item/weapon/rcd_ammo(get_step(get_turf(src), src.dir))
compressed_matter -= 10
src.visible_message("\blue \icon[src] [src] ejects some compressed matter units.")
ejected = 1
if(ejected)
usr << "\blue \icon[src] [src] ejects some compressed matter units."
else
usr << "\red \icon[src] there are no more compressed matter units in [src]."
if( href_list["activate"] )
//world << "\blue New fuel rod assembly"
@@ -83,7 +79,8 @@ var/const/max_assembly_amount = 300
var/fail = 0
var/old_matter = compressed_matter
for(var/reagent in new_assembly_quantities)
var/req_matter = F.rod_quantities[reagent] / 10
var/req_matter = new_assembly_quantities[reagent] / 30
//world << "[reagent] matter: [req_matter]/[compressed_matter]"
if(req_matter <= compressed_matter)
F.rod_quantities[reagent] = new_assembly_quantities[reagent]
compressed_matter -= req_matter
@@ -94,10 +91,12 @@ var/const/max_assembly_amount = 300
if(fail)
del(F)
compressed_matter = old_matter
src.visible_message("\red \icon[src] [src] flashes red: \'Out of matter.\'")
usr << "\red \icon[src] [src] flashes red: \'Out of matter.\'"
else
F.loc = src.loc
F.loc = get_step(get_turf(src), src.dir)
F.percent_depleted = 0
if(compressed_matter < 0.034)
compressed_matter = 0
if( href_list["change_reagent"] )
var/cur_reagent = href_list["change_reagent"]
@@ -42,9 +42,9 @@
dir = ndir
else
has_electronics = 3
opened = 1
opened = 0
locked = 0
icon_state = "port0"
icon_state = "fuel_compressor1"
//20% easier to read than apc code
pixel_x = (dir & 3)? 0 : (dir == 4 ? 32 : -32)
@@ -1,6 +1,6 @@
/obj/machinery/computer/rust_fuel_control
name = "Fuel Injection Control"
name = "RUST Fuel Injection Control"
icon = 'code/WorkInProgress/Cael_Aislinn/Rust/rust.dmi'
icon_state = "fuel"
var/list/connected_injectors = list()
@@ -4,7 +4,7 @@
icon = 'code/WorkInProgress/Cael_Aislinn/Rust/rust.dmi'
icon_state = "injector0"
density = 1
var/state = 0
var/state = 2
var/locked = 0
var/obj/item/weapon/fuel_assembly/cur_assembly
var/fuel_usage = 0.0001 //percentage of available fuel to use per cycle
@@ -17,13 +17,14 @@
use_power = 1
idle_power_usage = 10
active_power_usage = 500
directwired = 0
var/remote_access_enabled = 1
var/cached_power_avail = 0
var/emergency_insert_ready = 0
/obj/machinery/power/rust_fuel_injector/process()
if(injecting)
if(stat & BROKEN || !powernet)
if(stat & (BROKEN|NOPOWER))
StopInjecting()
else
Inject()
@@ -74,7 +75,7 @@
state = 2
user << "You weld the [src] to the floor."
connect_to_network()
src.directwired = 1
//src.directwired = 1
else
user << "\red You need more welding fuel to complete this task."
if(2)
@@ -88,7 +89,7 @@
state = 1
user << "You cut the [src] free from the floor."
disconnect_from_network()
src.directwired = 0
//src.directwired = 0
else
user << "\red You need more welding fuel to complete this task."
return
@@ -140,7 +141,7 @@
return
var/dat = ""
if (!powernet || locked || state != 2)
if (stat & NOPOWER || locked || state != 2)
dat += "<i>The console is dark and nonresponsive.</i>"
else
dat += "<B>Reactor Core Fuel Injector</B><hr>"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 42 KiB

@@ -2,14 +2,14 @@
//gimmicky hack to collect particles and direct them into the field
/obj/effect/rust_particle_catcher
icon = 'effects.dmi'
icon_state = "energynet"
density = 0
anchored = 1
invisibility = 101
layer = 4
var/obj/effect/rust_em_field/parent
var/mysize = 0
invisibility = 101
/*/obj/effect/rust_particle_catcher/New()
for(var/obj/machinery/rust/em_field/field in range(6))
parent = field
@@ -1,4 +1,30 @@
////////////////////////////////////////
// External Shield Generator
/obj/item/weapon/circuitboard/shield_gen_ex
name = "Circuit board (Experimental hull shield generator)"
board_type = "machine"
build_path = "/obj/machinery/shield_gen/external"
origin_tech = "bluespace=4;plasmatech=3"
frame_desc = "Requires 2 Pico Manipulators, 1 Subspace Transmitter, 5 Pieces of cable, 1 Subspace Crystal, 1 Subspace Amplifier and 1 Console Screen."
req_components = list(
"/obj/item/weapon/stock_parts/manipulator/pico" = 2,
"/obj/item/weapon/stock_parts/subspace/transmitter" = 1,
"/obj/item/weapon/stock_parts/subspace/crystal" = 1,
"/obj/item/weapon/stock_parts/subspace/amplifier" = 1,
"/obj/item/weapon/stock_parts/console_screen" = 1,
"/obj/item/weapon/cable_coil" = 5)
datum/design/shield_gen_ex
name = "Circuit Design (Experimental hull shield generator)"
desc = "Allows for the construction of circuit boards used to build an experimental hull shield generator."
id = "shield_gen"
req_tech = list("bluespace" = 4, "plasmatech" = 3)
build_type = IMPRINTER
materials = list("$glass" = 2000, "sacid" = 20, "$plasma" = 10000, "$diamond" = 5000, "$gold" = 10000)
build_path = "/obj/machinery/shield_gen/external"
////////////////////////////////////////
// Shield Generator
@@ -17,8 +43,8 @@
"/obj/item/weapon/cable_coil" = 5)
datum/design/shield_gen
name = "Circuit Design (Experimental hull shield generator)"
desc = "Allows for the construction of circuit boards used to build an experimental hull shield generator."
name = "Circuit Design (Experimental shield generator)"
desc = "Allows for the construction of circuit boards used to build an experimental shield generator."
id = "shield_gen"
req_tech = list("bluespace" = 4, "plasmatech" = 3)
build_type = IMPRINTER
@@ -9,38 +9,41 @@
anchored = 1
layer = 2.1
density = 0
invisibility = 2
invisibility = 101
var/strength = 0
var/obj/machinery/shield_gen/parent
var/stress = 0
/obj/effect/energy_field/ex_act(var/severity)
Stress(0.5 + severity)
/obj/effect/energy_field/bullet_act(var/obj/item/projectile/Proj)
Stress(1 + 1 * (Proj.damage / 100))
Stress(Proj.damage / 10)
/obj/effect/energy_field/meteorhit(obj/effect/meteor/M as obj)
if(M)
walk(M,0)
Stress(2)
/obj/effect/energy_field/proc/Stress(var/severity)
strength -= severity
stress += severity
//if we take too much damage, drop out - the generator will bring us back up if we have enough power
if(strength < 1)
invisibility = 2
invisibility = 101
density = 0
else if(strength >= 1)
invisibility = 0
density = 1
/obj/effect/energy_field/proc/Strengthen(var/severity)
strength += severity
//if we take too much damage, drop out - the generator will bring us back up if we have enough power
if(strength > 1)
if(strength >= 1)
invisibility = 0
density = 1
else if(strength < 1)
invisibility = 101
density = 0
/obj/effect/energy_field/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
//Purpose: Determines if the object (or airflow) can pass this atom.
@@ -49,4 +52,4 @@
//Outputs: Boolean if can pass.
//return (!density || !height || air_group)
return density
return !density
@@ -10,7 +10,6 @@
var/active = 1
density = 1
anchored = 1
var/obj/machinery/shield_gen/target_generator
var/stored_charge = 0
var/time_since_fail = 100
var/max_charge = 1000000
@@ -29,39 +28,84 @@
spawn(10)
for(var/obj/machinery/shield_gen/possible_gen in range(1, src))
if(get_dir(src, possible_gen) == src.dir)
target_generator = possible_gen
possible_gen.owned_capacitor = src
break
..()
/obj/machinery/shield_capacitor/verb/rotate()
set name = "Rotate Clockwise"
set category = "Object"
set src in oview(1)
/obj/machinery/shield_capacitor/attackby(obj/item/W, mob/user)
if (src.anchored || usr:stat)
usr << "It is fastened to the floor!"
return 0
src.dir = turn(src.dir, 270)
target_generator = locate() in get_step(src,dir)
if(target_generator && !target_generator.owned_capacitor)
target_generator.owned_capacitor = src
return 1
/obj/machinery/shield_capacitor/power_change()
if(stat & BROKEN)
icon_state = "broke"
else
if( powered() )
if (src.active)
icon_state = "capacitor"
else
icon_state = "capacitor"
stat &= ~NOPOWER
if(istype(W, /obj/item/weapon/card/id))
var/obj/item/weapon/card/id/C = W
if(access_captain in C.access || access_security in C.access || access_engine in C.access)
src.locked = !src.locked
user << "Controls are now [src.locked ? "locked." : "unlocked."]"
updateDialog()
else
spawn(rand(0, 15))
src.icon_state = "capacitor"
stat |= NOPOWER
user << "\red Access denied."
else if(istype(W, /obj/item/weapon/card/emag))
if(prob(75))
src.locked = !src.locked
user << "Controls are now [src.locked ? "locked." : "unlocked."]"
updateDialog()
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
else if(istype(W, /obj/item/weapon/wrench))
src.anchored = !src.anchored
src.visible_message("\blue \icon[src] [src] has been [anchored ? "bolted to the floor" : "unbolted from the floor"] by [user].")
spawn(0)
for(var/obj/machinery/shield_gen/gen in range(1, src))
if(get_dir(src, gen) == src.dir)
if(!src.anchored && gen.owned_capacitor == src)
gen.owned_capacitor = null
break
else if(src.anchored && !gen.owned_capacitor)
gen.owned_capacitor = src
break
gen.updateDialog()
updateDialog()
else
..()
/obj/machinery/shield_capacitor/attack_paw(user as mob)
return src.attack_hand(user)
/obj/machinery/shield_capacitor/attack_ai(user as mob)
return src.attack_hand(user)
/obj/machinery/shield_capacitor/attack_hand(mob/user)
if(stat & (NOPOWER|BROKEN))
return
interact(user)
/obj/machinery/shield_capacitor/interact(mob/user)
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
if (!istype(user, /mob/living/silicon))
user.unset_machine()
user << browse(null, "window=shield_capacitor")
return
var/t = "<B>Shield Capacitor Control Console</B><br><br>"
if(locked)
t += "<i>Swipe your ID card to begin.</i>"
else
t += "This capacitor is: [active ? "<font color=green>Online</font>" : "<font color=red>Offline</font>" ] <a href='?src=\ref[src];toggle=1'>[active ? "\[Deactivate\]" : "\[Activate\]"]</a><br>"
t += "[time_since_fail > 2 ? "<font color=green>Charging stable.</font>" : "<font color=red>Warning, low charge!</font>"]<br>"
t += "Charge: [stored_charge] Watts ([100 * stored_charge/max_charge]%)<br>"
t += "Charge rate: \
<a href='?src=\ref[src];charge_rate=[-max_charge_rate]'>\[min\]</a> \
<a href='?src=\ref[src];charge_rate=-1000'>\[--\]</a> \
<a href='?src=\ref[src];charge_rate=-100'>\[-\]</a>[charge_rate] Watts/sec \
<a href='?src=\ref[src];charge_rate=100'>\[+\]</a> \
<a href='?src=\ref[src];charge_rate=1000'>\[++\]</a> \
<a href='?src=\ref[src];charge_rate=[max_charge_rate]'>\[max\]</a><br>"
t += "<hr>"
t += "<A href='?src=\ref[src]'>Refresh</A> "
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
user << browse(t, "window=shield_capacitor;size=500x800")
user.set_machine(src)
/obj/machinery/shield_capacitor/process()
//
@@ -78,52 +122,12 @@
time_since_fail++
if(stored_charge < active_power_usage * 1.5)
time_since_fail = 0
//
updateDialog()
/obj/machinery/shield_capacitor/attackby(obj/item/W, mob/user)
/*if(istype(W, /obj/item/weapon/wrench))
if(active)
user << "Turn off the field generator first."
return
else if(state == 0)
state = 1
playsound(src.loc, 'Ratchet.ogg', 75, 1)
user << "You secure the external reinforcing bolts to the floor."
src.anchored = 1
return
else if(state == 1)
state = 0
playsound(src.loc, 'Ratchet.ogg', 75, 1)
user << "You undo the external reinforcing bolts."
src.anchored = 0
return*/
if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
if (src.allowed(user))
src.locked = !src.locked
user << "Controls are now [src.locked ? "locked." : "unlocked."]"
else
user << "\red Access denied."
else if(istype(W, /obj/item/weapon/wrench))
src.anchored = !src.anchored
src.visible_message("\blue \icon[src] [src] has been [anchored ? "bolted to the floor" : "unbolted from the floor"] by [user].")
else
src.add_fingerprint(user)
user << "\red You hit the [src.name] with your [W.name]!"
for(var/mob/M in viewers(src))
if(M == user) continue
M.show_message("\red The [src.name] has been hit with the [W.name] by [user.name]!")
/obj/machinery/shield_capacitor/Topic(href, href_list[])
..()
if( href_list["close"] )
usr << browse(null, "window=shield_capacitor")
usr.machine = null
usr.unset_machine()
return
if( href_list["toggle"] )
active = !active
@@ -140,20 +144,28 @@
//
updateDialog()
/obj/machinery/shield_capacitor/interact(mob/user)
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
if (!istype(user, /mob/living/silicon))
user.machine = null
user << browse(null, "window=shield_capacitor")
return
var/t = "<B>Shield Capacitor Control Console</B><BR>"
t += "[target_generator ? "<font color=green>Shield generator connected.</font>" : "<font color=red>Unable to locate shield generator!</font>"]<br>"
t += "This capacitor is: [active ? "<font color=green>Online</font>" : "<font color=red>Offline</font>" ] <a href='?src=\ref[src];toggle=1'>[active ? "\[Deactivate\]" : "\[Activate\]"]</a><br>"
t += "[time_since_fail > 2 ? "<font color=green>Charging stable.</font>" : "<font color=red>Warning, low charge!</font>"]<br>"
t += "Capacitor charge: [stored_charge] Watts ([100 * stored_charge/max_charge]%)<br>"
t += "Capacitor charge rate (approx): <a href='?src=\ref[src];charge_rate=[-max_charge_rate]'>\[min\]</a> <a href='?src=\ref[src];charge_rate=-1000'>\[--\]</a> <a href='?src=\ref[src];charge_rate=-100'>\[-\]</a>[charge_rate] Watts/sec <a href='?src=\ref[src];charge_rate=100'>\[+\]</a> <a href='?src=\ref[src];charge_rate=1000'>\[++\]</a> <a href='?src=\ref[src];charge_rate=[max_charge_rate]'>\[max\]</a><br>"
t += "<hr>"
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
/obj/machinery/shield_capacitor/power_change()
if(stat & BROKEN)
icon_state = "broke"
else
if( powered() )
if (src.active)
icon_state = "capacitor"
else
icon_state = "capacitor"
stat &= ~NOPOWER
else
spawn(rand(0, 15))
src.icon_state = "capacitor"
stat |= NOPOWER
user << browse(t, "window=shield_capacitor;size=500x800")
user.machine = src
/obj/machinery/shield_capacitor/verb/rotate()
set name = "Rotate capacitor clockwise"
set category = "Object"
set src in oview(1)
if (src.anchored)
usr << "It is fastened to the floor!"
return
src.dir = turn(src.dir, 270)
return
@@ -25,7 +25,6 @@
var/max_field_strength = 10
var/time_since_fail = 100
var/energy_conversion_rate = 0.01 //how many renwicks per watt?
var/flicker_shield_glitch = 1 //shield is slightly faulty and flickers - don't think this is working as intended
//
use_power = 1 //0 use nothing
//1 use idle power
@@ -38,14 +37,191 @@
for(var/obj/machinery/shield_capacitor/possible_cap in range(1, src))
if(get_dir(possible_cap, src) == possible_cap.dir)
owned_capacitor = possible_cap
possible_cap.target_generator = src
break
field = new/list()
..()
//copied from a copypaste. DRY, right?
/obj/machinery/shield_gen/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/weapon/card/id))
var/obj/item/weapon/card/id/C = W
if(access_captain in C.access || access_security in C.access || access_engine in C.access)
src.locked = !src.locked
user << "Controls are now [src.locked ? "locked." : "unlocked."]"
updateDialog()
else
user << "\red Access denied."
else if(istype(W, /obj/item/weapon/card/emag))
if(prob(75))
src.locked = !src.locked
user << "Controls are now [src.locked ? "locked." : "unlocked."]"
updateDialog()
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()
else if(istype(W, /obj/item/weapon/wrench))
src.anchored = !src.anchored
src.visible_message("\blue \icon[src] [src] has been [anchored?"bolted to the floor":"unbolted from the floor"] by [user].")
spawn(0)
for(var/obj/machinery/shield_gen/gen in range(1, src))
if(get_dir(src, gen) == src.dir)
if(!src.anchored && gen.owned_capacitor == src)
gen.owned_capacitor = null
break
else if(src.anchored && !gen.owned_capacitor)
gen.owned_capacitor = src
break
gen.updateDialog()
updateDialog()
else
..()
/obj/machinery/shield_gen/attack_paw(user as mob)
return src.attack_hand(user)
/obj/machinery/shield_gen/attack_ai(user as mob)
return src.attack_hand(user)
/obj/machinery/shield_gen/attack_hand(mob/user)
if(stat & (NOPOWER|BROKEN))
return
interact(user)
/obj/machinery/shield_gen/interact(mob/user)
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
if (!istype(user, /mob/living/silicon))
user.unset_machine()
user << browse(null, "window=shield_generator")
return
var/t = "<B>Shield Generator Control Console</B><BR><br>"
if(locked)
t += "<i>Swipe your ID card to begin.</i>"
else
t += "[owned_capacitor ? "<font color=green>Charge capacitor connected.</font>" : "<font color=red>Unable to locate charge capacitor!</font>"]<br>"
t += "This generator is: [active ? "<font color=green>Online</font>" : "<font color=red>Offline</font>" ] <a href='?src=\ref[src];toggle=1'>[active ? "\[Deactivate\]" : "\[Activate\]"]</a><br>"
t += "[time_since_fail > 2 ? "<font color=green>Field is stable.</font>" : "<font color=red>Warning, field is unstable!</font>"]<br>"
t += "Coverage radius (restart required): \
<a href='?src=\ref[src];change_radius=-5'>--</a> \
<a href='?src=\ref[src];change_radius=-1'>-</a> \
[field_radius * 2]m \
<a href='?src=\ref[src];change_radius=1'>+</a> \
<a href='?src=\ref[src];change_radius=5'>++</a><br>"
t += "Overall field strength: [average_field_strength] Renwicks ([max_field_strength ? 100 * average_field_strength / max_field_strength : "NA"]%)<br>"
t += "Charge rate: <a href='?src=\ref[src];strengthen_rate=-0.1'>--</a> \
<a href='?src=\ref[src];strengthen_rate=-0.01'>-</a> \
[strengthen_rate] Renwicks/sec \
<a href='?src=\ref[src];strengthen_rate=0.01'>+</a> \
<a href='?src=\ref[src];strengthen_rate=0.1'>++</a><br>"
t += "Upkeep energy: [field.len * average_field_strength / energy_conversion_rate] Watts/sec<br>"
t += "Additional energy required to charge: [field.len * strengthen_rate / energy_conversion_rate] Watts/sec<br>"
t += "Maximum field strength: \
<a href='?src=\ref[src];max_field_strength=-100'>\[min\]</a> \
<a href='?src=\ref[src];max_field_strength=-10'>--</a> \
<a href='?src=\ref[src];max_field_strength=-1'>-</a> \
[max_field_strength] Renwicks \
<a href='?src=\ref[src];max_field_strength=1'>+</a> \
<a href='?src=\ref[src];max_field_strength=10'>++</a> \
<a href='?src=\ref[src];max_field_strength=100'>\[max\]</a><br>"
t += "<hr>"
t += "<A href='?src=\ref[src]'>Refresh</A> "
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
user << browse(t, "window=shield_generator;size=500x800")
user.set_machine(src)
/obj/machinery/shield_gen/process()
if(active && field.len)
var/stored_renwicks = 0
var/target_field_strength = min(strengthen_rate + max(average_field_strength, 0), max_field_strength)
if(owned_capacitor)
var/required_energy = field.len * target_field_strength / energy_conversion_rate
var/assumed_charge = min(owned_capacitor.stored_charge, required_energy)
stored_renwicks = assumed_charge * energy_conversion_rate
owned_capacitor.stored_charge -= assumed_charge
time_since_fail++
average_field_strength = 0
target_field_strength = stored_renwicks / field.len
for(var/obj/effect/energy_field/E in field)
if(stored_renwicks)
var/strength_change = target_field_strength - E.strength
if(strength_change > stored_renwicks)
strength_change = stored_renwicks
if(E.strength >= 1)
E.Strengthen(strength_change)
else if(E.strength < 0)
E.strength = 0
E.Strengthen(0.1)
stored_renwicks -= strength_change
average_field_strength += E.strength
else
E.Strengthen(-E.strength)
average_field_strength /= field.len
if(average_field_strength < 0)
time_since_fail = 0
else
average_field_strength = 0
/obj/machinery/shield_gen/Topic(href, href_list[])
..()
if( href_list["close"] )
usr << browse(null, "window=shield_generator")
usr.unset_machine()
return
else if( href_list["toggle"] )
toggle()
else if( href_list["change_radius"] )
field_radius += text2num(href_list["change_radius"])
if(field_radius > 200)
field_radius = 200
else if(field_radius < 0)
field_radius = 0
else if( href_list["strengthen_rate"] )
strengthen_rate += text2num(href_list["strengthen_rate"])
if(strengthen_rate > 1)
strengthen_rate = 1
else if(strengthen_rate < 0)
strengthen_rate = 0
else if( href_list["max_field_strength"] )
max_field_strength += text2num(href_list["max_field_strength"])
if(max_field_strength > 1000)
max_field_strength = 1000
else if(max_field_strength < 0)
max_field_strength = 0
//
updateDialog()
/obj/machinery/shield_gen/power_change()
if(stat & BROKEN)
icon_state = "broke"
else
if( powered() )
if (src.active)
icon_state = "generator1"
else
icon_state = "generator0"
stat &= ~NOPOWER
else
spawn(rand(0, 15))
src.icon_state = "generator0"
stat |= NOPOWER
if (src.active)
toggle()
/obj/machinery/shield_gen/ex_act(var/severity)
if(active)
toggle()
return ..()
/*
/obj/machinery/shield_gen/proc/check_powered()
/*
check_powered = 1
if(!anchored)
powered = 0
@@ -76,122 +252,14 @@
PN.newload += shieldload //uses powernet power.
*/
/obj/machinery/shield_gen/process()
if(active && field.len)
var/stored_renwicks = 0
var/target_field_strength = min(average_field_strength + strengthen_rate, max_field_strength)
if(owned_capacitor)
var/assumed_charge = min(owned_capacitor.stored_charge, (target_field_strength / energy_conversion_rate) * field.len)
stored_renwicks = assumed_charge * energy_conversion_rate
owned_capacitor.stored_charge -= assumed_charge
time_since_fail++
average_field_strength = 0
target_field_strength = stored_renwicks / field.len
if(!flicker_shield_glitch)
for(var/obj/effect/energy_field/E in field)
//check to see if the shield is strengthening or failing
if(E.strength > target_field_strength)
E.strength = target_field_strength
else if(E.strength + strengthen_rate > target_field_strength)
E.strength = target_field_strength
else
E.strength += strengthen_rate
if(stored_renwicks - E.strength < 0)
E.strength = stored_renwicks
stored_renwicks -= E.strength
average_field_strength += E.strength
//check if the current shield tile has enough energy to maintain itself
if(E.strength >= 1)
E.density = 1
E.invisibility = 0
else
E.density = 0
E.invisibility = 2
else
//the flicker shield glitch is an intersting quirk in 'older' and/or faulty shielding models
//basically, it strengthens the shields continuously until it can no longer sustain them... then it drops out for a few seconds and starts again
//this makes the shield 'flicker' every now and then until it stabilises
//when this glitch is fixed, shields will only be charged as much as is sustainable
for(var/obj/effect/energy_field/E in field)
//check to see if the shield is strengthening or failing
if(E.strength < target_field_strength)
E.strength += strengthen_rate
if(stored_renwicks - E.strength < 0)
E.strength = stored_renwicks
stored_renwicks -= E.strength
average_field_strength += E.strength
//check if the current shield tile has enough energy to maintain itself
if(E.strength >= 1)
E.density = 1
E.invisibility = 0
else
E.density = 0
E.invisibility = 2
//add any leftover charge back to the capacitor
if(owned_capacitor && stored_renwicks >= 0)
owned_capacitor.stored_charge += stored_renwicks / energy_conversion_rate
average_field_strength /= field.len
if(average_field_strength < 0)
time_since_fail = 0
else
average_field_strength = 0
//
updateDialog()
/obj/machinery/shield_gen/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
if (src.allowed(user))
src.locked = !src.locked
user << "Controls are now [src.locked ? "locked." : "unlocked."]"
else
user << "\red Access denied."
else if(istype(W, /obj/item/weapon/wrench))
src.anchored = !src.anchored
src.visible_message("\blue \icon[src] [src] has been [anchored?"bolted to the floor":"unbolted from the floor"] by [user].")
else
src.add_fingerprint(user)
user << "\red You hit the [src.name] with your [W.name]!"
for(var/mob/M in viewers(src))
if(M == user) continue
M.show_message("\red The [src.name] has been hit with the [W.name] by [user.name]!")
/obj/machinery/shield_gen/power_change()
if(stat & BROKEN)
icon_state = "broke"
else
if( powered() )
if (src.active)
icon_state = "generator1"
else
icon_state = "generator0"
stat &= ~NOPOWER
else
spawn(rand(0, 15))
src.icon_state = "generator0"
stat |= NOPOWER
if (src.active)
toggle()
/obj/machinery/shield_gen/proc/toggle()
active = !active
power_change()
if(active)
var/list/covered_turfs = get_shielded_turfs()
if(get_turf(src) in covered_turfs)
covered_turfs.Remove(get_turf(src))
var/turf/T = get_turf(src)
if(T in covered_turfs)
covered_turfs.Remove(T)
for(var/turf/O in covered_turfs)
var/obj/effect/energy_field/E = new(O)
field.Add(E)
@@ -207,60 +275,10 @@
for(var/mob/M in view(5,src))
M << "\icon[src] You hear heavy droning fade out."
/obj/machinery/shield_gen/Topic(href, href_list[])
..()
if( href_list["close"] )
usr << browse(null, "window=shield_generator")
usr.machine = null
return
else if( href_list["toggle"] )
toggle()
else if( href_list["change_radius"] )
field_radius += text2num(href_list["change_radius"])
if(field_radius > 200)
field_radius = 200
else if(field_radius < 0)
field_radius = 0
else if( href_list["strengthen_rate"] )
strengthen_rate += text2num(href_list["strengthen_rate"])
if(strengthen_rate > 0.2)
strengthen_rate = 0.2
else if(strengthen_rate < 0)
strengthen_rate = 0
else if( href_list["max_field_strength"] )
max_field_strength += text2num(href_list["max_field_strength"])
if(max_field_strength > 1000)
max_field_strength = 1000
else if(max_field_strength < 0)
max_field_strength = 0
//
updateDialog()
/obj/machinery/shield_gen/interact(mob/user)
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
if (!istype(user, /mob/living/silicon))
user.machine = null
user << browse(null, "window=shield_generator")
return
var/t = "<B>Shield Generator Control Console</B><BR>"
t += "[owned_capacitor ? "<font color=green>Charge capacitor connected.</font>" : "<font color=red>Unable to locate charge capacitor!</font>"]<br>"
t += "This generator is: [active ? "<font color=green>Online</font>" : "<font color=red>Offline</font>" ] <a href='?src=\ref[src];toggle=1'>[active ? "\[Deactivate\]" : "\[Activate\]"]</a><br>"
t += "[time_since_fail > 2 ? "<font color=green>Field is stable.</font>" : "<font color=red>Warning, field is unstable!</font>"]<br>"
t += "Coverage radius (generator will need a restart to take effect): <a href='?src=\ref[src];change_radius=-5'>--</a> <a href='?src=\ref[src];change_radius=-1'>-</a> [field_radius * 2]m <a href='?src=\ref[src];change_radius=1'>+</a> <a href='?src=\ref[src];change_radius=5'>++</a><br>"
t += "Overall field strength: [average_field_strength] Renwicks ([100 * average_field_strength / max_field_strength]%)<br>"
t += "Charge consumption: [( (min(average_field_strength + strengthen_rate, max_field_strength)) / energy_conversion_rate) * field.len] Watts/sec<br>"
t += "Field charge rate (approx): <a href='?src=\ref[src];strengthen_rate=-0.1'>--</a> <a href='?src=\ref[src];strengthen_rate=-0.01'>-</a>[strengthen_rate] Renwicks/sec <a href='?src=\ref[src];strengthen_rate=0.01'>+</a> <a href='?src=\ref[src];strengthen_rate=0.1'>++</a><br>"
t += "Maximum field strength (avg across field): <a href='?src=\ref[src];max_field_strength=-100'>\[min\]</a> <a href='?src=\ref[src];max_field_strength=-10'>--</a> <a href='?src=\ref[src];max_field_strength=-1'>-</a>[max_field_strength] Renwicks <a href='?src=\ref[src];max_field_strength=1'>+</a> <a href='?src=\ref[src];max_field_strength=10'>++</a> <a href='?src=\ref[src];max_field_strength=100'>\[max\]</a><br>"
t += "<hr>"
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
user << browse(t, "window=shield_generator;size=500x800")
user.machine = src
//grab the border tiles in a circle around this machine
/obj/machinery/shield_gen/proc/get_shielded_turfs()
return list()
/obj/machinery/shield_gen/ex_act(var/severity)
if(active)
toggle()
return ..()
var/list/out = list()
for(var/turf/T in range(field_radius, src))
if(get_dist(src,T) == field_radius)
out.Add(T)
return out
@@ -21,12 +21,18 @@
for(var/turf/simulated/G in orange(1, O))
add_this_turf = 1
break
for(var/obj/structure/S in orange(1, O))
add_this_turf = 1
break
for(var/obj/structure/S in O)
add_this_turf = 0
break
//uncomment this for structures (but not lattices) to be surrounded by shield as well
/*if(!add_this_turf)
for(var/obj/structure/S in orange(1, O))
if(!istype(S, /obj/structure/lattice))
add_this_turf = 1
break
if(add_this_turf)
for(var/obj/structure/S in O)
if(!istype(S, /obj/structure/lattice))
add_this_turf = 0
break*/
if(add_this_turf && !(O in open) && !(O in closed))
open += O
+39 -9
View File
@@ -40,12 +40,23 @@ log transactions
machine_id = "[station_name()] RT #[num_financial_terminals++]"
/obj/machinery/atm/process()
if(stat & NOPOWER)
return
if(linked_db && ( (linked_db.stat & NOPOWER) || !linked_db.activated ) )
linked_db = null
authenticated_account = null
src.visible_message("\red \icon[src] [src] buzzes rudely, \"Connection to remote database lost.\"")
updateDialog()
if(ticks_left_timeout > 0)
ticks_left_timeout--
if(ticks_left_timeout <= 0)
authenticated_account = null
if(ticks_left_locked_down > 0)
ticks_left_locked_down--
if(ticks_left_locked_down <= 0)
number_incorrect_tries = 0
for(var/obj/item/weapon/spacecash/S in src)
S.loc = src.loc
@@ -57,7 +68,7 @@ log transactions
/obj/machinery/atm/proc/reconnect_database()
for(var/obj/machinery/account_database/DB in world)
if(DB.z == src.z)
if( DB.z == src.z && !(DB.stat & NOPOWER) && DB.activated )
linked_db = DB
break
@@ -68,7 +79,8 @@ log transactions
usr.drop_item()
idcard.loc = src
held_card = idcard
authenticated_account = null
if(authenticated_account && held_card.associated_account_number != authenticated_account.account_number)
authenticated_account = null
else if(authenticated_account)
if(istype(I,/obj/item/weapon/spacecash))
//consume the money
@@ -223,7 +235,7 @@ log transactions
var/new_sec_level = max( min(text2num(href_list["new_security_level"]), 2), 0)
authenticated_account.security_level = new_sec_level
if("attempt_auth")
if(linked_db)
if(linked_db && !ticks_left_locked_down)
var/tried_account_num = text2num(href_list["account_num"])
if(!tried_account_num)
tried_account_num = held_card.associated_account_number
@@ -231,11 +243,11 @@ log transactions
authenticated_account = linked_db.attempt_account_access(tried_account_num, tried_pin, held_card && held_card.associated_account_number == tried_account_num ? 2 : 1)
if(!authenticated_account)
number_incorrect_tries++
if(previous_account_number == tried_account_num)
if(++number_incorrect_tries > max_pin_attempts)
if(number_incorrect_tries > max_pin_attempts)
//lock down the atm
number_incorrect_tries = 0
ticks_left_locked_down = 10
ticks_left_locked_down = 30
playsound(src, 'buzz-two.ogg', 50, 1)
//create an entry in the account transaction log
@@ -247,9 +259,12 @@ log transactions
T.time = worldtime2text()
authenticated_account.transaction_log.Add(T)
else
usr << "\red \icon[src] Incorrect pin/account combination entered, [max_pin_attempts - number_incorrect_tries] attempts remaining."
previous_account_number = tried_account_num
number_incorrect_tries = 1
playsound(src, 'buzz-sigh.ogg', 50, 1)
else
usr << "\red \icon[src] incorrect pin/account combination entered."
number_incorrect_tries = 0
else
playsound(src, 'twobeep.ogg', 50, 1)
ticks_left_timeout = 120
@@ -263,6 +278,10 @@ log transactions
T.date = current_date_string
T.time = worldtime2text()
authenticated_account.transaction_log.Add(T)
usr << "\blue \icon[src] Access granted. Welcome user '[authenticated_account.owner_name].'"
previous_account_number = tried_account_num
if("withdrawal")
var/amount = max(text2num(href_list["funds_amount"]),0)
if(authenticated_account && amount > 0)
@@ -325,8 +344,8 @@ log transactions
held_card = I
if("logout")
authenticated_account = null
usr << browse(null,"window=atm")
return
//usr << browse(null,"window=atm")
src.attack_hand(usr)
//create the most effective combination of notes to make up the requested amount
@@ -368,3 +387,14 @@ log transactions
I = P.id
if(I)
authenticated_account = linked_db.attempt_account_access(I.associated_account_number)
if(authenticated_account)
human_user << "\blue \icon[src] Access granted. Welcome user '[authenticated_account.owner_name].'"
//create a transaction log entry
var/datum/transaction/T = new()
T.target_name = authenticated_account.owner_name
T.purpose = "Remote terminal access"
T.source_terminal = machine_id
T.date = current_date_string
T.time = worldtime2text()
authenticated_account.transaction_log.Add(T)
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

@@ -0,0 +1,405 @@
// Basic transit tubes. Straight pieces, curved sections,
// and basic splits/joins (no routing logic).
// Mappers: you can use "Generate Instances from Icon-states"
// to get the different pieces.
/obj/structure/transit_tube
icon = 'transit_tube.dmi'
icon_state = "E-W"
density = 1
layer = 3.1
anchored = 1.0
var/list/tube_dirs = null
var/exit_delay = 2
var/enter_delay = 1
// A place where tube pods stop, and people can get in or out.
// Mappers: use "Generate Instances from Directions" for this
// one.
/obj/structure/transit_tube/station
icon = 'transit_tube_station.dmi'
icon_state = "closed"
exit_delay = 2
enter_delay = 3
var/pod_moving = 0
var/automatic_launch_time = 100
var/const/OPEN_DURATION = 6
var/const/CLOSE_DURATION = 6
/obj/structure/transit_tube_pod
icon = 'transit_tube_pod.dmi'
icon_state = "pod"
animate_movement = FORWARD_STEPS
var/moving = 0
var/datum/gas_mixture/air_contents
/obj/structure/transit_tube/station/New(loc)
..(loc)
spawn(automatic_launch_time)
launch_pod()
/obj/structure/transit_tube/station/Bumped(mob/AM as mob|obj)
if(!pod_moving && icon_state == "open" && istype(AM, /mob))
for(var/obj/structure/transit_tube_pod/pod in loc)
if(!pod.moving && pod.dir in directions())
AM.loc = pod
return
/obj/structure/transit_tube/station/attack_hand(mob/user as mob)
if(!pod_moving)
for(var/obj/structure/transit_tube_pod/pod in loc)
if(!pod.moving && pod.dir in directions())
if(icon_state == "closed")
open_animation()
else if(icon_state == "open")
close_animation()
/obj/structure/transit_tube/station/proc/open_animation()
if(icon_state == "closed")
icon_state = "opening"
spawn(OPEN_DURATION)
if(icon_state == "opening")
icon_state = "open"
/obj/structure/transit_tube/station/proc/close_animation()
if(icon_state == "open")
icon_state = "closing"
spawn(CLOSE_DURATION)
if(icon_state == "closing")
icon_state = "closed"
/obj/structure/transit_tube/station/proc/launch_pod()
for(var/obj/structure/transit_tube_pod/pod in loc)
if(!pod.moving && pod.dir in directions())
spawn(5)
pod_moving = 1
close_animation()
sleep(CLOSE_DURATION + 2)
if(icon_state == "closed" && pod)
pod.follow_tube()
pod_moving = 0
return
/obj/structure/transit_tube/proc/should_stop_pod(pod, from_dir)
return 0
/obj/structure/transit_tube/station/should_stop_pod(pod, from_dir)
return 1
/obj/structure/transit_tube/proc/pod_stopped(pod, from_dir)
return 0
/obj/structure/transit_tube/station/pod_stopped(obj/structure/transit_tube_pod/pod, from_dir)
pod_moving = 1
spawn(5)
open_animation()
sleep(OPEN_DURATION + 2)
pod_moving = 0
pod.mix_air()
if(automatic_launch_time)
var/const/wait_step = 5
var/i = 0
while(i < automatic_launch_time)
sleep(wait_step)
i += wait_step
if(pod_moving || icon_state != "open")
return
launch_pod()
// Returns a /list of directions this tube section can
// connect to.
/obj/structure/transit_tube/proc/directions()
return tube_dirs
/obj/structure/transit_tube/proc/has_entrance(from_dir)
from_dir = turn(from_dir, 180)
for(var/direction in directions())
if(direction == from_dir)
return 1
return 0
/obj/structure/transit_tube/proc/has_exit(in_dir)
for(var/direction in directions())
if(direction == in_dir)
return 1
return 0
// Searches for an exit direction within 45 degrees of the
// specified dir. Returns that direction, or 0 if none match.
/obj/structure/transit_tube/proc/get_exit(in_dir)
var/near_dir = 0
var/in_dir_cw = turn(in_dir, -45)
var/in_dir_ccw = turn(in_dir, 45)
for(var/direction in directions())
if(direction == in_dir)
return direction
else if(direction == in_dir_cw)
near_dir = direction
else if(direction == in_dir_ccw)
near_dir = direction
return near_dir
/obj/structure/transit_tube/proc/exit_delay(pod, to_dir)
return exit_delay
/obj/structure/transit_tube/proc/enter_delay(pod, to_dir)
return enter_delay
/obj/structure/transit_tube_pod/proc/follow_tube()
if(moving)
return
moving = 1
spawn()
var/obj/structure/transit_tube/current_tube = null
var/next_dir
var/next_loc
for(var/obj/structure/transit_tube/tube in loc)
if(tube.has_exit(dir))
current_tube = tube
break
while(current_tube)
next_dir = current_tube.get_exit(dir)
if(!next_dir)
break
sleep(current_tube.exit_delay(src, dir))
next_loc = get_step(loc, next_dir)
current_tube = null
for(var/obj/structure/transit_tube/tube in next_loc)
if(tube.has_entrance(next_dir))
current_tube = tube
break
if(current_tube == null)
dir = next_dir
step(src, dir)
break
sleep(current_tube.enter_delay(src, next_dir))
dir = next_dir
loc = next_loc
if(current_tube && current_tube.should_stop_pod(src, next_dir))
current_tube.pod_stopped(src, dir)
break
moving = 0
// HUGE HACK: Because the pod isn't a mecha, travelling through tubes over space
// won't protect people from space.
// This avoids editing an additional file, so that adding
// tubes to a SS13 codebase is a simple as dropping this code file and the
// required icon files somewhere where BYOND can find them.
/mob/living/carbon/human/handle_environment(datum/gas_mixture/environment)
if(!istype(loc, /obj/structure/transit_tube_pod))
return ..(environment)
/obj/structure/transit_tube_pod/return_air()
var/datum/gas_mixture/GM = new()
GM.oxygen = MOLES_O2STANDARD * 2
GM.nitrogen = MOLES_N2STANDARD
GM.temperature = T20C
return GM
// For now, copying what I found in an unused FEA file (and almost identical in a
// used ZAS file). Means that assume_air and remove_air don't actually alter the
// air contents.
/obj/structure/transit_tube_pod/assume_air(datum/gas_mixture/giver)
return 0
/obj/structure/transit_tube_pod/remove_air(amount)
var/oxygen = MOLES_O2STANDARD
var/carbon_dioxide = 0
var/nitrogen = MOLES_N2STANDARD
var/toxins = 0
var/datum/gas_mixture/GM = new()
var/sum = oxygen + carbon_dioxide + nitrogen + toxins
if(sum>0)
GM.oxygen = (oxygen/sum)*amount
GM.carbon_dioxide = (carbon_dioxide/sum)*amount
GM.nitrogen = (nitrogen/sum)*amount
GM.toxins = (toxins/sum)*amount
GM.temperature = T20C
GM.update_values() //Needed in ZAS to prevent suffocation. Not present in FEA. Comment/uncomment as nessecary.
return GM
// Called when a pod arrives at, and before a pod departs from a station,
// giving it a chance to mix its internal air supply with the turf it is
// currently on.
/obj/structure/transit_tube_pod/proc/mix_air()
//Needs to be implemented at some point
// When the player moves, check if the pos is currently stopped at a station.
// if it is, check the direction. If the direction matches the direction of
// the station, try to exit. If the direction matches one of the station's
// tube directions, launch the pod in that direction.
/obj/structure/transit_tube_pod/relaymove(mob/mob, direction)
if(!moving && istype(mob, /mob) && mob.client)
for(var/obj/structure/transit_tube/station/station in loc)
if(!station.pod_moving && (dir in station.directions()))
if(direction == station.dir)
if(station.icon_state == "open")
mob.loc = loc
mob.client.Move(get_step(loc, direction), direction)
else
station.open_animation()
else if(direction in station.directions())
dir = direction
station.launch_pod()
/obj/structure/transit_tube/New(loc)
..(loc)
if(tube_dirs == null)
init_dirs()
// Parse the icon_state into a list of directions.
// This means that mappers can use Dream Maker's built in
// "Generate Instances from Icon-states" option to get all
// variations. Additionally, as a separate proc, sub-types
// can handle it more intelligently.
/obj/structure/transit_tube/proc/init_dirs()
tube_dirs = parse_dirs(icon_state)
if(copytext(icon_state, 1, 3) == "D-")
density = 0
// Tube station directions are simply 90 to either side of
// the exit.
/obj/structure/transit_tube/station/init_dirs()
tube_dirs = list(turn(dir, 90), turn(dir, -90))
// Uses a list() to cache return values. Since they should
// never be edited directly, all tubes with a certain
// icon_state can just reference the same list. In theory,
// reduces memory usage, and improves CPU cache usage.
// In reality, I don't know if that is quite how BYOND works,
// but it is probably safer to assume the existence of, and
// rely on, a sufficiently smart compiler/optimizer.
/obj/structure/transit_tube/proc/parse_dirs(text)
var/global/list/direction_table = list()
if(text in direction_table)
return direction_table[text]
var/list/split_text = stringsplit(text, "-")
// If the first token is D, the icon_state represents
// a purely decorative tube, and doesn't actually
// connect to anything.
if(split_text[1] == "D")
direction_table[text] = list()
return null
var/list/directions = list()
for(var/text_part in split_text)
var/direction = text2dir_extended(text_part)
if(direction > 0)
directions += direction
direction_table[text] = directions
return directions
// A copy of text2dir, extended to accept one and two letter
// directions, and to clearly return 0 otherwise.
/obj/structure/transit_tube/proc/text2dir_extended(direction)
switch(uppertext(direction))
if("NORTH", "N")
return 1
if("SOUTH", "S")
return 2
if("EAST", "E")
return 4
if("WEST", "W")
return 8
if("NORTHEAST", "NE")
return 5
if("NORTHWEST", "NW")
return 9
if("SOUTHEAST", "SE")
return 6
if("SOUTHWEST", "SW")
return 10
else
return 0