diff --git a/code/__defines/objects.dm b/code/__defines/objects.dm index 3d2891a3c5..d6530fecff 100644 --- a/code/__defines/objects.dm +++ b/code/__defines/objects.dm @@ -40,4 +40,12 @@ #define CATALOGUER_REWARD_SUPERHARD 2560 // Very difficult and dangerous, such as scanning the Advanced Dark Gygax. // 5 10 20 40 80 160 -// 10 40 160 640 2560 \ No newline at end of file +// 10 40 160 640 2560 + +// Defines for Exosuit components. + +#define MECH_HULL "Hull" +#define MECH_ACTUATOR "Actuator" +#define MECH_ARMOR "Plating" +#define MECH_GAS "Life Support" +#define MECH_ELECTRIC "Firmware" diff --git a/code/datums/autolathe/arms.dm b/code/datums/autolathe/arms.dm index e170d8c885..53a2f14fac 100644 --- a/code/datums/autolathe/arms.dm +++ b/code/datums/autolathe/arms.dm @@ -33,6 +33,12 @@ path =/obj/item/ammo_casing/a12g/stunshell hidden = 1 +/datum/category_item/autolathe/arms/flechetteshell + name = "ammunition (flechette cartridge, shotgun)" + path =/obj/item/ammo_casing/a12g/flechette + hidden = 1 + man_rating = 2 + ////////////////// /*Ammo magazines*/ ////////////////// @@ -64,6 +70,18 @@ name = "pistol magazine (.45 flash)" path =/obj/item/ammo_magazine/m45/flash +/datum/category_item/autolathe/arms/pistol_45ap + name = "pistol magazine (.45 armor piercing)" + path =/obj/item/ammo_magazine/m45/ap + hidden = 1 + resources = list(DEFAULT_WALL_MATERIAL = 500, MAT_PLASTEEL = 300) + +/datum/category_item/autolathe/arms/pistol_45hp + name = "pistol magazine (.45 hollowpoint)" + path =/obj/item/ammo_magazine/m45/hp + hidden = 1 + resources = list(DEFAULT_WALL_MATERIAL = 500, MAT_PLASTIC = 200) + /datum/category_item/autolathe/arms/pistol_45uzi name = "uzi magazine (.45)" path =/obj/item/ammo_magazine/m45uzi @@ -138,6 +156,12 @@ name = "top-mounted SMG magazine (9mm flash)" path =/obj/item/ammo_magazine/m9mmt/flash +/datum/category_item/autolathe/arms/smg_9mmap + name = "top-mounted SMG magazine (9mm armor piercing)" + path =/obj/item/ammo_magazine/m9mmt/ap + hidden = 1 + man_rating = 2 + /////// 10mm /datum/category_item/autolathe/arms/smg_10mm name = "SMG magazine (10mm)" diff --git a/code/datums/autolathe/autolathe.dm b/code/datums/autolathe/autolathe.dm index 91c9ec37b7..003212fe75 100644 --- a/code/datums/autolathe/autolathe.dm +++ b/code/datums/autolathe/autolathe.dm @@ -71,6 +71,7 @@ var/datum/category_collection/autolathe/autolathe_recipes var/is_stack // Creates multiple of an item if applied to non-stack items var/max_stack var/no_scale + var/man_rating = 0 /datum/category_item/autolathe/dd_SortValue() return name \ No newline at end of file diff --git a/code/datums/autolathe/general.dm b/code/datums/autolathe/general.dm index 891e73fb6b..5ad54b68bf 100644 --- a/code/datums/autolathe/general.dm +++ b/code/datums/autolathe/general.dm @@ -98,6 +98,18 @@ is_stack = TRUE no_scale = TRUE //prevents material duplication exploits +/datum/category_item/autolathe/general/plasteel + name = "plasteel sheets" + path =/obj/item/stack/material/plasteel + is_stack = TRUE + no_scale = TRUE //prevents material duplication exploits + +/datum/category_item/autolathe/general/plastic + name = "plastic sheets" + path =/obj/item/stack/material/plastic + is_stack = TRUE + no_scale = TRUE //prevents material duplication exploits + //TFF 24/12/19 - Let people print more spray bottles if needed. /datum/category_item/autolathe/general/spraybottle name = "spray bottle" @@ -133,6 +145,19 @@ name = "maglight" path =/obj/item/device/flashlight/maglight +<<<<<<< HEAD +======= +/datum/category_item/autolathe/general/ecigcartridge + name = "ecigarette cartridge" + path = /obj/item/weapon/reagent_containers/ecig_cartridge/blank + +/datum/category_item/autolathe/general/idcard + name = "ID Card" + path = /obj/item/weapon/card/id + resources = list(DEFAULT_WALL_MATERIAL = 100, MAT_GLASS = 100, MAT_PLASTIC = 300) + man_rating = 2 + +>>>>>>> 282b42d... Exosuit Modular Internals, The Squeakening (#7329) /datum/category_item/autolathe/general/handcuffs name = "handcuffs" path =/obj/item/weapon/handcuffs diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 1629b77bdd..3e1188198b 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -12,8 +12,8 @@ circuit = /obj/item/weapon/circuitboard/autolathe var/datum/category_collection/autolathe/machine_recipes - var/list/stored_material = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0) - var/list/storage_capacity = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0) + var/list/stored_material = list(DEFAULT_WALL_MATERIAL = 0, MAT_GLASS = 0, MAT_PLASTEEL = 0, MAT_PLASTIC = 0) + var/list/storage_capacity = list(DEFAULT_WALL_MATERIAL = 0, MAT_GLASS = 0, MAT_PLASTEEL = 0, MAT_PLASTIC = 0) var/datum/category_group/autolathe/current_category var/hacked = 0 @@ -26,6 +26,9 @@ var/datum/wires/autolathe/wires = null + var/mb_rating = 0 + var/man_rating = 0 + var/filtertext /obj/machinery/autolathe/Initialize() @@ -64,6 +67,9 @@ var/list/material_bottom = list("") for(var/material in stored_material) + if(material != DEFAULT_WALL_MATERIAL && material != MAT_GLASS) // Don't show the Extras unless people care enough to put them in. + if(stored_material[material] <= 0) + continue material_top += "[material]" material_bottom += "[stored_material[material]]/[storage_capacity[material]]" @@ -72,7 +78,9 @@ dat += "

Printable Designs

Showing: [current_category].

