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