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

This commit is contained in:
PsiOmega
2015-02-03 14:51:54 +01:00
236 changed files with 450 additions and 16884 deletions

View File

@@ -1980,7 +1980,7 @@
if(!ticker)
alert("The game hasn't started yet!")
return
var/objective = copytext(sanitize(input("Enter an objective")),1,MAX_MESSAGE_LEN)
var/objective = sanitize(copytext(input("Enter an objective"),1,MAX_MESSAGE_LEN))
if(!objective)
return
feedback_inc("admin_secrets_fun_used",1)

View File

@@ -4,7 +4,7 @@
set hidden = 1
if(!check_rights(R_ADMIN)) return
msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)
msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))
if(!msg) return
log_admin("[key_name(src)] : [msg]")
@@ -23,7 +23,7 @@
if(!check_rights(R_ADMIN|R_MOD|R_MENTOR)) return
msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)
msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))
log_admin("MOD: [key_name(src)] : [msg]")
if (!msg)

View File

@@ -0,0 +1,267 @@
/proc/togglebuildmode(mob/M as mob in player_list)
set name = "Toggle Build Mode"
set category = "Special Verbs"
if(M.client)
if(M.client.buildmode)
log_admin("[key_name(usr)] has left build mode.")
M.client.buildmode = 0
M.client.show_popup_menus = 1
for(var/obj/effect/bmode/buildholder/H)
if(H.cl == M.client)
del(H)
else
log_admin("[key_name(usr)] has entered build mode.")
M.client.buildmode = 1
M.client.show_popup_menus = 0
var/obj/effect/bmode/buildholder/H = new/obj/effect/bmode/buildholder()
var/obj/effect/bmode/builddir/A = new/obj/effect/bmode/builddir(H)
A.master = H
var/obj/effect/bmode/buildhelp/B = new/obj/effect/bmode/buildhelp(H)
B.master = H
var/obj/effect/bmode/buildmode/C = new/obj/effect/bmode/buildmode(H)
C.master = H
var/obj/effect/bmode/buildquit/D = new/obj/effect/bmode/buildquit(H)
D.master = H
H.builddir = A
H.buildhelp = B
H.buildmode = C
H.buildquit = D
M.client.screen += A
M.client.screen += B
M.client.screen += C
M.client.screen += D
H.cl = M.client
/obj/effect/bmode//Cleaning up the tree a bit
density = 1
anchored = 1
layer = 20
dir = NORTH
icon = 'icons/misc/buildmode.dmi'
var/obj/effect/bmode/buildholder/master = null
/obj/effect/bmode/builddir
icon_state = "build"
screen_loc = "NORTH,WEST"
Click()
switch(dir)
if(NORTH)
set_dir(EAST)
if(EAST)
set_dir(SOUTH)
if(SOUTH)
set_dir(WEST)
if(WEST)
set_dir(NORTHWEST)
if(NORTHWEST)
set_dir(NORTH)
return 1
/obj/effect/bmode/buildhelp
icon = 'icons/misc/buildmode.dmi'
icon_state = "buildhelp"
screen_loc = "NORTH,WEST+1"
Click()
switch(master.cl.buildmode)
if(1)
usr << "\blue ***********************************************************"
usr << "\blue Left Mouse Button = Construct / Upgrade"
usr << "\blue Right Mouse Button = Deconstruct / Delete / Downgrade"
usr << "\blue Left Mouse Button + ctrl = R-Window"
usr << "\blue Left Mouse Button + alt = Airlock"
usr << ""
usr << "\blue Use the button in the upper left corner to"
usr << "\blue change the direction of built objects."
usr << "\blue ***********************************************************"
if(2)
usr << "\blue ***********************************************************"
usr << "\blue Right Mouse Button on buildmode button = Set object type"
usr << "\blue Left Mouse Button on turf/obj = Place objects"
usr << "\blue Right Mouse Button = Delete objects"
usr << ""
usr << "\blue Use the button in the upper left corner to"
usr << "\blue change the direction of built objects."
usr << "\blue ***********************************************************"
if(3)
usr << "\blue ***********************************************************"
usr << "\blue Right Mouse Button on buildmode button = Select var(type) & value"
usr << "\blue Left Mouse Button on turf/obj/mob = Set var(type) & value"
usr << "\blue Right Mouse Button on turf/obj/mob = Reset var's value"
usr << "\blue ***********************************************************"
if(4)
usr << "\blue ***********************************************************"
usr << "\blue Left Mouse Button on turf/obj/mob = Select"
usr << "\blue Right Mouse Button on turf/obj/mob = Throw"
usr << "\blue ***********************************************************"
return 1
/obj/effect/bmode/buildquit
icon_state = "buildquit"
screen_loc = "NORTH,WEST+3"
Click()
togglebuildmode(master.cl.mob)
return 1
/obj/effect/bmode/buildholder
density = 0
anchored = 1
var/client/cl = null
var/obj/effect/bmode/builddir/builddir = null
var/obj/effect/bmode/buildhelp/buildhelp = null
var/obj/effect/bmode/buildmode/buildmode = null
var/obj/effect/bmode/buildquit/buildquit = null
var/atom/movable/throw_atom = null
/obj/effect/bmode/buildmode
icon_state = "buildmode1"
screen_loc = "NORTH,WEST+2"
var/varholder = "name"
var/valueholder = "derp"
var/objholder = /obj/structure/closet
Click(location, control, params)
var/list/pa = params2list(params)
if(pa.Find("left"))
switch(master.cl.buildmode)
if(1)
master.cl.buildmode = 2
src.icon_state = "buildmode2"
if(2)
master.cl.buildmode = 3
src.icon_state = "buildmode3"
if(3)
master.cl.buildmode = 4
src.icon_state = "buildmode4"
if(4)
master.cl.buildmode = 1
src.icon_state = "buildmode1"
else if(pa.Find("right"))
switch(master.cl.buildmode)
if(1)
return 1
if(2)
objholder = text2path(input(usr,"Enter typepath:" ,"Typepath","/obj/structure/closet"))
if(!ispath(objholder))
objholder = /obj/structure/closet
alert("That path is not allowed.")
else
if(ispath(objholder,/mob) && !check_rights(R_DEBUG,0))
objholder = /obj/structure/closet
if(3)
var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine")
master.buildmode.varholder = input(usr,"Enter variable name:" ,"Name", "name")
if(master.buildmode.varholder in locked && !check_rights(R_DEBUG,0))
return 1
var/thetype = input(usr,"Select variable type:" ,"Type") in list("text","number","mob-reference","obj-reference","turf-reference")
if(!thetype) return 1
switch(thetype)
if("text")
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", "value") as text
if("number")
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", 123) as num
if("mob-reference")
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as mob in mob_list
if("obj-reference")
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as obj in world
if("turf-reference")
master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as turf in world
return 1
/proc/build_click(var/mob/user, buildmode, params, var/obj/object)
var/obj/effect/bmode/buildholder/holder = null
for(var/obj/effect/bmode/buildholder/H)
if(H.cl == user.client)
holder = H
break
if(!holder) return
var/list/pa = params2list(params)
switch(buildmode)
if(1)
if(istype(object,/turf) && pa.Find("left") && !pa.Find("alt") && !pa.Find("ctrl") )
if(istype(object,/turf/space))
var/turf/T = object
T.ChangeTurf(/turf/simulated/floor)
return
else if(istype(object,/turf/simulated/floor))
var/turf/T = object
T.ChangeTurf(/turf/simulated/wall)
return
else if(istype(object,/turf/simulated/wall))
var/turf/T = object
T.ChangeTurf(/turf/simulated/wall/r_wall)
return
else if(pa.Find("right"))
if(istype(object,/turf/simulated/wall))
var/turf/T = object
T.ChangeTurf(/turf/simulated/floor)
return
else if(istype(object,/turf/simulated/floor))
var/turf/T = object
T.ChangeTurf(/turf/space)
return
else if(istype(object,/turf/simulated/wall/r_wall))
var/turf/T = object
T.ChangeTurf(/turf/simulated/wall)
return
else if(istype(object,/obj))
del(object)
return
else if(istype(object,/turf) && pa.Find("alt") && pa.Find("left"))
new/obj/machinery/door/airlock(get_turf(object))
else if(istype(object,/turf) && pa.Find("ctrl") && pa.Find("left"))
switch(holder.builddir.dir)
if(NORTH)
var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object))
WIN.set_dir(NORTH)
if(SOUTH)
var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object))
WIN.set_dir(SOUTH)
if(EAST)
var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object))
WIN.set_dir(EAST)
if(WEST)
var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object))
WIN.set_dir(WEST)
if(NORTHWEST)
var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object))
WIN.set_dir(NORTHWEST)
if(2)
if(pa.Find("left"))
if(ispath(holder.buildmode.objholder,/turf))
var/turf/T = get_turf(object)
T.ChangeTurf(holder.buildmode.objholder)
else
var/obj/A = new holder.buildmode.objholder (get_turf(object))
A.set_dir(holder.builddir.dir)
else if(pa.Find("right"))
if(isobj(object)) del(object)
if(3)
if(pa.Find("left")) //I cant believe this shit actually compiles.
if(object.vars.Find(holder.buildmode.varholder))
log_admin("[key_name(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]")
object.vars[holder.buildmode.varholder] = holder.buildmode.valueholder
else
usr << "\red [initial(object.name)] does not have a var called '[holder.buildmode.varholder]'"
if(pa.Find("right"))
if(object.vars.Find(holder.buildmode.varholder))
log_admin("[key_name(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]")
object.vars[holder.buildmode.varholder] = initial(object.vars[holder.buildmode.varholder])
else
usr << "\red [initial(object.name)] does not have a var called '[holder.buildmode.varholder]'"
if(4)
if(pa.Find("left"))
if(istype(object, /atom/movable))
holder.throw_atom = object
if(pa.Find("right"))
if(holder.throw_atom)
holder.throw_atom.throw_at(object, 10, 1)

View File

@@ -25,11 +25,11 @@
if (src.holder.rights & R_MENTOR)
stafftype = "MENTOR"
if (src.holder.rights & R_ADMIN)
stafftype = "ADMIN"
msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)
msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))
log_admin("[key_name(src)] : [msg]")
if (!msg)

View File

@@ -736,8 +736,8 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
M.equip_syndicate_commando()
if("nanotrasen representative")
M.equip_if_possible(new /obj/item/clothing/under/rank/centcom/representative(M), slot_w_uniform)
M.equip_if_possible(new /obj/item/clothing/shoes/centcom(M), slot_shoes)
M.equip_if_possible(new /obj/item/clothing/under/rank/centcom(M), slot_w_uniform)
M.equip_if_possible(new /obj/item/clothing/shoes/laceup(M), slot_shoes)
M.equip_if_possible(new /obj/item/clothing/gloves/white(M), slot_gloves)
M.equip_if_possible(new /obj/item/device/radio/headset/heads/hop(M), slot_l_ear)
@@ -761,8 +761,8 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
M.equip_if_possible(W, slot_wear_id)
if("nanotrasen officer")
M.equip_if_possible(new /obj/item/clothing/under/rank/centcom/officer(M), slot_w_uniform)
M.equip_if_possible(new /obj/item/clothing/shoes/centcom(M), slot_shoes)
M.equip_if_possible(new /obj/item/clothing/under/rank/centcom_officer(M), slot_w_uniform)
M.equip_if_possible(new /obj/item/clothing/shoes/laceup(M), slot_shoes)
M.equip_if_possible(new /obj/item/clothing/gloves/white(M), slot_gloves)
M.equip_if_possible(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear)
M.equip_if_possible(new /obj/item/clothing/head/beret/centcom/officer(M), slot_head)
@@ -786,8 +786,8 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if("nanotrasen captain")
M.equip_if_possible(new /obj/item/clothing/under/rank/centcom/captain(M), slot_w_uniform)
M.equip_if_possible(new /obj/item/clothing/shoes/centcom(M), slot_shoes)
M.equip_if_possible(new /obj/item/clothing/under/rank/centcom_captain(M), slot_w_uniform)
M.equip_if_possible(new /obj/item/clothing/shoes/laceup(M), slot_shoes)
M.equip_if_possible(new /obj/item/clothing/gloves/white(M), slot_gloves)
M.equip_if_possible(new /obj/item/device/radio/headset/heads/captain(M), slot_l_ear)
M.equip_if_possible(new /obj/item/clothing/head/beret/centcom/captain(M), slot_head)

View File

@@ -6,7 +6,7 @@
usr << "\red Speech is currently admin-disabled."
return
msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)
msg = sanitize(copytext(msg, 1, MAX_MESSAGE_LEN))
if(!msg) return
if(usr.client)
@@ -29,14 +29,14 @@
//log_admin("HELP: [key_name(src)]: [msg]")
/proc/Centcomm_announce(var/text , var/mob/Sender , var/iamessage)
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
msg = "\blue <b><font color=orange>CENTCOMM[iamessage ? " IA" : ""]:</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;CentcommReply=\ref[Sender]'>RPLY</A>):</b> [msg]"
for(var/client/C in admins)
if(R_ADMIN & C.holder.rights)
C << msg
/proc/Syndicate_announce(var/text , var/mob/Sender)
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
var/msg = sanitize(copytext(text, 1, MAX_MESSAGE_LEN))
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]"
for(var/client/C in admins)
if(R_ADMIN & C.holder.rights)

View File

