- Additional fixes for mech fabricator and added option to eject materials.

- If door access check fails for exosuit pilot, exosuit operation permissions will be checked instead (meaning, if your ID lacks permission, but exosuit has it, the door will open). Should work for MMI-ed exosuits.
- Exosuit Armor Booster Module (Ranged Weapons) will increase deflect probability.
- Added safepick() prock. Same as pick(), but no runtime errors if list is empty - in that case it returns null.
- Reagents in water particle (extinguisher foam) will react with atom said particle bumps into.
- Other bugfixes.

git-svn-id: http://tgstation13.googlecode.com/svn/trunk@2302 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
panurgomatic
2011-10-01 01:55:39 +00:00
parent 9c611cae1e
commit 268f1d4aea
8 changed files with 113 additions and 56 deletions

View File

@@ -1071,7 +1071,7 @@ proc/islist(list/list)
return 0 return 0
proc/isemptylist(list/list) proc/isemptylist(list/list)
if(istype(list) && !list.len) if(!list.len)
return 1 return 1
return 0 return 0
@@ -1433,3 +1433,9 @@ proc/get_cardinal_dir(atom/A, atom/B)
var/dy = abs(B.y - A.y) var/dy = abs(B.y - A.y)
return get_dir(A, B) & (rand() * (dx+dy) < dy ? 3 : 12) 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)

View File

@@ -23,7 +23,7 @@
else if(istype(AM, /obj/mecha)) else if(istype(AM, /obj/mecha))
var/obj/mecha/mecha = AM var/obj/mecha/mecha = AM
if(density) 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() open()
else else
flick("door_deny", src) flick("door_deny", src)

View File

@@ -36,9 +36,16 @@
/obj/item/mecha_parts/mecha_equipment/proc/destroy()//missiles detonating, teleporter creating singularity? /obj/item/mecha_parts/mecha_equipment/proc/destroy()//missiles detonating, teleporter creating singularity?
if(chassis) if(chassis)
chassis.equipment -= src chassis.equipment -= src
listclearnulls(chassis.equipment)
if(chassis.selected == src) if(chassis.selected == src)
chassis.selected = null chassis.selected = null
src.update_chassis_page() src.update_chassis_page()
chassis.occupant_message("<font color='red'>The [src] is destroyed!</font>")
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 spawn
del src del src
return return

View File

