From 90b96540612a1cf5e6670f897dbfd9580f66c2da Mon Sep 17 00:00:00 2001 From: "rastaf.zero@gmail.com" Date: Thu, 23 Dec 2010 03:31:13 +0000 Subject: [PATCH] Massive singularity fix: -engine won't get unlimited floor tiles from reinforced floor and thus won't grow constantly; -collectors can receive energy from several sings; -various graphic glitches fixed; -released singularity can now be catched. In theory. -singularity cannot be killed by small/far explosion; -containment field cannot be exploded at all; -fields and singularity now are immune to blob; -messages improved; -machinery fingerprints handling fixed; -engines 3*3 sings must work now; -emitters (and some other machines) now really uses power; -collector arrays and controllers now requires engine access; -powerful singularity now deal more radiation damage, but you can hide behind walls; -improved generator's sprites Miscellaneous: -cell chargers now actually consumes power; -fixed examine verb for tanks; -fixed airlocks won't opens automatically in rare cases; -beer now don't instakill plants; -vents and scrubbers now requires and uses power; -more user-friendly canisters interface; Optimizations: -brig doors now causes lesser cpu load; -small optimizations and code cleanup for some atmos machinery; git-svn-id: http://tgstation13.googlecode.com/svn/trunk@691 316c924e-a436-60f5-8080-3fe189b3f50e --- .../components/unary/vent_pump.dm | 27 +- .../components/unary/vent_scrubber.dm | 23 +- code/WorkInProgress/Chemistry-Recipes.dm | 2 +- code/game/cellautomata.dm | 2 +- code/game/machinery/atmoalter/canister.dm | 20 +- .../atmoalter/portable_atmospherics.dm | 2 + code/game/machinery/atmoalter/pump.dm | 17 +- code/game/machinery/atmoalter/scrubber.dm | 18 +- code/game/machinery/doors/brigdoors.dm | 70 +- code/game/machinery/doors/door.dm | 4 +- code/game/machinery/hydroponics.dm | 4 +- code/game/machinery/singularity.dm | 1008 +++++++++-------- code/game/objects/tank.dm | 36 +- code/modules/power/cell.dm | 9 +- code/modules/power/power.dm | 5 + config/admins.txt | 5 +- icons/obj/singularity.dmi | Bin 9011 -> 7252 bytes 17 files changed, 651 insertions(+), 601 deletions(-) diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm index 81883558d11..eb338e199b0 100644 --- a/code/ATMOSPHERICS/components/unary/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm @@ -29,19 +29,21 @@ var/welded = 0 // Added for aliens -- TLE update_icon() - if(on&&node) + if(on && !(stat & (NOPOWER|BROKEN))) if(pump_direction) icon_state = "[level == 1 && istype(loc, /turf/simulated) ? "h" : "" ]out" else icon_state = "[level == 1 && istype(loc, /turf/simulated) ? "h" : "" ]in" else icon_state = "[level == 1 && istype(loc, /turf/simulated) ? "h" : "" ]off" - on = 0 return - process() ..() + if(stat & (NOPOWER|BROKEN)) + return + if (!node) + on = 0 broadcast_status() if(!on) @@ -66,6 +68,7 @@ var/datum/gas_mixture/removed = air_contents.remove(transfer_moles) + use_power(10, ENVIRON) loc.assume_air(removed) if(network) @@ -84,7 +87,9 @@ var/transfer_moles = pressure_delta*air_contents.volume/(environment.temperature * R_IDEAL_GAS_EQUATION) var/datum/gas_mixture/removed = loc.remove_air(transfer_moles) - + if (isnull(removed)) //in space + return + use_power(10, ENVIRON) air_contents.merge(removed) if(network) @@ -204,14 +209,13 @@ user << "\blue You need more welding fuel to complete this task." return W:use_fuel(1) + playsound(src.loc, 'Welder2.ogg', 50, 1) if(!welded) - user.visible_message("[user] welds the vent shut.", "You weld the vent shut.") - playsound(src.loc, 'Welder2.ogg', 50, 1) + user.visible_message("[user] welds the vent shut.", "You weld the vent shut.", "You hear welding.") welded = 1 else - user.visible_message("[user] unwelds the vent.", "You unweld the vent.") - playsound(src.loc, 'Welder2.ogg', 50, 1) + user.visible_message("[user] unwelds the vent.", "You unweld the vent.", "You hear welding.") welded = 0 examine() @@ -219,3 +223,10 @@ ..() if(welded) usr << "It seems welded shut." + + power_change() + if(powered(ENVIRON)) + stat &= ~NOPOWER + else + stat |= NOPOWER + update_icon() diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm index 68a00623163..03317e68bb9 100644 --- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm @@ -21,18 +21,15 @@ var/panic = 0 //is this scrubber panicked? update_icon() - if(on&&node) + if(node && on && !(stat & (NOPOWER|BROKEN))) if(scrubbing) icon_state = "[level == 1 && istype(loc, /turf/simulated) ? "h" : "" ]on" else icon_state = "[level == 1 && istype(loc, /turf/simulated) ? "h" : "" ]in" else icon_state = "[level == 1 && istype(loc, /turf/simulated) ? "h" : "" ]off" - on = 0 - return - proc set_frequency(new_frequency) radio_controller.remove_object(src, "[frequency]") @@ -66,11 +63,15 @@ process() ..() + if(stat & (NOPOWER|BROKEN)) + return + if (!node) + on = 0 broadcast_status() - if(!on) return 0 + var/datum/gas_mixture/environment = loc.return_air() if(scrubbing) @@ -79,7 +80,9 @@ //Take a gas sample var/datum/gas_mixture/removed = loc.remove_air(transfer_moles) - + if (isnull(removed)) //in space + return + use_power(30, ENVIRON) //Filter it var/datum/gas_mixture/filtered_out = new filtered_out.temperature = removed.temperature @@ -109,6 +112,7 @@ network.update = 1 else //Just siphoning all air + use_power(volume_rate/12, ENVIRON) var/transfer_moles = environment.total_moles()*(volume_rate/environment.volume) var/datum/gas_mixture/removed = loc.remove_air(transfer_moles) @@ -161,3 +165,10 @@ broadcast_status() update_icon() return + + power_change() + if(powered(ENVIRON)) + stat &= ~NOPOWER + else + stat |= NOPOWER + update_icon() diff --git a/code/WorkInProgress/Chemistry-Recipes.dm b/code/WorkInProgress/Chemistry-Recipes.dm index c9476ff8b87..be1a0fbba46 100644 --- a/code/WorkInProgress/Chemistry-Recipes.dm +++ b/code/WorkInProgress/Chemistry-Recipes.dm @@ -669,7 +669,7 @@ datum result_amount = 5 manhattan - name = "Manhattan " + name = "Manhattan" id = "manhattan" result = "manhattan" required_reagents = list("whiskey" = 2, "vermouth" = 1) diff --git a/code/game/cellautomata.dm b/code/game/cellautomata.dm index ded8d44c385..003b48c2f66 100644 --- a/code/game/cellautomata.dm +++ b/code/game/cellautomata.dm @@ -150,7 +150,7 @@ /atom/movable/Bump(var/atom/A as mob|obj|turf|area, yes) spawn( 0 ) if ((A && yes)) - A.last_bumped = world.timeofday + A.last_bumped = world.time A.Bumped(src) return ..() diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 083d43569f1..d7c4d8ac090 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -93,16 +93,14 @@ ..() - var/datum/gas_mixture/environment - - if(holding) - environment = holding.air_contents - else - environment = loc.return_air() - - var/env_pressure = environment.return_pressure() - if(valve_open) + var/datum/gas_mixture/environment + if(holding) + environment = holding.air_contents + else + environment = loc.return_air() + + var/env_pressure = environment.return_pressure() var/pressure_delta = min(release_pressure - env_pressure, (air_contents.return_pressure() - env_pressure)/2) //Can not have a pressure delta that would cause environment pressure > tank pressure @@ -117,9 +115,9 @@ environment.merge(removed) else loc.assume_air(removed) + src.update_icon() src.updateDialog() - src.update_icon() return /obj/machinery/portable_atmospherics/canister/return_air() @@ -166,7 +164,7 @@ Port Status: [(connected_port)?("Connected"):("Disconnected")] [holding_text]
Release Valve: [valve_open?("Open"):("Closed")]
-Release Pressure: - - [release_pressure] + +
+Release Pressure: - - - - [release_pressure] + + + +