@@ -19,7 +19,7 @@ var/global/sent_strike_team = 0
var/input = null
while(!input)
input = copytext(sanitize(input(src, "Please specify which mission the death commando squad shall undertake.", "Specify Mission", "")),1,MAX_MESSAGE_LEN)
input = sanitize(copytext(input(src, "Please specify which mission the death commando squad 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

View File

@@ -24,7 +24,7 @@ var/global/sent_syndicate_strike_team = 0
var/input = null
while(!input)
input = copytext(sanitize(input(src, "Please specify which mission the strike team shall undertake.", "Specify Mission", "")),1,MAX_MESSAGE_LEN)
input = sanitize(copytext(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

View File

@@ -219,7 +219,7 @@
/obj/effect/landmark/corpse/commander
name = "Commander"
corpseuniform = /obj/item/clothing/under/rank/centcom_commander
corpseuniform = /obj/item/clothing/under/rank/centcom_captain
corpsesuit = /obj/item/clothing/suit/armor/bulletproof
corpseradio = /obj/item/device/radio/headset/heads/captain
corpseglasses = /obj/item/clothing/glasses/eyepatch

View File

@@ -657,7 +657,7 @@ var/global/list/gear_datums = list()
/datum/gear/dress_shoes
display_name = "shoes, dress"
path = /obj/item/clothing/shoes/centcom
path = /obj/item/clothing/shoes/laceup
cost = 1
slot = slot_shoes

View File

@@ -78,7 +78,14 @@
name = "purple beret"
desc = "A stylish, if purple, beret."
icon_state = "purpleberet"
/obj/item/clothing/head/beret/centcom/officer
name = "officers beret"
desc = "A black beret adorned with the shield<6C>a silver kite shield with an engraved sword<72>of the NanoTrasen security forces."
icon_state = "centcomofficerberet"
/obj/item/clothing/head/beret/centcom/captain
name = "captains beret"
desc = "A white beret adorned with the shield<6C>a silver kite shield with an engraved sword<72>of the NanoTrasen security forces."
icon_state = "centcomcaptain"
//Medical
/obj/item/clothing/head/surgery

View File

@@ -61,19 +61,30 @@
item_state = "gy_suit"
item_color = "vice"
/obj/item/clothing/under/rank/centcom_officer
desc = "It's a jumpsuit worn by CentCom Officers."
name = "\improper CentCom officer's jumpsuit"
/obj/item/clothing/under/rank/centcom
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Ensign.\""
name = "\improper NanoTrasen Navy Uniform"
icon_state = "officer"
item_state = "g_suit"
item_color = "officer"
displays_id = 0
/obj/item/clothing/under/rank/centcom_commander
desc = "It's a jumpsuit worn by CentCom's highest-tier Commanders."
name = "\improper CentCom officer's jumpsuit"
/obj/item/clothing/under/rank/centcom_officer
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Lieutenant Commander.\""
name = "\improper NanoTrasen Officers Uniform"
icon_state = "officer"
item_state = "g_suit"
item_color = "officer"
displays_id = 0
/obj/item/clothing/under/rank/centcom_captain
desc = "Gold trim on space-black cloth, this uniform displays the rank of \"Captain.\""
name = "\improper NanoTrasen Captains Uniform"
icon_state = "centcom"
item_state = "dg_suit"
item_color = "centcom"
displays_id = 0
/obj/item/clothing/under/ert
name = "ERT tactical uniform"

View File

@@ -195,12 +195,12 @@
admin_log_and_message_admins("has [report_at_round_end ? "enabled" : "disabled"] the round end event report.")
else if(href_list["dec_timer"])
var/datum/event_container/EC = locate(href_list["event"])
var/decrease = (60 * RaiseToPower(10, text2num(href_list["dec_timer"])))
var/decrease = (60 * 10 ** text2num(href_list["dec_timer"]))
EC.next_event_time -= decrease
admin_log_and_message_admins("decreased timer for [severity_to_string[EC.severity]] events by [decrease/600] minute(s).")
else if(href_list["inc_timer"])
var/datum/event_container/EC = locate(href_list["event"])
var/increase = (60 * RaiseToPower(10, text2num(href_list["inc_timer"])))
var/increase = (60 * 10 ** text2num(href_list["inc_timer"]))
EC.next_event_time += increase
admin_log_and_message_admins("increased timer for [severity_to_string[EC.severity]] events by [increase/600] minute(s).")
else if(href_list["select_event"])

View File

@@ -300,9 +300,9 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
if(checkoutperiod < 1)
checkoutperiod = 1
if(href_list["editbook"])
buffer_book = copytext(sanitize(input("Enter the book's title:") as text|null),1,MAX_MESSAGE_LEN)
buffer_book = sanitize(copytext(input("Enter the book's title:") as text|null,1,MAX_MESSAGE_LEN))
if(href_list["editmob"])
buffer_mob = copytext(sanitize(input("Enter the recipient's name:") as text|null),1,MAX_NAME_LEN)
buffer_mob = sanitize(copytext(input("Enter the recipient's name:") as text|null,1,MAX_NAME_LEN))
if(href_list["checkout"])
var/datum/borrowbook/b = new /datum/borrowbook
b.bookname = sanitize(buffer_book)
@@ -317,7 +317,7 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f
var/obj/item/weapon/book/b = locate(href_list["delbook"])
inventory.Remove(b)
if(href_list["setauthor"])
var/newauthor = copytext(sanitize(input("Enter the author's name: ") as text|null),1,MAX_MESSAGE_LEN)
var/newauthor = sanitize(copytext(input("Enter the author's name: ") as text|null,1,MAX_MESSAGE_LEN))
if(newauthor)
scanner.cache.author = newauthor
if(href_list["setcategory"])

View File

@@ -12,7 +12,7 @@
var/input
if(!message)
input = copytext(sanitize(input(src,"Choose an emote to display.") as text|null),1,MAX_MESSAGE_LEN)
input = sanitize(copytext(input(src,"Choose an emote to display.") as text|null,1,MAX_MESSAGE_LEN))
else
input = message
if(input)
@@ -108,7 +108,7 @@
var/input
if(!message)
input = copytext(sanitize(input(src, "Choose an emote to display.") as text|null), 1, MAX_MESSAGE_LEN)
input = sanitize(copytext(input(src, "Choose an emote to display.") as text|null, 1, MAX_MESSAGE_LEN))
else
input = message

View File

@@ -0,0 +1,149 @@
// MEDICAL SIDE EFFECT BASE
// ========================
/datum/medical_effect
var/name = "None"
var/strength = 0
var/start = 0
var/list/triggers
var/list/cures
var/cure_message
/datum/medical_effect/proc/manifest(mob/living/carbon/human/H)
for(var/R in cures)
if(H.reagents.has_reagent(R))
return 0
for(var/R in triggers)
if(H.reagents.get_reagent_amount(R) >= triggers[R])
return 1
return 0
/datum/medical_effect/proc/on_life(mob/living/carbon/human/H, strength)
return
/datum/medical_effect/proc/cure(mob/living/carbon/human/H)
for(var/R in cures)
if(H.reagents.has_reagent(R))
if (cure_message)
H <<"\blue [cure_message]"
return 1
return 0
// MOB HELPERS
// ===========
/mob/living/carbon/human/var/list/datum/medical_effect/side_effects = list()
/mob/proc/add_side_effect(name, strength = 0)
/mob/living/carbon/human/add_side_effect(name, strength = 0)
for(var/datum/medical_effect/M in src.side_effects)
if(M.name == name)
M.strength = max(M.strength, 10)
M.start = life_tick
return
var/T = side_effects[name]
if (!T)
return
var/datum/medical_effect/M = new T
if(M.name == name)
M.strength = strength
M.start = life_tick
side_effects += M
/mob/living/carbon/human/proc/handle_medical_side_effects()
//Going to handle those things only every few ticks.
if(life_tick % 15 != 0)
return 0
var/list/L = typesof(/datum/medical_effect)-/datum/medical_effect
for(var/T in L)
var/datum/medical_effect/M = new T
if (M.manifest(src))
src.add_side_effect(M.name)
// One full cycle(in terms of strength) every 10 minutes
for (var/datum/medical_effect/M in side_effects)
if (!M) continue
var/strength_percent = sin((life_tick - M.start) / 2)
// Only do anything if the effect is currently strong enough
if(strength_percent >= 0.4)
if (M.cure(src) || M.strength > 50)
side_effects -= M
M = null
else
if(life_tick % 45 == 0)
M.on_life(src, strength_percent*M.strength)
// Effect slowly growing stronger
M.strength+=0.08
// HEADACHE
// ========
/datum/medical_effect/headache
name = "Headache"
triggers = list("cryoxadone" = 10, "bicaridine" = 15, "tricordrazine" = 15)
cures = list("alkysine", "tramadol", "paracetamol", "oxycodone")
cure_message = "Your head stops throbbing..."
/datum/medical_effect/headache/on_life(mob/living/carbon/human/H, strength)
switch(strength)
if(1 to 10)
H.custom_pain("You feel a light pain in your head.",0)
if(11 to 30)
H.custom_pain("You feel a throbbing pain in your head!",1)
if(31 to INFINITY)
H.custom_pain("You feel an excrutiating pain in your head!",1)
// BAD STOMACH
// ===========
/datum/medical_effect/bad_stomach
name = "Bad Stomach"
triggers = list("kelotane" = 30, "dermaline" = 15)
cures = list("anti_toxin")
cure_message = "Your stomach feels a little better now..."
/datum/medical_effect/bad_stomach/on_life(mob/living/carbon/human/H, strength)
switch(strength)
if(1 to 10)
H.custom_pain("You feel a bit light around the stomach.",0)
if(11 to 30)
H.custom_pain("Your stomach hurts.",0)
if(31 to INFINITY)
H.custom_pain("You feel sick.",1)
// CRAMPS
// ======
/datum/medical_effect/cramps
name = "Cramps"
triggers = list("anti_toxin" = 30, "tramadol" = 15)
cures = list("inaprovaline")
cure_message = "The cramps let up..."
/datum/medical_effect/cramps/on_life(mob/living/carbon/human/H, strength)
switch(strength)
if(1 to 10)
H.custom_pain("The muscles in your body hurt a little.",0)
if(11 to 30)
H.custom_pain("The muscles in your body cramp up painfully.",0)
if(31 to INFINITY)
H.emote("me",1,"flinches as all the muscles in their body cramp up.")
H.custom_pain("There's pain all over your body.",1)
// ITCH
// ====
/datum/medical_effect/itch
name = "Itch"
triggers = list("space_drugs" = 10)
cures = list("inaprovaline")
cure_message = "The itching stops..."
/datum/medical_effect/itch/on_life(mob/living/carbon/human/H, strength)
switch(strength)
if(1 to 10)
H.custom_pain("You feel a slight itch.",0)
if(11 to 30)
H.custom_pain("You want to scratch your itch badly.",0)
if(31 to INFINITY)
H.emote("me",1,"shivers slightly.")
H.custom_pain("This itch makes it really hard to concentrate.",1)

View File

@@ -0,0 +1,149 @@
// MEDICAL SIDE EFFECT BASE
// ========================
/datum/medical_effect
var/name = "None"
var/strength = 0
var/start = 0
var/list/triggers
var/list/cures
var/cure_message
/datum/medical_effect/proc/manifest(mob/living/carbon/human/H)
for(var/R in cures)
if(H.reagents.has_reagent(R))
return 0
for(var/R in triggers)
if(H.reagents.get_reagent_amount(R) >= triggers[R])
return 1
return 0
/datum/medical_effect/proc/on_life(mob/living/carbon/human/H, strength)
return
/datum/medical_effect/proc/cure(mob/living/carbon/human/H)
for(var/R in cures)
if(H.reagents.has_reagent(R))
if (cure_message)
H <<"\blue [cure_message]"
return 1
return 0
// MOB HELPERS
// ===========
/mob/living/carbon/human/var/list/datum/medical_effect/side_effects = list()
/mob/proc/add_side_effect(name, strength = 0)
/mob/living/carbon/human/add_side_effect(name, strength = 0)
for(var/datum/medical_effect/M in src.side_effects)
if(M.name == name)
M.strength = max(M.strength, 10)
M.start = life_tick
return
var/T = side_effects[name]
if (!T)
return
var/datum/medical_effect/M = new T
if(M.name == name)
M.strength = strength
M.start = life_tick
side_effects += M
/mob/living/carbon/human/proc/handle_medical_side_effects()
//Going to handle those things only every few ticks.
if(life_tick % 15 != 0)
return 0
var/list/L = typesof(/datum/medical_effect)-/datum/medical_effect
for(var/T in L)
var/datum/medical_effect/M = new T
if (M.manifest(src))
src.add_side_effect(M.name)
// One full cycle(in terms of strength) every 10 minutes
for (var/datum/medical_effect/M in side_effects)
if (!M) continue
var/strength_percent = sin((life_tick - M.start) / 2)
// Only do anything if the effect is currently strong enough
if(strength_percent >= 0.4)
if (M.cure(src) || M.strength > 50)
side_effects -= M
M = null
else
if(life_tick % 45 == 0)
M.on_life(src, strength_percent*M.strength)
// Effect slowly growing stronger
M.strength+=0.08
// HEADACHE
// ========
/datum/medical_effect/headache
name = "Headache"
triggers = list("cryoxadone" = 10, "bicaridine" = 15, "tricordrazine" = 15)
cures = list("alkysine", "tramadol", "paracetamol", "oxycodone")
cure_message = "Your head stops throbbing..."
/datum/medical_effect/headache/on_life(mob/living/carbon/human/H, strength)
switch(strength)
if(1 to 10)
H.custom_pain("You feel a light pain in your head.",0)
if(11 to 30)
H.custom_pain("You feel a throbbing pain in your head!",1)
if(31 to INFINITY)
H.custom_pain("You feel an excrutiating pain in your head!",1)
// BAD STOMACH
// ===========
/datum/medical_effect/bad_stomach
name = "Bad Stomach"
triggers = list("kelotane" = 30, "dermaline" = 15)
cures = list("anti_toxin")
cure_message = "Your stomach feels a little better now..."
/datum/medical_effect/bad_stomach/on_life(mob/living/carbon/human/H, strength)
switch(strength)
if(1 to 10)
H.custom_pain("You feel a bit light around the stomach.",0)
if(11 to 30)
H.custom_pain("Your stomach hurts.",0)
if(31 to INFINITY)
H.custom_pain("You feel sick.",1)
// CRAMPS
// ======
/datum/medical_effect/cramps
name = "Cramps"
triggers = list("anti_toxin" = 30, "tramadol" = 15)
cures = list("inaprovaline")
cure_message = "The cramps let up..."
/datum/medical_effect/cramps/on_life(mob/living/carbon/human/H, strength)
switch(strength)
if(1 to 10)
H.custom_pain("The muscles in your body hurt a little.",0)
if(11 to 30)
H.custom_pain("The muscles in your body cramp up painfully.",0)
if(31 to INFINITY)
H.emote("me",1,"flinches as all the muscles in their body cramp up.")
H.custom_pain("There's pain all over your body.",1)
// ITCH
// ====
/datum/medical_effect/itch
name = "Itch"
triggers = list("space_drugs" = 10)
cures = list("inaprovaline")
cure_message = "The itching stops..."
/datum/medical_effect/itch/on_life(mob/living/carbon/human/H, strength)
switch(strength)
if(1 to 10)
H.custom_pain("You feel a slight itch.",0)
if(11 to 30)
H.custom_pain("You want to scratch your itch badly.",0)
if(31 to INFINITY)
H.emote("me",1,"shivers slightly.")
H.custom_pain("This itch makes it really hard to concentrate.",1)

View File

@@ -50,7 +50,7 @@
m_type = 1
if ("custom")
var/input = copytext(sanitize(input("Choose an emote to display.") as text|null),1,MAX_MESSAGE_LEN)
var/input = sanitize(copytext(input("Choose an emote to display.") as text|null,1,MAX_MESSAGE_LEN))
if (!input)
return
var/input2 = input("Is this a visible or hearable emote?") in list("Visible","Hearable")
@@ -577,7 +577,7 @@
set desc = "Sets a description which will be shown when someone examines you."
set category = "IC"
pose = copytext(sanitize(input(usr, "This is [src]. \He is...", "Pose", null) as text), 1, MAX_MESSAGE_LEN)
pose = sanitize(copytext(input(usr, "This is [src]. \He is...", "Pose", null) as text, 1, MAX_MESSAGE_LEN))
/mob/living/carbon/human/verb/set_flavor()
set name = "Set Flavour Text"

View File

@@ -499,7 +499,7 @@
for (var/datum/data/record/R in data_core.security)
if (R.fields["id"] == E.fields["id"])
if(hasHUD(usr,"security"))
var/t1 = copytext(sanitize(input("Add Comment:", "Sec. records", null, null) as message),1,MAX_MESSAGE_LEN)
var/t1 = sanitize(copytext(input("Add Comment:", "Sec. records", null, null) as message,1,MAX_MESSAGE_LEN))
if ( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"security")) )
return
var/counter = 1
@@ -628,7 +628,7 @@
for (var/datum/data/record/R in data_core.medical)
if (R.fields["id"] == E.fields["id"])
if(hasHUD(usr,"medical"))
var/t1 = copytext(sanitize(input("Add Comment:", "Med. records", null, null) as message),1,MAX_MESSAGE_LEN)
var/t1 = sanitize(copytext(input("Add Comment:", "Med. records", null, null) as message,1,MAX_MESSAGE_LEN))
if ( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"medical")) )
return
var/counter = 1

View File

@@ -175,7 +175,7 @@
text = input("What would you like to say?", "Speak to creature", null, null)
text = trim(copytext(sanitize(text), 1, MAX_MESSAGE_LEN))
text = trim(sanitize(copytext(text, 1, MAX_MESSAGE_LEN)))
if(!text) return
@@ -213,7 +213,7 @@
set desc = "Whisper silently to someone over a distance."
set category = "Abilities"
var/msg = sanitize(input("Message:", "Psychic Whisper") as text|null)
var/msg = sanitize(copytext(input("Message:", "Psychic Whisper") as text|null, 1, MAX_MESSAGE_LEN))
if(msg)
log_say("PsychicWhisper: [key_name(src)]->[M.key] : [msg]")
M << "\green You hear a strange, alien voice in your head... \italic [msg]"

View File

@@ -595,7 +595,7 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
pet.colour = "[M.colour]"
user <<"You feed the slime the potion, removing it's powers and calming it."
del(M)
var/newname = copytext(sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text),1,MAX_NAME_LEN)
var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN))
if (!newname)
newname = "pet slime"
@@ -626,7 +626,7 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
pet.colour = "[M.colour]"
user <<"You feed the slime the potion, removing it's powers and calming it."
del(M)
var/newname = copytext(sanitize(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text),1,MAX_NAME_LEN)
var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN))
if (!newname)
newname = "pet slime"

View File

@@ -58,32 +58,32 @@ var/datum/paiController/paiController // Global handler for pAI candidates
if("name")
t = input("Enter a name for your pAI", "pAI Name", candidate.name) as text
if(t)
candidate.name = copytext(sanitize(t),1,MAX_NAME_LEN)
candidate.name = sanitize(copytext(t,1,MAX_NAME_LEN))
if("desc")
t = input("Enter a description for your pAI", "pAI Description", candidate.description) as message
if(t)
candidate.description = copytext(sanitize(t),1,MAX_MESSAGE_LEN)
candidate.description = sanitize(copytext(t,1,MAX_MESSAGE_LEN))
if("role")
t = input("Enter a role for your pAI", "pAI Role", candidate.role) as text
if(t)
candidate.role = copytext(sanitize(t),1,MAX_MESSAGE_LEN)
candidate.role = sanitize(copytext(t,1,MAX_MESSAGE_LEN))
if("ooc")
t = input("Enter any OOC comments", "pAI OOC Comments", candidate.comments) as message
if(t)
candidate.comments = copytext(sanitize(t),1,MAX_MESSAGE_LEN)
candidate.comments = sanitize(copytext(t,1,MAX_MESSAGE_LEN))
if("save")
candidate.savefile_save(usr)
if("load")
candidate.savefile_load(usr)
//In case people have saved unsanitized stuff.
if(candidate.name)
candidate.name = copytext(sanitize(candidate.name),1,MAX_NAME_LEN)
candidate.name = sanitize(copytext(candidate.name,1,MAX_NAME_LEN))
if(candidate.description)
candidate.description = copytext(sanitize(candidate.description),1,MAX_MESSAGE_LEN)
candidate.description = sanitize(copytext(candidate.description,1,MAX_MESSAGE_LEN))
if(candidate.role)
candidate.role = copytext(sanitize(candidate.role),1,MAX_MESSAGE_LEN)
candidate.role = sanitize(copytext(candidate.role,1,MAX_MESSAGE_LEN))
if(candidate.comments)
candidate.comments = copytext(sanitize(candidate.comments),1,MAX_MESSAGE_LEN)
candidate.comments = sanitize(copytext(candidate.comments,1,MAX_MESSAGE_LEN))
if("submit")
if(candidate)

View File

@@ -226,14 +226,14 @@
set desc = "Sets a description which will be shown when someone examines you."
set category = "IC"
pose = copytext(sanitize(input(usr, "This is [src]. It is...", "Pose", null) as text), 1, MAX_MESSAGE_LEN)
pose = sanitize(copytext(input(usr, "This is [src]. It is...", "Pose", null) as text, 1, MAX_MESSAGE_LEN))
/mob/living/silicon/verb/set_flavor()
set name = "Set Flavour Text"
set desc = "Sets an extended description of your character's features."
set category = "IC"
flavor_text = copytext(sanitize(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text), 1)
flavor_text = sanitize(copytext(input(usr, "Please enter your new flavour text.", "Flavour text", null) as text, 1))
/mob/living/silicon/binarycheck()
return 1
@@ -277,4 +277,4 @@
if (stat != 2)
adjustBruteLoss(30)
updatehealth()
updatehealth()

View File

@@ -305,7 +305,7 @@ proc/slur(phrase)
n_letter = text("[n_letter]-[n_letter]")
t = text("[t][n_letter]")//since the above is ran through for each letter, the text just adds up back to the original word.
p++//for each letter p is increased to find where the next letter will be.
return copytext(sanitize(t),1,MAX_MESSAGE_LEN)
return sanitize(copytext(t,1,MAX_MESSAGE_LEN))
proc/Gibberish(t, p)//t is the inputted message, and any value higher than 70 for p will cause letters to be replaced instead of added
@@ -352,7 +352,7 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
n_letter = text("[n_letter]")
t = text("[t][n_letter]")
p=p+n_mod
return copytext(sanitize(t),1,MAX_MESSAGE_LEN)
return sanitize(copytext(t,1,MAX_MESSAGE_LEN))
/proc/shake_camera(mob/M, duration, strength=1)

View File

@@ -0,0 +1,104 @@
/*
The overmap system allows adding new maps to the big 'galaxy' map.
Idea is that new sectors can be added by just ticking in new maps and recompiling.
Not real hot-plugging, but still pretty modular.
It uses the fact that all ticked in .dme maps are melded together into one as different zlevels.
Metaobjects are used to make it not affected by map order in .dme and carry some additional info.
*************************************************************
Metaobject
*************************************************************
/obj/effect/mapinfo, sectors.dm
Used to build overmap in beginning, has basic information needed to create overmap objects and make shuttles work.
Its name and icon (if non-standard) vars will be applied to resulting overmap object.
'mapy' and 'mapx' vars are optional, sector will be assigned random overmap coordinates if they are not set.
Has two important vars:
obj_type - type of overmap object it spawns. Could be overriden for custom overmap objects.
landing_area - type of area used as inbound shuttle landing, null if no shuttle landing area.
Object could be placed anywhere on zlevel. Should only be placed on zlevel that should appear on overmap as a separate entitety.
Right after creation it sends itself to nullspace and creates an overmap object, corresponding to this zlevel.
*************************************************************
Overmap object
*************************************************************
/obj/effect/map, sectors.dm
Represents a zlevel on the overmap. Spawned by metaobjects at the startup.
var/area/shuttle/shuttle_landing - keeps a reference to the area of where inbound shuttles should land
-CanPass should be overriden for access restrictions
-Crossed/Uncrossed can be overriden for applying custom effects.
Remember to call ..() in children, it updates ship's current sector.
subtype /ship of this object represents spacefaring vessels.
It has 'current_sector' var that keeps refernce to, well, sector ship currently in.
*************************************************************
Helm console
*************************************************************
/obj/machinery/computer/helm, helm.dm
On creation console seeks a ship overmap object corresponding to this zlevel and links it.
Clicking with empty hand on it starts steering, Cancel-Camera-View stops it.
Helm console relays movement of mob to the linked overmap object.
Helm console currently has no interface. All travel happens instanceously too.
Sector shuttles are not supported currently, only ship shuttles.
*************************************************************
Exploration shuttle terminal
*************************************************************
A generic shuttle controller.
Has a var landing_type defining type of area shuttle should be landing at.
On initalizing, checks for a shuttle corresponding to this zlevel, and creates one if it's not there.
Changes desitnation area depending on current sector ship is in.
Currently updating is called in attack_hand(), until a better place is found.
Currently no modifications were made to interface to display availability of landing area in sector.
*************************************************************
Guide to how make new sector
*************************************************************
0.Map
Remember to define shuttle areas if you want sector be accessible via shuttles.
Currently there are no other ways to reach sectors from ships.
In examples, 4x6 shuttle area is used. In case of shuttle area being too big, it will apear in bottom left corner of it.
Remember to put a helm console and engine control console on ship maps.
Ships need engines to move. Currently there are only thermal engines.
Thermal engines are just a unary atmopheric machine, like a vent. They need high-pressure gas input to produce more thrust.
1.Metaobject
All vars needed for it to work could be set directly in map editor, so in most cases you won't have to define new in code.
Remember to set landing_area var for sectors.
2.Overmap object
If you need custom behaviour on entering/leaving this sector, or restricting access to it, you can define your custom map object.
Remember to put this new type into spawn_type var of metaobject.
3.Shuttle console
Remember to place one on the actual shuttle too, or it won't be able to return from sector without ship-side recall.
Remember to set landing_type var to ship-side shuttle area type.
shuttle_tag can be set to custom name (it shows up in console interface)
5.Engines
Actual engines could be any type of machinery, as long as it creates a ship_engine datum for itself.
6.Tick map in and compile.
Sector should appear on overmap (in random place if you didn't set mapx,mapy)
TODO:
shuttle console:
checking occupied pad or not with docking controllers
?landing pad size detection
non-zlevel overmap objects
field generator
meteor fields
speed-based chance for a rock in the ship
debris fields
speed-based chance of
debirs in the ship
a drone
EMP
nebulaes
*/

View File

@@ -0,0 +1,101 @@
//Zlevel where overmap objects should be
#define OVERMAP_ZLEVEL 1
//How far from the edge of overmap zlevel could randomly placed objects spawn
#define OVERMAP_EDGE 7
//list used to track which zlevels are being 'moved' by the proc below
var/list/moving_levels = list()
//Proc to 'move' stars in spess
//yes it looks ugly, but it should only fire when state actually change.
//null direction stops movement
proc/toggle_move_stars(zlevel, direction)
if(!zlevel)
return
var/gen_dir = null
if(direction & (NORTH|SOUTH))
gen_dir += "ns"
else if(direction & (EAST|WEST))
gen_dir += "ew"
if(!direction)
gen_dir = null
if (moving_levels["zlevel"] != gen_dir)
moving_levels["zlevel"] = gen_dir
for(var/turf/space/S in world)
if(S.z == zlevel)
spawn(0)
var/turf/T = S
if(!gen_dir)
T.icon_state = "[((T.x + T.y) ^ ~(T.x * T.y) + T.z) % 25]"
else
T.icon_state = "speedspace_[gen_dir]_[rand(1,15)]"
for(var/atom/movable/AM in T)
if (!AM.anchored)
AM.throw_at(get_step(T,reverse_direction(direction)), 5, 1)
//list used to cache empty zlevels to avoid nedless map bloat
var/list/cached_space = list()
proc/overmap_spacetravel(var/turf/space/T, var/atom/movable/A)
var/obj/effect/map/M = map_sectors["[T.z]"]
if (!M)
return
var/mapx = M.x
var/mapy = M.y
var/nx = 1
var/ny = 1
var/nz = M.map_z
if(T.x <= TRANSITIONEDGE)
nx = world.maxx - TRANSITIONEDGE - 2
ny = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
mapx = max(1, mapx-1)
else if (A.x >= (world.maxx - TRANSITIONEDGE - 1))
nx = TRANSITIONEDGE + 2
ny = rand(TRANSITIONEDGE + 2, world.maxy - TRANSITIONEDGE - 2)
mapx = min(world.maxx, mapx+1)
else if (T.y <= TRANSITIONEDGE)
ny = world.maxy - TRANSITIONEDGE -2
nx = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
mapy = max(1, mapy-1)
else if (A.y >= (world.maxy - TRANSITIONEDGE - 1))
ny = TRANSITIONEDGE + 2
nx = rand(TRANSITIONEDGE + 2, world.maxx - TRANSITIONEDGE - 2)
mapy = min(world.maxy, mapy+1)
testing("[A] moving from [M] ([M.x], [M.y]) to ([mapx],[mapy]).")
var/turf/map = locate(mapx,mapy,OVERMAP_ZLEVEL)
var/obj/effect/map/TM = locate() in map
if(TM)
nz = TM.map_z
testing("Destination: [TM]")
else
if(cached_space.len)
var/obj/effect/map/sector/temporary/cache = cached_space[cached_space.len]
cached_space -= cache
nz = cache.map_z
cache.x = mapx
cache.y = mapy
testing("Destination: *cached* [TM]")
else
world.maxz++
nz = world.maxz
TM = new /obj/effect/map/sector/temporary(mapx, mapy, nz)
testing("Destination: *new* [TM]")
var/turf/dest = locate(nx,ny,nz)
if(dest)
A.loc = dest
if(istype(M, /obj/effect/map/sector/temporary))
var/obj/effect/map/sector/temporary/source = M
if (source.can_die())
testing("Catching [M] for future use")
source.loc = null
cached_space += source

