diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index a09e285f3d2..077215afa1c 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -147,6 +147,11 @@ var/assistantlimit = 0 //enables assistant limiting var/assistantratio = 2 //how many assistants to security members + var/emag_energy = -1 + var/emag_starts_charged = 1 + var/emag_recharge_rate = 0 + var/emag_recharge_ticks = 0 + /datum/configuration/New() . = ..() var/list/L = typesof(/datum/game_mode) - /datum/game_mode @@ -544,6 +549,14 @@ config.limbs_can_break = value if("respawn_delay") config.respawn_delay = value + if("emag_energy") + config.emag_energy = value + if("emag_starts_charged") + config.emag_starts_charged = value + if("emag_recharge_rate") + config.emag_recharge_rate = value + if("emag_recharge_ticks") + config.emag_recharge_ticks = value else diary << "Unknown setting in configuration: '[name]'" diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 6b2606cffcb..3a61c67f387 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -49,6 +49,8 @@ autoclose = 1 var/busy = 0 + emag_cost = 1 // in MJ + /obj/machinery/door/airlock/Destroy() if(wires) wires.Destroy() @@ -105,6 +107,7 @@ name = "Vault" icon = 'icons/obj/doors/vault.dmi' opacity = 1 + emag_cost = 2 // in MJ assembly_type = /obj/structure/door_assembly/door_assembly_highsecurity //Until somebody makes better sprites. /obj/machinery/door/airlock/freezer @@ -284,6 +287,7 @@ name = "High Tech Security Airlock" icon = 'icons/obj/doors/hightechsecurity.dmi' assembly_type = /obj/structure/door_assembly/door_assembly_highsecurity + emag_cost = 2 // in MJ /* About the new airlock wires panel: diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 2f7c2e1ab40..ff36b3f0e85 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -116,7 +116,15 @@ Class Procs: var/custom_aghost_alerts=0 var/panel_open = 0 - var/machine_flags = 0//this is what you use for flags. + /** + * Machine construction/destruction/emag flags. + */ + var/machine_flags = 0 // This is what you use for flags. + + /** + * Emag energy cost. + */ + var/emag_cost = 0 // Emag energy cost. var/inMachineList = 1 // For debugging. @@ -447,29 +455,49 @@ Class Procs: return 1 return -1 +/** + * Handle emags. + * @param user /mob The mob that used the emag. + */ /obj/machinery/proc/emag(mob/user as mob) - return + // Disable emaggability. + machine_flags &= ~EMAGGABLE + +/** + * Returns the cost of emagging this machine (emag_cost by default) + * @param user /mob The mob that used the emag. + * @param emag /obj/item/weapon/card/emag The emag used on this device. + * @return number Cost to emag. + */ +/obj/machinery/proc/getEmagCost(var/mob/user, var/obj/item/weapon/card/emag/emag) + return emag_cost /obj/machinery/attackby(var/obj/O, var/mob/user) - if(istype(O, /obj/item/weapon/card/emag) && machine_flags &EMAGGABLE) - emag(user) - return - if(istype(O, /obj/item/weapon/wrench) && machine_flags &WRENCHMOVE) //make sure this is BEFORE the fixed2work check + if(istype(O, /obj/item/weapon/card/emag) && machine_flags & EMAGGABLE) + var/obj/item/weapon/card/emag/E = O + if(E.canUse(user,src)) + emag(user) + return + + if(istype(O, /obj/item/weapon/wrench) && machine_flags & WRENCHMOVE) //make sure this is BEFORE the fixed2work check if(!panel_open) return wrenchAnchor(user) else user <<"\The [src]'s maintenance panel must be closed first!" return -1 //we return -1 rather than 0 for the if(..()) checks - if(istype(O, /obj/item/weapon/screwdriver) && machine_flags &SCREWTOGGLE) + + if(istype(O, /obj/item/weapon/screwdriver) && machine_flags & SCREWTOGGLE) return togglePanelOpen(O, user) - if(istype(O, /obj/item/weapon/crowbar) && machine_flags &CROWDESTROY) + + if(istype(O, /obj/item/weapon/crowbar) && machine_flags & CROWDESTROY) if(panel_open) if(crowbarDestroy(user) == 1) qdel(src) return 1 else return -1 - if(!anchored && machine_flags &FIXED2WORK) + + if(!anchored && machine_flags & FIXED2WORK) return user << "\The [src] must be anchored first!" /obj/machinery/proc/shock(mob/user, prb, var/siemenspassed = -1) @@ -485,4 +513,4 @@ Class Procs: if (electrocute_mob(user, get_area(src), src, siemenspassed)) return 1 else - return -1 + return -1 diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 7152347ee52..c21dd101d4c 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -60,7 +60,99 @@ icon_state = "emag" item_state = "card-id" origin_tech = "magnets=2;syndicate=2" - var/uses = 10 + + /** + * Number of uses left. -1 = infinite + * (Note: Some devices can use more than 1 use, so this is just called "energy") + * @since 10-28-2014 + */ + var/energy = -1 + + /** + * Max energy per emag. -1 = infinite + * @since 10-28-2014 + */ + var/max_energy = -1 + + /** + * Every X ticks, add [recharge_rate] energy. + * @since 10-28-2014 + */ + var/recharge_ticks = 0 + + /** + * Every [recharge_ticks] ticks, add X energy. + * @since 10-28-2014 + */ + var/recharge_rate = 0 + + var/nticks=0 + +/obj/item/weapon/card/emag/New(var/loc, var/disable_tuning=0) + ..(loc) + + // For standardized subtypes, once they're established. + if(disable_tuning) + return + + // Tuning tools. + ////////////////// + if(config.emag_energy != -1) + max_energy = config.emag_energy + + if(config.emag_starts_charged) + energy = max_energy + + if(config.emag_recharge_rate != 0) + recharge_rate = config.emag_recharge_rate + + if(config.emag_recharge_ticks > 0) + recharge_ticks = config.emag_recharge_ticks + +/obj/item/weapon/card/emag/process() + if(energy < max_energy) + // Specified number of ticks has passed? Add charge. + if(nticks >= recharge_ticks) + nticks = 0 + energy = min(energy + recharge_rate, max_energy) + nticks ++ + else + nticks = 0 + processing_objects.Remove(src) + +/obj/item/weapon/card/emag/proc/canUse(var/mob/user, var/obj/machinery/M) + // We've already checked for emaggability. All we do here is check cost. + + // Infinite uses? Just return true. + if(energy < 0) + return 1 + + var/cost=M.getEmagCost(user,src) + + // Free to emag? Return true every time. + if(cost == 0) + return 1 + + if(energy >= cost) + energy -= cost + + // Start recharging, if we're supposed to. + if(energy < max_energy && recharge_rate && recharge_ticks) + if(!(src in processing_objects)) + processing_objects.Add(src) + + return 1 + + return 0 + +/obj/item/weapon/card/emag/examine() + ..() + if(energy==-1) + usr << "\The [name] has a tiny fusion generator for power." + else + usr << "This [name] has [energy]MJ left in its capacitor ([max_energy]MJ capacity)." + if(recharge_rate && recharge_ticks) + usr << "A small label on a thermocouple notes that it recharges at a rate of [recharge_rate]MJ for every [recharge_ticks>1?"":recharge_ticks] oscillator tick[recharge_ticks>1?"s":""]." /obj/item/weapon/card/id name = "identification card" diff --git a/config-example/game_options.txt b/config-example/game_options.txt index 949dc9622e5..419d71714bd 100644 --- a/config-example/game_options.txt +++ b/config-example/game_options.txt @@ -58,4 +58,24 @@ ANIMAL_DELAY 0 # Define how large an explosion can be. ## DEFAULT: 14 -MAX_EXPLOSION_RANGE 14 \ No newline at end of file +MAX_EXPLOSION_RANGE 14 + +################# +### EMAG SHIT ### +################# + +# Max energy an emag can hold. +## DEFAULT: -1 (infinite) +EMAG_ENERGY -1 + +# Whether an emag starts charged (1), or uncharged (0). +## DEFAULT: 1 (charged) +EMAG_STARTS_CHARGED 1 + +# Amount of energy to add per recharge cycle. +## DEFAULT: 0 +EMAG_RECHARGE_RATE 0 + +# Number of ticks per recharge cycle +## DEFAULT: 0 (no recharging) +EMAG_RECHARGE_TICKS 0 \ No newline at end of file