diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm index d156c97266b..ff62b7495f9 100644 --- a/code/game/gamemodes/meteor/meteors.dm +++ b/code/game/gamemodes/meteor/meteors.dm @@ -1,23 +1,27 @@ +#define DEFAULT_METEOR_LIFETIME 3 MINUTES +#define MAP_EDGE_PAD 5 + //Meteors probability of spawning during a given wave -GLOBAL_LIST_INIT(meteors_normal, list(/obj/effect/meteor/dust=3, /obj/effect/meteor/medium=8, /obj/effect/meteor/big=3, \ - /obj/effect/meteor/flaming=1, /obj/effect/meteor/irradiated=3)) //for normal meteor event +GLOBAL_LIST_INIT(meteors_normal, list(/obj/effect/meteor/dust = 3, /obj/effect/meteor/medium = 8, /obj/effect/meteor/big = 3, + /obj/effect/meteor/flaming = 1, /obj/effect/meteor/irradiated = 3)) //for normal meteor event -GLOBAL_LIST_INIT(meteors_threatening, list(/obj/effect/meteor/medium=4, /obj/effect/meteor/big=8, \ - /obj/effect/meteor/flaming=3, /obj/effect/meteor/irradiated=3)) //for threatening meteor event +GLOBAL_LIST_INIT(meteors_threatening, list(/obj/effect/meteor/medium = 4, /obj/effect/meteor/big = 8, + /obj/effect/meteor/flaming = 3, /obj/effect/meteor/irradiated = 3)) //for threatening meteor event -GLOBAL_LIST_INIT(meteors_catastrophic, list(/obj/effect/meteor/medium=5, /obj/effect/meteor/big=75, \ - /obj/effect/meteor/flaming=10, /obj/effect/meteor/irradiated=10, /obj/effect/meteor/tunguska = 1)) //for catastrophic meteor event +GLOBAL_LIST_INIT(meteors_catastrophic, list(/obj/effect/meteor/medium = 5, /obj/effect/meteor/big = 75, + /obj/effect/meteor/flaming = 10, /obj/effect/meteor/irradiated = 10, /obj/effect/meteor/tunguska = 1)) //for catastrophic meteor event + +GLOBAL_LIST_INIT(meteors_gore, list(/obj/effect/meteor/meaty = 5, /obj/effect/meteor/meaty/xeno = 1)) //for meaty ore event GLOBAL_LIST_INIT(meteors_dust, list(/obj/effect/meteor/dust)) //for space dust event -GLOBAL_LIST_INIT(meteors_gore, list(/obj/effect/meteor/gore)) //Meaty Gore - GLOBAL_LIST_INIT(meteors_ops, list(/obj/effect/meteor/goreops)) //Meaty Ops /////////////////////////////// //Meteor spawning global procs /////////////////////////////// + /proc/spawn_meteors(number = 10, list/meteortypes) for(var/i = 0; i < number; i++) spawn_meteor(meteortypes) @@ -25,86 +29,82 @@ GLOBAL_LIST_INIT(meteors_ops, list(/obj/effect/meteor/goreops)) //Meaty Ops /proc/spawn_meteor(list/meteortypes) var/turf/pickedstart var/turf/pickedgoal - var/max_i = 10//number of tries to spawn meteor. - while(!istype(pickedstart, /turf/space)) + var/max_i = 10 //number of tries to spawn meteor. + while(!isspaceturf(pickedstart)) var/startSide = pick(GLOB.cardinal) - pickedstart = spaceDebrisStartLoc(startSide, level_name_to_num(MAIN_STATION)) - pickedgoal = spaceDebrisFinishLoc(startSide, level_name_to_num(MAIN_STATION)) + var/startZ = level_name_to_num(MAIN_STATION) + pickedstart = spaceDebrisStartLoc(startSide, startZ) + pickedgoal = spaceDebrisFinishLoc(startSide, startZ) max_i-- - if(max_i<=0) + if(max_i <= 0) return var/Me = pickweight(meteortypes) - var/obj/effect/meteor/M = new Me(pickedstart) + var/obj/effect/meteor/M = new Me(pickedstart, pickedgoal) M.dest = pickedgoal - M.z_original = level_name_to_num(MAIN_STATION) - spawn(0) - walk_towards(M, M.dest, 1) - return /proc/spaceDebrisStartLoc(startSide, Z) var/starty var/startx switch(startSide) if(NORTH) - starty = world.maxy-(TRANSITIONEDGE+1) - startx = rand((TRANSITIONEDGE+1), world.maxx-(TRANSITIONEDGE+1)) + starty = world.maxy-(TRANSITIONEDGE + MAP_EDGE_PAD) + startx = rand((TRANSITIONEDGE + MAP_EDGE_PAD), world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD)) if(EAST) - starty = rand((TRANSITIONEDGE+1),world.maxy-(TRANSITIONEDGE+1)) - startx = world.maxx-(TRANSITIONEDGE+1) + starty = rand((TRANSITIONEDGE + MAP_EDGE_PAD),world.maxy-(TRANSITIONEDGE + MAP_EDGE_PAD)) + startx = world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD) if(SOUTH) - starty = (TRANSITIONEDGE+1) - startx = rand((TRANSITIONEDGE+1), world.maxx-(TRANSITIONEDGE+1)) + starty = (TRANSITIONEDGE + MAP_EDGE_PAD) + startx = rand((TRANSITIONEDGE + MAP_EDGE_PAD), world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD)) if(WEST) - starty = rand((TRANSITIONEDGE+1), world.maxy-(TRANSITIONEDGE+1)) - startx = (TRANSITIONEDGE+1) - var/turf/T = locate(startx, starty, Z) - return T + starty = rand((TRANSITIONEDGE + MAP_EDGE_PAD), world.maxy-(TRANSITIONEDGE + MAP_EDGE_PAD)) + startx = (TRANSITIONEDGE + MAP_EDGE_PAD) + . = locate(startx, starty, Z) /proc/spaceDebrisFinishLoc(startSide, Z) var/endy var/endx switch(startSide) if(NORTH) - endy = TRANSITIONEDGE - endx = rand(TRANSITIONEDGE, world.maxx-TRANSITIONEDGE) + endy = (TRANSITIONEDGE + MAP_EDGE_PAD) + endx = rand((TRANSITIONEDGE + MAP_EDGE_PAD), world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD)) if(EAST) - endy = rand(TRANSITIONEDGE, world.maxy-TRANSITIONEDGE) - endx = TRANSITIONEDGE + endy = rand((TRANSITIONEDGE + MAP_EDGE_PAD), world.maxy-(TRANSITIONEDGE + MAP_EDGE_PAD)) + endx = (TRANSITIONEDGE + MAP_EDGE_PAD) if(SOUTH) - endy = world.maxy-TRANSITIONEDGE - endx = rand(TRANSITIONEDGE, world.maxx-TRANSITIONEDGE) + endy = world.maxy-(TRANSITIONEDGE + MAP_EDGE_PAD) + endx = rand((TRANSITIONEDGE + MAP_EDGE_PAD), world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD)) if(WEST) - endy = rand(TRANSITIONEDGE,world.maxy-TRANSITIONEDGE) - endx = world.maxx-TRANSITIONEDGE - var/turf/T = locate(endx, endy, Z) - return T + endy = rand((TRANSITIONEDGE + MAP_EDGE_PAD),world.maxy-(TRANSITIONEDGE + MAP_EDGE_PAD)) + endx = world.maxx-(TRANSITIONEDGE + MAP_EDGE_PAD) + . = locate(endx, endy, Z) /////////////////////// //The meteor effect ////////////////////// /obj/effect/meteor - name = "the concept of meteor" + name = "\proper the concept of meteor" desc = "You should probably run instead of gawking at this." icon = 'icons/obj/meteor.dmi' icon_state = "small" - density = 1 - anchored = 1 + density = TRUE + anchored = TRUE var/hits = 4 - var/hitpwr = 2 //Level of ex_act to be called on hit. + var/hitpwr = EXPLODE_HEAVY //Level of ex_act to be called on hit. var/dest pass_flags = PASSTABLE - var/heavy = 0 + var/heavy = FALSE var/meteorsound = 'sound/effects/meteorimpact.ogg' - var/z_original = 1 - - var/meteordrop = /obj/item/stack/ore/iron + var/z_original + var/lifetime = DEFAULT_METEOR_LIFETIME + var/timerid = null + var/list/meteordrop = list(/obj/item/stack/ore/iron) var/dropamt = 2 /obj/effect/meteor/Move() if(z != z_original || loc == dest) qdel(src) - return + return FALSE . = ..() //process movement... @@ -112,35 +112,40 @@ GLOBAL_LIST_INIT(meteors_ops, list(/obj/effect/meteor/goreops)) //Meaty Ops var/turf/T = get_turf(loc) ram_turf(T) - if(prob(10) && !istype(T, /turf/space))//randomly takes a 'hit' from ramming + if(prob(10) && !isspaceturf(T))//randomly takes a 'hit' from ramming get_hit() - return . - /obj/effect/meteor/Destroy() + if(timerid) + deltimer(timerid) GLOB.meteor_list -= src - walk(src,0) //this cancels the walk_towards() proc + walk(src, 0) //this cancels the walk_towards() proc return ..() -/obj/effect/meteor/New() - ..() +/obj/effect/meteor/Initialize(mapload, target) + . = ..() + z_original = z GLOB.meteor_list += src SpinAnimation() + timerid = QDEL_IN(src, lifetime) + chase_target(target) /obj/effect/meteor/Bump(atom/A) if(A) ram_turf(get_turf(A)) - playsound(src.loc, meteorsound, 40, 1) + playsound(loc, meteorsound, 40, TRUE) get_hit() -/obj/effect/meteor/CanPass(atom/movable/mover, turf/target, height=0) - return istype(mover, /obj/effect/meteor) ? 1 : ..() - /obj/effect/meteor/proc/ram_turf(turf/T) //first bust whatever is in the turf - for(var/atom/A in T) - if(A != src) - A.ex_act(hitpwr) + for(var/thing in T) + var/atom/A = thing + if(thing == src) + continue + if(isliving(thing)) + var/mob/living/living_thing = thing + living_thing.visible_message("[src] slams into [living_thing].", "[src] slams into you!") + A.ex_act(hitpwr) //then, ram the turf if it still exists if(T) @@ -152,14 +157,14 @@ GLOBAL_LIST_INIT(meteors_ops, list(/obj/effect/meteor/goreops)) //Meaty Ops hits-- if(hits <= 0) make_debris() - meteor_effect(heavy) + meteor_effect() qdel(src) /obj/effect/meteor/ex_act() return -/obj/effect/meteor/attackby(obj/item/W as obj, mob/user as mob, params) - if(istype(W, /obj/item/pickaxe)) +/obj/effect/meteor/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/pickaxe)) make_debris() qdel(src) return @@ -167,23 +172,27 @@ GLOBAL_LIST_INIT(meteors_ops, list(/obj/effect/meteor/goreops)) //Meaty Ops /obj/effect/meteor/proc/make_debris() for(var/throws = dropamt, throws > 0, throws--) - var/obj/item/O = new meteordrop(get_turf(src)) - O.throw_at(dest, 5, 10) + var/thing_to_spawn = pick(meteordrop) + new thing_to_spawn(get_turf(src)) -/obj/effect/meteor/proc/meteor_effect(sound=1) - if(sound) +/obj/effect/meteor/proc/chase_target(atom/chasing, delay = 1) + set waitfor = FALSE + if(chasing) + walk_towards(src, chasing, delay) + +/obj/effect/meteor/proc/meteor_effect() + if(heavy) var/sound/meteor_sound = sound(meteorsound) var/random_frequency = get_rand_frequency() for(var/P in GLOB.player_list) var/mob/M = P var/turf/T = get_turf(M) - if(!T || T.z != src.z) + if(!T || T.z != z) continue - var/dist = get_dist(M.loc, src.loc) - if(prob(50)) - shake_camera(M, dist > 20 ? 3 : 5, dist > 20 ? 1 : 3) - M.playsound_local(src.loc, null, 50, 1, random_frequency, 10, S = meteor_sound) + var/dist = get_dist(M.loc, loc) + shake_camera(M, dist > 20 ? 2 : 4, dist > 20 ? 1 : 3) + M.playsound_local(loc, null, 50, TRUE, random_frequency, 10, S = meteor_sound) /////////////////////// //Meteor types @@ -195,9 +204,9 @@ GLOBAL_LIST_INIT(meteors_ops, list(/obj/effect/meteor/goreops)) //Meaty Ops icon_state = "dust" pass_flags = PASSTABLE | PASSGRILLE hits = 1 - hitpwr = 3 - meteorsound = 'sound/weapons/tap.ogg' - meteordrop = /obj/item/stack/ore/glass + hitpwr = EXPLODE_LIGHT + meteorsound = 'sound/weapons/gunshots/gunshot_smg.ogg' + meteordrop = list(/obj/item/stack/ore/glass) //Medium-sized /obj/effect/meteor/medium @@ -205,45 +214,45 @@ GLOBAL_LIST_INIT(meteors_ops, list(/obj/effect/meteor/goreops)) //Meaty Ops dropamt = 3 /obj/effect/meteor/medium/meteor_effect() - ..(heavy) - explosion(src.loc, 0, 1, 2, 3, 0) + ..() + explosion(loc, 0, 1, 2, 3, 0) //Large-sized /obj/effect/meteor/big - name = "large meteor" + name = "big meteor" icon_state = "large" hits = 6 - heavy = 1 + heavy = TRUE dropamt = 4 /obj/effect/meteor/big/meteor_effect() - ..(heavy) - explosion(src.loc, 1, 2, 3, 4, 0) + ..() + explosion(loc, 1, 2, 3, 4, 0) //Flaming meteor /obj/effect/meteor/flaming name = "flaming meteor" icon_state = "flaming" hits = 5 - heavy = 1 + heavy = TRUE meteorsound = 'sound/effects/bamf.ogg' - meteordrop = /obj/item/stack/ore/plasma + meteordrop = list(/obj/item/stack/ore/plasma) /obj/effect/meteor/flaming/meteor_effect() - ..(heavy) - explosion(src.loc, 1, 2, 3, 4, 0, 0, flame_range = 5) + ..() + explosion(loc, 1, 2, 3, 4, 0, 0, 5) //Radiation meteor /obj/effect/meteor/irradiated name = "glowing meteor" icon_state = "glowing" - heavy = 1 - meteordrop = /obj/item/stack/ore/uranium + heavy = TRUE + meteordrop = list(/obj/item/stack/ore/uranium) /obj/effect/meteor/irradiated/meteor_effect() - ..(heavy) - explosion(src.loc, 0, 0, 4, 3, 0) + ..() + explosion(loc, 0, 0, 4, 3, 0) new /obj/effect/decal/cleanable/greenglow(get_turf(src)) radiation_pulse(src, 500) @@ -251,56 +260,74 @@ GLOBAL_LIST_INIT(meteors_ops, list(/obj/effect/meteor/goreops)) //Meaty Ops /obj/effect/meteor/tunguska name = "tunguska meteor" icon_state = "flaming" - desc = "Your life briefly passes before your eyes the moment you lay them on this monstruosity." + desc = "Your life briefly passes before your eyes the moment you lay them on this monstrosity." hits = 30 - hitpwr = 1 - heavy = 1 + hitpwr = EXPLODE_DEVASTATE + heavy = TRUE meteorsound = 'sound/effects/bamf.ogg' - meteordrop = /obj/item/stack/ore/plasma + meteordrop = list(/obj/item/stack/ore/plasma) + +/obj/effect/meteor/tunguska/Move() + . = ..() + if(.) + new /obj/effect/temp_visual/revenant(get_turf(src)) /obj/effect/meteor/tunguska/meteor_effect() - ..(heavy) - explosion(src.loc, 5, 10, 15, 20, 0) + ..() + explosion(loc, 5, 10, 15, 20, 0) /obj/effect/meteor/tunguska/Bump() ..() if(prob(20)) - explosion(src.loc,2,4,6,8) + explosion(loc, 2, 4, 6, 8) - -//Gore -/obj/effect/meteor/gore - name = "Oraganic Debris" - icon = 'icons/mob/human.dmi' - icon_state = "body_m_s" - hits = 1 - hitpwr = 0 +//Meaty Ore +/obj/effect/meteor/meaty + name = "meaty ore" + icon_state = "meateor" + desc = "Just... don't think too hard about where this thing came from." + hits = 2 + heavy = TRUE meteorsound = 'sound/effects/blobattack.ogg' - meteordrop = /obj/item/reagent_containers/food/snacks/meat + meteordrop = list(/obj/item/reagent_containers/food/snacks/meat/human, /obj/item/organ/internal/heart, /obj/item/organ/internal/lungs, /obj/item/organ/internal/appendix) var/meteorgibs = /obj/effect/gibspawner/generic -/obj/effect/meteor/gore/make_debris() +/obj/effect/meteor/meaty/make_debris() ..() new meteorgibs(get_turf(src)) -/obj/effect/meteor/gore/ram_turf(turf/T) - if(!istype(T, /turf/space)) +/obj/effect/meteor/meaty/ram_turf(turf/T) + if(!isspaceturf(T)) new /obj/effect/decal/cleanable/blood(T) -/obj/effect/meteor/gore/Bump(atom/A) +/obj/effect/meteor/meaty/Bump(atom/A) A.ex_act(hitpwr) get_hit() +//Meaty Ore Xeno edition +/obj/effect/meteor/meaty/xeno + color = "#5EFF00" + meteordrop = list(/obj/item/reagent_containers/food/snacks/monstermeat/xenomeat) + meteorgibs = /obj/effect/gibspawner/xeno + +/obj/effect/meteor/meaty/xeno/Initialize(mapload, target) + meteordrop += subtypesof(/obj/item/organ/internal/xenos) + return ..() + +/obj/effect/meteor/meaty/xeno/ram_turf(turf/T) + if(!isspaceturf(T)) + new /obj/effect/decal/cleanable/blood/xeno(T) + //Meteor Ops /obj/effect/meteor/goreops name = "MeteorOps" icon = 'icons/mob/animal.dmi' icon_state = "syndicaterangedpsace" hits = 10 - hitpwr = 1 + hitpwr = EXPLODE_DEVASTATE meteorsound = 'sound/effects/blobattack.ogg' - meteordrop = /obj/item/reagent_containers/food/snacks/meat + meteordrop = list(/obj/item/reagent_containers/food/snacks/meat) var/meteorgibs = /obj/effect/gibspawner/generic /obj/effect/meteor/goreops/make_debris() @@ -309,9 +336,33 @@ GLOBAL_LIST_INIT(meteors_ops, list(/obj/effect/meteor/goreops)) //Meaty Ops /obj/effect/meteor/goreops/ram_turf(turf/T) - if(!istype(T, /turf/space)) + if(!isspaceturf(T)) new /obj/effect/decal/cleanable/blood(T) /obj/effect/meteor/goreops/Bump(atom/A) A.ex_act(hitpwr) get_hit() + +////////////////////////// +//Spookoween meteors +///////////////////////// + +GLOBAL_LIST_INIT(meteorsSPOOKY, list(/obj/effect/meteor/pumpkin)) + +/obj/effect/meteor/pumpkin + name = "PUMPKING" + desc = "THE PUMPKING'S COMING!" + icon = 'icons/obj/meteor_spooky.dmi' + icon_state = "pumpkin" + hits = 10 + heavy = TRUE + dropamt = 1 + meteordrop = list(/obj/item/clothing/head/hardhat/pumpkinhead, /obj/item/reagent_containers/food/snacks/grown/pumpkin) + +/obj/effect/meteor/pumpkin/Initialize(mapload, target) + . = ..() + meteorsound = pick('sound/hallucinations/im_here1.ogg','sound/hallucinations/im_here2.ogg') + +////////////////////////// +#undef DEFAULT_METEOR_LIFETIME +#undef MAP_EDGE_PAD diff --git a/code/modules/events/dust.dm b/code/modules/events/dust.dm index 4654a09ba72..596e3e31b5a 100644 --- a/code/modules/events/dust.dm +++ b/code/modules/events/dust.dm @@ -12,7 +12,7 @@ name = "Space Dust" desc = "Dust in space." icon = 'icons/obj/meteor.dmi' - icon_state = "space_dust" + icon_state = "dust" density = 1 anchored = 1 var/strength = 2 //ex_act severity number diff --git a/icons/obj/meteor.dmi b/icons/obj/meteor.dmi index 83a0a98a49a..84faabcc188 100644 Binary files a/icons/obj/meteor.dmi and b/icons/obj/meteor.dmi differ diff --git a/icons/obj/meteor_spooky.dmi b/icons/obj/meteor_spooky.dmi new file mode 100644 index 00000000000..287d5b47bd0 Binary files /dev/null and b/icons/obj/meteor_spooky.dmi differ