diff --git a/code/datums/material_container.dm b/code/datums/material_container.dm
index 21752e31bd6..daae39f0819 100644
--- a/code/datums/material_container.dm
+++ b/code/datums/material_container.dm
@@ -53,7 +53,8 @@
M.amount += amt
total_amount += amt
else
- for(var/datum/material/M in materials)
+ for(var/i in materials)
+ var/datum/material/M = materials[i]
M.amount += amt
total_amount += amt
return (total_amount - total_amount_saved)
@@ -135,7 +136,7 @@
return TRUE
else if(istype(mats))
for(var/M in mats)
- if(materials[M] && mats[M] <= materials[M])
+ if(materials[M] && (mats[M] <= materials[M]))
continue
else
return FALSE
@@ -276,4 +277,4 @@
/datum/material/bananium/New()
..()
material_type = MAT_BANANIUM
- sheet_type = /obj/item/stack/sheet/mineral/bananium
\ No newline at end of file
+ sheet_type = /obj/item/stack/sheet/mineral/bananium
diff --git a/code/game/machinery/droneDispenser.dm b/code/game/machinery/droneDispenser.dm
index c9836d94f24..56bb85cf53b 100644
--- a/code/game/machinery/droneDispenser.dm
+++ b/code/game/machinery/droneDispenser.dm
@@ -1,15 +1,23 @@
+#define DRONE_PRODUCTION "production"
+#define DRONE_RECHARGING "recharging"
+#define DRONE_READY "ready"
+
/obj/machinery/droneDispenser //Most customizable machine 2015
name = "drone shell dispenser"
- desc = "A hefty machine that, when supplied with metal and glass, will periodically create a drone shell. Does not need to be manually operated."
+ desc = "A hefty machine that, when supplied with metal and glass, \
+ will periodically create a drone shell. \
+ Does not need to be manually operated."
+
icon = 'icons/obj/machines/droneDispenser.dmi'
icon_state = "on"
anchored = 1
density = 1
- var/health = 100 //The health of the drone dispenser. It will break if it goes below 0
+ var/health = 100
var/max_health = 100
- var/icon_off = "off" //These variables allow for different icons when creating custom dispensers
+ //These variables allow for different icons when creating custom dispensers
+ var/icon_off = "off"
var/icon_on = "on"
var/icon_recharging = "recharge"
var/icon_creating = "make"
@@ -20,9 +28,16 @@
var/glass_cost = 1000
var/power_used = 1000
- var/droneMadeRecently = 0
+ var/mode = DRONE_READY
+ var/timer
var/cooldownTime = 1800 //3 minutes
- var/dispense_type = /obj/item/drone_shell //The item the dispenser will create
+ var/production_time = 30
+ //The item the dispenser will create
+ var/dispense_type = /obj/item/drone_shell
+
+ // The maximum number of "idle" drone shells it will make before
+ // ceasing production. Set to 0 for infinite.
+ var/maximum_idle = 3
var/work_sound = 'sound/items/rped.ogg'
var/create_sound = 'sound/items/Deconstruct.ogg'
@@ -31,7 +46,8 @@
var/begin_create_message = "whirs to life!"
var/end_create_message = "dispenses a drone shell."
var/recharge_message = "pings."
- var/recharging_text = "It is whirring and clicking. It seems to be recharging."
+ var/recharging_text = "It is whirring and clicking. \
+ It seems to be recharging."
var/break_message = "lets out a tinny alarm before falling dark."
var/break_sound = 'sound/machines/warning-buzzer.ogg'
@@ -39,15 +55,14 @@
/obj/machinery/droneDispenser/New()
..()
health = max_health
- materials = new(src, list(MAT_METAL=1, MAT_GLASS=1), MINERAL_MATERIAL_AMOUNT*MAX_STACK_SIZE*2)
+ materials = new(src, list(MAT_METAL=1, MAT_GLASS=1),
+ MINERAL_MATERIAL_AMOUNT*MAX_STACK_SIZE*2)
+
using_materials = list(MAT_METAL=metal_cost, MAT_GLASS=glass_cost)
- SSmachine.processing |= src
/obj/machinery/droneDispenser/Destroy()
- SSmachine.processing -= src
qdel(materials)
- materials = null
- return ..()
+ . = ..()
/obj/machinery/droneDispenser/preloaded/New()
..()
@@ -55,9 +70,11 @@
/obj/machinery/droneDispenser/syndrone //Please forgive me
name = "syndrone shell dispenser"
- desc = "A suspicious machine that will create Syndicate exterminator drones when supplied with metal and glass. Disgusting."
+ desc = "A suspicious machine that will create Syndicate \
+ exterminator drones when supplied with metal and glass. Disgusting."
dispense_type = /obj/item/drone_shell/syndrone
- cooldownTime = 100 //If we're gonna be a jackass, go the full mile - 10 second recharge timer
+ //If we're gonna be a jackass, go the full mile - 10 second recharge timer
+ cooldownTime = 100
end_create_message = "dispenses a suspicious drone shell."
/obj/machinery/droneDispenser/syndrone/New()
@@ -66,15 +83,20 @@
/obj/machinery/droneDispenser/syndrone/badass //Please forgive me
name = "badass syndrone shell dispenser"
- desc = "A suspicious machine that will create Syndicate exterminator drones when supplied with metal and glass. Disgusting. This one seems ominous."
+ desc = "A suspicious machine that will create Syndicate \
+ exterminator drones when supplied with metal and glass. \
+ Disgusting. This one seems ominous."
dispense_type = /obj/item/drone_shell/syndrone/badass
end_create_message = "dispenses a ominous suspicious drone shell."
// I don't need your forgiveness, this is awesome.
/obj/machinery/droneDispenser/snowflake
name = "snowflake drone shell dispenser"
- desc = "A hefty machine that, when supplied with metal and glass, will periodically create a snowflake drone shell. Does not need to be manually operated."
- dispense_type = /obj/item/drone_shell/snowflake //The item the dispenser will create
+ desc = "A hefty machine that, when supplied with metal and glass, \
+ will periodically create a snowflake drone shell. \
+ Does not need to be manually operated."
+ dispense_type = /obj/item/drone_shell/snowflake
+ end_create_message = "dispenses a snowflake drone shell."
// Those holoprojectors aren't cheap
metal_cost = 2000
glass_cost = 2000
@@ -84,9 +106,12 @@
..()
materials.insert_amount(10000)
-/obj/machinery/droneDispenser/hivebot //An example of a custom drone dispenser. This one requires no materials and creates basic hivebots
+// An example of a custom drone dispenser.
+// This one requires no materials and creates basic hivebots
+/obj/machinery/droneDispenser/hivebot
name = "hivebot fabricator"
- desc = "A large, bulky machine that whirs with activity, steam hissing from vents in its sides."
+ desc = "A large, bulky machine that whirs with activity, \
+ steam hissing from vents in its sides."
icon = 'icons/obj/objects.dmi'
icon_state = "hivebot_fab"
icon_off = "hivebot_fab"
@@ -105,7 +130,8 @@
/obj/machinery/droneDispenser/swarmer
name = "swarmer fabricator"
- desc = "An alien machine of unknown origin. It whirs and hums with green-blue light, the air above it shimmering."
+ desc = "An alien machine of unknown origin. \
+ It whirs and hums with green-blue light, the air above it shimmering."
icon = 'icons/obj/machines/gateway.dmi'
icon_state = "toffcenter"
icon_off = "toffcenter"
@@ -115,9 +141,12 @@
metal_cost = 0
glass_cost = 0
cooldownTime = 300 //30 seconds
+ maximum_idle = 0 // Swarmers have no restraint
dispense_type = /obj/item/device/unactivated_swarmer
- begin_create_message = "hums softly as an interface appears above it, scrolling by at unreadable speed."
- end_create_message = "materializes a strange shell, which drops to the ground."
+ begin_create_message = "hums softly as an interface appears above it, \
+ scrolling by at unreadable speed."
+ end_create_message = "materializes a strange shell, which drops to the \
+ ground."
recharging_text = "Its lights are slowly increasing in brightness."
work_sound = 'sound/effects/EMPulse.ogg'
create_sound = 'sound/effects/phasein.ogg'
@@ -126,132 +155,179 @@
/obj/machinery/droneDispenser/examine(mob/user)
..()
- if(droneMadeRecently && !stat && recharging_text)
+ if((mode == DRONE_RECHARGING) && !stat && recharging_text)
user << "[recharging_text]"
if(stat & BROKEN)
- user << "[src] is smoking and steadily buzzing. It seems to be broken."
+ user << "[src] is smoking and steadily buzzing. \
+ It seems to be broken."
if(metal_cost)
- user << "It has [materials.amount(MAT_METAL)] units of metal stored."
+ user << "It has [materials.amount(MAT_METAL)] \
+ units of metal stored."
if(glass_cost)
- user << "It has [materials.amount(MAT_GLASS)] units of glass stored."
+ user << "It has [materials.amount(MAT_GLASS)] \
+ units of glass stored."
/obj/machinery/droneDispenser/power_change()
..()
- if(stat & BROKEN)
- return
+ if(powered())
+ stat &= ~NOPOWER
else
- if(powered())
- stat &= ~NOPOWER
- else
- icon_state = "off"
- stat |= NOPOWER
+ stat |= NOPOWER
+ update_icon()
/obj/machinery/droneDispenser/process()
..()
- if(stat & (NOPOWER|BROKEN) || !anchored)
+ if((stat & (NOPOWER|BROKEN)) || !anchored)
return
- if((metal_cost && glass_cost) && materials.can_use_amount(mats=using_materials))
+
+ if(!materials.has_materials(using_materials))
+ return // We require more minerals
+
+ // We are currently in the middle of something
+ if(timer > world.time)
return
- if(droneMadeRecently)
- icon_state = icon_recharging
- return
- droneMadeRecently = 1
- if(begin_create_message)
- visible_message("[src] [begin_create_message]")
- if(work_sound)
- playsound(src, work_sound, 50, 1)
- icon_state = icon_creating
- sleep(30)
- icon_state = icon_on
- materials.use_amount(using_materials)
- if(power_used)
- use_power(power_used)
- new dispense_type(loc)
- if(create_sound)
- playsound(src, create_sound, 50, 1)
- if(end_create_message)
- visible_message("[src] [end_create_message]")
- icon_state = icon_recharging
- sleep(cooldownTime)
- if(!(stat & BROKEN))
- icon_state = icon_on
- else
+
+ switch(mode)
+ if(DRONE_READY)
+ // If we have X drone shells already on our turf
+ if(maximum_idle && (count_shells() >= maximum_idle))
+ return // then do nothing; check again next tick
+ if(begin_create_message)
+ visible_message("\
+ [src] [begin_create_message]")
+ if(work_sound)
+ playsound(src, work_sound, 50, 1)
+ mode = DRONE_PRODUCTION
+ timer = world.time + production_time
+ update_icon()
+
+ if(DRONE_PRODUCTION)
+ materials.use_amount(using_materials)
+ if(power_used)
+ use_power(power_used)
+
+ new dispense_type(loc)
+
+ if(create_sound)
+ playsound(src, create_sound, 50, 1)
+ if(end_create_message)
+ visible_message("[src] \
+ [end_create_message]")
+
+ mode = DRONE_RECHARGING
+ timer = world.time + cooldownTime
+ update_icon()
+
+ if(DRONE_RECHARGING)
+ if(recharge_sound)
+ playsound(src, recharge_sound, 50, 1)
+ if(recharge_message)
+ visible_message("\
+ [src] [recharge_message]")
+
+ mode = DRONE_READY
+ update_icon()
+
+/obj/machinery/droneDispenser/proc/count_shells()
+ . = 0
+ for(var/a in loc)
+ if(istype(a, dispense_type))
+ .++
+
+/obj/machinery/droneDispenser/update_icon()
+ if(stat & (BROKEN|NOPOWER))
icon_state = icon_off
- droneMadeRecently = 0
- if(recharge_sound)
- playsound(src, recharge_sound, 50, 1)
- if(recharge_message)
- visible_message("[src] [recharge_message]")
+ else if(mode == DRONE_RECHARGING)
+ icon_state = icon_recharging
+ else if(mode == DRONE_PRODUCTION)
+ icon_state = icon_creating
+ else
+ icon_state = icon_on
/obj/machinery/droneDispenser/attackby(obj/item/O, mob/living/user)
if(istype(O, /obj/item/stack))
if(!O.materials[MAT_METAL] && !O.materials[MAT_GLASS])
return ..()
if(!metal_cost && !glass_cost)
- user << "There isn't a place to insert [O]!"
- return
- var/stack = 1
- var/obj/item/stack/sheets
- sheets = O
- stack = (input(user, "How many sheets do you want to add?.", "Drone Dispenser", "[stack]") as num)
- if(stack <= 0)
- return
- if(!user.canUseTopic(src))
+ user << "There isn't a place \
+ to insert [O]!"
return
+ var/obj/item/stack/sheets = O
if(!user.canUnEquip(sheets))
- user << "[O] is stuck to your hand, you can't get it off!"
+ user << "[O] is stuck to your hand, \
+ you can't get it off!"
return
- stack = Clamp(stack, 1, sheets.max_amount)
- stack = materials.insert_stack(sheets, stack)
- if(stack)
- user << "You insert [stack] sheet[stack > 1 ? "s" : ""] into [src]."
+
+ var/used = materials.insert_stack(sheets, sheets.amount)
+
+ if(used)
+ user << "You insert [used] \
+ sheet[used > 1 ? "s" : ""] into [src]."
else
- user << "The [src] can't use [sheets]."
+ user << "The [src] isn't accepting the \
+ [sheets]."
else if(istype(O, /obj/item/weapon/weldingtool))
- if(stat & BROKEN)
- var/obj/item/weapon/weldingtool/WT = O
- if(!WT.isOn())
- return
- if(WT.get_fuel() < 1)
- user << "You need more fuel to complete this task!"
- return
- playsound(src, 'sound/items/Welder.ogg', 50, 1)
- user.visible_message("[user] begins patching up [src] with [WT].", \
- "You begin restoring the damage to [src]...")
- if(!do_after(user, 40/O.toolspeed, target = src))
- return
- if(!src || !WT.remove_fuel(1, user)) return
- user.visible_message("[user] fixes [src]!", \
- "You restore [src] to operation.")
- stat &= ~BROKEN
- health = max_health
- if(!stat)
- icon_state = icon_on
- else
+ if(!(stat & BROKEN))
user << "[src] doesn't need repairs."
+ return
+
+ var/obj/item/weapon/weldingtool/WT = O
+
+ if(!WT.isOn())
+ return
+
+ if(WT.get_fuel() < 1)
+ user << "You need more fuel to \
+ complete this task!"
+ return
+
+ playsound(src, 'sound/items/Welder.ogg', 50, 1)
+ user.visible_message(
+ "[user] begins patching up \
+ [src] with [WT].",
+ "You begin restoring the \
+ damage to [src]...")
+
+ if(!do_after(user, 40/O.toolspeed, target = src))
+ return
+ if(!src || !WT.remove_fuel(1, user))
+ return
+
+ user.visible_message(
+ "[user] fixes [src]!",
+ "You restore [src] to operation.")
+
+ stat &= ~BROKEN
+ health = max_health
+ update_icon()
else
return ..()
-/obj/machinery/droneDispenser/take_damage(damage, damage_type = BRUTE, sound_effect = 1)
- switch(damage_type)
+/obj/machinery/droneDispenser/take_damage(dmg, dmg_type=BRUTE, hit_sound=TRUE)
+ // But why would you hurt the dispenser?
+ switch(dmg_type)
if(BURN)
- if(sound_effect)
+ if(hit_sound)
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
if(BRUTE)
- if(sound_effect)
- if(damage)
+ if(hit_sound)
+ if(dmg)
playsound(loc, 'sound/weapons/smash.ogg', 50, 1)
else
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
else
return
- health = max(health - damage, 0)
+ health = max(health - dmg, 0)
if(!health && !(stat & BROKEN))
if(break_message)
- audible_message("[src] [break_message]")
+ audible_message("[src] \
+ [break_message]")
if(break_sound)
playsound(src, break_sound, 50, 1)
stat |= BROKEN
- icon_state = icon_off
+ update_icon()
+#undef DRONE_PRODUCTION
+#undef DRONE_RECHARGING
+#undef DRONE_READY