/* This is an attempt to make some easily reusable "particle" type effect, to stop the code constantly having to be rewritten. An item like the jetpack that uses the ion_trail_follow system, just has one defined, then set up when it is created with New(). Then this same system can just be reused each time it needs to create more trails.A beaker could have a steam_trail_follow system set up, then the steam would spawn and follow the beaker, even if it is carried or thrown. */ /obj/effect/effect name = "effect" icon = 'icons/effects/effects.dmi' mouse_opacity = 0 unacidable = 1//So effect are not targeted by alien acid. /datum/effect/effect/proc/fadeOut(var/atom/A, var/frames = 16) if(A.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 = A.alpha / frames for(var/i = 0, i < frames, i++) A.alpha -= step sleep(world.tick_lag) return /obj/effect/effect/water name = "water" icon = 'icons/effects/effects.dmi' icon_state = "extinguish" var/life = 15.0 mouse_opacity = 0 /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/proc/delete() qdel(src) /obj/effect/effect/water/New() ..() //var/turf/T = src.loc //if (istype(T, /turf)) // T.firelevel = 0 //TODO: FIX spawn( 70 ) delete() return return /obj/effect/effect/water/Destroy() //var/turf/T = src.loc //if (istype(T, /turf)) // T.firelevel = 0 //TODO: FIX src.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) if(istype(A,/atom/movable)) var/atom/movable/AM = A AM.water_act(life, 310.15, src) return ..() /datum/effect/effect/system var/number = 3 var/cardinals = 0 var/turf/location var/atom/holder var/setup = 0 proc/set_up(n = 3, c = 0, turf/loc) if(n > 10) n = 10 number = n cardinals = c location = loc setup = 1 proc/attach(atom/atom) holder = atom proc/start() ///////////////////////////////////////////// // GENERIC STEAM SPREAD SYSTEM //Usage: set_up(number of bits of steam, use North/South/East/West only, spawn location) // The attach(atom/atom) proc is optional, and can be called to attach the effect // to something, like a smoking beaker, so then you can just call start() and the steam // will always spawn at the items location, even if it's moved. /* Example: var/datum/effect/system/steam_spread/steam = new /datum/effect/system/steam_spread() -- creates new system steam.set_up(5, 0, mob.loc) -- sets up variables OPTIONAL: steam.attach(mob) steam.start() -- spawns the effect */ ///////////////////////////////////////////// /obj/effect/effect/steam name = "steam" icon = 'icons/effects/effects.dmi' icon_state = "extinguish" density = 0 /datum/effect/effect/system/steam_spread set_up(n = 3, c = 0, turf/loc) if(n > 10) n = 10 number = n cardinals = c location = loc start() var/i = 0 for(i=0, i 10) n = 10 number = n cardinals = c if(istype(loca, /turf/)) location = loca else location = get_turf(loca) start() var/i = 0 for(i=0, i 20) return spawn(0) if(holder) src.location = get_turf(holder) var/obj/effect/effect/sparks/sparks = new /obj/effect/effect/sparks(src.location) src.total_sparks++ var/direction if(src.cardinals) direction = pick(cardinal) else direction = pick(alldirs) for(i=0, i 10) n = 10 number = n cardinals = c if(istype(loca, /turf/)) location = loca else location = get_turf(loca) if(direct) direction = direct start() var/i = 0 for(i=0, i 20) return spawn(0) if(holder) src.location = get_turf(holder) var/obj/effect/effect/harmless_smoke/smoke = new /obj/effect/effect/harmless_smoke(src.location) src.total_smoke++ var/direction = src.direction if(!direction) if(src.cardinals) direction = pick(cardinal) else direction = pick(alldirs) for(i=0, i 20) n = 20 number = n cardinals = c if(istype(loca, /turf/)) location = loca else location = get_turf(loca) if(direct) direction = direct start() var/i = 0 for(i=0, i 20) return spawn(0) if(holder) src.location = get_turf(holder) var/obj/effect/effect/bad_smoke/smoke = new /obj/effect/effect/bad_smoke(src.location) src.total_smoke++ var/direction = src.direction if(!direction) if(src.cardinals) direction = pick(cardinal) else direction = pick(alldirs) for(i=0, i 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 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 = "[where]" if(carry && carry.my_atom) if(carry.my_atom.fingerprintslast) var/mob/M = get_mob_by_key(carry.my_atom.fingerprintslast) var/more = "" if(M) more = "(?)" msg_admin_attack("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 msg_admin_attack("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.") else msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink]). No associated key. CODERS: carry.my_atom may be null.", 0, 1) log_game("A chemical smoke reaction has taken place in ([where])[contained]. No associated key. CODERS: carry.my_atom may be null.") start(effect_range = 2) var/i = 0 var/color = mix_color_from_reagents(chemholder.reagents.reagent_list) var/obj/effect/effect/chem_smoke/smokeholder = new /obj/effect/effect/chem_smoke(src.location) for(var/atom/A in view(effect_range, smokeholder)) chemholder.reagents.reaction(A) if(iscarbon(A)) var/mob/living/carbon/C = A if(!(C.wear_mask && (C.internals != null || C.wear_mask.flags & BLOCK_GAS_SMOKE_EFFECT))) chemholder.reagents.copy_to(C, chemholder.reagents.total_volume) if(istype(A, /obj/machinery/portable_atmospherics/hydroponics)) var/obj/machinery/portable_atmospherics/hydroponics/tray = A chemholder.reagents.copy_to(tray, chemholder.reagents.total_volume) if(istype(A, /obj/effect/plant)) var/obj/effect/plant/plant = A if(chemholder.reagents.has_reagent("atrazine")) plant.die_off() qdel(smokeholder) for(i=0, i 20) return spawn(0) if(holder) src.location = get_turf(holder) var/obj/effect/effect/chem_smoke/smoke = new /obj/effect/effect/chem_smoke(src.location) src.total_smoke++ var/direction = src.direction if(!direction) if(src.cardinals) direction = pick(cardinal) else direction = pick(alldirs) if(color) smoke.icon += color // give the smoke color, if it has any to begin with else // if no color, just use the old smoke icon smoke.icon = 'icons/effects/96x96.dmi' smoke.icon_state = "smoke" for(i=0, i 20) n = 20 number = n cardinals = c chemholder.reagents.add_reagent("space_drugs", rand(1,10)) if(istype(loca, /turf/)) location = loca else location = get_turf(loca) if(direct) direction = direct var/contained = "\[[chemholder.reagents.get_reagent_ids()]\]" var/area/A = get_area(location) var/where = "[A.name] | [location.x], [location.y]" var/whereLink=formatJumpTo(location,where) var/more = "(?)" message_admins("[M][more] produced a toxic fart in ([whereLink])[contained].", 0, 1) log_game("[M][more] produced a toxic fart in ([where])[contained].") ///////////////////////////////////////////// // 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 color = "#9C3636" /obj/effect/effect/sleep_smoke/New() ..() spawn (200+rand(10,30)) delete() return /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 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 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 start() var/i = 0 for(i=0, i 20) return spawn(0) if(holder) src.location = get_turf(holder) var/obj/effect/effect/sleep_smoke/smoke = new /obj/effect/effect/sleep_smoke(src.location) src.total_smoke++ var/direction = src.direction if(!direction) if(src.cardinals) direction = pick(cardinal) else direction = pick(alldirs) for(i=0, i 20) n = 20 number = n cardinals = c if(istype(loca, /turf/)) location = loca else location = get_turf(loca) if(direct) direction = direct start() var/i = 0 for(i=0, i 20) return spawn(0) if(holder) src.location = get_turf(holder) var/obj/effect/effect/mustard_gas/smoke = new /obj/effect/effect/mustard_gas(src.location) src.total_smoke++ var/direction = src.direction if(!direction) if(src.cardinals) direction = pick(cardinal) else direction = pick(alldirs) for(i=0, i 0) devastation = min (MAX_EX_DEVESTATION_RANGE, devastation + round(amount/12)) if (round(amount/6) > 0) heavy = min (MAX_EX_HEAVY_RANGE, heavy + round(amount/6)) if (round(amount/3) > 0) light = min (MAX_EX_LIGHT_RANGE, light + round(amount/3)) if (flash && flashing_factor) flash += (round(amount/4) * flashing_factor) for(var/mob/M in viewers(8, location)) M << "\red The solution violently explodes." explosion(location, devastation, heavy, light, flash) proc/holder_damage(var/atom/holder) if(holder) var/dmglevel = 4 if (round(amount/8) > 0) dmglevel = 1 else if (round(amount/4) > 0) dmglevel = 2 else if (round(amount/2) > 0) dmglevel = 3 if(dmglevel<4) holder.ex_act(dmglevel) ////////////////////////////////// //////SPARKELS FIREWORKS ///////////////////////////////// //////////////////////////// /obj/effects/sparkels name = "sparkel" icon = 'icons/obj/fireworks.dmi'//findback icon_state = "sparkel" var/amount = 6.0 anchored = 1.0 mouse_opacity = 0 /obj/effects/sparkels/New() ..() var/icon/I = new(src.icon,src.icon_state) var/r = rand(0,255) var/g = rand(0,255) var/b = rand(0,255) world.log << "Colour , [r],[g],[b]" I.Blend(rgb(r,g,b),ICON_MULTIPLY) src.icon = I playsound(src.loc, "sparks", 100, 1) var/turf/T = src.loc if (istype(T, /turf)) T.hotspot_expose(3000,100) spawn (100) qdel(src) return /obj/effects/sparkels/Destroy() var/turf/T = src.loc if (istype(T, /turf)) T.hotspot_expose(3000,100) return ..() /obj/effects/sparkels/Move() ..() var/turf/T = src.loc if (istype(T, /turf)) T.hotspot_expose(3000,100) return /datum/effects/system/sparkel_spread var/number = 3 var/cardinals = 0 var/turf/location var/atom/holder var/total_sparks = 0 // To stop it being spammed and lagging! /datum/effects/system/sparkel_spread/proc/set_up(n = 3, c = 0, loca) if(n > 10) n = 10 number = n cardinals = c if(istype(loca, /turf/)) location = loca else location = get_turf(loca) /datum/effects/system/sparkel_spread/proc/attach(atom/atom) holder = atom /datum/effects/system/sparkel_spread/proc/start() var/i = 0 for(i=0, i 20) return spawn(0) if(holder) src.location = get_turf(holder) var/obj/effects/sparkels/sparks = new(src.location) src.total_sparks++ var/direction if(src.cardinals) direction = pick(cardinal) else direction = pick(alldirs) for(i=0, i