From f8e808f617f0187de4ca97382aa54638badf35ee Mon Sep 17 00:00:00 2001 From: Lohikar Date: Sun, 5 Mar 2017 14:05:57 -0600 Subject: [PATCH] /vg/ AME port (#1831) changes: Ported /vg/'s anti-matter engine. Anti-matter engine is now orderable from cargo. Anti-matter fuel is now orderable from cargo. Using 1 of each AM crate from Cargo, you can get 240 kW. Note: We already have this engine in our code, this is just an update to it. --- code/__defines/machinery.dm | 5 + code/datums/supplypacks.dm | 41 +++ code/modules/power/antimatter/computer.dm | 7 +- .../power/antimatter/containment_jar.dm | 29 +- code/modules/power/antimatter/control.dm | 280 +++++++++++------- code/modules/power/antimatter/engine.dm | 23 +- code/modules/power/antimatter/fuel.dm | 24 +- code/modules/power/antimatter/shielding.dm | 216 ++++++++------ html/changelogs/lohikar-ame.yml | 4 + icons/obj/machines/new_ame.dmi | Bin 0 -> 22056 bytes nano/templates/ame.tmpl | 56 ++++ 11 files changed, 458 insertions(+), 227 deletions(-) create mode 100644 html/changelogs/lohikar-ame.yml create mode 100644 icons/obj/machines/new_ame.dmi create mode 100644 nano/templates/ame.tmpl diff --git a/code/__defines/machinery.dm b/code/__defines/machinery.dm index ab74ab7ddfe..9758cfdef84 100644 --- a/code/__defines/machinery.dm +++ b/code/__defines/machinery.dm @@ -105,3 +105,8 @@ var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret // If this is returned from a machine's process() proc, the machine will stop processing but // will continue to have power calculations done. #define M_NO_PROCESS 27 + +// This controls how much power the AME generates per unit of fuel. +// Assuming 100% efficency, use this equation to figure out power output. +// power_generated = (fuel**2) * AM_POWER_FACTOR +#define AM_POWER_FACTOR 50000 diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 2ca39087c20..73cdc5f6884 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -1733,3 +1733,44 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee containertype = /obj/structure/closet/crate containername = "IPC/Shell tag implanters" group = "Security" + +/datum/supply_packs/ame_ctrl + name = "Antimatter Reactor Control Unit" + contains = list( + /obj/machinery/power/am_control_unit + ) + cost = 40 + containertype = /obj/structure/closet/crate/secure/large + containername = "antimatter reactor control unit kit" + group = "Engineering" + access = access_ce + +/datum/supply_packs/ame_section + name = "Antimatter Reactor Shielding Kit" + contains = list( + /obj/item/device/am_shielding_container, + /obj/item/device/am_shielding_container, + /obj/item/device/am_shielding_container, + /obj/item/device/am_shielding_container, + /obj/item/device/am_shielding_container, + /obj/item/device/am_shielding_container, + /obj/item/device/am_shielding_container, + /obj/item/device/am_shielding_container, + /obj/item/device/am_shielding_container + ) + cost = 20 + containertype = /obj/structure/closet/crate/secure/phoron + containername = "antimatter reactor shielding (9x) crate" + group = "Engineering" + access = access_ce + +/datum/supply_packs/ame_fuel + name = "Antimatter Reactor Fuel" + contains = list( + /obj/item/weapon/am_containment + ) + cost = 20 + containertype = /obj/structure/closet/crate/secure/bin + containername = "antimatter fuel container" + group = "Engineering" + access = access_engine diff --git a/code/modules/power/antimatter/computer.dm b/code/modules/power/antimatter/computer.dm index d531ccfb540..bbb9220f539 100644 --- a/code/modules/power/antimatter/computer.dm +++ b/code/modules/power/antimatter/computer.dm @@ -18,10 +18,10 @@ /obj/machinery/computer/am_engine/New() ..() spawn( 24 ) - for(var/obj/machinery/power/am_engine/engine/E in world) + for(var/obj/machinery/power/am_engine/engine/E in machines) if(E.engine_id == src.engine_id) src.connected_E = E - for(var/obj/machinery/power/am_engine/injector/I in world) + for(var/obj/machinery/power/am_engine/injector/I in machines) if(I.engine_id == src.engine_id) src.connected_I = I return @@ -45,7 +45,7 @@ src.state = STATE_DEFAULT if("login") var/mob/M = usr - var/obj/item/weapon/card/id/I = M.get_active_hand() + var/obj/item/weapon/card/id/I = M.equipped() if (I && istype(I)) if(src.check_access(I)) authenticated = 1 @@ -57,6 +57,7 @@ src.updateUsrDialog() /obj/machinery/computer/am_engine/attack_ai(var/mob/user as mob) + src.add_hiddenprint(user) return src.attack_hand(user) /obj/machinery/computer/am_engine/attack_paw(var/mob/user as mob) diff --git a/code/modules/power/antimatter/containment_jar.dm b/code/modules/power/antimatter/containment_jar.dm index dd0e503bd47..7c2c07b0022 100644 --- a/code/modules/power/antimatter/containment_jar.dm +++ b/code/modules/power/antimatter/containment_jar.dm @@ -1,6 +1,7 @@ /obj/item/weapon/am_containment name = "antimatter containment jar" - desc = "Holds antimatter." + desc = "Holds antimatter. Warranty void if exposed to matter." + description_antag = "Antimatter is extremely volatile, and containment jars are not particularly strong. Weak explosions will reduce the container's integrity, and larger ones will cause it to explode immediately." icon = 'icons/obj/machines/antimatter.dmi' icon_state = "jar" density = 0 @@ -10,24 +11,28 @@ throw_speed = 1 throw_range = 2 - var/fuel = 10000 - var/fuel_max = 10000//Lets try this for now + var/fuel = 1000 // WAS ORIGINALLY 10000 + var/fuel_max = 1000//Lets try this for now var/stability = 100//TODO: add all the stability things to this so its not very safe if you keep hitting in on things + var/exploded = 0 +/obj/item/weapon/am_containment/proc/boom() + var/percent = 0 + if(fuel) + percent = (fuel / fuel_max) * 100 + if(!exploded && percent >= 10) + explosion(get_turf(src), 1, 2, 3, 5)//Should likely be larger but this works fine for now I guess + exploded=1 + if(src) + qdel(src) /obj/item/weapon/am_containment/ex_act(severity) switch(severity) if(1.0) - explosion(get_turf(src), 1, 2, 3, 5)//Should likely be larger but this works fine for now I guess - if(src) - qdel(src) - return + boom() if(2.0) if(prob((fuel/10)-stability)) - explosion(get_turf(src), 1, 2, 3, 5) - if(src) - qdel(src) - return + boom() stability -= 40 if(3.0) stability -= 20 @@ -38,4 +43,4 @@ if(fuel < wanted) wanted = fuel fuel -= wanted - return wanted \ No newline at end of file + return wanted diff --git a/code/modules/power/antimatter/control.dm b/code/modules/power/antimatter/control.dm index 8c7af58346e..2ed4d447265 100644 --- a/code/modules/power/antimatter/control.dm +++ b/code/modules/power/antimatter/control.dm @@ -1,9 +1,13 @@ /obj/machinery/power/am_control_unit name = "antimatter control unit" - desc = "This device injects antimatter into connected shielding units, the more antimatter injected the more power produced. Wrench the device to set it up." - icon = 'icons/obj/machines/antimatter.dmi' + desc = "The control unit for an antimatter reactor. Probably safe." + description_info = "Use a wrench to attach the control unit to the ground, then arrange the reactor sections nearby. Reactor sections can only be activated if they are near the control unit, but otherwise are not restricted in how they must be placed." + description_antag = "The antimatter engine will quickly destabilize if the fuel injection rate is set too high, causing a large explosion." + icon = 'icons/obj/machines/new_ame.dmi' icon_state = "control" - anchored = 1 + var/icon_mod = "on" // on, critical, or fuck + var/old_icon_mod = "on" + anchored = 0 density = 1 use_power = 1 idle_power_usage = 100 @@ -15,18 +19,19 @@ var/update_shield_icons = 0 var/stability = 100 var/exploding = 0 + var/exploded = 0 - var/active = 0//On or not - var/fuel_injection = 2//How much fuel to inject - var/shield_icon_delay = 0//delays resetting for a short time + var/active = 0 //On or not + var/fuel_injection = 2 //How much fuel to inject + var/shield_icon_delay = 0 //delays resetting for a short time var/reported_core_efficiency = 0 var/power_cycle = 0 - var/power_cycle_delay = 4//How many ticks till produce_power is called + var/power_cycle_delay = 4 //How many ticks till produce_power is called var/stored_core_stability = 0 var/stored_core_stability_delay = 0 - var/stored_power = 0//Power to deploy per tick + var/stored_power = 0 //Power to deploy per tick /obj/machinery/power/am_control_unit/New() @@ -34,17 +39,25 @@ linked_shielding = list() linked_cores = list() - -/obj/machinery/power/am_control_unit/Destroy()//Perhaps damage and run stability checks rather than just qdel on the others +/obj/machinery/power/am_control_unit/Destroy()//Perhaps damage and run stability checks rather than just del on the others for(var/obj/machinery/am_shielding/AMS in linked_shielding) + AMS.control_unit = null qdel(AMS) + for(var/obj/machinery/am_shielding/AMS in linked_cores) + AMS.control_unit = null + qdel(AMS) + qdel(fueljar) + fueljar = null ..() /obj/machinery/power/am_control_unit/process() - if(exploding) - explosion(get_turf(src),8,12,18,12) - if(src) qdel(src) + if(exploding && !exploded) + message_admins("AME explosion at ([x],[y],[z] - JMP) - Last touched by [fingerprintslast]",0,1) + exploded=1 + explosion(get_turf(src),8,10,12,15) + if(src) + qdel(src) if(update_shield_icons && !shield_icon_delay) check_shield_icons() @@ -58,6 +71,8 @@ //Angry buzz or such here return + check_core_stability() + add_avail(stored_power) power_cycle++ @@ -65,41 +80,43 @@ produce_power() power_cycle = 0 - return - - /obj/machinery/power/am_control_unit/proc/produce_power() - playsound(src.loc, 'sound/effects/bang.ogg', 25, 1) - var/core_power = reported_core_efficiency//Effectively how much fuel we can safely deal with - if(core_power <= 0) return 0//Something is wrong + playsound(get_turf(src), 'sound/effects/bang.ogg', 25, 1) + for (var/thing in linked_cores) + flick("core2", thing) + var/core_power = reported_core_efficiency //Effectively how much fuel we can safely deal with + if(core_power <= 0) + return 0//Something is wrong var/core_damage = 0 var/fuel = fueljar.usefuel(fuel_injection) - stored_power = (fuel/core_power)*fuel*200000 + stored_power = (fuel / core_power) * fuel * AM_POWER_FACTOR // Was 200000, was too much. New value run past Aurx. - N3X //Now check if the cores could deal with it safely, this is done after so you can overload for more power if needed, still a bad idea - if(fuel > (2*core_power))//More fuel has been put in than the current cores can deal with - if(prob(50))core_damage = 1//Small chance of damage - if((fuel-core_power) > 5) core_damage = 5//Now its really starting to overload the cores - if((fuel-core_power) > 10) core_damage = 20//Welp now you did it, they wont stand much of this - if(core_damage == 0) return + if(fuel > (2*core_power)) //More fuel has been put in than the current cores can deal with + if(prob(50)) + core_damage = 1 //Small chance of damage + if((fuel-core_power) > 5) + core_damage = 5 //Now its really starting to overload the cores + if((fuel-core_power) > 10) + core_damage = 20 //Welp now you did it, they wont stand much of this + if(core_damage == 0) + return for(var/obj/machinery/am_shielding/AMS in linked_cores) AMS.stability -= core_damage AMS.check_stability(1) - playsound(src.loc, 'sound/effects/bang.ogg', 50, 1) - return - + playsound(get_turf(src), 'sound/effects/bang.ogg', 50, 1) /obj/machinery/power/am_control_unit/emp_act(severity) switch(severity) if(1) - if(active) toggle_power() + if(active) + toggle_power() stability -= rand(15,30) if(2) - if(active) toggle_power() + if(active) + toggle_power() stability -= rand(10,20) ..() - return 0 - /obj/machinery/power/am_control_unit/ex_act(severity) switch(severity) @@ -112,55 +129,50 @@ check_stability() return - -/obj/machinery/power/am_control_unit/bullet_act(var/obj/item/projectile/Proj) - if(Proj.check_armour != "bullet") - stability -= Proj.force - return 0 - - /obj/machinery/power/am_control_unit/power_change() ..() if(stat & NOPOWER && active) toggle_power() return - /obj/machinery/power/am_control_unit/update_icon() - if(active) icon_state = "control_on" - else icon_state = "control" + if(active) + icon_state = "control_[icon_mod]" + else + icon_state = "control" //No other icons for it atm - /obj/machinery/power/am_control_unit/attackby(obj/item/W, mob/user) - if(!istype(W) || !user) return - if(istype(W, /obj/item/weapon/wrench)) + if(!istype(W) || !user) + return + if(iswrench(W)) if(!anchored) - playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) + playsound(get_turf(src), 'sound/items/Ratchet.ogg', 75, 1) user.visible_message("[user.name] secures the [src.name] to the floor.", \ "You secure the anchor bolts to the floor.", \ "You hear a ratchet") src.anchored = 1 + update_shield_icons = 2 + check_shield_icons() connect_to_network() else if(!linked_shielding.len > 0) - playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) + playsound(get_turf(src), 'sound/items/Ratchet.ogg', 75, 1) user.visible_message("[user.name] unsecures the [src.name].", \ "You remove the anchor bolts.", \ "You hear a ratchet") src.anchored = 0 disconnect_from_network() else - user << "\red Once bolted and linked to a shielding unit it the [src.name] is unable to be moved!" + to_chat(user, "Once bolted and linked to a shielding unit it the [src.name] is unable to be moved!") return if(istype(W, /obj/item/weapon/am_containment)) if(fueljar) - user << "\red There is already a [fueljar] inside!" + to_chat(user, "There is already a [fueljar] inside!") return fueljar = W - user.remove_from_mob(W) - W.loc = src - user.update_icons() + user.drop_from_inventory(W, src) + message_admins("AME loaded with fuel by [user.real_name] ([user.key]) at ([x],[y],[z] - JMP)",0,1) user.visible_message("[user.name] loads an [W.name] into the [src.name].", \ "You load an [W.name].", \ "You hear a thunk.") @@ -180,19 +192,25 @@ /obj/machinery/power/am_control_unit/proc/add_shielding(var/obj/machinery/am_shielding/AMS, var/AMS_linking = 0) - if(!istype(AMS)) return 0 - if(!anchored) return 0 - if(!AMS_linking && !AMS.link_control(src)) return 0 - linked_shielding.Add(AMS) + if(!istype(AMS)) + return 0 + if(!anchored) + return 0 + if(!AMS_linking && !AMS.link_control(src)) + return 0 + if(!(AMS in linked_shielding)) + linked_shielding.Add(AMS) update_shield_icons = 1 return 1 /obj/machinery/power/am_control_unit/proc/remove_shielding(var/obj/machinery/am_shielding/AMS) - if(!istype(AMS)) return 0 + if(!istype(AMS)) + return 0 linked_shielding.Remove(AMS) update_shield_icons = 2 - if(active) toggle_power() + if(active) + toggle_power() return 1 @@ -210,40 +228,63 @@ else use_power = 1 visible_message("The [src.name] shuts down.") + for(var/obj/machinery/am_shielding/AMS in linked_cores) + AMS.update_icon() update_icon() return /obj/machinery/power/am_control_unit/proc/check_shield_icons()//Forces icon_update for all shields - if(shield_icon_delay) return + if(shield_icon_delay) + return shield_icon_delay = 1 if(update_shield_icons == 2)//2 means to clear everything and rebuild + for(var/obj/machinery/am_shielding/neighbor in cardinalrange(loc)) + if(!neighbor.control_unit) + linked_shielding += neighbor for(var/obj/machinery/am_shielding/AMS in linked_shielding) - if(AMS.processing) AMS.shutdown_core() + if(AMS.processing) + AMS.shutdown_core() AMS.control_unit = null spawn(10) AMS.controllerscan() + AMS.assimilate() linked_shielding = list() else for(var/obj/machinery/am_shielding/AMS in linked_shielding) AMS.update_icon() - spawn(20) - shield_icon_delay = 0 - return + sleep(20) + shield_icon_delay = 0 /obj/machinery/power/am_control_unit/proc/check_core_stability() - if(stored_core_stability_delay || linked_cores.len <= 0) return - stored_core_stability_delay = 1 + //if(stored_core_stability_delay || linked_cores.len <= 0) return + if(linked_cores.len <= 0) + return + //stored_core_stability_delay = 1 stored_core_stability = 0 - for(var/obj/machinery/am_shielding/AMS in linked_cores) - stored_core_stability += AMS.stability - stored_core_stability/=linked_cores.len - spawn(40) - stored_core_stability_delay = 0 - return + for(var/thing in linked_cores) + var/obj/machinery/am_shielding/AMS = thing + if (!AMS || AMS.gcDestroyed) + continue + stored_core_stability += AMS.stability + stored_core_stability /= linked_cores.len + switch(stored_core_stability) + if(0 to 24) + icon_mod = "fuck" + if(25 to 49) + icon_mod = "critical" + if(50 to INFINITY) + icon_mod = "on" + + if(icon_mod != old_icon_mod) + old_icon_mod = icon_mod + update_icon() + + //spawn(40) + // stored_core_stability_delay = 0 /obj/machinery/power/am_control_unit/interact(mob/user) if((get_dist(src, user) > 1) || (stat & (BROKEN|NOPOWER))) @@ -251,43 +292,56 @@ user.unset_machine() user << browse(null, "window=AMcontrol") return - user.set_machine(src) + return ui_interact(user) - var/dat = "" - dat += "AntiMatter Control Panel
" - dat += "Close
" - dat += "Refresh
" - dat += "Force Shielding Update

" - dat += "Status: [(active?"Injecting":"Standby")]
" - dat += "Toggle Status
" +/obj/machinery/power/am_control_unit/ui_interact(mob/user, ui_key = "main") + if(!user) + return - dat += "Instability: [stability]%
" - dat += "Reactor parts: [linked_shielding.len]
"//TODO: perhaps add some sort of stability check - dat += "Cores: [linked_cores.len]

" - dat += "-Current Efficiency: [reported_core_efficiency]
" - dat += "-Average Stability: [stored_core_stability] (update)
" - dat += "Last Produced: [stored_power]
" + var/list/fueljar_data=null + if(fueljar) + fueljar_data=list( + "fuel"=fueljar.fuel, + "fuel_max"=fueljar.fuel_max, + "injecting"=fuel_injection + ) - dat += "Fuel: " - if(!fueljar) - dat += "
No fuel receptacle detected." + var/list/data = list( + "active" = active, + //"stability" = stability, + "linked_shields" = linked_shielding.len, + "linked_cores" = linked_cores.len, + "efficiency" = reported_core_efficiency, + "stability" = stored_core_stability, + "stored_power" = stored_power, + "fueljar" = fueljar_data, + "siliconUser" = istype(user, /mob/living/silicon) + ) + + var/datum/nanoui/ui = nanomanager.get_open_ui(user, src, ui_key) + if (!ui) + // the ui does not exist, so we'll create a new one + ui = new(user, src, ui_key, "ame.tmpl", "Antimatter Control Unit", 500, data["siliconUser"] ? 465 : 390) + // When the UI is first opened this is the data it will use + ui.set_initial_data(data) + ui.open() + // Auto update every Master Controller tick + ui.set_auto_update(1) else - dat += "Eject
" - dat += "- [fueljar.fuel]/[fueljar.fuel_max] Units
" - - dat += "- Injecting: [fuel_injection] units
" - dat += "- --|++

" - - - user << browse(dat, "window=AMcontrol;size=420x500") - onclose(user, "AMcontrol") - return + // The UI is already open so push the new data to it + ui.push_data(data) + return /obj/machinery/power/am_control_unit/Topic(href, href_list) - ..() + if(..()) + return 1 + if(href_list["close"]) + if(usr.machine == src) + usr.unset_machine() + return 1 //Ignore input if we are broken or guy is not touching us, AI can control from a ways away - if(stat & (BROKEN|NOPOWER) || (get_dist(src, usr) > 1 && !istype(usr, /mob/living/silicon/ai))) + if(stat & (BROKEN|NOPOWER)) usr.unset_machine() usr << browse(null, "window=AMcontrol") return @@ -299,26 +353,34 @@ if(href_list["togglestatus"]) toggle_power() + message_admins("AME toggled [active?"on":"off"] by [usr.real_name] ([usr.key]) at ([x],[y],[z] - JMP)",0,1) + return 1 if(href_list["refreshicons"]) - update_shield_icons = 1 + update_shield_icons = 2 // Fuck it + return 1 if(href_list["ejectjar"]) if(fueljar) - fueljar.loc = src.loc + message_admins("AME fuel jar ejected by [usr.real_name] ([usr.key]) at ([x],[y],[z] - JMP)",0,1) + fueljar.forceMove(src.loc) fueljar = null //fueljar.control_unit = null currently it does not care where it is //update_icon() when we have the icon for it + return 1 - if(href_list["strengthup"]) - fuel_injection++ - - if(href_list["strengthdown"]) - fuel_injection-- - if(fuel_injection < 0) fuel_injection = 0 + if(href_list["set_strength"]) + var/newval = input("Enter new injection strength") as num|null + if(isnull(newval)) + return + fuel_injection=newval + fuel_injection=max(1,fuel_injection) + message_admins("AME injection strength set to [fuel_injection] by [usr.real_name] ([usr.key]) at ([x],[y],[z] - JMP)",0,1) + return 1 if(href_list["refreshstability"]) check_core_stability() + return 1 updateDialog() - return \ No newline at end of file + return 1 diff --git a/code/modules/power/antimatter/engine.dm b/code/modules/power/antimatter/engine.dm index a2d4a38ca04..a1ff0845c98 100644 --- a/code/modules/power/antimatter/engine.dm +++ b/code/modules/power/antimatter/engine.dm @@ -38,16 +38,18 @@ /obj/machinery/power/am_engine/injector/attackby(obj/item/weapon/fuel/F, mob/user) - if( (stat & BROKEN) || !connected) return + if( (stat & BROKEN) || !connected) + return if(istype(F, /obj/item/weapon/fuel/H)) if(injecting) - user << "Theres already a fuel rod in the injector!" + to_chat(user, "There's already a fuel rod in the injector!") return - user << "You insert the rod into the injector" + to_chat(user, "You insert the rod into the injector.") injecting = 1 var/fuel = F.fuel qdel(F) + F = null spawn( 300 ) injecting = 0 new/obj/item/weapon/fuel(src.loc) @@ -55,12 +57,13 @@ if(istype(F, /obj/item/weapon/fuel/antiH)) if(injecting) - user << "Theres already a fuel rod in the injector!" + to_chat(user, "There's already a fuel rod in the injector!") return - user << "You insert the rod into the injector" + to_chat(user, "You insert the rod into the injector.") injecting = 1 var/fuel = F.fuel qdel(F) + F = null spawn( 300 ) injecting = 0 new /obj/item/weapon/fuel(src.loc) @@ -83,6 +86,7 @@ /obj/machinery/power/am_engine/engine/proc/engine_go() + if( (!src.connected) || (stat & BROKEN) ) return @@ -109,7 +113,7 @@ antiH_fuel = residual_matter for(var/mob/M in hearers(src, null)) - M.show_message(text("\red You hear a loud bang!")) + M.show_message(text("You hear a loud bang!")) //Q = k x (delta T) @@ -123,6 +127,7 @@ /obj/machinery/power/am_engine/engine/proc/engine_process() + do if( (!src.connected) || (stat & BROKEN) ) return @@ -161,7 +166,7 @@ if(energy > convert2energy(8e-12)) //TOO MUCH ENERGY for(var/mob/M in hearers(src, null)) - M.show_message(text("\red You hear a loud whirring!")) + M.show_message(text("You hear a loud whirring!")) sleep(20) //Q = k x (delta T) @@ -180,7 +185,7 @@ if(energy > convert2energy(8e-12)) //FAR TOO MUCH ENERGY STILL for(var/mob/M in hearers(src, null)) - M.show_message(text("\red BANG!")) + M.show_message(text("BANG!")) new /obj/effect/bhole(src.loc) else //this amount of energy is okay so it does the proper output thing @@ -204,4 +209,4 @@ stopping = 0 - return \ No newline at end of file + return diff --git a/code/modules/power/antimatter/fuel.dm b/code/modules/power/antimatter/fuel.dm index 56098a0b56d..b700253c5cf 100644 --- a/code/modules/power/antimatter/fuel.dm +++ b/code/modules/power/antimatter/fuel.dm @@ -1,5 +1,5 @@ /obj/item/weapon/fuel - name = "Magnetic Storage Ring" + name = "nagnetic storage ring" desc = "A magnetic storage ring." icon = 'icons/obj/items.dmi' icon_state = "rcdammo" @@ -11,12 +11,12 @@ var/content = null /obj/item/weapon/fuel/H - name = "Hydrogen storage ring" + name = "hydrogen storage ring" content = "Hydrogen" fuel = 1e-12 //pico-kilogram /obj/item/weapon/fuel/antiH - name = "Anti-Hydrogen storage ring" + name = "anti-hydrogen storage ring" content = "Anti-Hydrogen" fuel = 1e-12 //pico-kilogram @@ -26,16 +26,17 @@ if(istype(F, /obj/item/weapon/fuel/antiH)) src.fuel += F.fuel F.fuel = 0 - user << "You have added the anti-Hydrogen to the storage ring, it now contains [src.fuel]kg" + to_chat(user, "You add the anti-Hydrogen to the storage ring. It now contains [src.fuel]kg.") if(istype(F, /obj/item/weapon/fuel/H)) src.fuel += F.fuel qdel(F) + F = null src:annihilation(src.fuel) if(istype(src, /obj/item/weapon/fuel/H)) if(istype(F, /obj/item/weapon/fuel/H)) src.fuel += F.fuel F.fuel = 0 - user << "You have added the Hydrogen to the storage ring, it now contains [src.fuel]kg" + to_chat(user, "You add the Hydrogen to the storage ring. It now contains [src.fuel]kg") if(istype(F, /obj/item/weapon/fuel/antiH)) src.fuel += F.fuel qdel(src) @@ -43,6 +44,7 @@ /obj/item/weapon/fuel/antiH/proc/annihilation(var/mass) + var/strength = convert2energy(mass) if (strength < 773.0) @@ -67,21 +69,23 @@ return -/obj/item/weapon/fuel/examine(mob/user) - if(get_dist(src, user) <= 1) - user << "A magnetic storage ring, it contains [fuel]kg of [content ? content : "nothing"]." +/obj/item/weapon/fuel/examine() + ..() + to_chat(user, "A magnetic storage ring containing [fuel]kg of [content ? content : "nothing"].") /obj/item/weapon/fuel/proc/injest(mob/M as mob) switch(content) if("Anti-Hydrogen") + mob << span("notice", "That was not a very bright idea.") M.gib() if("Hydrogen") - M << "\blue You feel very light, as if you might just float away..." + to_chat(M, "You feel very light, as if you might just float away...") qdel(src) return /obj/item/weapon/fuel/attack(mob/M as mob, mob/user as mob) if (user != M) + //If you come from the distant future and happen to find this unincluded and derelict file, you may be wondering what this is. In truth, it's better that you don't know. var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human( ) O.source = user O.target = M @@ -95,5 +99,5 @@ return else for(var/mob/O in viewers(M, null)) - O.show_message(text("\red [M] ate the [content ? content : "empty canister"]!"), 1) + O.show_message(text("\The [M] eats the [content ? content : "empty canister"]!"), 1) src.injest(M) diff --git a/code/modules/power/antimatter/shielding.dm b/code/modules/power/antimatter/shielding.dm index 4f89687fb4e..ece15f20691 100644 --- a/code/modules/power/antimatter/shielding.dm +++ b/code/modules/power/antimatter/shielding.dm @@ -3,15 +3,19 @@ proc/cardinalrange(var/center) var/list/things = list() for(var/direction in cardinal) var/turf/T = get_step(center, direction) - if(!T) continue + if(!T) + continue things += T.contents return things /obj/machinery/am_shielding name = "antimatter reactor section" - desc = "This device was built using a phoron life-form that seems to increase phoron's natural ability to react with neutrinos while reducing the combustibility." + desc = "A shielding component for an antimatter reactor. Looks delicate." + description_info = "Antimatter shielding sections must be beside an anchored control unit or another shielding section. If either are destroyed, the section will disappear." + description_antag = "Antimatter shielding sections are delicate. Attacking the shielding unit with a damaging object will reduce its stability, as will explosions. If the stability hits zero, the reactor may explode." - icon = 'icons/obj/machines/antimatter.dmi' + //icon = 'icons/obj/machines/antimatter.dmi' + icon = 'icons/obj/machines/new_ame.dmi' icon_state = "shield" anchored = 1 density = 1 @@ -24,14 +28,42 @@ proc/cardinalrange(var/center) var/processing = 0//To track if we are in the update list or not, we need to be when we are damaged and if we ever var/stability = 100//If this gets low bad things tend to happen var/efficiency = 1//How many cores this core counts for when doing power processing, phoron in the air and stability could affect this + var/coredirs = 0 + var/dirs = 0 + var/mapped = 0 //Set to 1 to ignore usual suicide if it doesn't immediately find a control_unit +// Stupidly easy way to use it in maps +/obj/machinery/am_shielding/map + mapped = 1 -/obj/machinery/am_shielding/New(loc) - ..(loc) - spawn(10) +/obj/machinery/am_shielding/New(loc, var/obj/machinery/power/am_control_unit/AMC) + ..() + if(!AMC) + if (!mapped) + WARNING("AME sector somehow created without a parent control unit!") controllerscan() - return + return + link_control(AMC) + remove_machine(src) + spawn (10) + update_icon() +/obj/machinery/am_shielding/proc/link_control(var/obj/machinery/power/am_control_unit/AMC) + if(!istype(AMC)) + return 0 + if(control_unit && control_unit != AMC) + return 0//Already have one + control_unit = AMC + return control_unit.add_shielding(src,1) + +/obj/machinery/am_shielding/Destroy() + if(control_unit) + control_unit.remove_shielding(src) + if(processing) + shutdown_core() + visible_message("\The [src.name] melts!") + //Might want to have it leave a mess on the floor but no sprites for now + ..() /obj/machinery/am_shielding/proc/controllerscan(var/priorscan = 0) //Make sure we are the only one here @@ -39,9 +71,9 @@ proc/cardinalrange(var/center) qdel(src) return for(var/obj/machinery/am_shielding/AMS in loc.contents) - if(AMS == src) continue - spawn(0) - qdel(src) + if(AMS == src) + continue + qdel(src) return //Search for shielding first @@ -49,41 +81,37 @@ proc/cardinalrange(var/center) if(AMS && AMS.control_unit && link_control(AMS.control_unit)) break - if(!control_unit)//No other guys nearby look for a control unit - for(var/direction in cardinal) + if(!control_unit)//No other guys nearby, look for a control unit for(var/obj/machinery/power/am_control_unit/AMC in cardinalrange(src)) if(AMC.add_shielding(src)) break - - if(!control_unit) - if(!priorscan) - spawn(20) + if(!mapped) // Prevent rescanning and suicide if it's part of the map + if(!priorscan) + sleep(20) controllerscan(1)//Last chance - return - spawn(0) + return qdel(src) - return +// Find surrounding unconnected shielding and add them to our controller +/obj/machinery/am_shielding/proc/assimilate() + if(!control_unit) + return // nothing to share :'^( + for(var/obj/machinery/am_shielding/neighbor in cardinalrange(src)) + if(neighbor && !neighbor.control_unit) + neighbor.link_control(control_unit) + neighbor.assimilate() // recursion is fun, right? -/obj/machinery/am_shielding/Destroy() - if(control_unit) control_unit.remove_shielding(src) - if(processing) shutdown_core() - visible_message("\red The [src.name] melts!") - //Might want to have it leave a mess on the floor but no sprites for now - ..() - return - - -/obj/machinery/am_shielding/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 +/obj/machinery/am_shielding/Cross(atom/movable/mover, turf/target, height=1.5, air_group = 0) + if(air_group || (height==0)) + return 1 return 0 /obj/machinery/am_shielding/process() - if(!processing) . = PROCESS_KILL + if(!processing) + . = PROCESS_KILL //TODO: core functions and stability //TODO: think about checking the airmix for phoron and increasing power output - return /obj/machinery/am_shielding/emp_act()//Immune due to not really much in the way of electronics. @@ -98,110 +126,130 @@ proc/cardinalrange(var/center) stability -= 40 if(3.0) stability -= 20 - check_stability() - return - - -/obj/machinery/am_shielding/bullet_act(var/obj/item/projectile/Proj) - if(Proj.check_armour != "bullet") - stability -= Proj.force/2 - return 0 - /obj/machinery/am_shielding/update_icon() - overlays.Cut() + overlays.len = 0 + coredirs = 0 + dirs = 0 for(var/direction in alldirs) - var/machine = locate(/obj/machinery, get_step(loc, direction)) - if((istype(machine, /obj/machinery/am_shielding) && machine:control_unit == control_unit)||(istype(machine, /obj/machinery/power/am_control_unit) && machine == control_unit)) - overlays += "shield_[direction]" + var/turf/T = get_step(loc, direction) + for(var/obj/machinery/machine in T) + // Detect cores + if((istype(machine, /obj/machinery/am_shielding) && machine:control_unit == control_unit && machine:processing)) + coredirs |= direction + + // Detect cores, shielding, and control boxen. + if(direction in cardinal) + if((istype(machine, /obj/machinery/am_shielding) && machine:control_unit == control_unit) || (istype(machine, /obj/machinery/power/am_control_unit) && machine == control_unit)) + dirs |= direction + + // If we're next to a core, set the prefix. + var/prefix = "" + var/icondirs = dirs + + if(coredirs) + prefix="core" + + // Set our overlay + icon_state = "[prefix]shield_[icondirs]" if(core_check()) - overlays += "core" - if(!processing) setup_core() - else if(processing) shutdown_core() + icon_state = "core[control_unit && control_unit.active]" + if(!processing) + setup_core() + else if(processing) + shutdown_core() /obj/machinery/am_shielding/attackby(obj/item/W, mob/user) - if(!istype(W) || !user) return + if(!istype(W) || !user) + return if(W.force > 10) stability -= W.force/2 check_stability() ..() return - - -//Call this to link a detected shilding unit to the controller -/obj/machinery/am_shielding/proc/link_control(var/obj/machinery/power/am_control_unit/AMC) - if(!istype(AMC)) return 0 - if(control_unit && control_unit != AMC) return 0//Already have one - control_unit = AMC - control_unit.add_shielding(src,1) - return 1 - - //Scans cards for shields or the control unit and if all there it /obj/machinery/am_shielding/proc/core_check() for(var/direction in alldirs) - var/machine = locate(/obj/machinery, get_step(loc, direction)) - if(!machine) return 0//Need all for a core - if(!istype(machine, /obj/machinery/am_shielding) && !istype(machine, /obj/machinery/power/am_control_unit)) return 0 + var/found_am_device=0 + for(var/obj/machinery/machine in get_step(loc, direction)) + if(!machine) + continue + if(istype(machine, /obj/machinery/am_shielding) || istype(machine, /obj/machinery/power/am_control_unit)) + found_am_device=1 + break + if(!found_am_device) + return 0 return 1 /obj/machinery/am_shielding/proc/setup_core() processing = 1 - machines.Add(src) - if(!control_unit) return + if(!control_unit) + return control_unit.linked_cores.Add(src) control_unit.reported_core_efficiency += efficiency - return /obj/machinery/am_shielding/proc/shutdown_core() processing = 0 - if(!control_unit) return + if(!control_unit) + return control_unit.linked_cores.Remove(src) control_unit.reported_core_efficiency -= efficiency - return /obj/machinery/am_shielding/proc/check_stability(var/injecting_fuel = 0) - if(stability > 0) return + if(stability > 0) + return if(injecting_fuel && control_unit) control_unit.exploding = 1 - if(src) - qdel(src) - return - + qdel(src) /obj/machinery/am_shielding/proc/recalc_efficiency(var/new_efficiency)//tbh still not 100% sure how I want to deal with efficiency so this is likely temp - if(!control_unit || !processing) return + if(!control_unit || !processing) + return if(stability < 50) new_efficiency /= 2 control_unit.reported_core_efficiency += (new_efficiency - efficiency) efficiency = new_efficiency - return /obj/item/device/am_shielding_container name = "packaged antimatter reactor section" - desc = "A small storage unit containing an antimatter reactor section. To use place near an antimatter control unit or deployed antimatter reactor section and use a multitool to activate this package." + desc = "A section of antimatter reactor shielding. Do not eat." + description_info = "To deploy, drop near an antimatter control unit or an existing deployed section and use your multitool on it." icon = 'icons/obj/machines/antimatter.dmi' icon_state = "box" item_state = "electronic" - w_class = 4.0 - flags = CONDUCT + siemens_coefficient = 1 throwforce = 5 throw_speed = 1 throw_range = 2 - matter = list(DEFAULT_WALL_MATERIAL = 100, "waste" = 2000) /obj/item/device/am_shielding_container/attackby(var/obj/item/I, var/mob/user) - if(istype(I, /obj/item/device/multitool) && istype(src.loc,/turf)) - new/obj/machinery/am_shielding(src.loc) - qdel(src) - return + if(ismultitool(I) && isturf(loc)) + if(locate(/obj/machinery/am_shielding/) in loc) + to_chat(user, "\icon[src]There is already an antimatter reactor section there.") + return + + //Search for shielding first + for(var/obj/machinery/am_shielding/AMS in cardinalrange(src)) + if(AMS.control_unit) + new/obj/machinery/am_shielding(src.loc, AMS.control_unit) + qdel(src) + return + + //No other guys nearby, look for a control unit + var/obj/machinery/power/am_control_unit/AMC = locate() in cardinalrange(src) + if(AMC && AMC.anchored) + new/obj/machinery/am_shielding(src.loc, AMC) + qdel(src) + else //Stranded & Alone + to_chat(user, "\icon[src]Couldn't connect to an Antimatter Control Unit.") + return + ..() - return \ No newline at end of file diff --git a/html/changelogs/lohikar-ame.yml b/html/changelogs/lohikar-ame.yml new file mode 100644 index 00000000000..3c494891011 --- /dev/null +++ b/html/changelogs/lohikar-ame.yml @@ -0,0 +1,4 @@ +author: Lohikar +delete-after: True +changes: + - rscadd: "A new engine type is now orderable from cargo." diff --git a/icons/obj/machines/new_ame.dmi b/icons/obj/machines/new_ame.dmi new file mode 100644 index 0000000000000000000000000000000000000000..2c7c6b24748528b04b9adbbdc8684f63db396fcf GIT binary patch literal 22056 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

9b^sSeY)fe)b4-^U9p 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 VU4dsB_y8;fxomcKqC4#W{XZc@^1uK9 literal 0 HcmV?d00001 diff --git a/nano/templates/ame.tmpl b/nano/templates/ame.tmpl new file mode 100644 index 00000000000..92501ee4655 --- /dev/null +++ b/nano/templates/ame.tmpl @@ -0,0 +1,56 @@ +

