initial commit - cross reference with 5th port - obviously has compile errors
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
/obj/mecha/combat
|
||||
force = 30
|
||||
internal_damage_threshold = 50
|
||||
damage_absorption = list("brute"=0.7,"fire"=1,"bullet"=0.7,"laser"=0.85,"energy"=1,"bomb"=0.8)
|
||||
|
||||
/obj/mecha/combat/CheckParts(atom/holder)
|
||||
..()
|
||||
var/obj/item/weapon/stock_parts/capacitor/C = locate() in holder
|
||||
var/obj/item/weapon/stock_parts/scanning_module/SM = locate() in holder
|
||||
step_energy_drain = 20 - (5 * SM.rating) //10 is normal, so on lowest part its worse, on second its ok and on higher its real good up to 0 on best
|
||||
var/DR = damage_absorption["energy"]
|
||||
damage_absorption["energy"] = DR - (C.rating / 10) //Each level of capacitor protects the mech against emp by 10%
|
||||
qdel(C)
|
||||
qdel(SM)
|
||||
|
||||
/obj/mecha/combat/moved_inside(mob/living/carbon/human/H)
|
||||
if(..())
|
||||
if(H.client)
|
||||
H.client.mouse_pointer_icon = file("icons/mecha/mecha_mouse.dmi")
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/mecha/combat/mmi_moved_inside(obj/item/device/mmi/mmi_as_oc,mob/user)
|
||||
if(..())
|
||||
if(occupant.client)
|
||||
occupant.client.mouse_pointer_icon = file("icons/mecha/mecha_mouse.dmi")
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
|
||||
/obj/mecha/combat/go_out()
|
||||
if(src.occupant && src.occupant.client)
|
||||
src.occupant.client.mouse_pointer_icon = initial(src.occupant.client.mouse_pointer_icon)
|
||||
..()
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/obj/mecha/combat/durand
|
||||
desc = "An aging combat exosuit utilized by the Nanotrasen corporation. Originally developed to combat hostile alien lifeforms."
|
||||
name = "\improper Durand"
|
||||
icon_state = "durand"
|
||||
step_in = 4
|
||||
dir_in = 1 //Facing North.
|
||||
health = 400
|
||||
deflect_chance = 20
|
||||
damage_absorption = list("brute"=0.5,"fire"=1.1,"bullet"=0.65,"laser"=0.85,"energy"=0.9,"bomb"=0.8)
|
||||
max_temperature = 30000
|
||||
infra_luminosity = 8
|
||||
force = 40
|
||||
wreckage = /obj/structure/mecha_wreckage/durand
|
||||
|
||||
/obj/mecha/combat/durand/GrantActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
defense_action.Grant(user, src)
|
||||
|
||||
/obj/mecha/combat/durand/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
defense_action.Remove(user)
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/obj/mecha/combat/gygax
|
||||
desc = "A lightweight, security exosuit. Popular among private and corporate security."
|
||||
name = "\improper Gygax"
|
||||
icon_state = "gygax"
|
||||
step_in = 3
|
||||
dir_in = 1 //Facing North.
|
||||
health = 250
|
||||
deflect_chance = 5
|
||||
damage_absorption = list("brute"=0.75,"fire"=1,"bullet"=0.8,"laser"=0.7,"energy"=0.85,"bomb"=1)
|
||||
max_temperature = 25000
|
||||
infra_luminosity = 6
|
||||
wreckage = /obj/structure/mecha_wreckage/gygax
|
||||
internal_damage_threshold = 35
|
||||
max_equip = 3
|
||||
step_energy_drain = 3
|
||||
|
||||
/obj/mecha/combat/gygax/dark
|
||||
desc = "A lightweight exosuit, painted in a dark scheme. This model appears to have some modifications."
|
||||
name = "\improper Dark Gygax"
|
||||
icon_state = "darkgygax"
|
||||
health = 300
|
||||
deflect_chance = 15
|
||||
damage_absorption = list("brute"=0.6,"fire"=0.8,"bullet"=0.6,"laser"=0.5,"energy"=0.65,"bomb"=0.8)
|
||||
max_temperature = 35000
|
||||
leg_overload_coeff = 100
|
||||
operation_req_access = list(access_syndicate)
|
||||
wreckage = /obj/structure/mecha_wreckage/gygax/dark
|
||||
max_equip = 4
|
||||
|
||||
/obj/mecha/combat/gygax/dark/loaded/New()
|
||||
..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/teleporter
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay
|
||||
ME.attach(src)
|
||||
return
|
||||
|
||||
/obj/mecha/combat/gygax/dark/add_cell(obj/item/weapon/stock_parts/cell/C=null)
|
||||
if(C)
|
||||
C.forceMove(src)
|
||||
cell = C
|
||||
return
|
||||
cell = new(src)
|
||||
cell.charge = 30000
|
||||
cell.maxcharge = 30000
|
||||
|
||||
|
||||
/obj/mecha/combat/gygax/GrantActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
overload_action.Grant(user, src)
|
||||
|
||||
/obj/mecha/combat/gygax/dark/GrantActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
thrusters_action.Grant(user, src)
|
||||
|
||||
|
||||
/obj/mecha/combat/gygax/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
overload_action.Remove(user)
|
||||
|
||||
/obj/mecha/combat/gygax/dark/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
thrusters_action.Remove(user)
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
/obj/mecha/combat/honker
|
||||
desc = "Produced by \"Tyranny of Honk, INC\", this exosuit is designed as heavy clown-support. Used to spread the fun and joy of life. HONK!"
|
||||
name = "\improper H.O.N.K"
|
||||
icon_state = "honker"
|
||||
step_in = 3
|
||||
health = 140
|
||||
deflect_chance = 60
|
||||
internal_damage_threshold = 60
|
||||
damage_absorption = list("brute"=1.2,"fire"=1.5,"bullet"=1,"laser"=1,"energy"=1,"bomb"=1)
|
||||
max_temperature = 25000
|
||||
infra_luminosity = 5
|
||||
operation_req_access = list(access_theatre)
|
||||
wreckage = /obj/structure/mecha_wreckage/honker
|
||||
add_req_access = 0
|
||||
max_equip = 3
|
||||
var/squeak = 0
|
||||
|
||||
/*
|
||||
/obj/mecha/combat/honker/New()
|
||||
..()
|
||||
|
||||
weapons += new /datum/mecha_weapon/honker(src)
|
||||
weapons += new /datum/mecha_weapon/missile_rack/banana_mortar(src)
|
||||
weapons += new /datum/mecha_weapon/missile_rack/mousetrap_mortar(src)
|
||||
selected_weapon = weapons[1]
|
||||
return
|
||||
*/
|
||||
|
||||
/obj/mecha/combat/honker/get_stats_part()
|
||||
var/integrity = health/initial(health)*100
|
||||
var/cell_charge = get_charge()
|
||||
var/datum/gas_mixture/int_tank_air = internal_tank.return_air()
|
||||
var/tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None"
|
||||
var/tank_temperature = internal_tank ? int_tank_air.temperature : "Unknown"
|
||||
var/cabin_pressure = round(return_pressure(),0.01)
|
||||
var/output = {"[report_internal_damage()]
|
||||
[integrity<30?"<font color='red'><b>DAMAGE LEVEL CRITICAL</b></font><br>":null]
|
||||
[internal_damage&MECHA_INT_TEMP_CONTROL?"<font color='red'><b>CLOWN SUPPORT SYSTEM MALFUNCTION</b></font><br>":null]
|
||||
[internal_damage&MECHA_INT_TANK_BREACH?"<font color='red'><b>GAS TANK HONK</b></font><br>":null]
|
||||
[internal_damage&MECHA_INT_CONTROL_LOST?"<font color='red'><b>HONK-A-DOODLE</b></font> - <a href='?src=\ref[src];repair_int_control_lost=1'>Recalibrate</a><br>":null]
|
||||
<b>IntegriHONK: </b> [integrity]%<br>
|
||||
<b>PowerHONK charge: </b>[isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]<br>
|
||||
<b>Air source: </b>[use_internal_tank?"Internal Airtank":"Environment"]<br>
|
||||
<b>AirHONK pressure: </b>[tank_pressure]kPa<br>
|
||||
<b>AirHONK temperature: </b>[tank_temperature]°K|[tank_temperature - T0C]°C<br>
|
||||
<b>HONK pressure: </b>[cabin_pressure>WARNING_HIGH_PRESSURE ? "<font color='red'>[cabin_pressure]</font>": cabin_pressure]kPa<br>
|
||||
<b>HONK temperature: </b> [return_temperature()]°K|[return_temperature() - T0C]°C<br>
|
||||
<b>Lights: </b>[lights?"on":"off"]<br>
|
||||
[dna_lock?"<b>DNA-locked:</b><br> <span style='font-size:10px;letter-spacing:-1px;'>[dna_lock]</span> \[<a href='?src=\ref[src];reset_dna=1'>Reset</a>\]<br>":null]
|
||||
"}
|
||||
return output
|
||||
|
||||
/obj/mecha/combat/honker/get_stats_html()
|
||||
var/output = {"<html>
|
||||
<head><title>[src.name] data</title>
|
||||
<style>
|
||||
body {color: #00ff00; background: #32CD32; font-family:"Courier",monospace; font-size: 12px;}
|
||||
hr {border: 1px solid #0f0; color: #fff; background-color: #000;}
|
||||
a {padding:2px 5px;;color:#0f0;}
|
||||
.wr {margin-bottom: 5px;}
|
||||
.header {cursor:pointer;}
|
||||
.open, .closed {background: #32CD32; color:#000; padding:1px 2px;}
|
||||
.links a {margin-bottom: 2px;padding-top:3px;}
|
||||
.visible {display: block;}
|
||||
.hidden {display: none;}
|
||||
</style>
|
||||
<script language='javascript' type='text/javascript'>
|
||||
[js_byjax]
|
||||
[js_dropdowns]
|
||||
function ticker() {
|
||||
setInterval(function(){
|
||||
window.location='byond://?src=\ref[src]&update_content=1';
|
||||
document.body.style.color = get_rand_color_string();
|
||||
document.body.style.background = get_rand_color_string();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function get_rand_color_string() {
|
||||
var color = new Array;
|
||||
for(var i=0;i<3;i++){
|
||||
color.push(Math.floor(Math.random()*255));
|
||||
}
|
||||
return "rgb("+color.toString()+")";
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
dropdowns();
|
||||
ticker();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id='content'>
|
||||
[src.get_stats_part()]
|
||||
</div>
|
||||
<div id='eq_list'>
|
||||
[src.get_equipment_list()]
|
||||
</div>
|
||||
<hr>
|
||||
<div id='commands'>
|
||||
[src.get_commands()]
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
return output
|
||||
|
||||
/obj/mecha/combat/honker/get_commands()
|
||||
var/output = {"<div class='wr'>
|
||||
<div class='header'>Sounds of HONK:</div>
|
||||
<div class='links'>
|
||||
<a href='?src=\ref[src];play_sound=sadtrombone'>Sad Trombone</a>
|
||||
</div>
|
||||
</div>
|
||||
"}
|
||||
output += ..()
|
||||
return output
|
||||
|
||||
|
||||
/obj/mecha/combat/honker/get_equipment_list()
|
||||
if(!equipment.len)
|
||||
return
|
||||
var/output = "<b>Honk-ON-Systems:</b><div style=\"margin-left: 15px;\">"
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/MT in equipment)
|
||||
output += "<div id='\ref[MT]'>[MT.get_equip_info()]</div>"
|
||||
output += "</div>"
|
||||
return output
|
||||
|
||||
|
||||
|
||||
/obj/mecha/combat/honker/mechstep(direction)
|
||||
var/result = step(src,direction)
|
||||
if(result)
|
||||
if(!squeak)
|
||||
playsound(src, "clownstep", 70, 1)
|
||||
squeak = 1
|
||||
else
|
||||
squeak = 0
|
||||
return result
|
||||
|
||||
/obj/mecha/combat/honker/Topic(href, href_list)
|
||||
..()
|
||||
if (href_list["play_sound"])
|
||||
switch(href_list["play_sound"])
|
||||
if("sadtrombone")
|
||||
playsound(src, 'sound/misc/sadtrombone.ogg', 50)
|
||||
return
|
||||
|
||||
/proc/rand_hex_color()
|
||||
var/list/colors = list("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f")
|
||||
var/color=""
|
||||
for (var/i=0;i<6;i++)
|
||||
color = color+pick(colors)
|
||||
return color
|
||||
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/obj/mecha/combat/marauder
|
||||
desc = "Heavy-duty, combat exosuit, developed after the Durand model. Rarely found among civilian populations."
|
||||
name = "\improper Marauder"
|
||||
icon_state = "marauder"
|
||||
step_in = 5
|
||||
health = 500
|
||||
deflect_chance = 25
|
||||
damage_absorption = list("brute"=0.5,"fire"=0.7,"bullet"=0.45,"laser"=0.6,"energy"=0.7,"bomb"=0.7)
|
||||
max_temperature = 60000
|
||||
burn_state = LAVA_PROOF
|
||||
infra_luminosity = 3
|
||||
operation_req_access = list(access_cent_specops)
|
||||
wreckage = /obj/structure/mecha_wreckage/marauder
|
||||
add_req_access = 0
|
||||
internal_damage_threshold = 25
|
||||
force = 45
|
||||
max_equip = 4
|
||||
bumpsmash = 1
|
||||
|
||||
/obj/mecha/combat/marauder/GrantActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
smoke_action.Grant(user, src)
|
||||
thrusters_action.Grant(user, src)
|
||||
zoom_action.Grant(user, src)
|
||||
|
||||
/obj/mecha/combat/marauder/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
smoke_action.Remove(user)
|
||||
thrusters_action.Remove(user)
|
||||
zoom_action.Remove(user)
|
||||
|
||||
/obj/mecha/combat/marauder/loaded/New()
|
||||
..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/missile_rack(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src)
|
||||
ME.attach(src)
|
||||
|
||||
/obj/mecha/combat/marauder/seraph
|
||||
desc = "Heavy-duty, command-type exosuit. This is a custom model, utilized only by high-ranking military personnel."
|
||||
name = "\improper Seraph"
|
||||
icon_state = "seraph"
|
||||
operation_req_access = list(access_cent_specops)
|
||||
step_in = 3
|
||||
health = 550
|
||||
wreckage = /obj/structure/mecha_wreckage/seraph
|
||||
internal_damage_threshold = 20
|
||||
force = 55
|
||||
max_equip = 5
|
||||
|
||||
/obj/mecha/combat/marauder/seraph/New()
|
||||
..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/missile_rack(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/teleporter(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src)
|
||||
ME.attach(src)
|
||||
|
||||
/obj/mecha/combat/marauder/mauler
|
||||
desc = "Heavy-duty, combat exosuit, developed off of the existing Marauder model."
|
||||
name = "\improper Mauler"
|
||||
icon_state = "mauler"
|
||||
operation_req_access = list(access_syndicate)
|
||||
wreckage = /obj/structure/mecha_wreckage/mauler
|
||||
max_equip = 5
|
||||
|
||||
/obj/mecha/combat/marauder/mauler/loaded/New()
|
||||
..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/missile_rack(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay(src)
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster(src)
|
||||
ME.attach(src)
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/obj/mecha/combat/phazon
|
||||
desc = "This is a Phazon exosuit. The pinnacle of scientific research and pride of Nanotrasen, it uses cutting edge bluespace technology and expensive materials."
|
||||
name = "\improper Phazon"
|
||||
icon_state = "phazon"
|
||||
step_in = 2
|
||||
dir_in = 2 //Facing South.
|
||||
step_energy_drain = 3
|
||||
health = 200
|
||||
deflect_chance = 30
|
||||
damage_absorption = list("brute"=0.7,"fire"=0.7,"bullet"=0.7,"laser"=0.7,"energy"=0.7,"bomb"=0.7)
|
||||
max_temperature = 25000
|
||||
infra_luminosity = 3
|
||||
wreckage = /obj/structure/mecha_wreckage/phazon
|
||||
add_req_access = 1
|
||||
internal_damage_threshold = 25
|
||||
force = 15
|
||||
max_equip = 3
|
||||
phase_state = "phazon-phase"
|
||||
|
||||
/obj/mecha/combat/phazon/GrantActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
switch_damtype_action.Grant(user, src)
|
||||
phasing_action.Grant(user, src)
|
||||
|
||||
|
||||
/obj/mecha/combat/phazon/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
..()
|
||||
switch_damtype_action.Remove(user)
|
||||
phasing_action.Remove(user)
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/obj/mecha/combat/reticence
|
||||
desc = "A silent, fast, and nigh-invisible miming exosuit. Popular among mimes and mime assassins."
|
||||
name = "\improper reticence"
|
||||
icon_state = "reticence"
|
||||
step_in = 2
|
||||
dir_in = 1 //Facing North.
|
||||
health = 100
|
||||
deflect_chance = 3
|
||||
damage_absorption = list("brute"=0.75,"fire"=1,"bullet"=0.8,"laser"=0.7,"energy"=0.85,"bomb"=1)
|
||||
max_temperature = 15000
|
||||
wreckage = /obj/structure/mecha_wreckage/reticence
|
||||
operation_req_access = list(access_theatre)
|
||||
add_req_access = 0
|
||||
internal_damage_threshold = 25
|
||||
max_equip = 2
|
||||
step_energy_drain = 3
|
||||
color = "#87878715"
|
||||
stepsound = null
|
||||
turnsound = null
|
||||
|
||||
/obj/mecha/combat/reticence/loaded/New()
|
||||
..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced
|
||||
ME.attach(src)
|
||||
ME = new /obj/item/mecha_parts/mecha_equipment/rcd //HAHA IT MAKES WALLS GET IT
|
||||
ME.attach(src)
|
||||
return
|
||||
@@ -0,0 +1,156 @@
|
||||
//DO NOT ADD MECHA PARTS TO THE GAME WITH THE DEFAULT "SPRITE ME" SPRITE!
|
||||
//I'm annoyed I even have to tell you this! SPRITE FIRST, then commit.
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment
|
||||
name = "mecha equipment"
|
||||
icon = 'icons/mecha/mecha_equipment.dmi'
|
||||
icon_state = "mecha_equip"
|
||||
force = 5
|
||||
origin_tech = "materials=2;engineering=2"
|
||||
var/equip_cooldown = 0 // cooldown after use
|
||||
var/equip_ready = 1 //whether the equipment is ready for use. (or deactivated/activated for static stuff)
|
||||
var/energy_drain = 0
|
||||
var/obj/mecha/chassis = null
|
||||
var/range = MELEE //bitflags
|
||||
var/salvageable = 1
|
||||
var/selectable = 1 // Set to 0 for passive equipment such as mining scanner or armor plates
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/update_chassis_page()
|
||||
if(chassis)
|
||||
send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list())
|
||||
send_byjax(chassis.occupant,"exosuit.browser","equipment_menu",chassis.get_equipment_menu(),"dropdowns")
|
||||
return 1
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/update_equip_info()
|
||||
if(chassis)
|
||||
send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",get_equip_info())
|
||||
return 1
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/Destroy()
|
||||
if(chassis)
|
||||
chassis.equipment -= src
|
||||
if(chassis.selected == src)
|
||||
chassis.selected = null
|
||||
src.update_chassis_page()
|
||||
chassis.occupant_message("<span class='danger'>The [src] is destroyed!</span>")
|
||||
chassis.log_append_to_last("[src] is destroyed.",1)
|
||||
if(istype(src, /obj/item/mecha_parts/mecha_equipment/weapon))
|
||||
chassis.occupant << sound('sound/mecha/weapdestr.ogg',volume=50)
|
||||
else
|
||||
chassis.occupant << sound('sound/mecha/critdestr.ogg',volume=50)
|
||||
chassis = null
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/critfail()
|
||||
if(chassis)
|
||||
log_message("Critical failure",1)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/get_equip_info()
|
||||
if(!chassis) return
|
||||
var/txt = "<span style=\"color:[equip_ready?"#0f0":"#f00"];\">*</span> "
|
||||
if(chassis.selected == src)
|
||||
txt += "<b>[src.name]</b>"
|
||||
else if(selectable)
|
||||
txt += "<a href='?src=\ref[chassis];select_equip=\ref[src]'>[src.name]</a>"
|
||||
else
|
||||
txt += "[src.name]"
|
||||
|
||||
return txt
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/is_ranged()//add a distance restricted equipment. Why not?
|
||||
return range&RANGED
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/is_melee()
|
||||
return range&MELEE
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/action_checks(atom/target)
|
||||
if(!target)
|
||||
return 0
|
||||
if(!chassis)
|
||||
return 0
|
||||
if(!equip_ready)
|
||||
return 0
|
||||
if(crit_fail)
|
||||
return 0
|
||||
if(energy_drain && !chassis.has_charge(energy_drain))
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/action(atom/target)
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/start_cooldown()
|
||||
set_ready_state(0)
|
||||
chassis.use_power(energy_drain)
|
||||
addtimer(src, "set_ready_state", equip_cooldown, FALSE, 1)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(atom/target)
|
||||
if(!chassis)
|
||||
return
|
||||
var/C = chassis.loc
|
||||
set_ready_state(0)
|
||||
chassis.use_power(energy_drain)
|
||||
. = do_after(chassis.occupant, equip_cooldown, target=target)
|
||||
set_ready_state(1)
|
||||
if(!chassis || chassis.loc != C || src != chassis.selected)
|
||||
return 0
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/can_attach(obj/mecha/M)
|
||||
if(M.equipment.len<M.max_equip)
|
||||
return 1
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/attach(obj/mecha/M)
|
||||
M.equipment += src
|
||||
chassis = M
|
||||
src.loc = M
|
||||
M.log_message("[src] initialized.")
|
||||
if(!M.selected && selectable)
|
||||
M.selected = src
|
||||
src.update_chassis_page()
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/detach(atom/moveto=null)
|
||||
moveto = moveto || get_turf(chassis)
|
||||
if(src.Move(moveto))
|
||||
chassis.equipment -= src
|
||||
if(chassis.selected == src)
|
||||
chassis.selected = null
|
||||
update_chassis_page()
|
||||
chassis.log_message("[src] removed from equipment.")
|
||||
chassis = null
|
||||
set_ready_state(1)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/Topic(href,href_list)
|
||||
if(href_list["detach"])
|
||||
detach()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/set_ready_state(state)
|
||||
equip_ready = state
|
||||
if(chassis)
|
||||
send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/occupant_message(message)
|
||||
if(chassis)
|
||||
chassis.occupant_message("\icon[src] [message]")
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/log_message(message)
|
||||
if(chassis)
|
||||
chassis.log_message("<i>[src]:</i> [message]")
|
||||
return
|
||||
|
||||
|
||||
//Used for reloading weapons/tools etc. that use some form of resource
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/rearm()
|
||||
return 0
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/proc/needs_rearm()
|
||||
return 0
|
||||
@@ -0,0 +1,564 @@
|
||||
// Sleeper, Medical Beam, and Syringe gun
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/New()
|
||||
..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/can_attach(obj/mecha/medical/M)
|
||||
if(..() && istype(M))
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/attach(obj/mecha/M)
|
||||
..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/process()
|
||||
if(!chassis)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return 1
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/detach()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper
|
||||
name = "mounted sleeper"
|
||||
desc = "Equipment for medical exosuits. A mounted sleeper that stabilizes patients and can inject reagents in the exosuit's reserves."
|
||||
icon = 'icons/obj/Cryogenic2.dmi'
|
||||
icon_state = "sleeper"
|
||||
origin_tech = "engineering=3;biotech=3;plasmatech=2"
|
||||
energy_drain = 20
|
||||
range = MELEE
|
||||
equip_cooldown = 20
|
||||
var/mob/living/carbon/patient = null
|
||||
var/inject_amount = 10
|
||||
salvageable = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/allow_drop()
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/Destroy()
|
||||
for(var/atom/movable/AM in src)
|
||||
AM.forceMove(get_turf(src))
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/Exit(atom/movable/O)
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/action(mob/living/carbon/target)
|
||||
if(!action_checks(target))
|
||||
return
|
||||
if(!istype(target))
|
||||
return
|
||||
if(!patient_insertion_check(target))
|
||||
return
|
||||
occupant_message("<span class='notice'>You start putting [target] into [src]...</span>")
|
||||
chassis.visible_message("<span class='warning'>[chassis] starts putting [target] into \the [src].</span>")
|
||||
if(do_after_cooldown(target))
|
||||
if(!patient_insertion_check(target))
|
||||
return
|
||||
target.forceMove(src)
|
||||
patient = target
|
||||
START_PROCESSING(SSobj, src)
|
||||
update_equip_info()
|
||||
occupant_message("<span class='notice'>[target] successfully loaded into [src]. Life support functions engaged.</span>")
|
||||
chassis.visible_message("<span class='warning'>[chassis] loads [target] into [src].</span>")
|
||||
log_message("[target] loaded. Life support functions engaged.")
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/patient_insertion_check(mob/living/carbon/target)
|
||||
if(target.buckled)
|
||||
occupant_message("<span class='warning'>[target] will not fit into the sleeper because they are buckled to [target.buckled]!</span>")
|
||||
return
|
||||
if(target.has_buckled_mobs())
|
||||
occupant_message("<span class='warning'>[target] will not fit into the sleeper because of the creatures attached to it!</span>")
|
||||
return
|
||||
if(patient)
|
||||
occupant_message("<span class='warning'>The sleeper is already occupied!</span>")
|
||||
return
|
||||
return 1
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/go_out()
|
||||
if(!patient)
|
||||
return
|
||||
patient.forceMove(get_turf(src))
|
||||
occupant_message("[patient] ejected. Life support functions disabled.")
|
||||
log_message("[patient] ejected. Life support functions disabled.")
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
patient = null
|
||||
update_equip_info()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/detach()
|
||||
if(patient)
|
||||
occupant_message("<span class='warning'>Unable to detach [src] - equipment occupied!</span>")
|
||||
return
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/get_equip_info()
|
||||
var/output = ..()
|
||||
if(output)
|
||||
var/temp = ""
|
||||
if(patient)
|
||||
temp = "<br />\[Occupant: [patient] ([patient.stat > 1 ? "*DECEASED*" : "Health: [patient.health]%"])\]<br /><a href='?src=\ref[src];view_stats=1'>View stats</a>|<a href='?src=\ref[src];eject=1'>Eject</a>"
|
||||
return "[output] [temp]"
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/Topic(href,href_list)
|
||||
..()
|
||||
var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
|
||||
if(filter.get("eject"))
|
||||
go_out()
|
||||
if(filter.get("view_stats"))
|
||||
chassis.occupant << browse(get_patient_stats(),"window=msleeper")
|
||||
onclose(chassis.occupant, "msleeper")
|
||||
return
|
||||
if(filter.get("inject"))
|
||||
inject_reagent(filter.getType("inject",/datum/reagent),filter.getObj("source"))
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_patient_stats()
|
||||
if(!patient)
|
||||
return
|
||||
return {"<html>
|
||||
<head>
|
||||
<title>[patient] statistics</title>
|
||||
<script language='javascript' type='text/javascript'>
|
||||
[js_byjax]
|
||||
</script>
|
||||
<style>
|
||||
h3 {margin-bottom:2px;font-size:14px;}
|
||||
#lossinfo, #reagents, #injectwith {padding-left:15px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h3>Health statistics</h3>
|
||||
<div id="lossinfo">
|
||||
[get_patient_dam()]
|
||||
</div>
|
||||
<h3>Reagents in bloodstream</h3>
|
||||
<div id="reagents">
|
||||
[get_patient_reagents()]
|
||||
</div>
|
||||
<div id="injectwith">
|
||||
[get_available_reagents()]
|
||||
</div>
|
||||
</body>
|
||||
</html>"}
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_patient_dam()
|
||||
var/t1
|
||||
switch(patient.stat)
|
||||
if(0)
|
||||
t1 = "Conscious"
|
||||
if(1)
|
||||
t1 = "Unconscious"
|
||||
if(2)
|
||||
t1 = "*dead*"
|
||||
else
|
||||
t1 = "Unknown"
|
||||
return {"<font color="[patient.health > 50 ? "blue" : "red"]"><b>Health:</b> [patient.stat > 1 ? "[t1]" : "[patient.health]% ([t1])"]</font><br />
|
||||
<font color="[patient.bodytemperature > 50 ? "blue" : "red"]"><b>Core Temperature:</b> [patient.bodytemperature-T0C]°C ([patient.bodytemperature*1.8-459.67]°F)</font><br />
|
||||
<font color="[patient.getBruteLoss() < 60 ? "blue" : "red"]"><b>Brute Damage:</b> [patient.getBruteLoss()]%</font><br />
|
||||
<font color="[patient.getOxyLoss() < 60 ? "blue" : "red"]"><b>Respiratory Damage:</b> [patient.getOxyLoss()]%</font><br />
|
||||
<font color="[patient.getToxLoss() < 60 ? "blue" : "red"]"><b>Toxin Content:</b> [patient.getToxLoss()]%</font><br />
|
||||
<font color="[patient.getFireLoss() < 60 ? "blue" : "red"]"><b>Burn Severity:</b> [patient.getFireLoss()]%</font><br />
|
||||
<font color="red">[patient.getCloneLoss() ? "Subject appears to have cellular damage." : ""]</font><br />
|
||||
<font color="red">[patient.getBrainLoss() ? "Significant brain damage detected." : ""]</font><br />
|
||||
"}
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_patient_reagents()
|
||||
if(patient.reagents)
|
||||
for(var/datum/reagent/R in patient.reagents.reagent_list)
|
||||
if(R.volume > 0)
|
||||
. += "[R]: [round(R.volume,0.01)]<br />"
|
||||
return . || "None"
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/get_available_reagents()
|
||||
var/output
|
||||
var/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/SG = locate(/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun) in chassis
|
||||
if(SG && SG.reagents && islist(SG.reagents.reagent_list))
|
||||
for(var/datum/reagent/R in SG.reagents.reagent_list)
|
||||
if(R.volume > 0)
|
||||
output += "<a href=\"?src=\ref[src];inject=\ref[R];source=\ref[SG]\">Inject [R.name]</a><br />"
|
||||
return output
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/proc/inject_reagent(datum/reagent/R,obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/SG)
|
||||
if(!R || !patient || !SG || !(SG in chassis.equipment))
|
||||
return 0
|
||||
var/to_inject = min(R.volume, inject_amount)
|
||||
if(to_inject && patient.reagents.get_reagent_amount(R.id) + to_inject <= inject_amount*2)
|
||||
occupant_message("Injecting [patient] with [to_inject] units of [R.name].")
|
||||
log_message("Injecting [patient] with [to_inject] units of [R.name].")
|
||||
add_logs(chassis.occupant, patient, "injected", "[name] ([R] - [to_inject] units)")
|
||||
SG.reagents.trans_id_to(patient,R.id,to_inject)
|
||||
update_equip_info()
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/update_equip_info()
|
||||
if(..())
|
||||
if(patient)
|
||||
send_byjax(chassis.occupant,"msleeper.browser","lossinfo",get_patient_dam())
|
||||
send_byjax(chassis.occupant,"msleeper.browser","reagents",get_patient_reagents())
|
||||
send_byjax(chassis.occupant,"msleeper.browser","injectwith",get_available_reagents())
|
||||
return 1
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/container_resist()
|
||||
go_out()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/sleeper/process()
|
||||
if(..())
|
||||
return
|
||||
if(!chassis.has_charge(energy_drain))
|
||||
set_ready_state(1)
|
||||
log_message("Deactivated.")
|
||||
occupant_message("[src] deactivated - no power.")
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return
|
||||
var/mob/living/carbon/M = patient
|
||||
if(!M)
|
||||
return
|
||||
if(M.health > 0)
|
||||
M.adjustOxyLoss(-1)
|
||||
M.updatehealth()
|
||||
M.AdjustStunned(-4)
|
||||
M.AdjustWeakened(-4)
|
||||
M.AdjustStunned(-4)
|
||||
if(M.reagents.get_reagent_amount("epinephrine") < 5)
|
||||
M.reagents.add_reagent("epinephrine", 5)
|
||||
chassis.use_power(energy_drain)
|
||||
update_equip_info()
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////// Syringe Gun ///////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun
|
||||
name = "exosuit syringe gun"
|
||||
desc = "Equipment for medical exosuits. A chem synthesizer with syringe gun. Reagents inside are held in stasis, so no reactions will occur."
|
||||
icon = 'icons/obj/guns/projectile.dmi'
|
||||
icon_state = "syringegun"
|
||||
var/list/syringes
|
||||
var/list/known_reagents
|
||||
var/list/processed_reagents
|
||||
var/max_syringes = 10
|
||||
var/max_volume = 75 //max reagent volume
|
||||
var/synth_speed = 5 //[num] reagent units per cycle
|
||||
energy_drain = 10
|
||||
var/mode = 0 //0 - fire syringe, 1 - analyze reagents.
|
||||
range = MELEE|RANGED
|
||||
equip_cooldown = 10
|
||||
origin_tech = "materials=3;biotech=4;magnets=4"
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/New()
|
||||
..()
|
||||
create_reagents(max_volume)
|
||||
reagents.set_reacting(FALSE)
|
||||
syringes = new
|
||||
known_reagents = list("epinephrine"="Epinephrine","charcoal"="Charcoal")
|
||||
processed_reagents = new
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/detach()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/critfail()
|
||||
..()
|
||||
if(reagents)
|
||||
reagents.set_reacting(TRUE)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/can_attach(obj/mecha/medical/M)
|
||||
if(..())
|
||||
if(istype(M))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/get_equip_info()
|
||||
var/output = ..()
|
||||
if(output)
|
||||
return "[output] \[<a href=\"?src=\ref[src];toggle_mode=1\">[mode? "Analyze" : "Launch"]</a>\]<br />\[Syringes: [syringes.len]/[max_syringes] | Reagents: [reagents.total_volume]/[reagents.maximum_volume]\]<br /><a href='?src=\ref[src];show_reagents=1'>Reagents list</a>"
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/action(atom/movable/target)
|
||||
if(!action_checks(target))
|
||||
return
|
||||
if(istype(target,/obj/item/weapon/reagent_containers/syringe))
|
||||
return load_syringe(target)
|
||||
if(istype(target,/obj/item/weapon/storage))//Loads syringes from boxes
|
||||
for(var/obj/item/weapon/reagent_containers/syringe/S in target.contents)
|
||||
load_syringe(S)
|
||||
return
|
||||
if(mode)
|
||||
return analyze_reagents(target)
|
||||
if(!syringes.len)
|
||||
occupant_message("<span class=\"alert\">No syringes loaded.</span>")
|
||||
return
|
||||
if(reagents.total_volume<=0)
|
||||
occupant_message("<span class=\"alert\">No available reagents to load syringe with.</span>")
|
||||
return
|
||||
var/turf/trg = get_turf(target)
|
||||
var/obj/item/weapon/reagent_containers/syringe/mechsyringe = syringes[1]
|
||||
mechsyringe.forceMove(get_turf(chassis))
|
||||
reagents.trans_to(mechsyringe, min(mechsyringe.volume, reagents.total_volume))
|
||||
syringes -= mechsyringe
|
||||
mechsyringe.icon = 'icons/obj/chemical.dmi'
|
||||
mechsyringe.icon_state = "syringeproj"
|
||||
playsound(chassis, 'sound/items/syringeproj.ogg', 50, 1)
|
||||
log_message("Launched [mechsyringe] from [src], targeting [target].")
|
||||
var/mob/originaloccupant = chassis.occupant
|
||||
spawn(0)
|
||||
src = null //if src is deleted, still process the syringe
|
||||
for(var/i=0, i<6, i++)
|
||||
if(!mechsyringe)
|
||||
break
|
||||
if(step_towards(mechsyringe,trg))
|
||||
var/list/mobs = new
|
||||
for(var/mob/living/carbon/M in mechsyringe.loc)
|
||||
mobs += M
|
||||
var/mob/living/carbon/M = safepick(mobs)
|
||||
if(M)
|
||||
var/R
|
||||
mechsyringe.visible_message("<span class=\"attack\"> [M] was hit by the syringe!</span>")
|
||||
if(M.can_inject(null, 1))
|
||||
if(mechsyringe.reagents)
|
||||
for(var/datum/reagent/A in mechsyringe.reagents.reagent_list)
|
||||
R += A.id + " ("
|
||||
R += num2text(A.volume) + "),"
|
||||
mechsyringe.icon_state = initial(mechsyringe.icon_state)
|
||||
mechsyringe.icon = initial(mechsyringe.icon)
|
||||
mechsyringe.reagents.reaction(M, INJECT)
|
||||
mechsyringe.reagents.trans_to(M, mechsyringe.reagents.total_volume)
|
||||
M.take_organ_damage(2)
|
||||
add_logs(originaloccupant, M, "shot", "syringegun")
|
||||
break
|
||||
else if(mechsyringe.loc == trg)
|
||||
mechsyringe.icon_state = initial(mechsyringe.icon_state)
|
||||
mechsyringe.icon = initial(mechsyringe.icon)
|
||||
mechsyringe.update_icon()
|
||||
break
|
||||
else
|
||||
mechsyringe.icon_state = initial(mechsyringe.icon_state)
|
||||
mechsyringe.icon = initial(mechsyringe.icon)
|
||||
mechsyringe.update_icon()
|
||||
break
|
||||
sleep(1)
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/Topic(href,href_list)
|
||||
..()
|
||||
var/datum/topic_input/filter = new (href,href_list)
|
||||
if(filter.get("toggle_mode"))
|
||||
mode = !mode
|
||||
update_equip_info()
|
||||
return
|
||||
if(filter.get("select_reagents"))
|
||||
processed_reagents.len = 0
|
||||
var/m = 0
|
||||
var/message
|
||||
for(var/i=1 to known_reagents.len)
|
||||
if(m>=synth_speed)
|
||||
break
|
||||
var/reagent = filter.get("reagent_[i]")
|
||||
if(reagent && (reagent in known_reagents))
|
||||
message = "[m ? ", " : null][known_reagents[reagent]]"
|
||||
processed_reagents += reagent
|
||||
m++
|
||||
if(processed_reagents.len)
|
||||
message += " added to production"
|
||||
START_PROCESSING(SSobj, src)
|
||||
occupant_message(message)
|
||||
occupant_message("Reagent processing started.")
|
||||
log_message("Reagent processing started.")
|
||||
return
|
||||
if(filter.get("show_reagents"))
|
||||
chassis.occupant << browse(get_reagents_page(),"window=msyringegun")
|
||||
if(filter.get("purge_reagent"))
|
||||
var/reagent = filter.get("purge_reagent")
|
||||
if(reagent)
|
||||
reagents.del_reagent(reagent)
|
||||
return
|
||||
if(filter.get("purge_all"))
|
||||
reagents.clear_reagents()
|
||||
return
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/get_reagents_page()
|
||||
var/output = {"<html>
|
||||
<head>
|
||||
<title>Reagent Synthesizer</title>
|
||||
<script language='javascript' type='text/javascript'>
|
||||
[js_byjax]
|
||||
</script>
|
||||
<style>
|
||||
h3 {margin-bottom:2px;font-size:14px;}
|
||||
#reagents, #reagents_form {}
|
||||
form {width: 90%; margin:10px auto; border:1px dotted #999; padding:6px;}
|
||||
#submit {margin-top:5px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h3>Current reagents:</h3>
|
||||
<div id="reagents">
|
||||
[get_current_reagents()]
|
||||
</div>
|
||||
<h3>Reagents production:</h3>
|
||||
<div id="reagents_form">
|
||||
[get_reagents_form()]
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
return output
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/get_reagents_form()
|
||||
var/r_list = get_reagents_list()
|
||||
var/inputs
|
||||
if(r_list)
|
||||
inputs += "<input type=\"hidden\" name=\"src\" value=\"\ref[src]\">"
|
||||
inputs += "<input type=\"hidden\" name=\"select_reagents\" value=\"1\">"
|
||||
inputs += "<input id=\"submit\" type=\"submit\" value=\"Apply settings\">"
|
||||
var/output = {"<form action="byond://" method="get">
|
||||
[r_list || "No known reagents"]
|
||||
[inputs]
|
||||
</form>
|
||||
[r_list? "<span style=\"font-size:80%;\">Only the first [synth_speed] selected reagent\s will be added to production</span>" : null]
|
||||
"}
|
||||
return output
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/get_reagents_list()
|
||||
var/output
|
||||
for(var/i=1 to known_reagents.len)
|
||||
var/reagent_id = known_reagents[i]
|
||||
output += {"<input type="checkbox" value="[reagent_id]" name="reagent_[i]" [(reagent_id in processed_reagents)? "checked=\"1\"" : null]> [known_reagents[reagent_id]]<br />"}
|
||||
return output
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/get_current_reagents()
|
||||
var/output
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
if(R.volume > 0)
|
||||
output += "[R]: [round(R.volume,0.001)] - <a href=\"?src=\ref[src];purge_reagent=[R.id]\">Purge Reagent</a><br />"
|
||||
if(output)
|
||||
output += "Total: [round(reagents.total_volume,0.001)]/[reagents.maximum_volume] - <a href=\"?src=\ref[src];purge_all=1\">Purge All</a>"
|
||||
return output || "None"
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/load_syringe(obj/item/weapon/reagent_containers/syringe/S)
|
||||
if(syringes.len<max_syringes)
|
||||
if(get_dist(src,S) >= 2)
|
||||
occupant_message("The syringe is too far away.")
|
||||
return 0
|
||||
for(var/obj/structure/D in S.loc)//Basic level check for structures in the way (Like grilles and windows)
|
||||
if(!(D.CanPass(S,src.loc)))
|
||||
occupant_message("Unable to load syringe.")
|
||||
return 0
|
||||
for(var/obj/machinery/door/D in S.loc)//Checks for doors
|
||||
if(!(D.CanPass(S,src.loc)))
|
||||
occupant_message("Unable to load syringe.")
|
||||
return 0
|
||||
S.reagents.trans_to(src, S.reagents.total_volume)
|
||||
S.forceMove(src)
|
||||
syringes += S
|
||||
occupant_message("Syringe loaded.")
|
||||
update_equip_info()
|
||||
return 1
|
||||
occupant_message("The [src] syringe chamber is full.")
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/analyze_reagents(atom/A)
|
||||
if(get_dist(src,A) >= 4)
|
||||
occupant_message("The object is too far away.")
|
||||
return 0
|
||||
if(!A.reagents || istype(A,/mob))
|
||||
occupant_message("<span class=\"alert\">No reagent info gained from [A].</span>")
|
||||
return 0
|
||||
occupant_message("Analyzing reagents...")
|
||||
for(var/datum/reagent/R in A.reagents.reagent_list)
|
||||
if(R.can_synth && add_known_reagent(R.id,R.name))
|
||||
occupant_message("Reagent analyzed, identified as [R.name] and added to database.")
|
||||
send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form())
|
||||
occupant_message("Analyzis complete.")
|
||||
return 1
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/proc/add_known_reagent(r_id,r_name)
|
||||
if(!(r_id in known_reagents))
|
||||
known_reagents += r_id
|
||||
known_reagents[r_id] = r_name
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/update_equip_info()
|
||||
if(..())
|
||||
send_byjax(chassis.occupant,"msyringegun.browser","reagents",get_current_reagents())
|
||||
send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form())
|
||||
return 1
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/on_reagent_change()
|
||||
..()
|
||||
update_equip_info()
|
||||
return
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/syringe_gun/process()
|
||||
if(..())
|
||||
return
|
||||
if(!processed_reagents.len || reagents.total_volume >= reagents.maximum_volume || !chassis.has_charge(energy_drain))
|
||||
occupant_message("<span class=\"alert\">Reagent processing stopped.</a>")
|
||||
log_message("Reagent processing stopped.")
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return
|
||||
var/amount = synth_speed / processed_reagents.len
|
||||
for(var/reagent in processed_reagents)
|
||||
reagents.add_reagent(reagent,amount)
|
||||
chassis.use_power(energy_drain)
|
||||
|
||||
///////////////////////////////// Medical Beam ///////////////////////////////////////////////////////////////
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam
|
||||
name = "exosuit medical beamgun"
|
||||
desc = "Equipment for medical exosuits. Generates a focused beam of medical nanites."
|
||||
icon_state = "mecha_medigun"
|
||||
energy_drain = 10
|
||||
range = MELEE|RANGED
|
||||
equip_cooldown = 0
|
||||
origin_tech = "combat=5;materials=6;powerstorage=7;biotech=6"
|
||||
var/obj/item/weapon/gun/medbeam/mech/medigun
|
||||
materials = list(MAT_METAL = 15000, MAT_GLASS = 8000, MAT_PLASMA = 3000, MAT_GOLD = 8000, MAT_DIAMOND = 2000)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/New()
|
||||
..()
|
||||
medigun = new(src)
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/Destroy()
|
||||
qdel(medigun)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/process()
|
||||
if(..())
|
||||
return
|
||||
medigun.process()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/action(atom/target)
|
||||
medigun.process_fire(target, loc)
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/medical/mechmedbeam/detach()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
medigun.LoseTarget()
|
||||
return ..()
|
||||
@@ -0,0 +1,145 @@
|
||||
|
||||
// Drill, Diamond drill, Mining scanner
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/drill
|
||||
name = "exosuit drill"
|
||||
desc = "Equipment for engineering and combat exosuits. This is the drill that'll pierce the heavens!"
|
||||
icon_state = "mecha_drill"
|
||||
equip_cooldown = 30
|
||||
energy_drain = 10
|
||||
force = 15
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/action(atom/target)
|
||||
if(!action_checks(target))
|
||||
return
|
||||
if(istype(target, /turf/open/space))
|
||||
return
|
||||
if(isobj(target))
|
||||
var/obj/target_obj = target
|
||||
if(target_obj.unacidable)
|
||||
return
|
||||
target.visible_message("<span class='warning'>[chassis] starts to drill [target].</span>", \
|
||||
"<span class='userdanger'>[chassis] starts to drill [target]...</span>", \
|
||||
"<span class='italics'>You hear drilling.</span>")
|
||||
|
||||
if(do_after_cooldown(target))
|
||||
if(isturf(target))
|
||||
var/turf/T = target
|
||||
T.drill_act(src)
|
||||
else
|
||||
log_message("Drilled through [target]")
|
||||
if(isliving(target))
|
||||
if(istype(src , /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill))
|
||||
drill_mob(target, chassis.occupant, 120)
|
||||
else
|
||||
drill_mob(target, chassis.occupant)
|
||||
else
|
||||
target.ex_act(2)
|
||||
|
||||
/turf/proc/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill)
|
||||
return
|
||||
|
||||
/turf/closed/wall/r_wall/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill)
|
||||
if(istype(drill, /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill))
|
||||
if(drill.do_after_cooldown(src))//To slow down how fast mechs can drill through the station
|
||||
drill.log_message("Drilled through [src]")
|
||||
ex_act(3)
|
||||
else
|
||||
drill.occupant_message("<span class='danger'>[src] is too durable to drill through.</span>")
|
||||
|
||||
/turf/closed/mineral/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill)
|
||||
for(var/turf/closed/mineral/M in range(drill.chassis,1))
|
||||
if(get_dir(drill.chassis,M)&drill.chassis.dir)
|
||||
M.gets_drilled()
|
||||
drill.log_message("Drilled through [src]")
|
||||
drill.move_ores()
|
||||
|
||||
/turf/open/floor/plating/asteroid/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill)
|
||||
for(var/turf/open/floor/plating/asteroid/M in range(1, drill.chassis))
|
||||
if(get_dir(drill.chassis,M)&drill.chassis.dir)
|
||||
M.gets_dug()
|
||||
drill.log_message("Drilled through [src]")
|
||||
drill.move_ores()
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/proc/move_ores()
|
||||
if(locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in chassis.equipment)
|
||||
var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo
|
||||
if(ore_box)
|
||||
for(var/obj/item/weapon/ore/ore in range(1, chassis))
|
||||
if(get_dir(chassis,ore)&chassis.dir)
|
||||
ore.Move(ore_box)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/can_attach(obj/mecha/M as obj)
|
||||
if(..())
|
||||
if(istype(M, /obj/mecha/working) || istype(M, /obj/mecha/combat))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/proc/drill_mob(mob/living/target, mob/user, var/drill_damage=80)
|
||||
target.visible_message("<span class='danger'>[chassis] drills [target] with [src].</span>", \
|
||||
"<span class='userdanger'>[chassis] drills [target] with [src].</span>")
|
||||
add_logs(user, target, "attacked", "[name]", "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])")
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/obj/item/bodypart/affecting = H.get_bodypart("chest")
|
||||
affecting.take_damage(drill_damage)
|
||||
H.update_damage_overlays(0)
|
||||
else if(target.stat == DEAD && target.butcher_results)
|
||||
target.harvest(chassis) // Butcher the mob with our drill.
|
||||
else
|
||||
target.take_organ_damage(drill_damage)
|
||||
|
||||
if(target)
|
||||
target.Paralyse(10)
|
||||
target.updatehealth()
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/drill/diamonddrill
|
||||
name = "diamond-tipped exosuit drill"
|
||||
desc = "Equipment for engineering and combat exosuits. This is an upgraded version of the drill that'll pierce the heavens!"
|
||||
icon_state = "mecha_diamond_drill"
|
||||
origin_tech = "materials=4;engineering=4"
|
||||
equip_cooldown = 20
|
||||
force = 15
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/mining_scanner
|
||||
name = "exosuit mining scanner"
|
||||
desc = "Equipment for engineering and combat exosuits. It will automatically check surrounding rock for useful minerals."
|
||||
icon_state = "mecha_analyzer"
|
||||
selectable = 0
|
||||
equip_cooldown = 30
|
||||
var/scanning = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/mining_scanner/New()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/mining_scanner/attach(obj/mecha/M)
|
||||
..()
|
||||
M.occupant_sight_flags |= SEE_TURFS
|
||||
if(M.occupant)
|
||||
M.occupant.update_sight()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/mining_scanner/detach()
|
||||
chassis.occupant_sight_flags &= ~SEE_TURFS
|
||||
if(chassis.occupant)
|
||||
chassis.occupant.update_sight()
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/mining_scanner/process()
|
||||
if(!loc)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
qdel(src)
|
||||
if(scanning)
|
||||
return
|
||||
if(istype(loc,/obj/mecha/working))
|
||||
var/obj/mecha/working/mecha = loc
|
||||
if(!mecha.occupant)
|
||||
return
|
||||
var/list/L = list(mecha.occupant)
|
||||
scanning = 1
|
||||
mineral_scan_pulse(L,get_turf(loc))
|
||||
spawn(equip_cooldown)
|
||||
scanning = 0
|
||||
@@ -0,0 +1,491 @@
|
||||
|
||||
// Teleporter, Wormhole generator, Gravitational catapult, Armor booster modules,
|
||||
// Repair droid, Tesla Energy relay, Generators
|
||||
|
||||
////////////////////////////////////////////// TELEPORTER ///////////////////////////////////////////////
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/teleporter
|
||||
name = "mounted teleporter"
|
||||
desc = "An exosuit module that allows exosuits to teleport to any position in view."
|
||||
icon_state = "mecha_teleport"
|
||||
origin_tech = "bluespace=7"
|
||||
equip_cooldown = 150
|
||||
energy_drain = 1000
|
||||
range = RANGED
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/teleporter/action(atom/target)
|
||||
if(!action_checks(target) || src.loc.z == ZLEVEL_CENTCOM) return
|
||||
var/turf/T = get_turf(target)
|
||||
if(T)
|
||||
do_teleport(chassis, T, 4)
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////// WORMHOLE GENERATOR //////////////////////////////////////////
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/wormhole_generator
|
||||
name = "mounted wormhole generator"
|
||||
desc = "An exosuit module that allows generating of small quasi-stable wormholes."
|
||||
icon_state = "mecha_wholegen"
|
||||
origin_tech = "bluespace=4;magnets=4;plasmatech=2"
|
||||
equip_cooldown = 50
|
||||
energy_drain = 300
|
||||
range = RANGED
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/wormhole_generator/action(atom/target)
|
||||
if(!action_checks(target) || src.loc.z == ZLEVEL_CENTCOM)
|
||||
return
|
||||
var/list/theareas = get_areas_in_range(100, chassis)
|
||||
if(!theareas.len)
|
||||
return
|
||||
var/area/thearea = pick(theareas)
|
||||
var/list/L = list()
|
||||
var/turf/pos = get_turf(src)
|
||||
for(var/turf/T in get_area_turfs(thearea.type))
|
||||
if(!T.density && pos.z == T.z)
|
||||
var/clear = 1
|
||||
for(var/obj/O in T)
|
||||
if(O.density)
|
||||
clear = 0
|
||||
break
|
||||
if(clear)
|
||||
L+=T
|
||||
if(!L.len)
|
||||
return
|
||||
var/turf/target_turf = pick(L)
|
||||
if(!target_turf)
|
||||
return
|
||||
var/obj/effect/portal/P = new /obj/effect/portal(get_turf(target))
|
||||
P.target = target_turf
|
||||
P.creator = null
|
||||
P.icon = 'icons/obj/objects.dmi'
|
||||
P.icon_state = "anom"
|
||||
P.name = "wormhole"
|
||||
var/turf/T = get_turf(target)
|
||||
message_admins("[key_name_admin(chassis.occupant, chassis.occupant.client)](<A HREF='?_src_=holder;adminmoreinfo=\ref[chassis.occupant]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[chassis.occupant]'>FLW</A>) used a Wormhole Generator in ([T.x],[T.y],[T.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)",0,1)
|
||||
log_game("[key_name(chassis.occupant)] used a Wormhole Generator in ([T.x],[T.y],[T.z])")
|
||||
src = null
|
||||
spawn(rand(150,300))
|
||||
qdel(P)
|
||||
return 1
|
||||
|
||||
|
||||
/////////////////////////////////////// GRAVITATIONAL CATAPULT ///////////////////////////////////////////
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/gravcatapult
|
||||
name = "mounted gravitational catapult"
|
||||
desc = "An exosuit mounted Gravitational Catapult."
|
||||
icon_state = "mecha_teleport"
|
||||
origin_tech = "bluespace=3;magnets=3;engineering=4"
|
||||
equip_cooldown = 10
|
||||
energy_drain = 100
|
||||
range = MELEE|RANGED
|
||||
var/atom/movable/locked
|
||||
var/mode = 1 //1 - gravsling 2 - gravpush
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/gravcatapult/action(atom/movable/target)
|
||||
if(!action_checks(target))
|
||||
return
|
||||
switch(mode)
|
||||
if(1)
|
||||
if(!locked)
|
||||
if(!istype(target) || target.anchored)
|
||||
occupant_message("Unable to lock on [target]")
|
||||
return
|
||||
locked = target
|
||||
occupant_message("Locked on [target]")
|
||||
send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
|
||||
else if(target!=locked)
|
||||
if(locked in view(chassis))
|
||||
locked.throw_at(target, 14, 1.5)
|
||||
locked = null
|
||||
send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
|
||||
return 1
|
||||
else
|
||||
locked = null
|
||||
occupant_message("Lock on [locked] disengaged.")
|
||||
send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
|
||||
if(2)
|
||||
var/list/atoms = list()
|
||||
if(isturf(target))
|
||||
atoms = range(3, target)
|
||||
else
|
||||
atoms = orange(3, target)
|
||||
for(var/atom/movable/A in atoms)
|
||||
if(A.anchored) continue
|
||||
spawn(0)
|
||||
var/iter = 5-get_dist(A,target)
|
||||
for(var/i=0 to iter)
|
||||
step_away(A,target)
|
||||
sleep(2)
|
||||
var/turf/T = get_turf(target)
|
||||
log_game("[chassis.occupant.ckey]([chassis.occupant]) used a Gravitational Catapult in ([T.x],[T.y],[T.z])")
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/gravcatapult/get_equip_info()
|
||||
return "[..()] [mode==1?"([locked||"Nothing"])":null] \[<a href='?src=\ref[src];mode=1'>S</a>|<a href='?src=\ref[src];mode=2'>P</a>\]"
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/gravcatapult/Topic(href, href_list)
|
||||
..()
|
||||
if(href_list["mode"])
|
||||
mode = text2num(href_list["mode"])
|
||||
send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////// ARMOR BOOSTER MODULES //////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster //what is that noise? A BAWWW from TK mutants.
|
||||
name = "armor booster module (Close Combat Weaponry)"
|
||||
desc = "Boosts exosuit armor against armed melee attacks. Requires energy to operate."
|
||||
icon_state = "mecha_abooster_ccw"
|
||||
origin_tech = "materials=4;combat=4"
|
||||
equip_cooldown = 10
|
||||
energy_drain = 50
|
||||
range = 0
|
||||
var/deflect_coeff = 1.15
|
||||
var/damage_coeff = 0.8
|
||||
selectable = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/proc/attack_react(mob/user as mob)
|
||||
if(action_checks(user))
|
||||
start_cooldown()
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster
|
||||
name = "armor booster module (Ranged Weaponry)"
|
||||
desc = "Boosts exosuit armor against ranged attacks. Completely blocks taser shots. Requires energy to operate."
|
||||
icon_state = "mecha_abooster_proj"
|
||||
origin_tech = "materials=4;combat=3;engineering=3"
|
||||
equip_cooldown = 10
|
||||
energy_drain = 50
|
||||
range = 0
|
||||
var/deflect_coeff = 1.15
|
||||
var/damage_coeff = 0.8
|
||||
selectable = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/proc/projectile_react()
|
||||
if(action_checks(src))
|
||||
start_cooldown()
|
||||
return 1
|
||||
|
||||
|
||||
////////////////////////////////// REPAIR DROID //////////////////////////////////////////////////
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/repair_droid
|
||||
name = "exosuit repair droid"
|
||||
desc = "An automated repair droid for exosuits. Scans for damage and repairs it. Can fix almost all types of external or internal damage."
|
||||
icon_state = "repair_droid"
|
||||
origin_tech = "magnets=3;programming=3;engineering=4"
|
||||
energy_drain = 50
|
||||
range = 0
|
||||
var/health_boost = 1
|
||||
var/icon/droid_overlay
|
||||
var/list/repairable_damage = list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH)
|
||||
selectable = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/repair_droid/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
if(chassis)
|
||||
chassis.overlays -= droid_overlay
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/repair_droid/attach(obj/mecha/M as obj)
|
||||
..()
|
||||
droid_overlay = new(src.icon, icon_state = "repair_droid")
|
||||
M.add_overlay(droid_overlay)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/repair_droid/detach()
|
||||
chassis.overlays -= droid_overlay
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/repair_droid/get_equip_info()
|
||||
if(!chassis) return
|
||||
return "<span style=\"color:[equip_ready?"#0f0":"#f00"];\">*</span> [src.name] - <a href='?src=\ref[src];toggle_repairs=1'>[equip_ready?"A":"Dea"]ctivate</a>"
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/repair_droid/Topic(href, href_list)
|
||||
..()
|
||||
if(href_list["toggle_repairs"])
|
||||
chassis.overlays -= droid_overlay
|
||||
if(equip_ready)
|
||||
START_PROCESSING(SSobj, src)
|
||||
droid_overlay = new(src.icon, icon_state = "repair_droid_a")
|
||||
log_message("Activated.")
|
||||
set_ready_state(0)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
droid_overlay = new(src.icon, icon_state = "repair_droid")
|
||||
log_message("Deactivated.")
|
||||
set_ready_state(1)
|
||||
chassis.add_overlay(droid_overlay)
|
||||
send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/repair_droid/process()
|
||||
if(!chassis)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
return
|
||||
var/h_boost = health_boost
|
||||
var/repaired = 0
|
||||
if(chassis.internal_damage & MECHA_INT_SHORT_CIRCUIT)
|
||||
h_boost *= -2
|
||||
else if(chassis.internal_damage && prob(15))
|
||||
for(var/int_dam_flag in repairable_damage)
|
||||
if(chassis.internal_damage & int_dam_flag)
|
||||
chassis.clearInternalDamage(int_dam_flag)
|
||||
repaired = 1
|
||||
break
|
||||
if(health_boost<0 || chassis.health < initial(chassis.health))
|
||||
chassis.health += min(health_boost, initial(chassis.health)-chassis.health)
|
||||
repaired = 1
|
||||
if(repaired)
|
||||
if(!chassis.use_power(energy_drain))
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
else //no repair needed, we turn off
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
chassis.overlays -= droid_overlay
|
||||
droid_overlay = new(src.icon, icon_state = "repair_droid")
|
||||
chassis.add_overlay(droid_overlay)
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////// TESLA ENERGY RELAY ////////////////////////////////////////////////
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay
|
||||
name = "exosuit energy relay"
|
||||
desc = "An exosuit module that wirelessly drains energy from any available power channel in area. The performance index is quite low."
|
||||
icon_state = "tesla"
|
||||
origin_tech = "magnets=4;powerstorage=4;engineering=4"
|
||||
energy_drain = 0
|
||||
range = 0
|
||||
var/coeff = 100
|
||||
var/list/use_channels = list(EQUIP,ENVIRON,LIGHT)
|
||||
selectable = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/detach()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_charge()
|
||||
if(equip_ready) //disabled
|
||||
return
|
||||
var/area/A = get_area(chassis)
|
||||
var/pow_chan = get_power_channel(A)
|
||||
if(pow_chan)
|
||||
return 1000 //making magic
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_power_channel(var/area/A)
|
||||
var/pow_chan
|
||||
if(A)
|
||||
for(var/c in use_channels)
|
||||
if(A.master && A.master.powered(c))
|
||||
pow_chan = c
|
||||
break
|
||||
return pow_chan
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/Topic(href, href_list)
|
||||
..()
|
||||
if(href_list["toggle_relay"])
|
||||
if(equip_ready) //inactive
|
||||
START_PROCESSING(SSobj, src)
|
||||
set_ready_state(0)
|
||||
log_message("Activated.")
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
log_message("Deactivated.")
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/get_equip_info()
|
||||
if(!chassis) return
|
||||
return "<span style=\"color:[equip_ready?"#0f0":"#f00"];\">*</span> [src.name] - <a href='?src=\ref[src];toggle_relay=1'>[equip_ready?"A":"Dea"]ctivate</a>"
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/process()
|
||||
if(!chassis || chassis.internal_damage & MECHA_INT_SHORT_CIRCUIT)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
return
|
||||
var/cur_charge = chassis.get_charge()
|
||||
if(isnull(cur_charge) || !chassis.cell)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
occupant_message("No powercell detected.")
|
||||
return
|
||||
if(cur_charge < chassis.cell.maxcharge)
|
||||
var/area/A = get_area(chassis)
|
||||
if(A)
|
||||
var/pow_chan
|
||||
for(var/c in list(EQUIP,ENVIRON,LIGHT))
|
||||
if(A.master.powered(c))
|
||||
pow_chan = c
|
||||
break
|
||||
if(pow_chan)
|
||||
var/delta = min(20, chassis.cell.maxcharge-cur_charge)
|
||||
chassis.give_power(delta)
|
||||
A.master.use_power(delta*coeff, pow_chan)
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////// GENERATOR /////////////////////////////////////////////
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator
|
||||
name = "exosuit plasma converter"
|
||||
desc = "An exosuit module that generates power using solid plasma as fuel. Pollutes the environment."
|
||||
icon_state = "tesla"
|
||||
origin_tech = "plasmatech=2;powerstorage=2;engineering=2"
|
||||
range = MELEE
|
||||
var/coeff = 100
|
||||
var/obj/item/stack/sheet/fuel
|
||||
var/max_fuel = 150000
|
||||
var/fuel_per_cycle_idle = 25
|
||||
var/fuel_per_cycle_active = 200
|
||||
var/power_per_cycle = 20
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/New()
|
||||
..()
|
||||
generator_init()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/proc/generator_init()
|
||||
fuel = new /obj/item/stack/sheet/mineral/plasma(src)
|
||||
fuel.amount = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/detach()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/Topic(href, href_list)
|
||||
..()
|
||||
if(href_list["toggle"])
|
||||
if(equip_ready) //inactive
|
||||
set_ready_state(0)
|
||||
START_PROCESSING(SSobj, src)
|
||||
log_message("Activated.")
|
||||
else
|
||||
set_ready_state(1)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
log_message("Deactivated.")
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/get_equip_info()
|
||||
var/output = ..()
|
||||
if(output)
|
||||
return "[output] \[[fuel]: [round(fuel.amount*fuel.perunit,0.1)] cm<sup>3</sup>\] - <a href='?src=\ref[src];toggle=1'>[equip_ready?"A":"Dea"]ctivate</a>"
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/action(target)
|
||||
if(chassis)
|
||||
var/result = load_fuel(target)
|
||||
if(result)
|
||||
send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/proc/load_fuel(var/obj/item/stack/sheet/P)
|
||||
if(P.type == fuel.type && P.amount > 0)
|
||||
var/to_load = max(max_fuel - fuel.amount*fuel.perunit,0)
|
||||
if(to_load)
|
||||
var/units = min(max(round(to_load / P.perunit),1),P.amount)
|
||||
fuel.amount += units
|
||||
P.use(units)
|
||||
occupant_message("[units] unit\s of [fuel] successfully loaded.")
|
||||
return units
|
||||
else
|
||||
occupant_message("Unit is full.")
|
||||
return 0
|
||||
else
|
||||
occupant_message("<span class='warning'>[fuel] traces in target minimal! [P] cannot be used as fuel.</span>")
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/attackby(weapon,mob/user, params)
|
||||
load_fuel(weapon)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/critfail()
|
||||
..()
|
||||
var/turf/open/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
var/datum/gas_mixture/GM = new
|
||||
GM.assert_gas("plasma")
|
||||
if(prob(10))
|
||||
GM.gases["plasma"][MOLES] += 100
|
||||
GM.temperature = 1500+T0C //should be enough to start a fire
|
||||
T.visible_message("The [src] suddenly disgorges a cloud of heated plasma.")
|
||||
qdel(src)
|
||||
else
|
||||
GM.gases["plasma"][MOLES] += 5
|
||||
GM.temperature = istype(T) ? T.air.return_temperature() : T20C
|
||||
T.visible_message("The [src] suddenly disgorges a cloud of plasma.")
|
||||
T.assume_air(GM)
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/process()
|
||||
if(!chassis)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
set_ready_state(1)
|
||||
return
|
||||
if(fuel.amount<=0)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
log_message("Deactivated - no fuel.")
|
||||
set_ready_state(1)
|
||||
return
|
||||
var/cur_charge = chassis.get_charge()
|
||||
if(isnull(cur_charge))
|
||||
set_ready_state(1)
|
||||
occupant_message("No powercell detected.")
|
||||
log_message("Deactivated.")
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return
|
||||
var/use_fuel = fuel_per_cycle_idle
|
||||
if(cur_charge < chassis.cell.maxcharge)
|
||||
use_fuel = fuel_per_cycle_active
|
||||
chassis.give_power(power_per_cycle)
|
||||
fuel.amount -= min(use_fuel/fuel.perunit,fuel.amount)
|
||||
update_equip_info()
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/nuclear
|
||||
name = "exonuclear reactor"
|
||||
desc = "An exosuit module that generates power using uranium as fuel. Pollutes the environment."
|
||||
icon_state = "tesla"
|
||||
origin_tech = "powerstorage=4;engineering=4"
|
||||
max_fuel = 50000
|
||||
fuel_per_cycle_idle = 10
|
||||
fuel_per_cycle_active = 30
|
||||
power_per_cycle = 50
|
||||
var/rad_per_cycle = 0.3
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/nuclear/generator_init()
|
||||
fuel = new /obj/item/stack/sheet/mineral/uranium(src)
|
||||
fuel.amount = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/nuclear/critfail()
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/generator/nuclear/process()
|
||||
if(..())
|
||||
radiation_pulse(get_turf(src), 2, 7, rad_per_cycle, 1)
|
||||
@@ -0,0 +1,427 @@
|
||||
|
||||
//Hydraulic clamp, Kill clamp, Extinguisher, RCD, Cable layer.
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp
|
||||
name = "hydraulic clamp"
|
||||
desc = "Equipment for engineering exosuits. Lifts objects and loads them into cargo."
|
||||
icon_state = "mecha_clamp"
|
||||
equip_cooldown = 15
|
||||
energy_drain = 10
|
||||
var/dam_force = 20
|
||||
var/obj/mecha/working/ripley/cargo_holder
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/can_attach(obj/mecha/working/ripley/M as obj)
|
||||
if(..())
|
||||
if(istype(M))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/attach(obj/mecha/M as obj)
|
||||
..()
|
||||
cargo_holder = M
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/detach(atom/moveto = null)
|
||||
..()
|
||||
cargo_holder = null
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/action(atom/target)
|
||||
if(!action_checks(target))
|
||||
return
|
||||
if(!cargo_holder)
|
||||
return
|
||||
if(istype(target,/obj))
|
||||
var/obj/O = target
|
||||
if(!O.anchored)
|
||||
if(cargo_holder.cargo.len < cargo_holder.cargo_capacity)
|
||||
chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.")
|
||||
O.anchored = 1
|
||||
if(do_after_cooldown(target))
|
||||
cargo_holder.cargo += O
|
||||
O.loc = chassis
|
||||
O.anchored = 0
|
||||
occupant_message("<span class='notice'>[target] successfully loaded.</span>")
|
||||
log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]")
|
||||
else
|
||||
O.anchored = initial(O.anchored)
|
||||
else
|
||||
occupant_message("<span class='warning'>Not enough room in cargo compartment!</span>")
|
||||
else
|
||||
occupant_message("<span class='warning'>[target] is firmly secured!</span>")
|
||||
|
||||
else if(istype(target,/mob/living))
|
||||
var/mob/living/M = target
|
||||
if(M.stat == DEAD) return
|
||||
if(chassis.occupant.a_intent == "harm")
|
||||
M.take_overall_damage(dam_force)
|
||||
if(!M)
|
||||
return
|
||||
M.adjustOxyLoss(round(dam_force/2))
|
||||
M.updatehealth()
|
||||
target.visible_message("<span class='danger'>[chassis] squeezes [target].</span>", \
|
||||
"<span class='userdanger'>[chassis] squeezes [target].</span>",\
|
||||
"<span class='italics'>You hear something crack.</span>")
|
||||
add_logs(chassis.occupant, M, "attacked", "[name]", "(INTENT: [uppertext(chassis.occupant.a_intent)]) (DAMTYE: [uppertext(damtype)])")
|
||||
else
|
||||
step_away(M,chassis)
|
||||
occupant_message("You push [target] out of the way.")
|
||||
chassis.visible_message("[chassis] pushes [target] out of the way.")
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
//This is pretty much just for the death-ripley
|
||||
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill
|
||||
name = "\improper KILL CLAMP"
|
||||
desc = "They won't know what clamped them!"
|
||||
energy_drain = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill/action(atom/target)
|
||||
if(!action_checks(target)) return
|
||||
if(!cargo_holder) return
|
||||
if(istype(target,/obj))
|
||||
var/obj/O = target
|
||||
if(!O.anchored)
|
||||
if(cargo_holder.cargo.len < cargo_holder.cargo_capacity)
|
||||
chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.")
|
||||
O.anchored = 1
|
||||
if(do_after_cooldown(target))
|
||||
cargo_holder.cargo += O
|
||||
O.loc = chassis
|
||||
O.anchored = 0
|
||||
occupant_message("<span class='notice'>[target] successfully loaded.</span>")
|
||||
log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]")
|
||||
else
|
||||
O.anchored = initial(O.anchored)
|
||||
else
|
||||
occupant_message("<span class='warning'>Not enough room in cargo compartment!</span>")
|
||||
else
|
||||
occupant_message("<span class='warning'>[target] is firmly secured!</span>")
|
||||
|
||||
else if(istype(target,/mob/living))
|
||||
var/mob/living/M = target
|
||||
if(M.stat == DEAD) return
|
||||
if(chassis.occupant.a_intent == "harm")
|
||||
target.visible_message("<span class='danger'>[chassis] destroys [target] in an unholy fury.</span>", \
|
||||
"<span class='userdanger'>[chassis] destroys [target] in an unholy fury.</span>")
|
||||
if(chassis.occupant.a_intent == "disarm")
|
||||
target.visible_message("<span class='danger'>[chassis] rips [target]'s arms off.</span>", \
|
||||
"<span class='userdanger'>[chassis] rips [target]'s arms off.</span>")
|
||||
else
|
||||
step_away(M,chassis)
|
||||
target.visible_message("[chassis] tosses [target] like a piece of paper.")
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/extinguisher
|
||||
name = "exosuit extinguisher"
|
||||
desc = "Equipment for engineering exosuits. A rapid-firing high capacity fire extinguisher."
|
||||
icon_state = "mecha_exting"
|
||||
equip_cooldown = 5
|
||||
energy_drain = 0
|
||||
range = MELEE|RANGED
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/extinguisher/New()
|
||||
create_reagents(1000)
|
||||
reagents.add_reagent("water", 1000)
|
||||
..()
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/extinguisher/action(atom/target) //copypasted from extinguisher. TODO: Rewrite from scratch.
|
||||
if(!action_checks(target) || get_dist(chassis, target)>3)
|
||||
return
|
||||
|
||||
if(istype(target, /obj/structure/reagent_dispensers/watertank) && get_dist(chassis,target) <= 1)
|
||||
var/obj/structure/reagent_dispensers/watertank/WT = target
|
||||
WT.reagents.trans_to(src, 1000)
|
||||
occupant_message("<span class='notice'>Extinguisher refilled.</span>")
|
||||
playsound(chassis, 'sound/effects/refill.ogg', 50, 1, -6)
|
||||
else
|
||||
if(reagents.total_volume > 0)
|
||||
playsound(chassis, 'sound/effects/extinguish.ogg', 75, 1, -3)
|
||||
var/direction = get_dir(chassis,target)
|
||||
var/turf/T = get_turf(target)
|
||||
var/turf/T1 = get_step(T,turn(direction, 90))
|
||||
var/turf/T2 = get_step(T,turn(direction, -90))
|
||||
|
||||
var/list/the_targets = list(T,T1,T2)
|
||||
spawn(0)
|
||||
for(var/a=0, a<5, a++)
|
||||
var/obj/effect/particle_effect/water/W = PoolOrNew(/obj/effect/particle_effect/water, get_turf(chassis))
|
||||
if(!W)
|
||||
return
|
||||
var/turf/my_target = pick(the_targets)
|
||||
var/datum/reagents/R = new/datum/reagents(5)
|
||||
W.reagents = R
|
||||
R.my_atom = W
|
||||
reagents.trans_to(W,1)
|
||||
for(var/b=0, b<4, b++)
|
||||
if(!W)
|
||||
return
|
||||
step_towards(W,my_target)
|
||||
if(!W)
|
||||
return
|
||||
var/turf/W_turf = get_turf(W)
|
||||
W.reagents.reaction(W_turf)
|
||||
for(var/atom/atm in W_turf)
|
||||
W.reagents.reaction(atm)
|
||||
if(W.loc == my_target)
|
||||
break
|
||||
sleep(2)
|
||||
return 1
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/extinguisher/get_equip_info()
|
||||
return "[..()] \[[src.reagents.total_volume]\]"
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/extinguisher/on_reagent_change()
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/extinguisher/can_attach(obj/mecha/working/M as obj)
|
||||
if(..())
|
||||
if(istype(M))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/rcd
|
||||
name = "mounted RCD"
|
||||
desc = "An exosuit-mounted Rapid Construction Device."
|
||||
icon_state = "mecha_rcd"
|
||||
origin_tech = "materials=4;bluespace=3;magnets=4;powerstorage=4;engineering=4"
|
||||
equip_cooldown = 10
|
||||
energy_drain = 250
|
||||
range = MELEE|RANGED
|
||||
var/mode = 0 //0 - deconstruct, 1 - wall or floor, 2 - airlock.
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/rcd/New()
|
||||
rcd_list += src
|
||||
..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/rcd/Destroy()
|
||||
rcd_list -= src
|
||||
..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/rcd/action(atom/target)
|
||||
if(istype(target, /turf/open/space/transit))//>implying these are ever made -Sieve
|
||||
return
|
||||
|
||||
if(!istype(target, /turf) && !istype(target, /obj/machinery/door/airlock))
|
||||
target = get_turf(target)
|
||||
if(!action_checks(target) || get_dist(chassis, target)>3)
|
||||
return
|
||||
playsound(chassis, 'sound/machines/click.ogg', 50, 1)
|
||||
|
||||
switch(mode)
|
||||
if(0)
|
||||
if (istype(target, /turf/closed/wall))
|
||||
var/turf/closed/wall/W = target
|
||||
occupant_message("Deconstructing [W]...")
|
||||
if(do_after_cooldown(W))
|
||||
chassis.spark_system.start()
|
||||
W.ChangeTurf(/turf/open/floor/plating)
|
||||
playsound(W, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
else if (istype(target, /turf/open/floor))
|
||||
var/turf/open/floor/F = target
|
||||
occupant_message("Deconstructing [F]...")
|
||||
if(do_after_cooldown(target))
|
||||
chassis.spark_system.start()
|
||||
F.ChangeTurf(F.baseturf)
|
||||
playsound(F, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
else if (istype(target, /obj/machinery/door/airlock))
|
||||
occupant_message("Deconstructing [target]...")
|
||||
if(do_after_cooldown(target))
|
||||
chassis.spark_system.start()
|
||||
qdel(target)
|
||||
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
if(1)
|
||||
if(istype(target, /turf/open/space))
|
||||
var/turf/open/space/S = target
|
||||
occupant_message("Building Floor...")
|
||||
if(do_after_cooldown(S))
|
||||
S.ChangeTurf(/turf/open/floor/plating)
|
||||
playsound(S, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
chassis.spark_system.start()
|
||||
else if(istype(target, /turf/open/floor))
|
||||
var/turf/open/floor/F = target
|
||||
occupant_message("Building Wall...")
|
||||
if(do_after_cooldown(F))
|
||||
F.ChangeTurf(/turf/closed/wall)
|
||||
playsound(F, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
chassis.spark_system.start()
|
||||
if(2)
|
||||
if(istype(target, /turf/open/floor))
|
||||
occupant_message("Building Airlock...")
|
||||
if(do_after_cooldown(target))
|
||||
chassis.spark_system.start()
|
||||
var/obj/machinery/door/airlock/T = new /obj/machinery/door/airlock(target)
|
||||
T.autoclose = 1
|
||||
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
playsound(target, 'sound/effects/sparks2.ogg', 50, 1)
|
||||
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/rcd/do_after_cooldown(var/atom/target)
|
||||
. = ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/rcd/Topic(href,href_list)
|
||||
..()
|
||||
if(href_list["mode"])
|
||||
mode = text2num(href_list["mode"])
|
||||
switch(mode)
|
||||
if(0)
|
||||
occupant_message("Switched RCD to Deconstruct.")
|
||||
energy_drain = initial(energy_drain)
|
||||
if(1)
|
||||
occupant_message("Switched RCD to Construct.")
|
||||
energy_drain = 2*initial(energy_drain)
|
||||
if(2)
|
||||
occupant_message("Switched RCD to Construct Airlock.")
|
||||
energy_drain = 2*initial(energy_drain)
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/rcd/get_equip_info()
|
||||
return "[..()] \[<a href='?src=\ref[src];mode=0'>D</a>|<a href='?src=\ref[src];mode=1'>C</a>|<a href='?src=\ref[src];mode=2'>A</a>\]"
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer
|
||||
name = "cable layer"
|
||||
desc = "Equipment for engineering exosuits. Lays cable along the exosuit's path."
|
||||
icon_state = "mecha_wire"
|
||||
var/datum/event/event
|
||||
var/turf/old_turf
|
||||
var/obj/structure/cable/last_piece
|
||||
var/obj/item/stack/cable_coil/cable
|
||||
var/max_cable = 1000
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/New()
|
||||
cable = new(src)
|
||||
cable.amount = 0
|
||||
..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/can_attach(obj/mecha/working/M)
|
||||
if(..())
|
||||
if(istype(M))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/attach()
|
||||
..()
|
||||
event = chassis.events.addEvent("onMove",src,"layCable")
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/detach()
|
||||
chassis.events.clearEvent("onMove",event)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/Destroy()
|
||||
chassis.events.clearEvent("onMove",event)
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/action(var/obj/item/stack/cable_coil/target)
|
||||
if(!action_checks(target))
|
||||
return
|
||||
if(istype(target) && target.amount)
|
||||
var/cur_amount = cable? cable.amount : 0
|
||||
var/to_load = max(max_cable - cur_amount,0)
|
||||
if(to_load)
|
||||
to_load = min(target.amount, to_load)
|
||||
if(!cable)
|
||||
cable = new(src)
|
||||
cable.amount = 0
|
||||
cable.amount += to_load
|
||||
target.use(to_load)
|
||||
occupant_message("<span class='notice'>[to_load] meters of cable successfully loaded.</span>")
|
||||
send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
|
||||
else
|
||||
occupant_message("<span class='warning'>Reel is full.</span>")
|
||||
else
|
||||
occupant_message("<span class='warning'>Unable to load [target] - no cable found.</span>")
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/Topic(href,href_list)
|
||||
..()
|
||||
if(href_list["toggle"])
|
||||
set_ready_state(!equip_ready)
|
||||
occupant_message("[src] [equip_ready?"dea":"a"]ctivated.")
|
||||
log_message("[equip_ready?"Dea":"A"]ctivated.")
|
||||
return
|
||||
if(href_list["cut"])
|
||||
if(cable && cable.amount)
|
||||
var/m = round(input(chassis.occupant,"Please specify the length of cable to cut","Cut cable",min(cable.amount,30)) as num, 1)
|
||||
m = min(m, cable.amount)
|
||||
if(m)
|
||||
use_cable(m)
|
||||
var/obj/item/stack/cable_coil/CC = new (get_turf(chassis))
|
||||
CC.amount = m
|
||||
else
|
||||
occupant_message("There's no more cable on the reel.")
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/get_equip_info()
|
||||
var/output = ..()
|
||||
if(output)
|
||||
return "[output] \[Cable: [cable ? cable.amount : 0] m\][(cable && cable.amount) ? "- <a href='?src=\ref[src];toggle=1'>[!equip_ready?"Dea":"A"]ctivate</a>|<a href='?src=\ref[src];cut=1'>Cut</a>" : null]"
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/use_cable(amount)
|
||||
if(!cable || cable.amount<1)
|
||||
set_ready_state(1)
|
||||
occupant_message("Cable depleted, [src] deactivated.")
|
||||
log_message("Cable depleted, [src] deactivated.")
|
||||
return
|
||||
if(cable.amount < amount)
|
||||
occupant_message("No enough cable to finish the task.")
|
||||
return
|
||||
cable.use(amount)
|
||||
update_equip_info()
|
||||
return 1
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/reset()
|
||||
last_piece = null
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/dismantleFloor(var/turf/new_turf)
|
||||
if(istype(new_turf, /turf/open/floor))
|
||||
var/turf/open/floor/T = new_turf
|
||||
if(!istype(T, /turf/open/floor/plating))
|
||||
if(!T.broken && !T.burnt)
|
||||
new T.floor_tile(T)
|
||||
T.make_plating()
|
||||
return !new_turf.intact
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/cable_layer/proc/layCable(var/turf/new_turf)
|
||||
if(equip_ready || !istype(new_turf) || !dismantleFloor(new_turf))
|
||||
return reset()
|
||||
var/fdirn = turn(chassis.dir,180)
|
||||
for(var/obj/structure/cable/LC in new_turf) // check to make sure there's not a cable there already
|
||||
if(LC.d1 == fdirn || LC.d2 == fdirn)
|
||||
return reset()
|
||||
if(!use_cable(1))
|
||||
return reset()
|
||||
var/obj/structure/cable/NC = new(new_turf)
|
||||
NC.cableColor("red")
|
||||
NC.d1 = 0
|
||||
NC.d2 = fdirn
|
||||
NC.updateicon()
|
||||
|
||||
var/datum/powernet/PN
|
||||
if(last_piece && last_piece.d2 != chassis.dir)
|
||||
last_piece.d1 = min(last_piece.d2, chassis.dir)
|
||||
last_piece.d2 = max(last_piece.d2, chassis.dir)
|
||||
last_piece.updateicon()
|
||||
PN = last_piece.powernet
|
||||
|
||||
if(!PN)
|
||||
PN = new()
|
||||
powernets += PN
|
||||
NC.powernet = PN
|
||||
PN.cables += NC
|
||||
NC.mergeConnectedNetworks(NC.d2)
|
||||
|
||||
//NC.mergeConnectedNetworksOnTurf()
|
||||
last_piece = NC
|
||||
return 1
|
||||
@@ -0,0 +1,388 @@
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon
|
||||
name = "mecha weapon"
|
||||
range = RANGED
|
||||
origin_tech = "materials=3;combat=3"
|
||||
var/projectile
|
||||
var/fire_sound
|
||||
var/projectiles_per_shot = 1
|
||||
var/variance = 0
|
||||
var/randomspread = 0 //use random spread for machineguns, instead of shotgun scatter
|
||||
var/projectile_delay = 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/can_attach(obj/mecha/combat/M)
|
||||
if(..())
|
||||
if(istype(M))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/proc/get_shot_amount()
|
||||
return projectiles_per_shot
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/action(atom/target, params)
|
||||
if(!action_checks(target))
|
||||
return 0
|
||||
|
||||
var/turf/curloc = get_turf(chassis)
|
||||
var/turf/targloc = get_turf(target)
|
||||
if (!targloc || !istype(targloc) || !curloc)
|
||||
return 0
|
||||
if (targloc == curloc)
|
||||
return 0
|
||||
|
||||
set_ready_state(0)
|
||||
for(var/i=1 to get_shot_amount())
|
||||
var/obj/item/projectile/A = new projectile(curloc)
|
||||
A.firer = chassis.occupant
|
||||
A.original = target
|
||||
A.current = curloc
|
||||
|
||||
var/spread = 0
|
||||
if(variance)
|
||||
if(randomspread)
|
||||
spread = round((rand() - 0.5) * variance)
|
||||
else
|
||||
spread = round((i / projectiles_per_shot - 0.5) * variance)
|
||||
A.preparePixelProjectile(target, targloc, chassis.occupant, params, spread)
|
||||
|
||||
A.fire()
|
||||
playsound(chassis, fire_sound, 50, 1)
|
||||
|
||||
sleep(max(0, projectile_delay))
|
||||
|
||||
chassis.log_message("Fired from [src.name], targeting [target].")
|
||||
return 1
|
||||
|
||||
|
||||
//Base energy weapon type
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy
|
||||
name = "general energy weapon"
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/get_shot_amount()
|
||||
return min(round(chassis.cell.charge / energy_drain), projectiles_per_shot)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/start_cooldown()
|
||||
set_ready_state(0)
|
||||
chassis.use_power(energy_drain*get_shot_amount())
|
||||
addtimer(src, "set_ready_state", equip_cooldown, FALSE, 1)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser
|
||||
equip_cooldown = 8
|
||||
name = "\improper CH-PS \"Immolator\" laser"
|
||||
desc = "A weapon for combat exosuits. Shoots basic lasers."
|
||||
icon_state = "mecha_laser"
|
||||
origin_tech = "magnets=3;combat=3;engineering=3"
|
||||
energy_drain = 30
|
||||
projectile = /obj/item/projectile/beam/laser
|
||||
fire_sound = 'sound/weapons/Laser.ogg'
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy
|
||||
equip_cooldown = 15
|
||||
name = "\improper CH-LC \"Solaris\" laser cannon"
|
||||
desc = "A weapon for combat exosuits. Shoots heavy lasers."
|
||||
icon_state = "mecha_laser"
|
||||
origin_tech = "magnets=4;combat=4;engineering=3"
|
||||
energy_drain = 60
|
||||
projectile = /obj/item/projectile/beam/laser/heavylaser
|
||||
fire_sound = 'sound/weapons/lasercannonfire.ogg'
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/ion
|
||||
equip_cooldown = 20
|
||||
name = "\improper MKIV ion heavy cannon"
|
||||
desc = "A weapon for combat exosuits. Shoots technology-disabling ion beams. Don't catch yourself in the blast!"
|
||||
icon_state = "mecha_ion"
|
||||
origin_tech = "materials=4;combat=5;magnets=4"
|
||||
energy_drain = 120
|
||||
projectile = /obj/item/projectile/ion
|
||||
fire_sound = 'sound/weapons/Laser.ogg'
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse
|
||||
equip_cooldown = 30
|
||||
name = "eZ-13 MK2 heavy pulse rifle"
|
||||
desc = "A weapon for combat exosuits. Shoots powerful destructive blasts capable of demloishing obstacles."
|
||||
icon_state = "mecha_pulse"
|
||||
energy_drain = 120
|
||||
origin_tech = "materials=3;combat=6;powerstorage=4"
|
||||
projectile = /obj/item/projectile/beam/pulse/heavy
|
||||
fire_sound = 'sound/weapons/marauder.ogg'
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma
|
||||
equip_cooldown = 20
|
||||
name = "217-D Heavy Plasma Cutter"
|
||||
desc = "A device that shoots resonant plasma bursts at extreme velocity. The blasts are capable of crushing rock and demloishing solid obstacles."
|
||||
icon_state = "mecha_plasmacutter"
|
||||
item_state = "plasmacutter"
|
||||
energy_drain = 60
|
||||
origin_tech = "materials=3;plasmatech=4;engineering=3"
|
||||
projectile = /obj/item/projectile/plasma/adv/mech
|
||||
fire_sound = 'sound/weapons/Laser.ogg'
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma/can_attach(obj/mecha/working/M)
|
||||
if(..()) //combat mech
|
||||
return 1
|
||||
else if(M.equipment.len < M.max_equip && istype(M))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/energy/taser
|
||||
name = "\improper PBT \"Pacifier\" mounted taser"
|
||||
desc = "A weapon for combat exosuits. Shoots non-lethal stunning electrodes."
|
||||
icon_state = "mecha_taser"
|
||||
origin_tech = "combat=3"
|
||||
energy_drain = 20
|
||||
equip_cooldown = 8
|
||||
projectile = /obj/item/projectile/energy/electrode
|
||||
fire_sound = 'sound/weapons/Taser.ogg'
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/honker
|
||||
name = "\improper HoNkER BlAsT 5000"
|
||||
desc = "Equipment for clown exosuits. Spreads fun and joy to everyone around. Honk!"
|
||||
icon_state = "mecha_honker"
|
||||
energy_drain = 200
|
||||
equip_cooldown = 150
|
||||
range = MELEE|RANGED
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/honker/can_attach(obj/mecha/combat/honker/M)
|
||||
if(..())
|
||||
if(istype(M))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/honker/action(target, params)
|
||||
if(!action_checks(target))
|
||||
return
|
||||
playsound(chassis, 'sound/items/AirHorn.ogg', 100, 1)
|
||||
chassis.occupant_message("<font color='red' size='5'>HONK</font>")
|
||||
for(var/mob/living/carbon/M in ohearers(6, chassis))
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(istype(H.ears, /obj/item/clothing/ears/earmuffs))
|
||||
continue
|
||||
M << "<font color='red' size='7'>HONK</font>"
|
||||
M.SetSleeping(0)
|
||||
M.stuttering += 20
|
||||
M.adjustEarDamage(0, 30)
|
||||
M.Weaken(3)
|
||||
if(prob(30))
|
||||
M.Stun(10)
|
||||
M.Paralyse(4)
|
||||
else
|
||||
M.Jitter(500)
|
||||
|
||||
log_message("Honked from [src.name]. HONK!")
|
||||
var/turf/T = get_turf(src)
|
||||
message_admins("[key_name_admin(chassis.occupant, chassis.occupant.client)](<A HREF='?_src_=holder;adminmoreinfo=\ref[chassis.occupant]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[chassis.occupant]'>FLW</A>) used a Mecha Honker in ([T.x],[T.y],[T.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)",0,1)
|
||||
log_game("[chassis.occupant.ckey]([chassis.occupant]) used a Mecha Honker in ([T.x],[T.y],[T.z])")
|
||||
return 1
|
||||
|
||||
|
||||
//Base ballistic weapon type
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic
|
||||
name = "general ballisic weapon"
|
||||
fire_sound = 'sound/weapons/Gunshot.ogg'
|
||||
var/projectiles
|
||||
var/projectile_energy_cost
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_shot_amount()
|
||||
return min(projectiles, projectiles_per_shot)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/action_checks(target)
|
||||
if(!..())
|
||||
return 0
|
||||
if(projectiles <= 0)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/get_equip_info()
|
||||
return "[..()] \[[src.projectiles]\][(src.projectiles < initial(src.projectiles))?" - <a href='?src=\ref[src];rearm=1'>Rearm</a>":null]"
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/rearm()
|
||||
if(projectiles < initial(projectiles))
|
||||
var/projectiles_to_add = initial(projectiles) - projectiles
|
||||
while(chassis.get_charge() >= projectile_energy_cost && projectiles_to_add)
|
||||
projectiles++
|
||||
projectiles_to_add--
|
||||
chassis.use_power(projectile_energy_cost)
|
||||
send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
|
||||
log_message("Rearmed [src.name].")
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/needs_rearm()
|
||||
. = !(projectiles > 0)
|
||||
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/Topic(href, href_list)
|
||||
..()
|
||||
if (href_list["rearm"])
|
||||
src.rearm()
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/action(atom/target)
|
||||
if(..())
|
||||
projectiles -= get_shot_amount()
|
||||
send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info())
|
||||
return 1
|
||||
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/carbine
|
||||
name = "\improper FNX-99 \"Hades\" Carbine"
|
||||
desc = "A weapon for combat exosuits. Shoots incendiary bullets."
|
||||
icon_state = "mecha_carbine"
|
||||
origin_tech = "materials=4;combat=4"
|
||||
equip_cooldown = 5
|
||||
projectile = /obj/item/projectile/bullet/incendiary/shell/dragonsbreath
|
||||
projectiles = 24
|
||||
projectile_energy_cost = 15
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/silenced
|
||||
name = "\improper S.H.H. \"Quietus\" Carbine"
|
||||
desc = "A weapon for combat exosuits. A mime invention, field tests have shown that targets cannot even scream before going down."
|
||||
fire_sound = "sound/weapons/Gunshot_silenced.ogg"
|
||||
icon_state = "mecha_mime"
|
||||
equip_cooldown = 30
|
||||
projectile = /obj/item/projectile/bullet/mime
|
||||
projectiles = 6
|
||||
projectile_energy_cost = 50
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot
|
||||
name = "\improper LBX AC 10 \"Scattershot\""
|
||||
desc = "A weapon for combat exosuits. Shoots a spread of pellets."
|
||||
icon_state = "mecha_scatter"
|
||||
origin_tech = "combat=4"
|
||||
equip_cooldown = 20
|
||||
projectile = /obj/item/projectile/bullet/midbullet
|
||||
projectiles = 40
|
||||
projectile_energy_cost = 25
|
||||
projectiles_per_shot = 4
|
||||
variance = 25
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg
|
||||
name = "\improper Ultra AC 2"
|
||||
desc = "A weapon for combat exosuits. Shoots a rapid, three shot burst."
|
||||
icon_state = "mecha_uac2"
|
||||
origin_tech = "combat=4"
|
||||
equip_cooldown = 10
|
||||
projectile = /obj/item/projectile/bullet/weakbullet3
|
||||
projectiles = 300
|
||||
projectile_energy_cost = 20
|
||||
projectiles_per_shot = 3
|
||||
variance = 6
|
||||
randomspread = 1
|
||||
projectile_delay = 2
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher
|
||||
var/missile_speed = 2
|
||||
var/missile_range = 30
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/action(target)
|
||||
if(!action_checks(target))
|
||||
return
|
||||
var/obj/O = new projectile(chassis.loc)
|
||||
playsound(chassis, fire_sound, 50, 1)
|
||||
log_message("Launched a [O.name] from [name], targeting [target].")
|
||||
projectiles--
|
||||
proj_init(O)
|
||||
O.throw_at_fast(target, missile_range, missile_speed, spin = 0)
|
||||
return 1
|
||||
|
||||
//used for projectile initilisation (priming flashbang) and additional logging
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/proc/proj_init(var/obj/O)
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/missile_rack
|
||||
name = "\improper SRM-8 missile rack"
|
||||
desc = "A weapon for combat exosuits. Shoots light explosive missiles."
|
||||
icon_state = "mecha_missilerack"
|
||||
origin_tech = "combat=5;materials=4;engineering=4"
|
||||
projectile = /obj/item/missile
|
||||
fire_sound = 'sound/weapons/grenadelaunch.ogg'
|
||||
projectiles = 8
|
||||
projectile_energy_cost = 1000
|
||||
equip_cooldown = 60
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/missile_rack/proj_init(var/obj/item/missile/M)
|
||||
M.primed = 1
|
||||
var/turf/T = get_turf(src)
|
||||
message_admins("[key_name(chassis.occupant, chassis.occupant.client)](<A HREF='?_src_=holder;adminmoreinfo=\ref[chassis.occupant]'>?</A>) fired a [src] in ([T.x],[T.y],[T.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)",0,1)
|
||||
log_game("[key_name(chassis.occupant)] fired a [src] ([T.x],[T.y],[T.z])")
|
||||
|
||||
/obj/item/missile
|
||||
icon = 'icons/obj/grenade.dmi'
|
||||
icon_state = "missile"
|
||||
var/primed = null
|
||||
throwforce = 15
|
||||
|
||||
/obj/item/missile/throw_impact(atom/hit_atom)
|
||||
if(primed)
|
||||
explosion(hit_atom, 0, 0, 2, 4, 0)
|
||||
qdel(src)
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang
|
||||
name = "\improper SGL-6 grenade launcher"
|
||||
desc = "A weapon for combat exosuits. Launches primed flashbangs."
|
||||
icon_state = "mecha_grenadelnchr"
|
||||
origin_tech = "combat=4;engineering=4"
|
||||
projectile = /obj/item/weapon/grenade/flashbang
|
||||
fire_sound = 'sound/weapons/grenadelaunch.ogg'
|
||||
projectiles = 6
|
||||
missile_speed = 1.5
|
||||
projectile_energy_cost = 800
|
||||
equip_cooldown = 60
|
||||
var/det_time = 20
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/proj_init(var/obj/item/weapon/grenade/flashbang/F)
|
||||
var/turf/T = get_turf(src)
|
||||
message_admins("[key_name(chassis.occupant, chassis.occupant.client)](<A HREF='?_src_=holder;adminmoreinfo=\ref[chassis.occupant]'>?</A>) fired a [src] in ([T.x],[T.y],[T.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</a>)",0,1)
|
||||
log_game("[key_name(chassis.occupant)] fired a [src] ([T.x],[T.y],[T.z])")
|
||||
addtimer(F, "prime", det_time)
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/clusterbang //Because I am a heartless bastard -Sieve //Heartless? for making the poor man's honkblast? - Kaze
|
||||
name = "\improper SOB-3 grenade launcher"
|
||||
desc = "A weapon for combat exosuits. Launches primed clusterbangs. You monster."
|
||||
origin_tech = "combat=4;materials=4"
|
||||
projectiles = 3
|
||||
projectile = /obj/item/weapon/grenade/clusterbuster
|
||||
projectile_energy_cost = 1600 //getting off cheap seeing as this is 3 times the flashbangs held in the grenade launcher.
|
||||
equip_cooldown = 90
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar
|
||||
name = "banana mortar"
|
||||
desc = "Equipment for clown exosuits. Launches banana peels."
|
||||
icon_state = "mecha_bananamrtr"
|
||||
projectile = /obj/item/weapon/grown/bananapeel
|
||||
fire_sound = 'sound/items/bikehorn.ogg'
|
||||
projectiles = 15
|
||||
missile_speed = 1.5
|
||||
projectile_energy_cost = 100
|
||||
equip_cooldown = 20
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/banana_mortar/can_attach(obj/mecha/combat/honker/M)
|
||||
if(..())
|
||||
if(istype(M))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar
|
||||
name = "mousetrap mortar"
|
||||
desc = "Equipment for clown exosuits. Launches armed mousetraps."
|
||||
icon_state = "mecha_mousetrapmrtr"
|
||||
projectile = /obj/item/device/assembly/mousetrap/armed
|
||||
fire_sound = 'sound/items/bikehorn.ogg'
|
||||
projectiles = 15
|
||||
missile_speed = 1.5
|
||||
projectile_energy_cost = 100
|
||||
equip_cooldown = 10
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar/can_attach(obj/mecha/combat/honker/M)
|
||||
if(..())
|
||||
if(istype(M))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/mousetrap_mortar/proj_init(var/obj/item/device/assembly/mousetrap/armed/M)
|
||||
M.secured = 1
|
||||
@@ -0,0 +1,151 @@
|
||||
/turf/open/floor/mech_bay_recharge_floor // Whos idea it was
|
||||
name = "mech bay recharge station" // Recharging turfs
|
||||
icon = 'icons/turf/floors.dmi' // That are set in stone to check the west turf for recharge port
|
||||
icon_state = "recharge_floor" // Some people just want to watch the world burn i guess
|
||||
|
||||
/turf/open/floor/mech_bay_recharge_floor/break_tile()
|
||||
src.ChangeTurf(/turf/open/floor/plating)
|
||||
|
||||
/turf/open/floor/mech_bay_recharge_floor/airless
|
||||
icon_state = "recharge_floor_asteroid"
|
||||
initial_gas_mix = "TEMP=2.7"
|
||||
|
||||
/obj/machinery/mech_bay_recharge_port
|
||||
name = "mech bay power port"
|
||||
density = 1
|
||||
anchored = 1
|
||||
dir = EAST
|
||||
icon = 'icons/mecha/mech_bay.dmi'
|
||||
icon_state = "recharge_port"
|
||||
var/obj/mecha/recharging_mech
|
||||
var/obj/machinery/computer/mech_bay_power_console/recharge_console
|
||||
var/max_charge = 50
|
||||
var/on = 0
|
||||
var/repairability = 0
|
||||
var/turf/recharging_turf = null
|
||||
|
||||
/obj/machinery/mech_bay_recharge_port/New()
|
||||
..()
|
||||
var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/mech_recharger(null)
|
||||
B.apply_default_parts(src)
|
||||
recharging_turf = get_step(loc, dir)
|
||||
|
||||
/obj/item/weapon/circuitboard/machine/mech_recharger
|
||||
name = "circuit board (Mechbay Recharger)"
|
||||
build_path = /obj/machinery/mech_bay_recharge_port
|
||||
origin_tech = "programming=3;powerstorage=3;engineering=3"
|
||||
req_components = list(
|
||||
/obj/item/stack/cable_coil = 2,
|
||||
/obj/item/weapon/stock_parts/capacitor = 5)
|
||||
|
||||
/obj/machinery/mech_bay_recharge_port/RefreshParts()
|
||||
var/MC
|
||||
for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts)
|
||||
MC += C.rating
|
||||
max_charge = MC * 25
|
||||
|
||||
/obj/machinery/mech_bay_recharge_port/process()
|
||||
if(stat & NOPOWER || !recharge_console)
|
||||
return
|
||||
if(!recharging_mech)
|
||||
recharging_mech = locate(/obj/mecha) in recharging_turf
|
||||
if(recharging_mech)
|
||||
recharge_console.update_icon()
|
||||
if(recharging_mech && recharging_mech.cell)
|
||||
if(recharging_mech.cell.charge < recharging_mech.cell.maxcharge)
|
||||
var/delta = min(max_charge, recharging_mech.cell.maxcharge - recharging_mech.cell.charge)
|
||||
recharging_mech.give_power(delta)
|
||||
use_power(delta*150)
|
||||
else
|
||||
recharge_console.update_icon()
|
||||
if(recharging_mech.loc != recharging_turf)
|
||||
recharging_mech = null
|
||||
recharge_console.update_icon()
|
||||
|
||||
|
||||
/obj/machinery/mech_bay_recharge_port/attackby(obj/item/I, mob/user, params)
|
||||
if(default_deconstruction_screwdriver(user, "recharge_port-o", "recharge_port", I))
|
||||
return
|
||||
|
||||
if(default_change_direction_wrench(user, I))
|
||||
recharging_turf = get_step(loc, dir)
|
||||
return
|
||||
|
||||
if(exchange_parts(user, I))
|
||||
return
|
||||
|
||||
if(default_deconstruction_crowbar(I))
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/mech_bay_power_console
|
||||
name = "mech bay power control console"
|
||||
desc = "Used to control mechbay power ports."
|
||||
icon_screen = "recharge_comp"
|
||||
icon_keyboard = "rd_key"
|
||||
circuit = /obj/item/weapon/circuitboard/computer/mech_bay_power_console
|
||||
var/obj/machinery/mech_bay_recharge_port/recharge_port
|
||||
|
||||
/obj/machinery/computer/mech_bay_power_console/attack_ai(mob/user)
|
||||
return interact(user)
|
||||
|
||||
/obj/machinery/computer/mech_bay_power_console/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/computer/mech_bay_power_console/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "mech_bay_power_console", "Mech Bay Power Control Console", 400, 170, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/mech_bay_power_console/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("reconnect")
|
||||
reconnect()
|
||||
. = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/computer/mech_bay_power_console/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
if(recharge_port && !qdeleted(recharge_port))
|
||||
data["recharge_port"] = list("mech" = null)
|
||||
if(recharge_port.recharging_mech && !qdeleted(recharge_port.recharging_mech))
|
||||
data["recharge_port"]["mech"] = list("health" = recharge_port.recharging_mech.health, "maxhealth" = initial(recharge_port.recharging_mech.health), "cell" = null)
|
||||
if(recharge_port.recharging_mech.cell && !qdeleted(recharge_port.recharging_mech.cell))
|
||||
data["recharge_port"]["mech"]["cell"] = list(
|
||||
"critfail" = recharge_port.recharging_mech.cell.crit_fail,
|
||||
"charge" = recharge_port.recharging_mech.cell.charge,
|
||||
"maxcharge" = recharge_port.recharging_mech.cell.maxcharge
|
||||
)
|
||||
return data
|
||||
|
||||
|
||||
/obj/machinery/computer/mech_bay_power_console/proc/reconnect()
|
||||
if(recharge_port)
|
||||
return
|
||||
recharge_port = locate(/obj/machinery/mech_bay_recharge_port) in range(1)
|
||||
if(!recharge_port )
|
||||
for(var/D in cardinal)
|
||||
var/turf/A = get_step(src, D)
|
||||
A = get_step(A, D)
|
||||
recharge_port = locate(/obj/machinery/mech_bay_recharge_port) in A
|
||||
if(recharge_port)
|
||||
break
|
||||
if(recharge_port)
|
||||
if(!recharge_port.recharge_console)
|
||||
recharge_port.recharge_console = src
|
||||
else
|
||||
recharge_port = null
|
||||
|
||||
/obj/machinery/computer/mech_bay_power_console/update_icon()
|
||||
..()
|
||||
if(!recharge_port || !recharge_port.recharging_mech || !recharge_port.recharging_mech.cell || !(recharge_port.recharging_mech.cell.charge < recharge_port.recharging_mech.cell.maxcharge) || stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
add_overlay("recharge_comp_on")
|
||||
|
||||
/obj/machinery/computer/mech_bay_power_console/initialize()
|
||||
reconnect()
|
||||
@@ -0,0 +1,466 @@
|
||||
/obj/machinery/mecha_part_fabricator
|
||||
icon = 'icons/obj/robotics.dmi'
|
||||
icon_state = "fab-idle"
|
||||
name = "exosuit fabricator"
|
||||
desc = "Nothing is being built."
|
||||
density = 1
|
||||
anchored = 1
|
||||
use_power = 1
|
||||
idle_power_usage = 20
|
||||
active_power_usage = 5000
|
||||
req_access = list(access_robotics)
|
||||
var/time_coeff = 1
|
||||
var/component_coeff = 1
|
||||
var/datum/material_container/materials
|
||||
var/datum/research/files
|
||||
var/sync = 0
|
||||
var/part_set
|
||||
var/datum/design/being_built
|
||||
var/list/queue = list()
|
||||
var/processing_queue = 0
|
||||
var/screen = "main"
|
||||
var/temp
|
||||
var/list/part_sets = list(
|
||||
"Cyborg",
|
||||
"Ripley",
|
||||
"Firefighter",
|
||||
"Odysseus",
|
||||
"Gygax",
|
||||
"Durand",
|
||||
"H.O.N.K",
|
||||
"Phazon",
|
||||
"Exosuit Equipment",
|
||||
"Cyborg Upgrade Modules",
|
||||
"Misc"
|
||||
)
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/New()
|
||||
..()
|
||||
files = new /datum/research(src) //Setup the research data holder.
|
||||
materials = new(src, list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM))
|
||||
var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/mechfab(null)
|
||||
B.apply_default_parts(src)
|
||||
|
||||
/obj/item/weapon/circuitboard/machine/mechfab
|
||||
name = "circuit board (Exosuit Fabricator)"
|
||||
build_path = /obj/machinery/mecha_part_fabricator
|
||||
origin_tech = "programming=2;engineering=2"
|
||||
req_components = list(
|
||||
/obj/item/weapon/stock_parts/matter_bin = 2,
|
||||
/obj/item/weapon/stock_parts/manipulator = 1,
|
||||
/obj/item/weapon/stock_parts/micro_laser = 1,
|
||||
/obj/item/weapon/stock_parts/console_screen = 1)
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/RefreshParts()
|
||||
var/T = 0
|
||||
|
||||
//maximum stocking amount (default 300000, 600000 at T4)
|
||||
for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts)
|
||||
T += M.rating
|
||||
materials.max_amount = (200000 + (T*50000))
|
||||
|
||||
//resources adjustment coefficient (1 -> 0.85 -> 0.7 -> 0.55)
|
||||
T = 1.15
|
||||
for(var/obj/item/weapon/stock_parts/micro_laser/Ma in component_parts)
|
||||
T -= Ma.rating*0.15
|
||||
component_coeff = T
|
||||
|
||||
//building time adjustment coefficient (1 -> 0.8 -> 0.6)
|
||||
T = -1
|
||||
for(var/obj/item/weapon/stock_parts/manipulator/Ml in component_parts)
|
||||
T += Ml.rating
|
||||
time_coeff = round(initial(time_coeff) - (initial(time_coeff)*(T))/5,0.01)
|
||||
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/check_access(obj/item/weapon/card/id/I)
|
||||
if(istype(I, /obj/item/device/pda))
|
||||
var/obj/item/device/pda/pda = I
|
||||
I = pda.id
|
||||
if(!istype(I) || !I.access) //not ID or no access
|
||||
return 0
|
||||
for(var/req in req_access)
|
||||
if(!(req in I.access)) //doesn't have this access
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/emag_act()
|
||||
if(emagged)
|
||||
return
|
||||
|
||||
emagged = 0.5
|
||||
say("DB error \[Code 0x00F1\]")
|
||||
sleep(10)
|
||||
say("Attempting auto-repair...")
|
||||
sleep(15)
|
||||
say("User DB corrupted \[Code 0x00FA\]. Truncating data structure...")
|
||||
sleep(30)
|
||||
say("User DB truncated. Please contact your Nanotrasen system operator for future assistance.")
|
||||
req_access = null
|
||||
emagged = 1
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/output_parts_list(set_name)
|
||||
var/output = ""
|
||||
for(var/v in files.known_designs)
|
||||
var/datum/design/D = files.known_designs[v]
|
||||
if(D.build_type & MECHFAB)
|
||||
if(!(set_name in D.category))
|
||||
continue
|
||||
output += "<div class='part'>[output_part_info(D)]<br>\["
|
||||
if(check_resources(D))
|
||||
output += "<a href='?src=\ref[src];part=[D.id]'>Build</a> | "
|
||||
output += "<a href='?src=\ref[src];add_to_queue=[D.id]'>Add to queue</a>\]\[<a href='?src=\ref[src];part_desc=[D.id]'>?</a>\]</div>"
|
||||
return output
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/output_part_info(datum/design/D)
|
||||
var/output = "[initial(D.name)] (Cost: [output_part_cost(D)]) [get_construction_time_w_coeff(D)/10]sec"
|
||||
return output
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/output_part_cost(datum/design/D)
|
||||
var/i = 0
|
||||
var/output
|
||||
for(var/c in D.materials)
|
||||
output += "[i?" | ":null][get_resource_cost_w_coeff(D, c)] [material2name(c)]"
|
||||
i++
|
||||
return output
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/output_available_resources()
|
||||
var/output
|
||||
for(var/mat_id in materials.materials)
|
||||
var/datum/material/M = materials.materials[mat_id]
|
||||
output += "<span class=\"res_name\">[M.name]: </span>[M.amount] cm³"
|
||||
if(M.amount >= MINERAL_MATERIAL_AMOUNT)
|
||||
output += "<span style='font-size:80%;'>- Remove \[<a href='?src=\ref[src];remove_mat=1;material=[mat_id]'>1</a>\]"
|
||||
if(M.amount >= (MINERAL_MATERIAL_AMOUNT * 10))
|
||||
output += " | \[<a href='?src=\ref[src];remove_mat=10;material=[mat_id]'>10</a>\]"
|
||||
output += " | \[<a href='?src=\ref[src];remove_mat=50;material=[mat_id]'>All</a>\]</span>"
|
||||
output += "<br/>"
|
||||
return output
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/get_resources_w_coeff(datum/design/D)
|
||||
var/list/resources = list()
|
||||
for(var/R in D.materials)
|
||||
resources[R] = get_resource_cost_w_coeff(D, R)
|
||||
return resources
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/check_resources(datum/design/D)
|
||||
if(D.reagents.len) // No reagents storage - no reagent designs.
|
||||
return 0
|
||||
if(materials.has_materials(get_resources_w_coeff(D)))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/build_part(datum/design/D)
|
||||
being_built = D
|
||||
desc = "It's building \a [initial(D.name)]."
|
||||
var/list/res_coef = get_resources_w_coeff(D)
|
||||
|
||||
materials.use_amount(res_coef)
|
||||
add_overlay("fab-active")
|
||||
use_power = 2
|
||||
updateUsrDialog()
|
||||
sleep(get_construction_time_w_coeff(D))
|
||||
use_power = 1
|
||||
overlays -= "fab-active"
|
||||
desc = initial(desc)
|
||||
|
||||
var/location = get_step(src,(dir))
|
||||
var/obj/item/I = new D.build_path(location)
|
||||
I.materials = res_coef
|
||||
say("\The [I] is complete.")
|
||||
being_built = null
|
||||
|
||||
updateUsrDialog()
|
||||
return 1
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/update_queue_on_page()
|
||||
send_byjax(usr,"mecha_fabricator.browser","queue",list_queue())
|
||||
return
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/add_part_set_to_queue(set_name)
|
||||
if(set_name in part_sets)
|
||||
for(var/v in files.known_designs)
|
||||
var/datum/design/D = files.known_designs[v]
|
||||
if(D.build_type & MECHFAB)
|
||||
if(set_name in D.category)
|
||||
add_to_queue(D)
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/add_to_queue(D)
|
||||
if(!istype(queue))
|
||||
queue = list()
|
||||
if(D)
|
||||
queue[++queue.len] = D
|
||||
return queue.len
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/remove_from_queue(index)
|
||||
if(!isnum(index) || !IsInteger(index) || !istype(queue) || (index<1 || index>queue.len))
|
||||
return 0
|
||||
queue.Cut(index,++index)
|
||||
return 1
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/process_queue()
|
||||
var/datum/design/D = queue[1]
|
||||
if(!D)
|
||||
remove_from_queue(1)
|
||||
if(queue.len)
|
||||
return process_queue()
|
||||
else
|
||||
return
|
||||
temp = null
|
||||
while(D)
|
||||
if(stat&(NOPOWER|BROKEN))
|
||||
return 0
|
||||
if(!check_resources(D))
|
||||
say("Not enough resources. Queue processing stopped.")
|
||||
temp = {"<span class='alert'>Not enough resources to build next part.</span><br>
|
||||
<a href='?src=\ref[src];process_queue=1'>Try again</a> | <a href='?src=\ref[src];clear_temp=1'>Return</a><a>"}
|
||||
return 0
|
||||
remove_from_queue(1)
|
||||
build_part(D)
|
||||
D = listgetindex(queue, 1)
|
||||
say("Queue processing finished successfully.")
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/list_queue()
|
||||
var/output = "<b>Queue contains:</b>"
|
||||
if(!istype(queue) || !queue.len)
|
||||
output += "<br>Nothing"
|
||||
else
|
||||
output += "<ol>"
|
||||
var/i = 0
|
||||
for(var/datum/design/D in queue)
|
||||
i++
|
||||
var/obj/part = D.build_path
|
||||
output += "<li[!check_resources(D)?" style='color: #f00;'":null]>"
|
||||
output += initial(part.name) + " - "
|
||||
output += "[i>1?"<a href='?src=\ref[src];queue_move=-1;index=[i]' class='arrow'>↑</a>":null] "
|
||||
output += "[i<queue.len?"<a href='?src=\ref[src];queue_move=+1;index=[i]' class='arrow'>↓</a>":null] "
|
||||
output += "<a href='?src=\ref[src];remove_from_queue=[i]'>Remove</a></li>"
|
||||
|
||||
output += "</ol>"
|
||||
output += "\[<a href='?src=\ref[src];process_queue=1'>Process queue</a> | <a href='?src=\ref[src];clear_queue=1'>Clear queue</a>\]"
|
||||
return output
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/sync()
|
||||
temp = "Updating local R&D database..."
|
||||
updateUsrDialog()
|
||||
sleep(30) //only sleep if called by user
|
||||
|
||||
for(var/obj/machinery/computer/rdconsole/RDC in oview(5,src))
|
||||
if(!RDC.sync)
|
||||
continue
|
||||
for(var/v in RDC.files.known_tech)
|
||||
var/datum/tech/T = RDC.files.known_tech[v]
|
||||
files.AddTech2Known(T)
|
||||
for(var/v in RDC.files.known_designs)
|
||||
var/datum/design/D = RDC.files.known_designs[v]
|
||||
files.AddDesign2Known(D)
|
||||
files.RefreshResearch()
|
||||
temp = "Processed equipment designs.<br>"
|
||||
//check if the tech coefficients have changed
|
||||
temp += "<a href='?src=\ref[src];clear_temp=1'>Return</a>"
|
||||
|
||||
updateUsrDialog()
|
||||
say("Successfully synchronized with R&D server.")
|
||||
return
|
||||
|
||||
temp = "Unable to connect to local R&D Database.<br>Please check your connections and try again.<br><a href='?src=\ref[src];clear_temp=1'>Return</a>"
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/get_resource_cost_w_coeff(datum/design/D, resource, roundto = 1)
|
||||
return round(D.materials[resource]*component_coeff, roundto)
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/get_construction_time_w_coeff(datum/design/D, roundto = 1) //aran
|
||||
return round(initial(D.construction_time)*time_coeff, roundto)
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/attack_hand(mob/user)
|
||||
if(!(..()))
|
||||
return interact(user)
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/interact(mob/user as mob)
|
||||
var/dat, left_part
|
||||
if (..())
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/turf/exit = get_step(src,(dir))
|
||||
if(exit.density)
|
||||
say("Error! Part outlet is obstructed.")
|
||||
return
|
||||
if(temp)
|
||||
left_part = temp
|
||||
else if(being_built)
|
||||
var/obj/I = being_built.build_path
|
||||
left_part = {"<TT>Building [initial(I.name)].<BR>
|
||||
Please wait until completion...</TT>"}
|
||||
else
|
||||
switch(screen)
|
||||
if("main")
|
||||
left_part = output_available_resources()+"<hr>"
|
||||
left_part += "<a href='?src=\ref[src];sync=1'>Sync with R&D servers</a><hr>"
|
||||
for(var/part_set in part_sets)
|
||||
left_part += "<a href='?src=\ref[src];part_set=[part_set]'>[part_set]</a> - \[<a href='?src=\ref[src];partset_to_queue=[part_set]'>Add all parts to queue</a>\]<br>"
|
||||
if("parts")
|
||||
left_part += output_parts_list(part_set)
|
||||
left_part += "<hr><a href='?src=\ref[src];screen=main'>Return</a>"
|
||||
dat = {"<html>
|
||||
<head>
|
||||
<title>[name]</title>
|
||||
<style>
|
||||
.res_name {font-weight: bold; text-transform: capitalize;}
|
||||
.red {color: #f00;}
|
||||
.part {margin-bottom: 10px;}
|
||||
.arrow {text-decoration: none; font-size: 10px;}
|
||||
body, table {height: 100%;}
|
||||
td {vertical-align: top; padding: 5px;}
|
||||
html, body {padding: 0px; margin: 0px;}
|
||||
h1 {font-size: 18px; margin: 5px 0px;}
|
||||
</style>
|
||||
<script language='javascript' type='text/javascript'>
|
||||
[js_byjax]
|
||||
</script>
|
||||
</head><body>
|
||||
<body>
|
||||
<table style='width: 100%;'>
|
||||
<tr>
|
||||
<td style='width: 65%; padding-right: 10px;'>
|
||||
[left_part]
|
||||
</td>
|
||||
<td style='width: 35%; background: #ccc;' id='queue'>
|
||||
[list_queue()]
|
||||
</td>
|
||||
<tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>"}
|
||||
user << browse(dat, "window=mecha_fabricator;size=1000x430")
|
||||
onclose(user, "mecha_fabricator")
|
||||
return
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
|
||||
if(href_list["part_set"])
|
||||
var/tpart_set = filter.getStr("part_set")
|
||||
if(tpart_set)
|
||||
if(tpart_set=="clear")
|
||||
part_set = null
|
||||
else
|
||||
part_set = tpart_set
|
||||
screen = "parts"
|
||||
if(href_list["part"])
|
||||
var/T = filter.getStr("part")
|
||||
for(var/v in files.known_designs)
|
||||
var/datum/design/D = files.known_designs[v]
|
||||
if(D.build_type & MECHFAB)
|
||||
if(D.id == T)
|
||||
if(!processing_queue)
|
||||
build_part(D)
|
||||
else
|
||||
add_to_queue(D)
|
||||
break
|
||||
if(href_list["add_to_queue"])
|
||||
var/T = filter.getStr("add_to_queue")
|
||||
for(var/v in files.known_designs)
|
||||
var/datum/design/D = files.known_designs[v]
|
||||
if(D.build_type & MECHFAB)
|
||||
if(D.id == T)
|
||||
add_to_queue(D)
|
||||
break
|
||||
return update_queue_on_page()
|
||||
if(href_list["remove_from_queue"])
|
||||
remove_from_queue(filter.getNum("remove_from_queue"))
|
||||
return update_queue_on_page()
|
||||
if(href_list["partset_to_queue"])
|
||||
add_part_set_to_queue(filter.get("partset_to_queue"))
|
||||
return update_queue_on_page()
|
||||
if(href_list["process_queue"])
|
||||
spawn(0)
|
||||
if(processing_queue || being_built)
|
||||
return 0
|
||||
processing_queue = 1
|
||||
process_queue()
|
||||
processing_queue = 0
|
||||
if(href_list["clear_temp"])
|
||||
temp = null
|
||||
if(href_list["screen"])
|
||||
screen = href_list["screen"]
|
||||
if(href_list["queue_move"] && href_list["index"])
|
||||
var/index = filter.getNum("index")
|
||||
var/new_index = index + filter.getNum("queue_move")
|
||||
if(isnum(index) && isnum(new_index) && IsInteger(index) && IsInteger(new_index))
|
||||
if(IsInRange(new_index,1,queue.len))
|
||||
queue.Swap(index,new_index)
|
||||
return update_queue_on_page()
|
||||
if(href_list["clear_queue"])
|
||||
queue = list()
|
||||
return update_queue_on_page()
|
||||
if(href_list["sync"])
|
||||
sync()
|
||||
if(href_list["part_desc"])
|
||||
var/T = filter.getStr("part_desc")
|
||||
for(var/v in files.known_designs)
|
||||
var/datum/design/D = files.known_designs[v]
|
||||
if(D.build_type & MECHFAB)
|
||||
if(D.id == T)
|
||||
var/obj/part = D.build_path
|
||||
temp = {"<h1>[initial(part.name)] description:</h1>
|
||||
[initial(part.desc)]<br>
|
||||
<a href='?src=\ref[src];clear_temp=1'>Return</a>
|
||||
"}
|
||||
break
|
||||
|
||||
if(href_list["remove_mat"] && href_list["material"])
|
||||
materials.retrieve_sheets(text2num(href_list["remove_mat"]), href_list["material"])
|
||||
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/deconstruction()
|
||||
materials.retrieve_all()
|
||||
..()
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/attackby(obj/item/W, mob/user, params)
|
||||
if(default_deconstruction_screwdriver(user, "fab-o", "fab-idle", W))
|
||||
return 1
|
||||
|
||||
if(exchange_parts(user, W))
|
||||
return 1
|
||||
|
||||
if(default_deconstruction_crowbar(W))
|
||||
return 1
|
||||
|
||||
if(istype(W, /obj/item/stack/sheet))
|
||||
if(panel_open)
|
||||
user << "<span class='warning'>You can't load [src] while it's opened!</span>"
|
||||
return 1
|
||||
if(being_built)
|
||||
user << "<span class='warning'>\The [src] is currently processing! Please wait until completion.</span>"
|
||||
return 1
|
||||
|
||||
var/material_amount = materials.get_item_material_amount(W)
|
||||
if(!material_amount)
|
||||
user << "<span class='warning'>This object does not contain sufficient amounts of materials to be accepted by [src].</span>"
|
||||
return 1
|
||||
if(!materials.has_space(material_amount))
|
||||
user << "<span class='warning'>\The [src] is full. Please remove some materials from [src] in order to insert more.</span>"
|
||||
return 1
|
||||
if(!user.unEquip(W))
|
||||
user << "<span class='warning'>\The [W] is stuck to you and cannot be placed into [src].</span>"
|
||||
return 1
|
||||
|
||||
var/inserted = materials.insert_item(W)
|
||||
if(inserted)
|
||||
user << "<span class='notice'>You insert [inserted] sheet\s into [src].</span>"
|
||||
if(W && W.materials.len)
|
||||
var/mat_overlay = "fab-load-[material2name(W.materials[1])]"
|
||||
add_overlay(mat_overlay)
|
||||
sleep(10)
|
||||
overlays -= mat_overlay //No matter what the overlay shall still be deleted
|
||||
|
||||
updateUsrDialog()
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/mecha_part_fabricator/proc/material2name(ID)
|
||||
return copytext(ID,2)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,281 @@
|
||||
//////////////////////////////////////// Action Buttons ///////////////////////////////////////////////
|
||||
|
||||
/obj/mecha/proc/GrantActions(mob/living/user, human_occupant = 0)
|
||||
if(human_occupant)
|
||||
eject_action.Grant(user, src)
|
||||
internals_action.Grant(user, src)
|
||||
cycle_action.Grant(user, src)
|
||||
lights_action.Grant(user, src)
|
||||
stats_action.Grant(user, src)
|
||||
strafing_action.Grant(user, src)
|
||||
|
||||
|
||||
/obj/mecha/proc/RemoveActions(mob/living/user, human_occupant = 0)
|
||||
if(human_occupant)
|
||||
eject_action.Remove(user)
|
||||
internals_action.Remove(user)
|
||||
cycle_action.Remove(user)
|
||||
lights_action.Remove(user)
|
||||
stats_action.Remove(user)
|
||||
strafing_action.Remove(user)
|
||||
|
||||
|
||||
/datum/action/innate/mecha
|
||||
check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUNNED | AB_CHECK_CONSCIOUS
|
||||
var/obj/mecha/chassis
|
||||
|
||||
/datum/action/innate/mecha/Grant(mob/living/L, obj/mecha/M)
|
||||
chassis = M
|
||||
..()
|
||||
|
||||
/datum/action/innate/mecha/Destroy()
|
||||
chassis = null
|
||||
return ..()
|
||||
|
||||
/datum/action/innate/mecha/mech_eject
|
||||
name = "Eject From Mech"
|
||||
button_icon_state = "mech_eject"
|
||||
|
||||
/datum/action/innate/mecha/mech_eject/Activate()
|
||||
if(!owner || !iscarbon(owner))
|
||||
return
|
||||
if(!chassis || chassis.occupant != owner)
|
||||
return
|
||||
chassis.go_out()
|
||||
|
||||
|
||||
/datum/action/innate/mecha/mech_toggle_internals
|
||||
name = "Toggle Internal Airtank Usage"
|
||||
button_icon_state = "mech_internals_off"
|
||||
|
||||
/datum/action/innate/mecha/mech_toggle_internals/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
chassis.use_internal_tank = !chassis.use_internal_tank
|
||||
button_icon_state = "mech_internals_[chassis.use_internal_tank ? "on" : "off"]"
|
||||
chassis.occupant_message("Now taking air from [chassis.use_internal_tank?"internal airtank":"environment"].")
|
||||
chassis.log_message("Now taking air from [chassis.use_internal_tank?"internal airtank":"environment"].")
|
||||
UpdateButtonIcon()
|
||||
|
||||
/datum/action/innate/mecha/mech_cycle_equip
|
||||
name = "Cycle Equipment"
|
||||
button_icon_state = "mech_cycle_equip_off"
|
||||
|
||||
/datum/action/innate/mecha/mech_cycle_equip/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
|
||||
var/list/available_equipment = list()
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/M in chassis.equipment)
|
||||
if(M.selectable)
|
||||
available_equipment += M
|
||||
|
||||
if(available_equipment.len == 0)
|
||||
chassis.occupant_message("No equipment available.")
|
||||
return
|
||||
if(!chassis.selected)
|
||||
chassis.selected = available_equipment[1]
|
||||
chassis.occupant_message("You select [chassis.selected]")
|
||||
send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list())
|
||||
button_icon_state = "mech_cycle_equip_on"
|
||||
UpdateButtonIcon()
|
||||
return
|
||||
var/number = 0
|
||||
for(var/A in available_equipment)
|
||||
number++
|
||||
if(A == chassis.selected)
|
||||
if(available_equipment.len == number)
|
||||
chassis.selected = null
|
||||
chassis.occupant_message("You switch to no equipment")
|
||||
button_icon_state = "mech_cycle_equip_off"
|
||||
else
|
||||
chassis.selected = available_equipment[number+1]
|
||||
chassis.occupant_message("You switch to [chassis.selected]")
|
||||
button_icon_state = "mech_cycle_equip_on"
|
||||
send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list())
|
||||
UpdateButtonIcon()
|
||||
return
|
||||
|
||||
|
||||
/datum/action/innate/mecha/mech_toggle_lights
|
||||
name = "Toggle Lights"
|
||||
button_icon_state = "mech_lights_off"
|
||||
|
||||
/datum/action/innate/mecha/mech_toggle_lights/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
chassis.lights = !chassis.lights
|
||||
if(chassis.lights)
|
||||
chassis.AddLuminosity(chassis.lights_power)
|
||||
button_icon_state = "mech_lights_on"
|
||||
else
|
||||
chassis.AddLuminosity(-chassis.lights_power)
|
||||
button_icon_state = "mech_lights_off"
|
||||
chassis.occupant_message("Toggled lights [chassis.lights?"on":"off"].")
|
||||
chassis.log_message("Toggled lights [chassis.lights?"on":"off"].")
|
||||
UpdateButtonIcon()
|
||||
|
||||
/datum/action/innate/mecha/mech_view_stats
|
||||
name = "View Stats"
|
||||
button_icon_state = "mech_view_stats"
|
||||
|
||||
/datum/action/innate/mecha/mech_view_stats/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
chassis.occupant << browse(chassis.get_stats_html(), "window=exosuit")
|
||||
|
||||
|
||||
/datum/action/innate/mecha/strafe
|
||||
name = "Toggle Strafing"
|
||||
button_icon_state = "strafe"
|
||||
|
||||
/datum/action/innate/mecha/strafe/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
|
||||
chassis.toggle_strafe()
|
||||
|
||||
/obj/mecha/AltClick(mob/living/user)
|
||||
if(user == occupant)
|
||||
toggle_strafe()
|
||||
|
||||
/obj/mecha/proc/toggle_strafe()
|
||||
strafe = !strafe
|
||||
|
||||
occupant_message("Toggled strafing mode [strafe?"on":"off"].")
|
||||
log_message("Toggled strafing mode [strafe?"on":"off"].")
|
||||
strafing_action.UpdateButtonIcon()
|
||||
|
||||
//////////////////////////////////////// Specific Ability Actions ///////////////////////////////////////////////
|
||||
//Need to be granted by the mech type, Not default abilities.
|
||||
|
||||
/datum/action/innate/mecha/mech_toggle_thrusters
|
||||
name = "Toggle Thrusters"
|
||||
button_icon_state = "mech_thrusters_off"
|
||||
|
||||
/datum/action/innate/mecha/mech_toggle_thrusters/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
if(chassis.get_charge() > 0)
|
||||
chassis.thrusters_active = !chassis.thrusters_active
|
||||
button_icon_state = "mech_thrusters_[chassis.thrusters_active ? "on" : "off"]"
|
||||
chassis.log_message("Toggled thrusters.")
|
||||
chassis.occupant_message("<font color='[chassis.thrusters_active ?"blue":"red"]'>Thrusters [chassis.thrusters_active ?"en":"dis"]abled.")
|
||||
|
||||
|
||||
/datum/action/innate/mecha/mech_defence_mode
|
||||
name = "Toggle Defence Mode"
|
||||
button_icon_state = "mech_defense_mode_off"
|
||||
|
||||
/datum/action/innate/mecha/mech_defence_mode/Activate(forced_state = null)
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
if(!isnull(forced_state))
|
||||
chassis.defence_mode = forced_state
|
||||
else
|
||||
chassis.defence_mode = !chassis.defence_mode
|
||||
button_icon_state = "mech_defense_mode_[chassis.defence_mode ? "on" : "off"]"
|
||||
if(chassis.defence_mode)
|
||||
chassis.deflect_chance = chassis.defence_mode_deflect_chance
|
||||
chassis.occupant_message("<span class='notice'>You enable [chassis] defence mode.</span>")
|
||||
else
|
||||
chassis.deflect_chance = initial(chassis.deflect_chance)
|
||||
chassis.occupant_message("<span class='danger'>You disable [chassis] defence mode.</span>")
|
||||
chassis.log_message("Toggled defence mode.")
|
||||
UpdateButtonIcon()
|
||||
|
||||
/datum/action/innate/mecha/mech_overload_mode
|
||||
name = "Toggle leg actuators overload"
|
||||
button_icon_state = "mech_overload_off"
|
||||
|
||||
/datum/action/innate/mecha/mech_overload_mode/Activate(forced_state = null)
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
if(!isnull(forced_state))
|
||||
chassis.leg_overload_mode = forced_state
|
||||
else
|
||||
chassis.leg_overload_mode = !chassis.leg_overload_mode
|
||||
button_icon_state = "mech_overload_[chassis.leg_overload_mode ? "on" : "off"]"
|
||||
chassis.log_message("Toggled leg actuators overload.")
|
||||
if(chassis.leg_overload_mode)
|
||||
chassis.leg_overload_mode = 1
|
||||
chassis.bumpsmash = 1
|
||||
chassis.step_in = min(1, round(chassis.step_in/2))
|
||||
chassis.step_energy_drain = chassis.step_energy_drain*chassis.leg_overload_coeff
|
||||
chassis.occupant_message("<span class='danger'>You enable leg actuators overload.</span>")
|
||||
else
|
||||
chassis.leg_overload_mode = 0
|
||||
chassis.bumpsmash = 0
|
||||
chassis.step_in = initial(chassis.step_in)
|
||||
chassis.step_energy_drain = initial(chassis.step_energy_drain)
|
||||
chassis.occupant_message("<span class='notice'>You disable leg actuators overload.</span>")
|
||||
UpdateButtonIcon()
|
||||
|
||||
/datum/action/innate/mecha/mech_smoke
|
||||
name = "Smoke"
|
||||
button_icon_state = "mech_smoke"
|
||||
|
||||
/datum/action/innate/mecha/mech_smoke/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
if(chassis.smoke_ready && chassis.smoke>0)
|
||||
chassis.smoke_system.start()
|
||||
chassis.smoke--
|
||||
chassis.smoke_ready = 0
|
||||
spawn(chassis.smoke_cooldown)
|
||||
chassis.smoke_ready = 1
|
||||
|
||||
|
||||
/datum/action/innate/mecha/mech_zoom
|
||||
name = "Zoom"
|
||||
button_icon_state = "mech_zoom_off"
|
||||
|
||||
/datum/action/innate/mecha/mech_zoom/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
if(owner.client)
|
||||
chassis.zoom_mode = !chassis.zoom_mode
|
||||
button_icon_state = "mech_zoom_[chassis.zoom_mode ? "on" : "off"]"
|
||||
chassis.log_message("Toggled zoom mode.")
|
||||
chassis.occupant_message("<font color='[chassis.zoom_mode?"blue":"red"]'>Zoom mode [chassis.zoom_mode?"en":"dis"]abled.</font>")
|
||||
if(chassis.zoom_mode)
|
||||
owner.client.view = 12
|
||||
owner << sound('sound/mecha/imag_enh.ogg',volume=50)
|
||||
else
|
||||
owner.client.view = world.view//world.view - default mob view size
|
||||
UpdateButtonIcon()
|
||||
|
||||
/datum/action/innate/mecha/mech_switch_damtype
|
||||
name = "Reconfigure arm microtool arrays"
|
||||
button_icon_state = "mech_damtype_brute"
|
||||
|
||||
/datum/action/innate/mecha/mech_switch_damtype/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
var/new_damtype
|
||||
switch(chassis.damtype)
|
||||
if("tox")
|
||||
new_damtype = "brute"
|
||||
chassis.occupant_message("Your exosuit's hands form into fists.")
|
||||
if("brute")
|
||||
new_damtype = "fire"
|
||||
chassis.occupant_message("A torch tip extends from your exosuit's hand, glowing red.")
|
||||
if("fire")
|
||||
new_damtype = "tox"
|
||||
chassis.occupant_message("A bone-chillingly thick plasteel needle protracts from the exosuit's palm.")
|
||||
chassis.damtype = new_damtype.
|
||||
button_icon_state = "mech_damtype_[new_damtype]"
|
||||
playsound(src, 'sound/mecha/mechmove01.ogg', 50, 1)
|
||||
UpdateButtonIcon()
|
||||
|
||||
/datum/action/innate/mecha/mech_toggle_phasing
|
||||
name = "Toggle Phasing"
|
||||
button_icon_state = "mech_phasing_off"
|
||||
|
||||
/datum/action/innate/mecha/mech_toggle_phasing/Activate()
|
||||
if(!owner || !chassis || chassis.occupant != owner)
|
||||
return
|
||||
chassis.phasing = !chassis.phasing
|
||||
button_icon_state = "mech_phasing_[chassis.phasing ? "on" : "off"]"
|
||||
chassis.occupant_message("<font color=\"[chassis.phasing?"#00f\">En":"#f00\">Dis"]abled phasing.</font>")
|
||||
UpdateButtonIcon()
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,124 @@
|
||||
/obj/machinery/computer/mecha
|
||||
name = "exosuit control console"
|
||||
desc = "Used to remotely locate or lockdown exosuits."
|
||||
icon_screen = "mecha"
|
||||
icon_keyboard = "tech_key"
|
||||
req_access = list(access_robotics)
|
||||
circuit = /obj/item/weapon/circuitboard/computer/mecha_control
|
||||
var/list/located = list()
|
||||
var/screen = 0
|
||||
var/stored_data
|
||||
|
||||
/obj/machinery/computer/mecha/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
user.set_machine(src)
|
||||
var/dat = "<html><head><title>[src.name]</title><style>h3 {margin: 0px; padding: 0px;}</style></head><body>"
|
||||
if(screen == 0)
|
||||
dat += "<h3>Tracking beacons data</h3>"
|
||||
for(var/obj/item/mecha_parts/mecha_tracking/TR in world)
|
||||
var/answer = TR.get_mecha_info()
|
||||
if(answer)
|
||||
dat += {"<hr>[answer]<br/>
|
||||
<a href='?src=\ref[src];send_message=\ref[TR]'>Send message</a><br/>
|
||||
<a href='?src=\ref[src];get_log=\ref[TR]'>Show exosuit log</a> | <a style='color: #f00;' href='?src=\ref[src];shock=\ref[TR]'>(EMP pulse)</a><br>"}
|
||||
|
||||
if(screen==1)
|
||||
dat += "<h3>Log contents</h3>"
|
||||
dat += "<a href='?src=\ref[src];return=1'>Return</a><hr>"
|
||||
dat += "[stored_data]"
|
||||
|
||||
dat += "<A href='?src=\ref[src];refresh=1'>(Refresh)</A><BR>"
|
||||
dat += "</body></html>"
|
||||
|
||||
user << browse(dat, "window=computer;size=400x500")
|
||||
onclose(user, "computer")
|
||||
return
|
||||
|
||||
/obj/machinery/computer/mecha/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
|
||||
if(href_list["send_message"])
|
||||
var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("send_message")
|
||||
var/message = stripped_input(usr,"Input message","Transmit message")
|
||||
var/obj/mecha/M = MT.in_mecha()
|
||||
if(trim(message) && M)
|
||||
M.occupant_message(message)
|
||||
return
|
||||
if(href_list["shock"])
|
||||
var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("shock")
|
||||
MT.shock()
|
||||
if(href_list["get_log"])
|
||||
var/obj/item/mecha_parts/mecha_tracking/MT = filter.getObj("get_log")
|
||||
stored_data = MT.get_mecha_log()
|
||||
screen = 1
|
||||
if(href_list["return"])
|
||||
screen = 0
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_tracking
|
||||
name = "exosuit tracking beacon"
|
||||
desc = "Device used to transmit exosuit data."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "motion2"
|
||||
w_class = 2
|
||||
origin_tech = "programming=2;magnets=2"
|
||||
|
||||
/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info()
|
||||
if(!in_mecha())
|
||||
return 0
|
||||
var/obj/mecha/M = src.loc
|
||||
var/cell_charge = M.get_charge()
|
||||
var/answer = {"<b>Name:</b> [M.name]<br>
|
||||
<b>Integrity:</b> [M.health/initial(M.health)*100]%<br>
|
||||
<b>Cell charge:</b> [isnull(cell_charge)?"Not found":"[M.cell.percent()]%"]<br>
|
||||
<b>Airtank:</b> [M.return_pressure()]kPa<br>
|
||||
<b>Pilot:</b> [M.occupant||"None"]<br>
|
||||
<b>Location:</b> [get_area(M)||"Unknown"]<br>
|
||||
<b>Active equipment:</b> [M.selected||"None"]<br>"}
|
||||
if(istype(M, /obj/mecha/working/ripley))
|
||||
var/obj/mecha/working/ripley/RM = M
|
||||
answer += "<b>Used cargo space:</b> [RM.cargo.len/RM.cargo_capacity*100]%<br>"
|
||||
|
||||
return answer
|
||||
|
||||
/obj/item/mecha_parts/mecha_tracking/emp_act()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_tracking/ex_act()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/item/mecha_parts/mecha_tracking/proc/in_mecha()
|
||||
if(istype(src.loc, /obj/mecha))
|
||||
return src.loc
|
||||
return 0
|
||||
|
||||
/obj/item/mecha_parts/mecha_tracking/proc/shock()
|
||||
var/obj/mecha/M = in_mecha()
|
||||
if(M)
|
||||
M.emp_act(2)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_log()
|
||||
if(!src.in_mecha())
|
||||
return 0
|
||||
var/obj/mecha/M = src.loc
|
||||
return M.get_log_html()
|
||||
|
||||
|
||||
/obj/item/weapon/storage/box/mechabeacons
|
||||
name = "exosuit tracking beacons"
|
||||
|
||||
/obj/item/weapon/storage/box/mechabeacons/New()
|
||||
..()
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
@@ -0,0 +1,336 @@
|
||||
/obj/mecha/proc/get_armour_facing(relative_dir)
|
||||
switch(relative_dir)
|
||||
if(0) // BACKSTAB!
|
||||
return facing_modifiers[BACK_ARMOUR]
|
||||
if(45, 90, 270, 315)
|
||||
return facing_modifiers[SIDE_ARMOUR]
|
||||
if(225, 180, 135)
|
||||
return facing_modifiers[FRONT_ARMOUR]
|
||||
return 1 //always return non-0
|
||||
|
||||
|
||||
/obj/mecha/proc/take_damage(amount, type="brute", booster_deflection_modifier = 1, booster_damage_modifier = 1)
|
||||
if(prob(deflect_chance * booster_deflection_modifier))
|
||||
visible_message("<span class='danger'>[src]'s armour deflects the attack!</span>")
|
||||
log_append_to_last("Armor saved.")
|
||||
return 0
|
||||
if(amount)
|
||||
var/damage = absorbDamage(amount,type)
|
||||
damage = damage * booster_damage_modifier
|
||||
health -= damage
|
||||
update_health()
|
||||
occupant_message("<span class='userdanger'>Taking damage!</span>")
|
||||
log_append_to_last("Took [damage] points of damage. Damage type: \"[type]\".",1)
|
||||
return 1
|
||||
|
||||
|
||||
/obj/mecha/proc/take_directional_damage(amount, type="brute", adir = 0, booster_deflection_modifier = 1, booster_damage_modifier = 1)
|
||||
var/facing_modifier = get_armour_facing(dir2angle(adir) - dir2angle(src))
|
||||
|
||||
booster_damage_modifier /= facing_modifier
|
||||
booster_deflection_modifier *= facing_modifier
|
||||
|
||||
return take_damage(amount, type, booster_deflection_modifier, booster_damage_modifier)
|
||||
|
||||
|
||||
/obj/mecha/proc/absorbDamage(damage,damage_type)
|
||||
var/coeff = 1
|
||||
if(damage_absorption[damage_type])
|
||||
coeff = damage_absorption[damage_type]
|
||||
return damage*coeff
|
||||
|
||||
|
||||
/obj/mecha/proc/update_health()
|
||||
if(health > 0)
|
||||
spark_system.start()
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/obj/mecha/attack_hulk(mob/living/carbon/human/user)
|
||||
..(user, 1)
|
||||
take_directional_damage(15, "brute", get_dir(src, user))
|
||||
check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
|
||||
user.visible_message("<span class='danger'>[user] hits [name]. The metal creaks and bends.</span>")
|
||||
|
||||
/obj/mecha/attack_hand(mob/living/user as mob)
|
||||
user.changeNext_move(CLICK_CD_MELEE) // Ugh. Ideally we shouldn't be setting cooldowns outside of click code.
|
||||
user.do_attack_animation(src)
|
||||
log_message("Attack by hand/paw. Attacker - [user].",1)
|
||||
user.visible_message("<span class='danger'>[user] hits [name]. Nothing happens</span>","<span class='danger'>You hit [name] with no visible effect.</span>")
|
||||
log_append_to_last("Armor saved.")
|
||||
return
|
||||
|
||||
/obj/mecha/attack_paw(mob/user as mob)
|
||||
return attack_hand(user)
|
||||
|
||||
|
||||
/obj/mecha/attack_alien(mob/living/user as mob)
|
||||
log_message("Attack by alien. Attacker - [user].",1)
|
||||
user.changeNext_move(CLICK_CD_MELEE) //Now stompy alien killer mechs are actually scary to aliens!
|
||||
user.do_attack_animation(src)
|
||||
take_directional_damage(15, "brute", get_dir(src, user))
|
||||
check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
|
||||
playsound(loc, 'sound/weapons/slash.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>The [user] slashes at [name]'s armor!</span>")
|
||||
|
||||
/obj/mecha/attack_animal(mob/living/simple_animal/user as mob)
|
||||
log_message("Attack by simple animal. Attacker - [user].",1)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
if(user.melee_damage_upper == 0)
|
||||
user.emote("[user.friendly] [src]")
|
||||
else
|
||||
user.do_attack_animation(src)
|
||||
var/damage = rand(user.melee_damage_lower, user.melee_damage_upper)
|
||||
take_directional_damage(damage, "brute", get_dir(src, user))
|
||||
check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
|
||||
visible_message("<span class='danger'>[user] [user.attacktext] [src]!</span>")
|
||||
add_logs(user, src, "attacked")
|
||||
|
||||
/obj/mecha/attack_tk()
|
||||
return
|
||||
|
||||
/obj/mecha/hitby(atom/movable/A as mob|obj) //wrapper
|
||||
log_message("Hit by [A].",1)
|
||||
var/deflection = 1
|
||||
var/dam_coeff = 1
|
||||
var/counter_tracking = 0
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/B in equipment)
|
||||
if(B.projectile_react())
|
||||
deflection = B.deflect_coeff
|
||||
dam_coeff = B.damage_coeff
|
||||
counter_tracking = 1
|
||||
break
|
||||
if(istype(A, /obj/item/mecha_parts/mecha_tracking))
|
||||
if(!counter_tracking)
|
||||
A.forceMove(src)
|
||||
visible_message("The [A] fastens firmly to [src].")
|
||||
return
|
||||
else
|
||||
deflection = 100 //will bounce off
|
||||
|
||||
if(istype(A, /obj))
|
||||
var/obj/O = A
|
||||
if(O.throwforce)
|
||||
visible_message("<span class='danger'>[name] is hit by [A].</span>")
|
||||
take_directional_damage(O.throwforce, "brute", get_dir(src, A), deflection, dam_coeff)
|
||||
check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
|
||||
return
|
||||
|
||||
|
||||
/obj/mecha/bullet_act(var/obj/item/projectile/Proj) //wrapper
|
||||
log_message("Hit by projectile. Type: [Proj.name]([Proj.flag]).",1)
|
||||
var/deflection = 1
|
||||
var/dam_coeff = 1
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/B in equipment)
|
||||
if(B.projectile_react())
|
||||
deflection = B.deflect_coeff
|
||||
dam_coeff = B.damage_coeff
|
||||
break
|
||||
|
||||
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
|
||||
visible_message("<span class='danger'>[name] is hit by [Proj].</span>")
|
||||
take_directional_damage(Proj.damage*dam_coeff,Proj.flag, turn(Proj.dir, 180), deflection, dam_coeff)
|
||||
check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT))
|
||||
Proj.on_hit(src)
|
||||
|
||||
/obj/mecha/ex_act(severity, target)
|
||||
log_message("Affected by explosion of severity: [severity].",1)
|
||||
if(prob(deflect_chance))
|
||||
severity++
|
||||
log_append_to_last("Armor saved, changing severity to [severity].")
|
||||
switch(severity)
|
||||
if(1)
|
||||
qdel(src)
|
||||
if(2)
|
||||
if (prob(30))
|
||||
qdel(src)
|
||||
else
|
||||
take_damage(initial(health)/2)
|
||||
check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1)
|
||||
if(3)
|
||||
if (prob(5))
|
||||
qdel(src)
|
||||
else
|
||||
take_damage(initial(health)/5)
|
||||
check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1)
|
||||
return
|
||||
|
||||
/obj/mecha/blob_act(obj/effect/blob/B)
|
||||
take_directional_damage(30, "brute", get_dir(src, B))
|
||||
|
||||
/obj/mecha/emp_act(severity)
|
||||
if(get_charge())
|
||||
use_power((cell.charge/3)/(severity*2))
|
||||
take_damage(30 / severity,"energy")
|
||||
log_message("EMP detected",1)
|
||||
check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1)
|
||||
return
|
||||
|
||||
/obj/mecha/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature>max_temperature)
|
||||
log_message("Exposed to dangerous temperature.",1)
|
||||
take_damage(5,"fire")
|
||||
check_for_internal_damage(list(MECHA_INT_FIRE, MECHA_INT_TEMP_CONTROL))
|
||||
return
|
||||
|
||||
|
||||
/obj/mecha/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
|
||||
if(istype(W, /obj/item/device/mmi))
|
||||
if(mmi_move_inside(W,user))
|
||||
user << "[src]-[W] interface initialized successfuly"
|
||||
else
|
||||
user << "[src]-[W] interface initialization failed."
|
||||
return
|
||||
|
||||
if(istype(W, /obj/item/mecha_parts/mecha_equipment))
|
||||
var/obj/item/mecha_parts/mecha_equipment/E = W
|
||||
spawn()
|
||||
if(E.can_attach(src))
|
||||
if(!user.drop_item())
|
||||
return
|
||||
E.attach(src)
|
||||
user.visible_message("[user] attaches [W] to [src].", "<span class='notice'>You attach [W] to [src].</span>")
|
||||
else
|
||||
user << "<span class='warning'>You were unable to attach [W] to [src]!</span>"
|
||||
return
|
||||
if(W.GetID())
|
||||
if(add_req_access || maint_access)
|
||||
if(internals_access_allowed(user))
|
||||
var/obj/item/weapon/card/id/id_card
|
||||
if(istype(W, /obj/item/weapon/card/id))
|
||||
id_card = W
|
||||
else
|
||||
var/obj/item/device/pda/pda = W
|
||||
id_card = pda.id
|
||||
output_maintenance_dialog(id_card, user)
|
||||
return
|
||||
else
|
||||
user << "<span class='warning'>Invalid ID: Access denied.</span>"
|
||||
else
|
||||
user << "<span class='warning'>Maintenance protocols disabled by operator.</span>"
|
||||
else if(istype(W, /obj/item/weapon/wrench))
|
||||
if(state==1)
|
||||
state = 2
|
||||
user << "<span class='notice'>You undo the securing bolts.</span>"
|
||||
else if(state==2)
|
||||
state = 1
|
||||
user << "<span class='notice'>You tighten the securing bolts.</span>"
|
||||
return
|
||||
else if(istype(W, /obj/item/weapon/crowbar))
|
||||
if(state==2)
|
||||
state = 3
|
||||
user << "<span class='notice'>You open the hatch to the power unit.</span>"
|
||||
else if(state==3)
|
||||
state=2
|
||||
user << "<span class='notice'>You close the hatch to the power unit.</span>"
|
||||
return
|
||||
else if(istype(W, /obj/item/stack/cable_coil))
|
||||
if(state == 3 && (internal_damage & MECHA_INT_SHORT_CIRCUIT))
|
||||
var/obj/item/stack/cable_coil/CC = W
|
||||
if(CC.use(2))
|
||||
clearInternalDamage(MECHA_INT_SHORT_CIRCUIT)
|
||||
user << "<span class='notice'>You replace the fused wires.</span>"
|
||||
else
|
||||
user << "<span class='warning'>You need two lengths of cable to fix this mech!</span>"
|
||||
return
|
||||
else if(istype(W, /obj/item/weapon/screwdriver) && user.a_intent != "harm")
|
||||
if(internal_damage & MECHA_INT_TEMP_CONTROL)
|
||||
clearInternalDamage(MECHA_INT_TEMP_CONTROL)
|
||||
user << "<span class='notice'>You repair the damaged temperature controller.</span>"
|
||||
else if(state==3 && cell)
|
||||
cell_power_remaining = max(0.1, cell.charge/cell.maxcharge) //10% charge or whatever is remaining in the current cell
|
||||
cell.forceMove(loc)
|
||||
cell = null
|
||||
state = 4
|
||||
user << "<span class='notice'>You unscrew and pry out the powercell.</span>"
|
||||
log_message("Powercell removed")
|
||||
else if(state==4 && cell)
|
||||
state=3
|
||||
user << "<span class='notice'>You screw the cell in place.</span>"
|
||||
return
|
||||
|
||||
else if(istype(W, /obj/item/weapon/stock_parts/cell))
|
||||
if(state==4)
|
||||
if(!cell)
|
||||
if(!user.drop_item())
|
||||
return
|
||||
var/obj/item/weapon/stock_parts/cell/C = W
|
||||
user << "<span class='notice'>You install the powercell.</span>"
|
||||
C.forceMove(src)
|
||||
C.use(max(0, C.charge - C.maxcharge*cell_power_remaining)) //Set inserted cell's power to saved percentage if that's higher
|
||||
cell = C
|
||||
log_message("Powercell installed")
|
||||
else
|
||||
user << "<span class='notice'>There's already a powercell installed.</span>"
|
||||
return
|
||||
|
||||
else if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != "harm")
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
var/obj/item/weapon/weldingtool/WT = W
|
||||
if(health<initial(health))
|
||||
if (WT.remove_fuel(0,user))
|
||||
if (internal_damage & MECHA_INT_TANK_BREACH)
|
||||
clearInternalDamage(MECHA_INT_TANK_BREACH)
|
||||
user << "<span class='notice'>You repair the damaged gas tank.</span>"
|
||||
else
|
||||
user.visible_message("<span class='notice'>[user] repairs some damage to [name].</span>")
|
||||
health += min(10, initial(health)-health)
|
||||
else
|
||||
user << "<span class='warning'>The welder must be on for this task!</span>"
|
||||
return 1
|
||||
else
|
||||
user << "<span class='warning'>The [name] is at full integrity!</span>"
|
||||
return 1
|
||||
|
||||
else if(istype(W, /obj/item/mecha_parts/mecha_tracking))
|
||||
if(!user.unEquip(W))
|
||||
user << "<span class='warning'>\the [W] is stuck to your hand, you cannot put it in \the [src]!</span>"
|
||||
return
|
||||
W.forceMove(src)
|
||||
user.visible_message("[user] attaches [W] to [src].", "<span class='notice'>You attach [W] to [src].</span>")
|
||||
return
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/mecha/attacked_by(obj/item/I, mob/living/user)
|
||||
log_message("Attacked by [I]. Attacker - [user]")
|
||||
var/deflection = deflect_chance
|
||||
var/dam_coeff = 1
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/B in equipment)
|
||||
if(B.attack_react(user))
|
||||
deflection *= B.deflect_coeff
|
||||
dam_coeff *= B.damage_coeff
|
||||
break
|
||||
if(prob(deflection))
|
||||
user << "<span class='danger'>\The [I.name] bounces off [name]'s armor.</span>"
|
||||
log_append_to_last("Armor saved.")
|
||||
else
|
||||
user.visible_message("<span class='danger'>[user] hits [src] with [I].</span>", "<span class='danger'>You hit [src] with [I].</span>")
|
||||
take_directional_damage(round(I.force*dam_coeff),I.damtype, get_dir(src, user))
|
||||
check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
|
||||
|
||||
|
||||
/obj/mecha/proc/mech_toxin_damage(mob/living/target)
|
||||
playsound(src, 'sound/effects/spray2.ogg', 50, 1)
|
||||
if(target.reagents)
|
||||
if(target.reagents.get_reagent_amount("cryptobiolin") + force < force*2)
|
||||
target.reagents.add_reagent("cryptobiolin", force/2)
|
||||
if(target.reagents.get_reagent_amount("toxin") + force < force*2)
|
||||
target.reagents.add_reagent("toxin", force/2.5)
|
||||
|
||||
|
||||
/atom/proc/mech_melee_attack(obj/mecha/M)
|
||||
return
|
||||
|
||||
/obj/mecha/mech_melee_attack(obj/mecha/M)
|
||||
if(M.damtype =="brute")
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
else if(M.damtype == "fire")
|
||||
playsound(src, 'sound/items/Welder.ogg', 50, 1)
|
||||
else
|
||||
return
|
||||
visible_message("<span class='danger'>[M.name] has hit [src].</span>")
|
||||
take_directional_damage(M.force, damtype, get_dir(src, M))
|
||||
add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
|
||||
return
|
||||
@@ -0,0 +1,402 @@
|
||||
/////////////////////////
|
||||
////// Mecha Parts //////
|
||||
/////////////////////////
|
||||
|
||||
/obj/item/mecha_parts
|
||||
name = "mecha part"
|
||||
icon = 'icons/mecha/mech_construct.dmi'
|
||||
icon_state = "blank"
|
||||
w_class = 6
|
||||
flags = CONDUCT
|
||||
origin_tech = "programming=2;materials=2;engineering=2"
|
||||
|
||||
/obj/item/mecha_parts/chassis
|
||||
name="Mecha Chassis"
|
||||
icon_state = "backbone"
|
||||
var/datum/construction/construct
|
||||
|
||||
/obj/item/mecha_parts/chassis/attackby(obj/item/W, mob/user, params)
|
||||
if(!construct || !construct.action(W, user))
|
||||
return ..()
|
||||
|
||||
/obj/item/mecha_parts/chassis/attack_hand()
|
||||
return
|
||||
|
||||
/////////// Ripley
|
||||
|
||||
/obj/item/mecha_parts/chassis/ripley
|
||||
name = "\improper Ripley chassis"
|
||||
|
||||
/obj/item/mecha_parts/chassis/ripley/New()
|
||||
..()
|
||||
construct = new /datum/construction/mecha/ripley_chassis(src)
|
||||
|
||||
/obj/item/mecha_parts/part/ripley_torso
|
||||
name = "\improper Ripley torso"
|
||||
desc = "A torso part of Ripley APLU. Contains power unit, processing core and life support systems."
|
||||
icon_state = "ripley_harness"
|
||||
origin_tech = "programming=2;materials=2;biotech=2;engineering=2"
|
||||
|
||||
/obj/item/mecha_parts/part/ripley_left_arm
|
||||
name = "\improper Ripley left arm"
|
||||
desc = "A Ripley APLU left arm. Data and power sockets are compatible with most exosuit tools."
|
||||
icon_state = "ripley_l_arm"
|
||||
|
||||
/obj/item/mecha_parts/part/ripley_right_arm
|
||||
name = "\improper Ripley right arm"
|
||||
desc = "A Ripley APLU right arm. Data and power sockets are compatible with most exosuit tools."
|
||||
icon_state = "ripley_r_arm"
|
||||
|
||||
/obj/item/mecha_parts/part/ripley_left_leg
|
||||
name = "\improper Ripley left leg"
|
||||
desc = "A Ripley APLU left leg. Contains somewhat complex servodrives and balance maintaining systems."
|
||||
icon_state = "ripley_l_leg"
|
||||
|
||||
/obj/item/mecha_parts/part/ripley_right_leg
|
||||
name = "\improper Ripley right leg"
|
||||
desc = "A Ripley APLU right leg. Contains somewhat complex servodrives and balance maintaining systems."
|
||||
icon_state = "ripley_r_leg"
|
||||
|
||||
///////// Odysseus
|
||||
|
||||
/obj/item/mecha_parts/chassis/odysseus
|
||||
name = "\improper Odysseus chassis"
|
||||
|
||||
/obj/item/mecha_parts/chassis/odysseus/New()
|
||||
..()
|
||||
construct = new /datum/construction/mecha/odysseus_chassis(src)
|
||||
|
||||
/obj/item/mecha_parts/part/odysseus_head
|
||||
name = "\improper Odysseus head"
|
||||
desc = "An Odysseus head. Contains an integrated medical HUD scanner."
|
||||
icon_state = "odysseus_head"
|
||||
|
||||
/obj/item/mecha_parts/part/odysseus_torso
|
||||
name = "\improper Odysseus torso"
|
||||
desc="A torso part of Odysseus. Contains power unit, processing core and life support systems along with an attachment port for a mounted sleeper."
|
||||
icon_state = "odysseus_torso"
|
||||
origin_tech = "programming=2;materials=2;biotech=2;engineering=2"
|
||||
|
||||
/obj/item/mecha_parts/part/odysseus_left_arm
|
||||
name = "\improper Odysseus left arm"
|
||||
desc = "An Odysseus left arm. Data and power sockets are compatible with specialized medical equipment."
|
||||
icon_state = "odysseus_l_arm"
|
||||
|
||||
/obj/item/mecha_parts/part/odysseus_right_arm
|
||||
name = "\improper Odysseus right arm"
|
||||
desc = "An Odysseus right arm. Data and power sockets are compatible with specialized medical equipment."
|
||||
icon_state = "odysseus_r_arm"
|
||||
|
||||
/obj/item/mecha_parts/part/odysseus_left_leg
|
||||
name = "\improper Odysseus left leg"
|
||||
desc = "An Odysseus left leg. Contains complex servodrives and balance maintaining systems to maintain stability for critical patients."
|
||||
icon_state = "odysseus_l_leg"
|
||||
|
||||
/obj/item/mecha_parts/part/odysseus_right_leg
|
||||
name = "\improper Odysseus right leg"
|
||||
desc = "A Odysseus right leg. Contains complex servodrives and balance maintaining systems to maintain stability for critical patients."
|
||||
icon_state = "odysseus_r_leg"
|
||||
|
||||
///////// Gygax
|
||||
|
||||
/obj/item/mecha_parts/chassis/gygax
|
||||
name = "\improper Gygax chassis"
|
||||
|
||||
/obj/item/mecha_parts/chassis/gygax/New()
|
||||
..()
|
||||
construct = new /datum/construction/mecha/gygax_chassis(src)
|
||||
|
||||
/obj/item/mecha_parts/part/gygax_torso
|
||||
name = "\improper Gygax torso"
|
||||
desc = "A torso part of Gygax. Contains power unit, processing core and life support systems."
|
||||
icon_state = "gygax_harness"
|
||||
origin_tech = "programming=2;materials=4;biotech=3;engineering=3"
|
||||
|
||||
/obj/item/mecha_parts/part/gygax_head
|
||||
name = "\improper Gygax head"
|
||||
desc = "A Gygax head. Houses advanced surveilance and targeting sensors."
|
||||
icon_state = "gygax_head"
|
||||
origin_tech = "programming=2;materials=4;magnets=3;engineering=3"
|
||||
|
||||
/obj/item/mecha_parts/part/gygax_left_arm
|
||||
name = "\improper Gygax left arm"
|
||||
desc = "A Gygax left arm. Data and power sockets are compatible with most exosuit tools and weapons."
|
||||
icon_state = "gygax_l_arm"
|
||||
origin_tech = "programming=2;materials=4;engineering=3"
|
||||
|
||||
/obj/item/mecha_parts/part/gygax_right_arm
|
||||
name = "\improper Gygax right arm"
|
||||
desc = "A Gygax right arm. Data and power sockets are compatible with most exosuit tools and weapons."
|
||||
icon_state = "gygax_r_arm"
|
||||
origin_tech = "programming=2;materials=4;engineering=3"
|
||||
|
||||
/obj/item/mecha_parts/part/gygax_left_leg
|
||||
name = "\improper Gygax left leg"
|
||||
desc = "A Gygax left leg. Constructed with advanced servomechanisms and actuators to enable faster speed."
|
||||
icon_state = "gygax_l_leg"
|
||||
origin_tech = "programming=2;materials=4;engineering=3"
|
||||
|
||||
/obj/item/mecha_parts/part/gygax_right_leg
|
||||
name = "\improper Gygax right leg"
|
||||
desc = "A Gygax right leg. Constructed with advanced servomechanisms and actuators to enable faster speed."
|
||||
icon_state = "gygax_r_leg"
|
||||
origin_tech = "programming=2;materials=4;engineering=3"
|
||||
|
||||
/obj/item/mecha_parts/part/gygax_armor
|
||||
gender = PLURAL
|
||||
name = "\improper Gygax armor plates"
|
||||
desc = "A set of armor plates designed for the Gygax. Designed to effectively deflect damage with a lightweight construction."
|
||||
icon_state = "gygax_armor"
|
||||
origin_tech = "materials=6;combat=4;engineering=4"
|
||||
|
||||
|
||||
//////////// Durand
|
||||
|
||||
/obj/item/mecha_parts/chassis/durand
|
||||
name = "\improper Durand chassis"
|
||||
|
||||
/obj/item/mecha_parts/chassis/durand/New()
|
||||
..()
|
||||
construct = new /datum/construction/mecha/durand_chassis(src)
|
||||
|
||||
/obj/item/mecha_parts/part/durand_torso
|
||||
name = "\improper Durand torso"
|
||||
desc = "A torso part of Durand. Contains power unit, processing core and life support systems within a robust protective frame."
|
||||
icon_state = "durand_harness"
|
||||
origin_tech = "programming=2;materials=3;biotech=3;engineering=3"
|
||||
|
||||
/obj/item/mecha_parts/part/durand_head
|
||||
name = "\improper Durand head"
|
||||
desc = "A Durand head. Houses advanced surveilance and targeting sensors."
|
||||
icon_state = "durand_head"
|
||||
origin_tech = "programming=2;materials=3;magnets=3;engineering=3"
|
||||
|
||||
/obj/item/mecha_parts/part/durand_left_arm
|
||||
name = "\improper Durand left arm"
|
||||
desc = "A Durand left arm. Data and power sockets are compatible with most exosuit tools and weapons. Packs a really mean punch as well."
|
||||
icon_state = "durand_l_arm"
|
||||
origin_tech = "programming=2;materials=3;engineering=3"
|
||||
|
||||
/obj/item/mecha_parts/part/durand_right_arm
|
||||
name = "\improper Durand right arm"
|
||||
desc = "A Durand right arm. Data and power sockets are compatible with most exosuit tools and weapons. Packs a really mean punch as well."
|
||||
icon_state = "durand_r_arm"
|
||||
origin_tech = "programming=2;materials=3;engineering=3"
|
||||
|
||||
/obj/item/mecha_parts/part/durand_left_leg
|
||||
name = "\improper Durand left leg"
|
||||
desc = "A Durand left leg. Built particlarly sturdy to support the Durand's heavy weight and defensive needs."
|
||||
icon_state = "durand_l_leg"
|
||||
origin_tech = "programming=2;materials=3;engineering=3"
|
||||
|
||||
/obj/item/mecha_parts/part/durand_right_leg
|
||||
name = "\improper Durand right leg"
|
||||
desc = "A Durand right leg. Built particlarly sturdy to support the Durand's heavy weight and defensive needs."
|
||||
icon_state = "durand_r_leg"
|
||||
origin_tech = "programming=2;materials=3;engineering=3"
|
||||
|
||||
/obj/item/mecha_parts/part/durand_armor
|
||||
gender = PLURAL
|
||||
name = "\improper Durand armor plates"
|
||||
desc = "A set of armor plates for the Durand. Built heavy to resist an incredible amount of brute force."
|
||||
icon_state = "durand_armor"
|
||||
origin_tech = "materials=5;combat=4;engineering=4"
|
||||
|
||||
////////// Firefighter
|
||||
|
||||
/obj/item/mecha_parts/chassis/firefighter
|
||||
name = "Firefighter chassis"
|
||||
|
||||
/obj/item/mecha_parts/chassis/firefighter/New()
|
||||
..()
|
||||
construct = new /datum/construction/mecha/firefighter_chassis(src)
|
||||
|
||||
|
||||
////////// HONK
|
||||
|
||||
/obj/item/mecha_parts/chassis/honker
|
||||
name = "\improper H.O.N.K chassis"
|
||||
|
||||
/obj/item/mecha_parts/chassis/honker/New()
|
||||
..()
|
||||
construct = new /datum/construction/mecha/honker_chassis(src)
|
||||
|
||||
/obj/item/mecha_parts/part/honker_torso
|
||||
name = "\improper H.O.N.K torso"
|
||||
desc = "A torso part of H.O.N.K. Contains chuckle unit, bananium core and honk support systems."
|
||||
icon_state = "honker_harness"
|
||||
|
||||
/obj/item/mecha_parts/part/honker_head
|
||||
name = "\improper H.O.N.K head"
|
||||
desc = "A H.O.N.K head. Appears to lack a face plate."
|
||||
icon_state = "honker_head"
|
||||
|
||||
/obj/item/mecha_parts/part/honker_left_arm
|
||||
name = "\improper H.O.N.K left arm"
|
||||
desc = "A H.O.N.K left arm. With unique sockets that accept odd weaponry designed by clown scientists."
|
||||
icon_state = "honker_l_arm"
|
||||
|
||||
/obj/item/mecha_parts/part/honker_right_arm
|
||||
name = "\improper H.O.N.K right arm"
|
||||
desc = "A H.O.N.K right arm. With unique sockets that accept odd weaponry designed by clown scientists."
|
||||
icon_state = "honker_r_arm"
|
||||
|
||||
/obj/item/mecha_parts/part/honker_left_leg
|
||||
name = "\improper H.O.N.K left leg"
|
||||
desc = "A H.O.N.K left leg. The foot appears just large enough to fully accomodate a clown shoe."
|
||||
icon_state = "honker_l_leg"
|
||||
|
||||
/obj/item/mecha_parts/part/honker_right_leg
|
||||
name = "\improper H.O.N.K right leg"
|
||||
desc = "A H.O.N.K right leg. The foot appears just large enough to fully accomodate a clown shoe."
|
||||
icon_state = "honker_r_leg"
|
||||
|
||||
|
||||
////////// Phazon
|
||||
|
||||
/obj/item/mecha_parts/chassis/phazon
|
||||
name = "\improper Phazon chassis"
|
||||
|
||||
/obj/item/mecha_parts/chassis/phazon/New()
|
||||
..()
|
||||
construct = new /datum/construction/mecha/phazon_chassis(src)
|
||||
|
||||
/obj/item/mecha_parts/part/phazon_torso
|
||||
name="\improper Phazon torso"
|
||||
desc="A Phazon torso part. The socket for the bluespace core that powers the exosuit's unique phase drives is located in the middle."
|
||||
icon_state = "phazon_harness"
|
||||
origin_tech = "programming=4;materials=4;bluespace=4;plasmatech=5"
|
||||
|
||||
/obj/item/mecha_parts/part/phazon_head
|
||||
name="\improper Phazon head"
|
||||
desc="A Phazon head. Its sensors are carefully calibrated to provide vision and data even when the exosuit is phasing."
|
||||
icon_state = "phazon_head"
|
||||
origin_tech = "programming=3;materials=3;magnets=3"
|
||||
|
||||
/obj/item/mecha_parts/part/phazon_left_arm
|
||||
name="\improper Phazon left arm"
|
||||
desc="A Phazon left arm. Several microtool arrays are located under the armor plating, which can be adjusted to the situation at hand."
|
||||
icon_state = "phazon_l_arm"
|
||||
origin_tech = "materials=3;bluespace=3;magnets=3"
|
||||
|
||||
/obj/item/mecha_parts/part/phazon_right_arm
|
||||
name="\improper Phazon right arm"
|
||||
desc="A Phazon right arm. Several microtool arrays are located under the armor plating, which can be adjusted to the situation at hand."
|
||||
icon_state = "phazon_r_arm"
|
||||
origin_tech = "materials=3;bluespace=3;magnets=3"
|
||||
|
||||
/obj/item/mecha_parts/part/phazon_left_leg
|
||||
name="\improper Phazon left leg"
|
||||
desc="A Phazon left leg. It contains the unique phase drives that allow the exosuit to phase through solid matter when engaged."
|
||||
icon_state = "phazon_l_leg"
|
||||
origin_tech = "materials=3;bluespace=3;magnets=3"
|
||||
|
||||
/obj/item/mecha_parts/part/phazon_right_leg
|
||||
name="\improper Phazon right leg"
|
||||
desc="A Phazon right leg. It contains the unique phase drives that allow the exosuit to phase through solid matter when engaged."
|
||||
icon_state = "phazon_r_leg"
|
||||
origin_tech = "materials=3;bluespace=3;magnets=3"
|
||||
|
||||
/obj/item/mecha_parts/part/phazon_armor
|
||||
name="Phazon armor"
|
||||
desc="Phazon armor plates. They are layered with plasma to protect the pilot from the stress of phasing and have unusual properties."
|
||||
icon_state = "phazon_armor"
|
||||
origin_tech = "materials=4;bluespace=4;plasmatech=5"
|
||||
|
||||
|
||||
///////// Circuitboards
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha
|
||||
name = "exosuit circuit board"
|
||||
icon = 'icons/obj/module.dmi'
|
||||
icon_state = "std_mod"
|
||||
item_state = "electronic"
|
||||
flags = CONDUCT
|
||||
force = 5
|
||||
w_class = 2
|
||||
throwforce = 0
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/ripley
|
||||
origin_tech = "programming=2"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/ripley/peripherals
|
||||
name = "circuit board (Ripley Peripherals Control module)"
|
||||
icon_state = "mcontroller"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/ripley/main
|
||||
name = "circuit board (Ripley Central Control module)"
|
||||
icon_state = "mainboard"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/gygax
|
||||
origin_tech = "programming=4;combat=3;engineering=3"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/gygax/peripherals
|
||||
name = "circuit board (Gygax Peripherals Control module)"
|
||||
icon_state = "mcontroller"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/gygax/targeting
|
||||
name = "circuit board (Gygax Weapon Control and Targeting module)"
|
||||
icon_state = "mcontroller"
|
||||
origin_tech = "programming=4;combat=4"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/gygax/main
|
||||
name = "circuit board (Gygax Central Control module)"
|
||||
icon_state = "mainboard"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/durand
|
||||
origin_tech = "programming=4;combat=3;engineering=3"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/durand/peripherals
|
||||
name = "circuit board (Durand Peripherals Control module)"
|
||||
icon_state = "mcontroller"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/durand/targeting
|
||||
name = "circuit board (Durand Weapon Control and Targeting module)"
|
||||
icon_state = "mcontroller"
|
||||
origin_tech = "programming=4;combat=4;engineering=3"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/durand/main
|
||||
name = "circuit board (Durand Central Control module)"
|
||||
icon_state = "mainboard"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/honker
|
||||
origin_tech = "programming=3;engineering=3"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/honker/peripherals
|
||||
name = "circuit board (H.O.N.K Peripherals Control module)"
|
||||
icon_state = "mcontroller"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/honker/targeting
|
||||
name = "circuit board (H.O.N.K Weapon Control and Targeting module)"
|
||||
icon_state = "mcontroller"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/honker/main
|
||||
name = "circuit board (H.O.N.K Central Control module)"
|
||||
icon_state = "mainboard"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/odysseus
|
||||
origin_tech = "programming=3;biotech=3"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/odysseus/peripherals
|
||||
name = "circuit board (Odysseus Peripherals Control module)"
|
||||
icon_state = "mcontroller"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/odysseus/main
|
||||
name = "circuit board (Odysseus Central Control module)"
|
||||
icon_state = "mainboard"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/phazon
|
||||
origin_tech = "programming=5;plasmatech=4"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/phazon/peripherals
|
||||
name = "circuit board (Phazon Peripherals Control module)"
|
||||
icon_state = "mcontroller"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/phazon/targeting
|
||||
name = "circuit board (Phazon Weapon Control and Targeting module)"
|
||||
icon_state = "mcontroller"
|
||||
|
||||
/obj/item/weapon/circuitboard/mecha/phazon/main
|
||||
name = "circuit board (Phazon Central Control module)"
|
||||
@@ -0,0 +1,331 @@
|
||||
|
||||
////////////////////////////////////
|
||||
///// Rendering stats window ///////
|
||||
////////////////////////////////////
|
||||
|
||||
/obj/mecha/proc/get_stats_html()
|
||||
. = {"<html>
|
||||
<head><title>[src.name] data</title>
|
||||
<style>
|
||||
body {color: #00ff00; background: #000000; font-family:"Lucida Console",monospace; font-size: 12px;}
|
||||
hr {border: 1px solid #0f0; color: #0f0; background-color: #0f0;}
|
||||
a {padding:2px 5px;;color:#0f0;}
|
||||
.wr {margin-bottom: 5px;}
|
||||
.header {cursor:pointer;}
|
||||
.open, .closed {background: #32CD32; color:#000; padding:1px 2px;}
|
||||
.links a {margin-bottom: 2px;padding-top:3px;}
|
||||
.visible {display: block;}
|
||||
.hidden {display: none;}
|
||||
</style>
|
||||
<script language='javascript' type='text/javascript'>
|
||||
[js_byjax]
|
||||
[js_dropdowns]
|
||||
function ticker() {
|
||||
setInterval(function(){
|
||||
window.location='byond://?src=\ref[src]&update_content=1';
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
dropdowns();
|
||||
ticker();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id='content'>
|
||||
[src.get_stats_part()]
|
||||
</div>
|
||||
<div id='eq_list'>
|
||||
[src.get_equipment_list()]
|
||||
</div>
|
||||
<hr>
|
||||
<div id='commands'>
|
||||
[src.get_commands()]
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
|
||||
|
||||
|
||||
/obj/mecha/proc/report_internal_damage()
|
||||
. = ""
|
||||
var/list/dam_reports = list(
|
||||
"[MECHA_INT_FIRE]" = "<span class='userdanger'>INTERNAL FIRE</span>",
|
||||
"[MECHA_INT_TEMP_CONTROL]" = "<span class='userdanger'>LIFE SUPPORT SYSTEM MALFUNCTION</span>",
|
||||
"[MECHA_INT_TANK_BREACH]" = "<span class='userdanger'>GAS TANK BREACH</span>",
|
||||
"[MECHA_INT_CONTROL_LOST]" = "<span class='userdanger'>COORDINATION SYSTEM CALIBRATION FAILURE</span> - <a href='?src=\ref[src];repair_int_control_lost=1'>Recalibrate</a>",
|
||||
"[MECHA_INT_SHORT_CIRCUIT]" = "<span class='userdanger'>SHORT CIRCUIT</span>"
|
||||
)
|
||||
for(var/tflag in dam_reports)
|
||||
var/intdamflag = text2num(tflag)
|
||||
if(internal_damage & intdamflag)
|
||||
. += dam_reports[tflag]
|
||||
. += "<br />"
|
||||
if(return_pressure() > WARNING_HIGH_PRESSURE)
|
||||
. += "<span class='userdanger'>DANGEROUSLY HIGH CABIN PRESSURE</span><br />"
|
||||
|
||||
|
||||
|
||||
/obj/mecha/proc/get_stats_part()
|
||||
var/integrity = health/initial(health)*100
|
||||
var/cell_charge = get_charge()
|
||||
var/datum/gas_mixture/int_tank_air = internal_tank.return_air()
|
||||
var/tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None"
|
||||
var/tank_temperature = internal_tank ? int_tank_air.temperature : "Unknown"
|
||||
var/cabin_pressure = round(return_pressure(),0.01)
|
||||
. = {"[report_internal_damage()]
|
||||
[integrity<30?"<span class='userdanger'>DAMAGE LEVEL CRITICAL</span><br>":null]
|
||||
<b>Integrity: </b> [integrity]%<br>
|
||||
<b>Powercell charge: </b>[isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]<br>
|
||||
<b>Air source: </b>[use_internal_tank?"Internal Airtank":"Environment"]<br>
|
||||
<b>Airtank pressure: </b>[tank_pressure]kPa<br>
|
||||
<b>Airtank temperature: </b>[tank_temperature]°K|[tank_temperature - T0C]°C<br>
|
||||
<b>Cabin pressure: </b>[cabin_pressure>WARNING_HIGH_PRESSURE ? "<span class='danger'>[cabin_pressure]</span>": cabin_pressure]kPa<br>
|
||||
<b>Cabin temperature: </b> [return_temperature()]°K|[return_temperature() - T0C]°C<br>
|
||||
[dna_lock?"<b>DNA-locked:</b><br> <span style='font-size:10px;letter-spacing:-1px;'>[dna_lock]</span> \[<a href='?src=\ref[src];reset_dna=1'>Reset</a>\]<br>":""]<br>
|
||||
[thrusters_action.owner ? "<b>Thrusters: </b> [thrusters_active ? "Enabled" : "Disabled"]<br>" : ""]
|
||||
[defense_action.owner ? "<b>Defence Mode: </b> [defence_mode ? "Enabled" : "Disabled"]<br>" : ""]
|
||||
[overload_action.owner ? "<b>Leg Actuators Overload: </b> [leg_overload_mode ? "Enabled" : "Disabled"]<br>" : ""]
|
||||
[smoke_action.owner ? "<b>Smoke: </b> [smoke]<br>" : ""]
|
||||
[zoom_action.owner ? "<b>Zoom: </b> [zoom_mode ? "Enabled" : "Disabled"]<br>" : ""]
|
||||
[switch_damtype_action.owner ? "<b>Damtype: </b> [damtype]<br>" : ""]
|
||||
[phasing_action.owner ? "<b>Phase Modulator: </b> [phasing ? "Enabled" : "Disabled"]<br>" : ""]
|
||||
"}
|
||||
|
||||
|
||||
/obj/mecha/proc/get_commands()
|
||||
. = {"<div class='wr'>
|
||||
<div class='header'>Electronics</div>
|
||||
<div class='links'>
|
||||
<b>Radio settings:</b><br>
|
||||
Microphone: <a href='?src=\ref[src];rmictoggle=1'><span id="rmicstate">[radio.broadcasting?"Engaged":"Disengaged"]</span></a><br>
|
||||
Speaker: <a href='?src=\ref[src];rspktoggle=1'><span id="rspkstate">[radio.listening?"Engaged":"Disengaged"]</span></a><br>
|
||||
Frequency:
|
||||
<a href='?src=\ref[src];rfreq=-10'>-</a>
|
||||
<a href='?src=\ref[src];rfreq=-2'>-</a>
|
||||
<span id="rfreq">[format_frequency(radio.frequency)]</span>
|
||||
<a href='?src=\ref[src];rfreq=2'>+</a>
|
||||
<a href='?src=\ref[src];rfreq=10'>+</a><br>
|
||||
</div>
|
||||
</div>
|
||||
<div class='wr'>
|
||||
<div class='header'>Permissions & Logging</div>
|
||||
<div class='links'>
|
||||
<a href='?src=\ref[src];toggle_id_upload=1'><span id='t_id_upload'>[add_req_access?"L":"Unl"]ock ID upload panel</span></a><br>
|
||||
<a href='?src=\ref[src];toggle_maint_access=1'><span id='t_maint_access'>[maint_access?"Forbid":"Permit"] maintenance protocols</span></a><br>
|
||||
<a href='?src=\ref[src];dna_lock=1'>DNA-lock</a><br>
|
||||
<a href='?src=\ref[src];view_log=1'>View internal log</a><br>
|
||||
<a href='?src=\ref[src];change_name=1'>Change exosuit name</a><br>
|
||||
</div>
|
||||
</div>
|
||||
<div id='equipment_menu'>[get_equipment_menu()]</div>
|
||||
"}
|
||||
|
||||
|
||||
/obj/mecha/proc/get_equipment_menu() //outputs mecha html equipment menu
|
||||
. = ""
|
||||
if(equipment.len)
|
||||
. += {"<div class='wr'>
|
||||
<div class='header'>Equipment</div>
|
||||
<div class='links'>"}
|
||||
for(var/X in equipment)
|
||||
var/obj/item/mecha_parts/mecha_equipment/W = X
|
||||
. += "[W.name] <a href='?src=\ref[W];detach=1'>Detach</a><br>"
|
||||
. += "<b>Available equipment slots:</b> [max_equip-equipment.len]"
|
||||
. += "</div></div>"
|
||||
|
||||
|
||||
/obj/mecha/proc/get_equipment_list() //outputs mecha equipment list in html
|
||||
if(!equipment.len)
|
||||
return
|
||||
. = "<b>Equipment:</b><div style=\"margin-left: 15px;\">"
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/MT in equipment)
|
||||
. += "<div id='\ref[MT]'>[MT.get_equip_info()]</div>"
|
||||
. += "</div>"
|
||||
|
||||
|
||||
|
||||
/obj/mecha/proc/get_log_html()
|
||||
. = "<html><head><title>[src.name] Log</title></head><body style='font: 13px 'Courier', monospace;'>"
|
||||
for(var/list/entry in log)
|
||||
. += {"<div style='font-weight: bold;'>[entry["time"]] [time2text(entry["date"],"MMM DD")] [entry["year"]]</div>
|
||||
<div style='margin-left:15px; margin-bottom:10px;'>[entry["message"]]</div>
|
||||
"}
|
||||
. += "</body></html>"
|
||||
|
||||
|
||||
|
||||
/obj/mecha/proc/output_access_dialog(obj/item/weapon/card/id/id_card, mob/user)
|
||||
if(!id_card || !user) return
|
||||
. = {"<html>
|
||||
<head><style>
|
||||
h1 {font-size:15px;margin-bottom:4px;}
|
||||
body {color: #00ff00; background: #000000; font-family:"Courier New", Courier, monospace; font-size: 12px;}
|
||||
a {color:#0f0;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Following keycodes are present in this system:</h1>"}
|
||||
for(var/a in operation_req_access)
|
||||
. += "[get_access_desc(a)] - <a href='?src=\ref[src];del_req_access=[a];user=\ref[user];id_card=\ref[id_card]'>Delete</a><br>"
|
||||
. += "<hr><h1>Following keycodes were detected on portable device:</h1>"
|
||||
for(var/a in id_card.access)
|
||||
if(a in operation_req_access) continue
|
||||
var/a_name = get_access_desc(a)
|
||||
if(!a_name) continue //there's some strange access without a name
|
||||
. += "[a_name] - <a href='?src=\ref[src];add_req_access=[a];user=\ref[user];id_card=\ref[id_card]'>Add</a><br>"
|
||||
. += "<hr><a href='?src=\ref[src];finish_req_access=1;user=\ref[user]'>Finish</a> "
|
||||
. += "<span class='danger'>(Warning! The ID upload panel will be locked. It can be unlocked only through Exosuit Interface.)</span>"
|
||||
. += "</body></html>"
|
||||
user << browse(., "window=exosuit_add_access")
|
||||
onclose(user, "exosuit_add_access")
|
||||
|
||||
|
||||
/obj/mecha/proc/output_maintenance_dialog(obj/item/weapon/card/id/id_card,mob/user)
|
||||
if(!id_card || !user) return
|
||||
. = {"<html>
|
||||
<head>
|
||||
<style>
|
||||
body {color: #00ff00; background: #000000; font-family:"Courier New", Courier, monospace; font-size: 12px;}
|
||||
a {padding:2px 5px; background:#32CD32;color:#000;display:block;margin:2px;text-align:center;text-decoration:none;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
[add_req_access?"<a href='?src=\ref[src];req_access=1;id_card=\ref[id_card];user=\ref[user]'>Edit operation keycodes</a>":null]
|
||||
[maint_access?"<a href='?src=\ref[src];maint_access=1;id_card=\ref[id_card];user=\ref[user]'>Initiate maintenance protocol</a>":null]
|
||||
[(state>0) ?"<a href='?src=\ref[src];set_internal_tank_valve=1;user=\ref[user]'>Set Cabin Air Pressure</a>":null]
|
||||
</body>
|
||||
</html>"}
|
||||
user << browse(., "window=exosuit_maint_console")
|
||||
onclose(user, "exosuit_maint_console")
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////
|
||||
///// Topic /////
|
||||
/////////////////
|
||||
|
||||
/obj/mecha/Topic(href, href_list)
|
||||
..()
|
||||
if(href_list["close"])
|
||||
return
|
||||
|
||||
if(usr.incapacitated())
|
||||
return
|
||||
|
||||
var/datum/topic_input/filter = new /datum/topic_input(href,href_list)
|
||||
|
||||
if(in_range(src, usr))
|
||||
|
||||
if(href_list["req_access"] && add_req_access)
|
||||
output_access_dialog(filter.getObj("id_card"),filter.getMob("user"))
|
||||
|
||||
if(href_list["maint_access"] && maint_access)
|
||||
var/mob/user = filter.getMob("user")
|
||||
if(user)
|
||||
if(state==0)
|
||||
state = 1
|
||||
user << "The securing bolts are now exposed."
|
||||
else if(state==1)
|
||||
state = 0
|
||||
user << "The securing bolts are now hidden."
|
||||
output_maintenance_dialog(filter.getObj("id_card"),user)
|
||||
|
||||
if(href_list["set_internal_tank_valve"] && state >=1)
|
||||
var/mob/user = filter.getMob("user")
|
||||
if(user)
|
||||
var/new_pressure = input(user,"Input new output pressure","Pressure setting",internal_tank_valve) as num
|
||||
if(new_pressure)
|
||||
internal_tank_valve = new_pressure
|
||||
user << "The internal pressure valve has been set to [internal_tank_valve]kPa."
|
||||
|
||||
if(href_list["add_req_access"] && add_req_access && filter.getObj("id_card"))
|
||||
operation_req_access += filter.getNum("add_req_access")
|
||||
output_access_dialog(filter.getObj("id_card"),filter.getMob("user"))
|
||||
|
||||
if(href_list["del_req_access"] && add_req_access && filter.getObj("id_card"))
|
||||
operation_req_access -= filter.getNum("del_req_access")
|
||||
output_access_dialog(filter.getObj("id_card"),filter.getMob("user"))
|
||||
|
||||
if(href_list["finish_req_access"])
|
||||
add_req_access = 0
|
||||
var/mob/user = filter.getMob("user")
|
||||
user << browse(null,"window=exosuit_add_access")
|
||||
|
||||
if(usr != occupant)
|
||||
return
|
||||
|
||||
if(href_list["update_content"])
|
||||
send_byjax(src.occupant,"exosuit.browser","content",src.get_stats_part())
|
||||
|
||||
if(href_list["select_equip"])
|
||||
var/obj/item/mecha_parts/mecha_equipment/equip = filter.getObj("select_equip")
|
||||
if(equip && equip.selectable)
|
||||
src.selected = equip
|
||||
src.occupant_message("You switch to [equip]")
|
||||
src.visible_message("[src] raises [equip]")
|
||||
send_byjax(src.occupant,"exosuit.browser","eq_list",src.get_equipment_list())
|
||||
|
||||
if(href_list["rmictoggle"])
|
||||
radio.broadcasting = !radio.broadcasting
|
||||
send_byjax(src.occupant,"exosuit.browser","rmicstate",(radio.broadcasting?"Engaged":"Disengaged"))
|
||||
|
||||
if(href_list["rspktoggle"])
|
||||
radio.listening = !radio.listening
|
||||
send_byjax(src.occupant,"exosuit.browser","rspkstate",(radio.listening?"Engaged":"Disengaged"))
|
||||
|
||||
if(href_list["rfreq"])
|
||||
var/new_frequency = (radio.frequency + filter.getNum("rfreq"))
|
||||
if (!radio.freerange || (radio.frequency < 1200 || radio.frequency > 1600))
|
||||
new_frequency = sanitize_frequency(new_frequency)
|
||||
radio.set_frequency(new_frequency)
|
||||
send_byjax(src.occupant,"exosuit.browser","rfreq","[format_frequency(radio.frequency)]")
|
||||
|
||||
if (href_list["view_log"])
|
||||
src.occupant << browse(src.get_log_html(), "window=exosuit_log")
|
||||
onclose(occupant, "exosuit_log")
|
||||
|
||||
if (href_list["change_name"])
|
||||
var/newname = stripped_input(occupant,"Choose new exosuit name","Rename exosuit","", MAX_NAME_LEN)
|
||||
if(newname && trim(newname))
|
||||
name = newname
|
||||
else
|
||||
alert(occupant, "nope.avi")
|
||||
|
||||
if (href_list["toggle_id_upload"])
|
||||
add_req_access = !add_req_access
|
||||
send_byjax(src.occupant,"exosuit.browser","t_id_upload","[add_req_access?"L":"Unl"]ock ID upload panel")
|
||||
|
||||
if(href_list["toggle_maint_access"])
|
||||
if(state)
|
||||
occupant_message("<span class='danger'>Maintenance protocols in effect</span>")
|
||||
return
|
||||
maint_access = !maint_access
|
||||
send_byjax(src.occupant,"exosuit.browser","t_maint_access","[maint_access?"Forbid":"Permit"] maintenance protocols")
|
||||
|
||||
if(href_list["dna_lock"])
|
||||
if(occupant && !iscarbon(occupant))
|
||||
occupant << "<span class='danger'> You do not have any DNA!</span>"
|
||||
return
|
||||
dna_lock = occupant.dna.unique_enzymes
|
||||
occupant_message("You feel a prick as the needle takes your DNA sample.")
|
||||
|
||||
if(href_list["reset_dna"])
|
||||
dna_lock = null
|
||||
|
||||
if(href_list["repair_int_control_lost"])
|
||||
occupant_message("Recalibrating coordination system...")
|
||||
log_message("Recalibration of coordination system started.")
|
||||
var/T = loc
|
||||
spawn(100)
|
||||
if(T == loc)
|
||||
clearInternalDamage(MECHA_INT_CONTROL_LOST)
|
||||
occupant_message("<span class='notice'>Recalibration successful.</span>")
|
||||
log_message("Recalibration of coordination system finished with 0 errors.")
|
||||
else
|
||||
occupant_message("<span class='warning'>Recalibration failed!</span>")
|
||||
log_message("Recalibration of coordination system failed with 1 error.",1)
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
///////////////////////////////////
|
||||
//////// Mecha wreckage ////////
|
||||
///////////////////////////////////
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage
|
||||
name = "exosuit wreckage"
|
||||
desc = "Remains of some unfortunate mecha. Completely unrepairable."
|
||||
icon = 'icons/mecha/mecha.dmi'
|
||||
density = 1
|
||||
anchored = 0
|
||||
opacity = 0
|
||||
var/list/welder_salvage = list(/obj/item/stack/sheet/plasteel,/obj/item/stack/sheet/metal,/obj/item/stack/rods)
|
||||
var/list/wirecutters_salvage = list(/obj/item/stack/cable_coil)
|
||||
var/list/crowbar_salvage = list()
|
||||
var/salvage_num = 5
|
||||
|
||||
/obj/structure/mecha_wreckage/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/weapon/weldingtool))
|
||||
if(salvage_num <= 0)
|
||||
user << "<span class='warning'>You don't see anything that can be cut with [I]!</span>"
|
||||
return
|
||||
var/obj/item/weapon/weldingtool/WT = I
|
||||
if(welder_salvage && welder_salvage.len && WT.remove_fuel(0, user))
|
||||
var/type = prob(70) ? pick(welder_salvage) : null
|
||||
if(type)
|
||||
var/N = new type(get_turf(user))
|
||||
user.visible_message("[user] cuts [N] from [src].", "<span class='notice'>You cut [N] from [src].</span>")
|
||||
if(istype(N, /obj/item/mecha_parts/part))
|
||||
welder_salvage -= type
|
||||
salvage_num--
|
||||
else
|
||||
user << "<span class='warning'>You fail to salvage anything valuable from [src]!</span>"
|
||||
else
|
||||
return
|
||||
|
||||
else if(istype(I, /obj/item/weapon/wirecutters))
|
||||
if(salvage_num <= 0)
|
||||
user << "<span class='warning'>You don't see anything that can be cut with [I]!</span>"
|
||||
return
|
||||
else if(wirecutters_salvage && wirecutters_salvage.len)
|
||||
var/type = prob(70) ? pick(wirecutters_salvage) : null
|
||||
if(type)
|
||||
var/N = new type(get_turf(user))
|
||||
user.visible_message("[user] cuts [N] from [src].", "<span class='notice'>You cut [N] from [src].</span>")
|
||||
salvage_num--
|
||||
else
|
||||
user << "<span class='warning'>You fail to salvage anything valuable from [src]!</span>"
|
||||
|
||||
else if(istype(I, /obj/item/weapon/crowbar))
|
||||
if(crowbar_salvage && crowbar_salvage.len)
|
||||
var/obj/S = pick(crowbar_salvage)
|
||||
if(S)
|
||||
S.loc = get_turf(user)
|
||||
crowbar_salvage -= S
|
||||
user.visible_message("[user] pries [S] from [src].", "<span class='notice'>You pry [S] from [src].</span>")
|
||||
return
|
||||
else
|
||||
user << "<span class='warning'>You don't see anything that can be pried with [I]!</span>"
|
||||
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage/gygax
|
||||
name = "\improper Gygax wreckage"
|
||||
icon_state = "gygax-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/gygax/New()
|
||||
..()
|
||||
var/list/parts = list(/obj/item/mecha_parts/part/gygax_torso,
|
||||
/obj/item/mecha_parts/part/gygax_head,
|
||||
/obj/item/mecha_parts/part/gygax_left_arm,
|
||||
/obj/item/mecha_parts/part/gygax_right_arm,
|
||||
/obj/item/mecha_parts/part/gygax_left_leg,
|
||||
/obj/item/mecha_parts/part/gygax_right_leg)
|
||||
for(var/i = 0; i < 2; i++)
|
||||
if(parts.len && prob(40))
|
||||
var/part = pick(parts)
|
||||
welder_salvage += part
|
||||
parts -= part
|
||||
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage/gygax/dark
|
||||
name = "\improper Dark Gygax wreckage"
|
||||
icon_state = "darkgygax-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/marauder
|
||||
name = "\improper Marauder wreckage"
|
||||
icon_state = "marauder-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/mauler
|
||||
name = "\improper Mauler wreckage"
|
||||
icon_state = "mauler-broken"
|
||||
desc = "The syndicate won't be very happy about this..."
|
||||
|
||||
/obj/structure/mecha_wreckage/seraph
|
||||
name = "\improper Seraph wreckage"
|
||||
icon_state = "seraph-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/reticence
|
||||
name = "\improper Reticence wreckage"
|
||||
icon_state = "reticence-broken"
|
||||
color = "#87878715"
|
||||
|
||||
/obj/structure/mecha_wreckage/ripley
|
||||
name = "\improper Ripley wreckage"
|
||||
icon_state = "ripley-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/ripley/New()
|
||||
..()
|
||||
var/list/parts = list(/obj/item/mecha_parts/part/ripley_torso,
|
||||
/obj/item/mecha_parts/part/ripley_left_arm,
|
||||
/obj/item/mecha_parts/part/ripley_right_arm,
|
||||
/obj/item/mecha_parts/part/ripley_left_leg,
|
||||
/obj/item/mecha_parts/part/ripley_right_leg)
|
||||
for(var/i = 0; i < 2; i++)
|
||||
if(parts.len && prob(40))
|
||||
var/part = pick(parts)
|
||||
welder_salvage += part
|
||||
parts -= part
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage/ripley/firefighter
|
||||
name = "\improper Firefighter wreckage"
|
||||
icon_state = "firefighter-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/ripley/firefighter/New()
|
||||
..()
|
||||
var/list/parts = list(/obj/item/mecha_parts/part/ripley_torso,
|
||||
/obj/item/mecha_parts/part/ripley_left_arm,
|
||||
/obj/item/mecha_parts/part/ripley_right_arm,
|
||||
/obj/item/mecha_parts/part/ripley_left_leg,
|
||||
/obj/item/mecha_parts/part/ripley_right_leg,
|
||||
/obj/item/clothing/suit/fire)
|
||||
for(var/i = 0; i < 2; i++)
|
||||
if(parts.len && prob(40))
|
||||
var/part = pick(parts)
|
||||
welder_salvage += part
|
||||
parts -= part
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage/ripley/deathripley
|
||||
name = "\improper Death-Ripley wreckage"
|
||||
icon_state = "deathripley-broken"
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage/honker
|
||||
name = "\improper H.O.N.K wreckage"
|
||||
icon_state = "honker-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/honker/New()
|
||||
..()
|
||||
var/list/parts = list(
|
||||
/obj/item/mecha_parts/chassis/honker,
|
||||
/obj/item/mecha_parts/part/honker_torso,
|
||||
/obj/item/mecha_parts/part/honker_head,
|
||||
/obj/item/mecha_parts/part/honker_left_arm,
|
||||
/obj/item/mecha_parts/part/honker_right_arm,
|
||||
/obj/item/mecha_parts/part/honker_left_leg,
|
||||
/obj/item/mecha_parts/part/honker_right_leg)
|
||||
for(var/i = 0; i < 2; i++)
|
||||
if(parts.len && prob(40))
|
||||
var/part = pick(parts)
|
||||
welder_salvage += part
|
||||
parts -= part
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage/durand
|
||||
name = "\improper Durand wreckage"
|
||||
icon_state = "durand-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/durand/New()
|
||||
..()
|
||||
var/list/parts = list(
|
||||
/obj/item/mecha_parts/part/durand_torso,
|
||||
/obj/item/mecha_parts/part/durand_head,
|
||||
/obj/item/mecha_parts/part/durand_left_arm,
|
||||
/obj/item/mecha_parts/part/durand_right_arm,
|
||||
/obj/item/mecha_parts/part/durand_left_leg,
|
||||
/obj/item/mecha_parts/part/durand_right_leg)
|
||||
for(var/i = 0; i < 2; i++)
|
||||
if(parts.len && prob(40))
|
||||
var/part = pick(parts)
|
||||
welder_salvage += part
|
||||
parts -= part
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage/phazon
|
||||
name = "\improper Phazon wreckage"
|
||||
icon_state = "phazon-broken"
|
||||
|
||||
|
||||
/obj/structure/mecha_wreckage/odysseus
|
||||
name = "\improper Odysseus wreckage"
|
||||
icon_state = "odysseus-broken"
|
||||
|
||||
/obj/structure/mecha_wreckage/odysseus/New()
|
||||
..()
|
||||
var/list/parts = list(
|
||||
/obj/item/mecha_parts/part/odysseus_torso,
|
||||
/obj/item/mecha_parts/part/odysseus_head,
|
||||
/obj/item/mecha_parts/part/odysseus_left_arm,
|
||||
/obj/item/mecha_parts/part/odysseus_right_arm,
|
||||
/obj/item/mecha_parts/part/odysseus_left_leg,
|
||||
/obj/item/mecha_parts/part/odysseus_right_leg)
|
||||
for(var/i = 0; i < 2; i++)
|
||||
if(parts.len && prob(40))
|
||||
var/part = pick(parts)
|
||||
welder_salvage += part
|
||||
parts -= part
|
||||
@@ -0,0 +1,22 @@
|
||||
/obj/mecha/medical/New()
|
||||
..()
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
return
|
||||
|
||||
|
||||
/obj/mecha/medical/mechturn(direction)
|
||||
setDir(direction)
|
||||
playsound(src,'sound/mecha/mechmove01.ogg',40,1)
|
||||
return 1
|
||||
|
||||
/obj/mecha/medical/mechstep(direction)
|
||||
var/result = step(src,direction)
|
||||
if(result)
|
||||
playsound(src,'sound/mecha/mechstep.ogg',25,1)
|
||||
return result
|
||||
|
||||
/obj/mecha/medical/mechsteprand()
|
||||
var/result = step_rand(src)
|
||||
if(result)
|
||||
playsound(src,'sound/mecha/mechstep.ogg',25,1)
|
||||
return result
|
||||
@@ -0,0 +1,33 @@
|
||||
/obj/mecha/medical/odysseus
|
||||
desc = "These exosuits are developed and produced by Vey-Med. (© All rights reserved)."
|
||||
name = "\improper Odysseus"
|
||||
icon_state = "odysseus"
|
||||
step_in = 3
|
||||
max_temperature = 15000
|
||||
health = 120
|
||||
wreckage = /obj/structure/mecha_wreckage/odysseus
|
||||
internal_damage_threshold = 35
|
||||
deflect_chance = 15
|
||||
step_energy_drain = 6
|
||||
var/builtin_hud_user = 0
|
||||
|
||||
/obj/mecha/medical/odysseus/moved_inside(mob/living/carbon/human/H)
|
||||
if(..())
|
||||
if(H.glasses && istype(H.glasses, /obj/item/clothing/glasses/hud))
|
||||
occupant_message("<span class='warning'>Your [H.glasses] prevent you from using the built-in medical hud.</span>")
|
||||
else
|
||||
var/datum/atom_hud/data/human/medical/advanced/A = huds[DATA_HUD_MEDICAL_ADVANCED]
|
||||
A.add_hud_to(H)
|
||||
builtin_hud_user = 1
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/mecha/medical/odysseus/go_out()
|
||||
if(ishuman(occupant) && builtin_hud_user)
|
||||
var/mob/living/carbon/human/H = occupant
|
||||
var/datum/atom_hud/data/human/medical/advanced/A = huds[DATA_HUD_MEDICAL_ADVANCED]
|
||||
A.remove_hud_from(H)
|
||||
..()
|
||||
return
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
/obj/mecha/working/ripley
|
||||
desc = "Autonomous Power Loader Unit. This newer model is refitted with powerful armour against the dangers of the EVA mining process."
|
||||
name = "\improper APLU \"Ripley\""
|
||||
icon_state = "ripley"
|
||||
step_in = 5
|
||||
max_temperature = 20000
|
||||
health = 200
|
||||
lights_power = 7
|
||||
deflect_chance = 15
|
||||
damage_absorption = list("brute"=0.6,"fire"=1,"bullet"=0.8,"laser"=0.9,"energy"=1,"bomb"=0.6)
|
||||
max_equip = 6
|
||||
wreckage = /obj/structure/mecha_wreckage/ripley
|
||||
var/list/cargo = new
|
||||
var/cargo_capacity = 15
|
||||
var/hides = 0
|
||||
|
||||
/obj/mecha/working/ripley/Move()
|
||||
. = ..()
|
||||
if(. && (locate(/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp) in equipment))
|
||||
var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in cargo
|
||||
if(ore_box)
|
||||
for(var/obj/item/weapon/ore/ore in get_turf(src))
|
||||
ore.Move(ore_box)
|
||||
update_pressure()
|
||||
|
||||
/obj/mecha/working/ripley/Destroy()
|
||||
for(var/i=1, i <= hides, i++)
|
||||
new /obj/item/stack/sheet/animalhide/goliath_hide(loc) //If a goliath-plated ripley gets killed, all the plates drop
|
||||
damage_absorption["brute"] = initial(damage_absorption["brute"])
|
||||
for(var/atom/movable/A in cargo)
|
||||
A.loc = loc
|
||||
step_rand(A)
|
||||
cargo.Cut()
|
||||
return ..()
|
||||
|
||||
/obj/mecha/working/ripley/go_out()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/mecha/working/ripley/moved_inside(mob/living/carbon/human/H)
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/mecha/working/ripley/mmi_moved_inside(obj/item/device/mmi/mmi_as_oc,mob/user)
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/mecha/working/ripley/update_icon()
|
||||
..()
|
||||
if (hides)
|
||||
overlays = null
|
||||
if(hides < 3)
|
||||
add_overlay(image("icon" = "mecha.dmi", "icon_state" = occupant ? "ripley-g" : "ripley-g-open"))
|
||||
else
|
||||
add_overlay(image("icon" = "mecha.dmi", "icon_state" = occupant ? "ripley-g-full" : "ripley-g-full-open"))
|
||||
|
||||
|
||||
/obj/mecha/working/ripley/firefighter
|
||||
desc = "Autonomous Power Loader Unit. This model is refitted with additional thermal protection."
|
||||
name = "\improper APLU \"Firefighter\""
|
||||
icon_state = "firefighter"
|
||||
max_temperature = 65000
|
||||
health = 250
|
||||
burn_state = LAVA_PROOF
|
||||
lights_power = 7
|
||||
damage_absorption = list("brute"=0.6,"fire"=0.5,"bullet"=0.7,"laser"=0.7,"energy"=1,"bomb"=0.4)
|
||||
max_equip = 5 // More armor, less tools
|
||||
wreckage = /obj/structure/mecha_wreckage/ripley/firefighter
|
||||
|
||||
|
||||
/obj/mecha/working/ripley/deathripley
|
||||
desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE"
|
||||
name = "\improper DEATH-RIPLEY"
|
||||
icon_state = "deathripley"
|
||||
step_in = 3
|
||||
opacity=0
|
||||
lights_power = 7
|
||||
wreckage = /obj/structure/mecha_wreckage/ripley/deathripley
|
||||
step_energy_drain = 0
|
||||
|
||||
/obj/mecha/working/ripley/deathripley/New()
|
||||
..()
|
||||
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/kill
|
||||
ME.attach(src)
|
||||
return
|
||||
|
||||
/obj/mecha/working/ripley/mining
|
||||
desc = "An old, dusty mining Ripley."
|
||||
name = "\improper APLU \"Miner\""
|
||||
|
||||
/obj/mecha/working/ripley/mining/New()
|
||||
..()
|
||||
//Attach drill
|
||||
if(prob(25)) //Possible diamond drill... Feeling lucky?
|
||||
var/obj/item/mecha_parts/mecha_equipment/drill/diamonddrill/D = new /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill
|
||||
D.attach(src)
|
||||
else
|
||||
var/obj/item/mecha_parts/mecha_equipment/drill/D = new /obj/item/mecha_parts/mecha_equipment/drill
|
||||
D.attach(src)
|
||||
|
||||
//Add possible plasma cutter
|
||||
if(prob(25))
|
||||
var/obj/item/mecha_parts/mecha_equipment/M = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/plasma
|
||||
M.attach(src)
|
||||
|
||||
//Add ore box to cargo
|
||||
cargo.Add(new /obj/structure/ore_box(src))
|
||||
|
||||
//Attach hydraulic clamp
|
||||
var/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/HC = new /obj/item/mecha_parts/mecha_equipment/hydraulic_clamp
|
||||
HC.attach(src)
|
||||
for(var/obj/item/mecha_parts/mecha_tracking/B in src.contents)//Deletes the beacon so it can't be found easily
|
||||
qdel(B)
|
||||
|
||||
var/obj/item/mecha_parts/mecha_equipment/mining_scanner/scanner = new /obj/item/mecha_parts/mecha_equipment/mining_scanner
|
||||
scanner.attach(src)
|
||||
|
||||
/obj/mecha/working/ripley/Exit(atom/movable/O)
|
||||
if(O in cargo)
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/obj/mecha/working/ripley/Topic(href, href_list)
|
||||
..()
|
||||
if(href_list["drop_from_cargo"])
|
||||
var/obj/O = locate(href_list["drop_from_cargo"])
|
||||
if(O && O in src.cargo)
|
||||
src.occupant_message("<span class='notice'>You unload [O].</span>")
|
||||
O.loc = loc
|
||||
src.cargo -= O
|
||||
src.log_message("Unloaded [O]. Cargo compartment capacity: [cargo_capacity - src.cargo.len]")
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/mecha/working/ripley/get_stats_part()
|
||||
var/output = ..()
|
||||
output += "<b>Cargo Compartment Contents:</b><div style=\"margin-left: 15px;\">"
|
||||
if(cargo.len)
|
||||
for(var/obj/O in cargo)
|
||||
output += "<a href='?src=\ref[src];drop_from_cargo=\ref[O]'>Unload</a> : [O]<br>"
|
||||
else
|
||||
output += "Nothing"
|
||||
output += "</div>"
|
||||
return output
|
||||
|
||||
/obj/mecha/working/ripley/proc/update_pressure()
|
||||
var/turf/T = get_turf(loc)
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
var/pressure = environment.return_pressure()
|
||||
|
||||
if(pressure < 40)
|
||||
step_in = 3
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/drill/drill in equipment)
|
||||
drill.equip_cooldown = initial(drill.equip_cooldown)/2
|
||||
else
|
||||
step_in = 5
|
||||
for(var/obj/item/mecha_parts/mecha_equipment/drill/drill in equipment)
|
||||
drill.equip_cooldown = initial(drill.equip_cooldown)
|
||||
|
||||
/obj/mecha/working/ripley/relay_container_resist(mob/living/user, obj/O)
|
||||
user << "<span class='notice'>You lean on the back of [O] and start pushing so it falls out of [src].</span>"
|
||||
if(do_after(user, 300, target = O))
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || O.loc != src )
|
||||
return
|
||||
user << "<span class='notice'>You successfully pushed [O] out of [src]!</span>"
|
||||
O.loc = loc
|
||||
cargo -= O
|
||||
else
|
||||
if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded.
|
||||
user << "<span class='warning'>You fail to push [O] out of [src]!</span>"
|
||||
@@ -0,0 +1,7 @@
|
||||
/obj/mecha/working
|
||||
internal_damage_threshold = 60
|
||||
|
||||
/obj/mecha/working/New()
|
||||
..()
|
||||
new /obj/item/mecha_parts/mecha_tracking(src)
|
||||
return
|
||||
Reference in New Issue
Block a user