View File

@@ -0,0 +1,124 @@
//===================================================================================
//Hook for building overmap
//===================================================================================
var/global/list/map_sectors = list()
/hook/startup/proc/build_map()
if(!config.use_overmap)
return 1
testing("Building overmap...")
var/obj/effect/mapinfo/data
for(var/level in 1 to world.maxz)
data = locate("sector[level]")
if (data)
testing("Located sector \"[data.name]\" at [data.mapx],[data.mapy] corresponding to zlevel [level]")
map_sectors["[level]"] = new data.obj_type(data)
return 1
//===================================================================================
//Metaobject for storing information about sector this zlevel is representing.
//Should be placed only once on every zlevel.
//===================================================================================
/obj/effect/mapinfo/
name = "map info metaobject"
icon = 'icons/mob/screen1.dmi'
icon_state = "x2"
invisibility = 101
var/obj_type //type of overmap object it spawns
var/landing_area //type of area used as inbound shuttle landing, null if no shuttle landing area
var/zlevel
var/mapx //coordinates on the
var/mapy //overmap zlevel
var/known = 1
/obj/effect/mapinfo/New()
tag = "sector[z]"
zlevel = z
loc = null
/obj/effect/mapinfo/sector
name = "generic sector"
obj_type = /obj/effect/map/sector
/obj/effect/mapinfo/ship
name = "generic ship"
obj_type = /obj/effect/map/ship
//===================================================================================
//Overmap object representing zlevel
//===================================================================================
/obj/effect/map
name = "map object"
icon = 'icons/obj/items.dmi'
icon_state = "sheet-plasteel"
var/map_z = 0
var/area/shuttle/shuttle_landing
var/always_known = 1
/obj/effect/map/New(var/obj/effect/mapinfo/data)
map_z = data.zlevel
name = data.name
always_known = data.known
if (data.icon != 'icons/mob/screen1.dmi')
icon = data.icon
icon_state = data.icon_state
if(data.desc)
desc = data.desc
var/new_x = data.mapx ? data.mapx : rand(OVERMAP_EDGE, world.maxx - OVERMAP_EDGE)
var/new_y = data.mapy ? data.mapy : rand(OVERMAP_EDGE, world.maxy - OVERMAP_EDGE)
loc = locate(new_x, new_y, OVERMAP_ZLEVEL)
if(data.landing_area)
shuttle_landing = locate(data.landing_area)
/obj/effect/map/CanPass(atom/movable/A)
testing("[A] attempts to enter sector\"[name]\"")
return 1
/obj/effect/map/Crossed(atom/movable/A)
testing("[A] has entered sector\"[name]\"")
if (istype(A,/obj/effect/map/ship))
var/obj/effect/map/ship/S = A
S.current_sector = src
/obj/effect/map/Uncrossed(atom/movable/A)
testing("[A] has left sector\"[name]\"")
if (istype(A,/obj/effect/map/ship))
var/obj/effect/map/ship/S = A
S.current_sector = null
/obj/effect/map/sector
name = "generic sector"
desc = "Sector with some stuff in it."
anchored = 1
//Space stragglers go here
/obj/effect/map/sector/temporary
name = "Deep Space"
icon_state = ""
always_known = 0
/obj/effect/map/sector/temporary/New(var/nx, var/ny, var/nz)
loc = locate(nx, ny, OVERMAP_ZLEVEL)
map_z = nz
map_sectors["[map_z]"] = src
testing("Temporary sector at [x],[y] was created, corresponding zlevel is [map_z].")
/obj/effect/map/sector/temporary/Del()
map_sectors["[map_z]"] = null
testing("Temporary sector at [x],[y] was deleted.")
if (can_die())
testing("Associated zlevel disappeared.")
world.maxz--
/obj/effect/map/sector/temporary/proc/can_die(var/mob/observer)
testing("Checking if sector at [map_z] can die.")
for(var/mob/M in player_list)
if(M != observer && M.z == map_z)
testing("There are people on it.")
return 0
return 1

View File

@@ -0,0 +1,99 @@
//Engine control and monitoring console
/obj/machinery/computer/engines
name = "engine control console"
icon_state = "id"
var/state = "status"
var/list/engines = list()
var/obj/effect/map/ship/linked
/obj/machinery/computer/engines/initialize()
linked = map_sectors["[z]"]
if (linked)
if (!linked.eng_control)
linked.eng_control = src
testing("Engines console at level [z] found a corresponding overmap object '[linked.name]'.")
else
testing("Engines console at level [z] was unable to find a corresponding overmap object.")
for(var/datum/ship_engine/E in engines)
if (E.zlevel == z && !(E in engines))
engines += E
/obj/machinery/computer/engines/attack_hand(var/mob/user as mob)
if(..())
user.unset_machine()
return
if(!isAI(user))
user.set_machine(src)
ui_interact(user)
/obj/machinery/computer/engines/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
if(!linked)
return
var/data[0]
data["state"] = state
var/list/enginfo[0]
for(var/datum/ship_engine/E in engines)
var/list/rdata[0]
rdata["eng_type"] = E.name
rdata["eng_on"] = E.is_on()
rdata["eng_thrust"] = E.get_thrust()
rdata["eng_thrust_limiter"] = round(E.get_thrust_limit()*100)
rdata["eng_status"] = E.get_status()
rdata["eng_reference"] = "\ref[E]"
enginfo.Add(list(rdata))
data["engines_info"] = enginfo
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "engines_control.tmpl", "[linked.name] Engines Control", 380, 530)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/computer/engines/Topic(href, href_list)
if(..())
return
if(href_list["state"])
state = href_list["state"]
if(href_list["engine"])
if(href_list["set_limit"])
var/datum/ship_engine/E = locate(href_list["engine"])
var/newlim = input("Input new thrust limit (0..100)", "Thrust limit", E.get_thrust_limit()) as num
var/limit = Clamp(newlim/100, 0, 1)
if(E)
E.set_thrust_limit(limit)
if(href_list["limit"])
var/datum/ship_engine/E = locate(href_list["engine"])
var/limit = Clamp(E.get_thrust_limit() + text2num(href_list["limit"]), 0, 1)
if(E)
E.set_thrust_limit(limit)
if(href_list["toggle"])
var/datum/ship_engine/E = locate(href_list["engine"])
if(E)
E.toggle()
add_fingerprint(usr)
updateUsrDialog()
/obj/machinery/computer/engines/proc/burn()
if(engines.len == 0)
return 0
var/res = 0
for(var/datum/ship_engine/E in engines)
res |= E.burn()
return res
/obj/machinery/computer/engines/proc/get_total_thrust()
for(var/datum/ship_engine/E in engines)
. += E.get_thrust()

View File

@@ -0,0 +1,174 @@
/obj/machinery/computer/helm
name = "helm control console"
icon_state = "id"
var/state = "status"
var/obj/effect/map/ship/linked //connected overmap object
var/autopilot = 0
var/manual_control = 0
var/list/known_sectors = list()
var/dx //desitnation
var/dy //coordinates
/obj/machinery/computer/helm/initialize()
linked = map_sectors["[z]"]
if (linked)
if(!linked.nav_control)
linked.nav_control = src
testing("Helm console at level [z] found a corresponding overmap object '[linked.name]'.")
else
testing("Helm console at level [z] was unable to find a corresponding overmap object.")
for(var/level in map_sectors)
var/obj/effect/map/sector/S = map_sectors["[level]"]
if (istype(S) && S.always_known)
var/datum/data/record/R = new()
R.fields["name"] = S.name
R.fields["x"] = S.x
R.fields["y"] = S.y
known_sectors += R
/obj/machinery/computer/helm/process()
..()
if (autopilot && dx && dy)
var/turf/T = locate(dx,dy,1)
if(linked.loc == T)
if(linked.is_still())
autopilot = 0
else
linked.decelerate()
var/brake_path = linked.get_brake_path()
if(get_dist(linked.loc, T) > brake_path)
linked.accelerate(get_dir(linked.loc, T))
else
linked.decelerate()
return
/obj/machinery/computer/helm/relaymove(var/mob/user, direction)
if(manual_control && linked)
linked.relaymove(user,direction)
return 1
/obj/machinery/computer/helm/check_eye(var/mob/user as mob)
if (!manual_control)
return null
if (!get_dist(user, src) > 1 || user.blinded || !linked )
return null
user.reset_view(linked)
return 1
/obj/machinery/computer/helm/attack_hand(var/mob/user as mob)
if(..())
user.unset_machine()
manual_control = 0
return
if(!isAI(user))
user.set_machine(src)
ui_interact(user)
/obj/machinery/computer/helm/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
if(!linked)
return
var/data[0]
data["state"] = state
data["sector"] = linked.current_sector ? linked.current_sector.name : "Deep Space"
data["sector_info"] = linked.current_sector ? linked.current_sector.desc : "Not Available"
data["s_x"] = linked.x
data["s_y"] = linked.y
data["dest"] = dy && dx
data["d_x"] = dx
data["d_y"] = dy
data["speed"] = linked.get_speed()
data["accel"] = round(linked.get_acceleration())
data["heading"] = linked.get_heading() ? dir2angle(linked.get_heading()) : 0
data["autopilot"] = autopilot
data["manual_control"] = manual_control
var/list/locations[0]
for (var/datum/data/record/R in known_sectors)
var/list/rdata[0]
rdata["name"] = R.fields["name"]
rdata["x"] = R.fields["x"]
rdata["y"] = R.fields["y"]
rdata["reference"] = "\ref[R]"
locations.Add(list(rdata))
data["locations"] = locations
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "helm.tmpl", "[linked.name] Helm Control", 380, 530)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/computer/helm/Topic(href, href_list)
if(..())
return
if (!linked)
return
if (href_list["add"])
var/datum/data/record/R = new()
var/sec_name = input("Input naviation entry name", "New navigation entry", "Sector #[known_sectors.len]") as text
if(!sec_name)
sec_name = "Sector #[known_sectors.len]"
R.fields["name"] = sec_name
switch(href_list["add"])
if("current")
R.fields["x"] = linked.x
R.fields["y"] = linked.y
if("new")
var/newx = input("Input new entry x coordinate", "Coordinate input", linked.x) as num
R.fields["x"] = Clamp(newx, 1, world.maxx)
var/newy = input("Input new entry y coordinate", "Coordinate input", linked.y) as num
R.fields["y"] = Clamp(newy, 1, world.maxy)
known_sectors += R
if (href_list["remove"])
var/datum/data/record/R = locate(href_list["remove"])
known_sectors.Remove(R)
if (href_list["setx"])
var/newx = input("Input new destiniation x coordinate", "Coordinate input", dx) as num|null
if (newx)
dx = Clamp(newx, 1, world.maxx)
if (href_list["sety"])
var/newy = input("Input new destiniation y coordinate", "Coordinate input", dy) as num|null
if (newy)
dy = Clamp(newy, 1, world.maxy)
if (href_list["x"] && href_list["y"])
dx = text2num(href_list["x"])
dy = text2num(href_list["y"])
if (href_list["reset"])
dx = 0
dy = 0
if (href_list["move"])
var/ndir = text2num(href_list["move"])
linked.relaymove(usr, ndir)
if (href_list["brake"])
linked.decelerate()
if (href_list["apilot"])
autopilot = !autopilot
if (href_list["manual"])
manual_control = !manual_control
if (href_list["state"])
state = href_list["state"]
add_fingerprint(usr)
updateUsrDialog()

View File

@@ -0,0 +1,139 @@
//Shuttle controller computer for shuttles going between sectors
/datum/shuttle/ferry/var/range = 0 //how many overmap tiles can shuttle go, for picking destinatiosn and returning.
/obj/machinery/computer/shuttle_control/explore
name = "exploration shuttle console"
shuttle_tag = "Exploration"
req_access = list()
var/landing_type //area for shuttle ship-side
var/obj/effect/map/destination //current destination
var/obj/effect/map/home //current destination
/obj/machinery/computer/shuttle_control/explore/initialize()
..()
home = map_sectors["[z]"]
shuttle_tag = "[shuttle_tag]-[z]"
if(!shuttle_controller.shuttles[shuttle_tag])
var/datum/shuttle/ferry/shuttle = new()
shuttle.warmup_time = 10
shuttle.area_station = locate(landing_type)
shuttle.area_offsite = shuttle.area_station
shuttle_controller.shuttles[shuttle_tag] = shuttle
shuttle_controller.process_shuttles += shuttle
testing("Exploration shuttle '[shuttle_tag]' at zlevel [z] successfully added.")
//Sets destination to new sector. Can be null.
/obj/machinery/computer/shuttle_control/explore/proc/update_destination(var/obj/effect/map/D)
destination = D
if(destination && shuttle_controller.shuttles[shuttle_tag])
var/datum/shuttle/ferry/shuttle = shuttle_controller.shuttles[shuttle_tag]
shuttle.area_offsite = destination.shuttle_landing
testing("Shuttle controller [shuttle_tag] now sends shuttle to [destination]")
shuttle_controller.shuttles[shuttle_tag] = shuttle
//Gets all sectors with landing zones in shuttle's range
/obj/machinery/computer/shuttle_control/explore/proc/get_possible_destinations()
var/list/res = list()
var/datum/shuttle/ferry/shuttle = shuttle_controller.shuttles[shuttle_tag]
for (var/obj/effect/map/S in orange(shuttle.range, home))
if(S.shuttle_landing)
res += S
return res
//Checks if current destination is still reachable
/obj/machinery/computer/shuttle_control/explore/proc/check_destination()
var/datum/shuttle/ferry/shuttle = shuttle_controller.shuttles[shuttle_tag]
return shuttle && destination && get_dist(home, destination) <= shuttle.range
/obj/machinery/computer/shuttle_control/explore/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
var/datum/shuttle/ferry/shuttle = shuttle_controller.shuttles[shuttle_tag]
if (!istype(shuttle))
return
//If we are already there, or can't reach place anymore, reset destination
if(!shuttle.location && !check_destination())
destination = null
//check if shuttle can fly at all
var/can_go = !isnull(destination)
var/current_destination = destination ? destination.name : "None"
//shuttle doesn't need destination set to return home, as long as it's in range.
if(shuttle.location)
current_destination = "Return"
var/area/offsite = shuttle.area_offsite
var/obj/effect/map/cur_loc = map_sectors["[offsite.z]"]
can_go = (get_dist(home,cur_loc) <= shuttle.range)
//disable picking locations if there are none, or shuttle is already off-site
var/list/possible_d = get_possible_destinations()
var/can_pick = !shuttle.location && possible_d.len
var/shuttle_state
switch(shuttle.moving_status)
if(SHUTTLE_IDLE) shuttle_state = "idle"
if(SHUTTLE_WARMUP) shuttle_state = "warmup"
if(SHUTTLE_INTRANSIT) shuttle_state = "in_transit"
var/shuttle_status
switch (shuttle.process_state)
if(IDLE_STATE)
if (shuttle.in_use)
shuttle_status = "Busy."
else if (!shuttle.location)
shuttle_status = "Standing-by at station."
else
shuttle_status = "Standing-by at offsite location."
if(WAIT_LAUNCH, FORCE_LAUNCH)
shuttle_status = "Shuttle has recieved command and will depart shortly."
if(WAIT_ARRIVE)
shuttle_status = "Proceeding to destination."
if(WAIT_FINISH)
shuttle_status = "Arriving at destination now."
data = list(
"destination_name" = current_destination,
"can_pick" = can_pick,
"shuttle_status" = shuttle_status,
"shuttle_state" = shuttle_state,
"has_docking" = shuttle.docking_controller? 1 : 0,
"docking_status" = shuttle.docking_controller? shuttle.docking_controller.get_docking_status() : null,
"docking_override" = shuttle.docking_controller? shuttle.docking_controller.override_enabled : null,
"can_launch" = can_go && shuttle.can_launch(),
"can_cancel" = can_go && shuttle.can_cancel(),
"can_force" = can_go && shuttle.can_force(),
)
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "shuttle_control_console_exploration.tmpl", "[shuttle_tag] Shuttle Control", 470, 310)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(1)
/obj/machinery/computer/shuttle_control/explore/Topic(href, href_list)
if(..())
return
usr.set_machine(src)
src.add_fingerprint(usr)
var/datum/shuttle/ferry/shuttle = shuttle_controller.shuttles[shuttle_tag]
if (!istype(shuttle))
return
if(href_list["pick"])
var/obj/effect/map/self = map_sectors["[z]"]
if(self)
var/list/possible_d = get_possible_destinations()
var/obj/effect/map/D
if(possible_d.len)
D = input("Choose shuttle destination", "Shuttle Destination") as null|anything in possible_d
update_destination(D)
if(href_list["move"])
shuttle.launch(src)
if(href_list["force"])
shuttle.force_launch(src)
else if(href_list["cancel"])
shuttle.cancel_launch(src)

View File

@@ -0,0 +1,60 @@
//Engine component object
var/list/ship_engines = list()
/datum/ship_engine
var/name = "ship engine"
var/obj/machinery/engine //actual engine object
var/zlevel = 0
/datum/ship_engine/New(var/obj/machinery/holder)
engine = holder
zlevel = holder.z
for(var/obj/machinery/computer/engines/E in machines)
if (E.z == zlevel && !(src in E.engines))
E.engines += src
break
//Tries to fire the engine. If successfull, returns 1
/datum/ship_engine/proc/burn()
if(!engine)
die()
return 1
//Returns status string for this engine
/datum/ship_engine/proc/get_status()
if(!engine)
die()
return "All systems nominal"
/datum/ship_engine/proc/get_thrust()
if(!engine)
die()
return 100
//Sets thrust limiter, a number between 0 and 1
/datum/ship_engine/proc/set_thrust_limit(var/new_limit)
if(!engine)
die()
return 1
/datum/ship_engine/proc/get_thrust_limit()
if(!engine)
die()
return 1
/datum/ship_engine/proc/is_on()
if(!engine)
die()
return 1
/datum/ship_engine/proc/toggle()
if(!engine)
die()
return 1
/datum/ship_engine/proc/die()
for(var/obj/machinery/computer/engines/E in machines)
if (E.z == zlevel)
E.engines -= src
break
del(src)

View File

@@ -0,0 +1,99 @@
//Thermal nozzle engine
/datum/ship_engine/thermal
name = "thermal engine"
/datum/ship_engine/thermal/get_status()
..()
var/obj/machinery/atmospherics/unary/engine/E = engine
return "Fuel pressure: [E.air_contents.return_pressure()]"
/datum/ship_engine/thermal/get_thrust()
..()
var/obj/machinery/atmospherics/unary/engine/E = engine
if(!is_on())
return 0
var/pressurized_coef = E.air_contents.return_pressure()/E.effective_pressure
return round(E.thrust_limit * E.nominal_thrust * pressurized_coef)
/datum/ship_engine/thermal/burn()
..()
var/obj/machinery/atmospherics/unary/engine/E = engine
return E.burn()
/datum/ship_engine/thermal/set_thrust_limit(var/new_limit)
..()
var/obj/machinery/atmospherics/unary/engine/E = engine
E.thrust_limit = new_limit
/datum/ship_engine/thermal/get_thrust_limit()
..()
var/obj/machinery/atmospherics/unary/engine/E = engine
return E.thrust_limit
/datum/ship_engine/thermal/is_on()
..()
var/obj/machinery/atmospherics/unary/engine/E = engine
return E.on
/datum/ship_engine/thermal/toggle()
..()
var/obj/machinery/atmospherics/unary/engine/E = engine
E.on = !E.on
//Actual thermal nozzle engine object
/obj/machinery/atmospherics/unary/engine
name = "engine nozzle"
desc = "Simple thermal nozzle, uses heated gast to propell the ship."
icon = 'icons/obj/ship_engine.dmi'
icon_state = "nozzle"
var/on = 1
var/thrust_limit = 1 //Value between 1 and 0 to limit the resulting thrust
var/nominal_thrust = 3000
var/effective_pressure = 3000
var/datum/ship_engine/thermal/controller
/obj/machinery/atmospherics/unary/engine/initialize()
..()
controller = new(src)
/obj/machinery/atmospherics/unary/engine/Del()
..()
controller.die()
/obj/machinery/atmospherics/unary/engine/proc/burn()
if (!on)
return
if(air_contents.temperature > 0)
var/transfer_moles = 100 * air_contents.volume/max(air_contents.temperature * R_IDEAL_GAS_EQUATION, 0,01)
transfer_moles = round(thrust_limit * transfer_moles, 0.01)
if(transfer_moles > air_contents.total_moles)
on = !on
return 0
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
loc.assume_air(removed)
if(air_contents.temperature > PHORON_MINIMUM_BURN_TEMPERATURE)
var/exhaust_dir = reverse_direction(dir)
var/turf/T = get_step(src,exhaust_dir)
if(T)
new/obj/effect/engine_exhaust(T,exhaust_dir,air_contents.temperature)
return 1
//Exhaust effect
/obj/effect/engine_exhaust
name = "engine exhaust"
icon = 'icons/effects/effects.dmi'
icon_state = "exhaust"
anchored = 1
New(var/turf/nloc, var/ndir, var/temp)
set_dir(ndir)
..(nloc)
if(nloc)
nloc.hotspot_expose(temp,125)
spawn(20)
loc = null

