mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 10:21:11 +00:00
- 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:
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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³<br>"
|
||||
var/amount = min(res_max_amount, resources[resource])
|
||||
output += "<span class=\"res_name\">[resource]: </span>[amount] cm³"
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -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()]°K|[src.return_temperature() - T0C]°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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user