initial commit - cross reference with 5th port - obviously has compile errors

This commit is contained in:
LetterJay
2016-07-03 02:17:19 -05:00
commit 35a1723e98
4355 changed files with 2221257 additions and 0 deletions
+38
View File
@@ -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)
..()
+22
View File
@@ -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)
+68
View File
@@ -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)
+156
View File
@@ -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]&deg;K|[tank_temperature - T0C]&deg;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()]&deg;K|[return_temperature() - T0C]&deg;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
+90
View File
@@ -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)
+30
View File
@@ -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)
+27
View File
@@ -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>&nbsp;"
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]&deg;C ([patient.bodytemperature*1.8-459.67]&deg;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>&nbsp; [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>&nbsp; [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
+151
View File
@@ -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()
+466
View File
@@ -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&sup3;"
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'>&uarr;</a>":null] "
output += "[i<queue.len?"<a href='?src=\ref[src];queue_move=+1;index=[i]' class='arrow'>&darr;</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
+281
View File
@@ -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
+124
View File
@@ -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)
+336
View File
@@ -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
+402
View File
@@ -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)"
+331
View File
@@ -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]&deg;K|[tank_temperature - T0C]&deg;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()]&deg;K|[return_temperature() - T0C]&deg;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)
+212
View File
@@ -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
+22
View File
@@ -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
+33
View File
@@ -0,0 +1,33 @@
/obj/mecha/medical/odysseus
desc = "These exosuits are developed and produced by Vey-Med. (&copy; 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
+171
View File
@@ -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>"
+7
View File
@@ -0,0 +1,7 @@
/obj/mecha/working
internal_damage_threshold = 60
/obj/mecha/working/New()
..()
new /obj/item/mecha_parts/mecha_tracking(src)
return