diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index f9c07321206..40b021f606f 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -3,37 +3,49 @@ desc = "Looks unstable. Best to test it carefully." icon = 'icons/obj/stationobjs.dmi' icon_state = "portal" - density = 1 - unacidable = 1//Can't destroy energy portals. + density = TRUE + unacidable = TRUE //Can't destroy energy portals. + var/does_teleport = TRUE // Some portals might just be visual + var/has_lifespan = TRUE // Whether we want to directly control the lifespan or not var/failchance = 5 - var/obj/target = null - var/creator = null - var/precision = 1 - anchored = 1.0 + var/obj/target + var/creator + var/precision = TRUE + anchored = TRUE /obj/effect/portal/CollidedWith(mob/M as mob|obj) set waitfor = FALSE - src.teleport(M) + + if(does_teleport) + src.teleport(M) /obj/effect/portal/Crossed(AM as mob|obj) set waitfor = FALSE - src.teleport(AM) + + if(does_teleport) + src.teleport(AM) /obj/effect/portal/attack_hand(mob/user as mob) set waitfor = FALSE - src.teleport(user) + + if(does_teleport) + src.teleport(user) /obj/effect/portal/New(loc, turf/target, creator=null, lifespan=300, precise = 1) ..() - src.target = target - src.creator = creator + if(target) + src.target = target + if(creator) + src.creator = creator - if(lifespan > 0) + if(has_lifespan && lifespan > 0) QDEL_IN(src, lifespan) precision = precise /obj/effect/portal/proc/teleport(atom/movable/M as mob|obj) + if(!does_teleport) // just to be safe + return if(istype(M, /obj/effect)) //sparks don't teleport return if (icon_state == "portal1") @@ -47,3 +59,78 @@ do_teleport(M, locate(rand(5, world.maxx - 5), rand(5, world.maxy -5), 3), 0) else do_teleport(M, target, precision) + +/obj/effect/portal/spawner + name = "portal" + desc = "Looks like a one-way portal, don't come too close." + description_info = "This portal is a spawner portal. You cannot enter it to teleport, but it will periodically spawn things." + does_teleport = FALSE + has_lifespan = FALSE + layer = OBJ_LAYER - 0.01 + var/list/spawn_things = list() // The list things to spawn + var/num_of_spawns // How many times we want to spawn them before qdel + var/next_spawn + +/obj/effect/portal/spawner/Initialize() + . = ..() + START_PROCESSING(SSprocessing, src) + next_spawn = world.time + 5 SECONDS + +/obj/effect/portal/spawner/Destroy() + STOP_PROCESSING(SSprocessing, src) + return ..() + +/obj/effect/portal/spawner/process() + if(next_spawn < world.time) + visible_message(SPAN_WARNING("\The [src] spits something out!")) + for(var/thing in spawn_things) + var/spawn_path = text2path(thing) + var/atom/spawned_thing = new spawn_path(get_turf(src)) + + if(istype(spawned_thing, /obj/item/stack)) + var/obj/item/stack/stack = spawned_thing + stack.amount = spawn_things[thing] + stack.throw_at(get_random_turf_in_range(get_turf(src), 1), 2) + else + for(var/i = 1; i < spawn_things[thing]; i++) + var/atom/movable/A = new spawn_path(get_turf(src)) + A.throw_at(get_random_turf_in_range(get_turf(src), 1), 2) + + next_spawn = world.time + 30 SECONDS + num_of_spawns-- + if(num_of_spawns <= 0) + visible_message(SPAN_WARNING("\The [src] collapses in on itself!")) + qdel(src) + +/obj/effect/portal/spawner/metal + num_of_spawns = 3 + spawn_things = list( + "/obj/item/stack/material/steel" = 10, + "/obj/item/stack/material/plasteel" = 5 + ) + +/obj/effect/portal/spawner/rare_metal + num_of_spawns = 4 + spawn_things = list( + "/obj/item/stack/material/gold" = 2, + "/obj/item/stack/material/silver" = 2, + "/obj/item/stack/material/uranium" = 2 + ) + +/obj/effect/portal/spawner/phoron + num_of_spawns = 3 + spawn_things = list( + "/obj/item/stack/material/phoron" = 10 + ) + +/obj/effect/portal/spawner/monkey_cube + num_of_spawns = 1 + spawn_things = list( + "/obj/item/reagent_containers/food/snacks/monkeycube" = 4 + ) + +/obj/effect/portal/spawner/cow // debug but funny so im keeping it + num_of_spawns = 1 + spawn_things = list( + "/mob/living/simple_animal/cow" = 1 + ) \ No newline at end of file diff --git a/code/game/objects/items/weapons/power_cells.dm b/code/game/objects/items/weapons/power_cells.dm index 7a723f0c5c6..861c9347ef6 100644 --- a/code/game/objects/items/weapons/power_cells.dm +++ b/code/game/objects/items/weapons/power_cells.dm @@ -127,11 +127,24 @@ name = "charged slime core" desc = "A yellow slime core infused with phoron, it crackles with power." origin_tech = list(TECH_POWER = 2, TECH_BIO = 4) - icon = 'icons/mob/npc/slimes.dmi' //'icons/obj/harvest.dmi' - icon_state = "yellow slime extract" //"potato_battery" + icon = 'icons/mob/npc/slimes.dmi' + icon_state = "yellow slime extract" maxcharge = 10000 matter = null + var/next_recharge +/obj/item/cell/slime/Initialize() + . = ..() + START_PROCESSING(SSprocessing, src) + +/obj/item/cell/slime/Destroy() + STOP_PROCESSING(SSprocessing, src) + return ..() + +/obj/item/cell/slime/process() + if(next_recharge < world.time) + charge += maxcharge / 10 + next_recharge = world.time + 1 MINUTE /obj/item/cell/device/emergency_light name = "miniature power cell" diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index 5da631df164..7b9cf20965d 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -1243,7 +1243,7 @@ var/obj/item/slime_extract/T = holder.my_atom if(T.uses > 0) return ..() - return 0 + return FALSE /datum/chemical_reaction/slime/on_reaction(var/datum/reagents/holder) var/obj/item/slime_extract/T = holder.my_atom @@ -1263,9 +1263,8 @@ required = /obj/item/slime_extract/grey /datum/chemical_reaction/slime/spawn/on_reaction(var/datum/reagents/holder) - holder.my_atom.visible_message("Infused with phoron, the core begins to quiver and grow, and soon a new baby slime emerges from it!") - var/mob/living/carbon/slime/S = new /mob/living/carbon/slime - S.forceMove(get_turf(holder.my_atom)) + holder.my_atom.visible_message(SPAN_WARNING("Infused with phoron, the core begins to quiver and grow, and soon a new baby slime emerges from it!")) + new /mob/living/carbon/slime(get_turf(holder.my_atom)) ..() /datum/chemical_reaction/slime/monkey @@ -1277,9 +1276,7 @@ required = /obj/item/slime_extract/grey /datum/chemical_reaction/slime/monkey/on_reaction(var/datum/reagents/holder) - for(var/i = 1, i <= 3, i++) - var /obj/item/reagent_containers/food/snacks/monkeycube/M = new /obj/item/reagent_containers/food/snacks/monkeycube - M.forceMove(get_turf(holder.my_atom)) + new /obj/effect/portal/spawner/monkey_cube(get_turf(holder.my_atom)) ..() //Green @@ -1301,12 +1298,7 @@ required = /obj/item/slime_extract/metal /datum/chemical_reaction/slime/metal/on_reaction(var/datum/reagents/holder) - var/obj/item/stack/material/steel/M = new /obj/item/stack/material/steel - M.amount = 15 - M.forceMove(get_turf(holder.my_atom)) - var/obj/item/stack/material/plasteel/P = new /obj/item/stack/material/plasteel - P.amount = 5 - P.forceMove(get_turf(holder.my_atom)) + new /obj/effect/portal/spawner/metal(get_turf(holder.my_atom)) ..() //Gold - added back in @@ -1375,6 +1367,18 @@ step(C, pick(NORTH,SOUTH,EAST,WEST)) ..() +/datum/chemical_reaction/slime/rare_metal + name = "Slime Rare Metal" + id = "rm_metal" + result = null + required_reagents = list("phoron" = 1) + result_amount = 1 + required = /obj/item/slime_extract/gold + +/datum/chemical_reaction/slime/rare_metal/on_reaction(var/datum/reagents/holder) + new /obj/effect/portal/spawner/rare_metal(get_turf(holder.my_atom)) + ..() + //Silver /datum/chemical_reaction/slime/bork name = "Slime Bork" @@ -1456,11 +1460,13 @@ /datum/chemical_reaction/slime/freeze/on_reaction(var/datum/reagents/holder) ..() - sleep(50) + addtimer(CALLBACK(src, .proc/do_reaction, holder), 50) + +/datum/chemical_reaction/slime/freeze/proc/do_reaction(var/datum/reagents/holder) playsound(get_turf(holder.my_atom), 'sound/effects/phasein.ogg', 100, 1) - for(var/mob/living/M in range (get_turf(holder.my_atom), 7)) + for(var/mob/living/M in range(7, get_turf(holder.my_atom))) M.bodytemperature -= 140 - to_chat(M, "You feel a chill!") + to_chat(M, SPAN_WARNING("You feel a cold chill!")) //Orange /datum/chemical_reaction/slime/casp @@ -1482,12 +1488,13 @@ /datum/chemical_reaction/slime/fire/on_reaction(var/datum/reagents/holder) ..() - sleep(50) - var/turf/location = get_turf(holder.my_atom.loc) - for(var/turf/simulated/floor/target_tile in range(0, location)) + addtimer(CALLBACK(src, .proc/do_reaction, holder), 50) + +/datum/chemical_reaction/slime/fire/proc/do_reaction(var/datum/reagents/holder) + var/turf/location = get_turf(holder.my_atom) + for(var/turf/simulated/floor/target_tile in range(1, location)) target_tile.assume_gas("phoron", 25, 1400) - spawn (0) - target_tile.hotspot_expose(700, 400) + target_tile.hotspot_expose(700, 400) //Yellow /datum/chemical_reaction/slime/overload @@ -1497,10 +1504,11 @@ required_reagents = list("blood" = 1) result_amount = 1 required = /obj/item/slime_extract/yellow + mix_message = "The slime extract begins to vibrate violently!" /datum/chemical_reaction/slime/overload/on_reaction(var/datum/reagents/holder, var/created_volume) ..() - empulse(get_turf(holder.my_atom), 3, 7) + addtimer(CALLBACK(GLOBAL_PROC, .proc/empulse, get_turf(holder.my_atom), 3, 7), 50) /datum/chemical_reaction/slime/cell name = "Slime Powercell" @@ -1509,10 +1517,10 @@ required_reagents = list("phoron" = 1) result_amount = 1 required = /obj/item/slime_extract/yellow + mix_message = "A small sparking part of the extract core falls onto the floor." /datum/chemical_reaction/slime/cell/on_reaction(var/datum/reagents/holder, var/created_volume) - var/obj/item/cell/slime/P = new /obj/item/cell/slime - P.forceMove(get_turf(holder.my_atom)) + new /obj/item/cell/slime(get_turf(holder.my_atom)) /datum/chemical_reaction/slime/glow name = "Slime Glow" @@ -1525,8 +1533,7 @@ /datum/chemical_reaction/slime/glow/on_reaction(var/datum/reagents/holder, var/created_volume) ..() - var/obj/item/device/flashlight/slime/F = new /obj/item/device/flashlight/slime - F.forceMove(get_turf(holder.my_atom)) + new /obj/item/device/flashlight/slime(get_turf(holder.my_atom)) //Purple /datum/chemical_reaction/slime/psteroid @@ -1539,8 +1546,7 @@ /datum/chemical_reaction/slime/psteroid/on_reaction(var/datum/reagents/holder, var/created_volume) ..() - var/obj/item/slimesteroid/P = new /obj/item/slimesteroid - P.forceMove(get_turf(holder.my_atom)) + new /obj/item/slimesteroid(get_turf(holder.my_atom)) /datum/chemical_reaction/slime/jam name = "Slime Jam" @@ -1561,9 +1567,7 @@ /datum/chemical_reaction/slime/plasma/on_reaction(var/datum/reagents/holder) ..() - var/obj/item/stack/material/phoron/P = new /obj/item/stack/material/phoron - P.amount = 10 - P.forceMove(get_turf(holder.my_atom)) + new /obj/effect/portal/spawner/phoron(get_turf(holder.my_atom)) //Red /datum/chemical_reaction/slime/glycerol @@ -1585,8 +1589,8 @@ /datum/chemical_reaction/slime/bloodlust/on_reaction(var/datum/reagents/holder) ..() for(var/mob/living/carbon/slime/slime in viewers(get_turf(holder.my_atom), null)) - slime.rabid = 1 - slime.visible_message("The [slime] is driven into a frenzy!") + slime.rabid = TRUE + slime.visible_message(SPAN_WARNING("\icon[slime] \The [slime] is driven into a frenzy!")) //Pink /datum/chemical_reaction/slime/ppotion @@ -1599,8 +1603,7 @@ /datum/chemical_reaction/slime/ppotion/on_reaction(var/datum/reagents/holder) ..() - var/obj/item/slimepotion/P = new /obj/item/slimepotion - P.forceMove(get_turf(holder.my_atom)) + new /obj/item/slimepotion(get_turf(holder.my_atom)) //Black /datum/chemical_reaction/slime/mutate2 @@ -1623,8 +1626,7 @@ /datum/chemical_reaction/slime/explosion/on_reaction(var/datum/reagents/holder) ..() - sleep(50) - explosion(get_turf(holder.my_atom), 1, 3, 6) + addtimer(CALLBACK(GLOBAL_PROC, .proc/explosion, get_turf(holder.my_atom), 1, 3, 6), 50) //Light Pink /datum/chemical_reaction/slime/potion2 @@ -1637,8 +1639,7 @@ /datum/chemical_reaction/slime/potion2/on_reaction(var/datum/reagents/holder) ..() - var/obj/item/slimepotion2/P = new /obj/item/slimepotion2 - P.forceMove(get_turf(holder.my_atom)) + new /obj/item/slimepotion2(get_turf(holder.my_atom)) //Adamantine /datum/chemical_reaction/slime/golem @@ -1648,11 +1649,11 @@ required_reagents = list("phoron" = 1) result_amount = 1 required = /obj/item/slime_extract/adamantine + mix_message = "A soft fizzle is heard within the slime extract, and mystic runes suddenly appear on the floor beneath it!" /datum/chemical_reaction/slime/golem/on_reaction(var/datum/reagents/holder) ..() - var/obj/effect/golemrune/Z = new /obj/effect/golemrune - Z.forceMove(get_turf(holder.my_atom)) + new /obj/effect/golemrune(get_turf(holder.my_atom)) /datum/chemical_reaction/soap_key name = "Soap Key" diff --git a/html/changelogs/geeves-xenobio_core_improvements.yml b/html/changelogs/geeves-xenobio_core_improvements.yml new file mode 100644 index 00000000000..87898602ec5 --- /dev/null +++ b/html/changelogs/geeves-xenobio_core_improvements.yml @@ -0,0 +1,12 @@ +author: Geeves + +delete-after: True + +changes: + - tweak: "Tweaked how xenobio spawns in steel, plasteel and phoron, when using slime extracts. They will make more of each now." + - rscadd: "The gray extract now spawns 4 monkey cubes instead of 3." + - rscadd: "Injecting phoron into a gold extract now spawns small amounts of gold, silver, and uranium." + - rscadd: "Slime core batteries now regain 10% of their charge every minute." + - tweak: "The slime extract EMP now has a five second timer, instead of being instant." + - tweak: "The oil extract flame now affects a slightly larger area, one tile to a one tile radius." + - bugfix: "The frost extract now properly chills every in a seven tile radius." \ No newline at end of file