From cd79ae951daeab02797e53f48c6b7ab0df4d248e Mon Sep 17 00:00:00 2001 From: "mport2004@gmail.com" Date: Thu, 3 Feb 2011 08:15:17 +0000 Subject: [PATCH] Updated: Singularity Engine -Recoded some parts, still works mostly the same Welders -Recoded, it works mostly the same but is easier to use in code -Cyborgs have a larger fuel tank -Brought most if not all of the areas that use welders upto spec Moved the changeling chem recharge code into the human life proc New players who log out before spawning in are now deleted New minor Common event Machines around the station use more power, system might need some changes later Likely few other minor changes that I just cant think of atm git-svn-id: http://tgstation13.googlecode.com/svn/trunk@945 316c924e-a436-60f5-8080-3fe189b3f50e --- code/ATMOSPHERICS/atmospherics.dm | 3 + .../components/binary_devices/pump.dm | 2 - .../components/unary/vent_pump.dm | 43 +- .../components/unary/vent_scrubber.dm | 5 +- code/ATMOSPHERICS/pipes.dm | 9 +- code/WorkInProgress/KeelinsStuff.dm | 4 +- .../recycling/disposal-construction.dm | 44 +- code/WorkInProgress/recycling/disposal.dm | 5 +- code/defines/area/Space Station 13 areas.dm | 1 + code/defines/atom.dm | 3 + code/defines/obj/machinery.dm | 81 +- code/defines/obj/weapon.dm | 15 - code/game/area/areas.dm | 12 +- code/game/dna.dm | 1 - code/game/gamemodes/events.dm | 3 + code/game/gamemodes/events/dust.dm | 117 + code/game/machinery/alarm.dm | 7 +- code/game/machinery/blender.dm | 1 + code/game/machinery/bots/ed209bot.dm | 5 +- code/game/machinery/bots/secbot.dm | 3 +- code/game/machinery/computer/aifixer.dm | 2 +- code/game/machinery/doors/airlock.dm | 10 +- code/game/machinery/doors/firedoor.dm | 58 +- code/game/machinery/hologram.dm | 2 - code/game/machinery/recharger.dm | 1 + code/game/machinery/rechargestation.dm | 2 +- code/game/machinery/robot_fabricator.dm | 3 +- code/game/machinery/shieldgen.dm | 1 + code/game/machinery/singularity.dm | 1347 -------- code/game/machinery/status_display.dm | 6 +- code/game/machinery/turrets.dm | 6 +- code/game/magic/cultist/runes.dm | 2 +- code/game/master_controller.dm | 8 +- code/game/mecha/mecha.dm | 12 +- code/game/mecha/mecha_construction.dm | 8 +- code/game/mecha/mecha_wreckage.dm | 9 +- code/game/objects/closets.dm | 7 +- code/game/objects/door_assembly.dm | 22 +- code/game/objects/items/helper_procs.dm | 8 +- code/game/objects/items/weapons/tools.dm | 379 ++- code/game/objects/stacks/metal.dm | 26 +- code/game/turf.dm | 42 +- code/modules/admin/admin_verbs.dm | 8 +- code/modules/admin/verbs/massmodvar.dm | 223 ++ code/modules/mob/living/carbon/human/life.dm | 12 +- code/modules/mob/living/carbon/monkey/life.dm | 10 +- .../mob/living/carbon/monkey/monkey.dm | 7 +- .../mob/living/silicon/hivebot/hivebot.dm | 16 +- code/modules/mob/living/silicon/robot/life.dm | 1 + .../modules/mob/living/silicon/robot/robot.dm | 16 +- .../mob/living/silicon/robot/robot_modules.dm | 2 +- code/modules/mob/mob.dm | 2 +- code/modules/mob/new_player/new_player.dm | 6 + code/modules/power/apc.dm | 36 +- code/modules/power/lighting.dm | 41 +- code/modules/power/singularity/collector.dm | 83 + .../power/singularity/containment_field.dm | 75 + code/modules/power/singularity/emitter.dm | 179 ++ .../power/singularity/field_generator.dm | 308 ++ code/modules/power/singularity/generator.dm | 42 + code/modules/power/singularity/singularity.dm | 269 ++ code/modules/power/smes.dm | 31 + code/modules/power/solar.dm | 2 + icons/obj/meteor.dmi | Bin 2432 -> 11700 bytes icons/obj/singularity.dmi | Bin 10450 -> 13685 bytes maps/tgstation.2.0.0.dmm | 2795 ++++++++--------- tgstation.dme | 25 +- 67 files changed, 3276 insertions(+), 3238 deletions(-) create mode 100644 code/game/gamemodes/events/dust.dm create mode 100644 code/modules/admin/verbs/massmodvar.dm create mode 100644 code/modules/power/singularity/collector.dm create mode 100644 code/modules/power/singularity/containment_field.dm create mode 100644 code/modules/power/singularity/emitter.dm create mode 100644 code/modules/power/singularity/field_generator.dm create mode 100644 code/modules/power/singularity/generator.dm create mode 100644 code/modules/power/singularity/singularity.dm diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 2dcadfa1c71..75d233eb467 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -12,6 +12,9 @@ Pipelines + Other Objects -> Pipe network obj/machinery/atmospherics anchored = 1 + power_usage = 10 + power_channel = ENVIRON + var/initialize_directions = 0 var/color diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm index 8b995faa2fe..31fc228cc9d 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm @@ -46,7 +46,6 @@ obj/machinery/atmospherics/binary/pump return if(!on) return 0 - use_power(5) var/output_starting_pressure = air2.return_pressure() @@ -69,7 +68,6 @@ obj/machinery/atmospherics/binary/pump if(network2) network2.update = 1 - use_power(round(air2.volume/12)) return 1 //Radio remote control diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm index f262f0d8793..632eac7e254 100644 --- a/code/ATMOSPHERICS/components/unary/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm @@ -6,7 +6,6 @@ desc = "Has a valve and pump attached to it" level = 1 - var/channel = ENVIRON var/area_uid var/id = null @@ -42,7 +41,6 @@ name = "Large Air Vent" New() ..() - channel = EQUIP air_contents.volume = 1000 update_icon() @@ -66,7 +64,6 @@ if(!on) return 0 - use_power(5, channel) if(welded) return 0 @@ -87,7 +84,6 @@ var/datum/gas_mixture/removed = air_contents.remove(transfer_moles) - use_power(round(air_contents.volume/12), channel) loc.assume_air(removed) if(network) @@ -108,8 +104,6 @@ if (isnull(removed)) //in space return - - use_power(round(air_contents.volume/12), channel) air_contents.merge(removed) if(network) @@ -151,7 +145,7 @@ initialize() ..() - + //some vents work his own spesial way radio_filter_in = frequency==initial(frequency)?(RADIO_FROM_AIRALARM):null radio_filter_out = frequency==initial(frequency)?(RADIO_TO_AIRALARM):null @@ -228,22 +222,21 @@ on = 0 return - attackby(obj/item/W, mob/user) // Added for aliens -- TLE - // Stolen from the Emitter welding code of the Singularity - if(istype(W, /obj/item/weapon/weldingtool) && W:welding) - if (W:get_fuel() < 1) + attackby(obj/item/W, mob/user) + if(istype(W, /obj/item/weapon/weldingtool)) + if (W:remove_fuel(2,user)) + user << "\blue Now welding the vent." + if(do_after(user, 20)) + playsound(src.loc, 'Welder2.ogg', 50, 1) + if(!welded) + 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.", "You hear welding.") + welded = 0 + else user << "\blue You need more welding fuel to complete this task." return 1 - 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.", "You hear welding.") - welded = 1 - else - user.visible_message("[user] unwelds the vent.", "You unweld the vent.", "You hear welding.") - welded = 0 - examine() set src in oview(1) ..() @@ -251,10 +244,10 @@ usr << "It seems welded shut." power_change() - if(powered(channel)) - stat &= ~NOPOWER - else - stat |= NOPOWER +// if(powered(EVNIRON)) +// stat &= ~NOPOWER +// else +// stat |= NOPOWER update_icon() attackby(var/obj/item/weapon/W as obj, var/mob/user as mob) diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm index e59a32eb4ce..f1af3e73b6e 100644 --- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm @@ -97,8 +97,7 @@ var/datum/gas_mixture/removed = loc.remove_air(transfer_moles) if (isnull(removed)) //in space return - var/power = (scrub_Toxins+scrub_CO2+scrub_N2O)*volume_rate/12 - use_power(round(power+5), ENVIRON) + //Filter it var/datum/gas_mixture/filtered_out = new filtered_out.temperature = removed.temperature @@ -130,7 +129,7 @@ else //Just siphoning all air if (air_contents.return_pressure()>=50*ONE_ATMOSPHERE) return - use_power(round(volume_rate/12)+5, ENVIRON) + var/transfer_moles = environment.total_moles()*(volume_rate/environment.volume) var/datum/gas_mixture/removed = loc.remove_air(transfer_moles) diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm index e8632377306..68cae4b272d 100644 --- a/code/ATMOSPHERICS/pipes.dm +++ b/code/ATMOSPHERICS/pipes.dm @@ -1,4 +1,5 @@ obj/machinery/atmospherics/pipe + power_usage = 0 var/datum/gas_mixture/air_temporary //used when reconstructing a pipeline that broke var/datum/pipeline/parent @@ -205,14 +206,14 @@ obj/machinery/atmospherics/pipe normalize_dir() var/node1_dir var/node2_dir - + for(var/direction in cardinal) if(direction&initialize_directions) if (!node1_dir) node1_dir = direction else if (!node2_dir) node2_dir = direction - + for(var/obj/machinery/atmospherics/target in get_step(src,node1_dir)) if(target.initialize_directions & get_dir(target,src)) node1 = target @@ -298,14 +299,14 @@ obj/machinery/atmospherics/pipe normalize_dir() var/node1_dir var/node2_dir - + for(var/direction in cardinal) if(direction&initialize_directions_he) if (!node1_dir) node1_dir = direction else if (!node2_dir) node2_dir = direction - + for(var/obj/machinery/atmospherics/pipe/simple/heat_exchanging/target in get_step(src,node1_dir)) if(target.initialize_directions_he & get_dir(target,src)) node1 = target diff --git a/code/WorkInProgress/KeelinsStuff.dm b/code/WorkInProgress/KeelinsStuff.dm index 170b7c244ca..30b91e5aac9 100644 --- a/code/WorkInProgress/KeelinsStuff.dm +++ b/code/WorkInProgress/KeelinsStuff.dm @@ -305,11 +305,11 @@ return 0 /proc/do_after(mob/M as mob, time as num) - var/turf/T = M.loc + var/turf/T = get_turf(M) var/holding = M.equipped() sleep(time) if(M) - if ((M.loc == T && M.equipped() == holding && !( M.stat ))) + if ((get_turf(M) == T && M.equipped() == holding && !( M.stat ))) return 1 else return 0 diff --git a/code/WorkInProgress/recycling/disposal-construction.dm b/code/WorkInProgress/recycling/disposal-construction.dm index 2e8dc5884cb..297638af0ea 100644 --- a/code/WorkInProgress/recycling/disposal-construction.dm +++ b/code/WorkInProgress/recycling/disposal-construction.dm @@ -132,33 +132,19 @@ else if(istype(I, /obj/item/weapon/weldingtool)) var/obj/item/weapon/weldingtool/W = I - if(W.welding) - if(W.get_fuel() > 2) - W.use_fuel(2) - playsound(src.loc, 'Welder2.ogg', 100, 1) - - // check if anything changed over 2 seconds - var/turf/uloc = user.loc - var/atom/wloc = W.loc - user << "Welding the pipe in place." - sleep(20) - if(user.loc == uloc && wloc == W.loc) - - update() - var/pipetype = dpipetype() - var/obj/disposalpipe/P = new pipetype(src.loc) - P.base_icon_state = base_state - P.dir = dir - P.dpdir = dpdir - P.updateicon() - - del(src) - else - user << "You must stay still while welding." - return - - - - else - user << "You need more welding fuel to complete this task." + if(W.remove_fuel(2)) + playsound(src.loc, 'Welder2.ogg', 100, 1) + user << "Welding the pipe in place." + if(do_after(user, 20)) + update() + var/pipetype = dpipetype() + var/obj/disposalpipe/P = new pipetype(src.loc) + P.base_icon_state = base_state + P.dir = dir + P.dpdir = dpdir + P.updateicon() + del(src) return + else + user << "You need more welding fuel to complete this task." + return diff --git a/code/WorkInProgress/recycling/disposal.dm b/code/WorkInProgress/recycling/disposal.dm index 00876122760..bf20cb222c9 100644 --- a/code/WorkInProgress/recycling/disposal.dm +++ b/code/WorkInProgress/recycling/disposal.dm @@ -685,17 +685,14 @@ var/obj/item/weapon/weldingtool/W = I if(W.welding) - if(W.get_fuel() > 3) - W.use_fuel(3) + if(W.remove_fuel(3)) playsound(src.loc, 'Welder2.ogg', 100, 1) - // check if anything changed over 2 seconds var/turf/uloc = user.loc var/atom/wloc = W.loc user << "Slicing the disposal pipe." sleep(30) if(user.loc == uloc && wloc == W.loc) - welded() else user << "You must stay still while welding the pipe." diff --git a/code/defines/area/Space Station 13 areas.dm b/code/defines/area/Space Station 13 areas.dm index ef3cac6a84b..7d95f1e1af1 100644 --- a/code/defines/area/Space Station 13 areas.dm +++ b/code/defines/area/Space Station 13 areas.dm @@ -42,6 +42,7 @@ var/area/master // master area used for power calcluations // (original area before splitting due to sd_DAL) var/list/related // the other areas of the same type as this + var/list/lights // list of all lights on this area /*Adding a wizard area teleport list because motherfucking lag -- Urist*/ /*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/ diff --git a/code/defines/atom.dm b/code/defines/atom.dm index b1f5da64de4..418a3cad36c 100644 --- a/code/defines/atom.dm +++ b/code/defines/atom.dm @@ -76,6 +76,9 @@ obj /atom/proc/HasProximity(atom/movable/AM as mob|obj) return +/atom/proc/emp_act(var/severity) + return + /atom/movable/overlay/attackby(a, b) if (src.master) return src.master.attackby(a, b) diff --git a/code/defines/obj/machinery.dm b/code/defines/obj/machinery.dm index b23300aad02..0640f0a0f27 100644 --- a/code/defines/obj/machinery.dm +++ b/code/defines/obj/machinery.dm @@ -1,7 +1,13 @@ /obj/machinery name = "machinery" icon = 'stationobjs.dmi' - var/stat = 0 + var + stat = 0 + power_usage = 200 + power_channel = EQUIP + //EQUIP,ENVIRON or LIGHT + + /obj/machinery/alarm name = "alarm" @@ -10,6 +16,7 @@ anchored = 1.0 var/skipprocess = 0 //Experimenting var/alarm_frequency = "1437" + power_usage = 5 /obj/machinery/autolathe name = "Autolathe" @@ -30,6 +37,7 @@ var/hack_wire var/disable_wire var/shock_wire + power_usage = 50 /obj/machinery/camera name = "Security Camera" @@ -43,7 +51,7 @@ anchored = 1.0 var/invuln = null var/bugged = 0 - + power_usage = 5 /obj/machinery/dispenser @@ -55,6 +63,7 @@ var/o2tanks = 10.0 var/pltanks = 10.0 anchored = 1.0 + power_usage = 10 /obj/machinery/dna_scanner name = "DNA Scanner/Implanter" @@ -64,6 +73,7 @@ var/locked = 0.0 var/mob/occupant = null anchored = 1.0 + power_usage = 200 /obj/machinery/dna_scannernew name = "DNA Modifier" @@ -73,7 +83,7 @@ var/locked = 0.0 var/mob/occupant = null anchored = 1.0 - + power_usage = 200 /obj/machinery/firealarm name = "Fire Alarm" @@ -85,6 +95,8 @@ var/timing = 0.0 var/lockdownbyai = 0 anchored = 1.0 + power_usage = 5 + power_channel = ENVIRON /obj/machinery/partyalarm name = "Party Button" @@ -96,7 +108,7 @@ var/timing = 0.0 var/lockdownbyai = 0 anchored = 1.0 - + power_usage = 5 /obj/machinery/hologram_proj @@ -143,6 +155,7 @@ var/id = 1.0 anchored = 1.0 var/drive_range = 50 //this is mostly irrelevant since current mass drivers throw into space, but you could make a lower-range mass driver for interstation transport or something I guess. + power_usage = 50 /obj/machinery/meter name = "meter" @@ -152,6 +165,7 @@ anchored = 1.0 var/frequency = 0 var/id + power_usage = 5 /obj/machinery/nuclearbomb desc = "Uh oh." @@ -169,6 +183,7 @@ var/safety = 1.0 var/obj/item/weapon/disk/nuclear/auth = null flags = FPRINT + power_usage = 0 /obj/machinery/optable name = "Operating Table" @@ -176,7 +191,7 @@ icon_state = "table2-idle" density = 1 anchored = 1.0 - + power_usage = 40 var/mob/living/carbon/human/victim = null var/strapped = 0.0 @@ -195,6 +210,7 @@ var/can_rotate = 1 var/can_maximize_speed = 0 var/one_person_only = 0 + power_usage = 0 /obj/machinery/vehicle/pod name = "Escape Pod" @@ -220,6 +236,7 @@ var/locked = 0.0 var/mob/occupant = null anchored = 1.0 + power_usage = 600 /obj/machinery/scan_console name = "DNA Scanner Access Console" @@ -238,6 +255,7 @@ var/temp = null var/obj/machinery/dna_scanner/connected = null anchored = 1.0 + power_usage = 400 /obj/machinery/scan_consolenew name = "DNA Modifier Access Console" @@ -272,6 +290,7 @@ var/obj/machinery/dna_scanner/connected = null var/obj/item/weapon/disk/data/diskette = null anchored = 1.0 + power_usage = 400 /obj/machinery/sec_lock name = "Security Pad" @@ -283,6 +302,7 @@ var/obj/machinery/door/d2 = null anchored = 1.0 req_access = list(access_brig) + power_usage = 5 /obj/machinery/door_control name = "Remote Door Control" @@ -291,6 +311,7 @@ desc = "A remote control switch for a door." var/id = null anchored = 1.0 + power_usage = 5 /obj/machinery/driver_button name = "Mass Driver Button" @@ -300,6 +321,7 @@ var/id = null var/active = 0 anchored = 1.0 + power_usage = 5 /obj/machinery/ignition_switch name = "Ignition Switch" @@ -309,10 +331,12 @@ var/id = null var/active = 0 anchored = 1.0 + power_usage = 5 /obj/machinery/shuttle name = "shuttle" icon = 'shuttle.dmi' + power_usage = 0 /obj/machinery/shuttle/engine name = "engine" @@ -358,17 +382,19 @@ name = "hub" icon_state = "tele0" var/accurate = 0 + power_usage = 100 /obj/machinery/teleport/station name = "station" icon_state = "controller" var/active = 0 var/engaged = 0 + power_usage = 100 /obj/machinery/wire name = "wire" icon = 'power_cond.dmi' - + power_usage = 1 /obj/machinery/power name = null @@ -378,6 +404,7 @@ var/netnum = 0 var/directwired = 1 // by default, power machines are connected by a cable in a neighbouring turf // if set to 0, requires a 0-X cable on this turf + power_usage = 0 /obj/machinery/power/terminal name = "terminal" @@ -420,36 +447,7 @@ icon_state = "power" density = 1 anchored = 1 - -#define SMESMAXCHARGELEVEL 200000 -#define SMESMAXOUTPUT 200000 - -/obj/machinery/power/smes/magical - name = "magical power storage unit" - desc = "A high-capacity superconducting magnetic energy storage (SMES) unit. Magically produces power." - process() - capacity = INFINITY - charge = INFINITY - ..() - -/obj/machinery/power/smes - name = "power storage unit" - desc = "A high-capacity superconducting magnetic energy storage (SMES) unit." - icon_state = "smes" - density = 1 - anchored = 1 - var/output = 30000 - var/lastout = 0 - var/loaddemand = 0 - var/capacity = 5e6 - var/charge = 1e6 - var/charging = 0 - var/chargemode = 0 - var/chargecount = 0 - var/chargelevel = 30000 - var/online = 1 - var/n_tag = null - var/obj/machinery/power/terminal/terminal = null + power_usage = 600 /obj/machinery/power/solar name = "solar panel" @@ -467,6 +465,7 @@ var/ndir = SOUTH var/turn_angle = 0 var/obj/machinery/power/solar_control/control + power_usage = 0 /obj/machinery/power/solar_control name = "solar panel control" @@ -484,7 +483,7 @@ var/trackrate = 600 // 300-900 seconds var/trackdir = 1 // 0 =CCW, 1=CW var/nexttime = 0 - + power_usage = 500 /obj/machinery/cell_charger @@ -495,6 +494,7 @@ var/obj/item/weapon/cell/charging = null var/chargelevel = -1 anchored = 1 + power_usage = 50 /obj/machinery/light_switch desc = "A light switch" @@ -525,6 +525,7 @@ icon_state = "mw" density = 1 anchored = 1 + power_usage = 100 var/egg_amount = 0 //Current number of eggs inside var/flour_amount = 0 //Current amount of flour inside var/water_amount = 0 //Current amount of water inside @@ -563,6 +564,8 @@ anchored = 1 var/broken = 0 var/processing = 0 + power_usage = 50 + /obj/machinery/gibber name = "Gibber" @@ -575,6 +578,7 @@ var/dirty = 0 // Does it need cleaning? var/gibtime = 40 // Time from starting until meat appears var/mob/occupant // Mob who has been put inside + power_usage = 50 /obj/machinery/holopad name = "holopad" @@ -582,4 +586,5 @@ icon_state = "holopad0" anchored = 1 var/state = "off" - var/slave_holo = null \ No newline at end of file + var/slave_holo = null + power_usage = 50 \ No newline at end of file diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index 33509032838..c0c9da1209b 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -1126,21 +1126,6 @@ Total SMES charging rate should not exceed total power generation rate, or an ov throw_speed = 4 throw_range = 20 -/obj/item/weapon/weldingtool - name = "weldingtool" - icon = 'items.dmi' - icon_state = "welder" - var/welding = 0 - var/status = 0 //flamethrower construction :shobon: - flags = FPRINT | TABLEPASS| CONDUCT - force = 3.0 - throwforce = 5.0 - throw_speed = 1 - throw_range = 5 - w_class = 2.0 - m_amt = 70 - g_amt = 30 - /obj/item/weapon/wire desc = "This is just a simple piece of regular insulated wire." name = "wire" diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 3dc15976f3b..7e1a34193ce 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -19,7 +19,7 @@ src.icon = 'alert.dmi' src.layer = 10 - +// update_lights() if(name == "Space") // override defaults for space requires_power = 0 @@ -56,7 +56,15 @@ A = A.loc return null */ - +/* +/area/proc/update_lights() + var/new_power = 0 + for(var/obj/machinery/light/L in src.contents) + if(L.on) + new_power += (L.luminosity * 20) + lighting_power_usage = new_power + return +*/ /area/proc/poweralert(var/state, var/source) if (state != poweralm) poweralm = state diff --git a/code/game/dna.dm b/code/game/dna.dm index 7315390fb3c..64da7a7de90 100644 --- a/code/game/dna.dm +++ b/code/game/dna.dm @@ -645,7 +645,6 @@ /obj/machinery/scan_consolenew/process() //not really used right now if(stat & (NOPOWER|BROKEN)) return - use_power(250) // power stuff if (!( src.status )) //remove this return return diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index db78133792b..1e316ba8b98 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -1,4 +1,7 @@ /proc/start_events() + if(prob(50))//Every 120 seconds and prob 50 4-8 weak spacedusts will hit the station + spawn(1) + dust_swarm("weak") if (!event && prob(eventchance)) event() hadevent = 1 diff --git a/code/game/gamemodes/events/dust.dm b/code/game/gamemodes/events/dust.dm new file mode 100644 index 00000000000..966b46c2c53 --- /dev/null +++ b/code/game/gamemodes/events/dust.dm @@ -0,0 +1,117 @@ +/* +Space dust +Commonish random event that causes small clumps of "space dust" to hit the station at high speeds. +No command report on the common version of this event. +The "dust" will damage the hull of the station causin minor hull breaches. +*/ + +/proc/dust_swarm(var/strength = "weak") + var/numbers = 1 + switch(strength) + if("weak") + numbers = rand(4,8) + for(var/i = 0 to numbers) + new/obj/space_dust/weak() + if("norm") + numbers = rand(5,10) + for(var/i = 0 to numbers) + new/obj/space_dust() + if("strong") + numbers = rand(10,15) + for(var/i = 0 to numbers) + new/obj/space_dust/strong() + if("super") + numbers = rand(15,25) + for(var/i = 0 to numbers) + new/obj/space_dust/super() + return + + +/obj/space_dust + name = "Space Dust" + desc = "Dust in space." + icon = 'meteor.dmi' + icon_state = "space_dust" + density = 1 + anchored = 1 + var + strength = 2 //ex_act severity number + life = 2 //how many things we hit before del(src) + + weak + strength = 3 + life = 1 + + strong + strength = 1 + life = 6 + + super + strength = 1 + life = 40 + + + New() + var/startx = 0 + var/starty = 0 + var/endy = 0 + var/endx = 0 + var/startside = pick(cardinal) + + switch(startside) + if(NORTH) + starty = world.maxy-1 + startx = rand(1, world.maxx-1) + endy = 1 + endx = rand(1, world.maxx-1) + if(EAST) + starty = rand(1,world.maxy-1) + startx = world.maxx-1 + endy = rand(1, world.maxy-1) + endx = 1 + if(SOUTH) + starty = 1 + startx = rand(1, world.maxx-1) + endy = world.maxy-1 + endx = rand(1, world.maxx-1) + if(WEST) + starty = rand(1, world.maxy-1) + startx = 1 + endy = rand(1,world.maxy-1) + endx = world.maxx-1 + var/goal = locate(endx, endy, src.z) + src.x = startx + src.y = starty + spawn(0) + walk_towards(src, goal, 1) + return + + + Bump(atom/A) + spawn(0) + if(prob(50)) + for(var/mob/M in range(10, src)) + if(!M.stat && !istype(M, /mob/living/silicon/ai)) + shake_camera(M, 3, 1) + if (A) + playsound(src.loc, 'meteorimpact.ogg', 40, 1) + if(ismob(A)) + A.meteorhit(src)//This should work for now I guess + else + A.ex_act(strength) + life-- + if(life <= 0) + spawn(0) + del(src) + return 0 + return + + + Bumped(atom/A) + Bump(A) + return + + + ex_act(severity) + del(src) + return \ No newline at end of file diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index a7e172e9ada..d4759ce66ca 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -1,5 +1,7 @@ /obj/machinery/alarm + power_usage = 5 + power_channel = ENVIRON var/frequency = 1439 var/list/sensors = list() var/list/vents = list() @@ -61,7 +63,7 @@ return spawn (10) send_signal(m_id, "init", new_name ) - + set_frequency(new_frequency) radio_controller.remove_object(src, frequency) frequency = new_frequency @@ -352,7 +354,6 @@ icon_state = "alarmp" return - use_power(5, ENVIRON) if (!( istype(location, /turf) )) return 0 @@ -574,8 +575,6 @@ if(stat & (NOPOWER|BROKEN)) return - use_power(10, ENVIRON) - var/area/A = src.loc A = A.loc diff --git a/code/game/machinery/blender.dm b/code/game/machinery/blender.dm index 25786ef77ad..e6d7cbae4fd 100644 --- a/code/game/machinery/blender.dm +++ b/code/game/machinery/blender.dm @@ -16,6 +16,7 @@ the blender or the processor: Processor items are solid objects and Blender resu icon_state = "blender_e" density = 1 anchored = 1 + power_usage = 20 flags = OPENCONTAINER //So that you can pour stuff into it. var/processing = 0 //This turns on (1) while it is processing so you don't accidentally get multiples from the same item. var/container = 1 //Is there a jug attached? Could have been done with a for loop but it's less code this way. diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm index ff4adaa9dbd..bdb8cb13181 100644 --- a/code/game/machinery/bots/ed209bot.dm +++ b/code/game/machinery/bots/ed209bot.dm @@ -781,8 +781,7 @@ Auto Patrol: []"}, src.icon_state = "ed209_shell" del(W) else if ((istype(W, /obj/item/weapon/weldingtool)) && (src.build_step == 3)) - if ((W:welding) && (W:get_fuel() >= 1)) - W:use_fuel(1) + if (W:remove_fuel(1,user)) src.build_step++ src.name = "shielded frame assembly" user << "You welded the vest to [src]!" @@ -864,10 +863,8 @@ Auto Patrol: []"}, var/obj/beam/a_laser/A if (src.emagged) A = new /obj/beam/a_laser( loc ) - use_power(50) else A = new /obj/bullet/electrode( loc ) - use_power(100) if (!( istype(U, /turf) )) //A = null diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm index 4ffee8902f1..487818cbb78 100644 --- a/code/game/machinery/bots/secbot.dm +++ b/code/game/machinery/bots/secbot.dm @@ -756,8 +756,7 @@ Auto Patrol: []"}, /obj/item/weapon/secbot_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob) if ((istype(W, /obj/item/weapon/weldingtool)) && (!src.build_step)) - if ((W:welding) && (W:get_fuel() >= 1)) - W:use_fuel(1) + if(W:remove_fuel(1,user)) src.build_step++ src.overlays += image('aibots.dmi', "hs_hole") user << "You weld a hole in [src]!" diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index 37508f93a34..580ae88b385 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -143,7 +143,7 @@ /obj/machinery/computer/aifixer/process() if(stat & (NOPOWER|BROKEN)) return - use_power(500) + src.updateDialog() return diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 6b1bbfb5108..6a1c42f3c3d 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -800,19 +800,15 @@ About the new airlock wires panel: src.add_fingerprint(user) if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && src.density)) var/obj/item/weapon/weldingtool/W = C - if(W.welding) - if (W.get_fuel() > 2) - W.use_fuel(2) - W.eyecheck(user) - else - user << "Need more welding fuel!" - return + if(W.remove_fuel(2,user)) if (!src.welded) src.welded = 1 else src.welded = null src.update_icon() return + else + return else if (istype(C, /obj/item/weapon/screwdriver)) src.p_open = !( src.p_open ) src.update_icon() diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 6c4c72b2571..43c3c01f3dd 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -20,44 +20,38 @@ src.add_fingerprint(user) if ((istype(C, /obj/item/weapon/weldingtool) && !( src.operating ) && src.density)) var/obj/item/weapon/weldingtool/W = C - if(W.welding) - if (W.get_fuel() > 2) - W.use_fuel(2) - if (!( src.blocked )) - src.blocked = 1 - else - src.blocked = 0 + if(W.remove_fuel(2, user)) + src.blocked = !src.blocked + user << text("\red You [blocked?"welded":"unwelded"] the [src]") update_icon() - return - if (!( istype(C, /obj/item/weapon/crowbar) )) - return + if (istype(C, /obj/item/weapon/crowbar)) + if (!src.blocked && !src.operating) + if(src.density) + spawn( 0 ) + src.operating = 1 - if (!src.blocked && !src.operating) - if(src.density) - spawn( 0 ) - src.operating = 1 + animate("opening") + sleep(15) + src.density = 0 + update_icon() - animate("opening") - sleep(15) - src.density = 0 - update_icon() + src.sd_SetOpacity(0) + src.operating = 0 + return + else //close it up again + spawn( 0 ) + src.operating = 1 - src.sd_SetOpacity(0) - src.operating = 0 - return - else //close it up again - spawn( 0 ) - src.operating = 1 + animate("closing") + src.density = 1 + sleep(15) + update_icon() - animate("closing") - src.density = 1 - sleep(15) - update_icon() - - src.sd_SetOpacity(1) - src.operating = 0 - return + src.sd_SetOpacity(1) + src.operating = 0 + return + ..() return /obj/machinery/door/firedoor/process() diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 6fe4ee9e218..5c2077753b4 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -53,8 +53,6 @@ src.state = "off" src.icon_state = "holopad0" src.slave_holo = null - else - use_power(300) if(src.state == "off" && src.slave_holo) //usually happens if the power ran out del(src.slave_holo) //code for returning the control back to the AI is in the mob's del() code src.slave_holo = null diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index fa7160fdc97..1f42c637a59 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -3,6 +3,7 @@ obj/machinery/recharger icon = 'stationobjs.dmi' icon_state = "recharger0" name = "recharger" + power_usage = 50 var obj/item/weapon/gun/energy/charging = null diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 4f7d511e41e..53300b433e1 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -4,7 +4,7 @@ icon_state = "pod_0" density = 1 anchored = 1.0 - + power_usage = 80 var/mob/occupant = null diff --git a/code/game/machinery/robot_fabricator.dm b/code/game/machinery/robot_fabricator.dm index 7f13c07d54e..7dc19291ea1 100644 --- a/code/game/machinery/robot_fabricator.dm +++ b/code/game/machinery/robot_fabricator.dm @@ -7,6 +7,7 @@ var/metal_amount = 0 var/operating = 0 var/obj/item/robot_parts/being_built = null + power_usage = 1000 /obj/machinery/robotic_fabricator/attackby(var/obj/item/O as obj, var/mob/user as mob) if (istype(O, /obj/item/stack/sheet/metal)) @@ -39,8 +40,6 @@ if (stat & (NOPOWER | BROKEN)) return - use_power(1000) - /obj/machinery/robotic_fabricator/attack_paw(user as mob) return src.attack_hand(user) diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 2d7c9789061..f0e627f8faf 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -34,6 +34,7 @@ var/obj/cable/attached // the attached cable var/storedpower = 0 flags = FPRINT | CONDUCT + power_usage = 500 /obj/machinery/shield name = "shield" diff --git a/code/game/machinery/singularity.dm b/code/game/machinery/singularity.dm index aa6afd0720d..4921fee4ba0 100644 --- a/code/game/machinery/singularity.dm +++ b/code/game/machinery/singularity.dm @@ -7,1355 +7,8 @@ However people seem to like it for some reason. #define collector_control_range 12 -/////SINGULARITY SPAWNER -/obj/machinery/the_singularitygen/ - name = "Gravitational Singularity Generator" - desc = "An Odd Device which produces a Gravitational Singularity when set up." - icon = 'singularity.dmi' - icon_state = "TheSingGen" - anchored = 1 - density = 1 - - -//////////////////////Singularity gen START - -/obj/machinery/the_singularitygen/process() - 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)) - anchored = !anchored - playsound(src.loc, 'Ratchet.ogg', 75, 1) - if(anchored) - user.visible_message("[user.name] secures [src.name] to the floor.", \ - "You secure the [src.name] to the floor.", \ - "You hear ratchet") - else - user.visible_message("[user.name] unsecures [src.name] from the floor.", \ - "You unsecure the [src.name] from the floor.", \ - "You hear ratchet") - return - 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/ - name = "Gravitational Singularity" - desc = "A Gravitational Singularity." - icon = '160x160.dmi' - icon_state = "Singularity" - anchored = 1 - density = 1 - layer = 6 - unacidable = 1 //Don't comment this out. - var/active = 0 - var/energy = 10 - var/Dtime = null - var/Wtime = 0 - var/dieot = 0 - var/selfmove = 1 - var/grav_pull = 6 - -//////////////////////Singularity START - -/obj/machinery/the_singularity/New(loc, var/E = 100, var/Ti = null) - src.energy = E - pixel_x = -64 - pixel_y = -64 - event() - if(Ti) - src.Dtime = Ti - ..() - notify_collector_controller() - -/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) - return - if(2.0 to 3.0) //no way - return - return - -/obj/machinery/the_singularity/Del() - //TODO: some animation - notify_collector_controller() - ..() - -/obj/machinery/the_singularity/process() - eat() - - if(src.Dtime)//If its a temp singularity IE: an event - if(Wtime != 0) - if((src.Wtime + src.Dtime) <= world.time) - src.Wtime = 0 - del(src) - else - src.Wtime = world.time - - if(dieot) - if(energy <= 0)//slowly dies over time - del(src) - else - energy -= 5 - - switch(energy) - if(1000 to 1999) - for(var/obj/machinery/field_generator/F in orange(5,src)) - F.turn_off() - Zzzzap() - BHolerip() - Toxmob() - if(2000 to INFINITY) - explosion(src.loc, 4, 8, 15, 0) - Zzzzap() - Toxmob() - src.ex_act(1) //if it survived the explosion - - 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 - notify_collector_controller() - 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 - notify_collector_controller() - if(active == 1) - move() - spawn(5) - move() - - -/obj/machinery/the_singularity/proc/notify_collector_controller() - var/oldsrc = src - src = null //for spawn() working even after Del(), see byond documentation about sleep() -rastaf0 - for(var/obj/machinery/power/collector_control/myCC in orange(collector_control_range,oldsrc)) - spawn() if(myCC) myCC.updatecons() - -/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(isarea(X)) - continue - 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,/obj/machinery/shieldwallgen)) - var/obj/machinery/shieldwallgen/S = X - if(S.active) - continue - switch(get_dist(src,X)) - if(0 to 2) - src.Bumped(X) - else if(!isturf(X)) - if(!istype(X,/mob/living/carbon/human)) - if(!X:anchored) - step_towards(X,src) - else - 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) - -/obj/machinery/the_singularity/proc/move() - 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" - step(src, direction_go) - - -/obj/machinery/the_singularity/Bumped(atom/A) - var/gain = 0 - 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 == "Chief Engineer") ) - gain = 100 - A:gib() - - else if(istype(A,/obj/)) - A:ex_act(1.0) - if(A) del(A) - gain = 2 - - else if(isturf(A)) - var/turf/T = A - if(T.intact) //stolen from t-ray - for(var/obj/O in T.contents) - if(O.level != 1) - continue - if(O.invisibility == 101) - src.Bumped(O) - A:ReplaceWithSpace() // - gain = 2 - - src.energy += gain - -/////////////////////////////////////////////Controls which "event" is called -/obj/machinery/the_singularity/proc/event() - var/numb = pick(1,2,3,4,5,6) - switch(numb) - if(1)//EMP - Zzzzap() - if(2)//Eats the turfs around it - if(prob(60)) - BHolerip() - else - event() - if(3,4)//tox damage all carbon mobs in area - Toxmob() - if(5)//Stun mobs who lack optic scanners - Mezzer() - else - //do nothing - return - - -/obj/machinery/the_singularity/proc/Toxmob() - var/toxrange = 7 - if (src.energy>100) - toxrange+=round((src.energy-100)/100) - var/toxloss = 3 - var/radiation = 10 - var/fireloss = 0 - if (src.energy>150) - toxloss += ((src.energy-150)/50)*3 - radiation += ((src.energy-150)/50)*10 - if (src.energy>300) - fireloss += ((src.energy-300)/50)*3 - for(var/mob/living/carbon/M in view(toxrange, src.loc)) - if(istype(M,/mob/living/carbon/human)) - if(M:wear_suit) //TODO: check for radiation protection - return - M.toxloss += toxloss - M.radiation += radiation - M.fireloss += fireloss - M.updatehealth() - M << "\red You feel odd." - -/obj/machinery/the_singularity/proc/Mezzer() - 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 << "\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) - M.stunned = 3 - for(var/mob/O in viewers(M, null)) - O.show_message(text("\red [] stares blankly at The []!", M, src), 1) - -/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/stack/tile (X) - X:break_tile_to_plating() - else - - X:break_tile() - else if(istype(X,/turf/simulated/wall)) - X:dismantle_wall() - 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) - - var/obj/overlay/pulse = new/obj/overlay ( myturf ) - pulse.icon = 'effects.dmi' - pulse.icon_state = "emppulse" - pulse.name = "emp pulse" - pulse.anchored = 1 - spawn(20) - del(pulse) - - for(var/mob/living/M in viewers(world.view-1, myturf)) - - //if(M == usr) continue - - if (istype(M, /mob/living/silicon)) - M.fireloss += 25 - flick("noise", M:flash) - M << "\red *BZZZT*" - M << "\red Warning: Electromagnetic pulse detected." - if(istype(M, /mob/living/silicon/ai)) - if (prob(30)) - switch(pick(1,2)) //Add Random laws. - if(1) - M:cancel_camera() - if(2) - M:ai_call_shuttle() - //if(3) - // M:lockdown() - continue - - - M << "\red Your equipment malfunctions." - if (locate(/obj/item/weapon/cloaking_device, M)) - for(var/obj/item/weapon/cloaking_device/S in M) - S.active = 0 - S.icon_state = "shield0" -/* - if (locate(/obj/item/device/disguiser, M)) - for(var/obj/item/device/disguiser/S in M) - S.disrupt(M) - S.on = 0 -*/ - - if (locate(/obj/item/weapon/gun/energy, M)) - for(var/obj/item/weapon/gun/energy/G in M) - G.charges = 0 - G.update_icon() - - if ((istype(M, /mob/living/carbon/human)) && (istype(M:glasses, /obj/item/clothing/glasses/thermal))) - M << "\red Your thermals malfunction." - M.eye_blind = 3 - M.eye_blurry = 5 - M.disabilities |= 1 - spawn(100) - if(M) - M.disabilities &= ~1 - - if (locate(/obj/item/device/radio, M)) - for(var/obj/item/device/radio/R in M) //Add something for the intercoms. - R.broadcasting = 0 - R.listening = 0 - - if (locate(/obj/item/device/flash, M)) - for(var/obj/item/device/flash/F in M) //Add something for the intercoms. - F.attack_self() - - if (locate(/obj/item/weapon/baton, M)) - for(var/obj/item/weapon/baton/B in M) //Add something for the intercoms. - B.charges = 0 - - if(locate(/obj/item/clothing/under/chameleon, M)) - for(var/obj/item/clothing/under/chameleon/C in M) //Add something for the intercoms. - M << "\red Your jumpsuit malfunctions" - C.name = "psychedelic" - C.desc = "Groovy!" - C.icon_state = "psyche" - C.color = "psyche" - spawn(200) - if(C) - C.name = "Black Jumpsuit" - C.icon_state = "bl_suit" - C.color = "black" - C.desc = null - - M << "\red BZZZT" - - - 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 ) - pulse2.icon = 'effects.dmi' - pulse2.icon_state = "empdisable" - pulse2.name = "emp sparks" - pulse2.anchored = 1 - pulse2.dir = pick(cardinal) - - spawn(10) - del(pulse2) - - if(istype(A, /obj/machinery/computer) && prob(20)) - A:set_broken() - - if(istype(A, /obj/machinery/firealarm) && prob(50)) - A:alarm() - - if(istype(A, /obj/machinery/power/smes)) - A:online = 0 - A:charging = 0 - A:output = 0 - A:charge -= 1e6 - if (A:charge < 0) - A:charge = 0 - - if(istype(A, /obj/machinery/power/apc)) - if(A:cell) - A:cell.use(1000) - A:lighting = 0 - A:equipment = 0 - A:environ = 0 - - if(istype(A, /obj/machinery/camera)) - A.icon_state = "cameraemp" - A:network = null - for(var/mob/living/silicon/ai/O in world) - if (O.current == A) - O.cancel_camera() - O << "Your connection to the camera has been lost." - - if(istype(A, /obj/machinery/clonepod)) - A:malfunction() - -////////CONTAINMENT FIELD - -/obj/machinery/containment_field - name = "Containment Field" - desc = "An energy field." - icon = 'singularity.dmi' - icon_state = "Contain_F" - anchored = 1 - density = 0 - unacidable = 1 - //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 - src.gen_secondary = B - if(A&&B) - src.dir = get_dir(B,A) - spawn(1) - 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(prob(50)) - gen_primary.power -= 1 - else - gen_secondary.power -= 1 - - -/obj/machinery/containment_field/proc/shock(mob/user as mob) - if(isnull(gen_primary)) - del(src) - return - if(isnull(gen_secondary)) - del(src) - return - - var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread - s.set_up(5, 1, user.loc) - s.start() - var/power = max(gen_primary.power,gen_secondary.power) - var/prot = 1 - var/shock_damage = 0 - if(power > 200) - shock_damage = min(rand(40,100),rand(40,100))*prot - else if(power > 120) - shock_damage = min(rand(30,90),rand(30,90))*prot - else if(power > 80) - shock_damage = min(rand(20,40),rand(20,40))*prot - 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.updatehealth() - 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) - src.gen_primary.power -= 3 - src.gen_secondary.power -= 3 - return - - -/obj/machinery/containment_field/HasProximity(atom/movable/AM as mob|obj) - if(istype(AM,/mob/living/carbon) && prob(50)) - shock(AM) - return /////EMITTER -/obj/machinery/emitter - name = "Emitter" - desc = "Shoots a high power laser when active" - icon = 'singularity.dmi' - icon_state = "Emitter" - anchored = 0 - density = 1 - req_access = list(access_engine) - var/active = 0 -// var/power = 20 - var/fire_delay = 100 -// var/HP = 20 - var/last_shot = 0 - var/shot_number = 0 - var/state = 0 - var/locked = 0 - - - -/obj/machinery/emitter/New() - ..() - return - -/obj/machinery/emitter/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(state == 3) - if(!src.locked || istype(user, /mob/living/silicon)) - src.add_fingerprint(user) - if(src.active==1) - src.active = 0 - user << "You turn off the [src]." - else - src.active = 1 - user << "You turn on the [src]." - src.shot_number = 0 - src.fire_delay = 100 - update_icon() - else - user << "The controls are locked!" - else - user << "The [src] needs to be firmly secured to the floor first." - return 1 - -/obj/machinery/emitter/process() - - if(stat & (NOPOWER|BROKEN)) - return - - if(src.state != 3) - src.active = 0 - return - - if(((src.last_shot + src.fire_delay) <= world.time) && (src.active == 1)) - src.last_shot = world.time - if(src.shot_number < 3) - src.fire_delay = 2 - src.shot_number ++ - else - 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, 'emitter.ogg', 75, 1) - - if(prob(35)) - var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread - s.set_up(5, 1, src) - s.start() - A.dir = src.dir - if(src.dir == 1)//Up - A.yo = 20 - A.xo = 0 - - else if(src.dir == 2)//Down - A.yo = -20 - A.xo = 0 - - else if(src.dir == 4)//Right - A.yo = 0 - A.xo = 20 - - else if(src.dir == 8)//Left - A.yo = 0 - A.xo = -20 - - else // Any other - A.yo = -20 - A.xo = 0 - - A.process() - ..() - - - -/obj/machinery/emitter/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/weapon/wrench)) - if(active) - user << "\red Turn off the [src] first." - return 1 - - else if(state == 0) - state = 1 - playsound(src.loc, 'Ratchet.ogg', 75, 1) - user.visible_message("[user.name] secures [src.name] to the floor.", \ - "You secure the external reinforcing bolts.", \ - "You hear ratchet") - src.anchored = 1 - - else if(state == 1) - state = 0 - playsound(src.loc, 'Ratchet.ogg', 75, 1) - user.visible_message("[user.name] unsecures [src.name] to the floor.", \ - "You undo the external reinforcing bolts.", \ - "You hear ratchet") - src.anchored = 0 - else - user << "\red [src] is welded to the floor!" - return 1 - - else if(istype(W, /obj/item/weapon/weldingtool) && W:welding) - if(active) - user << "\red Turn off the [src] first." - return 1 - if (state == 0) - user << "\red The [src] needs to be wrenched to the floor first." - return 1 - - if (W:get_fuel() < 2) //weldingtool always uses 1 additional unit of fuel - user << "\blue You need more welding fuel to complete this task." - return 1 - W:use_fuel(1) - W:eyecheck(user) - playsound(src.loc, 'Welder2.ogg', 50, 1) - - if(state == 1) - user.visible_message("[user.name] starts to weld [src.name] to the floor.", \ - "You start to weld the [src] to the floor.", \ - "You hear welding") - if (do_after(user,20)) - state = 3 - user << "You weld the [src] to the floor." - else - return 1 - - else if(state == 3) - user.visible_message("[user.name] starts to cut [src.name] from the floor.", \ - "You start to cut the [src] free from the floor.", \ - "You hear welding") - if (do_after(user,20)) - state = 1 - user << "You cut the [src] free from the floor." - else - return 1 - - 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 - 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 -/obj/machinery/power/collector_array - name = "Radiation Collector Array" - desc = "A device which uses Hawking Radiation and plasma to produce power." - icon = 'singularity.dmi' - 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 - var/obj/machinery/power/collector_control/CU = null - var/locked - - -/////////////ARRAY START - -/obj/machinery/power/collector_array/New() - ..() - spawn(5) - updateicon() - - -/obj/machinery/power/collector_array/proc/updateicon() - overlays = null - if(P) - overlays += image('singularity.dmi', "ptank") - if(stat & (NOPOWER|BROKEN)) - 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/proc/eject() - var/obj/item/weapon/tank/plasma/Z = src.P - if (!Z) - return - Z.loc = get_turf(src) - Z.layer = initial(Z.layer) - src.P = null - if (src.active) - src.active = 0 - updateicon_off() - else - updateicon() - if (CU) - CU.updatecons() - -/obj/machinery/power/collector_array/power_change() - ..() - updateicon() - -/obj/machinery/power/collector_array/process() - if(src.active == 1) - if(P) - if(P.air_contents.toxins <= 0) - P.air_contents.toxins = 0 - src.active = 0 - updateicon_off() - else - src.active = 0 - updateicon_off() - //use_power called from collector_array/process - -/obj/machinery/power/collector_array/attack_hand(mob/user as mob) - if (..()) - return - if(!src.anchored) - user << "\red The [src] needs to be secured to the floor first." - 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 - if(src.locked) - user << "\red The controls are locked." - return 1 - src.active = !src.active - if(src.active) - updateicon_on() - user.visible_message("[user.name] turns on the collector array.", \ - "You turn on the collector array.") - else - updateicon_off() - user.visible_message("[user.name] turns 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) - user << "The collector needs to be secured to the floor first." - return 1 - if(src.P) - user << "\red There appears to already be a plasma tank loaded!" - return 1 - src.P = W - W.loc = src - if (user.client) - user.client.screen -= W - user.u_equip(W) - updateicon() - if (CU) - CU.updatecons() - - else if(istype(W, /obj/item/weapon/crowbar)) - if(!P) - return 1 - if(active) - user << "\red Turn off the collector first." - return 1 - eject() - - else if(istype(W, /obj/item/weapon/wrench)) - if(active) - user << "\red Turn off the collector first." - return 1 - - playsound(src.loc, 'Ratchet.ogg', 75, 1) - src.anchored = !src.anchored - if(src.anchored == 1) - user.visible_message("[user.name] secures [src.name] reinforcing bolts to the floor.", \ - "You secure the collector reinforcing bolts.", \ - "You hear ratchet") - else - user.visible_message("[user.name] unsecures [src.name] reinforcing bolts from the floor.", \ - "You undo the external reinforcing bolts.", \ - "You hear ratchet") - for(var/obj/machinery/power/collector_control/myCC in orange(1,src)) - myCC.updatecons() - 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 - 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, 3) - eject() - return ..() - -/obj/machinery/power/collector_array/Del() - var/oldsrc = src - src = null - spawn(1) - for(var/obj/machinery/power/collector_control/myCC in orange(1,src)) - myCC.updatecons() - src = oldsrc - . = ..() - -////////////CONTROL UNIT - -/obj/machinery/power/collector_control - name = "Radiation Collector Control" - desc = "A device which uses Hawking Radiation and Plasma to produce power." - icon = 'singularity.dmi' - icon_state = "cu" - anchored = 1 - density = 1 - req_access = list(access_engine) - directwired = 1 - var/active = 0 - var/lastpower = 0 - var/obj/machinery/power/collector_array/CA[4] - var/list/obj/machinery/the_singularity/S - var/locked - -////////////CONTROL UNIT START - -/obj/machinery/power/collector_control/New() - ..() - spawn(10) - 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() - S = list() - for(var/obj/machinery/the_singularity/myS in orange(collector_control_range,src)) - S += myS - - for (var/ca_dir in list( WEST, EAST, NORTH, SOUTH ) /* cardinal*/ ) - var/obj/machinery/power/collector_array/newCA = locate() in get_step(src,ca_dir) - if (isnull(newCA)) - continue - if (!isnull(newCA.CU) && newCA.CU != src) - var/n = CA.Find(newCA) - if (n) - CA[n] = null - continue - if (!newCA.anchored || (!isnull(newCA.CU) && newCA.CU != src)) - var/n = CA.Find(newCA) - if (n) - CA[n] = null - newCA.CU = null - continue - if (add_ca(newCA)) - newCA.CU = src - updateicon() - //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)) - return - if(src.active == 0) - return - overlays += image('singularity.dmi', "cu on") - var/err = 0 - for (var/i = 1, i <= CA.len, 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") - if (myCA.P.air_contents.toxins <= 0) - err = 1 - else - err = 1 - if(err) - overlays += image('singularity.dmi', "cu n error") - 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() - ..() //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(!active) - return - var/power_a = 0 - var/power_s = 0 - var/power_p = 0 - - 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 (myCA.active && myP) - 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) - user << "\red The [src] needs to be secured to the floor first." - return 1 - if(src.locked) - user << "\red The controls are locked." - return 1 - src.active = !src.active - if(!src.active) - user << "You turn off the [src]." - src.lastpower = 0 - updateicon() - if(src.active) - user << "You turn on the [src]." - updatecons() - -/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." - else if(istype(W, /obj/item/weapon/wrench)) - if(active) - user << "\red Turn off the collector control first." - return 1 - - playsound(src.loc, 'Ratchet.ogg', 75, 1) - src.anchored = !src.anchored - if(src.anchored == 1) - user.visible_message("[user.name] secures [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] unsecures [src.name] to the floor.", \ - "You undo the [src] securing bolts.", \ - "You hear ratchet") - disconnect_from_network() - 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 - 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 -#define field_generator_max_power 250 -/obj/machinery/field_generator - name = "Field Generator" - desc = "Projects an energy field when active" - icon = 'singularity.dmi' - icon_state = "Field_Gen" - anchored = 0 - density = 1 - req_access = list(access_engine) - var/Varedit_start = 0 - var/Varpower = 0 - var/active = 0 - var/power = 20 - var/state = 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/update_icon() - if (!active) - icon_state = "Field_Gen" - return - var/level = 3 - switch (power) - if(0 to 60) - level = 1 - if(61 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_off() - src.active = 0 - spawn(1) - src.cleanup() - update_icon() - -/obj/machinery/field_generator/proc/turn_on() - src.active = 1 - warming_up = 1 - powerlevel = 0 - 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 || istype(user, /mob/living/silicon)) - if(src.active >= 1) - // src.active = 0 - // icon_state = "Field_Gen" - user << "You are unable to turn off the [src], wait till it powers down." - // src.cleanup() - return 1 - else - user.visible_message("[user.name] turns on [src.name]", \ - "You turn on the [src].", \ - "You hear heavy droning") - turn_on() - src.add_fingerprint(user) - else - user << "The controls are locked!" - else - user << "The [src] needs to be firmly secured to the floor first." - -/obj/machinery/field_generator/New() - ..() - fields = list() - return - -/obj/machinery/field_generator/process() - - if(src.Varedit_start == 1) - if(src.active == 0) - src.active = 1 - src.state = 3 - src.power = field_generator_max_power - src.anchored = 1 - src.warming_up = 1 - Varedit_start = 0 - - if(src.active == 1) - if(!src.state == 3 || !anchored) - turn_off() - return - spawn(1) - setup_field(1) - spawn(2) - setup_field(2) - spawn(3) - setup_field(4) - spawn(4) - setup_field(8) - src.active = 2 - if(src.power < 0) - src.power = 0 - if(src.power > field_generator_max_power) - src.power = field_generator_max_power - if(src.active >= 1) - src.power -= 1 - if(Varpower == 0) - 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!") - turn_off() - return - update_icon() - -/obj/machinery/field_generator/proc/setup_field(var/NSEW) - var/turf/T = src.loc - var/obj/machinery/field_generator/G - var/steps = 0 - - if(!NSEW)//Make sure its ran right - return - - for(var/dist = 0, dist <= 9, dist += 1) // checks out to 8 tiles away for another generator - T = get_step(T, NSEW) - steps += 1 - G = locate(/obj/machinery/field_generator) in T - if(!isnull(G)) - steps -= 1 - if(!G.active) - return - break - - if(isnull(G)) - return - - T = src.loc - - for(var/dist = 0, dist < steps, dist += 1) // creates each field tile - 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) && state!=3) - if(active) - user << "Turn off the [src] first." - return 1 - - if(state == 0) - state = 1 - playsound(src.loc, 'Ratchet.ogg', 75, 1) - user.visible_message("[user.name] secures [src.name] to the floor.", \ - "You secure the external reinforcing bolts to the floor.", \ - "You hear ratchet") - src.anchored = 1 - - else if(state == 1) - state = 0 - playsound(src.loc, 'Ratchet.ogg', 75, 1) - user.visible_message("[user.name] unsecures [src.name] reinforcing bolts from the floor.", \ - "You undo the external reinforcing bolts.", \ - "You hear ratchet") - src.anchored = 0 - - 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() < 2) - user << "\blue You need more welding fuel to complete this task." - return 1 - W:use_fuel(1) - W:eyecheck(user) - playsound(src.loc, 'Welder2.ogg', 50, 1) - - if(state == 1) - user.visible_message("[user.name] starts to weld [src.name] to the floor.", \ - "You start to weld the [src] to the floor.", \ - "You hear welding") - if (do_after(user,20)) - state = 3 - user << "You weld the field generator to the floor." - else - return 1 - - else if(state == 3) - user.visible_message("[user.name] starts to cut [src.name] free from the floor.", \ - "You start to cut the [src] free from the floor.", \ - "You hear welding") - if (do_after(user,20)) - state = 1 - user << "You cut the [src] free from the floor." - else - return 1 - - 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 - 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) - - if (flag == PROJECTILE_BULLET) - src.power -= 10 - /*else if (flag == PROJECTILE_MEDBULLET) - src.power -= 5*/ - else if (flag == PROJECTILE_WEAKBULLET) - src.power -= 1 - else if (flag == PROJECTILE_LASER) - src.power += 20 - else if (flag == PROJECTILE_TASER) - src.power += 3 - else - src.power -= 2 - update_icon() - return - -/obj/machinery/field_generator/proc/cleanup() - var/obj/machinery/field_generator/G - for (var/obj/machinery/containment_field/F in fields) - if (isnull(F)) - continue - G = (F.gen_primary == src) ? F.gen_secondary : F.gen_primary - if (G) - G.fields -= F - del(F) - fields = list() - -/obj/machinery/field_generator/Del() - src.cleanup() - ..() - diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index 3a6cdb86f1e..cdc59c7e672 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -11,7 +11,7 @@ name = "status display" anchored = 1 density = 1 - + power_usage = 250 var/mode = 1 // 0 = Blank // 1 = Shuttle timer // 2 = Arbitrary message(s) @@ -49,8 +49,6 @@ overlays = null return - use_power(200) - update() @@ -270,8 +268,6 @@ overlays = null return - use_power(200) - update() proc/update() diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm index 22e0048157f..5f00a96fe97 100644 --- a/code/game/machinery/turrets.dm +++ b/code/game/machinery/turrets.dm @@ -63,6 +63,7 @@ var/wasvalid = 0 var/lastfired = 0 var/shot_delay = 30 //3 seconds between shots + power_usage = 100 /obj/machinery/turretcover name = "pop-up turret cover" @@ -107,7 +108,6 @@ lastfired = world.time if (src.cover==null) src.cover = new /obj/machinery/turretcover(src.loc) - use_power(50) var/loc = src.loc if (istype(loc, /turf)) loc = loc:loc @@ -252,10 +252,10 @@ var/obj/beam/a_laser/A if (src.lasers) A = new /obj/beam/a_laser( loc ) - use_power(50) + use_power(500) else A = new /obj/bullet/electrode( loc ) - use_power(100) + use_power(200) if (!( istype(U, /turf) )) //A = null diff --git a/code/game/magic/cultist/runes.dm b/code/game/magic/cultist/runes.dm index d89232e2fcc..11b7c5e9ecb 100644 --- a/code/game/magic/cultist/runes.dm +++ b/code/game/magic/cultist/runes.dm @@ -127,7 +127,7 @@ var/list/sacrificed = list() M.say("Tok-lyr rqa'nap g'lt-ulotf!") cultist_count += 1 if(cultist_count >= 9) - var/obj/machinery/the_singularity/S = new /obj/machinery/the_singularity/(src.loc) + var/obj/machinery/singularity/S = new /obj/machinery/singularity/(src.loc) S.icon = 'magic_terror.dmi' S.name = "Tear in the Fabric of Reality" S.desc = "Your mind begins to bubble and ooze as it tries to comprehend what it sees." diff --git a/code/game/master_controller.dm b/code/game/master_controller.dm index 882eb9b405a..cf60b8e45e1 100644 --- a/code/game/master_controller.dm +++ b/code/game/master_controller.dm @@ -11,6 +11,7 @@ datum/controller/game_controller setup() if(master_controller && (master_controller != src)) del(src) + return //There can be only one master. if(!air_master) @@ -76,9 +77,7 @@ datum/controller/game_controller M.Life() else M.Life() - if (M && M.mind) //I think it will be better if author place this under mob/Life() - rastaf0 - if (M.mind.special_role == "Changeling") - M.chem_charges = between(0, (max((0.9 - (M.chem_charges / 50)), 0.1) + M.chem_charges), 50) + sleep(-1) for(var/datum/disease/D in active_diseases) @@ -86,6 +85,9 @@ datum/controller/game_controller for(var/obj/machinery/machine in machines) machine.process() + if(machine)//Testing this for now, might change it up later - Mport + if(machine.power_usage && machine.power_channel) + machine.use_power(machine.power_usage,machine.power_channel) sleep(-1) sleep(1) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index b57d2c5fd8e..01ed5937fc3 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -705,17 +705,15 @@ return else if(istype(W, /obj/item/weapon/weldingtool) && W:welding) - if (W:get_fuel() < 2) - user << "\blue You need more welding fuel to complete this task." + if (W:remove_fuel(1,user)) + if (src.internal_damage & MECHA_INT_TANK_BREACH) + src.internal_damage &= ~MECHA_INT_TANK_BREACH + user << "\blue You repair the damaged gas tank." + else return - if (src.internal_damage & MECHA_INT_TANK_BREACH) - src.internal_damage &= ~MECHA_INT_TANK_BREACH - user << "\blue You repair the damaged gas tank." - W:use_fuel(1) if(src.health 12) - user.eye_blurry += rand(3,6) - if(0) - usr << "\red Your eyes burn." - user.eye_stat += rand(2, 4) - if(user.eye_stat > 10) - user.eye_blurry += rand(4,10) - if(-1) - usr << "\red Your thermals intensify the welder's glow. Your eyes itch and burn severely." - user.eye_blurry += rand(12,20) - user.eye_stat += rand(12, 16) - if(user.eye_stat > 10 && safety < 2) - user << "\red Your eyes are really starting to hurt. This can't be good for you!" - if (prob(user.eye_stat - 25 + 1)) - user << "\red You go blind!" - user.sdisabilities |= 1 - else if (prob(user.eye_stat - 15 + 1)) - user << "\red You go blind!" - user.eye_blind = 5 - user.eye_blurry = 5 - user.disabilities |= 1 - spawn(100) - user.disabilities &= ~1 - -/obj/item/weapon/weldingtool/attack_self(mob/user as mob) - if(status > 1) return - src.welding = !( src.welding ) - if (src.welding) - if (get_fuel() <= 0) - user << "\blue Need more fuel!" - src.welding = 0 - return 0 - user << "\blue You will now weld when you attack." - src.force = 15 - src.damtype = "fire" - src.icon_state = "welder1" - processing_items.Add(src) - else - user << "\blue Not welding anymore." - src.force = 3 - src.damtype = "brute" - src.icon_state = "welder" - return - -/obj/item/weapon/weldingtool/process() - if(!welding) - processing_items.Remove(src) + New() + var/random_fuel = min(rand(10,20),max_fuel) + var/datum/reagents/R = new/datum/reagents(max_fuel) + reagents = R + R.my_atom = src + R.add_reagent("fuel", random_fuel) return - var/turf/location = src.loc - if(istype(location, /mob/)) - var/mob/M = location - if(M.l_hand == src || M.r_hand == src) - location = M.loc - if (istype(location, /turf)) - location.hotspot_expose(700, 5) + examine() + set src in usr + usr << text("\icon[] [] contains []/[] units of fuel!", src, src.name, get_fuel(),src.max_fuel ) + return + + + attackby(obj/item/W as obj, mob/user as mob) + if (istype(W,/obj/item/weapon/screwdriver)) + status = !status + if (status) + user << "\blue You resecure the welder." + else + user << "\blue The welder can now be attached and modified." + src.add_fingerprint(user) + else if (status == 1 && istype(W,/obj/item/stack/rods)) + var/obj/item/stack/rods/R = W + R.use(1) + var/obj/item/assembly/weld_rod/F = new /obj/item/assembly/weld_rod( user ) + src.loc = F + F.part1 = src + if (user.client) + user.client.screen -= src + if (user.r_hand == src) + user.u_equip(src) + user.r_hand = F + else + user.u_equip(src) + user.l_hand = F + R.master = F + src.master = F + src.layer = initial(src.layer) + user.u_equip(src) + if (user.client) + user.client.screen -= src + src.loc = F + F.part2 = W + F.layer = 20 + R.layer = 20 + F.loc = user + src.add_fingerprint(user) + else + ..() + + + process() + if(!welding) + processing_items.Remove(src) + return + var/turf/location = src.loc + if(istype(location, /mob/)) + var/mob/M = location + if(M.l_hand == src || M.r_hand == src) + location = get_turf(M) + if (istype(location, /turf)) + location.hotspot_expose(700, 5) + if(prob(20))//Welders left on now use up fuel, but lets not have them run out quite that fast + remove_fuel(1) + + + afterattack(obj/O as obj, mob/user as mob) + if (istype(O, /obj/reagent_dispensers/fueltank) && get_dist(src,O) <= 1 && !src.welding) + O.reagents.trans_to(src, max_fuel) + user << "\blue Welder refueled" + playsound(src.loc, 'refill.ogg', 50, 1, -6) + return + else if (istype(O, /obj/reagent_dispensers/fueltank) && get_dist(src,O) <= 1 && src.welding) + message_admins("[key_name_admin(user)] triggered a fueltank explosion.") + user << "\red That was stupid of you." + explosion(O.loc,-1,0,2) + if(O) + del(O) + return + if (src.welding) + remove_fuel(1) + var/turf/location = get_turf(user) + if (istype(location, /turf)) + location.hotspot_expose(700, 50, 1) + return + + + attack_self(mob/user as mob) + toggle() + return + + + proc + + +///GET prop for fuel + get_fuel() + return reagents.get_reagent_amount("fuel") + + +///SET prop for fuel +///Will also turn it off if it is out of fuel +///The mob argument is not needed but if included will call eyecheck() on it if the welder is on. + remove_fuel(var/amount = 1, var/mob/M = null) + if(!welding || !check_status()) + return 0 + if(get_fuel() >= amount) + reagents.remove_reagent("fuel", amount) + check_status() + if(M) + eyecheck()//TODO:eyecheck should really be in mob not here + return 1 + else + if(M) + M << "\blue You need more welding fuel to complete this task." + return 0 + + +///Quick check to see if we even have any fuel and should shut off +///This could use a better name + check_status() + if((get_fuel() <= 0) && welding) + toggle(1) + return 0 + return 1 + + +//toggles the welder off and on + toggle(var/message = 0) + if(status > 1) return + src.welding = !( src.welding ) + if (src.welding) + if (remove_fuel(1)) + usr << "\blue You switch the [src] on." + src.force = 15 + src.damtype = "fire" + src.icon_state = "welder1" + processing_items.Add(src) + else + usr << "\blue Need more fuel!" + src.welding = 0 + return + else + if(!message) + usr << "\blue You switch the [src] off." + else + usr << "\blue The [src] shuts off!" + src.force = 3 + src.damtype = "brute" + src.icon_state = "welder" + src.welding = 0 + + + eyecheck(mob/user as mob)//TODO:Move this over to /mob/ where it should be + //check eye protection + if(!ishuman() && !ismonkey()) + return 1 + var/safety = 0 + if (istype(user, /mob/living/carbon/human)) + if (istype(user:head, /obj/item/clothing/head/helmet/welding) || istype(user:head, /obj/item/clothing/head/helmet/space)) + safety = 2 + else if (istype(user:glasses, /obj/item/clothing/glasses/sunglasses)) + safety = 1 + else if (istype(user:glasses, /obj/item/clothing/glasses/thermal)) + safety = -1 + else + safety = 0 + switch(safety) + if(1) + usr << "\red Your eyes sting a little." + user.eye_stat += rand(1, 2) + if(user.eye_stat > 12) + user.eye_blurry += rand(3,6) + if(0) + usr << "\red Your eyes burn." + user.eye_stat += rand(2, 4) + if(user.eye_stat > 10) + user.eye_blurry += rand(4,10) + if(-1) + usr << "\red Your thermals intensify the welder's glow. Your eyes itch and burn severely." + user.eye_blurry += rand(12,20) + user.eye_stat += rand(12, 16) + if(user.eye_stat > 10 && safety < 2) + user << "\red Your eyes are really starting to hurt. This can't be good for you!" + if (prob(user.eye_stat - 25 + 1)) + user << "\red You go blind!" + user.sdisabilities |= 1 + else if (prob(user.eye_stat - 15 + 1)) + user << "\red You go blind!" + user.eye_blind = 5 + user.eye_blurry = 5 + user.disabilities |= 1 + spawn(100) + user.disabilities &= ~1 + return + + + +/obj/item/weapon/weldingtool/largetank + name = "weldingtool" + icon = 'items.dmi' + icon_state = "welder" + max_fuel = 40 \ No newline at end of file diff --git a/code/game/objects/stacks/metal.dm b/code/game/objects/stacks/metal.dm index b179f63dede..60e6ce8a5d2 100644 --- a/code/game/objects/stacks/metal.dm +++ b/code/game/objects/stacks/metal.dm @@ -15,21 +15,17 @@ FLOOR TILES if(amount < 2) user << "\red You need at least two rods to do this." return - if (W:get_fuel() < 3) - user << "\red You need more welding fuel to complete this task." - return - W:eyecheck(user) - W:use_fuel(2) - var/obj/item/stack/sheet/metal/new_item = new(usr.loc) - new_item.add_to_stacks(usr) - for (var/mob/M in viewers(src)) - M.show_message("\red [src] is shaped into metal by [user.name] with the weldingtool.", 3, "\red You hear welding.", 2) - var/obj/item/stack/rods/R = src - src = null - var/replace = (user.get_inactive_hand()==R) - R.use(2) - if (!R && replace) - user.put_in_hand(new_item) + if(W:remove_fuel(2,user)) + var/obj/item/stack/sheet/metal/new_item = new(usr.loc) + new_item.add_to_stacks(usr) + for (var/mob/M in viewers(src)) + M.show_message("\red [src] is shaped into metal by [user.name] with the weldingtool.", 3, "\red You hear welding.", 2) + var/obj/item/stack/rods/R = src + src = null + var/replace = (user.get_inactive_hand()==R) + R.use(2) + if (!R && replace) + user.put_in_hand(new_item) return ..() diff --git a/code/game/turf.dm b/code/game/turf.dm index 9cc7ca5266e..da800541e47 100644 --- a/code/game/turf.dm +++ b/code/game/turf.dm @@ -325,8 +325,7 @@ return if (istype(W, /obj/item/weapon/weldingtool) && W:welding) - W:eyecheck(user) - var/turf/T = user.loc + var/turf/T = get_turf(user) if (!( istype(T, /turf) )) return @@ -346,19 +345,18 @@ spawn(100) del(O) return - if (W:get_fuel() < 5) + if (W:remove_fuel(5,user)) + user << "\blue Now disassembling the outer wall plating." + playsound(src.loc, 'Welder.ogg', 100, 1) + sleep(100) + if (istype(src, /turf/simulated/wall)) + if ((get_turf(user) == T && user.equipped() == W)) + user << "\blue You disassembled the outer wall plating." + dismantle_wall() + else user << "\blue You need more welding fuel to complete this task." return - W:use_fuel(5) - user << "\blue Now disassembling the outer wall plating." - playsound(src.loc, 'Welder.ogg', 100, 1) - - sleep(100) - if (istype(src, /turf/simulated/wall)) - if ((user.loc == T && user.equipped() == W)) - user << "\blue You disassembled the outer wall plating." - dismantle_wall() else if(istype(W,/obj/item/apc_frame)) var/obj/item/apc_frame/AH = W AH.try_build(src) @@ -809,7 +807,7 @@ turf/simulated/floor/proc/update_icon() var/list/y_arr if(src.x <= 1) - if(istype(A, /obj/meteor)) + if(istype(A, /obj/meteor)||istype(A, /obj/space_dust)) del(A) return @@ -884,7 +882,7 @@ turf/simulated/floor/proc/update_icon() A.loc.Entered(A) else if (src.y >= world.maxy) - if(istype(A, /obj/meteor)) + if(istype(A, /obj/meteor)||istype(A, /obj/space_dust)) del(A) return var/list/cur_pos = src.get_global_map_pos() @@ -914,7 +912,7 @@ turf/simulated/floor/proc/update_icon() if (src.x <= 2) if(prob(50)) - if(istype(A, /obj/meteor)) + if(istype(A, /obj/meteor)||istype(A, /obj/space_dust)) del(A) return if(istype(A,/mob/living/carbon/human)) @@ -935,7 +933,7 @@ turf/simulated/floor/proc/update_icon() if ((A && A.loc)) A.loc.Entered(A) else - if(istype(A, /obj/meteor)) + if(istype(A, /obj/meteor)||istype(A, /obj/space_dust)) del(A) return if(istype(A,/mob/living/carbon/human)) @@ -957,7 +955,7 @@ turf/simulated/floor/proc/update_icon() A.loc.Entered(A) else if (A.x >= (world.maxx - 1)) if(prob(50)) - if(istype(A, /obj/meteor)) + if(istype(A, /obj/meteor)||istype(A, /obj/space_dust)) del(A) return if(istype(A,/mob/living/carbon/human)) @@ -978,7 +976,7 @@ turf/simulated/floor/proc/update_icon() if ((A && A.loc)) A.loc.Entered(A) else - if(istype(A, /obj/meteor)) + if(istype(A, /obj/meteor)||istype(A, /obj/space_dust)) del(A) return if(istype(A,/mob/living/carbon/human)) @@ -1000,7 +998,7 @@ turf/simulated/floor/proc/update_icon() A.loc.Entered(A) else if (src.y <= 2) if(prob(50)) - if(istype(A, /obj/meteor)) + if(istype(A, /obj/meteor)||istype(A, /obj/space_dust)) del(A) return if(istype(A,/mob/living/carbon/human)) @@ -1021,7 +1019,7 @@ turf/simulated/floor/proc/update_icon() if ((A && A.loc)) A.loc.Entered(A) else - if(istype(A, /obj/meteor)) + if(istype(A, /obj/meteor)||istype(A, /obj/space_dust)) del(A) return if(istype(A,/mob/living/carbon/human)) @@ -1044,7 +1042,7 @@ turf/simulated/floor/proc/update_icon() else if (A.y >= (world.maxy - 1)) if(prob(50)) - if(istype(A, /obj/meteor)) + if(istype(A, /obj/meteor)||istype(A, /obj/space_dust)) del(A) return if(istype(A,/mob/living/carbon/human)) @@ -1065,7 +1063,7 @@ turf/simulated/floor/proc/update_icon() if ((A && A.loc)) A.loc.Entered(A) else - if(istype(A, /obj/meteor)) + if(istype(A, /obj/meteor)||istype(A, /obj/space_dust)) del(A) return if(istype(A,/mob/living/carbon/human)) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 30565accaed..d20a73012bb 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -45,7 +45,7 @@ src.verbs += /proc/toggle_adminmsg src.verbs += /client/proc/triple_ai //triple AIs~ --NEO - + src.verbs += /client/proc/cmd_mass_modify_object_variables // Admin "must have" src.verbs += /client/proc/cmd_admin_list_occ src.verbs += /client/proc/cmd_admin_mute @@ -81,7 +81,7 @@ src.verbs += /proc/givetestverbs src.verbs += /obj/admins/proc/spawn_atom src.verbs += /obj/admins/proc/toggletintedweldhelmets - + // Admin helpers src.verbs += /client/proc/cmd_admin_attack_log @@ -171,7 +171,7 @@ src.verbs += /obj/admins/proc/voteres //toggle votes src.verbs += /client/proc/deadchat //toggles deadchat src.verbs += /proc/toggle_adminmsg - + src.verbs += /client/proc/cmd_mass_modify_object_variables // Admin "must have" src.verbs += /client/proc/cmd_admin_list_occ src.verbs += /client/proc/cmd_admin_mute @@ -1093,7 +1093,7 @@ src.verbs -= /client/proc/cmd_admin_prison src.verbs -= /obj/admins/proc/unprison src.verbs -= /proc/togglebuildmode - + src.verbs -= /client/proc/cmd_mass_modify_object_variables // Unnecessary commands src.verbs -= /client/proc/funbutton src.verbs -= /client/proc/make_sound // -- TLE diff --git a/code/modules/admin/verbs/massmodvar.dm b/code/modules/admin/verbs/massmodvar.dm new file mode 100644 index 00000000000..9d7bd924d69 --- /dev/null +++ b/code/modules/admin/verbs/massmodvar.dm @@ -0,0 +1,223 @@ +/client/proc/cmd_mass_modify_object_variables(obj/O as obj|mob|turf|area in world) + set category = "Debug" + set name = "Mass Edit Variables" + set desc="(target) Edit all instances of a target item's variables" + src.massmodify_variables(O) + + +/client/proc/massmodify_variables(var/atom/O) + var/list/locked = list("vars", "key", "ckey", "client") + + if(!src.authenticated || !src.holder) + src << "Only administrators may use this command." + return + + var/list/names = list() + for (var/V in O.vars) + names += V + + names = sortList(names) + + var/variable = input("Which var?","Var") as null|anything in names + if(!variable) + return + var/default + var/var_value = O.vars[variable] + var/dir + + if (locked.Find(variable) && !(src.holder.rank in list("Host", "Coder"))) + return + + if(isnull(var_value)) + usr << "Unable to determine variable type." + + else if(isnum(var_value)) + usr << "Variable appears to be NUM." + default = "num" + dir = 1 + + else if(istext(var_value)) + usr << "Variable appears to be TEXT." + default = "text" + + else if(isloc(var_value)) + usr << "Variable appears to be REFERENCE." + default = "reference" + + else if(isicon(var_value)) + usr << "Variable appears to be ICON." + var_value = "\icon[var_value]" + default = "icon" + + else if(istype(var_value,/atom) || istype(var_value,/datum)) + usr << "Variable appears to be TYPE." + default = "type" + + else if(istype(var_value,/list)) + usr << "Variable appears to be LIST." + default = "list" + + else if(istype(var_value,/client)) + usr << "Variable appears to be CLIENT." + default = "cancel" + + else + usr << "Variable appears to be FILE." + default = "file" + + usr << "Variable contains: [var_value]" + if(dir) + switch(var_value) + if(1) + dir = "NORTH" + if(2) + dir = "SOUTH" + if(4) + dir = "EAST" + if(8) + dir = "WEST" + if(5) + dir = "NORTHEAST" + if(6) + dir = "SOUTHEAST" + if(9) + dir = "NORTHWEST" + if(10) + dir = "SOUTHWEST" + else + dir = null + if(dir) + usr << "If a direction, direction is: [dir]" + + var/class = input("What kind of variable?","Variable Type",default) as null|anything in list("text", + "num","type","icon","file","edit referenced object","restore to default") + + if(!class) + return + + var/original_name + + if (!istype(O, /atom)) + original_name = "\ref[O] ([O])" + else + original_name = O:name + + switch(class) + + if("restore to default") + O.vars[variable] = initial(O.vars[variable]) + + if(istype(O, /mob)) + for(var/mob/M in world) + if (M.type == O.type) + M.vars[variable] = O.vars[variable] + + else if(istype(O, /obj)) + for(var/obj/A in world) + if (A.type == O.type) + A.vars[variable] = O.vars[variable] + + else if(istype(O, /turf)) + for(var/turf/A in world) + if (A.type == O.type) + A.vars[variable] = O.vars[variable] + + if("edit referenced object") + return .(O.vars[variable]) + + if("text") + O.vars[variable] = input("Enter new text:","Text",\ + O.vars[variable]) as text + + if(istype(O, /mob)) + for(var/mob/M in world) + if (M.type == O.type) + M.vars[variable] = O.vars[variable] + + else if(istype(O, /obj)) + for(var/obj/A in world) + if (A.type == O.type) + A.vars[variable] = O.vars[variable] + + else if(istype(O, /turf)) + for(var/turf/A in world) + if (A.type == O.type) + A.vars[variable] = O.vars[variable] + + if("num") + O.vars[variable] = input("Enter new number:","Num",\ + O.vars[variable]) as num + + if(istype(O, /mob)) + for(var/mob/M in world) + if (M.type == O.type) + M.vars[variable] = O.vars[variable] + + else if(istype(O, /obj)) + for(var/obj/A in world) + if (A.type == O.type) + A.vars[variable] = O.vars[variable] + + else if(istype(O, /turf)) + for(var/turf/A in world) + if (A.type == O.type) + A.vars[variable] = O.vars[variable] + + if("type") + O.vars[variable] = input("Enter type:","Type",O.vars[variable]) \ + in typesof(/obj,/mob,/area,/turf) + + if(istype(O, /mob)) + for(var/mob/M in world) + if (M.type == O.type) + M.vars[variable] = O.vars[variable] + + else if(istype(O, /obj)) + for(var/obj/A in world) + if (A.type == O.type) + A.vars[variable] = O.vars[variable] + + else if(istype(O, /turf)) + for(var/turf/A in world) + if (A.type == O.type) + A.vars[variable] = O.vars[variable] + + if("file") + O.vars[variable] = input("Pick file:","File",O.vars[variable]) \ + as file + + if(istype(O, /mob)) + for(var/mob/M in world) + if (M.type == O.type) + M.vars[variable] = O.vars[variable] + + else if(istype(O.type, /obj)) + for(var/obj/A in world) + if (A.type == O.type) + A.vars[variable] = O.vars[variable] + + else if(istype(O.type, /turf)) + for(var/turf/A in world) + if (A.type == O.type) + A.vars[variable] = O.vars[variable] + + if("icon") + O.vars[variable] = input("Pick icon:","Icon",O.vars[variable]) \ + as icon + if(istype(O, /mob)) + for(var/mob/M in world) + if (M.type == O.type) + M.vars[variable] = O.vars[variable] + + else if(istype(O, /obj)) + for(var/obj/A in world) + if (A.type == O.type) + A.vars[variable] = O.vars[variable] + + else if(istype(O, /turf)) + for(var/turf/A in world) + if (A.type == O.type) + A.vars[variable] = O.vars[variable] + + log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]") + message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]", 1) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 96967aaa0d9..63205e26303 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -41,6 +41,9 @@ //Disease Check handle_virus_updates() + //Changeling things + handle_changeling() + //Handle temperature/pressure differences between body and environment handle_environment(environment) @@ -720,7 +723,7 @@ if(!seer) src.see_invisible = 0 - if (istype(src.head, /obj/item/clothing/head/helmet/welding) && tinted_weldhelh) + if (istype(src.head, /obj/item/clothing/head/helmet/welding) && tinted_weldhelh) src.see_in_dark = 0 if (src.sleep) src.sleep.icon_state = text("sleep[]", src.sleeping) @@ -866,6 +869,13 @@ if(!M.nodamage) M.bruteloss += 5 src.nutrition += 10 + + handle_changeling() + if (mind) + if (mind.special_role == "Changeling") + src.chem_charges = between(0, (max((0.9 - (chem_charges / 50)), 0.1) + chem_charges), 50) + + /* // Commented out so hunger system won't be such shock // Damage and effects from not eating diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index 61f549ac071..0d3dbfaeee0 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -40,6 +40,9 @@ //Disease Check handle_virus_updates() + //Changeling things + handle_changeling() + //Handle temperature/pressure differences between body and environment if(environment) // More error checking -- TLE handle_environment(environment) @@ -564,4 +567,9 @@ src.drop_item() src.density = 1 else - src.density = !src.lying \ No newline at end of file + src.density = !src.lying + + handle_changeling() + if (mind) + if (mind.special_role == "Changeling") + src.chem_charges = between(0, (max((0.9 - (chem_charges / 50)), 0.1) + chem_charges), 50) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 2adb9e077b7..e7c4fc0a29d 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -351,9 +351,10 @@ statpanel("Status") stat(null, text("Intent: []", src.a_intent)) stat(null, text("Move Mode: []", src.m_intent)) - if (src.client.statpanel == "Status") - if (src.mind.special_role == "Changeling") - stat("Chemical Storage", src.chem_charges) + if(client && mind) + if (src.client.statpanel == "Status") + if (src.mind.special_role == "Changeling") + stat("Chemical Storage", src.chem_charges) return /mob/living/carbon/monkey/update_clothing() diff --git a/code/modules/mob/living/silicon/hivebot/hivebot.dm b/code/modules/mob/living/silicon/hivebot/hivebot.dm index f200313cf58..11111ea9205 100644 --- a/code/modules/mob/living/silicon/hivebot/hivebot.dm +++ b/code/modules/mob/living/silicon/hivebot/hivebot.dm @@ -185,18 +185,16 @@ /mob/living/silicon/hivebot/attackby(obj/item/weapon/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/weldingtool) && W:welding) - if (W:get_fuel() > 2) - W:use_fuel(1) + if (W:remove_fuel(4)) + src.bruteloss -= 30 + if(src.bruteloss < 0) src.bruteloss = 0 + src.updatehealth() + src.add_fingerprint(user) + for(var/mob/O in viewers(user, null)) + O.show_message(text("\red [user] has fixed some of the dents on [src]!"), 1) else user << "Need more welding fuel!" return - src.bruteloss -= 30 - if(src.bruteloss < 0) src.bruteloss = 0 - src.updatehealth() - src.add_fingerprint(user) - for(var/mob/O in viewers(user, null)) - O.show_message(text("\red [user] has fixed some of the dents on [src]!"), 1) - /mob/living/silicon/hivebot/attack_alien(mob/living/carbon/alien/humanoid/M as mob) diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index 4c063665c3e..685460a0700 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -281,6 +281,7 @@ process_locks() if(weapon_lock) + src.module_active = null src.module_state_1 = null src.module_state_2 = null src.module_state_3 = null diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index f4b5d58ad9e..0c5b45226ed 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -348,17 +348,17 @@ /mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob) if (istype(W, /obj/item/weapon/weldingtool) && W:welding) - if (W:get_fuel() > 2) - W:use_fuel(1) + if (W:remove_fuel(4)) + src.bruteloss -= 30 + if(src.bruteloss < 0) src.bruteloss = 0 + src.updatehealth() + src.add_fingerprint(user) + for(var/mob/O in viewers(user, null)) + O.show_message(text("\red [user] has fixed some of the dents on [src]!"), 1) else user << "Need more welding fuel!" return - src.bruteloss -= 30 - if(src.bruteloss < 0) src.bruteloss = 0 - src.updatehealth() - src.add_fingerprint(user) - for(var/mob/O in viewers(user, null)) - O.show_message(text("\red [user] has fixed some of the dents on [src]!"), 1) + else if(istype(W, /obj/item/weapon/cable_coil) && wiresexposed) var/obj/item/weapon/cable_coil/coil = W diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index cf96280f1b7..f6a00fdef60 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -45,7 +45,7 @@ ..() src.modules += new /obj/item/weapon/extinguisher(src) src.modules += new /obj/item/weapon/screwdriver(src) - src.modules += new /obj/item/weapon/weldingtool(src) + src.modules += new /obj/item/weapon/weldingtool/largetank(src) src.modules += new /obj/item/weapon/wrench(src) src.modules += new /obj/item/device/analyzer(src) src.modules += new /obj/item/device/flashlight(src) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 8c1a21dc7d2..9a2ed6f0672 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1381,7 +1381,7 @@ namecounts[name] = 1 creatures[name] = D - for (var/obj/machinery/the_singularity/S in world) + for (var/obj/machinery/singularity/S in world) var/name = "Singularity" if (name in names) namecounts[name]++ diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 2c8fd784cf6..60e974c5b6a 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -3,6 +3,7 @@ mob/new_player var/datum/preferences/preferences var/ready = 0 + var/spawning = 0 invisibility = 101 @@ -80,6 +81,8 @@ mob/new_player Logout() ready = 0 ..() + if(!spawning) + del(src) return verb @@ -142,6 +145,8 @@ mob/new_player if(alert(src,"Are you sure you wish to observe? You will not be able to play this round!","Player Setup","Yes","No") == "Yes") var/mob/dead/observer/observer = new() + src.spawning = 1 + close_spawn_windows() var/obj/O = locate("landmark*Observer-Start") src << "\blue Now teleporting." @@ -397,6 +402,7 @@ mob/new_player src << browse(dat, "window=latechoices;size=300x640;can_close=0") proc/create_character() + src.spawning = 1 var/mob/living/carbon/human/new_character = new(src.loc) close_spawn_windows() diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 6bcc111a2ae..e5f83a4d04e 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -366,23 +366,23 @@ user << "\blue You need more welding fuel to complete this task." return user << "You start welding APC frame..." - W:use_fuel(2) - W:eyecheck(user) - playsound(src.loc, 'Welder.ogg', 50, 1) - if(do_after(user, 50)) - if (emagged || malfhack || (stat & BROKEN) || opened==2) - new /obj/item/stack/sheet/metal(loc) - user.visible_message(\ - "\red [src] has been cut apart by [user.name] with the weldingtool.",\ - "You disassembled brocken APC frame.",\ - "\red You hear welding.") - else - new /obj/item/apc_frame(loc) - user.visible_message(\ - "\red [src] has been cut from the wall by [user.name] with the weldingtool.",\ - "You cut APC frame from the wall.",\ - "\red You hear welding.") - del(src) + if(W:remove_fuel(2)) + playsound(src.loc, 'Welder.ogg', 50, 1) + if(do_after(user, 50)) + if (emagged || malfhack || (stat & BROKEN) || opened==2) + new /obj/item/stack/sheet/metal(loc) + user.visible_message(\ + "\red [src] has been cut apart by [user.name] with the weldingtool.",\ + "You disassembled brocken APC frame.",\ + "\red You hear welding.") + else + new /obj/item/apc_frame(loc) + user.visible_message(\ + "\red [src] has been cut from the wall by [user.name] with the weldingtool.",\ + "You cut APC frame from the wall.",\ + "\red You hear welding.") + del(src) + return else if (istype(W, /obj/item/apc_frame) && opened && emagged) emagged = 0 if (opened==2) @@ -810,7 +810,7 @@ else malfai << "Hack complete. The APC is now under your exclusive control. Unable to fuse interface due to insufficient cell charge." else - malfai << "Hack complete. The APC is now under your exclusive control. Unable to fuse interface due to lack of cell do discharge." + malfai << "Hack complete. The APC is now under your exclusive control. Unable to fuse interface due to lack of cell to discharge." src.updateDialog() diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 5623de11cdf..7016c6878d4 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -19,7 +19,10 @@ desc = "A lighting fixture." anchored = 1 layer = 5 // They were appearing under mobs which is a little weird - Ostaf + power_usage = 0 + power_channel = LIGHT //Lights are calc'd via area so they dont need to be in the machine list var/on = 0 // 1 if on, 0 if off + var/on_gs = 0 var/brightness = 8 // luminosity when on, also used in power calculation var/status = LIGHT_OK // LIGHT_OK, _EMPTY, _BURNED or _BROKEN @@ -63,9 +66,23 @@ // create a new lighting fixture /obj/machinery/light/New() ..() + + switch(fitting) + if("tube") + brightness = rand(6,9) + if("bulb") + brightness = rand(3,6) spawn(1) update() +/obj/machinery/light/Del() + var/area/A = get_area(src) + if(A) + on = 0 +// A.update_lights() + ..() + + // update the icon_state and luminosity of the light depending on its state /obj/machinery/light/proc/update() @@ -100,7 +117,12 @@ icon_state = "[base_state]-burned" on = 0 sd_SetLuminosity(0) - + power_usage = (luminosity * 20) + if(on != on_gs) + on_gs = on +// var/area/A = get_area(src) +// if(A) +// A.update_lights() // attempt to set the light's on/off status @@ -129,8 +151,6 @@ /obj/machinery/light/attackby(obj/item/W, mob/user) - if (istype(user, /mob/living/silicon)) - return // attempt to insert light if(istype(W, /obj/item/weapon/light)) @@ -145,6 +165,7 @@ user << "You insert the [L.name]." switchcount = L.switchcount rigged = L.rigged + brightness = L.brightness del(L) on = has_power() @@ -255,6 +276,7 @@ var/obj/item/weapon/light/L = new light_type() L.status = status L.rigged = rigged + L.brightness = src.brightness L.loc = usr L.layer = 20 if(user.hand) @@ -318,8 +340,9 @@ #define LIGHTING_POWER_FACTOR 20 //20W per unit luminosity /obj/machinery/light/process() - if(on) - use_power(luminosity * LIGHTING_POWER_FACTOR, LIGHT) + return +// if(on) +// use_power(luminosity * LIGHTING_POWER_FACTOR, LIGHT) // called when area power state changes @@ -402,6 +425,7 @@ var/switchcount = 0 // number of times switched m_amt = 60 var/rigged = 0 // true if rigged to explode + var/brightness = 2 //how much light it gives off /obj/item/weapon/light/tube name = "light tube" @@ -410,6 +434,7 @@ base_state = "ltube" item_state = "c_tube" g_amt = 200 + brightness = 8 /obj/item/weapon/light/bulb name = "light bulb" @@ -418,6 +443,7 @@ base_state = "lbulb" item_state = "contvapour" g_amt = 100 + brightness = 5 // update the icon state and description of the light /obj/item/weapon/light @@ -436,6 +462,11 @@ /obj/item/weapon/light/New() ..() + switch(name) + if("light tube") + brightness = rand(6,9) + if("light bulb") + brightness = rand(4,6) update() diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm new file mode 100644 index 00000000000..6c84e384659 --- /dev/null +++ b/code/modules/power/singularity/collector.dm @@ -0,0 +1,83 @@ + +/obj/machinery/power/rad_collector + name = "Radiation Collector Array" + desc = "A device which uses Hawking Radiation and plasma to produce power." + icon = 'singularity.dmi' + icon_state = "collector" + anchored = 1 + density = 1 + directwired = 1 + var + obj/item/weapon/tank/plasma/P = null + last_power = 0 + + process() + if(P) + if(P.air_contents.toxins <= 0) + P.air_contents.toxins = 0 + eject() + else + P.air_contents.toxins -= 0.001 + return + + + attackby(obj/item/W, mob/user) + if(istype(W, /obj/item/device/analyzer)) + user << "\blue The [W.name] detects that [last_power]W were recently produced." + return 1 + if(istype(W, /obj/item/weapon/tank/plasma)) + if(!src.anchored) + user << "The [src] needs to be secured to the floor first." + return 1 + if(src.P) + user << "\red There appears to already be a plasma tank loaded!" + return 1 + icon_state = "collector +p" + src.P = W + W.loc = src + if (user.client) + user.client.screen -= W + user.u_equip(W) + else if(istype(W, /obj/item/weapon/crowbar)) + if(P) + eject() + return 1 + else if(istype(W, /obj/item/weapon/wrench)) + if(P) + user << "\red Remove the plasma tank first." + return 1 + playsound(src.loc, 'Ratchet.ogg', 75, 1) + src.anchored = !src.anchored + user.visible_message("[user.name] [anchored? "secures":"unsecures"] the [src.name].", \ + "You [anchored? "secure":"undo"] the external bolts.", \ + "You hear ratchet") + else + ..() + return 1 + + + ex_act(severity) + switch(severity) + if(2, 3) + eject() + return ..() + + + proc + eject() + var/obj/item/weapon/tank/plasma/Z = src.P + if (!Z) + return + Z.loc = get_turf(src) + Z.layer = initial(Z.layer) + src.P = null + icon_state = "collector" + + receive_pulse(var/pulse_strength) + if(P) + var/power_produced = 0 + power_produced = P.air_contents.toxins*pulse_strength*20 + add_avail(power_produced) + last_power = power_produced + return + return \ No newline at end of file diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm new file mode 100644 index 00000000000..c1737d906d9 --- /dev/null +++ b/code/modules/power/singularity/containment_field.dm @@ -0,0 +1,75 @@ + +/obj/machinery/containment_field + name = "Containment Field" + desc = "An energy field." + icon = 'singularity.dmi' + icon_state = "Contain_F" + anchored = 1 + density = 0 + unacidable = 1 + power_usage = 0 + + New() + spawn(1) + src.sd_SetLuminosity(5) + + + attack_hand(mob/user as mob) + if(get_dist(src, user) > 1) + return 0 + else + shock(user) + return 1 + + + blob_act() + return + + + ex_act(severity) + return + + + HasProximity(atom/movable/AM as mob|obj) + if(istype(AM,/mob/living/silicon) && prob(40)) + shock(AM) + return + if(istype(AM,/mob/living/carbon) && prob(50)) + shock(AM) + return + + + proc + shock(mob/user as mob) + if(iscarbon(user)) + var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread + s.set_up(5, 1, user.loc) + s.start() + var/shock_damage = min(rand(30,40),rand(30,40)) + user.burn_skin(shock_damage) + user.updatehealth() + 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") + var/stun = min(shock_damage, 15) + if(user.stunned < shock_damage) user.stunned = stun + if(user.weakened < 10) user.weakened = 10 + user.updatehealth() + var/atom/target = get_edge_target_turf(user, get_dir(src, get_step_away(user, src))) + user.throw_at(target, 200, 4) + return + else if(issilicon(user)) + var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread + s.set_up(5, 1, user.loc) + s.start() + var/shock_damage = rand(15,30) + user.fireloss += shock_damage + user.updatehealth() + user.visible_message("\red [user.name] was shocked by the [src.name]!", \ + "\red Energy pulse detected, system damaged!", \ + "\red You hear an electrical crack") + if(prob(20)) + if(user.stunned < 2) + user.stunned = 2 + return + return diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm new file mode 100644 index 00000000000..4865a54b167 --- /dev/null +++ b/code/modules/power/singularity/emitter.dm @@ -0,0 +1,179 @@ +/obj/machinery/emitter + name = "Emitter" + desc = "A heavy duty industrial laser" + icon = 'singularity.dmi' + icon_state = "Emitter" + anchored = 0 + density = 1 + req_access = list(access_engine) + var/active = 0 + var/fire_delay = 100 + var/last_shot = 0 + var/shot_number = 0 + var/state = 0 + var/locked = 0 + power_usage = 0 + + +/obj/machinery/emitter/New() + ..() + return + + +/obj/machinery/emitter/update_icon() + if (active && !(stat & (NOPOWER|BROKEN))) + icon_state = "Emitter +a" + else + icon_state = "Emitter" + + +/obj/machinery/emitter/attack_hand(mob/user as mob) + src.add_fingerprint(user) + if(state == 2) + if(!src.locked || istype(user, /mob/living/silicon)) + if(src.active==1) + src.active = 0 + user << "You turn off the [src]." + src.power_usage = 0 + else + src.active = 1 + user << "You turn on the [src]." + src.shot_number = 0 + src.fire_delay = 100 + src.power_usage = 100 + update_icon() + else + user << "The controls are locked!" + else + user << "The [src] needs to be firmly secured to the floor first." + return 1 + +/obj/machinery/emitter/emp_act()//Emitters are hardened but still might have issues + use_power(50) + if(prob(1)&&prob(1)) + if(src.active) + src.active = 0 + src.power_usage = 0 + return 1 + + +/obj/machinery/emitter/process() + + if(stat & (NOPOWER|BROKEN)) + return + + if(src.state != 2) + src.active = 0 + return + + if(((src.last_shot + src.fire_delay) <= world.time) && (src.active == 1)) + src.last_shot = world.time + if(src.shot_number < 3) + src.fire_delay = 2 + src.shot_number ++ + else + 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, 'emitter.ogg', 75, 1) + + if(prob(35)) + var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread + s.set_up(5, 1, src) + s.start() + A.dir = src.dir + if(src.dir == 1)//Up + A.yo = 20 + A.xo = 0 + + else if(src.dir == 2)//Down + A.yo = -20 + A.xo = 0 + + else if(src.dir == 4)//Right + A.yo = 0 + A.xo = 20 + + else if(src.dir == 8)//Left + A.yo = 0 + A.xo = -20 + + else // Any other + A.yo = -20 + A.xo = 0 + + A.process() + + +/obj/machinery/emitter/attackby(obj/item/W, mob/user) + if(active) + user << "Turn off the [src] first." + return + + else if(istype(W, /obj/item/weapon/wrench)) + switch(state) + if(0) + state = 1 + playsound(src.loc, 'Ratchet.ogg', 75, 1) + user.visible_message("[user.name] secures [src.name] to the floor.", \ + "You secure the external reinforcing bolts to the floor.", \ + "You hear ratchet") + src.anchored = 1 + if(1) + state = 0 + playsound(src.loc, 'Ratchet.ogg', 75, 1) + user.visible_message("[user.name] unsecures [src.name] reinforcing bolts from the floor.", \ + "You undo the external reinforcing bolts.", \ + "You hear ratchet") + src.anchored = 0 + if(2) + user << "\red The [src.name] needs to be unwelded from the floor." + return + + else if(istype(W, /obj/item/weapon/weldingtool)) + switch(state) + if(0) + user << "\red The [src.name] needs to be wrenched to the floor." + return + if(1) + if (W:remove_fuel(2)) + playsound(src.loc, 'Welder2.ogg', 50, 1) + user.visible_message("[user.name] starts to weld the [src.name] to the floor.", \ + "You start to weld the [src] to the floor.", \ + "You hear welding") + if (do_after(user,20)) + state = 2 + user << "You weld the [src] to the floor." + else + user << "\blue You need more welding fuel to complete this task." + return + if(2) + if (W:remove_fuel(2)) + playsound(src.loc, 'Welder2.ogg', 50, 1) + user.visible_message("[user.name] starts to cut the [src.name] free from the floor.", \ + "You start to cut the [src] free from the floor.", \ + "You hear welding") + if (do_after(user,20)) + state = 1 + user << "You cut the [src] free from the floor." + else + user << "\blue You need more welding fuel to complete this task." + return + 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 + else + ..() + return + + +/obj/machinery/emitter/power_change() + ..() + update_icon() \ No newline at end of file diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm new file mode 100644 index 00000000000..1a26b37091e --- /dev/null +++ b/code/modules/power/singularity/field_generator.dm @@ -0,0 +1,308 @@ + +/////FIELD GEN +#define field_generator_max_power 250 +/obj/machinery/field_generator + name = "Field Generator" + desc = "A large thermal battery that projects a high amount of energy when powered." + icon = 'singularity.dmi' + icon_state = "Field_Gen" + anchored = 0 + density = 1 + req_access = list(access_engine) + power_usage = 0 + var + Varedit_start = 0 + Varpower = 0 + active = 0 + power = 20 + state = 0 + warming_up = 0 + powerlevel = 0 + list/obj/machinery/containment_field/fields + list/obj/machinery/field_generator/connected_gens + + + update_icon() + if (!active) + icon_state = "Field_Gen" + return + var/level = 3 + switch (power) + if(0 to 60) + level = 1 + if(61 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]" + + + New() + ..() + fields = list() + connected_gens = list() + return + + + process() + if(src.Varedit_start == 1) + if(src.active == 0) + src.active = 1 + src.state = 2 + src.power = field_generator_max_power + src.anchored = 1 + src.warming_up = 3 + turn_on() + Varedit_start = 0 + if(src.active == 2) + calc_power() + + return + + + attack_hand(mob/user as mob) + if(state == 2) + if(get_dist(src, user) <= 1)//Need to actually touch the thing to turn it on + if(src.active >= 1) + user << "You are unable to turn off the [src] once it is online." + return 1 + else + user.visible_message("[user.name] turns on the [src.name]", \ + "You turn on the [src].", \ + "You hear heavy droning") + turn_on() + src.add_fingerprint(user) + else + user << "The [src] needs to be firmly secured to the floor first." + return + + + attackby(obj/item/W, mob/user) + if(active) + user << "The [src] needs to be off." + return + else if(istype(W, /obj/item/weapon/wrench)) + switch(state) + if(0) + state = 1 + playsound(src.loc, 'Ratchet.ogg', 75, 1) + user.visible_message("[user.name] secures [src.name] to the floor.", \ + "You secure the external reinforcing bolts to the floor.", \ + "You hear ratchet") + src.anchored = 1 + if(1) + state = 0 + playsound(src.loc, 'Ratchet.ogg', 75, 1) + user.visible_message("[user.name] unsecures [src.name] reinforcing bolts from the floor.", \ + "You undo the external reinforcing bolts.", \ + "You hear ratchet") + src.anchored = 0 + if(2) + user << "\red The [src.name] needs to be unwelded from the floor." + return + else if(istype(W, /obj/item/weapon/weldingtool)) + switch(state) + if(0) + user << "\red The [src.name] needs to be wrenched to the floor." + return + if(1) + if (W:remove_fuel(2,user)) + playsound(src.loc, 'Welder2.ogg', 50, 1) + user.visible_message("[user.name] starts to weld the [src.name] to the floor.", \ + "You start to weld the [src] to the floor.", \ + "You hear welding") + if (do_after(user,20)) + state = 2 + user << "You weld the field generator to the floor." + else + return + if(2) + if (W:remove_fuel(2,user)) + playsound(src.loc, 'Welder2.ogg', 50, 1) + user.visible_message("[user.name] starts to cut the [src.name] free from the floor.", \ + "You start to cut the [src] free from the floor.", \ + "You hear welding") + if (do_after(user,20)) + state = 1 + user << "You cut the [src] free from the floor." + else + return + else + ..() + return + + + emp_act() + return 0 + + + bullet_act(flag) + if (flag == PROJECTILE_BULLET) + src.power -= 100 + else if (flag == PROJECTILE_WEAKBULLET) + src.power -= 50 + else if (flag == PROJECTILE_LASER) + src.power += 20 + else if (flag == PROJECTILE_TASER) + src.power += 5 + else + src.power -= 30 + update_icon() + return + + + Del() + src.cleanup() + ..() + + + proc + turn_off() + src.active = 0 + spawn(1) + src.cleanup() + update_icon() + + + turn_on() + src.active = 1 + warming_up = 1 + powerlevel = 0 + spawn(1) + while (warming_up<3 && active) + sleep(50) + warming_up++ + update_icon() + if(warming_up >= 3) + start_fields() + update_icon() + + + calc_power() + if(Varpower) + return + + update_icon() + if(src.power > field_generator_max_power) + src.power = field_generator_max_power + + var/power_draw = 0 + for (var/obj/machinery/containment_field/F in fields) + if (isnull(F)) + continue + power_draw++ + + if(draw_power(round(power_draw/2,1))) + return 1 + else + for(var/mob/M in viewers(src)) + M.show_message("\red The [src.name] shuts down!") + turn_off() + src.power = 0 + return + + + draw_power(var/draw = 0,var/obj/machinery/field_generator/G = null, var/obj/machinery/field_generator/last = null) +// if(G && G == src)//Loopin, set fail +// return 0 + if(src.power >= draw)//We have enough power + src.power -= draw + return 1 + else//Need more power + return 0 +/* draw -= src.power + src.power = 0 ill finis this up when not about to pass out + for(var/obj/machinery/field_generator/FG in connected_gens) + if(isnull(FG)) + continue + if(FG == last)//We just asked you + continue + if(G)//Another gen is askin for power and we dont have it + if(FG.draw_power(draw,G,src))//Can you take the load + return 1 + else + return 0 + else//We are askin another for power + if(FG.draw_power(draw,src,src)) + return 1 + else + return 0 +*/ + + start_fields() + if(!src.state == 2 || !anchored) + turn_off() + return + spawn(1) + setup_field(1) + spawn(2) + setup_field(2) + spawn(3) + setup_field(4) + spawn(4) + setup_field(8) + src.active = 2 + + + setup_field(var/NSEW) + var/turf/T = src.loc + var/obj/machinery/field_generator/G + var/steps = 0 + if(!NSEW)//Make sure its ran right + return + for(var/dist = 0, dist <= 9, dist += 1) // checks out to 8 tiles away for another generator + T = get_step(T, NSEW) + steps += 1 + G = locate(/obj/machinery/field_generator) in T + if(!isnull(G)) + steps -= 1 + if(!G.active) + return + break + if(isnull(G)) + return + T = src.loc + for(var/dist = 0, dist < steps, dist += 1) // creates each field tile + var/field_dir = get_dir(T,get_step(G.loc, NSEW)) + T = get_step(T, NSEW) + if(!locate(/obj/machinery/containment_field) in T) + var/obj/machinery/containment_field/CF = new/obj/machinery/containment_field() + fields += CF + G.fields += CF + CF.loc = T + CF.dir = field_dir + var/listcheck = 0 + for(var/obj/machinery/field_generator/FG in connected_gens) + if (isnull(FG)) + continue + if(FG == G) + listcheck = 1 + break + if(!listcheck) + connected_gens.Add(G) + listcheck = 0 + for(var/obj/machinery/field_generator/FG2 in G.connected_gens) + if (isnull(FG2)) + continue + if(FG2 == src) + listcheck = 1 + break + if(!listcheck) + G.connected_gens.Add(src) + + + cleanup() + for (var/obj/machinery/containment_field/F in fields) + if (isnull(F)) + continue + del(F) + fields = list() + for(var/obj/machinery/field_generator/FG in connected_gens) + if (isnull(FG)) + continue + FG.connected_gens.Remove(src) + connected_gens.Remove(FG) + connected_gens = list() diff --git a/code/modules/power/singularity/generator.dm b/code/modules/power/singularity/generator.dm new file mode 100644 index 00000000000..b51ef565013 --- /dev/null +++ b/code/modules/power/singularity/generator.dm @@ -0,0 +1,42 @@ + +/////SINGULARITY SPAWNER +/obj/machinery/the_singularitygen/ + name = "Gravitational Singularity Generator" + desc = "An Odd Device which produces a Gravitational Singularity when set up." + icon = 'singularity.dmi' + icon_state = "TheSingGen" + anchored = 1 + density = 1 + power_usage = 0 + +//////////////////////Singularity gen START + +/obj/machinery/the_singularitygen/process() + var/turf/T = get_turf(src) + if (singularity_is_surrounded(T)) + new /obj/machinery/singularity/(T, 200) + spawn(0) + del(src) + return + +/obj/machinery/the_singularitygen/attackby(obj/item/W, mob/user) + if(istype(W, /obj/item/weapon/wrench)) + anchored = !anchored + playsound(src.loc, 'Ratchet.ogg', 75, 1) + if(anchored) + user.visible_message("[user.name] secures [src.name] to the floor.", \ + "You secure the [src.name] to the floor.", \ + "You hear ratchet") + else + user.visible_message("[user.name] unsecures [src.name] from the floor.", \ + "You unsecure the [src.name] from the floor.", \ + "You hear ratchet") + return + return ..() + +/proc/singularity_is_surrounded(turf/T)//TODO:Add a timer so we dont need this + var/checkpointC = 0 + for (var/obj/X in orange(4,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 \ No newline at end of file diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm new file mode 100644 index 00000000000..39d398f58b7 --- /dev/null +++ b/code/modules/power/singularity/singularity.dm @@ -0,0 +1,269 @@ +var/global/list/uneatable = list( + /obj/machinery/singularity, + /turf/space,/obj/effects, + /obj/overlay) + +/obj/machinery/singularity/ + name = "Gravitational Singularity" + desc = "A Gravitational Singularity." + icon = '160x160.dmi' + icon_state = "Singularity" + anchored = 1 + density = 1 + layer = 6 + unacidable = 1 //Don't comment this out. + power_usage = 0 + var + active = 0 + contained = 1 //Are we going to move around? + energy = 100 //How strong are we? + dissipate = 0 //Do we lose energy over time? TODO:Set this to 1 when/if the feederthing is finished + dissipate_delay = 5 + dissipate_track = 0 + dissipate_strength = 10 //How much energy do we lose? + move_self = 1 //Do we move on our own? + grav_pull = 6 //How many tiles out do we pull? + event_chance = 15 //Prob for event each tick + + + New(loc, var/starting_energy = 200, var/temp = 0) + src.energy = starting_energy + pixel_x = -64 + pixel_y = -64 + if(temp) + spawn(temp) + del(src) + ..() + return + + + Del() + //Could have it do something bad when this happens, explode/implode or something + ..() + + + attack_hand(mob/user as mob) + consume(user) + return 1 + + + blob_act(severity) + return + + + ex_act(severity) + switch(severity) + if(1.0) + if(prob(10)) + del(src) + return + if(2.0 to 3.0) + return + return + + + Bump(atom/A) + consume(A) + return + + + Bumped(atom/A) + consume(A) + return + + + process() + eat() + dissipate() + check_energy() + move() + if(prob(event_chance))//Chance for it to run a special event + event() + pulse() + return + + proc + dissipate() + if(!dissipate) + return + if(dissipate_track >= dissipate_delay) + src.energy -= dissipate_strength + dissipate_track = 0 + else + dissipate_track++ + + + check_energy() + if(energy <= 0) + del(src) + return 0 + switch(energy) + if(1000 to 1999) + for(var/obj/machinery/field_generator/F in orange(5,src)) + F.turn_off() + emp_area() + toxmob() + if(2000 to INFINITY) + explosion(src.loc, 4, 8, 15, 0) + if(src) + del(src) + return 0 + return 1 + + + is_eatable(atom/X) + for (var/Type in uneatable) + if (istype(X, Type)) + return 0 + return 1 + + + eat() + for (var/atom/X in orange(grav_pull,src)) + if(isarea(X)) + continue + if (!is_eatable(X)) + continue + switch(get_dist(src,X)) + if(0 to 2) + consume(X) + else if(!isturf(X)) + if(!X:anchored && !istype(X,/mob/living/carbon/human))//TODO:change the boots to just anchor so we dont have to add this to everything + 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) + return + + + consume(var/atom/A) + var/gain = 0 + if (!is_eatable(A)) + return + if (istype(A,/mob/living))//Mobs get gibbed + gain = 20 + if(istype(A,/mob/living/carbon/human)) + if(A:mind) + if((A:mind:assigned_role == "Station Engineer") || (A:mind:assigned_role == "Chief Engineer") ) + gain = 100 + A:gib() + else if(istype(A,/obj/)) + A:ex_act(1.0) + if(A) del(A) + gain = 2 + else if(isturf(A)) + var/turf/T = A + if(T.intact) + for(var/obj/O in T.contents) + if(O.level != 1) + continue + if(O.invisibility == 101) + src.consume(O) + A:ReplaceWithSpace() + gain = 2 + src.energy += gain + return + + + move(var/movement_dir = 0) + if(!movement_dir == 1 || !movement_dir == 2 || !movement_dir == 4 || !movement_dir == 8) + movement_dir = pick(NORTH, SOUTH, EAST, WEST) + var/turf/T = null + switch(movement_dir) + if(NORTH) + T = locate(src.x,src.y+3,src.z) + if(SOUTH) + T = locate(src.x,src.y-3,src.z) + if(EAST) + T =locate(src.x+3,src.y,src.z) + if(WEST) + T = locate(src.x-3,src.y,src.z) + if(can_move(T)) + spawn(0) + step(src, movement_dir) + + + can_move(var/turf/T) + if(!T) + return 0 + if(locate(/obj/machinery/containment_field) in T) + return 0 + else if(locate(/obj/machinery/field_generator) in T) + var/obj/machinery/field_generator/G = locate(/obj/machinery/field_generator) in T + if(G && G.active) + return 0 + return 1 + + + event() + var/numb = pick(1,2,3,4,5,6) + switch(numb) + if(1)//EMP + emp_area() + if(2,3)//tox damage all carbon mobs in area + toxmob() + if(4)//Stun mobs who lack optic scanners + mezzer() + else + //do nothing + return + + + toxmob() + var/toxrange = 8 + if (src.energy>100) + toxrange+=round((src.energy-100)/100) + var/toxloss = 4 + var/radiation = 5 + if (src.energy>150) + toxloss += round(((src.energy-150)/50)*4,1) + radiation += round(((src.energy-150)/50)*5,1) + for(var/mob/living/carbon/M in view(toxrange, src.loc)) + if(istype(M,/mob/living/carbon/human)) + if(M:wear_suit) //TODO: check for radiation protection + toxloss = round(toxloss/2,1) + radiation = round(radiation/2,1) + M.toxloss += toxloss + M.radiation += radiation + M.updatehealth() + M << "\red You feel odd." + return + + + mezzer() + 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 << "\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) + M.stunned = 3 + for(var/mob/O in viewers(M, null)) + O.show_message(text("\red [] stares blankly at The []!", M, src), 1) + return + + + emp_area() + var/turf/myturf = get_turf(src) + var/obj/overlay/pulse = new/obj/overlay ( myturf ) + pulse.icon = 'effects.dmi' + pulse.icon_state = "emppulse" + pulse.name = "emp pulse" + pulse.anchored = 1 + spawn(20) + del(pulse) + for (var/atom/X in orange(8,src)) + X.emp_act() + return + + + pulse() + for(var/obj/machinery/power/rad_collector/R in orange(15,src)) + if(istype(R,/obj/machinery/power/rad_collector)) + R.receive_pulse(energy) + return \ No newline at end of file diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index ca124241859..3b182f9aed0 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -1,6 +1,37 @@ // the SMES // stores power +#define SMESMAXCHARGELEVEL 200000 +#define SMESMAXOUTPUT 200000 + +/obj/machinery/power/smes/magical + name = "magical power storage unit" + desc = "A high-capacity superconducting magnetic energy storage (SMES) unit. Magically produces power." + process() + capacity = INFINITY + charge = INFINITY + ..() + +/obj/machinery/power/smes + name = "power storage unit" + desc = "A high-capacity superconducting magnetic energy storage (SMES) unit." + icon_state = "smes" + density = 1 + anchored = 1 + var/output = 50000 + var/lastout = 0 + var/loaddemand = 0 + var/capacity = 5e6 + var/charge = 1e6 + var/charging = 0 + var/chargemode = 0 + var/chargecount = 0 + var/chargelevel = 50000 + var/online = 1 + var/n_tag = null + var/obj/machinery/power/terminal/terminal = null + + /obj/machinery/power/smes/New() ..() diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index 95cbbadd636..e28204e1ca4 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -43,6 +43,8 @@ return /obj/machinery/power/solar/proc/update_solar_exposure() + if(!sun) + return if(obscured) sunfrac = 0 return diff --git a/icons/obj/meteor.dmi b/icons/obj/meteor.dmi index ed3111ec28b8b618e28afc4f36da1865e8266ab6..123a5bdf86e55167b5aaabba0447077b867c0f0d 100644 GIT binary patch literal 11700 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 BhbsU8 literal 2432 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≥)~#XP1X64|%y65C_j9AjPw!)-v>xZGN( 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 literal 10450 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