diff --git a/code/game/machinery/processor.dm b/code/game/machinery/processor.dm index 080b270da7..5b7ad5d435 100644 --- a/code/game/machinery/processor.dm +++ b/code/game/machinery/processor.dm @@ -1,105 +1,125 @@ -/obj/machinery/processor/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(src.contents.len > 0) - user << "Something is already in the processing chamber." - return 0 - else - if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown/potato) || istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown/wheat) || istype(O, /obj/item/weapon/reagent_containers/food/snacks/humanmeat) || istype(O, /obj/item/weapon/reagent_containers/food/snacks/monkeymeat)) - user.drop_item() - O.loc = src - else if(istype(O,/obj/item/weapon/grab)) - var/obj/item/weapon/grab/G = O - if(istype(G.affecting, /mob/living/carbon/alien/larva/metroid)) - G.affecting.loc = src - user.drop_item() - else - user << "That probably won't blend." - return 0 +/datum/food_processor_process + var/input + var/output + var/time = 40 + proc/process(loc, what) + if (src.output && loc) + new src.output(loc) + if (what) + del(what) + /* objs */ + wheat + input = /obj/item/weapon/reagent_containers/food/snacks/grown/wheat + output = /obj/item/weapon/reagent_containers/food/snacks/flour + monkeymeat + input = /obj/item/weapon/reagent_containers/food/snacks/monkeymeat + output = /obj/item/weapon/reagent_containers/food/snacks/faggot + + humanmeat + input = /obj/item/weapon/reagent_containers/food/snacks/humanmeat + output = /obj/item/weapon/reagent_containers/food/snacks/faggot + potato + input = /obj/item/weapon/reagent_containers/food/snacks/grown/potato + output = /obj/item/weapon/reagent_containers/food/snacks/fries -/obj/machinery/processor/attack_hand(user as mob) - if(src.processing) - user << "The processor is in the process of processing." - return - for(var/obj/O in src.contents) - if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown/wheat)) - src.processing = 1 - sleep(40) - playsound(src.loc, 'blender.ogg', 50, 1) - for(var/mob/V in viewers(src, null)) - V.show_message(text("\blue [user] turns on \a [src].")) - del(O) - new /obj/item/weapon/reagent_containers/food/snacks/flour(src.loc) - src.processing = 0 - return - - if (istype(O, /obj/item/weapon/reagent_containers/food/snacks/monkeymeat)) - src.processing = 1 - sleep(40) - playsound(src.loc, 'blender.ogg', 50, 1) - for(var/mob/V in viewers(src, null)) - V.show_message(text("\blue [user] turns on \a [src].")) - del(O) - new /obj/item/weapon/reagent_containers/food/snacks/faggot(src.loc) - src.processing = 0 - return - - if (istype(O, /obj/item/weapon/reagent_containers/food/snacks/humanmeat)) - src.processing = 1 - sleep(40) - playsound(src.loc, 'blender.ogg', 50, 1) - for(var/mob/V in viewers(src, null)) - V.show_message(text("\blue [user] turns on \a [src].")) - del(O) - new /obj/item/weapon/reagent_containers/food/snacks/faggot(src.loc) - processing = 0 - return - - if (istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown/potato)) - src.processing = 1 - sleep(40) - playsound(src.loc, 'blender.ogg', 50, 1) - for(var/mob/V in viewers(src, null)) - V.show_message(text("\blue [user] turns on \a [src].")) - del(O) - new /obj/item/weapon/reagent_containers/food/snacks/fries(src.loc) - processing = 0 - return - - - for(var/mob/O in src.contents) - if(istype(O, /mob/living/carbon/alien/larva/metroid)) - src.processing = 1 - sleep(40) - playsound(src.loc, 'blender.ogg', 50, 1) - for(var/mob/V in viewers(src, null)) - V.show_message(text("\blue [user] turns on \a [src].")) - var/mob/dead/observer/newmob + /* mobs */ + mob + process(loc, what) + var/mob/O = what if (O.client) - newmob = new/mob/dead/observer(O) - O:client:mob = newmob - newmob:client:eye = newmob - del(O) - new /obj/item/weapon/reagent_containers/food/drinks/jar(src.loc) - src.processing = 0 - return - user << "There doesn't appear to be anything in the processing chamber." -/* -/obj/machinery/processor/attackby(obj/item/weapon/grab/G as obj, mob/user as mob) - if(istype(G.affecting, /mob/living/carbon/alien/larva/metroid)) - sleep(40) + var/mob/dead/observer/newmob = new/mob/dead/observer(O) + O.client.mob = newmob + newmob.client.eye = newmob + ..() + + + metroid + input = /mob/living/carbon/alien/larva/metroid + output = /obj/item/weapon/reagent_containers/food/drinks/jar + + monkey + process(loc, what) + var/mob/living/carbon/monkey/O = what + if (O.client) //grief-proof + O.loc = loc + O.visible_message("\blue Suddenly [O] jumps out from the processor!", \ + "You jump out from the processor", \ + "You hear chimp") + return + var/obj/item/weapon/reagent_containers/glass/bucket/bucket_of_blood = new(loc) + var/datum/reagent/blood/B = new() + B.holder = bucket_of_blood + B.volume = 70 + //set reagent data + B.data["donor"] = O + if(O.virus && O.virus.spread_type != SPECIAL) + B.data["virus"] = new O.virus.type(0) + B.data["blood_DNA"] = copytext(O.dna.unique_enzymes,1,0) + if(O.resistances&&O.resistances.len) + B.data["resistances"] = O.resistances.Copy() + bucket_of_blood.reagents.reagent_list += B + bucket_of_blood.reagents.update_total() + bucket_of_blood.on_reagent_change() + //bucket_of_blood.reagents.handle_reactions() //blood doesn't react + ..() + + input = /mob/living/carbon/monkey + output = null + +/obj/machinery/processor/proc/select_recipe(var/X) + for (var/Type in typesof(/datum/food_processor_process) - /datum/food_processor_process - /datum/food_processor_process/mob) + var/datum/food_processor_process/P = new Type() + if (!istype(X, P.input)) + continue + return P + return 0 + +/obj/machinery/processor/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(src.processing) + user << "\red The processor is in the process of processing." + return 1 + if(src.contents.len > 0) //TODO: several items at once? several different items? + user << "\red Something is already in the processing chamber." + return 1 + var/what = O + if (istype(O, /obj/item/weapon/grab)) + var/obj/item/weapon/grab/G = O + what = G.affecting + + var/datum/food_processor_process/P = select_recipe(what) + if (!P) + user << "\red That probably won't blend." + return 1 + user.visible_message("[user] put [what] into [src].", \ + "You put the [what] into [src].") + user.drop_item() + what:loc = src + return + +/obj/machinery/processor/attack_hand(var/mob/user as mob) + if(src.processing) + user << "\red The processor is in the process of processing." + return 1 + if(src.contents.len == 0) + user << "\red The processor is empty." + return 1 + for(var/O in src.contents) + var/datum/food_processor_process/P = select_recipe(O) + if (!P) + log_admin("DEBUG: [O] in processor havent suitable recipe. How do you put it in?") //-rastaf0 + continue + src.processing = 1 + user.visible_message("\blue [user] turns on \a [src].", \ + "You turn on \a [src].", \ + "You hear food processor") playsound(src.loc, 'blender.ogg', 50, 1) - for(var/mob/V in viewers(src, null)) - V.show_message(text("\blue [user] turns on \a [src].")) - var/mob/dead/observer/newmob - if (G.affecting.client) - newmob = new/mob/dead/observer(G.affecting) - G.affecting:client:mob = newmob - newmob:client:eye = newmob - del(G.affecting) - del(G) - new /obj/item/weapon/reagent_containers/food/drinks/jar(src.loc) -*/ + sleep(P.time) + P.process(src.loc, O) + src.processing = 0 + src.visible_message("\blue \the [src] finished processing.", \ + "You hear food processor stop") diff --git a/code/game/machinery/singularity.dm b/code/game/machinery/singularity.dm index 9a4908f84f..25297b5e83 100644 --- a/code/game/machinery/singularity.dm +++ b/code/game/machinery/singularity.dm @@ -5,6 +5,8 @@ tbh this could likely be better and I did not use all that many comments on it. However people seem to like it for some reason. *///////////////////////////////////////////////// +#define collector_control_range 12 + /////SINGULARITY SPAWNER /obj/machinery/the_singularitygen/ name = "Gravitational Singularity Generator" @@ -73,6 +75,7 @@ However people seem to like it for some reason. if(Ti) src.Dtime = Ti ..() + notify_collector_controller() /obj/machinery/the_singularity/attack_hand(mob/user as mob) return 1 @@ -83,12 +86,17 @@ However people seem to like it for some reason. /obj/machinery/the_singularity/ex_act(severity) switch(severity) if(1.0) - del(src) //TODO: some animation + 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() @@ -113,6 +121,7 @@ However people seem to like it for some reason. if ( is_surrounded && active ) src.active = 0 src.dieot = 0 + notify_collector_controller() spawn(50) if (!active) grav_pull = 6 @@ -121,12 +130,18 @@ However people seem to like it for some reason. 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 = 0 //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() myCC.updatecons() /obj/machinery/the_singularity var/global/list/uneatable = list(\ @@ -287,6 +302,7 @@ However people seem to like it for some reason. new/obj/item/weapon/tile (X) X:break_tile_to_plating() else + X:break_tile() else if(istype(X,/turf/simulated/wall)) if (istype(X,/turf/simulated/wall/r_wall)) @@ -566,51 +582,30 @@ However people seem to like it for some reason. icon_state = "Emitter" /obj/machinery/emitter/attack_hand(mob/user as mob) - if (..()) - return if(state == 3) - if(!src.locked) + if(!src.locked || istype(user, /mob/living/silicon)) src.add_fingerprint(user) if(src.active==1) src.active = 0 - user << "You turn off the emitter." + user << "You turn off the [src]." else src.active = 1 - user << "You turn on the emitter." + 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 emitter needs to be firmly secured to the floor first." + user << "The [src] needs to be firmly secured to the floor first." return 1 - -/obj/machinery/emitter/attack_ai(mob/user as mob) - if (..()) - return - if(state == 3) - src.add_fingerprint(user) - if(src.active==1) - src.active = 0 - user << "You turn off the emitter." - else - src.active = 1 - user << "You turn on the emitter." - src.shot_number = 0 - src.fire_delay = 100 - update_icon() - else - user << "The emitter needs to be firmly secured to the floor first." - - /obj/machinery/emitter/process() if(stat & (NOPOWER|BROKEN)) return - if(!src.state == 3) + if(!src.state == 3 || !anchored) src.active = 0 return @@ -661,7 +656,7 @@ However people seem to like it for some reason. /obj/machinery/emitter/attackby(obj/item/W, mob/user) if(istype(W, /obj/item/weapon/wrench)) if(active) - user << "\red Turn off the emitter first." + user << "\red Turn off the [src] first." return 1 else if(state == 0) @@ -685,10 +680,10 @@ However people seem to like it for some reason. else if(istype(W, /obj/item/weapon/weldingtool) && W:welding) if (state == 0) - user << "\red The emitter needs to be wrenched to the floor first." + user << "\red The [src] needs to be wrenched to the floor first." return 1 - if (W:get_fuel() < 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) @@ -697,21 +692,21 @@ However people seem to like it for some reason. if(state == 1) user.visible_message("[user.name] start to weld [src.name] to the floor.", \ - "You start to weld the emitter 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 emitter to the floor." + user << "You weld the [src] to the floor." else return 1 else if(state == 3) user.visible_message("[user.name] start to cut [src.name] to the floor.", \ - "You start to cut the emitter free from the floor.", \ + "You start to cut the [src] free from the floor.", \ "You hear welding") if (do_after(user,20)) state = 1 - user << "You cut the emitter free from the floor." + user << "You cut the [src] free from the floor." else return 1 @@ -776,20 +771,34 @@ However people seem to like it for some reason. icon_state = "ca" flick("ca_deactive", src) +/obj/machinery/power/collector_array/proc/eject() + var/obj/item/weapon/tank/plasma/Z = src.P + 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(P) - if(P.air_contents.toxins <= 0) + 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() - else if(src.active == 1) - src.active = 0 - updateicon_off() - ..() + //use_power called from collector_array/process /obj/machinery/power/collector_array/attack_hand(mob/user as mob) if (..()) @@ -838,17 +847,7 @@ However people seem to like it for some reason. else if(istype(W, /obj/item/weapon/crowbar)) if(!P) return 1 - var/obj/item/weapon/tank/plasma/Z = src.P - 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() + eject() else if(istype(W, /obj/item/weapon/wrench)) if(active) @@ -866,8 +865,8 @@ However people seem to like it for some reason. user.visible_message("[user.name] unsecure [src.name] reinforcing bolts to the floor.", \ "You undo the external reinforcing bolts.", \ "You hear ratchet") - if (CU) - CU.updatecons() + for(var/obj/machinery/power/collector_control/myCC in orange(1,src)) + myCC.updatecons() else user.visible_message("\red The [src.name] has been hit with the [W.name] by [user.name]!", \ @@ -878,11 +877,14 @@ However people seem to like it for some reason. /obj/machinery/power/collector_array/ex_act(severity) switch(severity) if(2.0 to 3.0) - var/obj/item/weapon/tank/plasma/Z = src.P - Z.loc = get_turf(src) - Z.layer = initial(Z.layer) - src.P = null + eject() return ..() + +/obj/machinery/power/collector_array/Del() + . = ..() + for(var/obj/machinery/power/collector_control/myCC in orange(1,src)) + myCC.updatecons() + ////////////CONTROL UNIT /obj/machinery/power/collector_control @@ -921,14 +923,19 @@ However people seem to like it for some reason. /obj/machinery/power/collector_control/proc/updatecons() S = list() - for(var/obj/machinery/the_singularity/myS in orange(12,src)) + for(var/obj/machinery/the_singularity/myS in orange(collector_control_range,src)) S += myS - for (var/ca_dir in cardinal) + 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 (!newCA.anchored) + 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 @@ -947,12 +954,14 @@ However people seem to like it for some reason. return overlays += image('singularity.dmi', "cu on") var/err = 0 - for (var/i = 1, ((i<= CA.len) && (i<=4)), i++) + 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) @@ -962,7 +971,7 @@ However people seem to like it for some reason. overlays += image('singularity.dmi', "cu sing") break for (var/obj/machinery/the_singularity/myS in S) - if(myS && !myS.active) + if(myS && myS.active) overlays += image('singularity.dmi', "cu conterr") break @@ -977,31 +986,30 @@ However people seem to like it for some reason. /obj/machinery/power/collector_control/process() if(stat & (NOPOWER|BROKEN)) return - if(src.active == 1) - var/power_a = 0 - var/power_s = 0 - var/power_p = 0 + if(!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/obj/machinery/the_singularity/myS in S) + if(!isnull(myS)) + power_s += myS.energy - for (var/i = 1, i<= CA.len, i++) - var/obj/machinery/power/collector_array/myCA = CA[i] - if (!myCA) - continue - var/obj/item/weapon/tank/plasma/myP = myCA.P - if(myP) - if (myCA.active) - myCA.use_power(250) - power_p += myP.air_contents.toxins - myP.air_contents.toxins -= 0.001 + 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) - ..() + 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) @@ -1013,14 +1021,14 @@ However people seem to like it for some reason. return 1 src.active = !src.active if(!src.active) - user << "You turn off the collector control." + user << "You turn off the [src]." src.lastpower = 0 updateicon() if(src.active) - user << "You turn on the collector control." + user << "You turn on the [src]." updatecons() else - user << "\red The collector control needs to be secured to the floor first." + user << "\red The [src] needs to be secured to the floor first." return 1 /obj/machinery/power/collector_control/attackby(obj/item/W, mob/user) @@ -1040,7 +1048,7 @@ However people seem to like it for some reason. connect_to_network() else user.visible_message("[user.name] unsecure [src.name] to the floor.", \ - "You undo the collector control securing bolts.", \ + "You undo the [src] securing bolts.", \ "You hear ratchet") disconnect_from_network() else @@ -1050,7 +1058,7 @@ However people seem to like it for some reason. 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" @@ -1063,7 +1071,6 @@ However people seem to like it for some reason. var/Varpower = 0 var/active = 0 var/power = 20 - var/max_power = 250 var/state = 0 //var/steps = 0 //var/last_check = 0 @@ -1081,9 +1088,9 @@ However people seem to like it for some reason. return var/level = 3 switch (power) - if(0 to 40) + if(0 to 60) level = 1 - if(41 to 220) + if(61 to 220) level = 2 if(221 to INFINITY) level = 3 @@ -1092,9 +1099,16 @@ However people seem to like it for some reason. 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) @@ -1104,36 +1118,23 @@ However people seem to like it for some reason. /obj/machinery/field_generator/attack_hand(mob/user as mob) if(state == 3) - if(!src.locked) + 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 field generator, wait till it powers down." + user << "You are unable to turn off the [src]r, wait till it powers down." // src.cleanup() return 1 else user.visible_message("[user.name] turn on [src.name]", \ - "You turn on the field generator.", \ + "You turn on the [src].", \ "You hear heavy droning") turn_on() src.add_fingerprint(user) else user << "The controls are locked!" else - user << "The field generator needs to be firmly secured to the floor first." - -/obj/machinery/field_generator/attack_ai(mob/user as mob) - if(state == 3) - if(src.active >= 1) - user << "You are unable to turn off the field generator, wait till it powers down." - else - user.visible_message("[user.name] turn on [src.name]", \ - "You turn on the field generator.", \ - "You hear heavy droning") - turn_on() - src.add_fingerprint(user) - else - user << "The field generator needs to be firmly secured to the floor first." + user << "The [src] needs to be firmly secured to the floor first." /obj/machinery/field_generator/New() ..() @@ -1146,13 +1147,14 @@ However people seem to like it for some reason. if(src.active == 0) src.active = 1 src.state = 3 - src.power = 250 + src.power = field_generator_max_power src.anchored = 1 + src.warming_up = 1 Varedit_start = 0 if(src.active == 1) - if(!src.state == 3) - src.active = 0 + if(!src.state == 3 || !anchored) + turn_off() return spawn(1) setup_field(1) @@ -1165,17 +1167,16 @@ However people seem to like it for some reason. src.active = 2 if(src.power < 0) src.power = 0 - if(src.power > src.max_power) - src.power = src.max_power + 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!") - src.active = 0 - spawn(1) - src.cleanup() + turn_off() + return update_icon() /obj/machinery/field_generator/proc/setup_field(var/NSEW) @@ -1214,7 +1215,7 @@ However people seem to like it for some reason. /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 field generator first." + user << "Turn off the [src] first." return 1 if(state == 0) @@ -1237,7 +1238,7 @@ However people seem to like it for some reason. if(state == 0) user << "\red The [src.name] needs to be wrenched to the floor first." return 1 - if (W:get_fuel() < 1) + if (W:get_fuel() < 2) user << "\blue You need more welding fuel to complete this task." return 1 W:use_fuel(1) @@ -1246,7 +1247,7 @@ However people seem to like it for some reason. if(state == 1) user.visible_message("[user.name] start to weld [src.name] to the floor.", \ - "You start to weld the field generator to the floor.", \ + "You start to weld the [src] to the floor.", \ "You hear welding") if (do_after(user,20)) state = 3 @@ -1256,11 +1257,11 @@ However people seem to like it for some reason. else if(state == 3) user.visible_message("[user.name] start to cut [src.name] free from the floor.", \ - "You start to cut the field generator free from the floor.", \ + "You start to cut the [src] free from the floor.", \ "You hear welding") if (do_after(user,20)) state = 1 - user << "You cut the field generator free from the floor." + user << "You cut the [src] free from the floor." else return 1 @@ -1302,7 +1303,8 @@ However people seem to like it for some reason. if (isnull(F)) continue G = (F.gen_primary == src) ? F.gen_secondary : F.gen_primary - G.fields -= F + if (G) + G.fields -= F del(F) fields = list() diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index ee14675e4e..c98bd14d6b 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -25,7 +25,7 @@ var/obj/item/weapon/cell/cell var/start_charge = 90 // initial cell charge % var/cell_type = 2500 // 0=no cell, 1=regular, 2=high-cap (x5) <- old, now it's just 0=no cell, otherwise dictate cellcapacity by changing this value. 1 used to be 1000, 2 was 2500 - var/opened = 0 + var/opened = 0 //0=closed, 1=opened, 2=cover removed var/shorted = 0 var/lighting = 3 var/equipment = 3 @@ -44,9 +44,9 @@ var/lastused_environ = 0 var/lastused_total = 0 var/main_status = 0 - var/light_consumption = 0 - var/equip_consumption = 0 - var/environ_consumption = 0 + var/light_consumption = 0 //not used + var/equip_consumption = 0 //not used + var/environ_consumption = 0 //not used var/emagged = 0 var/wiresexposed = 0 var/apcwires = 15 @@ -78,22 +78,24 @@ return apcwires /obj/machinery/power/apc/updateUsrDialog() + if (stat & (BROKEN|MAINT)) + return var/list/nearby = viewers(1, src) - if (!(stat & (BROKEN|MAINT))) // unbroken - for(var/mob/M in nearby) - if ((M.client && M.machine == src)) - src.interact(M) + for(var/mob/M in nearby) + if ((M.client && M.machine == src)) + src.interact(M) if (istype(usr, /mob/living/silicon)) if (!(usr in nearby)) if (usr.client && usr.machine==src) // && M.machine == src is omitted because if we triggered this by using the dialog, it doesn't matter if our machine changed in between triggering it and this - the dialog is probably still supposed to refresh. src.interact(usr) /obj/machinery/power/apc/updateDialog() - if(!(stat & BROKEN|MAINT)) // unbroken - var/list/nearby = viewers(1, src) - for(var/mob/M in nearby) - if (M.client && M.machine == src) - src.interact(M) + if (stat & (BROKEN|MAINT)) + return + var/list/nearby = viewers(1, src) + for(var/mob/M in nearby) + if (M.client && M.machine == src) + src.interact(M) AutoUpdateAI(src) /obj/machinery/power/apc/New(turf/loc, var/ndir, var/building=0) @@ -154,14 +156,14 @@ /obj/machinery/power/apc/examine() set src in oview(1) - if(usr && !usr.stat) + if(usr /*&& !usr.stat*/) usr << "A control terminal for the area electrical systems." if(stat & BROKEN) usr << "Looks broken." return if(opened) if(has_electronics && terminal) - usr << "The cover is open and the power cell is [ cell ? "installed" : "missing"]." + usr << "The cover is [opened==2?"removed":"open"] and the power cell is [ cell ? "installed" : "missing"]." else if (!has_electronics && terminal) usr << "There are some wires but no any electronics." else if (has_electronics && !terminal) @@ -171,7 +173,9 @@ else if (stat & MAINT) - usr << "The cover is closed. Something wrong with this: it's doesn't work." + usr << "The cover is closed. Something wrong with it: it's doesn't work." + else if (emagged || malfhack) + usr << "The cover is broken. It's may be hard to force it open." else usr << "The cover is closed." @@ -180,11 +184,19 @@ // also add overlays for indicator lights /obj/machinery/power/apc/proc/updateicon() if(opened) - if (stat & MAINT) - icon_state = "apcmaint" - else - icon_state = "[ cell ? "apc2" : "apc1" ]" // if opened, show cell if it's inserted - src.overlays = null // also delete all overlays + var/basestate = "apc[ cell ? "2" : "1" ]" // if opened, show cell if it's inserted + if (opened==1) + if (stat & MAINT) + icon_state = "apcmaint" //disassembled APC cannot hold cell + else + icon_state = basestate + else if (opened == 2) + if ((stat & BROKEN) || malfhack ) + icon_state = "[basestate]-b-nocover" + else /* if (emagged)*/ + icon_state = "[basestate]-nocover" + src.overlays = null // also delete all overlays + return else if(emagged || malfhack) icon_state = "apcemag" src.overlays = null @@ -193,6 +205,10 @@ icon_state = "apcewires" src.overlays = null return + else if (stat & BROKEN) + icon_state = "apc-b" + src.overlays = null + return else icon_state = "apc0" @@ -211,35 +227,44 @@ //attack with an item - open/close cover, insert cell, or (un)lock interface -/obj/machinery/power/apc/attackby(obj/item/weapon/W, mob/user) +/obj/machinery/power/apc/attackby(obj/item/W, mob/user) - if(stat & BROKEN) return //TODO: repairing if (istype(user, /mob/living/silicon)) return src.attack_hand(user) - if (istype(W, /obj/item/weapon/crowbar)) // crowbar means open or close the cover - if(opened) - if (!terminal && has_electronics==1) - playsound(src.loc, 'Crowbar.ogg', 50, 1) - user << "You trying to remove the power control board..." - if(do_after(user, 50)) - has_electronics = 0 + if (istype(W, /obj/item/weapon/crowbar) && opened) + if (has_electronics==1) + if (terminal) + user << "\red Disconnect wires first." + return + playsound(src.loc, 'Crowbar.ogg', 50, 1) + user << "You trying to remove the power control board..." + if(do_after(user, 50)) + has_electronics = 0 + if ((stat & BROKEN) || malfhack) + user.visible_message(\ + "\red [user.name] has broken the power control board inside [src.name]!",\ + "You broke the charred power control board and remove remains.", + "You hear crack") + //ticker.mode:apcs-- //XSI said no and I agreed. -rastaf0 + else user.visible_message(\ "\red [user.name] has removed the power control board from [src.name]!",\ "You remove the power control board.") - new /obj/item/weapon/module/power_control(loc) - else - opened = 0 - updateicon() + else if (opened!=2) //cover isn't removed + opened = 0 + updateicon() + else if (istype(W, /obj/item/weapon/crowbar) && !((stat & BROKEN) || malfhack) ) + if(coverlocked && !(stat & MAINT)) + user << "\red The cover is locked and cannot be opened." + return else - if(coverlocked) - user << "The cover is locked and cannot be opened." - else - opened = 1 - updateicon() + opened = 1 + updateicon() else if (istype(W, /obj/item/weapon/cell) && opened) // trying to put a cell inside if(cell) user << "There is a power cell already installed." + return else if (stat & MAINT) user << "\red There is no any connector for your power cell." @@ -255,9 +280,11 @@ else if (istype(W, /obj/item/weapon/screwdriver)) // haxing if(opened) if (cell) - user << "\red Close the APC first" //Less hints more mistery! + user << "\red Close the APC first." //Less hints more mystery! + return else if (!has_electronics || !terminal) user << "\red There is nothing to secure." + return else if (has_electronics==1) has_electronics = 2 @@ -270,7 +297,6 @@ playsound(src.loc, 'Screwdriver.ogg', 50, 1) user << "You unfasten the electronics." updateicon() - else if(emagged || malfhack) user << "The interface is broken" else @@ -280,7 +306,7 @@ else if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) // trying to unlock the interface with an ID card if(emagged || malfhack) - user << "The interface is broken" + user << "The interface is broken." else if(opened) user << "You must close the cover to swipe an ID card." else if(wiresexposed) @@ -303,37 +329,35 @@ user << "Nothing happens." else flick("apc-spark", src) - sleep(6) - - if(prob(50)) - emagged = 1 - locked = 0 - user << "You emag the APC interface." - updateicon() - else - user << "You fail to [ locked ? "unlock" : "lock"] the APC interface." + if (do_after(user,6)) + if(prob(50)) + emagged = 1 + locked = 0 + user << "You emag the APC interface." + updateicon() + else + user << "You fail to [ locked ? "unlock" : "lock"] the APC interface." else if (istype(W, /obj/item/weapon/cable_coil) && !terminal && opened && has_electronics!=2) if (src.loc:intact) user << "\red You must remove the plating first." return var/obj/item/weapon/cable_coil/C = W - if(C.amount >= 10) - user << "You start adding cables to the APC frame..." - playsound(src.loc, 'Deconstruct.ogg', 50, 1) - if(do_after(user, 20)) - var/turf/T = get_turf_loc(src) - var/obj/cable/N = T.get_cable_node() - if (N.electrocute(usr, 50, N.netnum)) - return - C.amount -= 10 - if(!C.amount) del(C) - user.visible_message(\ - "\red [user.name] has added cables to the APC frame!",\ - "You add cables to the APC frame.") - make_terminal() - terminal.connect_to_network() - else + if(C.amount < 10) user << "\red You need more wires." + return + user << "You start adding cables to the APC frame..." + playsound(src.loc, 'Deconstruct.ogg', 50, 1) + if(do_after(user, 20) && C.amount >= 10) + var/turf/T = get_turf_loc(src) + var/obj/cable/N = T.get_cable_node() + if (N && N.electrocute(usr, 50, N.netnum)) + return + C.use(10) + user.visible_message(\ + "\red [user.name] has added cables to the APC frame!",\ + "You add cables to the APC frame.") + make_terminal() + terminal.connect_to_network() else if (istype(W, /obj/item/weapon/wirecutters) && terminal && opened && has_electronics!=2) if (src.loc:intact) user << "\red You must remove the plating first." @@ -343,16 +367,15 @@ if(do_after(user, 50)) if (terminal.electrocute(usr, 50, terminal.netnum)) return - var/obj/item/weapon/cable_coil/C = new /obj/item/weapon/cable_coil(loc) - C.amount = 10 + new /obj/item/weapon/cable_coil(loc,10) user.visible_message(\ "\red [user.name] cut cables and dismantled the power terminal.",\ "You cut cables and dismantle the power terminal.") del(terminal) - else if (istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics==0) + else if (istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics==0 && !((stat & BROKEN) || malfhack)) user << "You trying to insert the power control board into the frame..." playsound(src.loc, 'Deconstruct.ogg', 50, 1) - if(do_after(user, 20)) + if(do_after(user, 10)) has_electronics = 1 user << "You place the power control board inside the frame." del(W) @@ -361,11 +384,11 @@ user << "\blue You need more welding fuel to complete this task." return user << "You start welding APC frame..." - W:use_fuel(3) + W:use_fuel(2) W:eyecheck(user) playsound(src.loc, 'Welder.ogg', 50, 1) if(do_after(user, 50)) - if (emagged || malfhack) + if (emagged || malfhack || (stat & BROKEN) || opened==2) new /obj/item/weapon/sheet/metal(loc) user.visible_message(\ "\red [src] has been cut apart by [user.name] with the weldingtool.",\ @@ -378,18 +401,52 @@ "You cut APC frame from the wall.",\ "\red You hear welding.") del(src) - - -/obj/machinery/power/apc/attack_ai(mob/user) - return src.attack_hand(user) + else if (istype(W, /obj/item/apc_frame) && opened && emagged) + emagged = 0 + if (opened==2) + opened = 1 + user.visible_message(\ + "\red [user.name] has replace the damaged APC frontal panel with new one.",\ + "You replace the damaged APC frontal panel with new one.") + del(W) + updateicon() + else if (istype(W, /obj/item/apc_frame) && opened && ((stat & BROKEN) || malfhack)) + if (has_electronics) + user << "You cannot repair this heavy damaged APC until broken electronics still inside." + return + user << "You begin to replace the damaged APC frame..." + if(do_after(user, 50)) + user.visible_message(\ + "\red [user.name] has replace the damaged APC frame with new one.",\ + "You replace the damaged APC frame with new one.") + del(W) + stat &= ~BROKEN + malfai = null + malfhack = 0 + if (opened==2) + opened = 1 + updateicon() + else + if ( ((stat & BROKEN) || malfhack) \ + && !opened \ + && W.force >= 5 \ + && W.w_class >= 3.0 \ + && !istype(W, /obj/item/weapon/gun) \ + && prob(10) ) + opened = 2 + user.visible_message("\red The APC cover was knocked down with the [W.name] by [user.name]!", \ + "\red You knock down the APC cover with your [W.name]!", \ + "You hear bang") + updateicon() + 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") // attack with hand - remove cell (if cover open) or interact with the APC /obj/machinery/power/apc/attack_hand(mob/user) - add_fingerprint(user) - - if(stat & (BROKEN|MAINT)) return if(opened && (!istype(user, /mob/living/silicon))) if(cell) cell.loc = usr @@ -409,6 +466,7 @@ src.updateicon() else + if(stat & (BROKEN|MAINT)) return // do APC interaction src.interact(user) @@ -454,7 +512,7 @@ onclose(user, "apcwires") user.machine = src - var/t = "Area Power Controller ([area.name])
" + var/t = "[area.name] APCArea Power Controller ([area.name])
" if(locked && (!istype(user, /mob/living/silicon))) t += "(Swipe ID card to unlock inteface.)
" @@ -551,7 +609,7 @@ t += "