+
Status:
+ {{if data.active}} +
Injecting
+ {{else}} +
Standby
+ {{/if}} +  {{:helper.link("Toggle Status", "gear", {"togglestatus":1},null)}} +
+{{if !data.fueljar}} +
No fuel jar detected.
+{{else}} +
+
+
Fuel:
+
{{:data.fueljar.fuel}}/{{:data.fueljar.fuel_max}}
+ {{:helper.link("Eject", "eject", {"ejectjar":1},null,'floatRight')}} +
+
+
Injecting:
+
+ {{:helper.link(data.fueljar.injecting+" units", 'carat-2-n-s', {'set_strength': 1})}} +
+
+
+{{/if}} +
+
+
Stability:
+
+ {{:helper.displayBar(data.stability,0,100,"good")}} + {{:data.stability}}% +
+
+
+
Shielding Count:
+
{{:data.linked_shields}}
+
+
+
Cores:
+
{{:data.linked_cores}}
+ {{:helper.link("Refresh Parts",null,{"refreshicons" : 1},(data.active?"disabled":null),'floatRight')}} +
+
+
Current Efficiency:
+
{{:data.efficiency}}
+
+
+
Average Efficiency:
+
{{:data.stability}}
+
+
+
Last Produced:
+
{{:data.stored_power}}
+
+
\ No newline at end of file