@@ -178,6 +178,8 @@
var/disabled = 0 //malf var/disabled = 0 //malf
action(atom/target) 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 if(!action_checks(target) || disabled || get_dist(chassis, target)>3) return
playsound(chassis, 'click.ogg', 50, 1) playsound(chassis, 'click.ogg', 50, 1)
//meh //meh
@@ -450,6 +452,7 @@
energy_drain = 50 energy_drain = 50
range = 0 range = 0
construction_cost = list("metal"=20000,"gold"=5000) construction_cost = list("metal"=20000,"gold"=5000)
var/deflect_coeff = 1.15
var/damage_coeff = 0.8 var/damage_coeff = 0.8
can_attach(obj/mecha/M as obj) can_attach(obj/mecha/M as obj)
@@ -474,9 +477,13 @@
proc/dynbulletdamage(var/obj/item/projectile/Proj) proc/dynbulletdamage(var/obj/item/projectile/Proj)
if(!action_checks(src)) if(!action_checks(src))
return chassis.dynbulletdamage(Proj) return chassis.dynbulletdamage(Proj)
var/damage = Proj.damage if(prob(chassis.deflect_chance*deflect_coeff))
chassis.take_damage(round(damage*src.damage_coeff)) chassis.occupant_message("\blue The armor deflects incoming projectile.")
chassis.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) 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) set_ready_state(0)
chassis.use_power(energy_drain) chassis.use_power(energy_drain)
do_after_cooldown() do_after_cooldown()
@@ -485,7 +492,7 @@
proc/dynhitby(atom/movable/A) proc/dynhitby(atom/movable/A)
if(!action_checks(A)) if(!action_checks(A))
return chassis.dynhitby(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.occupant_message("\blue The [A] bounces off the armor.")
chassis.visible_message("The [A] bounces off the [chassis] armor") chassis.visible_message("The [A] bounces off the [chassis] armor")
chassis.log_append_to_last("Armor saved.") chassis.log_append_to_last("Armor saved.")

View File

@@ -107,8 +107,9 @@
check_for_null = 0 //since port.stop_charge() must be called. The checks are made in process() 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) process(var/obj/machinery/mech_bay_recharge_port/port, var/obj/mecha/mecha)
if((!port) || (!mecha)) return 0 if(!port)
if(mecha in port.recharge_floor) return 0
if(mecha && mecha in port.recharge_floor)
if(!mecha.cell) return if(!mecha.cell) return
var/delta = min(max_charge, mecha.cell.maxcharge - mecha.cell.charge) var/delta = min(max_charge, mecha.cell.maxcharge - mecha.cell.charge)
if(delta>0) if(delta>0)

View File

@@ -125,6 +125,8 @@
for(var/i=1;i<=parts.len;i++) for(var/i=1;i<=parts.len;i++)
var/path = parts[i] var/path = parts[i]
parts[i] = new path(src) parts[i] = new path(src)
//debug below
ASSERT(istype(parts[i],/obj/item))
return return
@@ -210,7 +212,11 @@
proc/output_available_resources() proc/output_available_resources()
var/output var/output
for(var/resource in resources) for(var/resource in resources)
output += "<span class=\"res_name\">[resource]: </span>[min(res_max_amount, resources[resource])] cm&sup3;<br>" var/amount = min(res_max_amount, resources[resource])
output += "<span class=\"res_name\">[resource]: </span>[amount] cm&sup3;"
if(amount>0)
output += "<span style='font-size:80%;'> - Remove \[<a href='?src=\ref[src];remove_mat=1;material=[resource]'>1</a>\] | \[<a href='?src=\ref[src];remove_mat=10;material=[resource]'>10</a>\] | \[<a href='?src=\ref[src];remove_mat=[res_max_amount];material=[resource]'>All</a>\]</span>"
output += "<br/>"
return output return output
proc/remove_resources(var/obj/item/mecha_parts/part) proc/remove_resources(var/obj/item/mecha_parts/part)
@@ -225,7 +231,8 @@
if(resource in src.resources) if(resource in src.resources)
if(src.resources[resource] < get_resource_cost_w_coeff(part,resource)) if(src.resources[resource] < get_resource_cost_w_coeff(part,resource))
return 0 return 0
return 1 return 1
return 0
proc/build_part(var/obj/item/mecha_parts/part) proc/build_part(var/obj/item/mecha_parts/part)
if(!part) return if(!part) return
@@ -255,7 +262,7 @@
if(set_name in part_sets) if(set_name in part_sets)
var/list/part_set = part_sets[set_name] var/list/part_set = part_sets[set_name]
if(islist(part_set)) if(islist(part_set))
for(var/part in part_set) for(var/obj/item/part in part_set)
add_to_queue(part) add_to_queue(part)
return return
@@ -485,6 +492,8 @@
[part.desc]<br> [part.desc]<br>
<a href='?src=\ref[src];clear_temp=1'>Return</a> <a href='?src=\ref[src];clear_temp=1'>Return</a>
"} "}
if(href_list["remove_mat"] && href_list["material"])
temp = "Ejected [remove_material(href_list["material"],text2num(href_list["remove_mat"]))] of [href_list["material"]]<br><a href='?src=\ref[src];clear_temp=1'>Return</a>"
src.updateUsrDialog() src.updateUsrDialog()
return return
@@ -539,3 +548,35 @@
user << "The fabricator cannot hold more [name]." user << "The fabricator cannot hold more [name]."
return 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

View File

