From 2ad1c7445749b2993678cbbd9df90d08c9e05de9 Mon Sep 17 00:00:00 2001 From: Fox-McCloud Date: Wed, 10 Jun 2015 20:04:28 -0400 Subject: [PATCH] Singularity Refactor --- code/ATMOSPHERICS/atmospherics.dm | 6 +- code/__DEFINES/misc.dm | 9 +- code/_onclick/observer.dm | 4 +- code/controllers/garbage.dm | 5 +- code/datums/spells/construct_spells.dm | 16 + code/game/atoms.dm | 9 + code/game/atoms_movable.dm | 5 - code/game/gamemodes/cult/runes.dm | 2 +- .../gamemodes/malfunction/Malf_Modules.dm | 4 +- code/game/gamemodes/wizard/artefact.dm | 2 +- code/game/gamemodes/wizard/soulstone.dm | 17 + code/game/gamemodes/wizard/wizard.dm | 3 + code/game/machinery/syndicatebeacon.dm | 4 +- code/game/objects/effects/overlays.dm | 6 + code/game/objects/items.dm | 6 + code/game/objects/items/devices/camera_bug.dm | 2 +- .../objects/items/weapons/chrono_eraser.dm | 3 + code/game/objects/items/weapons/grenades.dm | 4 +- .../objects/items/weapons/storage/backpack.dm | 11 +- code/game/objects/objs.dm | 13 + code/game/objects/structures/lattice.dm | 5 +- code/game/objects/structures/window.dm | 4 + code/game/turfs/simulated/floor.dm | 20 +- code/game/turfs/simulated/floor_types.dm | 10 + code/game/turfs/simulated/walls.dm | 13 + code/game/turfs/simulated/walls_misc.dm | 3 + code/game/turfs/simulated/walls_reinforced.dm | 7 +- code/game/turfs/space/space.dm | 3 + code/game/turfs/turf.dm | 12 +- code/modules/admin/verbs/debug.dm | 2 +- code/modules/admin/verbs/possess.dm | 2 +- .../awaymissions/mission_code/academy.dm | 6 +- .../mission_code/stationCollision.dm | 13 +- code/modules/lighting/lighting_overlay.dm | 8 +- code/modules/mob/living/carbon/human/human.dm | 35 +- code/modules/mob/living/living.dm | 20 +- .../mob/living/simple_animal/constructs.dm | 25 + code/modules/mob/mob.dm | 2 +- code/modules/mob/mob_helpers.dm | 7 + code/modules/power/cable.dm | 4 + .../power/singularity/field_generator.dm | 2 +- code/modules/power/singularity/generator.dm | 2 +- code/modules/power/singularity/narsie.dm | 159 ++++++ .../particle_accelerator/particle.dm | 2 +- code/modules/power/singularity/singularity.dm | 471 ++++-------------- code/modules/projectiles/projectile/beams.dm | 3 + code/modules/recycling/disposal.dm | 9 + code/modules/supermatter/supermatter.dm | 1 + paradise.dme | 1 + 49 files changed, 553 insertions(+), 429 deletions(-) create mode 100644 code/modules/power/singularity/narsie.dm diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 600c98f3ef6..de3d9544d22 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -191,4 +191,8 @@ obj/machinery/atmospherics/proc/check_connect_types_construction(obj/machinery/a ..() /obj/machinery/atmospherics/proc/can_crawl_through() - return 1 \ No newline at end of file + return 1 + +/obj/machinery/atmospherics/singularity_pull(S, current_size) + if(current_size >= STAGE_FIVE) + Destroy() \ No newline at end of file diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index df4737591a9..f313094b556 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -129,4 +129,11 @@ #define LIGHT_COLOR_WHITE "#FFFFFF" -#define RESIZE_DEFAULT_SIZE 1 \ No newline at end of file +#define RESIZE_DEFAULT_SIZE 1 + +//singularity defines +#define STAGE_ONE 1 +#define STAGE_TWO 3 +#define STAGE_THREE 5 +#define STAGE_FOUR 7 +#define STAGE_FIVE 9 \ No newline at end of file diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index bb5f8b10b4c..671bf0540b8 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -8,7 +8,7 @@ return // seems legit. // Things you might plausibly want to follow - if((ismob(A) && A != src) || istype(A,/obj/machinery/bot) || istype(A,/obj/machinery/singularity)) + if((ismob(A) && A != src) || istype(A,/obj/machinery/bot) || istype(A,/obj/singularity)) ManualFollow(A) // Otherwise jump @@ -19,7 +19,7 @@ if(client.buildmode) build_click(src, client.buildmode, params, A) return - if(world.time <= next_move) + if(world.time <= next_move) return var/list/modifiers = params2list(params) diff --git a/code/controllers/garbage.dm b/code/controllers/garbage.dm index f488ea92aa0..7a33bd6725b 100644 --- a/code/controllers/garbage.dm +++ b/code/controllers/garbage.dm @@ -10,10 +10,10 @@ var/datum/garbage_collector/garbageCollector set name = "(GC) Hard Del List" set desc = "List types that are hard del()'d by the GC." set category = "Debug" - + if(!check_rights(R_DEBUG)) return - + if(!gc_hard_del_types || !gc_hard_del_types.len) usr << "No hard del()'d types found." @@ -45,7 +45,6 @@ var/datum/garbage_collector/garbageCollector var/remainingCollectionPerTick = GC_COLLECTIONS_PER_TICK var/remainingForceDelPerTick = GC_FORCE_DEL_PER_TICK var/collectionTimeScope = world.timeofday - GC_COLLECTION_TIMEOUT - if(narsie_cometh) return //don't even fucking bother, its over. while(queue.len && --remainingCollectionPerTick >= 0) var/refID = queue[1] var/destroyedAtTime = queue[refID] diff --git a/code/datums/spells/construct_spells.dm b/code/datums/spells/construct_spells.dm index ab010295b5d..c81bb108d54 100644 --- a/code/datums/spells/construct_spells.dm +++ b/code/datums/spells/construct_spells.dm @@ -99,3 +99,19 @@ invocation_type = "none" proj_lifespan = 10 max_targets = 6 + +/obj/effect/proc_holder/spell/wizard/targeted/smoke/disable + name = "Paralysing Smoke" + desc = "This spell spawns a cloud of paralysing smoke." + + school = "conjuration" + charge_max = 200 + clothes_req = 0 + invocation = "none" + invocation_type = "none" + range = -1 + include_user = 1 + cooldown_min = 20 //25 deciseconds reduction per rank + + smoke_spread = 3 + smoke_amt = 10 diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 71c8f732d48..6681a1b3c6e 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -452,3 +452,12 @@ its easier to just keep the beam vertical. return 1 else return 0 + +/atom/proc/singularity_act() + return + +/atom/proc/singularity_pull() + return + +/atom/proc/narsie_act() + return diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index a9b2677aa89..2c63514ce5d 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -257,11 +257,6 @@ return src.master.attack_hand(a, b, c) return -///////////////////////////// -// SINGULOTH PULL REFACTOR -///////////////////////////// -/atom/movable/proc/canSingulothPull(var/obj/machinery/singularity/singulo) - return 1 /atom/movable/proc/water_act(var/volume, var/temperature, var/source) //amount of water acting : temperature of water in kelvin : object that called it (for shennagins) return 1 diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 504962771af..a8ebc32995d 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -136,7 +136,7 @@ var/list/sacrificed = list() cultist_count += 1 if(cultist_count >= 9) cult_log("THE CULT HAS SUMMONED NAR'SIE. GGNORE") - new /obj/machinery/singularity/narsie/large(src.loc) + new /obj/singularity/narsie/large(src.loc) if(ticker.mode.name == "cult") ticker.mode:eldergod = 0 return diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 12760904359..7b3066160e7 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -186,7 +186,7 @@ rcd light flash thingy on matter drain set name = "Overload Machine" set category = "Malfunction" if (istype(M, /obj/machinery)) - if(istype(M, /obj/machinery/singularity) || istype(M,/obj/machinery/field_generator) || istype(M, /obj/machinery/singularity/narsie)) + if(istype(M,/obj/machinery/field_generator)) src << "This machine can not be overloaded due to a firewall." return for(var/datum/AI_Module/small/overload_machine/overload in current_modules) @@ -214,7 +214,7 @@ rcd light flash thingy on matter drain set name = "Override Machine" set category = "Malfunction" if (istype(M, /obj/machinery)) - if(istype(M, /obj/machinery/singularity) || istype(M,/obj/machinery/field_generator) || istype(M, /obj/machinery/singularity/narsie)) + if(istype(M,/obj/machinery/field_generator)) src << "This machine can not be overloaded due to a firewall." return for(var/datum/AI_Module/small/override_machine/override in current_modules) diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index d4c1841a507..80b7aa10e81 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -132,7 +132,7 @@ /obj/effect/rend/New() spawn(50) - new /obj/machinery/singularity/narsie/wizard(get_turf(src)) + new /obj/singularity/narsie/wizard(get_turf(src)) del(src) return return diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index 58b0077d31b..0a1f21dd430 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -219,3 +219,20 @@ else U << "\red Creation failed!: \black The soul stone is empty! Go kill someone!" return + +/proc/makeNewConstruct(var/mob/living/simple_animal/construct/ctype, var/mob/target, var/mob/stoner = null, cultoverride = 0) + var/mob/living/simple_animal/construct/newstruct = new ctype(get_turf(target)) + newstruct.faction |= "\ref[stoner]" + newstruct.key = target.key + if(stoner && iscultist(stoner) || cultoverride) + if(ticker.mode.name == "cult") + ticker.mode:add_cultist(newstruct.mind) + else + ticker.mode.cult+=newstruct.mind + ticker.mode.update_cult_icons_added(newstruct.mind) + if(stoner && iswizard(stoner)) + newstruct << "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs." + else if(stoner && iscultist(stoner)) + newstruct << "You are still bound to serve the cult, follow their orders and help them complete their goals at all costs." + else newstruct << "You are still bound to serve your creator, follow their orders and help them complete their goals at all costs." + newstruct.cancel_camera() \ No newline at end of file diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index ea68cec863d..b0a76ac7f7b 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -293,3 +293,6 @@ Made a proc so this is not repeated 14 (or more) times.*/ return 0 else return 1 + +/proc/iswizard(mob/living/M as mob) + return istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.wizards) \ No newline at end of file diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index 916ae1a23af..0ccfdb5bda0 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -127,7 +127,7 @@ if(!checkWirePower()) if(user) user << "\blue The connected wire doesn't have enough current." return - for(var/obj/machinery/singularity/singulo in world) + for(var/obj/singularity/singulo in world) if(singulo.z == z) singulo.target = src icon_state = "[icontype]1" @@ -136,7 +136,7 @@ proc/Deactivate(mob/user = null) - for(var/obj/machinery/singularity/singulo in world) + for(var/obj/singularity/singulo in world) if(singulo.target == src) singulo.target = null icon_state = "[icontype]0" diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index a040e460b2c..e20010d0c2a 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -4,6 +4,12 @@ unacidable = 1 var/i_attached//Added for possible image attachments to objects. For hallucinations and the like. +/obj/effect/overlay/singularity_act() + return + +/obj/effect/overlay/singularity_pull() + return + /obj/effect/overlay/beam//Not actually a projectile, just an effect. name="beam" icon='icons/effects/beam.dmi' diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index e91c10432e3..728c4528da5 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -698,3 +698,9 @@ for(var/obj/item/A in world) if(A.type == type && !A.blood_overlay) A.blood_overlay = image(I) + +/obj/item/singularity_pull(S, current_size) + spawn(0) //this is needed or multiple items will be thrown sequentially and not simultaneously + if(current_size >= STAGE_FOUR) + throw_at(S,14,3) + else ..() \ No newline at end of file diff --git a/code/game/objects/items/devices/camera_bug.dm b/code/game/objects/items/devices/camera_bug.dm index d7967f6ccd2..69adcfb3ae9 100644 --- a/code/game/objects/items/devices/camera_bug.dm +++ b/code/game/objects/items/devices/camera_bug.dm @@ -170,7 +170,7 @@ if(current && current.can_use()) var/list/seen = current.can_see() var/list/names = list() - for(var/obj/machinery/singularity/S in seen) // god help you if you see more than one + for(var/obj/singularity/S in seen) // god help you if you see more than one if(S.name in names) names[S.name]++ dat += "[S.name] ([names[S.name]])" diff --git a/code/game/objects/items/weapons/chrono_eraser.dm b/code/game/objects/items/weapons/chrono_eraser.dm index e2b85f1069a..e0608af5e06 100644 --- a/code/game/objects/items/weapons/chrono_eraser.dm +++ b/code/game/objects/items/weapons/chrono_eraser.dm @@ -246,6 +246,9 @@ /obj/effect/chrono_field/Move() return +/obj/effect/chrono_field/singularity_act() + return + /obj/effect/chrono_field/ex_act() return diff --git a/code/game/objects/items/weapons/grenades.dm b/code/game/objects/items/weapons/grenades.dm index 43acc8df89b..dae50bb302a 100644 --- a/code/game/objects/items/weapons/grenades.dm +++ b/code/game/objects/items/weapons/grenades.dm @@ -349,7 +349,7 @@ /obj/item/weapon/grenade/clusterbuster/apocalypse name = "Apocalypse Bomb" desc = "No matter what, do not EVER use this." - payload = /obj/machinery/singularity + payload = /obj/singularity /obj/item/weapon/grenade/clusterbuster/ultima name = "Earth Shattering Kaboom" @@ -456,6 +456,6 @@ var/atom/A = new payload(loc) if(istype(A,/obj/item/weapon/grenade)) A:prime() - if(istype(A,/obj/machinery/singularity)) // I can't emphasize enough how much you should never use this grenade + if(istype(A,/obj/singularity)) // I can't emphasize enough how much you should never use this grenade A:energy = 200 del src diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index c81ff7d8dbc..b06ea04e671 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -41,7 +41,7 @@ investigate_log("has become a singularity. Caused by [user.key]","singulo") user << "\red The Bluespace interfaces of the two devices catastrophically malfunction!" del(W) - var/obj/machinery/singularity/singulo = new /obj/machinery/singularity (get_turf(src)) + var/obj/singularity/singulo = new /obj/singularity (get_turf(src)) singulo.energy = 300 //should make it a bit bigger~ message_admins("[key_name_admin(user)] detonated a bag of holding") log_game("[key_name(user)] detonated a bag of holding") @@ -61,6 +61,11 @@ crit_fail = 1 icon_state = "brokenpack" + singularity_act(current_size) + var/dist = max((current_size - 2),1) + explosion(src.loc,(dist),(dist*2),(dist*4)) + return + /obj/item/weapon/storage/backpack/santabag name = "Santa's Gift Bag" @@ -300,7 +305,7 @@ desc = "A duffelbag designed to hold bananas and bike horns." icon_state = "duffel-clown" item_state = "duffel-clown" - + //ERT backpacks. /obj/item/weapon/storage/backpack/ert name = "emergency response team backpack" @@ -330,7 +335,7 @@ name = "emergency response team medical backpack" desc = "A spacious backpack with lots of pockets, worn by medical members of a Nanotrasen Emergency Response Team." icon_state = "ert_medical" - + //Janitorial /obj/item/weapon/storage/backpack/ert/janitor name = "emergency response team janitor backpack" diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 31ff44b64f1..d3dbd5d9045 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -245,3 +245,16 @@ a { user << browse(dat, "window=mtcomputer") user.set_machine(src) onclose(user, "mtcomputer") + +/obj/singularity_act() + ex_act(1.0) + if(src && isnull(gc_destroyed)) + qdel(src) + return 2 + +/obj/singularity_pull(S, current_size) + if(anchored) + if(current_size >= STAGE_FIVE) + anchored = 0 + step_towards(src,S) + else step_towards(src,S) diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index 3ed779f7189..e14c9024d77 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -81,4 +81,7 @@ icon_state = "lattice[dir_sum]" return - \ No newline at end of file + +/obj/structure/lattice/singularity_pull(S, current_size) + if(current_size >= STAGE_FOUR) + Destroy() \ No newline at end of file diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index d217daad32a..0ef6f109b4e 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -95,6 +95,10 @@ var/global/wcColored /obj/structure/window/meteorhit() destroy() +/obj/structure/window/singularity_pull(S, current_size) + if(current_size >= STAGE_FIVE) + destroy() + /obj/structure/window/CheckExit(var/atom/movable/O, var/turf/target) if(istype(O) && O.checkpass(PASSGLASS)) return 1 diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index eb9478c2613..5a2fcbe719c 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -615,4 +615,22 @@ var/list/wood_icons = list("wood","wood-broken") P.x = src.x P.y = src.y P.z = src.z - P.loc = src \ No newline at end of file + P.loc = src + +/turf/simulated/floor/singularity_pull(S, current_size) + if(current_size == STAGE_THREE) + if(prob(30)) + make_plating() + else if(current_size == STAGE_FOUR) + if(prob(50)) + make_plating() + else if(current_size >= STAGE_FIVE) + if(prob(70)) + make_plating() + else + if(prob(50)) + ReplaceWithLattice() + +/turf/simulated/floor/narsie_act() + if(prob(20)) + ChangeTurf(/turf/simulated/floor/engine/cult) \ No newline at end of file diff --git a/code/game/turfs/simulated/floor_types.dm b/code/game/turfs/simulated/floor_types.dm index 21ae02b8758..08d1458f726 100644 --- a/code/game/turfs/simulated/floor_types.dm +++ b/code/game/turfs/simulated/floor_types.dm @@ -96,6 +96,8 @@ name = "engraved floor" icon_state = "cult" +/turf/simulated/floor/engine/cult/narsie_act() + return /turf/simulated/floor/engine/n20/New() ..() @@ -108,6 +110,14 @@ assume_air(adding) +/turf/simulated/floor/engine/singularity_pull(S, current_size) + if(current_size >= STAGE_FIVE) + if(prob(30)) + make_plating() + else + if(prob(30)) + ReplaceWithLattice() + /turf/simulated/floor/engine/vacuum name = "vacuum floor" icon_state = "engine" diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 482979bc0e2..c0d85564de8 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -478,3 +478,16 @@ else return attack_hand(user) return + +/turf/simulated/wall/singularity_pull(S, current_size) + if(current_size >= STAGE_FIVE) + if(prob(50)) + dismantle_wall() + return + if(current_size == STAGE_FOUR) + if(prob(30)) + dismantle_wall() + +/turf/simulated/wall/narsie_act() + if(prob(20)) + ChangeTurf(/turf/simulated/wall/cult) \ No newline at end of file diff --git a/code/game/turfs/simulated/walls_misc.dm b/code/game/turfs/simulated/walls_misc.dm index ca934731723..77edc3c2828 100644 --- a/code/game/turfs/simulated/walls_misc.dm +++ b/code/game/turfs/simulated/walls_misc.dm @@ -4,6 +4,9 @@ icon_state = "cult" walltype = "cult" +/turf/simulated/wall/cult/narsie_act() + return + /turf/simulated/wall/rust name = "rusted wall" desc = "A rusted metal wall." diff --git a/code/game/turfs/simulated/walls_reinforced.dm b/code/game/turfs/simulated/walls_reinforced.dm index bf79c84e7c0..93a7f289eb4 100644 --- a/code/game/turfs/simulated/walls_reinforced.dm +++ b/code/game/turfs/simulated/walls_reinforced.dm @@ -332,4 +332,9 @@ //Finally, CHECKING FOR FALSE WALLS if it isn't damaged else if(!d_state) return attack_hand(user) - return \ No newline at end of file + return + +/turf/simulated/wall/r_wall/singularity_pull(S, current_size) + if(current_size >= STAGE_FIVE) + if(prob(30)) + dismantle_wall() \ No newline at end of file diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 9d021fa6da2..87ab3a48ae0 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -341,3 +341,6 @@ proc/setup_map_transitions() //listamania S.transition = directions[Z_NORTH] S.Assign_Destination() + +/turf/space/singularity_act() + return \ No newline at end of file diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index a8fdfaeebd9..e861ac1786a 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -406,4 +406,14 @@ if(!src || !T) return 0 return abs(src.x - T.x) + abs(src.y - T.y) -//////////////////////////////////////////////////// \ No newline at end of file +//////////////////////////////////////////////////// + +/turf/singularity_act() + if(intact) + for(var/obj/O in contents) //this is for deleting things like wires contained in the turf + if(O.level != 1) + continue + if(O.invisibility == 101) + O.singularity_act() + ChangeTurf(/turf/space) + return(2) \ No newline at end of file diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index c9872de0a1b..bf381efbd9e 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -1109,7 +1109,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that spawn(30) for(var/obj/machinery/the_singularitygen/G in world) if(G.anchored) - var/obj/machinery/singularity/S = new /obj/machinery/singularity(get_turf(G), 50) + var/obj/singularity/S = new /obj/singularity(get_turf(G), 50) spawn(0) del(G) S.energy = 1750 diff --git a/code/modules/admin/verbs/possess.dm b/code/modules/admin/verbs/possess.dm index e2e004f215c..bb1a6b56480 100644 --- a/code/modules/admin/verbs/possess.dm +++ b/code/modules/admin/verbs/possess.dm @@ -2,7 +2,7 @@ set name = "Possess Obj" set category = null - if(istype(O,/obj/machinery/singularity)) + if(istype(O,/obj/singularity)) if(config.forbid_singulo_possession) usr << "It is forbidden to possess singularities." return diff --git a/code/modules/awaymissions/mission_code/academy.dm b/code/modules/awaymissions/mission_code/academy.dm index 16af3141647..9ae1cdb223e 100644 --- a/code/modules/awaymissions/mission_code/academy.dm +++ b/code/modules/awaymissions/mission_code/academy.dm @@ -23,15 +23,15 @@ //Academy Items -/obj/machinery/singularity/academy +/obj/singularity/academy dissipate = 0 move_self = 0 grav_pull = 1 -/obj/machinery/singularity/academy/admin_investigate_setup() +/obj/singularity/academy/admin_investigate_setup() return -/obj/machinery/singularity/academy/process() +/obj/singularity/academy/process() eat() if(prob(1)) mezzer() diff --git a/code/modules/awaymissions/mission_code/stationCollision.dm b/code/modules/awaymissions/mission_code/stationCollision.dm index dee5ae20af6..af73c27667d 100644 --- a/code/modules/awaymissions/mission_code/stationCollision.dm +++ b/code/modules/awaymissions/mission_code/stationCollision.dm @@ -21,7 +21,7 @@ //Gateroom gets its own APC specifically for the gate /area/awaymission report_alerts = 0 - + /area/awaymission/gateroom //Library, medbay, storage room @@ -162,21 +162,22 @@ var/sc_safecode5 = "[rand(0,9)]" /* * Modified Nar-Sie */ -/obj/machinery/singularity/narsie/sc_Narsie +/obj/singularity/narsie/sc_Narsie desc = "Your body becomes weak and your feel your mind slipping away as you try to comprehend what you know can't be possible." move_self = 0 //Contianed narsie does not move! grav_pull = 0 //Contained narsie does not pull stuff in! + var/uneatable = list(/turf/space, /obj/effect/overlay, /atom/movable/lighting_overlay, /mob/living/simple_animal/construct) //Override this to prevent no adminlog runtimes and admin warnings about a singularity without containment -/obj/machinery/singularity/narsie/sc_Narsie/admin_investigate_setup() +/obj/singularity/narsie/sc_Narsie/admin_investigate_setup() return -/obj/machinery/singularity/narsie/sc_Narsie/process() +/obj/singularity/narsie/sc_Narsie/process() eat() if(prob(25)) mezzer() -/obj/machinery/singularity/narsie/sc_Narsie/consume(var/atom/A) +/obj/singularity/narsie/sc_Narsie/consume(var/atom/A) if(is_type_in_list(A, uneatable)) return 0 if (istype(A,/mob/living)) @@ -197,5 +198,5 @@ var/sc_safecode5 = "[rand(0,9)]" T.ChangeTurf(/turf/space) return -/obj/machinery/singularity/narsie/sc_Narsie/ex_act() +/obj/singularity/narsie/sc_Narsie/ex_act() return \ No newline at end of file diff --git a/code/modules/lighting/lighting_overlay.dm b/code/modules/lighting/lighting_overlay.dm index efc19265e43..eb81621c628 100644 --- a/code/modules/lighting/lighting_overlay.dm +++ b/code/modules/lighting/lighting_overlay.dm @@ -54,4 +54,10 @@ ) #else color = rgb(lum_r * 255 * ., lum_g * 255 * ., lum_b * 255 * .) - #endif \ No newline at end of file + #endif + +/atom/movable/lighting_overlay/singularity_act() + return + +/atom/movable/lighting_overlay/singularity_pull() + return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index b4424b3fc66..7adb3db6607 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1501,18 +1501,6 @@ W.add_fingerprint(src) - -/mob/living/carbon/human/canSingulothPull(var/obj/machinery/singularity/singulo) - if(!..()) - return 0 - - if(istype(shoes,/obj/item/clothing/shoes/magboots)) - var/obj/item/clothing/shoes/magboots/M = shoes - if(M.magpulse) - return 0 - return 1 - - //Putting a couple of procs here that I don't know where else to dump. //Mostly going to be used for Vox and Vox Armalis, but other human mobs might like them (for adminbuse). @@ -1695,6 +1683,29 @@ return threatcount +/mob/living/carbon/human/singularity_act() + var/gain = 20 + if(mind) + if((mind.assigned_role == "Station Engineer") || (mind.assigned_role == "Chief Engineer") ) + gain = 100 + if(mind.assigned_role == "Clown") + gain = rand(-300, 300) + investigate_log("([key_name(src)]) has been consumed by the singularity.","singulo") //Oh that's where the clown ended up! + gib() + return(gain) + +/mob/living/carbon/human/singularity_pull(S, current_size) + if(current_size >= STAGE_THREE) + var/list/handlist = list(l_hand, r_hand) + for(var/obj/item/hand in handlist) + if(prob(current_size * 5) && hand.w_class >= ((11-current_size)/2) && unEquip(hand)) + step_towards(hand, src) + src << "\The [S] pulls \the [hand] from your grip!" + apply_effect(current_size * 3, IRRADIATE) + if(mob_negates_gravity()) + return + ..() + /mob/living/carbon/human/canBeHandcuffed() return 1 diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index d6c4a282aea..5ed6b60eceb 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -841,6 +841,21 @@ return "You can't fit into that vent." +/mob/living/singularity_act() + var/gain = 20 + investigate_log("([key_name(src)]) has been consumed by the singularity.","singulo") //Oh that's where the clown ended up! + gib() + return(gain) + +/mob/living/singularity_pull(S) + step_towards(src,S) + +/mob/living/narsie_act() + if(client) + makeNewConstruct(/mob/living/simple_animal/construct/harvester, src, null, 1) + spawn_dust() + gib() + return /atom/movable/proc/do_attack_animation(atom/A) var/pixel_x_diff = 0 @@ -897,4 +912,7 @@ return initial(pixel_x) /mob/living/proc/get_standard_pixel_y_offset(lying = 0) - return initial(pixel_y) \ No newline at end of file + return initial(pixel_y) + +/mob/living/proc/spawn_dust() + new /obj/effect/decal/cleanable/ash(loc) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index a3a3a73df05..9b579c4dadb 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -127,6 +127,8 @@ M.show_message("\red [user] gently taps [src] with [O]. ") +/mob/living/simple_animal/construct/narsie_act() + return /////////////////Juggernaut/////////////// @@ -301,6 +303,29 @@ +/////////////////////////////Harvester///////////////////////// + +/mob/living/simple_animal/construct/harvester + name = "Harvester" + real_name = "Harvester" + desc = "A harbinger of Nar-Sie's enlightenment. It'll be all over soon." + icon = 'icons/mob/mob.dmi' + icon_state = "harvester" + icon_living = "harvester" + maxHealth = 60 + health = 60 + melee_damage_lower = 1 + melee_damage_upper = 5 + attacktext = "prods" + speed = 0 + environment_smash = 1 + see_in_dark = 7 + attack_sound = 'sound/weapons/tap.ogg' + construct_spells = list(/obj/effect/proc_holder/spell/wizard/targeted/smoke/disable) + +/mob/living/simple_animal/construct/harvester/Process_Spacemove(var/check_drift = 0) + return 1 + ////////////////Powers////////////////// diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 12e8d071136..0792f04bf8e 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -704,7 +704,7 @@ var/list/slot_equipment_priority = list( \ namecounts[name] = 1 creatures[name] = O - if(istype(O, /obj/machinery/singularity)) + if(istype(O, /obj/singularity)) var/name = "Singularity" if (names.Find(name)) namecounts[name]++ diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 5dfa7fe46db..d6d1e3de046 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -492,3 +492,10 @@ var/list/intents = list("help","disarm","grab","harm") lname = name lname = "[lname] " M << "[lname][follow][message]" + +/proc/notify_ghosts(var/message, var/ghost_sound = null) //Easy notification of ghosts. + for(var/mob/dead/observer/O in player_list) + if(O.client) + O << "[message]" + if(ghost_sound) + O << sound(ghost_sound) \ No newline at end of file diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 4efe44ee90d..a9e7049c9d1 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -199,6 +199,10 @@ qdel(src) return +/obj/structure/cable/singularity_pull(S, current_size) + if(current_size >= STAGE_FIVE) + Destroy() + // the cable coil object, used for laying cable #define MAXCOIL 30 diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index 851bbe20eb2..01150e5c416 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -346,7 +346,7 @@ field_generator power level display //I want to avoid using global variables. spawn(1) var/temp = 1 //stops spam - for(var/obj/machinery/singularity/O in machines) + for(var/obj/singularity/O in machines) if(O.last_warning && temp) if((world.time - O.last_warning) > 50) //to stop message-spam temp = 0 diff --git a/code/modules/power/singularity/generator.dm b/code/modules/power/singularity/generator.dm index 1a88f444d24..ef3fb514b52 100644 --- a/code/modules/power/singularity/generator.dm +++ b/code/modules/power/singularity/generator.dm @@ -26,7 +26,7 @@ message_admins("[admin_message] at [x],[y],[z]",1) investigate_log("[admin_message] at [x],[y],[z]","singulo") - new /obj/machinery/singularity/(T, 50) + new /obj/singularity/(T, 50) if(src) del(src) /obj/machinery/the_singularitygen/attackby(obj/item/W, mob/user, params) diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm new file mode 100644 index 00000000000..9498a78d1c9 --- /dev/null +++ b/code/modules/power/singularity/narsie.dm @@ -0,0 +1,159 @@ +/obj/singularity/narsie //Moving narsie to a child object of the singularity so it can be made to function differently. --NEO + name = "Nar-sie's Avatar" + desc = "Your mind begins to bubble and ooze as it tries to comprehend what it sees." + icon = 'icons/obj/magic_terror.dmi' + pixel_x = -89 + pixel_y = -85 + current_size = 9 //It moves/eats like a max-size singulo, aside from range. --NEO + contained = 0 //Are we going to move around? + dissipate = 0 //Do we lose energy over time? + move_self = 1 //Do we move on our own? + grav_pull = 5 //How many tiles out do we pull? + consume_range = 6 //How many tiles out do we eat + +/obj/singularity/narsie/large + name = "Nar-Sie" + icon = 'icons/obj/narsie.dmi' + // Pixel stuff centers Narsie. + pixel_x = -236 + pixel_y = -256 + current_size = 12 + move_self = 1 //Do we move on our own? + grav_pull = 10 + consume_range = 12 //How many tiles out do we eat + +/obj/singularity/narsie/large/New() + ..() + world << "NAR-SIE HAS RISEN" + world << pick(sound('sound/hallucinations/im_here1.ogg'), sound('sound/hallucinations/im_here2.ogg')) + + var/area/A = get_area(src) + if(A) + notify_ghosts("Nar-Sie has risen in \the [A.name]. Reach out to the Geometer to be given a new shell for your soul.") + + narsie_spawn_animation() + + sleep(70) + if(emergency_shuttle && emergency_shuttle.can_call()) + emergency_shuttle.call_evac() + emergency_shuttle.launch_time = 0 // Cannot recall + + +/obj/singularity/narsie/large/attack_ghost(mob/dead/observer/user as mob) + if(!(src in view())) + user << "Your soul is too far away." + return + makeNewConstruct(/mob/living/simple_animal/construct/harvester, user, null, 1) + new /obj/effect/effect/sleep_smoke(user.loc) + + +/obj/singularity/narsie/process() + eat() + if(!target || prob(5)) + pickcultist() + move() + if(prob(25)) + mezzer() + + +/obj/singularity/narsie/Bump(atom/A)//you dare stand before a god?! + godsmack(A) + return + +/obj/singularity/narsie/Bumped(atom/A) + godsmack(A) + return + +/obj/singularity/narsie/proc/godsmack(var/atom/A) + if(istype(A,/obj/)) + var/obj/O = A + O.ex_act(1.0) + if(O) qdel(O) + + else if(isturf(A)) + var/turf/T = A + T.ChangeTurf(/turf/simulated/floor/engine/cult) + + +/obj/singularity/narsie/mezzer() + for(var/mob/living/carbon/M in oviewers(8, src)) + if(M.stat == CONSCIOUS) + if(!iscultist(M)) + M << "You feel your sanity crumble away in an instant as you gaze upon [src.name]..." + M.apply_effect(3, STUN) + + +/obj/singularity/narsie/consume(var/atom/A) + A.narsie_act() + + +/obj/singularity/narsie/ex_act() //No throwing bombs at it either. --NEO + return + + +/obj/singularity/narsie/proc/pickcultist() //Narsie rewards his cultists with being devoured first, then picks a ghost to follow. --NEO + var/list/cultists = list() + var/list/noncultists = list() + for(var/mob/living/carbon/food in living_mob_list) //we don't care about constructs or cult-Ians or whatever. cult-monkeys are fair game i guess + var/turf/pos = get_turf(food) + if(pos.z != src.z) + continue + + if(iscultist(food)) + cultists += food + else + noncultists += food + + if(cultists.len) //cultists get higher priority + acquire(pick(cultists)) + return + + if(noncultists.len) + acquire(pick(noncultists)) + return + + //no living humans, follow a ghost instead. + for(var/mob/dead/observer/ghost in player_list) + if(!ghost.client) + continue + var/turf/pos = get_turf(ghost) + if(pos.z != src.z) + continue + cultists += ghost + if(cultists.len) + acquire(pick(cultists)) + return + + +/obj/singularity/narsie/proc/acquire(var/mob/food) + target << "NAR-SIE HAS LOST INTEREST IN YOU" + target = food + if(ishuman(target)) + target << "NAR-SIE HUNGERS FOR YOUR SOUL" + else + target << "NAR-SIE HAS CHOSEN YOU TO LEAD HIM TO HIS NEXT MEAL" + +//Wizard narsie +/obj/singularity/narsie/wizard + grav_pull = 0 + +/obj/singularity/narsie/wizard/eat() + set background = BACKGROUND_ENABLED +// if(defer_powernet_rebuild != 2) +// defer_powernet_rebuild = 1 + for(var/atom/X in orange(consume_range,src)) + if(isturf(X) || istype(X, /atom/movable)) + consume(X) +// if(defer_powernet_rebuild != 2) +// defer_powernet_rebuild = 0 + return + + +/obj/singularity/narsie/proc/narsie_spawn_animation() + icon = 'icons/obj/narsie_spawn_anim.dmi' + dir = SOUTH + move_self = 0 + flick("narsie_spawn_anim",src) + sleep(11) + move_self = 1 + icon = initial(icon) diff --git a/code/modules/power/singularity/particle_accelerator/particle.dm b/code/modules/power/singularity/particle_accelerator/particle.dm index 88c87486c3f..540aee0b692 100644 --- a/code/modules/power/singularity/particle_accelerator/particle.dm +++ b/code/modules/power/singularity/particle_accelerator/particle.dm @@ -41,7 +41,7 @@ if (A) if(ismob(A)) toxmob(A) - if((istype(A,/obj/machinery/the_singularitygen))||(istype(A,/obj/machinery/singularity/))) + if((istype(A,/obj/machinery/the_singularitygen))||(istype(A,/obj/singularity/))) A:energy += energy /* else if( istype(A,/obj/effect/rust_particle_catcher) ) diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index f320bb64f6c..8d4cdbfc45c 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -1,27 +1,15 @@ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33 -// Added spess ghoasts/cameras to this so they don't add to the lag. - N3X -var/global/narsie_cometh = 0 -var/global/list/uneatable = list( - /turf/space, - /obj/effect/overlay, - /atom/movable/lighting_overlay, - /mob/dead, - /mob/camera, - /mob/new_player - ) - -/obj/machinery/singularity/ - name = "Gravitational Singularity" - desc = "A Gravitational Singularity." +/obj/singularity + name = "gravitational singularity" + desc = "A gravitational singularity." icon = 'icons/obj/singularity.dmi' icon_state = "singularity_s1" anchored = 1 density = 1 layer = 6 - light_range = 6 + luminosity = 6 unacidable = 1 //Don't comment this out. - use_power = 0 var/current_size = 1 var/allowed_size = 1 var/contained = 1 //Are we going to move around? @@ -36,86 +24,95 @@ var/global/list/uneatable = list( var/event_chance = 15 //Prob for event each tick var/target = null //its target. moves towards the target if it has one var/last_failed_movement = 0//Will not move in the same dir if it couldnt before, will help with the getting stuck on fields thing - var/teleport_del = 0 var/last_warning -/obj/machinery/singularity/New(loc, var/starting_energy = 50, var/temp = 0) +/obj/singularity/New(loc, var/starting_energy = 50, var/temp = 0) //CARN: admin-alert for chuckle-fuckery. admin_investigate_setup() src.energy = starting_energy - if(temp) - spawn(temp) - del(src) ..() - for(var/obj/machinery/singularity_beacon/singubeacon in machines) + processing_objects.Add(src) + for(var/obj/machinery/singularity_beacon/singubeacon in world) if(singubeacon.active) target = singubeacon break return +/obj/singularity/Destroy() + processing_objects.Remove(src) + ..() -/obj/machinery/singularity/attack_hand(mob/user as mob) +/obj/singularity/Move(atom/newloc, direct) + if(current_size >= STAGE_FIVE || check_turfs_in(direct)) + last_failed_movement = 0//Reset this because we moved + return ..() + else + last_failed_movement = direct + return 0 + + +/obj/singularity/attack_hand(mob/user as mob) consume(user) return 1 - -/obj/machinery/singularity/blob_act(severity) +/obj/singularity/blob_act(severity) return - -/obj/machinery/singularity/ex_act(severity) +/obj/singularity/ex_act(severity) switch(severity) if(1.0) - if(prob(25)) - investigate_log("has been destroyed by an explosion.","singulo") - del(src) + if(current_size <= STAGE_TWO) + investigate_log("has been destroyed by a heavy explosion.","singulo") + qdel(src) return else - energy += 50 - if(2.0 to 3.0) - energy += round((rand(20,60)/2),1) - return + energy -= round(((energy+1)/2),1) + if(2.0) + energy -= round(((energy+1)/3),1) + if(3.0) + energy -= round(((energy+1)/4),1) return -/obj/machinery/singularity/bullet_act(obj/item/projectile/P) + +/obj/singularity/bullet_act(obj/item/projectile/P) return 0 //Will there be an impact? Who knows. Will we see it? No. -/obj/machinery/singularity/Bump(atom/A) +/obj/singularity/Bump(atom/A) consume(A) return -/obj/machinery/singularity/Bumped(atom/A) +/obj/singularity/Bumped(atom/A) consume(A) return -/obj/machinery/singularity/process() - eat() - dissipate() - check_energy() - - if(current_size >= 3) +/obj/singularity/process() + if(current_size >= STAGE_TWO) move() pulse() if(prob(event_chance))//Chance for it to run a special event TODO:Come up with one or two more that fit event() + eat() + dissipate() + check_energy() + return -/obj/machinery/singularity/attack_ai() //to prevent ais from gibbing themselves when they click on one. +/obj/singularity/attack_ai() //to prevent ais from gibbing themselves when they click on one. return -/obj/machinery/singularity/proc/admin_investigate_setup() +/obj/singularity/proc/admin_investigate_setup() last_warning = world.time var/count = locate(/obj/machinery/containment_field) in orange(30, src) if(!count) message_admins("A singulo has been created without containment fields active ([x],[y],[z])",1) investigate_log("was created. [count?"":"No containment fields were active"]","singulo") -/obj/machinery/singularity/proc/dissipate() +/obj/singularity/proc/dissipate() if(!dissipate) return if(dissipate_track >= dissipate_delay) @@ -125,13 +122,13 @@ var/global/list/uneatable = list( dissipate_track++ -/obj/machinery/singularity/proc/expand(var/force_size = 0) +/obj/singularity/proc/expand(var/force_size = 0) var/temp_allowed_size = src.allowed_size if(force_size) temp_allowed_size = force_size switch(temp_allowed_size) - if(1) - current_size = 1 + if(STAGE_ONE) + current_size = STAGE_ONE icon = 'icons/obj/singularity.dmi' icon_state = "singularity_s1" pixel_x = 0 @@ -141,8 +138,8 @@ var/global/list/uneatable = list( dissipate_delay = 10 dissipate_track = 0 dissipate_strength = 1 - if(3)//1 to 3 does not check for the turfs if you put the gens right next to a 1x1 then its going to eat them - current_size = 3 + if(STAGE_TWO)//1 to 3 does not check for the turfs if you put the gens right next to a 1x1 then its going to eat them + current_size = STAGE_TWO icon = 'icons/effects/96x96.dmi' icon_state = "singularity_s3" pixel_x = -32 @@ -152,9 +149,9 @@ var/global/list/uneatable = list( dissipate_delay = 5 dissipate_track = 0 dissipate_strength = 5 - if(5) + if(STAGE_THREE) if((check_turfs_in(1,2))&&(check_turfs_in(2,2))&&(check_turfs_in(4,2))&&(check_turfs_in(8,2))) - current_size = 5 + current_size = STAGE_THREE icon = 'icons/effects/160x160.dmi' icon_state = "singularity_s5" pixel_x = -64 @@ -164,9 +161,9 @@ var/global/list/uneatable = list( dissipate_delay = 4 dissipate_track = 0 dissipate_strength = 20 - if(7) + if(STAGE_FOUR) if((check_turfs_in(1,3))&&(check_turfs_in(2,3))&&(check_turfs_in(4,3))&&(check_turfs_in(8,3))) - current_size = 7 + current_size = STAGE_FOUR icon = 'icons/effects/224x224.dmi' icon_state = "singularity_s7" pixel_x = -96 @@ -176,8 +173,8 @@ var/global/list/uneatable = list( dissipate_delay = 10 dissipate_track = 0 dissipate_strength = 10 - if(9)//this one also lacks a check for gens because it eats everything - current_size = 9 + if(STAGE_FIVE)//this one also lacks a check for gens because it eats everything + current_size = STAGE_FIVE icon = 'icons/effects/288x288.dmi' icon_state = "singularity_s9" pixel_x = -128 @@ -194,134 +191,46 @@ var/global/list/uneatable = list( return 0 -/obj/machinery/singularity/proc/check_energy() +/obj/singularity/proc/check_energy() if(energy <= 0) investigate_log("collapsed.","singulo") - del(src) + qdel(src) return 0 switch(energy)//Some of these numbers might need to be changed up later -Mport if(1 to 199) - allowed_size = 1 + allowed_size = STAGE_ONE if(200 to 499) - allowed_size = 3 + allowed_size = STAGE_TWO if(500 to 999) - allowed_size = 5 + allowed_size = STAGE_THREE if(1000 to 1999) - allowed_size = 7 + allowed_size = STAGE_FOUR if(2000 to INFINITY) - allowed_size = 9 + allowed_size = STAGE_FIVE if(current_size != allowed_size) expand() return 1 -/obj/machinery/singularity/proc/eat() - //set background = 1 - if(defer_powernet_rebuild != 2) - defer_powernet_rebuild = 1 - // Let's just make this one loop. +/obj/singularity/proc/eat() + set background = BACKGROUND_ENABLED for(var/atom/X in orange(grav_pull,src)) - // N3X: Move this up here since get_dist is slow. - if(is_type_in_list(X, uneatable)) continue - if(!X.simulated) continue - var/dist = get_dist(X, src) - - // Movable atoms only - if(dist > consume_range && istype(X, /atom/movable)) - if(canPull(X)) - step_towards(X,src) - /* - if((X &&!X:anchored && !istype(X,/mob/living/carbon/human))|| (src.current_size >= 9)) - step_towards(X,src) - else if(istype(X,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = X - if(istype(H.shoes,/obj/item/clothing/shoes/magboots)) - var/obj/item/clothing/shoes/magboots/M = H.shoes - if(M.magpulse) - continue - step_towards(H,src) - */ - // Turf and movable atoms - else if(dist <= consume_range && (isturf(X) || istype(X, /atom/movable))) + var/obj/singularity/S = src + if(dist > consume_range) + X.singularity_pull(S, current_size) + else if(dist <= consume_range) consume(X) - - if(defer_powernet_rebuild != 2) - defer_powernet_rebuild = 0 return -// Singulo optimization: -// Jump out whenever we've made a decision. -/obj/machinery/singularity/proc/canPull(var/atom/movable/A) - // If we're big enough, stop checking for this and that and JUST EAT. - if(current_size >= 9) - return 1 - else - if(A && !A:anchored) - if(A.canSingulothPull(src)) - return 1 - return 0 - -/obj/machinery/singularity/proc/consume(var/atom/A) - var/gain = 0 - if(is_type_in_list(A, uneatable)) - return 0 - if(!A.simulated) - return 0 - if (istype(A,/mob/living))//Mobs get gibbed - var/mob/living/M = A - gain = 20 - if(istype(M,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - if(H.mind) - switch(H.mind.assigned_role) - if("Station Engineer","Chief Engineer") - gain = 100 - if("Clown") - gain = rand(-300, 300) // HONK - M.gib() - // Why - sleep(1) - else if(istype(A,/obj/)) - - if (istype(A,/obj/item/weapon/storage/backpack/holding)) - var/dist = max((current_size - 2),1) - explosion(src.loc,(dist),(dist*2),(dist*4)) - return - if(istype(A, /obj/machinery/singularity))//Welp now you did it - var/obj/machinery/singularity/S = A - src.energy += (S.energy/2)//Absorb most of it - del(S) - var/dist = max((current_size - 2),1) - explosion(src.loc,(dist),(dist*2),(dist*4)) - return//Quits here, the obj should be gone, hell we might be - - if((teleport_del) && (!istype(A, /obj/machinery)))//Going to see if it does not lag less to tele items over to Z 2 - qdel(A) - else - A.ex_act(1.0) - if(A) - qdel(A) - gain = 2 - else if(isturf(A)) - var/turf/T = A - if(istype(T,/turf/simulated/wall)) - var/turf/simulated/wall/W = T - W.del_suppress_resmoothing=1 // Reduce lag from wallsmoothing. - if(T.intact) - for(var/obj/O in T.contents) - if(O.level != 1) - continue - if(O.invisibility == 101) - src.consume(O) - T.ChangeTurf(/turf/space) - gain = 2 +/obj/singularity/proc/consume(var/atom/A) + var/gain = A.singularity_act(current_size) src.energy += gain return -/obj/machinery/singularity/proc/move(var/force_move = 0) +/obj/singularity/proc/move(var/force_move = 0) if(!move_self) return 0 @@ -333,37 +242,24 @@ var/global/list/uneatable = list( if(target && prob(60)) movement_dir = get_dir(src,target) //moves to a singulo beacon, if there is one - if(current_size >= 9)//The superlarge one does not care about things in its way - spawn(0) - step(src, movement_dir) - spawn(1) - step(src, movement_dir) - return 1 - else if(check_turfs_in(movement_dir)) - last_failed_movement = 0//Reset this because we moved - spawn(0) - step(src, movement_dir) - return 1 - else - last_failed_movement = movement_dir - return 0 + step(src, movement_dir) -/obj/machinery/singularity/proc/check_turfs_in(var/direction = 0, var/step = 0) +/obj/singularity/proc/check_turfs_in(var/direction = 0, var/step = 0) if(!direction) return 0 var/steps = 0 if(!step) switch(current_size) - if(1) + if(STAGE_ONE) steps = 1 - if(3) + if(STAGE_TWO) steps = 3//Yes this is right - if(5) + if(STAGE_THREE) steps = 3 - if(7) + if(STAGE_FOUR) steps = 4 - if(9) + if(STAGE_FIVE) steps = 5 else steps = step @@ -384,12 +280,12 @@ var/global/list/uneatable = list( dir2 = 1 dir3 = 2 var/turf/T2 = T - for(var/j = 1 to steps) + for(var/j = 1 to steps-1) T2 = get_step(T2,dir2) if(!isturf(T2)) return 0 turfs.Add(T2) - for(var/k = 1 to steps) + for(var/k = 1 to steps-1) T = get_step(T,dir3) if(!isturf(T)) return 0 @@ -402,7 +298,7 @@ var/global/list/uneatable = list( return 1 -/obj/machinery/singularity/proc/can_move(var/turf/T) +/obj/singularity/proc/can_move(var/turf/T) if(!T) return 0 if((locate(/obj/machinery/containment_field) in T)||(locate(/obj/machinery/shieldwall) in T)) @@ -418,7 +314,7 @@ var/global/list/uneatable = list( return 1 -/obj/machinery/singularity/proc/event() +/obj/singularity/proc/event() var/numb = pick(1,2,3,4,5,6) switch(numb) if(1)//EMP @@ -432,7 +328,7 @@ var/global/list/uneatable = list( return 1 -/obj/machinery/singularity/proc/toxmob() +/obj/singularity/proc/toxmob() var/toxrange = 10 var/toxdamage = 4 var/radiation = 15 @@ -448,7 +344,7 @@ var/global/list/uneatable = list( return -/obj/machinery/singularity/proc/mezzer() +/obj/singularity/proc/mezzer() for(var/mob/living/carbon/M in oviewers(8, src)) if(istype(M, /mob/living/carbon/brain)) //Ignore brains continue @@ -456,202 +352,33 @@ var/global/list/uneatable = list( if(M.stat == CONSCIOUS) if (istype(M,/mob/living/carbon/human)) var/mob/living/carbon/human/H = M - if(istype(H.glasses,/obj/item/clothing/glasses/meson)) - H << "\blue You look directly into The [src.name], good thing you had your protective eyewear on!" - return - M << "\red You look directly into The [src.name] and feel weak." + if(istype(H.glasses, /obj/item/clothing/glasses/meson)) + var/obj/item/clothing/glasses/meson/MS = H.glasses + if(MS.vision_flags == SEE_TURFS) + H << "You look directly into the [src.name], good thing you had your protective eyewear on!" + return + M.apply_effect(3, STUN) - for(var/mob/O in viewers(M, null)) - O.show_message(text("\red [] stares blankly at The []!", M, src), 1) + M.visible_message("[M] stares blankly at the [src.name]!", \ + "You look directly into the [src.name] and feel weak.") return -/obj/machinery/singularity/proc/emp_area() +/obj/singularity/proc/emp_area() empulse(src, 8, 10) return -/obj/machinery/singularity/proc/pulse() +/obj/singularity/proc/pulse() for(var/obj/machinery/power/rad_collector/R in rad_collectors) if(get_dist(R, src) <= 15) // Better than using orange() every process R.receive_pulse(energy) return - - -/obj/machinery/singularity/narsie //Moving narsie to a child object of the singularity so it can be made to function differently. --NEO - gender = NEUTER - name = "Nar-sie's Avatar" - desc = "Your mind begins to bubble and ooze as it tries to comprehend what it sees." - icon = 'icons/obj/magic_terror.dmi' - pixel_x = -89 - pixel_y = -85 - current_size = 9 //It moves/eats like a max-size singulo, aside from range. --NEO - contained = 0 //Are we going to move around? - dissipate = 0 //Do we lose energy over time? - move_self = 1 //Do we move on our own? - grav_pull = 10 //How many tiles out do we pull? - consume_range = 3 //How many tiles out do we eat - var/last_boom = 0 - -/obj/machinery/singularity/narsie/large - name = "Nar-Sie" - icon = 'icons/obj/narsie.dmi' - // Pixel stuff centers Narsie. - pixel_x = -236 - pixel_y = -256 - current_size = 12 - grav_pull = 10 - consume_range = 12 - - -/obj/machinery/singularity/narsie/large/New() - ..() - world << "NAR-SIE HAS RISEN" - spawn_animation() - if(emergency_shuttle && emergency_shuttle.can_call()) - emergency_shuttle.call_evac() - emergency_shuttle.launch_time = 0 // Cannot recall - narsie_cometh = 1 - - -/obj/machinery/singularity/narsie/proc/spawn_animation() - icon = 'icons/obj/narsie_spawn_anim.dmi' - src.dir = SOUTH - move_self = 0 - flick("narsie_spawn_anim", src) - sleep(11) //0.5 longer than the animation. - move_self = 1 - icon = initial(icon) - - -/obj/machinery/singularity/narsie/process() - eat() - if(!target || prob(5)) - pickcultist() - move() - if(prob(25)) - mezzer() - - -/obj/machinery/singularity/narsie/Bump(atom/A)//you dare stand before a god?! - godsmack(A) - return - -/obj/machinery/singularity/narsie/Bumped(atom/A) - godsmack(A) - return - -/obj/machinery/singularity/narsie/proc/godsmack(var/atom/A) - if(istype(A,/obj/)) - var/obj/O = A - O.ex_act(1.0) - if(O) qdel(O) - - else if(isturf(A)) - var/turf/T = A - T.ChangeTurf(/turf/simulated/floor/engine/cult) - - -/obj/machinery/singularity/narsie/mezzer() - for(var/mob/living/carbon/M in oviewers(8, src)) - if(M.stat == CONSCIOUS) - if(!iscultist(M)) - M << "\red You feel your sanity crumble away in an instant as you gaze upon [src.name]..." - M.apply_effect(3, STUN) - - -/obj/machinery/singularity/narsie/consume(var/atom/A) - if(is_type_in_list(A, uneatable)) - return 0 - if(!A.simulated) - return 0 - if (istype(A,/mob/living))//Mobs get gibbed - A:gib() - else if(istype(A,/obj)) - var/obj/O = A - machines -= O - processing_objects -= O - qdel(O) - else if(isturf(A)) - var/turf/T = A - if(istype(T,/turf/simulated/wall)) - var/turf/simulated/wall/W = T - W.del_suppress_resmoothing=1 // Reduce lag from wallsmoothing. - if(T.intact) - for(var/obj/O in T.contents) - if(O.level != 1) - continue - if(O.invisibility == 101) - src.consume(O) - A:ChangeTurf(/turf/space) - if(last_boom + 100 < world.time && prob(5)) - explosion(loc, -1, -1, -1, 1, 0) //Since we're not exploding everything in consume() toss out an explosion effect every now and again - last_boom = world.time - return - -/obj/machinery/singularity/narsie/ex_act() //No throwing bombs at it either. --NEO - return - -/obj/machinery/singularity/narsie/proc/pickcultist() //Narsie rewards it's cultists with being devoured first, then picks a ghost to follow. --NEO - var/list/cultists = list() - for(var/datum/mind/cult_nh_mind in ticker.mode.cult) - if(!cult_nh_mind.current) - continue - if(cult_nh_mind.current.stat) - continue - var/turf/pos = get_turf(cult_nh_mind.current) - if(pos.z != src.z) - continue - cultists += cult_nh_mind.current - if(cultists.len) - acquire(pick(cultists)) - return - //If there was living cultists, it picks one to follow. - for(var/mob/living/carbon/human/food in living_mob_list) - if(food.stat) - continue - var/turf/pos = get_turf(food) - if(pos.z != src.z) - continue - cultists += food - if(cultists.len) - acquire(pick(cultists)) - return - //no living cultists, pick a living human instead. - for(var/mob/dead/observer/ghost in player_list) - if(!ghost.client) - continue - var/turf/pos = get_turf(ghost) - if(pos.z != src.z) - continue - cultists += ghost - if(cultists.len) - acquire(pick(cultists)) - return - //no living humans, follow a ghost instead. - -/obj/machinery/singularity/narsie/proc/acquire(var/mob/food) - target << "\blue NAR-SIE HAS LOST INTEREST IN YOU" - target = food - if(ishuman(target)) - target << "\red NAR-SIE HUNGERS FOR YOUR SOUL" - else - target << "\red NAR-SIE HAS CHOSEN YOU TO LEAD THEM TO THEIR NEXT MEAL" - -//Wizard narsie - -/obj/machinery/singularity/narsie/wizard - grav_pull = 0 - -/obj/machinery/singularity/narsie/wizard/eat() - //set background = 1 - if(defer_powernet_rebuild != 2) - defer_powernet_rebuild = 1 - for(var/atom/X in orange(consume_range,src)) - if(isturf(X) || istype(X, /atom/movable)) - consume(X) - if(defer_powernet_rebuild != 2) - defer_powernet_rebuild = 0 - return +/obj/singularity/singularity_act() + var/gain = (energy/2) + var/dist = max((current_size - 2),1) + explosion(src.loc,(dist),(dist*2),(dist*4)) + qdel(src) + return(gain) diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index b378282ca27..556e172050b 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -72,6 +72,9 @@ icon_state = "emitter" damage = 30 +/obj/item/projectile/beam/emitter/singularity_pull() + return //don't want the emitters to miss + /obj/item/projectile/lasertag name = "laser tag beam" icon_state = "omnilaser" diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 4bb71244045..1aef00f1965 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -478,6 +478,11 @@ else return ..(mover, target, height, air_group) + + singularity_pull(S, current_size) + if(current_size >= STAGE_FIVE) + Destroy() + // virtual disposal object // travels through pipes in lieu of actual items // contents will be items flushed by the disposal @@ -682,6 +687,10 @@ expel(H, T, 0) ..() + singularity_pull(S, current_size) + if(current_size >= STAGE_FIVE) + Destroy() + // returns the direction of the next pipe object, given the entrance dir // by default, returns the bitmask of remaining directions proc/nextdir(var/fromdir) diff --git a/code/modules/supermatter/supermatter.dm b/code/modules/supermatter/supermatter.dm index f0a80a866ee..bc75e077e27 100644 --- a/code/modules/supermatter/supermatter.dm +++ b/code/modules/supermatter/supermatter.dm @@ -86,6 +86,7 @@ var/obj/item/device/radio/radio var/debug = 0 + var/uneatable = list(/turf/space, /obj/effect/overlay, /atom/movable/lighting_overlay, /mob/dead, /mob/camera, /mob/new_player) /obj/machinery/power/supermatter/New() . = ..() diff --git a/paradise.dme b/paradise.dme index b94388425b1..92e739d195b 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1512,6 +1512,7 @@ #include "code\modules\power\singularity\field_generator.dm" #include "code\modules\power\singularity\generator.dm" #include "code\modules\power\singularity\investigate.dm" +#include "code\modules\power\singularity\narsie.dm" #include "code\modules\power\singularity\singularity.dm" #include "code\modules\power\singularity\particle_accelerator\particle.dm" #include "code\modules\power\singularity\particle_accelerator\particle_accelerator.dm"