Close" - t += "
" + t += "
" user << browse(t, "window=apc") onclose(user, "apc") return @@ -825,6 +883,7 @@ if (src.cell) if (src.cell.charge > 0) src.cell.charge = 0 + cell.corrupt() src.malfhack = 1 malfai << "Hack complete. The APC is now under your exclusive control. Discharging cell to fuse interface." updateicon() @@ -843,9 +902,9 @@ else malfai << "Hack complete. The APC is now under your exclusive control. Unable to fuse interface due to lack of cell do discharge." - return src.updateUsrDialog() + return else usr << browse(null, "window=apc") @@ -972,9 +1031,13 @@ if(chargemode && charging == 1 && operating) if(excess > 0) // check to make sure we have enough to charge // Max charge is perapc share, capped to cell capacity, or % per second constant (Whichever is smallest) - var/ch = min(perapc, (cell.maxcharge - cell.charge), (cell.maxcharge*CHARGELEVEL)) +/* var/ch = min(perapc, (cell.maxcharge - cell.charge), (cell.maxcharge*CHARGELEVEL)) add_load(ch) // Removes the power we're taking from the grid cell.give(ch) // actually recharge the cell +*/ + var/ch = min(perapc*CELLRATE, (cell.maxcharge - cell.charge), (cell.maxcharge*CHARGELEVEL)) + add_load(ch/CELLRATE) // Removes the power we're taking from the grid + cell.give(ch) // actually recharge the cell else charging = 0 // stop charging @@ -1016,7 +1079,8 @@ updateicon() update() - src.updateDialog() + //src.updateDialog() + src.updateUsrDialog() // val 0=off, 1=off(auto) 2=on 3=on(auto) // on 0=off, 1=on, 2=autooff @@ -1051,26 +1115,32 @@ switch(severity) if(1.0) //set_broken() //now Del() do what we need + if (cell) + cell.ex_act(1.0) // more lags woohoo del(src) return if(2.0) if (prob(50)) set_broken() + if (cell && prob(50)) + cell.ex_act(2.0) if(3.0) if (prob(25)) set_broken() + if (cell && prob(25)) + cell.ex_act(3.0) return /obj/machinery/power/apc/blob_act() if (prob(75)) set_broken() + if (cell && prob(5)) + cell.blob_act() /obj/machinery/power/apc/proc/set_broken() stat |= BROKEN - icon_state = "apc-b" - overlays = null - operating = 0 + updateicon() update() // overload all the lights in this APC area diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 649a22070c..0591a2707a 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -47,7 +47,7 @@ /obj/item/weapon/cell/examine() set src in view(1) - if(usr && !usr.stat) + if(usr /*&& !usr.stat*/) if(maxcharge <= 2500) usr << "[desc]\nThe manufacturer's label states this cell has a power rating of [maxcharge], and that you should not swallow it.\nThe charge meter reads [round(src.percent() )]%." else @@ -80,8 +80,54 @@ /obj/item/weapon/cell/proc/explode() var/turf/T = get_turf(src.loc) - - explosion(T, 0, 1, 2, 2) //TODO: involve charge +/* + * 1000-cell explosion(T, -1, 0, 1, 1) + * 2500-cell explosion(T, -1, 0, 1, 1) + * 10000-cell explosion(T, -1, 1, 3, 3) + * 15000-cell explosion(T, -1, 2, 4, 4) + * */ + if (charge==0) + return + var/devastation_range = -1 //round(charge/11000) + var/heavy_impact_range = round(sqrt(charge)/60) + var/light_impact_range = round(sqrt(charge)/30) + var/flash_range = light_impact_range + if (light_impact_range==0) + rigged = 0 + corrupt() + return + //explosion(T, 0, 1, 2, 2) + explosion(T, devastation_range, heavy_impact_range, light_impact_range, flash_range) spawn(1) - del(src) \ No newline at end of file + del(src) + +/obj/item/weapon/cell/proc/corrupt() + charge /= 2 + maxcharge /= 2 + if (prob(10)) + rigged = 1 //broken batterys are dangerous + +/obj/item/weapon/cell/ex_act(severity) + + switch(severity) + if(1.0) + del(src) + return + if(2.0) + if (prob(50)) + del(src) + return + if (prob(50)) + corrupt() + if(3.0) + if (prob(25)) + del(src) + return + if (prob(25)) + corrupt() + return + +/obj/item/weapon/cell/blob_act() + if(prob(75)) + explode() diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index b059b2af2d..50433f0c6a 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -359,7 +359,7 @@ /obj/machinery/power/proc/connect_to_network() var/turf/T = src.loc var/obj/cable/C = T.get_cable_node() - if (!C.netnum) + if (!C || !C.netnum) return makepowernets() //TODO: find fast way diff --git a/icons/obj/power.dmi b/icons/obj/power.dmi index 205989a039..55825b3d51 100644 Binary files a/icons/obj/power.dmi and b/icons/obj/power.dmi differ