View File

@@ -0,0 +1,106 @@
/obj/effect/map/ship
name = "generic ship"
desc = "Space faring vessel."
icon_state = "sheet-sandstone"
var/vessel_mass = 9000 //tonnes, random number
var/default_delay = 60
var/list/speed = list(0,0)
var/last_burn = 0
var/list/last_movement = list(0,0)
var/fore_dir = NORTH
var/obj/effect/map/current_sector
var/obj/machinery/computer/helm/nav_control
var/obj/machinery/computer/engines/eng_control
/obj/effect/map/ship/initialize()
for(var/obj/machinery/computer/engines/E in machines)
if (E.z == map_z)
eng_control = E
break
for(var/obj/machinery/computer/helm/H in machines)
if (H.z == map_z)
nav_control = H
break
processing_objects.Add(src)
/obj/effect/map/ship/relaymove(mob/user, direction)
accelerate(direction)
/obj/effect/map/ship/proc/is_still()
return !(speed[1] || speed[2])
/obj/effect/map/ship/proc/get_acceleration()
return eng_control.get_total_thrust()/vessel_mass
/obj/effect/map/ship/proc/get_speed()
return round(sqrt(speed[1]*speed[1] + speed[2]*speed[2]))
/obj/effect/map/ship/proc/get_heading()
var/res = 0
if(speed[1])
if(speed[1] > 0)
res |= EAST
else
res |= WEST
if(speed[2])
if(speed[2] > 0)
res |= NORTH
else
res |= SOUTH
return res
/obj/effect/map/ship/proc/adjust_speed(n_x, n_y)
speed[1] = Clamp(speed[1] + n_x, -default_delay, default_delay)
speed[2] = Clamp(speed[2] + n_y, -default_delay, default_delay)
if(is_still())
toggle_move_stars(map_z)
else
toggle_move_stars(map_z, fore_dir)
/obj/effect/map/ship/proc/can_burn()
if (!eng_control)
return 0
if (world.time < last_burn + 10)
return 0
if (!eng_control.burn())
return 0
return 1
/obj/effect/map/ship/proc/get_brake_path()
if(!get_acceleration())
return INFINITY
return max(abs(speed[1]),abs(speed[2]))/get_acceleration()
#define SIGN(X) (X == 0 ? 0 : (X > 0 ? 1 : -1))
/obj/effect/map/ship/proc/decelerate()
if(!is_still() && can_burn())
if (speed[1])
adjust_speed(-SIGN(speed[1]) * min(get_acceleration(),speed[1]), 0)
if (speed[2])
adjust_speed(0, -SIGN(speed[2]) * min(get_acceleration(),speed[2]))
last_burn = world.time
/obj/effect/map/ship/proc/accelerate(direction)
if(can_burn())
last_burn = world.time
if(direction & EAST)
adjust_speed(get_acceleration(), 0)
if(direction & WEST)
adjust_speed(-get_acceleration(), 0)
if(direction & NORTH)
adjust_speed(0, get_acceleration())
if(direction & SOUTH)
adjust_speed(0, -get_acceleration())
/obj/effect/map/ship/process()
if(!is_still())
var/list/deltas = list(0,0)
for(var/i=1, i<=2, i++)
if(speed[i] && world.time > last_movement[i] + default_delay - speed[i])
deltas[i] = speed[i] > 0 ? 1 : -1
last_movement[i] = world.time
var/turf/newloc = locate(x + deltas[1], y + deltas[2], z)
if(newloc)
Move(newloc)

View File

@@ -35,7 +35,7 @@
user << "<span class='notice'>You put the [W] into \the [src].</span>"
update_icon()
else if(istype(W, /obj/item/weapon/pen))
var/n_name = copytext(sanitize(input(usr, "What would you like to label the folder?", "Folder Labelling", null) as text), 1, MAX_NAME_LEN)
var/n_name = sanitize(copytext(input(usr, "What would you like to label the folder?", "Folder Labelling", null) as text, 1, MAX_NAME_LEN))
if((loc == usr && usr.stat == 0))
name = "folder[(n_name ? text("- '[n_name]'") : null)]"
return

View File

@@ -86,7 +86,7 @@
if((CLUMSY in usr.mutations) && prob(50))
usr << "<span class='warning'>You cut yourself on the paper.</span>"
return
var/n_name = copytext(sanitize(input(usr, "What would you like to label the paper?", "Paper Labelling", null) as text), 1, MAX_NAME_LEN)
var/n_name = sanitize(copytext(input(usr, "What would you like to label the paper?", "Paper Labelling", null) as text, 1, MAX_NAME_LEN))
if((loc == usr && usr.stat == 0))
name = "[(n_name ? text("[n_name]") : initial(name))]"
if(name != "paper")

View File

@@ -192,7 +192,7 @@
set category = "Object"
set src in usr
var/n_name = copytext(sanitize(input(usr, "What would you like to label the bundle?", "Bundle Labelling", null) as text), 1, MAX_NAME_LEN)
var/n_name = sanitize(copytext(input(usr, "What would you like to label the bundle?", "Bundle Labelling", null) as text, 1, MAX_NAME_LEN))
if((loc == usr && usr.stat == 0))
name = "[(n_name ? text("[n_name]") : "paper")]"
add_fingerprint(usr)

View File

@@ -43,8 +43,7 @@ var/global/photo_count = 0
/obj/item/weapon/photo/attackby(obj/item/weapon/P as obj, mob/user as mob)
if(istype(P, /obj/item/weapon/pen) || istype(P, /obj/item/toy/crayon))
var/txt = sanitize(input(user, "What would you like to write on the back?", "Photo Writing", null) as text)
txt = copytext(txt, 1, 128)
var/txt = sanitize(copytext(input(user, "What would you like to write on the back?", "Photo Writing", null) as text, 1, 128))
if(loc == user && user.stat == 0)
scribble = txt
..()
@@ -71,7 +70,7 @@ var/global/photo_count = 0
set category = "Object"
set src in usr
var/n_name = copytext(sanitize(input(usr, "What would you like to label the photo?", "Photo Labelling", null) as text), 1, MAX_NAME_LEN)
var/n_name = sanitize(copytext(input(usr, "What would you like to label the photo?", "Photo Labelling", null) as text, 1, MAX_NAME_LEN))
//loc.loc check is for making possible renaming photos in clipboards
if(( (loc == usr || (loc.loc && loc.loc == usr)) && usr.stat == 0))
name = "[(n_name ? text("[n_name]") : "photo")]"

View File

@@ -0,0 +1,70 @@
//reactor areas
/area/engine
icon_state = "engine"
fore
name = "\improper Fore"
construction_storage
name = "\improper Construction storage"
atmos_storage
name = "\improper Atmos storage"
icon_state = "engine_storage"
control
name = "\improper Control"
icon_state = "engine_control"
electrical_storage
name = "\improper Electrical storage"
reactor_core
name = "\improper Reactor Core"
//icon_state = "engine_core"
reactor_gas
name = "Reactor Gas Storage"
//icon_state = "engine_atmos"
aux_control
name = "Reactor Auxiliary Control"
//icon_state = "engine_aux"
turbine_control
name = "Turbine Control"
//icon_state = "engine_turbine"
reactor_airlock
name = "\improper Reactor Primary Entrance"
//icon_state = "engine_airlock"
reactor_fuel_storage
name = "Reactor Fuel Storage"
//icon_state = "engine_fuel"
reactor_fuel_ports
name = "\improper Reactor Fuel Ports"
//icon_state = "engine_port"
generators
name = "\improper Generator Room"
//icon_state = "engine_generators"
port_gyro_bay
name = "\improper Port Gyrotron Bay"
//icon_state = "engine_starboardgyro"
starboard_gyro_bay
name = "\improper Starboard Gyrotron Bay"
//icon_state = "engine_portgyro"
storage
name = "\improper Engineering Storage"
icon_state = "engine_storage"
storage_hard
name = "\improper Engineering Hard Storage"
icon_state = "engine_storage"

View File

@@ -0,0 +1,120 @@
#define IMPRINTER 1 //For circuits. Uses glass/chemicals.
//////////////////////////////////////
// RUST Core Control computer
/obj/item/weapon/circuitboard/rust_core_control
name = "Circuit board (RUST core controller)"
build_path = "/obj/machinery/computer/rust_core_control"
origin_tech = "programming=4;engineering=4"
datum/design/rust_core_control
name = "Circuit Design (RUST core controller)"
desc = "Allows for the construction of circuit boards used to build a core control console for the RUST fusion engine."
id = "rust_core_control"
req_tech = list("programming" = 4, "engineering" = 4)
build_type = IMPRINTER
materials = list("$glass" = 2000, "sacid" = 20)
build_path = "/obj/item/weapon/circuitboard/rust_core_control"
//////////////////////////////////////
// RUST Fuel Control computer
/obj/item/weapon/circuitboard/rust_fuel_control
name = "Circuit board (RUST fuel controller)"
build_path = "/obj/machinery/computer/rust_fuel_control"
origin_tech = "programming=4;engineering=4"
datum/design/rust_fuel_control
name = "Circuit Design (RUST fuel controller)"
desc = "Allows for the construction of circuit boards used to build a fuel injector control console for the RUST fusion engine."
id = "rust_fuel_control"
req_tech = list("programming" = 4, "engineering" = 4)
build_type = IMPRINTER
materials = list("$glass" = 2000, "sacid" = 20)
build_path = "/obj/item/weapon/circuitboard/rust_fuel_control"
//////////////////////////////////////
// RUST Fuel Port board
/obj/item/weapon/module/rust_fuel_port
name = "Internal circuitry (RUST fuel port)"
icon_state = "card_mod"
origin_tech = "engineering=4;materials=5"
datum/design/rust_fuel_port
name = "Internal circuitry (RUST fuel port)"
desc = "Allows for the construction of circuit boards used to build a fuel injection port for the RUST fusion engine."
id = "rust_fuel_port"
req_tech = list("engineering" = 4, "materials" = 5)
build_type = IMPRINTER
materials = list("$glass" = 2000, "sacid" = 20, "$uranium" = 3000)
build_path = "/obj/item/weapon/module/rust_fuel_port"
//////////////////////////////////////
// RUST Fuel Compressor board
/obj/item/weapon/module/rust_fuel_compressor
name = "Internal circuitry (RUST fuel compressor)"
icon_state = "card_mod"
origin_tech = "materials=6;phorontech=4"
datum/design/rust_fuel_compressor
name = "Circuit Design (RUST fuel compressor)"
desc = "Allows for the construction of circuit boards used to build a fuel compressor of the RUST fusion engine."
id = "rust_fuel_compressor"
req_tech = list("materials" = 6, "phorontech" = 4)
build_type = IMPRINTER
materials = list("$glass" = 2000, "sacid" = 20, "$phoron" = 3000, "$diamond" = 1000)
build_path = "/obj/item/weapon/module/rust_fuel_compressor"
//////////////////////////////////////
// RUST Tokamak Core board
/obj/item/weapon/circuitboard/rust_core
name = "Internal circuitry (RUST tokamak core)"
build_path = "/obj/machinery/power/rust_core"
board_type = "machine"
origin_tech = "bluespace=3;phorontech=4;magnets=5;powerstorage=6"
frame_desc = "Requires 2 Pico Manipulators, 1 Ultra Micro-Laser, 5 Pieces of Cable, 1 Subspace Crystal and 1 Console Screen."
req_components = list(
"/obj/item/weapon/stock_parts/manipulator/pico" = 2,
"/obj/item/weapon/stock_parts/micro_laser/ultra" = 1,
"/obj/item/weapon/stock_parts/subspace/crystal" = 1,
"/obj/item/weapon/stock_parts/console_screen" = 1,
"/obj/item/stack/cable_coil" = 5)
datum/design/rust_core
name = "Internal circuitry (RUST tokamak core)"
desc = "The circuit board that for a RUST-pattern tokamak fusion core."
id = "pacman"
req_tech = list(bluespace = 3, phorontech = 4, magnets = 5, powerstorage = 6)
build_type = IMPRINTER
reliability_base = 79
materials = list("$glass" = 2000, "sacid" = 20, "$phoron" = 3000, "$diamond" = 2000)
build_path = "/obj/item/weapon/circuitboard/rust_core"
//////////////////////////////////////
// RUST Fuel Injector board
/obj/item/weapon/circuitboard/rust_injector
name = "Internal circuitry (RUST fuel injector)"
build_path = "/obj/machinery/power/rust_fuel_injector"
board_type = "machine"
origin_tech = "powerstorage=3;engineering=4;phorontech=4;materials=6"
frame_desc = "Requires 2 Pico Manipulators, 1 Phasic Scanning Module, 1 Super Matter Bin, 1 Console Screen and 5 Pieces of Cable."
req_components = list(
"/obj/item/weapon/stock_parts/manipulator/pico" = 2,
"/obj/item/weapon/stock_parts/scanning_module/phasic" = 1,
"/obj/item/weapon/stock_parts/matter_bin/super" = 1,
"/obj/item/weapon/stock_parts/console_screen" = 1,
"/obj/item/stack/cable_coil" = 5)
datum/design/rust_injector
name = "Internal circuitry (RUST tokamak core)"
desc = "The circuit board that for a RUST-pattern particle accelerator."
id = "pacman"
req_tech = list(powerstorage = 3, engineering = 4, phorontech = 4, materials = 6)
build_type = IMPRINTER
reliability_base = 79
materials = list("$glass" = 2000, "sacid" = 20, "$phoron" = 3000, "$uranium" = 2000)
build_path = "/obj/item/weapon/circuitboard/rust_core"

View File

@@ -0,0 +1,143 @@
/obj/machinery/computer/rust_core_control
name = "RUST Core Control"
icon = 'icons/rust.dmi'
icon_state = "core_control"
var/list/connected_devices = list()
var/id_tag = "allan remember to update this before you leave"
var/scan_range = 25
//currently viewed
var/obj/machinery/power/rust_core/cur_viewed_device
/obj/machinery/computer/rust_core_control/process()
if(stat & (BROKEN|NOPOWER))
return
/obj/machinery/computer/rust_core_control/attack_ai(mob/user)
attack_hand(user)
/obj/machinery/computer/rust_core_control/attack_hand(mob/user)
add_fingerprint(user)
interact(user)
/obj/machinery/computer/rust_core_control/interact(mob/user)
if(stat & BROKEN)
user.unset_machine()
user << browse(null, "window=core_control")
return
if (!istype(user, /mob/living/silicon) && (get_dist(src, user) > 1 ))
user.unset_machine()
user << browse(null, "window=core_control")
return
var/dat = ""
if(stat & NOPOWER)
dat += "<i>The console is dark and nonresponsive.</i>"
else
dat += "<B>Reactor Core Primary Monitor</B><BR>"
if(cur_viewed_device && cur_viewed_device.stat & (BROKEN|NOPOWER))
cur_viewed_device = null
if(cur_viewed_device && !cur_viewed_device.remote_access_enabled)
cur_viewed_device = null
if(cur_viewed_device)
dat += "<b>Device tag:</b> [cur_viewed_device.id_tag ? cur_viewed_device.id_tag : "UNSET"]<br>"
dat += "<font color=blue>Device [cur_viewed_device.owned_field ? "activated" : "deactivated"].</font><br>"
dat += "<a href='?src=\ref[cur_viewed_device];extern_update=\ref[src];toggle_active=1'>\[Bring field [cur_viewed_device.owned_field ? "offline" : "online"]\]</a><br>"
dat += "<b>Device [cur_viewed_device.anchored ? "secured" : "unsecured"].</b><br>"
dat += "<hr>"
dat += "<b>Field encumbrance:</b> [cur_viewed_device.owned_field ? 0 : "NA"]<br>"
dat += "<b>Field strength:</b> [cur_viewed_device.field_strength] Wm^3<br>"
dat += "<a href='?src=\ref[cur_viewed_device];extern_update=\ref[src];str=-1000'>\[----\]</a> \
<a href='?src=\ref[cur_viewed_device];extern_update=\ref[src];str=-100'>\[--- \]</a> \
<a href='?src=\ref[cur_viewed_device];extern_update=\ref[src];str=-10'>\[-- \]</a> \
<a href='?src=\ref[cur_viewed_device];extern_update=\ref[src];str=-1'>\[- \]</a> \
<a href='?src=\ref[cur_viewed_device];extern_update=\ref[src];str=1'>\[+ \]</a> \
<a href='?src=\ref[cur_viewed_device];extern_update=\ref[src];str=10'>\[++ \]</a> \
<a href='?src=\ref[cur_viewed_device];extern_update=\ref[src];str=100'>\[+++ \]</a> \
<a href='?src=\ref[cur_viewed_device];extern_update=\ref[src];str=1000'>\[++++\]</a><br>"
dat += "<b>Field frequency:</b> [cur_viewed_device.field_frequency] MHz<br>"
dat += "<a href='?src=\ref[cur_viewed_device];extern_update=\ref[src];freq=-1000'>\[----\]</a> \
<a href='?src=\ref[cur_viewed_device];extern_update=\ref[src];freq=-100'>\[--- \]</a> \
<a href='?src=\ref[cur_viewed_device];extern_update=\ref[src];freq=-10'>\[-- \]</a> \
<a href='?src=\ref[cur_viewed_device];extern_update=\ref[src];freq=-1'>\[- \]</a> \
<a href='?src=\ref[cur_viewed_device];extern_update=\ref[src];freq=1'>\[+ \]</a> \
<a href='?src=\ref[cur_viewed_device];extern_update=\ref[src];freq=10'>\[++ \]</a> \
<a href='?src=\ref[cur_viewed_device];extern_update=\ref[src];freq=100'>\[+++ \]</a> \
<a href='?src=\ref[cur_viewed_device];extern_update=\ref[src];freq=1000'>\[++++\]</a><br>"
var/power_stat = "Good"
if(cur_viewed_device.cached_power_avail < cur_viewed_device.active_power_usage)
power_stat = "Insufficient"
else if(cur_viewed_device.cached_power_avail < cur_viewed_device.active_power_usage * 2)
power_stat = "Check"
dat += "<b>Power status:</b> [power_stat]<br>"
else
dat += "<a href='?src=\ref[src];scan=1'>\[Refresh device list\]</a><br><br>"
if(connected_devices.len)
dat += "<table width='100%' border=1>"
dat += "<tr>"
dat += "<td><b>Device tag</b></td>"
dat += "<td></td>"
dat += "</tr>"
for(var/obj/machinery/power/rust_core/C in connected_devices)
if(!check_core_status(C))
connected_devices.Remove(C)
continue
dat += "<tr>"
dat += "<td>[C.id_tag]</td>"
dat += "<td><a href='?src=\ref[src];manage_individual=\ref[C]'>\[Manage\]</a></td>"
dat += "</tr>"
dat += "</table>"
else
dat += "No devices connected.<br>"
dat += "<hr>"
dat += "<a href='?src=\ref[src];refresh=1'>Refresh</a> "
dat += "<a href='?src=\ref[src];close=1'>Close</a>"
user << browse(dat, "window=core_control;size=500x400")
onclose(user, "core_control")
user.set_machine(src)
/obj/machinery/computer/rust_core_control/Topic(href, href_list)
..()
if( href_list["goto_scanlist"] )
cur_viewed_device = null
if( href_list["manage_individual"] )
cur_viewed_device = locate(href_list["manage_individual"])
if( href_list["scan"] )
connected_devices = list()
for(var/obj/machinery/power/rust_core/C in range(scan_range, src))
if(check_core_status(C))
connected_devices.Add(C)
if( href_list["startup"] )
if(cur_viewed_device)
cur_viewed_device.Startup()
if( href_list["shutdown"] )
if(cur_viewed_device)
cur_viewed_device.Shutdown()
if( href_list["close"] )
usr << browse(null, "window=core_control")
usr.unset_machine()
updateDialog()
/obj/machinery/computer/rust_core_control/proc/check_core_status(var/obj/machinery/power/rust_core/C)
if(!C)
return 0
if(C.stat & (BROKEN|NOPOWER) || !C.remote_access_enabled || !C.id_tag)
if(connected_devices.Find(C))
connected_devices.Remove(C)
return 0
return 1

View File

