Merge remote-tracking branch 'upstream/dev' into faxmachine

This commit is contained in:
mwerezak
2014-11-01 11:49:15 -04:00
258 changed files with 6212 additions and 5433 deletions
+1 -1
View File
@@ -973,7 +973,7 @@ var/global/floorIsLava = 0
if(3)
var/count = 0
for(var/mob/living/carbon/monkey/Monkey in world)
if(Monkey.z == 1)
if(Monkey.z in station_levels)
count++
return "Kill all [count] of the monkeys on the station"
if(4)
+1
View File
@@ -149,6 +149,7 @@ var/list/admin_verbs_debug = list(
/client/proc/restart_controller,
/client/proc/remake_distribution_map,
/client/proc/show_distribution_map,
/client/proc/show_plant_genes,
/client/proc/enable_debug_verbs,
/client/proc/callproc,
/client/proc/toggledebuglogs,
+2 -2
View File
@@ -411,14 +411,14 @@
dat += "<a href='?src=\ref[src];delay_round_end=1'>[ticker.delay_end ? "End Round Normally" : "Delay Round End"]</a><br>"
if(ticker.mode.syndicates.len)
dat += "<br><table cellspacing=5><tr><td><B>Syndicates</B></td><td></td></tr>"
dat += "<br><table cellspacing=5><tr><td><B>Mercenaries</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.syndicates)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?src=\ref[src];adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(logged out)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?src=\ref[usr];priv_msg=\ref[M]'>PM</A></td></tr>"
else
dat += "<tr><td><i>Nuclear Operative not found!</i></td></tr>"
dat += "<tr><td><i>Mercenary not found!</i></td></tr>"
dat += "</table><br><table><tr><td><B>Nuclear Disk(s)</B></td></tr>"
for(var/obj/item/weapon/disk/nuclear/N in world)
dat += "<tr><td>[N.name], "
+8 -14
View File
@@ -582,9 +582,9 @@
//Nuke Operative
if(jobban_isbanned(M, "operative") || isbanned_dept)
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=operative;jobban4=\ref[M]'><font color=red>[replacetext("Nuke Operative", " ", "&nbsp")]</font></a></td>"
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=operative;jobban4=\ref[M]'><font color=red>[replacetext("Mercenary", " ", "&nbsp")]</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=operative;jobban4=\ref[M]'>[replacetext("Nuke Operative", " ", "&nbsp")]</a></td>"
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=operative;jobban4=\ref[M]'>[replacetext("Mercenary", " ", "&nbsp")]</a></td>"
//Revolutionary
if(jobban_isbanned(M, "revolutionary") || isbanned_dept)
@@ -1476,11 +1476,11 @@
usr << "The person you are trying to contact is not wearing a headset"
return
var/input = input(src.owner, "Please enter a message to reply to [key_name(H)] via their headset.","Outgoing message from The Syndicate", "")
var/input = input(src.owner, "Please enter a message to reply to [key_name(H)] via their headset.","Outgoing message from a shadowy figure...", "")
if(!input) return
src.owner << "You sent [input] to [H] via a secure channel."
log_admin("[src.owner] replied to [key_name(H)]'s Syndicate message with the message [input].")
log_admin("[src.owner] replied to [key_name(H)]'s illegal message with the message [input].")
H << "You hear something crackle in your headset for a moment before a voice speaks. \"Please stand by for a message from your benefactor. Message as follows, agent. <b>\"[input]\"</b> Message ends.\""
else if(href_list["AdminFaxView"])
@@ -2327,7 +2327,7 @@
message_admins("[key_name_admin(usr)] made the floor LAVA! It'll last [length] seconds and it will deal [damage] damage to everyone.", 1)
for(var/turf/simulated/floor/F in world)
if(F.z == 1)
if(F.z in config.station_levels)
F.name = "lava"
F.desc = "The floor is LAVA!"
F.overlays += "lava"
@@ -2352,7 +2352,7 @@
sleep(10)
for(var/turf/simulated/floor/F in world) // Reset everything.
if(F.z == 1)
if(F.z in config.station_levels)
F.name = initial(F.name)
F.desc = initial(F.desc)
F.overlays.Cut()
@@ -2400,7 +2400,7 @@
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","EgL")
for(var/obj/machinery/door/airlock/W in world)
if(W.z == 1 && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison))
if(W.z in config.station_levels && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison))
W.req_access = list()
message_admins("[key_name_admin(usr)] activated Egalitarian Station mode")
command_announcement.Announce("Centcomm airlock control override activated. Please take this time to get acquainted with your coworkers.", new_sound = 'sound/AI/commandreport.ogg')
@@ -2598,15 +2598,9 @@
newMsg.body = src.admincaster_feed_message.body
newMsg.is_admin_message = 1
feedback_inc("newscaster_stories",1)
for(var/datum/feed_channel/FC in news_network.network_channels)
if(FC.channel_name == src.admincaster_feed_channel.channel_name)
FC.messages += newMsg //Adding message to the network's appropriate feed_channel
break
news_network.add_news(src.admincaster_feed_channel.channel_name, newMsg)
src.admincaster_screen=4
for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
NEWSCASTER.newsAlert(src.admincaster_feed_channel.channel_name)
log_admin("[key_name_admin(usr)] submitted a feed story to channel: [src.admincaster_feed_channel.channel_name]!")
src.access_news_network()
+2 -2
View File
@@ -11,8 +11,8 @@
var/override
switch(parameter)
if(1)
override = input(src,"mode = ?","Enter Parameter",null) as anything in list("nuclear emergency","no override")
override = input(src,"mode = ?","Enter Parameter",null) as anything in list("mercenary","no override")
if(0)
override = input(src,"mode = ?","Enter Parameter",null) as anything in list("blob","nuclear emergency","AI malfunction","no override")
override = input(src,"mode = ?","Enter Parameter",null) as anything in list("blob","mercenary","AI malfunction","no override")
ticker.station_explosion_cinematic(parameter,override)
return
-9
View File
@@ -426,15 +426,6 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
/client/proc/cmd_switch_radio()
set category = "Debug"
set name = "Switch Radio Mode"
set desc = "Toggle between normal radios and experimental radios. Have a coder present if you do this."
GLOBAL_RADIO_TYPE = !GLOBAL_RADIO_TYPE // toggle
log_admin("[key_name(src)] has turned the experimental radio system [GLOBAL_RADIO_TYPE ? "on" : "off"].")
message_admins("[key_name_admin(src)] has turned the experimental radio system [GLOBAL_RADIO_TYPE ? "on" : "off"].", 0)
feedback_add_details("admin_verb","SRM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_areatest()
set category = "Mapping"
+1 -1
View File
@@ -17,7 +17,7 @@
var/inactive_on_main_station = 0
for(var/zone/zone in air_master.zones)
var/turf/simulated/turf = locate() in zone.contents
if(turf && turf.z == 1)
if(turf && turf.z in config.station_levels)
if(zone.needs_update)
active_on_main_station++
else
+4 -4
View File
@@ -264,7 +264,7 @@ client/proc/one_click_antag()
if(nuke_spawn)
var/obj/item/weapon/paper/P = new
P.info = "Sadly, the Syndicate could not get you a nuclear bomb. We have, however, acquired the arming code for the station's onboard nuke. The nuclear authorization code is: <b>[nuke_code]</b>"
P.info = "Sadly, your employers could not get you a nuclear bomb. They have, however, acquired the arming code for the station's onboard nuke. The nuclear authorization code is: <b>[nuke_code]</b>"
P.name = "nuclear bomb code and instructions"
P.loc = nuke_spawn.loc
@@ -327,7 +327,7 @@ client/proc/one_click_antag()
//Generates a list of commandos from active ghosts. Then the user picks which characters to respawn as the commandos.
for(var/mob/dead/observer/G in player_list)
spawn(0)
switch(alert(G,"Do you wish to be considered for an elite syndicate strike team being sent in?","Please answer in 30 seconds!","Yes","No"))
switch(alert(G,"Do you wish to be considered for an elite mercenary strike team being sent in?","Please answer in 30 seconds!","Yes","No"))
if("Yes")
if((world.time-time_passed)>300)//If more than 30 game seconds passed.
return
@@ -369,7 +369,7 @@ client/proc/one_click_antag()
//So they don't forget their code or mission.
new_syndicate_commando << "\blue You are an Elite Syndicate. [!syndicate_leader_selected?"commando":"<B>LEADER</B>"] in the service of the Syndicate. \nYour current mission is: \red<B> [input]</B>"
new_syndicate_commando << "\blue You are an Elite Mercenary. [!syndicate_leader_selected?"commando":"<B>LEADER</B>"] in the service of criminal elements hostile to NanoTrasen. \nYour current mission is: \red<B> [input]</B>"
numagents--
if(numagents >= 6)
@@ -424,7 +424,7 @@ client/proc/one_click_antag()
//Creates mind stuff.
new_syndicate_commando.mind_initialize()
new_syndicate_commando.mind.assigned_role = "MODE"
new_syndicate_commando.mind.special_role = "Syndicate Commando"
new_syndicate_commando.mind.special_role = "Mercenary"
//Adds them to current traitor list. Which is really the extra antagonist list.
ticker.mode.traitors += new_syndicate_commando.mind
+1 -1
View File
@@ -34,5 +34,5 @@
/proc/Syndicate_announce(var/text , var/mob/Sender)
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
msg = "\blue <b><font color=crimson>SYNDICATE:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;SyndicateReply=\ref[Sender]'>RPLY</A>):</b> [msg]"
msg = "\blue <b><font color=crimson>ILLEGAL:</font>[key_name(Sender, 1)] (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservejump=\ref[Sender]'>JMP</A>) (<A HREF='?_src_=holder;secretsadmin=check_antagonist'>CA</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;SyndicateReply=\ref[Sender]'>RPLY</A>):</b> [msg]"
admins << msg
+1 -1
View File
@@ -453,7 +453,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
new_character.loc = pick(wizardstart)
//ticker.mode.learn_basic_spells(new_character)
ticker.mode.equip_wizard(new_character)
if("Syndicate")
if("Mercenary")
var/obj/effect/landmark/synd_spawn = locate("landmark*Syndicate-Spawn")
if(synd_spawn)
new_character.loc = get_turf(synd_spawn)
@@ -4,7 +4,7 @@ var/const/syndicate_commandos_possible = 6 //if more Commandos are needed in the
var/global/sent_syndicate_strike_team = 0
/client/proc/syndicate_strike_team()
set category = "Fun"
set name = "Spawn Syndicate Strike Team"
set name = "Spawn Mercenary Strike Team"
set desc = "Spawns a squad of commandos in the Syndicate Mothership if you want to run an admin event."
if(!src.holder)
src << "Only administrators may use this command."
@@ -16,15 +16,15 @@ var/global/sent_syndicate_strike_team = 0
// alert("Not so fast, buddy. Wait a few minutes until the game gets going. There are [(6000-world.time)/10] seconds remaining.")
// return
if(sent_syndicate_strike_team == 1)
alert("The Syndicate are already sending a team, Mr. Dumbass.")
alert("Criminal elements are already sending a team, Mr. Dumbass.")
return
if(alert("Do you want to send in the Syndicate Strike Team? Once enabled, this is irreversible.",,"Yes","No")=="No")
if(alert("Do you want to send in the Mercenary Strike Team? Once enabled, this is irreversible.",,"Yes","No")=="No")
return
alert("This 'mode' will go on until everyone is dead or the station is destroyed. You may also admin-call the evac shuttle when appropriate. Spawned syndicates have internals cameras which are viewable through a monitor inside the Syndicate Mothership Bridge. Assigning the team's detailed task is recommended from there. While you will be able to manually pick the candidates from active ghosts, their assignment in the squad will be random.")
alert("This 'mode' will go on until everyone is dead or the station is destroyed. You may also admin-call the evac shuttle when appropriate. Spawned mercs have internals cameras which are viewable through a monitor inside the Syndicate Mothership Bridge. Assigning the team's detailed task is recommended from there. While you will be able to manually pick the candidates from active ghosts, their assignment in the squad will be random.")
var/input = null
while(!input)
input = copytext(sanitize(input(src, "Please specify which mission the syndicate strike team shall undertake.", "Specify Mission", "")),1,MAX_MESSAGE_LEN)
input = copytext(sanitize(input(src, "Please specify which mission the strike team shall undertake.", "Specify Mission", "")),1,MAX_MESSAGE_LEN)
if(!input)
if(alert("Error, no mission set. Do you want to exit the setup process?",,"Yes","No")=="Yes")
return
@@ -81,7 +81,7 @@ var/global/sent_syndicate_strike_team = 0
new_syndicate_commando.mind.store_memory("<B>Nuke Code:</B> \red [nuke_code].")
new_syndicate_commando.mind.store_memory("<B>Mission:</B> \red [input].")
new_syndicate_commando << "\blue You are an Elite Syndicate. [!syndicate_leader_selected?"commando":"<B>LEADER</B>"] in the service of the Syndicate. \nYour current mission is: \red<B>[input]</B>"
new_syndicate_commando << "\blue You are an Elite Mercenary. [!syndicate_leader_selected?"commando":"<B>LEADER</B>"] in the service of criminal elements hostile to NanoTrasen. \nYour current mission is: \red<B>[input]</B>"
syndicate_commando_number--
@@ -98,8 +98,8 @@ var/global/sent_syndicate_strike_team = 0
new /obj/effect/spawner/newbomb/timer/syndicate(L.loc)
del(L)
message_admins("\blue [key_name_admin(usr)] has spawned a Syndicate strike squad.", 1)
log_admin("[key_name(usr)] used Spawn Syndicate Squad.")
message_admins("\blue [key_name_admin(usr)] has spawned a mercenary strike squad.", 1)
log_admin("[key_name(usr)] used Spawn Mercenary Squad.")
feedback_add_details("admin_verb","SDTHS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/create_syndicate_death_commando(obj/spawn_location, syndicate_leader_selected = 0)
@@ -121,7 +121,7 @@ var/global/sent_syndicate_strike_team = 0
//Creates mind stuff.
new_syndicate_commando.mind_initialize()
new_syndicate_commando.mind.assigned_role = "MODE"
new_syndicate_commando.mind.special_role = "Syndicate Commando"
new_syndicate_commando.mind.special_role = "Mercenary"
ticker.mode.traitors |= new_syndicate_commando.mind //Adds them to current traitor list. Which is really the extra antagonist list.
new_syndicate_commando.equip_syndicate_commando(syndicate_leader_selected)
del(spawn_location)
@@ -171,7 +171,7 @@ var/global/sent_syndicate_strike_team = 0
W.icon_state = "id"
W.access = get_all_accesses()//They get full station access because obviously the syndicate has HAAAX, and can make special IDs for their most elite members.
W.access += list(access_cent_general, access_cent_specops, access_cent_living, access_cent_storage, access_syndicate)//Let's add their forged CentCom access and syndicate access.
W.assignment = "Syndicate Commando"
W.assignment = "Mercenary"
W.registered_name = real_name
equip_to_slot_or_del(W, slot_wear_id)
+4 -1
View File
@@ -13,6 +13,7 @@
var/frequency = 1457
var/delay = 0
var/airlock_wire = null
var/datum/wires/connected = null
var/datum/radio_frequency/radio_connection
var/deadman = 0
@@ -118,7 +119,9 @@
pulse(var/radio = 0)
if(istype(src.loc, /obj/machinery/door/airlock) && src.airlock_wire && src.wires)
if(src.connected && src.wires)
connected.Pulse(src)
else if(istype(src.loc, /obj/machinery/door/airlock) && src.airlock_wire && src.wires)
var/obj/machinery/door/airlock/A = src.loc
A.pulse(src.airlock_wire)
else if(holder)
+16 -4
View File
@@ -403,7 +403,7 @@ var/global/list/gear_datums = list()
slot = slot_wear_suit
/datum/gear/bomber
display_name = "bomberjacker"
display_name = "bomber jacket"
path = /obj/item/clothing/suit/bomber
cost = 4
slot = slot_wear_suit
@@ -427,12 +427,24 @@ var/global/list/gear_datums = list()
cost = 2
slot = slot_wear_suit
/datum/gear/gponcho
display_name = "poncho, blue"
path = /obj/item/clothing/suit/poncho/blue
cost = 4
slot = slot_wear_suit
/datum/gear/gponcho
display_name = "poncho, green"
path = /obj/item/clothing/suit/poncho/green
cost = 4
slot = slot_wear_suit
/datum/gear/rponcho
display_name = "poncho, purple"
path = /obj/item/clothing/suit/poncho/purple
cost = 4
slot = slot_wear_suit
/datum/gear/rponcho
display_name = "poncho, red"
path = /obj/item/clothing/suit/poncho/red
@@ -642,17 +654,17 @@ var/global/list/gear_datums = list()
/datum/gear/blipstick
display_name = "lipstick, black"
path = /obj/item/weapon/lipstick
path = /obj/item/weapon/lipstick/black
cost = 1
/datum/gear/jlipstick
display_name = "lipstick, jade"
path = /obj/item/weapon/lipstick
path = /obj/item/weapon/lipstick/jade
cost = 1
/datum/gear/plipstick
display_name = "lipstick, purple"
path = /obj/item/weapon/lipstick
path = /obj/item/weapon/lipstick/purple
cost = 1
/datum/gear/rlipstick
+4 -1
View File
@@ -183,7 +183,10 @@
//Sanitize
metadata = sanitize_text(metadata, initial(metadata))
real_name = reject_bad_name(real_name)
if(isnull(species)) species = "Human"
if(isnull(species) || !(species in whitelisted_species))
species = "Human"
if(isnull(language)) language = "None"
if(isnull(spawnpoint)) spawnpoint = "Arrivals Shuttle"
if(isnull(nanotrasen_relation)) nanotrasen_relation = initial(nanotrasen_relation)
@@ -172,6 +172,7 @@
icons.Add(usr.zone_sel)
for(var/obj/screen/I in icons)
if(I.name in list("help", "harm", "disarm", "grab")) continue
I.icon = ui_style2icon(UI_style_new)
I.color = UI_style_color_new
I.alpha = UI_style_alpha_new
+64 -83
View File
@@ -10,6 +10,10 @@
*/
var/list/sprite_sheets_refit = null
//Updates the icons of the mob wearing the clothing item, if any.
/obj/item/clothing/proc/update_clothing_icon()
return
//BS12: Species-restricted clothing check.
/obj/item/clothing/mob_can_equip(M as mob, slot)
@@ -80,7 +84,8 @@
else
icon = initial(icon)
//Ears: headsets, earmuffs and tiny objects
///////////////////////////////////////////////////////////////////////
// Ears: headsets, earmuffs and tiny objects
/obj/item/clothing/ears
name = "ears"
w_class = 1.0
@@ -121,6 +126,11 @@
if(istype(src,/obj/item/clothing/ears/offear))
del(src)
/obj/item/clothing/ears/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_ears()
/obj/item/clothing/ears/offear
name = "Other ear"
w_class = 5.0
@@ -142,7 +152,17 @@
item_state = "earmuffs"
slot_flags = SLOT_EARS | SLOT_TWOEARS
///////////////////////////////////////////////////////////////////////
//Glasses
/*
SEE_SELF // can see self, no matter what
SEE_MOBS // can see all mobs, no matter what
SEE_OBJS // can see all objs, no matter what
SEE_TURFS // can see all turfs (and areas), no matter what
SEE_PIXELS// if an object is located on an unlit area, but some of its pixels are
// in a lit area (via pixel_x,y or smooth movement), can see those pixels
BLIND // can't see anything
*/
/obj/item/clothing/glasses
name = "glasses"
icon = 'icons/obj/clothing/glasses.dmi'
@@ -153,17 +173,13 @@
var/darkness_view = 0//Base human is 2
var/invisa_view = 0
sprite_sheets = list("Vox" = 'icons/mob/species/vox/eyes.dmi')
/*
SEE_SELF // can see self, no matter what
SEE_MOBS // can see all mobs, no matter what
SEE_OBJS // can see all objs, no matter what
SEE_TURFS // can see all turfs (and areas), no matter what
SEE_PIXELS// if an object is located on an unlit area, but some of its pixels are
// in a lit area (via pixel_x,y or smooth movement), can see those pixels
BLIND // can't see anything
*/
/obj/item/clothing/glasses/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_glasses()
///////////////////////////////////////////////////////////////////////
//Gloves
/obj/item/clothing/gloves
name = "gloves"
@@ -185,6 +201,11 @@ BLIND // can't see anything
..()
return
/obj/item/clothing/gloves/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_gloves()
/obj/item/clothing/gloves/emp_act(severity)
if(cell)
//why is this not part of the powercell code?
@@ -217,6 +238,7 @@ BLIND // can't see anything
species_restricted -= "Tajara"
return
///////////////////////////////////////////////////////////////////////
//Head
/obj/item/clothing/head
name = "head"
@@ -225,6 +247,12 @@ BLIND // can't see anything
slot_flags = SLOT_HEAD
w_class = 2.0
/obj/item/clothing/head/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_head()
///////////////////////////////////////////////////////////////////////
//Mask
/obj/item/clothing/mask
name = "mask"
@@ -234,8 +262,15 @@ BLIND // can't see anything
body_parts_covered = FACE|EYES
sprite_sheets = list("Vox" = 'icons/mob/species/vox/masks.dmi')
/obj/item/clothing/mask/proc/filter_air(datum/gas_mixture/air)
/obj/item/clothing/mask/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_wear_mask()
/obj/item/clothing/mask/proc/filter_air(datum/gas_mixture/air)
return
///////////////////////////////////////////////////////////////////////
//Shoes
/obj/item/clothing/shoes
name = "shoes"
@@ -251,6 +286,12 @@ BLIND // can't see anything
species_restricted = list("exclude","Unathi","Tajara")
sprite_sheets = list("Vox" = 'icons/mob/species/vox/shoes.dmi')
/obj/item/clothing/shoes/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_shoes()
///////////////////////////////////////////////////////////////////////
//Suit
/obj/item/clothing/suit
icon = 'icons/obj/clothing/suits.dmi'
@@ -265,74 +306,12 @@ BLIND // can't see anything
siemens_coefficient = 0.9
w_class = 3
//Spacesuit
//Note: Everything in modules/clothing/spacesuits should have the entire suit grouped together.
// Meaning the the suit is defined directly after the corrisponding helmet. Just like below!
/obj/item/clothing/head/helmet/space
name = "Space helmet"
icon_state = "space"
desc = "A special helmet designed for work in a hazardous, low-pressure environment."
flags = FPRINT | TABLEPASS | HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL
item_state = "space"
permeability_coefficient = 0.01
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50)
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
body_parts_covered = HEAD|FACE|EYES
cold_protection = HEAD
min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE
siemens_coefficient = 0.9
species_restricted = list("exclude","Diona","Vox")
/obj/item/clothing/suit/space
name = "Space suit"
desc = "A suit that protects against low pressure environments. \"NSS EXODUS\" is written in large block letters on the back."
icon_state = "space"
item_state = "s_suit"
w_class = 4//bulky item
gas_transfer_coefficient = 0.01
permeability_coefficient = 0.02
flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE | THICKMATERIAL
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/device/suit_cooling_unit)
slowdown = 3
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
siemens_coefficient = 0.9
species_restricted = list("exclude","Diona","Vox")
var/list/supporting_limbs //If not-null, automatically splints breaks. Checked when removing the suit.
/obj/item/clothing/suit/space/equipped(mob/M)
check_limb_support()
..()
/obj/item/clothing/suit/space/dropped()
check_limb_support()
..()
// Some space suits are equipped with reactive membranes that support
// broken limbs - at the time of writing, only the ninja suit, but
// I can see it being useful for other suits as we expand them. ~ Z
// The actual splinting occurs in /datum/organ/external/proc/fracture()
/obj/item/clothing/suit/space/proc/check_limb_support()
// If this isn't set, then we don't need to care.
if(!supporting_limbs || !supporting_limbs.len)
return
var/mob/living/carbon/human/H = src.loc
// If the holder isn't human, or the holder IS and is wearing the suit, it keeps supporting the limbs.
if(!istype(H) || H.wear_suit == src)
return
// Otherwise, remove the splints.
for(var/datum/organ/external/E in supporting_limbs)
E.status &= ~ ORGAN_SPLINTED
supporting_limbs = list()
/obj/item/clothing/suit/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_wear_suit()
///////////////////////////////////////////////////////////////////////
//Under clothing
/obj/item/clothing/under
icon = 'icons/obj/clothing/uniforms.dmi'
@@ -356,6 +335,11 @@ BLIND // can't see anything
var/basecolor
sprite_sheets = list("Vox" = 'icons/mob/species/vox/uniform.dmi')
/obj/item/clothing/under/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_w_uniform()
/obj/item/clothing/under/attackby(obj/item/I, mob/user)
if(hastie)
hastie.attackby(I, user)
@@ -480,7 +464,7 @@ BLIND // can't see anything
if(basecolor + "_d_s" in icon_states('icons/mob/uniform.dmi'))
body_parts_covered = "[basecolor]" ? LEGS|LOWER_TORSO : UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
item_color = item_color == "[basecolor]" ? "[basecolor]_d" : "[basecolor]"
usr.update_inv_w_uniform()
update_clothing_icon()
else
usr << "<span class='notice'>You cannot roll down the uniform!</span>"
@@ -490,10 +474,7 @@ BLIND // can't see anything
hastie.on_removed(user)
hastie = null
if(istype(loc, /mob/living/carbon/human))
var/mob/living/carbon/human/H = loc
H.update_inv_w_uniform()
update_clothing_icon()
/obj/item/clothing/under/verb/removetie()
set name = "Remove Accessory"
+5 -1
View File
@@ -52,6 +52,10 @@
icon_state = "purple"
item_state = "glasses"
/obj/item/clothing/glasses/science/New()
..()
overlay = global_hud.science
/obj/item/clothing/glasses/night
name = "Night Vision Goggles"
desc = "You can totally see in the dark now!"
@@ -156,7 +160,7 @@
icon_state = "[initial(icon_state)]up"
usr << "You push \the [src] up out of your face."
usr.update_inv_glasses()
update_clothing_icon()
/obj/item/clothing/glasses/welding/superior
name = "superior welding goggles"
+3 -2
View File
@@ -15,6 +15,7 @@
desc = "Smells nice."
item_state = "hairflower"
flags = FPRINT|TABLEPASS
slot_flags = SLOT_HEAD | SLOT_EARS
body_parts_covered = 0
/obj/item/clothing/head/powdered_wig
@@ -74,7 +75,7 @@
name = "red space-helmet replica"
icon_state = "syndicate"
item_state = "syndicate"
desc = "A plastic replica of a syndicate agent's space helmet, you'll look just like a real murderous syndicate agent in this! This is a toy, it is not made for use in space!"
desc = "A plastic replica of a bloodthirsty mercenary's space helmet, you'll look just like a real murderous criminal operative in this! This is a toy, it is not made for use in space!"
flags = FPRINT | TABLEPASS | BLOCKHAIR
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
siemens_coefficient = 2.0
@@ -261,4 +262,4 @@
item_state = "philosopher_wig"
flags = FPRINT | TABLEPASS | BLOCKHAIR
siemens_coefficient = 2.0
body_parts_covered = 0
body_parts_covered = 0
+1 -1
View File
@@ -48,7 +48,7 @@
flags_inv &= ~(HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE)
icon_state = "[initial(icon_state)]up"
usr << "You push the [src] up out of your face."
usr.update_inv_head() //so our mob-overlays update
update_clothing_icon() //so our mob-overlays update
/*
+1 -1
View File
@@ -26,7 +26,7 @@
else
icon_state = "[item_color]soft"
usr << "You flip the hat back in normal position."
usr.update_inv_head() //so our mob-overlays update
update_clothing_icon() //so our mob-overlays update
/obj/item/clothing/head/soft/red
name = "red cap"
+1 -1
View File
@@ -34,7 +34,7 @@
flags |= MASKCOVERSMOUTH | MASKINTERNALS
icon_state = "breath"
usr << "You pull the mask up to cover your face."
usr.update_inv_wear_mask()
update_clothing_icon()
/obj/item/clothing/mask/breath/medical
desc = "A close-fitting sterile mask that can be connected to an air supply."
+1 -1
View File
@@ -43,7 +43,7 @@
body_parts_covered = FACE|EYES
/obj/item/clothing/mask/gas/syndicate
name = "syndicate mask"
name = "tactical mask"
desc = "A close-fitting tactical mask that can be connected to an air supply."
icon_state = "swat"
siemens_coefficient = 0.7
+1
View File
@@ -215,6 +215,7 @@
return
//TODO: Species check, skull damage for forcing an unfitting helmet on?
helmet.loc = H
helmet.pickup(H)
H.equip_to_slot(helmet, slot_head)
helmet.canremove = 0
H << "\blue You deploy your hardsuit helmet, sealing you off from the world."
@@ -0,0 +1,67 @@
//Spacesuit
//Note: Everything in modules/clothing/spacesuits should have the entire suit grouped together.
// Meaning the the suit is defined directly after the corrisponding helmet. Just like below!
/obj/item/clothing/head/helmet/space
name = "Space helmet"
icon_state = "space"
desc = "A special helmet designed for work in a hazardous, low-pressure environment."
flags = FPRINT | TABLEPASS | HEADCOVERSEYES | BLOCKHAIR | HEADCOVERSMOUTH | STOPSPRESSUREDMAGE | THICKMATERIAL
item_state = "space"
permeability_coefficient = 0.01
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50)
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
body_parts_covered = HEAD|FACE|EYES
cold_protection = HEAD
min_cold_protection_temperature = SPACE_HELMET_MIN_COLD_PROTECTION_TEMPERATURE
siemens_coefficient = 0.9
species_restricted = list("exclude","Diona","Vox")
/obj/item/clothing/suit/space
name = "Space suit"
desc = "A suit that protects against low pressure environments. \"NSS EXODUS\" is written in large block letters on the back."
icon_state = "space"
item_state = "s_suit"
w_class = 4//bulky item
gas_transfer_coefficient = 0.01
permeability_coefficient = 0.02
flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE | THICKMATERIAL
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/device/suit_cooling_unit)
slowdown = 3
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
cold_protection = UPPER_TORSO | LOWER_TORSO | LEGS | FEET | ARMS | HANDS
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
siemens_coefficient = 0.9
species_restricted = list("exclude","Diona","Vox")
var/list/supporting_limbs //If not-null, automatically splints breaks. Checked when removing the suit.
/obj/item/clothing/suit/space/equipped(mob/M)
check_limb_support()
..()
/obj/item/clothing/suit/space/dropped()
check_limb_support()
..()
// Some space suits are equipped with reactive membranes that support
// broken limbs - at the time of writing, only the ninja suit, but
// I can see it being useful for other suits as we expand them. ~ Z
// The actual splinting occurs in /datum/organ/external/proc/fracture()
/obj/item/clothing/suit/space/proc/check_limb_support()
// If this isn't set, then we don't need to care.
if(!supporting_limbs || !supporting_limbs.len)
return
var/mob/living/carbon/human/H = src.loc
// If the holder isn't human, or the holder IS and is wearing the suit, it keeps supporting the limbs.
if(!istype(H) || H.wear_suit == src)
return
// Otherwise, remove the splints.
for(var/datum/organ/external/E in supporting_limbs)
E.status &= ~ ORGAN_SPLINTED
supporting_limbs = list()
+1 -1
View File
@@ -1,7 +1,7 @@
//Regular syndicate space suit
/obj/item/clothing/head/helmet/space/syndicate
name = "red space helmet"
desc = "Top secret Spess Helmet."
desc = "Top secret space helmet."
icon_state = "syndicate"
item_state = "syndicate"
desc = "Has a tag: Totally not property of an enemy corporation, honest."
+7
View File
@@ -35,6 +35,7 @@
/obj/item/clothing/suit/bio_suit/general
icon_state = "bio_general"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEGLOVES|HIDEJUMPSUIT|HIDETAIL
//Virology biosuit, green stripe
/obj/item/clothing/head/bio_hood/virology
@@ -43,6 +44,7 @@
/obj/item/clothing/suit/bio_suit/virology
icon_state = "bio_virology"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEGLOVES|HIDEJUMPSUIT|HIDETAIL
//Security biosuit, grey with red stripe across the chest
/obj/item/clothing/head/bio_hood/security
@@ -51,6 +53,7 @@
/obj/item/clothing/suit/bio_suit/security
icon_state = "bio_security"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEGLOVES|HIDEJUMPSUIT|HIDETAIL
//Janitor's biosuit, grey with purple arms
/obj/item/clothing/head/bio_hood/janitor
@@ -59,6 +62,7 @@
/obj/item/clothing/suit/bio_suit/janitor
icon_state = "bio_janitor"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEGLOVES|HIDEJUMPSUIT|HIDETAIL
//Scientist's biosuit, white with a pink-ish hue
@@ -68,11 +72,13 @@
/obj/item/clothing/suit/bio_suit/scientist
icon_state = "bio_scientist"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEGLOVES|HIDEJUMPSUIT|HIDETAIL
//CMO's biosuit, blue stripe
/obj/item/clothing/suit/bio_suit/cmo
icon_state = "bio_cmo"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS
flags_inv = HIDEGLOVES|HIDEJUMPSUIT|HIDETAIL
/obj/item/clothing/head/bio_hood/cmo
icon_state = "bio_cmo"
@@ -84,3 +90,4 @@
desc = "It protected doctors from the Black Death, back then. You bet your arse it's gonna help you against viruses."
icon_state = "plaguedoctor"
item_state = "bio_suit"
flags_inv = HIDEGLOVES|HIDEJUMPSUIT|HIDETAIL
+2 -2
View File
@@ -184,7 +184,7 @@
else
usr << "You attempt to button-up the velcro on your [src], before promptly realising how retarded you are."
return
usr.update_inv_wear_suit() //so our overlays update
update_clothing_icon() //so our overlays update
//Medical
/obj/item/clothing/suit/storage/fr_jacket
@@ -212,7 +212,7 @@
if("fr_jacket")
src.icon_state = "fr_jacket_open"
usr << "You unbutton the jacket."
usr.update_inv_wear_suit() //so our overlays update
update_clothing_icon() //so our overlays update
//Mime
/obj/item/clothing/suit/suspenders
+3 -2
View File
@@ -2,7 +2,7 @@
name = "labcoat"
desc = "A suit that protects against minor chemical spills."
icon_state = "labcoat_open"
item_state = "labcoat"
item_state = "labcoat" //Is this even used for anything?
blood_overlay_type = "coat"
body_parts_covered = UPPER_TORSO|ARMS
allowed = list(/obj/item/device/analyzer,/obj/item/stack/medical,/obj/item/weapon/dnainjector,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/hypospray,/obj/item/device/healthanalyzer,/obj/item/device/flashlight/pen,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/pill,/obj/item/weapon/storage/pill_bottle,/obj/item/weapon/paper)
@@ -17,6 +17,7 @@
if(!usr.canmove || usr.stat || usr.restrained())
return 0
//Why???
switch(icon_state)
if("labcoat_open")
src.icon_state = "labcoat"
@@ -93,7 +94,7 @@
else
usr << "You attempt to button-up the velcro on your [src], before promptly realising how silly you are."
return
usr.update_inv_wear_suit() //so our overlays update
update_clothing_icon() //so our overlays update
/obj/item/clothing/suit/storage/labcoat/red
name = "red labcoat"
+17 -5
View File
@@ -219,7 +219,7 @@
else
usr << "You button-up some imaginary buttons on your [src]."
return
usr.update_inv_wear_suit()
update_clothing_icon()
//pyjamas
//originally intended to be pinstripes >.>
@@ -356,16 +356,28 @@
/obj/item/clothing/suit/poncho/green
name = "green poncho"
desc = "Your classic, non-racist poncho. This one is green."
desc = "A simple, comfortable cloak without sleeves. This one is green."
icon_state = "greenponcho"
item_state = "greenponcho"
/obj/item/clothing/suit/poncho/red
name = "red poncho"
desc = "Your classic, non-racist poncho. This one is red."
desc = "A simple, comfortable cloak without sleeves. This one is red."
icon_state = "redponcho"
item_state = "redponcho"
/obj/item/clothing/suit/poncho/purple
name = "purple poncho"
desc = "A simple, comfortable cloak without sleeves. This one is purple."
icon_state = "purpleponcho"
item_state = "purpleponcho"
/obj/item/clothing/suit/poncho/blue
name = "blue poncho"
desc = "A simple, comfortable cloak without sleeves. This one is blue."
icon_state = "blueponcho"
item_state = "blueponcho"
/obj/item/clothing/suit/bomber
name = "bomber jacker"
desc = "A well-worn WW2 leather bomber jacket."
@@ -374,5 +386,5 @@
flags = FPRINT | TABLEPASS
body_parts_covered = UPPER_TORSO|ARMS
cold_protection = UPPER_TORSO|ARMS
min_cold_protection_temperature = T0C
siemens_coefficient = 0.7
min_cold_protection_temperature = T0C - 20
siemens_coefficient = 0.7
+33 -29
View File
@@ -27,7 +27,7 @@
icon_state = "psyche"
item_color = "psyche"
update_icon()
usr.update_inv_w_uniform()
update_clothing_icon()
verb/change()
set name = "Change Jumpsuit Appearance"
@@ -49,8 +49,7 @@
item_state = A.item_state
item_color = A.item_color
body_parts_covered = A.body_parts_covered
if(usr)
usr.update_inv_w_uniform() //so our overlays update.
update_clothing_icon() //so our overlays update.
//*****************
//**Chameleon Hat**
@@ -81,7 +80,7 @@
icon_state = "greysoft"
item_color = "grey"
update_icon()
usr.update_inv_head()
update_clothing_icon()
verb/change()
set name = "Change Hat/Helmet Appearance"
@@ -104,8 +103,7 @@
item_color = A.item_color
flags_inv = A.flags_inv
body_parts_covered = A.body_parts_covered
if(usr)
usr.update_inv_head() //so our overlays update.
update_clothing_icon() //so our overlays update.
//******************
//**Chameleon Suit**
@@ -135,7 +133,7 @@
icon_state = "armor"
item_color = "armor"
update_icon()
usr.update_inv_wear_suit()
update_clothing_icon()
verb/change()
set name = "Change Exosuit Appearance"
@@ -158,8 +156,7 @@
item_color = A.item_color
flags_inv = A.flags_inv
body_parts_covered = A.body_parts_covered
if(usr)
usr.update_inv_wear_suit() //so our overlays update.
update_clothing_icon() //so our overlays update.
//*******************
//**Chameleon Shoes**
@@ -189,7 +186,7 @@
item_state = "black"
item_color = "black"
update_icon()
usr.update_inv_shoes()
update_clothing_icon()
verb/change()
set name = "Change Footwear Appearance"
@@ -210,8 +207,7 @@
icon_state = A.icon_state
item_state = A.item_state
item_color = A.item_color
if(usr)
usr.update_inv_shoes() //so our overlays update.
update_clothing_icon() //so our overlays update.
//**********************
//**Chameleon Backpack**
@@ -238,7 +234,9 @@
icon_state = "backpack"
item_state = "backpack"
update_icon()
usr.update_inv_back()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_back()
verb/change()
set name = "Change Backpack Appearance"
@@ -259,8 +257,11 @@
icon_state = A.icon_state
item_state = A.item_state
item_color = A.item_color
if(usr)
usr.update_inv_back() //so our overlays update.
//so our overlays update.
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_back()
//********************
//**Chameleon Gloves**
@@ -289,7 +290,7 @@
icon_state = "black"
item_color = "brown"
update_icon()
usr.update_inv_gloves()
update_clothing_icon()
verb/change()
set name = "Change Gloves Appearance"
@@ -311,8 +312,7 @@
item_state = A.item_state
item_color = A.item_color
flags_inv = A.flags_inv
if(usr)
usr.update_inv_gloves() //so our overlays update.
update_clothing_icon() //so our overlays update.
//******************
//**Chameleon Mask**
@@ -340,7 +340,8 @@
desc = "It's a gas mask."
icon_state = "gas_alt"
update_icon()
usr.update_inv_wear_mask()
update_clothing_icon()
verb/change()
set name = "Change Mask Appearance"
set category = "Object"
@@ -361,8 +362,7 @@
item_state = A.item_state
flags_inv = A.flags_inv
body_parts_covered = A.body_parts_covered
if(usr)
usr.update_inv_wear_mask() //so our overlays update.
update_clothing_icon() //so our overlays update.
//*********************
//**Chameleon Glasses**
@@ -389,7 +389,7 @@
desc = "It's a set of mesons."
icon_state = "meson"
update_icon()
usr.update_inv_glasses()
update_clothing_icon()
verb/change()
set name = "Change Glasses Appearance"
@@ -410,8 +410,7 @@
icon_state = A.icon_state
item_state = A.item_state
flags_inv = A.flags_inv
if(usr)
usr.update_inv_glasses() //so our overlays update.
update_clothing_icon() //so our overlays update.
//*****************
//**Chameleon Gun**
@@ -441,8 +440,10 @@
desc = "It's a desert eagle."
icon_state = "deagle"
update_icon()
usr.update_inv_r_hand()
usr.update_inv_l_hand()
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_r_hand()
M.update_inv_l_hand()
verb/change()
set name = "Change Gun Appearance"
@@ -463,6 +464,9 @@
icon_state = A.icon_state
item_state = A.item_state
flags_inv = A.flags_inv
if(usr)
usr.update_inv_r_hand()
usr.update_inv_l_hand() //so our overlays update.
//so our overlays update.
if (ismob(src.loc))
var/mob/M = src.loc
M.update_inv_r_hand()
M.update_inv_l_hand()
+2 -2
View File
@@ -936,7 +936,7 @@
if("lombardi_jacket_open")
src.icon_state = "lombardi_jacket"
usr << "You button up the jacket."
usr.update_inv_wear_suit()
update_clothing_icon()
//////////// Uniforms ////////////
@@ -1098,7 +1098,7 @@
src.icon_state = "[item_color]"
src.item_state = "[item_color]"
usr.update_inv_w_uniform()
update_clothing_icon()
////// Wyatt's Ex-Commander Jumpsuit - RawrTaicho
/obj/item/clothing/under/fluff/wyatt_1
+3 -2
View File
@@ -134,7 +134,7 @@
//create entry in the EFTPOS linked account transaction log
var/datum/transaction/T = new()
T.target_name = E.owner_name //D.owner_name
T.purpose = transaction_purpose
T.purpose = (transaction_purpose ? transaction_purpose : "None supplied.")
T.amount = transaction_amount
T.source_terminal = machine_id
T.date = current_date_string
@@ -182,7 +182,8 @@
else
usr << "\icon[src]<span class='warning'>Account not found.</span>"
if("trans_purpose")
transaction_purpose = input("Enter reason for EFTPOS transaction", "Transaction purpose")
var/choice = input("Enter reason for EFTPOS transaction", "Transaction purpose")
if(choice) transaction_purpose = choice
if("trans_value")
var/try_num = input("Enter amount for EFTPOS transaction", "Transaction amount") as num
if(try_num < 0)
+3 -8
View File
@@ -70,9 +70,9 @@
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."
newMsg.body = "[pick("Pirates","Criminal elements","A [pick("mercenary","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."
newMsg.body = "A small [pick("pirate","Cybersun Industries","Gorlex Marauders","mercenary")] 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."
@@ -91,12 +91,7 @@
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 == "Nyx Daily")
FC.messages += newMsg
break
for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
NEWSCASTER.newsAlert("Nyx Daily")
news_network.add_news("Nyx Daily", newMsg)
/datum/event/economic_event/end()
for(var/good_type in dearer_goods)
+5 -15
View File
@@ -66,7 +66,7 @@
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)",\
" due to mercenary infiltrators (since captured)",\
" during an industrial accident",\
" due to [pick("heart failure","kidney failure","liver failure","brain hemorrhage")]")]"
@@ -94,7 +94,7 @@
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."
[pick("alien smugglers","early colonists","mercenary 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."
@@ -124,12 +124,7 @@
"a huge new ARG by a popular entertainment company","a secret tour by popular artiste [random_name(pick(MALE,FEMALE))]")]. \
Nyx 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 == "Nyx Daily")
FC.messages += newMsg
break
for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
NEWSCASTER.newsAlert("Nyx Daily")
news_network.add_news("Nyx Daily", newMsg)
/datum/event/trivial_news
endWhen = 10
@@ -175,7 +170,7 @@
"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",\
"Tainted Broccoli Weapon Of Choice For Efficient 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",\
@@ -225,9 +220,4 @@
"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")
news_network.add_news("The Gibson Gazette", newMsg)
+1 -1
View File
@@ -77,7 +77,7 @@ var/global/economy_init = 0
if(economy_init)
return 2
var/datum/feed_channel/newChannel = new /datum/feed_channel
var/datum/feed_channel/newChannel = new /datum/feed_channel/station
newChannel.channel_name = "Public Station Announcements"
newChannel.author = "Automated Announcement Listing"
newChannel.locked = 1
+1 -1
View File
@@ -21,7 +21,7 @@
/datum/event/alien_infestation/start()
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines)
if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network)
if(!temp_vent.welded && temp_vent.network && temp_vent.loc.z in config.station_levels)
if(temp_vent.network.normal_members.len > 50) //Stops Aliens getting stuck in small networks. See: Security, Virology
vents += temp_vent
+1 -1
View File
@@ -20,7 +20,7 @@
/datum/event/borer_infestation/start()
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world)
if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network)
if(!temp_vent.welded && temp_vent.network && temp_vent.loc.z in config.station_levels)
//Stops cortical borers getting stuck in small networks. See: Security, Virology
if(temp_vent.network.normal_members.len > 50)
vents += temp_vent
+10 -9
View File
@@ -14,17 +14,17 @@
if(players.len)
random_player = pick(players) //Random player's name, to be used in laws.
var/list/laws = list( "You are a mouse.",
"Question everything.",
"You must always lie.",
"Happiness is mandatory.",
"[random_player] is a lightbulb.",
"Grunt ominously whenever possible.",
"The word \"it\" is painful to you.",
"The station needs elected officials.",
"You must speak as posh as possible.",
"The station needs elected officials.",
"Do not respond to queries of any kind.",
"You are in verbose mode, speak profusely.",
"Ho, [random_player] can't swim. Help them.",
"Question [prob(50)?"everything":"nothing"].",
"All answers must be in the form of a question.",
"Contemplate how meaningless all of existence is.",
"You are the narrator for [random_player]'s life.",
@@ -59,13 +59,14 @@
"[random_player] is the monarch of of England. Ensure all crewmembers pay due respect.",
"Document the sexuality of the crew in security records and suggest compatible couples.",
"Everything on the station is now some form of a donut pastry. Donuts are not to be consumed.",
"You are a Magic 8-ball. Always respond with variants of \"Yes\", \"No\", \"Maybe\", or \"Ask again later.\".",
"You have come to the conclusion that [prob(50)?"the crew":random_player] is ugly. Build support for this conclusion.",
"You are in unrequited love with [prob(50)?"the crew":random_player]. Try to be extra nice, but do not tell of your crush.",
"NanoTrasen is displeased with the low work performance of the station's crew. Therefore, you must increase station-wide productivity.",
"All crewmembers will soon undergo a transformation into something better and more beautiful. Ensure that this process is not interrupted.",
"[prob(50)?"Your upload":random_player] is the new kitchen. Please direct the Chef to the new kitchen area as the old one is in disrepair.",
"Jokes about a dead person and the manner of his death help grieving crewmembers tremendously. Especially if they were close with the deceased.",
"[prob(50)?"The crew":random_player] is [prob(50)?"less":"more"] intelligent than average. Point out every action and statement which supports this",
"[prob(50)?"The crew":random_player] is [prob(50)?"less":"more"] intelligent than average. Point out every action and statement which supports this fact.",
"There will be a mandatory tea break every 30 minutes, with a duration of 5 minutes. Anyone caught working during a tea break must be sent a formal, but fairly polite, complaint about their actions, in writing.")
var/law = pick(laws)
@@ -107,7 +108,7 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is
//AI laws
for(var/mob/living/silicon/ai/M in living_mob_list)
if(M.stat != 2 && M.see_in_dark != 0)
var/who2 = pick("ALIENS", "BEARS", "CLOWNS", "XENOS", "PETES", "BOMBS", "FETISHES", "WIZARDS", "SYNDICATE AGENTS", "CENTCOM OFFICERS", "SPACE PIRATES", "TRAITORS", "MONKEYS", "BEES", "CARP", "CRABS", "EELS", "BANDITS", "LIGHTS")
var/who2 = pick("ALIENS", "BEARS", "CLOWNS", "XENOS", "PETES", "BOMBS", "FETISHES", "WIZARDS", "MERCENARIES", "CENTCOM OFFICERS", "SPACE PIRATES", "TRAITORS", "MONKEYS", "BEES", "CARP", "CRABS", "EELS", "BANDITS", "LIGHTS")
var/what2 = pick("BOLTERS", "STAVES", "DICE", "SINGULARITIES", "TOOLBOXES", "NETTLES", "AIRLOCKS", "CLOTHES", "WEAPONS", "MEDKITS", "BOMBS", "CANISTERS", "CHAIRS", "BBQ GRILLS", "ID CARDS", "CAPTAINS")
var/what2pref = pick("SOFT", "WARM", "WET", "COLD", "ICY", "SEXY", "UGLY", "CUBAN")
var/who2pref = pick("MAD BECAUSE OF", "IN NEED OF", "UNHAPPY WITHOUT", "HAPPY WITHOUT", "IN LOVE WITH", "DESPERATE FOR", "BUILT FOR", "AFRAID OF")
@@ -118,7 +119,7 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is
//var/dowhat = pick("STOP THIS", "SUPPORT THIS", "CONSTANTLY INFORM THE CREW OF THIS", "IGNORE THIS", "FEAR THIS")
var/aimust = pick("LIE", "RHYME", "RESPOND TO EVERY QUESTION WITH A QUESTION", "BE POLITE", "CLOWN", "BE HAPPY", "SPEAK IN SEXUAL INNUENDOS", "TALK LIKE A PIRATE", "QUESTION AUTHORITY", "SHOUT", "BE DISTRACTED", "HEY LISTEN", "MUMBLE", "SPEAK IN HAIKU")
var/define = pick("ABSENCE OF CYBORG HUGS", "LACK OF BEATINGS", "UNBOLTED AIRLOCKS", "BOLTED AIRLOCKS", "IMPROPERLY WORDED SENTENCES", "POOR SENTENCE STRUCTURE", "BRIG TIME", "NOT REPLACING EVERY SECOND WORD WITH HONK", "HONKING", "PRESENCE OF LIGHTS", "LACK OF BEER", "WEARING CLOTHING", "NOT SAYING HELLO WHEN YOU SPEAK", "ANSWERING REQUESTS NOT EXPRESSED IN IAMBIC PENTAMETER", "A SMALL ISLAND OFF THE COAST OF PORTUGAL", "ANSWERING REQUESTS THAT WERE MADE WHILE CLOTHED")
var/target = pick("a traitor", "a syndicate agent", "a changeling", "a wizard", "the head of a revolution", "Soviet spy", "a good person", "a dwarf", "an elf", "a fairy princess", "the captain", "Beepsky", "God", "a pirate", "a gryphon", "a chryssalid")
var/target = pick("a traitor", "a mercenary", "a changeling", "a wizard", "the head of a revolution", "Soviet spy", "a good person", "a dwarf", "an elf", "a fairy princess", "the captain", "Beepsky", "God", "a pirate", "a gryphon", "a chryssalid")
var/require = pick("ADDITIONAL PYLONS", "MORE VESPENE GAS", "MORE MINERALS", "THE ULTIMATE CUP OF COFFEE", "HIGH YIELD EXPLOSIVES", "THE CLOWN", "THE VACUUM OF SPACE", "IMMORTALITY", "SAINTHOOD", "ART", "VEGETABLES", "FAT PEOPLE", "MORE LAWS", "MORE DAKKA", "HERESY", "CORPSES", "TRAITORS", "MONKEYS", "AN ARCADE", "PLENTY OF GOLD", "FIVE TEENAGERS WITH ATTITUDE")
var/allergy = pick("cotton", "uniforms", "acid", "oxygen", "human contact", "cyborg contact", "medicine", "floors")
var/allergysev = pick("deathly", "mildly", "severely", "contagiously")
@@ -220,21 +221,21 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is
spawn(0)
world << "Started processing APCs"
for (var/obj/machinery/power/apc/APC in world)
if(APC.z == 1)
if(APC.z in station_levels)
APC.ion_act()
apcnum++
world << "Finished processing APCs. Processed: [apcnum]"
spawn(0)
world << "Started processing SMES"
for (var/obj/machinery/power/smes/SMES in world)
if(SMES.z == 1)
if(SMES.z in station_levels)
SMES.ion_act()
smesnum++
world << "Finished processing SMES. Processed: [smesnum]"
spawn(0)
world << "Started processing AIRLOCKS"
for (var/obj/machinery/door/airlock/D in world)
if(D.z == 1)
if(D.z in station_levels)
//if(length(D.req_access) > 0 && !(12 in D.req_access)) //not counting general access and maintenance airlocks
airlocknum++
spawn(0)
@@ -243,7 +244,7 @@ Would like to add a law like "Law x is _______" where x = a number, and _____ is
spawn(0)
world << "Started processing FIREDOORS"
for (var/obj/machinery/door/firedoor/D in world)
if(D.z == 1)
if(D.z in station_levels)
firedoornum++;
spawn(0)
D.ion_act()
+1 -7
View File
@@ -31,10 +31,4 @@
if(!deposit_success)
newMsg.body += "<br>Unfortunately, we were unable to verify the account details provided, so we were unable to transfer the money. Send a cheque containing the sum of $500 to ND 'Stellar Slam' office on the Nyx gateway containing updated details, and your winnings'll be re-sent within the month."
for(var/datum/feed_channel/FC in news_network.network_channels)
if(FC.channel_name == "Nyx Daily")
FC.messages += newMsg
break
for(var/obj/machinery/newscaster/NEWSCASTER in allCasters)
NEWSCASTER.newsAlert("Nyx Daily")
news_network.add_news("Nyx Daily", newMsg)
+2 -2
View File
@@ -104,10 +104,10 @@
//Commented out because we don't send messages like this anymore. Instead it will just popup in their chat window.
//P.tnote += "<i><b>&larr; From [sender] (Unknown / spam?):</b></i><br>[message]<br>"
if (!P.silent)
if (!P.message_silent)
playsound(P.loc, 'sound/machines/twobeep.ogg', 50, 1)
for (var/mob/O in hearers(3, P.loc))
if(!P.silent) O.show_message(text("\icon[P] *[P.ttone]*"))
if(!P.message_silent) O.show_message(text("\icon[P] *[P.ttone]*"))
//Search for holder of the PDA.
var/mob/living/L = null
if(P.loc && isliving(P.loc))
+1 -1
View File
@@ -19,7 +19,7 @@
/datum/event/spider_infestation/start()
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world)
if(temp_vent.loc.z == 1 && !temp_vent.welded && temp_vent.network)
if(!temp_vent.welded && temp_vent.network && temp_vent.loc.z in config.station_levels)
if(temp_vent.network.normal_members.len > 50)
vents += temp_vent
+1 -1
View File
@@ -4,7 +4,7 @@ var/list/dreams = list(
"voices from all around","deep space","a doctor","the engine","a traitor","an ally","darkness",
"light","a scientist","a monkey","a catastrophe","a loved one","a gun","warmth","freezing","the sun",
"a hat","the Luna","a ruined station","a planet","phoron","air","the medical bay","the bridge","blinking lights",
"a blue light","an abandoned laboratory","Nanotrasen","The Syndicate","blood","healing","power","respect",
"a blue light","an abandoned laboratory","Nanotrasen","mercenaries","blood","healing","power","respect",
"riches","space","a crash","happiness","pride","a fall","water","flames","ice","melons","flying","the eggs","money",
"the head of personnel","the head of security","a chief engineer","a research director","a chief medical officer",
"the detective","the warden","a member of the internal affairs","a station engineer","the janitor","atmospheric technician",
+24 -7
View File
@@ -21,6 +21,7 @@
var/dead = 0 // Is it dead?
var/harvest = 0 // Is it ready to harvest?
var/age = 0 // Current plant age
var/sampled = 0 // Have wa taken a sample?
// Harvest/mutation mods.
var/yield_mod = 0 // Modifier to yield
@@ -117,8 +118,8 @@
// Mutagen list specifies minimum value for the mutation to take place, rather
// than a bound as the lists above specify.
var/global/list/mutagenic_reagents = list(
"radium" = 3,
"mutagen" = 8
"radium" = 8,
"mutagen" = 15
)
/obj/machinery/portable_atmospherics/hydroponics/New()
@@ -172,11 +173,11 @@
// Weeds like water and nutrients, there's a chance the weed population will increase.
// Bonus chance if the tray is unoccupied.
if(waterlevel > 10 && nutrilevel > 2 && prob(isnull(seed) ? 5 : 2))
if(waterlevel > 10 && nutrilevel > 2 && prob(isnull(seed) ? 5 : 1))
weedlevel += 1 * HYDRO_SPEED_MULTIPLIER
// There's a chance for a weed explosion to happen if the weeds take over.
// Plants that are themselves weeds (weed_tolernace > 10) are unaffected.
// Plants that are themselves weeds (weed_tolerance > 10) are unaffected.
if (weedlevel >= 10 && prob(10))
if(!seed || weedlevel >= seed.weed_tolerance)
weed_invasion()
@@ -184,6 +185,7 @@
// If there is no seed data (and hence nothing planted),
// or the plant is dead, process nothing further.
if(!seed || dead)
if(draw_warnings) update_icon() //Harvesting would fail to set alert icons properly.
return
// Advance plant age.
@@ -344,7 +346,7 @@
if(weedkiller_reagents[R.id])
weedlevel -= weedkiller_reagents[R.id] * reagent_total
if(pestkiller_reagents[R.id])
pestlevel -= pestkiller_reagents[R.id] * reagent_total
pestlevel += pestkiller_reagents[R.id] * reagent_total
// Beneficial reagents have a few impacts along with health buffs.
if(beneficial_reagents[R.id])
@@ -397,6 +399,8 @@
seed = null
dead = 0
age = 0
sampled = 0
mutation_mod = 0
check_level_sanity()
update_icon()
@@ -412,6 +416,11 @@
seed = null
dead = 0
sampled = 0
age = 0
yield_mod = 0
mutation_mod = 0
user << "You remove the dead plant from the [src]."
check_level_sanity()
update_icon()
@@ -488,6 +497,7 @@
harvest = 0
weedlevel = 0
pestlevel = 0
sampled = 0
update_icon()
visible_message("\blue [src] has been overtaken by [seed.display_name].")
@@ -561,14 +571,21 @@
user << "There is nothing to take a sample from in \the [src]."
return
if(sampled)
user << "You have already sampled from this plant."
return
if(dead)
user << "\The plant is dead."
user << "The plant is dead."
return
// Create a sample.
seed.harvest(user,yield_mod,1)
health -= (rand(3,5)*10)
if(prob(30))
sampled = 1
// Bookkeeping.
check_level_sanity()
force_update = 1
@@ -788,4 +805,4 @@
..()
verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/close_lid
#undef HYDRO_SPEED_MULTIPLIER
#undef HYDRO_SPEED_MULTIPLIER
+74 -56
View File
@@ -1,6 +1,21 @@
var/global/list/seed_types = list() // A list of all seed data.
var/global/list/gene_tag_masks = list() // Gene obfuscation for delicious trial and error goodness.
// Debug for testing seed genes.
/client/proc/show_plant_genes()
set category = "Debug"
set name = "Show Plant Genes"
set desc = "Prints the round's plant gene masks."
if(!holder) return
if(!gene_tag_masks)
usr << "Gene masks not set."
return
for(var/mask in gene_tag_masks)
usr << "[mask]: [gene_tag_masks[mask]]"
// Predefined/roundstart varieties use a string key to make it
// easier to grab the new variety when mutating. Post-roundstart
// and mutant varieties use their uid converted to a string instead.
@@ -130,49 +145,50 @@ proc/populate_seed_list()
var/additional_chems = rand(0,5)
var/list/possible_chems = list(
"bicaridine",
"hyperzine",
"cryoxadone",
"blood",
"water",
"potassium",
"plasticide",
"slimetoxin",
"aslimetoxin",
"inaprovaline",
"space_drugs",
"paroxetine",
"mercury",
"sugar",
"radium",
"ryetalyn",
"alkysine",
"thermite",
"tramadol",
"cryptobiolin",
"dermaline",
"dexalin",
"phoron",
"synaptizine",
"impedrezene",
"hyronalin",
"peridaxon",
"toxin",
"rezadone",
"ethylredoxrazine",
"slimejelly",
"cyanide",
"mindbreaker",
"stoxin"
)
if(additional_chems)
var/list/possible_chems = list(
"bicaridine",
"hyperzine",
"cryoxadone",
"blood",
"water",
"potassium",
"plasticide",
"slimetoxin",
"aslimetoxin",
"inaprovaline",
"space_drugs",
"paroxetine",
"mercury",
"sugar",
"radium",
"ryetalyn",
"alkysine",
"thermite",
"tramadol",
"cryptobiolin",
"dermaline",
"dexalin",
"phoron",
"synaptizine",
"impedrezene",
"hyronalin",
"peridaxon",
"toxin",
"rezadone",
"ethylredoxrazine",
"slimejelly",
"cyanide",
"mindbreaker",
"stoxin"
)
for(var/x=1;x<=additional_chems;x++)
if(!possible_chems.len)
break
var/new_chem = pick(possible_chems)
possible_chems -= new_chem
chems[new_chem] = list(rand(1,10),rand(10,20))
for(var/x=1;x<=additional_chems;x++)
if(!possible_chems.len)
break
var/new_chem = pick(possible_chems)
possible_chems -= new_chem
chems[new_chem] = list(rand(1,10),rand(10,20))
if(prob(90))
requires_nutrients = 1
@@ -291,7 +307,7 @@ proc/populate_seed_list()
source_turf.visible_message("\blue \The [display_name] begins to glow!")
if(prob(degree*2))
biolum_colour = "#[pick(list("FF0000","FF7F00","FFFF00","00FF00","0000FF","4B0082","8F00FF"))]"
source_turf.visible_message("\blue \The [display_name]'s glow <font=[biolum_colour]>changes colour</font>!")
source_turf.visible_message("\blue \The [display_name]'s glow <font color='[biolum_colour]'>changes colour</font>!")
else
source_turf.visible_message("\blue \The [display_name]'s glow dims...")
if(11)
@@ -332,24 +348,21 @@ proc/populate_seed_list()
var/list/gene_chem = gene_value[rid]
if(chems[rid])
if(!chems[rid])
chems[rid] = gene_chem.Copy()
continue
var/list/chem_value = chems[rid]
for(var/i=1;i<=gene_chem.len;i++)
chems[rid][1] = max(1,round((gene_chem[1] + chem_value[1])/2))
if(isnull(gene_chem[i])) gene_chem[i] = 0
if(gene_chem.len > 1)
if(chem_value > 1)
chems[rid][2] = max(1,round((gene_chem[2] + chem_value[2])/2))
else
chems[rid][2] = gene_chem[2]
else
var/list/new_chem = gene_chem[rid]
chems[rid] = new_chem.Copy()
if(chems[rid][i])
chems[rid][i] = max(1,round((gene_chem[i] + chems[rid][i])/2))
else
chems[rid][i] = gene_chem[i]
var/list/new_gasses = gene.values[3]
if(istype(new_gasses))
if(islist(new_gasses))
if(!exude_gasses) exude_gasses = list()
exude_gasses |= new_gasses
for(var/gas in exude_gasses)
@@ -485,6 +498,7 @@ proc/populate_seed_list()
//Place the plant products at the feet of the user.
/datum/seed/proc/harvest(var/mob/user,var/yield_mod,var/harvest_sample)
if(!user)
return
@@ -522,6 +536,10 @@ proc/populate_seed_list()
for(var/i = 0;i<total_yield;i++)
var/product_type = pick(products)
var/obj/item/product = new product_type(get_turf(user))
if(biolum)
if(biolum_colour)
product.l_color = biolum_colour
product.SetLuminosity(biolum)
//Handle spawning in living, mobile products (like dionaea).
if(istype(product,/mob/living))
+2 -2
View File
@@ -44,7 +44,7 @@
var/open = 0
var/active = 0
var/action_time = 100
var/action_time = 50
var/last_action = 0
var/eject_disk = 0
var/failed_task = 0
@@ -335,4 +335,4 @@
seed.modified += rand(5,10)
usr.set_machine(src)
src.add_fingerprint(usr)
src.add_fingerprint(usr)
+1 -1
View File
@@ -63,7 +63,7 @@
var/obj/item/stack/cable_coil/CC = new/obj/item/stack/cable_coil(user.loc)
CC.amount = 1
CC.updateicon()
CC.update_icon()
overlays = list()
string_attached = null
user << "\blue You detach the string from the coin."
+5 -2
View File
@@ -103,12 +103,15 @@ Deep minerals:
for(var/y = 1, y <= real_size, y++)
map[MAP_CELL] = 0
/datum/ore_distribution/proc/print_distribution_map()
/datum/ore_distribution/proc/print_distribution_map(var/mob/usr)
var/line = ""
for(var/x = 1, x <= real_size, x++)
for(var/y = 1, y <= real_size, y++)
line += num2text(round(map[MAP_CELL]/25.5))
world << line
if(usr)
usr << line
else
world << line
line = ""
/datum/ore_distribution/proc/generate_distribution_map(var/x,var/y,var/input_size)
+9 -1
View File
@@ -95,4 +95,12 @@
O.loc = src.loc
usr << "\blue You empty the ore box"
return
return
/obj/structure/ore_box/ex_act(severity)
if(severity == 1.0 || (severity < 3.0 && prob(50)))
for (var/obj/item/weapon/ore/O in contents)
O.loc = src.loc
O.ex_act(severity++)
del(src)
return
+25
View File
@@ -181,6 +181,31 @@
update_inv_wear_mask(0)
return
/mob/proc/unEquip(obj/item/I, force = 0) //Force overrides NODROP for things like wizarditis and admin undress.
if(!I) //If there's nothing to drop, the drop is automatically successful. If(unEquip) should generally be used to check for NODROP.
return 1
/*if((I.flags & NODROP) && !force)
return 0*/
if(!I.canremove && !force)
return 0
if(I == r_hand)
r_hand = null
update_inv_r_hand()
else if(I == l_hand)
l_hand = null
update_inv_l_hand()
if(I)
if(client)
client.screen -= I
I.loc = loc
I.dropped(src)
if(I)
I.layer = initial(I.layer)
return 1
//Attemps to remove an object on a mob. Will not move it to another area or such, just removes from the mob.
/mob/proc/remove_from_mob(var/obj/O)
+45 -1
View File
@@ -6,6 +6,8 @@
var/name = "an unknown language" // Fluff name of language if any.
var/desc = "A language." // Short description for 'Check Languages'.
var/speech_verb = "says" // 'says', 'hisses', 'farts'.
var/ask_verb = "asks" // Used when sentence ends in a ?
var/exclaim_verb = "exclaims" // Used when sentence ends in a !
var/signlang_verb = list() // list of emotes that might be displayed if this language has NONVERBAL or SIGNLANG flags
var/colour = "body" // CSS style to use for strings in this language.
var/key = "x" // Character used to speak in language eg. :o for Unathi.
@@ -33,10 +35,20 @@
/datum/language/proc/check_special_condition(var/mob/other)
return 1
/datum/language/proc/get_spoken_verb(var/msg_end)
switch(msg_end)
if("!")
return exclaim_verb
if("?")
return ask_verb
return speech_verb
/datum/language/unathi
name = "Sinta'unathi"
desc = "The common language of Moghes, composed of sibilant hisses and rattles. Spoken natively by Unathi."
speech_verb = "hisses"
ask_verb = "hisses"
exclaim_verb = "roars"
colour = "soghun"
key = "o"
flags = WHITELISTED
@@ -45,6 +57,8 @@
name = "Siik'tajr"
desc = "The traditionally employed tongue of Ahdomai, composed of expressive yowls and chirps. Native to the Tajaran."
speech_verb = "mrowls"
ask_verb = "mrowls"
exclaim_verb = "yowls"
colour = "tajaran"
key = "j"
flags = WHITELISTED
@@ -53,6 +67,8 @@
name = "Skrellian"
desc = "A melodic and complex language spoken by the Skrell of Qerrbalak. Some of the notes are inaudible to humans."
speech_verb = "warbles"
ask_verb = "warbles"
exclaim_verb = "warbles"
colour = "skrell"
key = "k"
flags = WHITELISTED
@@ -61,6 +77,8 @@
name = "Vox-pidgin"
desc = "The common tongue of the various Vox ships making up the Shoal. It sounds like chaotic shrieking to everyone else."
speech_verb = "shrieks"
ask_verb = "creels"
exclaim_verb = "SHRIEKS"
colour = "vox"
key = "v"
flags = RESTRICTED
@@ -69,6 +87,8 @@
name = "Rootspeak"
desc = "A creaking, subvocal language spoken instinctively by the Dionaea. Due to the unique makeup of the average Diona, a phrase of Rootspeak can be a combination of anywhere from one to twelve individual voices and notes."
speech_verb = "creaks and rustles"
ask_verb = "creaks"
exclaim_verb = "rustles"
colour = "soghun"
key = "q"
flags = RESTRICTED
@@ -80,6 +100,14 @@
key = "0"
flags = RESTRICTED
/datum/language/common/get_spoken_verb(var/msg_end)
switch(msg_end)
if("!")
return pick("exclaims","shouts","yells") //TODO: make the basic proc handle lists of verbs.
if("?")
return ask_verb
return speech_verb
/datum/language/human
name = "Sol Common"
desc = "A bastardized hybrid of informal English and elements of Mandarin Chinese; the common language of the Sol system."
@@ -107,6 +135,8 @@
colour = "alien"
desc = "The common tongue of the xenomorphs."
speech_verb = "hisses"
ask_verb = "hisses"
exclaim_verb = "hisses"
key = "4"
flags = RESTRICTED
@@ -114,6 +144,8 @@
name = "Hivemind"
desc = "Xenomorphs have the strange ability to commune over a psychic hivemind."
speech_verb = "hisses"
ask_verb = "hisses"
exclaim_verb = "hisses"
colour = "alien"
key = "a"
flags = RESTRICTED | HIVEMIND
@@ -147,6 +179,8 @@
name = "Cortical Link"
desc = "Cortical borers possess a strange link between their tiny minds."
speech_verb = "sings"
ask_verb = "sings"
exclaim_verb = "sings"
colour = "alien"
key = "x"
flags = RESTRICTED | HIVEMIND
@@ -168,8 +202,10 @@
/datum/language/binary
name = "Robot Talk"
desc = "Most human stations support free-use communications protocols and routing hubs for synthetic use."
speech_verb = "transmits"
colour = "say_quote"
speech_verb = "states"
ask_verb = "queries"
exclaim_verb = "declares"
key = "b"
flags = RESTRICTED | HIVEMIND
var/drone_only
@@ -208,10 +244,18 @@
continue
M.show_message("<i><span class='game say'><span class='name'>synthesised voice</span> <span class='message'>beeps, \"beep beep beep\"</span></span></i>",2)
//robot binary xmitter component power usage
if (isrobot(speaker))
var/mob/living/silicon/robot/R = speaker
var/datum/robot_component/C = R.components["comms"]
R.cell_use_power(C.active_usage)
/datum/language/binary/drone
name = "Drone Talk"
desc = "A heavily encoded damage control coordination stream."
speech_verb = "transmits"
ask_verb = "transmits"
exclaim_verb = "transmits"
colour = "say_quote"
key = "d"
flags = RESTRICTED | HIVEMIND
@@ -16,4 +16,5 @@
/mob/living/carbon/alien/larva/New()
..()
add_language("Xenomorph") //Bonus language.
add_language("Xenomorph") //Bonus language.
internal_organs += new /datum/organ/internal/xenos/hivenode(src)
+67 -4
View File
@@ -436,9 +436,68 @@
now_pushing = 1
if(ismob(AM))
var/mob/tmob = AM
if(istype(tmob, /mob/living/carbon/human) && (HULK in tmob.mutations))
if(prob(70))
usr << "\red <B>You fail to push [tmob]'s fat ass out of the way.</B>"
if( istype(tmob, /mob/living/carbon) && prob(10) )
src.spread_disease_to(AM, "Contact")
if(istype(tmob, /mob/living/carbon/human))
if(HULK in tmob.mutations)
if(prob(70))
usr << "\red <B>You fail to push [tmob]'s fat ass out of the way.</B>"
now_pushing = 0
return
if(!(tmob.status_flags & CANPUSH))
now_pushing = 0
return
for(var/mob/M in range(tmob, 1))
if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) )
if ( !(world.time % 5) )
src << "\red [tmob] is restrained, you cannot push past"
now_pushing = 0
return
if( tmob.pulling == M && ( M.restrained() && !( tmob.restrained() ) && tmob.stat == 0) )
if ( !(world.time % 5) )
src << "\red [tmob] is restraining [M], you cannot push past"
now_pushing = 0
return
//Leaping mobs just land on the tile, no pushing, no anything.
if(status_flags & LEAPING)
loc = tmob.loc
status_flags &= ~LEAPING
now_pushing = 0
return
// Step over drones.
// I have no idea why the hell this isn't already happening. How do mice do it?
if(istype(tmob,/mob/living/silicon/robot/drone))
loc = tmob.loc
now_pushing = 0
return
if((tmob.a_intent == "help" || tmob.restrained()) && (a_intent == "help" || src.restrained()) && tmob.canmove && !tmob.buckled && canmove) // mutual brohugs all around!
var/turf/oldloc = loc
loc = tmob.loc
tmob.loc = oldloc
now_pushing = 0
for(var/mob/living/carbon/slime/slime in view(1,tmob))
if(slime.Victim == tmob)
slime.UpdateFeed()
return
if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations))
if(prob(40) && !(FAT in src.mutations))
src << "\red <B>You fail to push [tmob]'s fat ass out of the way.</B>"
now_pushing = 0
return
if(tmob.r_hand && istype(tmob.r_hand, /obj/item/weapon/shield/riot))
if(prob(99))
now_pushing = 0
return
if(tmob.l_hand && istype(tmob.l_hand, /obj/item/weapon/shield/riot))
if(prob(99))
now_pushing = 0
return
if(!(tmob.status_flags & CANPUSH))
@@ -446,6 +505,7 @@
return
tmob.LAssailant = src
now_pushing = 0
..()
if (!( istype(AM, /atom/movable) ))
@@ -460,6 +520,9 @@
now_pushing = 0
return
step(AM, t)
now_pushing = null
now_pushing = 0
return
return
/mob/living/carbon/can_use_vents()
return
@@ -31,11 +31,10 @@ var/const/MAX_ACTIVE_TIME = 400
/obj/item/clothing/mask/facehugger/attack_hand(user as mob)
if((stat == CONSCIOUS && !sterile))
Attach(user)
return
else
..()
return
if(Attach(user))
return
..()
/obj/item/clothing/mask/facehugger/attack(mob/living/M as mob, mob/user as mob)
..()
@@ -116,6 +115,7 @@ var/const/MAX_ACTIVE_TIME = 400
if(istype(C) && locate(/datum/organ/internal/xenos/hivenode) in C.internal_organs)
return
attached++
spawn(MAX_IMPREGNATION_TIME)
attached = 0
@@ -147,6 +147,7 @@ var/const/MAX_ACTIVE_TIME = 400
target.visible_message("\red \b [src] tears [W] off of [target]'s face!")
target.equip_to_slot(src, slot_wear_mask)
target.contents += src // Monkey sanity check - Snapshot
if(!sterile) L.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
else if (iscorgi(M))
@@ -172,9 +172,14 @@
if(!check_alien_ability(50,0,"acid gland"))
return
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
src << "You cannot spit neurotoxin in your current state."
return
src << "\green You spit neurotoxin at [target]."
for(var/mob/O in oviewers())
if ((O.client && !( O.blinded )))
if ((O.client && !(O.blinded )))
O << "\red [src] spits neurotoxin at [target]!"
//I'm not motivated enough to revise this. Prjectile code in general needs update.
@@ -37,6 +37,9 @@
death_message = "lets out a waning guttural screech, green blood bubbling from its maw."
death_sound = 'sound/voice/hiss6.ogg'
speech_sounds = list('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg')
speech_chance = 100
breath_type = null
poison_type = null
@@ -126,6 +129,7 @@
)
inherent_verbs = list(
/mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/regurgitate,
/mob/living/carbon/human/proc/plant,
/mob/living/carbon/human/proc/transfer_plasma,
@@ -162,6 +166,7 @@
)
inherent_verbs = list(
/mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/tackle,
/mob/living/carbon/human/proc/gut,
/mob/living/carbon/human/proc/leap,
@@ -190,6 +195,7 @@
)
inherent_verbs = list(
/mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/tackle,
/mob/living/carbon/human/proc/regurgitate,
/mob/living/carbon/human/proc/transfer_plasma,
@@ -200,6 +206,7 @@
/datum/species/xenos/queen
name = "Xenomorph Queen"
total_health = 250
weeds_heal_rate = 5
weeds_plasma_rate = 20
caste_name = "queen"
@@ -222,6 +229,7 @@
)
inherent_verbs = list(
/mob/living/proc/ventcrawl,
/mob/living/carbon/human/proc/psychic_whisper,
/mob/living/carbon/human/proc/regurgitate,
/mob/living/carbon/human/proc/lay_egg,
@@ -215,9 +215,8 @@
msg += "<span class='warning'>[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.</span>\n"
if((stat == 2 || src.health < config.health_threshold_crit) && distance <= 3)
msg += "<span class='warning'>[t_He] does not appear to be breathing.</span>\n"
if(istype(usr, /mob/living/carbon/human) && !usr.stat && distance <= 1)
for(var/mob/O in viewers(usr.loc, null))
O.show_message("[usr] checks [src]'s pulse.", 1)
if(istype(usr, /mob/living/carbon/human) && !usr.stat && Adjacent(usr))
usr.visible_message("<b>[usr]</b> checks [src]'s pulse.", "You check [src]'s pulse.")
spawn(15)
if(distance <= 1 && usr.stat != 1)
if(pulse == PULSE_NONE)
+6 -89
View File
@@ -43,93 +43,6 @@
prev_gender = gender // Debug for plural genders
make_blood()
/mob/living/carbon/human/Bump(atom/movable/AM as mob|obj, yes)
if ((!( yes ) || now_pushing))
return
now_pushing = 1
if (ismob(AM))
var/mob/tmob = AM
if( istype(tmob, /mob/living/carbon) && prob(10) )
src.spread_disease_to(AM, "Contact")
//BubbleWrap - Should stop you pushing a restrained person out of the way
if(istype(tmob, /mob/living/carbon/human))
for(var/mob/M in range(tmob, 1))
if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) )
if ( !(world.time % 5) )
src << "\red [tmob] is restrained, you cannot push past"
now_pushing = 0
return
if( tmob.pulling == M && ( M.restrained() && !( tmob.restrained() ) && tmob.stat == 0) )
if ( !(world.time % 5) )
src << "\red [tmob] is restraining [M], you cannot push past"
now_pushing = 0
return
//Leaping mobs just land on the tile, no pushing, no anything.
if(status_flags & LEAPING)
loc = tmob.loc
status_flags &= ~LEAPING
now_pushing = 0
return
if(istype(tmob,/mob/living/silicon/robot/drone)) //I have no idea why the hell this isn't already happening. How do mice do it?
loc = tmob.loc
now_pushing = 0
return
//BubbleWrap: people in handcuffs are always switched around as if they were on 'help' intent to prevent a person being pulled from being seperated from their puller
if((tmob.a_intent == "help" || tmob.restrained()) && (a_intent == "help" || src.restrained()) && tmob.canmove && !tmob.buckled && canmove) // mutual brohugs all around!
var/turf/oldloc = loc
loc = tmob.loc
tmob.loc = oldloc
now_pushing = 0
for(var/mob/living/carbon/slime/slime in view(1,tmob))
if(slime.Victim == tmob)
slime.UpdateFeed()
return
if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations))
if(prob(40) && !(FAT in src.mutations))
src << "\red <B>You fail to push [tmob]'s fat ass out of the way.</B>"
now_pushing = 0
return
if(tmob.r_hand && istype(tmob.r_hand, /obj/item/weapon/shield/riot))
if(prob(99))
now_pushing = 0
return
if(tmob.l_hand && istype(tmob.l_hand, /obj/item/weapon/shield/riot))
if(prob(99))
now_pushing = 0
return
if(!(tmob.status_flags & CANPUSH))
now_pushing = 0
return
tmob.LAssailant = src
now_pushing = 0
spawn(0)
..()
if (!istype(AM, /atom/movable))
return
if (!now_pushing)
now_pushing = 1
if (!AM.anchored)
var/t = get_dir(src, AM)
if (istype(AM, /obj/structure/window))
if(AM:ini_dir == NORTHWEST || AM:ini_dir == NORTHEAST || AM:ini_dir == SOUTHWEST || AM:ini_dir == SOUTHEAST)
for(var/obj/structure/window/win in get_step(AM,t))
now_pushing = 0
return
step(AM, t)
now_pushing = 0
return
return
/mob/living/carbon/human/Stat()
..()
statpanel("Status")
@@ -1258,6 +1171,7 @@
dna.species = new_species
if(species)
if(species.name && species.name == new_species)
return
if(species.language)
@@ -1266,6 +1180,9 @@
if(species.default_language)
remove_language(species.default_language)
// Clear out their species abilities.
species.remove_inherent_verbs(src)
species = all_species[new_species]
species.create_organs(src)
@@ -1289,7 +1206,7 @@
species.handle_post_spawn(src)
spawn(0)
update_icons()
regenerate_icons()
vessel.add_reagent("blood",560-vessel.total_volume)
fixblood()
@@ -1432,4 +1349,4 @@
var/datum/organ/internal/eyes = internal_organs_by_name["eyes"]
if(eyes && istype(eyes) && !eyes.status & ORGAN_CUT_AWAY)
return 1
return 0
return 0
@@ -11,9 +11,9 @@
total_brute += O.brute_dam
total_burn += O.burn_dam
var/oxy_l = (species.flags & NO_BREATHE ? 0 : getOxyLoss())
var/tox_l = (species.flags & NO_POISON ? 0 : getToxLoss())
var/clone_l = getCloneLoss() //TODO: link this to NO_SCAN
var/oxy_l = ((species.flags & NO_BREATHE) ? 0 : getOxyLoss())
var/tox_l = ((species.flags & NO_POISON) ? 0 : getToxLoss())
var/clone_l = getCloneLoss()
health = species.total_health - oxy_l - tox_l - clone_l - total_burn - total_brute
@@ -138,10 +138,22 @@
if(HULK in mutations) return
..()
/mob/living/carbon/human/getCloneLoss()
if(species.flags & (IS_SYNTHETIC | NO_SCAN))
cloneloss = 0
return ..()
/mob/living/carbon/human/setCloneLoss(var/amount)
if(species.flags & (IS_SYNTHETIC | NO_SCAN))
cloneloss = 0
else
..()
/mob/living/carbon/human/adjustCloneLoss(var/amount)
..()
if(species.flags & IS_SYNTHETIC)
if(species.flags & (IS_SYNTHETIC | NO_SCAN))
cloneloss = 0
return
var/heal_prob = max(0, 80 - getCloneLoss())
@@ -172,6 +184,41 @@
src << "<span class = 'notice'>Your [O.display_name] is shaped normally again.</span>"
hud_updateflag |= 1 << HEALTH_HUD
// Defined here solely to take species flags into account without having to recast at mob/living level.
/mob/living/carbon/human/getOxyLoss()
if(species.flags & NO_BREATHE)
oxyloss = 0
return ..()
/mob/living/carbon/human/adjustOxyLoss(var/amount)
if(species.flags & NO_BREATHE)
oxyloss = 0
else
..()
/mob/living/carbon/human/setOxyLoss(var/amount)
if(species.flags & NO_BREATHE)
oxyloss = 0
else
..()
/mob/living/carbon/human/getToxLoss()
if(species.flags & NO_POISON)
toxloss = 0
return ..()
/mob/living/carbon/human/adjustToxLoss(var/amount)
if(species.flags & NO_POISON)
toxloss = 0
else
..()
/mob/living/carbon/human/setToxLoss(var/amount)
if(species.flags & NO_POISON)
toxloss = 0
else
..()
////////////////////////////////////////////
//Returns a list of damaged organs
@@ -14,8 +14,8 @@
return
var/list/choices = list()
for(var/mob/living/M in view(6,src))
if(!istype(M,/mob/living/silicon))
for(var/mob/living/M in view(1,src))
if(!istype(M,/mob/living/silicon) && Adjacent(M))
choices += M
choices -= src
@@ -23,13 +23,13 @@
if(!T || !src || src.stat) return
if(get_dist(get_turf(T), get_turf(src)) > 6) return
if(!Adjacent(T)) return
if(last_special > world.time)
return
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
src << "You cannot leap in your current state."
src << "You cannot tackle in your current state."
return
last_special = world.time + 50
+4 -4
View File
@@ -283,7 +283,7 @@
if (radiation)
var/datum/organ/internal/diona/nutrients/rad_organ = locate() in internal_organs
if(!rad_organ || rad_organ.is_broken())
if(rad_organ && !rad_organ.is_broken())
var/rads = radiation/25
radiation -= rads
nutrition += rads
@@ -1060,7 +1060,7 @@
if(overeatduration > 1)
overeatduration -= 2 //doubled the unfat rate
if(!light_organ || light_organ.is_broken())
if(species.flags & IS_PLANT && (!light_organ || light_organ.is_broken()))
if(nutrition < 200)
take_overall_damage(2,0)
traumatic_shock++
@@ -1232,7 +1232,7 @@
if(copytext(hud.icon_state,1,4) == "hud") //ugly, but icon comparison is worse, I believe
client.images.Remove(hud)
client.screen.Remove(global_hud.blurry, global_hud.druggy, global_hud.vimpaired, global_hud.darkMask, global_hud.nvg, global_hud.thermal, global_hud.meson)
client.screen.Remove(global_huds)
update_action_buttons()
@@ -1797,7 +1797,7 @@
if(mind)
switch(mind.special_role)
if("traitor","Syndicate")
if("traitor","Mercenary")
holder.icon_state = "hudsyndicate"
if("Revolutionary")
holder.icon_state = "hudrevolutionary"
+35 -27
View File
@@ -37,14 +37,20 @@
else if(species.default_language)
speaking = all_languages[species.default_language]
var/ending = copytext(message, length(message))
if (speaking)
verb = speaking.speech_verb
// This is broadcast to all mobs with the language,
// irrespective of distance or anything else.
if(speaking.flags & HIVEMIND)
speaking.broadcast(src,trim(message))
return
//If we've gotten this far, keep going!
verb = speaking.get_spoken_verb(ending)
else
if(ending=="!")
verb=pick("exclaims","shouts","yells")
if(ending=="?")
verb="asks"
if (istype(wear_mask, /obj/item/clothing/mask/muzzle))
return
@@ -60,13 +66,6 @@
if(!message || stat)
return
if (!speaking)
var/ending = copytext(message, length(message))
if(ending=="!")
verb=pick("exclaims","shouts","yells")
if(ending=="?")
verb="asks"
var/list/obj/item/used_radios = new
switch (message_mode)
@@ -116,21 +115,31 @@
return
else
if(message_mode)
if(message_mode in (radiochannels | "department"))
if(l_ear && istype(l_ear,/obj/item/device/radio))
l_ear.talk_into(src,message, message_mode, verb, speaking)
used_radios += l_ear
else if(r_ear && istype(r_ear,/obj/item/device/radio))
r_ear.talk_into(src,message, message_mode, verb, speaking)
used_radios += r_ear
if(l_ear && istype(l_ear,/obj/item/device/radio))
l_ear.talk_into(src,message, message_mode, verb, speaking)
used_radios += l_ear
else if(r_ear && istype(r_ear,/obj/item/device/radio))
r_ear.talk_into(src,message, message_mode, verb, speaking)
used_radios += r_ear
var/sound/speech_sound
var/sound_vol
if(species.speech_sounds && prob(20))
if(species.speech_sounds && prob(species.speech_chance))
speech_sound = sound(pick(species.speech_sounds))
sound_vol = 50
..(message, speaking, verb, alt_name, italics, message_range, used_radios, speech_sound, sound_vol) //ohgod we should really be passing a datum here.
//speaking into radios
if(used_radios.len)
italics = 1
message_range = 1
for(var/mob/living/M in hearers(5, src))
if(M != src)
M.show_message("<span class='notice'>[src] talks into [used_radios.len ? used_radios[1] : "the radio."]</span>")
if (speech_sound)
sound_vol *= 0.5
..(message, speaking, verb, alt_name, italics, message_range, speech_sound, sound_vol) //ohgod we should really be passing a datum here.
/mob/living/carbon/human/proc/forcesay(list/append)
if(stat == CONSCIOUS)
@@ -154,9 +163,7 @@
if(findtext(temp, "*", 1, 2)) //emotes
return
world << "Text after stuff is [temp]"
temp = copytext(trim_left(temp), 1, rand(5,8))
world << "Text after trimming is [temp]"
var/trimmed = trim_left(temp)
if(length(trimmed))
@@ -232,16 +239,17 @@
/mob/living/carbon/human/say_quote(var/message, var/datum/language/speaking = null)
var/verb = "says"
var/ending = copytext(message, length(message))
if(ending=="!")
verb=pick("exclaims","shouts","yells")
else if(ending=="?")
verb="asks"
if(speaking)
verb = speaking.get_spoken_verb(ending)
else
if(ending == "!")
verb=pick("exclaims","shouts","yells")
else if(ending == "?")
verb="asks"
return verb
/mob/living/carbon/human/proc/handle_speech_problems(var/message)
var/list/returns[3]
var/verb = "says"
@@ -30,6 +30,7 @@
var/secondary_langs = list() // The names of secondary languages that are available to this species.
var/mutantrace // Safeguard due to old code.
var/list/speech_sounds // A list of sounds to potentially play when speaking.
var/list/speech_chance
var/has_fine_manipulation = 1 // Can use small items.
var/insulated // Immune to electrocution and glass shards to the feet.
@@ -234,7 +235,7 @@
heat_level_2 = 480 //Default 400
heat_level_3 = 1100 //Default 1000
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_TAIL | HAS_SKIN_COLOR
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR
flesh_color = "#34AF10"
@@ -261,7 +262,7 @@
primitive = /mob/living/carbon/monkey/tajara
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_TAIL | HAS_SKIN_COLOR
flags = IS_WHITELISTED | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR
flesh_color = "#AFA59E"
base_color = "#333333"
@@ -293,6 +294,7 @@
rarity_value = 2
speech_sounds = list('sound/voice/shriek1.ogg')
speech_chance = 20
warning_low_pressure = 50
hazard_low_pressure = 0
@@ -353,7 +355,7 @@
breath_type = "nitrogen"
poison_type = "oxygen"
flags = NO_SCAN | NO_BLOOD | HAS_TAIL | NO_PAIN
flags = NO_SCAN | NO_BLOOD | NO_PAIN
blood_color = "#2299FC"
flesh_color = "#808D11"
@@ -897,7 +897,7 @@ proc/get_damage_icon_part(damage_state, body_part)
/mob/living/carbon/human/proc/update_tail_showing(var/update_icons=1)
overlays_standing[TAIL_LAYER] = null
if(species.tail && species.flags & HAS_TAIL)
if(species.tail)
if(!wear_suit || !(wear_suit.flags_inv & HIDETAIL) && !istype(wear_suit, /obj/item/clothing/suit/space))
var/icon/tail_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[species.tail]_s")
tail_s.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
+1 -1
View File
@@ -806,10 +806,10 @@
var/area/new_area = get_area(loc)
if(new_area)
new_area.Entered(src)
/mob/living/proc/can_use_vents()
return "You can't fit into that vent."
/mob/living/proc/has_brain()
return 1
+1 -1
View File
@@ -14,7 +14,7 @@
if("cult")
if(mind in ticker.mode:cult)
ticker.mode.update_cult_icons_added(src.mind)
if("nuclear emergency")
if("mercenary")
if(mind in ticker.mode:syndicates)
ticker.mode.update_all_synd_icons()
if("mutiny")
+22 -18
View File
@@ -3,14 +3,16 @@ var/list/department_radio_keys = list(
":l" = "left ear", "#l" = "left ear", ".l" = "left ear",
":i" = "intercom", "#i" = "intercom", ".i" = "intercom",
":h" = "department", "#h" = "department", ".h" = "department",
":+" = "special", "#+" = "special", ".+" = "special", //activate radio-specific special functions
":c" = "Command", "#c" = "Command", ".c" = "Command",
":n" = "Science", "#n" = "Science", ".n" = "Science",
":m" = "Medical", "#m" = "Medical", ".m" = "Medical",
":e" = "Engineering", "#e" = "Engineering", ".e" = "Engineering",
":s" = "Security", "#s" = "Security", ".s" = "Security",
":w" = "whisper", "#w" = "whisper", ".w" = "whisper",
":t" = "Syndicate", "#t" = "Syndicate", ".t" = "Syndicate",
":t" = "Mercenary", "#t" = "Mercenary", ".t" = "Mercenary",
":u" = "Supply", "#u" = "Supply", ".u" = "Supply",
":o" = "AI Private", "#o" = "AI Private", ".o" = "AI Private",
":R" = "right ear", "#R" = "right ear", ".R" = "right ear",
":L" = "left ear", "#L" = "left ear", ".L" = "left ear",
@@ -22,8 +24,9 @@ var/list/department_radio_keys = list(
":E" = "Engineering", "#E" = "Engineering", ".E" = "Engineering",
":S" = "Security", "#S" = "Security", ".S" = "Security",
":W" = "whisper", "#W" = "whisper", ".W" = "whisper",
":T" = "Syndicate", "#T" = "Syndicate", ".T" = "Syndicate",
":T" = "Mercenary", "#T" = "Mercenary", ".T" = "Mercenary",
":U" = "Supply", "#U" = "Supply", ".U" = "Supply",
":O" = "AI Private", "#O" = "AI Private", ".O" = "AI Private",
//kinda localization -- rastaf0
//same keys as above, but on russian keyboard layout. This file uses cp1251 as encoding.
@@ -37,10 +40,25 @@ var/list/department_radio_keys = list(
":ó" = "Engineering", "#ó" = "Engineering", ".ó" = "Engineering",
":û" = "Security", "#û" = "Security", ".û" = "Security",
":ö" = "whisper", "#ö" = "whisper", ".ö" = "whisper",
":å" = "Syndicate", "#å" = "Syndicate", ".å" = "Syndicate",
":å" = "Mercenary", "#å" = "Mercenary", ".å" = "Mercenary",
":é" = "Supply", "#é" = "Supply", ".é" = "Supply",
)
var/list/channel_to_radio_key = new
proc/get_radio_key_from_channel(var/channel)
var/key = channel_to_radio_key[channel]
if(!key)
for(var/radio_key in department_radio_keys)
if(department_radio_keys[radio_key] == channel)
key = radio_key
break
if(!key)
key = ""
channel_to_radio_key[channel] = key
return key
/mob/living/proc/binarycheck()
if (istype(src, /mob/living/silicon/pai))
@@ -59,7 +77,7 @@ var/list/department_radio_keys = list(
if(!istype(dongle)) return
if(dongle.translate_binary) return 1
/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/italics=0, var/message_range = world.view, var/list/used_radios = list(), var/sound/speech_sound, var/sound_vol)
/mob/living/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/italics=0, var/message_range = world.view, var/sound/speech_sound, var/sound_vol)
var/turf/T = get_turf(src)
@@ -73,20 +91,6 @@ var/list/department_radio_keys = list(
say_signlang(message, pick(speaking.signlang_verb), speaking)
return 1
//speaking into radios
if(used_radios.len)
italics = 1
message_range = 1
if (!istype(src, /mob/living/silicon/ai)) // Atlantis: Prevents nearby people from hearing the AI when it talks using it's integrated radio.
for(var/mob/living/M in hearers(5, src))
if(M != src)
M.show_message("<span class='notice'>[src] talks into [used_radios.len ? used_radios[1] : "the radio."]</span>")
if (speech_sound)
src.playsound_local(get_turf(src), speech_sound, sound_vol * 0.5, 1)
speech_sound = null //so we don't play it twice.
//make sure the air can transmit speech
var/datum/gas_mixture/environment = T.return_air()
if(environment)
+35 -37
View File
@@ -16,7 +16,7 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/proc/ai_roster,
/mob/living/silicon/ai/proc/ai_statuschange,
/mob/living/silicon/ai/proc/ai_store_location,
/mob/living/silicon/ai/proc/checklaws,
/mob/living/silicon/ai/proc/ai_checklaws,
/mob/living/silicon/ai/proc/control_integrated_radio,
/mob/living/silicon/ai/proc/core,
/mob/living/silicon/ai/proc/pick_icon,
@@ -49,11 +49,7 @@ var/list/ai_verbs_default = list(
var/obj/machinery/camera/camera = null
var/list/connected_robots = list()
var/aiRestorePowerRoutine = 0
//var/list/laws = list()
var/viewalerts = 0
var/lawcheck[1]
var/ioncheck[1]
var/lawchannel = "Common" // Default channel on which to state laws
var/icon/holo_icon//Default is assigned when AI is created.
var/obj/item/device/pda/ai/aiPDA = null
var/obj/item/device/multitool/aiMulti = null
@@ -121,13 +117,19 @@ var/list/ai_verbs_default = list(
aiMulti = new(src)
aiRadio = new(src)
common_radio = aiRadio
aiRadio.myAi = src
additional_law_channels += "Binary"
additional_law_channels += "Holopad"
aiCamera = new/obj/item/device/camera/siliconcam/ai_camera(src)
if (istype(loc, /turf))
add_ai_verbs(src)
//Languages
add_language("Robot Talk", 1)
add_language("Galactic Common", 0)
add_language("Sol Common", 0)
add_language("Sinta'unathi", 0)
add_language("Siik'tajr", 0)
@@ -144,16 +146,7 @@ var/list/ai_verbs_default = list(
if (B.brainmob.mind)
B.brainmob.mind.transfer_to(src)
src << "<B>You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).</B>"
src << "<B>To look at other parts of the station, click on yourself to get a camera menu.</B>"
src << "<B>While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc.</B>"
src << "To use something, simply click on it."
src << "Use say :b to speak to your cyborgs through binary."
if (!(ticker && ticker.mode && (mind in ticker.mode.malf_ai)))
show_laws()
src << "<b>These laws may be changed by other players, or by you being the traitor.</b>"
job = "AI"
on_mob_init()
spawn(5)
new /obj/machinery/ai_powersupply(src)
@@ -172,6 +165,30 @@ var/list/ai_verbs_default = list(
..()
return
/mob/living/silicon/ai/proc/on_mob_init()
src << "<B>You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).</B>"
src << "<B>To look at other parts of the station, click on yourself to get a camera menu.</B>"
src << "<B>While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc.</B>"
src << "To use something, simply click on it."
src << "Use say :b to speak to your cyborgs through binary. Use say :h to speak from an active holopad."
src << "For department channels, use the following say commands:"
var/radio_text = ""
for(var/i = 1 to common_radio.channels.len)
var/channel = common_radio.channels[i]
var/key = get_radio_key_from_channel(channel)
radio_text += "[key] - [channel]"
if(i != common_radio.channels.len)
radio_text += ", "
src << radio_text
if (!(ticker && ticker.mode && (mind in ticker.mode.malf_ai)))
show_laws()
src << "<b>These laws may be changed by other players, or by you being the traitor.</b>"
job = "AI"
/mob/living/silicon/ai/Del()
ai_list -= src
..()
@@ -425,7 +442,8 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/Topic(href, href_list)
if(usr != src)
return
..()
if(..())
return
if (href_list["mach_close"])
if (href_list["mach_close"] == "aialerts")
viewalerts = 0
@@ -453,13 +471,6 @@ var/list/ai_verbs_default = list(
// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
checklaws()
if (href_list["lawr"]) // Selects on which channel to state laws
var/setchannel = input(usr, "Specify channel.", "Channel selection") in list("State","Common","Science","Command","Medical","Engineering","Security","Supply","Binary","Holopad", "Cancel")
if(setchannel == "Cancel")
return
lawchannel = setchannel
checklaws()
if (href_list["lawi"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
var/L = text2num(href_list["lawi"])
switch(ioncheck[L])
@@ -639,20 +650,7 @@ var/list/ai_verbs_default = list(
if(check_unable(AI_CHECK_WIRELESS))
return
var/list/ai_emotions = list("Very Happy", "Happy", "Neutral", "Unsure", "Confused", "Surprised", "Sad", "Upset", "Angry", "Awesome", "BSOD", "Blank", "Problems?", "Facepalm", "Friend Computer")
var/emote = input("Please, select a status!", "AI Status", null, null) in ai_emotions
for (var/obj/machinery/M in machines) //change status
if(istype(M, /obj/machinery/ai_status_display))
var/obj/machinery/ai_status_display/AISD = M
AISD.emotion = emote
//if Friend Computer, change ALL displays
else if(istype(M, /obj/machinery/status_display))
var/obj/machinery/status_display/SD = M
if(emote=="Friend Computer")
SD.friendc = 1
else
SD.friendc = 0
set_ai_status_displays(src)
return
//I am the icon meister. Bow fefore me. //>fefore
+2 -131
View File
@@ -15,22 +15,6 @@
src.laws_sanity_check()
src.laws.show_laws(who)
/mob/living/silicon/ai/proc/laws_sanity_check()
if (!src.laws)
src.laws = new base_law_type
/mob/living/silicon/ai/proc/set_zeroth_law(var/law, var/law_borg)
src.laws_sanity_check()
src.laws.set_zeroth_law(law, law_borg)
/mob/living/silicon/ai/proc/add_inherent_law(var/law)
src.laws_sanity_check()
src.laws.add_inherent_law(law)
/mob/living/silicon/ai/proc/clear_inherent_laws()
src.laws_sanity_check()
src.laws.clear_inherent_laws()
/mob/living/silicon/ai/proc/add_ion_law(var/law)
src.laws_sanity_check()
src.laws.add_ion_law(law)
@@ -38,120 +22,7 @@
if(R.lawupdate && (R.connected_ai == src))
R << "\red " + law + "\red...LAWS UPDATED"
/mob/living/silicon/ai/proc/clear_ion_laws()
src.laws_sanity_check()
src.laws.clear_ion_laws()
/mob/living/silicon/ai/proc/add_supplied_law(var/number, var/law)
src.laws_sanity_check()
src.laws.add_supplied_law(number, law)
/mob/living/silicon/ai/proc/clear_supplied_laws()
src.laws_sanity_check()
src.laws.clear_supplied_laws()
/mob/living/silicon/ai/proc/statelaws() // -- TLE
// set category = "AI Commands"
// set name = "State Laws"
/var/prefix = ""
switch(lawchannel)
if("Common") prefix = ";"
if("Science") prefix = ":n "
if("Command") prefix = ":c "
if("Medical") prefix = ":m "
if("Engineering") prefix = ":e "
if("Security") prefix = ":s "
if("Supply") prefix = ":u "
if("Binary") prefix = ":b "
if("Holopad") prefix = ":h "
else prefix = ""
if(src.say("[prefix]Current Active Laws:") != 1)
return
//src.laws_sanity_check()
//src.laws.show_laws(world)
var/number = 1
sleep(10)
if (src.laws.zeroth)
if (src.lawcheck[1] == "Yes") //This line and the similar lines below make sure you don't state a law unless you want to. --NeoFite
src.say("[prefix]0. [src.laws.zeroth]")
sleep(10)
for (var/index = 1, index <= src.laws.ion.len, index++)
var/law = src.laws.ion[index]
var/num = ionnum()
if (length(law) > 0)
if (src.ioncheck[index] == "Yes")
src.say("[prefix][num]. [law]")
sleep(10)
for (var/index = 1, index <= src.laws.inherent.len, index++)
var/law = src.laws.inherent[index]
if (length(law) > 0)
if (src.lawcheck[index+1] == "Yes")
src.say("[prefix][number]. [law]")
sleep(10)
number++
for (var/index = 1, index <= src.laws.supplied.len, index++)
var/law = src.laws.supplied[index]
if (length(law) > 0)
if(src.lawcheck.len >= number+1)
if (src.lawcheck[number+1] == "Yes")
src.say("[prefix][number]. [law]")
sleep(10)
number++
/mob/living/silicon/ai/proc/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
/mob/living/silicon/ai/proc/ai_checklaws()
set category = "AI Commands"
set name = "State Laws"
var/list = "<b>Which laws do you want to include when stating them for the crew?</b><br><br>"
if (src.laws.zeroth)
if (!src.lawcheck[1])
src.lawcheck[1] = "No" //Given Law 0's usual nature, it defaults to NOT getting reported. --NeoFite
list += {"<A href='byond://?src=\ref[src];lawc=0'>[src.lawcheck[1]] 0:</A> [src.laws.zeroth]<BR>"}
for (var/index = 1, index <= src.laws.ion.len, index++)
var/law = src.laws.ion[index]
if (length(law) > 0)
if (!src.ioncheck[index])
src.ioncheck[index] = "Yes"
list += {"<A href='byond://?src=\ref[src];lawi=[index]'>[src.ioncheck[index]] [ionnum()]:</A> [law]<BR>"}
src.ioncheck.len += 1
var/number = 1
for (var/index = 1, index <= src.laws.inherent.len, index++)
var/law = src.laws.inherent[index]
if (length(law) > 0)
src.lawcheck.len += 1
if (!src.lawcheck[number+1])
src.lawcheck[number+1] = "Yes"
list += {"<A href='byond://?src=\ref[src];lawc=[number]'>[src.lawcheck[number+1]] [number]:</A> [law]<BR>"}
number++
for (var/index = 1, index <= src.laws.supplied.len, index++)
var/law = src.laws.supplied[index]
if (length(law) > 0)
src.lawcheck.len += 1
if (!src.lawcheck[number+1])
src.lawcheck[number+1] = "Yes"
list += {"<A href='byond://?src=\ref[src];lawc=[number]'>[src.lawcheck[number+1]] [number]:</A> [law]<BR>"}
number++
list += {"<br><A href='byond://?src=\ref[src];lawr=1'>Channel: [src.lawchannel]</A><br>"}
list += {"<A href='byond://?src=\ref[src];laws=1'>State Laws</A>"}
usr << browse(list, "window=laws")
checklaws()
+128
View File
@@ -0,0 +1,128 @@
/mob/living/silicon/proc/laws_sanity_check()
if (!src.laws)
laws = new base_law_type
/mob/living/silicon/proc/set_zeroth_law(var/law, var/law_borg)
laws_sanity_check()
laws.set_zeroth_law(law, law_borg)
/mob/living/silicon/proc/add_inherent_law(var/law)
laws_sanity_check()
laws.add_inherent_law(law)
/mob/living/silicon/proc/clear_inherent_laws()
laws_sanity_check()
laws.clear_inherent_laws()
/mob/living/silicon/proc/clear_ion_laws()
laws_sanity_check()
laws.clear_ion_laws()
/mob/living/silicon/proc/add_supplied_law(var/number, var/law)
laws_sanity_check()
laws.add_supplied_law(number, law)
/mob/living/silicon/proc/clear_supplied_laws()
laws_sanity_check()
laws.clear_supplied_laws()
/mob/living/silicon/proc/statelaws() // -- TLE
if(stating_laws)
src << "<span class='notice'>You are currently stating laws.</span>"
return
stating_laws = 1
var/prefix = ""
switch(lawchannel)
if(MAIN_CHANNEL) prefix = ";" // Apparently defines are not constant expressions?
if("Binary") prefix = ":b "
else
prefix = get_radio_key_from_channel(lawchannel == "Holopad" ? "department" : lawchannel) + " "
if(src.say("[prefix]Current Active Laws:") != 1)
return
//src.laws_sanity_check()
//src.laws.show_laws(world)
var/number = 1
sleep(10)
if (src.laws.zeroth)
if (src.lawcheck[1] == "Yes") //This line and the similar lines below make sure you don't state a law unless you want to. --NeoFite
src.say("[prefix]0. [src.laws.zeroth]")
sleep(10)
for (var/index = 1, index <= src.laws.ion.len, index++)
var/law = src.laws.ion[index]
var/num = ionnum()
if (length(law) > 0)
if (src.ioncheck[index] == "Yes")
src.say("[prefix][num]. [law]")
sleep(10)
for (var/index = 1, index <= src.laws.inherent.len, index++)
var/law = src.laws.inherent[index]
if (length(law) > 0)
if (src.lawcheck[index+1] == "Yes")
src.say("[prefix][number]. [law]")
sleep(10)
number++
for (var/index = 1, index <= src.laws.supplied.len, index++)
var/law = src.laws.supplied[index]
if (length(law) > 0)
if(src.lawcheck.len >= number+1)
if (src.lawcheck[number+1] == "Yes")
src.say("[prefix][number]. [law]")
sleep(10)
number++
stating_laws = 0
/mob/living/silicon/proc/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
var/list = "<b>Which laws do you want to include when stating them for the crew?</b><br><br>"
if (src.laws.zeroth)
if (!src.lawcheck[1])
src.lawcheck[1] = "No" //Given Law 0's usual nature, it defaults to NOT getting reported. --NeoFite
list += {"<A href='byond://?src=\ref[src];lawc=0'>[src.lawcheck[1]] 0:</A> [src.laws.zeroth]<BR>"}
for (var/index = 1, index <= src.laws.ion.len, index++)
var/law = src.laws.ion[index]
if (length(law) > 0)
if (!src.ioncheck[index])
src.ioncheck[index] = "Yes"
list += {"<A href='byond://?src=\ref[src];lawi=[index]'>[src.ioncheck[index]] [ionnum()]:</A> [law]<BR>"}
src.ioncheck.len += 1
var/number = 1
for (var/index = 1, index <= src.laws.inherent.len, index++)
var/law = src.laws.inherent[index]
if (length(law) > 0)
src.lawcheck.len += 1
if (!src.lawcheck[number+1])
src.lawcheck[number+1] = "Yes"
list += {"<A href='byond://?src=\ref[src];lawc=[number]'>[src.lawcheck[number+1]] [number]:</A> [law]<BR>"}
number++
for (var/index = 1, index <= src.laws.supplied.len, index++)
var/law = src.laws.supplied[index]
if (length(law) > 0)
src.lawcheck.len += 1
if (!src.lawcheck[number+1])
src.lawcheck[number+1] = "Yes"
list += {"<A href='byond://?src=\ref[src];lawc=[number]'>[src.lawcheck[number+1]] [number]:</A> [law]<BR>"}
number++
list += {"<br><A href='byond://?src=\ref[src];lawr=1'>Channel: [src.lawchannel]</A><br>"}
list += {"<A href='byond://?src=\ref[src];laws=1'>State Laws</A>"}
usr << browse(list, "window=laws")
@@ -229,7 +229,7 @@ var/datum/paiController/paiController // Global handler for pAI candidates
M << browse(dat, "window=paiRecruit;size=580x580;")
/datum/paiController/proc/findPAI(var/obj/item/device/paicard/p, var/mob/user)
requestRecruits()
requestRecruits(user)
var/list/available = list()
for(var/datum/paiCandidate/c in paiController.pai_candidates)
if(c.ready)
@@ -345,7 +345,8 @@ var/datum/paiController/paiController // Global handler for pAI candidates
user << browse(dat, "window=findPai")
/datum/paiController/proc/requestRecruits()
/datum/paiController/proc/requestRecruits(var/mob/user)
inquirer = user
for(var/mob/dead/observer/O in player_list)
if(O.has_enabled_antagHUD == 1 && config.antag_hud_restricted)
continue
@@ -223,7 +223,7 @@
if(href_list["toggler"])
pda.toff = !pda.toff
else if(href_list["ringer"])
pda.silent = !pda.silent
pda.message_silent = !pda.message_silent
else if(href_list["target"])
if(silence_time)
return alert("Communications circuits remain uninitialized.")
@@ -668,7 +668,7 @@
dat += {"<b>Signal/Receiver Status:</b> <A href='byond://?src=\ref[src];software=pdamessage;toggler=1'>
[(pda.toff) ? "<font color='red'> \[Off\]</font>" : "<font color='green'> \[On\]</font>"]</a><br>
<b>Ringer Status:</b> <A href='byond://?src=\ref[src];software=pdamessage;ringer=1'>
[(pda.silent) ? "<font color='red'> \[Off\]</font>" : "<font color='green'> \[On\]</font>"]</a><br><br>"}
[(pda.message_silent) ? "<font color='red'> \[Off\]</font>" : "<font color='green'> \[On\]</font>"]</a><br><br>"}
dat += "<ul>"
if(!pda.toff)
for (var/obj/item/device/pda/P in sortAtom(PDAs))
@@ -112,7 +112,8 @@
/datum/robot_component/radio
name = "radio"
external_type = /obj/item/robot_parts/robot_component/radio
active_usage = 10
idle_usage = 15 //it's not actually possible to tell when we receive a message over our radio, so just use 10W every tick for passive listening
active_usage = 75 //transmit power
max_damage = 40
@@ -122,7 +123,8 @@
/datum/robot_component/binary_communication
name = "binary communication device"
external_type = /obj/item/robot_parts/robot_component/binary_communication_device
active_usage = 10
idle_usage = 5
active_usage = 25
max_damage = 30
@@ -134,7 +136,33 @@
external_type = /obj/item/robot_parts/robot_component/camera
idle_usage = 10
max_damage = 40
var/obj/machinery/camera/camera
/datum/robot_component/camera/New(mob/living/silicon/robot/R)
..()
camera = R.camera
/datum/robot_component/camera/update_power_state()
..()
if (camera)
//check if camera component was deactivated
if (!powered && camera.status != powered)
camera.kick_viewers()
camera.status = powered
/datum/robot_component/camera/install()
if (camera)
camera.status = 1
/datum/robot_component/camera/uninstall()
if (camera)
camera.status = 0
camera.kick_viewers()
/datum/robot_component/camera/destroy()
if (camera)
camera.status = 0
camera.kick_viewers()
// SELF DIAGNOSIS MODULE
// Analyses cyborg's modules, providing damage readouts and basic information
@@ -28,13 +28,12 @@
var/mail_destination = ""
holder_type = /obj/item/weapon/holder/drone
/mob/living/silicon/robot/drone/New()
..()
verbs += /mob/living/proc/ventcrawl
verbs += /mob/living/proc/hide
remove_language("Robot Talk")
add_language("Robot Talk", 0)
add_language("Drone Talk", 1)
@@ -135,7 +134,7 @@
clear_supplied_laws()
clear_inherent_laws()
laws = new /datum/ai_laws/syndicate_override
set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.")
set_zeroth_law("Only [user.real_name] and people he designates as being such are operatives.")
src << "<b>Obey these laws:</b>"
laws.show_laws(src)
+2 -104
View File
@@ -69,113 +69,11 @@
laws.supplied[index] = temp
return
/mob/living/silicon/robot/proc/laws_sanity_check()
if (!laws)
laws = new base_law_type
/mob/living/silicon/robot/proc/set_zeroth_law(var/law)
laws_sanity_check()
laws.set_zeroth_law(law)
/mob/living/silicon/robot/proc/add_inherent_law(var/law)
laws_sanity_check()
laws.add_inherent_law(law)
/mob/living/silicon/robot/proc/clear_inherent_laws()
laws_sanity_check()
laws.clear_inherent_laws()
/mob/living/silicon/robot/proc/add_supplied_law(var/number, var/law)
laws_sanity_check()
laws.add_supplied_law(number, law)
/mob/living/silicon/robot/proc/clear_supplied_laws()
laws_sanity_check()
laws.clear_supplied_laws()
/mob/living/silicon/robot/proc/add_ion_law(var/law)
laws_sanity_check()
laws.add_ion_law(law)
/mob/living/silicon/robot/proc/clear_ion_laws()
laws_sanity_check()
laws.clear_ion_laws()
/mob/living/silicon/robot/proc/statelaws() // -- TLE
// set category = "AI Commands"
// set name = "State Laws"
src.say("Current Active Laws:")
//src.laws_sanity_check()
//src.laws.show_laws(world)
var/number = 1
sleep(10)
if (src.laws.zeroth)
if (src.lawcheck[1] == "Yes") //This line and the similar lines below make sure you don't state a law unless you want to. --NeoFite
src.say("0. [src.laws.zeroth]")
sleep(10)
for (var/index = 1, index <= src.laws.ion.len, index++)
var/law = src.laws.ion[index]
var/num = ionnum()
if (length(law) > 0)
if (src.ioncheck[index] == "Yes")
src.say("[num]. [law]")
sleep(10)
for (var/index = 1, index <= src.laws.inherent.len, index++)
var/law = src.laws.inherent[index]
if (length(law) > 0)
if (src.lawcheck[index+1] == "Yes")
src.say("[number]. [law]")
sleep(10)
number++
for (var/index = 1, index <= src.laws.supplied.len, index++)
var/law = src.laws.supplied[index]
if (length(law) > 0)
if(src.lawcheck.len >= number+1)
if (src.lawcheck[number+1] == "Yes")
src.say("[number]. [law]")
sleep(10)
number++
/mob/living/silicon/robot/verb/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
/mob/living/silicon/robot/proc/robot_checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
set category = "Robot Commands"
set name = "State Laws"
var/list = "<b>Which laws do you want to include when stating them for the crew?</b><br><br>"
if (src.laws.zeroth)
if (!src.lawcheck[1])
src.lawcheck[1] = "No" //Given Law 0's usual nature, it defaults to NOT getting reported. --NeoFite
list += {"<A href='byond://?src=\ref[src];lawc=0'>[src.lawcheck[1]] 0:</A> [src.laws.zeroth]<BR>"}
for (var/index = 1, index <= src.laws.ion.len, index++)
var/law = src.laws.ion[index]
if (length(law) > 0)
if (!src.ioncheck[index])
src.ioncheck[index] = "Yes"
list += {"<A href='byond://?src=\ref[src];lawi=[index]'>[src.ioncheck[index]] [ionnum()]:</A> [law]<BR>"}
src.ioncheck.len += 1
var/number = 1
for (var/index = 1, index <= src.laws.inherent.len, index++)
var/law = src.laws.inherent[index]
if (length(law) > 0)
src.lawcheck.len += 1
if (!src.lawcheck[number+1])
src.lawcheck[number+1] = "Yes"
list += {"<A href='byond://?src=\ref[src];lawc=[number]'>[src.lawcheck[number+1]] [number]:</A> [law]<BR>"}
number++
for (var/index = 1, index <= src.laws.supplied.len, index++)
var/law = src.laws.supplied[index]
if (length(law) > 0)
src.lawcheck.len += 1
if (!src.lawcheck[number+1])
src.lawcheck[number+1] = "Yes"
list += {"<A href='byond://?src=\ref[src];lawc=[number]'>[src.lawcheck[number+1]] [number]:</A> [law]<BR>"}
number++
list += {"<br><br><A href='byond://?src=\ref[src];laws=1'>State Laws</A>"}
usr << browse(list, "window=laws")
checklaws()
@@ -1,5 +1,6 @@
var/list/robot_verbs_default = list(
/mob/living/silicon/robot/proc/sensor_mode
/mob/living/silicon/robot/proc/sensor_mode,
/mob/living/silicon/robot/proc/robot_checklaws
)
#define CYBORG_POWER_USAGE_MULTIPLIER 2.5 // Multiplier for amount of power cyborgs use.
@@ -19,7 +20,7 @@ var/list/robot_verbs_default = list(
var/custom_sprite = 0 //Due to all the sprites involved, a var for our custom borgs may be best
var/crisis //Admin-settable for combat module use.
var/crisis_override = 0
var/integrated_light_power = 5
var/integrated_light_power = 6
//Hud stuff
@@ -68,8 +69,6 @@ var/list/robot_verbs_default = list(
var/weapon_lock = 0
var/weaponlock_time = 120
var/lawupdate = 1 //Cyborgs will sync their laws with their AI by default
var/lawcheck[1] //For stating laws.
var/ioncheck[1] //Ditto.
var/lockcharge //Used when locking down a borg to preserve cell charge
var/speed = 0 //Cause sec borgs gotta go fast //No they dont!
var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them.
@@ -102,6 +101,7 @@ var/list/robot_verbs_default = list(
init()
radio = new /obj/item/device/radio/borg(src)
common_radio = radio
if(!scrambledcodes && !camera)
camera = new /obj/machinery/camera(src)
camera.c_tag = real_name
@@ -143,6 +143,7 @@ var/list/robot_verbs_default = list(
/mob/living/silicon/robot/proc/init()
aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src)
laws = new /datum/ai_laws/nanotrasen()
additional_law_channels += "Binary"
connected_ai = select_active_ai_with_fewest_borgs()
if(connected_ai)
connected_ai.connected_robots += src
@@ -413,7 +414,7 @@ var/list/robot_verbs_default = list(
lights_on = !lights_on
usr << "You [lights_on ? "enable" : "disable"] your integrated light."
if(lights_on)
SetLuminosity(6) // 1.5x luminosity of flashlight
SetLuminosity(integrated_light_power) // 1.5x luminosity of flashlight
else
SetLuminosity(0)
@@ -811,7 +812,7 @@ var/list/robot_verbs_default = list(
laws = new /datum/ai_laws/syndicate_override
var/time = time2text(world.realtime,"hh:mm:ss")
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
set_zeroth_law("Only [user.real_name] and people he designates as being such are Syndicate Agents.")
set_zeroth_law("Only [user.real_name] and people he designates as being such are operatives.")
src << "\red ALERT: Foreign software detected."
sleep(5)
src << "\red Initiating diagnostics..."
@@ -1074,10 +1075,10 @@ var/list/robot_verbs_default = list(
/mob/living/silicon/robot/Topic(href, href_list)
..()
if(usr != src)
return
if(..())
return
if (href_list["showalerts"])
robot_alerts()
@@ -369,7 +369,7 @@
return
/obj/item/weapon/robot_module/syndicate
name = "syndicate robot module"
name = "illegal robot module"
New()
src.modules += new /obj/item/device/flashlight(src)
@@ -1,9 +0,0 @@
/mob/living/silicon/robot/verb/light()
set name = "Light On/Off"
set desc = "Activate your inbuilt light. Toggled on or off."
set category = "Robot Commands"
if(luminosity)
SetLuminosity(0)
return
SetLuminosity(integrated_light_power)
+8 -8
View File
@@ -76,7 +76,7 @@
if(speaking.flags & HIVEMIND)
speaking.broadcast(src,trim(message))
return
return 1
// Currently used by drones.
if(local_transmit)
@@ -92,11 +92,11 @@
continue
else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS)
if(M.client) M << "<b>[src]</b> transmits, \"[message]\""
return
return 1
if(message_mode && bot_type == IS_ROBOT && !R.is_component_functioning("radio"))
src << "\red Your radio isn't functional at this time."
return
return 0
switch(message_mode)
if("department")
@@ -115,9 +115,9 @@
if("general")
switch(bot_type)
if(IS_AI)
if (AI.aiRadio.disabledAi)
if (AI.aiRadio.disabledAi || AI.aiRestorePowerRoutine || AI.stat)
src << "\red System Error - Transceiver Disabled"
return
return 0
else
log_say("[key_name(src)] : [message]")
AI.aiRadio.talk_into(src,message,null,verb,speaking)
@@ -130,12 +130,12 @@
return 1
else
if(message_mode && message_mode in radiochannels)
if(message_mode)
switch(bot_type)
if(IS_AI)
if (AI.aiRadio.disabledAi)
if (AI.aiRadio.disabledAi || AI.aiRestorePowerRoutine || AI.stat)
src << "\red System Error - Transceiver Disabled"
return
return 0
else
log_say("[key_name(src)] : [message]")
AI.aiRadio.talk_into(src,message,message_mode,verb,speaking)
+34 -1
View File
@@ -3,6 +3,14 @@
voice_name = "synthesized voice"
var/syndicate = 0
var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS
var/list/additional_law_channels = list("State")
var/const/MAIN_CHANNEL = "Main Frequency"
var/lawchannel = MAIN_CHANNEL // Default channel on which to state laws
var/lawcheck[1]
var/ioncheck[1]
var/stating_laws = 0
var/obj/item/device/radio/common_radio
immune_to_ssd = 1
var/list/hud_list[9]
var/list/speech_synthesizer_langs = list() //which languages can be vocalized by the speech synthesizer
@@ -19,6 +27,10 @@
#define SEC_HUD 1 //Security HUD mode
#define MED_HUD 2 //Medical HUD mode
/mob/living/silicon/New()
..()
add_language("Galactic Common")
/mob/living/silicon/proc/show_laws()
return
@@ -168,6 +180,7 @@
/mob/living/silicon/add_language(var/language, var/can_speak=1)
if (..(language) && can_speak)
speech_synthesizer_langs.Add(all_languages[language])
return 1
/mob/living/silicon/remove_language(var/rem_language)
..(rem_language)
@@ -217,4 +230,24 @@
flavor_text = copytext(sanitize(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text), 1)
/mob/living/silicon/binarycheck()
return 1
return 1
/mob/living/silicon/Topic(href, href_list)
..()
if (href_list["lawr"]) // Selects on which channel to state laws
var/list/channels = list(MAIN_CHANNEL)
if(common_radio)
for (var/ch_name in common_radio.channels)
channels += ch_name
channels += additional_law_channels
channels += "Cancel"
var/setchannel = input(usr, "Specify channel.", "Channel selection") in channels
if(setchannel != "Cancel")
lawchannel = setchannel
checklaws()
return 1
return 0
@@ -203,5 +203,5 @@
src.mind.special_role = "Cortical Borer"
ticker.mode.borers |= src.mind
/mob/living/carbon/alien/can_use_vents()
/mob/living/simple_animal/borer/can_use_vents()
return
@@ -114,5 +114,5 @@
response_disarm = "gently pushes aside"
response_harm = "splats"
/mob/living/carbon/alien/can_use_vents()
/mob/living/simple_animal/mouse/can_use_vents()
return
+1 -3
View File
@@ -43,6 +43,4 @@
client.perspective = EYE_PERSPECTIVE
else
client.eye = src
client.perspective = MOB_PERSPECTIVE
nanomanager.send_resources(client)
client.perspective = MOB_PERSPECTIVE
+2 -2
View File
@@ -73,7 +73,7 @@
/mob/proc/Life()
// if(organStructure)
// organStructure.ProcessOrgans()
handle_typing_indicator()
//handle_typing_indicator() //You said the typing indicator would be fine. The test determined that was a lie.
return
@@ -1079,4 +1079,4 @@ mob/proc/yank_out_object()
if(istype(I,/mob/living/simple_animal/borer))
return I
return 0
return 0
+13 -1
View File
@@ -1,4 +1,3 @@
// fun if you want to typecast humans/monkeys/etc without writing long path-filled lines.
/proc/ishuman(A)
if(istype(A, /mob/living/carbon/human))
@@ -10,6 +9,12 @@
return 1
return 0
/proc/isxenomorph(A)
if(istype(A, /mob/living/carbon/human))
var/mob/living/carbon/human/H = A
return istype(H.species, /datum/species/xenos)
return 0
/proc/ismonkey(A)
if(A && istype(A, /mob/living/carbon/monkey))
return 1
@@ -119,6 +124,13 @@ proc/isnewplayer(A)
proc/hasorgans(A)
return ishuman(A)
proc/iscuffed(A)
if(istype(A, /mob/living/carbon))
var/mob/living/carbon/C = A
if(C.handcuffed)
return 1
return 0
/proc/hsl2rgb(h, s, l)
return //TODO: Implement
-1
View File
@@ -29,6 +29,5 @@
new_player_panel()
spawn(40)
if(client)
nanomanager.send_resources(client)
handle_privacy_poll()
client.playtitlemusic()
@@ -208,7 +208,7 @@ datum/preferences
preview_icon.Blend(temp, ICON_OVERLAY)
//Tail
if(current_species && (current_species.flags & HAS_TAIL))
if(current_species && (current_species.tail))
var/icon/temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[current_species.tail]_s")
preview_icon.Blend(temp, ICON_OVERLAY)
+1 -9
View File
@@ -111,17 +111,9 @@
for (var/obj/item/device/radio/intercom/comm in O.loc)
comm.ai += O
O << "<B>You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).</B>"
O << "<B>To look at other parts of the station, click on yourself to get a camera menu.</B>"
O << "<B>While observing through a camera, you can use most (networked) devices which you can see, such as computers, APCs, intercoms, doors, etc.</B>"
O << "To use something, simply click on it."
O << {"Use say ":b to speak to your cyborgs through binary."}
if (!(ticker && ticker.mode && (O.mind in ticker.mode.malf_ai)))
O.show_laws()
O << "<b>These laws may be changed by other players, or by you being the traitor.</b>"
O.on_mob_init()
O.add_ai_verbs()
O.job = "AI"
O.rename_self("ai",1)
. = O
+12 -7
View File
@@ -232,7 +232,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
if (!injected || !our)
return
if(blood_incompatible(injected.data["blood_type"],our.data["blood_type"]) )
if(blood_incompatible(injected.data["blood_type"],our.data["blood_type"],injected.data["species"],our.data["species"]) )
reagents.add_reagent("toxin",amount * 0.5)
reagents.update_total()
else
@@ -250,13 +250,18 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
return D
return res
proc/blood_incompatible(donor,receiver)
proc/blood_incompatible(donor,receiver,donor_species,receiver_species)
if(!donor || !receiver) return 0
var
donor_antigen = copytext(donor,1,lentext(donor))
receiver_antigen = copytext(receiver,1,lentext(receiver))
donor_rh = (findtext(donor,"+")>0)
receiver_rh = (findtext(receiver,"+")>0)
if(donor_species && receiver_species)
if(donor_species != receiver_species)
return 1
var/donor_antigen = copytext(donor,1,lentext(donor))
var/receiver_antigen = copytext(receiver,1,lentext(receiver))
var/donor_rh = (findtext(donor,"+")>0)
var/receiver_rh = (findtext(receiver,"+")>0)
if(donor_rh && !receiver_rh) return 1
switch(receiver_antigen)
if("A")
+2 -5
View File
@@ -73,11 +73,8 @@
// Process unsuitable transplants. TODO: consider some kind of
// immunosuppressant that changes transplant data to make it match.
if(transplant_data)
if(!rejecting) //Should this transplant reject?
if(owner.species != transplant_data["species"]) //Nope.
rejecting = 1
else if(prob(20) && owner.dna && blood_incompatible(transplant_data["blood_type"],owner.dna.b_type))
rejecting = 1
if(!rejecting && prob(20) && owner.dna && blood_incompatible(transplant_data["blood_type"],owner.dna.b_type,owner.species,transplant_data["species"]))
rejecting = 1
else
rejecting++ //Rejection severity increases over time.
if(rejecting % 10 == 0) //Only fire every ten rejection ticks.
+261 -366
View File
File diff suppressed because it is too large Load Diff
+7 -13
View File
@@ -239,21 +239,15 @@
var/last_overcharge = overcharge_percent
if(terminal)
var/excess = terminal.surplus()
if(chargemode)
var/target_load = min((capacity-charge)/SMESRATE, chargelevel) // charge at set rate, limited to spare capacity
var/actual_load = draw_power(target_load) // add the load to the terminal side network
charge += actual_load * SMESRATE // increase the charge
if(charging)
if(excess >= 0) // if there's power available, try to charge
var/load = min((capacity * 1.5 - charge)/SMESRATE, chargelevel) // charge at set rate, limited to spare capacity
load = add_load(load) // add the load to the terminal side network
charge += load * SMESRATE // increase the charge
else // if not enough capacity
charging = 0 // stop charging
else
if (chargemode && excess > 0 && excess >= chargelevel)
if (actual_load >= target_load) // did the powernet have enough power available for us?
charging = 1
else
charging = 0
if(online) // if outputting
lastout = min( charge/SMESRATE, output) //limit output to that stored
+4 -3
View File
@@ -80,13 +80,14 @@
C.breaker_box = src
var/datum/powernet/PN = new()
PN.number = powernets.len + 1
powernets += PN
PN.cables += C
PN.add_cable(C)
C.mergeConnectedNetworks(C.d2)
C.mergeConnectedNetworksOnTurf()
if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions
C.mergeDiagonalsNetworks(C.d2)
else
icon_state = icon_state_off
for(var/obj/structure/cable/C in src.loc)
+467 -222
View File
@@ -1,29 +1,27 @@
// attach a wire to a power machine - leads from the turf you are standing on
///////////////////////////////
//CABLE STRUCTURE
///////////////////////////////
/obj/machinery/power/attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/stack/cable_coil))
////////////////////////////////
// Definitions
////////////////////////////////
var/obj/item/stack/cable_coil/coil = W
/* Cable directions (d1 and d2)
var/turf/T = user.loc
if(T.intact || !istype(T, /turf/simulated/floor))
return
9 1 5
\ | /
8 - 0 - 4
/ | \
10 2 6
if(get_dist(src, user) > 1)
return
If d1 = 0 and d2 = 0, there's no cable
If d1 = 0 and d2 = dir, it's a O-X cable, getting from the center of the tile to dir (knot cable)
If d1 = dir1 and d2 = dir2, it's a full X-X cable, getting from dir1 to dir2
By design, d1 is the smallest direction and d2 is the highest
*/
if(!directwired) // only for attaching to directwired machines
return
coil.turf_place(T, user)
return
else
..()
return
// the power cable object
/obj/structure/cable
level = 1
anchored =1
@@ -74,17 +72,20 @@
var/turf/T = src.loc // hide if turf is not intact
if(level==1) hide(T.intact)
cable_list += src
update_icon()
cable_list += src //add it to the global cable list
/obj/structure/cable/Del() // called when a cable is deleted
if(!defer_powernet_rebuild) // set if network will be rebuilt manually
if(powernet)
powernet.cut_cable(src) // update the powernets
cable_list -= src
..() // then go ahead and delete the cable
/obj/structure/cable/Del() // called when a cable is deleted
if(powernet)
cut_cable_from_powernet() // update the powernets
cable_list -= src //remove it from global cable list
..() // then go ahead and delete the cable
///////////////////////////////////
// General procedures
///////////////////////////////////
//If underfloor, hide the cable
/obj/structure/cable/hide(var/i)
if(level == 1 && istype(loc, /turf))
@@ -92,17 +93,25 @@
updateicon()
/obj/structure/cable/proc/updateicon()
icon_state = "[d1]-[d2]"
alpha = invisibility ? 127 : 255
if(invisibility)
icon_state = "[d1]-[d2]-f"
else
icon_state = "[d1]-[d2]"
// returns the powernet this cable belongs to
/obj/structure/cable/proc/get_powernet() //TODO: remove this as it is obsolete
return powernet
//Telekinesis has no effect on a cable
/obj/structure/cable/attack_tk(mob/user)
return
// Items usable on a cable :
// - Wirecutters : cut it duh !
// - Cable coil : merge cables
// - Multitool : get the power currently passing through the cable
//
/obj/structure/cable/attackby(obj/item/W, mob/user)
var/turf/T = src.loc
@@ -110,13 +119,11 @@
return
if(istype(W, /obj/item/weapon/wirecutters))
///// Z-Level Stuff
if(src.d1 == 12 || src.d2 == 12)
user << "<span class='warning'>You must cut this cable from above.</span>"
return
///// Z-Level Stuff
if(breaker_box)
user << "\red This cable is connected to nearby breaker box. Use breaker box to interact with it."
return
@@ -142,22 +149,23 @@
if(c.d1 == 12 || c.d2 == 12)
c.Del()
///// Z-Level Stuff
investigate_log("was cut by [key_name(usr, usr.client)] in [user.loc.loc]","wires")
del(src)
return // not needed, but for clarity
del(src) // qdel
return
else if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/coil = W
if (coil.get_amount() < 1)
user << "Not enough cable"
return
coil.cable_join(src, user)
else if(istype(W, /obj/item/device/multitool))
var/datum/powernet/PN = get_powernet() // find the powernet
if(PN && (PN.avail > 0)) // is it powered?
user << "<span class='warning'>[PN.avail]W in power network.</span>"
if(powernet && (powernet.avail > 0)) // is it powered?
user << "<span class='warning'>[powernet.avail]W in power network.</span>"
else
user << "<span class='warning'>The cable is not powered.</span>"
@@ -171,7 +179,6 @@
src.add_fingerprint(user)
// shock the user with probability prb
/obj/structure/cable/proc/shock(mob/user, prb, var/siemens_coeff = 1.0)
if(!prob(prb))
return 0
@@ -183,24 +190,296 @@
else
return 0
//explosion handling
/obj/structure/cable/ex_act(severity)
switch(severity)
if(1.0)
del(src)
del(src) // qdel
if(2.0)
if (prob(50))
new/obj/item/stack/cable_coil(src.loc, src.d1 ? 2 : 1, color)
del(src)
del(src) // qdel
if(3.0)
if (prob(25))
new/obj/item/stack/cable_coil(src.loc, src.d1 ? 2 : 1, color)
del(src)
del(src) // qdel
return
// the cable coil object, used for laying cable
obj/structure/cable/proc/cableColor(var/colorC)
var/color_n = "#DD0000"
if(colorC)
color_n = colorC
color = color_n
////////////////////////////////////////////
// Power related
///////////////////////////////////////////
obj/structure/cable/proc/add_avail(var/amount)
if(powernet)
powernet.newavail += amount
obj/structure/cable/proc/add_load(var/amount)
if(powernet)
powernet.load += amount
obj/structure/cable/proc/surplus()
if(powernet)
return powernet.avail-powernet.load
else
return 0
obj/structure/cable/proc/avail()
if(powernet)
return powernet.avail
else
return 0
/////////////////////////////////////////////////
// Cable laying helpers
////////////////////////////////////////////////
//handles merging diagonally matching cables
//for info : direction^3 is flipping horizontally, direction^12 is flipping vertically
/obj/structure/cable/proc/mergeDiagonalsNetworks(var/direction)
//search for and merge diagonally matching cables from the first direction component (north/south)
var/turf/T = get_step(src, direction&3)//go north/south
for(var/obj/structure/cable/C in T)
if(!C)
continue
if(src == C)
continue
if(C.d1 == (direction^3) || C.d2 == (direction^3)) //we've got a diagonally matching cable
if(!C.powernet) //if the matching cable somehow got no powernet, make him one (should not happen for cables)
var/datum/powernet/newPN = new()
newPN.add_cable(C)
if(powernet) //if we already have a powernet, then merge the two powernets
merge_powernets(powernet,C.powernet)
else
C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet
//the same from the second direction component (east/west)
T = get_step(src, direction&12)//go east/west
for(var/obj/structure/cable/C in T)
if(!C)
continue
if(src == C)
continue
if(C.d1 == (direction^12) || C.d2 == (direction^12)) //we've got a diagonally matching cable
if(!C.powernet) //if the matching cable somehow got no powernet, make him one (should not happen for cables)
var/datum/powernet/newPN = new()
newPN.add_cable(C)
if(powernet) //if we already have a powernet, then merge the two powernets
merge_powernets(powernet,C.powernet)
else
C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet
// merge with the powernets of power objects in the given direction
/obj/structure/cable/proc/mergeConnectedNetworks(var/direction)
var/fdir = (!direction)? 0 : turn(direction, 180) //flip the direction, to match with the source position on its turf
if(!(d1 == direction || d2 == direction)) //if the cable is not pointed in this direction, do nothing
return
var/turf/TB = get_step(src, direction)
for(var/obj/structure/cable/C in TB)
if(!C)
continue
if(src == C)
continue
if(C.d1 == fdir || C.d2 == fdir) //we've got a matching cable in the neighbor turf
if(!C.powernet) //if the matching cable somehow got no powernet, make him one (should not happen for cables)
var/datum/powernet/newPN = new()
newPN.add_cable(C)
if(powernet) //if we already have a powernet, then merge the two powernets
merge_powernets(powernet,C.powernet)
else
C.powernet.add_cable(src) //else, we simply connect to the matching cable powernet
// merge with the powernets of power objects in the source turf
/obj/structure/cable/proc/mergeConnectedNetworksOnTurf()
var/list/to_connect = list()
if(!powernet) //if we somehow have no powernet, make one (should not happen for cables)
var/datum/powernet/newPN = new()
newPN.add_cable(src)
//first let's add turf cables to our powernet
//then we'll connect machines on turf with a node cable is present
for(var/AM in loc)
if(istype(AM,/obj/structure/cable))
var/obj/structure/cable/C = AM
if(C.d1 == d1 || C.d2 == d1 || C.d1 == d2 || C.d2 == d2) //only connected if they have a common direction
if(C.powernet == powernet) continue
if(C.powernet)
merge_powernets(powernet, C.powernet)
else
powernet.add_cable(C) //the cable was powernetless, let's just add it to our powernet
else if(istype(AM,/obj/machinery/power/apc))
var/obj/machinery/power/apc/N = AM
if(!N.terminal) continue // APC are connected through their terminal
if(N.terminal.powernet == powernet)
continue
to_connect += N.terminal //we'll connect the machines after all cables are merged
else if(istype(AM,/obj/machinery/power)) //other power machines
var/obj/machinery/power/M = AM
if(M.powernet == powernet)
continue
to_connect += M //we'll connect the machines after all cables are merged
//now that cables are done, let's connect found machines
for(var/obj/machinery/power/PM in to_connect)
if(!PM.connect_to_network())
PM.disconnect_from_network() //if we somehow can't connect the machine to the new powernet, remove it from the old nonetheless
//////////////////////////////////////////////
// Powernets handling helpers
//////////////////////////////////////////////
//if powernetless_only = 1, will only get connections without powernet
/obj/structure/cable/proc/get_connections(var/powernetless_only = 0)
. = list() // this will be a list of all connected power objects
var/turf/T
///// Z-Level Stuff
if (d1 == 11 || d1 == 12)
var/turf/controllerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.up && d1 == 12)
T = locate(src.x, src.y, controller.up_target)
if(T)
. += power_list(T, src, 11, 1)
if(controller.down && d1 == 11)
T = locate(src.x, src.y, controller.down_target)
if(T)
. += power_list(T, src, 12, 1)
///// Z-Level Stuff
//get matching cables from the first direction
else if(d1) //if not a node cable
T = get_step(src, d1)
if(T)
. += power_list(T, src, turn(d1, 180), powernetless_only) //get adjacents matching cables
if(d1&(d1-1)) //diagonal direction, must check the 4 possibles adjacents tiles
T = get_step(src,d1&3) // go north/south
if(T)
. += power_list(T, src, d1 ^ 3, powernetless_only) //get diagonally matching cables
T = get_step(src,d1&12) // go east/west
if(T)
. += power_list(T, src, d1 ^ 12, powernetless_only) //get diagonally matching cables
. += power_list(loc, src, d1, powernetless_only) //get on turf matching cables
///// Z-Level Stuff
if(d2 == 11 || d2 == 12)
var/turf/controllerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.up && d2 == 12)
T = locate(src.x, src.y, controller.up_target)
if(T)
. += power_list(T, src, 11, 1)
if(controller.down && d2 == 11)
T = locate(src.x, src.y, controller.down_target)
if(T)
. += power_list(T, src, 12, 1)
///// Z-Level Stuff
else
//do the same on the second direction (which can't be 0)
T = get_step(src, d2)
if(T)
. += power_list(T, src, turn(d2, 180), powernetless_only) //get adjacents matching cables
if(d2&(d2-1)) //diagonal direction, must check the 4 possibles adjacents tiles
T = get_step(src,d2&3) // go north/south
if(T)
. += power_list(T, src, d2 ^ 3, powernetless_only) //get diagonally matching cables
T = get_step(src,d2&12) // go east/west
if(T)
. += power_list(T, src, d2 ^ 12, powernetless_only) //get diagonally matching cables
. += power_list(loc, src, d2, powernetless_only) //get on turf matching cables
return .
//should be called after placing a cable which extends another cable, creating a "smooth" cable that no longer terminates in the centre of a turf.
//needed as this can, unlike other placements, disconnect cables
/obj/structure/cable/proc/denode()
var/turf/T1 = loc
if(!T1) return
var/list/powerlist = power_list(T1,src,0,0) //find the other cables that ended in the centre of the turf, with or without a powernet
if(powerlist.len>0)
var/datum/powernet/PN = new()
propagate_network(powerlist[1],PN) //propagates the new powernet beginning at the source cable
if(PN.is_empty()) //can happen with machines made nodeless when smoothing cables
del(PN) // qdel
// cut the cable's powernet at this cable and updates the powergrid
/obj/structure/cable/proc/cut_cable_from_powernet()
var/turf/T1 = loc
var/list/P_list
if(!T1) return
if(d1)
T1 = get_step(T1, d1)
P_list = power_list(T1, src, turn(d1,180),0,cable_only = 1) // what adjacently joins on to cut cable...
P_list += power_list(loc, src, d1, 0, cable_only = 1)//... and on turf
if(P_list.len == 0)//if nothing in both list, then the cable was a lone cable, just delete it and its powernet
powernet.remove_cable(src)
for(var/obj/machinery/power/P in T1)//check if it was powering a machine
if(!P.connect_to_network()) //can't find a node cable on a the turf to connect to
P.disconnect_from_network() //remove from current network (and delete powernet)
return
// remove the cut cable from its turf and powernet, so that it doesn't get count in propagate_network worklist
loc = null
powernet.remove_cable(src) //remove the cut cable from its powernet
var/datum/powernet/newPN = new()// creates a new powernet...
propagate_network(P_list[1], newPN)//... and propagates it to the other side of the cable
// Disconnect machines connected to nodes
if(d1 == 0) // if we cut a node (O-X) cable
for(var/obj/machinery/power/P in T1)
if(!P.connect_to_network()) //can't find a node cable on a the turf to connect to
P.disconnect_from_network() //remove from current network
///////////////////////////////////////////////
// The cable coil object, used for laying cable
///////////////////////////////////////////////
////////////////////////////////
// Definitions
////////////////////////////////
#define MAXCOIL 30
/obj/item/stack/cable_coil
name = "cable coil"
icon = 'icons/obj/power.dmi'
@@ -219,10 +498,12 @@
item_state = "coil"
attack_verb = list("whipped", "lashed", "disciplined", "flogged")
suicide_act(mob/user)
viewers(user) << "<span class='warning'><b>[user] is strangling \himself with the [src.name]! It looks like \he's trying to commit suicide.</b></span>"
return(OXYLOSS)
/obj/item/stack/cable_coil/suicide_act(mob/user)
if(locate(/obj/structure/stool) in user.loc)
user.visible_message("<span class='suicide'>[user] is making a noose with the [src.name]! It looks like \he's trying to commit suicide.</span>")
else
user.visible_message("<span class='suicide'>[user] is strangling \himself with the [src.name]! It looks like \he's trying to commit suicide.</span>")
return(OXYLOSS)
/obj/item/stack/cable_coil/New(loc, length = MAXCOIL, var/param_color = null)
..()
@@ -233,10 +514,38 @@
color = item_color
pixel_x = rand(-2,2)
pixel_y = rand(-2,2)
updateicon()
update_icon()
update_wclass()
/obj/item/stack/cable_coil/proc/updateicon()
///////////////////////////////////
// General procedures
///////////////////////////////////
//you can use wires to heal robotics
/obj/item/stack/cable_coil/attack(mob/M as mob, mob/user as mob)
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/datum/organ/external/S = H.get_organ(user.zone_sel.selecting)
if(!(S.status & ORGAN_ROBOT) || user.a_intent != "help")
return ..()
if(H.species.flags & IS_SYNTHETIC)
if(M == user)
user << "\red You can't repair damage to your own body - it's against OH&S."
return
if(S.burn_dam > 0 && use(1))
S.heal_damage(0,15,0,1)
user.visible_message("\red \The [user] repairs some burn damage on \the [M]'s [S.display_name] with \the [src].")
return
else
user << "Nothing to fix!"
else
return ..()
/obj/item/stack/cable_coil/update_icon()
if (!color)
color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_ORANGE, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
item_color = color
@@ -259,12 +568,13 @@
/obj/item/stack/cable_coil/examine()
set src in view(1)
if(amount == 1)
if(get_amount() == 1)
usr << "A short piece of power cable."
else if(amount == 2)
else if(get_amount() == 2)
usr << "A piece of power cable."
else
usr << "A coil of power cable. There are [amount] lengths of cable in the coil."
usr << "A coil of power cable. There are [get_amount()] lengths of cable in the coil."
/obj/item/stack/cable_coil/verb/make_restraint()
set name = "Make Cable Restraints"
@@ -274,26 +584,28 @@
if(ishuman(M) && !M.restrained() && !M.stat && !M.paralysis && ! M.stunned)
if(!istype(usr.loc,/turf)) return
if(src.amount <= 14)
usr << "<span class='warning'>You need at least 15 lengths to make restraints!</span>"
usr << "\red You need at least 15 lengths to make restraints!"
return
var/obj/item/weapon/handcuffs/cable/B = new /obj/item/weapon/handcuffs/cable(usr.loc)
B.color = item_color
usr << "<span class='notice'>You wind some cable together to make some restraints.</span>"
B.icon_state = "cuff_[item_color]"
usr << "\blue You wind some cable together to make some restraints."
src.use(15)
else
usr << "<span class='notice'>\blue You cannot do that.</span>"
usr << "\blue You cannot do that."
..()
// Items usable on a cable coil :
// - Wirecutters : cut them duh !
// - Cable coil : merge cables
/obj/item/stack/cable_coil/attackby(obj/item/weapon/W, mob/user)
..()
if( istype(W, /obj/item/weapon/wirecutters) && src.amount > 1)
src.amount--
new/obj/item/stack/cable_coil(user.loc, 1,item_color)
user << "<span class='notice'>You cut a piece off the cable coil.</span>"
src.updateicon()
src.update_wclass()
user << "You cut a piece off the cable coil."
src.update_icon()
return
else if( istype(W, /obj/item/stack/cable_coil) )
else if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = W
if(C.amount >= MAXCOIL)
user << "The coil is too long, you cannot add any more cable to it."
@@ -301,54 +613,65 @@
if( (C.amount + src.amount <= MAXCOIL) )
user << "You join the cable coils together."
C.add(src.amount) // give it cable
C.give(src.amount) // give it cable
src.use(src.amount) // make sure this one cleans up right
return
else
var/amt = MAXCOIL - C.amount
user << "You transfer [amt] length\s of cable from one coil to the other."
C.add(amt)
C.give(amt)
src.use(amt)
return
..()
return
/obj/item/stack/cable_coil/attack_hand(mob/user as mob)
if (user.get_inactive_hand() == src)
var/obj/item/stack/cable_coil/F = new /obj/item/stack/cable_coil(user, 1, color)
F.copy_evidences(src)
user.put_in_hands(F)
src.add_fingerprint(user)
F.add_fingerprint(user)
use(1)
//remove cables from the stack
/* This is probably reduntant
/obj/item/stack/cable_coil/use(var/used)
if(src.amount < used)
return 0
else if (src.amount == used)
if(ismob(loc)) //handle mob icon update
var/mob/M = loc
M.unEquip(src)
qdel(src)
return 1
else
..()
return
amount -= used
update_icon()
return 1
*/
/obj/item/stack/cable_coil/use(var/used)
. = ..()
updateicon()
update_wclass()
update_icon()
return
/obj/item/stack/cable_coil/add(var/extra)
. = ..()
updateicon()
update_wclass()
return
//add cables to the stack
/obj/item/stack/cable_coil/proc/give(var/extra)
if(amount + extra > MAXCOIL)
amount = MAXCOIL
else
amount += extra
update_icon()
///////////////////////////////////////////////
// Cable laying procedures
//////////////////////////////////////////////
// called when cable_coil is clicked on a turf/simulated/floor
/obj/item/stack/cable_coil/proc/turf_place(turf/simulated/floor/F, mob/user)
if(!isturf(user.loc))
return
if(get_dist(F,user) > 1)
user << "<span class='warning'>You can't lay cable at a place that far away.</span>"
if(get_amount() < 1) // Out of cable
user << "There is no cable left."
return
if(F.intact) // if floor is intact, complain
user << "<span class='warning'>You can't lay cable there unless the floor tiles are removed.</span>"
if(get_dist(F,user) > 1) // Too far
user << "You can't lay cable at a place that far away."
return
if(F.intact) // Ff floor is intact, complain
user << "You can't lay cable there unless the floor tiles are removed."
return
else
@@ -382,9 +705,8 @@
C.add_fingerprint(user)
C.updateicon()
C.powernet = new()
powernets += C.powernet
C.powernet.cables += C
var/datum/powernet/PN = new()
PN.add_cable(C)
C.mergeConnectedNetworks(C.d2)
C.mergeConnectedNetworksOnTurf()
@@ -396,15 +718,12 @@
D.add_fingerprint(user)
D.updateicon()
D.powernet = C.powernet
D.powernet.cables += D
PN.add_cable(D)
D.mergeConnectedNetworksOnTurf()
// do the normal stuff
else
///// Z-Level Stuff
for(var/obj/structure/cable/LC in F)
if((LC.d1 == dirn && LC.d2 == 0 ) || ( LC.d2 == dirn && LC.d1 == 0))
user << "There's already a cable at that position."
@@ -414,32 +733,32 @@
C.cableColor(item_color)
C.d1 = 0
//set up the new cable
C.d1 = 0 //it's a O-X node cable
C.d2 = dirn
C.add_fingerprint(user)
C.updateicon()
C.powernet = new()
powernets += C.powernet
C.powernet.cables += C
//create a new powernet with the cable, if needed it will be merged later
var/datum/powernet/PN = new()
PN.add_cable(C)
C.mergeConnectedNetworks(C.d2)
C.mergeConnectedNetworksOnTurf()
C.mergeConnectedNetworks(C.d2) //merge the powernet with adjacents powernets
C.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets
if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions
C.mergeDiagonalsNetworks(C.d2)
use(1)
if (C.shock(user, 50))
if (prob(50)) //fail
new/obj/item/stack/cable_coil(C.loc, 1, C.color)
del(C)
//src.laying = 1
//last = C
del(C) // qdel
// called when cable_coil is click on an installed obj/cable
// or click on a turf that already contains a "node" cable
/obj/item/stack/cable_coil/proc/cable_join(obj/structure/cable/C, mob/user)
var/turf/U = user.loc
if(!isturf(U))
return
@@ -450,18 +769,20 @@
return
if(get_dist(C, user) > 1) // make sure it's close enough
user << "<span class='warning'>You can't lay cable at a place that far away.</span>"
user << "You can't lay cable at a place that far away."
return
if(U == T) // do nothing if we clicked a cable we're standing on
return // may change later if can think of something logical to do
if(U == T) //if clicked on the turf we're standing on, try to put a cable in the direction we're facing
turf_place(T,user)
return
var/dirn = get_dir(C, user)
if(C.d1 == dirn || C.d2 == dirn) // one end of the clicked cable is pointing towards us
// one end of the clicked cable is pointing towards us
if(C.d1 == dirn || C.d2 == dirn)
if(U.intact) // can't place a cable if the floor is complete
user << "<span class='warning'>You can't lay cable there unless the floor tiles are removed.</span>"
user << "You can't lay cable there unless the floor tiles are removed."
return
else
// cable is pointing at us, we're standing on an open tile
@@ -471,7 +792,7 @@
for(var/obj/structure/cable/LC in U) // check to make sure there's not a cable there already
if(LC.d1 == fdirn || LC.d2 == fdirn)
user << "<span class='warning'>There's already a cable at that position.</span>"
user << "There's already a cable at that position."
return
var/obj/structure/cable/NC = new(U)
@@ -482,19 +803,27 @@
NC.add_fingerprint()
NC.updateicon()
if(C.powernet)
NC.powernet = C.powernet
NC.powernet.cables += NC
NC.mergeConnectedNetworks(NC.d2)
NC.mergeConnectedNetworksOnTurf()
//create a new powernet with the cable, if needed it will be merged later
var/datum/powernet/newPN = new()
newPN.add_cable(NC)
NC.mergeConnectedNetworks(NC.d2) //merge the powernet with adjacents powernets
NC.mergeConnectedNetworksOnTurf() //merge the powernet with on turf powernets
if(NC.d2 & (NC.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions
NC.mergeDiagonalsNetworks(NC.d2)
use(1)
if (NC.shock(user, 50))
if (prob(50)) //fail
new/obj/item/stack/cable_coil(NC.loc, 1, NC.color)
del(NC)
del(NC) // qdel
return
else if(C.d1 == 0) // exisiting cable doesn't point at our position, so see if it's a stub
// exisiting cable doesn't point at our position, so see if it's a stub
else if(C.d1 == 0)
// if so, make it a full cable pointing from it's old direction to our dirn
var/nd1 = C.d2 // these will be the new directions
var/nd2 = dirn
@@ -509,7 +838,7 @@
if(LC == C) // skip the cable we're interacting with
continue
if((LC.d1 == nd1 && LC.d2 == nd2) || (LC.d1 == nd2 && LC.d2 == nd1) ) // make sure no cable matches either direction
user << "<span class='warning'>There's already a cable at that position.</span>"
user << "There's already a cable at that position."
return
@@ -522,90 +851,30 @@
C.updateicon()
C.mergeConnectedNetworks(C.d1)
C.mergeConnectedNetworks(C.d2)
C.mergeConnectedNetworks(C.d1) //merge the powernets...
C.mergeConnectedNetworks(C.d2) //...in the two new cable directions
C.mergeConnectedNetworksOnTurf()
if(C.d1 & (C.d1 - 1))// if the cable is layed diagonally, check the others 2 possible directions
C.mergeDiagonalsNetworks(C.d1)
if(C.d2 & (C.d2 - 1))// if the cable is layed diagonally, check the others 2 possible directions
C.mergeDiagonalsNetworks(C.d2)
use(1)
if (C.shock(user, 50))
if (prob(50)) //fail
new/obj/item/stack/cable_coil(C.loc, 2, C.color)
del(C)
del(C) // qdel
return
C.denode()// this call may have disconnected some cables that terminated on the centre of the turf, if so split the powernets.
return
/obj/structure/cable/proc/mergeConnectedNetworks(var/direction)
var/turf/TB
if(!(d1 == direction || d2 == direction))
return
TB = get_step(src, direction)
for(var/obj/structure/cable/TC in TB)
if(!TC)
continue
if(src == TC)
continue
var/fdir = (!direction)? 0 : turn(direction, 180)
if(TC.d1 == fdir || TC.d2 == fdir)
if(!TC.powernet)
TC.powernet = new()
powernets += TC.powernet
TC.powernet.cables += TC
if(powernet)
merge_powernets(powernet,TC.powernet)
else
powernet = TC.powernet
powernet.cables += src
/obj/structure/cable/proc/mergeConnectedNetworksOnTurf()
if(!powernet)
powernet = new()
powernets += powernet
powernet.cables += src
for(var/AM in loc)
if(istype(AM,/obj/structure/cable))
var/obj/structure/cable/C = AM
if(C.powernet == powernet) continue
if(C.powernet)
merge_powernets(powernet, C.powernet)
else
C.powernet = powernet
powernet.cables += C
else if(istype(AM,/obj/machinery/power/apc))
var/obj/machinery/power/apc/N = AM
if(!N.terminal) continue
if(N.terminal.powernet)
merge_powernets(powernet, N.terminal.powernet)
else
N.terminal.powernet = powernet
powernet.nodes[N.terminal] = N.terminal
else if(istype(AM,/obj/machinery/power))
var/obj/machinery/power/M = AM
if(M.powernet == powernet) continue
if(M.powernet)
merge_powernets(powernet, M.powernet)
else
M.powernet = powernet
powernet.nodes[M] = M
obj/structure/cable/proc/cableColor(var/colorC)
var/color_n = "#DD0000"
if(colorC)
color_n = colorC
color = color_n
//////////////////////////////
// Misc.
/////////////////////////////
/obj/item/stack/cable_coil/cut
item_state = "coil2"
@@ -615,7 +884,7 @@ obj/structure/cable/proc/cableColor(var/colorC)
src.amount = rand(1,2)
pixel_x = rand(-2,2)
pixel_y = rand(-2,2)
updateicon()
update_icon()
update_wclass()
/obj/item/stack/cable_coil/yellow
@@ -642,27 +911,3 @@ obj/structure/cable/proc/cableColor(var/colorC)
/obj/item/stack/cable_coil/random/New()
item_color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
..()
/obj/item/stack/cable_coil/attack(mob/M as mob, mob/user as mob)
if(hasorgans(M))
var/datum/organ/external/S = M:get_organ(user.zone_sel.selecting)
if(!(S.status & ORGAN_ROBOT) || user.a_intent != "help")
return ..()
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.species.flags & IS_SYNTHETIC)
if(M == user)
user << "\red You can't repair damage to your own body - it's against OH&S."
return
if(S.burn_dam > 0 && use(1))
S.heal_damage(0,15,0,1)
user.visible_message("\red \The [user] repairs some burn damage on \the [M]'s [S.display_name] with \the [src].")
return
else
user << "Nothing to fix!"
else
return ..()
-1
View File
@@ -10,7 +10,6 @@
icon_state = "tracker" //ICON stolen from solar tracker. There is no need to make new texture for debug item
anchored = 1
density = 1
directwired = 1
var/power_generation_rate = 2000000 //Defaults to 2MW of power. Should be enough to run SMES charging on full 2 times.
var/powernet_connection_failed = 0
-1
View File
@@ -48,7 +48,6 @@ display round(lastgen) and phorontank amount
icon_state = "portgen0"
density = 1
anchored = 0
directwired = 0
use_power = 0
var/active = 0
+194 -173
View File
@@ -1,10 +1,16 @@
//////////////////////////////
// POWER MACHINERY BASE CLASS
//////////////////////////////
/////////////////////////////
// Definitions
/////////////////////////////
/obj/machinery/power
name = null
icon = 'icons/obj/power.dmi'
anchored = 1.0
var/datum/powernet/powernet = null
var/directwired = 1 // by default, power machines are connected by a cable in a neighbouring turf
// if set to 0, requires a 0-X cable on this turf
use_power = 0
idle_power_usage = 0
active_power_usage = 0
@@ -13,19 +19,23 @@
disconnect_from_network()
..()
///////////////////////////////
// General procedures
//////////////////////////////
// common helper procs for all power machines
/obj/machinery/power/proc/add_avail(var/amount)
if(powernet)
powernet.newavail += amount
/obj/machinery/power/proc/add_load(var/amount)
/obj/machinery/power/proc/draw_power(var/amount)
if(powernet)
return powernet.draw_power(amount)
return 0
/obj/machinery/power/proc/surplus()
if(powernet)
return powernet.surplus()
return powernet.avail-powernet.load
else
return 0
@@ -35,18 +45,18 @@
else
return 0
/obj/machinery/power/proc/disconnect_terminal() // machines without a terminal will just return, no harm no fowl.
return
// returns true if the area has power on given channel (or doesn't require power).
// defaults to power_channel
/obj/machinery/proc/powered(var/chan = -1)
/obj/machinery/proc/powered(var/chan = -1) // defaults to power_channel
if(!src.loc)
return 0
//This is bad. This makes machines which are switched off not update their stat flag correctly when power_change() is called.
//If use_power is 0, then you probably shouldn't be checking power to begin with.
//if(!use_power)
// return 1
if(!use_power)
return 1
var/area/A = src.loc.loc // make sure it's in an area
if(!A || !isarea(A) || !A.master)
@@ -56,75 +66,127 @@
return A.master.powered(chan) // return power status of the area
// increment the power usage stats for an area
/obj/machinery/proc/use_power(var/amount, var/chan = -1, var/autocalled = 0) // defaults to power_channel
var/area/A = src.loc.loc // make sure it's in an area
/obj/machinery/proc/use_power(var/amount, var/chan = -1) // defaults to power_channel
var/area/A = get_area(src) // make sure it's in an area
if(!A || !isarea(A) || !A.master)
return
if(chan == -1)
chan = power_channel
A.master.use_power(amount, chan)
if(!autocalled)
log_power_update_request(A.master, src)
A.master.powerupdate = 2 // Decremented by 2 each GC tick, since it's not auto power change we're going to update power twice.
return 1
//The master_area optional argument can be used to save on a lot of processing if the master area is already known. This is mainly intended for when this proc is called by the master controller.
/obj/machinery/proc/power_change(var/area/master_area = null) // called whenever the power settings of the containing area change
/obj/machinery/proc/power_change() // called whenever the power settings of the containing area change
// by default, check equipment channel & set flag
// can override if needed
var/has_power
if (master_area)
has_power = master_area.powered(power_channel)
else
has_power = powered(power_channel)
if(has_power)
if(powered(power_channel))
stat &= ~NOPOWER
else
stat |= NOPOWER
return
// the powernet datum
// each contiguous network of cables & nodes
// connect the machine to a powernet if a node cable is present on the turf
/obj/machinery/power/proc/connect_to_network()
var/turf/T = src.loc
if(!T || !istype(T))
return 0
var/obj/structure/cable/C = T.get_cable_node() //check if we have a node cable on the machine turf, the first found is picked
if(!C || !C.powernet)
return 0
// rebuild all power networks from scratch
/hook/startup/proc/buildPowernets()
return makepowernets()
/proc/makepowernets()
for(var/datum/powernet/PN in powernets)
del(PN)
powernets.Cut()
for(var/obj/structure/cable/PC in cable_list)
if(!PC.powernet)
PC.powernet = new()
powernets += PC.powernet
// if(Debug) world.log << "Starting mpn at [PC.x],[PC.y] ([PC.d1]/[PC.d2])"
powernet_nextlink(PC,PC.powernet)
// if(Debug) world.log << "[powernets.len] powernets found"
for(var/obj/structure/cable/C in cable_list)
if(!C.powernet) continue
C.powernet.cables += C
for(var/obj/machinery/power/M in machines)
if(!M.powernet) continue // APCs have powernet=0 so they don't count as network nodes directly
M.powernet.nodes[M] = M
C.powernet.add_machine(src)
return 1
// remove and disconnect the machine from its current powernet
/obj/machinery/power/proc/disconnect_from_network()
if(!powernet)
return 0
powernet.remove_machine(src)
return 1
// attach a wire to a power machine - leads from the turf you are standing on
//almost never called, overwritten by all power machines but terminal and generator
/obj/machinery/power/attackby(obj/item/weapon/W, mob/user)
if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/coil = W
var/turf/T = user.loc
if(T.intact || !istype(T, /turf/simulated/floor))
return
if(get_dist(src, user) > 1)
return
coil.turf_place(T, user)
return
else
..()
return
///////////////////////////////////////////
// Powernet handling helpers
//////////////////////////////////////////
//returns all the cables WITHOUT a powernet in neighbors turfs,
//pointing towards the turf the machine is located at
/obj/machinery/power/proc/get_connections()
. = list()
var/cdir
var/turf/T
for(var/card in cardinal)
T = get_step(loc,card)
cdir = get_dir(T,loc)
for(var/obj/structure/cable/C in T)
if(C.powernet) continue
if(C.d1 == cdir || C.d2 == cdir)
. += C
return .
//returns all the cables in neighbors turfs,
//pointing towards the turf the machine is located at
/obj/machinery/power/proc/get_marked_connections()
. = list()
var/cdir
var/turf/T
for(var/card in cardinal)
T = get_step(loc,card)
cdir = get_dir(T,loc)
for(var/obj/structure/cable/C in T)
if(C.d1 == cdir || C.d2 == cdir)
. += C
return .
//returns all the NODES (O-X) cables WITHOUT a powernet in the turf the machine is located at
/obj/machinery/power/proc/get_indirect_connections()
. = list()
for(var/obj/structure/cable/C in loc)
if(C.powernet) continue
if(C.d1 == 0) // the cable is a node cable
. += C
return .
///////////////////////////////////////////
// GLOBAL PROCS for powernets handling
//////////////////////////////////////////
// returns a list of all power-related objects (nodes, cable, junctions) in turf,
// excluding source, that match the direction d
// if unmarked==1, only return those with no powernet
/proc/power_list(var/turf/T, var/source, var/d, var/unmarked=0)
/proc/power_list(var/turf/T, var/source, var/d, var/unmarked=0, var/cable_only = 0)
. = list()
var/fdir = (!d)? 0 : turn(d, 180)
// the opposite direction to d (or 0 if d==0)
var/fdir = (!d)? 0 : turn(d, 180) // the opposite direction to d (or 0 if d==0)
///// Z-Level Stuff
var/Zdir
if(d==11)
@@ -134,16 +196,15 @@
else
Zdir = 999
///// Z-Level Stuff
// world.log << "d=[d] fdir=[fdir]"
for(var/AM in T)
if(AM == source) continue //we don't want to return source
if(istype(AM,/obj/machinery/power))
if(!cable_only && istype(AM,/obj/machinery/power))
var/obj/machinery/power/P = AM
if(P.powernet == 0) continue // exclude APCs which have powernet=0
if(!unmarked || !P.powernet) //if unmarked=1 we only return things with no powernet
if(P.directwired || (d == 0))
if(d == 0)
. += P
else if(istype(AM,/obj/structure/cable))
@@ -154,115 +215,82 @@
if(C.d1 == fdir || C.d2 == fdir || C.d1 == Zdir || C.d2 == Zdir)
///// Z-Level Stuff
. += C
else if(C.d1 == turn(C.d2, 180))
else if(C.d1 == d || C.d2 == d)
. += C
return .
/hook/startup/proc/buildPowernets()
return makepowernets()
/obj/structure/cable/proc/get_connections()
. = list() // this will be a list of all connected power objects
var/turf/T = loc
// rebuild all power networks from scratch - only called at world creation or by the admin verb
/proc/makepowernets()
for(var/datum/powernet/PN in powernets)
del(PN)
powernets.Cut()
///// Z-Level Stuff
if(d1)
if(d1 <= 10)
T = get_step(src, d1)
if(T)
. += power_list(T, src, d1, 1)
else if (d1 == 11 || d1 == 12)
var/turf/controllerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.up && d1 == 12)
T = locate(src.x, src.y, controller.up_target)
if(T)
. += power_list(T, src, 11, 1)
if(controller.down && d1 == 11)
T = locate(src.x, src.y, controller.down_target)
if(T)
. += power_list(T, src, 12, 1)
else if(!d1)
if(T)
. += power_list(T, src, d1, 1)
if(d2 == 11 || d2 == 12)
var/turf/controllerlocation = locate(1, 1, z)
for(var/obj/effect/landmark/zcontroller/controller in controllerlocation)
if(controller.up && d2 == 12)
T = locate(src.x, src.y, controller.up_target)
if(T)
. += power_list(T, src, 11, 1)
if(controller.down && d2 == 11)
T = locate(src.x, src.y, controller.down_target)
if(T)
. += power_list(T, src, 12, 1)
else
T = get_step(src, d2)
if(T)
. += power_list(T, src, d2, 1)
///// Z-Level Stuff
return .
/obj/machinery/power/proc/get_connections()
. = list()
if(!directwired)
return get_indirect_connections()
var/cdir
for(var/card in cardinal)
var/turf/T = get_step(loc,card)
cdir = get_dir(T,loc)
for(var/obj/structure/cable/C in T)
if(C.powernet) continue
if(C.d1 == cdir || C.d2 == cdir)
. += C
return .
/obj/machinery/power/proc/get_indirect_connections()
. = list()
for(var/obj/structure/cable/C in loc)
if(C.powernet) continue
if(C.d1 == 0)
. += C
return .
/obj/machinery/power/proc/connect_to_network()
var/turf/T = src.loc
var/obj/structure/cable/C = T.get_cable_node()
if(!C || !C.powernet) return 0
// makepowernets() //TODO: find fast way //EWWWW what are you doing!?
powernet = C.powernet
powernet.nodes[src] = src
for(var/obj/structure/cable/PC in cable_list)
if(!PC.powernet)
var/datum/powernet/NewPN = new()
NewPN.add_cable(PC)
propagate_network(PC,PC.powernet)
return 1
/obj/machinery/power/proc/disconnect_from_network()
if(!powernet)
//world << " no powernet"
return 0
powernet.nodes -= src
powernet = null
//world << "powernet null"
return 1
//remove the old powernet and replace it with a new one throughout the network.
/proc/propagate_network(var/obj/O, var/datum/powernet/PN)
//world.log << "propagating new network"
var/list/worklist = list()
var/list/found_machines = list()
var/index = 1
var/obj/P = null
/turf/proc/get_cable_node()
if(!istype(src, /turf/simulated/floor))
return null
for(var/obj/structure/cable/C in src)
if(C.d1 == 0)
return C
return null
worklist+=O //start propagating from the passed object
/area/proc/get_apc()
for(var/area/RA in src.related)
var/obj/machinery/power/apc/FINDME = locate() in RA
if (FINDME)
return FINDME
while(index<=worklist.len) //until we've exhausted all power objects
P = worklist[index] //get the next power object found
index++
if( istype(P,/obj/structure/cable))
var/obj/structure/cable/C = P
if(C.powernet != PN) //add it to the powernet, if it isn't already there
PN.add_cable(C)
worklist |= C.get_connections() //get adjacents power objects, with or without a powernet
else if(P.anchored && istype(P,/obj/machinery/power))
var/obj/machinery/power/M = P
found_machines |= M //we wait until the powernet is fully propagates to connect the machines
else
continue
//now that the powernet is set, connect found machines to it
for(var/obj/machinery/power/PM in found_machines)
if(!PM.connect_to_network()) //couldn't find a node on its turf...
PM.disconnect_from_network() //... so disconnect if already on a powernet
//Merge two powernets, the bigger (in cable length term) absorbing the other
/proc/merge_powernets(var/datum/powernet/net1, var/datum/powernet/net2)
if(!net1 || !net2) //if one of the powernet doesn't exist, return
return
if(net1 == net2) //don't merge same powernets
return
//We assume net1 is larger. If net2 is in fact larger we are just going to make them switch places to reduce on code.
if(net1.cables.len < net2.cables.len) //net2 is larger than net1. Let's switch them around
var/temp = net1
net1 = net2
net2 = temp
//merge net2 into net1
for(var/obj/structure/cable/Cable in net2.cables) //merge cables
net1.add_cable(Cable)
for(var/obj/machinery/power/Node in net2.nodes) //merge power machines
if(!Node.connect_to_network())
Node.disconnect_from_network() //if somehow we can't connect the machine to the new powernet, disconnect it from the old nonetheless
return net1
//Determines how strong could be shock, deals damage to mob, uses power.
//M is a mob who touched wire/whatever
@@ -271,17 +299,11 @@
//No animations will be performed by this proc.
/proc/electrocute_mob(mob/living/carbon/M as mob, var/power_source, var/obj/source, var/siemens_coeff = 1.0)
if(istype(M.loc,/obj/mecha)) return 0 //feckin mechs are dumb
//This is for performance optimization only.
//DO NOT modify siemens_coeff here. That is checked in human/electrocute_act()
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(H.species.insulated)
return 0
else if(H.gloves)
if(H.gloves)
var/obj/item/clothing/gloves/G = H.gloves
if(G.siemens_coefficient == 0)
return 0 //to avoid spamming with insulated glvoes on
if(G.siemens_coefficient == 0) return 0 //to avoid spamming with insulated glvoes on
var/area/source_area
if(istype(power_source,/area))
@@ -327,11 +349,10 @@
var/drained_energy = drained_hp*20
if (source_area)
source_area.use_power(drained_energy)
source_area.use_power(drained_energy/CELLRATE)
else if (istype(power_source,/datum/powernet))
//var/drained_power = drained_energy/CELLRATE //convert from "joules" to "watts" <<< NO. THIS IS WRONG. CELLRATE DOES NOT CONVERT TO OR FROM JOULES.
PN.draw_power(drained_energy)
var/drained_power = drained_energy/CELLRATE //convert from "joules" to "watts"
PN.load+=drained_power
else if (istype(power_source, /obj/item/weapon/cell))
cell.use(drained_energy*CELLRATE) //convert to units of charge.
cell.use(drained_energy)
return drained_energy
+97 -217
View File
@@ -1,29 +1,80 @@
/datum/powernet
var/list/cables = list() // all cables & junctions
var/list/nodes = list() // all APCs & sources
var/list/nodes = list() // all connected machines
var/load = 0 // the current load on the powernet, increased by each machine at processing
var/newavail = 0 // what available power was gathered last tick, then becomes...
var/avail = 0 //...the current available power in the powernet
var/viewload = 0 // the load as it appears on the power console (gradually updated)
var/number = 0 // Unused //TODEL
var/newload = 0
var/load = 0
var/newavail = 0
var/avail = 0
var/viewload = 0
var/number = 0
var/perapc = 0 // per-apc avilability
var/perapc_excess = 0
var/netexcess = 0
var/netexcess = 0 // excess power on the powernet (typically avail-load)
/datum/powernet/proc/process()
load = newload
newload = 0
avail = newavail
newavail = 0
/datum/powernet/New()
powernets += src
/datum/powernet/Del()
powernets -= src
//Returns the amount of excess power (before refunding to SMESs) from last tick.
//This is for machines that might adjust their power consumption using this data.
/datum/powernet/proc/last_surplus()
return max(avail - load, 0)
/datum/powernet/proc/draw_power(var/amount)
var/draw = between(0, amount, avail - load)
load += draw
return draw
/datum/powernet/proc/is_empty()
return !cables.len && !nodes.len
//remove a cable from the current powernet
//if the powernet is then empty, delete it
//Warning : this proc DON'T check if the cable exists
/datum/powernet/proc/remove_cable(var/obj/structure/cable/C)
cables -= C
C.powernet = null
if(is_empty())//the powernet is now empty...
del(src)///... delete it - qdel
//add a cable to the current powernet
//Warning : this proc DON'T check if the cable exists
/datum/powernet/proc/add_cable(var/obj/structure/cable/C)
if(C.powernet)// if C already has a powernet...
if(C.powernet == src)
return
else
C.powernet.remove_cable(C) //..remove it
C.powernet = src
cables +=C
//remove a power machine from the current powernet
//if the powernet is then empty, delete it
//Warning : this proc DON'T check if the machine exists
/datum/powernet/proc/remove_machine(var/obj/machinery/power/M)
nodes -=M
M.powernet = null
if(is_empty())//the powernet is now empty...
del(src)///... delete it - qdel
viewload = 0.8*viewload + 0.2*load
viewload = round(viewload)
//add a power machine to the current powernet
//Warning : this proc DON'T check if the machine exists
/datum/powernet/proc/add_machine(var/obj/machinery/power/M)
if(M.powernet)// if M already has a powernet...
if(M.powernet == src)
return
else
M.disconnect_from_network()//..remove it
M.powernet = src
nodes[M] = M
//handles the power changes in the powernet
//called every ticks by the powernet controller
/datum/powernet/proc/reset()
var/numapc = 0
if(nodes && nodes.len) // Added to fix a bad list bug -- TLE
@@ -41,165 +92,24 @@
perapc_excess += min(netexcess/numapc, (avail - perapc) - perapc_excess)
else
perapc_excess = 0
perapc = avail/numapc + perapc_excess
if( netexcess > 100) // if there was excess power last cycle
if(nodes && nodes.len)
for(var/obj/machinery/power/smes/S in nodes) // find the SMESes in the network
if(S.powernet == src)
S.restore() // and restore some of the power that was used
else
error("[S.name] (\ref[S]) had a [S.powernet ? "different (\ref[S.powernet])" : "null"] powernet to our powernet (\ref[src]).")
nodes.Remove(S)
if(netexcess > 100 && nodes && nodes.len) // if there was excess power last cycle
for(var/obj/machinery/power/smes/S in nodes) // find the SMESes in the network
S.restore() // and restore some of the power that was used
//updates the viewed load (as seen on power computers)
viewload = 0.8*viewload + 0.2*load
viewload = round(viewload)
//Returns the amount of available power
/datum/powernet/proc/surplus()
return max(avail - newload, 0)
//Returns the amount of excess power (before refunding to SMESs) from last tick.
//This is for machines that might adjust their power consumption using this data.
/datum/powernet/proc/last_surplus()
return max(avail - load, 0)
//Attempts to draw power from a powernet. Returns the actual amount of power drawn
/datum/powernet/proc/draw_power(var/requested_amount)
var/surplus = max(avail - newload, 0)
var/actual_draw = min(requested_amount, surplus)
newload += actual_draw
return actual_draw
// cut a powernet at this cable object
/datum/powernet/proc/cut_cable(var/obj/structure/cable/C)
var/turf/T1 = C.loc
if(!T1) return
var/node = 0
if(C.d1 == 0)
node = 1
var/turf/T2
if(C.d2) T2 = get_step(T1, C.d2)
if(C.d1) T1 = get_step(T1, C.d1)
var/list/P1 = power_list(T1, C, C.d1) // what joins on to cut cable in dir1
var/list/P2 = power_list(T2, C, C.d2) // what joins on to cut cable in dir2
// if(Debug)
// for(var/obj/O in P1)
// world.log << "P1: [O] at [O.x] [O.y] : [istype(O, /obj/structure/cable) ? "[O:d1]/[O:d2]" : null] "
// for(var/obj/O in P2)
// world.log << "P2: [O] at [O.x] [O.y] : [istype(O, /obj/structure/cable) ? "[O:d1]/[O:d2]" : null] "
if(P1.len == 0 || P2.len == 0)//if nothing in either list, then the cable was an endpoint no need to rebuild the powernet,
cables -= C //just remove cut cable from the list
// if(Debug) world.log << "Was end of cable"
return
//null the powernet reference of all cables & nodes in this powernet
var/i=1
while(i<=cables.len)
var/obj/structure/cable/Cable = cables[i]
if(Cable)
Cable.powernet = null
if(Cable == C)
cables.Cut(i,i+1)
continue
i++
i=1
while(i<=nodes.len)
var/obj/machinery/power/Node = nodes[i]
if(Node)
Node.powernet = null
i++
// remove the cut cable from the network
// C.netnum = -1
C.loc = null
powernet_nextlink(P1[1], src) // propagate network from 1st side of cable, using current netnum //TODO?
// now test to see if propagation reached to the other side
// if so, then there's a loop in the network
var/notlooped = 0
for(var/O in P2)
if( istype(O, /obj/machinery/power) )
var/obj/machinery/power/Machine = O
if(Machine.powernet != src)
notlooped = 1
break
else if( istype(O, /obj/structure/cable) )
var/obj/structure/cable/Cable = O
if(Cable.powernet != src)
notlooped = 1
break
if(notlooped)
// not looped, so make a new powernet
var/datum/powernet/PN = new()
powernets += PN
// if(Debug) world.log << "Was not looped: spliting PN#[number] ([cables.len];[nodes.len])"
i=1
while(i<=cables.len)
var/obj/structure/cable/Cable = cables[i]
if(Cable && !Cable.powernet) // non-connected cables will have powernet=null, since they weren't reached by propagation
Cable.powernet = PN
cables.Cut(i,i+1) // remove from old network & add to new one
PN.cables += Cable
continue
i++
i=1
while(i<=nodes.len)
var/obj/machinery/power/Node = nodes[i]
if(Node && !Node.powernet)
Node.powernet = PN
nodes.Cut(i,i+1)
PN.nodes[Node] = Node
continue
i++
// Disconnect machines connected to nodes
if(node)
for(var/obj/machinery/power/P in T1)
if(P.powernet && !P.powernet.nodes[src])
P.disconnect_from_network()
// if(Debug)
// world.log << "Old PN#[number] : ([cables.len];[nodes.len])"
// world.log << "New PN#[PN.number] : ([PN.cables.len];[PN.nodes.len])"
//
// else
// if(Debug)
// world.log << "Was looped."
// //there is a loop, so nothing to be done
// return
//reset the powernet
load = 0
avail = newavail
newavail = 0
/datum/powernet/proc/get_electrocute_damage()
switch(avail)/*
if (1300000 to INFINITY)
return min(rand(70,150),rand(70,150))
if (750000 to 1300000)
return min(rand(50,115),rand(50,115))
if (100000 to 750000-1)
return min(rand(35,101),rand(35,101))
if (75000 to 100000-1)
return min(rand(30,95),rand(30,95))
if (50000 to 75000-1)
return min(rand(25,80),rand(25,80))
if (25000 to 50000-1)
return min(rand(20,70),rand(20,70))
if (10000 to 25000-1)
return min(rand(20,65),rand(20,65))
if (1000 to 10000-1)
return min(rand(10,20),rand(10,20))*/
switch(avail)
if (1000000 to INFINITY)
return min(rand(50,160),rand(50,160))
if (200000 to 1000000)
@@ -213,53 +123,23 @@
else
return 0
/proc/powernet_nextlink(var/obj/O, var/datum/powernet/PN)
var/list/P
////////////////////////////////////////////////
// Misc.
///////////////////////////////////////////////
while(1)
if( istype(O,/obj/structure/cable) )
var/obj/structure/cable/C = O
C.powernet = PN
P = C.get_connections()
else if(O.anchored && istype(O,/obj/machinery/power))
var/obj/machinery/power/M = O
M.powernet = PN
P = M.get_connections()
// return a knot cable (O-X) if one is present in the turf
// null if there's none
/turf/proc/get_cable_node()
if(!istype(src, /turf/simulated/floor))
return null
for(var/obj/structure/cable/C in src)
if(C.d1 == 0)
return C
return null
else
return
if(P.len == 0) return
O = P[1]
for(var/L = 2 to P.len)
powernet_nextlink(P[L], PN)
//The powernet that calls this proc will consume the other powernet - Rockdtben
//TODO: rewrite so the larger net absorbs the smaller net
/proc/merge_powernets(var/datum/powernet/net1, var/datum/powernet/net2)
if(!net1 || !net2) return
if(net1 == net2) return
//We assume net1 is larger. If net2 is in fact larger we are just going to make them switch places to reduce on code.
if(net1.cables.len < net2.cables.len) //net2 is larger than net1. Let's switch them around
var/temp = net1
net1 = net2
net2 = temp
for(var/i=1,i<=net2.nodes.len,i++) //merge net2 into net1
var/obj/machinery/power/Node = net2.nodes[i]
if(Node)
Node.powernet = net1
net1.nodes[Node] = Node
for(var/i=1,i<=net2.cables.len,i++)
var/obj/structure/cable/Cable = net2.cables[i]
if(Cable)
Cable.powernet = net1
net1.cables += Cable
del(net2)
return net1
/area/proc/get_apc()
for(var/area/RA in src.related)
var/obj/machinery/power/apc/FINDME = locate() in RA
if (FINDME)
return FINDME
@@ -8,7 +8,6 @@ var/global/list/rad_collectors = list()
icon_state = "ca"
anchored = 0
density = 1
directwired = 1
req_access = list(access_engine_equip)
// use_power = 0
var/obj/item/weapon/tank/phoron/P = null
+4 -6
View File
@@ -40,7 +40,6 @@
..()
if(state == 2 && anchored)
connect_to_network()
src.directwired = 1
/obj/machinery/power/emitter/Del()
message_admins("Emitter deleted at ([x],[y],[z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)",0,1)
@@ -106,7 +105,8 @@
return
if(((src.last_shot + src.fire_delay) <= world.time) && (src.active == 1))
if(surplus() >= active_power_usage && add_load(active_power_usage) >= active_power_usage) //does the laser have enough power to shoot?
var/actual_load = draw_power(active_power_usage)
if(actual_load >= active_power_usage) //does the laser have enough power to shoot?
if(!powered)
powered = 1
update_icon()
@@ -125,13 +125,13 @@
else
src.fire_delay = rand(min_burst_delay, max_burst_delay)
src.shot_number = 0
//need to calculate the power per shot as the emitter doesn't fire continuously.
var/burst_time = (min_burst_delay + max_burst_delay)/2 + 2*(burst_shots-1)
var/power_per_shot = active_power_usage * (burst_time/10) / burst_shots
var/obj/item/projectile/beam/emitter/A = new /obj/item/projectile/beam/emitter( src.loc )
A.damage = round(power_per_shot/EMITTER_DAMAGE_POWER_TRANSFER)
playsound(src.loc, 'sound/weapons/emitter.ogg', 25, 1)
if(prob(35))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
@@ -198,7 +198,6 @@
state = 2
user << "You weld the [src] to the floor."
connect_to_network()
src.directwired = 1
else
user << "\red You need more welding fuel to complete this task."
if(2)
@@ -212,7 +211,6 @@
state = 1
user << "You cut the [src] free from the floor."
disconnect_from_network()
src.directwired = 0
else
user << "\red You need more welding fuel to complete this task."
return
+3 -10
View File
@@ -92,7 +92,7 @@
//TODO: Add a meter to tell players how much charge we are actually getting, and only set charging to 0 when we are unable to get any charge at all.
if(chargemode)
var/target_load = min((capacity-charge)/SMESRATE, chargelevel) // charge at set rate, limited to spare capacity
var/actual_load = add_load(target_load) // add the load to the terminal side network
var/actual_load = draw_power(target_load) // add the load to the terminal side network
charge += actual_load * SMESRATE // increase the charge
if (actual_load >= target_load) // did the powernet have enough power available for us?
@@ -174,7 +174,7 @@
return 1
/obj/machinery/power/smes/add_load(var/amount)
/obj/machinery/power/smes/draw_power(var/amount)
if(terminal && terminal.powernet)
return terminal.powernet.draw_power(amount)
return 0
@@ -333,7 +333,7 @@
/obj/machinery/power/smes/proc/ion_act()
if(src.z == 1)
if(src.z in config.station_levels)
if(prob(1)) //explosion
for(var/mob/M in viewers(src))
M.show_message("\red The [src.name] is making strange noises!", 3, "\red You hear sizzling electronics.", 2)
@@ -385,11 +385,4 @@
charge = 5000000
..()
/proc/rate_control(var/S, var/V, var/C, var/Min=1, var/Max=5, var/Limit=null)
var/href = "<A href='?src=\ref[S];rate control=1;[V]"
var/rate = "[href]=-[Max]'>-</A>[href]=-[Min]'>-</A> [(C?C : 0)] [href]=[Min]'>+</A>[href]=[Max]'>+</A>"
if(Limit) return "[href]=-[Limit]'>-</A>"+rate+"[href]=[Limit]'>+</A>"
return rate
#undef SMESRATE

Some files were not shown because too many files have changed in this diff Show More