- 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
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)

View File

@@ -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)

View File

@@ -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("<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
del src
return

View File

@@ -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.")

View File

@@ -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)

View File

@@ -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 += "<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
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]<br>
<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()
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

View File

@@ -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)<src.internal_damage_threshold)
for(var/T in possible_int_damage)
if(internal_damage & T)
possible_int_damage -= T
if(possible_int_damage.len)
var/int_dam_flag = pick(possible_int_damage)
if(int_dam_flag)
src.internal_damage |= int_dam_flag
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.occupant << sound('warning-buzzer.ogg',wait=0)
var/int_dam_flag = pick(possible_int_damage)
if(int_dam_flag)
src.internal_damage |= int_dam_flag
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.occupant << sound('warning-buzzer.ogg',wait=0)
if(prob(5))
if(ignore_threshold || src.health*100/initial(src.health)<src.internal_damage_threshold)
if(equipment.len)
var/obj/item/mecha_parts/mecha_equipment/destr = pick(equipment)
if(destr)
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)
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 = {"<html>
<head><title>[src.name] data</title>
<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;}
.wr {margin-bottom: 5px;}
.header {cursor:pointer;}
@@ -1078,7 +1068,7 @@
<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>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
@@ -1134,6 +1124,8 @@
if(href_list["update_content"])
send_byjax(src.occupant,"exosuit.browser","content",src.get_stats_part())
return
if(usr==occupant && occupant.stat>0)
return
if (href_list["close"])
return
if (href_list["toggle_lights"])
@@ -1156,12 +1148,11 @@
onclose(occupant, "exosuit_log")
return
if (href_list["change_name"])
var/newname = strip_html_simple(input(occupant,"Choose new exosuit name","Rename exosuit",initial(name)))
if(newname)
var/newname = strip_html_simple(input(occupant,"Choose new exosuit name","Rename exosuit",initial(name)) as text)
if(newname && trim(newname))
name = newname
else
if(!newname || newname == "" || newname == " ")
alert(occupant, "nope.avi")
alert(occupant, "nope.avi")
return
if (href_list["repair_int_control_lost"])
src.occupant_message("Recalibrating coordination system.")
@@ -1361,7 +1352,7 @@
mecha.pr_int_temp_processor.stop()
if(mecha.internal_damage & MECHA_INT_TANK_BREACH) //remove some air from internal tank
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"))
mecha.loc.assume_air(leaked_gas)
else

View File

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