Close
"} diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm index 3c9872d2669..f7c964dea8c 100644 --- a/code/game/machinery/atmoalter/portable_atmospherics.dm +++ b/code/game/machinery/atmoalter/portable_atmospherics.dm @@ -22,6 +22,8 @@ if(!connected_port) //only react when pipe_network will ont it do it for you //Allow for reactions air_contents.react() + else + update_icon() Del() del(air_contents) diff --git a/code/game/machinery/atmoalter/pump.dm b/code/game/machinery/atmoalter/pump.dm index c0f14b1a358..b1c57a8d611 100644 --- a/code/game/machinery/atmoalter/pump.dm +++ b/code/game/machinery/atmoalter/pump.dm @@ -23,15 +23,12 @@ /obj/machinery/portable_atmospherics/pump/process() ..() - - var/datum/gas_mixture/environment - if(holding) - environment = holding.air_contents - else - environment = loc.return_air() - - if(on) + var/datum/gas_mixture/environment + if(holding) + environment = holding.air_contents + else + environment = loc.return_air() if(direction_out) var/pressure_delta = target_pressure - environment.return_pressure() //Can not have a pressure delta that would cause environment pressure > tank pressure @@ -63,9 +60,9 @@ removed = loc.remove_air(transfer_moles) air_contents.merge(removed) + //src.update_icon() src.updateDialog() - src.update_icon() return /obj/machinery/portable_atmospherics/pump/return_air() @@ -93,7 +90,7 @@ Port Status: [(connected_port)?("Connected"):("Disconnected")]
Power Switch: [on?("On"):("Off")]
Pump Direction: [direction_out?("Out"):("In")]
-Target Pressure: - - [target_pressure] + +
+Target Pressure: - - - - [target_pressure] + + + +

Close
"} diff --git a/code/game/machinery/atmoalter/scrubber.dm b/code/game/machinery/atmoalter/scrubber.dm index 7012473d256..228d50d7522 100644 --- a/code/game/machinery/atmoalter/scrubber.dm +++ b/code/game/machinery/atmoalter/scrubber.dm @@ -23,14 +23,12 @@ /obj/machinery/portable_atmospherics/scrubber/process() ..() - var/datum/gas_mixture/environment - if(holding) - environment = holding.air_contents - else - environment = loc.return_air() - - if(on) + var/datum/gas_mixture/environment + if(holding) + environment = holding.air_contents + else + environment = loc.return_air() var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles() //Take a gas sample @@ -64,9 +62,8 @@ environment.merge(removed) else loc.assume_air(removed) - + //src.update_icon() src.updateDialog() - src.update_icon() return /obj/machinery/portable_atmospherics/scrubber/return_air() @@ -93,7 +90,8 @@ Port Status: [(connected_port)?("Connected"):("Disconnected")] [holding_text]
Power Switch: [on?("On"):("Off")]
-Target Pressure: - - [volume_rate] + +
+Power regulator: - - - - [volume_rate] + + + +
+
Close
"} diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index f64c0a293ee..60086494cf3 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -19,27 +19,41 @@ var/timing = 1 // boolean, true/1 timer is on, false/0 means it's not timing var/childproof = 0 // boolean, when activating the door controls, locks door for 1 minute var/picture_state // icon_state of alert picture, if not displaying text/numbers + var/obj/machinery/door/window/brigdoor/targetdoor + var/list/obj/machinery/flasher/targetflashers + +/obj/machinery/door_timer/New() + ..() + for(var/obj/machinery/door/window/brigdoor/M in world) + if (M.id == src.id) + targetdoor = M + break + if (isnull(targetdoor)) + stat |= BROKEN + targetflashers = list() + for(var/obj/machinery/flasher/F in world) + if(F.id == src.id) + targetflashers += F //Main door timer loop, if it's timing and time is >0 reduce time by 1. // if it's less than 0, open door, reset timer // update the door_timer window and the icon /obj/machinery/door_timer/process() - ..() + if (stat & (NOPOWER|BROKEN)) + return if (src.timing) if (src.time > 0) - src.time = round(src.time) - 1 + src.time-- else src.opendoor() // open doors, reset timer, clear status screen src.time = 0 src.timing = 0 src.updateDialog() src.update_icon() - else // keep door open may cause lag as it's checking every second if someone closed door - for(var/obj/machinery/door/window/brigdoor/M in world) - if (M.id == src.id) - if(M.density) - spawn( 0 ) - M.open() + else + if(targetdoor && targetdoor.density) //door searching cicle moved to New() + spawn( 0 ) + targetdoor.open() return // has the door power sitatuation changed, if so update icon. @@ -51,11 +65,9 @@ /obj/machinery/door_timer/proc/opendoor() if(stat & (NOPOWER|BROKEN)) return - for(var/obj/machinery/door/window/brigdoor/M in world) - if (M.id == src.id) - if(M.density) - spawn( 0 ) - M.open() + if(targetdoor.density) + spawn( 0 ) + targetdoor.open() src.updateUsrDialog() src.update_icon() return @@ -63,11 +75,9 @@ /obj/machinery/door_timer/proc/closedoor() if(stat & (NOPOWER|BROKEN)) return - for(var/obj/machinery/door/window/brigdoor/M in world) - if (M.id == src.id) - if(!M.density) - spawn( 0 ) - M.close() + if(!targetdoor.density) + spawn( 0 ) + targetdoor.close() src.updateUsrDialog() src.update_icon() return @@ -100,12 +110,13 @@ var/second = src.time % 60 var/minute = (src.time - second) / 60 dat += text("

\nTimer System: [d2]\nTime Left: [(minute ? text("[minute]:") : null)][second] - - + +") - for(var/obj/machinery/flasher/F in world) - if(F.id == src.id) - if(F.last_flash && world.time < F.last_flash + 150) - dat += text("

Flash Cell (Charging)", src) - else - dat += text("

Flash Cell", src) + if (targetflashers.len) + dat += "
" + for(var/obj/machinery/flasher/F in targetflashers) + if(F.last_flash && world.time < F.last_flash + 150) + dat += text("
Flash Cell (Charging)", src) + else + dat += text("
Flash Cell", src) dat += text("

