Files
CHOMPstation/code/WorkInProgress/Chemistry-Holder.dm
T
rastaf.zero@gmail.com 3008281e3c Gamemodes bugfix:
- heads, security officers, wardens and detectives cannot be cultists or revs again.
- chaplain cannot be cultist.
- players with unfilled preferences wouldn't huddle together in same departments.
- fixed bug in get_players_for_role caused to players jobbanned from syndicate get special roles.
Fixed major bug with reagents not adding when same reagent is already present in container.


git-svn-id: http://tgstation13.googlecode.com/svn/trunk@1802 316c924e-a436-60f5-8080-3fe189b3f50e
2011-07-08 16:35:36 +00:00

360 lines
11 KiB
Plaintext

#define TOUCH 1
#define INGEST 2
///////////////////////////////////////////////////////////////////////////////////
datum
reagents
var/list/datum/reagent/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
get_master_reagent_id()
var/the_id = null
var/the_volume = 0
for(var/datum/reagent/A in reagent_list)
if(A.volume > the_volume)
the_volume = A.volume
the_id = A.id
return the_id
trans_to(var/obj/target, var/amount=1, var/multiplier=1, var/preserve_data=1)//if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred.
if (!target )
return
if (!target.reagents || src.total_volume<=0)
return
var/datum/reagents/R = target.reagents
amount = min(min(amount, src.total_volume), R.maximum_volume-R.total_volume)
var/part = amount / src.total_volume
var/trans_data = null
for (var/datum/reagent/current_reagent in src.reagent_list)
var/current_reagent_transfer = current_reagent.volume * part
if(preserve_data)
trans_data = current_reagent.data
R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data)
src.remove_reagent(current_reagent.id, current_reagent_transfer)
src.update_total()
R.update_total()
R.handle_reactions()
src.handle_reactions()
return amount
trans_id_to(var/obj/target, var/reagent, var/amount=1, var/preserve_data=1)//Not sure why this proc didn't exist before. It does now! /N
if (!target)
return
if (!target.reagents || src.total_volume<=0 || !src.get_reagent_amount(reagent))
return
var/datum/reagents/R = target.reagents
if(src.get_reagent_amount(reagent)<amount)
amount = src.get_reagent_amount(reagent)
amount = min(amount, R.maximum_volume-R.total_volume)
var/trans_data = null
for (var/datum/reagent/current_reagent in src.reagent_list)
if(current_reagent.id == reagent)
if(preserve_data)
trans_data = current_reagent.data
R.add_reagent(current_reagent.id, amount, trans_data)
src.remove_reagent(current_reagent.id, amount, 1)
break
src.update_total()
R.update_total()
R.handle_reactions()
//src.handle_reactions() Don't need to handle reactions on the source since you're (presumably isolating and) transferring a specific reagent.
return amount
/*
if (!target) return
var/total_transfered = 0
var/current_list_element = 1
var/datum/reagents/R = target.reagents
var/trans_data = null
//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]
if(preserve_data)
trans_data = current_reagent.data
R.add_reagent(current_reagent.id, (1 * multiplier), trans_data)
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
if(M)
R.on_mob_life(M)
update_total()
conditional_update_move(var/atom/A, var/Running = 0)
for(var/datum/reagent/R in reagent_list)
R.on_move (A, Running)
update_total()
conditional_update(var/atom/A, )
for(var/datum/reagent/R in reagent_list)
R.on_update (A)
update_total()
handle_reactions()
if(my_atom.flags & NOREACT) return //Yup, no reactions here. No siree.
var/reaction_occured = 0
do
reaction_occured = 0
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/total_required_catalysts = C.required_catalysts.len
var/total_matching_catalysts= 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])
for(var/B in C.required_catalysts)
if(has_reagent(B, C.required_catalysts[B]))
total_matching_catalysts++
if(total_matching_reagents == total_required_reagents && total_matching_catalysts == total_required_catalysts)
var/multiplier = min(multipliers)
for(var/B in C.required_reagents)
remove_reagent(B, (multiplier * C.required_reagents[B]), safety = 1)
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)
reaction_occured = 1
while(reaction_occured)
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 < 0.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)
if(!R) return
else R.reaction_mob(A, TOUCH, R.volume+volume_modifier)
if(isturf(A))
spawn(0)
if(!R) return
else R.reaction_turf(A, R.volume+volume_modifier)
if(isobj(A))
spawn(0)
if(!R) return
else R.reaction_obj(A, R.volume+volume_modifier)
if(INGEST)
for(var/datum/reagent/R in reagent_list)
if(ismob(A) && R)
spawn(0)
if(!R) return
else R.reaction_mob(A, INGEST, R.volume+volume_modifier)
if(isturf(A) && R)
spawn(0)
if(!R) return
else R.reaction_turf(A, R.volume+volume_modifier)
if(isobj(A) && R)
spawn(0)
if(!R) return
else R.reaction_obj(A, R.volume+volume_modifier)
return
add_reagent(var/reagent, var/amount, var/data=null)
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()
// mix dem viruses
if(R.data && R.data["viruses"] || data &&data["viruses"])
var/list/this = R.data["viruses"]
var/list/that = data["viruses"]
this += that // combine the two
for(var/datum/disease/D in this) // makes sure no two viruses are in the reagent at the same time
for(var/datum/disease/d in this)
d.cure(0)
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
R.data = data
//debug
//world << "Adding data"
//for(var/D in R.data)
// world << "Container data: [D] = [R.data[D]]"
//debug
update_total()
my_atom.on_reagent_change()
return 0
return 1
remove_reagent(var/reagent, var/amount, var/safety)//Added a safety check for the trans_id_to
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()
if(!safety)//So it does not handle reactions when it need not to
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 R
else
if(R.volume >= amount) return R
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
get_reagents()
var/res = ""
for(var/datum/reagent/A in reagent_list)
if (res != "") res += ","
res += A.name
return res
///////////////////////////////////////////////////////////////////////////////////
// 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