@@ -0,0 +1,437 @@
//the em field is where the fun happens
/*
Deuterium-deuterium fusion : 40 x 10^7 K
Deuterium-tritium fusion: 4.5 x 10^7 K
*/
//#DEFINE MAX_STORED_ENERGY (held_phoron.phoron * held_phoron.phoron * SPECIFIC_HEAT_TOXIN)
/obj/effect/rust_em_field
name = "EM Field"
desc = "A coruscating, barely visible field of energy. It is shaped like a slightly flattened torus."
icon = 'icons/rust.dmi'
icon_state = "emfield_s1"
//
var/major_radius = 0 //longer radius in meters = field_strength * 0.21875, max = 8.75
var/minor_radius = 0 //shorter radius in meters = field_strength * 0.2125, max = 8.625
var/size = 1 //diameter in tiles
var/volume_covered = 0 //atmospheric volume covered
//
var/obj/machinery/power/rust_core/owned_core
var/list/dormant_reactant_quantities = new
//luminosity = 1
layer = 3.1
//
var/energy = 0
var/mega_energy = 0
var/radiation = 0
var/frequency = 1
var/field_strength = 0.01 //in teslas, max is 50T
var/obj/machinery/rust/rad_source/radiator
var/datum/gas_mixture/held_phoron = new
var/particle_catchers[13]
var/emp_overload = 0
/obj/effect/rust_em_field/New()
..()
//create radiator
for(var/obj/machinery/rust/rad_source/rad in range(0))
radiator = rad
if(!radiator)
radiator = new()
//make sure there's a field generator
for(var/obj/machinery/power/rust_core/core in loc)
owned_core = core
if(!owned_core)
del(src)
//create the gimmicky things to handle field collisions
var/obj/effect/rust_particle_catcher/catcher
//
catcher = new (locate(src.x,src.y,src.z))
catcher.parent = src
catcher.SetSize(1)
particle_catchers.Add(catcher)
//
catcher = new (locate(src.x-1,src.y,src.z))
catcher.parent = src
catcher.SetSize(3)
particle_catchers.Add(catcher)
catcher = new (locate(src.x+1,src.y,src.z))
catcher.parent = src
catcher.SetSize(3)
particle_catchers.Add(catcher)
catcher = new (locate(src.x,src.y+1,src.z))
catcher.parent = src
catcher.SetSize(3)
particle_catchers.Add(catcher)
catcher = new (locate(src.x,src.y-1,src.z))
catcher.parent = src
catcher.SetSize(3)
particle_catchers.Add(catcher)
//
catcher = new (locate(src.x-2,src.y,src.z))
catcher.parent = src
catcher.SetSize(5)
particle_catchers.Add(catcher)
catcher = new (locate(src.x+2,src.y,src.z))
catcher.parent = src
catcher.SetSize(5)
particle_catchers.Add(catcher)
catcher = new (locate(src.x,src.y+2,src.z))
catcher.parent = src
catcher.SetSize(5)
particle_catchers.Add(catcher)
catcher = new (locate(src.x,src.y-2,src.z))
catcher.parent = src
catcher.SetSize(5)
particle_catchers.Add(catcher)
//
catcher = new (locate(src.x-3,src.y,src.z))
catcher.parent = src
catcher.SetSize(7)
particle_catchers.Add(catcher)
catcher = new (locate(src.x+3,src.y,src.z))
catcher.parent = src
catcher.SetSize(7)
particle_catchers.Add(catcher)
catcher = new (locate(src.x,src.y+3,src.z))
catcher.parent = src
catcher.SetSize(7)
particle_catchers.Add(catcher)
catcher = new (locate(src.x,src.y-3,src.z))
catcher.parent = src
catcher.SetSize(7)
particle_catchers.Add(catcher)
//init values
major_radius = field_strength * 0.21875// max = 8.75
minor_radius = field_strength * 0.2125// max = 8.625
volume_covered = PI * major_radius * minor_radius * 2.5 * 2.5 * 1000
processing_objects.Add(src)
/obj/effect/rust_em_field/process()
//make sure the field generator is still intact
if(!owned_core)
del(src)
//handle radiation
if(!radiator)
radiator = new /obj/machinery/rust/rad_source()
radiator.mega_energy += radiation
radiator.source_alive++
radiation = 0
//update values
var/transfer_ratio = field_strength / 50 //higher field strength will result in faster phoron aggregation
major_radius = field_strength * 0.21875// max = 8.75m
minor_radius = field_strength * 0.2125// max = 8.625m
volume_covered = PI * major_radius * minor_radius * 2.5 * 2.5 * 2.5 * 7 * 7 * transfer_ratio //one tile = 2.5m*2.5m*2.5m
//add phoron from the surrounding environment
var/datum/gas_mixture/environment = loc.return_air()
//hack in some stuff to remove phoron from the air because SCIENCE
//the amount of phoron pulled in each update is relative to the field strength, with 50T (max field strength) = 100% of area covered by the field
//at minimum strength, 0.25% of the field volume is pulled in per update (?)
//have a max of 1000 moles suspended
if(held_phoron.gas["phoron"] < transfer_ratio * 1000)
var/moles_covered = environment.return_pressure()*volume_covered/(environment.temperature * R_IDEAL_GAS_EQUATION)
//world << "\blue moles_covered: [moles_covered]"
//
var/datum/gas_mixture/gas_covered = environment.remove(moles_covered)
var/datum/gas_mixture/phoron_captured = new /datum/gas_mixture()
//
phoron_captured.gas["phoron"] = round(gas_covered.gas["phoron"] * transfer_ratio)
//world << "\blue[phoron_captured.phoron] moles of phoron captured"
phoron_captured.temperature = gas_covered.temperature
phoron_captured.update_values()
//
gas_covered.adjust_gas("phoron", -phoron_captured.gas["phoron"])
//
held_phoron.merge(phoron_captured)
//
environment.merge(gas_covered)
//let the particles inside the field react
React()
//forcibly radiate any excess energy
/*var/energy_max = transfer_ratio * 100000
if(mega_energy > energy_max)
var/energy_lost = rand( 1.5 * (mega_energy - energy_max), 2.5 * (mega_energy - energy_max) )
mega_energy -= energy_lost
radiation += energy_lost*/
//change held phoron temp according to energy levels
//SPECIFIC_HEAT_TOXIN
if(mega_energy > 0 && held_phoron.gas["phoron"])
var/heat_capacity = held_phoron.heat_capacity()//200 * number of phoron moles
if(heat_capacity > 0.0003) //formerly MINIMUM_HEAT_CAPACITY
held_phoron.temperature = (heat_capacity + mega_energy * 35000)/heat_capacity
//if there is too much phoron in the field, lose some
/*if( held_phoron.phoron > (MOLES_CELLSTANDARD * 7) * (50 / field_strength) )
LosePhoron()*/
if(held_phoron.gas["phoron"] > 1)
//lose a random amount of phoron back into the air, increased by the field strength (want to switch this over to frequency eventually)
var/loss_ratio = rand() * (0.05 + (0.05 * 50 / field_strength))
//world << "lost [loss_ratio*100]% of held phoron"
//
var/datum/gas_mixture/phoron_lost = new
phoron_lost.temperature = held_phoron.temperature
//
phoron_lost.gas["phoron"] = held_phoron.gas["phoron"] * loss_ratio
//phoron_lost.update_values()
held_phoron.gas["phoron"] -= held_phoron.gas["phoron"] * loss_ratio
//held_phoron.update_values()
//
environment.merge(phoron_lost)
radiation += loss_ratio * mega_energy * 0.1
mega_energy -= loss_ratio * mega_energy * 0.1
else
held_phoron.gas["phoron"] = null
//held_phoron.update_values()
//handle some reactants formatting
for(var/reactant in dormant_reactant_quantities)
var/amount = dormant_reactant_quantities[reactant]
if(amount < 1)
dormant_reactant_quantities.Remove(reactant)
else if(amount >= 1000000)
var/radiate = rand(3 * amount / 4, amount / 4)
dormant_reactant_quantities[reactant] -= radiate
radiation += radiate
return 1
/obj/effect/rust_em_field/proc/ChangeFieldStrength(var/new_strength)
var/calc_size = 1
emp_overload = 0
if(new_strength <= 50)
calc_size = 1
else if(new_strength <= 200)
calc_size = 3
else if(new_strength <= 500)
calc_size = 5
else
calc_size = 7
if(new_strength > 900)
emp_overload = 1
//
field_strength = new_strength
change_size(calc_size)
/obj/effect/rust_em_field/proc/ChangeFieldFrequency(var/new_frequency)
frequency = new_frequency
/obj/effect/rust_em_field/proc/AddEnergy(var/a_energy, var/a_mega_energy, var/a_frequency)
var/energy_loss_ratio = 0
if(a_frequency != src.frequency)
energy_loss_ratio = 1 / abs(a_frequency - src.frequency)
energy += a_energy - a_energy * energy_loss_ratio
mega_energy += a_mega_energy - a_mega_energy * energy_loss_ratio
while(energy > 100000)
energy -= 100000
mega_energy += 0.1
/obj/effect/rust_em_field/proc/AddParticles(var/name, var/quantity = 1)
if(name in dormant_reactant_quantities)
dormant_reactant_quantities[name] += quantity
else if(name != "proton" && name != "electron" && name != "neutron")
dormant_reactant_quantities.Add(name)
dormant_reactant_quantities[name] = quantity
/obj/effect/rust_em_field/proc/RadiateAll(var/ratio_lost = 1)
for(var/particle in dormant_reactant_quantities)
radiation += dormant_reactant_quantities[particle]
dormant_reactant_quantities.Remove(particle)
radiation += mega_energy
mega_energy = 0
//lose all held phoron back into the air
var/datum/gas_mixture/environment = loc.return_air()
environment.merge(held_phoron)
/obj/effect/rust_em_field/proc/change_size(var/newsize = 1)
//
var/changed = 0
switch(newsize)
if(1)
size = 1
icon = 'icons/rust.dmi'
icon_state = "emfield_s1"
pixel_x = 0
pixel_y = 0
//
changed = 1
if(3)
size = 3
icon = 'icons/effects/96x96.dmi'
icon_state = "emfield_s3"
pixel_x = -32
pixel_y = -32
//
changed = 3
if(5)
size = 5
icon = 'icons/effects/160x160.dmi'
icon_state = "emfield_s5"
pixel_x = -64
pixel_y = -64
//
changed = 5
if(7)
size = 7
icon = 'icons/effects/224x224.dmi'
icon_state = "emfield_s7"
pixel_x = -96
pixel_y = -96
//
changed = 7
for(var/obj/effect/rust_particle_catcher/catcher in particle_catchers)
catcher.UpdateSize()
return changed
//the !!fun!! part
/obj/effect/rust_em_field/proc/React()
//loop through the reactants in random order
var/list/reactants_reacting_pool = dormant_reactant_quantities.Copy()
/*
for(var/reagent in dormant_reactant_quantities)
world << " before: [reagent]: [dormant_reactant_quantities[reagent]]"
*/
//cant have any reactions if there aren't any reactants present
if(reactants_reacting_pool.len)
//determine a random amount to actually react this cycle, and remove it from the standard pool
//this is a hack, and quite nonrealistic :(
for(var/reactant in reactants_reacting_pool)
reactants_reacting_pool[reactant] = rand(0,reactants_reacting_pool[reactant])
dormant_reactant_quantities[reactant] -= reactants_reacting_pool[reactant]
if(!reactants_reacting_pool[reactant])
reactants_reacting_pool -= reactant
//loop through all the reacting reagents, picking out random reactions for them
var/list/produced_reactants = new/list
var/list/primary_reactant_pool = reactants_reacting_pool.Copy()
while(primary_reactant_pool.len)
//pick one of the unprocessed reacting reagents randomly
var/cur_primary_reactant = pick(primary_reactant_pool)
primary_reactant_pool.Remove(cur_primary_reactant)
//world << "\blue primary reactant chosen: [cur_primary_reactant]"
//grab all the possible reactants to have a reaction with
var/list/possible_secondary_reactants = reactants_reacting_pool.Copy()
//if there is only one of a particular reactant, then it can not react with itself so remove it
possible_secondary_reactants[cur_primary_reactant] -= 1
if(possible_secondary_reactants[cur_primary_reactant] < 1)
possible_secondary_reactants.Remove(cur_primary_reactant)
//loop through and work out all the possible reactions
var/list/possible_reactions = new/list
for(var/cur_secondary_reactant in possible_secondary_reactants)
if(possible_secondary_reactants[cur_secondary_reactant] < 1)
continue
var/datum/fusion_reaction/cur_reaction = get_fusion_reaction(cur_primary_reactant, cur_secondary_reactant)
if(cur_reaction)
//world << "\blue secondary reactant: [cur_secondary_reactant], [reaction_products.len]"
possible_reactions.Add(cur_reaction)
//if there are no possible reactions here, abandon this primary reactant and move on
if(!possible_reactions.len)
//world << "\blue no reactions"
continue
//split up the reacting atoms between the possible reactions
while(possible_reactions.len)
//pick a random substance to react with
var/datum/fusion_reaction/cur_reaction = pick(possible_reactions)
possible_reactions.Remove(cur_reaction)
//set the randmax to be the lower of the two involved reactants
var/max_num_reactants = reactants_reacting_pool[cur_reaction.primary_reactant] > reactants_reacting_pool[cur_reaction.secondary_reactant] ? \
reactants_reacting_pool[cur_reaction.secondary_reactant] : reactants_reacting_pool[cur_reaction.primary_reactant]
if(max_num_reactants < 1)
continue
//make sure we have enough energy
if(mega_energy < max_num_reactants * cur_reaction.energy_consumption)
max_num_reactants = round(mega_energy / cur_reaction.energy_consumption)
if(max_num_reactants < 1)
continue
//randomly determined amount to react
var/amount_reacting = rand(1, max_num_reactants)
//removing the reacting substances from the list of substances that are primed to react this cycle
//if there aren't enough of that substance (there should be) then modify the reactant amounts accordingly
if( reactants_reacting_pool[cur_reaction.primary_reactant] - amount_reacting >= 0 )
reactants_reacting_pool[cur_reaction.primary_reactant] -= amount_reacting
else
amount_reacting = reactants_reacting_pool[cur_reaction.primary_reactant]
reactants_reacting_pool[cur_reaction.primary_reactant] = 0
//same again for secondary reactant
if( reactants_reacting_pool[cur_reaction.secondary_reactant] - amount_reacting >= 0 )
reactants_reacting_pool[cur_reaction.secondary_reactant] -= amount_reacting
else
reactants_reacting_pool[cur_reaction.primary_reactant] += amount_reacting - reactants_reacting_pool[cur_reaction.primary_reactant]
amount_reacting = reactants_reacting_pool[cur_reaction.secondary_reactant]
reactants_reacting_pool[cur_reaction.secondary_reactant] = 0
//remove the consumed energy
mega_energy -= max_num_reactants * cur_reaction.energy_consumption
//add any produced energy
mega_energy += max_num_reactants * cur_reaction.energy_production
//add any produced radiation
radiation += max_num_reactants * cur_reaction.radiation
//create the reaction products
for(var/reactant in cur_reaction.products)
var/success = 0
for(var/check_reactant in produced_reactants)
if(check_reactant == reactant)
produced_reactants[reactant] += cur_reaction.products[reactant] * amount_reacting
success = 1
break
if(!success)
produced_reactants[reactant] = cur_reaction.products[reactant] * amount_reacting
//this reaction is done, and can't be repeated this sub-cycle
possible_reactions.Remove(cur_reaction.secondary_reactant)
//
/*if(new_radiation)
if(!radiating)
radiating = 1
PeriodicRadiate()*/
//loop through the newly produced reactants and add them to the pool
//var/list/neutronic_radiation = new
//var/list/protonic_radiation = new
for(var/reactant in produced_reactants)
AddParticles(reactant, produced_reactants[reactant])
//world << "produced: [reactant], [dormant_reactant_quantities[reactant]]"
//check whether there are reactants left, and add them back to the pool
for(var/reactant in reactants_reacting_pool)
AddParticles(reactant, reactants_reacting_pool[reactant])
//world << "retained: [reactant], [reactants_reacting_pool[reactant]]"
/obj/effect/rust_em_field/Del()
//radiate everything in one giant burst
for(var/obj/effect/rust_particle_catcher/catcher in particle_catchers)
del (catcher)
RadiateAll()
processing_objects.Remove(src)
..()

View File

@@ -0,0 +1,284 @@
//the core [tokamaka generator] big funky solenoid, it generates an EM field
/*
when the core is turned on, it generates [creates] an electromagnetic field
the em field attracts phoron, and suspends it in a controlled torus (doughnut) shape, oscillating around the core
the field strength is directly controllable by the user
field strength = sqrt(energy used by the field generator)
the size of the EM field = field strength / k
(k is an arbitrary constant to make the calculated size into tilewidths)
1 tilewidth = below 5T
3 tilewidth = between 5T and 12T
5 tilewidth = between 10T and 25T
7 tilewidth = between 20T and 50T
(can't go higher than 40T)
energy is added by a gyrotron, and lost when phoron escapes
energy transferred from the gyrotron beams is reduced by how different the frequencies are (closer frequencies = more energy transferred)
frequency = field strength * (stored energy / stored moles of phoron) * x
(where x is an arbitrary constant to make the frequency something realistic)
the gyrotron beams' frequency and energy are hardcapped low enough that they won't heat the phoron much
energy is generated in considerable amounts by fusion reactions from injected particles
fusion reactions only occur when the existing energy is above a certain level, and it's near the max operating level of the gyrotron. higher energy reactions only occur at higher energy levels
a small amount of energy constantly bleeds off in the form of radiation
the field is constantly pulling in phoron from the surrounding [local] atmosphere
at random intervals, the field releases a random percentage of stored phoron in addition to a percentage of energy as intense radiation
the amount of phoron is a percentage of the field strength, increased by frequency
*/
/*
- VALUES -
max volume of phoron storeable by the field = the total volume of a number of tiles equal to the (field tilewidth)^2
*/
#define MAX_FIELD_FREQ 1000
#define MIN_FIELD_FREQ 1
#define MAX_FIELD_STR 1000
#define MIN_FIELD_STR 1
/obj/machinery/power/rust_core
name = "RUST Tokamak core"
desc = "Enormous solenoid for generating extremely high power electromagnetic fields"
icon = 'icons/rust.dmi'
icon_state = "core0"
density = 1
var/obj/effect/rust_em_field/owned_field
var/field_strength = 1//0.01
var/field_frequency = 1
var/id_tag = "allan, don't forget to set the ID of this one too"
req_access = list(access_engine)
//
use_power = 1
idle_power_usage = 50
active_power_usage = 500 //multiplied by field strength
var/cached_power_avail = 0
anchored = 0
var/state = 0
var/locked = 1
var/remote_access_enabled = 1
/obj/machinery/power/rust_core/process()
if(stat & BROKEN || !powernet)
Shutdown()
cached_power_avail = avail()
//luminosity = round(owned_field.field_strength/10)
//luminosity = max(luminosity,1)
/obj/machinery/power/rust_core/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/weapon/wrench))
if(owned_field)
user << "Turn off [src] first."
return
switch(state)
if(0)
state = 1
playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
user.visible_message("[user.name] secures [src.name] to the floor.", \
"You secure the external reinforcing bolts to the floor.", \
"You hear a ratchet")
src.anchored = 1
if(1)
state = 0
playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
user.visible_message("[user.name] unsecures [src.name] reinforcing bolts from the floor.", \
"You undo the external reinforcing bolts.", \
"You hear a ratchet")
src.anchored = 0
if(2)
user << "\red The [src.name] needs to be unwelded from the floor."
return
if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(owned_field)
user << "Turn off the [src] first."
return
switch(state)
if(0)
user << "\red The [src.name] needs to be wrenched to the floor."
if(1)
if (WT.remove_fuel(0,user))
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
user.visible_message("[user.name] starts to weld the [src.name] to the floor.", \
"You start to weld the [src] to the floor.", \
"You hear welding")
if (do_after(user,20))
if(!src || !WT.isOn()) return
state = 2
user << "You weld the [src] to the floor."
connect_to_network()
else
user << "\red You need more welding fuel to complete this task."
if(2)
if (WT.remove_fuel(0,user))
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
user.visible_message("[user.name] starts to cut the [src.name] free from the floor.", \
"You start to cut the [src] free from the floor.", \
"You hear welding")
if (do_after(user,20))
if(!src || !WT.isOn()) return
state = 1
user << "You cut the [src] free from the floor."
disconnect_from_network()
else
user << "\red You need more welding fuel to complete this task."
return
if(istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda))
if(emagged)
user << "\red The lock seems to be broken"
return
if(src.allowed(user))
if(owned_field)
src.locked = !src.locked
user << "The controls are now [src.locked ? "locked." : "unlocked."]"
else
src.locked = 0 //just in case it somehow gets locked
user << "\red The controls can only be locked when the [src] is online"
else
user << "\red Access denied."
return
if(istype(W, /obj/item/weapon/card/emag) && !emagged)
locked = 0
emagged = 1
user.visible_message("[user.name] emags the [src.name].","\red You short out the lock.")
return
..()
return
/obj/machinery/power/rust_core/attack_ai(mob/user)
attack_hand(user)
/obj/machinery/power/rust_core/attack_hand(mob/user)
add_fingerprint(user)
interact(user)
/obj/machinery/power/rust_core/interact(mob/user)
if(stat & BROKEN)
user.unset_machine()
user << browse(null, "window=core_gen")
return
if(!istype(user, /mob/living/silicon) && get_dist(src, user) > 1)
user.unset_machine()
user << browse(null, "window=core_gen")
return
var/dat = ""
if(stat & NOPOWER || locked || state != 2)
dat += "<i>The console is dark and nonresponsive.</i>"
else
dat += "<b>RUST Tokamak pattern Electromagnetic Field Generator</b><br>"
dat += "<b>Device ID tag: </b> [id_tag ? id_tag : "UNSET"] <a href='?src=\ref[src];new_id_tag=1'>\[Modify\]</a><br>"
dat += "<a href='?src=\ref[src];toggle_active=1'>\[[owned_field ? "Deactivate" : "Activate"]\]</a><br>"
dat += "<a href='?src=\ref[src];toggle_remote=1'>\[[remote_access_enabled ? "Disable remote access to this device" : "Enable remote access to this device"]\]</a><br>"
dat += "<hr>"
dat += "<b>Field strength:</b> [field_strength]Wm^3<br>"
dat += "<a href='?src=\ref[src];str=-1000'>\[----\]</a> \
<a href='?src=\ref[src];str=-100'>\[--- \]</a> \
<a href='?src=\ref[src];str=-10'>\[-- \]</a> \
<a href='?src=\ref[src];str=-1'>\[- \]</a> \
<a href='?src=\ref[src];str=1'>\[+ \]</a> \
<a href='?src=\ref[src];str=10'>\[++ \]</a> \
<a href='?src=\ref[src];str=100'>\[+++ \]</a> \
<a href='?src=\ref[src];str=1000'>\[++++\]</a><br>"
dat += "<b>Field frequency:</b> [field_frequency]MHz<br>"
dat += "<a href='?src=\ref[src];freq=-1000'>\[----\]</a> \
<a href='?src=\ref[src];freq=-100'>\[--- \]</a> \
<a href='?src=\ref[src];freq=-10'>\[-- \]</a> \
<a href='?src=\ref[src];freq=-1'>\[- \]</a> \
<a href='?src=\ref[src];freq=1'>\[+ \]</a> \
<a href='?src=\ref[src];freq=10'>\[++ \]</a> \
<a href='?src=\ref[src];freq=100'>\[+++ \]</a> \
<a href='?src=\ref[src];freq=1000'>\[++++\]</a><br>"
var/font_colour = "green"
if(cached_power_avail < active_power_usage)
font_colour = "red"
else if(cached_power_avail < active_power_usage * 2)
font_colour = "orange"
dat += "<b>Power status:</b> <font color=[font_colour]>[active_power_usage]/[cached_power_avail] W</font><br>"
user << browse(dat, "window=core_gen;size=500x300")
onclose(user, "core_gen")
user.set_machine(src)
/obj/machinery/power/rust_core/Topic(href, href_list)
if(href_list["str"])
var/dif = text2num(href_list["str"])
field_strength = min(max(field_strength + dif, MIN_FIELD_STR), MAX_FIELD_STR)
active_power_usage = 5 * field_strength //change to 500 later
if(owned_field)
owned_field.ChangeFieldStrength(field_strength)
if(href_list["freq"])
var/dif = text2num(href_list["freq"])
field_frequency = min(max(field_frequency + dif, MIN_FIELD_FREQ), MAX_FIELD_FREQ)
if(owned_field)
owned_field.ChangeFieldFrequency(field_frequency)
if(href_list["toggle_active"])
if(!Startup())
Shutdown()
if( href_list["toggle_remote"] )
remote_access_enabled = !remote_access_enabled
if(href_list["new_id_tag"])
if(usr)
id_tag = input("Enter a new ID tag", "Tokamak core ID tag", id_tag) as text|null
if(href_list["close"])
usr << browse(null, "window=core_gen")
usr.unset_machine()
if(href_list["extern_update"])
var/obj/machinery/computer/rust_core_control/C = locate(href_list["extern_update"])
if(C)
C.updateDialog()
src.updateDialog()
/obj/machinery/power/rust_core/proc/Startup()
if(owned_field)
return
owned_field = new(src.loc)
owned_field.ChangeFieldStrength(field_strength)
owned_field.ChangeFieldFrequency(field_frequency)
icon_state = "core1"
luminosity = 1
use_power = 2
return 1
/obj/machinery/power/rust_core/proc/Shutdown()
//todo: safety checks for field status
if(owned_field)
icon_state = "core0"
del(owned_field)
luminosity = 0
use_power = 1
/obj/machinery/power/rust_core/proc/AddParticles(var/name, var/quantity = 1)
if(owned_field)
owned_field.AddParticles(name, quantity)
return 1
return 0
/obj/machinery/power/rust_core/bullet_act(var/obj/item/projectile/Proj)
if(owned_field)
return owned_field.bullet_act(Proj)
return 0