Close", user) user << browse(dat, "window=computer;size=400x500") onclose(user, "computer") @@ -136,9 +147,8 @@ src.closedoor() if (href_list["fc"]) if(src.allowed(usr)) - for (var/obj/machinery/flasher/F in world) - if (F.id == src.id) - F.flash() + for (var/obj/machinery/flasher/F in targetflashers) + F.flash() src.add_fingerprint(usr) src.updateUsrDialog() src.update_icon() @@ -151,10 +161,6 @@ // if BROKEN, display blue screen of death icon AI uses // if timing=true, run update display function /obj/machinery/door_timer/proc/update_icon() - var/disp1 - var/disp2 - disp1 = uppertext(id) - disp2 = "[add_zero(num2text((time / 60) % 60),2)]~[add_zero(num2text(time % 60), 2)]" if(stat & (NOPOWER)) icon_state = "frame" return @@ -164,6 +170,8 @@ return else if(src.timing) + var/disp1 = uppertext(id) + var/disp2 = "[add_zero(num2text((time / 60) % 60),2)]~[add_zero(num2text(time % 60), 2)]" spawn( 5 ) update_display(disp1, disp2) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 89e8edb794c..0b30d134608 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -2,7 +2,7 @@ if(p_open || operating) return if(ismob(AM)) var/mob/M = AM - if(world.timeofday - AM.last_bumped <= 60) return + if(world.time - AM.last_bumped <= 60) return //NOTE do we really need that? if(M.client && !M:handcuffed) bumpopen(M) else if(istype(AM, /obj/machinery/bot)) @@ -237,7 +237,7 @@ return if(ismob(AM)) var/mob/M = AM - if(world.timeofday - AM.last_bumped <= 60) return + if(world.time - AM.last_bumped <= 60) return if(M.client && !M:handcuffed) bumpopen(M) else if(istype(AM, /obj/machinery/bot)) diff --git a/code/game/machinery/hydroponics.dm b/code/game/machinery/hydroponics.dm index b8bd4ea7bb3..616c921202b 100644 --- a/code/game/machinery/hydroponics.dm +++ b/code/game/machinery/hydroponics.dm @@ -436,7 +436,7 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob) // Beer is a chemical composition of alcohol and various other things. It's a shitty nutrient but hey, it's still one. Also alcohol is bad, mmmkay? if(S.reagents.has_reagent("beer", 1)) - src.health =- round(S.reagents.get_reagent_amount("beer")*0.05) + src.health -= round(S.reagents.get_reagent_amount("beer")*0.05) src.nutrilevel += round(S.reagents.get_reagent_amount("beer")*0.04) src.waterlevel += round(S.reagents.get_reagent_amount("beer")*0.7) @@ -694,7 +694,7 @@ obj/machinery/hydroponics/attackby(var/obj/item/O as obj, var/mob/user as mob) else if(src.myseed.species == "liberty") t_prod.drug_amt = round(src.myseed.potency / 5, 1) // TRIP TIME else if(src.myseed.species == "chili" || src.myseed.species == "chiliice") - t_prod.heat_amt = src.myseed.potency // BRING ON THE HEAT + t_prod.heat_amt = src.myseed.potency // BRING ON THE HEAT //BUG: heat_amt not used at all t_amount++ src.harvest = 0 src.lastproduce = src.age diff --git a/code/game/machinery/singularity.dm b/code/game/machinery/singularity.dm index 8cb9ac01d9d..92ee64096dd 100644 --- a/code/game/machinery/singularity.dm +++ b/code/game/machinery/singularity.dm @@ -20,30 +20,31 @@ However people seem to like it for some reason. ..() /obj/machinery/the_singularitygen/process() - var/checkpointC = 0 - for (var/obj/X in orange(3,src)) - if(istype(X, /obj/machinery/containment_field) || istype(X, /obj/machinery/shieldwall)) - checkpointC ++ - if(checkpointC >= 20) - var/turf/T = src.loc + var/turf/T = get_turf(src) + if (singularity_is_surrounded(T)) new /obj/machinery/the_singularity/(T, 100) del(src) /obj/machinery/the_singularitygen/attackby(obj/item/W, mob/user) if(istype(W, /obj/item/weapon/wrench)) - if(!anchored) - anchored = 1 - playsound(src.loc, 'Ratchet.ogg', 75, 1) - user << "You secure the [src.name] to the floor." - src.anchored = 1 - return - else if(anchored) - anchored = 0 - playsound(src.loc, 'Ratchet.ogg', 75, 1) - user << "You unsecure the [src.name]." - src.anchored = 0 - return + anchored = !anchored + playsound(src.loc, 'Ratchet.ogg', 75, 1) + if(anchored) + user.visible_message("[user.name] secure [src.name] to the floor.", \ + "You secure the [src.name] to the floor.", \ + "You hear ratchet") + else + user.visible_message("[user.name] unsecure [src.name] from the floor.", \ + "You unsecure the [src.name] to the floor.", \ + "You hear ratchet") + return ..() +/proc/singularity_is_surrounded(turf/T) + var/checkpointC = 0 + for (var/obj/X in orange(3,T)) //TODO: do we need requirement to singularity be actually _surrounded_ by field? + if(istype(X, /obj/machinery/containment_field) || istype(X, /obj/machinery/shieldwall)) + checkpointC ++ + return checkpointC >= 20 /////SINGULARITY /obj/machinery/the_singularity/ @@ -73,6 +74,20 @@ However people seem to like it for some reason. src.Dtime = Ti ..() +/obj/machinery/the_singularity/attack_hand(mob/user as mob) + return 1 + +/obj/machinery/the_singularity/blob_act(severity) + return + +/obj/machinery/the_singularity/ex_act(severity) + switch(severity) + if(1.0) + del(src) //TODO: some animation + return + if(2.0 to 3.0) //no way + return + return /obj/machinery/the_singularity/process() eat() @@ -93,72 +108,71 @@ However people seem to like it for some reason. if(prob(15))//Chance for it to run a special event event() + var/turf/T = get_turf(src) + var/is_surrounded = singularity_is_surrounded(T) + if ( is_surrounded && active ) + src.active = 0 + src.dieot = 0 + spawn(50) + if (!active) + grav_pull = 6 + icon_state = "Singularity" + else if ( is_surrounded==0 && active==0 ) + src.active = 1 + src.dieot = 1 + grav_pull = 8 if(active == 1) move() spawn(5) move() - else - var/checkpointC = 0 - for (var/obj/X in orange(3,src)) - if(istype(X, /obj/machinery/containment_field) || istype(X, /obj/machinery/shieldwall)) - checkpointC ++ - if(checkpointC < 18) - src.active = 1 - src.dieot = 1 - grav_pull = 8 + +/obj/machinery/the_singularity + var/global/list/uneatable = list(\ + /obj/machinery/the_singularity, \ + /obj/machinery/containment_field, \ + /obj/machinery/shieldwall, \ + /turf/space, \ + /obj/effects, \ + /obj/beam, /* not sure*/ \ + /obj/overlay + ) + +/obj/machinery/the_singularity/proc/is_eatable(atom/X) + for (var/Type in uneatable) + if (istype(X, Type)) + return 0 + return 1 + /obj/machinery/the_singularity/proc/eat() for (var/atom/X in orange(grav_pull,src)) - if(istype(X,/obj/machinery/the_singularity)) + if(isarea(X)) continue - if(istype(X,/obj/machinery/containment_field)) + if (!is_eatable(X)) continue + if(istype(X,/obj/machinery/field_generator)) var/obj/machinery/field_generator/F = X if(F.active) continue - if(istype(X,/turf/space)) - continue - if(istype(X,/obj/machinery/shieldwall)) - continue if(istype(X,/obj/machinery/shieldwallgen)) var/obj/machinery/shieldwallgen/S = X if(S.active) continue - if(!active) - if(isturf(X,/turf/simulated/floor/engine)) - continue - if(!isarea(X)) - switch(get_dist(src,X)) - if(2) - src.Bumped(X) - if(1) - src.Bumped(X) - if(0) - src.Bumped(X) - else if(!isturf(X)) - if(!X:anchored) - step_towards(X,src) + switch(get_dist(src,X)) + if(0 to 2) + src.Bumped(X) + else if(!isturf(X)) + if(!X:anchored) + step_towards(X,src) /obj/machinery/the_singularity/proc/move() - var/direction_go = pick(1,2,4,8) - if(locate(/obj/machinery/containment_field) || locate(/obj/machinery/shieldwall) in get_step(src,NORTH)) - if(direction_go == 1) - icon_state = "Singularity" - return - if(locate(/obj/machinery/containment_field) || locate(/obj/machinery/shieldwall) in get_step(src,SOUTH)) - if(direction_go == 2) - icon_state = "Singularity" - return - if(locate(/obj/machinery/containment_field) || locate(/obj/machinery/shieldwall) in get_step(src,EAST)) - if(direction_go == 4) - icon_state = "Singularity" - return - if(locate(/obj/machinery/containment_field) || locate(/obj/machinery/shieldwall) in get_step(src,WEST)) - if(direction_go == 8) - icon_state = "Singularity" - return + var/direction_go = pick(cardinal) + if(locate(/obj/machinery/containment_field) in get_step(src,direction_go) || \ + locate(/obj/machinery/shieldwall) in get_step(src,direction_go)) + icon_state = "Singularity" + return if(selfmove) spawn(0) icon_state = "Singularity2" @@ -167,41 +181,34 @@ However people seem to like it for some reason. /obj/machinery/the_singularity/Bumped(atom/A) var/gain = 0 - - if(istype(A,/obj/machinery/the_singularity)) - return - - if(istype(A,/obj/machinery/the_singularity))//Dont eat other sings + if (!is_eatable(A)) return if (istype(A,/mob/living))//if its a mob gain = 20 if(istype(A,/mob/living/carbon/human)) if(A:mind) - if((A:mind:assigned_role == "Station Engineer") || (A:mind:assigned_role == "Cief Engineer") ) + if((A:mind:assigned_role == "Station Engineer") || (A:mind:assigned_role == "Chief Engineer") ) gain = 100 A:gib() else if(istype(A,/obj/)) - if(istype(A,/obj/machinery/containment_field)) - return - if(istype(A,/obj/machinery/shieldwall)) - return A:ex_act(1.0) if(A) del(A) gain = 2 else if(isturf(A)) - if(isturf(/turf/space)) + if(istype(A, /turf/space)) + world << "DEBUG: the_singularity tryes to eat space!!!11" return - if(!active) - if(isturf(A,/turf/simulated/floor/engine)) - return + /*if(!active) + if(isturf(A,/turf/simulated/floor/engine)) //here was a bug. But now it's a feature. -rasta0 + return*/ - if(!istype(A,/turf/simulated/floor)&& (!isturf(/turf/space))) - A:ReplaceWithFloor() - if(istype(A,/turf/simulated/floor) && (!isturf(/turf/space))) + if(istype(A,/turf/simulated/floor)) A:ReplaceWithSpace() gain = 2 + else + A:ReplaceWithFloor() src.energy += gain /////////////////////////////////////////////Controls which "event" is called @@ -210,30 +217,32 @@ However people seem to like it for some reason. switch(numb) if(1)//EMP Zzzzap() - return if(2)//Eats the turfs around it if(prob(60)) BHolerip() else event() - return if(3)//tox damage all carbon mobs in area Toxmob() - return if(4)//Stun mobs who lack optic scanners Mezzer() - return else + //do nothing return /obj/machinery/the_singularity/proc/Toxmob() - for(var/mob/living/carbon/M in orange(7, src)) + for(var/mob/living/carbon/M in view(7, src.loc)) if(istype(M,/mob/living/carbon/human)) if(M:wear_suit) return M.toxloss += 3 M.radiation += 10 + if (src.energy>150) + M.toxloss += ((src.energy-150)/50)*3 + M.radiation += ((src.energy-150)/50)*10 + if (src.energy>300) + M.fireloss += ((src.energy-300)/50)*3 M.updatehealth() M << "\red You feel odd." @@ -241,7 +250,7 @@ However people seem to like it for some reason. for(var/mob/living/carbon/M in oviewers(8, src)) if(istype(M,/mob/living/carbon/human)) if(istype(M:glasses,/obj/item/clothing/glasses/meson)) - M << "\red You look directly into The [src.name], good thing you had your protective eyewear on!" + M << "\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 (M:stunned < 3) @@ -249,28 +258,48 @@ However people seem to like it for some reason. for(var/mob/O in viewers(M, null)) O.show_message(text("\red [] stares blankly at The []!", M, src), 1) -/obj/machinery/the_singularity/proc/BHolerip() - for (var/atom/X in orange(6,src)) - if(isturf(X)) - if(!istype(X,/turf/space)) - switch(get_dist(src,X)) - if(4 to 5) - if(prob(30)) - if(istype(X,/turf/simulated/floor) && !istype(X,/turf/simulated/floor/plating)) - if(!X:broken) - if(prob(80)) - new/obj/item/weapon/tile (X) - X:break_tile_to_plating() - else - X:break_tile() - else if(istype(X,/turf/simulated/wall)) - new /obj/structure/girder/reinforced( X ) - new /obj/item/weapon/sheet/r_metal( X ) - X:ReplaceWithFloor() - else - X:ReplaceWithFloor() - return +/obj/machinery/the_singularity + var/global/list/turf/simulated/unstrippable = list(\ + /turf/simulated/floor/engine, \ + /turf/simulated/floor/grid, \ + /turf/simulated/shuttle, \ + /turf/simulated/wall/asteroid + ) +//looks like I need new function istypefromlist +/obj/machinery/the_singularity/proc/is_strippable(turf/simulated/X) + for(var/Type in unstrippable) + if (istype(X,Type)) + return 0 + return 1 + +/obj/machinery/the_singularity/proc/BHolerip() + for (var/turf/simulated/X in orange(5,src)) + if (!is_strippable(X)) + continue + if (!prob(30)) + continue + var/dist = get_dist(src,X) + if ( (dist>=3 && dist<=5) ) + if (istype(X,/turf/simulated/floor) && !istype(X,/turf/simulated/floor/plating)) + if(!X:broken) + if(prob(80)) + new/obj/item/weapon/tile (X) + X:break_tile_to_plating() + else + X:break_tile() + else if(istype(X,/turf/simulated/wall)) + if (istype(X,/turf/simulated/wall/r_wall)) + new /obj/structure/girder/reinforced( X ) + new /obj/item/weapon/sheet/r_metal( X ) + else + new /obj/structure/girder( X ) + new /obj/item/weapon/sheet/metal( X ) + X:ReplaceWithFloor() + else + X:ReplaceWithFloor() + +/* NOTE: someone said he has plan to redo EMP so I dont touch anything except excluding pipes - rastaf0 */ /obj/machinery/the_singularity/proc/Zzzzap()///Pulled from wizard spells might edit later var/turf/myturf = get_turf(src) @@ -282,10 +311,9 @@ However people seem to like it for some reason. spawn(20) del(pulse) - for(var/mob/M in viewers(world.view-1, myturf)) + for(var/mob/living/M in viewers(world.view-1, myturf)) - if(!istype(M, /mob/living)) continue - if(M == usr) continue + //if(M == usr) continue if (istype(M, /mob/living/silicon)) M.fireloss += 25 @@ -361,6 +389,18 @@ However people seem to like it for some reason. for(var/obj/machinery/A in range(world.view-1, myturf)) + var/unpowered = 0 + for (var/Type in list(\ + /obj/machinery/atmospherics/pipe, \ + /obj/machinery/the_singularity, \ + /obj/machinery/containment_field, \ + /obj/machinery/shieldwall, \ + /obj/machinery/field_generator )) //field generators arent connected to apc + if (istype(A,Type)) + unpowered = 1 + break + if (unpowered) + continue A.use_power(7500) var/obj/overlay/pulse2 = new/obj/overlay ( A.loc ) @@ -389,9 +429,7 @@ However people seem to like it for some reason. if(istype(A, /obj/machinery/power/apc)) if(A:cell) - A:cell:charge -= 1000 - if (A:cell:charge < 0) - A:cell:charge = 0 + A:cell.use(1000) A:lighting = 0 A:equipment = 0 A:environ = 0 @@ -407,8 +445,6 @@ However people seem to like it for some reason. if(istype(A, /obj/machinery/clonepod)) A:malfunction() - - ////////CONTAINMENT FIELD /obj/machinery/containment_field @@ -419,19 +455,16 @@ However people seem to like it for some reason. anchored = 1 density = 0 unacidable = 1 - var/active = 1 - var/power = 10 - var/delay = 5 - var/last_active - var/mob/U + //var/active = 1 + //var/power = 10 + //var/delay = 5 + //var/last_active + //var/mob/U var/obj/machinery/field_generator/gen_primary var/obj/machinery/field_generator/gen_secondary - - //////////////Contaiment Field START - /obj/machinery/containment_field/New(var/obj/machinery/field_generator/A, var/obj/machinery/field_generator/B) ..() src.gen_primary = A @@ -440,18 +473,15 @@ However people seem to like it for some reason. src.sd_SetLuminosity(5) /obj/machinery/containment_field/attack_hand(mob/user as mob) + return 1 + +/obj/machinery/containment_field/blob_act() return +/obj/machinery/containment_field/ex_act(severity) + return /obj/machinery/containment_field/process() - if(isnull(gen_primary)||isnull(gen_secondary)) - del(src) - return - - if(!(gen_primary.active)||!(gen_secondary.active)) - del(src) - return - if(prob(50)) gen_primary.power -= 1 else @@ -469,33 +499,32 @@ However people seem to like it for some reason. var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread s.set_up(5, 1, user.loc) s.start() - src.power = max(gen_primary.power,gen_secondary.power) + var/power = max(gen_primary.power,gen_secondary.power) var/prot = 1 var/shock_damage = 0 - if(src.power > 200) + if(power > 200) shock_damage = min(rand(40,100),rand(40,100))*prot - else if(src.power > 120) + else if(power > 120) shock_damage = min(rand(30,90),rand(30,90))*prot - else if(src.power > 80) + else if(power > 80) shock_damage = min(rand(20,40),rand(20,40))*prot - else if(src.power > 60) + else if(power > 60) shock_damage = min(rand(20,30),rand(20,30))*prot else shock_damage = min(rand(10,20),rand(10,20))*prot user.burn_skin(shock_damage) - user.fireloss += shock_damage + //user.fireloss += shock_damage user.updatehealth() - user << "\red You feel a powerful shock course through your body sending you flying!" + user.visible_message("\red [user.name] was shocked by the [src.name]!", \ + "\red You feel a powerful shock course through your body sending you flying!", \ + "\red You hear a heavy electrical crack") //user.unlock_medal("High Voltage", 1) if(user.stunned < shock_damage) user.stunned = shock_damage if(user.weakened < 10*prot) user.weakened = 10*prot var/atom/target = get_edge_target_turf(user, get_dir(src, get_step_away(user, src))) user.throw_at(target, 200, 4) - for(var/mob/M in viewers(src)) - if(M == user) continue - M.show_message("\red [user.name] was shocked by the [src.name]!", 3, "\red You hear a heavy electrical crack", 2) src.gen_primary.power -= 3 src.gen_secondary.power -= 3 return @@ -506,8 +535,6 @@ However people seem to like it for some reason. shock(AM) return - - /////EMITTER /obj/machinery/emitter name = "Emitter" @@ -518,9 +545,9 @@ However people seem to like it for some reason. density = 1 req_access = list(access_engine) var/active = 0 - var/power = 20 +// var/power = 20 var/fire_delay = 100 - var/HP = 20 +// var/HP = 20 var/last_shot = 0 var/shot_number = 0 var/state = 0 @@ -532,42 +559,50 @@ However people seem to like it for some reason. ..() return +/obj/machinery/emitter/proc/update_icon() + if (active && !(stat & (NOPOWER|BROKEN))) + icon_state = "Emitter +a" + else + icon_state = "Emitter" + /obj/machinery/emitter/attack_hand(mob/user as mob) + if (..()) + return if(state == 3) if(!src.locked) + src.add_fingerprint(user) if(src.active==1) src.active = 0 - icon_state = "Emitter" user << "You turn off the emitter." else src.active = 1 - icon_state = "Emitter +a" user << "You turn on the emitter." src.shot_number = 0 src.fire_delay = 100 + update_icon() else user << "The controls are locked!" else user << "The emitter needs to be firmly secured to the floor first." - src.add_fingerprint(user) - ..() + return 1 /obj/machinery/emitter/attack_ai(mob/user as mob) + if (..()) + return if(state == 3) + src.add_fingerprint(user) if(src.active==1) src.active = 0 - icon_state = "Emitter" user << "You turn off the emitter." else src.active = 1 - icon_state = "Emitter +a" user << "You turn on the emitter." src.shot_number = 0 src.fire_delay = 100 + update_icon() else user << "The emitter needs to be firmly secured to the floor first." - src.add_fingerprint(user) /obj/machinery/emitter/process() @@ -588,6 +623,7 @@ However people seem to like it for some reason. src.fire_delay = rand(20,100) src.shot_number = 0 + use_power(1000) var/obj/beam/a_laser/A = new /obj/beam/a_laser( src.loc ) A.icon_state = "u_laser" playsound(src.loc, 'Laser.ogg', 75, 1) @@ -625,82 +661,77 @@ However people seem to like it for some reason. /obj/machinery/emitter/attackby(obj/item/W, mob/user) if(istype(W, /obj/item/weapon/wrench)) if(active) - user << "Turn off the emitter first." - return + user << "\red Turn off the emitter first." + return 1 else if(state == 0) state = 1 playsound(src.loc, 'Ratchet.ogg', 75, 1) - user << "You secure the external reinforcing bolts to the floor." + user.visible_message("[user.name] secure [src.name] to the floor.", \ + "You secure the external reinforcing bolts to the floor.", \ + "You hear ratchet") src.anchored = 1 - return else if(state == 1) state = 0 playsound(src.loc, 'Ratchet.ogg', 75, 1) - user << "You undo the external reinforcing bolts." + user.visible_message("[user.name] unsecure [src.name] to the floor.", \ + "You undo the external reinforcing bolts to the floor.", \ + "You hear ratchet") src.anchored = 0 - return - - if(istype(W, /obj/item/weapon/weldingtool) && W:welding) - - var/turf/T = user.loc + else + user << "\red [src] is welded to the floor!" + return 1 + + else if(istype(W, /obj/item/weapon/weldingtool) && W:welding) + if (state == 0) + user << "\red The emitter needs to be wrenched to the floor first." + return 1 if (W:get_fuel() < 1) user << "\blue You need more welding fuel to complete this task." - return + return 1 W:use_fuel(1) + W:eyecheck(user) + playsound(src.loc, 'Welder2.ogg', 50, 1) if(state == 1) - W:eyecheck(user) - user << "You start to weld the emitter to the floor." - playsound(src.loc, 'Welder2.ogg', 50, 1) - sleep(20) - - if ((user.loc == T && user.equipped() == W)) - state = 3 - - user << "You weld the emitter to the floor." - else if((istype(user, /mob/living/silicon/robot) && (user.loc == T))) + user.visible_message("[user.name] start to weld [src.name] to the floor.", \ + "You start to weld the emitter to the floor.", \ + "You hear welding") + if (do_after(user,20)) state = 3 user << "You weld the emitter to the floor." - return + else + return 1 - if(state == 3) - user << "You start to cut the emitter free from the floor." - playsound(src.loc, 'Welder2.ogg', 50, 1) - sleep(20) - if ((user.loc == T && user.equipped() == W)) + else if(state == 3) + user.visible_message("[user.name] start to cut [src.name] to the floor.", \ + "You start to cut the emitter free from the floor.", \ + "You hear welding") + if (do_after(user,20)) state = 1 -/* if(src.link) //Time to clear our link. - src.link.master = null - src.link = null*/ user << "You cut the emitter free from the floor." - else if((istype(user, /mob/living/silicon/robot) && (user.loc == T))) - state = 1 -/* if(src.link) - src.link.master = null - src.link = null*/ - user << "You cut the emitter free from the floor." - return + else + return 1 - if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) + else if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) if (src.allowed(user)) src.locked = !src.locked user << "Controls are now [src.locked ? "locked." : "unlocked."]" else user << "\red Access denied." - + return 1 else - src.add_fingerprint(user) - user << "\red You hit the [src.name] with your [W.name]!" - for(var/mob/M in viewers(src)) - if(M == user) continue - M.show_message("\red The [src.name] has been hit with the [W.name] by [user.name]!") - - + user.visible_message("\red The [src.name] has been hit with the [W.name] by [user.name]!", \ + "\red You hit the [src.name] with your [W.name]!", \ + "You hear bang") + src.add_fingerprint(user) +/obj/machinery/emitter/power_change() + ..() + update_icon() //////////////ARRAY @@ -711,6 +742,7 @@ However people seem to like it for some reason. icon_state = "ca" anchored = 1 density = 1 + req_access = list(access_engine) directwired = 1 var/active = 0 var/obj/item/weapon/tank/plasma/P = null @@ -726,109 +758,131 @@ However people seem to like it for some reason. /obj/machinery/power/collector_array/proc/updateicon() - + overlays = null + if(P) + overlays += image('singularity.dmi', "ptank") if(stat & (NOPOWER|BROKEN)) - overlays = null - if(P) - overlays += image('singularity.dmi', "ptank") - else - overlays = null - overlays += image('singularity.dmi', "on") - if(P) - overlays += image('singularity.dmi', "ptank") + return + if(active) + overlays += image('singularity.dmi', "on") + +/obj/machinery/power/collector_array/proc/updateicon_on() + icon_state = "ca_on" + flick("ca_active", src) + updateicon() + +/obj/machinery/power/collector_array/proc/updateicon_off() + updateicon() + icon_state = "ca" + flick("ca_deactive", src) /obj/machinery/power/collector_array/power_change() - updateicon() ..() - + updateicon() /obj/machinery/power/collector_array/process() if(P) if(P.air_contents.toxins <= 0) src.active = 0 - icon_state = "ca_deactive" - updateicon() + updateicon_off() else if(src.active == 1) src.active = 0 - icon_state = "ca_deactive" - updateicon() + updateicon_off() ..() /obj/machinery/power/collector_array/attack_hand(mob/user as mob) - if(src.anchored == 1) - if(src.active==1) - src.active = 0 - icon_state = "ca_deactive" - CU.updatecons() - user << "You turn off the collector array." - return - - if(src.active==0) - src.active = 1 - icon_state = "ca_active" - CU.updatecons() - user << "You turn on the collector array." - return - else - src.add_fingerprint(user) - user << "\red The collector needs to be secured to the floor first." + if (..()) return + if(src.anchored != 1) + user << "\red The [src] needs to be secured to the floor first." + return 1 + if (!src.allowed(user)) + user << "\red Access denied." + return 1 + if (!P) + user << "\red The [src] cannot be turned on without plasma." + return 1 + if (!CU) + user << "\red The [src] is not connected with The Radiation Collector Control." + return 1 + src.active = !src.active + if(src.active) + updateicon_on() + user.visible_message("[user.name] turn on the collector array.", \ + "You turn on the collector array.") + else + updateicon_off() + user.visible_message("[user.name] turn off the collector array.", \ + "You turn off the collector array.") + CU.updatecons() /obj/machinery/power/collector_array/attackby(obj/item/W, mob/user) if(istype(W, /obj/item/weapon/tank/plasma)) if(src.anchored == 1) if(src.P) user << "\red There appears to already be a plasma tank loaded!" - return + return 1 src.P = W W.loc = src if (user.client) user.client.screen -= W user.u_equip(W) - CU.updatecons() updateicon() - return + if (CU) + CU.updatecons() else user << "The collector needs to be secured to the floor first." - return + return 1 - if(istype(W, /obj/item/weapon/crowbar)) + else if(istype(W, /obj/item/weapon/crowbar)) if(!P) - return + return 1 var/obj/item/weapon/tank/plasma/Z = src.P Z.loc = get_turf(src) Z.layer = initial(Z.layer) src.P = null - CU.updatecons() - updateicon() - return + if (src.active) + src.active = 0 + updateicon_off() + else + updateicon() + if (CU) + CU.updatecons() - if(istype(W, /obj/item/weapon/wrench)) + else if(istype(W, /obj/item/weapon/wrench)) if(active) user << "\red Turn off the collector first." - return + return 1 - else if(src.anchored == 0) + else playsound(src.loc, 'Ratchet.ogg', 75, 1) - user << "You secure the collector reinforcing bolts to the floor." - src.anchored = 1 - return - - else if(src.anchored == 1) - playsound(src.loc, 'Ratchet.ogg', 75, 1) - user << "You undo the external reinforcing bolts." - src.anchored = 0 - return + src.anchored = !src.anchored + if(src.anchored == 1) + user.visible_message("[user.name] secure [src.name] reinforcing bolts to the floor.", \ + "You secure the collector reinforcing bolts to the floor.", \ + "You hear ratchet") + else + user.visible_message("[user.name] unsecure [src.name] reinforcing bolts to the floor.", \ + "You undo the external reinforcing bolts.", \ + "You hear ratchet") + if (CU) + CU.updatecons() else - src.add_fingerprint(user) - user << "\red You hit the [src.name] with your [W.name]!" - for(var/mob/M in viewers(src)) - if(M == user) continue - M.show_message("\red The [src.name] has been hit with the [W.name] by [user.name]!") - + user.visible_message("\red The [src.name] has been hit with the [W.name] by [user.name]!", \ + "\red You hit the [src.name] with your [W.name]!", \ + "You hear bang") + src.add_fingerprint(user) +/obj/machinery/power/collector_array/ex_act(severity) + switch(severity) + if(2.0 to 3.0) + var/obj/item/weapon/tank/plasma/Z = src.P + Z.loc = get_turf(src) + Z.layer = initial(Z.layer) + src.P = null + return ..() ////////////CONTROL UNIT /obj/machinery/power/collector_control @@ -838,184 +892,162 @@ However people seem to like it for some reason. icon_state = "cu" anchored = 1 density = 1 + req_access = list(access_engine) directwired = 1 var/active = 0 var/lastpower = 0 - var/obj/item/weapon/tank/plasma/P1 = null - var/obj/item/weapon/tank/plasma/P2 = null - var/obj/item/weapon/tank/plasma/P3 = null - var/obj/item/weapon/tank/plasma/P4 = null - var/obj/machinery/power/collector_array/CA1 = null - var/obj/machinery/power/collector_array/CA2 = null - var/obj/machinery/power/collector_array/CA3 = null - var/obj/machinery/power/collector_array/CA4 = null - var/obj/machinery/power/collector_array/CAN = null - var/obj/machinery/power/collector_array/CAS = null - var/obj/machinery/power/collector_array/CAE = null - var/obj/machinery/power/collector_array/CAW = null - var/obj/machinery/the_singularity/S1 = null + var/obj/machinery/power/collector_array/CA[4] + var/list/obj/machinery/the_singularity/S ////////////CONTROL UNIT START /obj/machinery/power/collector_control/New() ..() spawn(10) - updatecons() + while(1) + updatecons() + sleep(600) + +/obj/machinery/power/collector_control/proc/add_ca(var/obj/machinery/power/collector_array/newCA) + if (newCA in CA) + return 1 + for (var/i = 1, i<= CA.len, i++) + var/obj/machinery/power/collector_array/nextCA = CA[i] + if (isnull(nextCA)) + CA[i] = newCA + return 1 + //CA += newCA + return 0 /obj/machinery/power/collector_control/proc/updatecons() - - CAN = locate(/obj/machinery/power/collector_array) in get_step(src,NORTH) - CAS = locate(/obj/machinery/power/collector_array) in get_step(src,SOUTH) - CAE = locate(/obj/machinery/power/collector_array) in get_step(src,EAST) - CAW = locate(/obj/machinery/power/collector_array) in get_step(src,WEST) - for(var/obj/machinery/the_singularity/S in orange(12,src)) - S1 = S - - if(!isnull(CAN)) - CA1 = CAN - CAN.CU = src - if(CA1.P) - P1 = CA1.P - else - CAN = null - if(!isnull(CAS)) - CA3 = CAS - CAS.CU = src - if(CA3.P) - P3 = CA3.P - else - CAS = null - if(!isnull(CAW)) - CA4 = CAW - CAW.CU = src - if(CA4.P) - P4 = CA4.P - else - CAW = null - if(!isnull(CAE)) - CA2 = CAE - CAE.CU = src - if(CA2.P) - P2 = CA2.P - else - CAE = null - if(isnull(S1)) - S1 = null - + S = list() + for(var/obj/machinery/the_singularity/myS in orange(12,src)) + S += myS + + for (var/ca_dir in cardinal) + var/obj/machinery/power/collector_array/newCA = locate() in get_step(src,ca_dir) + if (isnull(newCA)) + continue + if (!newCA.anchored) + var/n = CA.Find(newCA) + if (n) + CA[n] = null + newCA.CU = null + continue + if (add_ca(newCA)) + newCA.CU = src updateicon() - spawn(600) - updatecons() - + //is not recursive now, because can be called several times. See New(). - rastaf0 /obj/machinery/power/collector_control/proc/updateicon() - + overlays = null if(stat & (NOPOWER|BROKEN)) - overlays = null - else - overlays = null + return if(src.active == 0) return overlays += image('singularity.dmi', "cu on") - if((P1)&&(CA1.active != 0)) - overlays += image('singularity.dmi', "cu 1 on") - if((P2)&&(CA2.active != 0)) - overlays += image('singularity.dmi', "cu 2 on") - if((P3)&&(CA3.active != 0)) - overlays += image('singularity.dmi', "cu 3 on") - if((!P1)||(!P2)||(!P3)) + var/err = 0 + for (var/i = 1, ((i<= CA.len) && (i<=4)), i++) + var/obj/machinery/power/collector_array/myCA = CA[i] + if(myCA) + if (myCA.P) + if(myCA.active) + overlays += image('singularity.dmi', "cu [i] on") + else + err = 1 + if(err) overlays += image('singularity.dmi', "cu n error") - if(S1) - overlays += image('singularity.dmi', "cu sing") - if(!S1.active) + for (var/obj/machinery/the_singularity/myS in S) + if(myS) + overlays += image('singularity.dmi', "cu sing") + break + for (var/obj/machinery/the_singularity/myS in S) + if(myS && !myS.active) overlays += image('singularity.dmi', "cu conterr") + break /obj/machinery/power/collector_control/power_change() - updateicon() - ..() + ..() //this set NOPOWER + if (stat & (NOPOWER|BROKEN)) + lastpower = 0 + updateicon() //this checks NOPOWER /obj/machinery/power/collector_control/process() + if(stat & (NOPOWER|BROKEN)) + return if(src.active == 1) var/power_a = 0 var/power_s = 0 var/power_p = 0 - if(!isnull(S1)) - power_s += S1.energy - if(!isnull(P1)) - if(CA1.active != 0) - power_p += P1.air_contents.toxins - P1.air_contents.toxins -= 0.001 - if(!isnull(P2)) - if(CA2.active != 0) - power_p += P2.air_contents.toxins - P2.air_contents.toxins -= 0.001 - if(!isnull(P3)) - if(CA3.active != 0) - power_p += P3.air_contents.toxins - P3.air_contents.toxins -= 0.001 - if(!isnull(P4)) - if(CA4.active != 0) - power_p += P4.air_contents.toxins - P4.air_contents.toxins -= 0.001 + for (var/obj/machinery/the_singularity/myS in S) + if(!isnull(myS)) + power_s += myS.energy + + for (var/i = 1, i<= CA.len, i++) + var/obj/machinery/power/collector_array/myCA = CA[i] + if (!myCA) + continue + var/obj/item/weapon/tank/plasma/myP = myCA.P + if(myP) + if (myCA.active) + myCA.use_power(250) + power_p += myP.air_contents.toxins + myP.air_contents.toxins -= 0.001 + power_a = power_p*power_s*50 src.lastpower = power_a add_avail(power_a) + use_power(250) ..() /obj/machinery/power/collector_control/attack_hand(mob/user as mob) + if (..()) + return if(src.anchored==1) - if(src.active==1) - src.active = 0 + if (!src.allowed(user)) + user << "\red Access denied." + return 1 + src.active = !src.active + if(!src.active) user << "You turn off the collector control." src.lastpower = 0 updateicon() - return - - if(src.active==0) - src.active = 1 + if(src.active) user << "You turn on the collector control." updatecons() - return else - src.add_fingerprint(user) user << "\red The collector control needs to be secured to the floor first." - return - + return 1 /obj/machinery/power/collector_control/attackby(obj/item/W, mob/user) if(istype(W, /obj/item/device/analyzer)) user << "\blue The analyzer detects that [lastpower]W are being produced." - - if(istype(W, /obj/item/weapon/wrench)) + else if(istype(W, /obj/item/weapon/wrench)) if(active) user << "\red Turn off the collector control first." - return - - else if(src.anchored == 0) - playsound(src.loc, 'Ratchet.ogg', 75, 1) - user << "You secure the collector control to the floor." - src.anchored = 1 - return - - else if(src.anchored == 1) - playsound(src.loc, 'Ratchet.ogg', 75, 1) - user << "You undo the collector control securing bolts." - src.anchored = 0 - return + return 1 + playsound(src.loc, 'Ratchet.ogg', 75, 1) + src.anchored = !src.anchored + if(src.anchored == 1) + user.visible_message("[user.name] secure [src.name] to the floor.", \ + "You secure the [src.name] to the floor.", \ + "You hear ratchet") + connect_to_network() + else + user.visible_message("[user.name] unsecure [src.name] to the floor.", \ + "You undo the collector control securing bolts.", \ + "You hear ratchet") + disconnect_from_network() else - src.add_fingerprint(user) - user << "\red You hit the [src.name] with your [W.name]!" - for(var/mob/M in viewers(src)) - if(M == user) continue - M.show_message("\red The [src.name] has been hit with the [W.name] by [user.name]!") - - - - + user.visible_message("\red The [src.name] has been hit with the [W.name] by [user.name]!", \ + "\red You hit the [src.name] with your [W.name]!", \ + "You hear bang") + src.add_fingerprint(user) /////FIELD GEN @@ -1033,14 +1065,43 @@ However people seem to like it for some reason. var/power = 20 var/max_power = 250 var/state = 0 - var/steps = 0 - var/last_check = 0 - var/check_delay = 10 - var/recalc = 0 + //var/steps = 0 + //var/last_check = 0 + //var/check_delay = 10 + //var/recalc = 0 var/locked = 0 - + var/warming_up = 0 + var/powerlevel = 0 + var/list/obj/machinery/containment_field/fields ////FIELD GEN START +/obj/machinery/field_generator/proc/update_icon() + if (!active) + icon_state = "Field_Gen" + return + var/level = 3 + switch (power) + if(0 to 40) + level = 1 + if(41 to 220) + level = 2 + if(221 to INFINITY) + level = 3 + level = min(level,warming_up) + if (powerlevel!=level) + powerlevel = level + icon_state = "Field_Gen +a[powerlevel]" + +/obj/machinery/field_generator/proc/turn_on() + src.active = 1 + warming_up = 1 + spawn(1) + while (warming_up<3 && active) + sleep(50) + warming_up++ + update_icon() + update_icon() + /obj/machinery/field_generator/attack_hand(mob/user as mob) if(state == 3) if(!src.locked) @@ -1049,30 +1110,34 @@ However people seem to like it for some reason. // icon_state = "Field_Gen" user << "You are unable to turn off the field generator, wait till it powers down." // src.cleanup() + return 1 else - src.active = 1 - icon_state = "Field_Gen +a" - user << "You turn on the field generator." + user.visible_message("[user.name] turn on [src.name]", \ + "You turn on the field generator.", \ + "You hear heavy droning") + turn_on() + src.add_fingerprint(user) else user << "The controls are locked!" else user << "The field generator needs to be firmly secured to the floor first." - src.add_fingerprint(user) /obj/machinery/field_generator/attack_ai(mob/user as mob) if(state == 3) if(src.active >= 1) user << "You are unable to turn off the field generator, wait till it powers down." else - src.active = 1 - icon_state = "Field_Gen +a" - user << "You turn on the field generator." + user.visible_message("[user.name] turn on [src.name]", \ + "You turn on the field generator.", \ + "You hear heavy droning") + turn_on() + src.add_fingerprint(user) else user << "The field generator needs to be firmly secured to the floor first." - src.add_fingerprint(user) /obj/machinery/field_generator/New() ..() + fields = list() return /obj/machinery/field_generator/process() @@ -1083,7 +1148,6 @@ However people seem to like it for some reason. src.state = 3 src.power = 250 src.anchored = 1 - icon_state = "Field_Gen +a" Varedit_start = 0 if(src.active == 1) @@ -1109,138 +1173,110 @@ However people seem to like it for some reason. if(src.power <= 0) for(var/mob/M in viewers(src)) M.show_message("\red The [src.name] shuts down due to lack of power!") - icon_state = "Field_Gen" src.active = 0 spawn(1) - src.cleanup(1) - spawn(1) - src.cleanup(2) - spawn(1) - src.cleanup(4) - spawn(1) - src.cleanup(8) + src.cleanup() + update_icon() -/obj/machinery/field_generator/proc/setup_field(var/NSEW = 0) +/obj/machinery/field_generator/proc/setup_field(var/NSEW) var/turf/T = src.loc - var/turf/T2 = src.loc var/obj/machinery/field_generator/G var/steps = 0 - var/oNSEW = 0 if(!NSEW)//Make sure its ran right return - if(NSEW == 1) - oNSEW = 2 - else if(NSEW == 2) - oNSEW = 1 - else if(NSEW == 4) - oNSEW = 8 - else if(NSEW == 8) - oNSEW = 4 - for(var/dist = 0, dist <= 9, dist += 1) // checks out to 8 tiles away for another generator - T = get_step(T2, NSEW) - T2 = T + T = get_step(T, NSEW) steps += 1 - if(locate(/obj/machinery/field_generator) in T) - G = (locate(/obj/machinery/field_generator) in T) + G = locate(/obj/machinery/field_generator) in T + if(!isnull(G)) steps -= 1 if(!G.active) return - G.cleanup(oNSEW) break if(isnull(G)) return - T2 = src.loc + T = src.loc for(var/dist = 0, dist < steps, dist += 1) // creates each field tile - var/field_dir = get_dir(T2,get_step(T2, NSEW)) - T = get_step(T2, NSEW) - T2 = T + var/field_dir = get_dir(T,get_step(G.loc, NSEW)) + T = get_step(T, NSEW) var/obj/machinery/containment_field/CF = new/obj/machinery/containment_field/(src, G) //(ref to this gen, ref to connected gen) + fields += CF + G.fields += CF CF.loc = T CF.dir = field_dir /obj/machinery/field_generator/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/weapon/wrench)) + if(istype(W, /obj/item/weapon/wrench) && state!=3) if(active) user << "Turn off the field generator first." - return + return 1 - else if(state == 0) + if(state == 0) state = 1 playsound(src.loc, 'Ratchet.ogg', 75, 1) - user << "You secure the external reinforcing bolts to the floor." + user.visible_message("[user.name] secure [src.name] to the floor.", \ + "You secure the external reinforcing bolts to the floor.", \ + "You hear ratchet") src.anchored = 1 - return else if(state == 1) state = 0 playsound(src.loc, 'Ratchet.ogg', 75, 1) - user << "You undo the external reinforcing bolts." + user.visible_message("[user.name] unsecure [src.name] reinforcing bolts to the floor.", \ + "You undo the external reinforcing bolts.", \ + "You hear ratchet") src.anchored = 0 - return - - if(istype(W, /obj/item/weapon/weldingtool) && W:welding) - - var/turf/T = user.loc + else if(istype(W, /obj/item/weapon/weldingtool) && W:welding) + if(state == 0) + user << "\red The [src.name] needs to be wrenched to the floor first." + return 1 if (W:get_fuel() < 1) user << "\blue You need more welding fuel to complete this task." - return + return 1 W:use_fuel(1) + W:eyecheck(user) + playsound(src.loc, 'Welder2.ogg', 50, 1) if(state == 1) - user << "You start to weld the field generator to the floor." - playsound(src.loc, 'Welder2.ogg', 50, 1) - sleep(20) - - if ((user.loc == T && user.equipped() == W)) - state = 3 - W:eyecheck(user) - user << "You weld the field generator to the floor." - else if((istype(user, /mob/living/silicon/robot) && (user.loc == T))) + user.visible_message("[user.name] start to weld [src.name] to the floor.", \ + "You start to weld the field generator to the floor.", \ + "You hear welding") + if (do_after(user,20)) state = 3 user << "You weld the field generator to the floor." - return + else + return 1 - if(state == 3) - user << "You start to cut the field generator free from the floor." - playsound(src.loc, 'Welder2.ogg', 50, 1) - sleep(20) - - if ((user.loc == T && user.equipped() == W)) + else if(state == 3) + user.visible_message("[user.name] start to cut [src.name] free from the floor.", \ + "You start to cut the field generator free from the floor.", \ + "You hear welding") + if (do_after(user,20)) state = 1 -/* if(src.link) //Clear active link. - src.link.master = null - src.link = null*/ - W:eyecheck(user) user << "You cut the field generator free from the floor." - else if((istype(user, /mob/living/silicon/robot) && (user.loc == T))) - state = 1 -/* if(src.link) //Clear active link. - src.link.master = null - src.link = null*/ - user << "You cut the field generator free from the floor." - return + else + return 1 - if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) + else if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) if (src.allowed(user)) src.locked = !src.locked user << "Controls are now [src.locked ? "locked." : "unlocked."]" else user << "\red Access denied." + return 1 else - src.add_fingerprint(user) - user << "\red You hit the [src.name] with your [W.name]!" - for(var/mob/M in viewers(src)) - if(M == user) continue - M.show_message("\red The [src.name] has been hit with the [W.name] by [user.name]!") + user.visible_message("\red The [src.name] has been hit with the [W.name] by [user.name]!", \ + "\red You hit the [src.name] with your [W.name]!", \ + "You hear bang") + src.add_fingerprint(user) /obj/machinery/field_generator/bullet_act(flag) @@ -1257,32 +1293,20 @@ However people seem to like it for some reason. src.power += 3 else src.power -= 2 + update_icon() return - -/obj/machinery/field_generator/proc/cleanup(var/NSEW) - var/obj/machinery/containment_field/F +/obj/machinery/field_generator/proc/cleanup() var/obj/machinery/field_generator/G - var/turf/T = src.loc - var/turf/T2 = src.loc - - for(var/dist = 0, dist <= 9, dist += 1) // checks out to 8 tiles away for fields - T = get_step(T2, NSEW) - T2 = T - if(locate(/obj/machinery/containment_field) in T) - F = (locate(/obj/machinery/containment_field) in T) - del(F) - - if(locate(/obj/machinery/field_generator) in T) - G = (locate(/obj/machinery/field_generator) in T) - if(!G.active) - break + for (var/obj/machinery/containment_field/F in fields) + if (isnull(F)) + continue + G = (F.gen_primary == src) ? F.gen_secondary : F.gen_primary + G.fields -= F + del(F) + fields = list() /obj/machinery/field_generator/Del() - src.cleanup(1) - src.cleanup(2) - src.cleanup(4) - src.cleanup(8) + src.cleanup() ..() - diff --git a/code/game/objects/tank.dm b/code/game/objects/tank.dm index 42f7439df2f..229475e95bc 100644 --- a/code/game/objects/tank.dm +++ b/code/game/objects/tank.dm @@ -220,27 +220,27 @@ var/obj/item/weapon/icon = src if (istype(src.loc, /obj/item/assembly)) icon = src.loc - if (!in_range(src, usr)) - if (icon == src) usr << "\blue It's a \icon[icon]! If you want any more information you'll need to get closer." - return + if (!in_range(src, usr)) + if (icon == src) usr << "\blue It's a \icon[icon][src]! If you want any more information you'll need to get closer." + return - var/celsius_temperature = src.air_contents.temperature-T0C - var/descriptive + var/celsius_temperature = src.air_contents.temperature-T0C + var/descriptive - if (celsius_temperature < 20) - descriptive = "cold" - else if (celsius_temperature < 40) - descriptive = "room temperature" - else if (celsius_temperature < 80) - descriptive = "lukewarm" - else if (celsius_temperature < 100) - descriptive = "warm" - else if (celsius_temperature < 300) - descriptive = "hot" - else - descriptive = "furiously hot" + if (celsius_temperature < 20) + descriptive = "cold" + else if (celsius_temperature < 40) + descriptive = "room temperature" + else if (celsius_temperature < 80) + descriptive = "lukewarm" + else if (celsius_temperature < 100) + descriptive = "warm" + else if (celsius_temperature < 300) + descriptive = "hot" + else + descriptive = "furiously hot" - usr << text("\blue The \icon[] feels []", icon, descriptive) + usr << text("\blue The \icon[][src] feels []", icon, descriptive) return diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index de7163a7559..649a22070c1 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -38,9 +38,11 @@ // recharge the cell /obj/item/weapon/cell/proc/give(var/amount) - charge = min(maxcharge, charge+amount) + var/power_used = min(maxcharge-charge,amount) + charge += power_used if(rigged && amount > 0) explode() + return power_used /obj/item/weapon/cell/examine() @@ -52,9 +54,6 @@ usr << "This power cell has an exciting chrome finish, as it is an uber-capacity cell type! It has a power rating of [maxcharge]!!!\nThe charge meter reads [round(src.percent() )]%." - - - /obj/item/weapon/cell/attackby(obj/item/W, mob/user) var/obj/item/clothing/gloves/G = W if(istype(G)) @@ -82,7 +81,7 @@ /obj/item/weapon/cell/proc/explode() var/turf/T = get_turf(src.loc) - explosion(T, 0, 1, 2, 2) + explosion(T, 0, 1, 2, 2) //TODO: involve charge spawn(1) del(src) \ No newline at end of file diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index 1b6063ee028..b059b2af2df 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -363,6 +363,11 @@ return makepowernets() //TODO: find fast way + +/obj/machinery/power/proc/disconnect_from_network() + //TODO: dunno how to do that + return + /turf/proc/get_cable_node() if(!istype(src, /turf/simulated/floor)) return diff --git a/config/admins.txt b/config/admins.txt index 73d716133d8..d0c89f3c4da 100644 --- a/config/admins.txt +++ b/config/admins.txt @@ -1,5 +1,2 @@ -deuryn - Host +rastaf0 - Host -tle - Host - -mport2004 - Coder \ No newline at end of file diff --git a/icons/obj/singularity.dmi b/icons/obj/singularity.dmi index fb43916e0a66df1362310f9967fec308c1e65ae8..24c50bae434cadeb3d097cdb3e66cd3265b656d9 100644 GIT binary patch literal 7252 zcmZ`;cUTimx8D$|5I_+rK?#C@NRuuogd#9CqIuz0Ukcy01%Q>I`q-|E9@)-p09aUg3rnPOORgr zsPS*1dlOSy3mv+Fur?8MYP0rJwj>5~wTrn=9&^Mg+N~h{bpqWF5|5p8Vss9x=GTUn zWZ?zf*Pz|I+6UKeYcfQ(P; z6t+9r`n~fovrpm7?AEE_9HgF;2^ZWj3urN}_TJ+DvGmhr!JMZr@q$~P+mN%NViu)v z>CDTMXWsRnXORU6x(N7P?rj}Qkp{W%_fqx;ittr!JwMbt0tXnkx1JN3Lgi~r4nxZa z7+oGV-hY7@?m9J+KSP}Dl|%Z!Ckp`pl+8d#(<~%sJs0^}u~W%EAcnmqa`xHCIGK0fsrhgz!_03_kH{{7$uQcNZ?~(qx{`%ffvSWHO`t`i6S6 zvw+)=kl{It&Rj-~4n@_zdnYR|&ov1F+%q>fWoomDg5=?I@j$|2CX z#FH|5G=&m=egCKbc0>{8Yve)wVv*k!YQpiJ7e;Z==^@I4sQyz{cKUT}-RsQEFSuo* zQ*YedkMQrFIrOtKRJ~^JaFqM1<(YdFYK4E1N3_h^k2}5`2TE|be6u-q+k9H1Ikt9p zMZ@?)6DfOv>ia8<6tXcD+)LSa3Ii%&;RC;hY^7JPrM0DVb@dO*1lsa8QVP|YT`8zj zJ(5&RGm0ODq%b^^Q-@(e&5DX|`wq;tx`_q*ik>Uw+b`OpbqI^*5G96n629vh0Hk@e6R zlsxIrGF1g9?C|CSzIF&jn%U#h(D!!k93n!bQ1*=ORhny=6hbr79pSU@e`~C&x^`}J z_-u}M``6QB?e}A!W`1)7M#zk26w%!*KXtEo%}J z+S6&_H1iVWz@yMFGSdTfn|v-Vmax4)!g{K8%LD4>g}p_@BiFc7-)9rE1br8xxFt{< zrjRA@tK19KuXA(FbEC~TT@R0x;By}S>(yf~k;$whWP{%e**@_`hJTmN@f`2jssjBY zvCC!_7&_cGaT$xVy*0nV;iq}y#hW0^7pHROpOyZ4vlDOo^?w{f<3Tv_gXKkre@Ioz zjIC*=to)Ule;Sjn$g4}BsQBBjIZfx;L8ia>bmj$1jy*&ZOiD~N&6Tk$EFd$=mtGD0 zZC)boG*&C~Kr$)g*-n)8CjhfnfY zSK1Z4TxzVb_k@$a4cYKYNPw3mPjU?{D%0DTn52QQ=SGBi+>dD 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