@@ -17,7 +17,7 @@
anchored = 1 //no pulling around. anchored = 1 //no pulling around.
unacidable = 1 //and no deleting hoomans inside unacidable = 1 //and no deleting hoomans inside
layer = MOB_LAYER //icon draw layer layer = MOB_LAYER //icon draw layer
infra_luminosity = 15 infra_luminosity = 15 //byond implementation is bugged.
var/can_move = 1 var/can_move = 1
var/mob/living/carbon/occupant = null var/mob/living/carbon/occupant = null
var/step_in = 10 //make a step in step_in/10 sec. 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 if(dir_to_target && !(dir_to_target & src.dir))//wrong direction
return return
if(internal_damage&MECHA_INT_CONTROL_LOST) 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(get_dist(src, target)>1)
if(selected && selected.is_ranged()) if(selected && selected.is_ranged())
selected.action(target) selected.action(target)
@@ -171,6 +173,7 @@
/obj/mecha/relaymove(mob/user,direction) /obj/mecha/relaymove(mob/user,direction)
if(user != src.occupant) //While not "realistic", this piece is player friendly. if(user != src.occupant) //While not "realistic", this piece is player friendly.
user.loc = get_turf(src) user.loc = get_turf(src)
user.loc.Entered(user)
user << "You climb out from [src]" user << "You climb out from [src]"
return 0 return 0
if(!can_move) if(!can_move)
@@ -271,34 +274,23 @@
return return
/obj/mecha/proc/check_for_internal_damage(var/list/possible_int_damage,var/ignore_threshold=null) /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(prob(20))
if(ignore_threshold || src.health*100/initial(src.health)<src.internal_damage_threshold) if(ignore_threshold || src.health*100/initial(src.health)<src.internal_damage_threshold)
for(var/T in possible_int_damage) for(var/T in possible_int_damage)
if(internal_damage & T) if(internal_damage & T)
possible_int_damage -= T possible_int_damage -= T
if(possible_int_damage.len) var/int_dam_flag = pick(possible_int_damage)
var/int_dam_flag = pick(possible_int_damage) if(int_dam_flag)
if(int_dam_flag) src.internal_damage |= int_dam_flag
src.internal_damage |= int_dam_flag src.pr_internal_damage.start()
src.pr_internal_damage.start() src.log_append_to_last("Internal damage of type [int_dam_flag].[ignore_threshold?"Ignoring damage threshold.":null]",1)
src.log_append_to_last("Internal damage of type [int_dam_flag].[ignore_threshold?"Ignoring damage threshold.":null]",1) src.occupant << sound('warning-buzzer.ogg',wait=0)
src.occupant << sound('warning-buzzer.ogg',wait=0)
if(prob(5)) if(prob(5))
if(ignore_threshold || src.health*100/initial(src.health)<src.internal_damage_threshold) if(ignore_threshold || src.health*100/initial(src.health)<src.internal_damage_threshold)
if(equipment.len) var/obj/item/mecha_parts/mecha_equipment/destr = safepick(equipment)
var/obj/item/mecha_parts/mecha_equipment/destr = pick(equipment) if(destr)
if(destr) destr.destroy()
equipment -= destr
while(null in equipment)
equipment -= null
destr.destroy()
src.occupant_message("<font color='red'>The [destr] is destroyed!</font>")
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)
return return
@@ -351,7 +343,7 @@
return 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) src.log_message("Hit by [A].",1)
call((proc_res["dynhitby"]||src), "dynhitby")(A) call((proc_res["dynhitby"]||src), "dynhitby")(A)
return return
@@ -376,29 +368,25 @@
return 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) src.log_message("Hit by projectile. Type: [Proj.name]([Proj.flag]).",1)
if(prob(src.deflect_chance)) call((proc_res["dynbulletdamage"]||src), "dynbulletdamage")(Proj) //calls equipment
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
..() ..()
return return
/obj/mecha/proc/dynbulletdamage(var/obj/item/projectile/Proj) /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 var/ignore_threshold
if(Proj.flag == "taser") if(Proj.flag == "taser")
use_power(500) use_power(500)
return return
if(istype(Proj, /obj/item/projectile/beam/pulse)) if(istype(Proj, /obj/item/projectile/beam/pulse))
ignore_threshold = 1 ignore_threshold = 1
src.take_damage(Proj.damage)
damage = Proj.damage
src.take_damage(damage)
src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST),ignore_threshold) src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST),ignore_threshold)
return return
@@ -473,6 +461,7 @@
/obj/mecha/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) /obj/mecha/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature>src.max_temperature) if(exposed_temperature>src.max_temperature)
src.log_message("Exposed to dangerous temperature.",1)
src.take_damage(5,"fire") src.take_damage(5,"fire")
src.check_for_internal_damage(list(MECHA_INT_FIRE, MECHA_INT_TEMP_CONTROL)) src.check_for_internal_damage(list(MECHA_INT_FIRE, MECHA_INT_TEMP_CONTROL))
return return
@@ -574,7 +563,7 @@
var/obj/machinery/atmospherics/portables_connector/possible_port = locate(/obj/machinery/atmospherics/portables_connector/) in loc var/obj/machinery/atmospherics/portables_connector/possible_port = locate(/obj/machinery/atmospherics/portables_connector/) in loc
if(possible_port) if(possible_port)
if(connect(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/disconnect_from_port
src.verbs -= /obj/mecha/verb/connect_to_port src.verbs -= /obj/mecha/verb/connect_to_port
return return
@@ -593,7 +582,7 @@
if(usr!=src.occupant) if(usr!=src.occupant)
return return
if(disconnect()) 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/disconnect_from_port
src.verbs += /obj/mecha/verb/connect_to_port src.verbs += /obj/mecha/verb/connect_to_port
else else
@@ -693,6 +682,7 @@
user << "Beta-rhythm below acceptable level." user << "Beta-rhythm below acceptable level."
return 0 return 0
else if(occupant) else if(occupant)
user << "Occupant detected."
return 0 return 0
else if(dna && dna!=mmi_as_oc.brainmob.dna.unique_enzymes) else if(dna && dna!=mmi_as_oc.brainmob.dna.unique_enzymes)
user << "Stop it!" user << "Stop it!"
@@ -1026,7 +1016,7 @@
var/output = {"<html> var/output = {"<html>
<head><title>[src.name] data</title> <head><title>[src.name] data</title>
<style> <style>
body {color: #00ff00; background: #000000; font: 13px 'Courier', monospace;} body {color: #00ff00; background: #000000; font-family:"Courier New", Courier, monospace; font-size: 12px;}
hr {border: 1px solid #0f0; color: #0f0; background-color: #0f0;} hr {border: 1px solid #0f0; color: #0f0; background-color: #0f0;}
.wr {margin-bottom: 5px;} .wr {margin-bottom: 5px;}
.header {cursor:pointer;} .header {cursor:pointer;}
@@ -1078,7 +1068,7 @@
<b>Airtank pressure: </b>[src.return_pressure()]kPa<br> <b>Airtank pressure: </b>[src.return_pressure()]kPa<br>
<b>Internal temperature: </b> [src.return_temperature()]&deg;K|[src.return_temperature() - T0C]&deg;C<br> <b>Internal temperature: </b> [src.return_temperature()]&deg;K|[src.return_temperature() - T0C]&deg;C<br>
<b>Lights: </b>[lights?"on":"off"]<br> <b>Lights: </b>[lights?"on":"off"]<br>
[src.dna?"<b>DNA-locked:</b><br> <span style='font-size:5px;letter-spacing:-1px;'>[src.dna]</span> \[<a href='?src=\ref[src];reset_dna=1'>Reset</a>\]<br>":null] [src.dna?"<b>DNA-locked:</b><br> <span style='font-size:10px;letter-spacing:-1px;'>[src.dna]</span> \[<a href='?src=\ref[src];reset_dna=1'>Reset</a>\]<br>":null]
"} "}
return output return output
@@ -1134,6 +1124,8 @@
if(href_list["update_content"]) if(href_list["update_content"])
send_byjax(src.occupant,"exosuit.browser","content",src.get_stats_part()) send_byjax(src.occupant,"exosuit.browser","content",src.get_stats_part())
return return
if(usr==occupant && occupant.stat>0)
return
if (href_list["close"]) if (href_list["close"])
return return
if (href_list["toggle_lights"]) if (href_list["toggle_lights"])
@@ -1156,12 +1148,11 @@
onclose(occupant, "exosuit_log") onclose(occupant, "exosuit_log")
return return
if (href_list["change_name"]) if (href_list["change_name"])
var/newname = strip_html_simple(input(occupant,"Choose new exosuit name","Rename exosuit",initial(name))) var/newname = strip_html_simple(input(occupant,"Choose new exosuit name","Rename exosuit",initial(name)) as text)
if(newname) if(newname && trim(newname))
name = newname name = newname
else else
if(!newname || newname == "" || newname == " ") alert(occupant, "nope.avi")
alert(occupant, "nope.avi")
return return
if (href_list["repair_int_control_lost"]) if (href_list["repair_int_control_lost"])
src.occupant_message("Recalibrating coordination system.") src.occupant_message("Recalibrating coordination system.")
@@ -1361,7 +1352,7 @@
mecha.pr_int_temp_processor.stop() mecha.pr_int_temp_processor.stop()
if(mecha.internal_damage & MECHA_INT_TANK_BREACH) //remove some air from internal tank if(mecha.internal_damage & MECHA_INT_TANK_BREACH) //remove some air from internal tank
if(int_tank_air) if(int_tank_air)
var/datum/gas_mixture/leaked_gas = int_tank_air.remove_ratio(0.25) var/datum/gas_mixture/leaked_gas = int_tank_air.remove_ratio(0.10)
if(mecha.loc && hascall(mecha.loc,"assume_air")) if(mecha.loc && hascall(mecha.loc,"assume_air"))
mecha.loc.assume_air(leaked_gas) mecha.loc.assume_air(leaked_gas)
else else

View File

@@ -59,6 +59,10 @@ would spawn and follow the beaker, even if it is carried or thrown.
return 0 return 0
.=..() .=..()
/obj/effects/water/Bump(atom/A)
if(reagents)
reagents.reaction(A)
return ..()
///////////////////////////////////////////// /////////////////////////////////////////////
// GENERIC STEAM SPREAD SYSTEM // GENERIC STEAM SPREAD SYSTEM