View File

View File

@@ -0,0 +1,17 @@
/obj/item/weapon/fuel_assembly
icon = 'icons/rust.dmi'
icon_state = "fuel_assembly"
name = "Fuel Rod Assembly"
var/list/rod_quantities
var/percent_depleted = 1
layer = 3.1
//
New()
rod_quantities = new/list
//these can be abstracted away for now
/*
/obj/item/weapon/fuel_rod
/obj/item/weapon/control_rod
*/

View File

@@ -0,0 +1,102 @@
/obj/machinery/rust_fuel_assembly_port
name = "Fuel Assembly Port"
icon = 'icons/rust.dmi'
icon_state = "port2"
density = 0
var/obj/item/weapon/fuel_assembly/cur_assembly
var/busy = 0
anchored = 1
var/opened = 1 //0=closed, 1=opened
var/has_electronics = 0 // 0 - none, bit 1 - circuitboard, bit 2 - wires
/obj/machinery/rust_fuel_assembly_port/attackby(var/obj/item/I, var/mob/user)
if(istype(I,/obj/item/weapon/fuel_assembly) && !opened)
if(cur_assembly)
user << "\red There is already a fuel rod assembly in there!"
else
cur_assembly = I
user.drop_item()
I.loc = src
icon_state = "port1"
user << "\blue You insert [I] into [src]. Touch the panel again to insert [I] into the injector."
/obj/machinery/rust_fuel_assembly_port/attack_hand(mob/user)
add_fingerprint(user)
if(stat & (BROKEN|NOPOWER) || opened)
return
if(cur_assembly)
if(try_insert_assembly())
user << "\blue \icon[src] [src] inserts it's fuel rod assembly into an injector."
else
if(eject_assembly())
user << "\red \icon[src] [src] ejects it's fuel assembly. Check the fuel injector status."
else if(try_draw_assembly())
user << "\blue \icon[src] [src] draws a fuel rod assembly from an injector."
else if(try_draw_assembly())
user << "\blue \icon[src] [src] draws a fuel rod assembly from an injector."
else
user << "\red \icon[src] [src] was unable to draw a fuel rod assembly from an injector."
/obj/machinery/rust_fuel_assembly_port/proc/try_insert_assembly()
var/success = 0
if(cur_assembly)
var/turf/check_turf = get_step(get_turf(src), src.dir)
check_turf = get_step(check_turf, src.dir)
for(var/obj/machinery/power/rust_fuel_injector/I in check_turf)
if(I.stat & (BROKEN|NOPOWER))
break
if(I.cur_assembly)
break
if(I.state != 2)
break
I.cur_assembly = cur_assembly
cur_assembly.loc = I
cur_assembly = null
icon_state = "port0"
success = 1
return success
/obj/machinery/rust_fuel_assembly_port/proc/eject_assembly()
if(cur_assembly)
cur_assembly.loc = src.loc//get_step(get_turf(src), src.dir)
cur_assembly = null
icon_state = "port0"
return 1
/obj/machinery/rust_fuel_assembly_port/proc/try_draw_assembly()
var/success = 0
if(!cur_assembly)
var/turf/check_turf = get_step(get_turf(src), src.dir)
check_turf = get_step(check_turf, src.dir)
for(var/obj/machinery/power/rust_fuel_injector/I in check_turf)
if(I.stat & (BROKEN|NOPOWER))
break
if(!I.cur_assembly)
break
if(I.injecting)
break
if(I.state != 2)
break
cur_assembly = I.cur_assembly
cur_assembly.loc = src
I.cur_assembly = null
icon_state = "port1"
success = 1
break
return success
/obj/machinery/rust_fuel_assembly_port/verb/eject_assembly_verb()
set name = "Eject assembly from port"
set category = "Object"
set src in oview(1)
eject_assembly()

View File

@@ -0,0 +1,133 @@
//frame assembly
/obj/item/rust_fuel_assembly_port_frame
name = "Fuel Assembly Port frame"
icon = 'icons/rust.dmi'
icon_state = "port2"
w_class = 4
flags = CONDUCT
/obj/item/rust_fuel_assembly_port_frame/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/wrench))
new /obj/item/stack/sheet/plasteel( get_turf(src.loc), 12 )
del(src)
return
..()
/obj/item/rust_fuel_assembly_port_frame/proc/try_build(turf/on_wall)
if (get_dist(on_wall,usr)>1)
return
var/ndir = get_dir(usr,on_wall)
if (!(ndir in cardinal))
return
var/turf/loc = get_turf(usr)
var/area/A = loc.loc
if (!istype(loc, /turf/simulated/floor))
usr << "\red Port cannot be placed on this spot."
return
if (A.requires_power == 0 || A.name == "Space")
usr << "\red Port cannot be placed in this area."
return
new /obj/machinery/rust_fuel_assembly_port(loc, ndir, 1)
del(src)
//construction steps
/obj/machinery/rust_fuel_assembly_port/New(turf/loc, var/ndir, var/building=0)
..()
// offset 24 pixels in direction of dir
// this allows the APC to be embedded in a wall, yet still inside an area
if (building)
set_dir(ndir)
else
has_electronics = 3
opened = 0
icon_state = "port0"
//20% easier to read than apc code
pixel_x = (dir & 3)? 0 : (dir == 4 ? 32 : -32)
pixel_y = (dir & 3)? (dir ==1 ? 32 : -32) : 0
/obj/machinery/rust_fuel_assembly_port/attackby(obj/item/W, mob/user)
if (istype(user, /mob/living/silicon) && get_dist(src,user)>1)
return src.attack_hand(user)
if (istype(W, /obj/item/weapon/crowbar))
if(opened)
if(has_electronics & 1)
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
user << "You begin removing the circuitboard" //lpeters - fixed grammar issues
if(do_after(user, 50))
user.visible_message(\
"\red [user.name] has removed the circuitboard from [src.name]!",\
"\blue You remove the circuitboard.")
has_electronics = 0
new /obj/item/weapon/module/rust_fuel_port(loc)
has_electronics &= ~1
else
opened = 0
icon_state = "port0"
user << "\blue You close the maintenance cover."
else
if(cur_assembly)
user << "\red You cannot open the cover while there is a fuel assembly inside."
else
opened = 1
user << "\blue You open the maintenance cover."
icon_state = "port2"
return
else if (istype(W, /obj/item/stack/cable_coil) && opened && !(has_electronics & 2))
var/obj/item/stack/cable_coil/C = W
if(C.amount < 10)
user << "\red You need more wires."
return
user << "You start adding cables to the frame..."
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
if(do_after(user, 20) && C.amount >= 10)
C.use(10)
user.visible_message(\
"\red [user.name] has added cables to the port frame!",\
"You add cables to the port frame.")
has_electronics &= 2
return
else if (istype(W, /obj/item/weapon/wirecutters) && opened && (has_electronics & 2))
user << "You begin to cut the cables..."
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
if(do_after(user, 50))
new /obj/item/stack/cable_coil(loc,10)
user.visible_message(\
"\red [user.name] cut the cabling inside the port.",\
"You cut the cabling inside the port.")
has_electronics &= ~2
return
else if (istype(W, /obj/item/weapon/module/rust_fuel_port) && opened && !(has_electronics & 1))
user << "You trying to insert the port control board into the frame..."
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
if(do_after(user, 10))
has_electronics &= 1
user << "You place the port control board inside the frame."
del(W)
return
else if (istype(W, /obj/item/weapon/weldingtool) && opened && !has_electronics)
var/obj/item/weapon/weldingtool/WT = W
if (WT.get_fuel() < 3)
user << "\blue You need more welding fuel to complete this task."
return
user << "You start welding the port frame..."
playsound(src.loc, 'sound/items/Welder.ogg', 50, 1)
if(do_after(user, 50))
if(!src || !WT.remove_fuel(3, user)) return
new /obj/item/rust_fuel_assembly_port_frame(loc)
user.visible_message(\
"\red [src] has been cut away from the wall by [user.name].",\
"You detached the port frame.",\
"\red You hear welding.")
del(src)
return
..()

View File

@@ -0,0 +1,116 @@
var/const/max_assembly_amount = 300
/obj/machinery/rust_fuel_compressor
icon = 'icons/rust.dmi'
icon_state = "fuel_compressor1"
name = "Fuel Compressor"
var/list/new_assembly_quantities = list("Deuterium" = 150,"Tritium" = 150,"Rodinium-6" = 0,"Stravium-7" = 0, "Pergium" = 0, "Dilithium" = 0)
var/compressed_matter = 0
anchored = 1
layer = 2.9
var/opened = 1 //0=closed, 1=opened
var/locked = 0
var/has_electronics = 0 // 0 - none, bit 1 - circuitboard, bit 2 - wires
/obj/machinery/rust_fuel_compressor/attack_ai(mob/user)
attack_hand(user)
/obj/machinery/rust_fuel_compressor/attack_hand(mob/user)
add_fingerprint(user)
/*if(stat & (BROKEN|NOPOWER))
return*/
interact(user)
/obj/machinery/rust_fuel_compressor/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/rcd_ammo))
compressed_matter += 10
del(W)
return
..()
/obj/machinery/rust_fuel_compressor/interact(mob/user)
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
if (!istype(user, /mob/living/silicon))
user.unset_machine()
user << browse(null, "window=fuelcomp")
return
var/t = "<B>Reactor Fuel Rod Compressor / Assembler</B><BR>"
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
if(locked)
t += "Swipe your ID to unlock this console."
else
t += "Compressed matter in storage: [compressed_matter] <A href='?src=\ref[src];eject_matter=1'>\[Eject all\]</a><br>"
t += "<A href='?src=\ref[src];activate=1'><b>Activate Fuel Synthesis</b></A><BR> (fuel assemblies require no more than [max_assembly_amount] rods).<br>"
t += "<hr>"
t += "- New fuel assembly constituents:- <br>"
for(var/reagent in new_assembly_quantities)
t += " [reagent] rods: [new_assembly_quantities[reagent]] \[<A href='?src=\ref[src];change_reagent=[reagent]'>Modify</A>\]<br>"
t += "<hr>"
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
user << browse(t, "window=fuelcomp;size=500x300")
user.set_machine(src)
//var/locked
//var/coverlocked
/obj/machinery/rust_fuel_compressor/Topic(href, href_list)
..()
if( href_list["close"] )
usr << browse(null, "window=fuelcomp")
usr.machine = null
if( href_list["eject_matter"] )
var/ejected = 0
while(compressed_matter > 10)
new /obj/item/weapon/rcd_ammo(get_step(get_turf(src), src.dir))
compressed_matter -= 10
ejected = 1
if(ejected)
usr << "\blue \icon[src] [src] ejects some compressed matter units."
else
usr << "\red \icon[src] there are no more compressed matter units in [src]."
if( href_list["activate"] )
//world << "\blue New fuel rod assembly"
var/obj/item/weapon/fuel_assembly/F = new(src)
var/fail = 0
var/old_matter = compressed_matter
for(var/reagent in new_assembly_quantities)
var/req_matter = round(new_assembly_quantities[reagent] / 30)
//world << "[reagent] matter: [req_matter]/[compressed_matter]"
if(req_matter <= compressed_matter)
F.rod_quantities[reagent] = new_assembly_quantities[reagent]
compressed_matter -= req_matter
if(compressed_matter < 1)
compressed_matter = 0
else
/*world << "bad reagent: [reagent], [req_matter > compressed_matter ? "req_matter > compressed_matter"\
: (req_matter < compressed_matter ? "req_matter < compressed_matter" : "req_matter == compressed_matter")]"*/
fail = 1
break
//world << "\blue [reagent]: new_assembly_quantities[reagent]<br>"
if(fail)
del(F)
compressed_matter = old_matter
usr << "\red \icon[src] [src] flashes red: \'Out of matter.\'"
else
F.loc = src.loc//get_step(get_turf(src), src.dir)
F.percent_depleted = 0
if(compressed_matter < 0.034)
compressed_matter = 0
if( href_list["change_reagent"] )
var/cur_reagent = href_list["change_reagent"]
var/avail_rods = 300
for(var/rod in new_assembly_quantities)
avail_rods -= new_assembly_quantities[rod]
avail_rods += new_assembly_quantities[cur_reagent]
avail_rods = max(avail_rods, 0)
var/new_amount = min(input("Enter new [cur_reagent] rod amount (max [avail_rods])", "Fuel Assembly Rod Composition ([cur_reagent])") as num, avail_rods)
new_assembly_quantities[cur_reagent] = new_amount
updateDialog()

View File

@@ -0,0 +1,160 @@
//frame assembly
/obj/item/rust_fuel_compressor_frame
name = "Fuel Compressor frame"
icon = 'icons/rust.dmi'
icon_state = "fuel_compressor0"
w_class = 4
flags = CONDUCT
/obj/item/rust_fuel_compressor_frame/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/wrench))
new /obj/item/stack/sheet/plasteel( get_turf(src.loc), 12 )
del(src)
return
..()
/obj/item/rust_fuel_compressor_frame/proc/try_build(turf/on_wall)
if (get_dist(on_wall,usr)>1)
return
var/ndir = get_dir(usr,on_wall)
if (!(ndir in cardinal))
return
var/turf/loc = get_turf(usr)
var/area/A = loc.loc
if (!istype(loc, /turf/simulated/floor))
usr << "\red Compressor cannot be placed on this spot."
return
if (A.requires_power == 0 || A.name == "Space")
usr << "\red Compressor cannot be placed in this area."
return
new /obj/machinery/rust_fuel_assembly_port(loc, ndir, 1)
del(src)
//construction steps
/obj/machinery/rust_fuel_compressor/New(turf/loc, var/ndir, var/building=0)
..()
// offset 24 pixels in direction of dir
// this allows the APC to be embedded in a wall, yet still inside an area
if (building)
set_dir(ndir)
else
has_electronics = 3
opened = 0
locked = 0
icon_state = "fuel_compressor1"
//20% easier to read than apc code
pixel_x = (dir & 3)? 0 : (dir == 4 ? 32 : -32)
pixel_y = (dir & 3)? (dir ==1 ? 32 : -32) : 0
/obj/machinery/rust_fuel_compressor/attackby(obj/item/W, mob/user)
if (istype(user, /mob/living/silicon) && get_dist(src,user)>1)
return src.attack_hand(user)
if (istype(W, /obj/item/weapon/crowbar))
if(opened)
if(has_electronics & 1)
playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1)
user << "You begin removing the circuitboard" //lpeters - fixed grammar issues
if(do_after(user, 50))
user.visible_message(\
"\red [user.name] has removed the circuitboard from [src.name]!",\
"\blue You remove the circuitboard board.")
has_electronics = 0
new /obj/item/weapon/module/rust_fuel_compressor(loc)
has_electronics &= ~1
else
opened = 0
icon_state = "fuel_compressor0"
user << "\blue You close the maintenance cover."
else
if(compressed_matter > 0)
user << "\red You cannot open the cover while there is compressed matter inside."
else
opened = 1
user << "\blue You open the maintenance cover."
icon_state = "fuel_compressor1"
return
else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) // trying to unlock the interface with an ID card
if(opened)
user << "You must close the cover to swipe an ID card."
else
if(src.allowed(usr))
locked = !locked
user << "You [ locked ? "lock" : "unlock"] the compressor interface."
update_icon()
else
user << "\red Access denied."
return
else if (istype(W, /obj/item/weapon/card/emag) && !emagged) // trying to unlock with an emag card
if(opened)
user << "You must close the cover to swipe an ID card."
else
flick("apc-spark", src)
if (do_after(user,6))
if(prob(50))
emagged = 1
locked = 0
user << "You emag the port interface."
else
user << "You fail to [ locked ? "unlock" : "lock"] the compressor interface."
return
else if (istype(W, /obj/item/stack/cable_coil) && opened && !(has_electronics & 2))
var/obj/item/stack/cable_coil/C = W
if(C.amount < 10)
user << "\red You need more wires."
return
user << "You start adding cables to the compressor frame..."
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
if(do_after(user, 20) && C.amount >= 10)
C.use(10)
user.visible_message(\
"\red [user.name] has added cables to the compressor frame!",\
"You add cables to the port frame.")
has_electronics &= 2
return
else if (istype(W, /obj/item/weapon/wirecutters) && opened && (has_electronics & 2))
user << "You begin to cut the cables..."
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
if(do_after(user, 50))
new /obj/item/stack/cable_coil(loc,10)
user.visible_message(\
"\red [user.name] cut the cabling inside the compressor.",\
"You cut the cabling inside the port.")
has_electronics &= ~2
return
else if (istype(W, /obj/item/weapon/module/rust_fuel_compressor) && opened && !(has_electronics & 1))
user << "You trying to insert the circuitboard into the frame..."
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
if(do_after(user, 10))
has_electronics &= 1
user << "You place the circuitboard inside the frame."
del(W)
return
else if (istype(W, /obj/item/weapon/weldingtool) && opened && !has_electronics)
var/obj/item/weapon/weldingtool/WT = W
if (WT.get_fuel() < 3)
user << "\blue You need more welding fuel to complete this task."
return
user << "You start welding the compressor frame..."
playsound(src.loc, 'sound/items/Welder.ogg', 50, 1)
if(do_after(user, 50))
if(!src || !WT.remove_fuel(3, user)) return
new /obj/item/rust_fuel_assembly_port_frame(loc)
user.visible_message(\
"\red [src] has been cut away from the wall by [user.name].",\
"You detached the compressor frame.",\
"\red You hear welding.")
del(src)
return
..()

