git-svn-id: http://tgstation13.googlecode.com/svn/trunk@2 316c924e-a436-60f5-8080-3fe189b3f50e

This commit is contained in:
only.lurking
2010-08-23 14:29:20 +00:00
parent 757ea7b077
commit 662c08272a
919 changed files with 136852 additions and 0 deletions
+36
View File
@@ -0,0 +1,36 @@
/proc/getbrokeninhands()
var/icon/IL = new('items_lefthand.dmi')
var/list/Lstates = IL.IconStates()
var/icon/IR = new('items_righthand.dmi')
var/list/Rstates = IR.IconStates()
var/text
for(var/A in typesof(/obj/item))
var/obj/item/O = new A( locate(1,1,1) )
if(!O) continue
var/icon/J = new(O.icon)
var/list/istates = J.IconStates()
if(!Lstates.Find(O.icon_state) && !Lstates.Find(O.item_state))
if(O.icon_state)
text += "[O.type] WANTS IN LEFT HAND CALLED\n\"[O.icon_state]\".\n"
if(!Rstates.Find(O.icon_state) && !Rstates.Find(O.item_state))
if(O.icon_state)
text += "[O.type] WANTS IN RIGHT HAND CALLED\n\"[O.icon_state]\".\n"
if(O.icon_state)
if(!istates.Find(O.icon_state))
text += "[O.type] MISSING NORMAL ICON CALLED\n\"[O.icon_state]\" IN \"[O.icon]\"\n"
if(O.item_state)
if(!istates.Find(O.item_state))
text += "[O.type] MISSING NORMAL ICON CALLED\n\"[O.item_state]\" IN \"[O.icon]\"\n"
text+="\n"
del(O)
if(text)
var/F = file("broken_icons.txt")
fdel(F)
F << text
world << "Completely successfully and written to [F]"
+188
View File
@@ -0,0 +1,188 @@
/obj/item/weapon/storage/photo_album
name = "Photo album"
icon = 'old_or_unused.dmi'
icon_state = "album"
item_state = "briefcase"
/obj/item/weapon/storage/photo_album/MouseDrop(obj/over_object as obj)
if ((istype(usr, /mob/living/carbon/human) || (ticker && ticker.mode.name == "monkey")))
var/mob/M = usr
if (!( istype(over_object, /obj/screen) ))
return ..()
playsound(src.loc, "rustle", 50, 1, -5)
if ((!( M.restrained() ) && !( M.stat ) && M.back == src))
if (over_object.name == "r_hand")
if (!( M.r_hand ))
M.u_equip(src)
M.r_hand = src
else
if (over_object.name == "l_hand")
if (!( M.l_hand ))
M.u_equip(src)
M.l_hand = src
M.update_clothing()
src.add_fingerprint(usr)
return
if(over_object == usr && in_range(src, usr) || usr.contents.Find(src))
if (usr.s_active)
usr.s_active.close(usr)
src.show_to(usr)
return
return
/obj/item/weapon/storage/photo_album/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (src.contents.len >= 7)
return
if (!istype(W,/obj/item/weapon/photo))
user << "\red You can only put photos in a photo album."
return
var/t
for(var/obj/item/weapon/O in src)
t += O.w_class
playsound(src.loc, "rustle", 50, 1, -5)
user.u_equip(W)
W.loc = src
if ((user.client && user.s_active != src))
user.client.screen -= W
src.orient2hud(user)
W.dropped(user)
add_fingerprint(user)
for(var/mob/O in viewers(user, null))
O.show_message(text("\blue [] has added [] to []!", user, W, src), 1)
return
/obj/item/weapon/camera_test
name = "camera"
icon = 'old_or_unused.dmi'
desc = "A one use - polaroid camera. 10 photos left."
icon_state = "camera"
item_state = "electropack"
w_class = 2.0
flags = 466.0
m_amt = 2000
throwforce = 5
throw_speed = 4
throw_range = 10
var/pictures_left = 10
var/can_use = 1
/obj/item/weapon/photo
name = "photo"
icon = 'old_or_unused.dmi'
icon_state = "photo"
item_state = "clipboard"
w_class = 1.0
//////////////////////////////////////////////////////////////////////////////////////////////////
/obj/item/weapon/camera_test/proc/build_composite_icon(var/atom/C)
var/icon/composite = icon(C.icon, C.icon_state, C.dir, 1)
for(var/O in C.overlays)
var/image/I = O
composite.Blend(icon(I.icon, I.icon_state, I.dir, 1), ICON_OVERLAY)
return composite
//////////////////////////////////////////////////////////////////////////////////////////////////
/obj/item/weapon/camera_test/attack(mob/living/carbon/human/M as mob, mob/user as mob)
return
/obj/item/weapon/camera_test/afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag)
if (!can_use || !pictures_left || ismob(target.loc)) return
var/turf/the_turf = get_turf(target)
var/icon/photo = icon('old_or_unused.dmi',"photo")
var/icon/turficon = build_composite_icon(the_turf)
turficon.Scale(22,20)
photo.Blend(turficon,ICON_OVERLAY,6,8)
var/mob_title = null
var/mob_detail = null
var/item_title = null
var/item_detail = null
var/itemnumber = 0
for(var/atom/A in the_turf)
if(A.invisibility) continue
if(ismob(A))
var/icon/X = build_composite_icon(A)
X.Scale(22,20)
photo.Blend(X,ICON_OVERLAY,6,8)
del(X)
if(!mob_title)
mob_title = "[A]"
else
mob_title += " and [A]"
if(!mob_detail)
var/holding = null
if(istype(A, /mob/living/carbon))
var/mob/living/carbon/temp = A
if(temp.l_hand || temp.r_hand)
if(temp.l_hand) holding = "They are holding \a [temp.l_hand]"
if(temp.r_hand)
if(holding)
holding += " and \a [temp.r_hand]."
else
holding = "They are holding \a [temp.r_hand]."
if(!mob_detail)
mob_detail = "You can see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]"
else
mob_detail += "You can also see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]"
else
if(itemnumber < 5)
var/icon/X = build_composite_icon(A)
X.Scale(22,20)
photo.Blend(X,ICON_OVERLAY,6,8)
del(X)
itemnumber++
if(!item_title)
item_title = " \a [A]"
else
item_title = " some objects"
if(!item_detail)
item_detail = "\a [A]"
else
item_detail += " and \a [A]"
var/finished_title = null
var/finished_detail = null
if(!item_title && !mob_title)
finished_title = "boring photo"
finished_detail = "This is a pretty boring photo of \a [the_turf]."
else
if(mob_title)
finished_title = "photo of [mob_title][item_title ? " and[item_title]":""]"
finished_detail = "[mob_detail][item_detail ? " Theres also [item_detail].":"."]"
else if(item_title)
finished_title = "photo of[item_title]"
finished_detail = "You can see [item_detail]."
var/obj/item/weapon/photo/P = new/obj/item/weapon/photo( get_turf(src) )
P.icon = photo
P.name = finished_title
P.desc = finished_detail
playsound(src.loc, pick('polaroid1.ogg','polaroid2.ogg'), 75, 1, -3)
pictures_left--
src.desc = "A one use - polaroid camera. [pictures_left] photos left."
user << "\blue [pictures_left] photos left."
can_use = 0
spawn(50) can_use = 1
+235
View File
@@ -0,0 +1,235 @@
#define TOUCH 1
#define INGEST 2
///////////////////////////////////////////////////////////////////////////////////
datum
reagents
var/list/reagent_list = new/list()
var/total_volume = 0
var/maximum_volume = 100
var/atom/my_atom = null
New(maximum=100)
maximum_volume = maximum
proc
remove_any(var/amount=1)
var/total_transfered = 0
var/current_list_element = 1
current_list_element = rand(1,reagent_list.len)
while(total_transfered != amount)
if(total_transfered >= amount) break
if(total_volume <= 0 || !reagent_list.len) break
if(current_list_element > reagent_list.len) current_list_element = 1
var/datum/reagent/current_reagent = reagent_list[current_list_element]
src.remove_reagent(current_reagent.id, 1)
current_list_element++
total_transfered++
src.update_total()
handle_reactions()
return total_transfered
get_master_reagent_name()
var/the_name = null
var/the_volume = 0
for(var/datum/reagent/A in reagent_list)
if(A.volume > the_volume)
the_volume = A.volume
the_name = A.name
return the_name
trans_to(var/obj/target, var/amount=1, var/multiplier=1)
var/total_transfered = 0
var/current_list_element = 1
var/datum/reagents/R = target.reagents
//if(R.total_volume + amount > R.maximum_volume) return 0
current_list_element = rand(1,reagent_list.len) //Eh, bandaid fix.
while(total_transfered != amount)
if(total_transfered >= amount) break //Better safe than sorry.
if(total_volume <= 0 || !reagent_list.len) break
if(R.total_volume >= R.maximum_volume) break
if(current_list_element > reagent_list.len) current_list_element = 1
var/datum/reagent/current_reagent = reagent_list[current_list_element]
R.add_reagent(current_reagent.id, (1 * multiplier) )
src.remove_reagent(current_reagent.id, 1)
current_list_element++
total_transfered++
src.update_total()
R.update_total()
R.handle_reactions()
handle_reactions()
return total_transfered
metabolize(var/mob/M)
for(var/A in reagent_list)
var/datum/reagent/R = A
R.on_mob_life(M)
update_total()
handle_reactions()
if(ismob(my_atom)) return //No reactions inside mobs :I
for(var/A in typesof(/datum/chemical_reaction) - /datum/chemical_reaction)
var/datum/chemical_reaction/C = new A()
var/total_required_reagents = C.required_reagents.len
var/total_matching_reagents = 0
var/list/multipliers = new/list()
for(var/B in C.required_reagents)
if(has_reagent(B, C.required_reagents[B]))
total_matching_reagents++
multipliers += round(get_reagent_amount(B) / C.required_reagents[B])
if(total_matching_reagents == total_required_reagents)
var/multiplier = min(multipliers)
for(var/B in C.required_reagents)
del_reagent(B)
var/created_volume = C.result_amount*multiplier
if(C.result)
multiplier = max(multiplier, 1) //this shouldnt happen ...
add_reagent(C.result, C.result_amount*multiplier)
for(var/mob/M in viewers(4, get_turf(my_atom)) )
M << "\blue \icon[my_atom] The solution begins to bubble."
playsound(get_turf(my_atom), 'bubbles.ogg', 80, 1)
C.on_reaction(src, created_volume)
update_total()
return 0
isolate_reagent(var/reagent)
for(var/A in reagent_list)
var/datum/reagent/R = A
if (R.id != reagent)
del_reagent(R.id)
update_total()
del_reagent(var/reagent)
for(var/A in reagent_list)
var/datum/reagent/R = A
if (R.id == reagent)
reagent_list -= A
del(A)
update_total()
my_atom.on_reagent_change()
return 0
return 1
update_total()
total_volume = 0
for(var/datum/reagent/R in reagent_list)
if(R.volume < 1)
del_reagent(R.id)
else
total_volume += R.volume
return 0
clear_reagents()
for(var/datum/reagent/R in reagent_list)
del_reagent(R.id)
return 0
reaction(var/atom/A, var/method=TOUCH, var/volume_modifier=0)
switch(method)
if(TOUCH)
for(var/datum/reagent/R in reagent_list)
if(ismob(A)) spawn(0) R.reaction_mob(A, TOUCH, R.volume+volume_modifier)
if(isturf(A)) spawn(0) R.reaction_turf(A, R.volume+volume_modifier)
if(isobj(A)) spawn(0) R.reaction_obj(A, R.volume+volume_modifier)
if(INGEST)
for(var/datum/reagent/R in reagent_list)
if(ismob(A)) spawn(0) R.reaction_mob(A, INGEST, R.volume+volume_modifier)
if(isturf(A)) spawn(0) R.reaction_turf(A, R.volume+volume_modifier)
if(isobj(A)) spawn(0) R.reaction_obj(A, R.volume+volume_modifier)
return
add_reagent(var/reagent, var/amount)
if(!isnum(amount)) return 1
update_total()
if(total_volume + amount > maximum_volume) amount = (maximum_volume - total_volume) //Doesnt fit in. Make it disappear. Shouldnt happen. Will happen.
for(var/A in reagent_list)
var/datum/reagent/R = A
if (R.id == reagent)
R.volume += amount
update_total()
my_atom.on_reagent_change()
return 0
for(var/A in typesof(/datum/reagent) - /datum/reagent)
var/datum/reagent/R = new A()
if (R.id == reagent)
reagent_list += R
R.holder = src
R.volume = amount
update_total()
my_atom.on_reagent_change()
return 0
return 1
remove_reagent(var/reagent, var/amount)
if(!isnum(amount)) return 1
for(var/A in reagent_list)
var/datum/reagent/R = A
if (R.id == reagent)
R.volume -= amount
update_total()
handle_reactions()
my_atom.on_reagent_change()
return 0
return 1
has_reagent(var/reagent, var/amount = -1)
for(var/A in reagent_list)
var/datum/reagent/R = A
if (R.id == reagent)
if(!amount) return 1
else
if(R.volume >= amount) return 1
else return 0
return 0
get_reagent_amount(var/reagent)
for(var/A in reagent_list)
var/datum/reagent/R = A
if (R.id == reagent)
return R.volume
return 0
///////////////////////////////////////////////////////////////////////////////////
// Convenience proc to create a reagents holder for an atom
// Max vol is maximum volume of holder
atom/proc/create_reagents(var/max_vol)
reagents = new/datum/reagents(max_vol)
reagents.my_atom = src
+231
View File
@@ -0,0 +1,231 @@
#define SOLID 1
#define LIQUID 2
#define GAS 3
/obj/machinery/chem_dispenser/
name = "chem dispenser"
density = 1
anchored = 1
icon = 'chemical.dmi'
icon_state = "dispenser"
var/energy = 25
var/max_energy = 25
var/list/dispensable_reagents = list("water","oxygen","nitrogen","hydrogen","potassium","mercury","sulfur","carbon","chlorine","fluorine","phosphorus","lithium","acid","radium","iron","aluminium","silicon","plasma","sugar","ethanol")
proc
recharge()
if(stat & BROKEN) return
if(energy != max_energy)
energy++
use_power(50)
spawn(600) recharge()
New()
recharge()
ex_act(severity)
switch(severity)
if(1.0)
del(src)
return
if(2.0)
if (prob(50))
del(src)
return
blob_act()
if (prob(25))
del(src)
meteorhit()
del(src)
return
Topic(href, href_list)
if(stat & BROKEN) return
if(usr.stat || usr.restrained()) return
if(!in_range(src, usr)) return
usr.machine = src
if (href_list["dispense"])
if(!energy)
var/dat = "Not enough energy.<BR><A href='?src=\ref[src];ok=1'>OK</A>"
usr << browse("<TITLE>Chemical Dispenser</TITLE>Chemical dispenser:<BR>Energy = [energy]/[max_energy]<BR><BR>[dat]", "window=chem_dispenser")
return
var/id = href_list["dispense"]
var/obj/item/weapon/reagent_containers/glass/dispenser/G = new/obj/item/weapon/reagent_containers/glass/dispenser(src.loc)
switch(text2num(href_list["state"]))
if(LIQUID)
G.icon_state = "liquid"
if(GAS)
G.icon_state = "vapour"
if(SOLID)
G.icon_state = "solid"
G.name += " ([lowertext(href_list["name"])])"
G.reagents.add_reagent(id,30)
energy--
src.updateUsrDialog()
return
else
usr << browse(null, "window=chem_dispenser")
return
src.add_fingerprint(usr)
return
attack_ai(mob/user as mob)
return src.attack_hand(user)
attack_paw(mob/user as mob)
return src.attack_hand(user)
attack_hand(mob/user as mob)
if(stat & BROKEN)
return
user.machine = src
var/dat = ""
for(var/re in dispensable_reagents)
for(var/da in typesof(/datum/reagent) - /datum/reagent)
var/datum/reagent/temp = new da()
if(temp.id == re)
dat += "<A href='?src=\ref[src];dispense=[temp.id];state=[temp.reagent_state];name=[temp.name]'>[temp.name]</A><BR>"
dat += "[temp.description]<BR><BR>"
user << browse("<TITLE>Chemical Dispenser</TITLE>Chemical dispenser:<BR>Energy = [energy]/[max_energy]<BR><BR>[dat]", "window=chem_dispenser")
onclose(user, "chem_dispenser")
return
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/obj/machinery/chem_master/
name = "CheMaster 3000"
density = 1
anchored = 1
icon = 'chemical.dmi'
icon_state = "mixer0"
var/beaker = null
ex_act(severity)
switch(severity)
if(1.0)
del(src)
return
if(2.0)
if (prob(50))
del(src)
return
blob_act()
if (prob(25))
del(src)
meteorhit()
del(src)
return
attackby(var/obj/item/weapon/reagent_containers/glass/B as obj, var/mob/user as mob)
if(!istype(B, /obj/item/weapon/reagent_containers/glass))
return
if(src.beaker)
user << "A beaker is already loaded into the machine."
return
src.beaker = B
user.drop_item()
B.loc = src
user << "You add the beaker to the machine!"
src.updateUsrDialog()
icon_state = "mixer1"
Topic(href, href_list)
if(stat & BROKEN) return
if(usr.stat || usr.restrained()) return
if(!in_range(src, usr)) return
usr.machine = src
if(!beaker) return
var/datum/reagents/R = beaker:reagents
if (href_list["isolate"])
R.isolate_reagent(href_list["isolate"])
src.updateUsrDialog()
return
else if (href_list["remove"])
R.del_reagent(href_list["remove"])
src.updateUsrDialog()
return
else if (href_list["remove5"])
R.remove_reagent(href_list["remove5"], 5)
src.updateUsrDialog()
return
else if (href_list["remove1"])
R.remove_reagent(href_list["remove1"], 1)
src.updateUsrDialog()
return
else if (href_list["analyze"])
var/dat = "<TITLE>Chemmaster 3000</TITLE>Chemical infos:<BR><BR>Name:<BR>[href_list["name"]]<BR><BR>Description:<BR>[href_list["desc"]]<BR><BR><BR><A href='?src=\ref[src];main=1'>(Back)</A>"
usr << browse(dat, "window=chem_master;size=575x400")
return
else if (href_list["main"])
attack_hand(usr)
return
else if (href_list["eject"])
beaker:loc = src.loc
beaker = null
icon_state = "mixer0"
src.updateUsrDialog()
return
else if (href_list["createpill"])
var/obj/item/weapon/reagent_containers/pill/P = new/obj/item/weapon/reagent_containers/pill(src.loc)
var/name = input(usr,"Name:","Name your pill!",R.get_master_reagent_name())
if(!name || name == " ") name = R.get_master_reagent_name()
P.name = "[name] pill"
R.trans_to(P,R.total_volume)
src.updateUsrDialog()
return
else if (href_list["createbottle"])
var/obj/item/weapon/reagent_containers/glass/bottle/P = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc)
var/name = input(usr,"Name:","Name your bottle!",R.get_master_reagent_name())
if(!name || name == " ") name = R.get_master_reagent_name()
P.name = "[name] bottle"
R.trans_to(P,30)
src.updateUsrDialog()
return
else
usr << browse(null, "window=chem_master")
return
src.add_fingerprint(usr)
return
attack_ai(mob/user as mob)
return src.attack_hand(user)
attack_paw(mob/user as mob)
return src.attack_hand(user)
attack_hand(mob/user as mob)
if(stat & BROKEN)
return
user.machine = src
var/dat = ""
if(!beaker)
dat = "Please insert beaker.<BR>"
dat += "<A href='?src=\ref[src];close=1'>Close</A>"
else
var/datum/reagents/R = beaker:reagents
dat += "<A href='?src=\ref[src];eject=1'>Eject beaker</A><BR><BR>"
if(!R.total_volume)
dat += "Beaker is empty."
else
dat += "Contained reagents:<BR>"
for(var/datum/reagent/G in R.reagent_list)
dat += "[G.name] , [G.volume] Units - <A href='?src=\ref[src];isolate=[G.id]'>(Isolate)</A> <A href='?src=\ref[src];remove=[G.id]'>(Remove all)</A> <A href='?src=\ref[src];remove5=[G.id]'>(Remove 5)</A> <A href='?src=\ref[src];remove1=[G.id]'>(Remove 1)</A> <A href='?src=\ref[src];analyze=1;desc=[G.description];name=[G.name]'>(Analyze)</A><BR>"
dat += "<BR><A href='?src=\ref[src];createpill=1'>Create pill</A><BR>"
dat += "<A href='?src=\ref[src];createbottle=1'>Create bottle (30 units max)</A>"
user << browse("<TITLE>Chemmaster 3000</TITLE>Chemmaster menu:<BR><BR>[dat]", "window=chem_master;size=575x400")
onclose(user, "chem_master")
return
+219
View File
@@ -0,0 +1,219 @@
/*
NOTE: IF YOU UPDATE THE REAGENT-SYSTEM, ALSO UPDATE THIS README.
Structure: /////////////////// //////////////////////////
// Mob or object // -------> // Reagents var (datum) // Is a reference to the datum that holds the reagents.
/////////////////// //////////////////////////
| |
The object that holds everything. V
reagent_list var (list) A List of datums, each datum is a reagent.
| | |
V V V
reagents (datums) Reagents. I.e. Water , antitoxins or mercury.
Random important notes:
An objects on_reagent_change will be called every time the objects reagents change.
Useful if you want to update the objects icon etc.
About the Holder:
The holder (reagents datum) is the datum that holds a list of all reagents
currently in the object.It also has all the procs needed to manipulate reagents
remove_any(var/amount)
This proc removes reagents from the holder until the passed amount
is matched. It'll try to remove some of ALL reagents contained.
trans_to(var/obj/target, var/amount)
This proc equally transfers the contents of the holder to another
objects holder. You need to pass it the object (not the holder) you want
to transfer to and the amount you want to transfer. Its return value is the
actual amount transfered (if one of the objects is full/empty)
metabolize(var/mob/M)
This proc is called by the mobs life proc. It simply calls on_mob_life for
all contained reagents. You shouldnt have to use this one directly.
handle_reactions()
This proc check all recipes and, on a match, uses them.
It will also call the recipe's on_reaction proc (for explosions or w/e).
Currently, this proc is automatically called by trans_to.
isolate_reagent(var/reagent)
Pass it a reagent id and it will remove all reagents but that one.
It's that simple.
del_reagent(var/reagent)
Completely remove the reagent with the matching id.
reaction_fire(exposed_temp)
Simply calls the reaction_fire procs of all contained reagents.
update_total()
This one simply updates the total volume of the holder.
(the volume of all reagents added together)
clear_reagents()
This proc removes ALL reagents from the holder.
reaction(var/atom/A, var/method=TOUCH, var/volume_modifier=0)
This proc calls the appropriate reaction procs of the reagents.
I.e. if A is an object, it will call the reagents reaction_obj
proc. The method var is used for reaction on mobs. It simply tells
us if the mob TOUCHed the reagent or if it INGESTed the reagent.
Since the volume can be checked in a reagents proc, you might want to
use the volume_modifier var to modifiy the passed value without actually
changing the volume of the reagents.
If you're not sure if you need to use this the answer is very most likely 'No'.
You'll want to use this proc whenever an atom first comes in
contact with the reagents of a holder. (in the 'splash' part of a beaker i.e.)
More on the reaction in the reagent part of this readme.
add_reagent(var/reagent, var/amount)
Attempts to add X of the matching reagent to the holder.
You wont use this much. Mostly in new procs for pre-filled
objects.
remove_reagent(var/reagent, var/amount)
The exact opposite of the add_reagent proc.
has_reagent(var/reagent, var/amount)
Returns 1 if the holder contains this reagent.
Or 0 if not.
If you pass it an amount it will additionally check
if the amount is matched. This is optional.
get_reagent_amount(var/reagent)
Returns the amount of the matching reagent inside the
holder. Returns 0 if the reagent is missing.
Important variables:
total_volume
This variable contains the total volume of all reagents in this holder.
reagent_list
This is a list of all contained reagents. More specifically, references
to the reagent datums.
maximum_volume
This is the maximum volume of the holder.
my_atom
This is the atom the holder is 'in'. Useful if you need to find the location.
(i.e. for explosions)
About Reagents:
Reagents are all the things you can mix and fille in bottles etc. This can be anything from
rejuvs over water to ... iron. Each reagent also has a few procs - i'll explain those below.
reaction_mob(var/mob/M, var/method=TOUCH)
This is called by the holder's reation proc.
This version is only called when the reagent
reacts with a mob. The method var can be either
TOUCH or INGEST. You'll want to put stuff like
acid-facemelting in here.
reaction_obj(var/obj/O)
This is called by the holder's reation proc.
This version is called when the reagents reacts
with an object. You'll want to put stuff like
object melting in here ... or something. i dunno.
reaction_turf(var/turf/T)
This is called by the holder's reation proc.
This version is called when the reagents reacts
with a turf. You'll want to put stuff like extra
slippery floors for lube or something in here.
on_mob_life(var/mob/M)
This proc is called everytime the mobs life proc executes.
This is the place where you put damage for toxins ,
drowsyness for sleep toxins etc etc.
You'll want to call the parents proc by using ..() .
If you dont, the chemical will stay in the mob forever -
unless you write your own piece of code to slowly remove it.
(Should be pretty easy, 1 line of code)
Important variables:
holder
This variable contains a reference to the holder the chemical is 'in'
volume
This is the volume of the reagent.
id
The id of the reagent
name
The name of the reagent.
data
This var can be used for whatever the fuck you want. I used it for the sleep
toxins to make them work slowly instead of instantly. You could also use this
for DNA in a blood reagent or ... well whatever you want.
About Recipes:
Recipes are simple datums that contain a list of required reagents and a result.
They also have a proc that is called when the recipe is matched.
on_reaction(var/datum/reagents/holder, var/created_volume)
This proc is called when the recipe is matched.
You'll want to add explosions etc here.
To find the location you'll have to do something
like get_turf(holder.my_atom)
name & id
Should be pretty obvious.
result
This var contains the id of the resulting reagent.
required_reagents
This is a list of ids of the required reagents.
Each id also needs an associated value that gives us the minimum required amount
of that reagent. The handle_reaction proc can detect mutiples of the same recipes
so for most cases you want to set the required amount to 1.
result_amount
This is the amount of the resulting reagent this recipe will produce.
I recommend you set this to the total volume of all required reagent.
About the Tools:
By default, all atom have a reagents var - but its empty. if you want to use an object for the chem.
system you'll need to add something like this in its new proc:
var/datum/reagents/R = new/datum/reagents(100) <<<<< create a new datum , 100 is the maximum_volume of the new holder datum.
reagents = R <<<<< assign the new datum to the objects reagents var
R.my_atom = src <<<<< set the holders my_atom to src so that we know where we are.
This can also be done by calling a convenience proc:
atom/proc/create_reagents(var/max_volume)
Other important stuff:
amount_per_transfer_from_this var
This var is mostly used by beakers and bottles.
It simply tells us how much to transfer when
'pouring' our reagents into something else.
atom/proc/is_open_container()
Checks atom/var/flags & OPENCONTAINER.
If this returns 1 , you can use syringes, beakers etc
to manipulate the contents of this object.
If it's 0, you'll need to write your own custom reagent
transfer code since you will not be able to use the standard
tools to manipulate it.
*/
+920
View File
@@ -0,0 +1,920 @@
#define SOLID 1
#define LIQUID 2
#define GAS 3
//The reaction procs must ALWAYS set src = null, this detaches the proc from the object (the reagent)
//so that it can continue working when the reagent is deleted while the proc is still active.
datum
reagent
var/name = "Reagent"
var/id = "reagent"
var/description = ""
var/datum/reagents/holder = null
var/reagent_state = SOLID
var/data = null
var/volume = 0
proc
reaction_mob(var/mob/M, var/method=TOUCH, var/volume) //By default we have a chance to transfer some
var/datum/reagent/self = src
src = null //of the reagent to the mob on TOUCHING it.
if(method == TOUCH)
var/chance = 1
for(var/obj/item/clothing/C in M.get_equipped_items())
if(C.permeability_coefficient < chance) chance = C.permeability_coefficient
chance = chance * 100
if(prob(chance))
if(M.reagents)
M.reagents.add_reagent(self.id,self.volume/2)
return
reaction_obj(var/obj/O, var/volume) //By default we transfer a small part of the reagent to the object
src = null //if it can hold reagents. nope!
//if(O.reagents)
// O.reagents.add_reagent(id,volume/3)
return
reaction_turf(var/turf/T, var/volume)
src = null
return
on_mob_life(var/mob/M)
holder.remove_reagent(src.id, 0.4) //By default it slowly disappears.
return
milk
name = "Milk"
id = "milk"
description = "An opaque white liquid produced by the mammary glands of mammals."
reagent_state = LIQUID
beer
name = "Beer"
id = "beer"
description = "An alcoholic beverage made from malted grains, hops, yeast, and water."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!data) data = 1
data++
M.make_dizzy(3)
M:jitteriness = max(M:jitteriness-3,0)
if(data >= 25)
if (!M:stuttering) M:stuttering = 1
M:stuttering += 3
if(data >= 40 && prob(33))
if (!M:confused) M:confused = 1
M:confused += 2
..()
water
name = "Water"
id = "water"
description = "A ubiquitous chemical substance that is composed of hydrogen and oxygen."
reagent_state = LIQUID
reaction_turf(var/turf/T, var/volume)
src = null
if(volume >= 3)
if(T:wet >= 1) return
T:wet = 1
if(T:wet_overlay)
T:overlays -= T:wet_overlay
T:wet_overlay = null
T:wet_overlay = image('water.dmi',T,"wet_floor")
T:overlays += T:wet_overlay
spawn(800)
if(T:wet >= 2) return
T:wet = 0
if(T:wet_overlay)
T:overlays -= T:wet_overlay
T:wet_overlay = null
var/hotspot = (locate(/obj/hotspot) in T)
if(hotspot)
var/datum/gas_mixture/lowertemp = T.remove_air( T:air:total_moles() )
lowertemp.temperature = max( min(lowertemp.temperature-2000,lowertemp.temperature / 2) ,0)
lowertemp.react()
T.assume_air(lowertemp)
del(hotspot)
return
reaction_obj(var/obj/O, var/volume)
src = null
var/turf/T = get_turf(O)
var/hotspot = (locate(/obj/hotspot) in T)
if(hotspot)
var/datum/gas_mixture/lowertemp = T.remove_air( T:air:total_moles() )
lowertemp.temperature = max( min(lowertemp.temperature-2000,lowertemp.temperature / 2) ,0)
lowertemp.react()
T.assume_air(lowertemp)
del(hotspot)
return
lube
name = "Space Lube"
id = "lube"
description = "Lubricant is a substance introduced between two moving surfaces to reduce the friction and wear between them. giggity."
reagent_state = LIQUID
reaction_turf(var/turf/T, var/volume)
src = null
if(T:wet >= 2) return
T:wet = 2
spawn(800)
T:wet = 0
if(T:wet_overlay)
T:overlays -= T:wet_overlay
T:wet_overlay = null
return
bilk
name = "Bilk"
id = "bilk"
description = "This appears to be beer mixed with milk. Disgusting."
reagent_state = LIQUID
anti_toxin
name = "Anti-Toxin (Dylovene)"
id = "anti_toxin"
description = "Dylovene is a broad-spectrum antitoxin."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M:drowsyness = max(M:drowsyness-2, 0)
if(holder.has_reagent("toxin"))
holder.remove_reagent("toxin", 2)
if(holder.has_reagent("stoxin"))
holder.remove_reagent("stoxin", 2)
if(holder.has_reagent("plasma"))
holder.remove_reagent("plasma", 1)
if(holder.has_reagent("acid"))
holder.remove_reagent("acid", 1)
if(holder.has_reagent("cyanide"))
holder.remove_reagent("cyanide", 1)
M:toxloss = max(M:toxloss-2,0)
..()
return
toxin
name = "Toxin"
id = "toxin"
description = "A Toxic chemical."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M:toxloss += 1.5
..()
return
cyanide
name = "Cyanide"
id = "cyanide"
description = "A highly toxic chemical."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M:toxloss += 3
M:oxyloss += 3
..()
return
stoxin
name = "Sleep Toxin"
id = "stoxin"
description = "An effective hypnotic used to treat insomnia."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
if(!data) data = 1
switch(data)
if(1 to 15)
M.eye_blurry = max(M.eye_blurry, 10)
if(15 to 25)
M:drowsyness = max(M:drowsyness, 20)
if(25 to INFINITY)
M:paralysis = max(M:paralysis, 20)
M:drowsyness = max(M:drowsyness, 30)
data++
..()
return
inaprovaline
name = "Inaprovaline"
id = "inaprovaline"
description = "Inaprovaline is a synaptic stimulant and cardiostimulant. Commonly used to stabilize patients."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
if(M.losebreath >= 10)
M.losebreath = max(10, M.losebreath-5)
holder.remove_reagent(src.id, 0.2)
return
space_drugs
name = "Space drugs"
id = "space_drugs"
description = "An illegal chemical compound used as drug."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M.druggy = max(M.druggy, 15)
if(M.canmove) step(M, pick(cardinal))
if(prob(7)) M:emote(pick("twitch","drool","moan","giggle"))
holder.remove_reagent(src.id, 0.2)
return
silicate
name = "Silicate"
id = "silicate"
description = "A compound that can be used to reinforce glass."
reagent_state = LIQUID
reaction_obj(var/obj/O, var/volume)
src = null
if(istype(O,/obj/window))
O:health = O:health * 2
var/icon/I = icon(O.icon,O.icon_state,O.dir)
I.SetIntensity(1.15,1.50,1.75)
O.icon = I
return
oxygen
name = "Oxygen"
id = "oxygen"
description = "A colorless, odorless gas."
reagent_state = GAS
nitrogen
name = "Nitrogen"
id = "nitrogen"
description = "A colorless, odorless, tasteless gas."
reagent_state = GAS
hydrogen
name = "Hydrogen"
id = "hydrogen"
description = "A colorless, odorless, nonmetallic, tasteless, highly combustible diatomic gas."
reagent_state = GAS
potassium
name = "Potassium"
id = "potassium"
description = "A soft, low-melting solid that can easily be cut with a knife. Reacts violently with water."
reagent_state = SOLID
mercury
name = "Mercury"
id = "mercury"
description = "A chemical element."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
if(M.canmove) step(M, pick(cardinal))
if(prob(5)) M:emote(pick("twitch","drool","moan"))
..()
return
sulfur
name = "Sulfur"
id = "sulfur"
description = "A chemical element."
reagent_state = SOLID
carbon
name = "Carbon"
id = "carbon"
description = "A chemical element."
reagent_state = SOLID
reaction_turf(var/turf/T, var/volume)
src = null
if(!istype(T, /turf/space))
new /obj/decal/cleanable/dirt(T)
chlorine
name = "Chlorine"
id = "chlorine"
description = "A chemical element."
reagent_state = GAS
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M:bruteloss++
..()
return
fluorine
name = "Fluorine"
id = "fluorine"
description = "A highly-reactive chemical element."
reagent_state = GAS
on_mob_life(var/mob.M)
if(!M) M = holder.my_atom
M:toxloss++
..()
return
phosphorus
name = "Phosphorus"
id = "phosphorus"
description = "A chemical element."
reagent_state = SOLID
lithium
name = "Lithium"
id = "lithium"
description = "A chemical element."
reagent_state = SOLID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
if(M.canmove) step(M, pick(cardinal))
if(prob(5)) M:emote(pick("twitch","drool","moan"))
..()
return
sugar
name = "Sugar"
id = "sugar"
description = "The organic compound commonly known as table sugar and sometimes called saccharose. This white, odorless, crystalline powder has a pleasing, sweet taste."
reagent_state = SOLID
acid
name = "Sulphuric acid"
id = "acid"
description = "A strong mineral acid with the molecular formula H2SO4."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M:toxloss++
M:fireloss++
..()
return
reaction_mob(var/mob/M, var/method=TOUCH, var/volume)
if(method == TOUCH)
if(istype(M, /mob/living/carbon/human))
if(M:wear_mask)
del (M:wear_mask)
M << "\red Your mask melts away but protects you from the acid!"
return
if(M:head)
del (M:head)
M << "\red Your helmet melts into uselessness but protects you from the acid!"
return
if(prob(75))
var/datum/organ/external/affecting = M:organs["head"]
affecting.take_damage(25, 0)
M:UpdateDamage()
M:UpdateDamageIcon()
M:emote("scream")
M << "\red Your face has become disfigured!"
M.real_name = "Unknown"
else
M:bruteloss += 15
else
M:bruteloss += 15
reaction_obj(var/obj/O, var/volume)
if(istype(O,/obj/item) && prob(40))
var/obj/decal/cleanable/molten_item/I = new/obj/decal/cleanable/molten_item(O.loc)
I.desc = "Looks like this was \an [O] some time ago."
for(var/mob/M in viewers(5, O))
M << "\red \the [O] melts."
del(O)
pacid
name = "Polytrinic acid"
id = "pacid"
description = "Polytrinic acid is a an extremely corrosive chemical substance."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M:toxloss++
M:fireloss++
..()
return
reaction_mob(var/mob/M, var/method=TOUCH, var/volume)
if(method == TOUCH)
if(istype(M, /mob/living/carbon/human))
if(M:wear_mask)
del (M:wear_mask)
M << "\red Your mask melts away!"
return
if(M:head)
del (M:head)
M << "\red Your helmet melts into uselessness!"
return
var/datum/organ/external/affecting = M:organs["head"]
affecting.take_damage(75, 0)
M:UpdateDamage()
M:UpdateDamageIcon()
M:emote("scream")
M << "\red Your face has become disfigured!"
M.real_name = "Unknown"
else
M:bruteloss += 15
else
if(istype(M, /mob/living/carbon/human))
var/datum/organ/external/affecting = M:organs["head"]
affecting.take_damage(75, 0)
M:UpdateDamage()
M:UpdateDamageIcon()
M:emote("scream")
M << "\red Your face has become disfigured!"
M.real_name = "Unknown"
else
M:bruteloss += 15
reaction_obj(var/obj/O, var/volume)
if(istype(O,/obj/item))
var/obj/decal/cleanable/molten_item/I = new/obj/decal/cleanable/molten_item(O.loc)
I.desc = "Looks like this was \an [O] some time ago."
for(var/mob/M in viewers(5, O))
M << "\red \the [O] melts."
del(O)
radium
name = "Radium"
id = "radium"
description = "Radium is an alkaline earth metal. It is extremely radioactive."
reagent_state = SOLID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M.radiation += 3
..()
return
reaction_turf(var/turf/T, var/volume)
src = null
if(!istype(T, /turf/space))
new /obj/decal/cleanable/greenglow(T)
ryetalyn
name = "Ryetalyn"
id = "ryetalyn"
description = "Ryetalyn can cure all genetic abnomalities."
reagent_state = SOLID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M.mutations = 0
M.disabilities = 0
M.sdisabilities = 0
..()
return
thermite
name = "Thermite"
id = "thermite"
description = "Thermite produces an aluminothermic reaction known as a thermite reaction. Can be used to melt walls."
reagent_state = SOLID
reaction_turf(var/turf/T, var/volume)
src = null
if(istype(T, /turf/simulated/wall))
T:thermite = 1
T.overlays = null
T.overlays = image('effects.dmi',icon_state = "thermite")
return
mutagen
name = "Unstable mutagen"
id = "mutagen"
description = "Might cause unpredictable mutations. Keep away from children."
reagent_state = LIQUID
reaction_mob(var/mob/M, var/method=TOUCH, var/volume)
src = null
if ( (method==TOUCH && prob(33)) || method==INGEST)
randmuti(M)
if(prob(98))
randmutb(M)
else
randmutg(M)
domutcheck(M, null, 1)
updateappearance(M,M.dna.uni_identity)
return
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M.radiation += 3
..()
return
iron
name = "Iron"
id = "iron"
description = "Pure iron is a metal."
reagent_state = SOLID
aluminium
name = "Aluminium"
id = "aluminium"
description = "A silvery white and ductile member of the boron group of chemical elements."
reagent_state = SOLID
silicon
name = "Silicon"
id = "silicon"
description = "A tetravalent metalloid, silicon is less reactive than its chemical analog carbon."
reagent_state = SOLID
fuel
name = "Welding fuel"
id = "fuel"
description = "Required for welders. Flamable."
reagent_state = LIQUID
reaction_obj(var/obj/O, var/volume)
src = null
var/turf/the_turf = get_turf(O)
var/datum/gas_mixture/napalm = new
var/datum/gas/volatile_fuel/fuel = new
fuel.moles = 15
napalm.trace_gases += fuel
the_turf.assume_air(napalm)
reaction_turf(var/turf/T, var/volume)
src = null
var/datum/gas_mixture/napalm = new
var/datum/gas/volatile_fuel/fuel = new
fuel.moles = 15
napalm.trace_gases += fuel
T.assume_air(napalm)
return
coffee
name = "Coffee"
id = "coffee"
description = "Coffee is a brewed drink prepared from roasted seeds, commonly called coffee beans, of the coffee plant."
reagent_state = LIQUID
on_mob_life(var/mob/M)
..()
M.dizziness = max(0,M.dizziness-5)
M:drowsyness = max(0,M:drowsyness-3)
M:sleeping = 0
M.bodytemperature = min(310, M.bodytemperature+5) //310 is the normal bodytemp. 310.055
M.make_jittery(5)
space_cleaner
name = "Space cleaner"
id = "cleaner"
description = "A compound used to clean things. Now with 50% more sodium hypochlorite!"
reagent_state = LIQUID
reaction_obj(var/obj/O, var/volume)
if(istype(O,/obj/decal/cleanable))
del(O)
else
O.clean_blood()
reaction_turf(var/turf/T, var/volume)
T.overlays = null
T.clean_blood()
for(var/obj/decal/cleanable/C in src)
del(C)
reaction_mob(var/mob/M, var/method=TOUCH, var/volume)
M.clean_blood()
if(istype(M, /mob/living/carbon))
var/mob/living/carbon/C = M
if(C.r_hand)
C.r_hand.clean_blood()
if(C.l_hand)
C.l_hand.clean_blood()
if(C.wear_mask)
C.wear_mask.clean_blood()
if(istype(M, /mob/living/carbon/human))
if(C:w_uniform)
C:w_uniform.clean_blood()
if(C:wear_suit)
C:wear_suit.clean_blood()
if(C:shoes)
C:shoes.clean_blood()
if(C:gloves)
C:gloves.clean_blood()
if(C:head)
C:head.clean_blood()
space_cola
name = "Cola"
id = "cola"
description = "A refreshing beverage."
reagent_state = LIQUID
on_mob_life(var/mob/M)
M:drowsyness = max(0,M:drowsyness-5)
M.bodytemperature = max(310, M.bodytemperature-5) //310 is the normal bodytemp. 310.055
plasma
name = "Plasma"
id = "plasma"
description = "Plasma in its liquid form."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
if(holder.has_reagent("inaprovaline"))
holder.remove_reagent("inaprovaline", 2)
M:toxloss++
..()
return
reaction_obj(var/obj/O, var/volume)
src = null
var/turf/the_turf = get_turf(O)
var/datum/gas_mixture/napalm = new
var/datum/gas/volatile_fuel/fuel = new
fuel.moles = 5
napalm.trace_gases += fuel
the_turf.assume_air(napalm)
reaction_turf(var/turf/T, var/volume)
src = null
var/datum/gas_mixture/napalm = new
var/datum/gas/volatile_fuel/fuel = new
fuel.moles = 5
napalm.trace_gases += fuel
T.assume_air(napalm)
return
leporazine
name = "Leporazine"
id = "leporazine"
description = "Leporazine can be use to stabilize an individuals body temperature."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
if(M.bodytemperature < 310)
M.bodytemperature = max(310, M.bodytemperature-10)
else if(M.bodytemperature > 311)
M.bodytemperature = min(310, M.bodytemperature+10)
..()
return
cryptobiolin
name = "Cryptobiolin"
id = "cryptobiolin"
description = "Cryptobiolin causes confusion and dizzyness."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M.make_dizzy(1)
if(!M.confused) M.confused = 1
M.confused = max(M.confused, 20)
holder.remove_reagent(src.id, 0.2)
return
lexorin
name = "Lexorin"
id = "lexorin"
description = "Lexorin temporarily stops respiration. Causes tissue damage."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
if(prob(33)) M.bruteloss++
holder.remove_reagent(src.id, 0.3)
return
kelotane
name = "Kelotane"
id = "kelotane"
description = "Kelotane is a drug used to treat burns."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M:fireloss = max(M:fireloss-2,0)
..()
return
dexalin
name = "Dexalin"
id = "dexalin"
description = "Dexalin is used in the treatment of oxygen deprivation."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M:oxyloss = max(M:oxyloss-2, 0)
..()
return
dexalinp
name = "Dexalin Plus"
id = "dexalinp"
description = "Dexalin Plus is used in the treatment of oxygen deprivation. Its highly effective."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M:oxyloss = 0
..()
return
tricordrazine
name = "Tricordrazine"
id = "tricordrazine"
description = "Tricordrazine is a highly potent stimulant, originally derived from cordrazine. Can be used to treat a wide range of injuries."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
if(M:oxyloss && prob(40)) M:oxyloss--
if(M:bruteloss && prob(40)) M:bruteloss--
if(M:fireloss && prob(40)) M:fireloss--
if(M:toxloss && prob(40)) M:toxloss--
..()
return
synaptizine
name = "Synaptizine"
id = "synaptizine"
description = "Synaptizine is used to treat neuroleptic shock. Can be used to help remove disabling symptoms such as paralysis."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M:drowsyness = max(M:drowsyness-5, 0)
if(M:paralysis) M:paralysis--
if(M:stunned) M:stunned--
if(M:weakened) M:weakened--
..()
return
impedrezene
name = "Impedrezene"
id = "impedrezene"
description = "Impedrezene is a narcotic that impedes one's ability by slowing down the higher brain cell functions."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M:jitteriness = max(M:jitteriness-5,0)
if(prob(80)) M:brainloss++
if(prob(50)) M:drowsyness = max(M:drowsyness, 3)
if(prob(10)) M:emote("drool")
..()
return
hyronalin
name = "Hyronalin"
id = "hyronalin"
description = "Hyronalin is a medicinal drug used to counter the effects of radiation poisoning."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
if(M:radiation && prob(80)) M:radiation--
..()
return
alkysine
name = "Alkysine"
id = "alkysine"
description = "Alkysine is a drug used to lessen the damage to neurological tissue after a catastrophic injury. Can heal brain tissue."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M:brainloss = max(M:brainloss-3 , 0)
..()
return
arithrazine
name = "Arithrazine"
id = "arithrazine"
description = "Arithrazine is an unstable medication used for the most extreme cases of radiation poisoning."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
M:radiation = max(M:radiation-3,0)
if(M:toxloss && prob(50)) M:toxloss--
if(prob(15)) M:bruteloss++
..()
return
bicaridine
name = "Bicaridine"
id = "bicaridine"
description = "Bicaridine is an analgesic medication and can be used to treat blunt trauma."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
if(M:bruteloss && prob(40)) M:bruteloss--
..()
return
hyperzine
name = "Hyperzine"
id = "hyperzine"
description = "Hyperzine is a highly effective, long lasting, muscle stimulant."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
if(prob(5)) M:emote(pick("twitch","blink_r","shiver"))
holder.remove_reagent(src.id, 0.2)
return
cryoxadone
name = "Cryoxadone"
id = "cryoxadone"
description = "A chemical mixture with almost magical healing powers. Its main limitation is that the targets body temperature must be under 170K for it to metabolise correctly."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
if(M.bodytemperature < 170)
if(M:oxyloss) M:oxyloss = max(0, M:oxyloss-3)
if(M:bruteloss) M:bruteloss = max(0, M:bruteloss-3)
if(M:fireloss) M:fireloss = max(0, M:fireloss-3)
if(M:toxloss) M:toxloss = max(0, M:toxloss-3)
return
spaceacillin
name = "Spaceacillin"
id = "spaceacillin"
description = "An all-purpose antiviral agent."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!M) M = holder.my_atom
if((M.virus) && (prob(8)))
if(M.virus.spread == "Airborne")
M.virus.spread = "Remissive"
M.virus.stage--
if(M.virus.stage <= 0)
M.resistances += M.virus.type
M.virus = null
holder.remove_reagent(src.id, 0.2)
return
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
nanites
name = "Nanomachines"
id = "nanites"
description = "Microscopic construction robots."
reagent_state = LIQUID
reaction_mob(var/mob/M, var/method=TOUCH, var/volume)
src = null
if( (prob(10) && method==TOUCH) || method==INGEST)
if(!M.virus)
M.virus = new /datum/disease/robotic_transformation
M.virus.affected_mob = M
xenomicrobes
name = "Xenomicrobes"
id = "xenomicrobes"
description = "Microbes with an entirely alien cellular structure."
reagent_state = LIQUID
reaction_mob(var/mob/M, var/method=TOUCH, var/volume)
src = null
if( (prob(10) && method==TOUCH) || method==INGEST)
if(!M.virus)
M.virus = new /datum/disease/xeno_transformation
M.virus.affected_mob = M
//foam precursor
fluorosurfactant
name = "Fluorosurfactant"
id = "fluorosurfactant"
description = "A perfluoronated sulfonic acid that forms a foam when mixed with water."
reagent_state = LIQUID
// metal foaming agent
// this is lithium hydride. Add other recipies (e.g. LiH + H2O -> LiOH + H2) eventually
foaming_agent
name = "Foaming agent"
id = "foaming_agent"
description = "A agent that yields metallic foam when mixed with light metal and a strong acid."
reagent_state = SOLID
nicotine
name = "Nicotine"
id = "nicotine"
description = "A highly addictive stimulant extracted from the tobacco plant."
reagent_state = LIQUID
ethanol
name = "Ethanol"
id = "ethanol"
description = "A well-known alcohol with a variety of applications."
reagent_state = LIQUID
on_mob_life(var/mob/M)
if(!data) data = 1
data++
M.make_dizzy(5)
M:jitteriness = max(M:jitteriness-5,0)
if(data >= 25)
if (!M:stuttering) M:stuttering = 1
M:stuttering += 4
if(data >= 40 && prob(33))
if (!M:confused) M:confused = 1
M:confused += 3
..()
ammonia
name = "Ammonia"
id = "ammonia"
description = "A caustic substance commonly used in fertilizer or household cleaners."
reagent_state = GAS
diethylamine
name = "Diethylamine"
id = "diethylamine"
description = "A secondary amine, mildly corrosive."
reagent_state = LIQUID
+390
View File
@@ -0,0 +1,390 @@
///////////////////////////////////////////////////////////////////////////////////
datum
chemical_reaction
var/name = null
var/id = null
var/result = null
var/list/required_reagents = new/list()
var/result_amount = 0
proc
on_reaction(var/datum/reagents/holder, var/created_volume)
return
//I recommend you set the result amount to the total volume of all components.
bilk
name = "Bilk"
id = "bilk"
result = "bilk"
required_reagents = list("milk" = 1, "beer" = 1)
result_amount = 2
explosion_potassium
name = "Explosion"
id = "explosion_potassium"
result = null
required_reagents = list("water" = 1, "potassium" = 1)
result_amount = null
on_reaction(var/datum/reagents/holder, var/created_volume)
var/location = get_turf(holder.my_atom)
var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread
s.set_up(2, 1, location)
s.start()
for(var/mob/M in viewers(5, location))
M << "\red The solution violently explodes."
for(var/mob/M in viewers(1, location))
M << "\red The explosion knocks you down."
M:weakened += 3
return
silicate
name = "Silicate"
id = "silicate"
result = "silicate"
required_reagents = list("aluminium" = 1, "silicon" = 1, "oxygen" = 1)
result_amount = 3
mutagen
name = "Unstable mutagen"
id = "mutagen"
result = "mutagen"
required_reagents = list("radium" = 1, "phosphorus" = 1, "chlorine" = 1)
result_amount = 3
//cyanide
// name = "Cyanide"
// id = "cyanide"
// result = "cyanide"
// required_reagents = list("hydrogen" = 1, "carbon" = 1, "nitrogen" = 1)
// result_amount = 3
thermite
name = "Thermite"
id = "thermite"
result = "thermite"
required_reagents = list("aluminium" = 1, "iron" = 1, "oxygen" = 1)
result_amount = 3
lexorin
name = "Lexorin"
id = "lexorin"
result = "lexorin"
required_reagents = list("plasma" = 1, "hydrogen" = 1, "nitrogen" = 1)
result_amount = 3
space_drugs
name = "Space Drugs"
id = "space_drugs"
result = "space_drugs"
required_reagents = list("mercury" = 1, "sugar" = 1, "lithium" = 1)
result_amount = 3
lube
name = "Space Lube"
id = "lube"
result = "lube"
required_reagents = list("water" = 1, "silicon" = 1, "oxygen" = 1)
result_amount = 4
pacid
name = "Polytrinic acid"
id = "pacid"
result = "pacid"
required_reagents = list("acid" = 1, "chlorine" = 1, "potassium" = 1)
result_amount = 3
synaptizine
name = "Synaptizine"
id = "synaptizine"
result = "synaptizine"
required_reagents = list("sugar" = 1, "lithium" = 1, "water" = 1)
result_amount = 3
hyronalin
name = "Hyronalin"
id = "hyronalin"
result = "hyronalin"
required_reagents = list("radium" = 1, "anti_toxin" = 1)
result_amount = 2
arithrazine
name = "Arithrazine"
id = "arithrazine"
result = "arithrazine"
required_reagents = list("hyronalin" = 1, "hydrogen" = 1)
result_amount = 2
impedrezene
name = "Impedrezene"
id = "impedrezene"
result = "impedrezene"
required_reagents = list("mercury" = 1, "oxygen" = 1, "sugar" = 1)
result_amount = 2
kelotane
name = "Kelotane"
id = "kelotane"
result = "kelotane"
required_reagents = list("silicon" = 1, "carbon" = 1)
result_amount = 2
leporazine
name = "Leporazine"
id = "leporazine"
result = "leporazine"
required_reagents = list("silicon" = 1, "plasma" = 1, )
result_amount = 2
cryptobiolin
name = "Cryptobiolin"
id = "cryptobiolin"
result = "cryptobiolin"
required_reagents = list("potassium" = 1, "oxygen" = 1, "sugar" = 1)
result_amount = 3
tricordrazine
name = "Tricordrazine"
id = "tricordrazine"
result = "tricordrazine"
required_reagents = list("inaprovaline" = 1, "anti_toxin" = 1)
result_amount = 2
alkysine
name = "Alkysine"
id = "alkysine"
result = "alkysine"
required_reagents = list("chlorine" = 1, "nitrogen" = 1, "anti_toxin" = 1)
result_amount = 2
dexalin
name = "Dexalin"
id = "dexalin"
result = "dexalin"
required_reagents = list("plasma" = 1, "oxygen" = 1)
result_amount = 2
dexalinp
name = "Dexalin Plus"
id = "dexalinp"
result = "dexalinp"
required_reagents = list("dexalin" = 1, "carbon" = 1, "iron" = 1)
result_amount = 3
bicaridine
name = "Bicaridine"
id = "bicaridine"
result = "bicaridine"
required_reagents = list("inaprovaline" = 1, "carbon" = 1)
result_amount = 2
hyperzine
name = "Hyperzine"
id = "hyperzine"
result = "hyperzine"
required_reagents = list("sugar" = 1, "phosphorus" = 1, "sulfur" = 1,)
result_amount = 3
ryetalyn
name = "Ryetalyn"
id = "ryetalyn"
result = "ryetalyn"
required_reagents = list("arithrazine" = 1, "carbon" = 1)
result_amount = 2
cryoxadone
name = "Cryoxadone"
id = "cryoxadone"
result = "cryoxadone"
required_reagents = list("dexalin" = 1, "water" = 1, "oxygen" = 1)
result_amount = 10
spaceacillin
name = "spaceacillin"
id = "spaceacillin"
result = "spaceacillin"
required_reagents = list("cryptobiolin" = 1, "inaprovaline" = 1)
result_amount = 2
flash_powder
name = "Flash powder"
id = "flash_powder"
result = null
required_reagents = list("aluminium" = 1, "potassium" = 1, "sulfur" = 1 )
result_amount = null
on_reaction(var/datum/reagents/holder, var/created_volume)
var/location = get_turf(holder.my_atom)
var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread
s.set_up(2, 1, location)
s.start()
for(var/mob/living/carbon/M in viewers(world.view, location))
switch(get_dist(M, location))
if(0 to 3)
if(hasvar(M, "glasses"))
if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses))
continue
flick("e_flash", M.flash)
M.weakened = 15
if(4 to 5)
if(hasvar(M, "glasses"))
if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses))
continue
flick("e_flash", M.flash)
M.stunned = 5
napalm
name = "Napalm"
id = "napalm"
result = null
required_reagents = list("aluminium" = 1, "plasma" = 1, "acid" = 1 )
result_amount = null
on_reaction(var/datum/reagents/holder, var/created_volume)
var/location = get_turf(holder.my_atom)
for(var/turf/simulated/floor/target_tile in range(1,location))
if(target_tile.parent && target_tile.parent.group_processing)
target_tile.parent.suspend_group_processing()
var/datum/gas_mixture/napalm = new
var/datum/gas/volatile_fuel/fuel = new
fuel.moles = 15
napalm.trace_gases += fuel
target_tile.assume_air(napalm)
spawn (0) target_tile.hotspot_expose(700, 400)
return
smoke
name = "Smoke"
id = "smoke"
result = null
required_reagents = list("potassium" = 1, "sugar" = 1, "phosphorus" = 1 )
result_amount = null
on_reaction(var/datum/reagents/holder, var/created_volume)
var/location = get_turf(holder.my_atom)
var/datum/effects/system/bad_smoke_spread/S = new /datum/effects/system/bad_smoke_spread
S.attach(location)
S.set_up(10, 0, location)
playsound(location, 'smoke.ogg', 50, 1, -3)
spawn(0)
S.start()
sleep(10)
S.start()
sleep(10)
S.start()
sleep(10)
S.start()
sleep(10)
S.start()
return
///////////////////////////////////////////////////////////////////////////////////
// foam and foam precursor
surfactant
name = "Foam surfactant"
id = "foam surfactant"
result = "fluorosurfactant"
required_reagents = list("fluorine" = 2, "carbon" = 2, "acid" = 1)
result_amount = 5
foam
name = "Foam"
id = "foam"
result = null
required_reagents = list("fluorosurfactant" = 1, "water" = 1)
result_amount = 2
on_reaction(var/datum/reagents/holder, var/created_volume)
var/location = get_turf(holder.my_atom)
for(var/mob/M in viewers(5, location))
M << "\red The solution violently bubbles!"
location = get_turf(holder.my_atom)
for(var/mob/M in viewers(5, location))
M << "\red The solution spews out foam!"
//world << "Holder volume is [holder.total_volume]"
//for(var/datum/reagent/R in holder.reagent_list)
// world << "[R.name] = [R.volume]"
var/datum/effects/system/foam_spread/s = new()
s.set_up(created_volume, location, holder, 0)
s.start()
holder.clear_reagents()
return
metalfoam
name = "Metal Foam"
id = "metalfoam"
result = null
required_reagents = list("aluminium" = 3, "foaming_agent" = 1, "pacid" = 1)
result_amount = 5
on_reaction(var/datum/reagents/holder, var/created_volume)
var/location = get_turf(holder.my_atom)
for(var/mob/M in viewers(5, location))
M << "\red The solution spews out a metalic foam!"
var/datum/effects/system/foam_spread/s = new()
s.set_up(created_volume/2, location, holder, 1)
s.start()
return
ironfoam
name = "Iron Foam"
id = "ironlfoam"
result = null
required_reagents = list("iron" = 3, "foaming_agent" = 1, "pacid" = 1)
result_amount = 5
on_reaction(var/datum/reagents/holder, var/created_volume)
var/location = get_turf(holder.my_atom)
for(var/mob/M in viewers(5, location))
M << "\red The solution spews out a metalic foam!"
var/datum/effects/system/foam_spread/s = new()
s.set_up(created_volume/2, location, holder, 2)
s.start()
return
foaming_agent
name = "Foaming Agent"
id = "foaming_agent"
result = "foaming_agent"
required_reagents = list("lithium" = 1, "hydrogen" = 1)
result_amount = 1
// Synthesizing these three chemicals is pretty complex in real life, but fuck it, it's just a game!
ammonia
name = "Ammonia"
id = "ammonia"
result = "ammonia"
required_reagents = list("hydrogen" = 3, "nitrogen" = 1)
result_amount = 3
space_cleaner
name = "Space cleaner"
id = "cleaner"
result = "cleaner"
required_reagents = list("ammonia" = 1, "water" = 1)
result_amount = 1
File diff suppressed because it is too large Load Diff
+490
View File
@@ -0,0 +1,490 @@
/obj/signpost
icon = 'old_or_unused.dmi'
icon_state = "signpost"
anchored = 1
density = 1
attackby(obj/item/weapon/W as obj, mob/user as mob)
return attack_hand(user)
attack_hand(mob/user as mob)
switch(alert("Travel back to ss13?",,"Yes","No"))
if("Yes")
user.loc.loc.Exited(user)
user.loc = pick(latejoin)
if("No")
return
/area/beach
name = "Keelin's private beach"
icon_state = "null"
luminosity = 1
sd_lighting = 0
requires_power = 0
var/sound/mysound = null
New()
..()
var/sound/S = new/sound()
mysound = S
S.file = 'shore.ogg'
S.repeat = 1
S.wait = 0
S.channel = 123
S.volume = 100
S.priority = 255
S.status = SOUND_UPDATE
process()
Entered(atom/movable/Obj,atom/OldLoc)
if(ismob(Obj))
if(Obj:client)
mysound.status = SOUND_UPDATE
Obj << mysound
return
Exited(atom/movable/Obj)
if(ismob(Obj))
if(Obj:client)
mysound.status = SOUND_PAUSED | SOUND_UPDATE
Obj << mysound
proc/process()
set background = 1
var/sound/S = null
var/sound_delay = 0
if(prob(25))
S = sound(file=pick('seag1.ogg','seag2.ogg','seag3.ogg'), volume=100)
sound_delay = rand(0, 50)
for(var/mob/living/carbon/human/H in src)
if(H.s_tone > -55)
H.s_tone--
H.update_body()
if(H.client)
mysound.status = SOUND_UPDATE
H << mysound
if(S)
spawn(sound_delay)
H << S
spawn(60) .()
/obj/item/weapon/beach_ball
icon = 'beach.dmi'
icon_state = "ball"
name = "beach ball"
item_state = "clown"
density = 0
anchored = 0
w_class = 1.0
force = 0.0
throwforce = 0.0
throw_speed = 1
throw_range = 20
flags = FPRINT | USEDELAY | TABLEPASS | CONDUCT
afterattack(atom/target as mob|obj|turf|area, mob/user as mob)
user.drop_item()
src.throw_at(target, throw_range, throw_speed)
/obj/item/weapon/hand_labeler
icon = 'old_or_unused.dmi'
icon_state = "labeler"
item_state = "flight"
name = "Hand labeler"
var/label = null
var/labels_left = 10
/obj/item/weapon/hand_labeler/afterattack(atom/A, mob/user as mob)
if(A==loc) // if placing the labeller into something (e.g. backpack)
return // don't set a label
if(!labels_left)
user << "\red No labels left."
return
if(!label || !length(label))
user << "\red No text set."
return
if(length(A.name) + length(label) > 64)
user << "\red Label too big."
return
for(var/mob/M in viewers())
M << "\blue [user] puts a label on [A]."
A.name = "[A.name] ([label])"
/obj/item/weapon/hand_labeler/attack_self()
var/str = input(usr,"Label text?","Set label","")
if(!str || !length(str))
usr << "\red Invalid text."
return
if(length(str) > 10)
usr << "\red Text too long."
return
label = str
usr << "\blue You set the text to '[str]'."
/proc/testa()
fake_attack(usr)
/proc/testb()
fake_attack(input(usr) as mob in world)
/obj/fake_attacker
icon = null
icon_state = null
name = ""
desc = ""
density = 0
anchored = 1
opacity = 0
var/mob/living/carbon/human/my_target = null
var/weapon_name = null
/obj/fake_attacker/attackby()
step_away(src,my_target,2)
for(var/mob/M in oviewers(world.view,my_target))
M << "\red <B>[my_target] flails around wildly.</B>"
my_target.show_message("\red <B>[src] has been attacked by [my_target] </B>", 1) //Lazy.
return
/obj/fake_attacker/HasEntered(var/mob/M, somenumber)
if(M == my_target)
step_away(src,my_target,2)
if(prob(30))
for(var/mob/O in oviewers(world.view , my_target))
O << "\red <B>[my_target] stumbles around.</B>"
/obj/fake_attacker/New()
spawn(300) del(src)
step_away(src,my_target,2)
proccess()
/obj/fake_attacker/proc/proccess()
if(!my_target) spawn(5) .()
if(get_dist(src,my_target) > 1)
step_towards(src,my_target)
else
if(prob(15))
if(weapon_name)
my_target << sound(pick('genhit1.ogg', 'genhit2.ogg', 'genhit3.ogg'))
my_target.show_message("\red <B>[my_target] has been attacked with [weapon_name] by [src.name] </B>", 1)
if(prob(20)) my_target.eye_blurry += 3
if(prob(33))
if(!locate(/obj/overlay) in my_target.loc)
fake_blood(my_target)
else
my_target << sound(pick('punch1.ogg','punch2.ogg','punch3.ogg','punch4.ogg'))
my_target.show_message("\red <B>[src.name] has punched [my_target]!</B>", 1)
if(prob(33))
if(!locate(/obj/overlay) in my_target.loc)
fake_blood(my_target)
if(prob(15)) step_away(src,my_target,2)
spawn(5) .()
/proc/fake_blood(var/mob/target)
var/obj/overlay/O = new/obj/overlay(target.loc)
O.name = "blood"
var/image/I = image('blood.dmi',O,"floor[rand(1,7)]",O.dir,1)
target << I
spawn(300)
del(O)
return
/proc/fake_attack(var/mob/target)
var/list/possible_clones = new/list()
var/mob/living/carbon/human/clone = null
var/clone_weapon = null
for(var/mob/living/carbon/human/H in world)
if(H.stat || H.lying || H.dir == NORTH) continue
possible_clones += H
if(!possible_clones.len) return
clone = pick(possible_clones)
if(clone.l_hand)
clone_weapon = clone.l_hand.name
else if (clone.r_hand)
clone_weapon = clone.r_hand.name
var/obj/fake_attacker/F = new/obj/fake_attacker(target.loc)
F.name = clone.name
F.my_target = target
F.weapon_name = clone_weapon
var/image/O = image(clone,F)
target << O
/proc/can_see(var/atom/source, var/atom/target, var/length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate.
var/turf/current = get_turf(source)
var/turf/target_turf = get_turf(target)
var/steps = 0
while(current != target_turf)
if(steps > length) return 0
if(current.opacity) return 0
for(var/atom/A in current)
if(A.opacity) return 0
current = get_step_towards(current, target_turf)
steps++
return 1
/mob/proc/get_equipped_items()
var/list/items = new/list()
if(hasvar(src,"back")) if(src:back) items += src:back
if(hasvar(src,"belt")) if(src:belt) items += src:belt
if(hasvar(src,"ears")) if(src:ears) items += src:ears
if(hasvar(src,"glasses")) if(src:glasses) items += src:glasses
if(hasvar(src,"gloves")) if(src:gloves) items += src:gloves
if(hasvar(src,"head")) if(src:head) items += src:head
if(hasvar(src,"shoes")) if(src:shoes) items += src:shoes
if(hasvar(src,"wear_id")) if(src:wear_id) items += src:wear_id
if(hasvar(src,"wear_mask")) if(src:wear_mask) items += src:wear_mask
if(hasvar(src,"wear_suit")) if(src:wear_suit) items += src:wear_suit
// if(hasvar(src,"w_radio")) if(src:w_radio) items += src:w_radio commenting this out since headsets go on your ears now PLEASE DON'T BE MAD KEELIN
if(hasvar(src,"w_uniform")) if(src:w_uniform) items += src:w_uniform
//if(hasvar(src,"l_hand")) if(src:l_hand) items += src:l_hand
//if(hasvar(src,"r_hand")) if(src:r_hand) items += src:r_hand
return items
/proc/is_blocked_turf(var/turf/T)
var/cant_pass = 0
if(T.density) cant_pass = 1
for(var/atom/A in T)
if(A.density)//&&A.anchored
cant_pass = 1
return cant_pass
/proc/get_step_towards2(var/atom/ref , var/atom/trg)
var/base_dir = get_dir(ref, get_step_towards(ref,trg))
var/turf/temp = get_step_towards(ref,trg)
if(is_blocked_turf(temp))
var/dir_alt1 = turn(base_dir, 90)
var/dir_alt2 = turn(base_dir, -90)
var/turf/turf_last1 = temp
var/turf/turf_last2 = temp
var/free_tile = null
var/breakpoint = 0
while(!free_tile && breakpoint < 10)
if(!is_blocked_turf(turf_last1))
free_tile = turf_last1
break
if(!is_blocked_turf(turf_last2))
free_tile = turf_last2
break
turf_last1 = get_step(turf_last1,dir_alt1)
turf_last2 = get_step(turf_last2,dir_alt2)
breakpoint++
if(!free_tile) return get_step(ref, base_dir)
else return get_step_towards(ref,free_tile)
else return get_step(ref, base_dir)
/proc/do_mob(var/mob/user , var/mob/target, var/time = 30) //This is quite an ugly solution but i refuse to use the old request system.
if(!user || !target) return 0
var/user_loc = user.loc
var/target_loc = target.loc
var/holding = user.equipped()
sleep(time)
if ( user.loc == user_loc && target.loc == target_loc && user.equipped() == holding && !( user.stat ) && ( !user.stunned && !user.weakened && !user.paralysis && !user.lying ) )
return 1
else
return 0
/proc/do_after(mob/M as mob, time as num)
var/turf/T = M.loc
var/holding = M.equipped()
sleep(time)
if ((M.loc == T && M.equipped() == holding && !( M.stat )))
return 1
else
return 0
/proc/hasvar(var/datum/A, var/varname)
//Takes: Anything that could possibly have variables and a varname to check.
//Returns: 1 if found, 0 if not.
//Notes: Do i really need to explain this?
if(A.vars.Find(lowertext(varname))) return 1
else return 0
/proc/get_areas(var/areatype)
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all areas of that type in the world.
//Notes: Simple!
if(!areatype) return null
if(istext(areatype)) areatype = text2path(areatype)
if(isarea(areatype))
var/area/areatemp = areatype
areatype = areatemp.type
var/list/areas = new/list()
for(var/area/N in world)
if(istype(N, areatype)) areas += N
return areas
/proc/get_area_turfs(var/areatype)
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all turfs in areas of that type of that type in the world.
//Notes: Simple!
if(!areatype) return null
if(istext(areatype)) areatype = text2path(areatype)
if(isarea(areatype))
var/area/areatemp = areatype
areatype = areatemp.type
var/list/turfs = new/list()
for(var/area/N in world)
if(istype(N, areatype))
for(var/turf/T in N) turfs += T
return turfs
/proc/get_area_all_atoms(var/areatype)
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all atoms (objs, turfs, mobs) in areas of that type of that type in the world.
//Notes: Simple!
if(!areatype) return null
if(istext(areatype)) areatype = text2path(areatype)
if(isarea(areatype))
var/area/areatemp = areatype
areatype = areatemp.type
var/list/atoms = new/list()
for(var/area/N in world)
if(istype(N, areatype))
for(var/atom/A in N)
atoms += A
return atoms
/datum/coords //Simple datum for storing coordinates.
var/x_pos = null
var/y_pos = null
var/z_pos = null
/area/proc/move_contents_to(var/area/A, var/turftoleave=null)
//Takes: Area. Optional: turf type to leave behind.
//Returns: Nothing.
//Notes: Attempts to move the contents of one area to another area.
// Movement based on lower left corner. Tiles that do not fit
// into the new area will not be moved.
if(!A || !src) return 0
var/list/turfs_src = get_area_turfs(src.type)
var/list/turfs_trg = get_area_turfs(A.type)
var/src_min_x = 0
var/src_min_y = 0
for (var/turf/T in turfs_src)
if(T.x < src_min_x || !src_min_x) src_min_x = T.x
if(T.y < src_min_y || !src_min_y) src_min_y = T.y
var/trg_min_x = 0
var/trg_min_y = 0
for (var/turf/T in turfs_trg)
if(T.x < trg_min_x || !trg_min_x) trg_min_x = T.x
if(T.y < trg_min_y || !trg_min_y) trg_min_y = T.y
var/list/refined_src = new/list()
for(var/turf/T in turfs_src)
refined_src += T
refined_src[T] = new/datum/coords
var/datum/coords/C = refined_src[T]
C.x_pos = (T.x - src_min_x)
C.y_pos = (T.y - src_min_y)
var/list/refined_trg = new/list()
for(var/turf/T in turfs_trg)
refined_trg += T
refined_trg[T] = new/datum/coords
var/datum/coords/C = refined_trg[T]
C.x_pos = (T.x - trg_min_x)
C.y_pos = (T.y - trg_min_y)
var/list/fromupdate = new/list()
var/list/toupdate = new/list()
moving:
for (var/turf/T in refined_src)
var/datum/coords/C_src = refined_src[T]
for (var/turf/B in refined_trg)
var/datum/coords/C_trg = refined_trg[B]
if(C_src.x_pos == C_trg.x_pos && C_src.y_pos == C_trg.y_pos)
var/old_dir1 = T.dir
var/old_icon_state1 = T.icon_state
var/turf/X = new T.type(B)
X.dir = old_dir1
X.icon_state = old_icon_state1
for(var/obj/O in T)
if(!istype(O,/obj)) continue
O.loc = X
for(var/mob/M in T)
if(!istype(M,/mob)) continue
M.loc = X
var/area/AR = X.loc
if(AR.sd_lighting)
X.opacity = !X.opacity
X.sd_SetOpacity(!X.opacity)
toupdate += X
if(turftoleave)
var/turf/ttl = new turftoleave(T)
var/area/AR2 = ttl.loc
if(AR2.sd_lighting)
ttl.opacity = !ttl.opacity
ttl.sd_SetOpacity(!ttl.opacity)
fromupdate += ttl
else
T.ReplaceWithSpace()
refined_src -= T
refined_trg -= B
continue moving
var/list/doors = new/list()
if(toupdate.len)
for(var/turf/simulated/T1 in toupdate)
for(var/obj/machinery/door/D2 in T1)
doors += D2
if(T1.parent)
air_master.groups_to_rebuild += T1.parent
else
air_master.tiles_to_update += T1
if(fromupdate.len)
for(var/turf/simulated/T2 in fromupdate)
for(var/obj/machinery/door/D2 in T2)
doors += D2
if(T2.parent)
air_master.groups_to_rebuild += T2.parent
else
air_master.tiles_to_update += T2
for(var/obj/O in doors)
O:update_nearby_tiles(1)
+194
View File
@@ -0,0 +1,194 @@
var/CMinutes = null
var/savefile/Banlist
/proc/CheckBan(var/client/clientvar)
var/id = clientvar.computer_id
var/key = clientvar.ckey
Banlist.cd = "/base"
if (Banlist.dir.Find("[key][id]"))
Banlist.cd = "[key][id]"
if (Banlist["temp"])
if (!GetExp(Banlist["minutes"]))
ClearTempbans()
return 0
else
return "[Banlist["reason"]]\n(This ban will be automatically removed in [GetExp(Banlist["minutes"])].)"
else
Banlist.cd = "/base/[key][id]"
return "[Banlist["reason"]]\n(This is a permanent ban)"
Banlist.cd = "/base"
for (var/A in Banlist.dir)
Banlist.cd = "/base/[A]"
if (id == Banlist["id"] || key == Banlist["key"])
if(Banlist["temp"])
if (!GetExp(Banlist["minutes"]))
ClearTempbans()
return 0
else
return "[Banlist["reason"]]\n(This ban will be automatically removed in [GetExp(Banlist["minutes"])].)"
else
return "[Banlist["reason"]]\n(This is a permanent ban)"
return 0
/proc/UpdateTime() //No idea why i made this a proc.
CMinutes = (world.realtime / 10) / 60
return 1
/proc/LoadBans()
Banlist = new("data/banlist.bdb")
log_admin("Loading Banlist")
if (!length(Banlist.dir)) log_admin("Banlist is empty.")
if (!Banlist.dir.Find("base"))
log_admin("Banlist missing base dir.")
Banlist.dir.Add("base")
Banlist.cd = "/base"
else if (Banlist.dir.Find("base"))
Banlist.cd = "/base"
ClearTempbans()
return 1
/proc/ClearTempbans()
UpdateTime()
Banlist.cd = "/base"
for (var/A in Banlist.dir)
Banlist.cd = "/base/[A]"
if (!Banlist["key"] || !Banlist["id"])
RemoveBan(A)
log_admin("Invalid Ban.")
message_admins("Invalid Ban.")
continue
if (!Banlist["temp"]) continue
if (CMinutes >= Banlist["minutes"]) RemoveBan(A)
return 1
/proc/AddBan(ckey, computerid, reason, bannedby, temp, minutes)
var/bantimestamp
if (temp)
UpdateTime()
bantimestamp = CMinutes + minutes
Banlist.cd = "/base"
if ( Banlist.dir.Find("[ckey][computerid]") )
usr << text("\red Ban already exists.")
return 0
else
Banlist.dir.Add("[ckey][computerid]")
Banlist.cd = "/base/[ckey][computerid]"
Banlist["key"] << ckey
Banlist["id"] << computerid
Banlist["reason"] << reason
Banlist["bannedby"] << bannedby
Banlist["temp"] << temp
if (temp)
Banlist["minutes"] << bantimestamp
return 1
/proc/RemoveBan(foldername)
var/key
var/id
Banlist.cd = "/base/[foldername]"
Banlist["key"] >> key
Banlist["id"] >> id
Banlist.cd = "/base"
if (!Banlist.dir.Remove(foldername)) return 0
if(!usr)
log_admin("Ban Expired: [key]")
message_admins("Ban Expired: [key]")
else
log_admin("[key_name_admin(usr)] unbanned [key]")
message_admins("[key_name_admin(usr)] unbanned: [key]")
for (var/A in Banlist.dir)
Banlist.cd = "/base/[A]"
if (key == Banlist["key"] || id == Banlist["id"])
Banlist.cd = "/base"
Banlist.dir.Remove(A)
continue
return 1
/proc/GetExp(minutes as num)
UpdateTime()
var/exp = minutes - CMinutes
if (exp <= 0)
return 0
else
var/timeleftstring
if (exp >= 1440) //1440 = 1 day in minutes
timeleftstring = "[round(exp / 1440, 0.1)] Days"
else if (exp >= 60) //60 = 1 hour in minutes
timeleftstring = "[round(exp / 60, 0.1)] Hours"
else
timeleftstring = "[exp] Minutes"
return timeleftstring
/obj/admins/proc/unbanpanel()
var/count = 0
var/dat
//var/dat = "<HR><B>Unban Player:</B> \blue(U) = Unban , (E) = Edit Ban\green (Total<HR><table border=1 rules=all frame=void cellspacing=0 cellpadding=3 >"
Banlist.cd = "/base"
for (var/A in Banlist.dir)
count++
Banlist.cd = "/base/[A]"
dat += text("<tr><td><A href='?src=\ref[src];unbanf=[Banlist["key"]][Banlist["id"]]'>(U)</A><A href='?src=\ref[src];unbane=[Banlist["key"]][Banlist["id"]]'>(E)</A> Key: <B>[Banlist["key"]]</B></td><td> ([Banlist["temp"] ? "[GetExp(Banlist["minutes"]) ? GetExp(Banlist["minutes"]) : "Removal pending" ]" : "Permaban"])</td><td>(By: [Banlist["bannedby"]])</td><td>(Reason: [Banlist["reason"]])</td></tr>")
dat += "</table>"
dat = "<HR><B>Bans:</B> <FONT COLOR=blue>(U) = Unban , (E) = Edit Ban</FONT> - <FONT COLOR=green>([count] Bans)</FONT><HR><table border=1 rules=all frame=void cellspacing=0 cellpadding=3 >[dat]"
usr << browse(dat, "window=unbanp;size=875x400")
//////////////////////////////////// DEBUG ////////////////////////////////////
/proc/CreateBans()
UpdateTime()
var/i
var/last
for(i=0, i<1001, i++)
var/a = pick(1,0)
var/b = pick(1,0)
if(b)
Banlist.cd = "/base"
Banlist.dir.Add("trash[i]trashid[i]")
Banlist.cd = "/base/trash[i]trashid[i]"
Banlist["key"] << "trash[i]"
else
Banlist.cd = "/base"
Banlist.dir.Add("[last]trashid[i]")
Banlist.cd = "/base/[last]trashid[i]"
Banlist["key"] << last
Banlist["id"] << "trashid[i]"
Banlist["reason"] << "Trashban[i]."
Banlist["temp"] << a
Banlist["minutes"] << CMinutes + rand(1,2000)
Banlist["bannedby"] << "trashmin"
last = "trash[i]"
Banlist.cd = "/base"
/proc/ClearAllBans()
Banlist.cd = "/base"
for (var/A in Banlist.dir)
RemoveBan(A)
+263
View File
@@ -0,0 +1,263 @@
/proc/togglebuildmode(mob/M as mob in world)
if(M.client)
if(M.client.buildmode)
M.client.buildmode = 0
M.client.show_popup_menus = 1
for(var/obj/buildholder/H)
if(H.cl == M.client)
del(H)
else
M.client.buildmode = 1
M.client.show_popup_menus = 0
var/obj/buildholder/H = new/obj/buildholder()
var/obj/builddir/A = new/obj/builddir(H)
A.master = H
var/obj/buildhelp/B = new/obj/buildhelp(H)
B.master = H
var/obj/buildmode/C = new/obj/buildmode(H)
C.master = H
var/obj/buildquit/D = new/obj/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/builddir
density = 1
anchored = 1
layer = 20
dir = NORTH
icon = 'buildmode.dmi'
icon_state = "build"
screen_loc = "NORTH,WEST"
var/obj/buildholder/master = null
/obj/buildhelp
density = 1
anchored = 1
layer = 20
dir = NORTH
icon = 'buildmode.dmi'
icon_state = "buildhelp"
screen_loc = "NORTH,WEST+1"
var/obj/buildholder/master = null
/obj/buildmode
density = 1
anchored = 1
layer = 20
dir = NORTH
icon = 'buildmode.dmi'
icon_state = "buildmode1"
screen_loc = "NORTH,WEST+2"
var/obj/buildholder/master = null
var/varholder = "name"
var/valueholder = "derp"
var/objholder = "/obj/closet"
/obj/buildquit
density = 1
anchored = 1
layer = 20
dir = NORTH
icon = 'buildmode.dmi'
icon_state = "buildquit"
screen_loc = "NORTH,WEST+3"
var/obj/buildholder/master = null
/obj/buildquit/Click()
togglebuildmode(master.cl.mob)
/obj/buildholder
density = 0
anchored = 1
var/client/cl = null
var/obj/builddir/builddir = null
var/obj/buildhelp/buildhelp = null
var/obj/buildmode/buildmode = null
var/obj/buildquit/buildquit = null
/obj/builddir/Click()
switch(dir)
if(NORTH)
dir = EAST
if(EAST)
dir = SOUTH
if(SOUTH)
dir = WEST
if(WEST)
dir = NORTHWEST
if(NORTHWEST)
dir = NORTH
/obj/buildhelp/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 ***********************************************************"
/obj/buildmode/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 = 1
src.icon_state = "buildmode1"
else if(pa.Find("right"))
switch(master.cl.buildmode)
if(1)
return
if(2)
objholder = input(usr,"Enter typepath:" ,"Typepath","/obj/closet")
var/list/removed_paths = list("/obj/bhole")
if(objholder in removed_paths)
alert("That path is not allowed.")
objholder = "/obj/closet"
else if (dd_hasprefix(objholder, "/mob") && !(usr.client.holder.rank in list("Host", "Coder", "Shit Guy")))
objholder = "/obj/closet"
if(3)
var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "cuffed", "ka", "last_eaten", "urine")
master.buildmode.varholder = input(usr,"Enter variable name:" ,"Name", "name")
if(master.buildmode.varholder in locked && !(usr.client.holder.rank in list("Host", "Coder")))
return
var/thetype = input(usr,"Select variable type:" ,"Type") in list("text","number","mob-reference","obj-reference","turf-reference")
if(!thetype) return
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 world
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
/proc/build_click(var/mob/user, buildmode, location, control, params, var/obj/object)
var/obj/buildholder/holder = null
for(var/obj/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.ReplaceWithFloor()
return
else if(istype(object,/turf/simulated/floor))
var/turf/T = object
T.ReplaceWithWall()
return
else if(istype(object,/turf/simulated/wall))
var/turf/T = object
T.ReplaceWithRWall()
return
else if(pa.Find("right"))
if(istype(object,/turf/simulated/wall))
var/turf/T = object
T.ReplaceWithFloor()
return
else if(istype(object,/turf/simulated/floor))
var/turf/T = object
T.ReplaceWithSpace()
return
else if(istype(object,/turf/simulated/wall/r_wall))
var/turf/T = object
T.ReplaceWithWall()
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)
new/obj/window/reinforced/north(get_turf(object))
if(EAST)
new/obj/window/reinforced/east(get_turf(object))
if(SOUTH)
new/obj/window/reinforced/south(get_turf(object))
if(WEST)
new/obj/window/reinforced/west(get_turf(object))
if(NORTHWEST)
new/obj/window/reinforced/northwest(get_turf(object))
if(2)
if(pa.Find("left"))
var/obj/A = new holder.buildmode.objholder (get_turf(object))
A.dir = holder.builddir.dir
blink(A)
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]")
// message_admins("[key_name_admin(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]", 1)
object.vars[holder.buildmode.varholder] = holder.buildmode.valueholder
blink(object)
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]")
// message_admins("[key_name_admin(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]", 1)
object.vars[holder.buildmode.varholder] = initial(object.vars[holder.buildmode.varholder])
blink(object)
else
usr << "\red [initial(object.name)] does not have a var called '[holder.buildmode.varholder]'"
/proc/blink(atom/A)
A.icon += rgb(0,75,75)
spawn(10) A.icon = initial(A.icon)
+724
View File
@@ -0,0 +1,724 @@
//Cloning revival method.
//The pod handles the actual cloning while the computer manages the clone profiles
//Potential replacement for genetics revives or something I dunno (?)
/obj/machinery/clonepod
anchored = 1
name = "cloning pod"
desc = "An electronically-lockable pod for growing organic tissue."
density = 1
icon = 'cloning.dmi'
icon_state = "pod_0"
req_access = list(access_medlab) //For premature unlocking.
var/mob/living/occupant
var/heal_level = 90 //The clone is released once its health reaches this level.
var/locked = 0
var/obj/machinery/computer/cloning/connected = null //So we remember the connected clone machine.
var/mess = 0 //Need to clean out it if it's full of exploded clone.
var/attempting = 0 //One clone attempt at a time thanks
var/eject_wait = 0 //Don't eject them as soon as they are created fuckkk
/obj/machinery/computer/cloning
name = "Cloning console"
icon = 'computer.dmi'
icon_state = "dna"
req_access = list(access_heads) //Only used for record deletion right now.
var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning.
var/obj/machinery/clonepod/pod1 = null //Linked cloning pod.
var/temp = "Initializing System..."
var/menu = 1 //Which menu screen to display
var/list/records = list()
var/datum/data/record/active_record = null
var/obj/item/weapon/disk/data/diskette = null //Mostly so the geneticist can steal everything.
//The return of data disks?? Just for transferring between genetics machine/cloning machine.
//TO-DO: Make the genetics machine accept them.
/obj/item/weapon/disk/data
name = "data disk"
icon = 'cloning.dmi'
icon_state = "datadisk0" //Gosh I hope syndies don't mistake them for the nuke disk.
item_state = "card-id"
w_class = 1.0
var/data = ""
var/ue = 0
var/data_type = "ui" //ui|se
var/owner = "God Emperor of Mankind"
var/read_only = 0 //Well,it's still a floppy disk
/obj/item/weapon/disk/data/demo
name = "data disk - 'God Emperor of Mankind'"
data = "066000033000000000AF00330660FF4DB002690"
//data = "0C80C80C80C80C80C8000000000000161FBDDEF" - Farmer Jeff
ue = 1
read_only = 1
/obj/item/weapon/disk/data/monkey
name = "data disk - 'Mr. Muggles'"
data_type = "se"
data = "0983E840344C39F4B059D5145FC5785DC6406A4FFF"
read_only = 1
/obj/machinery/computer/cloning/New()
..()
spawn(5)
src.scanner = locate(/obj/machinery/dna_scannernew, get_step(src, WEST))
src.pod1 = locate(/obj/machinery/clonepod, get_step(src, EAST))
src.temp = ""
if (isnull(src.scanner))
src.temp += " <font color=red>SCNR-ERROR</font>"
if (isnull(src.pod1))
src.temp += " <font color=red>POD1-ERROR</font>"
else
src.pod1.connected = src
if (src.temp == "")
src.temp = "System ready."
return
return
/obj/machinery/computer/cloning/attackby(obj/item/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES
if (!src.diskette)
user.drop_item()
W.loc = src
src.diskette = W
user << "You insert [W]."
src.updateUsrDialog()
return
else if((istype(W, /obj/item/weapon/screwdriver)) && (src.stat & BROKEN))
playsound(src.loc, 'Screwdriver.ogg', 50, 1)
if(do_after(user, 20))
user << "\blue The broken glass falls out."
var/obj/computerframe/A = new /obj/computerframe( src.loc )
new /obj/item/weapon/shard( src.loc )
var/obj/item/weapon/circuitboard/cloning/M = new /obj/item/weapon/circuitboard/cloning( A )
for (var/obj/C in src)
C.loc = src.loc
M.records = src.records
A.circuit = M
A.state = 3
A.icon_state = "3"
A.anchored = 1
del(src)
else
src.attack_hand(user)
return
/obj/machinery/computer/cloning/attack_paw(mob/user as mob)
return attack_hand(user)
/obj/machinery/computer/cloning/attack_ai(mob/user as mob)
return attack_hand(user)
/obj/machinery/computer/cloning/attack_hand(mob/user as mob)
user.machine = src
add_fingerprint(user)
if(stat & (BROKEN|NOPOWER))
return
var/dat = "<h3>Cloning System Control</h3>"
dat += "<font size=-1><a href='byond://?src=\ref[src];refresh=1'>Refresh</a></font>"
dat += "<br><tt>[temp]</tt><br>"
switch(src.menu)
if(1)
dat += "<h4>Scanner Functions</h4>"
if (isnull(src.scanner))
dat += "No scanner connected!"
else
if (src.scanner.occupant)
dat += "<a href='byond://?src=\ref[src];scan=1'>Scan - [src.scanner.occupant]</a>"
else
dat += "Scanner unoccupied"
dat += "<br>Lock status: <a href='byond://?src=\ref[src];lock=1'>[src.scanner.locked ? "Locked" : "Unlocked"]</a>"
dat += "<h4>Database Functions</h4>"
dat += "<a href='byond://?src=\ref[src];menu=2'>View Records</a><br>"
if (src.diskette)
dat += "<a href='byond://?src=\ref[src];disk=eject'>Eject Disk</a>"
if(2)
dat += "<h4>Current records</h4>"
dat += "<a href='byond://?src=\ref[src];menu=1'>Back</a><br><br>"
for(var/datum/data/record/R in src.records)
dat += "<a href='byond://?src=\ref[src];view_rec=\ref[R]'>[R.fields["id"]]-[R.fields["name"]]</a><br>"
if(3)
dat += "<h4>Selected Record</h4>"
dat += "<a href='byond://?src=\ref[src];menu=2'>Back</a><br>"
if (!src.active_record)
dat += "<font color=red>ERROR: Record not found.</font>"
else
dat += "<br><font size=1><a href='byond://?src=\ref[src];del_rec=1'>Delete Record</a></font><br>"
dat += "<b>Name:</b> [src.active_record.fields["name"]]<br>"
var/obj/item/weapon/implant/health/H = locate(src.active_record.fields["imp"])
if ((H) && (istype(H)))
dat += "<b>Health:</b> [H.sensehealth()] | OXY-BURN-TOX-BRUTE<br>"
else
dat += "<font color=red>Unable to locate implant.</font><br>"
if (!isnull(src.diskette))
dat += "<a href='byond://?src=\ref[src];disk=load'>Load from disk.</a>"
dat += " | Save: <a href='byond://?src=\ref[src];save_disk=ue'>UI + UE</a>"
dat += " | Save: <a href='byond://?src=\ref[src];save_disk=ui'>UI</a>"
dat += " | Save: <a href='byond://?src=\ref[src];save_disk=se'>SE</a>"
dat += "<br>"
else
dat += "<br>" //Keeping a line empty for appearances I guess.
dat += {"<b>UI:</b> [src.active_record.fields["UI"]]<br>
<b>SE:</b> [src.active_record.fields["SE"]]<br><br>
<a href='byond://?src=\ref[src];clone=\ref[src.active_record]'>Clone</a><br>"}
if(4)
if (!src.active_record)
src.menu = 2
dat = "[src.temp]<br>"
dat += "<h4>Confirm Record Deletion</h4>"
dat += "<b><a href='byond://?src=\ref[src];del_rec=1'>Scan card to confirm.</a></b><br>"
dat += "<b><a href='byond://?src=\ref[src];menu=3'>No</a></b>"
user << browse(dat, "window=cloning")
onclose(user, "cloning")
return
/obj/machinery/computer/cloning/Topic(href, href_list)
if(..())
return
if ((href_list["scan"]) && (!isnull(src.scanner)))
src.scan_mob(src.scanner.occupant)
//No locking an open scanner.
else if ((href_list["lock"]) && (!isnull(src.scanner)))
if ((!src.scanner.locked) && (src.scanner.occupant))
src.scanner.locked = 1
else
src.scanner.locked = 0
else if (href_list["view_rec"])
src.active_record = locate(href_list["view_rec"])
if ((isnull(src.active_record.fields["ckey"])) || (src.active_record.fields["ckey"] == ""))
del(src.active_record)
src.temp = "ERROR: Record Corrupt"
else
src.menu = 3
else if (href_list["del_rec"])
if ((!src.active_record) || (src.menu < 3))
return
if (src.menu == 3) //If we are viewing a record, confirm deletion
src.temp = "Delete record?"
src.menu = 4
else if (src.menu == 4)
var/obj/item/weapon/card/id/C = usr.equipped()
if (istype(C))
if(src.check_access(C))
src.records.Remove(src.active_record)
del(src.active_record)
src.temp = "Record deleted."
src.menu = 2
else
src.temp = "Access Denied."
else if (href_list["disk"]) //Load or eject.
switch(href_list["disk"])
if("load")
if ((isnull(src.diskette)) || (src.diskette.data == ""))
src.temp = "Load error."
src.updateUsrDialog()
return
if (isnull(src.active_record))
src.temp = "Record error."
src.menu = 1
src.updateUsrDialog()
return
if (src.diskette.data_type == "ui")
src.active_record.fields["UI"] = src.diskette.data
if (src.diskette.ue)
src.active_record.fields["name"] = src.diskette.owner
else if (src.diskette.data_type == "se")
src.active_record.fields["SE"] = src.diskette.data
src.temp = "Load successful."
if("eject")
if (!isnull(src.diskette))
src.diskette.loc = src.loc
src.diskette = null
else if (href_list["save_disk"]) //Save to disk!
if ((isnull(src.diskette)) || (src.diskette.read_only) || (isnull(src.active_record)))
src.temp = "Save error."
src.updateUsrDialog()
return
switch(href_list["save_disk"]) //Save as Ui/Ui+Ue/Se
if("ui")
src.diskette.data = src.active_record.fields["UI"]
src.diskette.ue = 0
src.diskette.data_type = "ui"
if("ue")
src.diskette.data = src.active_record.fields["UI"]
src.diskette.ue = 1
src.diskette.data_type = "ui"
if("se")
src.diskette.data = src.active_record.fields["SE"]
src.diskette.ue = 0
src.diskette.data_type = "se"
src.diskette.owner = src.active_record.fields["name"]
src.diskette.name = "data disk - '[src.diskette.owner]'"
src.temp = "Save \[[href_list["save_disk"]]\] successful."
else if (href_list["refresh"])
src.updateUsrDialog()
else if (href_list["clone"])
var/datum/data/record/C = locate(href_list["clone"])
//Look for that player! They better be dead!
var/mob/selected = find_dead_player("[C.fields["ckey"]]")
//Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.
if ((!selected) || (!src.pod1) || (src.pod1.occupant) || (src.pod1.mess))
src.temp = "Unable to initiate cloning cycle." // most helpful error message in THE HISTORY OF THE WORLD
else if (src.pod1.growclone(selected, C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"]))
src.temp = "Cloning cycle activated."
src.records.Remove(C)
del(C)
src.menu = 1
else if (href_list["menu"])
src.menu = text2num(href_list["menu"])
src.add_fingerprint(usr)
src.updateUsrDialog()
return
/obj/machinery/computer/cloning/proc/scan_mob(mob/living/carbon/human/subject as mob)
if ((isnull(subject)) || (!istype(subject, /mob/living/carbon/human)) || (!subject.dna))
src.temp = "Error: Unable to locate valid genetic data."
return
if ((!subject.ckey) || (!subject.client))
src.temp = "Error: Mental interface failure."
return
if (!isnull(find_record(subject.ckey)))
src.temp = "Subject already in database."
return
subject.dna.check_integrity()
var/datum/data/record/R = new /datum/data/record( )
R.fields["ckey"] = subject.ckey
R.fields["name"] = subject.real_name
R.fields["id"] = copytext(md5(subject.real_name), 2, 6)
R.fields["UI"] = subject.dna.uni_identity
R.fields["SE"] = subject.dna.struc_enzymes
//Add an implant if needed
var/obj/item/weapon/implant/health/imp =locate(/obj/item/weapon/implant/health, subject)
if (isnull(imp))
imp = new /obj/item/weapon/implant/health(subject)
imp.implanted = subject
R.fields["imp"] = "\ref[imp]"
//Update it if needed
else
R.fields["imp"] = "\ref[imp]"
if (!isnull(subject.mind)) //Save that mind so traitors can continue traitoring after cloning.
R.fields["mind"] = "\ref[subject.mind]"
src.records += R
src.temp = "Subject successfully scanned."
//Find a specific record by key.
/obj/machinery/computer/cloning/proc/find_record(var/find_key)
var/selected_record = null
for(var/datum/data/record/R in src.records)
if (R.fields["ckey"] == find_key)
selected_record = R
break
return selected_record
/obj/machinery/computer/cloning/power_change()
if(stat & BROKEN)
icon_state = "commb"
else
if( powered() )
icon_state = initial(icon_state)
stat &= ~NOPOWER
else
spawn(rand(0, 15))
src.icon_state = "c_unpowered"
stat |= NOPOWER
//Find a dead mob with a brain and client.
/proc/find_dead_player(var/find_key)
if (isnull(find_key))
return
var/mob/selected = null
for(var/mob/M in world)
//Dead people only thanks!
if ((M.stat != 2) || (!M.client))
continue
//They need a brain!
if ((istype(M, /mob/living/carbon/human)) && (M:brain_op_stage >= 4.0))
continue
if (M.ckey == find_key)
selected = M
break
return selected
//Disk stuff.
/obj/item/weapon/disk/data/New()
..()
var/diskcolor = pick(0,1,2)
src.icon_state = "datadisk[diskcolor]"
/obj/item/weapon/disk/data/attack_self(mob/user as mob)
src.read_only = !src.read_only
user << "You flip the write-protect tab to [src.read_only ? "protected" : "unprotected"]."
/obj/item/weapon/disk/data/examine()
set src in oview(5)
..()
usr << text("The write-protect tab is set to [src.read_only ? "protected" : "unprotected"].")
return
//Health Tracker Implant
/obj/item/weapon/implant/health
name = "health implant"
var/healthstring = ""
/obj/item/weapon/implant/health/proc/sensehealth()
if (!src.implanted)
return "ERROR"
else
src.healthstring = "[round(src.implanted:oxyloss)] - [round(src.implanted:fireloss)] - [round(src.implanted:toxloss)] - [round(src.implanted:bruteloss)]"
if (!src.healthstring)
src.healthstring = "ERROR"
return src.healthstring
/obj/machinery/clonepod/attack_ai(mob/user as mob)
return attack_hand(user)
/obj/machinery/clonepod/attack_paw(mob/user as mob)
return attack_hand(user)
/obj/machinery/clonepod/attack_hand(mob/user as mob)
if ((isnull(src.occupant)) || (stat & NOPOWER))
return
if ((!isnull(src.occupant)) && (src.occupant.stat != 2))
var/completion = (100 * ((src.occupant.health + 100) / (src.heal_level + 100)))
user << "Current clone cycle is [round(completion)]% complete."
return
//Clonepod
//Start growing a human clone in the pod!
/obj/machinery/clonepod/proc/growclone(mob/ghost as mob, var/clonename, var/ui, var/se, var/mindref)
if (((!ghost) || (!ghost.client)) || src.mess || src.attempting)
return 0
src.attempting = 1 //One at a time!!
src.locked = 1
src.eject_wait = 1
spawn(30)
src.eject_wait = 0
src.occupant = new /mob/living/carbon/human(src)
ghost.client.mob = src.occupant
src.icon_state = "pod_1"
//Get the clone body ready
src.occupant.rejuv = 10
src.occupant.bruteloss += 90
src.occupant.toxloss += 50
src.occupant.oxyloss += 40
src.occupant.brainloss += 90
src.occupant.paralysis += 4
//Here let's calculate their health so the pod doesn't immediately eject them!!!
src.occupant.health = (src.occupant.bruteloss + src.occupant.toxloss + src.occupant.oxyloss)
src.occupant << "\blue <b>Clone generation process initiated.</b>"
src.occupant << "\blue This will take a moment, please hold."
if (clonename)
src.occupant.real_name = clonename
else
src.occupant.real_name = "clone" //No null names!!
var/datum/mind/clonemind = (locate(mindref) in ticker.minds)
if ((clonemind) && (istype(clonemind))) //Move that mind over!!
clonemind.transfer_to(src.occupant)
else //welp
src.occupant.mind = new /datum/mind( )
src.occupant.mind.key = src.occupant.key
src.occupant.mind.current = src.occupant
src.occupant.mind.transfer_to(src.occupant)
ticker.minds += src.occupant.mind
// -- Mode/mind specific stuff goes here
switch(ticker.mode.name)
if ("revolution")
if ((src.occupant.mind in ticker.mode:revolutionaries) || (src.occupant.mind in ticker.mode:head_revolutionaries))
ticker.mode:add_revolutionary(src.occupant.mind)
ticker.mode:update_all_rev_icons() //So the icon actually appears
// -- End mode specific stuff
if (istype(ghost, /mob/dead/observer))
del(ghost) //Don't leave ghosts everywhere!!
if (!src.occupant.dna)
src.occupant.dna = new /datum/dna( )
if (ui)
src.occupant.dna.uni_identity = ui
updateappearance(src.occupant, ui)
if (se)
src.occupant.dna.struc_enzymes = se
randmutb(src.occupant) //Sometimes the clones come out wrong.
src.attempting = 0
return 1
//Grow clones to maturity then kick them out. FREELOADERS
/obj/machinery/clonepod/process()
if (stat & NOPOWER) //Autoeject if power is lost
if (src.occupant)
src.locked = 0
src.go_out()
return
if ((src.occupant) && (src.occupant.loc == src))
if((src.occupant.stat == 2) || (src.occupant.suiciding)) //Autoeject corpses and suiciding dudes.
src.locked = 0
src.go_out()
src.connected_message("Clone Rejected: Deceased.")
return
else if(src.occupant.health < src.heal_level)
src.occupant.paralysis = 4
//Slowly get that clone healed and finished.
src.occupant.bruteloss = max(src.occupant.bruteloss-1, 0)
//At this rate one clone takes about 95 seconds to produce.(with heal_level 90)
src.occupant.toxloss = max(src.occupant.toxloss-0.5, 0)
//Premature clones may have brain damage.
src.occupant.brainloss = max(src.occupant.brainloss-1, 0)
//So clones don't die of oxyloss in a running pod.
if (src.occupant.reagents.get_reagent_amount("inaprovaline") < 30)
src.occupant.reagents.add_reagent("inaprovaline", 60)
//Also heal some oxyloss ourselves because inaprovaline is so bad at preventing it!!
src.occupant.oxyloss = max(src.occupant.oxyloss-2, 0)
//Stop baking in the tubes you jerks.
src.occupant.fireloss = max(src.occupant.fireloss-2, 0)
use_power(7500) //This might need tweaking.
return
else if((src.occupant.health >= src.heal_level) && (!src.eject_wait))
src.connected_message("Cloning Process Complete.")
src.locked = 0
src.go_out()
return
else if ((!src.occupant) || (src.occupant.loc != src))
src.occupant = null
if (src.locked)
src.locked = 0
if (!src.mess)
icon_state = "pod_0"
use_power(200)
return
return
//Let's unlock this early I guess. Might be too early, needs tweaking.
/obj/machinery/clonepod/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/card/id))
if (!src.check_access(W))
user << "\red Access Denied."
return
if ((!src.locked) || (isnull(src.occupant)))
return
if ((src.occupant.health < -20) && (src.occupant.stat != 2))
user << "\red Access Refused."
return
else
src.locked = 0
user << "System unlocked."
else if (istype(W, /obj/item/weapon/card/emag))
if (isnull(src.occupant))
return
user << "You force an emergency ejection."
src.locked = 0
src.go_out()
return
else
..()
//Put messages in the connected computer's temp var for display.
/obj/machinery/clonepod/proc/connected_message(var/message)
if ((isnull(src.connected)) || (!istype(src.connected, /obj/machinery/computer/cloning)))
return 0
if (!message)
return 0
src.connected.temp = message
src.connected.updateUsrDialog()
return 1
/obj/machinery/clonepod/verb/eject()
set src in oview(1)
if (usr.stat != 0)
return
src.go_out()
add_fingerprint(usr)
return
/obj/machinery/clonepod/proc/go_out()
if (src.locked)
return
if (src.mess) //Clean that mess and dump those gibs!
src.mess = 0
gibs(src.loc)
src.icon_state = "pod_0"
for(var/obj/O in src)
O.loc = src.loc
return
if (!(src.occupant))
return
for(var/obj/O in src)
O.loc = src.loc
if (src.occupant.client)
src.occupant.client.eye = src.occupant.client.mob
src.occupant.client.perspective = MOB_PERSPECTIVE
src.occupant.loc = src.loc
src.icon_state = "pod_0"
src.eject_wait = 0 //If it's still set somehow.
domutcheck(src.occupant) //Waiting until they're out before possible monkeyizing.
src.occupant = null
return
/obj/machinery/clonepod/proc/malfunction()
if (src.occupant)
src.connected_message("Critical Error!")
src.mess = 1
src.icon_state = "pod_g"
src.occupant.ghostize()
spawn(5)
del(src.occupant)
return
/obj/machinery/clonepod/relaymove(mob/user as mob)
if (user.stat)
return
src.go_out()
return
/obj/machinery/clonepod/ex_act(severity)
switch(severity)
if(1.0)
for(var/atom/movable/A as mob|obj in src)
A.loc = src.loc
ex_act(severity)
del(src)
return
if(2.0)
if (prob(50))
for(var/atom/movable/A as mob|obj in src)
A.loc = src.loc
ex_act(severity)
del(src)
return
if(3.0)
if (prob(25))
for(var/atom/movable/A as mob|obj in src)
A.loc = src.loc
ex_act(severity)
del(src)
return
else
return
/*
* Diskette Box
*/
/obj/item/weapon/storage/diskbox
name = "Diskette Box"
icon_state = "disk_kit"
item_state = "syringe_kit"
/obj/item/weapon/storage/diskbox/New()
..()
new /obj/item/weapon/disk/data(src)
new /obj/item/weapon/disk/data(src)
new /obj/item/weapon/disk/data(src)
new /obj/item/weapon/disk/data(src)
new /obj/item/weapon/disk/data(src)
new /obj/item/weapon/disk/data(src)
new /obj/item/weapon/disk/data(src)
/*
* Manual -- A big ol' manual.
*/
/obj/item/weapon/paper/Cloning
name = "paper - 'H-87 Cloning Apparatus Manual"
info = {"<h4>Getting Started</h4>
Congratulations, your station has purchased the H-87 industrial cloning device!<br>
Using the H-87 is almost as simple as brain surgery! Simply insert the target humanoid into the scanning chamber and select the scan option to create a new profile!<br>
<b>That's all there is to it!</b><br>
<i>Notice, cloning system cannot scan inorganic life or small primates. Scan may fail if subject has suffered extreme brain damage.</i><br>
<p>Clone profiles may be viewed through the profiles menu. Scanning implants a complementary HEALTH MONITOR IMPLANT into the subject, which may be viewed from each profile.
Profile Deletion has been restricted to \[Station Head\] level access.</p>
<h4>Cloning from a profile</h4>
Cloning is as simple as pressing the CLONE option at the bottom of the desired profile.<br>
Per your company's EMPLOYEE PRIVACY RIGHTS agreement, the H-87 has been blocked from cloning crewmembers while they are still alive.<br>
<br>
<p>The provided CLONEPOD SYSTEM will produce the desired clone. Standard clone maturation times (With SPEEDCLONE technology) are roughly 90 seconds.
The cloning pod may be unlocked early with any \[Medical Researcher\] ID after initial maturation is complete.</p><br>
<i>Please note that resulting clones may have a small DEVELOPMENTAL DEFECT as a result of genetic drift.</i><br>
<h4>Profile Management</h4>
<p>The H-87 (as well as your station's standard genetics machine) can accept STANDARD DATA DISKETTES.
These diskettes are used to transfer genetic information between machines and profiles.
A load/save dialog will become available in each profile if a disk is inserted.</p><br>
<i>A good diskette is a great way to counter aforementioned genetic drift!</i><br>
<br>
<font size=1>This technology produced under license from Thinktronic Systems, LTD.</font>"}
//SOME SCRAPS I GUESS
/* EMP grenade/spell effect
if(istype(A, /obj/machinery/clonepod))
A:malfunction()
*/
@@ -0,0 +1,60 @@
/datum/computer/file/computer_program/airlock_control
name = "Airlock Master"
size = 16.0
id_tag = "TAG"
return_text()
if(..())
return
var/dat = "<a href='byond://?src=\ref[src];close=1'>Close</a> | "
dat += "<a href='byond://?src=\ref[src];quit=1'>Quit</a>"
/*
dat += "<br><TT>Frequency: "
dat += "<a href='?src=\ref[src];adj_freq=-10'>--</a> "
dat += "<a href='?src=\ref[src];adj_freq=-2'>-</a> "
dat += "[format_frequency(src.master.frequency)] "
dat += "<a href='?src=\ref[src];adj_freq=2'>+</a> "
dat += "<a href='?src=\ref[src];adj_freq=10'>++</a>"
dat += "</TT><br>"
*/
dat += "<br>ID:<a href='byond://?src=\ref[src];set_tag=1'>[src.id_tag]</a><br>"
dat += "<a href='byond://?src=\ref[src];send_command=cycle'>Cycle</a>"
dat += "</b></center>"
return dat
Topic(href, href_list)
if(..())
return
if(href_list["set_tag"])
var/t = input(usr, "Please enter new tag", src.id_tag, null) as text
t = copytext(sanitize(t), 1, MAX_MESSAGE_LEN)
if (!t)
return
if (!in_range(src.master, usr))
return
src.id_tag = t
// if(href_list["adj_freq"])
// var/new_frequency = (src.master.frequency + text2num(href_list["adj_freq"]))
// src.master.set_frequency(new_frequency)
if(href_list["send_command"])
var/datum/signal/signal = new
signal.data["tag"] = id_tag
signal.data["command"] = href_list["send_command"]
peripheral_command("send signal", signal)
src.master.add_fingerprint(usr)
src.master.updateUsrDialog()
return
+136
View File
@@ -0,0 +1,136 @@
/datum/computer/file/computer_program/arcade
name = "Arcade 500"
size = 8.0
var/enemy_name = "Space Villian"
var/temp = "Winners Don't Use Spacedrugs" //Temporary message, for attack messages, etc
var/player_hp = 30 //Player health/attack points
var/player_mp = 10
var/enemy_hp = 45 //Enemy health/attack points
var/enemy_mp = 20
var/gameover = 0
var/blocked = 0 //Player cannot attack/heal while set
New(obj/holding as obj)
if(holding)
src.holder = holding
if(istype(src.holder.loc,/obj/machinery/computer2))
src.master = src.holder.loc
// var/name_action = pick("Defeat ", "Annihilate ", "Save ", "Strike ", "Stop ", "Destroy ", "Robust ", "Romance ")
var/name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Evil ", "the Dread King ", "the Space ", "Lord ")
var/name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon")
src.enemy_name = dd_replacetext((name_part1 + name_part2), "the ", "")
// src.name = (name_action + name_part1 + name_part2)
/datum/computer/file/computer_program/arcade/return_text()
if(..())
return
var/dat = "<a href='byond://?src=\ref[src];close=1'>Close</a> | "
dat += "<a href='byond://?src=\ref[src];quit=1'>Quit</a>"
dat += "<center><h4>[src.enemy_name]</h4></center>"
dat += "<br><center><h3>[src.temp]</h3></center>"
dat += "<br><center>Health: [src.player_hp] | Magic: [src.player_mp] | Enemy Health: [src.enemy_hp]</center>"
if (src.gameover)
dat += "<center><b><a href='byond://?src=\ref[src];newgame=1'>New Game</a>"
else
dat += "<center><b><a href='byond://?src=\ref[src];attack=1'>Attack</a> | "
dat += "<a href='byond://?src=\ref[src];heal=1'>Heal</a> | "
dat += "<a href='byond://?src=\ref[src];charge=1'>Recharge Power</a>"
dat += "</b></center>"
return dat
/datum/computer/file/computer_program/arcade/Topic(href, href_list)
if(..())
return
if (!src.blocked)
if (href_list["attack"])
src.blocked = 1
var/attackamt = rand(2,6)
src.temp = "You attack for [attackamt] damage!"
src.master.updateUsrDialog()
sleep(10)
src.enemy_hp -= attackamt
src.arcade_action()
else if (href_list["heal"])
src.blocked = 1
var/pointamt = rand(1,3)
var/healamt = rand(6,8)
src.temp = "You use [pointamt] magic to heal for [healamt] damage!"
src.master.updateUsrDialog()
sleep(10)
src.player_mp -= pointamt
src.player_hp += healamt
src.blocked = 1
src.master.updateUsrDialog()
src.arcade_action()
else if (href_list["charge"])
src.blocked = 1
var/chargeamt = rand(4,7)
src.temp = "You regain [chargeamt] points"
src.player_mp += chargeamt
src.master.updateUsrDialog()
sleep(10)
src.arcade_action()
if (href_list["newgame"]) //Reset everything
temp = "New Round"
player_hp = 30
player_mp = 10
enemy_hp = 45
enemy_mp = 20
gameover = 0
src.master.add_fingerprint(usr)
src.master.updateUsrDialog()
return
/datum/computer/file/computer_program/arcade/proc/arcade_action()
if ((src.enemy_mp <= 0) || (src.enemy_hp <= 0))
src.gameover = 1
src.temp = "[src.enemy_name] has fallen! Rejoice!"
src.peripheral_command("vend prize")
else if ((src.enemy_mp <= 5) && (prob(70)))
var/stealamt = rand(2,3)
src.temp = "[src.enemy_name] steals [stealamt] of your power!"
src.player_mp -= stealamt
src.master.updateUsrDialog()
if (src.player_mp <= 0)
src.gameover = 1
sleep(10)
src.temp = "You have been drained! GAME OVER"
else if ((src.enemy_hp <= 10) && (src.enemy_mp > 4))
src.temp = "[src.enemy_name] heals for 4 health!"
src.enemy_hp += 4
src.enemy_mp -= 4
else
var/attackamt = rand(3,6)
src.temp = "[src.enemy_name] attacks for [attackamt] damage!"
src.player_hp -= attackamt
if ((src.player_mp <= 0) || (src.player_hp <= 0))
src.gameover = 1
src.temp = "You have been crushed! GAME OVER"
src.blocked = 0
return
@@ -0,0 +1,263 @@
/datum/computer
var/size = 4.0
var/obj/item/weapon/disk/data/holder = null
var/datum/computer/folder/holding_folder = null
folder
name = "Folder"
size = 0.0
var/gen = 0
Del()
for(var/datum/computer/F in src.contents)
del(F)
..()
proc
add_file(datum/computer/R)
if(!holder || holder.read_only || !R)
return 0
if(istype(R,/datum/computer/folder) && (src.gen>=10))
return 0
if((holder.file_used + R.size) <= holder.file_amount)
src.contents.Add(R)
R.holder = holder
R.holding_folder = src
src.holder.file_used -= src.size
src.size += R.size
src.holder.file_used += src.size
if(istype(R,/datum/computer/folder))
R:gen = (src.gen+1)
return 1
return 0
remove_file(datum/computer/R)
if(holder && !holder.read_only || !R)
// world << "Removing file [R]. File_used: [src.holder.file_used]"
src.contents.Remove(R)
src.holder.file_used -= src.size
src.size -= R.size
src.holder.file_used += src.size
src.holder.file_used = max(src.holder.file_used, 0)
// world << "Removed file [R]. File_used: [src.holder.file_used]"
return 1
return 0
file
name = "File"
var/extension = "FILE" //Differentiate between types of files, why not
proc
copy_file_to_folder(datum/computer/folder/newfolder)
if(!newfolder || (!istype(newfolder)) || (!newfolder.holder) || (newfolder.holder.read_only))
return 0
if((newfolder.holder.file_used + src.size) <= newfolder.holder.file_amount)
var/datum/computer/file/newfile = new src.type
for(var/V in src.vars)
if (issaved(src.vars[V]) && V != "holder")
newfile.vars[V] = src.vars[V]
if(!newfolder.add_file(newfile))
del(newfile)
return 1
return 0
Del()
if(holder && holding_folder)
holding_folder.remove_file(src)
..()
/datum/computer/file/computer_program
name = "blank program"
extension = "PROG"
//var/size = 4.0
//var/obj/item/weapon/disk/data/holder = null
var/obj/machinery/computer2/master = null
var/active_icon = null
var/id_tag = null
var/list/req_access = list()
New(obj/holding as obj)
if(holding)
src.holder = holding
if(istype(src.holder.loc,/obj/machinery/computer2))
src.master = src.holder.loc
Del()
if(master)
master.processing_programs.Remove(src)
..()
proc
return_text()
if((!src.holder) || (!src.master))
return 1
if((!istype(holder)) || (!istype(master)))
return 1
if(master.stat & (NOPOWER|BROKEN))
return 1
if(!(holder in src.master.contents))
//world << "Holder [holder] not in [master] of prg:[src]"
if(master.active_program == src)
master.active_program = null
return 1
if(!src.holder.root)
src.holder.root = new /datum/computer/folder
src.holder.root.holder = src
src.holder.root.name = "root"
return 0
process()
if((!src.holder) || (!src.master))
return 1
if((!istype(holder)) || (!istype(master)))
return 1
if(!(holder in src.master.contents))
if(master.active_program == src)
master.active_program = null
master.processing_programs.Remove(src)
return 1
if(!src.holder.root)
src.holder.root = new /datum/computer/folder
src.holder.root.holder = src
src.holder.root.name = "root"
return 0
receive_command(obj/source, command, datum/signal/signal)
if((!src.holder) || (!src.master) || (!source) || (source != src.master))
return 1
if((!istype(holder)) || (!istype(master)))
return 1
if(master.stat & (NOPOWER|BROKEN))
return 1
if(!(holder in src.master.contents))
if(master.active_program == src)
master.active_program = null
return 1
return 0
peripheral_command(command, datum/signal/signal)
if(master)
master.send_command(command, signal)
else
del(signal)
transfer_holder(obj/item/weapon/disk/data/newholder,datum/computer/folder/newfolder)
if((newholder.file_used + src.size) > newholder.file_amount)
return 0
if(!newholder.root)
newholder.root = new /datum/computer/folder
newholder.root.holder = newholder
newholder.root.name = "root"
if(!newfolder)
newfolder = newholder.root
if((src.holder && src.holder.read_only) || newholder.read_only)
return 0
if((src.holder) && (src.holder.root))
src.holder.root.remove_file(src)
newfolder.add_file(src)
if(istype(newholder.loc,/obj/machinery/computer2))
src.master = newholder.loc
//world << "Setting [src.holder] to [newholder]"
src.holder = newholder
return 1
//Check access per program.
allowed(mob/M)
//check if it doesn't require any access at all
if(src.check_access(null))
return 1
if(istype(M, /mob/living/silicon))
//AI can do whatever he wants
return 1
else if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
//if they are holding or wearing a card that has access, that works
if(src.check_access(H.equipped()) || src.check_access(H.wear_id))
return 1
else if(istype(M, /mob/living/carbon/monkey))
var/mob/living/carbon/monkey/george = M
//they can only hold things :(
if(george.equipped() && istype(george.equipped(), /obj/item/weapon/card/id) && src.check_access(george.equipped()))
return 1
return 0
check_access(obj/item/weapon/card/id/I)
if(!src.req_access) //no requirements
return 1
if(!istype(src.req_access, /list)) //something's very wrong
return 1
var/list/L = src.req_access
if(!L.len) //no requirements
return 1
if(!I || !istype(I, /obj/item/weapon/card/id) || !I.access) //not ID or no access
return 0
for(var/req in src.req_access)
if(!(req in I.access)) //doesn't have this access
return 0
return 1
Topic(href, href_list)
if((!src.holder) || (!src.master))
return 1
if((!istype(holder)) || (!istype(master)))
return 1
if(master.stat & (NOPOWER|BROKEN))
return 1
if(src.master.active_program != src)
return 1
if ((!usr.contents.Find(src.master) && (!in_range(src.master, usr) || !istype(src.master.loc, /turf))) && (!istype(usr, /mob/living/silicon)))
return 1
if(!(holder in src.master.contents))
if(master.active_program == src)
master.active_program = null
return 1
usr.machine = src.master
if (href_list["close"])
usr.machine = null
usr << browse(null, "window=comp2")
return 0
if (href_list["quit"])
// src.master.processing_programs.Remove(src)
if(src.master.host_program && src.master.host_program.holder && (src.master.host_program.holder in src.master.contents))
src.master.run_program(src.master.host_program)
src.master.updateUsrDialog()
return 1
else
src.master.active_program = null
src.master.updateUsrDialog()
return 1
return 0
@@ -0,0 +1,153 @@
//Motherboard is just used in assembly/disassembly, doesn't exist in the actual computer object.
/obj/item/weapon/motherboard
name = "Computer mainboard"
desc = "A computer motherboard."
icon = 'module.dmi'
icon_state = "mainboard"
item_state = "electronic"
w_class = 3
var/created_name = null //If defined, result computer will have this name.
/obj/computer2frame
density = 1
anchored = 0
name = "Computer-frame"
icon = 'computer_frame.dmi'
icon_state = "0"
var/state = 0
var/obj/item/weapon/motherboard/mainboard = null
var/obj/item/weapon/disk/data/fixed_disk/hd = null
var/list/peripherals = list()
var/created_icon_state = "aiupload"
/obj/computer2frame/attackby(obj/item/weapon/P as obj, mob/user as mob)
switch(state)
if(0)
if(istype(P, /obj/item/weapon/wrench))
playsound(src.loc, 'Ratchet.ogg', 50, 1)
if(do_after(user, 20))
user << "\blue You wrench the frame into place."
src.anchored = 1
src.state = 1
if(istype(P, /obj/item/weapon/weldingtool))
playsound(src.loc, 'Welder.ogg', 50, 1)
if(do_after(user, 20))
user << "\blue You deconstruct the frame."
var/obj/item/weapon/sheet/metal/A = new /obj/item/weapon/sheet/metal( src.loc )
A.amount = 5
del(src)
if(1)
if(istype(P, /obj/item/weapon/wrench))
playsound(src.loc, 'Ratchet.ogg', 50, 1)
if(do_after(user, 20))
user << "\blue You unfasten the frame."
src.anchored = 0
src.state = 0
if(istype(P, /obj/item/weapon/motherboard) && !mainboard)
playsound(src.loc, 'Deconstruct.ogg', 50, 1)
user << "\blue You place the mainboard inside the frame."
src.icon_state = "1"
src.mainboard = P
user.drop_item()
P.loc = src
if(istype(P, /obj/item/weapon/screwdriver) && mainboard)
playsound(src.loc, 'Screwdriver.ogg', 50, 1)
user << "\blue You screw the mainboard into place."
src.state = 2
src.icon_state = "2"
if(istype(P, /obj/item/weapon/crowbar) && mainboard)
playsound(src.loc, 'Crowbar.ogg', 50, 1)
user << "\blue You remove the mainboard."
src.state = 1
src.icon_state = "0"
mainboard.loc = src.loc
src.mainboard = null
if(2)
if(istype(P, /obj/item/weapon/screwdriver) && mainboard && (!peripherals.len))
playsound(src.loc, 'Screwdriver.ogg', 50, 1)
user << "\blue You unfasten the mainboard."
src.state = 1
src.icon_state = "1"
if(istype(P, /obj/item/weapon/peripheral))
if(src.peripherals.len < 3)
user.drop_item()
src.peripherals.Add(P)
P.loc = src
user << "\blue You add [P] to the frame."
else
user << "\red There is no more room for peripheral cards."
if(istype(P, /obj/item/weapon/crowbar) && src.peripherals.len)
playsound(src.loc, 'Crowbar.ogg', 50, 1)
user << "\blue You remove the peripheral boards."
for(var/obj/item/weapon/peripheral/W in src.peripherals)
W.loc = src.loc
src.peripherals.Remove(W)
if(istype(P, /obj/item/weapon/cable_coil))
if(P:amount >= 5)
playsound(src.loc, 'Deconstruct.ogg', 50, 1)
if(do_after(user, 20))
P:amount -= 5
if(!P:amount) del(P)
user << "\blue You add cables to the frame."
src.state = 3
src.icon_state = "3"
if(3)
if(istype(P, /obj/item/weapon/wirecutters))
playsound(src.loc, 'wirecutter.ogg', 50, 1)
user << "\blue You remove the cables."
src.state = 2
src.icon_state = "2"
var/obj/item/weapon/cable_coil/A = new /obj/item/weapon/cable_coil( src.loc )
A.amount = 5
if(src.hd)
src.hd.loc = src.loc
src.hd = null
if(istype(P, /obj/item/weapon/disk/data/fixed_disk) && !src.hd)
user.drop_item()
src.hd = P
P.loc = src
user << "\blue You connect the drive to the cabling."
if(istype(P, /obj/item/weapon/crowbar) && src.hd)
playsound(src.loc, 'Crowbar.ogg', 50, 1)
user << "\blue You remove the hard drive."
src.hd.loc = src.loc
src.hd = null
if(istype(P, /obj/item/weapon/sheet/glass))
if(P:amount >= 2)
playsound(src.loc, 'Deconstruct.ogg', 50, 1)
if(do_after(user, 20))
P:amount -= 2
if(!P:amount) del(P)
user << "\blue You put in the glass panel."
src.state = 4
src.icon_state = "4"
if(4)
if(istype(P, /obj/item/weapon/crowbar))
playsound(src.loc, 'Crowbar.ogg', 50, 1)
user << "\blue You remove the glass panel."
src.state = 3
src.icon_state = "3"
var/obj/item/weapon/sheet/glass/A = new /obj/item/weapon/sheet/glass( src.loc )
A.amount = 2
if(istype(P, /obj/item/weapon/screwdriver))
playsound(src.loc, 'Screwdriver.ogg', 50, 1)
user << "\blue You connect the monitor."
var/obj/machinery/computer2/C= new /obj/machinery/computer2( src.loc )
C.setup_drive_size = 0
C.icon_state = src.created_icon_state
if(mainboard.created_name) C.name = mainboard.created_name
del(mainboard)
if(hd)
C.hd = hd
hd.loc = C
for(var/obj/item/weapon/peripheral/W in src.peripherals)
W.loc = C
W.host = C
C.peripherals.Add(W)
del(src)
+414
View File
@@ -0,0 +1,414 @@
/obj/machinery/computer2
name = "computer"
desc = "A computer workstation."
icon = 'computer.dmi'
icon_state = "aiupload"
density = 1
anchored = 1.0
req_access = list() //This doesn't determine PROGRAM req access, just the access needed to install/delete programs.
var/base_icon_state = "aiupload" //Assembly creates a new computer2 and not a child typepath, so initial doesn't work!!
var/datum/radio_frequency/radio_connection
var/obj/item/weapon/disk/data/fixed_disk/hd = null
var/datum/computer/file/computer_program/active_program
var/datum/computer/file/computer_program/host_program //active is set to this when the normal active quits, if available
var/list/processing_programs = list()
var/obj/item/weapon/card/id/authid = null //For records computers etc
var/obj/item/weapon/card/id/auxid = null //For computers that need two ids for some reason.
var/obj/item/weapon/disk/data/diskette = null
var/list/peripherals = list()
//Setup for Starting program & peripherals
var/setup_starting_program = null //If set to a program path it will start with this one active.
var/setup_starting_peripheral = null //Spawn with radio card and whatever path is here.
var/setup_drive_size = 64.0 //How big is the drive (set to 0 for no drive)
var/setup_id_tag
var/setup_has_radio = 0 //Does it spawn with a radio peripheral?
var/setup_radio_tag
var/setup_frequency = 1411
/obj/item/weapon/disk/data
var/datum/computer/folder/root = null
var/file_amount = 32.0
var/file_used = 0.0
var/portable = 1
var/title = "Data Disk"
New()
src.root = new /datum/computer/folder
src.root.holder = src
src.root.name = "root"
/obj/item/weapon/disk/data/fixed_disk
name = "Storage Drive"
icon_state = "harddisk"
title = "Storage Drive"
file_amount = 80.0
portable = 0
attack_self(mob/user as mob)
return
/obj/item/weapon/disk/data/computer2test
name = "Programme Diskette"
file_amount = 128.0
New()
..()
src.root.add_file( new /datum/computer/file/computer_program/arcade(src))
src.root.add_file( new /datum/computer/file/computer_program/med_data(src))
src.root.add_file( new /datum/computer/file/computer_program/airlock_control(src))
src.root.add_file( new /datum/computer/file/computer_program/messenger(src))
src.root.add_file( new /datum/computer/file/computer_program/progman(src))
/obj/machinery/computer2/medical
name = "Medical computer"
icon_state = "dna"
setup_has_radio = 1
setup_starting_program = /datum/computer/file/computer_program/med_data
setup_starting_peripheral = /obj/item/weapon/peripheral/printer
/obj/machinery/computer2/arcade
name = "arcade machine"
icon_state = "arcade"
desc = "An arcade machine."
setup_drive_size = 16.0
setup_starting_program = /datum/computer/file/computer_program/arcade
setup_starting_peripheral = /obj/item/weapon/peripheral/prize_vendor
/obj/machinery/computer2/New()
..()
spawn(4)
if(setup_has_radio)
var/obj/item/weapon/peripheral/radio/radio = new /obj/item/weapon/peripheral/radio(src)
radio.frequency = setup_frequency
radio.code = setup_radio_tag
if(!hd && (setup_drive_size > 0))
src.hd = new /obj/item/weapon/disk/data/fixed_disk(src)
src.hd.file_amount = src.setup_drive_size
if(ispath(src.setup_starting_program))
src.active_program = new src.setup_starting_program
src.active_program.id_tag = setup_id_tag
src.hd.file_amount = max(src.hd.file_amount, src.active_program.size)
src.active_program.transfer_holder(src.hd)
if(ispath(src.setup_starting_peripheral))
new src.setup_starting_peripheral(src)
src.base_icon_state = src.icon_state
return
/obj/machinery/computer2/attack_hand(mob/user as mob)
if(..())
return
user.machine = src
var/dat
if((src.active_program) && (src.active_program.master == src) && (src.active_program.holder in src))
dat = src.active_program.return_text()
else
dat = "<TT><b>Thinktronic BIOS V1.4</b><br><br>"
dat += "Current ID: <a href='?src=\ref[src];id=auth'>[src.authid ? "[src.authid.name]" : "----------"]</a><br>"
dat += "Auxiliary ID: <a href='?src=\ref[src];id=aux'>[src.auxid ? "[src.auxid.name]" : "----------"]</a><br><br>"
var/progdat
if((src.hd) && (src.hd.root))
for(var/datum/computer/file/computer_program/P in src.hd.root.contents)
progdat += "<tr><td>[P.name]</td><td>Size: [P.size]</td>"
progdat += "<td><a href='byond://?src=\ref[src];prog=\ref[P];function=run'>Run</a></td>"
if(P in src.processing_programs)
progdat += "<td><a href='byond://?src=\ref[src];prog=\ref[P];function=unload'>Halt</a></td>"
else
progdat += "<td><a href='byond://?src=\ref[src];prog=\ref[P];function=load'>Load</a></td>"
progdat += "<td><a href='byond://?src=\ref[src];file=\ref[P];function=delete'>Del</a></td></tr>"
continue
dat += "Disk Space: \[[src.hd.file_used]/[src.hd.file_amount]\]<br>"
dat += "<b>Programs on Fixed Disk:</b><br>"
if(!progdat)
progdat = "No programs found.<br>"
dat += "<center><table cellspacing=4>[progdat]</table></center>"
else
dat += "<b>Programs on Fixed Disk:</b><br>"
dat += "<center>No fixed disk detected.</center><br>"
dat += "<br>"
progdat = null
if((src.diskette) && (src.diskette.root))
dat += "<font size=1><a href='byond://?src=\ref[src];disk=1'>Eject</a></font><br>"
for(var/datum/computer/file/computer_program/P in src.diskette.root.contents)
progdat += "<tr><td>[P.name]</td><td>Size: [P.size]</td>"
progdat += "<td><a href='byond://?src=\ref[src];prog=\ref[P];function=run'>Run</a></td>"
if(P in src.processing_programs)
progdat += "<td><a href='byond://?src=\ref[src];prog=\ref[P];function=unload'>Halt</a></td>"
else
progdat += "<td><a href='byond://?src=\ref[src];prog=\ref[P];function=load'>Load</a></td>"
progdat += "<td><a href='byond://?src=\ref[src];file=\ref[P];function=install'>Install</a></td></tr>"
continue
dat += "Disk Space: \[[src.diskette.file_used]/[src.diskette.file_amount]\]<br>"
dat += "<b>Programs on Disk:</b><br>"
if(!progdat)
progdat = "No data found.<br>"
dat += "<center><table cellspacing=4>[progdat]</table></center>"
else
dat += "<b>Programs on Disk:</b><br>"
dat += "<center>No diskette loaded.</center><br>"
dat += "</TT>"
user << browse(dat,"window=comp2")
onclose(user,"comp2")
return
/obj/machinery/computer2/Topic(href, href_list)
if(..())
return
if(!src.active_program)
if((href_list["prog"]) && (href_list["function"]))
var/datum/computer/file/computer_program/newprog = locate(href_list["prog"])
if(newprog && istype(newprog))
switch(href_list["function"])
if("run")
src.run_program(newprog)
if("load")
src.load_program(newprog)
if("unload")
src.unload_program(newprog)
if((href_list["file"]) && (href_list["function"]))
var/datum/computer/file/newfile = locate(href_list["file"])
if(!newfile)
return
switch(href_list["function"])
if("install")
if((src.hd) && (src.hd.root) && (src.allowed(usr)))
newfile.copy_file_to_folder(src.hd.root)
if("delete")
if(src.allowed(usr))
src.delete_file(newfile)
//If there is already one loaded eject, or if not and they have one insert it.
if (href_list["id"])
switch(href_list["id"])
if("auth")
if(!isnull(src.authid))
src.authid.loc = get_turf(src)
src.authid = null
else
var/obj/item/I = usr.equipped()
if (istype(I, /obj/item/weapon/card/id))
usr.drop_item()
I.loc = src
src.authid = I
if("aux")
if(!isnull(src.auxid))
src.auxid.loc = get_turf(src)
src.auxid = null
else
var/obj/item/I = usr.equipped()
if (istype(I, /obj/item/weapon/card/id))
usr.drop_item()
I.loc = src
src.auxid = I
//Same but for a data disk
else if (href_list["disk"])
if(!isnull(src.diskette))
src.diskette.loc = get_turf(src)
src.diskette = null
/* else
var/obj/item/I = usr.equipped()
if (istype(I, /obj/item/weapon/disk/data))
usr.drop_item()
I.loc = src
src.diskette = I
*/
src.add_fingerprint(usr)
src.updateUsrDialog()
return
/obj/machinery/computer2/process()
if(stat & (NOPOWER|BROKEN))
return
use_power(250)
for(var/datum/computer/file/computer_program/P in src.processing_programs)
P.process()
return
/obj/machinery/computer2/power_change()
if(stat & BROKEN)
icon_state = src.base_icon_state
src.icon_state += "b"
else if(powered())
icon_state = src.base_icon_state
stat &= ~NOPOWER
else
spawn(rand(0, 15))
icon_state = src.base_icon_state
src.icon_state += "0"
stat |= NOPOWER
/obj/machinery/computer2/attackby(obj/item/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES
if ((!src.diskette) && W:portable)
user.machine = src
user.drop_item()
W.loc = src
src.diskette = W
user << "You insert [W]."
src.updateUsrDialog()
return
else if (istype(W, /obj/item/weapon/screwdriver))
playsound(src.loc, 'Screwdriver.ogg', 50, 1)
if(do_after(user, 20))
var/obj/computer2frame/A = new /obj/computer2frame( src.loc )
A.created_icon_state = src.base_icon_state
if (src.stat & BROKEN)
user << "\blue The broken glass falls out."
new /obj/item/weapon/shard( src.loc )
A.state = 3
A.icon_state = "3"
else
user << "\blue You disconnect the monitor."
A.state = 4
A.icon_state = "4"
for (var/obj/item/weapon/peripheral/C in src.peripherals)
C.loc = A
A.peripherals.Add(C)
if(src.diskette)
src.diskette.loc = src.loc
//TO-DO: move card reading to peripheral cards instead
if(src.authid)
src.authid.loc = src.loc
if(src.auxid)
src.auxid.loc = src.loc
if(src.hd)
src.hd.loc = A
A.hd = src.hd
A.mainboard = new /obj/item/weapon/motherboard(A)
A.mainboard.created_name = src.name
A.anchored = 1
del(src)
else
src.attack_hand(user)
return
/obj/machinery/computer2/proc/send_command(command, datum/signal/signal)
for(var/obj/item/weapon/peripheral/P in src.peripherals)
P.receive_command(src, command, signal)
del(signal)
/obj/machinery/computer2/proc/receive_command(obj/source, command, datum/signal/signal)
if(source in src.contents)
for(var/datum/computer/file/computer_program/P in src.processing_programs)
P.receive_command(src, command, signal)
del(signal)
return
/obj/machinery/computer2/proc/run_program(datum/computer/file/computer_program/program,datum/computer/file/computer_program/host)
if(!program)
return 0
// src.unload_program(src.active_program)
if(src.load_program(program))
if(host && istype(host))
src.host_program = host
else
src.host_program = null
src.active_program = program
return 1
return 0
/obj/machinery/computer2/proc/load_program(datum/computer/file/computer_program/program)
if((!program) || (!program.holder))
return 0
if(!(program.holder in src))
// world << "Not in src"
program = new program.type
program.transfer_holder(src.hd)
if(program.master != src)
program.master = src
if(program in src.processing_programs)
return 1
else
src.processing_programs.Add(program)
return 1
return 0
/obj/machinery/computer2/proc/unload_program(datum/computer/file/computer_program/program)
if((!program) || (!src.hd))
return 0
if(program in src.processing_programs)
src.processing_programs.Remove(program)
return 1
return 0
/obj/machinery/computer2/proc/delete_file(datum/computer/file/file)
//world << "Deleting [file]..."
if((!file) || (!file.holder) || (file.holder.read_only))
//world << "Cannot delete :("
return 0
if(file in src.processing_programs)
src.processing_programs.Remove(file)
if(src.active_program == file)
src.active_program = null
// file.holder.root.remove_file(file)
//world << "Now calling del on [file]..."
del(file)
return 1
+164
View File
@@ -0,0 +1,164 @@
/datum/computer/file/computer_program/progman
name = "ProgManager"
size = 16.0
var/datum/computer/folder/current_folder
var/mode = 0
var/datum/computer/file/clipboard
return_text()
if(..())
return
if((!src.current_folder) || !(src.current_folder.holder in src.master))
src.current_folder = src.holder.root
var/dat = "<a href='byond://?src=\ref[src];close=1'>Close</a> | "
dat += "<a href='byond://?src=\ref[src];quit=1'>Quit</a>"
switch(mode)
if(0)
dat += " |<a href='byond://?src=\ref[src];create=folder'>Create Folder</a>"
//dat += " | <a href='byond://?src=\ref[src];create=file'>Create File</a>"
dat += " | <a href='byond://?src=\ref[src];file=\ref[src.current_folder];function=paste'>Paste</a>"
dat += " | <a href='byond://?src=\ref[src];top_folder=1'>Root</a>"
dat += " | <a href='byond://?src=\ref[src];mode=1'>Drive</a><br>"
dat += "<b>Contents of [current_folder] | Drive:\[[src.current_folder.holder.title]]</b><br>"
dat += "<b>Used: \[[src.current_folder.holder.file_used]/[src.current_folder.holder.file_amount]\]</b><hr>"
dat += "<table cellspacing=5>"
for(var/datum/computer/P in current_folder.contents)
if(P == src)
dat += "<tr><td>System</td><td>Size: [src.size]</td><td>SYSTEM</td></tr>"
continue
dat += "<tr><td><a href='byond://?src=\ref[src];file=\ref[P];function=open'>[P.name]</a></td>"
dat += "<td>Size: [P.size]</td>"
dat += "<td>[(istype(P,/datum/computer/folder)) ? "FOLDER" : "[P:extension]"]</td>"
dat += "<td><a href='byond://?src=\ref[src];file=\ref[P];function=delete'>Del</a></td>"
dat += "<td><a href='byond://?src=\ref[src];file=\ref[P];function=rename'>Rename</a></td>"
if(istype(P,/datum/computer/file))
dat += "<td><a href='byond://?src=\ref[src];file=\ref[P];function=copy'>Copy</a></td>"
dat += "</tr>"
dat += "</table>"
if(1)
dat += " | <a href='byond://?src=\ref[src];mode=0'>Main</a>"
dat += " | <a href='byond://?src=\ref[master];disk=1'>Eject</a><br>"
for(var/obj/item/weapon/disk/data/D in src.master)
if(D == current_folder.holder)
dat += "[D.name]<br>"
else
dat += "<a href='byond://?src=\ref[src];drive=\ref[D]'>[D.title]</a><br>"
return dat
Topic(href, href_list)
if(..())
return
if(href_list["create"])
if(current_folder)
var/datum/computer/F = null
switch(href_list["create"])
if("folder")
F = new /datum/computer/folder
if(!current_folder.add_file(F))
//world << "Couldn't add folder :("
del(F)
if("file")
F = new /datum/computer/file
if(!current_folder.add_file(F))
//world << "Couldn't add file :("
del(F)
if(href_list["file"] && href_list["function"])
var/datum/computer/F = locate(href_list["file"])
if(!F || !istype(F))
return
switch(href_list["function"])
if("open")
if(istype(F,/datum/computer/folder))
src.current_folder = F
else if(istype(F,/datum/computer/file/computer_program))
src.master.run_program(F,src)
src.master.updateUsrDialog()
return
if("delete")
src.master.delete_file(F)
if("copy")
if(istype(F,/datum/computer/file) && (!F.holder || (F.holder in src.master.contents)))
src.clipboard = F
if("paste")
if(istype(F,/datum/computer/folder))
if(!src.clipboard || !src.clipboard.holder || !(src.clipboard.holder in src.master.contents))
return
if(!istype(src.clipboard))
return
src.clipboard.copy_file_to_folder(F)
if("rename")
spawn(0)
var/t = input(usr, "Please enter new name", F.name, null) as text
t = copytext(sanitize(t), 1, 16)
if (!t)
return
if (!in_range(src.master, usr) || !(F.holder in src.master))
return
if(F.holder.read_only)
return
F.name = capitalize(lowertext(t))
src.master.updateUsrDialog()
return
/*
if(href_list["open"])
var/datum/computer/F = locate(href_list["open"])
if(!F || !istype(F))
return
if(istype(F,/datum/computer/folder))
src.current_folder = F
else if(istype(F,/datum/computer/file/computer_program))
src.master.run_program(F)
src.master.updateUsrDialog()
return
if(href_list["delete"])
var/datum/computer/F = locate(href_list["delete"])
if(!F || !istype(F))
return
src.master.delete_file(F)
*/
if(href_list["top_folder"])
src.current_folder = src.current_folder.holder.root
if(href_list["mode"])
var/newmode = text2num(href_list["mode"])
newmode = max(newmode,0)
src.mode = newmode
if(href_list["drive"])
var/obj/item/weapon/disk/data/D = locate(href_list["drive"])
if(D && istype(D) && D.root)
current_folder = D.root
src.mode = 0
src.master.add_fingerprint(usr)
src.master.updateUsrDialog()
return
+463
View File
@@ -0,0 +1,463 @@
/datum/computer/file/computer_program/med_data
name = "Medical Records"
size = 32.0
active_icon = "dna"
req_access = list(access_medical)
var/authenticated = null
var/rank = null
var/screen = null
var/datum/data/record/active1 = null
var/datum/data/record/active2 = null
var/a_id = null
var/temp = null
/datum/computer/file/computer_program/med_data/return_text()
if(..())
return
var/dat
if (src.temp)
dat = text("<TT>[src.temp]</TT><BR><BR><A href='?src=\ref[src];temp=1'>Clear Screen</A>")
else
dat = text("Confirm Identity: <A href='?src=\ref[];id=auth'>[]</A><HR>", master, (src.master.authid ? text("[]", src.master.authid.name) : "----------"))
if (src.authenticated)
switch(src.screen)
if(1.0)
dat += {"
<A href='?src=\ref[src];search=1'>Search Records</A>
<BR><A href='?src=\ref[src];screen=2'>List Records</A>
<BR>
<BR><A href='?src=\ref[src];screen=5'>Virus Database</A>
<BR><A href='?src=\ref[src];screen=6'>Medbot Tracking</A>
<BR>
<BR><A href='?src=\ref[src];screen=3'>Record Maintenance</A>
<BR><A href='?src=\ref[src];logout=1'>{Log Out}</A><BR>
"}
if(2.0)
dat += "<B>Record List</B>:<HR>"
for(var/datum/data/record/R in data_core.general)
dat += text("<A href='?src=\ref[];d_rec=\ref[]'>[]: []<BR>", src, R, R.fields["id"], R.fields["name"])
//Foreach goto(132)
dat += text("<HR><A href='?src=\ref[];screen=1'>Back</A>", src)
if(3.0)
dat += text("<B>Records Maintenance</B><HR>\n<A href='?src=\ref[];back=1'>Backup To Disk</A><BR>\n<A href='?src=\ref[];u_load=1'>Upload From disk</A><BR>\n<A href='?src=\ref[];del_all=1'>Delete All Records</A><BR>\n<BR>\n<A href='?src=\ref[];screen=1'>Back</A>", src, src, src, src)
if(4.0)
dat += "<CENTER><B>Medical Record</B></CENTER><BR>"
if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1)))
dat += text("Name: [] ID: []<BR>\nSex: <A href='?src=\ref[];field=sex'>[]</A><BR>\nAge: <A href='?src=\ref[];field=age'>[]</A><BR>\nFingerprint: <A href='?src=\ref[];field=fingerprint'>[]</A><BR>\nPhysical Status: <A href='?src=\ref[];field=p_stat'>[]</A><BR>\nMental Status: <A href='?src=\ref[];field=m_stat'>[]</A><BR>", src.active1.fields["name"], src.active1.fields["id"], src, src.active1.fields["sex"], src, src.active1.fields["age"], src, src.active1.fields["fingerprint"], src, src.active1.fields["p_stat"], src, src.active1.fields["m_stat"])
else
dat += "<B>General Record Lost!</B><BR>"
if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2)))
dat += text("<BR>\n<CENTER><B>Medical Data</B></CENTER><BR>\nBlood Type: <A href='?src=\ref[];field=b_type'>[]</A><BR>\n<BR>\nMinor Disabilities: <A href='?src=\ref[];field=mi_dis'>[]</A><BR>\nDetails: <A href='?src=\ref[];field=mi_dis_d'>[]</A><BR>\n<BR>\nMajor Disabilities: <A href='?src=\ref[];field=ma_dis'>[]</A><BR>\nDetails: <A href='?src=\ref[];field=ma_dis_d'>[]</A><BR>\n<BR>\nAllergies: <A href='?src=\ref[];field=alg'>[]</A><BR>\nDetails: <A href='?src=\ref[];field=alg_d'>[]</A><BR>\n<BR>\nCurrent Diseases: <A href='?src=\ref[];field=cdi'>[]</A> (per disease info placed in log/comment section)<BR>\nDetails: <A href='?src=\ref[];field=cdi_d'>[]</A><BR>\n<BR>\nImportant Notes:<BR>\n\t<A href='?src=\ref[];field=notes'>[]</A><BR>\n<BR>\n<CENTER><B>Comments/Log</B></CENTER><BR>", src, src.active2.fields["b_type"], src, src.active2.fields["mi_dis"], src, src.active2.fields["mi_dis_d"], src, src.active2.fields["ma_dis"], src, src.active2.fields["ma_dis_d"], src, src.active2.fields["alg"], src, src.active2.fields["alg_d"], src, src.active2.fields["cdi"], src, src.active2.fields["cdi_d"], src, src.active2.fields["notes"])
var/counter = 1
while(src.active2.fields[text("com_[]", counter)])
dat += text("[]<BR><A href='?src=\ref[];del_c=[]'>Delete Entry</A><BR><BR>", src.active2.fields[text("com_[]", counter)], src, counter)
counter++
dat += text("<A href='?src=\ref[];add_c=1'>Add Entry</A><BR><BR>", src)
dat += text("<A href='?src=\ref[];del_r=1'>Delete Record (Medical Only)</A><BR><BR>", src)
else
dat += "<B>Medical Record Lost!</B><BR>"
dat += text("<A href='?src=\ref[src];new=1'>New Record</A><BR><BR>")
dat += text("\n<A href='?src=\ref[];print_p=1'>Print Record</A><BR>\n<A href='?src=\ref[];screen=2'>Back</A><BR>", src, src)
if(5.0)
dat += {"<CENTER><B>Virus Database</B></CENTER>
<br><a href='?src=\ref[src];vir=gbs'>GBS</a>
<br><a href='?src=\ref[src];vir=cc'>Common Cold</a>
<br><a href='?src=\ref[src];vir=f'>Flu</A>
<br><a href='?src=\ref[src];vir=jf'>Jungle Fever</a>
<br><a href='?src=\ref[src];vir=ca'>Clowning Around</a>
<br><a href='?src=\ref[src];vir=p'>Plasmatoid</a>
<br><a href='?src=\ref[src];vir=dna'>Space Rhinovirus</a>
<br><a href='?src=\ref[src];vir=bot'>Robot Transformation</a>
<br><a href='?src=\ref[src];screen=1'>Back</a>"}
if(6.0)
dat += "<center><b>Medical Robot Monitor</b></center>"
dat += "<a href='?src=\ref[src];screen=1'>Back</a>"
dat += "<br><b>Medical Robots:</b>"
var/bdat = null
for(var/obj/machinery/bot/medbot/M in world)
var/turf/bl = get_turf(M)
bdat += "[M.name] - <b>\[[bl.x],[bl.y]\]</b> - [M.on ? "Online" : "Offline"]<br>"
if(!isnull(M.reagent_glass))
bdat += "Reservoir: \[[M.reagent_glass.reagents.total_volume]/[M.reagent_glass.reagents.maximum_volume]\]"
else
bdat += "Using Internal Synthesizer."
if(!bdat)
dat += "<br><center>None detected</center>"
else
dat += "[bdat]"
else
else
dat += text("<A href='?src=\ref[];login=1'>{Log In}</A>", src)
dat += "<br><a href='byond://?src=\ref[src];quit=1'>{Quit}</a>"
return dat
/datum/computer/file/computer_program/med_data/Topic(href, href_list)
if(..())
return
if (!( data_core.general.Find(src.active1) ))
src.active1 = null
if (!( data_core.medical.Find(src.active2) ))
src.active2 = null
if (href_list["temp"])
src.temp = null
else if (href_list["logout"])
src.authenticated = null
src.screen = null
src.active1 = null
src.active2 = null
else if (href_list["login"])
if (istype(usr, /mob/living/silicon))
src.active1 = null
src.active2 = null
src.authenticated = 1
src.rank = "AI"
src.screen = 1
else if (istype(src.master.authid, /obj/item/weapon/card/id))
src.active1 = null
src.active2 = null
if (src.check_access(src.master.authid))
src.authenticated = src.master.authid.registered
src.rank = src.master.authid.assignment
src.screen = 1
if (src.authenticated)
if(href_list["screen"])
src.screen = text2num(href_list["screen"])
if(src.screen < 1)
src.screen = 1
src.active1 = null
src.active2 = null
if(href_list["vir"])
switch(href_list["vir"])
if("gbs")
src.temp = {"<b>Name:</b> GBS
<BR><b>Number of stages:</b> 5
<BR><b>Spread:</b> Airborne Transmission
<BR><b>Possible Cure:</b> Spaceacillin
<BR><b>Affected Species:</b> Human
<BR>
<BR><b>Notes:</b> If left untreated death will occur.
<BR>
<BR><b>Severity:</b> Major"}
if("cc")
src.temp = {"<b>Name:</b> Common Cold
<BR><b>Number of stages:</b> 3
<BR><b>Spread:</b> Airborne Transmission
<BR><b>Possible Cure:</b> Rest
<BR><b>Affected Species:</b> Human
<BR>
<BR><b>Notes:</b> If left untreated the subject will contract the flu.
<BR>
<BR><b>Severity:</b> Minor"}
if("f")
src.temp = {"<b>Name:</b> The Flu
<BR><b>Number of stages:</b> 3
<BR><b>Spread:</b> Airborne Transmission
<BR><b>Possible Cure:</b> Rest
<BR><b>Affected Species:</b> Human
<BR>
<BR><b>Notes:</b> If left untreated the subject will feel quite unwell.
<BR>
<BR><b>Severity:</b> Medium"}
if("jf")
src.temp = {"<b>Name:</b> Jungle Fever
<BR><b>Number of stages:</b> 1
<BR><b>Spread:</b> Airborne Transmission
<BR><b>Possible Cure:</b> None
<BR><b>Affected Species:</b> Monkey
<BR>
<BR><b>Notes:</b> Monkies with this disease will bite humans, causing humans to spontaneously to mutate into a monkey.
<BR>
<BR><b>Severity:</b> Medium"}
if("ca")
src.temp = {"<b>Name:</b> Clowning Around
<BR><b>Number of stages:</b> 4
<BR><b>Spread:</b> Airborne Transmission
<BR><b>Possible Cure:</b> Spaceacillin
<BR><b>Affected Species:</b> Human
<BR>
<BR><b>Notes:</b> Subjects are affected by rampant honking and a fondness for shenanigans. They may also spontaneously phase through closed airlocks.
<BR>
<BR><b>Severity:</b> Laughable"}
if("p")
src.temp = {"<b>Name:</b> Plasmatoid
<BR><b>Number of stages:</b> 3
<BR><b>Spread:</b> Airborne Transmission
<BR><b>Possible Cure:</b> Inaprovaline
<BR><b>Affected Species:</b> Human and Monkey
<BR>
<BR><b>Notes:</b> With this disease the victim will need plasma to breathe.
<BR>
<BR><b>Severity:</b> Major"}
if("dna")
src.temp = {"<b>Name:</b> Space Rhinovirus
<BR><b>Number of stages:</b> 4
<BR><b>Spread:</b> Airborne Transmission
<BR><b>Possible Cure:</b> Spaceacillin
<BR><b>Affected Species:</b> Human
<BR>
<BR><b>Notes:</b> This disease transplants the genetic code of the intial vector into new hosts.
<BR>
<BR><b>Severity:</b> Medium"}
if("bot")
src.temp = {"<b>Name:</b> Robot Transformation
<BR><b>Number of stages:</b> 5
<BR><b>Spread:</b> Infected food
<BR><b>Possible Cure:</b> None
<BR><b>Affected Species:</b> Human
<BR>
<BR><b>Notes:</b> This disease, actually acute nanomachine infection, converts the victim into a cyborg.
<BR>
<BR><b>Severity:</b> Major"}
if (href_list["del_all"])
src.temp = text("Are you sure you wish to delete all records?<br>\n\t<A href='?src=\ref[];temp=1;del_all2=1'>Yes</A><br>\n\t<A href='?src=\ref[];temp=1'>No</A><br>", src, src)
if (href_list["del_all2"])
for(var/datum/data/record/R in data_core.medical)
del(R)
src.temp = "All records deleted."
if (href_list["field"])
var/a1 = src.active1
var/a2 = src.active2
switch(href_list["field"])
if("fingerprint")
if (istype(src.active1, /datum/data/record))
var/t1 = input("Please input fingerprint hash:", "Med. records", src.active1.fields["id"], null) as text
if ((!( t1 ) || !( src.authenticated ) || (!src.master) || usr.stat || usr.restrained() || (!in_range(src.master, usr) && (!istype(usr, /mob/living/silicon))) || src.active1 != a1))
return
src.active1.fields["fingerprint"] = t1
if("sex")
if (istype(src.active1, /datum/data/record))
if (src.active1.fields["sex"] == "Male")
src.active1.fields["sex"] = "Female"
else
src.active1.fields["sex"] = "Male"
if("age")
if (istype(src.active1, /datum/data/record))
var/t1 = input("Please input age:", "Med. records", src.active1.fields["age"], null) as text
if ((!( t1 ) || !( src.authenticated ) || (!src.master) || usr.stat || usr.restrained() || (!in_range(src.master, usr) && (!istype(usr, /mob/living/silicon))) || src.active1 != a1))
return
src.active1.fields["age"] = t1
if("mi_dis")
if (istype(src.active2, /datum/data/record))
var/t1 = input("Please input minor disabilities list:", "Med. records", src.active2.fields["mi_dis"], null) as text
if ((!( t1 ) || !( src.authenticated ) || (!src.master) || usr.stat || usr.restrained() || (!in_range(src.master, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
return
src.active2.fields["mi_dis"] = t1
if("mi_dis_d")
if (istype(src.active2, /datum/data/record))
var/t1 = input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null) as message
if ((!( t1 ) || !( src.authenticated ) || (!src.master) || usr.stat || usr.restrained() || (!in_range(src.master, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
return
src.active2.fields["mi_dis_d"] = t1
if("ma_dis")
if (istype(src.active2, /datum/data/record))
var/t1 = input("Please input major diabilities list:", "Med. records", src.active2.fields["ma_dis"], null) as text
if ((!( t1 ) || !( src.authenticated ) || (!src.master) || usr.stat || usr.restrained() || (!in_range(src.master, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
return
src.active2.fields["ma_dis"] = t1
if("ma_dis_d")
if (istype(src.active2, /datum/data/record))
var/t1 = input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null) as message
if ((!( t1 ) || !( src.authenticated ) || (!src.master) || usr.stat || usr.restrained() || (!in_range(src.master, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
return
src.active2.fields["ma_dis_d"] = t1
if("alg")
if (istype(src.active2, /datum/data/record))
var/t1 = input("Please state allergies:", "Med. records", src.active2.fields["alg"], null) as text
if ((!( t1 ) || !( src.authenticated ) || (!src.master) || usr.stat || usr.restrained() || (!in_range(src.master, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
return
src.active2.fields["alg"] = t1
if("alg_d")
if (istype(src.active2, /datum/data/record))
var/t1 = input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null) as message
if ((!( t1 ) || !( src.authenticated ) || (!src.master) || usr.stat || usr.restrained() || (!in_range(src.master, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
return
src.active2.fields["alg_d"] = t1
if("cdi")
if (istype(src.active2, /datum/data/record))
var/t1 = input("Please state diseases:", "Med. records", src.active2.fields["cdi"], null) as text
if ((!( t1 ) || !( src.authenticated ) || (!src.master) || usr.stat || usr.restrained() || (!in_range(src.master, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
return
src.active2.fields["cdi"] = t1
if("cdi_d")
if (istype(src.active2, /datum/data/record))
var/t1 = input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null) as message
if ((!( t1 ) || !( src.authenticated ) || (!src.master) || usr.stat || usr.restrained() || (!in_range(src.master, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
return
src.active2.fields["cdi_d"] = t1
if("notes")
if (istype(src.active2, /datum/data/record))
var/t1 = input("Please summarize notes:", "Med. records", src.active2.fields["notes"], null) as message
if ((!( t1 ) || !( src.authenticated ) || (!src.master) || usr.stat || usr.restrained() || (!in_range(src.master, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
return
src.active2.fields["notes"] = t1
if("p_stat")
if (istype(src.active1, /datum/data/record))
src.temp = text("<B>Physical Condition:</B><BR>\n\t<A href='?src=\ref[];temp=1;p_stat=deceased'>*Deceased*</A><BR>\n\t<A href='?src=\ref[];temp=1;p_stat=unconscious'>*Unconscious*</A><BR>\n\t<A href='?src=\ref[];temp=1;p_stat=active'>Active</A><BR>\n\t<A href='?src=\ref[];temp=1;p_stat=unfit'>Physically Unfit</A><BR>", src, src, src, src)
if("m_stat")
if (istype(src.active1, /datum/data/record))
src.temp = text("<B>Mental Condition:</B><BR>\n\t<A href='?src=\ref[];temp=1;m_stat=insane'>*Insane*</A><BR>\n\t<A href='?src=\ref[];temp=1;m_stat=unstable'>*Unstable*</A><BR>\n\t<A href='?src=\ref[];temp=1;m_stat=watch'>*Watch*</A><BR>\n\t<A href='?src=\ref[];temp=1;m_stat=stable'>Stable</A><BR>", src, src, src, src)
if("b_type")
if (istype(src.active2, /datum/data/record))
src.temp = text("<B>Blood Type:</B><BR>\n\t<A href='?src=\ref[];temp=1;b_type=an'>A-</A> <A href='?src=\ref[];temp=1;b_type=ap'>A+</A><BR>\n\t<A href='?src=\ref[];temp=1;b_type=bn'>B-</A> <A href='?src=\ref[];temp=1;b_type=bp'>B+</A><BR>\n\t<A href='?src=\ref[];temp=1;b_type=abn'>AB-</A> <A href='?src=\ref[];temp=1;b_type=abp'>AB+</A><BR>\n\t<A href='?src=\ref[];temp=1;b_type=on'>O-</A> <A href='?src=\ref[];temp=1;b_type=op'>O+</A><BR>", src, src, src, src, src, src, src, src)
else
if (href_list["p_stat"])
if (src.active1)
switch(href_list["p_stat"])
if("deceased")
src.active1.fields["p_stat"] = "*Deceased*"
if("unconscious")
src.active1.fields["p_stat"] = "*Unconscious*"
if("active")
src.active1.fields["p_stat"] = "Active"
if("unfit")
src.active1.fields["p_stat"] = "Physically Unfit"
if (href_list["m_stat"])
if (src.active1)
switch(href_list["m_stat"])
if("insane")
src.active1.fields["m_stat"] = "*Insane*"
if("unstable")
src.active1.fields["m_stat"] = "*Unstable*"
if("watch")
src.active1.fields["m_stat"] = "*Watch*"
if("stable")
src.active2.fields["m_stat"] = "Stable"
if (href_list["b_type"])
if (src.active2)
switch(href_list["b_type"])
if("an")
src.active2.fields["b_type"] = "A-"
if("bn")
src.active2.fields["b_type"] = "B-"
if("abn")
src.active2.fields["b_type"] = "AB-"
if("on")
src.active2.fields["b_type"] = "O-"
if("ap")
src.active2.fields["b_type"] = "A+"
if("bp")
src.active2.fields["b_type"] = "B+"
if("abp")
src.active2.fields["b_type"] = "AB+"
if("op")
src.active2.fields["b_type"] = "O+"
if (href_list["del_r"])
if (src.active2)
src.temp = "Are you sure you wish to delete the record (Medical Portion Only)?<br>\n\t<A href='?src=\ref[src];temp=1;del_r2=1'>Yes</A><br>\n\t<A href='?src=\ref[src];temp=1'>No</A><br>"
if (href_list["del_r2"])
if (src.active2)
del(src.active2)
if (href_list["d_rec"])
var/datum/data/record/R = locate(href_list["d_rec"])
var/datum/data/record/M = locate(href_list["d_rec"])
if (!( data_core.general.Find(R) ))
src.temp = "Record Not Found!"
return
for(var/datum/data/record/E in data_core.medical)
if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
M = E
else
//Foreach continue //goto(2540)
src.active1 = R
src.active2 = M
src.screen = 4
if (href_list["new"])
if ((istype(src.active1, /datum/data/record) && !( istype(src.active2, /datum/data/record) )))
var/datum/data/record/R = new /datum/data/record( )
R.fields["name"] = src.active1.fields["name"]
R.fields["id"] = src.active1.fields["id"]
R.name = text("Medical Record #[]", R.fields["id"])
R.fields["b_type"] = "Unknown"
R.fields["mi_dis"] = "None"
R.fields["mi_dis_d"] = "No minor disabilities have been declared."
R.fields["ma_dis"] = "None"
R.fields["ma_dis_d"] = "No major disabilities have been diagnosed."
R.fields["alg"] = "None"
R.fields["alg_d"] = "No allergies have been detected in this patient."
R.fields["cdi"] = "None"
R.fields["cdi_d"] = "No diseases have been diagnosed at the moment."
R.fields["notes"] = "No notes."
data_core.medical += R
src.active2 = R
src.screen = 4
if (href_list["add_c"])
if (!( istype(src.active2, /datum/data/record) ))
return
var/a2 = src.active2
var/t1 = input("Add Comment:", "Med. records", null, null) as message
if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src.master, usr) && (!istype(usr, /mob/living/silicon))) || src.active2 != a2))
return
var/counter = 1
while(src.active2.fields[text("com_[]", counter)])
counter++
src.active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [], 2053<BR>[]", src.authenticated, src.rank, time2text(world.realtime, "DDD MMM DD hh:mm:ss"), t1)
if (href_list["del_c"])
if ((istype(src.active2, /datum/data/record) && src.active2.fields[text("com_[]", href_list["del_c"])]))
src.active2.fields[text("com_[]", href_list["del_c"])] = "<B>Deleted</B>"
if (href_list["search"])
var/t1 = input("Search String: (Name or ID)", "Med. records", null, null) as text
if ((!( t1 ) || usr.stat || (!src.master) || !( src.authenticated ) || usr.restrained() || ((!in_range(src.master, usr)) && (!istype(usr, /mob/living/silicon)))))
return
src.active1 = null
src.active2 = null
t1 = lowertext(t1)
for(var/datum/data/record/R in data_core.general)
if ((lowertext(R.fields["name"]) == t1 || t1 == lowertext(R.fields["id"])))
src.active1 = R
else
if (!( src.active1 ))
src.temp = text("Could not locate record [].", t1)
else
for(var/datum/data/record/E in data_core.medical)
if ((E.fields["name"] == src.active1.fields["name"] || E.fields["id"] == src.active1.fields["id"]))
src.active2 = E
else
src.screen = 4
if (href_list["print_p"])
var/info = "<CENTER><B>Medical Record</B></CENTER><BR>"
if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1)))
info += text("Name: [] ID: []<BR>\nSex: []<BR>\nAge: []<BR>\nFingerprint: []<BR>\nPhysical Status: []<BR>\nMental Status: []<BR>", src.active1.fields["name"], src.active1.fields["id"], src.active1.fields["sex"], src.active1.fields["age"], src.active1.fields["fingerprint"], src.active1.fields["p_stat"], src.active1.fields["m_stat"])
else
info += "<B>General Record Lost!</B><BR>"
if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2)))
info += text("<BR>\n<CENTER><B>Medical Data</B></CENTER><BR>\nBlood Type: []<BR>\n<BR>\nMinor Disabilities: []<BR>\nDetails: []<BR>\n<BR>\nMajor Disabilities: []<BR>\nDetails: []<BR>\n<BR>\nAllergies: []<BR>\nDetails: []<BR>\n<BR>\nCurrent Diseases: [] (per disease info placed in log/comment section)<BR>\nDetails: []<BR>\n<BR>\nImportant Notes:<BR>\n\t[]<BR>\n<BR>\n<CENTER><B>Comments/Log</B></CENTER><BR>", src.active2.fields["b_type"], src.active2.fields["mi_dis"], src.active2.fields["mi_dis_d"], src.active2.fields["ma_dis"], src.active2.fields["ma_dis_d"], src.active2.fields["alg"], src.active2.fields["alg_d"], src.active2.fields["cdi"], src.active2.fields["cdi_d"], src.active2.fields["notes"])
var/counter = 1
while(src.active2.fields[text("com_[]", counter)])
info += text("[]<BR>", src.active2.fields[text("com_[]", counter)])
counter++
else
info += "<B>Medical Record Lost!</B><BR>"
info += "</TT>"
var/datum/signal/signal = new
signal.data["data"] = info
signal.data["title"] = "Medical Record"
src.peripheral_command("print",signal)
src.master.add_fingerprint(usr)
src.master.updateUsrDialog()
return
@@ -0,0 +1,96 @@
/datum/computer/file/computer_program/messenger
name = "Messenger"
size = 8.0
var/messages = null
var/screen_name = "User"
//To-do: take screen_name from inserted id card??
//Saving log to file datum
return_text()
if(..())
return
var/dat = "<a href='byond://?src=\ref[src];close=1'>Close</a> | "
dat += "<a href='byond://?src=\ref[src];quit=1'>Quit</a><br>"
dat += "<b>SpaceMessenger V4.1.2</b><br>"
dat += "<a href='byond://?src=\ref[src];send_msg=1'>Send Message</a>"
dat += " | <a href='byond://?src=\ref[src];func_msg=clear'>Clear</a>"
dat += " | <a href='byond://?src=\ref[src];func_msg=print'>Print</a>"
dat += " | Name:<a href='byond://?src=\ref[src];set_name=1'>[src.screen_name]</a><hr>"
dat += messages
dat += "</center>"
return dat
Topic(href, href_list)
if(..())
return
if(href_list["send_msg"])
var/t = input(usr, "Please enter messenger", src.id_tag, null) as text
t = copytext(sanitize(t), 1, MAX_MESSAGE_LEN)
if (!t)
return
if (!in_range(src.master, usr))
return
var/datum/signal/signal = new
signal.data["type"] = "message"
signal.data["data"] = t
signal.data["sender"] = src.screen_name
src.messages += "<i><b>&rarr; You:</b></i><br>[t]<br>"
peripheral_command("send signal", signal)
if(href_list["func_msg"])
switch(href_list["func_msg"])
if("clear")
src.messages = null
if("print")
var/datum/signal/signal = new
signal.data["data"] = src.messages
signal.data["title"] = "Chatlog"
peripheral_command("print", signal)
//if("save")
//TO-DO
if(href_list["set_name"])
var/t = input(usr, "Please enter screen name", src.id_tag, null) as text
t = copytext(sanitize(t), 1, 20)
if (!t)
return
if (!in_range(src.master, usr))
return
src.screen_name = t
src.master.add_fingerprint(usr)
src.master.updateUsrDialog()
return
receive_command(obj/source, command, datum/signal/signal)
if(..() || !signal)
return
if(command == "radio signal")
switch(signal.data["type"])
if("message")
var/sender = signal.data["sender"]
if(!sender)
sender = "Unknown"
src.messages += "<i><b>&larr; From [sender]:</b></i><br>[signal.data["data"]]<br>"
if(src.master.active_program == src)
playsound(src.master.loc, 'twobeep.ogg', 50, 1)
src.master.updateUsrDialog()
return
@@ -0,0 +1,209 @@
/obj/item/weapon/peripheral
name = "Peripheral card"
desc = "A computer circuit board."
icon = 'module.dmi'
icon_state = "id_mod"
item_state = "electronic"
w_class = 2
var/obj/machinery/computer2/host
var/id = null
New()
..()
spawn(2)
if(istype(src.loc,/obj/machinery/computer2))
host = src.loc
host.peripherals.Add(src)
// var/setup_id = "\ref[src]"
// src.id = copytext(setup_id,4,(length(setup_id)-1) )
Del()
if(host)
host.peripherals.Remove(src)
..()
proc
receive_command(obj/source, command, datum/signal/signal)
if((source != host) || !(src in host))
return 1
if(!command)
return 1
return 0
send_command(command, datum/signal/signal)
if(!command || !host)
return
src.host.receive_command(src, command, signal)
return
/obj/item/weapon/peripheral/radio
name = "Wireless card"
var/frequency = 1419
var/code = null
var/datum/radio_frequency/radio_connection
New()
..()
if(radio_controller)
initialize()
initialize()
set_frequency(frequency)
proc
set_frequency(new_frequency)
radio_controller.remove_object(src, "[frequency]")
frequency = new_frequency
radio_connection = radio_controller.add_object(src, "[frequency]")
receive_command(obj/source, command, datum/signal/signal)
if(..())
return
if(!signal || !radio_connection)
return
switch(command)
if("send signal")
src.radio_connection.post_signal(src, signal)
return
receive_signal(datum/signal/signal)
if(!signal || (signal.encryption && signal.encryption != code))
return
var/datum/signal/newsignal = new
newsignal.data = signal.data
if(src.code)
newsignal.encryption = src.code
send_command("radio signal",newsignal)
return
/obj/item/weapon/peripheral/printer
name = "Printer module"
desc = "A small printer designed to fit into a computer casing."
icon_state = "card_mod"
var/printing = 0
receive_command(obj/source,command, datum/signal/signal)
if(..())
return
if(!signal)
return
if((command == "print") && !src.printing)
src.printing = 1
var/print_data = signal.data["data"]
var/print_title = signal.data["title"]
if(!print_data)
src.printing = 0
return
spawn(50)
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( src.host.loc )
P.info = print_data
if(print_title)
P.name = "paper- '[print_title]'"
src.printing = 0
return
return
/obj/item/weapon/peripheral/prize_vendor
name = "Prize vending module"
desc = "An arcade prize dispenser designed to fit inside a computer casing."
icon_state = "power_mod"
var/last_vend = 0 //Delay between vends if manually activated(ie a dude is holding it and shaking stuff out)
receive_command(obj/source,command, datum/signal/signal)
if(..())
return
if(command == "vend prize")
src.vend_prize()
return
attack_self(mob/user as mob)
if( (last_vend + 400) < world.time)
user << "You shake something out of [src]!"
src.vend_prize()
src.last_vend = world.time
else
user << "\red [src] isn't ready to dispense a prize yet."
return
proc/vend_prize()
var/obj/item/prize
var/prizeselect = rand(1,4)
var/turf/prize_location = null
if(src.host)
prize_location = src.host.loc
else
prize_location = get_turf(src)
switch(prizeselect)
if(1)
prize = new /obj/item/weapon/spacecash( prize_location )
prize.name = "space ticket"
prize.desc = "It's almost like actual currency!"
if(2)
prize = new /obj/item/device/radio/beacon( prize_location )
prize.name = "electronic blink toy game"
prize.desc = "Blink. Blink. Blink."
if(3)
prize = new /obj/item/weapon/zippo( prize_location )
prize.name = "Burno Lighter"
prize.desc = "Almost like a decent lighter!"
if(4)
prize = new /obj/item/weapon/c_tube( prize_location )
prize.name = "toy sword"
prize.icon = 'weapons.dmi'
prize.icon_state = "sword1"
prize.desc = "A sword made of cheap plastic."
/*
/obj/item/weapon/peripheral/card_scanner
name = "ID scanner module"
icon_state = "card_mod"
var/obj/item/weapon/card/id/authid = null
attack_self(mob/user as mob)
if(authid)
user << "The card falls out."
src.authid.loc = get_turf(user)
src.authid = null
return
receive_command(obj/source,command, datum/signal/signal)
if(..())
return
if(!signal || (signal.data["ref_id"] != "\ref[src]") )
return
switch(command)
if("eject card")
if(src.authid)
src.authid.loc = src.host.loc
src.authid = null
if("add card access")
var/new_access = signal.data["access"]
if(!new_access)
return
return
*/
@@ -0,0 +1,70 @@
/obj/effects/expl_particles
name = "fire"
icon = 'effects.dmi'
icon_state = "explosion_particle"
opacity = 1
anchored = 1
mouse_opacity = 0
/obj/effects/expl_particles/New()
..()
spawn (15)
del(src)
return
/obj/effects/expl_particles/Move()
..()
return
/datum/effects/system/expl_particles
var/number = 10
var/turf/location
var/total_particles = 0
/datum/effects/system/expl_particles/proc/set_up(n = 10, loca)
number = n
if(istype(loca, /turf/)) location = loca
else location = get_turf(loca)
/datum/effects/system/expl_particles/proc/start()
var/i = 0
for(i=0, i<src.number, i++)
spawn(0)
var/obj/effects/expl_particles/expl = new /obj/effects/expl_particles(src.location)
var/direct = pick(alldirs)
for(i=0, i<pick(1;25,2;50,3,4;200), i++)
sleep(1)
step(expl,direct)
/obj/effects/explosion
name = "fire"
icon = '96x96.dmi'
icon_state = "explosion"
opacity = 1
anchored = 1
mouse_opacity = 0
pixel_x = -32
pixel_y = -32
/obj/effects/explosion/New()
..()
spawn (10)
del(src)
return
/datum/effects/system/explosion
var/turf/location
/datum/effects/system/explosion/proc/set_up(loca)
if(istype(loca, /turf/)) location = loca
else location = get_turf(loca)
/datum/effects/system/explosion/proc/start()
new/obj/effects/explosion( location )
var/datum/effects/system/expl_particles/P = new/datum/effects/system/expl_particles()
P.set_up(10,location)
P.start()
spawn(5)
var/datum/effects/system/harmless_smoke_spread/S = new/datum/effects/system/harmless_smoke_spread()
S.set_up(5,0,location,null)
S.start()
+179
View File
@@ -0,0 +1,179 @@
// the laser beam
/obj/beam/laser
name = "laser beam"
icon = 'beam.dmi'
icon_state = "full"
density = 0
mouse_opacity = 0
flags = TABLEPASS
var/wavelength // the (vaccuum) wavelength of the beam
var/width = 1 // 1=thin, 2=medium, 3=wide
var/obj/beam/laser/next
var/obj/beam/laser/prev
var/obj/master
New(var/atom/newloc, var/dirn, var/lambda, var/omega=1, var/half=0)
if(!isturf(loc))
return
//world << "creating beam at ([newloc.x],[newloc.y]) with [dirn] [lambda] [omega] [half]"
icon_state = "[omega]-[half ? "half" : "full"]"
dir = dirn
set_wavelength(lambda)
..(newloc)
spawn(0)
src.propagate()
src.verbs -= /atom/movable/verb/pull
proc/propagate()
var/turf/T = get_step(src, dir)
if(T)
if(T.Enter(src))
next = new(T, dir, wavelength, width, 0)
next.prev = src
next.master = src.master
else
spawn(5)
propagate()
proc/remove()
if(next)
next.remove()
del(src)
proc/blocked(var/atom/A)
return density || opacity
/*
/turf/Enter(atom/movable/mover as mob|obj)
if (!mover || !isturf(mover.loc))
return 1
//First, check objects to block exit that are not on the border
for(var/obj/obstacle in mover.loc)
if((obstacle.flags & ~ON_BORDER) && (mover != obstacle) && (forget != obstacle))
if(!obstacle.CheckExit(mover, src))
mover.Bump(obstacle, 1)
return 0
//Now, check objects to block exit that are on the border
for(var/obj/border_obstacle in mover.loc)
if((border_obstacle.flags & ON_BORDER) && (mover != border_obstacle) && (forget != border_obstacle))
if(!border_obstacle.CheckExit(mover, src))
mover.Bump(border_obstacle, 1)
return 0
//Next, check objects to block entry that are on the border
for(var/obj/border_obstacle in src)
if(border_obstacle.flags & ON_BORDER)
if(!border_obstacle.CanPass(mover, mover.loc, 1, 0) && (forget != border_obstacle))
mover.Bump(border_obstacle, 1)
return 0
//Then, check the turf itself
if (!src.CanPass(mover, src))
mover.Bump(src, 1)
return 0
//Finally, check objects/mobs to block entry that are not on the border
for(var/atom/movable/obstacle in src)
if(obstacle.flags & ~ON_BORDER)
if(!obstacle.CanPass(mover, mover.loc, 1, 0) && (forget != obstacle))
mover.Bump(obstacle, 1)
return 0
return 1 //Nothing found to block so return success!
*/
HasEntered(var/atom/movable/AM)
if(istype(AM, /obj/beam))
return
if(blocked(AM))
remove(src)
if(prev)
prev.propagate()
else if(master)
master:turn_on()
proc/set_wavelength(var/lambda)
var/w = round(lambda,1) // integer wavelength
wavelength = lambda
// first look for cached version of the icon at this wavelength
var/icon/cached = beam_icons["[w]"]
if(cached)
icon = cached
return
// no cached version, so generate a new one
// this maps a wavelength in the range 380-780 nm to an R,G,B,A value
var/red = 0
var/green = 0
var/blue = 0
var/alpha = 0
switch(w)
if(380 to 439)
red = (440-w) / 60
green = 0
blue = 1
if(440 to 489)
red = 0
green = (w-440) / 50
blue = 1
if(490 to 509)
red = 0
green = 1
blue = (510 - w) / 20
if(510 to 579)
red = (w-510) / 70
green = 1
blue = 0
if(580 to 644)
red = 1
green = (645-w) / 65
blue = 0
if(645 to 780)
red = 1
green = 0
blue = 0
// colour is done, now calculate intensity
switch(w)
if(380 to 419)
alpha = 0.75*(w-380)/40
if(420 to 700)
alpha = 0.75
if(701 to 780)
alpha = 0.75*(780-w)/80
// remap alpha by intensity gamma
if(alpha != 0)
alpha = alpha**0.80
var/icon/I = icon('beam.dmi')
I.MapColors(red,0,0,0, 0,green,0,0, 0,0,blue,0, 0,0,0,alpha, 0,0,0,0)
icon = I
beam_icons["[w]"] = I
// global cache of beam icons
// this is an assoc list mapping (integer) wavelength to icons
var/list/beam_icons = new()
@@ -0,0 +1,72 @@
// A laser pointer. Emits a (tunable) low-power laser beam
// Used for alignment and testing of the optics system
/obj/item/device/laser_pointer
name = "laser pointer"
desc = "A portable low-power laser used for optical system alignment. The label reads: 'Danger: Class IIIa laser device. Avoid direct eye exposure."
icon = 'optics.dmi'
icon_state = "pointer0"
var/on = 0 // true if operating
var/wavelength = 632 // operation wavelength (nm)
var/gain_peak = 632 // gain peak (nm)
var/gain_width = 35 // gain bandwidth (nm)
var/peak_output = 0.005 // max output 5 mW
layer = OBJ_LAYER + 0.1
w_class = 4
m_amt = 500
g_amt = 100
w_amt = 200
var/obj/beam/laser/beam // the created beam
flags = FPRINT | CONDUCT | TABLEPASS
attack_ai()
return
attack_paw()
return
attack_self(var/mob/user)
on = !on
if(on)
turn_on()
else
turn_off()
updateicon()
verb/rotate()
set src in view(1)
turn_off()
dir = turn(dir, -90)
if(on) turn_on()
Move(var/atom/newloc,var/newdir)
. = ..(newloc,newdir)
if(on && . && isturf(newloc))
turn_off()
turn_on()
return .
proc/turn_on()
if(!isturf(loc))
return
beam = new(loc, dir, wavelength, 1, 1)
beam.master = src
proc/turn_off()
if(beam)
beam.remove()
dropped()
turn_off()
turn_on()
proc/updateicon()
icon_state = "pointer[on]"
+83
View File
@@ -0,0 +1,83 @@
// Mirror object
// Part of the optics system
//
// reflects laser beams
// 16 directional states 0/22.5/45/67.5deg to allow for 0/45deg beam angles
// ideas:
// frame/stand icon w/ mirror directional overlay
// two sets of overlay icons for 0/45 and 22.5/67.5 deg angles
// can rotate cw/acw - need screwdriver to loosen/tighten mirror
// use wrench to anchor/unanchor frame
// if touched, gets dirty - fingerprints, which reduce reflectivity
// if dirty and hit with high-power beam, mirror may shatter
// some kind of dust accumulation with HasProximity? Could check for mob w/o labcoat etc.
// can clean with acetone+wipes
/obj/optical/mirror
icon = 'optical.dmi'
icon_state = "mirrorA"
dir = 1
desc = "A large, optical-grade mirror firmly mounted on a stand."
flags = FPRINT
anchored = 0
var/rotatable = 0 // true if mirror can be rotated
var/angle = 0 // normal of mirror, 0-15. 0=N, 1=NNE, 2=NE, 3=ENE, 4=E etc
New()
..()
set_angle()
//set the angle from icon_state and dir
proc/set_angle()
switch(dir)
if(1)
angle = 0
if(5)
angle = 2
if(4)
angle = 4
if(6)
angle = 6
if(2)
angle = 8
if(10)
angle = 10
if(8)
angle = 12
if(9)
angle = 14
if(icon_state == "mirrorB") // 22.5deg turned states
angle++
return
// set the dir and icon_state from the angle
proc/set_dir()
if(angle%2 == 1)
icon_state = "mirrorB"
else
icon_state = "mirrorA"
switch(round(angle/2)*2)
if(0)
dir = 1
if(2)
dir = 5
if(4)
dir = 4
if(6)
dir = 6
if(8)
dir = 2
if(10)
dir = 10
if(12)
dir = 8
if(14)
dir = 9
return
+445
View File
@@ -0,0 +1,445 @@
/datum/computer/file/pda_program/os
proc
receive_os_command(list/command_list)
if((!src.holder) || (!src.master) || (!command_list) || !(command_list["command"]))
return 1
if((!istype(holder)) || (!istype(master)))
return 1
if(!(holder in src.master.contents))
if(master.active_program == src)
master.active_program = null
return 1
return 0
//Main os program: Provides old pda interface and four programs including file browser, notes, messenger, and atmos scan
main_os
name = "ThinkOS 7"
size = 8.0
var/mode = 0
//Note vars
var/note = "Congratulations, your station has chosen the Thinktronic 5150 Personal Data Assistant!"
var/note_mode = 0 //0 For note editor, 1 for note browser
var/datum/computer/file/text/note_file = null //If set, save to this file.
//Messenger vars
var/list/detected_pdas = list()
var/message_on = 1
var/message_silent = 0 //To beep or not to beep, that is the question
var/message_mode = 0 //0 for pda list, 1 for messages
var/message_tone = "beep" //Custom ringtone
var/message_note = null //Current messages in memory (Store as separate file only later??)
//File browser vars
var/datum/computer/folder/browse_folder = null
var/datum/computer/file/clipboard = null //Current file to copy
receive_os_command(list/command_list)
if(..())
return
//world << "[command_list["command"]]"
return
return_text()
if(..())
return
var/dat = src.return_text_header()
switch(src.mode)
if(0)
dat += "<h2>PERSONAL DATA ASSISTANT</h2>"
dat += "Owner: [src.master.owner]<br><br>"
dat += "<h4>General Functions</h4>"
dat += "<ul>"
dat += "<li><a href='byond://?src=\ref[src];mode=1'>Notekeeper</a></li>"
dat += "<li><a href='byond://?src=\ref[src];mode=2'>Messenger</a></li>"
dat += "<li><a href='byond://?src=\ref[src];mode=3'>File Browser</a></li>"
dat += "</ul>"
dat += "<h4>Utilities</h4>"
dat += "<ul>"
dat += "<li><a href='byond://?src=\ref[src];mode=4'>Atmospheric Scan</a></li>"
dat += "<li>Scanner: [src.master.scan_program ? "<a href='byond://?src=\ref[src];scanner=1'>[src.master.scan_program.name]</a>" : "None loaded"]</li>"
dat += "<li><a href='byond://?src=\ref[src];flight=1'>[src.master.fon ? "Disable" : "Enable"] Flashlight</a></li>"
dat += "</ul>"
if(1)
//Note Program. Can save/load note files.
dat += "<h4>Notekeeper V2.5</h4>"
if(!src.note_mode)
dat += "<a href='byond://?src=\ref[src];input=note'>Edit</a>"
dat += " | <a href='byond://?src=\ref[src];note_func=new'>New File</a>"
dat += " | <a href='byond://?src=\ref[src];note_func=save'>Save</a>"
dat += " | <a href='byond://?src=\ref[src];note_func=switchmenu'>Load</a><br>"
dat += src.note
else
dat += " <a href='byond://?src=\ref[src];note_func=switchmenu'>Back</a>"
dat += " | \[[src.holding_folder.holder.file_amount - src.holding_folder.holder.file_used]\] Free<br>"
dat += "<table cellspacing=5>"
for(var/datum/computer/file/text/T in src.holding_folder.contents)
dat += "<tr><td><a href='byond://?src=\ref[src];target=\ref[T];note_func=load'>[T.name]</a></td>"
dat += "<td>[T.extension]</td>"
dat += "<td>Length: [T.data ? (length(T.data)) : "0"]</td></tr>"
dat += "</table>"
if(2)
//Messenger. Uses Radio. Is a messenger.
//TO-DO: ~file sharing~
src.master.overlays = null //Remove existing alerts
dat += "<h4>SpaceMessenger V4.0.5</h4>"
if (!src.message_mode)
dat += "<a href='byond://?src=\ref[src];message_func=ringer'>Ringer: [src.message_silent == 1 ? "Off" : "On"]</a> | "
dat += "<a href='byond://?src=\ref[src];message_func=on'>Send / Receive: [src.message_on == 1 ? "On" : "Off"]</a> | "
dat += "<a href='byond://?src=\ref[src];input=tone'>Set Ringtone</a> | "
dat += "<a href='byond://?src=\ref[src];message_mode=1'>Messages</a><br>"
dat += "<font size=2><a href='byond://?src=\ref[src];message_func=scan'>Scan</a></font><br>"
dat += "<b>Detected PDAs</b><br>"
dat += "<ul>"
var/count = 0
if (src.message_on)
for (var/obj/item/device/pda2/P in src.detected_pdas)
if (!P.owner)
src.detected_pdas -= P
continue
else if (P == src) //I guess this can happen if somebody copies the system file.
src.detected_pdas -= P
continue
dat += "<li><a href='byond://?src=\ref[src];input=message;target=\ref[P]'>[P]</a>"
dat += "</li>"
count++
dat += "</ul>"
if (count == 0)
dat += "None detected.<br>"
else
dat += "<a href='byond://?src=\ref[src];message_func=clear'>Clear</a> | "
dat += "<a href='byond://?src=\ref[src];message_mode=0'>Back</a><br>"
dat += "<h4>Messages</h4>"
dat += src.message_note
dat += "<br>"
if(3)
//File Browser.
//To-do(?): Setting "favorite" programs to access straight from main menu
//Not sure how needed it is, not like they have to go through 500 subfolders or whatever
if((!src.browse_folder) || !(src.browse_folder.holder in src.master))
src.browse_folder = src.holding_folder
dat += " | <a href='byond://?src=\ref[src];target=\ref[src.browse_folder];browse_func=paste'>Paste</a>"
dat += " | Drive: "
dat += "\[<a href='byond://?src=\ref[src];browse_func=drive'>[src.browse_folder.holder == src.master.hd ? "MAIN" : "CART"]</a>\]<br>"
dat += "<b>Contents of [browse_folder] | Drive ID:\[[src.browse_folder.holder.title]]</b><br>"
dat += "<b>Used: \[[src.browse_folder.holder.file_used]/[src.browse_folder.holder.file_amount]\]</b><hr>"
dat += "<table cellspacing=5>"
for(var/datum/computer/file/F in browse_folder.contents)
if(F == src)
dat += "<tr><td>System</td><td>Size: [src.size]</td><td>SYSTEM</td></tr>"
continue
dat += "<tr><td><a href='byond://?src=\ref[src];target=\ref[F];browse_func=open'>[F.name]</a></td>"
dat += "<td>Size: [F.size]</td>"
dat += "<td>[F.extension]</td>"
dat += "<td><a href='byond://?src=\ref[src];target=\ref[F];browse_func=delete'>Del</a></td>"
dat += "<td><a href='byond://?src=\ref[src];target=\ref[F];input=rename'>Rename</a></td>"
dat += "<td><a href='byond://?src=\ref[src];target=\ref[F];browse_func=copy'>Copy</a></td>"
dat += "</tr>"
dat += "</table>"
if(4)
//Atmos Scanner
dat += "<h4>Atmospheric Readings</h4>"
var/turf/T = get_turf_or_move(get_turf(src.master))
if (isnull(T))
dat += "Unable to obtain a reading.<br>"
else
var/datum/gas_mixture/environment = T.return_air()
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles()
dat += "Air Pressure: [round(pressure,0.1)] kPa<br>"
if (total_moles)
var/o2_level = environment.oxygen/total_moles
var/n2_level = environment.nitrogen/total_moles
var/co2_level = environment.carbon_dioxide/total_moles
var/plasma_level = environment.toxins/total_moles
var/unknown_level = 1-(o2_level+n2_level+co2_level+plasma_level)
dat += "Nitrogen: [round(n2_level*100)]%<br>"
dat += "Oxygen: [round(o2_level*100)]%<br>"
dat += "Carbon Dioxide: [round(co2_level*100)]%<br>"
dat += "Plasma: [round(plasma_level*100)]%<br>"
if(unknown_level > 0.01)
dat += "OTHER: [round(unknown_level)]%<br>"
dat += "Temperature: [round(environment.temperature-T0C)]&deg;C<br>"
dat += "<br>"
return dat
Topic(href, href_list)
if(..())
return
if(href_list["mode"])
var/newmode = text2num(href_list["mode"])
src.mode = max(newmode, 0)
else if(href_list["flight"])
src.master.toggle_light()
else if(href_list["scanner"])
if(src.master.scan_program)
src.master.scan_program = null
else if(href_list["input"])
switch(href_list["input"])
if("tone")
var/t = input(usr, "Please enter new ringtone", src.name, src.message_tone) as text
if (!t)
return
if (!src.master || !in_range(src.master, usr) && src.master.loc != usr)
return
if(!(src.holder in src.master))
return
t = copytext(sanitize(t), 1, 20)
src.message_tone = t
if("note")
var/t = input(usr, "Please enter note", src.name, src.note) as message
if (!t)
return
if (!src.master || !in_range(src.master, usr) && src.master.loc != usr)
return
if(!(src.holder in src.master))
return
t = copytext(adminscrub(t), 1, MAX_MESSAGE_LEN)
src.note = t
if("message")
var/obj/item/device/pda2/P = locate(href_list["target"])
if(!P || !istype(P))
return
var/t = input(usr, "Please enter message", P.name, null) as text
if (!t)
return
if (!src.master || !in_range(src.master, usr) && src.master.loc != usr)
return
if(!(src.holder in src.master))
return
var/datum/signal/signal = new
signal.data["command"] = "text message"
signal.data["message"] = t
signal.data["sender"] = src.master.owner
signal.data["tag"] = "\ref[P]"
src.post_signal(signal)
src.message_note += "<i><b>&rarr; To [P.owner]:</b></i><br>[t]<br>"
if("rename")
var/datum/computer/file/F = locate(href_list["target"])
if(!F || !istype(F))
return
var/t = input(usr, "Please enter new name", src.name, F.name) as text
t = copytext(sanitize(t), 1, 16)
if (!t)
return
if (!in_range(src.master, usr) || !(F.holder in src.master))
return
if(F.holder.read_only)
return
F.name = capitalize(lowertext(t))
else if(href_list["message_func"]) //Messenger specific topic junk
switch(href_list["message_func"])
if("ringer")
src.message_silent = !src.message_silent
if("on")
src.message_on = !src.message_on
if("clear")
src.message_note = null
if("scan")
if(src.message_on)
src.detected_pdas = list()
var/datum/signal/signal = new
signal.data["command"] = "report pda"
src.post_signal(signal)
else if(href_list["note_func"]) //Note program specific topic junk
switch(href_list["note_func"])
if("new")
src.note_file = null
src.note = null
if("save")
if(src.note_file && src.note_file.holder in src.master)
src.note_file.data = src.note
else
var/datum/computer/file/text/F = new /datum/computer/file/text
if(!src.holding_folder.add_file(F))
del(F)
else
src.note_file = F
F.data = src.note
if("load")
var/datum/computer/file/text/T = locate(href_list["target"])
if(!T || !istype(T))
return
src.note_file = T
src.note = note_file.data
src.note_mode = 0
if("switchmenu")
src.note_mode = !src.note_mode
else if(href_list["browse_func"]) //File browser specific topic junk
var/datum/computer/target = locate(href_list["target"])
switch(href_list["browse_func"])
if("drive")
if(src.browse_folder.holder == src.master.hd && src.master.cartridge && (src.master.cartridge.root))
src.browse_folder = src.master.cartridge.root
else
src.browse_folder = src.holding_folder
if("open")
if(!target || !istype(target))
return
if(istype(target, /datum/computer/file/pda_program))
if(istype(target,/datum/computer/file/pda_program/os) && (src.master.host_program))
return
else
src.master.run_program(target)
src.master.updateSelfDialog()
return
if("delete")
if(!target || !istype(target))
return
src.master.delete_file(target)
if("copy")
if(istype(target,/datum/computer/file) && (!target.holder || (target.holder in src.master.contents)))
src.clipboard = target
if("paste")
if(istype(target,/datum/computer/folder))
if(!src.clipboard || !src.clipboard.holder || !(src.clipboard.holder in src.master.contents))
return
if(!istype(src.clipboard))
return
src.clipboard.copy_file_to_folder(target)
else if(href_list["message_mode"])
var/newmode = text2num(href_list["message_mode"])
src.message_mode = max(newmode, 0)
src.master.add_fingerprint(usr)
src.master.updateSelfDialog()
return
receive_signal(datum/signal/signal)
if(..())
return
switch(signal.data["command"])
if("text message")
if(!message_on || !signal.data["message"])
return
var/sender = signal.data["sender"]
if(!sender)
sender = "!Unknown!"
src.message_note += "<i><b>&larr; From <a href='byond://?src=\ref[src];input=message;target=\ref[signal.source]'>[sender]</a>:</b></i><br>[signal.data["message"]]<br>"
var/alert_beep = null //Don't beep if set to silent.
if(!src.message_silent)
alert_beep = src.message_tone
src.master.display_alert(alert_beep)
src.master.updateSelfDialog()
if("report pda")
if(!message_on)
return
var/datum/signal/newsignal = new
newsignal.data["command"] = "reporting pda"
newsignal.data["tag"] = "\ref[signal.source]"
src.post_signal(newsignal)
if("reporting pda")
if(!detected_pdas)
detected_pdas = new()
if(!(signal.source in detected_pdas))
detected_pdas += signal.source
src.master.updateSelfDialog()
return
return_text_header()
if(!src.master)
return
var/dat
if(src.mode)
dat += " | <a href='byond://?src=\ref[src];mode=0'>Main Menu</a>"
else if (!isnull(src.master.cartridge))
dat += " | <a href='byond://?src=\ref[src.master];eject_cart=1'>Eject [src.master.cartridge]</a>"
dat += " | <a href='byond://?src=\ref[src.master];refresh=1'>Refresh</a>"
return dat
+185
View File
@@ -0,0 +1,185 @@
//Eventual plan: Convert all datum/data to datum/computer/file
/datum/computer/file/text
name = "text"
extension = "TEXT"
size = 2.0
var/data = null
/datum/computer/file/record
name = "record"
extension = "REC"
var/list/fields = list( )
//base pda program
/datum/computer/file/pda_program
name = "blank program"
extension = "PPROG"
var/obj/item/device/pda2/master = null
var/id_tag = null
os
name = "blank system program"
extension = "PSYS"
scan
name = "blank scan program"
extension = "PSCAN"
New(obj/holding as obj)
if(holding)
src.holder = holding
if(istype(src.holder.loc,/obj/item/device/pda2))
src.master = src.holder.loc
proc
return_text()
if((!src.holder) || (!src.master))
return 1
if((!istype(holder)) || (!istype(master)))
return 1
if(!(holder in src.master.contents))
//world << "Holder [holder] not in [master] of prg:[src]"
if(master.active_program == src)
master.active_program = null
return 1
if(!src.holder.root)
src.holder.root = new /datum/computer/folder
src.holder.root.holder = src
src.holder.root.name = "root"
return 0
process() //This isn't actually used at the moment
if((!src.holder) || (!src.master))
return 1
if((!istype(holder)) || (!istype(master)))
return 1
if(!(holder in src.master.contents))
if(master.active_program == src)
master.active_program = null
return 1
if(!src.holder.root)
src.holder.root = new /datum/computer/folder
src.holder.root.holder = src
src.holder.root.name = "root"
return 0
//maybe remove this, I haven't found a good use for it yet
send_os_command(list/command_list)
if(!src.master || !src.holder || src.master.host_program || !command_list)
return 1
if(!istype(src.master.host_program) || src.master.host_program == src)
return 1
src.master.host_program.receive_os_command()
return 0
return_text_header()
if(!src.master || !src.holder)
return
var/dat = " | <a href='byond://?src=\ref[src];quit=1'>Main Menu</a>"
dat += " | <a href='byond://?src=\ref[src.master];refresh=1'>Refresh</a>"
return dat
post_signal(datum/signal/signal, newfreq)
if(master)
master.post_signal(signal, newfreq)
else
del(signal)
transfer_holder(obj/item/weapon/disk/data/newholder,datum/computer/folder/newfolder)
if((newholder.file_used + src.size) > newholder.file_amount)
return 0
if(!newholder.root)
newholder.root = new /datum/computer/folder
newholder.root.holder = newholder
newholder.root.name = "root"
if(!newfolder)
newfolder = newholder.root
if((src.holder && src.holder.read_only) || newholder.read_only)
return 0
if((src.holder) && (src.holder.root))
src.holder.root.remove_file(src)
newfolder.add_file(src)
if(istype(newholder.loc,/obj/item/device/pda2))
src.master = newholder.loc
//world << "Setting [src.holder] to [newholder]"
src.holder = newholder
return 1
receive_signal(datum/signal/signal)
if((!src.holder) || (!src.master))
return 1
if((!istype(holder)) || (!istype(master)))
return 1
if(!(holder in src.master.contents))
if(master.active_program == src)
master.active_program = null
return 1
return 0
Topic(href, href_list)
if((!src.holder) || (!src.master))
return 1
if((!istype(holder)) || (!istype(master)))
return 1
if(src.master.active_program != src)
return 1
if ((!usr.contents.Find(src.master) && (!in_range(src.master, usr) || !istype(src.master.loc, /turf))) && (!istype(usr, /mob/living/silicon)))
return 1
if(!(holder in src.master.contents))
if(master.active_program == src)
master.active_program = null
return 1
usr.machine = src.master
if (href_list["close"])
usr.machine = null
usr << browse(null, "window=pda2")
return 0
if (href_list["quit"])
// src.master.processing_programs.Remove(src)
if(src.master.host_program && src.master.host_program.holder && (src.master.host_program.holder in src.master.contents))
src.master.run_program(src.master.host_program)
src.master.updateSelfDialog()
return 1
else
src.master.active_program = null
src.master.updateSelfDialog()
return 1
return 0
+297
View File
@@ -0,0 +1,297 @@
//The advanced pea-green monochrome lcd of tomorrow.
//TO-DO: rearrange all this disk/data stuff so that fixed disks are the parent type
//because otherwise you have carts going into floppy drives and it's ALL MAD
/obj/item/weapon/disk/data/cartridge
name = "Cart 2.0"
desc = "A data cartridge for portable microcomputers."
icon = 'pda.dmi'
icon_state = "cart"
item_state = "electronic"
file_amount = 80.0
title = "ROM Cart"
pda2test
name = "Test Cart"
New()
..()
src.root.add_file( new /datum/computer/file/computer_program/arcade(src))
src.root.add_file( new /datum/computer/file/pda_program/manifest(src))
src.root.add_file( new /datum/computer/file/pda_program/status_display(src))
src.root.add_file( new /datum/computer/file/pda_program/signaler(src))
src.root.add_file( new /datum/computer/file/pda_program/qm_records(src))
src.root.add_file( new /datum/computer/file/pda_program/scan/health_scan(src))
src.root.add_file( new /datum/computer/file/pda_program/records/security(src))
src.root.add_file( new /datum/computer/file/pda_program/records/medical(src))
src.read_only = 1
/obj/item/device/pda2
name = "PDA"
desc = "A portable microcomputer by Thinktronic Systems, LTD. Functionality determined by an EEPROM cartridge."
icon = 'pda.dmi'
icon_state = "pda"
item_state = "electronic"
w_class = 2.0
flags = FPRINT | TABLEPASS | ONBELT
var/owner = null
var/default_cartridge = null // Access level defined by cartridge
var/obj/item/weapon/disk/data/cartridge/cartridge = null //current cartridge
var/datum/computer/file/pda_program/active_program = null
var/datum/computer/file/pda_program/os/host_program = null
var/datum/computer/file/pda_program/scan/scan_program = null
var/obj/item/weapon/disk/data/fixed_disk/hd = null
var/fon = 0 //Is the flashlight function on?
var/f_lum = 3 //Luminosity for the flashlight function
// var/datum/data/record/active1 = null //General
// var/datum/data/record/active2 = null //Medical
// var/datum/data/record/active3 = null //Security
// var/obj/item/weapon/integrated_uplink/uplink = null //Maybe replace uplink with some remote ~syndicate~ server
var/frequency = 1149
var/datum/radio_frequency/radio_connection
var/setup_default_cartridge = null //Cartridge contains job-specific programs
var/setup_drive_size = 24.0 //PDAs don't have much work room at all, really.
var/setup_system_os_path = /datum/computer/file/pda_program/os/main_os //Needs an operating system to...operate!!
/obj/item/device/pda2/pickup(mob/user)
if (src.fon)
src.sd_SetLuminosity(0)
user.sd_SetLuminosity(user.luminosity + src.f_lum)
/obj/item/device/pda2/dropped(mob/user)
if (src.fon)
user.sd_SetLuminosity(user.luminosity - src.f_lum)
src.sd_SetLuminosity(src.f_lum)
/obj/item/device/pda2/New()
..()
spawn(5)
src.hd = new /obj/item/weapon/disk/data/fixed_disk(src)
src.hd.file_amount = src.setup_drive_size
src.hd.name = "Minidrive"
src.hd.title = "Minidrive"
if(src.setup_system_os_path)
src.host_program = new src.setup_system_os_path
src.hd.file_amount = max(src.hd.file_amount, src.host_program.size)
src.host_program.transfer_holder(src.hd)
if(radio_controller)
radio_controller.add_object(src, "[frequency]")
if (src.default_cartridge)
src.cartridge = new src.setup_default_cartridge(src)
// if(src.owner)
// processing_items.Add(src)
/obj/item/device/pda2/attack_self(mob/user as mob)
user.machine = src
var/dat = "<html><head><title>Personal Data Assistant</title></head><body>"
dat += "<a href='byond://?src=\ref[src];close=1'>Close</a>"
if (!src.owner)
if(src.cartridge)
dat += " | <a href='byond://?src=\ref[src];eject_cart=1'>Eject [src.cartridge]</a>"
dat += "<br>Warning: No owner information entered. Please swipe card.<br><br>"
dat += "<a href='byond://?src=\ref[src];refresh=1'>Retry</a>"
else
if(src.active_program)
dat += src.active_program.return_text()
else
if(src.host_program)
src.run_program(src.host_program)
dat += src.active_program.return_text()
else
if(src.cartridge)
dat += " | <a href='byond://?src=\ref[src];eject_cart=1'>Eject [src.cartridge]</a><br>"
dat += "<center><font color=red>Fatal Error 0x17<br>"
dat += "No System Software Loaded</font></center>"
//To-do: System recovery shit (maybe have a dedicated computer for this kind of thing)
user << browse(dat,"window=pda2")
onclose(user,"pda2")
return
/obj/item/device/pda2/Topic(href, href_list)
..()
if (usr.contents.Find(src) || usr.contents.Find(src.master) || (istype(src.loc, /turf) && get_dist(src, usr) <= 1))
if (usr.stat || usr.restrained())
return
src.add_fingerprint(usr)
usr.machine = src
if(href_list["return_to_host"])
if(src.host_program)
src.active_program = src.host_program
src.host_program = null
else if (href_list["eject_cart"])
src.eject_cartridge()
else if (href_list["refresh"])
src.updateSelfDialog()
else if (href_list["close"])
usr << browse(null, "window=pda2")
usr.machine = null
src.updateSelfDialog()
return
/obj/item/device/pda2/attackby(obj/item/weapon/C as obj, mob/user as mob)
if (istype(C, /obj/item/weapon/disk/data/cartridge) && isnull(src.cartridge))
user.drop_item()
C.loc = src
user << "\blue You insert [C] into [src]."
src.cartridge = C
src.updateSelfDialog()
else if (istype(C, /obj/item/weapon/card/id) && !src.owner && C:registered)
src.owner = C:registered
src.name = "PDA-[src.owner]"
user << "\blue Card scanned."
src.updateSelfDialog()
/obj/item/device/pda2/receive_signal(datum/signal/signal)
if(!signal || signal.encryption || !src.owner) return
if(signal.data["tag"] && signal.data["tag"] != "\ref[src]") return
if(src.host_program)
src.host_program.receive_signal(signal)
if(src.active_program && (src.active_program != src.host_program))
src.host_program.receive_signal(signal)
return
/obj/item/device/pda2/attack(mob/M as mob, mob/user as mob)
if(src.scan_program)
return
else
..()
/obj/item/device/pda2/afterattack(atom/A as mob|obj|turf|area, mob/user as mob)
var/scan_dat = null
if(src.scan_program && istype(src.scan_program))
scan_dat = src.scan_program.scan_atom(A)
if(scan_dat)
A.visible_message("\red [user] has scanned [A]!")
user.show_message(scan_dat, 1)
return
/obj/item/device/pda2/proc
post_signal(datum/signal/signal,var/newfreq)
if(!signal)
return
var/freq = newfreq
if(!freq)
freq = src.frequency
signal.source = src
var/datum/radio_frequency/frequency = radio_controller.return_frequency("[freq]")
signal.transmission_method = TRANSMISSION_RADIO
if(frequency)
return frequency.post_signal(src, signal)
else
del(signal)
eject_cartridge()
if(src.cartridge)
var/turf/T = get_turf(src)
if(src.active_program && (src.active_program.holder == src.cartridge))
src.active_program = null
if(src.host_program && (src.host_program.holder == src.cartridge))
src.host_program = null
if(src.scan_program && (src.scan_program.holder == src.cartridge))
src.scan_program = null
src.cartridge.loc = T
src.cartridge = null
return
//Toggle the built-in flashlight
toggle_light()
src.fon = (!src.fon)
if (ismob(src.loc))
if (src.fon)
src.loc.sd_SetLuminosity(src.loc.luminosity + src.f_lum)
else
src.loc.sd_SetLuminosity(src.loc.luminosity - src.f_lum)
else
src.sd_SetLuminosity(src.fon * src.f_lum)
src.updateSelfDialog()
display_alert(var/alert_message) //Add alert overlay and beep
if (alert_message)
playsound(src.loc, 'twobeep.ogg', 50, 1)
for (var/mob/O in hearers(3, src.loc))
O.show_message(text("\icon[src] *[alert_message]*"))
src.overlays = null
src.overlays += image('pda.dmi', "pda-r")
return
run_program(datum/computer/file/pda_program/program)
if((!program) || (!program.holder))
return 0
if(!(program.holder in src))
// world << "Not in src"
program = new program.type
program.transfer_holder(src.hd)
if(program.master != src)
program.master = src
if(!src.host_program && istype(program, /datum/computer/file/pda_program/os))
src.host_program = program
if(istype(program, /datum/computer/file/pda_program/scan))
if(program == src.scan_program)
src.scan_program = null
else
src.scan_program = program
return 1
src.active_program = program
return 1
delete_file(datum/computer/file/file)
//world << "Deleting [file]..."
if((!file) || (!file.holder) || (file.holder.read_only))
//world << "Cannot delete :("
return 0
//Don't delete the running program you jerk
if(src.active_program == file || src.host_program == file)
src.active_program = null
//world << "Now calling del on [file]..."
del(file)
return 1
+181
View File
@@ -0,0 +1,181 @@
//CONTENTS:
//Generic records
//Security records
//Medical records
/datum/computer/file/pda_program/records
var/mode = 0
var/datum/data/record/active1 = null //General
var/datum/data/record/active2 = null //Security/Medical/Whatever
//To-do: editing arrest status/etc from pda.
/datum/computer/file/pda_program/records/security
name = "Security Records"
size = 12.0
return_text()
if(..())
return
var/dat = src.return_text_header()
switch(src.mode)
if(0)
dat += "<h4>Security Record List</h4>"
for (var/datum/data/record/R in data_core.general)
dat += "<a href='byond://?src=\ref[src];select_rec=\ref[R]'>[R.fields["id"]]: [R.fields["name"]]<br>"
dat += "<br>"
if(1)
dat += "<h4>Security Record</h4>"
dat += "<a href='byond://?src=\ref[src];mode=0'>Back</a><br>"
if (istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1))
dat += "Name: [src.active1.fields["name"]] ID: [src.active1.fields["id"]]<br>"
dat += "Sex: [src.active1.fields["sex"]]<br>"
dat += "Age: [src.active1.fields["age"]]<br>"
dat += "Fingerprint: [src.active1.fields["fingerprint"]]<br>"
dat += "Physical Status: [src.active1.fields["p_stat"]]<br>"
dat += "Mental Status: [src.active1.fields["m_stat"]]<br>"
else
dat += "<b>Record Lost!</b><br>"
dat += "<br>"
dat += "<h4>Security Data</h4>"
if (istype(src.active2, /datum/data/record) && data_core.security.Find(src.active2))
dat += "Criminal Status: [src.active2.fields["criminal"]]<br>"
dat += "Minor Crimes: [src.active2.fields["mi_crim"]]<br>"
dat += "Details: [src.active2.fields["mi_crim"]]<br><br>"
dat += "Major Crimes: [src.active2.fields["ma_crim"]]<br>"
dat += "Details: [src.active2.fields["ma_crim_d"]]<br><br>"
dat += "Important Notes:<br>"
dat += "[src.active2.fields["notes"]]"
else
dat += "<b>Record Lost!</b><br>"
dat += "<br>"
return dat
Topic(href, href_list)
if(..())
return
if(href_list["mode"])
var/newmode = text2num(href_list["mode"])
src.mode = max(newmode, 0)
else if(href_list["select_rec"])
var/datum/data/record/R = locate(href_list["select_rec"])
var/datum/data/record/S = locate(href_list["select_rec"])
if (data_core.general.Find(R))
for (var/datum/data/record/E in data_core.security)
if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
S = E
break
src.active1 = R
src.active2 = S
src.mode = 1
src.master.add_fingerprint(usr)
src.master.updateSelfDialog()
return
/datum/computer/file/pda_program/records/medical
name = "Medical Records"
size = 8.0
return_text()
if(..())
return
var/dat = src.return_text_header()
switch(src.mode)
if(0)
dat += "<h4>Medical Record List</h4>"
for (var/datum/data/record/R in data_core.general)
dat += "<a href='byond://?src=\ref[src];select_rec=\ref[R]'>[R.fields["id"]]: [R.fields["name"]]<br>"
dat += "<br>"
if(1)
dat += "<h4>Medical Record</h4>"
dat += "<a href='byond://?src=\ref[src];mode=0'>Back</a><br>"
if (istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1))
dat += "Name: [src.active1.fields["name"]] ID: [src.active1.fields["id"]]<br>"
dat += "Sex: [src.active1.fields["sex"]]<br>"
dat += "Age: [src.active1.fields["age"]]<br>"
dat += "Fingerprint: [src.active1.fields["fingerprint"]]<br>"
dat += "Physical Status: [src.active1.fields["p_stat"]]<br>"
dat += "Mental Status: [src.active1.fields["m_stat"]]<br>"
else
dat += "<b>Record Lost!</b><br>"
dat += "<br>"
dat += "<h4>Medical Data</h4>"
if (istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2))
dat += "Blood Type: [src.active2.fields["b_type"]]<br><br>"
dat += "Minor Disabilities: [src.active2.fields["mi_dis"]]<br>"
dat += "Details: [src.active2.fields["mi_dis_d"]]<br><br>"
dat += "Major Disabilities: [src.active2.fields["ma_dis"]]<br>"
dat += "Details: [src.active2.fields["ma_dis_d"]]<br><br>"
dat += "Allergies: [src.active2.fields["alg"]]<br>"
dat += "Details: [src.active2.fields["alg_d"]]<br><br>"
dat += "Current Diseases: [src.active2.fields["cdi"]]<br>"
dat += "Details: [src.active2.fields["cdi_d"]]<br><br>"
dat += "Important Notes: [src.active2.fields["notes"]]<br>"
else
dat += "<b>Record Lost!</b><br>"
dat += "<br>"
return dat
Topic(href, href_list)
if(..())
return
if(href_list["mode"])
var/newmode = text2num(href_list["mode"])
src.mode = max(newmode, 0)
else if(href_list["select_rec"])
var/datum/data/record/R = locate(href_list["select_rec"])
var/datum/data/record/M = locate(href_list["select_rec"])
if (data_core.general.Find(R))
for (var/datum/data/record/E in data_core.medical)
if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"]))
M = E
break
src.active1 = R
src.active2 = M
src.mode = 1
src.master.add_fingerprint(usr)
src.master.updateSelfDialog()
return
+101
View File
@@ -0,0 +1,101 @@
//CONTENTS:
//Base scanner stuff
//Health scanner
//Forensic scanner
//Reagent scanner
/datum/computer/file/pda_program/scan
return_text()
return src.return_text_header()
proc/scan_atom(atom/A as mob|obj|turf|area)
if( !A || (!src.holder) || (!src.master))
return 1
if((!istype(holder)) || (!istype(master)))
return 1
if(!(holder in src.master.contents))
if(master.scan_program == src)
master.scan_program = null
return 1
return 0
//Health analyzer program
health_scan
name = "Health Scan"
size = 8.0
scan_atom(atom/A as mob|obj|turf|area)
if(..())
return
var/mob/living/carbon/C = A
if(!istype(C))
return
var/dat = "\blue Analyzing Results for [C]:\n"
dat += "\blue \t Overall Status: [C.stat > 1 ? "dead" : "[C.health]% healthy"]\n"
dat += "\blue \t Damage Specifics: [C.oxyloss > 50 ? "\red" : "\blue"][C.oxyloss]-[C.toxloss > 50 ? "\red" : "\blue"][C.toxloss]-[C.fireloss > 50 ? "\red" : "\blue"][C.fireloss]-[C.bruteloss > 50 ? "\red" : "\blue"][C.bruteloss]\n"
dat += "\blue \t Key: Suffocation/Toxin/Burns/Brute\n"
dat += "\blue \t Body Temperature: [C.bodytemperature-T0C]&deg;C ([C.bodytemperature*1.8-459.67]&deg;F)"
if(C.virus)
dat += "\red \n<b>Warning Virus Detected.</b>\nName: [C.virus.name].\nType: [C.virus.spread].\nStage: [C.virus.stage]/[C.virus.max_stages].\nPossible Cure: [C.virus.cure]"
return dat
//Forensic scanner
forensic_scan
name = "Forensic Scan"
size = 8.0
scan_atom(atom/A as mob|obj|turf|area)
if(..())
return
var/dat = null
if(istype(A,/mob/living/carbon/human))
var/mob/living/carbon/human/H = A
if (!istype(H.dna, /datum/dna) || !isnull(H.gloves))
dat += "\blue Unable to scan [A]'s fingerprints.\n"
else
dat += "\blue [H]'s Fingerprints: [md5(H.dna.uni_identity)]\n"
if ( !(H.blood_DNA) )
dat += "\blue No blood found on [H]\n"
else
dat += "\blue Blood type: [H.blood_type]\nDNA: [H.blood_DNA]\n"
if (!A.fingerprints)
dat += "\blue Unable to locate any fingerprints on [A]!\n"
else
var/list/L = params2list(A:fingerprints)
dat += "\blue Isolated [L.len] fingerprints.\n"
for(var/i in L)
dat += "\blue \t [i]\n"
return dat
//Reagent scanning program
reagent_scan
name = "Reagent Scan"
size = 6.0
scan_atom(atom/A as mob|obj|turf|area)
if(..())
return
var/dat = null
if(!isnull(A.reagents))
if(A.reagents.reagent_list.len > 0)
var/reagents_length = A.reagents.reagent_list.len
dat += "\blue [reagents_length] chemical agent[reagents_length > 1 ? "s" : ""] found.\n"
for (var/datum/reagent/re in A.reagents.reagent_list)
dat += "\blue \t [re] - [re.volume]\n"
else
dat = "\blue No active chemical agents found in [A]."
else
dat = "\blue No significant chemical agents found in [A]."
return dat
+204
View File
@@ -0,0 +1,204 @@
//Assorted small programs not worthy of their own file
//CONTENTS:
//Crew Manifest viewer
//Status display controller
//Remote signaling program
//Cargo orders monitor
//Manifest
/datum/computer/file/pda_program/manifest
name = "Manifest"
return_text()
if(..())
return
var/dat = src.return_text_header()
dat += "<h4>Crew Manifest</h4>"
dat += "Entries cannot be modified from this terminal.<br><br>"
for (var/datum/data/record/t in data_core.general)
dat += "[t.fields["name"]] - [t.fields["rank"]]<br>"
dat += "<br>"
return dat
//Status Display
/datum/computer/file/pda_program/status_display
name = "Status Controller"
size = 8.0
var/message1 // For custom messages on the displays.
var/message2
return_text()
if(..())
return
var/dat = src.return_text_header()
dat += "<h4>Station Status Display Interlink</h4>"
dat += "\[ <A HREF='?src=\ref[src];statdisp=blank'>Clear</A> \]<BR>"
dat += "\[ <A HREF='?src=\ref[src];statdisp=shuttle'>Shuttle ETA</A> \]<BR>"
dat += "\[ <A HREF='?src=\ref[src];statdisp=message'>Message</A> \]"
dat += "<ul><li> Line 1: <A HREF='?src=\ref[src];statdisp=setmsg1'>[ message1 ? message1 : "(none)"]</A>"
dat += "<li> Line 2: <A HREF='?src=\ref[src];statdisp=setmsg2'>[ message2 ? message2 : "(none)"]</A></ul><br>"
dat += "\[ Alert: <A HREF='?src=\ref[src];statdisp=alert;alert=default'>None</A> |"
dat += " <A HREF='?src=\ref[src];statdisp=alert;alert=redalert'>Red Alert</A> |"
dat += " <A HREF='?src=\ref[src];statdisp=alert;alert=lockdown'>Lockdown</A> |"
dat += " <A HREF='?src=\ref[src];statdisp=alert;alert=biohazard'>Biohazard</A> \]<BR>"
return dat
Topic(href, href_list)
if(..())
return
if(href_list["statdisp"])
switch(href_list["statdisp"])
if("message")
post_status("message", message1, message2)
if("alert")
post_status("alert", href_list["alert"])
if("setmsg1")
message1 = input("Line 1", "Enter Message Text", message1) as text|null
if (!src.master || !in_range(src.master, usr) && src.master.loc != usr)
return
if(!(src.holder in src.master))
return
src.master.updateSelfDialog()
if("setmsg2")
message2 = input("Line 2", "Enter Message Text", message2) as text|null
if (!src.master || !in_range(src.master, usr) && src.master.loc != usr)
return
if(!(src.holder in src.master))
return
src.master.updateSelfDialog()
else
post_status(href_list["statdisp"])
src.master.add_fingerprint(usr)
src.master.updateSelfDialog()
return
proc/post_status(var/command, var/data1, var/data2)
if(!src.master)
return
var/datum/signal/status_signal = new
status_signal.source = src.master
status_signal.transmission_method = 1
status_signal.data["command"] = command
switch(command)
if("message")
status_signal.data["msg1"] = data1
status_signal.data["msg2"] = data2
if("alert")
status_signal.data["picture_state"] = data1
src.post_signal(status_signal,"1435")
//Signaler
/datum/computer/file/pda_program/signaler
name = "Signalix 5"
size = 8.0
var/send_freq = 1457 //Frequency signal is sent at, should be kept within normal radio ranges.
var/send_code = 30
var/last_transmission = 0 //No signal spamming etc
return_text()
if(..())
return
var/dat = src.return_text_header()
dat += "<h4>Remote Signaling System</h4>"
dat += {"
<a href='byond://?src=\ref[src];send=1'>Send Signal</A><BR>
Frequency:
<a href='byond://?src=\ref[src];adj_freq=-10'>-</a>
<a href='byond://?src=\ref[src];adj_freq=-2'>-</a>
[format_frequency(send_freq)]
<a href='byond://?src=\ref[src];adj_freq=2'>+</a>
<a href='byond://?src=\ref[src];adj_freq=10'>+</a><br>
<br>
Code:
<a href='byond://?src=\ref[src];adj_code=-5'>-</a>
<a href='byond://?src=\ref[src];adj_code=-1'>-</a>
[send_code]
<a href='byond://?src=\ref[src];adj_code=1'>+</a>
<a href='byond://?src=\ref[src];adj_code=5'>+</a><br>"}
return dat
Topic(href, href_list)
if(..())
return
if (href_list["send"])
if(last_transmission && world.time < (last_transmission + 5))
return
last_transmission = world.time
spawn( 0 )
var/time = time2text(world.realtime,"hh:mm:ss")
lastsignalers.Add("[time] <B>:</B> [usr.key] used [src.master] @ location ([src.master.loc.x],[src.master.loc.y],[src.master.loc.z]) <B>:</B> [format_frequency(send_freq)]/[send_code]")
var/datum/signal/signal = new
signal.source = src
signal.encryption = send_code
signal.data["message"] = "ACTIVATE"
src.post_signal(signal,"[send_freq]")
return
else if (href_list["adj_freq"])
src.send_freq = sanitize_frequency(src.send_freq + text2num(href_list["adj_freq"]))
else if (href_list["adj_code"])
src.send_code += text2num(href_list["adj_code"])
src.send_code = round(src.send_code)
src.send_code = min(100, src.send_code)
src.send_code = max(1, src.send_code)
src.master.add_fingerprint(usr)
src.master.updateSelfDialog()
return
//Supply record monitor
/datum/computer/file/pda_program/qm_records
name = "Supply Records"
size = 8.0
return_text()
if(..())
return
var/dat = src.return_text_header()
dat += "<h4>Supply Record Interlink</h4>"
dat += "<BR><B>Supply shuttle</B><BR>"
dat += "Location: [supply_shuttle_moving ? "Moving to station ([supply_shuttle_timeleft] Mins.)":supply_shuttle_at_station ? "Station":"Dock"]<BR>"
dat += "Current approved orders: <BR><ol>"
for(var/S in supply_shuttle_shoppinglist)
var/datum/supply_order/SO = S
dat += "<li>[SO.object.name] approved by [SO.orderedby] [SO.comment ? "([SO.comment])":""]</li>"
dat += "</ol>"
dat += "Current requests: <BR><ol>"
for(var/S in supply_shuttle_requestlist)
var/datum/supply_order/SO = S
dat += "<li>[SO.object.name] requested by [SO.orderedby]</li>"
dat += "</ol><font size=\"-3\">Upgrade NOW to Space Parts & Space Vendors PLUS for full remote order control and inventory management."
return dat
+18
View File
@@ -0,0 +1,18 @@
/*
/obj/plant
name = "plant"
icon = 'plants.dmi'
flags = FPRINT | TABLEPASS
var/health = 100
var/bruteloss = 0
var/toxloss = 0
var/generation = 1
var/life_stage = 0
var/datum/disease/virus = null
/obj/item/seedpacket
name = "seed packet"
icon = 'plants.dmi'
icon_state = "packet"
flags = FPRINT | TABLEPASS
*/
+389
View File
@@ -0,0 +1,389 @@
// converyor belt
// moves items/mobs/movables in set direction every ptick
/obj/machinery/conveyor
icon = 'recycling.dmi'
icon_state = "conveyor0"
name = "conveyor belt"
desc = "A conveyor belt."
anchored = 1
var/operating = 0 // 1 if running forward, -1 if backwards, 0 if off
var/operable = 1 // true if can operate (no broken segments in this belt run)
var/basedir // this is the default (forward) direction, set by the map dir
// note dir var can vary when the direction changes
var/list/affecting // the list of all items that will be moved this ptick
var/id = "" // the control ID - must match controller ID
// following two only used if a diverter is present
var/divert = 0 // if non-zero, direction to divert items
var/divdir = 0 // if diverting, will be conveyer dir needed to divert (otherwise dense)
// create a conveyor
/obj/machinery/conveyor/New()
..()
basedir = dir
setdir()
// set the dir and target turf depending on the operating direction
/obj/machinery/conveyor/proc/setdir()
if(operating == -1)
dir = turn(basedir,180)
else
dir = basedir
update()
// update the icon depending on the operating condition
/obj/machinery/conveyor/proc/update()
if(stat & BROKEN)
icon_state = "conveyor-b"
operating = 0
return
if(!operable)
operating = 0
icon_state = "conveyor[(operating != 0) && !(stat & NOPOWER)]"
// machine process
// move items to the target location
/obj/machinery/conveyor/process()
if(stat & (BROKEN | NOPOWER))
return
if(!operating)
return
use_power(100)
var/movedir = dir // base movement dir
if(divert && dir==divdir) // update if diverter present
movedir = divert
affecting = loc.contents - src // moved items will be all in loc
spawn(1) // slight delay to prevent infinite propagation due to map order
for(var/atom/movable/A in affecting)
if(!A.anchored)
if(ismob(A))
var/mob/M = A
if(M.buckled == src)
var/obj/machinery/conveyor/C = locate() in get_step(src, dir)
M.buckled = null
step(M,dir)
if(C)
M.buckled = C
else
new/obj/item/weapon/cable_coil/cut(M.loc)
else
step(M,movedir)
else
step(A,movedir)
// attack with item, place item on conveyor
/obj/machinery/conveyor/attackby(var/obj/item/I, mob/user)
if(istype(I, /obj/item/weapon/grab)) // special handling if grabbing a mob
var/obj/item/weapon/grab/G = I
G.affecting.Move(src.loc)
del(G)
return
else if(istype(I, /obj/item/weapon/cable_coil)) // if cable, see if a mob is present
var/mob/M = locate() in src.loc
if(M)
if (M == user)
src.visible_message("\blue [M] ties \himself to the conveyor.")
// note don't check for lying if self-tying
else
if(M.lying)
user.visible_message("\blue [M] has been tied to the conveyor by [user].", "\blue You tie [M] to the converyor!")
else
user << "\blue [M] must be lying down to be tied to the converyor!"
return
M.buckled = src
src.add_fingerprint(user)
I:use(1)
M.lying = 1
return
// else if no mob in loc, then allow coil to be placed
else if(istype(I, /obj/item/weapon/wirecutters))
var/mob/M = locate() in src.loc
if(M && M.buckled == src)
M.buckled = null
src.add_fingerprint(user)
if (M == user)
src.visible_message("\blue [M] cuts \himself free from the conveyor.")
else
src.visible_message("\blue [M] had been cut free from the conveyor by [user].")
return
// otherwise drop and place on conveyor
user.drop_item()
if(I && I.loc) I.loc = src.loc
return
// attack with hand, move pulled object onto conveyor
/obj/machinery/conveyor/attack_hand(mob/user as mob)
if ((!( user.canmove ) || user.restrained() || !( user.pulling )))
return
if (user.pulling.anchored)
return
if ((user.pulling.loc != user.loc && get_dist(user, user.pulling) > 1))
return
if (ismob(user.pulling))
var/mob/M = user.pulling
M.pulling = null
step(user.pulling, get_dir(user.pulling.loc, src))
user.pulling = null
else
step(user.pulling, get_dir(user.pulling.loc, src))
user.pulling = null
return
// make the conveyor broken
// also propagate inoperability to any connected conveyor with the same ID
/obj/machinery/conveyor/proc/broken()
stat |= BROKEN
update()
var/obj/machinery/conveyor/C = locate() in get_step(src, basedir)
if(C)
C.set_operable(basedir, id, 0)
C = locate() in get_step(src, turn(basedir,180))
if(C)
C.set_operable(turn(basedir,180), id, 0)
//set the operable var if ID matches, propagating in the given direction
/obj/machinery/conveyor/proc/set_operable(stepdir, match_id, op)
if(id != match_id)
return
operable = op
update()
var/obj/machinery/conveyor/C = locate() in get_step(src, stepdir)
if(C)
C.set_operable(stepdir, id, op)
/*
/obj/machinery/conveyor/verb/destroy()
set src in view()
src.broken()
*/
/obj/machinery/conveyor/power_change()
..()
update()
// converyor diverter
// extendable arm that can be switched so items on the conveyer are diverted sideways
// situate in same turf as conveyor
// only works if belts is running proper direction
//
//
/obj/machinery/diverter
icon = 'recycling.dmi'
icon_state = "diverter0"
name = "diverter"
desc = "A diverter arm for a conveyor belt."
anchored = 1
layer = FLY_LAYER
var/obj/machinery/conveyor/conv // the conveyor this diverter works on
var/deployed = 0 // true if diverter arm is extended
var/operating = 0 // true if arm is extending/contracting
var/divert_to // the dir that diverted items will be moved
var/divert_from // the dir items must be moving to divert
// create a diverter
// set up divert_to and divert_from directions depending on dir state
/obj/machinery/diverter/New()
..()
switch(dir)
if(NORTH)
divert_to = WEST // stuff will be moved to the west
divert_from = NORTH // if entering from the north
if(SOUTH)
divert_to = EAST
divert_from = NORTH
if(EAST)
divert_to = EAST
divert_from = SOUTH
if(WEST)
divert_to = WEST
divert_from = SOUTH
if(NORTHEAST)
divert_to = NORTH
divert_from = EAST
if(NORTHWEST)
divert_to = NORTH
divert_from = WEST
if(SOUTHEAST)
divert_to = SOUTH
divert_from = EAST
if(SOUTHWEST)
divert_to = SOUTH
divert_from = WEST
spawn(2)
// wait for map load then find the conveyor in this turf
conv = locate() in src.loc
if(conv) // divert_from dir must match possible conveyor movement
if(conv.basedir != divert_from && conv.basedir != turn(divert_from,180) )
del(src) // if no dir match, then delete self
set_divert()
update()
// update the icon state depending on whether the diverter is extended
/obj/machinery/diverter/proc/update()
icon_state = "diverter[deployed]"
// call to set the diversion vars of underlying conveyor
/obj/machinery/diverter/proc/set_divert()
if(conv)
if(deployed)
conv.divert = divert_to
conv.divdir = divert_from
else
conv.divert= 0
// *** TESTING click to toggle
/obj/machinery/diverter/Click()
toggle()
// toggle between arm deployed and not deployed, showing animation
//
/obj/machinery/diverter/proc/toggle()
if( stat & (NOPOWER|BROKEN))
return
if(operating)
return
use_power(50)
operating = 1
if(deployed)
flick("diverter10",src)
icon_state = "diverter0"
sleep(10)
deployed = 0
else
flick("diverter01",src)
icon_state = "diverter1"
sleep(10)
deployed = 1
operating = 0
update()
set_divert()
// don't allow movement into the 'backwards' direction if deployed
/obj/machinery/diverter/CanPass(atom/movable/O, var/turf/target)
var/direct = get_dir(O, target)
if(direct == divert_to) // prevent movement through body of diverter
return 0
if(!deployed)
return 1
return(direct != turn(divert_from,180))
// don't allow movement through the arm if deployed
/obj/machinery/diverter/CheckExit(atom/movable/O, var/turf/target)
var/direct = get_dir(O, target)
if(direct == turn(divert_to,180)) // prevent movement through body of diverter
return 0
if(!deployed)
return 1
return(direct != divert_from)
// the conveyor control switch
//
//
/obj/machinery/conveyor_switch
name = "conveyor switch"
desc = "A conveyor control switch."
icon = 'recycling.dmi'
icon_state = "switch-off"
var/position = 0 // 0 off, -1 reverse, 1 forward
var/last_pos = -1 // last direction setting
var/operated = 1 // true if just operated
var/id = "" // must match conveyor IDs to control them
var/list/conveyors // the list of converyors that are controlled by this switch
anchored = 1
/obj/machinery/conveyor_switch/New()
..()
update()
spawn(5) // allow map load
conveyors = list()
for(var/obj/machinery/conveyor/C in world)
if(C.id == id)
conveyors += C
// update the icon depending on the position
/obj/machinery/conveyor_switch/proc/update()
if(position<0)
icon_state = "switch-rev"
else if(position>0)
icon_state = "switch-fwd"
else
icon_state = "switch-off"
// timed process
// if the switch changed, update the linked conveyors
/obj/machinery/conveyor_switch/process()
if(!operated)
return
operated = 0
for(var/obj/machinery/conveyor/C in conveyors)
C.operating = position
C.setdir()
// attack with hand, switch position
/obj/machinery/conveyor_switch/attack_hand(mob/user)
if(position == 0)
if(last_pos < 0)
position = 1
last_pos = 0
else
position = -1
last_pos = 0
else
last_pos = position
position = 0
operated = 1
update()
// find any switches with same id as this one, and set their positions to match us
for(var/obj/machinery/conveyor_switch/S in world)
if(S.id == src.id)
S.position = position
S.update()
@@ -0,0 +1,162 @@
// Disposal pipe construction
/obj/disposalconstruct
name = "disposal pipe segment"
desc = "A huge pipe segment used for constructing disposal systems."
icon = 'disposal.dmi'
icon_state = "conpipe-s"
anchored = 0
density = 1
pressure_resistance = 5*ONE_ATMOSPHERE
m_amt = 1850
level = 2
var/ptype = 0
// 0=straight, 1=bent, 2=junction-j1, 3=junction-j2, 4=junction-y, 5=trunk
var/dpdir = 0 // directions as disposalpipe
var/base_state = "pipe-s"
// update iconstate and dpdir due to dir and type
proc/update()
var/flip = turn(dir, 180)
var/left = turn(dir, 90)
var/right = turn(dir, -90)
switch(ptype)
if(0)
base_state = "pipe-s"
dpdir = dir | flip
if(1)
base_state = "pipe-c"
dpdir = dir | right
if(2)
base_state = "pipe-j1"
dpdir = dir | right | flip
if(3)
base_state = "pipe-j2"
dpdir = dir | left | flip
if(4)
base_state = "pipe-y"
dpdir = dir | left | right
if(5)
base_state = "pipe-t"
dpdir = dir
icon_state = "con[base_state]"
if(invisibility) // if invisible, fade icon
icon -= rgb(0,0,0,128)
// hide called by levelupdate if turf intact status changes
// change visibility status and force update of icon
hide(var/intact)
invisibility = (intact && level==1) ? 101: 0 // hide if floor is intact
update()
// flip and rotate verbs
verb/rotate()
set src in view(1)
if(usr.stat)
return
if(anchored)
usr << "You must unfasten the pipe before rotating it."
dir = turn(dir, -90)
update()
verb/flip()
set src in view(1)
if(usr.stat)
return
if(anchored)
usr << "You must unfasten the pipe before flipping it."
dir = turn(dir, 180)
if(ptype == 2)
ptype = 3
else if(ptype == 3)
ptype = 2
update()
// returns the type path of disposalpipe corresponding to this item dtype
proc/dpipetype()
switch(ptype)
if(0,1)
return /obj/disposalpipe/segment
if(2,3,4)
return /obj/disposalpipe/junction
if(5)
return /obj/disposalpipe/trunk
return
// attackby item
// wrench: (un)anchor
// weldingtool: convert to real pipe
attackby(var/obj/item/I, var/mob/user)
var/turf/T = src.loc
if(T.intact)
user << "You can only attach the pipe if the floor plating is removed."
return
var/obj/disposalpipe/CP = locate() in T
if(CP)
update()
var/pdir = CP.dpdir
if(istype(CP, /obj/disposalpipe/broken))
pdir = CP.dir
if(pdir & dpdir)
user << "There is already a pipe at that location."
return
if(istype(I, /obj/item/weapon/wrench))
if(anchored)
anchored = 0
level = 2
density = 1
user << "You detach the pipe from the underfloor."
else
anchored = 1
level = 1
density = 0
user << "You attach the pipe to the underfloor."
playsound(src.loc, 'Ratchet.ogg', 100, 1)
else if(istype(I, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/W = I
if(W.welding)
if(W.get_fuel() > 2)
W.use_fuel(2)
playsound(src.loc, 'Welder2.ogg', 100, 1)
// check if anything changed over 2 seconds
var/turf/uloc = user.loc
var/atom/wloc = W.loc
user << "Welding the pipe in place."
sleep(20)
if(user.loc == uloc && wloc == W.loc)
update()
var/pipetype = dpipetype()
var/obj/disposalpipe/P = new pipetype(src.loc)
P.base_icon_state = base_state
P.dir = dir
P.dpdir = dpdir
P.updateicon()
del(src)
else
user << "You must stay still while welding."
return
else
user << "You need more welding fuel to complete this task."
return
+936
View File
@@ -0,0 +1,936 @@
// Disposal bin
// Holds items for disposal into pipe system
// Draws air from turf, gradually charges internal reservoir
// Once full (~1 atm), uses air resv to flush items into the pipes
// Automatically recharges air (unless off), will flush when ready if pre-set
// Can hold items and human size things, no other draggables
/obj/machinery/disposal
name = "disposal unit"
desc = "A pneumatic waste disposal unit."
icon = 'disposal.dmi'
icon_state = "disposal"
anchored = 1
density = 1
var/datum/gas_mixture/air_contents // internal reservoir
var/mode = 1 // item mode 0=off 1=charging 2=charged
var/flush = 0 // true if flush handle is pulled
var/obj/disposalpipe/trunk/trunk = null // the attached pipe trunk
var/flushing = 0 // true if flushing in progress
// create a new disposal
// find the attached trunk (if present) and init gas resvr.
New()
..()
spawn(5)
trunk = locate() in src.loc
if(!trunk)
mode = 0
flush = 0
else
trunk.linked = src // link the pipe trunk to self
air_contents = new/datum/gas_mixture()
//gas.volume = 1.05 * CELLSTANDARD
update()
// attack by item places it in to disposal
attackby(var/obj/item/I, var/mob/user)
if(stat & BROKEN)
return
var/obj/item/weapon/grab/G = I
if(istype(G)) // handle grabbed mob
if(ismob(G.affecting))
var/mob/GM = G.affecting
if (GM.client)
GM.client.perspective = EYE_PERSPECTIVE
GM.client.eye = src
GM.loc = src
for (var/mob/C in viewers(src))
C.show_message("\red [GM.name] has been placed in the [src] by [user].", 3)
del(G)
else
user.drop_item()
I.loc = src
user << "You place \the [I] into the [src]."
for(var/mob/M in viewers(src))
if(M == user)
continue
M.show_message("[user.name] places \the [I] into the [src].", 3)
update()
// mouse drop another mob or self
//
MouseDrop_T(mob/target, mob/user)
if (!istype(target) || target.buckled || get_dist(user, src) > 1 || get_dist(user, target) > 1 || user.stat || istype(user, /mob/living/silicon/ai))
return
var/msg
if(target == user && !user.stat) // if drop self, then climbed in
// must be awake
msg = "[user.name] climbs into the [src]."
user << "You climb into the [src]."
else if(target != user && !user.restrained())
msg = "[user.name] stuffs [target.name] into the [src]!"
user << "You stuff [target.name] into the [src]!"
else
return
if (target.client)
target.client.perspective = EYE_PERSPECTIVE
target.client.eye = src
target.loc = src
for (var/mob/C in viewers(src))
if(C == user)
continue
C.show_message(msg, 3)
update()
return
// can breath normally in the disposal
alter_health()
return get_turf(src)
// attempt to move while inside
relaymove(mob/user as mob)
if(user.stat || src.flushing)
return
src.go_out(user)
return
// leave the disposal
proc/go_out(mob/user)
if (user.client)
user.client.eye = user.client.mob
user.client.perspective = MOB_PERSPECTIVE
user.loc = src.loc
update()
return
// monkeys can only pull the flush lever
attack_paw(mob/user as mob)
if(stat & BROKEN)
return
flush = !flush
update()
return
// ai as human but can't flush
attack_ai(mob/user as mob)
interact(user, 1)
// human interact with machine
attack_hand(mob/user as mob)
interact(user, 0)
// user interaction
proc/interact(mob/user, var/ai=0)
src.add_fingerprint(user)
if(stat & BROKEN)
user.machine = null
return
var/dat = "<head><title>Waste Disposal Unit</title></head><body><TT><B>Waste Disposal Unit</B><HR>"
if(!ai) // AI can't pull flush handle
if(flush)
dat += "Disposal handle: <A href='?src=\ref[src];handle=0'>Disengage</A> <B>Engaged</B>"
else
dat += "Disposal handle: <B>Disengaged</B> <A href='?src=\ref[src];handle=1'>Engage</A>"
dat += "<BR><HR><A href='?src=\ref[src];eject=1'>Eject contents</A><HR>"
if(mode == 0)
dat += "Pump: <B>Off</B> <A href='?src=\ref[src];pump=1'>On</A><BR>"
else if(mode == 1)
dat += "Pump: <A href='?src=\ref[src];pump=0'>Off</A> <B>On</B> (pressurizing)<BR>"
else
dat += "Pump: <A href='?src=\ref[src];pump=0'>Off</A> <B>On</B> (idle)<BR>"
var/per = 100* air_contents.return_pressure() / (2*ONE_ATMOSPHERE)
dat += "Pressure: [round(per, 1)]%<BR></body>"
user.machine = src
user << browse(dat, "window=disposal;size=360x170")
onclose(user, "disposal")
// handle machine interaction
Topic(href, href_list)
..()
src.add_fingerprint(usr)
if(stat & BROKEN)
return
if(usr.stat || usr.restrained() || src.flushing)
return
if (in_range(src, usr) && istype(src.loc, /turf))
usr.machine = src
if(href_list["close"])
usr.machine = null
usr << browse(null, "window=disposal")
return
if(href_list["pump"])
if(text2num(href_list["pump"]))
mode = 1
else
mode = 0
update()
if(href_list["handle"])
flush = text2num(href_list["handle"])
update()
if(href_list["eject"])
eject()
else
usr << browse(null, "window=disposal")
usr.machine = null
return
return
// eject the contents of the disposal unit
proc/eject()
for(var/atom/movable/AM in src)
AM.loc = src.loc
AM.pipe_eject(0)
update()
// update the icon & overlays to reflect mode & status
proc/update()
overlays = null
if(stat & BROKEN)
icon_state = "disposal-broken"
mode = 0
flush = 0
return
// flush handle
if(flush)
overlays += image('disposal.dmi', "dispover-handle")
// only handle is shown if no power
if(stat & NOPOWER)
return
// check for items in disposal - occupied light
if(contents.len > 0)
overlays += image('disposal.dmi', "dispover-full")
// charging and ready light
if(mode == 1)
overlays += image('disposal.dmi', "dispover-charge")
else if(mode == 2)
overlays += image('disposal.dmi', "dispover-ready")
// timed process
// charge the gas reservoir and perform flush if ready
process()
if(stat & BROKEN) // nothing can happen if broken
return
src.updateDialog()
if(flush && air_contents.return_pressure() >= 2*ONE_ATMOSPHERE) // flush can happen even without power
flush()
if(stat & NOPOWER) // won't charge if no power
return
use_power(100) // base power usage
if(mode != 1) // if off or ready, no need to charge
return
// otherwise charge
use_power(500) // charging power usage
var/atom/L = loc // recharging from loc turf
var/datum/gas_mixture/env = L.return_air()
var/pressure_delta = (ONE_ATMOSPHERE*2.1) - air_contents.return_pressure()
if(env.temperature > 0)
var/transfer_moles = 0.1 * pressure_delta*air_contents.volume/(env.temperature * R_IDEAL_GAS_EQUATION)
//Actually transfer the gas
var/datum/gas_mixture/removed = env.remove(transfer_moles)
air_contents.merge(removed)
// if full enough, switch to ready mode
if(air_contents.return_pressure() >= 2*ONE_ATMOSPHERE)
mode = 2
update()
return
// perform a flush
proc/flush()
flushing = 1
flick("disposal-flush", src)
var/obj/disposalholder/H = new() // virtual holder object which actually
// travels through the pipes.
H.init(src) // copy the contents of disposer to holder
air_contents = new() // new empty gas resv.
sleep(10)
playsound(src, 'disposalflush.ogg', 50, 0, 0)
sleep(5) // wait for animation to finish
H.start(src) // start the holder processing movement
flushing = 0
// now reset disposal state
flush = 0
if(mode == 2) // if was ready,
mode = 1 // switch to charging
update()
return
// called when area power changes
power_change()
..() // do default setting/reset of stat NOPOWER bit
update() // update icon
return
// called when holder is expelled from a disposal
// should usually only occur if the pipe network is modified
proc/expel(var/obj/disposalholder/H)
var/turf/target
playsound(src, 'hiss.ogg', 50, 0, 0)
for(var/atom/movable/AM in H)
target = get_offset_target_turf(src.loc, rand(5)-rand(5), rand(5)-rand(5))
AM.loc = src.loc
AM.pipe_eject(0)
spawn(1)
if(AM)
AM.throw_at(target, 5, 1)
H.vent_gas(loc)
del(H)
// virtual disposal object
// travels through pipes in lieu of actual items
// contents will be items flushed by the disposal
// this allows the gas flushed to be tracked
/obj/disposalholder
invisibility = 101
var/datum/gas_mixture/gas = null // gas used to flush, will appear at exit point
var/active = 0 // true if the holder is moving, otherwise inactive
dir = 0
var/count = 1000 //*** can travel 1000 steps before going inactive (in case of loops)
var/has_fat_guy = 0 // true if contains a fat person
// initialize a holder from the contents of a disposal unit
proc/init(var/obj/machinery/disposal/D)
gas = D.air_contents // transfer gas resv. into holder object
// now everything inside the disposal gets put into the holder
// note AM since can contain mobs or objs
for(var/atom/movable/AM in D)
AM.loc = src
if(istype(AM, /mob/living/carbon/human))
var/mob/living/carbon/human/H = AM
if(H.mutations & 32) // is a human and fat?
has_fat_guy = 1 // set flag on holder
// start the movement process
// argument is the disposal unit the holder started in
proc/start(var/obj/machinery/disposal/D)
if(!D.trunk)
D.expel(src) // no trunk connected, so expel immediately
return
loc = D.trunk
active = 1
dir = DOWN
spawn(1)
process() // spawn off the movement process
return
// movement process, persists while holder is moving through pipes
proc/process()
var/obj/disposalpipe/last
while(active)
if(has_fat_guy && prob(2)) // chance of becoming stuck per segment if contains a fat guy
active = 0
// find the fat guys
for(var/mob/living/carbon/human/H in src)
break
sleep(1) // was 1
var/obj/disposalpipe/curr = loc
last = curr
curr = curr.transfer(src)
if(!curr)
last.expel(src, loc, dir)
//
if(!(count--))
active = 0
return
// find the turf which should contain the next pipe
proc/nextloc()
return get_step(loc,dir)
// find a matching pipe on a turf
proc/findpipe(var/turf/T)
if(!T)
return null
var/fdir = turn(dir, 180) // flip the movement direction
for(var/obj/disposalpipe/P in T)
if(fdir & P.dpdir) // find pipe direction mask that matches flipped dir
return P
// if no matching pipe, return null
return null
// merge two holder objects
// used when a a holder meets a stuck holder
proc/merge(var/obj/disposalholder/other)
for(var/atom/movable/AM in other)
AM.loc = src // move everything in other holder to this one
if(ismob(AM))
var/mob/M = AM
if(M.client) // if a client mob, update eye to follow this holder
M.client.eye = src
if(other.has_fat_guy)
has_fat_guy = 1
del(other)
// called when player tries to move while in a pipe
relaymove(mob/user as mob)
if (user.stat)
return
for (var/mob/M in hearers(src.loc.loc))
M << "<FONT size=[max(0, 5 - get_dist(src, M))]>CLONG, clong!</FONT>"
playsound(src.loc, 'clang.ogg', 50, 0, 0)
// called to vent all gas in holder to a location
proc/vent_gas(var/atom/location)
location.assume_air(gas) // vent all gas to turf
return
// Disposal pipes
/obj/disposalpipe
icon = 'disposal.dmi'
name = "disposal pipe"
desc = "An underfloor disposal pipe."
anchored = 1
density = 0
level = 1 // underfloor only
var/dpdir = 0 // bitmask of pipe directions
dir = 0 // dir will contain dominant direction for junction pipes
var/health = 10 // health points 0-10
layer = 2.4 // slightly lower than wires
var/base_icon_state // initial icon state on map
// new pipe, set the icon_state as on map
New()
..()
base_icon_state = icon_state
return
// pipe is deleted
// ensure if holder is present, it is expelled
Del()
var/obj/disposalholder/H = locate() in src
if(H)
// holder was present
H.active = 0
var/turf/T = src.loc
if(T.density)
// deleting pipe is inside a dense turf (wall)
// this is unlikely, but just dump out everything into the turf in case
for(var/atom/movable/AM in H)
AM.loc = T
AM.pipe_eject(0)
del(H)
..()
return
// otherswise, do normal expel from turf
expel(H, T, 0)
..()
// returns the direction of the next pipe object, given the entrance dir
// by default, returns the bitmask of remaining directions
proc/nextdir(var/fromdir)
return dpdir & (~turn(fromdir, 180))
// transfer the holder through this pipe segment
// overriden for special behaviour
//
proc/transfer(var/obj/disposalholder/H)
var/nextdir = nextdir(H.dir)
H.dir = nextdir
var/turf/T = H.nextloc()
var/obj/disposalpipe/P = H.findpipe(T)
if(P)
// find other holder in next loc, if inactive merge it with current
var/obj/disposalholder/H2 = locate() in P
if(H2 && !H2.active)
H.merge(H2)
H.loc = P
else // if wasn't a pipe, then set loc to turf
H.loc = T
return null
return P
// update the icon_state to reflect hidden status
proc/update()
var/turf/T = src.loc
hide(T.intact && !istype(T,/turf/space)) // space never hides pipes
// hide called by levelupdate if turf intact status changes
// change visibility status and force update of icon
hide(var/intact)
invisibility = intact ? 101: 0 // hide if floor is intact
updateicon()
// update actual icon_state depending on visibility
// if invisible, append "f" to icon_state to show faded version
// this will be revealed if a T-scanner is used
// if visible, use regular icon_state
proc/updateicon()
if(invisibility)
icon_state = "[base_icon_state]f"
else
icon_state = base_icon_state
return
// expel the held objects into a turf
// called when there is a break in the pipe
//
proc/expel(var/obj/disposalholder/H, var/turf/T, var/direction)
var/turf/target
if(T.density) // dense ouput turf, so stop holder
H.active = 0
H.loc = src
return
if(T.intact && istype(T,/turf/simulated/floor)) //intact floor, pop the tile
var/turf/simulated/floor/F = T
//F.health = 100
F.burnt = 1
F.intact = 0
F.levelupdate()
new /obj/item/weapon/tile(H) // add to holder so it will be thrown with other stuff
F.icon_state = "Floor[F.burnt ? "1" : ""]"
if(direction) // direction is specified
if(istype(T, /turf/space)) // if ended in space, then range is unlimited
target = get_edge_target_turf(T, direction)
else // otherwise limit to 10 tiles
target = get_ranged_target_turf(T, direction, 10)
playsound(src, 'hiss.ogg', 50, 0, 0)
for(var/atom/movable/AM in H)
AM.loc = T
AM.pipe_eject(direction)
spawn(1)
if(AM)
AM.throw_at(target, 100, 1)
H.vent_gas(T)
del(H)
else // no specified direction, so throw in random direction
playsound(src, 'hiss.ogg', 50, 0, 0)
for(var/atom/movable/AM in H)
target = get_offset_target_turf(T, rand(5)-rand(5), rand(5)-rand(5))
AM.loc = T
AM.pipe_eject(0)
spawn(1)
if(AM)
AM.throw_at(target, 5, 1)
H.vent_gas(T) // all gas vent to turf
del(H)
return
// call to break the pipe
// will expel any holder inside at the time
// then delete the pipe
// remains : set to leave broken pipe pieces in place
proc/broken(var/remains = 0)
if(remains)
for(var/D in cardinal)
if(D & dpdir)
var/obj/disposalpipe/broken/P = new(src.loc)
P.dir = D
src.invisibility = 101 // make invisible (since we won't delete the pipe immediately)
var/obj/disposalholder/H = locate() in src
if(H)
// holder was present
H.active = 0
var/turf/T = src.loc
if(T.density)
// broken pipe is inside a dense turf (wall)
// this is unlikely, but just dump out everything into the turf in case
for(var/atom/movable/AM in H)
AM.loc = T
AM.pipe_eject(0)
del(H)
return
// otherswise, do normal expel from turf
expel(H, T, 0)
spawn(2) // delete pipe after 2 ticks to ensure expel proc finished
del(src)
// pipe affected by explosion
ex_act(severity)
switch(severity)
if(1.0)
broken(0)
return
if(2.0)
health -= rand(5,15)
healthcheck()
return
if(3.0)
health -= rand(0,15)
healthcheck()
return
// test health for brokenness
proc/healthcheck()
if(health < -2)
broken(0)
else if(health<1)
broken(1)
return
//attack by item
//weldingtool: unfasten and convert to obj/disposalconstruct
attackby(var/obj/item/I, var/mob/user)
var/turf/T = src.loc
if(T.intact)
return // prevent interaction with T-scanner revealed pipes
if(istype(I, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/W = I
if(W.welding)
if(W.get_fuel() > 3)
W.use_fuel(3)
playsound(src.loc, 'Welder2.ogg', 100, 1)
// check if anything changed over 2 seconds
var/turf/uloc = user.loc
var/atom/wloc = W.loc
user << "Slicing the disposal pipe."
sleep(30)
if(user.loc == uloc && wloc == W.loc)
welded()
else
user << "You must stay still while welding the pipe."
return
else
user << "You need more welding fuel to cut the pipe."
return
// called when pipe is cut with welder
proc/welded()
var/obj/disposalconstruct/C = new (src.loc)
switch(base_icon_state)
if("pipe-s")
C.ptype = 0
if("pipe-c")
C.ptype = 1
if("pipe-j1")
C.ptype = 2
if("pipe-j2")
C.ptype = 3
if("pipe-y")
C.ptype = 4
if("pipe-t")
C.ptype = 5
C.dir = dir
C.update()
del(src)
// *** TEST verb
//client/verb/dispstop()
// for(var/obj/disposalholder/H in world)
// H.active = 0
// a straight or bent segment
/obj/disposalpipe/segment
icon_state = "pipe-s"
New()
..()
if(icon_state == "pipe-s")
dpdir = dir | turn(dir, 180)
else
dpdir = dir | turn(dir, -90)
update()
return
//a three-way junction with dir being the dominant direction
/obj/disposalpipe/junction
icon_state = "pipe-j1"
New()
..()
if(icon_state == "pipe-j1")
dpdir = dir | turn(dir, -90) | turn(dir,180)
else if(icon_state == "pipe-j2")
dpdir = dir | turn(dir, 90) | turn(dir,180)
else // pipe-y
dpdir = dir | turn(dir,90) | turn(dir, -90)
update()
return
// next direction to move
// if coming in from secondary dirs, then next is primary dir
// if coming in from primary dir, then next is equal chance of other dirs
nextdir(var/fromdir)
var/flipdir = turn(fromdir, 180)
if(flipdir != dir) // came from secondary dir
return dir // so exit through primary
else // came from primary
// so need to choose either secondary exit
var/mask = ..(fromdir)
// find a bit which is set
var/setbit = 0
if(mask & NORTH)
setbit = NORTH
else if(mask & SOUTH)
setbit = SOUTH
else if(mask & EAST)
setbit = EAST
else
setbit = WEST
if(prob(50)) // 50% chance to choose the found bit or the other one
return setbit
else
return mask & (~setbit)
//a trunk joining to a disposal bin or outlet on the same turf
/obj/disposalpipe/trunk
icon_state = "pipe-t"
var/obj/linked // the linked obj/machinery/disposal or obj/disposaloutlet
New()
..()
dpdir = dir
spawn(1)
getlinked()
update()
return
proc/getlinked()
linked = null
var/obj/machinery/disposal/D = locate() in src.loc
if(D)
linked = D
var/obj/disposaloutlet/O = locate() in src.loc
if(O)
linked = O
update()
return
// would transfer to next pipe segment, but we are in a trunk
// if not entering from disposal bin,
// transfer to linked object (outlet or bin)
transfer(var/obj/disposalholder/H)
if(H.dir == DOWN) // we just entered from a disposer
return ..() // so do base transfer proc
// otherwise, go to the linked object
if(linked)
var/obj/disposaloutlet/O = linked
if(istype(O))
O.expel(H) // expel at outlet
else
var/obj/machinery/disposal/D = linked
D.expel(H) // expel at disposal
else
src.expel(H, src.loc, 0) // expel at turf
return null
// nextdir
nextdir(var/fromdir)
if(fromdir == DOWN)
return dir
else
return 0
// a broken pipe
/obj/disposalpipe/broken
icon_state = "pipe-b"
dpdir = 0 // broken pipes have dpdir=0 so they're not found as 'real' pipes
// i.e. will be treated as an empty turf
desc = "A broken piece of disposal pipe."
New()
..()
update()
return
// called when welded
// for broken pipe, remove and turn into scrap
welded()
var/obj/item/scrap/S = new(src.loc)
S.set_components(200,0,0)
del(src)
// the disposal outlet machine
/obj/disposaloutlet
name = "disposal outlet"
desc = "An outlet for the pneumatic disposal system."
icon = 'disposal.dmi'
icon_state = "outlet"
density = 1
anchored = 1
var/active = 0
var/turf/target // this will be where the output objects are 'thrown' to.
New()
..()
spawn(1)
target = get_ranged_target_turf(src, dir, 10)
// expel the contents of the holder object, then delete it
// called when the holder exits the outlet
proc/expel(var/obj/disposalholder/H)
flick("outlet-open", src)
playsound(src, 'warning-buzzer.ogg', 50, 0, 0)
sleep(20) //wait until correct animation frame
playsound(src, 'hiss.ogg', 50, 0, 0)
for(var/atom/movable/AM in H)
AM.loc = src.loc
AM.pipe_eject(dir)
spawn(1)
AM.throw_at(target, 3, 1)
H.vent_gas(src.loc)
del(H)
return
// called when movable is expelled from a disposal pipe or outlet
// by default does nothing, override for special behaviour
/atom/movable/proc/pipe_eject(var/direction)
return
// check if mob has client, if so restore client view on eject
/mob/pipe_eject(var/direction)
if (src.client)
src.client.perspective = MOB_PERSPECTIVE
src.client.eye = src
return
/obj/decal/cleanable/blood/gibs/pipe_eject(var/direction)
var/list/dirs
if(direction)
dirs = list( direction, turn(direction, -45), turn(direction, 45))
else
dirs = alldirs.Copy()
src.streak(dirs)
/obj/decal/cleanable/robot_debris/gib/pipe_eject(var/direction)
var/list/dirs
if(direction)
dirs = list( direction, turn(direction, -45), turn(direction, 45))
else
dirs = alldirs.Copy()
src.streak(dirs)
+288
View File
@@ -0,0 +1,288 @@
// The scrap item
// a single object type represents all combinations of size and composition of scrap
//
/obj/item/scrap
name = "scrap"
icon = 'scrap.dmi'
icon_state = "1metal0"
item_state = "scrap-metal"
desc = "A piece of scrap"
var/classtext = ""
throwforce = 14.0
m_amt = 0
g_amt = 0
w_amt = 0
var/size = 1 // 1=piece, 2= few pieces, 3=small pile, 4=large pile
var/blood = 0 // 0=none, 1=blood-stained, 2=bloody
throwforce = 8.0
throw_speed = 1
throw_range = 4
w_class = 1
flags = FPRINT | TABLEPASS | CONDUCT
#define MAX_SCRAP 15000 // maximum content amount of a scrap pile
/obj/item/scrap/New()
src.verbs -= /atom/movable/verb/pull
..()
update()
// return a copy
/obj/item/scrap/proc/copy()
var/obj/item/scrap/ret = new()
ret.set_components(m_amt, g_amt, w_amt)
return ret
// set the metal, glass and waste content
/obj/item/scrap/proc/set_components(var/m, var/g, var/w)
m_amt = m
g_amt = g
w_amt = w
update()
// returns the total amount of scrap in this pile
/obj/item/scrap/proc/total()
return m_amt + g_amt + w_amt
// sets the size, appearance, and description of the scrap depending on component amounts
/obj/item/scrap/proc/update()
var/total = total()
// determine size of pile
if(total<=400)
size = 1
else if(total<=1600)
size = 2
else
size = 3
w_class = size
var/sizetext = ""
switch(size)
if(1)
sizetext = "A piece of"
if(2)
sizetext = "A few pieces of"
if(3)
sizetext = "A pile of"
// determine bloodiness
var/bloodtext = ""
switch(blood)
if(0)
bloodtext = ""
if(1)
bloodtext = "blood-stained "
if(2)
bloodtext = "bloody "
// find mixture and composition
var/class = 0 // 0 = mixed, 1=mostly. 2=pure
var/major = "waste" // the major component type
var/max = 0
if(m_amt > max)
max = m_amt
else if(g_amt > max)
max = g_amt
else if(w_amt > max)
max = w_amt
if(max == total)
class = 2 // pure
else if(max/total > 0.6)
class = 1 // mostly
else
class = 0 // mixed
if(class>0)
var/remain = total - max
if(m_amt > remain)
major = "metal"
else if(g_amt > remain)
major = "glass"
else
major = "waste"
if(class == 1)
desc = "[sizetext] mostly [major] [bloodtext]scrap."
classtext = "mostly [major] [bloodtext]"
else
desc = "[sizetext] [bloodtext][major] scrap."
classtext = "[bloodtext][major] "
icon_state = "[size][major][blood]"
else
desc = "[sizetext] [bloodtext]mixed scrap."
classtext = "[bloodtext]mixed"
icon_state = "[size]mixed[blood]"
if(size==0)
pixel_x = rand(-5,5)
pixel_y = rand(-5,5)
else
pixel_x = 0
pixel_y = 0
// clear or set conduction flag depending on whether scrap is mostly metal
if(major=="metal")
flags |= CONDUCT
else
flags &= ~CONDUCT
item_state = "scrap-[major]"
// add a scrap item to this one
// if the resulting pile is too big, transfer only what will fit
// otherwise add them and deleted the added pile
/obj/item/scrap/proc/add_scrap(var/obj/item/scrap/other, var/limit = MAX_SCRAP)
var/total = total()
var/other_total = other.total()
if( (total + other_total) <= limit )
m_amt += other.m_amt
g_amt += other.g_amt
w_amt += other.w_amt
blood = (total*blood + other_total*other.blood) / (total + other_total)
del(other)
else
var/space = limit - total
var/m = round(other.m_amt/other_total*space, 1)
var/g = round(other.g_amt/other_total*space, 1)
var/w = round(other.w_amt/other_total*space, 1)
m_amt += m
g_amt += g
w_amt += w
other.m_amt -= m
other.g_amt -= g
other.w_amt -= w
var/other_trans = m + g + w
other.update()
blood = (total*blood + other_trans*other.blood) / (total + other_trans)
blood = round(blood,1)
src.update()
// limit this pile to maximum size
// return any remainder as a new scrap item (or null if none)
// note return item is not necessarily smaller than max size
/obj/item/scrap/proc/remainder(var/limit = MAX_SCRAP)
var/total = total()
if(total > limit)
var/m = round( m_amt/total * limit, 1)
var/g = round( g_amt/total * limit, 1)
var/w = round( w_amt/total * limit, 1)
var/obj/item/scrap/S = new()
S.set_components(m_amt - m,g_amt - g,w_amt - w)
src.set_components(m,g,w)
return S
return null
// if other pile of scrap tries to enter the same turf, then add that pile to this one
/obj/item/scrap/CanPass(var/obj/item/scrap/O)
if(istype(O))
src.add_scrap(O)
if(O)
return 0 // O still exists if not all could be transfered, so block it
return 1
/obj/item/scrap/proc/to_text()
return "[m_amt],[g_amt],[w_amt] ([total()])"
// attack with hand removes a single piece from a pile
/obj/item/scrap/attack_hand(mob/user)
add_fingerprint(user)
if(src.is_single_piece())
return ..(user)
var/obj/item/scrap/S = src.get_single_piece()
S.attack_hand(user)
return
/obj/item/scrap/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/scrap))
var/obj/item/scrap/S = I
if( (S.total()+src.total() ) > MAX_SCRAP )
user << "The pile is full."
return
if(ismob(src.loc)) // can't combine scrap in hand
return
src.add_scrap(S)
// when dropped, try to make a pile if scrap is already there
/obj/item/scrap/dropped()
spawn(2) // delay to allow drop postprocessing (since src may be destroyed)
for(var/obj/item/scrap/S in oview(0,src)) // excludes src itself
S.add_scrap(src)
// return true if this is a single piece of scrap
// must be total<=400 and of single composition
/obj/item/scrap/proc/is_single_piece()
if(total() > 400)
return 0
var/empty = (m_amt == 0) + (g_amt == 0) + (w_amt == 0)
return (empty==2) // must be 2 components with zero amount
// get a single piece of scrap from a pile
/obj/item/scrap/proc/get_single_piece()
var/obj/item/scrap/S = new()
var/cmp = pick(m_amt;1 , g_amt;2, w_amt;3)
var/amount = 400
switch(cmp)
if(1)
if(m_amt < amount)
amount = m_amt
S.set_components(amount, 0, 0)
src.set_components(m_amt - amount, g_amt, w_amt)
if(2)
if(g_amt < amount)
amount = g_amt
S.set_components(0, amount, 0)
src.set_components(m_amt, g_amt - amount, w_amt)
if(3)
if(w_amt < amount)
amount = w_amt
S.set_components(0, 0, amount)
src.set_components(m_amt, g_amt, w_amt - amount)
return S