Files
kiwistation/code/game/objects/effects/effect_system/effects_smoke.dm
T
phil235 d2a4024e7f reagent reaction() now use more methods. Instead of just INGEST or TOUCH, we now have INGEST (for injection, ingestion), TOUCH (for splashing), PATCH (for patch application and blob attack), and VAPOR (for smoke, foam and spray application).
- TOUCH no longer transfer reagent by default, it's now only used for touch based effect like being flammable when touched by fuel or you and your stuff being acided when touched by acid).

- PATCH does no transfer of its own (but actual patches code do make a transfer) but is used for touch effect that ignore clothes and protection (blob attacks, patches effect going through hardsuits)

- VAPOR does reagent transfer but it takes into account clothing protection

Fixes a typo in humanoid/get_permeability_prot
Fixes acid splashing on objects not destroying it. Fixes acid splashing on turf not destroying objects on the turf.

Changed damp rag smothering code a bit.

Blob Smoke now doesn't do anything.
2015-08-09 14:23:12 +02:00

296 lines
7.5 KiB
Plaintext

/////////////////////////////////////////////
//// SMOKE SYSTEMS
// direct can be optionally added when set_up, to make the smoke always travel in one direction
// in case you wanted a vent to always smoke north for example
/////////////////////////////////////////////
/obj/effect/effect/smoke
name = "smoke"
icon = 'icons/effects/96x96.dmi'
pixel_x = -32
pixel_y = -32
icon_state = "smoke"
opacity = 1
anchored = 0
mouse_opacity = 0
var/steps = 0
var/lifetime = 5
var/direction
/obj/effect/effect/smoke/proc/fade_out(frames = 16)
if(alpha == 0) //Handle already transparent case
return
if(frames == 0)
frames = 1 //We will just assume that by 0 frames, the coder meant "during one frame".
var/step = alpha / frames
for(var/i = 0, i < frames, i++)
alpha -= step
sleep(world.tick_lag)
/obj/effect/effect/smoke/New()
..()
create_reagents(500)
SSobj.processing |= src
lifetime += rand(-1,1)
/obj/effect/effect/smoke/Destroy()
SSobj.processing.Remove(src)
..()
/obj/effect/effect/smoke/proc/kill_smoke()
SSobj.processing.Remove(src)
spawn(0)
fade_out()
spawn(10)
qdel(src)
/obj/effect/effect/smoke/process()
lifetime--
if(lifetime < 1)
kill_smoke()
return 0
if(steps >= 1)
step(src,direction)
steps--
return 1
/obj/effect/effect/smoke/Crossed(mob/living/M)
if(!istype(M))
return
smoke_mob(M)
/obj/effect/effect/smoke/proc/smoke_mob(mob/living/carbon/M)
if(!istype(M))
return 0
if(lifetime<1)
return 0
if(M.internal != null || (M.wear_mask && (M.wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT)))
return 0
if(M.smoke_delay)
return 0
M.smoke_delay++
spawn(10)
if(M)
M.smoke_delay = 0
return 1
/datum/effect/effect/system/smoke_spread
var/direction
var/smoke_type = /obj/effect/effect/smoke
/datum/effect/effect/system/smoke_spread/set_up(n = 5, c = 0, loca, direct)
if(n > 20)
n = 20
number = n
cardinals = c
if(istype(loca, /turf/))
location = loca
else
location = get_turf(loca)
if(direct)
direction = direct
/datum/effect/effect/system/smoke_spread/start()
for(var/i=0, i<src.number, i++)
if(holder)
src.location = get_turf(holder)
var/obj/effect/effect/smoke/S = PoolOrNew(smoke_type, location)
if(!direction)
if(src.cardinals)
S.direction = pick(cardinal)
else
S.direction = pick(alldirs)
else
S.direction = direction
S.steps = pick(0,1,1,1,2,2,2,3)
S.process()
/////////////////////////////////////////////
// Bad smoke
/////////////////////////////////////////////
/obj/effect/effect/smoke/bad
lifetime = 8
/obj/effect/effect/smoke/bad/process()
if(..())
for(var/mob/living/carbon/M in range(1,src))
smoke_mob(M)
/obj/effect/effect/smoke/bad/smoke_mob(mob/living/carbon/M)
if(..())
M.drop_item()
M.adjustOxyLoss(1)
M.emote("cough")
/obj/effect/effect/smoke/bad/CanPass(atom/movable/mover, turf/target, height=0)
if(height==0) return 1
if(istype(mover, /obj/item/projectile/beam))
var/obj/item/projectile/beam/B = mover
B.damage = (B.damage/2)
return 1
/datum/effect/effect/system/smoke_spread/bad
smoke_type = /obj/effect/effect/smoke/bad
/////////////////////////////////////////////
// Chem smoke
/////////////////////////////////////////////
/obj/effect/effect/smoke/chem
icon = 'icons/effects/chemsmoke.dmi'
icon_state = ""
lifetime = 10
/obj/effect/effect/smoke/chem/process()
if(..())
var/fraction = 1/initial(lifetime)
for(var/obj/O in range(1,src))
if(O.type == src.type)
continue
reagents.reaction(O, VAPOR, fraction)
for(var/turf/T in range(1,src))
reagents.reaction(T, VAPOR, fraction)
var/hit = 0
for(var/mob/living/L in range(1,src))
hit += smoke_mob(L)
if(hit)
lifetime++ //this is so the decrease from mobs hit and the natural decrease don't cumulate.
/obj/effect/effect/smoke/chem/smoke_mob(mob/living/carbon/M)
if(lifetime<1)
return 0
if(!istype(M))
return 0
var/fraction = 1/initial(lifetime)
reagents.reaction(M, VAPOR, fraction)
lifetime--
return 1
/datum/effect/effect/system/smoke_spread/chem
var/obj/chemholder
smoke_type = /obj/effect/effect/smoke/chem
/datum/effect/effect/system/smoke_spread/chem/New()
..()
chemholder = PoolOrNew(/obj)
var/datum/reagents/R = new/datum/reagents(500)
chemholder.reagents = R
R.my_atom = chemholder
/datum/effect/effect/system/smoke_spread/chem/Destroy()
chemholder = null
..()
return QDEL_HINT_PUTINPOOL
/datum/effect/effect/system/smoke_spread/chem/set_up(datum/reagents/carry = null, n = 5, c = 0, loca, direct, silent = 0)
if(n > 20)
n = 20
number = n
cardinals = c
if(istype(loca, /turf/))
location = loca
else
location = get_turf(loca)
if(direct)
direction = direct
carry.copy_to(chemholder, 4*carry.total_volume) //The smoke holds 4 times the total reagents volume for balance purposes.
if(!silent)
var/contained = ""
for(var/reagent in carry.reagent_list)
contained += " [reagent] "
if(contained)
contained = "\[[contained]\]"
var/area/A = get_area(location)
var/where = "[A.name] | [location.x], [location.y]"
var/whereLink = "<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[location.x];Y=[location.y];Z=[location.z]'>[where]</a>"
if(carry.my_atom.fingerprintslast)
var/mob/M = get_mob_by_key(carry.my_atom.fingerprintslast)
var/more = ""
if(M)
more = "(<A HREF='?_src_=holder;adminmoreinfo=\ref[M]'>?</a>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</A>) "
message_admins("A chemical smoke reaction has taken place in ([whereLink])[contained]. Last associated key is [carry.my_atom.fingerprintslast][more].", 0, 1)
log_game("A chemical smoke reaction has taken place in ([where])[contained]. Last associated key is [carry.my_atom.fingerprintslast].")
else
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.")
/datum/effect/effect/system/smoke_spread/chem/start()
var/color = mix_color_from_reagents(chemholder.reagents.reagent_list)
for(var/i=0, i<src.number, i++)
if(holder)
src.location = get_turf(holder)
var/obj/effect/effect/smoke/chem/S = PoolOrNew(smoke_type, location)
if(!direction)
if(src.cardinals)
S.direction = pick(cardinal)
else
S.direction = pick(alldirs)
else
S.direction = direction
if(number == 1)
S.steps = 0
else if(number<=5)
S.steps = pick(0,1,1)
else if(number<=10)
S.steps = pick(0,1,1,1,2)
else
S.steps = pick(0,1,1,1,2,2,2,3)
if(chemholder.reagents.total_volume > 1) // can't split 1 very well
chemholder.reagents.copy_to(S, chemholder.reagents.total_volume/number) // copy reagents to each smoke, divide evenly
if(color)
S.color = color // give the smoke color, if it has any to begin with
else
// if no color, just use the old smoke icon
S.icon = 'icons/effects/96x96.dmi'
S.icon_state = "smoke"
S.process() //calling process right now so the smoke immediately attacks mobs.
/////////////////////////////////////////////
// Sleep smoke
/////////////////////////////////////////////
/obj/effect/effect/smoke/sleeping
color = "#9C3636"
lifetime = 10
/obj/effect/effect/smoke/sleeping/process()
if(..())
for(var/mob/living/carbon/M in range(1,src))
smoke_mob(M)
/obj/effect/effect/smoke/sleeping/smoke_mob(mob/living/carbon/M)
if(..())
if(M.internal != null || (M.wear_mask && (M.wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT)))
return
else
M.drop_item()
M.sleeping = max(M.sleeping,10)
M.emote("cough")
/datum/effect/effect/system/smoke_spread/sleeping
smoke_type = /obj/effect/effect/smoke/sleeping
var/obj/chemholder