View File

@@ -0,0 +1,192 @@
/obj/machinery/computer/rust_fuel_control
name = "RUST Fuel Injection Control"
icon = 'icons/rust.dmi'
icon_state = "fuel"
var/list/connected_injectors = list()
var/list/active_stages = list()
var/list/proceeding_stages = list()
var/list/stage_times = list()
//var/list/stage_status
var/announce_fueldepletion = 0
var/announce_stageprogression = 0
var/scan_range = 25
var/ticks_this_stage = 0
/*/obj/machinery/computer/rust_fuel_control/New()
..()
//these are the only three stages we can accept
//we have another console for SCRAM
fuel_injectors = new/list
stage_status = new/list
fuel_injectors.Add("One")
fuel_injectors["One"] = new/list
stage_status.Add("One")
stage_status["One"] = 0
fuel_injectors.Add("Two")
fuel_injectors["Two"] = new/list
stage_status.Add("Two")
stage_status["Two"] = 0
fuel_injectors.Add("Three")
fuel_injectors["Three"] = new/list
stage_status.Add("Three")
stage_status["Three"] = 0
fuel_injectors.Add("SCRAM")
fuel_injectors["SCRAM"] = new/list
stage_status.Add("SCRAM")
stage_status["SCRAM"] = 0
spawn(0)
for(var/obj/machinery/power/rust_fuel_injector/Injector in world)
if(Injector.stage in fuel_injectors)
var/list/targetlist = fuel_injectors[Injector.stage]
targetlist.Add(Injector)*/
/obj/machinery/computer/rust_fuel_control/attack_ai(mob/user)
attack_hand(user)
/obj/machinery/computer/rust_fuel_control/attack_hand(mob/user)
add_fingerprint(user)
interact(user)
/obj/machinery/computer/rust_fuel_control/interact(mob/user)
if(stat & (BROKEN|NOPOWER))
user.unset_machine()
user << browse(null, "window=fuel_control")
return
if (!istype(user, /mob/living/silicon) && get_dist(src, user) > 1)
user.unset_machine()
user << browse(null, "window=fuel_control")
return
var/dat = "<B>Reactor Core Fuel Control</B><BR>"
/*dat += "<b>Fuel depletion announcement:</b> "
dat += "[announce_fueldepletion == 0 ? "Disabled" : "<a href='?src=\ref[src];announce_fueldepletion=0'>\[Disable\]</a>"] "
dat += "[announce_fueldepletion == 1 ? "Announcing" : "<a href='?src=\ref[src];announce_fueldepletion=1'>\[Announce\]</a>"] "
dat += "[announce_fueldepletion == 2 ? "Broadcasting" : "<a href='?src=\ref[src];announce_fueldepletion=2'>\[Broadcast\]</a>"]<br>"
dat += "<b>Stage progression announcement:</b> "
dat += "[announce_stageprogression == 0 ? "Disabled" : "<a href='?src=\ref[src];announce_stageprogression=0'>\[Disable\]</a>"] "
dat += "[announce_stageprogression == 1 ? "Announcing" : "<a href='?src=\ref[src];announce_stageprogression=1'>\[Announce\]</a>"] "
dat += "[announce_stageprogression == 2 ? "Broadcasting" : "<a href='?src=\ref[src];announce_stageprogression=2'>\[Broadcast\]</a>"]<br>"*/
dat += "<hr>"
dat += "<b>Detected devices</b> <a href='?src=\ref[src];scan=1'>\[Refresh list\]</a>"
dat += "<table border=1 width='100%'>"
dat += "<tr>"
dat += "<td><b>ID</b></td>"
dat += "<td><b>Assembly</b></td>"
dat += "<td><b>Consumption</b></td>"
dat += "<td><b>Depletion</b></td>"
dat += "<td><b>Duration</b></td>"
dat += "<td><b>Next stage</b></td>"
dat += "<td></td>"
dat += "<td></td>"
dat += "</tr>"
for(var/obj/machinery/power/rust_fuel_injector/I in connected_injectors)
dat += "<tr>"
dat += "<td>[I.id_tag]</td>"
if(I.cur_assembly)
dat += "<td><a href='?src=\ref[I];toggle_injecting=1;update_extern=\ref[src]'>\[[I.injecting ? "Halt injecting" : "Begin injecting"]\]</a></td>"
else
dat += "<td>None</td>"
dat += "<td>[I.fuel_usage * 100]%</td>"
if(I.cur_assembly)
dat += "<td>[I.cur_assembly.percent_depleted * 100]%</td>"
else
dat += "<td>NA</td>"
if(stage_times.Find(I.id_tag))
dat += "<td>[ticks_this_stage]/[stage_times[I.id_tag]]s <a href='?src=\ref[src];stage_time=[I.id_tag]'>Modify</td>"
else
dat += "<td>[ticks_this_stage]s <a href='?src=\ref[src];stage_time=[I.id_tag]'>Set</td>"
if(proceeding_stages.Find(I.id_tag))
dat += "<td><a href='?src=\ref[src];set_next_stage=[I.id_tag]'>[proceeding_stages[I.id_tag]]</a></td>"
else
dat += "<td>None <a href='?src=\ref[src];set_next_stage=[I.id_tag]'>\[modify\]</a></td>"
dat += "<td><a href='?src=\ref[src];toggle_stage=[I.id_tag]'>\[[active_stages.Find(I.id_tag) ? "Deactivate stage" : "Activate stage "] \]</a></td>"
dat += "</tr>"
dat += "</table>"
dat += "<hr>"
dat += "<A href='?src=\ref[src];refresh=1'>Refresh</A> "
dat += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
user << browse(dat, "window=fuel_control;size=800x400")
user.set_machine(src)
/obj/machinery/computer/rust_fuel_control/Topic(href, href_list)
..()
if( href_list["scan"] )
connected_injectors = list()
for(var/obj/machinery/power/rust_fuel_injector/I in range(scan_range, src))
if(check_injector_status(I))
connected_injectors.Add(I)
if( href_list["toggle_stage"] )
var/cur_stage = href_list["toggle_stage"]
if(active_stages.Find(cur_stage))
active_stages.Remove(cur_stage)
for(var/obj/machinery/power/rust_fuel_injector/I in connected_injectors)
if(I.id_tag == cur_stage && check_injector_status(I))
I.StopInjecting()
else
active_stages.Add(cur_stage)
for(var/obj/machinery/power/rust_fuel_injector/I in connected_injectors)
if(I.id_tag == cur_stage && check_injector_status(I))
I.BeginInjecting()
if( href_list["cooldown"] )
for(var/obj/machinery/power/rust_fuel_injector/I in connected_injectors)
if(check_injector_status(I))
I.StopInjecting()
active_stages = list()
if( href_list["warmup"] )
for(var/obj/machinery/power/rust_fuel_injector/I in connected_injectors)
if(check_injector_status(I))
I.BeginInjecting()
if(!active_stages.Find(I.id_tag))
active_stages.Add(I.id_tag)
if( href_list["stage_time"] )
var/cur_stage = href_list["stage_time"]
var/new_duration = input("Enter new stage duration in seconds", "Stage duration") as num
if(new_duration)
stage_times[cur_stage] = new_duration
else if(stage_times.Find(cur_stage))
stage_times.Remove(cur_stage)
if( href_list["announce_fueldepletion"] )
announce_fueldepletion = text2num(href_list["announce_fueldepletion"])
if( href_list["announce_stageprogression"] )
announce_stageprogression = text2num(href_list["announce_stageprogression"])
if( href_list["close"] )
usr << browse(null, "window=fuel_control")
usr.unset_machine()
if( href_list["set_next_stage"] )
var/cur_stage = href_list["set_next_stage"]
if(!proceeding_stages.Find(cur_stage))
proceeding_stages.Add(cur_stage)
var/next_stage = input("Enter next stage ID", "Automated stage procession") as text|null
if(next_stage)
proceeding_stages[cur_stage] = next_stage
else
proceeding_stages.Remove(cur_stage)
updateDialog()
/obj/machinery/computer/rust_fuel_control/proc/check_injector_status(var/obj/machinery/power/rust_fuel_injector/I)
if(!I)
return 0
if(I.stat & (BROKEN|NOPOWER) || !I.remote_access_enabled || !I.id_tag)
if(connected_injectors.Find(I))
connected_injectors.Remove(I)
return 0
return 1

View File

@@ -0,0 +1,307 @@
/obj/machinery/power/rust_fuel_injector
name = "Fuel Injector"
icon = 'icons/rust.dmi'
icon_state = "injector0"
density = 1
anchored = 0
var/state = 0
var/locked = 0
req_access = list(access_engine)
var/obj/item/weapon/fuel_assembly/cur_assembly
var/fuel_usage = 0.0001 //percentage of available fuel to use per cycle
var/id_tag = "One"
var/injecting = 0
var/trying_to_swap_fuel = 0
use_power = 1
idle_power_usage = 10
active_power_usage = 500
var/remote_access_enabled = 1
var/cached_power_avail = 0
var/emergency_insert_ready = 0
/obj/machinery/power/rust_fuel_injector/process()
if(injecting)
if(stat & (BROKEN|NOPOWER))
StopInjecting()
else
Inject()
cached_power_avail = avail()
/obj/machinery/power/rust_fuel_injector/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/weapon/wrench))
if(injecting)
user << "Turn off the [src] first."
return
switch(state)
if(0)
state = 1
playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
user.visible_message("[user.name] secures [src.name] to the floor.", \
"You secure the external reinforcing bolts to the floor.", \
"You hear a ratchet")
src.anchored = 1
if(1)
state = 0
playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1)
user.visible_message("[user.name] unsecures [src.name] reinforcing bolts from the floor.", \
"You undo the external reinforcing bolts.", \
"You hear a ratchet")
src.anchored = 0
if(2)
user << "\red The [src.name] needs to be unwelded from the floor."
return
if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(injecting)
user << "Turn off the [src] first."
return
switch(state)
if(0)
user << "\red The [src.name] needs to be wrenched to the floor."
if(1)
if (WT.remove_fuel(0,user))
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
user.visible_message("[user.name] starts to weld the [src.name] to the floor.", \
"You start to weld the [src] to the floor.", \
"You hear welding")
if (do_after(user,20))
if(!src || !WT.isOn()) return
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)
if (WT.remove_fuel(0,user))
playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1)
user.visible_message("[user.name] starts to cut the [src.name] free from the floor.", \
"You start to cut the [src] free from the floor.", \
"You hear welding")
if (do_after(user,20))
if(!src || !WT.isOn()) return
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
if(istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda))
if(emagged)
user << "\red The lock seems to be broken"
return
if(src.allowed(user))
src.locked = !src.locked
user << "The controls are now [src.locked ? "locked." : "unlocked."]"
else
user << "\red Access denied."
return
if(istype(W, /obj/item/weapon/card/emag) && !emagged)
locked = 0
emagged = 1
user.visible_message("[user.name] emags the [src.name].","\red You short out the lock.")
return
if(istype(W, /obj/item/weapon/fuel_assembly) && !cur_assembly)
if(emergency_insert_ready)
cur_assembly = W
user.drop_item()
W.loc = src
emergency_insert_ready = 0
return
..()
return
/obj/machinery/power/rust_fuel_injector/attack_ai(mob/user)
attack_hand(user)
/obj/machinery/power/rust_fuel_injector/attack_hand(mob/user)
add_fingerprint(user)
interact(user)
/obj/machinery/power/rust_fuel_injector/interact(mob/user)
if(stat & BROKEN)
user.unset_machine()
user << browse(null, "window=fuel_injector")
return
if(get_dist(src, user) > 1 )
if (!istype(user, /mob/living/silicon))
user.unset_machine()
user << browse(null, "window=fuel_injector")
return
var/dat = ""
if (stat & NOPOWER || locked || state != 2)
dat += "<i>The console is dark and nonresponsive.</i>"
else
dat += "<B>Reactor Core Fuel Injector</B><hr>"
dat += "<b>Device ID tag:</b> [id_tag] <a href='?src=\ref[src];modify_tag=1'>\[Modify\]</a><br>"
dat += "<b>Status:</b> [injecting ? "<font color=green>Active</font> <a href='?src=\ref[src];toggle_injecting=1'>\[Disable\]</a>" : "<font color=blue>Standby</font> <a href='?src=\ref[src];toggle_injecting=1'>\[Enable\]</a>"]<br>"
dat += "<b>Fuel usage:</b> [fuel_usage*100]% <a href='?src=\ref[src];fuel_usage=1'>\[Modify\]</a><br>"
dat += "<b>Fuel assembly port:</b> "
dat += "<a href='?src=\ref[src];fuel_assembly=1'>\[[cur_assembly ? "Eject assembly to port" : "Draw assembly from port"]\]</a> "
if(cur_assembly)
dat += "<a href='?src=\ref[src];emergency_fuel_assembly=1'>\[Emergency eject\]</a><br>"
else
dat += "<a href='?src=\ref[src];emergency_fuel_assembly=1'>\[[emergency_insert_ready ? "Cancel emergency insertion" : "Emergency insert"]\]</a><br>"
var/font_colour = "green"
if(cached_power_avail < active_power_usage)
font_colour = "red"
else if(cached_power_avail < active_power_usage * 2)
font_colour = "orange"
dat += "<b>Power status:</b> <font color=[font_colour]>[active_power_usage]/[cached_power_avail] W</font><br>"
dat += "<a href='?src=\ref[src];toggle_remote=1'>\[[remote_access_enabled ? "Disable remote access" : "Enable remote access"]\]</a><br>"
dat += "<hr>"
dat += "<A href='?src=\ref[src];refresh=1'>Refresh</A> "
dat += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
user << browse(dat, "window=fuel_injector;size=500x300")
onclose(user, "fuel_injector")
user.set_machine(src)
/obj/machinery/power/rust_fuel_injector/Topic(href, href_list)
..()
if( href_list["modify_tag"] )
id_tag = input("Enter new ID tag", "Modifying ID tag") as text|null
if( href_list["fuel_assembly"] )
attempt_fuel_swap()
if( href_list["emergency_fuel_assembly"] )
if(cur_assembly)
cur_assembly.loc = src.loc
cur_assembly = null
//irradiate!
else
emergency_insert_ready = !emergency_insert_ready
if( href_list["toggle_injecting"] )
if(injecting)
StopInjecting()
else
BeginInjecting()
if( href_list["toggle_remote"] )
remote_access_enabled = !remote_access_enabled
if( href_list["fuel_usage"] )
var/new_usage = text2num(input("Enter new fuel usage (0.01% - 100%)", "Modifying fuel usage", fuel_usage * 100))
if(!new_usage)
usr << "\red That's not a valid number."
return
new_usage = max(new_usage, 0.01)
new_usage = min(new_usage, 100)
fuel_usage = new_usage / 100
active_power_usage = 500 + 1000 * fuel_usage
if( href_list["update_extern"] )
var/obj/machinery/computer/rust_fuel_control/C = locate(href_list["update_extern"])
if(C)
C.updateDialog()
if( href_list["close"] )
usr << browse(null, "window=fuel_injector")
usr.unset_machine()
updateDialog()
/obj/machinery/power/rust_fuel_injector/proc/BeginInjecting()
if(!injecting && cur_assembly)
icon_state = "injector1"
injecting = 1
use_power = 1
/obj/machinery/power/rust_fuel_injector/proc/StopInjecting()
if(injecting)
injecting = 0
icon_state = "injector0"
use_power = 0
/obj/machinery/power/rust_fuel_injector/proc/Inject()
if(!injecting)
return
if(cur_assembly)
var/amount_left = 0
for(var/reagent in cur_assembly.rod_quantities)
//world << "checking [reagent]"
if(cur_assembly.rod_quantities[reagent] > 0)
//world << " rods left: [cur_assembly.rod_quantities[reagent]]"
var/amount = cur_assembly.rod_quantities[reagent] * fuel_usage
var/numparticles = round(amount * 1000)
if(numparticles < 1)
numparticles = 1
//world << " amount: [amount]"
//world << " numparticles: [numparticles]"
//
var/obj/effect/accelerated_particle/A = new/obj/effect/accelerated_particle(get_turf(src), dir)
A.particle_type = reagent
A.additional_particles = numparticles - 1
//A.target = target_field
//
cur_assembly.rod_quantities[reagent] -= amount
amount_left += cur_assembly.rod_quantities[reagent]
cur_assembly.percent_depleted = amount_left / 300
flick("injector-emitting",src)
else
StopInjecting()
/obj/machinery/power/rust_fuel_injector/proc/attempt_fuel_swap()
var/rev_dir = reverse_direction(dir)
var/turf/mid = get_step(src, rev_dir)
var/success = 0
for(var/obj/machinery/rust_fuel_assembly_port/check_port in get_step(mid, rev_dir))
if(cur_assembly)
if(!check_port.cur_assembly)
check_port.cur_assembly = cur_assembly
cur_assembly.loc = check_port
cur_assembly = null
check_port.icon_state = "port1"
success = 1
else
if(check_port.cur_assembly)
cur_assembly = check_port.cur_assembly
cur_assembly.loc = src
check_port.cur_assembly = null
check_port.icon_state = "port0"
success = 1
break
if(success)
src.visible_message("\blue \icon[src] a green light flashes on [src].")
updateDialog()
else
src.visible_message("\red \icon[src] a red light flashes on [src].")
/obj/machinery/power/rust_fuel_injector/verb/rotate_clock()
set category = "Object"
set name = "Rotate Generator (Clockwise)"
set src in view(1)
if (usr.stat || usr.restrained() || anchored)
return
src.set_dir(turn(src.dir, 90))
/obj/machinery/power/rust_fuel_injector/verb/rotate_anticlock()
set category = "Object"
set name = "Rotate Generator (Counterclockwise)"
set src in view(1)
if (usr.stat || usr.restrained() || anchored)
return
src.set_dir(turn(src.dir, -90))

View File

@@ -0,0 +1,160 @@
datum/fusion_reaction
var/primary_reactant = ""
var/secondary_reactant = ""
var/energy_consumption = 0
var/energy_production = 0
var/radiation = 0
var/list/products = list()
/datum/controller/game_controller/var/list/fusion_reactions
proc/get_fusion_reaction(var/primary_reactant, var/secondary_reactant)
if(!master_controller.fusion_reactions)
populate_fusion_reactions()
if(master_controller.fusion_reactions.Find(primary_reactant))
var/list/secondary_reactions = master_controller.fusion_reactions[primary_reactant]
if(secondary_reactions.Find(secondary_reactant))
return master_controller.fusion_reactions[primary_reactant][secondary_reactant]
proc/populate_fusion_reactions()
if(!master_controller.fusion_reactions)
master_controller.fusion_reactions = list()
for(var/cur_reaction_type in typesof(/datum/fusion_reaction) - /datum/fusion_reaction)
var/datum/fusion_reaction/cur_reaction = new cur_reaction_type()
if(!master_controller.fusion_reactions[cur_reaction.primary_reactant])
master_controller.fusion_reactions[cur_reaction.primary_reactant] = list()
master_controller.fusion_reactions[cur_reaction.primary_reactant][cur_reaction.secondary_reactant] = cur_reaction
if(!master_controller.fusion_reactions[cur_reaction.secondary_reactant])
master_controller.fusion_reactions[cur_reaction.secondary_reactant] = list()
master_controller.fusion_reactions[cur_reaction.secondary_reactant][cur_reaction.primary_reactant] = cur_reaction
//Fake elements and fake reactions, but its nicer gameplay-wise
//Deuterium
//Tritium
//Uridium-3
//Obdurium
//Solonium
//Rodinium-6
//Dilithium
//Trilithium
//Pergium
//Stravium-7
//Primary Production Reactions
datum/fusion_reaction/tritium_deuterium
primary_reactant = "Tritium"
secondary_reactant = "Deuterium"
energy_consumption = 1
energy_production = 5
radiation = 0
//Secondary Production Reactions
datum/fusion_reaction/deuterium_deuterium
primary_reactant = "Deuterium"
secondary_reactant = "Deuterium"
energy_consumption = 1
energy_production = 4
radiation = 1
products = list("Obdurium" = 2)
datum/fusion_reaction/tritium_tritium
primary_reactant = "Tritium"
secondary_reactant = "Tritium"
energy_consumption = 1
energy_production = 4
radiation = 1
products = list("Solonium" = 2)
//Cleanup Reactions
datum/fusion_reaction/rodinium6_obdurium
primary_reactant = "Rodinium-6"
secondary_reactant = "Obdurium"
energy_consumption = 1
energy_production = 2
radiation = 2
datum/fusion_reaction/rodinium6_solonium
primary_reactant = "Rodinium-6"
secondary_reactant = "Solonium"
energy_consumption = 1
energy_production = 2
radiation = 2
//Breeder Reactions
datum/fusion_reaction/dilithium_obdurium
primary_reactant = "Dilithium"
secondary_reactant = "Obdurium"
energy_consumption = 1
energy_production = 1
radiation = 3
products = list("Deuterium" = 1, "Dilithium" = 1)
datum/fusion_reaction/dilithium_solonium
primary_reactant = "Dilithium"
secondary_reactant = "Solonium"
energy_consumption = 1
energy_production = 1
radiation = 3
products = list("Tritium" = 1, "Dilithium" = 1)
//Breeder Inhibitor Reactions
datum/fusion_reaction/stravium7_dilithium
primary_reactant = "Stravium-7"
secondary_reactant = "Dilithium"
energy_consumption = 2
energy_production = 1
radiation = 4
//Enhanced Breeder Reactions
datum/fusion_reaction/trilithium_obdurium
primary_reactant = "Trilithium"
secondary_reactant = "Obdurium"
energy_consumption = 1
energy_production = 2
radiation = 5
products = list("Dilithium" = 1, "Trilithium" = 1, "Deuterium" = 1)
datum/fusion_reaction/trilithium_solonium
primary_reactant = "Trilithium"
secondary_reactant = "Solonium"
energy_consumption = 1
energy_production = 2
radiation = 5
products = list("Dilithium" = 1, "Trilithium" = 1, "Tritium" = 1)
//Control Reactions
datum/fusion_reaction/pergium_deuterium
primary_reactant = "Pergium"
secondary_reactant = "Deuterium"
energy_consumption = 5
energy_production = 0
radiation = 5
datum/fusion_reaction/pergium_tritium
primary_reactant = "Pergium"
secondary_reactant = "Tritium"
energy_consumption = 5
energy_production = 0
radiation = 5
datum/fusion_reaction/pergium_obdurium
primary_reactant = "Pergium"
secondary_reactant = "Obdurium"
energy_consumption = 5
energy_production = 0
radiation = 5
datum/fusion_reaction/pergium_solonium
primary_reactant = "Pergium"
secondary_reactant = "Solonium"
energy_consumption = 5
energy_production = 0
radiation = 5