" for(var/datum/category_item/autolathe/R in current_category.items) - if(R.hidden && !hacked) + if(R.hidden && !hacked) // Illegal or nonstandard. + continue + if(R.man_rating > man_rating) // Advanced parts. continue if(filtertext && findtext(R.name, filtertext) == 0) continue @@ -311,14 +319,16 @@ //Updates overall lathe storage size. /obj/machinery/autolathe/RefreshParts() ..() - var/mb_rating = 0 - var/man_rating = 0 + mb_rating = 0 + man_rating = 0 for(var/obj/item/weapon/stock_parts/matter_bin/MB in component_parts) mb_rating += MB.rating for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) man_rating += M.rating storage_capacity[DEFAULT_WALL_MATERIAL] = mb_rating * 25000 + storage_capacity[MAT_PLASTIC] = mb_rating * 20000 + storage_capacity[MAT_PLASTEEL] = mb_rating * 16250 storage_capacity["glass"] = mb_rating * 12500 build_time = 50 / man_rating mat_efficiency = 1.1 - man_rating * 0.1// Normally, price is 1.25 the amount of material, so this shouldn't go higher than 0.6. Maximum rating of parts is 5 diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm index b5d3351b21..d618d276c3 100644 --- a/code/game/mecha/combat/combat.dm +++ b/code/game/mecha/combat/combat.dm @@ -17,6 +17,14 @@ max_special_equip = 1 cargo_capacity = 1 + starting_components = list( + /obj/item/mecha_parts/component/hull/durable, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor/reinforced, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + /* /obj/mecha/combat/range_action(target as obj|mob|turf) if(internal_damage&MECHA_INT_CONTROL_LOST) diff --git a/code/game/mecha/combat/durand.dm b/code/game/mecha/combat/durand.dm index 5ab43a93ee..aa5a9e000c 100644 --- a/code/game/mecha/combat/durand.dm +++ b/code/game/mecha/combat/durand.dm @@ -5,8 +5,8 @@ initial_icon = "durand" step_in = 4 dir_in = 1 //Facing North. - health = 400 - maxhealth = 400 //Don't forget to update the /old variant if you change this number. + health = 300 + maxhealth = 300 //Don't forget to update the /old variant if you change this number. 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 @@ -23,6 +23,14 @@ max_universal_equip = 1 max_special_equip = 1 + starting_components = list( + /obj/item/mecha_parts/component/hull/durable, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor/military, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + defence_mode_possible = 1 /* @@ -73,5 +81,5 @@ /obj/mecha/combat/durand/old/New() ..() health = 25 - maxhealth = 350 //Just slightly worse. + maxhealth = 250 //Just slightly worse. cell.charge = rand(0, (cell.charge/2)) \ No newline at end of file diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index d74b96cf99..0323124c47 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -5,8 +5,8 @@ initial_icon = "gygax" step_in = 3 dir_in = 1 //Facing North. - health = 300 - maxhealth = 300 //Don't forget to update the /old variant if you change this number. + health = 250 + maxhealth = 250 //Don't forget to update the /old variant if you change this number. deflect_chance = 15 damage_absorption = list("brute"=0.75,"fire"=1,"bullet"=0.8,"laser"=0.7,"energy"=0.85,"bomb"=1) max_temperature = 25000 @@ -21,6 +21,14 @@ max_universal_equip = 1 max_special_equip = 1 + starting_components = list( + /obj/item/mecha_parts/component/hull/lightweight, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor/marshal, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + overload_possible = 1 //Not quite sure how to move those yet. @@ -58,17 +66,12 @@ max_universal_equip = 1 max_special_equip = 2 -/obj/mecha/combat/gygax/dark/Initialize() - ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/clusterbang - 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 + starting_equipment = list( + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot, + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/grenade/clusterbang, + /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay, + /obj/item/mecha_parts/mecha_equipment/teleporter + ) /obj/mecha/combat/gygax/dark/add_cell(var/obj/item/weapon/cell/C=null) if(C) @@ -101,6 +104,14 @@ max_universal_equip = 1 max_special_equip = 1 + starting_components = list( + /obj/item/mecha_parts/component/hull, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor/lightweight, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + var/obj/item/clothing/glasses/hud/health/mech/hud /obj/mecha/combat/gygax/serenity/New() diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm index a79dc3fda2..e2c0b9467a 100644 --- a/code/game/mecha/combat/marauder.dm +++ b/code/game/mecha/combat/marauder.dm @@ -5,8 +5,8 @@ icon_state = "marauder" initial_icon = "marauder" step_in = 5 - health = 500 - maxhealth = 500 //Don't forget to update the /old variant if you change this number. + health = 350 + maxhealth = 350 //Don't forget to update the /old variant if you change this number. 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 @@ -29,6 +29,21 @@ zoom_possible = 1 thrusters_possible = 1 + starting_components = list( + /obj/item/mecha_parts/component/hull/durable, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor/military, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + + starting_equipment = list( + /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse, + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive, + /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay, + /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster + ) + /obj/mecha/combat/marauder/seraph desc = "Heavy-duty, command-type exosuit. This is a custom model, utilized only by high-ranking military personnel." name = "Seraph" @@ -37,12 +52,20 @@ initial_icon = "seraph" operation_req_access = list(access_cent_creed) step_in = 3 - health = 550 + health = 450 wreckage = /obj/effect/decal/mecha_wreckage/seraph internal_damage_threshold = 20 force = 55 max_equip = 5 + starting_equipment = list( + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot, + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive, + /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay, + /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster, + /obj/item/mecha_parts/mecha_equipment/teleporter + ) + //Note that is the Mauler /obj/mecha/combat/marauder/mauler desc = "Heavy-duty, combat exosuit, developed off of the existing Marauder model." @@ -53,40 +76,6 @@ wreckage = /obj/effect/decal/mecha_wreckage/mauler mech_faction = MECH_FACTION_SYNDI -//Note that is the default Marauder -/obj/mecha/combat/marauder/Initialize() - ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/energy/pulse - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/explosive - 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) - return - -//Note that this is the seraph. -/obj/mecha/combat/marauder/seraph/Initialize() - ..()//Let it equip whatever is needed. - var/obj/item/mecha_parts/mecha_equipment/ME - if(equipment.len)//Now to remove it and equip anew. - for(ME in equipment) - ME.detach() - qdel(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/missile_rack/explosive(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) - return - - //I'll break this down later /obj/mecha/combat/marauder/relaymove(mob/user,direction) if(user != src.occupant) //While not "realistic", this piece is player friendly. @@ -150,17 +139,10 @@ /obj/mecha/combat/marauder/old desc = "Heavy-duty, combat exosuit, developed after the Durand model. Rarely found among civilian populations. This one is particularly worn looking and likely isn't as sturdy." + starting_equipment = null + /obj/mecha/combat/marauder/old/New() ..() health = 25 - maxhealth = 400 //Just slightly worse. + maxhealth = 300 //Just slightly worse. cell.charge = rand(0, (cell.charge/2)) - -/obj/mecha/combat/marauder/old/Initialize() - ..() - var/obj/item/mecha_parts/mecha_equipment/ME - if(equipment.len) - for(ME in equipment) - ME.detach() - qdel(ME) - return \ No newline at end of file diff --git a/code/game/mecha/combat/phazon.dm b/code/game/mecha/combat/phazon.dm index 121bab34f9..17aea92345 100644 --- a/code/game/mecha/combat/phazon.dm +++ b/code/game/mecha/combat/phazon.dm @@ -25,15 +25,24 @@ max_universal_equip = 3 max_special_equip = 4 - phasing_possible = 1 - switch_dmg_type_possible = 1 + starting_components = list( + /obj/item/mecha_parts/component/hull/durable, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor/alien, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + + cloak_possible = TRUE + phasing_possible = TRUE + switch_dmg_type_possible = TRUE /obj/mecha/combat/phazon/equipped/Initialize() ..() - var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tool/rcd - ME.attach(src) - ME = new /obj/item/mecha_parts/mecha_equipment/gravcatapult - ME.attach(src) + starting_equipment = list( + /obj/item/mecha_parts/mecha_equipment/tool/rcd, + /obj/item/mecha_parts/mecha_equipment/gravcatapult + ) return /* Leaving this until we are really sure we don't need it for reference. @@ -95,8 +104,9 @@ max_universal_equip = 2 max_special_equip = 2 - phasing_possible = 1 - switch_dmg_type_possible = 1 + phasing_possible = TRUE + switch_dmg_type_possible = TRUE + cloak_possible = FALSE /obj/mecha/combat/phazon/janus/take_damage(amount, type="brute") ..() diff --git a/code/game/mecha/components/_component.dm b/code/game/mecha/components/_component.dm new file mode 100644 index 0000000000..aadf390c61 --- /dev/null +++ b/code/game/mecha/components/_component.dm @@ -0,0 +1,155 @@ + +/obj/item/mecha_parts/component + name = "mecha component" + icon = 'icons/mecha/mech_component.dmi' + icon_state = "component" + w_class = ITEMSIZE_HUGE + origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + + var/component_type = null + + var/obj/mecha/chassis = null + var/start_damaged = FALSE + + var/emp_resistance = 0 // Amount of emp 'levels' removed. + + var/list/required_type = null // List, if it exists. Exosuits meant to use the component (Unique var changes / effects) + + var/integrity + var/integrity_danger_mod = 0.5 // Multiplier for comparison to max_integrity before problems start. + var/max_integrity = 100 + + var/step_delay = 0 + + var/relative_size = 30 // Percent chance for the component to be hit. + + var/internal_damage_flag // If set, the component will toggle the flag on or off if it is destroyed / severely damaged. + +/obj/item/mecha_parts/component/examine(mob/user) + . = ..() + var/show_integrity = round(integrity/max_integrity*100, 0.1) + switch(show_integrity) + if(85 to 100) + . += "It's fully intact." + if(65 to 85) + . += "It's slightly damaged." + if(45 to 65) + . += "It's badly damaged." + if(25 to 45) + . += "It's heavily damaged." + if(2 to 25) + . += "It's falling apart." + if(0 to 1) + . += "It is completely destroyed." + +/obj/item/mecha_parts/component/Initialize() + ..() + integrity = max_integrity + + if(start_damaged) + integrity = round(integrity * integrity_danger_mod) + +/obj/item/mecha_parts/component/Destroy() + detach() + return ..() + +// Damage code. + +/obj/item/mecha_parts/component/emp_act(var/severity = 4) + if(severity + emp_resistance > 4) + return + + severity = clamp(severity + emp_resistance, 1, 4) + + take_damage((4 - severity) * round(integrity * 0.1, 0.1)) + +/obj/item/mecha_parts/component/proc/adjust_integrity(var/amt = 0) + integrity = clamp(integrity + amt, 0, max_integrity) + return + +/obj/item/mecha_parts/component/proc/damage_part(var/dam_amt = 0, var/type = BRUTE) + if(dam_amt <= 0) + return FALSE + + adjust_integrity(-1 * dam_amt) + + if(chassis && internal_damage_flag) + if(get_efficiency() < 0.5) + chassis.check_for_internal_damage(list(internal_damage_flag), TRUE) + + return TRUE + +/obj/item/mecha_parts/component/proc/get_efficiency() + var/integ_limit = round(max_integrity * integrity_danger_mod) + + if(integrity < integ_limit) + var/int_percent = round(integrity / integ_limit, 0.1) + + return int_percent + + return 1 + +// Attach/Detach code. + +/obj/item/mecha_parts/component/proc/attach(var/obj/mecha/target, var/mob/living/user) + if(target) + if(!(component_type in target.internal_components)) + if(user) + to_chat(user, "\The [target] doesn't seem to have anywhere to put \the [src].") + return FALSE + if(target.internal_components[component_type]) + if(user) + to_chat(user, "\The [target] already has a [component_type] installed!") + return FALSE + chassis = target + if(user) + user.drop_from_inventory(src) + forceMove(target) + + if(internal_damage_flag) + if(integrity > (max_integrity * integrity_danger_mod)) + if(chassis.hasInternalDamage(internal_damage_flag)) + chassis.clearInternalDamage(internal_damage_flag) + + else + chassis.check_for_internal_damage(list(internal_damage_flag)) + + chassis.internal_components[component_type] = src + + if(user) + chassis.visible_message("[user] installs \the [src] in \the [chassis].") + return TRUE + return FALSE + +/obj/item/mecha_parts/component/proc/detach() + if(chassis) + chassis.internal_components[component_type] = null + + if(internal_damage_flag && chassis.hasInternalDamage(internal_damage_flag)) // If the module has been removed, it's kind of unfair to keep it causing problems by being damaged. It's nonfunctional either way. + chassis.clearInternalDamage(internal_damage_flag) + + forceMove(get_turf(chassis)) + chassis = null + return TRUE + + +/obj/item/mecha_parts/component/attackby(obj/item/weapon/W as obj, mob/user as mob) + if(istype(W,/obj/item/stack/nanopaste)) + var/obj/item/stack/nanopaste/NP = W + + if(integrity < max_integrity) + while(integrity < max_integrity && NP) + if(do_after(user, 1 SECOND, src) && NP.use(1)) + adjust_integrity(10) + + return + + return ..() + +// Various procs to handle different calls by Exosuits. IE, movement actions, damage actions, etc. + +/obj/item/mecha_parts/component/proc/get_step_delay() + return step_delay + +/obj/item/mecha_parts/component/proc/handle_move() + return diff --git a/code/game/mecha/components/actuators.dm b/code/game/mecha/components/actuators.dm new file mode 100644 index 0000000000..d814518629 --- /dev/null +++ b/code/game/mecha/components/actuators.dm @@ -0,0 +1,37 @@ + +/obj/item/mecha_parts/component/actuator + name = "mecha actuator" + icon = 'icons/mecha/mech_component.dmi' + icon_state = "motor" + w_class = ITEMSIZE_HUGE + origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + + component_type = MECH_ACTUATOR + + start_damaged = FALSE + + emp_resistance = 1 + + required_type = null // List, if it exists. Exosuits meant to use the component. + + integrity_danger_mod = 0.6 // Multiplier for comparison to max_integrity before problems start. + max_integrity = 50 + + internal_damage_flag = MECHA_INT_CONTROL_LOST + + var/strafing_multiplier = 1.5 + +/obj/item/mecha_parts/component/actuator/get_step_delay() + return step_delay + +/obj/item/mecha_parts/component/actuator/hispeed + name = "overclocked mecha actuator" + + step_delay = -1 + + emp_resistance = -1 + + integrity_danger_mod = 0.7 + max_integrity = 60 + + strafing_multiplier = 1.2 diff --git a/code/game/mecha/components/armor.dm b/code/game/mecha/components/armor.dm new file mode 100644 index 0000000000..b64c37bca5 --- /dev/null +++ b/code/game/mecha/components/armor.dm @@ -0,0 +1,238 @@ + +/obj/item/mecha_parts/component/armor + name = "mecha plating" + icon = 'icons/mecha/mech_component.dmi' + icon_state = "armor" + w_class = ITEMSIZE_HUGE + origin_tech = list(TECH_DATA = 1, TECH_ENGINEERING = 2) + + component_type = MECH_ARMOR + + start_damaged = FALSE + + emp_resistance = 4 + + required_type = null // List, if it exists. Exosuits meant to use the component. + + integrity_danger_mod = 0.4 // Multiplier for comparison to max_integrity before problems start. + max_integrity = 120 + + internal_damage_flag = MECHA_INT_TEMP_CONTROL + + step_delay = 1 + + var/deflect_chance = 10 + var/list/damage_absorption = list( + "brute"= 0.8, + "fire"= 1.2, + "bullet"= 0.9, + "laser"= 1, + "energy"= 1, + "bomb"= 1, + "bio"= 1, + "rad"= 1 + ) + + var/damage_minimum = 10 + var/minimum_penetration = 0 + var/fail_penetration_value = 0.66 + +/obj/item/mecha_parts/component/armor/mining + name = "blast-resistant mecha plating" + + step_delay = 2 + max_integrity = 80 + + damage_absorption = list( + "brute"=0.8, + "fire"=0.8, + "bullet"=1.2, + "laser"=1.2, + "energy"=1, + "bomb"=0.5, + "bio"=1, + "rad"=1 + ) + +/obj/item/mecha_parts/component/armor/lightweight + name = "lightweight mecha plating" + + max_integrity = 50 + step_delay = 0 + + damage_absorption = list( + "brute"=1, + "fire"=1.4, + "bullet"=1.1, + "laser"=1.2, + "energy"=1, + "bomb"=1, + "bio"=1, + "rad"=1 + ) + +/obj/item/mecha_parts/component/armor/reinforced + name = "reinforced mecha plating" + + step_delay = 4 + + max_integrity = 80 + + minimum_penetration = 10 + + damage_absorption = list( + "brute"=0.7, + "fire"=1, + "bullet"=0.7, + "laser"=0.85, + "energy"=1, + "bomb"=0.8 + ) + +/obj/item/mecha_parts/component/armor/military + name = "military grade mecha plating" + + step_delay = 6 + + max_integrity = 100 + + emp_resistance = 2 + + required_type = list(/obj/mecha/combat) + + damage_minimum = 15 + minimum_penetration = 25 + + damage_absorption = list( + "brute"=0.5, + "fire"=1.1, + "bullet"=0.65, + "laser"=0.85, + "energy"=0.9, + "bomb"=0.8 + ) + +/obj/item/mecha_parts/component/armor/military/attach(var/obj/mecha/target, var/mob/living/user) + . = ..() + if(.) + var/typepass = FALSE + for(var/type in required_type) + if(istype(chassis, type)) + typepass = TRUE + + if(typepass) + step_delay = 3 + else + step_delay = initial(step_delay) + +/obj/item/mecha_parts/component/armor/marshal + name = "marshal mecha plating" + + step_delay = 5 + + max_integrity = 100 + + emp_resistance = 3 + + deflect_chance = 15 + + minimum_penetration = 10 + + required_type = list(/obj/mecha/combat) + + damage_absorption = list( + "brute"=0.75, + "fire"=1, + "bullet"=0.8, + "laser"=0.7, + "energy"=0.85, + "bomb"=1 + ) + +/obj/item/mecha_parts/component/armor/marshal/attach(var/obj/mecha/target, var/mob/living/user) + . = ..() + if(.) + var/typepass = FALSE + for(var/type in required_type) + if(istype(chassis, type)) + typepass = TRUE + + if(typepass) + step_delay = 2 + else + step_delay = initial(step_delay) + +/obj/item/mecha_parts/component/armor/marshal/reinforced + name = "blackops mecha plating" + + step_delay = 5 + + damage_absorption = list( + "brute"=0.6, + "fire"=0.8, + "bullet"=0.6, + "laser"=0.5, + "energy"=0.65, + "bomb"=0.8 + ) + +/obj/item/mecha_parts/component/armor/military/marauder + name = "cutting edge mecha plating" + + step_delay = 4 + + max_integrity = 150 + + emp_resistance = 3 + + required_type = list(/obj/mecha/combat/marauder) + + deflect_chance = 25 + damage_minimum = 30 + minimum_penetration = 25 + + damage_absorption = list( + "brute"=0.5, + "fire"=0.7, + "bullet"=0.45, + "laser"=0.6, + "energy"=0.7, + "bomb"=0.7 + ) + +/obj/item/mecha_parts/component/armor/military/marauder/attach(var/obj/mecha/target, var/mob/living/user) + . = ..() + if(.) + var/typepass = FALSE + for(var/type in required_type) + if(istype(chassis, type)) + typepass = TRUE + + if(typepass) + step_delay = 1 + else + step_delay = initial(step_delay) + +/obj/item/mecha_parts/component/armor/alien + name = "strange mecha plating" + step_delay = 3 + damage_absorption = list( + "brute"=0.7, + "fire"=0.7, + "bullet"=0.7, + "laser"=0.7, + "energy"=0.7, + "bomb"=0.7 + ) + +/obj/item/mecha_parts/component/armor/alien/attach(var/obj/mecha/target, var/mob/living/user) + . = ..() + if(.) + if(istype(target, /obj/mecha/combat/phazon/janus)) + step_delay = -1 + + else if(istype(target, /obj/mecha/combat/phazon)) + step_delay = -3 + + else + step_delay = initial(step_delay) diff --git a/code/game/mecha/components/electrical.dm b/code/game/mecha/components/electrical.dm new file mode 100644 index 0000000000..de07c96c84 --- /dev/null +++ b/code/game/mecha/components/electrical.dm @@ -0,0 +1,31 @@ + +/obj/item/mecha_parts/component/electrical + name = "mecha electrical harness" + icon = 'icons/mecha/mech_component.dmi' + icon_state = "board" + w_class = ITEMSIZE_HUGE + origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + + component_type = MECH_ELECTRIC + + emp_resistance = 1 + + integrity_danger_mod = 0.4 + max_integrity = 40 + + step_delay = 0 + + relative_size = 20 + + internal_damage_flag = MECHA_INT_SHORT_CIRCUIT + + var/charge_cost_mod = 1 + +/obj/item/mecha_parts/component/electrical/high_current + name = "efficient mecha electrical harness" + + emp_resistance = 0 + max_integrity = 30 + + relative_size = 10 + charge_cost_mod = 0.6 diff --git a/code/game/mecha/components/hull.dm b/code/game/mecha/components/hull.dm new file mode 100644 index 0000000000..16d01ad92c --- /dev/null +++ b/code/game/mecha/components/hull.dm @@ -0,0 +1,33 @@ + +/obj/item/mecha_parts/component/hull + name = "mecha hull" + icon = 'icons/mecha/mech_component.dmi' + icon_state = "hull" + w_class = ITEMSIZE_HUGE + origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + + component_type = MECH_HULL + + emp_resistance = 0 // Amount of emp 'levels' removed. + + required_type = null // List, if it exists. Exosuits meant to use the component. + + integrity_danger_mod = 0.5 // Multiplier for comparison to max_integrity before problems start. + max_integrity = 50 + + internal_damage_flag = MECHA_INT_FIRE + + step_delay = 2 + +/obj/item/mecha_parts/component/hull/durable + name = "durable mecha hull" + + step_delay = 4 + integrity_danger_mod = 0.3 + max_integrity = 100 + +/obj/item/mecha_parts/component/hull/lightweight + name = "lightweight mecha hull" + + step_delay = 1 + integrity_danger_mod = 0.3 diff --git a/code/game/mecha/components/lifesupport.dm b/code/game/mecha/components/lifesupport.dm new file mode 100644 index 0000000000..d98cefda4d --- /dev/null +++ b/code/game/mecha/components/lifesupport.dm @@ -0,0 +1,28 @@ + +/obj/item/mecha_parts/component/gas + name = "mecha life-support" + icon = 'icons/mecha/mech_component.dmi' + icon_state = "lifesupport" + w_class = ITEMSIZE_HUGE + origin_tech = list(TECH_DATA = 2, TECH_ENGINEERING = 2) + + component_type = MECH_GAS + + emp_resistance = 1 + + integrity_danger_mod = 0.4 + max_integrity = 40 + + step_delay = 0 + + relative_size = 20 + + internal_damage_flag = MECHA_INT_TANK_BREACH + +/obj/item/mecha_parts/component/gas/reinforced + name = "reinforced mecha life-support" + + emp_resistance = 2 + max_integrity = 80 + + relative_size = 40 diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index 678ac64910..617af4849f 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -28,6 +28,8 @@ var/ready_sound = 'sound/mecha/mech_reload_default.ogg' //Sound to play once the fire delay passed. var/enable_special = FALSE // Will the tool do its special? + var/step_delay = 0 // Does the component slow/speed up the suit? + /obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(target=1) sleep(equip_cooldown) set_ready_state(1) @@ -273,3 +275,6 @@ /obj/item/mecha_parts/mecha_equipment/proc/MoveAction() //Allows mech equipment to do an action upon the mech moving return + +/obj/item/mecha_parts/mecha_equipment/proc/get_step_delay() // Equipment returns its slowdown or speedboost. + return step_delay diff --git a/code/game/mecha/equipment/tools/armor_melee.dm b/code/game/mecha/equipment/tools/armor_melee.dm index 8390a2cc52..085148d938 100644 --- a/code/game/mecha/equipment/tools/armor_melee.dm +++ b/code/game/mecha/equipment/tools/armor_melee.dm @@ -9,6 +9,8 @@ var/deflect_coeff = 1.15 var/damage_coeff = 0.8 + step_delay = 1 + equip_type = EQUIP_HULL /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/get_equip_info() diff --git a/code/game/mecha/equipment/tools/armor_ranged.dm b/code/game/mecha/equipment/tools/armor_ranged.dm index 4fb3aac32b..5b8d6d8172 100644 --- a/code/game/mecha/equipment/tools/armor_ranged.dm +++ b/code/game/mecha/equipment/tools/armor_ranged.dm @@ -9,6 +9,8 @@ var/deflect_coeff = 1.15 var/damage_coeff = 0.8 + step_delay = 2 + equip_type = EQUIP_HULL /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/handle_projectile_contact(var/obj/item/projectile/Proj, var/inc_damage) diff --git a/code/game/mecha/equipment/tools/repair_droid.dm b/code/game/mecha/equipment/tools/repair_droid.dm index f4f9696aa5..7cd8ebd9ab 100644 --- a/code/game/mecha/equipment/tools/repair_droid.dm +++ b/code/game/mecha/equipment/tools/repair_droid.dm @@ -11,6 +11,8 @@ var/icon/droid_overlay var/list/repairable_damage = list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH) + step_delay = 1 + equip_type = EQUIP_HULL /obj/item/mecha_parts/mecha_equipment/repair_droid/New() @@ -79,8 +81,23 @@ RD.chassis.clearInternalDamage(int_dam_flag) repaired = 1 break - if(health_boost<0 || RD.chassis.health < initial(RD.chassis.health)) + + var/obj/item/mecha_parts/component/AC = RD.chassis.internal_components[MECH_ARMOR] + var/obj/item/mecha_parts/component/HC = RD.chassis.internal_components[MECH_HULL] + + var/damaged_armor = AC.integrity < AC.max_integrity + + var/damaged_hull = HC.integrity < HC.max_integrity + + if(health_boost<0 || RD.chassis.health < initial(RD.chassis.health) || damaged_armor || damaged_hull) RD.chassis.health += min(health_boost, initial(RD.chassis.health)-RD.chassis.health) + + if(AC) + AC.adjust_integrity(round(health_boost * 0.5, 0.5)) + + if(HC) + HC.adjust_integrity(round(health_boost * 0.5, 0.5)) + repaired = 1 if(repaired) if(RD.chassis.use_power(RD.energy_drain)) diff --git a/code/game/mecha/equipment/tools/shield.dm b/code/game/mecha/equipment/tools/shield.dm index 1ceab07945..453c2ba9da 100644 --- a/code/game/mecha/equipment/tools/shield.dm +++ b/code/game/mecha/equipment/tools/shield.dm @@ -7,6 +7,8 @@ energy_drain = 20 range = 0 + step_delay = 1 + var/obj/item/shield_projector/line/exosuit/my_shield = null var/my_shield_type = /obj/item/shield_projector/line/exosuit var/icon/drone_overlay @@ -66,9 +68,11 @@ my_shield.attack_self(chassis.occupant) if(my_shield.active) set_ready_state(0) + step_delay = 4 log_message("Activated.") else set_ready_state(1) + step_delay = 1 log_message("Deactivated.") /obj/item/mecha_parts/mecha_equipment/combat_shield/Topic(href, href_list) diff --git a/code/game/mecha/equipment/tools/shield_omni.dm b/code/game/mecha/equipment/tools/shield_omni.dm index 1d230c4deb..aae68ef4cd 100644 --- a/code/game/mecha/equipment/tools/shield_omni.dm +++ b/code/game/mecha/equipment/tools/shield_omni.dm @@ -9,6 +9,8 @@ energy_drain = OMNI_SHIELD_DRAIN range = 0 + step_delay = 1 + var/obj/item/shield_projector/shields = null var/shield_type = /obj/item/shield_projector/rectangle/mecha @@ -42,9 +44,11 @@ shields.set_on(!shields.active) if(shields.active) set_ready_state(0) + step_delay = 4 log_message("Activated.") else set_ready_state(1) + step_delay = 1 log_message("Deactivated.") /obj/item/mecha_parts/mecha_equipment/omni_shield/Topic(href, href_list) diff --git a/code/game/mecha/equipment/tools/speedboost.dm b/code/game/mecha/equipment/tools/speedboost.dm index 6e7ad06f69..7ffbeaee38 100644 --- a/code/game/mecha/equipment/tools/speedboost.dm +++ b/code/game/mecha/equipment/tools/speedboost.dm @@ -7,6 +7,9 @@ equip_type = EQUIP_HULL + var/slowdown_multiplier = 0.75 // How much does the exosuit multiply its slowdown by if it's the proper type? + +/* /obj/item/mecha_parts/mecha_equipment/speedboost/attach(obj/mecha/M as obj) ..() if(enable_special) @@ -14,6 +17,13 @@ else chassis.step_in = 6 // Improper parts slow the mech down return +*/ + +/obj/item/mecha_parts/mecha_equipment/speedboost/get_step_delay() + if(enable_special) + return -1 + else + return 3 /obj/item/mecha_parts/mecha_equipment/speedboost/detach() chassis.step_in = initial(chassis.step_in) diff --git a/code/game/mecha/equipment/weapons/ballistic/mortar.dm b/code/game/mecha/equipment/weapons/ballistic/mortar.dm index 86928c9da5..c192d0fc9b 100644 --- a/code/game/mecha/equipment/weapons/ballistic/mortar.dm +++ b/code/game/mecha/equipment/weapons/ballistic/mortar.dm @@ -11,6 +11,8 @@ projectile = /obj/item/projectile/arc/fragmentation/mortar projectile_energy_cost = 600 + step_delay = 2 + origin_tech = list(TECH_MATERIAL = 4, TECH_COMBAT = 5, TECH_ILLEGAL = 3) /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/mortar/action_checks(atom/target) diff --git a/code/game/mecha/equipment/weapons/ballistic/shotgun.dm b/code/game/mecha/equipment/weapons/ballistic/shotgun.dm index d2232d0004..e6b12d8ebd 100644 --- a/code/game/mecha/equipment/weapons/ballistic/shotgun.dm +++ b/code/game/mecha/equipment/weapons/ballistic/shotgun.dm @@ -11,6 +11,8 @@ deviation = 0.7 projectile_energy_cost = 25 + step_delay = 2 + origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 4) /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot/rigged diff --git a/code/game/mecha/equipment/weapons/energy/laser.dm b/code/game/mecha/equipment/weapons/energy/laser.dm index 8bdcbcf71f..0dfcbd1328 100644 --- a/code/game/mecha/equipment/weapons/energy/laser.dm +++ b/code/game/mecha/equipment/weapons/energy/laser.dm @@ -52,6 +52,8 @@ projectile = /obj/item/projectile/beam/heavylaser fire_sound = 'sound/weapons/lasercannonfire.ogg' + step_delay = 2 + origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 4, TECH_MAGNET = 4) /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/rigged diff --git a/code/game/mecha/equipment/weapons/explosive/missile.dm b/code/game/mecha/equipment/weapons/explosive/missile.dm index 1c14a8c1dd..df8cf0c3bb 100644 --- a/code/game/mecha/equipment/weapons/explosive/missile.dm +++ b/code/game/mecha/equipment/weapons/explosive/missile.dm @@ -2,6 +2,8 @@ var/missile_speed = 2 var/missile_range = 30 + step_delay = 2 + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/Fire(atom/movable/AM, atom/target, turf/aimloc) AM.throw_at(target,missile_range, missile_speed, chassis) @@ -19,6 +21,8 @@ missile_range = 15 required_type = /obj/mecha //Why restrict it to just mining or combat mechs? + step_delay = 0 + equip_type = EQUIP_UTILITY /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flare/Fire(atom/movable/AM, atom/target, turf/aimloc) diff --git a/code/game/mecha/equipment/weapons/fire/flamethrower.dm b/code/game/mecha/equipment/weapons/fire/flamethrower.dm index f97f598e24..532c35a6b4 100644 --- a/code/game/mecha/equipment/weapons/fire/flamethrower.dm +++ b/code/game/mecha/equipment/weapons/fire/flamethrower.dm @@ -7,6 +7,8 @@ energy_drain = 30 + step_delay = 2 + projectile = /obj/item/projectile/bullet/incendiary/flamethrower/large fire_sound = 'sound/weapons/towelwipe.ogg' diff --git a/code/game/mecha/equipment/weapons/fire/incendiary.dm b/code/game/mecha/equipment/weapons/fire/incendiary.dm index 3d3c174839..ff49d42016 100644 --- a/code/game/mecha/equipment/weapons/fire/incendiary.dm +++ b/code/game/mecha/equipment/weapons/fire/incendiary.dm @@ -16,3 +16,5 @@ projectile_energy_cost = 40 fire_cooldown = 3 origin_tech = list(TECH_MATERIAL = 4, TECH_COMBAT = 5, TECH_PHORON = 2, TECH_ILLEGAL = 1) + + step_delay = 1 diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 355ce629ac..9dccf551c9 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -12,6 +12,8 @@ var/auto_rearm = 0 //Does the weapon reload itself after each shot? required_type = list(/obj/mecha/combat, /obj/mecha/working/hoverpod/combatpod) + step_delay = 1 + equip_type = EQUIP_WEAPON /obj/item/mecha_parts/mecha_equipment/weapon/action_checks(atom/target) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index ca2bcab7b9..130b6f20e6 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -7,6 +7,11 @@ #define MELEE 1 #define RANGED 2 +#define MECHA_OPERATING 0 +#define MECHA_BOLTS_SECURED 1 +#define MECHA_PANEL_LOOSE 2 +#define MECHA_CELL_OPEN 3 +#define MECHA_CELL_OUT 4 #define MECH_FACTION_NT "nano" #define MECH_FACTION_SYNDI "syndi" @@ -48,7 +53,7 @@ var/fail_penetration_value = 0.66 //By how much failing to penetrate reduces your shit. 66% by default. var/obj/item/weapon/cell/cell - var/state = 0 + var/state = MECHA_OPERATING var/list/log = new var/last_message = 0 var/add_req_access = 1 @@ -108,6 +113,24 @@ var/max_universal_equip = 2 var/max_special_equip = 1 + var/list/starting_equipment = null // List containing starting tools. + +// Mech Components, similar to Cyborg, but Bigger. + var/list/internal_components = list( + MECH_HULL = null, + MECH_ACTUATOR = null, + MECH_ARMOR = null, + MECH_GAS = null, + MECH_ELECTRIC = null + ) + var/list/starting_components = list( + /obj/item/mecha_parts/component/hull, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + //Working exosuit vars var/list/cargo = list() var/cargo_capacity = 3 @@ -139,7 +162,7 @@ var/phasing_possible = 0 //This is to allow phasing. var/can_phase = TRUE //This is an internal check during the relevant procs. var/phasing_energy_drain = 200 - + var/switch_dmg_type_possible = 0 //Can you switch damage type? It is mostly for the Phazon and its children. var/smoke_possible = 0 @@ -148,6 +171,8 @@ var/smoke_cooldown = 100 //How long you have between uses. var/datum/effect/effect/system/smoke_spread/smoke_system = new + var/cloak_possible = FALSE // Can this exosuit innately cloak? + ////All of those are for the HUD buttons in the top left. See Grant and Remove procs in mecha_actions. var/datum/action/innate/mecha/mech_eject/eject_action = new @@ -164,10 +189,20 @@ var/datum/action/innate/mecha/mech_cycle_equip/cycle_action = new var/datum/action/innate/mecha/mech_switch_damtype/switch_damtype_action = new var/datum/action/innate/mecha/mech_toggle_phasing/phasing_action = new + var/datum/action/innate/mecha/mech_toggle_cloaking/cloak_action = new var/weapons_only_cycle = FALSE //So combat mechs don't switch to their equipment at times. +/obj/mecha/Initialize() + ..() + for(var/path in starting_components) + var/obj/item/mecha_parts/component/C = new path(src) + C.attach(src) + if(starting_equipment && LAZYLEN(starting_equipment)) + for(var/path in starting_equipment) + var/obj/item/mecha_parts/mecha_equipment/ME = new path(src) + ME.attach(src) /obj/mecha/drain_power(var/drain_check) @@ -245,6 +280,15 @@ else E.forceMove(loc) E.destroy() + + for(var/slot in internal_components) + var/obj/item/mecha_parts/component/C = internal_components[slot] + if(istype(C)) + C.damage_part(rand(10, 20)) + C.detach() + WR.crowbar_salvage += C + C.forceMove(WR) + if(cell) WR.crowbar_salvage += cell cell.forceMove(WR) @@ -256,6 +300,11 @@ for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) E.detach(loc) E.destroy() + for(var/slot in internal_components) + var/obj/item/mecha_parts/component/C = internal_components[slot] + if(istype(C)) + C.detach() + qdel(C) if(cell) qdel(cell) if(internal_tank) @@ -351,6 +400,26 @@ /obj/mecha/examine(mob/user) . = ..() + + var/obj/item/mecha_parts/component/armor/AC = internal_components[MECH_ARMOR] + + var/obj/item/mecha_parts/component/hull/HC = internal_components[MECH_HULL] + + if(AC) + . += "It has [AC] attached. [AC.get_efficiency()<0.5?"It is severely damaged.":""]" + else + . += "It has no armor plating." + + if(HC) + if(!AC || AC.get_efficiency() < 0.7) + . += "It has [HC] attached. [HC.get_efficiency()<0.5?"It is severely damaged.":""]" + else + . += "You cannot tell what type of hull it has." + + else + . += "It does not seem to have a completed hull." + + var/integrity = health/initial(health)*100 switch(integrity) if(85 to 100) @@ -536,6 +605,12 @@ user.forceMove(get_turf(src)) to_chat(user, "You climb out from [src]") return 0 + + var/obj/item/mecha_parts/component/hull/HC = internal_components[MECH_HULL] + if(!HC) + occupant_message("You can't operate an exosuit that doesn't have a hull!") + return + if(connected_port) if(world.time - last_message > 20) src.occupant_message("Unable to move while connected to the air system port") @@ -562,6 +637,44 @@ return call((proc_res["dyndomove"]||src), "dyndomove")(direction) +/obj/mecha/proc/get_step_delay() + var/tally = 0 + + if(overload) + tally = min(1, round(step_in/2)) + + for(var/slot in internal_components) + var/obj/item/mecha_parts/component/C = internal_components[slot] + if(C && C.get_step_delay()) + tally += C.get_step_delay() + + for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) + if(ME.get_step_delay()) + tally += ME.get_step_delay() + + var/obj/item/mecha_parts/component/actuator/actuator = internal_components[MECH_ACTUATOR] + + if(!actuator) // Relying purely on hydraulic pumps. You're going nowhere fast. + tally = 2 SECONDS + + return tally + + tally += 0.5 SECONDS * (1 - actuator.get_efficiency()) // Damaged actuators run slower, slowing as damage increases beyond its threshold. + + if(strafing) + tally = round(tally * actuator.strafing_multiplier) + + for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) + if(istype(ME, /obj/item/mecha_parts/mecha_equipment/speedboost)) + var/obj/item/mecha_parts/mecha_equipment/speedboost/SB = ME + for(var/path in ME.required_type) + if(istype(src, path)) + tally = round(tally * SB.slowdown_multiplier) + break + break + + return max(1, round(tally)) + /obj/mecha/proc/dyndomove(direction) if(!can_move) return 0 @@ -600,7 +713,6 @@ health-- if(health < initial(health) - initial(health)/3) overload = 0 - step_in = initial(step_in) step_energy_drain = initial(step_energy_drain) src.occupant_message("Leg actuators damage threshold exceded. Disabling overload.") @@ -656,7 +768,7 @@ if(!src.check_for_support()) src.pr_inertial_movement.start(list(src,direction)) src.log_message("Movement control lost. Inertial movement started.") - if(do_after(step_in)) + if(do_after(get_step_delay())) can_move = 1 return 1 return 0 @@ -708,7 +820,7 @@ flick("[initial_icon]-phase", src) src.loc = get_step(src,src.dir) src.use_power(phasing_energy_drain) - sleep(step_in*3) + sleep(get_step_delay() * 3) can_phase = TRUE occupant_message("Phazed.") . = ..(obstacle) @@ -785,16 +897,57 @@ update_damage_alerts() if(amount) var/damage = absorbDamage(amount,type) + + damage = components_handle_damage(damage,type) + health -= damage + update_health() log_append_to_last("Took [damage] points of damage. Damage type: \"[type]\".",1) return +/obj/mecha/proc/components_handle_damage(var/damage, var/type = BRUTE) + var/obj/item/mecha_parts/component/armor/AC = internal_components[MECH_ARMOR] + + if(AC) + var/armor_efficiency = AC.get_efficiency() + var/damage_change = armor_efficiency * (damage * 0.5) * AC.damage_absorption[type] + AC.damage_part(damage_change, type) + damage -= damage_change + + var/obj/item/mecha_parts/component/hull/HC = internal_components[MECH_HULL] + + if(HC) + if(HC.integrity) + var/hull_absorb = round(rand(5, 10) / 10, 0.1) * damage + HC.damage_part(hull_absorb, type) + damage -= hull_absorb + + for(var/obj/item/mecha_parts/component/C in (internal_components - list(MECH_HULL, MECH_ARMOR))) + if(prob(C.relative_size)) + var/damage_part_amt = round(damage / 4, 0.1) + C.damage_part(damage_part_amt) + damage -= damage_part_amt + + return damage + +/obj/mecha/proc/get_damage_absorption() + var/obj/item/mecha_parts/component/armor/AC = internal_components[MECH_ARMOR] + + if(!istype(AC)) + return + + else + if(AC.get_efficiency() > 0.25) + return AC.damage_absorption + + return + /obj/mecha/proc/absorbDamage(damage,damage_type) return call((proc_res["dynabsorbdamage"]||src), "dynabsorbdamage")(damage,damage_type) /obj/mecha/proc/dynabsorbdamage(damage,damage_type) - return damage*(listgetindex(damage_absorption,damage_type) || 1) + return damage*(listgetindex(get_damage_absorption(),damage_type) || 1) /obj/mecha/airlock_crush(var/crush_damage) ..() @@ -814,14 +967,24 @@ if(user == occupant) show_radial_occupant(user) return - + user.setClickCooldown(user.get_attack_speed()) src.log_message("Attack by hand/paw. Attacker - [user].",1) + var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR] + + var/temp_deflect_chance = deflect_chance + + if(!ArmC) + temp_deflect_chance = 1 + + else + temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0)) + if(istype(user,/mob/living/carbon/human)) var/mob/living/carbon/human/H = user if(H.species.can_shred(user)) - if(!prob(src.deflect_chance)) + if(!prob(temp_deflect_chance)) src.take_damage(15) //The take_damage() proc handles armor values if(prob(25)) //Why would they get free internal damage. At least make it a bit RNG. src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) @@ -838,7 +1001,7 @@ user.visible_message("\The [user] hits \the [src]. Nothing happens.","You hit \the [src] with no visible effect.") src.log_append_to_last("Armor saved.") return - else if ((HULK in user.mutations) && !prob(src.deflect_chance)) + else if ((HULK in user.mutations) && !prob(temp_deflect_chance)) src.take_damage(15) //The take_damage() proc handles armor values if(prob(25)) //Hulks punch hard but lets not give them consistent internal damage. src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) @@ -856,11 +1019,30 @@ //I think this is relative to throws. /obj/mecha/proc/dynhitby(atom/movable/A) + var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR] + + var/temp_deflect_chance = deflect_chance + var/temp_damage_minimum = damage_minimum + var/temp_minimum_penetration = minimum_penetration + var/temp_fail_penetration_value = fail_penetration_value + + if(!ArmC) + temp_deflect_chance = 0 + temp_damage_minimum = 0 + temp_minimum_penetration = 0 + temp_fail_penetration_value = 1 + + else + temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0)) + temp_damage_minimum = round(ArmC.get_efficiency() * ArmC.damage_minimum) + temp_minimum_penetration = round(ArmC.get_efficiency() * ArmC.minimum_penetration) + temp_fail_penetration_value = round(ArmC.get_efficiency() * ArmC.fail_penetration_value) + if(istype(A, /obj/item/mecha_parts/mecha_tracking)) A.forceMove(src) src.visible_message("The [A] fastens firmly to [src].") return - if(prob(src.deflect_chance) || istype(A, /mob)) + if(prob(temp_deflect_chance) || istype(A, /mob)) src.occupant_message("\The [A] bounces off the armor.") src.visible_message("\The [A] bounces off \the [src] armor") src.log_append_to_last("Armor saved.") @@ -873,18 +1055,18 @@ var/pass_damage = O.throwforce var/pass_damage_reduc_mod - if(pass_damage <= damage_minimum)//Too little to go through. + if(pass_damage <= temp_damage_minimum)//Too little to go through. src.occupant_message("\The [A] bounces off the armor.") src.visible_message("\The [A] bounces off \the [src] armor") return - else if(O.armor_penetration < minimum_penetration) //If you don't have enough pen, you won't do full damage + else if(O.armor_penetration < temp_minimum_penetration) //If you don't have enough pen, you won't do full damage src.occupant_message("\The [A] struggles to bypass \the [src] armor.") src.visible_message("\The [A] struggles to bypass \the [src] armor") - pass_damage_reduc_mod = fail_penetration_value //This will apply to reduce damage to 2/3 or 66% by default + pass_damage_reduc_mod = temp_fail_penetration_value //This will apply to reduce damage to 2/3 or 66% by default else - src.occupant_message("\The [A] manages to pierces \the [src] armor.") - src.visible_message("\The [A] manages to pierces \the [src] armor") + src.occupant_message("\The [A] manages to pierce \the [src] armor.") +// src.visible_message("\The [A] manages to pierce \the [src] armor") pass_damage_reduc_mod = 1 @@ -911,7 +1093,26 @@ return /obj/mecha/proc/dynbulletdamage(var/obj/item/projectile/Proj) - if(prob(src.deflect_chance)) + var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR] + + var/temp_deflect_chance = deflect_chance + var/temp_damage_minimum = damage_minimum + var/temp_minimum_penetration = minimum_penetration + var/temp_fail_penetration_value = fail_penetration_value + + if(!ArmC) + temp_deflect_chance = 0 + temp_damage_minimum = 0 + temp_minimum_penetration = 0 + temp_fail_penetration_value = 1 + + else + temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0)) + temp_damage_minimum = round(ArmC.get_efficiency() * ArmC.damage_minimum) + temp_minimum_penetration = round(ArmC.get_efficiency() * ArmC.minimum_penetration) + temp_fail_penetration_value = round(ArmC.get_efficiency() * ArmC.fail_penetration_value) + + if(prob(temp_deflect_chance)) src.occupant_message("The armor deflects incoming projectile.") src.visible_message("The [src.name] armor deflects the projectile") src.log_append_to_last("Armor saved.") @@ -930,19 +1131,19 @@ for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) pass_damage = ME.handle_projectile_contact(Proj, pass_damage) - if(pass_damage < damage_minimum)//too pathetic to really damage you. + if(pass_damage < temp_damage_minimum)//too pathetic to really damage you. src.occupant_message("The armor deflects incoming projectile.") src.visible_message("The [src.name] armor deflects\the [Proj]") return - else if(Proj.armor_penetration < minimum_penetration) //If you don't have enough pen, you won't do full damage + else if(Proj.armor_penetration < temp_minimum_penetration) //If you don't have enough pen, you won't do full damage src.occupant_message("\The [Proj] struggles to pierce \the [src] armor.") src.visible_message("\The [Proj] struggles to pierce \the [src] armor") - pass_damage_reduc_mod = fail_penetration_value //This will apply to reduce damage to 2/3 or 66% by default + pass_damage_reduc_mod = temp_fail_penetration_value //This will apply to reduce damage to 2/3 or 66% by default else //You go through completely because you use AP. Nice. src.occupant_message("\The [Proj] manages to pierce \the [src] armor.") - src.visible_message("\The [Proj] manages to pierce \the [src] armor") +// src.visible_message("\The [Proj] manages to pierce \the [src] armor") pass_damage_reduc_mod = 1 pass_damage = (pass_damage_reduc_mod*pass_damage)//Apply damage reduction before usage. @@ -961,7 +1162,7 @@ Proj.attack_mob(src.occupant, distance) hit_occupant = 0 else - if(pass_damage > internal_damage_minimum) //Only decently painful attacks trigger a chance of mech damage. + if(pass_damage > internal_damage_minimum) //Only decently painful attacks trigger a chance of mech damage. src.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) Proj.penetrating-- @@ -974,24 +1175,34 @@ //This refer to whenever you are caught in an explosion. /obj/mecha/ex_act(severity) + var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR] + + var/temp_deflect_chance = deflect_chance + + if(!ArmC) + temp_deflect_chance = 0 + + else + temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0)) + src.log_message("Affected by explosion of severity: [severity].",1) - if(prob(src.deflect_chance)) + if(prob(temp_deflect_chance)) severity++ src.log_append_to_last("Armor saved, changing severity to [severity].") switch(severity) if(1.0) - qdel(src) + src.take_damage(initial(src.health), "bomb") if(2.0) if (prob(30)) - qdel(src) + src.take_damage(initial(src.health), "bomb") else - src.take_damage(initial(src.health)/2) //The take_damage() proc handles armor values + src.take_damage(initial(src.health)/2, "bomb") src.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.0) if (prob(5)) qdel(src) else - src.take_damage(initial(src.health)/5) //The take_damage() proc handles armor values + src.take_damage(initial(src.health)/5, "bomb") src.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 @@ -1038,20 +1249,39 @@ src.log_message("Attacked by [W]. Attacker - [user]") var/pass_damage_reduc_mod //Modifer for failing to bring AP. - if(prob(src.deflect_chance)) //Does your attack get deflected outright. + var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR] + + var/temp_deflect_chance = deflect_chance + var/temp_damage_minimum = damage_minimum + var/temp_minimum_penetration = minimum_penetration + var/temp_fail_penetration_value = fail_penetration_value + + if(!ArmC) + temp_deflect_chance = 0 + temp_damage_minimum = 0 + temp_minimum_penetration = 0 + temp_fail_penetration_value = 1 + + else + temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0)) + temp_damage_minimum = round(ArmC.get_efficiency() * ArmC.damage_minimum) + temp_minimum_penetration = round(ArmC.get_efficiency() * ArmC.minimum_penetration) + temp_fail_penetration_value = round(ArmC.get_efficiency() * ArmC.fail_penetration_value) + + if(prob(temp_deflect_chance)) //Does your attack get deflected outright. src.occupant_message("\The [W] bounces off [src.name].") to_chat(user, "\The [W] bounces off [src.name].") src.log_append_to_last("Armor saved.") - else if(W.force < damage_minimum) //Is your attack too PATHETIC to do anything. 3 damage to a person shouldn't do anything to a mech. + else if(W.force < temp_damage_minimum) //Is your attack too PATHETIC to do anything. 3 damage to a person shouldn't do anything to a mech. src.occupant_message("\The [W] bounces off the armor.") src.visible_message("\The [W] bounces off \the [src] armor") return - else if(W.armor_penetration < minimum_penetration) //If you don't have enough pen, you won't do full damage + else if(W.armor_penetration < temp_minimum_penetration) //If you don't have enough pen, you won't do full damage src.occupant_message("\The [W] struggles to bypass \the [src] armor.") src.visible_message("\The [W] struggles to bypass \the [src] armor") - pass_damage_reduc_mod = fail_penetration_value //This will apply to reduce damage to 2/3 or 66% by default + pass_damage_reduc_mod = temp_fail_penetration_value //This will apply to reduce damage to 2/3 or 66% by default else pass_damage_reduc_mod = 1 //Just making sure. @@ -1080,6 +1310,11 @@ to_chat(user, "[src]-MMI interface initialization failed.") return + if(istype(W, /obj/item/device/robotanalyzer)) + var/obj/item/device/robotanalyzer/RA = W + RA.do_scan(src, user) + return + if(istype(W, /obj/item/mecha_parts/mecha_equipment)) var/obj/item/mecha_parts/mecha_equipment/E = W spawn() @@ -1090,6 +1325,20 @@ else to_chat(user, "You were unable to attach [W] to [src]") return + + if(istype(W, /obj/item/mecha_parts/component) && state == MECHA_CELL_OUT) + var/obj/item/mecha_parts/component/MC = W + spawn() + if(MC.attach(src)) + user.drop_item() + MC.forceMove(src) + user.visible_message("[user] installs \the [W] in \the [src]", "You install \the [W] in \the [src].") + return + + if(istype(W, /obj/item/weapon/card/robot)) + var/obj/item/weapon/card/robot/RoC = W + return attackby(RoC.dummy_card, user) + if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) if(add_req_access || maint_access) if(internals_access_allowed(usr)) @@ -1106,23 +1355,39 @@ else to_chat(user, "Maintenance protocols disabled by operator.") else if(W.is_wrench()) - if(state==1) - state = 2 + if(state==MECHA_BOLTS_SECURED) + state = MECHA_PANEL_LOOSE to_chat(user, "You undo the securing bolts.") - else if(state==2) - state = 1 + else if(state==MECHA_PANEL_LOOSE) + state = MECHA_BOLTS_SECURED to_chat(user, "You tighten the securing bolts.") return else if(W.is_crowbar()) - if(state==2) - state = 3 + if(state==MECHA_PANEL_LOOSE) + state = MECHA_CELL_OPEN to_chat(user, "You open the hatch to the power unit") - else if(state==3) - state=2 + else if(state==MECHA_CELL_OPEN) + state=MECHA_PANEL_LOOSE to_chat(user, "You close the hatch to the power unit") + else if(state==MECHA_CELL_OUT) + var/list/removable_components = list() + for(var/slot in internal_components) + var/obj/item/mecha_parts/component/MC = internal_components[slot] + if(istype(MC)) + removable_components[MC.name] = MC + else + to_chat(user, "\The [src] appears to be missing \the [slot].") + + var/remove = input(user, "Which component do you want to pry out?", "Remove Component") as null|anything in removable_components + if(!remove) + return + + var/obj/item/mecha_parts/component/RmC = removable_components[remove] + RmC.detach() + return else if(istype(W, /obj/item/stack/cable_coil)) - if(state == 3 && hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) + if(state >= MECHA_CELL_OPEN && hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) var/obj/item/stack/cable_coil/CC = W if(CC.use(2)) clearInternalDamage(MECHA_INT_SHORT_CIRCUIT) @@ -1134,19 +1399,19 @@ if(hasInternalDamage(MECHA_INT_TEMP_CONTROL)) clearInternalDamage(MECHA_INT_TEMP_CONTROL) to_chat(user, "You repair the damaged temperature controller.") - else if(state==3 && src.cell) + else if(state==MECHA_CELL_OPEN && src.cell) src.cell.forceMove(src.loc) src.cell = null - state = 4 + state = MECHA_CELL_OUT to_chat(user, "You unscrew and pry out the powercell.") src.log_message("Powercell removed") - else if(state==4 && src.cell) - state=3 + else if(state==MECHA_CELL_OUT && src.cell) + state=MECHA_CELL_OPEN to_chat(user, "You screw the cell in place") return else if(istype(W, /obj/item/device/multitool)) - if(state>=3 && src.occupant) + if(state>=MECHA_CELL_OPEN && src.occupant) to_chat(user, "You attempt to eject the pilot using the maintenance controls.") if(src.occupant.stat) src.go_out() @@ -1158,7 +1423,7 @@ return else if(istype(W, /obj/item/weapon/cell)) - if(state==4) + if(state==MECHA_CELL_OUT) if(!src.cell) to_chat(user, "You install the powercell") user.drop_item() @@ -1191,6 +1456,28 @@ user.visible_message("[user] attaches [W] to [src].", "You attach [W] to [src]") return + else if(istype(W,/obj/item/stack/nanopaste)) + if(state >= MECHA_PANEL_LOOSE) + var/obj/item/stack/nanopaste/NP = W + + for(var/slot in internal_components) + var/obj/item/mecha_parts/component/C = internal_components[slot] + + if(C) + + if(C.integrity < C.max_integrity) + while(C.integrity < C.max_integrity && NP && do_after(user, 1 SECOND, src)) + if(NP.use(1)) + C.adjust_integrity(10) + + to_chat(user, "You repair damage to \the [C].") + + return + + else + to_chat(user, "You can't reach \the [src]'s internal components.") + return + else call((proc_res["dynattackby"]||src), "dynattackby")(W,user) /* @@ -1299,7 +1586,8 @@ return /obj/mecha/remove_air(amount) - if(use_internal_tank) + var/obj/item/mecha_parts/component/gas/GC = internal_components[MECH_GAS] + if(use_internal_tank && (GC && prob(GC.get_efficiency() * 100))) return cabin_air.remove(amount) else var/turf/T = get_turf(src) @@ -1314,7 +1602,8 @@ /obj/mecha/proc/return_pressure() . = 0 - if(use_internal_tank) + var/obj/item/mecha_parts/component/gas/GC = internal_components[MECH_GAS] + if(use_internal_tank && (GC && prob(GC.get_efficiency() * 100))) . = cabin_air.return_pressure() else var/datum/gas_mixture/t_air = get_turf_air() @@ -1325,7 +1614,8 @@ //skytodo: //No idea what you want me to do here, mate. /obj/mecha/proc/return_temperature() . = 0 - if(use_internal_tank) + var/obj/item/mecha_parts/component/gas/GC = internal_components[MECH_GAS] + if(use_internal_tank && (GC && prob(GC.get_efficiency() * 100))) . = cabin_air.temperature else var/datum/gas_mixture/t_air = get_turf_air() @@ -1380,13 +1670,17 @@ set category = "Exosuit Interface" set src = usr.loc set popup_menu = 0 - + if(!occupant) return - + if(usr != occupant) return - + + var/obj/item/mecha_parts/component/gas/GC = internal_components[MECH_GAS] + if(!GC) + return + for(var/turf/T in locs) var/obj/machinery/atmospherics/portables_connector/possible_port = locate(/obj/machinery/atmospherics/portables_connector) in T if(possible_port) @@ -1407,13 +1701,13 @@ set category = "Exosuit Interface" set src = usr.loc set popup_menu = 0 - + if(!occupant) return - + if(usr != occupant) return - + if(disconnect()) occupant_message("[name] disconnects from the port.") verbs -= /obj/mecha/verb/disconnect_from_port @@ -1449,6 +1743,16 @@ /obj/mecha/proc/internal_tank() if(usr!=src.occupant) return + + var/obj/item/mecha_parts/component/gas/GC = internal_components[MECH_GAS] + if(!GC) + to_chat(occupant, "The life support systems don't seem to respond.") + return + + if(!prob(GC.get_efficiency() * 100)) + to_chat(occupant, "\The [GC] shudders and barks, before returning to how it was before.") + return + use_internal_tank = !use_internal_tank src.occupant_message("Now taking air from [use_internal_tank?"internal airtank":"environment"].") src.log_message("Now taking air from [use_internal_tank?"internal airtank":"environment"].") @@ -1579,6 +1883,8 @@ verbs -= /obj/mecha/verb/toggle_phasing if(!switch_dmg_type_possible) verbs -= /obj/mecha/verb/switch_damtype + if(!cloak_possible) + verbs -= /obj/mecha/verb/toggle_cloak occupant.in_enclosed_vehicle = 1 //Useful for when you need to know if someone is in a mecho. update_cell_alerts() @@ -1697,8 +2003,13 @@ /obj/mecha/proc/internals_access_allowed(mob/living/carbon/human/H) - for(var/atom/ID in list(H.get_active_hand(), H.wear_id, H.belt)) - if(src.check_access(ID,src.internals_req_access)) + if(istype(H)) + for(var/atom/ID in list(H.get_active_hand(), H.wear_id, H.belt)) + if(src.check_access(ID,src.internals_req_access)) + return 1 + else if(istype(H, /mob/living/silicon/robot)) + var/mob/living/silicon/robot/R = H + if(src.check_access(R.idcard,src.internals_req_access)) return 1 return 0 @@ -1799,9 +2110,15 @@ var/tank_pressure = internal_tank ? round(internal_tank.return_pressure(),0.01) : "None" var/tank_temperature = internal_tank ? internal_tank.return_temperature() : "Unknown" var/cabin_pressure = round(return_pressure(),0.01) + + var/obj/item/mecha_parts/component/hull/HC = internal_components[MECH_HULL] + var/obj/item/mecha_parts/component/armor/AC = internal_components[MECH_ARMOR] + var/output = {"[report_internal_damage()] + Armor Integrity: [AC?"[round(AC.integrity / AC.max_integrity * 100, 0.1)]%":"ARMOR MISSING"]
+ Hull Integrity: [HC?"[round(HC.integrity / HC.max_integrity * 100, 0.1)]%":"HULL MISSING"]
[integrity<30?"DAMAGE LEVEL CRITICAL
":null] - Integrity: [integrity]%
+ Chassis Integrity: [integrity]%
Powercell charge: [isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]
Air source: [use_internal_tank?"Internal Airtank":"Environment"]
Airtank pressure: [tank_pressure]kPa
@@ -1888,6 +2205,7 @@ output += "Universal Module: [W.name] Detach
" for(var/obj/item/mecha_parts/mecha_equipment/W in special_equipment) output += "Special Module: [W.name] Detach
" +<<<<<<< HEAD for(var/obj/item/mecha_parts/mecha_equipment/W in micro_utility_equipment) // VOREstation Edit - Adds micro equipent to the menu output += "Micro Utility Module: [W.name] Detach
" for(var/obj/item/mecha_parts/mecha_equipment/W in micro_weapon_equipment) @@ -1901,6 +2219,15 @@ Available special slots: [max_special_equip-special_equipment.len]
"} +======= + output += {"Available hull slots: [max_hull_equip-hull_equipment.len]
+ Available weapon slots: [max_weapon_equip-weapon_equipment.len]
+ Available utility slots: [max_utility_equip-utility_equipment.len]
+ Available universal slots: [max_universal_equip-universal_equipment.len]
+ Available special slots: [max_special_equip-special_equipment.len]
+ + "} +>>>>>>> 282b42d... Exosuit Modular Internals, The Squeakening (#7329) return output /obj/mecha/proc/get_equipment_list() //outputs mecha equipment list in html @@ -2109,15 +2436,15 @@ if(!in_range(src, usr)) return var/mob/user = top_filter.getMob("user") if(user) - if(state==0) - state = 1 + if(state==MECHA_OPERATING) + state = MECHA_BOLTS_SECURED to_chat(user, "The securing bolts are now exposed.") - else if(state==1) - state = 0 + else if(state==MECHA_BOLTS_SECURED) + state = MECHA_OPERATING to_chat(user, "The securing bolts are now hidden.") output_maintenance_dialog(top_filter.getObj("id_card"),user) return - if(href_list["set_internal_tank_valve"] && state >=1) + if(href_list["set_internal_tank_valve"] && state >=MECHA_BOLTS_SECURED) if(!in_range(src, usr)) return var/mob/user = top_filter.getMob("user") if(user) @@ -2125,7 +2452,7 @@ if(new_pressure) internal_tank_valve = new_pressure to_chat(user, "The internal pressure valve has been set to [internal_tank_valve]kPa.") - if(href_list["remove_passenger"] && state >= 1) + if(href_list["remove_passenger"] && state >= MECHA_BOLTS_SECURED) var/mob/user = top_filter.getMob("user") var/list/passengers = list() for (var/obj/item/mecha_parts/mecha_equipment/tool/passenger/P in contents) @@ -2284,6 +2611,13 @@ /obj/mecha/proc/dynusepower(amount) update_cell_alerts() + var/obj/item/mecha_parts/component/electrical/EC = internal_components[MECH_ELECTRIC] + + if(EC) + amount = amount * (2 - EC.get_efficiency()) * EC.charge_cost_mod + else + amount *= 5 + if(get_charge()) cell.use(amount) return 1 @@ -2291,6 +2625,13 @@ /obj/mecha/proc/give_power(amount) update_cell_alerts() + var/obj/item/mecha_parts/component/electrical/EC = internal_components[MECH_ELECTRIC] + + if(!EC) + amount /= 4 + else + amount *= EC.get_efficiency() + if(!isnull(get_charge())) cell.give(amount) return 1 @@ -2306,6 +2647,19 @@ //This is for mobs mostly. /obj/mecha/attack_generic(var/mob/user, var/damage, var/attack_message) + var/obj/item/mecha_parts/component/armor/ArmC = internal_components[MECH_ARMOR] + + var/temp_deflect_chance = deflect_chance + var/temp_damage_minimum = damage_minimum + + if(!ArmC) + temp_deflect_chance = 1 + temp_damage_minimum = 0 + + else + temp_deflect_chance = round(ArmC.get_efficiency() * ArmC.deflect_chance + (defence_mode ? 25 : 0)) + temp_damage_minimum = round(ArmC.get_efficiency() * ArmC.damage_minimum) + user.setClickCooldown(user.get_attack_speed()) if(!damage) return 0 @@ -2313,14 +2667,14 @@ src.log_message("Attacked. Attacker - [user].",1) user.do_attack_animation(src) - if(prob(src.deflect_chance))//Deflected + if(prob(temp_deflect_chance))//Deflected src.log_append_to_last("Armor saved.") src.occupant_message("\The [user]'s attack is stopped by the armor.") visible_message("\The [user] rebounds off [src.name]'s armor!") user.attack_log += text("\[[time_stamp()]\] attacked [src.name]") playsound(src, 'sound/weapons/slash.ogg', 50, 1, -1) - else if(damage < damage_minimum)//Pathetic damage levels just don't harm MECH. + else if(damage < temp_damage_minimum)//Pathetic damage levels just don't harm MECH. src.occupant_message("\The [user]'s doesn't dent \the [src] paint.") src.visible_message("\The [user]'s attack doesn't dent \the [src] armor") src.log_append_to_last("Armor saved.") diff --git a/code/game/mecha/mecha_actions.dm b/code/game/mecha/mecha_actions.dm index 33307c77d3..c70c3b9b83 100644 --- a/code/game/mecha/mecha_actions.dm +++ b/code/game/mecha/mecha_actions.dm @@ -3,7 +3,7 @@ //THIS FILE CONTAINS THE CODE TO ADD THE HUD BUTTONS AND THE MECH ACTIONS THEMSELVES. // // -// I better get some free food for this.. +// I better get some free food for this.. @@ -35,7 +35,9 @@ phasing_action.Grant(user, src) if(switch_dmg_type_possible) switch_damtype_action.Grant(user, src) - + if(cloak_possible) + cloak_action.Grant(user, src) + /obj/mecha/proc/RemoveActions(mob/living/user, human_occupant = 0) if(human_occupant) eject_action.Remove(user, src) @@ -51,8 +53,8 @@ thrusters_action.Remove(user, src) phasing_action.Remove(user, src) switch_damtype_action.Remove(user, src) - overload_action.Remove(user, src) - + overload_action.Remove(user, src) + cloak_action.Remove(user, src) // @@ -242,6 +244,15 @@ +/datum/action/innate/mecha/mech_toggle_cloaking + name = "Toggle Mech phasing" + button_icon_state = "mech_phasing_off" + +/datum/action/innate/mecha/mech_toggle_cloaking/Activate() + button_icon_state = "mech_phasing_[chassis.cloaked ? "off" : "on"]" + button.UpdateIcon() + chassis.toggle_cloaking() + ///// @@ -293,12 +304,10 @@ return if(overload) overload = 0 - step_in = initial(step_in) step_energy_drain = initial(step_energy_drain) src.occupant_message("You disable leg actuators overload.") else overload = 1 - step_in = min(1, round(step_in/2)) step_energy_drain = step_energy_drain*overload_coeff src.occupant_message("You enable leg actuators overload.") src.log_message("Toggled leg actuators overload.") @@ -324,7 +333,7 @@ if(smoke_ready) smoke_reserve-- //Remove ammo src.occupant_message("Smoke fired. [smoke_reserve] usages left.") - + var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread() smoke.attach(src) smoke.set_up(10, 0, usr.loc) @@ -422,6 +431,25 @@ return +/obj/mecha/verb/toggle_cloak() + set category = "Exosuit Interface" + set name = "Toggle cloaking" + set src = usr.loc + set popup_menu = 0 + toggle_cloaking() + +/obj/mecha/proc/toggle_cloaking() + if(usr!=src.occupant) + return + + if(cloaked) + uncloak() + else + cloak() + + src.occupant_message("En":"#f00\">Dis"]abled cloaking.") + return + /obj/mecha/verb/toggle_weapons_only_cycle() set category = "Exosuit Interface" set name = "Toggle weapons only cycling" @@ -435,4 +463,3 @@ weapons_only_cycle = !weapons_only_cycle src.occupant_message("En":"#f00\">Dis"]abled weapons only cycling.") return - diff --git a/code/game/mecha/medical/medical.dm b/code/game/mecha/medical/medical.dm index 6e9dee5047..973ddec3fc 100644 --- a/code/game/mecha/medical/medical.dm +++ b/code/game/mecha/medical/medical.dm @@ -9,6 +9,14 @@ cargo_capacity = 1 + starting_components = list( + /obj/item/mecha_parts/component/hull, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor/lightweight, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + /obj/mecha/medical/Initialize() . = ..() var/turf/T = get_turf(src) diff --git a/code/game/mecha/medical/odysseus.dm b/code/game/mecha/medical/odysseus.dm index 00be6d3c3f..dbba0cd251 100644 --- a/code/game/mecha/medical/odysseus.dm +++ b/code/game/mecha/medical/odysseus.dm @@ -1,4 +1,4 @@ -/obj/mecha/medical/odysseus/ +/obj/mecha/medical/odysseus desc = "These exosuits are developed and produced by Vey-Med. (© All rights reserved)." name = "Odysseus" catalogue_data = list( @@ -9,8 +9,8 @@ initial_icon = "odysseus" step_in = 2 max_temperature = 15000 - health = 120 - maxhealth = 120 + health = 70 + maxhealth = 70 wreckage = /obj/effect/decal/mecha_wreckage/odysseus internal_damage_threshold = 35 deflect_chance = 15 @@ -139,5 +139,5 @@ /obj/mecha/medical/odysseus/old/New() ..() health = 25 - maxhealth = 100 //Just slightly worse. + maxhealth = 50 //Just slightly worse. cell.charge = rand(0, (cell.charge/2)) \ No newline at end of file diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm index 5bfe3b4395..86405b6934 100644 --- a/code/game/mecha/working/ripley.dm +++ b/code/game/mecha/working/ripley.dm @@ -14,6 +14,14 @@ minimum_penetration = 10 + starting_components = list( + /obj/item/mecha_parts/component/hull/durable, + /obj/item/mecha_parts/component/actuator, + /obj/item/mecha_parts/component/armor/mining, + /obj/item/mecha_parts/component/gas, + /obj/item/mecha_parts/component/electrical + ) + /obj/mecha/working/ripley/Destroy() for(var/atom/movable/A in src.cargo) A.loc = loc diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 3ef882c381..96e4c87da3 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -199,6 +199,16 @@ /obj/item/weapon/storage/box/empshells/large starts_with = list(/obj/item/ammo_casing/a12g/emp = 16) +/obj/item/weapon/storage/box/flechetteshells + name = "box of shotgun flechettes" + desc = "It has a picture of a gun and several warning symbols on the front.
WARNING: Live ammunition. Misuse may result in serious injury or death." + icon_state = "lethalslug_box" + item_state_slots = list(slot_r_hand_str = "syringe_kit", slot_l_hand_str = "syringe_kit") + starts_with = list(/obj/item/ammo_casing/a12g/flechette = 8) + +/obj/item/weapon/storage/box/flechetteshells/large + starts_with = list(/obj/item/ammo_casing/a12g/flechette = 16) + /obj/item/weapon/storage/box/sniperammo name = "box of 14.5mm shells" desc = "It has a picture of a gun and several warning symbols on the front.
WARNING: Live ammunition. Misuse may result in serious injury or death." diff --git a/code/modules/mob/living/silicon/robot/analyzer.dm b/code/modules/mob/living/silicon/robot/analyzer.dm index f1b2d76eec..e946c7999c 100644 --- a/code/modules/mob/living/silicon/robot/analyzer.dm +++ b/code/modules/mob/living/silicon/robot/analyzer.dm @@ -34,6 +34,8 @@ scan_type = "robot" else if(istype(M, /mob/living/carbon/human)) scan_type = "prosthetics" + else if(istype(M, /obj/mecha)) + scan_type = "mecha" else to_chat(user, "You can't analyze non-robotic things!") return @@ -95,5 +97,37 @@ if(!organ_found) to_chat(user, "No prosthetics located.") + if("mecha") + + var/obj/mecha/Mecha = M + + var/integrity = Mecha.health/initial(Mecha.health)*100 + var/cell_charge = Mecha.get_charge() + var/tank_pressure = Mecha.internal_tank ? round(Mecha.internal_tank.return_pressure(),0.01) : "None" + var/tank_temperature = Mecha.internal_tank ? Mecha.internal_tank.return_temperature() : "Unknown" + var/cabin_pressure = round(Mecha.return_pressure(),0.01) + + var/output = {"Analyzing Results for \the [Mecha]:
+ Chassis Integrity: [integrity]%
+ Powercell charge: [isnull(cell_charge)?"No powercell installed":"[Mecha.cell.percent()]%"]
+ Air source: [Mecha.use_internal_tank?"Internal Airtank":"Environment"]
+ Airtank pressure: [tank_pressure]kPa
+ Airtank temperature: [tank_temperature]K|[tank_temperature - T0C]°C
+ Cabin pressure: [cabin_pressure>WARNING_HIGH_PRESSURE ? "[cabin_pressure]": cabin_pressure]kPa
+ Cabin temperature: [Mecha.return_temperature()]K|[Mecha.return_temperature() - T0C]°C
+ DNA Lock: [Mecha.dna?"Mecha.dna":"Not Found"]
+ "} + + to_chat(user, output) + to_chat(user, "
") + to_chat(user, "Internal Diagnostics:") + for(var/slot in Mecha.internal_components) + var/obj/item/mecha_parts/component/MC = Mecha.internal_components[slot] + to_chat(user, "[MC?"[slot]: [MC] [round((MC.integrity / MC.max_integrity) * 100, 0.1)]% integrity. [MC.get_efficiency() * 100] Operational capacity.":"[slot]: Component Not Found"]") + + to_chat(user, "
") + to_chat(user, "General Statistics:") + to_chat(user, "Movement Weight: [Mecha.get_step_delay()]
") + src.add_fingerprint(user) return diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm index 7ccdbfc9ba..1d08811bae 100644 --- a/code/modules/projectiles/ammunition/magazines.dm +++ b/code/modules/projectiles/ammunition/magazines.dm @@ -88,6 +88,10 @@ name = "magazine (.45 AP)" ammo_type = /obj/item/ammo_casing/a45/ap +/obj/item/ammo_magazine/m45/hp + name = "magazine (.45 HP)" + ammo_type = /obj/item/ammo_casing/a45/hp + /obj/item/ammo_magazine/box/emp/b45 name = "ammunition box (.45 haywire)" ammo_type = /obj/item/ammo_casing/a45/emp @@ -293,6 +297,11 @@ name = "top mounted magazine (9mm practice)" ammo_type = /obj/item/ammo_casing/a9mm/practice +/obj/item/ammo_magazine/m9mmt/ap + name = "top mounted magazine (9mm armor piercing)" + ammo_type = /obj/item/ammo_casing/a9mm/ap + matter = list(DEFAULT_WALL_MATERIAL = 1000, MAT_PLASTEEL = 2000) + /obj/item/ammo_magazine/m9mmp90 name = "large capacity top mounted magazine (9mm armor-piercing)" icon_state = "p90" diff --git a/code/modules/projectiles/ammunition/rounds.dm b/code/modules/projectiles/ammunition/rounds.dm index b83d7ad235..fa6c5d21aa 100644 --- a/code/modules/projectiles/ammunition/rounds.dm +++ b/code/modules/projectiles/ammunition/rounds.dm @@ -131,6 +131,7 @@ desc = "A .45 Armor-Piercing bullet casing." icon_state = "r-casing" projectile_type = /obj/item/projectile/bullet/pistol/medium/ap + matter = list(DEFAULT_WALL_MATERIAL = 50, MAT_PLASTEEL = 25) /obj/item/ammo_casing/a45/practice desc = "A .45 practice bullet casing." @@ -160,6 +161,7 @@ /obj/item/ammo_casing/a45/hp desc = "A .45 hollow-point bullet casing." projectile_type = /obj/item/projectile/bullet/pistol/medium/hp + matter = list(DEFAULT_WALL_MATERIAL = 60, MAT_PLASTIC = 15) /* * 10mm @@ -246,6 +248,14 @@ // projectile_type = /obj/item/projectile/bullet/shotgun/ion matter = list(DEFAULT_WALL_MATERIAL = 360, "uranium" = 240) +/obj/item/ammo_casing/a12g/flechette + name = "shotgun flechette" + desc = "A 12 gauge flechette cartidge, also known as nailshot." + icon_state = "slshell" + caliber = "12g" + projectile_type = /obj/item/projectile/scatter/flechette + matter = list(DEFAULT_WALL_MATERIAL = 360, MAT_PLASTEEL = 100) + /* * 7.62mm */ diff --git a/code/modules/projectiles/projectile/scatter.dm b/code/modules/projectiles/projectile/scatter.dm index 4b0511d0b4..b3900f8429 100644 --- a/code/modules/projectiles/projectile/scatter.dm +++ b/code/modules/projectiles/projectile/scatter.dm @@ -27,6 +27,10 @@ /obj/item/projectile/bullet/pellet/shotgun/flak = 3 ) +/* + * Energy + */ + /obj/item/projectile/scatter/laser damage = 40 @@ -61,6 +65,12 @@ /obj/item/projectile/bullet/shotgun/ion = 3 ) + +/* + * Flame + */ + + /obj/item/projectile/scatter/flamethrower damage = 5 submunition_spread_max = 100 @@ -70,3 +80,19 @@ submunitions = list( /obj/item/projectile/bullet/incendiary/flamethrower/tiny = 7 ) + + +/* + * Ballistic + */ + + +/obj/item/projectile/scatter/flechette + damage = 60 + + submunition_spread_max = 40 + submunition_spread_min = 10 + + submunitions = list( + /obj/item/projectile/bullet/magnetic/flechette/small = 4 + ) diff --git a/code/modules/research/circuitprinter.dm b/code/modules/research/circuitprinter.dm index 468c7ff6bb..d0aaebb7d8 100644 --- a/code/modules/research/circuitprinter.dm +++ b/code/modules/research/circuitprinter.dm @@ -16,7 +16,7 @@ using metal and glass, it uses glass and reagents (usually sulphuric acid). var/mat_efficiency = 1 var/speed = 1 - materials = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0, MAT_PLASTEEL = 0, "plastic" = 0, MAT_GRAPHITE, "gold" = 0, "silver" = 0, "osmium" = 0, MAT_LEAD = 0, "phoron" = 0, "uranium" = 0, "diamond" = 0, MAT_DURASTEEL = 0, MAT_VERDANTIUM = 0, MAT_MORPHIUM = 0, MAT_METALHYDROGEN = 0, MAT_SUPERMATTER = 0) + materials = list(DEFAULT_WALL_MATERIAL = 0, "glass" = 0, MAT_PLASTEEL = 0, "plastic" = 0, MAT_GRAPHITE = 0, "gold" = 0, "silver" = 0, "osmium" = 0, MAT_LEAD = 0, "phoron" = 0, "uranium" = 0, "diamond" = 0, MAT_DURASTEEL = 0, MAT_VERDANTIUM = 0, MAT_MORPHIUM = 0, MAT_METALHYDROGEN = 0, MAT_SUPERMATTER = 0) hidden_materials = list(MAT_PLASTEEL, MAT_DURASTEEL, MAT_GRAPHITE, MAT_VERDANTIUM, MAT_MORPHIUM, MAT_METALHYDROGEN, MAT_SUPERMATTER) diff --git a/code/modules/research/designs/circuits/circuits.dm b/code/modules/research/designs/circuits/circuits.dm index e2479a8e1c..425223ffe7 100644 --- a/code/modules/research/designs/circuits/circuits.dm +++ b/code/modules/research/designs/circuits/circuits.dm @@ -493,6 +493,8 @@ CIRCUITS BELOW name = "'Durand' central control" id = "durand_main" req_tech = list(TECH_DATA = 4) + materials = list("glass" = 2000, MAT_GRAPHITE = 1250) + chemicals = list("pacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/durand/main sort_string = "NAADA" @@ -500,6 +502,8 @@ CIRCUITS BELOW name = "'Durand' peripherals control" id = "durand_peri" req_tech = list(TECH_DATA = 4) + materials = list("glass" = 2000, MAT_GRAPHITE = 1250) + chemicals = list("pacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/durand/peripherals sort_string = "NAADB" @@ -507,6 +511,8 @@ CIRCUITS BELOW name = "'Durand' weapon control and targeting" id = "durand_targ" req_tech = list(TECH_DATA = 4, TECH_COMBAT = 2) + materials = list("glass" = 2000, MAT_GRAPHITE = 1250) + chemicals = list("pacid" = 20) build_path = /obj/item/weapon/circuitboard/mecha/durand/targeting sort_string = "NAADC" diff --git a/code/modules/research/designs/weapons.dm b/code/modules/research/designs/weapons.dm index 13d6036edd..f57b285118 100644 --- a/code/modules/research/designs/weapons.dm +++ b/code/modules/research/designs/weapons.dm @@ -100,14 +100,23 @@ sort_string = "MABBA" /datum/design/item/weapon/ballistic/ammo/stunshell - name = "stun shell" + name = "stun shells" desc = "A stunning shell for a shotgun." id = "stunshell" req_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 3) materials = list(DEFAULT_WALL_MATERIAL = 4000) - build_path = /obj/item/ammo_casing/a12g/stunshell + build_path = /obj/item/weapon/storage/box/stunshells sort_string = "MABBB" +/datum/design/item/weapon/ballistic/ammo/empshell + name = "emp shells" + desc = "An electromagnetic shell for a shotgun." + id = "empshell" + req_tech = list(TECH_COMBAT = 4, TECH_MAGNET = 3) + materials = list(DEFAULT_WALL_MATERIAL = 4000, MAT_URANIUM = 1000) + build_path = /obj/item/weapon/storage/box/empshells + sort_string = "MABBC" + // Phase weapons /datum/design/item/weapon/phase/AssembleDesignName() diff --git a/code/modules/research/mechfab_designs.dm b/code/modules/research/mechfab_designs.dm index 7316c42179..899b5fd9db 100644 --- a/code/modules/research/mechfab_designs.dm +++ b/code/modules/research/mechfab_designs.dm @@ -177,57 +177,57 @@ name = "Durand Chassis" id = "durand_chassis" build_path = /obj/item/mecha_parts/chassis/durand - time = 10 - materials = list(DEFAULT_WALL_MATERIAL = 18750) + time = 20 + materials = list(DEFAULT_WALL_MATERIAL = 18750, MAT_PLASTEEL = 20000) /datum/design/item/mechfab/durand/torso name = "Durand Torso" id = "durand_torso" build_path = /obj/item/mecha_parts/part/durand_torso - time = 30 - materials = list(DEFAULT_WALL_MATERIAL = 41250, "glass" = 15000, "silver" = 7500) + time = 60 + materials = list(DEFAULT_WALL_MATERIAL = 41250, MAT_PLASTEEL = 15000, "silver" = 7500) /datum/design/item/mechfab/durand/head name = "Durand Head" id = "durand_head" build_path = /obj/item/mecha_parts/part/durand_head - time = 20 + time = 40 materials = list(DEFAULT_WALL_MATERIAL = 18750, "glass" = 7500, "silver" = 2250) /datum/design/item/mechfab/durand/left_arm name = "Durand Left Arm" id = "durand_left_arm" build_path = /obj/item/mecha_parts/part/durand_left_arm - time = 20 + time = 40 materials = list(DEFAULT_WALL_MATERIAL = 26250, "silver" = 2250) /datum/design/item/mechfab/durand/right_arm name = "Durand Right Arm" id = "durand_right_arm" build_path = /obj/item/mecha_parts/part/durand_right_arm - time = 20 + time = 40 materials = list(DEFAULT_WALL_MATERIAL = 26250, "silver" = 2250) /datum/design/item/mechfab/durand/left_leg name = "Durand Left Leg" id = "durand_left_leg" build_path = /obj/item/mecha_parts/part/durand_left_leg - time = 20 + time = 40 materials = list(DEFAULT_WALL_MATERIAL = 30000, "silver" = 2250) /datum/design/item/mechfab/durand/right_leg name = "Durand Right Leg" id = "durand_right_leg" build_path = /obj/item/mecha_parts/part/durand_right_leg - time = 20 + time = 40 materials = list(DEFAULT_WALL_MATERIAL = 30000, "silver" = 2250) /datum/design/item/mechfab/durand/armour name = "Durand Armour Plates" id = "durand_armour" build_path = /obj/item/mecha_parts/part/durand_armour - time = 60 - materials = list(DEFAULT_WALL_MATERIAL = 37500, "uranium" = 7500) + time = 90 + materials = list(DEFAULT_WALL_MATERIAL = 27500, MAT_PLASTEEL = 10000, "uranium" = 7500) /datum/design/item/mechfab/janus category = "Janus" @@ -1038,4 +1038,151 @@ time = 20 req_tech = list(TECH_MATERIAL = 6, TECH_ENGINEERING = 5, TECH_PHORON = 3, TECH_MAGNET = 4, TECH_POWER = 6) materials = list(DEFAULT_WALL_MATERIAL = 10000, "glass" = 6000, "silver" = 4000) - \ No newline at end of file + +// Exosuit Internals + +/datum/design/item/mechfab/exointernal + category = "Exosuit Internals" + time = 120 + req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 3) + +/datum/design/item/mechfab/exointernal/stan_armor + name = "Armor Plate (Standard)" + category = "Exosuit Internals" + id = "exo_int_armor_standard" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 10000) + build_path = /obj/item/mecha_parts/component/armor + +/datum/design/item/mechfab/exointernal/light_armor + name = "Armor Plate (Lightweight)" + category = "Exosuit Internals" + id = "exo_int_armor_lightweight" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 3) + materials = list(DEFAULT_WALL_MATERIAL = 5000, MAT_PLASTIC = 3000) + build_path = /obj/item/mecha_parts/component/armor/lightweight + +/datum/design/item/mechfab/exointernal/reinf_armor + name = "Armor Plate (Reinforced)" + category = "Exosuit Internals" + id = "exo_int_armor_reinforced" + req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4) + materials = list(DEFAULT_WALL_MATERIAL = 20000, MAT_PLASTEEL = 10000) + build_path = /obj/item/mecha_parts/component/armor/reinforced + +/datum/design/item/mechfab/exointernal/mining_armor + name = "Armor Plate (Blast)" + category = "Exosuit Internals" + id = "exo_int_armor_blast" + req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4) + materials = list(DEFAULT_WALL_MATERIAL = 20000, MAT_PLASTEEL = 10000) + build_path = /obj/item/mecha_parts/component/armor/mining + +/datum/design/item/mechfab/exointernal/gygax_armor + name = "Armor Plate (Marshal)" + category = "Exosuit Internals" + id = "exo_int_armor_gygax" + req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_COMBAT = 2) + materials = list(DEFAULT_WALL_MATERIAL = 40000, MAT_DIAMOND = 8000) + build_path = /obj/item/mecha_parts/component/armor/marshal + +/datum/design/item/mechfab/exointernal/darkgygax_armor + name = "Armor Plate (Blackops)" + category = "Exosuit Internals" + id = "exo_int_armor_dgygax" + req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 5, TECH_COMBAT = 4, TECH_ILLEGAL = 2) + materials = list(MAT_PLASTEEL = 20000, MAT_DIAMOND = 10000, MAT_GRAPHITE = 20000) + build_path = /obj/item/mecha_parts/component/armor/marshal/reinforced + +/datum/design/item/mechfab/exointernal/durand_armour + name = "Armor Plate (Military)" + id = "exo_int_armor_durand" + req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_COMBAT = 2) + materials = list(DEFAULT_WALL_MATERIAL = 40000, MAT_PLASTEEL = 9525, "uranium" = 8000) + build_path = /obj/item/mecha_parts/component/armor/military + +/datum/design/item/mechfab/exointernal/marauder_armour + name = "Armor Plate (Cutting Edge)" + id = "exo_int_armor_marauder" + req_tech = list(TECH_MATERIAL = 8, TECH_ENGINEERING = 7, TECH_COMBAT = 6, TECH_ILLEGAL = 4) + materials = list(MAT_DURASTEEL = 40000, MAT_GRAPHITE = 8000, MAT_OSMIUM = 8000) + build_path = /obj/item/mecha_parts/component/armor/military/marauder + +/datum/design/item/mechfab/exointernal/phazon_armour + name = "Armor Plate (Janus)" + id = "exo_int_armor_phazon" + req_tech = list(TECH_MATERIAL = 6, TECH_ENGINEERING = 6, TECH_COMBAT = 6, TECH_ILLEGAL = 4) + materials = list(MAT_MORPHIUM = 40000, MAT_DURASTEEL = 8000, MAT_OSMIUM = 8000) + build_path = /obj/item/mecha_parts/component/armor/alien + +/datum/design/item/mechfab/exointernal/stan_hull + name = "Hull (Standard)" + category = "Exosuit Internals" + id = "exo_int_hull_standard" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 10000) + build_path = /obj/item/mecha_parts/component/hull + +/datum/design/item/mechfab/exointernal/durable_hull + name = "Hull (Durable)" + category = "Exosuit Internals" + id = "exo_int_hull_durable" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 8000, MAT_PLASTEEL = 5000) + build_path = /obj/item/mecha_parts/component/hull/durable + +/datum/design/item/mechfab/exointernal/light_hull + name = "Hull (Lightweight)" + category = "Exosuit Internals" + id = "exo_int_hull_light" + req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 4) + materials = list(DEFAULT_WALL_MATERIAL = 5000, MAT_PLASTIC = 3000) + build_path = /obj/item/mecha_parts/component/hull/lightweight + +/datum/design/item/mechfab/exointernal/stan_gas + name = "Life-Support (Standard)" + category = "Exosuit Internals" + id = "exo_int_lifesup_standard" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 10000) + build_path = /obj/item/mecha_parts/component/gas + +/datum/design/item/mechfab/exointernal/reinf_gas + name = "Life-Support (Reinforced)" + category = "Exosuit Internals" + id = "exo_int_lifesup_reinforced" + req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 4) + materials = list(DEFAULT_WALL_MATERIAL = 8000, MAT_PLASTEEL = 8000, MAT_GRAPHITE = 1000) + build_path = /obj/item/mecha_parts/component/gas/reinforced + +/datum/design/item/mechfab/exointernal/stan_electric + name = "Electrical Harness (Standard)" + category = "Exosuit Internals" + id = "exo_int_electric_standard" + req_tech = list(TECH_POWER = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000, MAT_PLASTIC = 1000) + build_path = /obj/item/mecha_parts/component/electrical + +/datum/design/item/mechfab/exointernal/efficient_electric + name = "Electrical Harness (High)" + category = "Exosuit Internals" + id = "exo_int_electric_efficient" + req_tech = list(TECH_POWER = 4, TECH_ENGINEERING = 4, TECH_DATA = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000, MAT_PLASTIC = 3000, MAT_SILVER = 3000) + build_path = /obj/item/mecha_parts/component/electrical/high_current + +/datum/design/item/mechfab/exointernal/stan_actuator + name = "Actuator Lattice (Standard)" + category = "Exosuit Internals" + id = "exo_int_actuator_standard" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 10000) + build_path = /obj/item/mecha_parts/component/actuator + +/datum/design/item/mechfab/exointernal/hispeed_actuator + name = "Actuator Lattice (Overclocked)" + category = "Exosuit Internals" + id = "exo_int_actuator_overclock" + req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_POWER = 4) + materials = list(MAT_PLASTEEL = 10000, MAT_OSMIUM = 3000, MAT_GOLD = 5000) + build_path = /obj/item/mecha_parts/component/actuator/hispeed \ No newline at end of file diff --git a/html/changelogs/mechoid - exointernals.yml b/html/changelogs/mechoid - exointernals.yml new file mode 100644 index 0000000000..dd25e29efb --- /dev/null +++ b/html/changelogs/mechoid - exointernals.yml @@ -0,0 +1,39 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +################################# + +# Your name. +author: Mechoid + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Exosuits now have internal components." + - rscadd: "Autolathes can use plastic and plasteel." + - rscadd: "Autolathes can have tiered recipes, based on their manipulator rating." + - tweak: "Exosuit base health has been lowered due to the changes to damage processing." diff --git a/icons/effects/actions_mecha.dmi b/icons/effects/actions_mecha.dmi index 0a505767a3..882ceb534f 100644 Binary files a/icons/effects/actions_mecha.dmi and b/icons/effects/actions_mecha.dmi differ diff --git a/icons/mecha/mech_component.dmi b/icons/mecha/mech_component.dmi new file mode 100644 index 0000000000..c23c2d81e1 Binary files /dev/null and b/icons/mecha/mech_component.dmi differ diff --git a/vorestation.dme b/vorestation.dme index 7772b2ebf9..1ba2305d3d 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -941,6 +941,12 @@ #include "code\game\mecha\combat\gygax.dm" #include "code\game\mecha\combat\marauder.dm" #include "code\game\mecha\combat\phazon.dm" +#include "code\game\mecha\components\_component.dm" +#include "code\game\mecha\components\actuators.dm" +#include "code\game\mecha\components\armor.dm" +#include "code\game\mecha\components\electrical.dm" +#include "code\game\mecha\components\hull.dm" +#include "code\game\mecha\components\lifesupport.dm" #include "code\game\mecha\equipment\mecha_equipment.dm" #include "code\game\mecha\equipment\mecha_equipment_dynamicprocs.dm" #include "code\game\mecha\equipment\tools\armor_melee.dm"