mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 23:27:34 +01:00
Lots of work on acids, smoke, foam, reagents reaction() proc.
- fixed the fraction argument in reaction(...., INGESTED, fraction) so the proper amounts of each reagent react, not all of it. - slight optimization of datum/reagents/reaction() - small optimization /datum/reagent/proc/reaction_mob - the smoke's reagents no longer do direct transfer upon crossed()/move() but uses "reagents.reaction( mob, TOUCH)" only. - fixes no ingesting smoke if it's in the dark. - removed block gas smoke effect flag from clown mask and other non "actual" gas mask. - refactor how protection against touched chems being absorbed is done. get_permeability_protection() to get that protection. No more simple RNG get touched or not, now the amount that touches you depends on your protection and the volume in question. - changes acid_act to take volume into account. - chem_smoke now uses process() just like foam, we remove the reaction from crossed() and Move(), it's only done in process() now. - optimization of effect/smoke, OOP! And now all smoke effects use objprocessing instead of shitty sleep/spawn - removed mob var/coughedtime. - add a volume check to item/acid_act(), there's a threshold to be able to melt and then a probability to melt (acidpwr&volume). - greatly lowered the amount of reagent in the smoke from dead blobspore (so the volume isn't enough for melting) - human/acid_act(): damage to limbs depends on acidpwr&volume. - fixes metalfoam not working. - smoke powder: only one start() call. - Amound of smoke objects depends on amount of smoke recipe created. - Adds an argument to add_reagent() to block automatic call of handle_reaction() - When using reagents/proc/trans_to(), reactions are now only handled after every reagent is transfered and not before. - Amount of smoke objects depends on amount of smoke reagent created. - radius of foam reaction depends on amount of foam reagent created. - The amount of other reagents inside the smoke/foam decides the life expectancy of the effect. - The amount of reagents in each small smoke cloud/foam cell depends on the amount of other reagents in the initial reaction but also how much smoke/foam was created (more smoke means dilution of the reagents). - smoke/foam's reagent reaction on mob decreases the life expectancy of the effect (to avoid reagent duplication) - The amount of reagent reacting with atoms is less if the life expectancy is high.(to avoid reagent duplication) - The amount of movement from the smoke now depends on the number of smoke clouds created. - removing some useless code in chem_grenade/prime(). - When calling human/acid_act(), item acid melting chance lowers after each each successful melt in the list, some of the acid is "used" to melt that item so the next items have a lower chance to melt (to make melting every clothing harder). - remove the banned reagent list from sprays, not needed anymore now that acid is nerfed. - chem_grenade reaction, if there's no reagent left after reaction (smoke/foam/etc, reagents cleared) you don't get the steam effect and immediate reaction with all atoms around the grenade explosion. (Fixes foam cleaner grenade deleting bloodstains around it as soon as the grenade explodes, even if the foam hasn't reached the tile yet). - melted storage items now drop their content instead of deleting everything.
This commit is contained in:
@@ -198,20 +198,20 @@ var/list/spells = typesof(/obj/effect/proc_holder/spell) //needed for the badmin
|
||||
if(istype(target,/mob/living) && message)
|
||||
target << text("[message]")
|
||||
if(sparks_spread)
|
||||
var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
|
||||
var/datum/effect/effect/system/spark_spread/sparks = new
|
||||
sparks.set_up(sparks_amt, 0, location) //no idea what the 0 is
|
||||
sparks.start()
|
||||
if(smoke_spread)
|
||||
if(smoke_spread == 1)
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new
|
||||
smoke.set_up(smoke_amt, 0, location, smoke_amt == 1 ? 15 : 0) // if more than one smoke, spread it around
|
||||
smoke.start()
|
||||
else if(smoke_spread == 2)
|
||||
var/datum/effect/effect/system/bad_smoke_spread/smoke = new /datum/effect/effect/system/bad_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/bad/smoke = new
|
||||
smoke.set_up(smoke_amt, 0, location, smoke_amt == 1 ? 15 : 0) // same here
|
||||
smoke.start()
|
||||
else if(smoke_spread == 3)
|
||||
var/datum/effect/effect/system/sleep_smoke_spread/smoke = new /datum/effect/effect/system/sleep_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/sleeping/smoke = new
|
||||
smoke.set_up(smoke_amt, 0, location, smoke_amt == 1 ? 15 : 0) // same here
|
||||
smoke.start()
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
H << "Unable to reach your apprentice! You can either attack the spellbook with the contract to refund your points, or wait and try again later."
|
||||
|
||||
/obj/item/weapon/antag_spawner/contract/spawn_antag(var/client/C, var/turf/T, var/type = "")
|
||||
PoolOrNew(/obj/effect/effect/harmless_smoke, T)
|
||||
PoolOrNew(/obj/effect/effect/smoke, T)
|
||||
var/mob/living/carbon/human/M = new/mob/living/carbon/human(T)
|
||||
C.prefs.copy_to(M)
|
||||
M.key = C.key
|
||||
|
||||
@@ -90,11 +90,11 @@
|
||||
/mob/living/simple_animal/hostile/blob/blobspore/death(gibbed)
|
||||
..(1)
|
||||
// On death, create a small smoke of harmful gas (s-Acid)
|
||||
var/datum/effect/effect/system/chem_smoke_spread/S = new
|
||||
var/datum/effect/effect/system/smoke_spread/chem/S = new
|
||||
var/turf/location = get_turf(src)
|
||||
|
||||
// Create the reagents to put into the air
|
||||
create_reagents(25)
|
||||
create_reagents(2)
|
||||
|
||||
if(overmind && overmind.blob_reagent_datum)
|
||||
reagents.add_reagent(overmind.blob_reagent_datum.id, 25)
|
||||
|
||||
@@ -346,10 +346,10 @@
|
||||
B.reagents.clear_reagents() //Just in case!
|
||||
B.icon_state = null //Invisible
|
||||
B.reagents.add_reagent("blindness_smoke", 10)
|
||||
var/datum/effect/effect/system/chem_smoke_spread/S = new /datum/effect/effect/system/chem_smoke_spread
|
||||
var/datum/effect/effect/system/smoke_spread/chem/S = new
|
||||
S.attach(B)
|
||||
if(S)
|
||||
S.set_up(B.reagents, 10, 0, B.loc)
|
||||
S.set_up(10, 0, B.loc, null, 0, B.reagents)
|
||||
S.start()
|
||||
sleep(10)
|
||||
S.start()
|
||||
|
||||
@@ -487,8 +487,9 @@
|
||||
if ((get_dist(src, patient) <= 1) && (on))
|
||||
if(reagent_id == "internal_beaker")
|
||||
if(use_beaker && reagent_glass && reagent_glass.reagents.total_volume)
|
||||
var/fraction = min(injection_amount/reagent_glass.reagents.total_volume, 1)
|
||||
reagent_glass.reagents.reaction(patient, INGEST, fraction)
|
||||
reagent_glass.reagents.trans_to(patient,injection_amount) //Inject from beaker instead.
|
||||
reagent_glass.reagents.reaction(patient, INGEST)
|
||||
else
|
||||
patient.reagents.add_reagent(reagent_id,injection_amount)
|
||||
C.visible_message("<span class='danger'>[src] injects [patient] with its syringe!</span>", \
|
||||
|
||||
@@ -107,7 +107,8 @@
|
||||
if(istype(beaker, /obj/item/weapon/reagent_containers/blood))
|
||||
// speed up transfer on blood packs
|
||||
transfer_amount = 10
|
||||
beaker.reagents.reaction(attached, INGEST, 1,0) //make reagents reacts, but don't spam messages
|
||||
var/fraction = min(transfer_amount/beaker.volume, 1) //the fraction that is transfered of the total volume
|
||||
beaker.reagents.reaction(attached, INGEST, fraction,0) //make reagents reacts, but don't spam messages
|
||||
beaker.reagents.trans_to(attached, transfer_amount)
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
var/smoke = 5
|
||||
var/smoke_ready = 1
|
||||
var/smoke_cooldown = 100
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke_system = new
|
||||
var/datum/effect/effect/system/smoke_spread/smoke_system = new
|
||||
operation_req_access = list(access_cent_specops)
|
||||
wreckage = /obj/structure/mecha_wreckage/marauder
|
||||
add_req_access = 0
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
|
||||
/obj/effect/anomaly/proc/anomalyNeutralize()
|
||||
PoolOrNew(/obj/effect/effect/bad_smoke, loc)
|
||||
PoolOrNew(/obj/effect/effect/smoke/bad, loc)
|
||||
|
||||
for(var/atom/movable/O in src)
|
||||
O.loc = src.loc
|
||||
|
||||
@@ -16,7 +16,7 @@ would spawn and follow the beaker, even if it is carried or thrown.
|
||||
/obj/effect/effect/Destroy()
|
||||
..()
|
||||
return QDEL_HINT_PUTINPOOL
|
||||
|
||||
/*
|
||||
/datum/effect/effect/proc/fadeOut(var/atom/A, var/frames = 16)
|
||||
if(A.alpha == 0) //Handle already transparent case
|
||||
return
|
||||
@@ -27,7 +27,7 @@ would spawn and follow the beaker, even if it is carried or thrown.
|
||||
A.alpha -= step
|
||||
sleep(world.tick_lag)
|
||||
return
|
||||
|
||||
*/
|
||||
/datum/effect/effect/system
|
||||
var/number = 3
|
||||
var/cardinals = 0
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
layer = TURF_LAYER + 0.1
|
||||
mouse_opacity = 0
|
||||
var/amount = 3
|
||||
var/expand = 1
|
||||
animate_movement = 0
|
||||
var/metal = 0
|
||||
var/lifetime = 6
|
||||
var/max_lifetime = 6
|
||||
|
||||
|
||||
/obj/effect/effect/foam/metal/aluminium
|
||||
@@ -36,16 +36,20 @@
|
||||
/obj/effect/effect/foam/Destroy()
|
||||
SSobj.processing.Remove(src)
|
||||
return ..()
|
||||
|
||||
/*
|
||||
/obj/effect/effect/foam/metal/New(loc)
|
||||
..()
|
||||
var/obj/structure/foamedmetal/M = new(src.loc)
|
||||
M.metal = metal
|
||||
M.updateicon()
|
||||
M.updateicon()*/
|
||||
|
||||
|
||||
/obj/effect/effect/foam/proc/kill_foam()
|
||||
SSobj.processing.Remove(src)
|
||||
if(metal)
|
||||
var/obj/structure/foamedmetal/M = new(src.loc)
|
||||
M.metal = metal
|
||||
M.updateicon()
|
||||
flick("[icon_state]-disolve", src)
|
||||
spawn(5)
|
||||
qdel(src)
|
||||
@@ -55,21 +59,36 @@
|
||||
lifetime--
|
||||
if(lifetime < 1)
|
||||
kill_foam()
|
||||
return
|
||||
|
||||
var/fraction = 1/max_lifetime
|
||||
for(var/obj/O in range(0,src))
|
||||
if(O.type == src.type)
|
||||
continue
|
||||
reagents.reaction(O, TOUCH, fraction)
|
||||
for(var/mob/living/L in range(0,src))
|
||||
foam_mob(L)
|
||||
var/T = get_turf(src)
|
||||
reagents.reaction(T, TOUCH, fraction)
|
||||
|
||||
if(--amount < 0)
|
||||
return
|
||||
for(var/atom/M in view(1,src))
|
||||
if(M == src)
|
||||
continue
|
||||
reagents.reaction(M, TOUCH)
|
||||
spread_foam()
|
||||
|
||||
/obj/effect/effect/foam/proc/foam_mob(var/mob/living/L as mob)
|
||||
if(lifetime<1)
|
||||
return
|
||||
if(!istype(L))
|
||||
return
|
||||
var/fraction = 1/max_lifetime
|
||||
reagents.reaction(L, TOUCH, fraction)
|
||||
lifetime--
|
||||
|
||||
/obj/effect/effect/foam/Crossed(var/atom/movable/AM)
|
||||
if(istype(AM, /mob/living/carbon))
|
||||
var/mob/living/carbon/M = AM
|
||||
M.slip(5, 2, src)
|
||||
|
||||
|
||||
/obj/effect/effect/foam/metal/Crossed(var/atom/movable/AM)
|
||||
return
|
||||
|
||||
@@ -87,10 +106,14 @@
|
||||
if(foundfoam)
|
||||
continue
|
||||
|
||||
var/obj/effect/effect/foam/F = PoolOrNew(/obj/effect/effect/foam, T)
|
||||
for(var/mob/living/L in T)
|
||||
foam_mob(L)
|
||||
var/obj/effect/effect/foam/F = PoolOrNew(src.type, T)
|
||||
F.amount = amount
|
||||
reagents.copy_to(F, (reagents.total_volume))
|
||||
F.color = color
|
||||
F.metal = metal
|
||||
F.max_lifetime = max_lifetime
|
||||
|
||||
|
||||
/obj/effect/effect/foam/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
@@ -136,7 +159,6 @@
|
||||
amount = round(sqrt(amt / 2), 1)
|
||||
carry.copy_to(chemholder, carry.total_volume)
|
||||
|
||||
|
||||
/datum/effect/effect/system/foam_spread/metal/set_up(amt=5, loca, var/datum/reagents/carry = null, var/metaltype)
|
||||
..()
|
||||
metal = metaltype
|
||||
@@ -148,11 +170,12 @@
|
||||
else
|
||||
var/obj/effect/effect/foam/F = PoolOrNew(foamtype, location)
|
||||
var/foamcolor = mix_color_from_reagents(chemholder.reagents.reagent_list)
|
||||
chemholder.reagents.copy_to(F, chemholder.reagents.total_volume)
|
||||
chemholder.reagents.copy_to(F, chemholder.reagents.total_volume/amount) //how much reagents each foam cell holds
|
||||
F.color = foamcolor
|
||||
F.amount = amount
|
||||
F.metal = metal
|
||||
|
||||
F.max_lifetime = Clamp(round(sqrt(chemholder.reagents.total_volume/2), 1), 3, 10) //how long each foam cell lasts.
|
||||
F.lifetime = F.max_lifetime
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// FOAM STRUCTURE. Formed by metal foams. Dense and opaque, but easy to break
|
||||
|
||||
@@ -6,37 +6,92 @@
|
||||
|
||||
/obj/effect/effect/smoke
|
||||
name = "smoke"
|
||||
icon = 'icons/effects/water.dmi'
|
||||
icon_state = "smoke"
|
||||
opacity = 1
|
||||
anchored = 0.0
|
||||
mouse_opacity = 0
|
||||
var/amount = 8.0
|
||||
|
||||
/obj/effect/effect/harmless_smoke
|
||||
name = "smoke"
|
||||
icon_state = "smoke"
|
||||
opacity = 1
|
||||
anchored = 0.0
|
||||
mouse_opacity = 0
|
||||
var/amount = 6.0
|
||||
//Remove this bit to use the old smoke
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
|
||||
/obj/effect/effect/harmless_smoke/New()
|
||||
..()
|
||||
spawn (100)
|
||||
qdel(src)
|
||||
|
||||
/datum/effect/effect/system/harmless_smoke_spread
|
||||
var/total_smoke = 0 // To stop it being spammed and lagging!
|
||||
icon_state = "smoke"
|
||||
opacity = 1
|
||||
anchored = 0
|
||||
mouse_opacity = 0
|
||||
var/steps = 0
|
||||
var/lifetime = 10
|
||||
var/direction
|
||||
var/fading = 0
|
||||
|
||||
/datum/effect/effect/system/harmless_smoke_spread/set_up(n = 5, c = 0, loca, direct)
|
||||
if(n > 10)
|
||||
n = 10
|
||||
|
||||
/obj/effect/effect/smoke/proc/fade_out(var/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.Add(src)
|
||||
lifetime = lifetime + rand(1,3)
|
||||
|
||||
/obj/effect/effect/smoke/Destroy()
|
||||
SSobj.processing.Remove(src)
|
||||
..()
|
||||
|
||||
/obj/effect/effect/smoke/proc/kill_smoke()
|
||||
SSobj.processing.Remove(src)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/effect/smoke/process()
|
||||
world << "Process"
|
||||
lifetime--
|
||||
if(lifetime < 3 && !fading)
|
||||
fading = 1
|
||||
spawn(0)
|
||||
fade_out(100)
|
||||
if(lifetime < 1)
|
||||
kill_smoke()
|
||||
return 0
|
||||
if(steps >= 1)
|
||||
step(src,direction)
|
||||
steps--
|
||||
return 1
|
||||
|
||||
/obj/effect/effect/smoke/Crossed(mob/living/M as mob)
|
||||
if(!istype(M))
|
||||
return
|
||||
smoke_mob(M)
|
||||
|
||||
/obj/effect/effect/smoke/Cross(mob/living/M as mob)
|
||||
if(!istype(M))
|
||||
return
|
||||
smoke_mob(M)
|
||||
|
||||
/obj/effect/effect/smoke/proc/smoke_mob(mob/living/carbon/M as mob)
|
||||
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/))
|
||||
@@ -46,70 +101,39 @@
|
||||
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)
|
||||
SSobj.processing.Add(S)
|
||||
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)
|
||||
|
||||
/datum/effect/effect/system/harmless_smoke_spread/start()
|
||||
var/i = 0
|
||||
for(i=0, i<src.number, i++)
|
||||
if(src.total_smoke > 20)
|
||||
return
|
||||
spawn(0)
|
||||
if(holder)
|
||||
src.location = get_turf(holder)
|
||||
var/obj/effect/effect/harmless_smoke/smoke = PoolOrNew(/obj/effect/effect/harmless_smoke, location)
|
||||
src.total_smoke++
|
||||
var/direction = src.direction
|
||||
if(!direction)
|
||||
if(src.cardinals)
|
||||
direction = pick(cardinal)
|
||||
else
|
||||
direction = pick(alldirs)
|
||||
for(i=0, i<pick(0,1,1,1,2,2,2,3), i++)
|
||||
sleep(10)
|
||||
step(smoke,direction)
|
||||
spawn(75+rand(10,30))
|
||||
if(smoke)
|
||||
fadeOut(smoke)
|
||||
qdel(smoke)
|
||||
src.total_smoke--
|
||||
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Bad smoke
|
||||
/////////////////////////////////////////////
|
||||
|
||||
/obj/effect/effect/bad_smoke
|
||||
name = "smoke"
|
||||
icon_state = "smoke"
|
||||
opacity = 1
|
||||
anchored = 0.0
|
||||
mouse_opacity = 0
|
||||
var/amount = 6.0
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
/obj/effect/effect/smoke/bad/process()
|
||||
if(..())
|
||||
for(var/mob/living/carbon/M in range(1,src))
|
||||
smoke_mob(M)
|
||||
|
||||
/obj/effect/effect/bad_smoke/New()
|
||||
..()
|
||||
spawn (200+rand(10,30))
|
||||
qdel(src)
|
||||
/obj/effect/effect/smoke/bad/smoke_mob(mob/living/carbon/M as mob)
|
||||
if(..())
|
||||
M.drop_item()
|
||||
M.adjustOxyLoss(1)
|
||||
M.emote("cough")
|
||||
|
||||
/obj/effect/effect/bad_smoke/Move()
|
||||
..()
|
||||
for(var/mob/living/carbon/M in get_turf(src))
|
||||
if (M.internal != null && M.wear_mask && (M.wear_mask.flags & MASKINTERNALS))
|
||||
else
|
||||
M.drop_item()
|
||||
M.adjustOxyLoss(1)
|
||||
if (M.coughedtime != 1)
|
||||
M.coughedtime = 1
|
||||
M.emote("cough")
|
||||
spawn(20)
|
||||
if(M && M.loc)
|
||||
M.coughedtime = 0
|
||||
return
|
||||
|
||||
|
||||
/obj/effect/effect/bad_smoke/CanPass(atom/movable/mover, turf/target, height=0)
|
||||
/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
|
||||
@@ -117,135 +141,73 @@
|
||||
return 1
|
||||
|
||||
|
||||
/obj/effect/effect/bad_smoke/Crossed(mob/living/carbon/M as mob )
|
||||
..()
|
||||
if(istype(M, /mob/living/carbon))
|
||||
if (M.internal != null && M.wear_mask && (M.wear_mask.flags & MASKINTERNALS))
|
||||
return
|
||||
else
|
||||
M.drop_item()
|
||||
M.adjustOxyLoss(1)
|
||||
if (M.coughedtime != 1)
|
||||
M.coughedtime = 1
|
||||
M.emote("cough")
|
||||
spawn(20)
|
||||
if(M && M.loc)
|
||||
M.coughedtime = 0
|
||||
return
|
||||
|
||||
/datum/effect/effect/system/bad_smoke_spread
|
||||
var/total_smoke = 0 // To stop it being spammed and lagging!
|
||||
var/direction
|
||||
|
||||
/datum/effect/effect/system/bad_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/bad_smoke_spread/start()
|
||||
var/i = 0
|
||||
for(i=0, i<src.number, i++)
|
||||
if(src.total_smoke > 20)
|
||||
return
|
||||
spawn(0)
|
||||
if(holder)
|
||||
src.location = get_turf(holder)
|
||||
var/obj/effect/effect/bad_smoke/smoke = PoolOrNew(/obj/effect/effect/bad_smoke, location)
|
||||
src.total_smoke++
|
||||
var/direction = src.direction
|
||||
if(!direction)
|
||||
if(src.cardinals)
|
||||
direction = pick(cardinal)
|
||||
else
|
||||
direction = pick(alldirs)
|
||||
for(i=0, i<pick(0,1,1,1,2,2,2,3), i++)
|
||||
sleep(10)
|
||||
step(smoke,direction)
|
||||
spawn(150+rand(10,30))
|
||||
if(smoke)
|
||||
fadeOut(smoke)
|
||||
qdel(smoke)
|
||||
src.total_smoke--
|
||||
/datum/effect/effect/system/smoke_spread/bad
|
||||
smoke_type = /obj/effect/effect/smoke/bad
|
||||
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Chem smoke
|
||||
/////////////////////////////////////////////
|
||||
|
||||
|
||||
/obj/effect/effect/chem_smoke
|
||||
name = "smoke"
|
||||
opacity = 1
|
||||
anchored = 0.0
|
||||
mouse_opacity = 0
|
||||
var/amount = 6.0
|
||||
/obj/effect/effect/smoke/chem
|
||||
icon = 'icons/effects/chemsmoke.dmi'
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
icon_state = ""
|
||||
var/max_lifetime = 10
|
||||
|
||||
/obj/effect/effect/smoke/chem/process()
|
||||
if(..())
|
||||
var/fraction = 1/max_lifetime
|
||||
for(var/obj/O in range(1,src))
|
||||
if(O.type == src.type)
|
||||
continue
|
||||
reagents.reaction(O, TOUCH, fraction)
|
||||
|
||||
for(var/turf/T in range(1,src))
|
||||
reagents.reaction(T, TOUCH, fraction)
|
||||
|
||||
for(var/mob/living/L in range(1,src))
|
||||
smoke_mob(L)
|
||||
|
||||
/obj/effect/effect/smoke/chem/smoke_mob((mob/living/carbon/M as mob))
|
||||
if(lifetime<1)
|
||||
return
|
||||
if(!istype(M))
|
||||
return
|
||||
var/fraction = 1/max_lifetime
|
||||
reagents.reaction(M, TOUCH, fraction)
|
||||
lifetime--
|
||||
|
||||
|
||||
/obj/effect/effect/chem_smoke/New()
|
||||
..()
|
||||
create_reagents(500)
|
||||
spawn(200+rand(10,30))
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/effect/effect/chem_smoke/Move()
|
||||
..()
|
||||
for(var/mob/living/A in view(1, src))
|
||||
if(reagents.total_volume >= 1)
|
||||
reagents.reaction(A, TOUCH)
|
||||
reagents.trans_to(A.reagents, 10)
|
||||
return
|
||||
|
||||
|
||||
/obj/effect/effect/chem_smoke/Crossed(mob/living/carbon/M as mob )
|
||||
..()
|
||||
if(reagents.total_volume >= 1)
|
||||
reagents.reaction(M, TOUCH)
|
||||
reagents.trans_to(M.reagents, 10)
|
||||
|
||||
/datum/effect/effect/system/chem_smoke_spread
|
||||
var/total_smoke = 0 // To stop it being spammed and lagging!
|
||||
var/direction
|
||||
/datum/effect/effect/system/smoke_spread/chem
|
||||
var/obj/chemholder
|
||||
smoke_type = /obj/effect/effect/smoke/chem
|
||||
|
||||
|
||||
/datum/effect/effect/system/chem_smoke_spread/New()
|
||||
/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/chem_smoke_spread/Destroy()
|
||||
/datum/effect/effect/system/smoke_spread/chem/Destroy()
|
||||
chemholder = null
|
||||
..()
|
||||
return QDEL_HINT_PUTINPOOL
|
||||
|
||||
/datum/effect/effect/system/chem_smoke_spread/set_up(var/datum/reagents/carry = null, n = 5, c = 0, loca, direct, silent = 0)
|
||||
/datum/effect/effect/system/smoke_spread/chem/set_up(var/datum/reagents/carry = null, n = 5, c = 0, loca, direct, silent = 0)
|
||||
if(n > 20)
|
||||
n = 20
|
||||
number = n
|
||||
cardinals = c
|
||||
carry.copy_to(chemholder, carry.total_volume)
|
||||
|
||||
|
||||
if(istype(loca, /turf/))
|
||||
location = loca
|
||||
else
|
||||
location = get_turf(loca)
|
||||
|
||||
if(direct)
|
||||
direction = direct
|
||||
carry.copy_to(chemholder, carry.total_volume)
|
||||
|
||||
if(!silent)
|
||||
var/contained = ""
|
||||
@@ -270,140 +232,63 @@
|
||||
log_game("A chemical smoke reaction has taken place in ([where])[contained]. No associated key.")
|
||||
|
||||
|
||||
/datum/effect/effect/system/chem_smoke_spread/start()
|
||||
var/i = 0
|
||||
/datum/effect/effect/system/smoke_spread/chem/start()
|
||||
|
||||
var/color = mix_color_from_reagents(chemholder.reagents.reagent_list)
|
||||
|
||||
for(i=0, i<src.number, i++)
|
||||
if(src.total_smoke > 20)
|
||||
return
|
||||
spawn(0)
|
||||
if(holder)
|
||||
src.location = get_turf(holder)
|
||||
var/obj/effect/effect/chem_smoke/smoke = PoolOrNew(/obj/effect/effect/chem_smoke, location)
|
||||
src.total_smoke++
|
||||
var/direction = src.direction
|
||||
if(!direction)
|
||||
if(src.cardinals)
|
||||
direction = pick(cardinal)
|
||||
else
|
||||
direction = pick(alldirs)
|
||||
|
||||
if(chemholder.reagents.total_volume != 1) // can't split 1 very well
|
||||
chemholder.reagents.copy_to(smoke, chemholder.reagents.total_volume / number) // copy reagents to each smoke, divide evenly
|
||||
|
||||
if(color)
|
||||
smoke.color = color // give the smoke color, if it has any to begin with
|
||||
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
|
||||
// if no color, just use the old smoke icon
|
||||
smoke.icon = 'icons/effects/96x96.dmi'
|
||||
smoke.icon_state = "smoke"
|
||||
S.direction = pick(alldirs)
|
||||
else
|
||||
S.direction = direction
|
||||
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)
|
||||
S.max_lifetime = Clamp(round(sqrt(chemholder.reagents.total_volume/2), 1), 4, 10) //the more chemicals, the longer the smoke duration.
|
||||
S.lifetime = S.max_lifetime
|
||||
|
||||
for(i=0, i<pick(0,1,1,1,2,2,2,3), i++)
|
||||
sleep(10)
|
||||
step(smoke,direction)
|
||||
spawn(150+rand(10,30))
|
||||
if(smoke)
|
||||
fadeOut(smoke)
|
||||
qdel(smoke)
|
||||
src.total_smoke--
|
||||
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/sleep_smoke
|
||||
name = "smoke"
|
||||
icon_state = "smoke"
|
||||
opacity = 1
|
||||
anchored = 0.0
|
||||
mouse_opacity = 0
|
||||
var/amount = 6.0
|
||||
//Remove this bit to use the old smoke
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
/obj/effect/effect/smoke/sleeping
|
||||
color = "#9C3636"
|
||||
|
||||
/obj/effect/effect/sleep_smoke/New()
|
||||
..()
|
||||
spawn (200+rand(10,30))
|
||||
qdel(src)
|
||||
/obj/effect/effect/smoke/sleeping/process()
|
||||
for(var/mob/living/carbon/M in range(1,src))
|
||||
smoke_mob(M)
|
||||
|
||||
/obj/effect/effect/sleep_smoke/Move()
|
||||
..()
|
||||
for(var/mob/living/carbon/M in get_turf(src))
|
||||
if (M.internal != null && M.wear_mask && (M.wear_mask.flags & MASKINTERNALS))
|
||||
// if (M.wear_suit, /obj/item/clothing/suit/wizrobe && (M.hat, /obj/item/clothing/head/wizard) && (M.shoes, /obj/item/clothing/shoes/sandal)) // I'll work on it later
|
||||
else
|
||||
M.drop_item()
|
||||
M:sleeping += 5
|
||||
if (M.coughedtime != 1)
|
||||
M.coughedtime = 1
|
||||
M.emote("cough")
|
||||
spawn(20)
|
||||
if(M && M.loc)
|
||||
M.coughedtime = 0
|
||||
return
|
||||
|
||||
/obj/effect/effect/sleep_smoke/Crossed(mob/living/carbon/M as mob )
|
||||
..()
|
||||
if(istype(M, /mob/living/carbon))
|
||||
if (M.internal != null && M.wear_mask && (M.wear_mask.flags & MASKINTERNALS))
|
||||
// if (M.wear_suit, /obj/item/clothing/suit/wizrobe && (M.hat, /obj/item/clothing/head/wizard) && (M.shoes, /obj/item/clothing/shoes/sandal)) // Work on it later
|
||||
/obj/effect/effect/smoke/sleeping/smoke_mob(mob/living/carbon/M as mob)
|
||||
if(..())
|
||||
if(M.internal != null || (M.wear_mask && (M.wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT)))
|
||||
return
|
||||
else
|
||||
M.drop_item()
|
||||
M:sleeping += 5
|
||||
if (M.coughedtime != 1)
|
||||
M.coughedtime = 1
|
||||
M.emote("cough")
|
||||
spawn(20)
|
||||
if(M && M.loc)
|
||||
M.coughedtime = 0
|
||||
return
|
||||
|
||||
/datum/effect/effect/system/sleep_smoke_spread
|
||||
var/total_smoke = 0 // To stop it being spammed and lagging!
|
||||
var/direction
|
||||
|
||||
/datum/effect/effect/system/sleep_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
|
||||
M.sleeping = max(M.sleeping,10)
|
||||
M.emote("cough")
|
||||
|
||||
|
||||
/datum/effect/effect/system/sleep_smoke_spread/start()
|
||||
var/i = 0
|
||||
for(i=0, i<src.number, i++)
|
||||
if(src.total_smoke > 20)
|
||||
return
|
||||
spawn(0)
|
||||
if(holder)
|
||||
src.location = get_turf(holder)
|
||||
var/obj/effect/effect/sleep_smoke/smoke = PoolOrNew(/obj/effect/effect/sleep_smoke, location)
|
||||
src.total_smoke++
|
||||
var/direction = src.direction
|
||||
if(!direction)
|
||||
if(src.cardinals)
|
||||
direction = pick(cardinal)
|
||||
else
|
||||
direction = pick(alldirs)
|
||||
for(i=0, i<pick(0,1,1,1,2,2,2,3), i++)
|
||||
sleep(10)
|
||||
step(smoke,direction)
|
||||
spawn(150+rand(10,30))
|
||||
if(smoke)
|
||||
fadeOut(smoke)
|
||||
qdel(smoke)
|
||||
src.total_smoke--
|
||||
/datum/effect/effect/system/smoke_spread/sleeping
|
||||
smoke_type = /obj/effect/effect/smoke/sleeping
|
||||
var/obj/chemholder
|
||||
|
||||
@@ -65,6 +65,6 @@
|
||||
P.set_up(10,location)
|
||||
P.start()
|
||||
spawn(5)
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/S = new/datum/effect/effect/system/harmless_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/S = new
|
||||
S.set_up(5,0,location,null)
|
||||
S.start()
|
||||
@@ -144,20 +144,20 @@
|
||||
M.Move(dest)
|
||||
|
||||
if(entersparks)
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
var/datum/effect/effect/system/spark_spread/s = new
|
||||
s.set_up(4, 1, src)
|
||||
s.start()
|
||||
if(exitsparks)
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
var/datum/effect/effect/system/spark_spread/s = new
|
||||
s.set_up(4, 1, dest)
|
||||
s.start()
|
||||
|
||||
if(entersmoke)
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/s = new /datum/effect/effect/system/harmless_smoke_spread
|
||||
var/datum/effect/effect/system/smoke_spread/s = new
|
||||
s.set_up(4, 1, src, 0)
|
||||
s.start()
|
||||
if(exitsmoke)
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/s = new /datum/effect/effect/system/harmless_smoke_spread
|
||||
var/datum/effect/effect/system/smoke_spread/s = new
|
||||
s.set_up(4, 1, dest, 0)
|
||||
s.start()
|
||||
|
||||
|
||||
@@ -411,27 +411,34 @@
|
||||
throw_at(S,14,3)
|
||||
else ..()
|
||||
|
||||
/obj/item/acid_act(var/acidpwr, var/toxpwr, var/acid_volume)
|
||||
/obj/item/acid_act(var/acidpwr, var/acid_volume)
|
||||
. = 1
|
||||
if(unacidable)
|
||||
return
|
||||
|
||||
var/meltingpwr = acid_volume*acidpwr
|
||||
var/melting_threshold = 100
|
||||
if(meltingpwr <= melting_threshold) // so a single unit can't melt items. You need 5.1+ unit for fluoro and 10.1+ for sulphuric
|
||||
return
|
||||
|
||||
for(var/V in armor)
|
||||
if(armor[V] > 0)
|
||||
.-- //it survives the acid...
|
||||
break
|
||||
if(.)
|
||||
if(. && prob(min(meltingpwr/10,90))) //chance to melt depends on acid power and volume.
|
||||
var/turf/T = get_turf(src)
|
||||
if(T)
|
||||
T.visible_message("<span class='danger'>[src] melts away!</span>")
|
||||
var/obj/effect/decal/cleanable/molten_item/I = new (T)
|
||||
I.pixel_x = rand(-16,16)
|
||||
I.pixel_y = rand(-16,16)
|
||||
I.desc = "Looks like this was \an [src] some time ago."
|
||||
if(istype(src,/obj/item/weapon/storage))
|
||||
var/obj/item/weapon/storage/S = src
|
||||
S.do_quick_empty() //melted storage item drops its content.
|
||||
qdel(src)
|
||||
else
|
||||
for(var/armour_value in armor) //but is weakened
|
||||
armor[armour_value] = max(armor[armour_value]-acidpwr,0)
|
||||
armor[armour_value] = max(armor[armour_value]-min(acidpwr,meltingpwr/10),0)
|
||||
if(!findtext(desc, "it looks slightly melted...")) //it looks slightly melted... it looks slightly melted... it looks slightly melted... etc.
|
||||
desc += " it looks slightly melted..." //needs a space at the start, formatting
|
||||
|
||||
|
||||
@@ -203,14 +203,16 @@ CIGARETTE PACKETS ARE IN FANCY.DM
|
||||
|
||||
|
||||
/obj/item/clothing/mask/cigarette/proc/handle_reagents()
|
||||
if(iscarbon(loc))
|
||||
var/mob/living/carbon/C = loc
|
||||
if (src == C.wear_mask) // if it's in the human/monkey mouth, transfer reagents to the mob
|
||||
if(prob(15)) // so it's not an instarape in case of acid
|
||||
reagents.reaction(C, INGEST)
|
||||
reagents.trans_to(C, REAGENTS_METABOLISM)
|
||||
return
|
||||
reagents.remove_any(REAGENTS_METABOLISM)
|
||||
if(reagents.total_volume)
|
||||
if(iscarbon(loc))
|
||||
var/mob/living/carbon/C = loc
|
||||
if (src == C.wear_mask) // if it's in the human/monkey mouth, transfer reagents to the mob
|
||||
if(prob(15)) // so it's not an instarape in case of acid
|
||||
var/fraction = min(REAGENTS_METABOLISM/reagents.total_volume, 1)
|
||||
reagents.reaction(C, INGEST, fraction)
|
||||
reagents.trans_to(C, REAGENTS_METABOLISM)
|
||||
return
|
||||
reagents.remove_any(REAGENTS_METABOLISM)
|
||||
|
||||
|
||||
/obj/item/clothing/mask/cigarette/process()
|
||||
|
||||
@@ -180,31 +180,29 @@
|
||||
|
||||
mix_reagents()
|
||||
|
||||
if(reagents.total_volume) //The possible reactions didnt use up all reagents.
|
||||
if(reagents.total_volume) //The possible reactions didnt use up all reagents, so we spread it around.
|
||||
var/datum/effect/effect/system/steam_spread/steam = new /datum/effect/effect/system/steam_spread()
|
||||
steam.set_up(10, 0, get_turf(src))
|
||||
steam.attach(src)
|
||||
steam.start()
|
||||
|
||||
var/list/viewable = view(affected_area, loc)
|
||||
var/list/accessible = can_flood_from(loc, affected_area)
|
||||
var/list/reactable = accessible
|
||||
var/mycontents = GetAllContents()
|
||||
for(var/turf/T in accessible)
|
||||
for(var/atom/A in T.GetAllContents())
|
||||
if(A in mycontents) continue
|
||||
if(!(A in viewable)) continue
|
||||
reactable |= A
|
||||
if(!reactable.len) //Nothing to react with. Probably means we're in nullspace.
|
||||
qdel(src)
|
||||
return
|
||||
var/fraction = 1/reactable.len
|
||||
for(var/atom/A in reactable)
|
||||
reagents.reaction(A, TOUCH, fraction)
|
||||
var/list/viewable = view(affected_area, loc)
|
||||
var/list/accessible = can_flood_from(loc, affected_area)
|
||||
var/list/reactable = accessible
|
||||
var/mycontents = GetAllContents()
|
||||
for(var/turf/T in accessible)
|
||||
for(var/atom/A in T.GetAllContents())
|
||||
if(A in mycontents) continue
|
||||
if(!(A in viewable)) continue
|
||||
reactable |= A
|
||||
if(!reactable.len) //Nothing to react with. Probably means we're in nullspace.
|
||||
qdel(src)
|
||||
return
|
||||
var/fraction = 1/reactable.len
|
||||
for(var/atom/A in reactable)
|
||||
reagents.reaction(A, TOUCH, fraction)
|
||||
|
||||
invisibility = INVISIBILITY_MAXIMUM //Why am i doing this?
|
||||
spawn(50) //To make sure all reagents can work
|
||||
qdel(src) //correctly before deleting the grenade.
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/grenade/chem_grenade/proc/mix_reagents()
|
||||
var/total_temp
|
||||
@@ -381,6 +379,7 @@
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
|
||||
|
||||
/obj/item/weapon/grenade/chem_grenade/colorful
|
||||
name = "colorful grenade"
|
||||
desc = "Used for wide scale painting projects."
|
||||
@@ -399,6 +398,7 @@
|
||||
beakers += B1
|
||||
beakers += B2
|
||||
|
||||
|
||||
/obj/item/weapon/grenade/chem_grenade/clf3
|
||||
name = "clf3 grenade"
|
||||
desc = "BURN!-brand foaming clf3. In a special applicator for rapid purging of wide areas."
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
det_time = 20
|
||||
item_state = "flashbang"
|
||||
slot_flags = SLOT_BELT
|
||||
var/datum/effect/effect/system/bad_smoke_spread/smoke
|
||||
var/datum/effect/effect/system/smoke_spread/bad/smoke
|
||||
|
||||
/obj/item/weapon/grenade/smokebomb/New()
|
||||
..()
|
||||
src.smoke = new /datum/effect/effect/system/bad_smoke_spread
|
||||
src.smoke = new /datum/effect/effect/system/smoke_spread/bad
|
||||
src.smoke.attach(src)
|
||||
|
||||
/obj/item/weapon/grenade/smokebomb/Destroy()
|
||||
@@ -24,10 +24,6 @@
|
||||
src.smoke.start()
|
||||
sleep(10)
|
||||
src.smoke.start()
|
||||
sleep(10)
|
||||
src.smoke.start()
|
||||
sleep(10)
|
||||
src.smoke.start()
|
||||
|
||||
for(var/obj/effect/blob/B in view(8,src))
|
||||
var/damage = round(30/(get_dist(B,src)+1))
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
if(!((user == loc || (in_range(src, user) && istype(src.loc, /turf)))))
|
||||
return
|
||||
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new
|
||||
smoke.set_up(5, 0, user.loc)
|
||||
smoke.attach(user)
|
||||
smoke.start()
|
||||
|
||||
@@ -309,7 +309,9 @@
|
||||
pass_flags = PASSTABLE
|
||||
|
||||
/obj/effect/nanofrost_container/proc/Smoke()
|
||||
PoolOrNew(/obj/effect/effect/freezing_smoke, list(loc, 6, 1))
|
||||
var/datum/effect/effect/system/smoke_spread/freezing/S = new
|
||||
S.set_up(6, 0, loc, null, 1)
|
||||
S.start()
|
||||
var/obj/effect/decal/cleanable/flour/F = new /obj/effect/decal/cleanable/flour(src.loc)
|
||||
F.color = "#B2FFFF"
|
||||
F.name = "nanofrost residue"
|
||||
@@ -317,33 +319,16 @@
|
||||
playsound(src,'sound/effects/bamf.ogg',100,1)
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/effect/freezing_smoke
|
||||
/obj/effect/effect/smoke/freezing
|
||||
name = "nanofrost smoke"
|
||||
icon_state = "smoke"
|
||||
opacity = 0
|
||||
anchored = 0.0
|
||||
mouse_opacity = 0
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
color = "#B2FFFF"
|
||||
var/amount = 0
|
||||
|
||||
/obj/effect/effect/freezing_smoke/New(loc, var/amt, var/blast)
|
||||
..()
|
||||
spawn(100+rand(10,30))
|
||||
qdel(src)
|
||||
amount = amt
|
||||
if(amount)
|
||||
var/datum/effect/effect/system/freezing_smoke_spread/F = new /datum/effect/effect/system/freezing_smoke_spread
|
||||
F.set_up(amount, 0, src.loc)
|
||||
F.start()
|
||||
if(blast)
|
||||
for(var/turf/T in trange(2, src.loc))
|
||||
Chilled(T)
|
||||
return
|
||||
/datum/effect/effect/system/smoke_spread/freezing
|
||||
smoke_type = /obj/effect/effect/smoke/freezing
|
||||
var/blast = 0
|
||||
|
||||
/obj/effect/effect/freezing_smoke/proc/Chilled(atom/A)
|
||||
/datum/effect/effect/system/smoke_spread/freezing/proc/Chilled(atom/A)
|
||||
if(istype(A, /turf/simulated))
|
||||
var/turf/simulated/T = A
|
||||
if(T.air)
|
||||
@@ -364,29 +349,16 @@
|
||||
L.ExtinguishMob()
|
||||
return
|
||||
|
||||
/datum/effect/effect/system/freezing_smoke_spread
|
||||
/datum/effect/effect/system/smoke_spread/freezing/set_up(n = 5, c = 0, loca, direct, blasting = 0)
|
||||
..()
|
||||
blast = blasting
|
||||
|
||||
/datum/effect/effect/system/freezing_smoke_spread/set_up(n = 6, c = 0, loca)
|
||||
number = n
|
||||
if(istype(loca, /turf/))
|
||||
location = loca
|
||||
else
|
||||
location = get_turf(loca)
|
||||
/datum/effect/effect/system/smoke_spread/freezing/start()
|
||||
if(blast)
|
||||
for(var/turf/T in trange(2, location))
|
||||
Chilled(T)
|
||||
..()
|
||||
|
||||
/datum/effect/effect/system/freezing_smoke_spread/start()
|
||||
var/i = 0
|
||||
for(i=0, i<number, i++)
|
||||
spawn(0)
|
||||
var/obj/effect/effect/freezing_smoke/smoke = PoolOrNew(/obj/effect/effect/freezing_smoke, list(location, 0, 0))
|
||||
smoke.amount = 0
|
||||
var/direction = pick(alldirs)
|
||||
for(i=0, i<rand(1,3), i++)
|
||||
sleep(5)
|
||||
step(smoke,direction)
|
||||
spawn(150+rand(10,30))
|
||||
if(smoke)
|
||||
fadeOut(smoke)
|
||||
qdel(smoke)
|
||||
|
||||
#undef EXTINGUISHER
|
||||
#undef NANOFROST
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
/obj/structure/hivebot_beacon/New()
|
||||
..()
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new
|
||||
smoke.set_up(5, 0, src.loc)
|
||||
smoke.start()
|
||||
visible_message("<span class='boldannounce'>The [src] warps in!</span>")
|
||||
|
||||
@@ -222,7 +222,7 @@
|
||||
/obj/item/clothing/mask/gas/clown_hat
|
||||
name = "clown wig and mask"
|
||||
desc = "A true prankster's facial attire. A clown is incomplete without his wig and mask."
|
||||
flags = MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS
|
||||
flags = MASKCOVERSEYES | MASKINTERNALS
|
||||
icon_state = "clown"
|
||||
item_state = "clown_hat"
|
||||
|
||||
@@ -245,28 +245,28 @@
|
||||
/obj/item/clothing/mask/gas/sexyclown
|
||||
name = "sexy-clown wig and mask"
|
||||
desc = "A feminine clown mask for the dabbling crossdressers or female entertainers."
|
||||
flags = MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS
|
||||
flags = MASKCOVERSEYES | MASKINTERNALS
|
||||
icon_state = "sexyclown"
|
||||
item_state = "sexyclown"
|
||||
|
||||
/obj/item/clothing/mask/gas/mime
|
||||
name = "mime mask"
|
||||
desc = "The traditional mime's mask. It has an eerie facial posture."
|
||||
flags = MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS
|
||||
flags = MASKCOVERSEYES | MASKINTERNALS
|
||||
icon_state = "mime"
|
||||
item_state = "mime"
|
||||
|
||||
/obj/item/clothing/mask/gas/monkeymask
|
||||
name = "monkey mask"
|
||||
desc = "A mask used when acting as a monkey."
|
||||
flags = MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS
|
||||
flags = MASKCOVERSEYES | MASKINTERNALS
|
||||
icon_state = "monkeymask"
|
||||
item_state = "monkeymask"
|
||||
|
||||
/obj/item/clothing/mask/gas/sexymime
|
||||
name = "sexy mime mask"
|
||||
desc = "A traditional female mime's mask."
|
||||
flags = MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS
|
||||
flags = MASKCOVERSEYES | MASKINTERNALS
|
||||
icon_state = "sexymime"
|
||||
item_state = "sexymime"
|
||||
|
||||
@@ -283,5 +283,5 @@
|
||||
/obj/item/clothing/mask/gas/owl_mask
|
||||
name = "owl mask"
|
||||
desc = "Twoooo!"
|
||||
flags = MASKCOVERSEYES | BLOCK_GAS_SMOKE_EFFECT | MASKINTERNALS
|
||||
flags = MASKCOVERSEYES | MASKINTERNALS
|
||||
icon_state = "owl"
|
||||
@@ -33,7 +33,7 @@
|
||||
R.my_atom = vent
|
||||
R.add_reagent(pick(gunk), 50)
|
||||
|
||||
var/datum/effect/effect/system/chem_smoke_spread/smoke = new
|
||||
var/datum/effect/effect/system/smoke_spread/chem/smoke = new
|
||||
smoke.set_up(R, rand(1, 2), 0, vent, 0, silent = 1)
|
||||
playsound(vent.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
smoke.start()
|
||||
|
||||
@@ -43,6 +43,6 @@
|
||||
I.name = "cursed " + I.name
|
||||
|
||||
for(var/mob/living/carbon/human/H in living_mob_list)
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new
|
||||
smoke.set_up(max(1,1), 0, H.loc)
|
||||
smoke.start()
|
||||
@@ -14,7 +14,7 @@
|
||||
if(!candidates) return //Sad Trombone
|
||||
var/client/C = pick(candidates)
|
||||
|
||||
PoolOrNew(/obj/effect/effect/harmless_smoke, W.loc)
|
||||
PoolOrNew(/obj/effect/effect/smoke, W.loc)
|
||||
|
||||
var/mob/living/carbon/human/I = new /mob/living/carbon/human(W.loc)
|
||||
I.real_name = W.real_name
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
moblocs.len -= 1
|
||||
|
||||
for(var/mob/living/carbon/human/H in living_mob_list)
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new
|
||||
smoke.set_up(max(1,1), 0, H.loc)
|
||||
smoke.start()
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
mobnames.len -= 1
|
||||
|
||||
for(var/mob/living/carbon/human/H in living_mob_list)
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new
|
||||
smoke.set_up(max(1,1), 0, H.loc)
|
||||
smoke.start()
|
||||
|
||||
@@ -92,6 +92,6 @@
|
||||
mobs -= mobs[mobs.len]
|
||||
|
||||
for(var/mob/living/carbon/human/H in living_mob_list)
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new
|
||||
smoke.set_up(max(1,1), 0, H.loc)
|
||||
smoke.start()
|
||||
|
||||
@@ -34,24 +34,19 @@
|
||||
|
||||
if(M == user)
|
||||
M << "<span class='notice'>You swallow a gulp of [src].</span>"
|
||||
if(reagents.total_volume)
|
||||
reagents.reaction(M, INGEST)
|
||||
spawn(5)
|
||||
reagents.trans_to(M, gulp_size)
|
||||
else
|
||||
|
||||
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
|
||||
return 1
|
||||
|
||||
user.visible_message("<span class='warning'>[user] attempts to feed [src] to [M].</span>", "<span class='notice'>You attempt to feed [src] to [M].</span>")
|
||||
if(!do_mob(user, M)) return
|
||||
if(!reagents.total_volume) return // The drink might be empty after the delay, such as by spam-feeding
|
||||
user.visible_message("<span class='warning'>[user] feeds [src] to [M].</span>", "<span class='notice'>You feed [src] to [M].</span>")
|
||||
add_logs(user, M, "fed", object="[reagentlist(src)]")
|
||||
if(reagents.total_volume)
|
||||
reagents.reaction(M, INGEST)
|
||||
spawn(5)
|
||||
reagents.trans_to(M, gulp_size)
|
||||
user.visible_message("<span class='warning'>[user] attempts to feed [src] to [M].</span>", "<span class='notice'>You attempt to feed [src] to [M].</span>")
|
||||
if(!do_mob(user, M))
|
||||
return
|
||||
if(!reagents || !reagents.total_volume)
|
||||
return // The drink might be empty after the delay, such as by spam-feeding
|
||||
user.visible_message("<span class='warning'>[user] feeds [src] to [M].</span>", "<span class='notice'>You feed [src] to [M].</span>")
|
||||
add_logs(user, M, "fed", object="[reagentlist(src)]")
|
||||
|
||||
var/fraction = min(gulp_size/reagents.total_volume, 1)
|
||||
reagents.reaction(M, INGEST, fraction)
|
||||
reagents.trans_to(M, gulp_size)
|
||||
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -30,9 +30,8 @@
|
||||
return
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/condiment/attack(mob/M as mob, mob/user as mob, def_zone)
|
||||
var/datum/reagents/R = src.reagents
|
||||
|
||||
if(!R || !R.total_volume)
|
||||
if(!reagents || !reagents.total_volume)
|
||||
user << "<span class='warning'>None of [src] left, oh no!</span>"
|
||||
return 0
|
||||
|
||||
@@ -41,28 +40,20 @@
|
||||
|
||||
if(M == user)
|
||||
M << "<span class='notice'>You swallow some of contents of \the [src].</span>"
|
||||
if(reagents.total_volume)
|
||||
reagents.reaction(M, INGEST)
|
||||
spawn(5)
|
||||
reagents.trans_to(M, 10)
|
||||
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
|
||||
return 1
|
||||
|
||||
else
|
||||
user.visible_message("<span class='warning'>[user] attempts to feed [M] from [src].</span>")
|
||||
if(!do_mob(user, M)) return
|
||||
if(!do_mob(user, M))
|
||||
return
|
||||
if(!reagents || !reagents.total_volume)
|
||||
return // The condiment might be empty after the delay.
|
||||
user.visible_message("<span class='warning'>[user] feeds [M] from [src].</span>")
|
||||
|
||||
add_logs(user, M, "fed", object="[reagentlist(src)]")
|
||||
|
||||
if(reagents.total_volume)
|
||||
reagents.reaction(M, INGEST)
|
||||
spawn(5)
|
||||
reagents.trans_to(M, 10)
|
||||
|
||||
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
|
||||
return 1
|
||||
return 0
|
||||
var/fraction = min(10/reagents.total_volume, 1)
|
||||
reagents.reaction(M, INGEST, fraction)
|
||||
reagents.trans_to(M, 10)
|
||||
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
|
||||
return 1
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/condiment/afterattack(obj/target, mob/user , proximity)
|
||||
if(!proximity) return
|
||||
|
||||
@@ -105,14 +105,11 @@
|
||||
M.satiety -= junkiness
|
||||
playsound(M.loc,'sound/items/eatfood.ogg', rand(10,50), 1)
|
||||
if(reagents.total_volume)
|
||||
reagents.reaction(M, INGEST)
|
||||
spawn(5)
|
||||
if(reagents.total_volume > bitesize) //pretty sure this is unnecessary
|
||||
reagents.trans_to(M, bitesize)
|
||||
else
|
||||
reagents.trans_to(M, reagents.total_volume)
|
||||
bitecount++
|
||||
On_Consume()
|
||||
var/fraction = min(bitesize/reagents.total_volume, 1)
|
||||
reagents.reaction(M, INGEST, fraction)
|
||||
reagents.trans_to(M, bitesize)
|
||||
bitecount++
|
||||
On_Consume()
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
@@ -146,3 +146,6 @@
|
||||
|
||||
/mob/living/carbon/alien/humanoid/check_ear_prot()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/carbon/alien/humanoid/get_permeability_protection()
|
||||
return 0.8
|
||||
@@ -238,6 +238,9 @@ emp_act
|
||||
/mob/living/carbon/human/acid_act(var/acidpwr, var/toxpwr, var/acid_volume)
|
||||
var/list/damaged = list()
|
||||
var/list/inventory_items_to_kill = list()
|
||||
var/acidity = min(acidpwr*acid_volume/200, toxpwr)
|
||||
var/acid_volume_left = acid_volume
|
||||
var/acid_decay = 200/acidpwr // how much volume we lose per item we try to melt. 10 for fluoro, 20 for sulphuric
|
||||
|
||||
//HEAD//
|
||||
var/obj/item/clothing/head_clothes = null
|
||||
@@ -249,7 +252,8 @@ emp_act
|
||||
head_clothes = head
|
||||
if(head_clothes)
|
||||
if(!head_clothes.unacidable)
|
||||
head_clothes.acid_act(acidpwr)
|
||||
head_clothes.acid_act(acidpwr, acid_volume_left)
|
||||
acid_volume_left = max(acid_volume_left - acid_decay, 0) //We remove some of the acid volume.
|
||||
update_inv_glasses()
|
||||
update_inv_wear_mask()
|
||||
update_inv_head()
|
||||
@@ -270,7 +274,8 @@ emp_act
|
||||
chest_clothes = wear_suit
|
||||
if(chest_clothes)
|
||||
if(!chest_clothes.unacidable)
|
||||
chest_clothes.acid_act(acidpwr)
|
||||
chest_clothes.acid_act(acidpwr, acid_volume_left)
|
||||
acid_volume_left = max(acid_volume_left - acid_decay, 0)
|
||||
update_inv_w_uniform()
|
||||
update_inv_wear_suit()
|
||||
else
|
||||
@@ -299,7 +304,8 @@ emp_act
|
||||
arm_clothes = wear_suit
|
||||
if(arm_clothes)
|
||||
if(!arm_clothes.unacidable)
|
||||
arm_clothes.acid_act(acidpwr)
|
||||
arm_clothes.acid_act(acidpwr, acid_volume_left)
|
||||
acid_volume_left = max(acid_volume_left - acid_decay, 0)
|
||||
update_inv_gloves()
|
||||
update_inv_w_uniform()
|
||||
update_inv_wear_suit()
|
||||
@@ -324,7 +330,8 @@ emp_act
|
||||
leg_clothes = wear_suit
|
||||
if(leg_clothes)
|
||||
if(!leg_clothes.unacidable)
|
||||
leg_clothes.acid_act(acidpwr)
|
||||
leg_clothes.acid_act(acidpwr, acid_volume_left)
|
||||
acid_volume_left = max(acid_volume_left - acid_decay, 0)
|
||||
update_inv_shoes()
|
||||
update_inv_w_uniform()
|
||||
update_inv_wear_suit()
|
||||
@@ -341,11 +348,11 @@ emp_act
|
||||
|
||||
//DAMAGE//
|
||||
for(var/obj/item/organ/limb/affecting in damaged)
|
||||
affecting.take_damage(2*toxpwr, toxpwr)
|
||||
affecting.take_damage(acidity, 2*acidity)
|
||||
|
||||
if(affecting.name == "head")
|
||||
affecting.take_damage(2*toxpwr, toxpwr)
|
||||
if(prob(2*acidpwr)) //Applies disfigurement
|
||||
if(prob(min(acidpwr*acid_volume/10, 90))) //Applies disfigurement
|
||||
affecting.take_damage(acidity, 2*acidity)
|
||||
emote("scream")
|
||||
facial_hair_style = "Shaved"
|
||||
hair_style = "Bald"
|
||||
@@ -366,7 +373,8 @@ emp_act
|
||||
inventory_items_to_kill += l_hand
|
||||
|
||||
for(var/obj/item/I in inventory_items_to_kill)
|
||||
I.acid_act(acidpwr)
|
||||
I.acid_act(acidpwr, acid_volume_left)
|
||||
acid_volume_left = max(acid_volume_left - acid_decay, 0)
|
||||
|
||||
/mob/living/carbon/human/grabbedby(mob/living/user)
|
||||
if(w_uniform)
|
||||
|
||||
@@ -139,10 +139,30 @@
|
||||
|
||||
/mob/living/carbon/human/can_track(mob/living/user)
|
||||
if(wear_id && istype(wear_id.GetID(), /obj/item/weapon/card/id/syndicate))
|
||||
return 0
|
||||
return 0
|
||||
if(istype(head, /obj/item/clothing/head))
|
||||
var/obj/item/clothing/head/hat = head
|
||||
if(hat.blockTracking)
|
||||
return 0
|
||||
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/get_permeability_protection()
|
||||
var/list/prot = list("hands"=0, "chest"=0, "groin"=0, "legs"=0, "feet"=0, "arms"=0, "head"=0)
|
||||
for(var/obj/item/I in get_equipped_items())
|
||||
if(I.body_parts_covered & HANDS)
|
||||
prot["hands"] = max(1 - I.permeability_coefficient, prot["hands"])
|
||||
if(I.body_parts_covered & CHEST)
|
||||
prot["chest"] = max(1 - I.permeability_coefficient, prot["chest"])
|
||||
if(I.body_parts_covered & GROIN)
|
||||
prot["groin"] = max(1 - I.permeability_coefficient, prot["groin"])
|
||||
if(I.body_parts_covered & LEGS)
|
||||
prot["legs"] = max(1 - I.permeability_coefficient, prot["legs"])
|
||||
if(I.body_parts_covered & FEET)
|
||||
prot["feet"] = max(1 - I.permeability_coefficient, prot["feet"])
|
||||
if(I.body_parts_covered & ARMS)
|
||||
prot["arms"] = max(1 - I.permeability_coefficient, prot["arms"])
|
||||
if(I.body_parts_covered & HEAD)
|
||||
prot["head"] = max(1 - I.permeability_coefficient, prot["head"])
|
||||
var/protection = (prot["head"] + prot["arms"] + prot["feet"] + prot["legs"] + prot["groin"] + prot["chest"] + prot["hands"])/7
|
||||
return protection
|
||||
@@ -1101,13 +1101,14 @@
|
||||
|
||||
// Handle chem smoke effect -- Doohl
|
||||
if(!H.has_smoke_protection())
|
||||
for(var/obj/effect/effect/chem_smoke/smoke in view(1, H))
|
||||
if(smoke.reagents.total_volume)
|
||||
smoke.reagents.reaction(H, INGEST)
|
||||
spawn(5)
|
||||
if(smoke)
|
||||
smoke.reagents.copy_to(H, 10) // I dunno, maybe the reagents enter the blood stream through the lungs?
|
||||
break // If they breathe in the nasty stuff once, no need to continue checking
|
||||
for(var/obj/effect/effect/smoke/chem/S in range(1, H))
|
||||
if(S.reagents.total_volume)
|
||||
var/amount = min(S.reagents.total_volume/2, 10)
|
||||
if(amount >= 1)
|
||||
var/fraction = min(amount/S.reagents.total_volume, 1)
|
||||
S.reagents.reaction(H,INGEST, fraction)
|
||||
S.reagents.trans_to(H, amount)
|
||||
break // If they breathe in the nasty stuff once, no need to continue checking
|
||||
|
||||
else //Still give containing object the chance to interact
|
||||
if(istype(H.loc, /obj/))
|
||||
|
||||
@@ -71,12 +71,12 @@
|
||||
|
||||
//Harmful gasses
|
||||
if(!has_smoke_protection())
|
||||
for(var/obj/effect/effect/chem_smoke/smoke in view(1,src))
|
||||
if(smoke.reagents.total_volume)
|
||||
smoke.reagents.reaction(src,INGEST)
|
||||
spawn(5)
|
||||
if(smoke)
|
||||
smoke.reagents.copy_to(src, 10)
|
||||
for(var/obj/effect/effect/smoke/chem/S in range(1,src))
|
||||
if(S.reagents.total_volume)
|
||||
var/amount = min(S.reagents.total_volume, 10)
|
||||
var/fraction = min(amount/S.reagents.total_volume, 1)
|
||||
S.reagents.reaction(src,INGEST, fraction)
|
||||
S.reagents.copy_to(src, amount)
|
||||
break
|
||||
|
||||
else //Breathe from loc as obj again
|
||||
|
||||
@@ -255,7 +255,7 @@
|
||||
src << "<span class='warning'>Your mask protects you from the acid.</span>"
|
||||
return
|
||||
|
||||
take_organ_damage(min(6*toxpwr, acid_volume * toxpwr))
|
||||
take_organ_damage(min(6*toxpwr, acid_volume * acidpwr/10))
|
||||
|
||||
/mob/living/carbon/monkey/help_shake_act(mob/living/carbon/M)
|
||||
if(health < 0 && ishuman(M))
|
||||
@@ -263,3 +263,12 @@
|
||||
H.do_cpr(src)
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/get_permeability_protection()
|
||||
var/protection = 0
|
||||
if(head)
|
||||
protection = 1 - head.permeability_coefficient
|
||||
if(wear_mask)
|
||||
protection = max(1 - wear_mask.permeability_coefficient, protection)
|
||||
protection = protection/7 //the rest of the body isn't covered.
|
||||
return protection
|
||||
@@ -858,3 +858,7 @@ Sorry Giacom. Please don't be mad :(
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
//used in datum/reagents/reaction() proc
|
||||
/mob/living/proc/get_permeability_protection()
|
||||
return 0
|
||||
@@ -43,4 +43,6 @@
|
||||
var/list/datum/action/actions = list()
|
||||
|
||||
var/list/pipes_shown = list()
|
||||
var/last_played_vent
|
||||
var/last_played_vent
|
||||
|
||||
var/smoke_delay = 0 //used to prevent spam with smoke reagent reaction on mob.
|
||||
@@ -101,8 +101,6 @@
|
||||
emag.reagents.add_reagent("facid", 250)
|
||||
emag.name = "Fluacid spray"
|
||||
|
||||
var/obj/item/weapon/reagent_containers/spray/S = emag
|
||||
S.banned_reagents = list()
|
||||
|
||||
var/datum/robot_energy_storage/gauze/gauzestore = new /datum/robot_energy_storage/gauze(src)
|
||||
|
||||
|
||||
@@ -100,8 +100,6 @@
|
||||
|
||||
var/in_throw_mode = 0
|
||||
|
||||
var/coughedtime = null
|
||||
|
||||
var/music_lastplayed = "null"
|
||||
|
||||
var/job = null//Living
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
spawn(30)//Slight delay so the enemy does not immedietly know the ability was used. Due to lag, this often came before waking up.
|
||||
H.say(pick("A CORNERED FOX IS MORE DANGEROUS THAN A JACKAL!","HURT ME MOOORRREEE!","IMPRESSIVE!"))
|
||||
spawn(70)
|
||||
reagents.reaction(H, 2)
|
||||
reagents.reaction(H, INGEST)
|
||||
reagents.trans_id_to(H, "radium", a_transfer)
|
||||
H << "<span class='danger'>You are beginning to feel the after-effect of the injection.</span>"
|
||||
a_boost--
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
if(!ninjacost(0,N_SMOKE_BOMB))
|
||||
var/mob/living/carbon/human/H = affecting
|
||||
var/datum/effect/effect/system/bad_smoke_spread/smoke = new /datum/effect/effect/system/bad_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/bad/smoke = new
|
||||
smoke.set_up(10, 0, H.loc)
|
||||
smoke.start()
|
||||
playsound(H.loc, 'sound/effects/bamf.ogg', 50, 2)
|
||||
|
||||
@@ -945,11 +945,11 @@
|
||||
cell.corrupt()
|
||||
src.malfhack = 1
|
||||
update_icon()
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new
|
||||
smoke.set_up(3, 0, src.loc)
|
||||
smoke.attach(src)
|
||||
smoke.start()
|
||||
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
|
||||
var/datum/effect/effect/system/spark_spread/s = new
|
||||
s.set_up(3, 1, src)
|
||||
s.start()
|
||||
visible_message("<span class='warning'>The [src.name] suddenly lets out a blast of smoke and some sparks!</span>", \
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
user << "Your soul is too far away."
|
||||
return
|
||||
makeNewConstruct(/mob/living/simple_animal/construct/harvester, user, null, 1)
|
||||
PoolOrNew(/obj/effect/effect/sleep_smoke, user.loc)
|
||||
PoolOrNew(/obj/effect/effect/smoke/sleeping, user.loc)
|
||||
|
||||
|
||||
/obj/singularity/narsie/process()
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
|
||||
/obj/item/weapon/gun/magic/wand/teleport/zap_self(mob/living/user as mob)
|
||||
do_teleport(user, user, 10)
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new
|
||||
smoke.set_up(10, 0, user.loc)
|
||||
smoke.start()
|
||||
charges--
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
if(!stuff.anchored && stuff.loc)
|
||||
teleammount++
|
||||
do_teleport(stuff, stuff, 10)
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new /datum/effect/effect/system/harmless_smoke_spread()
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new
|
||||
smoke.set_up(max(round(10 - teleammount),1), 0, stuff.loc) //Smoke drops off if a lot of stuff is moved for the sake of sanity
|
||||
smoke.start()
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ var/const/INGEST = 2
|
||||
var/current_reagent_transfer = current_reagent.volume * part
|
||||
if(preserve_data)
|
||||
trans_data = copy_data(current_reagent)
|
||||
R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data, src.chem_temp)
|
||||
R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data, src.chem_temp, no_react = 1) //we only handle reaction after every reagent has been transfered.
|
||||
src.remove_reagent(current_reagent.id, current_reagent_transfer)
|
||||
|
||||
src.update_total()
|
||||
@@ -426,17 +426,21 @@ var/const/INGEST = 2
|
||||
return 0
|
||||
|
||||
/datum/reagents/proc/reaction(var/atom/A, var/method=TOUCH, var/volume_modifier=1,var/show_message=1)
|
||||
for(var/datum/reagent/R in reagent_list)
|
||||
if(ismob(A))
|
||||
R.reaction_mob(A, method, R.volume*volume_modifier, show_message)
|
||||
if(isturf(A))
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
var/touch_protection = 0
|
||||
if(method == TOUCH)
|
||||
touch_protection = L.get_permeability_protection()
|
||||
for(var/datum/reagent/R in reagent_list)
|
||||
R.reaction_mob(L, method, R.volume*volume_modifier, show_message, touch_protection)
|
||||
else if(isturf(A))
|
||||
for(var/datum/reagent/R in reagent_list)
|
||||
R.reaction_turf(A, R.volume*volume_modifier, show_message)
|
||||
if(isobj(A))
|
||||
else if(isobj(A))
|
||||
for(var/datum/reagent/R in reagent_list)
|
||||
R.reaction_obj(A, R.volume*volume_modifier, show_message)
|
||||
|
||||
return
|
||||
|
||||
/datum/reagents/proc/add_reagent(var/reagent, var/amount, var/list/data=null, var/reagtemp = 300)
|
||||
/datum/reagents/proc/add_reagent(var/reagent, var/amount, var/list/data=null, var/reagtemp = 300, var/no_react = 0)
|
||||
if(!isnum(amount) || !amount)
|
||||
return 1
|
||||
update_total()
|
||||
@@ -451,7 +455,8 @@ var/const/INGEST = 2
|
||||
update_total()
|
||||
my_atom.on_reagent_change()
|
||||
R.on_merge(data)
|
||||
handle_reactions()
|
||||
if(!no_react)
|
||||
handle_reactions()
|
||||
return 0
|
||||
|
||||
var/datum/reagent/D = chemical_reagents_list[reagent]
|
||||
@@ -465,19 +470,16 @@ var/const/INGEST = 2
|
||||
R.data = data
|
||||
R.on_new(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()
|
||||
handle_reactions()
|
||||
if(!no_react)
|
||||
handle_reactions()
|
||||
return 0
|
||||
else
|
||||
WARNING("[my_atom] attempted to add a reagent called ' [reagent] ' which doesn't exist. ([usr])")
|
||||
|
||||
handle_reactions()
|
||||
if(!no_react)
|
||||
handle_reactions()
|
||||
|
||||
return 1
|
||||
|
||||
|
||||
@@ -34,43 +34,22 @@
|
||||
..()
|
||||
holder = null
|
||||
|
||||
/datum/reagent/proc/reaction_mob(var/mob/M, var/method=TOUCH, var/volume, var/show_message = 1) //By default we have a chance to transfer some
|
||||
if(!istype(M, /mob/living))
|
||||
/datum/reagent/proc/reaction_mob(var/mob/living/M, var/method=TOUCH, var/volume, var/show_message = 1, var/touch_protection = 0)
|
||||
if(!istype(M))
|
||||
return 0
|
||||
var/datum/reagent/self = src
|
||||
src = null //of the reagent to the mob on TOUCHING it.
|
||||
src = null
|
||||
|
||||
if(!istype(self.holder.my_atom, /obj/effect/effect/chem_smoke))
|
||||
// If the chemicals are in a smoke cloud, do not try to let the chemicals "penetrate" into the mob's system (balance station 13) -- Doohl
|
||||
|
||||
if(method == TOUCH)
|
||||
|
||||
var/chance = 1
|
||||
var/block = 0
|
||||
|
||||
for(var/obj/item/clothing/C in M.get_equipped_items())
|
||||
if(C.permeability_coefficient < chance) chance = C.permeability_coefficient
|
||||
if(istype(C, /obj/item/clothing/suit/bio_suit))
|
||||
// bio suits are just about completely fool-proof - Doohl
|
||||
// kind of a hacky way of making bio suits more resistant to chemicals but w/e
|
||||
if(prob(75))
|
||||
block = 1
|
||||
|
||||
if(istype(C, /obj/item/clothing/head/bio_hood))
|
||||
if(prob(75))
|
||||
block = 1
|
||||
|
||||
chance = chance * 100
|
||||
|
||||
if(prob(chance) && !block)
|
||||
if(M.reagents)
|
||||
M.reagents.add_reagent(self.id,self.volume/2)
|
||||
if(method == TOUCH)
|
||||
if(M.reagents)
|
||||
var/modifier = Clamp((1 - touch_protection) + rand(-5,5)/100, 0, 1)
|
||||
var/amount = round(volume*modifier)
|
||||
if(amount >= 1)
|
||||
M.reagents.add_reagent(self.id, amount)
|
||||
return 1
|
||||
|
||||
/datum/reagent/proc/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)
|
||||
/datum/reagent/proc/reaction_obj(var/obj/O, var/volume)
|
||||
src = null
|
||||
return
|
||||
|
||||
/datum/reagent/proc/reaction_turf(var/turf/T, var/volume)
|
||||
|
||||
@@ -143,10 +143,10 @@
|
||||
|
||||
/datum/chemical_reaction/foam/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
|
||||
world << "holder volb4:[holder.total_volume]"
|
||||
for(var/mob/M in viewers(5, location))
|
||||
M << "<span class='danger'>The solution spews out foam!</span>"
|
||||
|
||||
world << "holder vol w/o created vol:[holder.total_volume]"
|
||||
var/datum/effect/effect/system/foam_spread/s = new()
|
||||
s.set_up(created_volume, location, holder)
|
||||
s.start()
|
||||
|
||||
@@ -215,20 +215,19 @@
|
||||
/datum/chemical_reaction/smoke_powder/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
if(holder.has_reagent("stabilizing_agent"))
|
||||
return
|
||||
world << "holder volb4:[holder.total_volume]"
|
||||
holder.remove_reagent("smoke_powder", created_volume)
|
||||
world << "holder vol w/o created vol:[holder.total_volume]"
|
||||
var/smoke_amount = round(Clamp(created_volume/5, 1, 20),1)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
var/datum/effect/effect/system/chem_smoke_spread/S = new /datum/effect/effect/system/chem_smoke_spread
|
||||
var/datum/effect/effect/system/smoke_spread/chem/S = new
|
||||
S.attach(location)
|
||||
playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
spawn(0)
|
||||
if(S)
|
||||
S.set_up(holder, 10, 0, location)
|
||||
S.start()
|
||||
sleep(10)
|
||||
S.start()
|
||||
if(holder && holder.my_atom)
|
||||
holder.clear_reagents()
|
||||
return
|
||||
if(S)
|
||||
S.set_up(holder, smoke_amount, 0, location)
|
||||
S.start()
|
||||
if(holder && holder.my_atom)
|
||||
holder.clear_reagents()
|
||||
|
||||
/datum/chemical_reaction/smoke_powder_smoke
|
||||
name = "smoke_powder_smoke"
|
||||
@@ -242,18 +241,16 @@
|
||||
|
||||
/datum/chemical_reaction/smoke_powder_smoke/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
var/datum/effect/effect/system/chem_smoke_spread/S = new /datum/effect/effect/system/chem_smoke_spread
|
||||
var/smoke_amount = round(Clamp(created_volume/5, 1, 20),1)
|
||||
var/datum/effect/effect/system/smoke_spread/chem/S = new
|
||||
S.attach(location)
|
||||
playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
spawn(0)
|
||||
if(S)
|
||||
S.set_up(holder, 10, 0, location)
|
||||
S.start()
|
||||
sleep(10)
|
||||
S.start()
|
||||
if(holder && holder.my_atom)
|
||||
holder.clear_reagents()
|
||||
return
|
||||
if(S)
|
||||
S.set_up(holder, smoke_amount, 0, location)
|
||||
S.start()
|
||||
if(holder && holder.my_atom)
|
||||
holder.clear_reagents()
|
||||
|
||||
|
||||
|
||||
/datum/chemical_reaction/sonic_powder
|
||||
@@ -318,6 +315,7 @@
|
||||
var/turf/simulated/T = get_turf(holder.my_atom)
|
||||
if(istype(T))
|
||||
T.atmos_spawn_air(SPAWN_HEAT | SPAWN_TOXINS, created_volume)
|
||||
holder.clear_reagents()
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
var/amount_per_transfer_from_this = 5
|
||||
var/possible_transfer_amounts = list(5,10,15,25,30)
|
||||
var/volume = 30
|
||||
var/list/banned_reagents = list() //List of reagent IDs we reject.
|
||||
var/list/list_reagents = null
|
||||
var/spawned_disease = null
|
||||
var/disease_amount = 20
|
||||
|
||||
@@ -92,7 +92,8 @@ Borg Hypospray
|
||||
if (R.total_volume && M.can_inject(user, 1))
|
||||
M << "<span class='warning'>You feel a tiny prick!</span>"
|
||||
user << "<span class='notice'>You inject [M] with the injector.</span>"
|
||||
R.reaction(M, INGEST)
|
||||
var/fraction = min(amount_per_transfer_from_this/R.total_volume, 1)
|
||||
R.reaction(M, INGEST, fraction)
|
||||
if(M.reagents)
|
||||
var/trans = R.trans_to(M, amount_per_transfer_from_this)
|
||||
user << "<span class='notice'>[trans] unit\s injected. [R.total_volume] unit\s remaining.</span>"
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
return
|
||||
|
||||
var/trans = 0
|
||||
var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1)
|
||||
|
||||
if(ismob(target))
|
||||
if(istype(target , /mob/living/carbon/human))
|
||||
@@ -40,12 +41,12 @@
|
||||
if(safe_thing)
|
||||
if(!safe_thing.reagents)
|
||||
safe_thing.create_reagents(100)
|
||||
|
||||
reagents.reaction(safe_thing, TOUCH, fraction)
|
||||
trans = reagents.trans_to(safe_thing, amount_per_transfer_from_this)
|
||||
|
||||
target.visible_message("<span class='danger'>[user] tries to squirt something into [target]'s eyes, but fails!</span>", \
|
||||
"<span class='userdanger'>[user] tries to squirt something into [target]'s eyes, but fails!</span>")
|
||||
spawn(5)
|
||||
reagents.reaction(safe_thing, TOUCH)
|
||||
|
||||
user << "<span class='notice'>You transfer [trans] unit\s of the solution.</span>"
|
||||
update_icon()
|
||||
@@ -53,7 +54,8 @@
|
||||
|
||||
target.visible_message("<span class='danger'>[user] squirts something into [target]'s eyes!</span>", \
|
||||
"<span class='userdanger'>[user] squirts something into [target]'s eyes!</span>")
|
||||
reagents.reaction(target, TOUCH)
|
||||
|
||||
reagents.reaction(target, TOUCH, fraction)
|
||||
var/mob/M = target
|
||||
var/R
|
||||
if(reagents)
|
||||
|
||||
@@ -72,12 +72,6 @@
|
||||
user << "<span class='notice'>[target] is full.</span>"
|
||||
return
|
||||
|
||||
if(istype(target, /obj/item/weapon/reagent_containers))
|
||||
var/obj/item/weapon/reagent_containers/RC = target
|
||||
for(var/bad_reg in RC.banned_reagents)
|
||||
if(reagents.has_reagent(bad_reg, 1)) //Message is a bit "Game-y" but I can't think up a better one.
|
||||
user << "<span class='warning'>A chemical in [src] is far too dangerous to transfer to [RC]!</span>"
|
||||
return
|
||||
|
||||
var/trans = reagents.trans_to(target, amount_per_transfer_from_this)
|
||||
user << "<span class='notice'>You transfer [trans] unit\s of the solution to [target].</span>"
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
M << "<span class='warning'>You feel a tiny prick!</span>"
|
||||
user << "<span class='notice'>You inject [M] with [src].</span>"
|
||||
|
||||
reagents.reaction(M, INGEST)
|
||||
var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1)
|
||||
reagents.reaction(M, INGEST, fraction)
|
||||
if(M.reagents)
|
||||
var/list/injected = list()
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
|
||||
@@ -45,10 +45,9 @@
|
||||
|
||||
if(reagents.total_volume)
|
||||
reagents.reaction(M, apply_type)
|
||||
spawn(5)
|
||||
reagents.trans_to(M, reagents.total_volume)
|
||||
qdel(src)
|
||||
return 1
|
||||
reagents.trans_to(M, reagents.total_volume)
|
||||
qdel(src)
|
||||
return 1
|
||||
else
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
amount_per_transfer_from_this = 5
|
||||
volume = 250
|
||||
possible_transfer_amounts = null
|
||||
banned_reagents = list("facid","sacid")
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/spray/afterattack(atom/A as mob|obj, mob/user as mob)
|
||||
@@ -159,7 +158,6 @@
|
||||
amount_per_transfer_from_this = 10
|
||||
volume = 600
|
||||
origin_tech = "combat=3;materials=3;engineering=3"
|
||||
banned_reagents = list()//the safeties are off, spray and pay!
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/spray/chemsprayer/spray(var/atom/A)
|
||||
|
||||
@@ -151,7 +151,8 @@
|
||||
var/contained = english_list(rinject)
|
||||
var/mob/M = target
|
||||
add_logs(user, M, "injected", object="[src.name]", addition="which had [contained]")
|
||||
reagents.reaction(target, INGEST)
|
||||
var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1)
|
||||
reagents.reaction(target, INGEST, fraction)
|
||||
if(ismob(target) && target == user)
|
||||
//Attack log entries are produced here due to failure to produce elsewhere. Remove them here if you have doubles from normal syringes.
|
||||
var/list/rinject = list()
|
||||
@@ -161,8 +162,8 @@
|
||||
var/mob/M = target
|
||||
log_attack("<font color='red'>[user.name] ([user.ckey]) injected [M.name] ([M.ckey]) with [src.name], which had [contained] (INTENT: [uppertext(user.a_intent)])</font>")
|
||||
M.attack_log += text("\[[time_stamp()]\] <font color='orange'>Injected themselves ([contained]) with [src.name].</font>")
|
||||
|
||||
reagents.reaction(target, INGEST)
|
||||
var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1)
|
||||
reagents.reaction(target, INGEST, fraction)
|
||||
spawn(5)
|
||||
var/datum/reagent/blood/B
|
||||
for(var/datum/reagent/blood/d in src.reagents.reagent_list)
|
||||
|
||||
@@ -230,7 +230,7 @@
|
||||
loaded_item = null
|
||||
|
||||
/obj/machinery/r_n_d/experimentor/proc/throwSmoke(var/turf/where)
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new
|
||||
smoke.set_up(1,0, where, 0)
|
||||
smoke.start()
|
||||
|
||||
@@ -322,7 +322,7 @@
|
||||
R.my_atom = src
|
||||
R.add_reagent(chosenchem , 50)
|
||||
investigate_log("Experimentor has released [chosenchem] smoke.", "experimentor")
|
||||
var/datum/effect/effect/system/chem_smoke_spread/smoke = new
|
||||
var/datum/effect/effect/system/smoke_spread/chem/smoke = new
|
||||
smoke.set_up(R, 1, 0, src, 0, silent = 1)
|
||||
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
smoke.start()
|
||||
@@ -334,7 +334,7 @@
|
||||
var/datum/reagents/R = new/datum/reagents(50)
|
||||
R.my_atom = src
|
||||
R.add_reagent(chosenchem , 50)
|
||||
var/datum/effect/effect/system/chem_smoke_spread/smoke = new
|
||||
var/datum/effect/effect/system/smoke_spread/chem/smoke = new
|
||||
smoke.set_up(R, 1, 0, src, 0, silent = 1)
|
||||
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
smoke.start()
|
||||
@@ -421,7 +421,7 @@
|
||||
R.my_atom = src
|
||||
R.add_reagent("frostoil" , 50)
|
||||
investigate_log("Experimentor has released frostoil gas.", "experimentor")
|
||||
var/datum/effect/effect/system/chem_smoke_spread/smoke = new
|
||||
var/datum/effect/effect/system/smoke_spread/chem/smoke = new
|
||||
smoke.set_up(R, 1, 0, src, 0, silent = 1)
|
||||
playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3)
|
||||
smoke.start()
|
||||
@@ -443,7 +443,7 @@
|
||||
ejectItem(TRUE)
|
||||
if(prob(EFFECT_PROB_MEDIUM-badThingCoeff))
|
||||
visible_message("<span class='warning'>[src] malfunctions, releasing a flurry of chilly air as [exp_on] pops out!</span>")
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new
|
||||
smoke.set_up(1,0, src.loc, 0)
|
||||
smoke.start()
|
||||
ejectItem()
|
||||
@@ -651,7 +651,7 @@
|
||||
//////////////// RELIC PROCS /////////////////////////////
|
||||
|
||||
/obj/item/weapon/relic/proc/throwSmoke(var/turf/where)
|
||||
var/datum/effect/effect/system/harmless_smoke_spread/smoke = new
|
||||
var/datum/effect/effect/system/smoke_spread/smoke = new
|
||||
smoke.set_up(1,0, where, 0)
|
||||
smoke.start()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user