diff --git a/code/defines/procs/helpers.dm b/code/defines/procs/helpers.dm
index ba4973fb229..020cc8e2cf4 100644
--- a/code/defines/procs/helpers.dm
+++ b/code/defines/procs/helpers.dm
@@ -1071,7 +1071,7 @@ proc/islist(list/list)
return 0
proc/isemptylist(list/list)
- if(istype(list) && !list.len)
+ if(!list.len)
return 1
return 0
@@ -1433,3 +1433,9 @@ proc/get_cardinal_dir(atom/A, atom/B)
var/dy = abs(B.y - A.y)
return get_dir(A, B) & (rand() * (dx+dy) < dy ? 3 : 12)
+//return either pick(list) or null if list is not of type /list or empty
+proc/safepick(list/list)
+ if(!islist(list) || !list.len)
+ return
+ return pick(list)
+
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index cba4311241d..30380bda10a 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -23,7 +23,7 @@
else if(istype(AM, /obj/mecha))
var/obj/mecha/mecha = AM
if(density)
- if(mecha.occupant && src.allowed(mecha.occupant))
+ if(mecha.occupant && (src.allowed(mecha.occupant) || src.check_access_list(mecha.operation_req_access)))
open()
else
flick("door_deny", src)
diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm
index f5cce35f4ef..ea3f3270302 100644
--- a/code/game/mecha/equipment/mecha_equipment.dm
+++ b/code/game/mecha/equipment/mecha_equipment.dm
@@ -36,9 +36,16 @@
/obj/item/mecha_parts/mecha_equipment/proc/destroy()//missiles detonating, teleporter creating singularity?
if(chassis)
chassis.equipment -= src
+ listclearnulls(chassis.equipment)
if(chassis.selected == src)
chassis.selected = null
src.update_chassis_page()
+ chassis.occupant_message("The [src] is destroyed!")
+ chassis.log_append_to_last("[src] is destroyed.",1)
+ if(istype(src, /obj/item/mecha_parts/mecha_equipment/weapon))
+ chassis.occupant << sound('weapdestr.ogg',volume=50)
+ else
+ chassis.occupant << sound('critdestr.ogg',volume=50)
spawn
del src
return
diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm
index d99d3920b9f..b4283d36fdc 100644
--- a/code/game/mecha/equipment/tools/tools.dm
+++ b/code/game/mecha/equipment/tools/tools.dm
@@ -178,6 +178,8 @@
var/disabled = 0 //malf
action(atom/target)
+ if(!istype(target, /turf) && !istype(target, /obj/machinery/door/airlock))
+ target = get_turf(target)
if(!action_checks(target) || disabled || get_dist(chassis, target)>3) return
playsound(chassis, 'click.ogg', 50, 1)
//meh
@@ -450,6 +452,7 @@
energy_drain = 50
range = 0
construction_cost = list("metal"=20000,"gold"=5000)
+ var/deflect_coeff = 1.15
var/damage_coeff = 0.8
can_attach(obj/mecha/M as obj)
@@ -474,9 +477,13 @@
proc/dynbulletdamage(var/obj/item/projectile/Proj)
if(!action_checks(src))
return chassis.dynbulletdamage(Proj)
- var/damage = Proj.damage
- chassis.take_damage(round(damage*src.damage_coeff))
- chassis.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
+ if(prob(chassis.deflect_chance*deflect_coeff))
+ chassis.occupant_message("\blue The armor deflects incoming projectile.")
+ chassis.visible_message("The [chassis.name] armor deflects the projectile")
+ chassis.log_append_to_last("Armor saved.")
+ else
+ chassis.take_damage(round(Proj.damage*src.damage_coeff))
+ chassis.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
set_ready_state(0)
chassis.use_power(energy_drain)
do_after_cooldown()
@@ -485,7 +492,7 @@
proc/dynhitby(atom/movable/A)
if(!action_checks(A))
return chassis.dynhitby(A)
- if(prob(chassis.deflect_chance) || istype(A, /mob/living) || istype(A, /obj/item/mecha_tracking))
+ if(prob(chassis.deflect_chance*deflect_coeff) || istype(A, /mob/living) || istype(A, /obj/item/mecha_tracking))
chassis.occupant_message("\blue The [A] bounces off the armor.")
chassis.visible_message("The [A] bounces off the [chassis] armor")
chassis.log_append_to_last("Armor saved.")
diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm
index a31918318a1..4d07e08dc28 100644
--- a/code/game/mecha/mech_bay.dm
+++ b/code/game/mecha/mech_bay.dm
@@ -107,8 +107,9 @@
check_for_null = 0 //since port.stop_charge() must be called. The checks are made in process()
process(var/obj/machinery/mech_bay_recharge_port/port, var/obj/mecha/mecha)
- if((!port) || (!mecha)) return 0
- if(mecha in port.recharge_floor)
+ if(!port)
+ return 0
+ if(mecha && mecha in port.recharge_floor)
if(!mecha.cell) return
var/delta = min(max_charge, mecha.cell.maxcharge - mecha.cell.charge)
if(delta>0)
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index 6f46b2fd551..b38999803cb 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -125,6 +125,8 @@
for(var/i=1;i<=parts.len;i++)
var/path = parts[i]
parts[i] = new path(src)
+ //debug below
+ ASSERT(istype(parts[i],/obj/item))
return
@@ -210,7 +212,11 @@
proc/output_available_resources()
var/output
for(var/resource in resources)
- output += "[resource]: [min(res_max_amount, resources[resource])] cm³
"
+ var/amount = min(res_max_amount, resources[resource])
+ output += "[resource]: [amount] cm³"
+ if(amount>0)
+ output += " - Remove \[1\] | \[10\] | \[All\]"
+ output += "
"
return output
proc/remove_resources(var/obj/item/mecha_parts/part)
@@ -225,7 +231,8 @@
if(resource in src.resources)
if(src.resources[resource] < get_resource_cost_w_coeff(part,resource))
return 0
- return 1
+ return 1
+ return 0
proc/build_part(var/obj/item/mecha_parts/part)
if(!part) return
@@ -255,7 +262,7 @@
if(set_name in part_sets)
var/list/part_set = part_sets[set_name]
if(islist(part_set))
- for(var/part in part_set)
+ for(var/obj/item/part in part_set)
add_to_queue(part)
return
@@ -485,6 +492,8 @@
[part.desc]
Return
"}
+ if(href_list["remove_mat"] && href_list["material"])
+ temp = "Ejected [remove_material(href_list["material"],text2num(href_list["remove_mat"]))] of [href_list["material"]]
Return"
src.updateUsrDialog()
return
@@ -539,3 +548,35 @@
user << "The fabricator cannot hold more [name]."
return
+ proc/remove_material(var/mat_string, var/amount)
+ var/type
+ switch(mat_string)
+ if("metal")
+ type = /obj/item/stack/sheet/metal
+ if("glass")
+ type = /obj/item/stack/sheet/glass
+ if("gold")
+ type = /obj/item/stack/sheet/gold
+ if("silver")
+ type = /obj/item/stack/sheet/silver
+ if("diamond")
+ type = /obj/item/stack/sheet/diamond
+ if("plasma")
+ type = /obj/item/stack/sheet/plasma
+ if("uranium")
+ type = /obj/item/stack/sheet/uranium
+ if("bananium")
+ type = /obj/item/stack/sheet/clown
+ else
+ return 0
+ var/obj/item/stack/sheet/res = new type(src)
+ var/total_amount = round(resources[mat_string]/res.perunit)
+ res.amount = min(total_amount,amount)
+ if(res.amount>0)
+ resources[mat_string] -= res.amount*res.perunit
+ res.Move(src.loc)
+ else
+ del res
+ return res.amount
+
+
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index c93d6988f39..8d7ef2538e5 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -17,7 +17,7 @@
anchored = 1 //no pulling around.
unacidable = 1 //and no deleting hoomans inside
layer = MOB_LAYER //icon draw layer
- infra_luminosity = 15
+ infra_luminosity = 15 //byond implementation is bugged.
var/can_move = 1
var/mob/living/carbon/occupant = null
var/step_in = 10 //make a step in step_in/10 sec.
@@ -129,7 +129,9 @@
if(dir_to_target && !(dir_to_target & src.dir))//wrong direction
return
if(internal_damage&MECHA_INT_CONTROL_LOST)
- target = pick(view(3,target))
+ target = safepick(view(3,target))
+ if(!target)
+ return
if(get_dist(src, target)>1)
if(selected && selected.is_ranged())
selected.action(target)
@@ -171,6 +173,7 @@
/obj/mecha/relaymove(mob/user,direction)
if(user != src.occupant) //While not "realistic", this piece is player friendly.
user.loc = get_turf(src)
+ user.loc.Entered(user)
user << "You climb out from [src]"
return 0
if(!can_move)
@@ -271,34 +274,23 @@
return
/obj/mecha/proc/check_for_internal_damage(var/list/possible_int_damage,var/ignore_threshold=null)
- if(!src) return
+ if(!islist(possible_int_damage) || isemptylist(possible_int_damage)) return
if(prob(20))
if(ignore_threshold || src.health*100/initial(src.health)The [destr] is destroyed!")
- src.log_append_to_last("[destr] is destroyed.",1)
- if(istype(destr, /obj/item/mecha_parts/mecha_equipment/weapon))
- src.occupant << sound('weapdestr.ogg',volume=50)
- else
- src.occupant << sound('critdestr.ogg',volume=50)
+ var/obj/item/mecha_parts/mecha_equipment/destr = safepick(equipment)
+ if(destr)
+ destr.destroy()
return
@@ -351,7 +343,7 @@
return
-/obj/mecha/hitby(atom/movable/A as mob|obj)
+/obj/mecha/hitby(atom/movable/A as mob|obj) //wrapper
src.log_message("Hit by [A].",1)
call((proc_res["dynhitby"]||src), "dynhitby")(A)
return
@@ -376,29 +368,25 @@
return
-/obj/mecha/bullet_act(var/obj/item/projectile/Proj)
+/obj/mecha/bullet_act(var/obj/item/projectile/Proj) //wrapper
src.log_message("Hit by projectile. Type: [Proj.name]([Proj.flag]).",1)
- if(prob(src.deflect_chance))
- src.occupant_message("\blue The armor deflects the incoming projectile.")
- src.visible_message("The [src.name] armor deflects the projectile")
- src.log_append_to_last("Armor saved.")
- else
- call((proc_res["dynbulletdamage"]||src), "dynbulletdamage")(Proj) //calls equipment
+ call((proc_res["dynbulletdamage"]||src), "dynbulletdamage")(Proj) //calls equipment
..()
return
/obj/mecha/proc/dynbulletdamage(var/obj/item/projectile/Proj)
- var/damage
+ if(prob(src.deflect_chance))
+ src.occupant_message("\blue The armor deflects incoming projectile.")
+ src.visible_message("The [src.name] armor deflects the projectile")
+ src.log_append_to_last("Armor saved.")
+ return
var/ignore_threshold
-
if(Proj.flag == "taser")
use_power(500)
return
if(istype(Proj, /obj/item/projectile/beam/pulse))
ignore_threshold = 1
-
- damage = Proj.damage
- src.take_damage(damage)
+ src.take_damage(Proj.damage)
src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST),ignore_threshold)
return
@@ -473,6 +461,7 @@
/obj/mecha/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature>src.max_temperature)
+ src.log_message("Exposed to dangerous temperature.",1)
src.take_damage(5,"fire")
src.check_for_internal_damage(list(MECHA_INT_FIRE, MECHA_INT_TEMP_CONTROL))
return
@@ -574,7 +563,7 @@
var/obj/machinery/atmospherics/portables_connector/possible_port = locate(/obj/machinery/atmospherics/portables_connector/) in loc
if(possible_port)
if(connect(possible_port))
- src.occupant << "\blue [name] connects to the port."
+ src.occupant_message("\blue [name] connects to the port.")
src.verbs += /obj/mecha/verb/disconnect_from_port
src.verbs -= /obj/mecha/verb/connect_to_port
return
@@ -593,7 +582,7 @@
if(usr!=src.occupant)
return
if(disconnect())
- src.occupant << "\blue [name] disconnects from the port."
+ src.occupant_message("\blue [name] disconnects from the port.")
src.verbs -= /obj/mecha/verb/disconnect_from_port
src.verbs += /obj/mecha/verb/connect_to_port
else
@@ -693,6 +682,7 @@
user << "Beta-rhythm below acceptable level."
return 0
else if(occupant)
+ user << "Occupant detected."
return 0
else if(dna && dna!=mmi_as_oc.brainmob.dna.unique_enzymes)
user << "Stop it!"
@@ -1026,7 +1016,7 @@
var/output = {"
[src.name] data