View File

@@ -0,0 +1,188 @@
//high frequency photon (laser beam)
/obj/item/projectile/beam/ehf_beam
/obj/machinery/rust/gyrotron
icon = 'icons/rust.dmi'
icon_state = "emitter-off"
name = "Gyrotron"
anchored = 1
density = 0
layer = 4
var/frequency = 1
var/emitting = 0
var/rate = 10
var/mega_energy = 0.001
var/on = 1
var/remoteenabled = 1
//
req_access = list(access_engine)
//
use_power = 1
idle_power_usage = 10
active_power_usage = 300
New()
..()
//pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
//pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0
Topic(href, href_list)
..()
if( href_list["close"] )
usr << browse(null, "window=gyro_monitor")
usr.machine = null
return
if( href_list["modifypower"] )
var/new_val = text2num(input("Enter new emission power level (0.001 - 0.01)", "Modifying power level (MeV)", mega_energy))
if(!new_val)
usr << "\red That's not a valid number."
return
new_val = min(new_val,0.01)
new_val = max(new_val,0.001)
mega_energy = new_val
for(var/obj/machinery/computer/rust_gyrotron_controller/comp in range(25))
comp.updateDialog()
return
if( href_list["modifyrate"] )
var/new_val = text2num(input("Enter new emission rate (1 - 10)", "Modifying emission rate (sec)", rate))
if(!new_val)
usr << "\red That's not a valid number."
return
new_val = min(new_val,1)
new_val = max(new_val,10)
rate = new_val
for(var/obj/machinery/computer/rust_gyrotron_controller/comp in range(25))
comp.updateDialog()
return
if( href_list["modifyfreq"] )
var/new_val = text2num(input("Enter new emission frequency (1 - 50000)", "Modifying emission frequency (GHz)", frequency))
if(!new_val)
usr << "\red That's not a valid number."
return
new_val = min(new_val,1)
new_val = max(new_val,50000)
frequency = new_val
for(var/obj/machinery/computer/rust_gyrotron_controller/comp in range(25))
comp.updateDialog()
return
if( href_list["activate"] )
emitting = 1
spawn(rate)
Emit()
for(var/obj/machinery/computer/rust_gyrotron_controller/comp in range(25))
comp.updateDialog()
return
if( href_list["deactivate"] )
emitting = 0
for(var/obj/machinery/computer/rust_gyrotron_controller/comp in range(25))
comp.updateDialog()
return
if( href_list["enableremote"] )
remoteenabled = 1
for(var/obj/machinery/computer/rust_gyrotron_controller/comp in range(25))
comp.updateDialog()
return
if( href_list["disableremote"] )
remoteenabled = 0
for(var/obj/machinery/computer/rust_gyrotron_controller/comp in range(25))
comp.updateDialog()
return
/*
var/obj/item/projectile/beam/emitter/A = new /obj/item/projectile/beam/emitter( src.loc )
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
s.set_up(5, 1, src)
s.start()
A.set_dir(src.dir)
if(src.dir == 1)//Up
A.yo = 20
A.xo = 0
else if(src.dir == 2)//Down
A.yo = -20
A.xo = 0
else if(src.dir == 4)//Right
A.yo = 0
A.xo = 20
else if(src.dir == 8)//Left
A.yo = 0
A.xo = -20
else // Any other
A.yo = -20
A.xo = 0
A.fired()
*/
proc/Emit()
var/obj/item/projectile/beam/emitter/A = new /obj/item/projectile/beam/emitter( src.loc )
A.frequency = frequency
A.damage = mega_energy * 500
//
A.icon_state = "emitter"
playsound(src.loc, 'sound/weapons/emitter.ogg', 25, 1)
use_power(100 * mega_energy + 500)
/*if(prob(35))
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
s.set_up(5, 1, src)
s.start()*/
A.set_dir(src.dir)
if(src.dir == 1)//Up
A.yo = 20
A.xo = 0
else if(src.dir == 2)//Down
A.yo = -20
A.xo = 0
else if(src.dir == 4)//Right
A.yo = 0
A.xo = 20
else if(src.dir == 8)//Left
A.yo = 0
A.xo = -20
else // Any other
A.yo = -20
A.xo = 0
A.process()
//
flick("emitter-active",src)
if(emitting)
spawn(rate)
Emit()
proc/UpdateIcon()
if(on)
icon_state = "emitter-on"
else
icon_state = "emitter-off"
/obj/machinery/rust/gyrotron/control_panel
icon_state = "control_panel"
name = "Control panel"
var/obj/machinery/rust/gyrotron/owned_gyrotron
New()
..()
pixel_x = -pixel_x
pixel_y = -pixel_y
interact(mob/user)
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
if (!istype(user, /mob/living/silicon))
user.machine = null
user << browse(null, "window=gyro_monitor")
return
var/t = "<B>Free electron MASER (Gyrotron) Control Panel</B><BR>"
if(owned_gyrotron && owned_gyrotron.on)
t += "<font color=green>Gyrotron operational</font><br>"
t += "Operational mode: <font color=blue>"
if(owned_gyrotron.emitting)
t += "Emitting</font> <a href='?src=\ref[owned_gyrotron];deactivate=1'>\[Deactivate\]</a><br>"
else
t += "Not emitting</font> <a href='?src=\ref[owned_gyrotron];activate=1'>\[Activate\]</a><br>"
t += "Emission rate: [owned_gyrotron.rate] <a href='?src=\ref[owned_gyrotron];modifyrate=1'>\[Modify\]</a><br>"
t += "Beam frequency: [owned_gyrotron.frequency] <a href='?src=\ref[owned_gyrotron];modifyfreq=1'>\[Modify\]</a><br>"
t += "Beam power: [owned_gyrotron.mega_energy] <a href='?src=\ref[owned_gyrotron];modifypower=1'>\[Modify\]</a><br>"
else
t += "<b><font color=red>Gyrotron unresponsive</font></b>"
t += "<hr>"
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
user << browse(t, "window=gyro_monitor;size=500x800")
user.machine = src

View File

@@ -0,0 +1,88 @@
/obj/machinery/computer/rust_gyrotron_controller
name = "Gyrotron Remote Controller"
icon = 'icons/rust.dmi'
icon_state = "engine"
var/updating = 1
New()
..()
Topic(href, href_list)
..()
if( href_list["close"] )
usr << browse(null, "window=gyrotron_controller")
usr.machine = null
return
if( href_list["target"] )
var/obj/machinery/rust/gyrotron/gyro = locate(href_list["target"])
gyro.Topic(href, href_list)
return
process()
..()
if(updating)
src.updateDialog()
interact(mob/user)
if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
if (!istype(user, /mob/living/silicon))
user.machine = null
user << browse(null, "window=gyrotron_controller")
return
var/t = "<B>Gyrotron Remote Control Console</B><BR>"
t += "<hr>"
for(var/obj/machinery/rust/gyrotron/gyro in world)
if(gyro.remoteenabled && gyro.on)
t += "<font color=green>Gyrotron operational</font><br>"
t += "Operational mode: <font color=blue>"
if(gyro.emitting)
t += "Emitting</font> <a href='?src=\ref[gyro];deactivate=1'>\[Deactivate\]</a><br>"
else
t += "Not emitting</font> <a href='?src=\ref[gyro];activate=1'>\[Activate\]</a><br>"
t += "Emission rate: [gyro.rate] <a href='?src=\ref[gyro];modifyrate=1'>\[Modify\]</a><br>"
t += "Beam frequency: [gyro.frequency] <a href='?src=\ref[gyro];modifyfreq=1'>\[Modify\]</a><br>"
t += "Beam power: [gyro.mega_energy] <a href='?src=\ref[gyro];modifypower=1'>\[Modify\]</a><br>"
else
t += "<b><font color=red>Gyrotron unresponsive</font></b>"
t += "<hr>"
/*
var/t = "<B>Reactor Core Fuel Control</B><BR>"
t += "Current fuel injection stage: [active_stage]<br>"
if(active_stage == "Cooling")
//t += "<a href='?src=\ref[src];restart=1;'>Restart injection cycle</a><br>"
t += "----<br>"
else
t += "<a href='?src=\ref[src];cooldown=1;'>Enter cooldown phase</a><br>"
t += "Fuel depletion announcement: "
t += "[announce_fueldepletion ? "<a href='?src=\ref[src];disable_fueldepletion=1'>Disable</a>" : "<b>Disabled</b>"] "
t += "[announce_fueldepletion == 1 ? "<b>Announcing</b>" : "<a href='?src=\ref[src];announce_fueldepletion=1'>Announce</a>"] "
t += "[announce_fueldepletion == 2 ? "<b>Broadcasting</b>" : "<a href='?src=\ref[src];broadcast_fueldepletion=1'>Broadcast</a>"]<br>"
t += "Stage progression announcement: "
t += "[announce_stageprogression ? "<a href='?src=\ref[src];disable_stageprogression=1'>Disable</a>" : "<b>Disabled</b>"] "
t += "[announce_stageprogression == 1 ? "<b>Announcing</b>" : "<a href='?src=\ref[src];announce_stageprogression=1'>Announce</a>"] "
t += "[announce_stageprogression == 2 ? "<b>Broadcasting</b>" : "<a href='?src=\ref[src];broadcast_stageprogression=1'>Broadcast</a>"] "
t += "<hr>"
t += "<table border=1><tr>"
t += "<td><b>Injector Status</b></td>"
t += "<td><b>Injection interval (sec)</b></td>"
t += "<td><b>Assembly consumption per injection</b></td>"
t += "<td><b>Fuel Assembly Port</b></td>"
t += "<td><b>Assembly depletion percentage</b></td>"
t += "</tr>"
for(var/stage in fuel_injectors)
var/list/cur_stage = fuel_injectors[stage]
t += "<tr><td colspan=5><b>Fuel Injection Stage:</b> <font color=blue>[stage]</font> [active_stage == stage ? "<font color=green> (Currently active)</font>" : "<a href='?src=\ref[src];beginstage=[stage]'>Activate</a>"]</td></tr>"
for(var/obj/machinery/rust/fuel_injector/Injector in cur_stage)
t += "<tr>"
t += "<td>[Injector.on && Injector.remote_enabled ? "<font color=green>Operational</font>" : "<font color=red>Unresponsive</font>"]</td>"
t += "<td>[Injector.rate/10] <a href='?src=\ref[Injector];cyclerate=1'>Modify</a></td>"
t += "<td>[Injector.fuel_usage*100]% <a href='?src=\ref[Injector];fuel_usage=1'>Modify</a></td>"
t += "<td>[Injector.owned_assembly_port ? "[Injector.owned_assembly_port.cur_assembly ? "<font color=green>Loaded</font>": "<font color=blue>Empty</font>"]" : "<font color=red>Disconnected</font>" ]</td>"
t += "<td>[Injector.owned_assembly_port && Injector.owned_assembly_port.cur_assembly ? "[Injector.owned_assembly_port.cur_assembly.amount_depleted*100]%" : ""]</td>"
t += "</tr>"
t += "</table>"
*/
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
user << browse(t, "window=gyrotron_controller;size=500x400")
user.machine = src

View File

@@ -0,0 +1,74 @@
/obj/machinery/rust/rad_source
var/mega_energy = 0
var/time_alive = 0
var/source_alive = 2
New()
..()
process()
..()
//fade away over time
if(source_alive > 0)
time_alive++
source_alive--
else
time_alive -= 0.1
if(time_alive < 0)
del(src)
//radiate mobs nearby here
//
/*
/obj/machinery/rust
proc/RadiateParticle(var/energy, var/ionizing, var/dir = 0)
if(!dir)
RadiateParticleRand(energy, ionizing)
var/obj/effect/accelerated_particle/particle = new
particle.set_dir(dir)
particle.ionizing = ionizing
if(energy)
particle.energy = energy
//particle.invisibility = 2
//
return particle
proc/RadiateParticleRand(var/energy, var/ionizing)
var/turf/target
var/particle_range = 3 * round(energy) + rand(3,20)
if(energy > 1)
//for penetrating radiation
for(var/mob/M in range(particle_range))
var/dist_ratio = particle_range / get_dist(M, src)
//particles are more likely to hit a person if the person is closer
// 1/8 = 12.5% (closest)
// 1/360 = 0.27% (furthest)
// variation of 12.2%
if( rand() < (0.25 + dist_ratio * 12.5) )
target = get_turf(M)
break
if(!target)
target = pick(range(particle_range))
else
//for slower, non-penetrating radiation
for(var/mob/M in view(particle_range))
var/dist_ratio = particle_range / get_dist(M, src)
if( rand() < (0.25 + dist_ratio * 12.5) )
target = get_turf(M)
break
if(!target)
target = pick(view(particle_range))
var/obj/effect/accelerated_particle/particle = new
particle.target = target
particle.ionizing = ionizing
if(energy)
particle.energy = energy
//particle.invisibility = 2
//
return particle
*/
/obj/machinery/computer/rust_radiation_monitor
name = "Radiation Monitor"
icon_state = "power"

View File

@@ -0,0 +1,53 @@
//gimmicky hack to collect particles and direct them into the field
/obj/effect/rust_particle_catcher
icon = 'icons/effects/effects.dmi'
density = 0
anchored = 1
layer = 4
var/obj/effect/rust_em_field/parent
var/mysize = 0
invisibility = 101
/*/obj/effect/rust_particle_catcher/New()
for(var/obj/machinery/rust/em_field/field in range(6))
parent = field
if(!parent)
del(src)*/
/obj/effect/rust_particle_catcher/process()
if(!parent)
del(src)
/obj/effect/rust_particle_catcher/proc/SetSize(var/newsize)
name = "collector [newsize]"
mysize = newsize
UpdateSize()
/obj/effect/rust_particle_catcher/proc/AddParticles(var/name, var/quantity = 1)
if(parent && parent.size >= mysize)
parent.AddParticles(name, quantity)
return 1
return 0
/obj/effect/rust_particle_catcher/proc/UpdateSize()
if(parent.size >= mysize)
density = 1
//invisibility = 0
name = "collector [mysize] ON"
else
density = 0
//invisibility = 101
name = "collector [mysize] OFF"
/obj/effect/rust_particle_catcher/bullet_act(var/obj/item/projectile/Proj)
if(Proj.flag != "bullet" && parent)
parent.AddEnergy(Proj.damage * 20, 0, 1)
update_icon()
return 0
/obj/effect/rust_particle_catcher/Bumped(atom/AM)
if(ismob(AM) && density && prob(10))
AM << "\red A powerful force pushes you back."
..()

View File

@@ -26,7 +26,7 @@
if(BB)
if(initial(BB.name) == "bullet")
var/tmp_label = ""
var/label_text = sanitize(input(user, "Inscribe some text into \the [initial(BB.name)]","Inscription",tmp_label))
var/label_text = sanitize(copytext(input(user, "Inscribe some text into \the [initial(BB.name)]","Inscription",tmp_label), 1, MAX_NAME_LEN))
if(length(label_text) > 20)
user << "\red The inscription can be at most 20 characters long."
else

View File

@@ -646,7 +646,7 @@
if(type in diseases) // Make sure this is a disease
D = new type(0, null)
var/list/data = list("viruses"=list(D))
var/name = sanitize(input(usr,"Name:","Name the culture",D.name))
var/name = sanitize(copytext(input(usr,"Name:","Name the culture",D.name), 1, MAX_NAME_LEN))
if(!name || name == " ") name = D.name
B.name = "[name] culture bottle"
B.desc = "A small bottle. Contains [D.agent] culture in synthblood medium."

View File

@@ -137,7 +137,7 @@
attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/pen) || istype(W, /obj/item/device/flashlight/pen))
var/tmp_label = sanitize(input(user, "Enter a label for [src.name]","Label",src.label_text))
var/tmp_label = sanitize(copytext(input(user, "Enter a label for [src.name]","Label",src.label_text), 1, MAX_NAME_LEN))
if(length(tmp_label) > 10)
user << "\red The label can be at most 10 characters long."
else

View File

@@ -43,7 +43,7 @@
else if(istype(W, /obj/item/weapon/pen))
switch(alert("What would you like to alter?",,"Title","Description", "Cancel"))
if("Title")
var/str = trim(copytext(sanitize(input(usr,"Label text?","Set label","")),1,MAX_NAME_LEN))
var/str = trim(sanitize(copytext(input(usr,"Label text?","Set label",""),1,MAX_NAME_LEN)))
if(!str || !length(str))
usr << "<span class='warning'> Invalid text.</span>"
return
@@ -57,7 +57,7 @@
else
nameset = 1
if("Description")
var/str = trim(copytext(sanitize(input(usr,"Label text?","Set label","")),1,MAX_MESSAGE_LEN))
var/str = trim(sanitize(copytext(input(usr,"Label text?","Set label",""),1,MAX_MESSAGE_LEN)))
if(!str || !length(str))
usr << "\red Invalid text."
return
@@ -150,7 +150,7 @@
else if(istype(W, /obj/item/weapon/pen))
switch(alert("What would you like to alter?",,"Title","Description", "Cancel"))
if("Title")
var/str = trim(copytext(sanitize(input(usr,"Label text?","Set label","")),1,MAX_NAME_LEN))
var/str = trim(sanitize(copytext(input(usr,"Label text?","Set label",""),1,MAX_NAME_LEN)))
if(!str || !length(str))
usr << "<span class='warning'> Invalid text.</span>"
return
@@ -165,7 +165,7 @@
nameset = 1
if("Description")
var/str = trim(copytext(sanitize(input(usr,"Label text?","Set label","")),1,MAX_MESSAGE_LEN))
var/str = trim(sanitize(copytext(input(usr,"Label text?","Set label",""),1,MAX_MESSAGE_LEN)))
if(!str || !length(str))
usr << "\red Invalid text."
return
@@ -304,7 +304,7 @@
examine(mob/user)
if(..(user, 0))
user << "\blue There are [amount] units of package wrap left!"
return

View File

@@ -26,9 +26,7 @@
/mob/living/simple_animal/hostile/giant_spider/nurse,\
/mob/living/simple_animal/hostile/alien,\
/mob/living/simple_animal/hostile/bear,\
/mob/living/simple_animal/hostile/creature,\
/mob/living/simple_animal/hostile/panther,\
/mob/living/simple_animal/hostile/snake\
/mob/living/simple_animal/hostile/creature\
)
else
spawn_type = pick(\

View File

@@ -5,7 +5,7 @@
icon_state = "samak"
icon_living = "samak"
icon_dead = "samak_dead"
icon = 'code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi'
icon = 'icons/jungle.dmi'
move_to_delay = 2
maxHealth = 125
health = 125
@@ -26,7 +26,7 @@
icon_state = "diyaab"
icon_living = "diyaab"
icon_dead = "diyaab_dead"
icon = 'code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi'
icon = 'icons/jungle.dmi'
move_to_delay = 1
maxHealth = 25
health = 25
@@ -47,7 +47,7 @@
icon_state = "shantak"
icon_living = "shantak"
icon_dead = "shantak_dead"
icon = 'code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi'
icon = 'icons/jungle.dmi'
move_to_delay = 1
maxHealth = 75
health = 75
@@ -66,7 +66,7 @@
icon_state = "yithian"
icon_living = "yithian"
icon_dead = "yithian_dead"
icon = 'code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi'
icon = 'icons/jungle.dmi'
/mob/living/simple_animal/tindalos
name = "tindalos"
@@ -74,4 +74,4 @@
icon_state = "tindalos"
icon_living = "tindalos"
icon_dead = "tindalos_dead"
icon = 'code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi'
icon = 'icons/jungle.dmi'