Chemistry commit

I messed something in the git
This commit is contained in:
Kelenius
2015-03-25 19:09:10 +03:00
parent d518df1076
commit b4b635f32d
88 changed files with 7327 additions and 8992 deletions
@@ -5,13 +5,11 @@
icon = 'icons/effects/chemsmoke.dmi'
opacity = 0
time_to_live = 300
pass_flags = PASSTABLE | PASSGRILLE | PASSGLASS //PASSGLASS is fine here, it's just so the visual effect can "flow" around glass
pass_flags = PASSTABLE | PASSGRILLE | PASSGLASS //PASSGLASS is fine here, it's just so the visual effect can "flow" around glass
/obj/effect/effect/smoke/chem/New()
..()
var/datum/reagents/R = new/datum/reagents(500)
reagents = R
R.my_atom = src
create_reagents(500)
return
/datum/effect/effect/system/smoke_spread/chem
@@ -37,21 +35,16 @@
/datum/effect/effect/system/smoke_spread/chem/New()
..()
chemholder = new/obj()
var/datum/reagents/R = new/datum/reagents(500)
chemholder.reagents = R
R.my_atom = chemholder
chemholder.create_reagents(500)
//------------------------------------------
//Sets up the chem smoke effect
//
// Calculates the max range smoke can travel, then gets all turfs in that view range.
// Culls the selected turfs to a (roughly) circle shape, then calls smokeFlow() to make
// sure the smoke can actually path to the turfs. This culls any turfs it can't reach.
//------------------------------------------
/datum/effect/effect/system/smoke_spread/chem/set_up(var/datum/reagents/carry = null, n = 10, c = 0, loca, direct)
range = n * 0.3
cardinals = c
carry.copy_to(chemholder, carry.total_volume)
carry.trans_to_obj(chemholder, carry.total_volume, copy = 1)
if(istype(loca, /turf/))
location = loca
@@ -62,28 +55,19 @@
targetTurfs = new()
//build affected area list
for(var/turf/T in view(range, location))
//cull turfs to circle
if(cheap_pythag(T.x - location.x, T.y - location.y) <= range)
for(var/turf/T in view(range, location)) //build affected area list
if(cheap_pythag(T.x - location.x, T.y - location.y) <= range) //cull turfs to circle
targetTurfs += T
//make secondary list for reagents that affect walls
if(chemholder.reagents.has_reagent("thermite") || chemholder.reagents.has_reagent("plantbgone"))
wallList = new()
wallList = new()
//pathing check
smokeFlow(location, targetTurfs, wallList)
smokeFlow() //pathing check
//set the density of the cloud - for diluting reagents
density = max(1, targetTurfs.len / 4) //clamp the cloud density minimum to 1 so it cant multiply the reagents
density = max(1, targetTurfs.len / 4) //clamp the cloud density minimum to 1 so it cant multiply the reagents
//Admin messaging
var/contained = ""
for(var/reagent in carry.reagent_list)
contained += " [reagent] "
if(contained)
contained = "\[[contained]\]"
var/contained = carry.get_reagents()
var/area/A = get_area(location)
var/where = "[A.name] | [location.x], [location.y]"
@@ -101,61 +85,27 @@
message_admins("A chemical smoke reaction has taken place in ([whereLink]). No associated key.", 0, 1)
log_game("A chemical smoke reaction has taken place in ([where])[contained]. No associated key.")
//------------------------------------------
//Runs the chem smoke effect
//
// Spawns damage over time loop for each reagent held in the cloud.
// Applies reagents to walls that affect walls (only thermite and plant-b-gone at the moment).
// Also calculates target locations to spawn the visual smoke effect on, so the whole area
// is covered fairly evenly.
//------------------------------------------
/datum/effect/effect/system/smoke_spread/chem/start()
if(!location) //kill grenade if it somehow ends up in nullspace
if(!location)
return
//reagent application - only run if there are extra reagents in the smoke
if(chemholder.reagents.reagent_list.len)
for(var/datum/reagent/R in chemholder.reagents.reagent_list)
var/proba = 100
var/runs = 5
if(chemholder.reagents.reagent_list.len) //reagent application - only run if there are extra reagents in the smoke
for(var/turf/T in wallList)
chemholder.reagents.touch_turf(T)
for(var/turf/T in targetTurfs)
chemholder.reagents.touch_turf(T)
for(var/atom/A in T.contents)
if(istype(A, /obj/effect/effect/smoke/chem) || istype(A, /mob))
continue
else if(isobj(A))
chemholder.reagents.touch_obj(A)
//dilute the reagents according to cloud density
R.volume /= density
chemholder.reagents.update_total()
//apply wall affecting reagents to walls
if(R.id in list("thermite", "plantbgone"))
for(var/turf/T in wallList)
R.reaction_turf(T, R.volume)
//reagents that should be applied to turfs in a random pattern
if(R.id == "carbon")
proba = 75
else if(R.id in list("blood", "radium", "uranium"))
proba = 25
spawn(0)
for(var/i = 0, i < runs, i++)
for(var/turf/T in targetTurfs)
if(prob(proba))
R.reaction_turf(T, R.volume)
for(var/atom/A in T.contents)
if(istype(A, /obj/effect/effect/smoke/chem)) //skip the item if it is chem smoke
continue
else if(istype(A, /mob))
var/dist = cheap_pythag(T.x - location.x, T.y - location.y)
if(!dist)
dist = 1
R.reaction_mob(A, volume = R.volume / dist)
else if(istype(A, /obj))
R.reaction_obj(A, R.volume)
sleep(30)
//build smoke icon
var/color = mix_color_from_reagents(chemholder.reagents.reagent_list)
var/color = chemholder.reagents.get_color() //build smoke icon
var/icon/I
if(color)
I = icon('icons/effects/chemsmoke.dmi')
@@ -163,13 +113,9 @@
else
I = icon('icons/effects/96x96.dmi', "smoke")
var/const/arcLength = 2.3559 //distance between each smoke cloud
//distance between each smoke cloud
var/const/arcLength = 2.3559
//calculate positions for smoke coverage - then spawn smoke
for(var/i = 0, i < range, i++)
for(var/i = 0, i < range, i++) //calculate positions for smoke coverage - then spawn smoke
var/radius = i * 1.5
if(!radius)
spawn(0)
@@ -194,25 +140,16 @@
spawn(0)
spawnSmoke(T, I, range)
//------------------------------------------
// Randomizes and spawns the smoke effect.
// Also handles deleting the smoke once the effect is finished.
//------------------------------------------
/datum/effect/effect/system/smoke_spread/chem/proc/spawnSmoke(var/turf/T, var/icon/I, var/dist = 1, var/obj/effect/effect/smoke/chem/passed_smoke)
var/obj/effect/effect/smoke/chem/smoke
if(passed_smoke)
smoke = passed_smoke
else
smoke = new(location)
/datum/effect/effect/system/smoke_spread/chem/proc/spawnSmoke(var/turf/T, var/icon/I, var/dist = 1) // Randomizes and spawns the smoke effect. Also handles deleting the smoke once the effect is finished.
var/obj/effect/effect/smoke/chem/smoke = new(location)
if(chemholder.reagents.reagent_list.len)
chemholder.reagents.copy_to(smoke, chemholder.reagents.total_volume / dist, safety = 1) //copy reagents to the smoke so mob/breathe() can handle inhaling the reagents
chemholder.reagents.trans_to_obj(smoke, chemholder.reagents.total_volume / dist, copy = 1) //copy reagents to the smoke so mob/breathe() can handle inhaling the reagents
smoke.icon = I
smoke.layer = 6
smoke.set_dir(pick(cardinal))
smoke.pixel_x = -32 + rand(-8,8)
smoke.pixel_y = -32 + rand(-8,8)
smoke.pixel_x = -32 + rand(-8, 8)
smoke.pixel_y = -32 + rand(-8, 8)
walk_to(smoke, T)
smoke.opacity = 1 //switching opacity on after the smoke has spawned, and then
sleep(150+rand(0,20)) // turning it off before it is deleted results in cleaner
@@ -225,21 +162,15 @@
spores.name = "cloud of [seed.seed_name] [seed.seed_noun]"
..(T, I, dist, spores)
//------------------------------------------
// Fades out the smoke smoothly using it's alpha variable.
//------------------------------------------
/datum/effect/effect/system/smoke_spread/chem/proc/fadeOut(var/atom/A, var/frames = 16)
/datum/effect/effect/system/smoke_spread/chem/proc/fadeOut(var/atom/A, var/frames = 16) // Fades out the smoke smoothly using it's alpha variable.
var/step = A.alpha / frames
for(var/i = 0, i < frames, i++)
A.alpha -= step
sleep(world.tick_lag)
return
//------------------------------------------
// Smoke pathfinder. Uses a flood fill method based on zones to
// quickly check what turfs the smoke (airflow) can actually reach.
//------------------------------------------
/datum/effect/effect/system/smoke_spread/chem/proc/smokeFlow()
/datum/effect/effect/system/smoke_spread/chem/proc/smokeFlow() // Smoke pathfinder. Uses a flood fill method based on zones to quickly check what turfs the smoke (airflow) can actually reach.
var/list/pending = new()
var/list/complete = new()
+184
View File
@@ -0,0 +1,184 @@
// Foam
// Similar to smoke, but spreads out more
// metal foams leave behind a foamed metal wall
/obj/effect/effect/foam
name = "foam"
icon_state = "foam"
opacity = 0
anchored = 1
density = 0
layer = OBJ_LAYER + 0.9
mouse_opacity = 0
animate_movement = 0
var/amount = 3
var/expand = 1
var/metal = 0
/obj/effect/effect/foam/New(var/loc, var/ismetal = 0)
..(loc)
icon_state = "[ismetal? "m" : ""]foam"
metal = ismetal
playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3)
spawn(3 + metal * 3)
process()
checkReagents()
spawn(120)
processing_objects.Remove(src)
sleep(30)
if(metal)
var/obj/structure/foamedmetal/M = new(src.loc)
M.metal = metal
M.updateicon()
flick("[icon_state]-disolve", src)
sleep(5)
delete()
return
/obj/effect/effect/foam/proc/checkReagents() // transfer any reagents to the floor
if(!metal && reagents)
var/turf/T = get_turf(src)
reagents.touch_turf(T)
/obj/effect/effect/foam/process()
if(--amount < 0)
return
for(var/direction in cardinal)
var/turf/T = get_step(src, direction)
if(!T)
continue
if(!T.Enter(src))
continue
var/obj/effect/effect/foam/F = locate() in T
if(F)
continue
F = new(T, metal)
F.amount = amount
if(!metal)
F.create_reagents(10)
if(reagents)
for(var/datum/reagent/R in reagents.reagent_list)
F.reagents.add_reagent(R.id, 1, safety = 1) //added safety check since reagents in the foam have already had a chance to react
/obj/effect/effect/foam/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) // foam disolves when heated, except metal foams
if(!metal && prob(max(0, exposed_temperature - 475)))
flick("[icon_state]-disolve", src)
spawn(5)
delete()
/obj/effect/effect/foam/Crossed(var/atom/movable/AM)
if(metal)
return
if(istype(AM, /mob/living))
var/mob/living/M = AM
M.slip("the foam", 6)
/datum/effect/effect/system/foam_spread
var/amount = 5 // the size of the foam spread.
var/list/carried_reagents // the IDs of reagents present when the foam was mixed
var/metal = 0 // 0 = foam, 1 = metalfoam, 2 = ironfoam
/datum/effect/effect/system/foam_spread/set_up(amt=5, loca, var/datum/reagents/carry = null, var/metalfoam = 0)
amount = round(sqrt(amt / 3), 1)
if(istype(loca, /turf/))
location = loca
else
location = get_turf(loca)
carried_reagents = list()
metal = metalfoam
// bit of a hack here. Foam carries along any reagent also present in the glass it is mixed with (defaults to water if none is present). Rather than actually transfer the reagents, this makes a list of the reagent ids and spawns 1 unit of that reagent when the foam disolves.
if(carry && !metal)
for(var/datum/reagent/R in carry.reagent_list)
carried_reagents += R.id
/datum/effect/effect/system/foam_spread/start()
spawn(0)
var/obj/effect/effect/foam/F = locate() in location
if(F)
F.amount += amount
return
F = new(location, metal)
F.amount = amount
if(!metal) // don't carry other chemicals if a metal foam
F.create_reagents(10)
if(carried_reagents)
for(var/id in carried_reagents)
F.reagents.add_reagent(id, 1, safety = 1) //makes a safety call because all reagents should have already reacted anyway
else
F.reagents.add_reagent("water", 1, safety = 1)
// wall formed by metal foams, dense and opaque, but easy to break
/obj/structure/foamedmetal
icon = 'icons/effects/effects.dmi'
icon_state = "metalfoam"
density = 1
opacity = 1 // changed in New()
anchored = 1
name = "foamed metal"
desc = "A lightweight foamed metal wall."
var/metal = 1 // 1 = aluminum, 2 = iron
/obj/structure/foamedmetal/New()
..()
update_nearby_tiles(1)
/obj/structure/foamedmetal/Del()
density = 0
update_nearby_tiles(1)
..()
/obj/structure/foamedmetal/proc/updateicon()
if(metal == 1)
icon_state = "metalfoam"
else
icon_state = "ironfoam"
/obj/structure/foamedmetal/ex_act(severity)
del(src)
/obj/structure/foamedmetal/blob_act()
del(src)
/obj/structure/foamedmetal/bullet_act()
if(metal == 1 || prob(50))
del(src)
/obj/structure/foamedmetal/attack_hand(var/mob/user)
if ((HULK in user.mutations) || (prob(75 - metal * 25)))
user.visible_message("<span class='warning'>[user] smashes through the foamed metal.</span>", "<span class='notice'>You smash through the metal foam wall.</span>")
del(src)
else
user << "<span class='notice'>You hit the metal foam but bounce off it.</span>"
return
/obj/structure/foamedmetal/attackby(var/obj/item/I, var/mob/user)
if(istype(I, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = I
G.affecting.loc = src.loc
visible_message("<span class='warning'>[G.assailant] smashes [G.affecting] through the foamed metal wall.</span>")
del(I)
del(src)
return
if(prob(I.force * 20 - metal * 25))
user.visible_message("<span class='warning'>[user] smashes through the foamed metal.</span>", "<span class='notice'>You smash through the foamed metal with \the [I].</span>")
del(src)
else
user << "<span class='notice'>You hit the metal foam to no effect.</span>"
/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
if(air_group)
return 0
return !density
+50
View File
@@ -0,0 +1,50 @@
/obj/effect/effect/water
name = "water"
icon = 'icons/effects/effects.dmi'
icon_state = "extinguish"
mouse_opacity = 0
/obj/effect/effect/water/New(loc)
..()
spawn(150) // In case whatever made it forgets to delete it
if(src)
delete()
/obj/effect/effect/water/proc/set_color() // Call it after you move reagents to it
icon += reagents.get_color()
/obj/effect/effect/water/proc/set_up(var/turf/target, var/step_count = 5, var/delay = 5)
if(!target)
return
for(var/i = 1 to step_count)
step_towards(src, target)
var/turf/T = get_turf(src)
reagents.touch_turf(T)
var/mob/M = locate() in T
if(M)
reagents.splash_mob(M, reagents.total_volume)
break
for(var/atom/A in T)
reagents.touch(A)
if(T == get_turf(target))
break
sleep(delay)
sleep(10)
delete()
/obj/effect/effect/water/Move(turf/newloc)
if(newloc.density)
return 0
. = ..()
/obj/effect/effect/water/Bump(atom/A)
if(reagents)
reagents.touch(A)
return ..()
//Used by spraybottles.
/obj/effect/effect/water/chempuff
name = "chemicals"
icon = 'icons/obj/chempuff.dmi'
icon_state = ""
pass_flags = PASSTABLE | PASSGRILLE
+1 -7
View File
@@ -11,10 +11,4 @@
/obj/effect/decal/spraystill
density = 0
anchored = 1
layer = 50
//Used by spraybottles.
/obj/effect/decal/chempuff
name = "chemicals"
icon = 'icons/obj/chempuff.dmi'
pass_flags = PASSTABLE | PASSGRILLE
layer = 50
-245
View File
@@ -13,36 +13,12 @@ would spawn and follow the beaker, even if it is carried or thrown.
unacidable = 1//So effect are not targeted by alien acid.
pass_flags = PASSTABLE | PASSGRILLE
/obj/effect/effect/water
name = "water"
icon = 'icons/effects/effects.dmi'
icon_state = "extinguish"
var/life = 15.0
mouse_opacity = 0
/obj/effect/proc/delete()
loc = null
if(reagents)
reagents.delete()
return
/obj/effect/effect/water/Move(turf/newloc)
//var/turf/T = src.loc
//if (istype(T, /turf))
// T.firelevel = 0 //TODO: FIX
if (--src.life < 1)
//SN src = null
delete()
if(newloc.density)
return 0
.=..()
/obj/effect/effect/water/Bump(atom/A)
if(reagents)
reagents.reaction(A)
return ..()
/datum/effect/effect/system
var/number = 3
var/cardinals = 0
@@ -482,227 +458,6 @@ steam.start() -- spawns the effect
src.processing = 0
src.on = 0
// Foam
// Similar to smoke, but spreads out more
// metal foams leave behind a foamed metal wall
/obj/effect/effect/foam
name = "foam"
icon_state = "foam"
opacity = 0
anchored = 1
density = 0
layer = OBJ_LAYER + 0.9
mouse_opacity = 0
var/amount = 3
var/expand = 1
animate_movement = 0
var/metal = 0
/obj/effect/effect/foam/New(loc, var/ismetal=0)
..(loc)
icon_state = "[ismetal ? "m":""]foam"
metal = ismetal
playsound(src, 'sound/effects/bubbles2.ogg', 80, 1, -3)
spawn(3 + metal*3)
process()
checkReagents()
spawn(120)
processing_objects.Remove(src)
sleep(30)
if(metal)
var/obj/structure/foamedmetal/M = new(src.loc)
M.metal = metal
M.updateicon()
flick("[icon_state]-disolve", src)
sleep(5)
delete()
return
// transfer any reagents to the floor
/obj/effect/effect/foam/proc/checkReagents()
if(!metal && reagents)
for(var/atom/A in src.loc.contents)
if(A == src)
continue
reagents.reaction(A, 1, 1)
/obj/effect/effect/foam/process()
if(--amount < 0)
return
for(var/direction in cardinal)
var/turf/T = get_step(src,direction)
if(!T)
continue
if(!T.Enter(src))
continue
var/obj/effect/effect/foam/F = locate() in T
if(F)
continue
F = new(T, metal)
F.amount = amount
if(!metal)
F.create_reagents(10)
if (reagents)
for(var/datum/reagent/R in reagents.reagent_list)
F.reagents.add_reagent(R.id, 1, safety = 1) //added safety check since reagents in the foam have already had a chance to react
// foam disolves when heated
// except metal foams
/obj/effect/effect/foam/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(!metal && prob(max(0, exposed_temperature - 475)))
flick("[icon_state]-disolve", src)
spawn(5)
delete()
/obj/effect/effect/foam/Crossed(var/atom/movable/AM)
if(metal)
return
if(istype(AM, /mob/living))
var/mob/living/M = AM
M.slip("the foam",6)
/datum/effect/effect/system/foam_spread
var/amount = 5 // the size of the foam spread.
var/list/carried_reagents // the IDs of reagents present when the foam was mixed
var/metal = 0 // 0=foam, 1=metalfoam, 2=ironfoam
set_up(amt=5, loca, var/datum/reagents/carry = null, var/metalfoam = 0)
amount = round(sqrt(amt / 3), 1)
if(istype(loca, /turf/))
location = loca
else
location = get_turf(loca)
carried_reagents = list()
metal = metalfoam
// bit of a hack here. Foam carries along any reagent also present in the glass it is mixed
// with (defaults to water if none is present). Rather than actually transfer the reagents,
// this makes a list of the reagent ids and spawns 1 unit of that reagent when the foam disolves.
if(carry && !metal)
for(var/datum/reagent/R in carry.reagent_list)
carried_reagents += R.id
start()
spawn(0)
var/obj/effect/effect/foam/F = locate() in location
if(F)
F.amount += amount
return
F = new(src.location, metal)
F.amount = amount
if(!metal) // don't carry other chemicals if a metal foam
F.create_reagents(10)
if(carried_reagents)
for(var/id in carried_reagents)
F.reagents.add_reagent(id, 1, null, 1) //makes a safety call because all reagents should have already reacted anyway
else
F.reagents.add_reagent("water", 1, safety = 1)
// wall formed by metal foams
// dense and opaque, but easy to break
/obj/structure/foamedmetal
icon = 'icons/effects/effects.dmi'
icon_state = "metalfoam"
density = 1
opacity = 1 // changed in New()
anchored = 1
name = "foamed metal"
desc = "A lightweight foamed metal wall."
var/metal = 1 // 1=aluminum, 2=iron
New()
..()
update_nearby_tiles(1)
Del()
density = 0
update_nearby_tiles(1)
..()
proc/updateicon()
if(metal == 1)
icon_state = "metalfoam"
else
icon_state = "ironfoam"
ex_act(severity)
del(src)
blob_act()
del(src)
bullet_act()
if(metal==1 || prob(50))
del(src)
attack_hand(var/mob/user)
if ((HULK in user.mutations) || (prob(75 - metal*25)))
user << "\blue You smash through the metal foam wall."
for(var/mob/O in oviewers(user))
if ((O.client && !( O.blinded )))
O << "\red [user] smashes through the foamed metal."
del(src)
else
user << "\blue You hit the metal foam but bounce off it."
return
attackby(var/obj/item/I, var/mob/user)
if (istype(I, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = I
G.affecting.loc = src.loc
for(var/mob/O in viewers(src))
if (O.client)
O << "\red [G.assailant] smashes [G.affecting] through the foamed metal wall."
del(I)
del(src)
return
if(prob(I.force*20 - metal*25))
user << "\blue You smash through the foamed metal with \the [I]."
for(var/mob/O in oviewers(user))
if ((O.client && !( O.blinded )))
O << "\red [user] smashes through the foamed metal."
del(src)
else
user << "\blue You hit the metal foam to no effect."
CanPass(atom/movable/mover, turf/target, height=1.5, air_group = 0)
if(air_group) return 0
return !density
/datum/effect/effect/system/reagents_explosion
var/amount // TNT equivalent
var/flashing = 0 // does explosion creates flash effect?