diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm index 5d692b39b9..54e2b9c87b 100644 --- a/code/game/mecha/combat/combat.dm +++ b/code/game/mecha/combat/combat.dm @@ -10,6 +10,13 @@ damage_absorption = list("brute"=0.7,"fire"=1,"bullet"=0.7,"laser"=0.85,"energy"=1,"bomb"=0.8) var/am = "d3c2fbcadca903a41161ccc9df9cf948" + max_hull_equip = 2 + max_weapon_equip = 2 + max_utility_equip = 1 + max_universal_equip = 1 + max_special_equip = 1 + cargo_capacity = 1 + /* /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 2d3034573a..7b9eb67691 100644 --- a/code/game/mecha/combat/durand.dm +++ b/code/game/mecha/combat/durand.dm @@ -6,6 +6,7 @@ step_in = 4 dir_in = 1 //Facing North. health = 400 + maxhealth = 400 deflect_chance = 20 damage_absorption = list("brute"=0.5,"fire"=1.1,"bullet"=0.65,"laser"=0.85,"energy"=0.9,"bomb"=0.8) max_temperature = 30000 @@ -15,6 +16,12 @@ var/defence_deflect = 35 wreckage = /obj/effect/decal/mecha_wreckage/durand + max_hull_equip = 2 + max_weapon_equip = 1 + max_utility_equip = 2 + max_universal_equip = 1 + max_special_equip = 1 + /* /obj/mecha/combat/durand/New() ..() diff --git a/code/game/mecha/combat/gorilla.dm b/code/game/mecha/combat/gorilla.dm index cc5dacebc3..100bae9f19 100644 --- a/code/game/mecha/combat/gorilla.dm +++ b/code/game/mecha/combat/gorilla.dm @@ -64,6 +64,7 @@ pixel_x = -16 step_in = 10 health = 5000 + maxhealth = 5000 opacity = 0 // Because there's big tall legs to look through. Also it looks fucky if this is set to 1. deflect_chance = 50 damage_absorption = list("brute"=0.1,"fire"=0.8,"bullet"=0.1,"laser"=0.6,"energy"=0.7,"bomb"=0.7) //values show how much damage will pass through, not how much will be absorbed. @@ -79,6 +80,12 @@ internal_damage_threshold = 25 force = 60 max_equip = 5 +//This will (Should) never be in the hands of players. If it is, the one who inflicted this monster upon the server can edit these vars to not be insane. + max_hull_equip = 5 + max_weapon_equip = 5 + max_utility_equip = 5 + max_universal_equip = 5 + max_special_equip = 2 /obj/mecha/combat/gorilla/New() ..() diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index eadc96aadd..22b52e6203 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -6,6 +6,7 @@ step_in = 3 dir_in = 1 //Facing North. health = 300 + maxhealth = 300 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 @@ -16,12 +17,19 @@ internal_damage_threshold = 35 max_equip = 3 + max_hull_equip = 1 + max_weapon_equip = 2 + max_utility_equip = 2 + max_universal_equip = 1 + max_special_equip = 1 + /obj/mecha/combat/gygax/dark desc = "A lightweight exosuit used by Heavy Asset Protection. A significantly upgraded Gygax security mech." name = "Dark Gygax" icon_state = "darkgygax" initial_icon = "darkgygax" health = 400 + maxhealth = 400 deflect_chance = 25 damage_absorption = list("brute"=0.6,"fire"=0.8,"bullet"=0.6,"laser"=0.5,"energy"=0.65,"bomb"=0.8) max_temperature = 45000 @@ -30,6 +38,12 @@ max_equip = 4 step_energy_drain = 5 + max_hull_equip = 1 + max_weapon_equip = 2 + max_utility_equip = 2 + max_universal_equip = 1 + max_special_equip = 2 + /obj/mecha/combat/gygax/dark/New() ..() var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm index 5b456e0900..3236600309 100644 --- a/code/game/mecha/combat/marauder.dm +++ b/code/game/mecha/combat/marauder.dm @@ -5,6 +5,7 @@ initial_icon = "marauder" step_in = 5 health = 500 + maxhealth = 500 deflect_chance = 25 damage_absorption = list("brute"=0.5,"fire"=0.7,"bullet"=0.45,"laser"=0.6,"energy"=0.7,"bomb"=0.7) max_temperature = 60000 @@ -22,6 +23,12 @@ force = 45 max_equip = 4 + max_hull_equip = 3 + max_weapon_equip = 3 + max_utility_equip = 3 + max_universal_equip = 1 + max_special_equip = 1 + /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" @@ -62,7 +69,7 @@ var/obj/item/mecha_parts/mecha_equipment/ME if(equipment.len)//Now to remove it and equip anew. for(ME in equipment) - equipment -= ME + ME.detach() qdel(ME) ME = new /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot(src) ME.attach(src) diff --git a/code/game/mecha/combat/phazon.dm b/code/game/mecha/combat/phazon.dm index b98f4697e5..77ce768fc8 100644 --- a/code/game/mecha/combat/phazon.dm +++ b/code/game/mecha/combat/phazon.dm @@ -7,6 +7,7 @@ dir_in = 1 //Facing North. step_energy_drain = 3 health = 200 + maxhealth = 200 deflect_chance = 30 damage_absorption = list("brute"=0.7,"fire"=0.7,"bullet"=0.7,"laser"=0.7,"energy"=0.7,"bomb"=0.7) max_temperature = 25000 @@ -20,6 +21,11 @@ var/phasing_energy_drain = 200 max_equip = 4 + max_hull_equip = 3 + max_weapon_equip = 3 + max_utility_equip = 3 + max_universal_equip = 3 + max_special_equip = 4 /obj/mecha/combat/phazon/New() ..() diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index db1cb3d004..1c1bfdff22 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -1,5 +1,9 @@ //DO NOT ADD MECHA PARTS TO THE GAME WITH THE DEFAULT "SPRITE ME" SPRITE! //I'm annoyed I even have to tell you this! SPRITE FIRST, then commit. +#define EQUIP_HULL 1 +#define EQUIP_WEAPON 2 +#define EQUIP_UTILITY 3 +#define EQUIP_SPECIAL 4 /obj/item/mecha_parts/mecha_equipment name = "mecha equipment" @@ -14,7 +18,7 @@ var/range = MELEE //bitflags var/salvageable = 1 var/required_type = /obj/mecha //may be either a type or a list of allowed types - + var/equip_type = null //mechaequip2 /obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(target=1) sleep(equip_cooldown) @@ -43,6 +47,20 @@ /obj/item/mecha_parts/mecha_equipment/proc/destroy()//missiles detonating, teleporter creating singularity? if(chassis) + if(equip_type) + if(equip_type == EQUIP_HULL) + chassis.hull_equipment -= src + listclearnulls(chassis.hull_equipment) + if(equip_type == EQUIP_WEAPON) + chassis.weapon_equipment -= src + listclearnulls(chassis.weapon_equipment) + if(equip_type == EQUIP_UTILITY) + chassis.utility_equipment -= src + listclearnulls(chassis.utility_equipment) + if(equip_type == EQUIP_SPECIAL) + chassis.special_equipment -= src + listclearnulls(chassis.special_equipment) + chassis.universal_equipment -= src chassis.equipment -= src listclearnulls(chassis.equipment) if(chassis.selected == src) @@ -89,19 +107,49 @@ return /obj/item/mecha_parts/mecha_equipment/proc/can_attach(obj/mecha/M as obj) - if(M.equipment.len >= M.max_equip) - return 0 - - if (ispath(required_type)) + //if(M.equipment.len >= M.max_equip) + // return 0 + for(var/obj/item/mecha_parts/mecha_equipment/ME in M.equipment) //Exact duplicate components aren't allowed. + if(ME.type == src.type) + return 0 + if(equip_type == EQUIP_HULL && M.hull_equipment.len < M.max_hull_equip) + return 1 + if(equip_type == EQUIP_WEAPON && M.weapon_equipment.len < M.max_weapon_equip) + return 1 + if(equip_type == EQUIP_UTILITY && M.utility_equipment.len < M.max_utility_equip) + return 1 + if(equip_type == EQUIP_SPECIAL && M.special_equipment.len < M.max_special_equip) + return 1 + if(equip_type != EQUIP_SPECIAL && M.universal_equipment.len < M.max_universal_equip) //The exosuit needs to be military grade to actually have a universal slot capable of accepting a true weapon. + if(equip_type == EQUIP_WEAPON && !istype(M, /obj/mecha/combat)) + return 0 + return 1 + /*if (ispath(required_type)) return istype(M, required_type) for (var/path in required_type) if (istype(M, path)) return 1 - + */ return 0 /obj/item/mecha_parts/mecha_equipment/proc/attach(obj/mecha/M as obj) + //M.equipment += src + var/has_equipped = 0 + if(equip_type == EQUIP_HULL && M.hull_equipment.len < M.max_hull_equip && !has_equipped) + M.hull_equipment += src + has_equipped = 1 + if(equip_type == EQUIP_WEAPON && M.weapon_equipment.len < M.max_weapon_equip && !has_equipped) + M.weapon_equipment += src + has_equipped = 1 + if(equip_type == EQUIP_UTILITY && M.utility_equipment.len < M.max_utility_equip && !has_equipped) + M.utility_equipment += src + has_equipped = 1 + if(equip_type == EQUIP_SPECIAL && M.special_equipment.len < M.max_special_equip && !has_equipped) + M.special_equipment += src + has_equipped = 1 + if(equip_type != EQUIP_SPECIAL && M.universal_equipment.len < M.max_universal_equip && !has_equipped) + M.universal_equipment += src M.equipment += src chassis = M src.loc = M @@ -115,6 +163,17 @@ moveto = moveto || get_turf(chassis) if(src.Move(moveto)) chassis.equipment -= src + chassis.universal_equipment -= src + if(equip_type) + switch(equip_type) + if(EQUIP_HULL) + chassis.hull_equipment -= src + if(EQUIP_WEAPON) + chassis.weapon_equipment -= src + if(EQUIP_UTILITY) + chassis.utility_equipment -= src + if(EQUIP_SPECIAL) + chassis.special_equipment -= src if(chassis.selected == src) chassis.selected = null update_chassis_page() diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm index f06cf40da2..70edf23665 100644 --- a/code/game/mecha/equipment/tools/medical_tools.dm +++ b/code/game/mecha/equipment/tools/medical_tools.dm @@ -13,196 +13,196 @@ required_type = /obj/mecha/medical salvageable = 0 - New() - ..() - pr_mech_sleeper = new /datum/global_iterator/mech_sleeper(list(src),0) - pr_mech_sleeper.set_delay(equip_cooldown) +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/New() + ..() + pr_mech_sleeper = new /datum/global_iterator/mech_sleeper(list(src),0) + pr_mech_sleeper.set_delay(equip_cooldown) + return + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/Destroy() + qdel(pr_mech_sleeper) + for(var/atom/movable/AM in src) + AM.forceMove(get_turf(src)) + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/Exit(atom/movable/O) + return 0 + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/action(var/mob/living/carbon/human/target) + if(!action_checks(target)) return - - Destroy() - qdel(pr_mech_sleeper) - for(var/atom/movable/AM in src) - AM.forceMove(get_turf(src)) - return ..() - - Exit(atom/movable/O) - return 0 - - action(var/mob/living/carbon/human/target) - if(!action_checks(target)) + if(!istype(target)) + return + if(target.buckled) + occupant_message("[target] will not fit into the sleeper because they are buckled to [target.buckled].") + return + if(occupant) + occupant_message("The sleeper is already occupied") + return + for(var/mob/living/simple_animal/slime/M in range(1,target)) + if(M.victim == target) + occupant_message("[target] will not fit into the sleeper because they have a slime latched onto their head.") return - if(!istype(target)) - return - if(target.buckled) - occupant_message("[target] will not fit into the sleeper because they are buckled to [target.buckled].") + occupant_message("You start putting [target] into [src].") + chassis.visible_message("[chassis] starts putting [target] into the [src].") + var/C = chassis.loc + var/T = target.loc + if(do_after_cooldown(target)) + if(chassis.loc!=C || target.loc!=T) return if(occupant) - occupant_message("The sleeper is already occupied") + occupant_message("The sleeper is already occupied!") return - for(var/mob/living/simple_animal/slime/M in range(1,target)) - if(M.victim == target) - occupant_message("[target] will not fit into the sleeper because they have a slime latched onto their head.") - return - occupant_message("You start putting [target] into [src].") - chassis.visible_message("[chassis] starts putting [target] into the [src].") - var/C = chassis.loc - var/T = target.loc - if(do_after_cooldown(target)) - if(chassis.loc!=C || target.loc!=T) - return - if(occupant) - occupant_message("The sleeper is already occupied!") - return - target.forceMove(src) - occupant = target - target.reset_view(src) - occupant.Stasis(3) - /* - if(target.client) - target.client.perspective = EYE_PERSPECTIVE - target.client.eye = chassis - */ - set_ready_state(0) - pr_mech_sleeper.start() - occupant_message("[target] successfully loaded into [src]. Life support functions engaged.") - chassis.visible_message("[chassis] loads [target] into [src].") - log_message("[target] loaded. Life support functions engaged.") - return - - proc/go_out() - if(!occupant) - return - occupant.forceMove(get_turf(src)) - occupant_message("[occupant] ejected. Life support functions disabled.") - log_message("[occupant] ejected. Life support functions disabled.") - occupant.reset_view() + target.forceMove(src) + occupant = target + target.reset_view(src) + occupant.Stasis(3) /* - if(occupant.client) - occupant.client.eye = occupant.client.mob - occupant.client.perspective = MOB_PERSPECTIVE + if(target.client) + target.client.perspective = EYE_PERSPECTIVE + target.client.eye = chassis */ - occupant.Stasis(0) - occupant = null - pr_mech_sleeper.stop() - set_ready_state(1) - return + set_ready_state(0) + pr_mech_sleeper.start() + occupant_message("[target] successfully loaded into [src]. Life support functions engaged.") + chassis.visible_message("[chassis] loads [target] into [src].") + log_message("[target] loaded. Life support functions engaged.") + return - detach() +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/proc/go_out() + if(!occupant) + return + occupant.forceMove(get_turf(src)) + occupant_message("[occupant] ejected. Life support functions disabled.") + log_message("[occupant] ejected. Life support functions disabled.") + occupant.reset_view() + /* + if(occupant.client) + occupant.client.eye = occupant.client.mob + occupant.client.perspective = MOB_PERSPECTIVE + */ + occupant.Stasis(0) + occupant = null + pr_mech_sleeper.stop() + set_ready_state(1) + return + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/detach() + if(occupant) + occupant_message("Unable to detach [src] - equipment occupied.") + return + pr_mech_sleeper.stop() + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/get_equip_info() + var/output = ..() + if(output) + var/temp = "" if(occupant) - occupant_message("Unable to detach [src] - equipment occupied.") - return - pr_mech_sleeper.stop() - return ..() + temp = "
\[Occupant: [occupant] (Health: [occupant.health]%)\]
View stats|Eject" + return "[output] [temp]" + return - get_equip_info() - var/output = ..() - if(output) - var/temp = "" - if(occupant) - temp = "
\[Occupant: [occupant] (Health: [occupant.health]%)\]
View stats|Eject" - return "[output] [temp]" +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/Topic(href,href_list) + ..() + var/datum/topic_input/top_filter = new /datum/topic_input(href,href_list) + if(top_filter.get("eject")) + go_out() + if(top_filter.get("view_stats")) + chassis.occupant << browse(get_occupant_stats(),"window=msleeper") + onclose(chassis.occupant, "msleeper") return + if(top_filter.get("inject")) + inject_reagent(top_filter.getType("inject",/datum/reagent),top_filter.getObj("source")) + return - Topic(href,href_list) - ..() - var/datum/topic_input/top_filter = new /datum/topic_input(href,href_list) - if(top_filter.get("eject")) - go_out() - if(top_filter.get("view_stats")) - chassis.occupant << browse(get_occupant_stats(),"window=msleeper") - onclose(chassis.occupant, "msleeper") - return - if(top_filter.get("inject")) - inject_reagent(top_filter.getType("inject",/datum/reagent),top_filter.getObj("source")) +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/proc/get_occupant_stats() + if(!occupant) return + return {" + + [occupant] statistics + + + + +

Health statistics

+
+ [get_occupant_dam()] +
+

Reagents in bloodstream

+
+ [get_occupant_reagents()] +
+
+ [get_available_reagents()] +
+ + "} - proc/get_occupant_stats() - if(!occupant) - return - return {" - - [occupant] statistics - - - - -

Health statistics

-
- [get_occupant_dam()] -
-

Reagents in bloodstream

-
- [get_occupant_reagents()] -
-
- [get_available_reagents()] -
- - "} - - proc/get_occupant_dam() - var/t1 - switch(occupant.stat) - if(0) - t1 = "Conscious" - if(1) - t1 = "Unconscious" - if(2) - t1 = "*dead*" - else - t1 = "Unknown" - return {"Health: [occupant.health]% ([t1])
- Core Temperature: [src.occupant.bodytemperature-T0C]°C ([src.occupant.bodytemperature*1.8-459.67]°F)
- Brute Damage: [occupant.getBruteLoss()]%
- Respiratory Damage: [occupant.getOxyLoss()]%
- Toxin Content: [occupant.getToxLoss()]%
- Burn Severity: [occupant.getFireLoss()]%
- "} - - proc/get_occupant_reagents() - if(occupant.reagents) - for(var/datum/reagent/R in occupant.reagents.reagent_list) - if(R.volume > 0) - . += "[R]: [round(R.volume,0.01)]
" - return . || "None" - - proc/get_available_reagents() - var/output - var/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/SG = locate(/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun) in chassis - if(SG && SG.reagents && islist(SG.reagents.reagent_list)) - for(var/datum/reagent/R in SG.reagents.reagent_list) - if(R.volume > 0) - output += "Inject [R.name]
" - return output - - - proc/inject_reagent(var/datum/reagent/R,var/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/SG) - if(!R || !occupant || !SG || !(SG in chassis.equipment)) - return 0 - var/to_inject = min(R.volume, inject_amount) - if(to_inject && occupant.reagents.get_reagent_amount(R.id) + to_inject > inject_amount*4) - occupant_message("Sleeper safeties prohibit you from injecting more than [inject_amount*4] units of [R.name].") +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/proc/get_occupant_dam() + var/t1 + switch(occupant.stat) + if(0) + t1 = "Conscious" + if(1) + t1 = "Unconscious" + if(2) + t1 = "*dead*" else - occupant_message("Injecting [occupant] with [to_inject] units of [R.name].") - log_message("Injecting [occupant] with [to_inject] units of [R.name].") - //SG.reagents.trans_id_to(occupant,R.id,to_inject) - SG.reagents.remove_reagent(R.id,to_inject) - occupant.reagents.add_reagent(R.id,to_inject) - update_equip_info() - return + t1 = "Unknown" + return {"Health: [occupant.health]% ([t1])
+ Core Temperature: [src.occupant.bodytemperature-T0C]°C ([src.occupant.bodytemperature*1.8-459.67]°F)
+ Brute Damage: [occupant.getBruteLoss()]%
+ Respiratory Damage: [occupant.getOxyLoss()]%
+ Toxin Content: [occupant.getToxLoss()]%
+ Burn Severity: [occupant.getFireLoss()]%
+ "} - update_equip_info() - if(..()) - send_byjax(chassis.occupant,"msleeper.browser","lossinfo",get_occupant_dam()) - send_byjax(chassis.occupant,"msleeper.browser","reagents",get_occupant_reagents()) - send_byjax(chassis.occupant,"msleeper.browser","injectwith",get_available_reagents()) - return 1 - return +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/proc/get_occupant_reagents() + if(occupant.reagents) + for(var/datum/reagent/R in occupant.reagents.reagent_list) + if(R.volume > 0) + . += "[R]: [round(R.volume,0.01)]
" + return . || "None" + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/proc/get_available_reagents() + var/output + var/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/SG = locate(/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun) in chassis + if(SG && SG.reagents && islist(SG.reagents.reagent_list)) + for(var/datum/reagent/R in SG.reagents.reagent_list) + if(R.volume > 0) + output += "Inject [R.name]
" + return output + + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/proc/inject_reagent(var/datum/reagent/R,var/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/SG) + if(!R || !occupant || !SG || !(SG in chassis.equipment)) + return 0 + var/to_inject = min(R.volume, inject_amount) + if(to_inject && occupant.reagents.get_reagent_amount(R.id) + to_inject > inject_amount*4) + occupant_message("Sleeper safeties prohibit you from injecting more than [inject_amount*4] units of [R.name].") + else + occupant_message("Injecting [occupant] with [to_inject] units of [R.name].") + log_message("Injecting [occupant] with [to_inject] units of [R.name].") + //SG.reagents.trans_id_to(occupant,R.id,to_inject) + SG.reagents.remove_reagent(R.id,to_inject) + occupant.reagents.add_reagent(R.id,to_inject) + update_equip_info() + return + +/obj/item/mecha_parts/mecha_equipment/tool/sleeper/update_equip_info() + if(..()) + send_byjax(chassis.occupant,"msleeper.browser","lossinfo",get_occupant_dam()) + send_byjax(chassis.occupant,"msleeper.browser","reagents",get_occupant_reagents()) + send_byjax(chassis.occupant,"msleeper.browser","injectwith",get_available_reagents()) + return 1 + return /obj/item/mecha_parts/mecha_equipment/tool/sleeper/verb/eject() set name = "Sleeper Eject" @@ -219,32 +219,32 @@ /datum/global_iterator/mech_sleeper - process(var/obj/item/mecha_parts/mecha_equipment/tool/sleeper/S) - if(!S.chassis) - S.set_ready_state(1) - return stop() - if(!S.chassis.has_charge(S.energy_drain)) - S.set_ready_state(1) - S.log_message("Deactivated.") - S.occupant_message("[src] deactivated - no power.") - return stop() - var/mob/living/carbon/M = S.occupant - if(!M) - return - if(M.health > 0) - M.adjustOxyLoss(-1) - M.updatehealth() - M.AdjustStunned(-4) - M.AdjustWeakened(-4) - M.AdjustStunned(-4) - M.Paralyse(2) - M.Weaken(2) - M.Stun(2) - if(M.reagents.get_reagent_amount("inaprovaline") < 5) - M.reagents.add_reagent("inaprovaline", 5) - S.chassis.use_power(S.energy_drain) - S.update_equip_info() +/datum/global_iterator/mech_sleeper/process(var/obj/item/mecha_parts/mecha_equipment/tool/sleeper/S) + if(!S.chassis) + S.set_ready_state(1) + return stop() + if(!S.chassis.has_charge(S.energy_drain)) + S.set_ready_state(1) + S.log_message("Deactivated.") + S.occupant_message("[src] deactivated - no power.") + return stop() + var/mob/living/carbon/M = S.occupant + if(!M) return + if(M.health > 0) + M.adjustOxyLoss(-1) + M.updatehealth() + M.AdjustStunned(-4) + M.AdjustWeakened(-4) + M.AdjustStunned(-4) + M.Paralyse(2) + M.Weaken(2) + M.Stun(2) + if(M.reagents.get_reagent_amount("inaprovaline") < 5) + M.reagents.add_reagent("inaprovaline", 5) + S.chassis.use_power(S.energy_drain) + S.update_equip_info() + return /obj/item/mecha_parts/mecha_equipment/tool/cable_layer @@ -257,133 +257,133 @@ var/max_cable = 1000 required_type = /obj/mecha/working - New() - cable = new(src) - cable.amount = 0 - ..() +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/New() + cable = new(src) + cable.amount = 0 + ..() - attach() - ..() - event = chassis.events.addEvent("onMove",src,"layCable") +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/attach() + ..() + event = chassis.events.addEvent("onMove",src,"layCable") + return + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/detach() + chassis.events.clearEvent("onMove",event) + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/destroy() + chassis.events.clearEvent("onMove",event) + return ..() + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/action(var/obj/item/stack/cable_coil/target) + if(!action_checks(target)) return + var/result = load_cable(target) + var/message + if(isnull(result)) + message = "Unable to load [target] - no cable found." + else if(!result) + message = "Reel is full." + else + message = "[result] meters of cable successfully loaded." + send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) + occupant_message(message) + return - detach() - chassis.events.clearEvent("onMove",event) - return ..() - - destroy() - chassis.events.clearEvent("onMove",event) - return ..() - - action(var/obj/item/stack/cable_coil/target) - if(!action_checks(target)) - return - var/result = load_cable(target) - var/message - if(isnull(result)) - message = "Unable to load [target] - no cable found." - else if(!result) - message = "Reel is full." +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/Topic(href,href_list) + ..() + if(href_list["toggle"]) + set_ready_state(!equip_ready) + occupant_message("[src] [equip_ready?"dea":"a"]ctivated.") + log_message("[equip_ready?"Dea":"A"]ctivated.") + return + if(href_list["cut"]) + if(cable && cable.amount) + var/m = round(input(chassis.occupant,"Please specify the length of cable to cut","Cut cable",min(cable.amount,30)) as num, 1) + m = min(m, cable.amount) + if(m) + use_cable(m) + var/obj/item/stack/cable_coil/CC = new (get_turf(chassis)) + CC.amount = m else - message = "[result] meters of cable successfully loaded." - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) - occupant_message(message) + occupant_message("There's no more cable on the reel.") + return + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/get_equip_info() + var/output = ..() + if(output) + return "[output] \[Cable: [cable ? cable.amount : 0] m\][(cable && cable.amount) ? "- [!equip_ready?"Dea":"A"]ctivate|Cut" : null]" + return + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/load_cable(var/obj/item/stack/cable_coil/CC) + if(istype(CC) && CC.amount) + var/cur_amount = cable? cable.amount : 0 + var/to_load = max(max_cable - cur_amount,0) + if(to_load) + to_load = min(CC.amount, to_load) + if(!cable) + cable = new(src) + cable.amount = 0 + cable.amount += to_load + CC.use(to_load) + return to_load + else + return 0 + return + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/use_cable(amount) + if(!cable || cable.amount<1) + set_ready_state(1) + occupant_message("Cable depleted, [src] deactivated.") + log_message("Cable depleted, [src] deactivated.") return - - Topic(href,href_list) - ..() - if(href_list["toggle"]) - set_ready_state(!equip_ready) - occupant_message("[src] [equip_ready?"dea":"a"]ctivated.") - log_message("[equip_ready?"Dea":"A"]ctivated.") - return - if(href_list["cut"]) - if(cable && cable.amount) - var/m = round(input(chassis.occupant,"Please specify the length of cable to cut","Cut cable",min(cable.amount,30)) as num, 1) - m = min(m, cable.amount) - if(m) - use_cable(m) - var/obj/item/stack/cable_coil/CC = new (get_turf(chassis)) - CC.amount = m - else - occupant_message("There's no more cable on the reel.") + if(cable.amount < amount) + occupant_message("No enough cable to finish the task.") return + cable.use(amount) + update_equip_info() + return 1 - get_equip_info() - var/output = ..() - if(output) - return "[output] \[Cable: [cable ? cable.amount : 0] m\][(cable && cable.amount) ? "- [!equip_ready?"Dea":"A"]ctivate|Cut" : null]" - return +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/reset() + last_piece = null - proc/load_cable(var/obj/item/stack/cable_coil/CC) - if(istype(CC) && CC.amount) - var/cur_amount = cable? cable.amount : 0 - var/to_load = max(max_cable - cur_amount,0) - if(to_load) - to_load = min(CC.amount, to_load) - if(!cable) - cable = new(src) - cable.amount = 0 - cable.amount += to_load - CC.use(to_load) - return to_load - else - return 0 - return +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/dismantleFloor(var/turf/new_turf) + if(istype(new_turf, /turf/simulated/floor)) + var/turf/simulated/floor/T = new_turf + if(!T.is_plating()) + T.make_plating(!(T.broken || T.burnt)) + return new_turf.is_plating() - proc/use_cable(amount) - if(!cable || cable.amount<1) - set_ready_state(1) - occupant_message("Cable depleted, [src] deactivated.") - log_message("Cable depleted, [src] deactivated.") - return - if(cable.amount < amount) - occupant_message("No enough cable to finish the task.") - return - cable.use(amount) - update_equip_info() - return 1 - - proc/reset() - last_piece = null - - proc/dismantleFloor(var/turf/new_turf) - if(istype(new_turf, /turf/simulated/floor)) - var/turf/simulated/floor/T = new_turf - if(!T.is_plating()) - T.make_plating(!(T.broken || T.burnt)) - return new_turf.is_plating() - - proc/layCable(var/turf/new_turf) - if(equip_ready || !istype(new_turf) || !dismantleFloor(new_turf)) +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer/proc/layCable(var/turf/new_turf) + if(equip_ready || !istype(new_turf) || !dismantleFloor(new_turf)) + return reset() + var/fdirn = turn(chassis.dir,180) + for(var/obj/structure/cable/LC in new_turf) // check to make sure there's not a cable there already + if(LC.d1 == fdirn || LC.d2 == fdirn) return reset() - var/fdirn = turn(chassis.dir,180) - for(var/obj/structure/cable/LC in new_turf) // check to make sure there's not a cable there already - if(LC.d1 == fdirn || LC.d2 == fdirn) - return reset() - if(!use_cable(1)) - return reset() - var/obj/structure/cable/NC = new(new_turf) - NC.cableColor("red") - NC.d1 = 0 - NC.d2 = fdirn - NC.update_icon() + if(!use_cable(1)) + return reset() + var/obj/structure/cable/NC = new(new_turf) + NC.cableColor("red") + NC.d1 = 0 + NC.d2 = fdirn + NC.update_icon() - var/datum/powernet/PN - if(last_piece && last_piece.d2 != chassis.dir) - last_piece.d1 = min(last_piece.d2, chassis.dir) - last_piece.d2 = max(last_piece.d2, chassis.dir) - last_piece.update_icon() - PN = last_piece.powernet + var/datum/powernet/PN + if(last_piece && last_piece.d2 != chassis.dir) + last_piece.d1 = min(last_piece.d2, chassis.dir) + last_piece.d2 = max(last_piece.d2, chassis.dir) + last_piece.update_icon() + PN = last_piece.powernet - if(!PN) - PN = new() - PN.add_cable(NC) - NC.mergeConnectedNetworks(NC.d2) + if(!PN) + PN = new() + PN.add_cable(NC) + NC.mergeConnectedNetworks(NC.d2) - //NC.mergeConnectedNetworksOnTurf() - last_piece = NC - return 1 + //NC.mergeConnectedNetworksOnTurf() + last_piece = NC + return 1 /obj/item/mecha_parts/mecha_equipment/tool/syringe_gun name = "syringe gun" @@ -404,259 +404,259 @@ origin_tech = list(TECH_MATERIAL = 3, TECH_BIO = 4, TECH_MAGNET = 4, TECH_DATA = 3) required_type = /obj/mecha/medical - New() - ..() - flags |= NOREACT - syringes = new - known_reagents = list("inaprovaline"="Inaprovaline","anti_toxin"="Dylovene") - processed_reagents = new - create_reagents(max_volume) - synth = new (list(src),0) +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/New() + ..() + flags |= NOREACT + syringes = new + known_reagents = list("inaprovaline"="Inaprovaline","anti_toxin"="Dylovene") + processed_reagents = new + create_reagents(max_volume) + synth = new (list(src),0) - detach() - synth.stop() - return ..() +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/detach() + synth.stop() + return ..() - critfail() - ..() - flags &= ~NOREACT +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/critfail() + ..() + flags &= ~NOREACT + return + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/get_equip_info() + var/output = ..() + if(output) + return "[output] \[[mode? "Analyze" : "Launch"]\]
\[Syringes: [syringes.len]/[max_syringes] | Reagents: [reagents.total_volume]/[reagents.maximum_volume]\]
Reagents list" + return + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/action(atom/movable/target) + if(!action_checks(target)) return - - get_equip_info() - var/output = ..() - if(output) - return "[output] \[[mode? "Analyze" : "Launch"]\]
\[Syringes: [syringes.len]/[max_syringes] | Reagents: [reagents.total_volume]/[reagents.maximum_volume]\]
Reagents list" + if(istype(target,/obj/item/weapon/reagent_containers/syringe)) + return load_syringe(target) + if(istype(target,/obj/item/weapon/storage))//Loads syringes from boxes + for(var/obj/item/weapon/reagent_containers/syringe/S in target.contents) + load_syringe(S) return - - action(atom/movable/target) - if(!action_checks(target)) - return - if(istype(target,/obj/item/weapon/reagent_containers/syringe)) - return load_syringe(target) - if(istype(target,/obj/item/weapon/storage))//Loads syringes from boxes - for(var/obj/item/weapon/reagent_containers/syringe/S in target.contents) - load_syringe(S) - return - if(mode) - return analyze_reagents(target) - if(!syringes.len) - occupant_message("No syringes loaded.") - return - if(reagents.total_volume<=0) - occupant_message("No available reagents to load syringe with.") - return - set_ready_state(0) - chassis.use_power(energy_drain) - var/turf/trg = get_turf(target) - var/obj/item/weapon/reagent_containers/syringe/S = syringes[1] - S.forceMove(get_turf(chassis)) - reagents.trans_to_obj(S, min(S.volume, reagents.total_volume)) - syringes -= S - S.icon = 'icons/obj/chemical.dmi' - S.icon_state = "syringeproj" - playsound(chassis, 'sound/items/syringeproj.ogg', 50, 1) - log_message("Launched [S] from [src], targeting [target].") - spawn(-1) - src = null //if src is deleted, still process the syringe - for(var/i=0, i<6, i++) - if(!S) + if(mode) + return analyze_reagents(target) + if(!syringes.len) + occupant_message("No syringes loaded.") + return + if(reagents.total_volume<=0) + occupant_message("No available reagents to load syringe with.") + return + set_ready_state(0) + chassis.use_power(energy_drain) + var/turf/trg = get_turf(target) + var/obj/item/weapon/reagent_containers/syringe/S = syringes[1] + S.forceMove(get_turf(chassis)) + reagents.trans_to_obj(S, min(S.volume, reagents.total_volume)) + syringes -= S + S.icon = 'icons/obj/chemical.dmi' + S.icon_state = "syringeproj" + playsound(chassis, 'sound/items/syringeproj.ogg', 50, 1) + log_message("Launched [S] from [src], targeting [target].") + spawn(-1) + src = null //if src is deleted, still process the syringe + for(var/i=0, i<6, i++) + if(!S) + break + if(step_towards(S,trg)) + var/list/mobs = new + for(var/mob/living/carbon/M in S.loc) + mobs += M + var/mob/living/carbon/M = safepick(mobs) + if(M) + S.icon_state = initial(S.icon_state) + S.icon = initial(S.icon) + S.reagents.trans_to_mob(M, S.reagents.total_volume, CHEM_BLOOD) + M.take_organ_damage(2) + S.visible_message(" [M] was hit by the syringe!") break - if(step_towards(S,trg)) - var/list/mobs = new - for(var/mob/living/carbon/M in S.loc) - mobs += M - var/mob/living/carbon/M = safepick(mobs) - if(M) - S.icon_state = initial(S.icon_state) - S.icon = initial(S.icon) - S.reagents.trans_to_mob(M, S.reagents.total_volume, CHEM_BLOOD) - M.take_organ_damage(2) - S.visible_message(" [M] was hit by the syringe!") - break - else if(S.loc == trg) - S.icon_state = initial(S.icon_state) - S.icon = initial(S.icon) - S.update_icon() - break - else + else if(S.loc == trg) S.icon_state = initial(S.icon_state) S.icon = initial(S.icon) S.update_icon() break - sleep(1) - do_after_cooldown() - return 1 + else + S.icon_state = initial(S.icon_state) + S.icon = initial(S.icon) + S.update_icon() + break + sleep(1) + do_after_cooldown() + return 1 - Topic(href,href_list) - ..() - var/datum/topic_input/top_filter = new (href,href_list) - if(top_filter.get("toggle_mode")) - mode = !mode - update_equip_info() - return - if(top_filter.get("select_reagents")) - processed_reagents.len = 0 - var/m = 0 - var/message - for(var/i=1 to known_reagents.len) - if(m>=synth_speed) - break - var/reagent = top_filter.get("reagent_[i]") - if(reagent && (reagent in known_reagents)) - message = "[m ? ", " : null][known_reagents[reagent]]" - processed_reagents += reagent - m++ - if(processed_reagents.len) - message += " added to production" - synth.start() - occupant_message(message) - occupant_message("Reagent processing started.") - log_message("Reagent processing started.") - return - if(top_filter.get("show_reagents")) - chassis.occupant << browse(get_reagents_page(),"window=msyringegun") - if(top_filter.get("purge_reagent")) - var/reagent = top_filter.get("purge_reagent") - if(reagent) - reagents.del_reagent(reagent) - return - if(top_filter.get("purge_all")) - reagents.clear_reagents() - return - return - - proc/get_reagents_page() - var/output = {" - - Reagent Synthesizer - - - - -

Current reagents:

-
- [get_current_reagents()] -
-

Reagents production:

-
- [get_reagents_form()] -
- - - "} - return output - - proc/get_reagents_form() - var/r_list = get_reagents_list() - var/inputs - if(r_list) - inputs += "" - inputs += "" - inputs += "" - var/output = {"
- [r_list || "No known reagents"] - [inputs] -
- [r_list? "Only the first [synth_speed] selected reagent\s will be added to production" : null] - "} - return output - - proc/get_reagents_list() - var/output - for(var/i=1 to known_reagents.len) - var/reagent_id = known_reagents[i] - output += {" [known_reagents[reagent_id]]
"} - return output - - proc/get_current_reagents() - var/output - for(var/datum/reagent/R in reagents.reagent_list) - if(R.volume > 0) - output += "[R]: [round(R.volume,0.001)] - Purge Reagent
" - if(output) - output += "Total: [round(reagents.total_volume,0.001)]/[reagents.maximum_volume] - Purge All" - return output || "None" - - proc/load_syringe(obj/item/weapon/reagent_containers/syringe/S) - if(syringes.len= 2) - occupant_message("The syringe is too far away.") - return 0 - for(var/obj/structure/D in S.loc)//Basic level check for structures in the way (Like grilles and windows) - if(!(D.CanPass(S,src.loc))) - occupant_message("Unable to load syringe.") - return 0 - for(var/obj/machinery/door/D in S.loc)//Checks for doors - if(!(D.CanPass(S,src.loc))) - occupant_message("Unable to load syringe.") - return 0 - S.reagents.trans_to_obj(src, S.reagents.total_volume) - S.forceMove(src) - syringes += S - occupant_message("Syringe loaded.") - update_equip_info() - return 1 - occupant_message("The [src] syringe chamber is full.") - return 0 - - proc/analyze_reagents(atom/A) - if(get_dist(src,A) >= 4) - occupant_message("The object is too far away.") - return 0 - if(!A.reagents || istype(A,/mob)) - occupant_message("No reagent info gained from [A].") - return 0 - occupant_message("Analyzing reagents...") - for(var/datum/reagent/R in A.reagents.reagent_list) - if(R.reagent_state == 2 && add_known_reagent(R.id,R.name)) - occupant_message("Reagent analyzed, identified as [R.name] and added to database.") - send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form()) - occupant_message("Analyzis complete.") - return 1 - - proc/add_known_reagent(r_id,r_name) - set_ready_state(0) - do_after_cooldown() - if(!(r_id in known_reagents)) - known_reagents += r_id - known_reagents[r_id] = r_name - return 1 - return 0 - - - update_equip_info() - if(..()) - send_byjax(chassis.occupant,"msyringegun.browser","reagents",get_current_reagents()) - send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form()) - return 1 - return - - on_reagent_change() - ..() +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/Topic(href,href_list) + ..() + var/datum/topic_input/top_filter = new (href,href_list) + if(top_filter.get("toggle_mode")) + mode = !mode update_equip_info() return + if(top_filter.get("select_reagents")) + processed_reagents.len = 0 + var/m = 0 + var/message + for(var/i=1 to known_reagents.len) + if(m>=synth_speed) + break + var/reagent = top_filter.get("reagent_[i]") + if(reagent && (reagent in known_reagents)) + message = "[m ? ", " : null][known_reagents[reagent]]" + processed_reagents += reagent + m++ + if(processed_reagents.len) + message += " added to production" + synth.start() + occupant_message(message) + occupant_message("Reagent processing started.") + log_message("Reagent processing started.") + return + if(top_filter.get("show_reagents")) + chassis.occupant << browse(get_reagents_page(),"window=msyringegun") + if(top_filter.get("purge_reagent")) + var/reagent = top_filter.get("purge_reagent") + if(reagent) + reagents.del_reagent(reagent) + return + if(top_filter.get("purge_all")) + reagents.clear_reagents() + return + return + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/proc/get_reagents_page() + var/output = {" + + Reagent Synthesizer + + + + +

Current reagents:

+
+ [get_current_reagents()] +
+

Reagents production:

+
+ [get_reagents_form()] +
+ + + "} + return output + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/proc/get_reagents_form() + var/r_list = get_reagents_list() + var/inputs + if(r_list) + inputs += "" + inputs += "" + inputs += "" + var/output = {"
+ [r_list || "No known reagents"] + [inputs] +
+ [r_list? "Only the first [synth_speed] selected reagent\s will be added to production" : null] + "} + return output + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/proc/get_reagents_list() + var/output + for(var/i=1 to known_reagents.len) + var/reagent_id = known_reagents[i] + output += {" [known_reagents[reagent_id]]
"} + return output + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/proc/get_current_reagents() + var/output + for(var/datum/reagent/R in reagents.reagent_list) + if(R.volume > 0) + output += "[R]: [round(R.volume,0.001)] - Purge Reagent
" + if(output) + output += "Total: [round(reagents.total_volume,0.001)]/[reagents.maximum_volume] - Purge All" + return output || "None" + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/proc/load_syringe(obj/item/weapon/reagent_containers/syringe/S) + if(syringes.len= 2) + occupant_message("The syringe is too far away.") + return 0 + for(var/obj/structure/D in S.loc)//Basic level check for structures in the way (Like grilles and windows) + if(!(D.CanPass(S,src.loc))) + occupant_message("Unable to load syringe.") + return 0 + for(var/obj/machinery/door/D in S.loc)//Checks for doors + if(!(D.CanPass(S,src.loc))) + occupant_message("Unable to load syringe.") + return 0 + S.reagents.trans_to_obj(src, S.reagents.total_volume) + S.forceMove(src) + syringes += S + occupant_message("Syringe loaded.") + update_equip_info() + return 1 + occupant_message("The [src] syringe chamber is full.") + return 0 + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/proc/analyze_reagents(atom/A) + if(get_dist(src,A) >= 4) + occupant_message("The object is too far away.") + return 0 + if(!A.reagents || istype(A,/mob)) + occupant_message("No reagent info gained from [A].") + return 0 + occupant_message("Analyzing reagents...") + for(var/datum/reagent/R in A.reagents.reagent_list) + if(R.reagent_state == 2 && add_known_reagent(R.id,R.name)) + occupant_message("Reagent analyzed, identified as [R.name] and added to database.") + send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form()) + occupant_message("Analyzis complete.") + return 1 + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/proc/add_known_reagent(r_id,r_name) + set_ready_state(0) + do_after_cooldown() + if(!(r_id in known_reagents)) + known_reagents += r_id + known_reagents[r_id] = r_name + return 1 + return 0 + + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/update_equip_info() + if(..()) + send_byjax(chassis.occupant,"msyringegun.browser","reagents",get_current_reagents()) + send_byjax(chassis.occupant,"msyringegun.browser","reagents_form",get_reagents_form()) + return 1 + return + +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/on_reagent_change() + ..() + update_equip_info() + return /datum/global_iterator/mech_synth delay = 100 - process(var/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/S) - if(!S.chassis) - return stop() - var/energy_drain = S.energy_drain*10 - if(!S.processed_reagents.len || S.reagents.total_volume >= S.reagents.maximum_volume || !S.chassis.has_charge(energy_drain)) - S.occupant_message("Reagent processing stopped.") - S.log_message("Reagent processing stopped.") - return stop() - var/amount = S.synth_speed / S.processed_reagents.len - for(var/reagent in S.processed_reagents) - S.reagents.add_reagent(reagent,amount) - S.chassis.use_power(energy_drain) - return 1 +/datum/global_iterator/mech_synth/process(var/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun/S) + if(!S.chassis) + return stop() + var/energy_drain = S.energy_drain*10 + if(!S.processed_reagents.len || S.reagents.total_volume >= S.reagents.maximum_volume || !S.chassis.has_charge(energy_drain)) + S.occupant_message("Reagent processing stopped.") + S.log_message("Reagent processing stopped.") + return stop() + var/amount = S.synth_speed / S.processed_reagents.len + for(var/reagent in S.processed_reagents) + S.reagents.add_reagent(reagent,amount) + S.chassis.use_power(energy_drain) + return 1 diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index 164140583f..e5e7c929f7 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -1,3 +1,6 @@ +/obj/item/mecha_parts/mecha_equipment/tool + equip_type = EQUIP_UTILITY + /obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp name = "hydraulic clamp" icon_state = "mecha_clamp" @@ -7,66 +10,66 @@ var/obj/mecha/working/ripley/cargo_holder required_type = /obj/mecha/working - attach(obj/mecha/M as obj) - ..() - cargo_holder = M - return +/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/attach(obj/mecha/M as obj) + ..() + cargo_holder = M + return - action(atom/target) - if(!action_checks(target)) return - if(!cargo_holder) return +/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp/action(atom/target) + if(!action_checks(target)) return + if(!cargo_holder) return - //loading - if(istype(target,/obj)) - var/obj/O = target - if(O.has_buckled_mobs()) - return - if(locate(/mob/living) in O) - occupant_message("You can't load living things into the cargo compartment.") - return - if(O.anchored) - occupant_message("[target] is firmly secured.") - return - if(cargo_holder.cargo.len >= cargo_holder.cargo_capacity) - occupant_message("Not enough room in cargo compartment.") - return + //loading + if(istype(target,/obj)) + var/obj/O = target + if(O.has_buckled_mobs()) + return + if(locate(/mob/living) in O) + occupant_message("You can't load living things into the cargo compartment.") + return + if(O.anchored) + occupant_message("[target] is firmly secured.") + return + if(cargo_holder.cargo.len >= cargo_holder.cargo_capacity) + occupant_message("Not enough room in cargo compartment.") + return - occupant_message("You lift [target] and start to load it into cargo compartment.") - chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") - set_ready_state(0) - chassis.use_power(energy_drain) - O.anchored = 1 - var/T = chassis.loc - if(do_after_cooldown(target)) - if(T == chassis.loc && src == chassis.selected) - cargo_holder.cargo += O - O.loc = chassis - O.anchored = 0 - occupant_message("[target] succesfully loaded.") - log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") - else - occupant_message("You must hold still while handling objects.") - O.anchored = initial(O.anchored) - - //attacking - else if(istype(target,/mob/living)) - var/mob/living/M = target - if(M.stat>1) return - if(chassis.occupant.a_intent == I_HURT || istype(chassis.occupant,/mob/living/carbon/brain)) //No tactile feedback for brains - M.take_overall_damage(dam_force) - M.adjustOxyLoss(round(dam_force/2)) - M.updatehealth() - occupant_message("You squeeze [target] with [src.name]. Something cracks.") - playsound(src.loc, "fracture", 5, 1, -2) //CRACK - chassis.visible_message("[chassis] squeezes [target].") + occupant_message("You lift [target] and start to load it into cargo compartment.") + chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") + set_ready_state(0) + chassis.use_power(energy_drain) + O.anchored = 1 + var/T = chassis.loc + if(do_after_cooldown(target)) + if(T == chassis.loc && src == chassis.selected) + cargo_holder.cargo += O + O.loc = chassis + O.anchored = 0 + occupant_message("[target] succesfully loaded.") + log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") else - step_away(M,chassis) - occupant_message("You push [target] out of the way.") - chassis.visible_message("[chassis] pushes [target] out of the way.") - set_ready_state(0) - chassis.use_power(energy_drain) - do_after_cooldown() - return 1 + occupant_message("You must hold still while handling objects.") + O.anchored = initial(O.anchored) + + //attacking + else if(istype(target,/mob/living)) + var/mob/living/M = target + if(M.stat>1) return + if(chassis.occupant.a_intent == I_HURT || istype(chassis.occupant,/mob/living/carbon/brain)) //No tactile feedback for brains + M.take_overall_damage(dam_force) + M.adjustOxyLoss(round(dam_force/2)) + M.updatehealth() + occupant_message("You squeeze [target] with [src.name]. Something cracks.") + playsound(src.loc, "fracture", 5, 1, -2) //CRACK + chassis.visible_message("[chassis] squeezes [target].") + else + step_away(M,chassis) + occupant_message("You push [target] out of the way.") + chassis.visible_message("[chassis] pushes [target] out of the way.") + set_ready_state(0) + chassis.use_power(energy_drain) + do_after_cooldown() + return 1 /obj/item/mecha_parts/mecha_equipment/tool/drill name = "drill" @@ -77,48 +80,48 @@ force = 15 required_type = list(/obj/mecha/working/ripley, /obj/mecha/combat) - action(atom/target) - if(!action_checks(target)) return - if(isobj(target)) - var/obj/target_obj = target - if(!target_obj.vars.Find("unacidable") || target_obj.unacidable) return - set_ready_state(0) - chassis.use_power(energy_drain) - chassis.visible_message("[chassis] starts to drill [target]", "You hear the drill.") - occupant_message("You start to drill [target]") - var/T = chassis.loc - var/C = target.loc //why are these backwards? we may never know -Pete - if(do_after_cooldown(target)) - if(T == chassis.loc && src == chassis.selected) - if(istype(target, /turf/simulated/wall)) - var/turf/simulated/wall/W = target - if(W.reinf_material) - occupant_message("[target] is too durable to drill through.") - else - log_message("Drilled through [target]") - target.ex_act(2) - else if(istype(target, /turf/simulated/mineral)) - for(var/turf/simulated/mineral/M in range(chassis,1)) - if(get_dir(chassis,M)&chassis.dir) - M.GetDrilled() - log_message("Drilled through [target]") - if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment) - var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo - if(ore_box) - for(var/obj/item/weapon/ore/ore in range(chassis,1)) - if(get_dir(chassis,ore)&chassis.dir) - ore.Move(ore_box) - log_message("Drilled through [target]") - if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment) - var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo - if(ore_box) - for(var/obj/item/weapon/ore/ore in range(chassis,1)) - if(get_dir(chassis,ore)&chassis.dir) - ore.Move(ore_box) - else if(target.loc == C) +/obj/item/mecha_parts/mecha_equipment/tool/drill/action(atom/target) + if(!action_checks(target)) return + if(isobj(target)) + var/obj/target_obj = target + if(!target_obj.vars.Find("unacidable") || target_obj.unacidable) return + set_ready_state(0) + chassis.use_power(energy_drain) + chassis.visible_message("[chassis] starts to drill [target]", "You hear the drill.") + occupant_message("You start to drill [target]") + var/T = chassis.loc + var/C = target.loc //why are these backwards? we may never know -Pete + if(do_after_cooldown(target)) + if(T == chassis.loc && src == chassis.selected) + if(istype(target, /turf/simulated/wall)) + var/turf/simulated/wall/W = target + if(W.reinf_material) + occupant_message("[target] is too durable to drill through.") + else log_message("Drilled through [target]") target.ex_act(2) - return 1 + else if(istype(target, /turf/simulated/mineral)) + for(var/turf/simulated/mineral/M in range(chassis,1)) + if(get_dir(chassis,M)&chassis.dir) + M.GetDrilled() + log_message("Drilled through [target]") + if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment) + var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo + if(ore_box) + for(var/obj/item/weapon/ore/ore in range(chassis,1)) + if(get_dir(chassis,ore)&chassis.dir) + ore.Move(ore_box) + log_message("Drilled through [target]") + if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment) + var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo + if(ore_box) + for(var/obj/item/weapon/ore/ore in range(chassis,1)) + if(get_dir(chassis,ore)&chassis.dir) + ore.Move(ore_box) + else if(target.loc == C) + log_message("Drilled through [target]") + target.ex_act(2) + return 1 /obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill name = "diamond drill" @@ -128,39 +131,39 @@ equip_cooldown = 20 force = 15 - action(atom/target) - if(!action_checks(target)) return - if(isobj(target)) - var/obj/target_obj = target - if(target_obj.unacidable) return - set_ready_state(0) - chassis.use_power(energy_drain) - chassis.visible_message("[chassis] starts to drill [target]", "You hear the drill.") - occupant_message("You start to drill [target]") - var/T = chassis.loc - var/C = target.loc //why are these backwards? we may never know -Pete - if(do_after_cooldown(target)) - if(T == chassis.loc && src == chassis.selected) - if(istype(target, /turf/simulated/wall)) - var/turf/simulated/wall/W = target - if(!W.reinf_material || do_after_cooldown(target))//To slow down how fast mechs can drill through the station - log_message("Drilled through [target]") - target.ex_act(3) - else if(istype(target, /turf/simulated/mineral)) - for(var/turf/simulated/mineral/M in range(chassis,1)) - if(get_dir(chassis,M)&chassis.dir) - M.GetDrilled() +/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill/action(atom/target) + if(!action_checks(target)) return + if(isobj(target)) + var/obj/target_obj = target + if(target_obj.unacidable) return + set_ready_state(0) + chassis.use_power(energy_drain) + chassis.visible_message("[chassis] starts to drill [target]", "You hear the drill.") + occupant_message("You start to drill [target]") + var/T = chassis.loc + var/C = target.loc //why are these backwards? we may never know -Pete + if(do_after_cooldown(target)) + if(T == chassis.loc && src == chassis.selected) + if(istype(target, /turf/simulated/wall)) + var/turf/simulated/wall/W = target + if(!W.reinf_material || do_after_cooldown(target))//To slow down how fast mechs can drill through the station log_message("Drilled through [target]") - if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment) - var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo - if(ore_box) - for(var/obj/item/weapon/ore/ore in range(chassis,1)) - if(get_dir(chassis,ore)&chassis.dir) - ore.Move(ore_box) - else if(target.loc == C) - log_message("Drilled through [target]") - target.ex_act(2) - return 1 + target.ex_act(3) + else if(istype(target, /turf/simulated/mineral)) + for(var/turf/simulated/mineral/M in range(chassis,1)) + if(get_dir(chassis,M)&chassis.dir) + M.GetDrilled() + log_message("Drilled through [target]") + if(locate(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp) in chassis.equipment) + var/obj/structure/ore_box/ore_box = locate(/obj/structure/ore_box) in chassis:cargo + if(ore_box) + for(var/obj/item/weapon/ore/ore in range(chassis,1)) + if(get_dir(chassis,ore)&chassis.dir) + ore.Move(ore_box) + else if(target.loc == C) + log_message("Drilled through [target]") + target.ex_act(2) + return 1 /obj/item/mecha_parts/mecha_equipment/tool/extinguisher name = "extinguisher" @@ -174,64 +177,64 @@ var/spray_amount = 5 //units of liquid per particle. 5 is enough to wet the floor - it's a big fire extinguisher, so should be fine var/max_water = 1000 - New() - reagents = new/datum/reagents(max_water) - reagents.my_atom = src - reagents.add_reagent("water", max_water) - ..() - return +/obj/item/mecha_parts/mecha_equipment/tool/extinguisher/New() + reagents = new/datum/reagents(max_water) + reagents.my_atom = src + reagents.add_reagent("water", max_water) + ..() + return - action(atom/target) //copypasted from extinguisher. TODO: Rewrite from scratch. - if(!action_checks(target) || get_dist(chassis, target)>3) return - if(get_dist(chassis, target)>2) return - set_ready_state(0) - if(do_after_cooldown(target)) - if( istype(target, /obj/structure/reagent_dispensers/watertank) && get_dist(chassis,target) <= 1) - var/obj/o = target - var/amount = o.reagents.trans_to_obj(src, 200) - occupant_message("[amount] units transferred into internal tank.") - playsound(chassis, 'sound/effects/refill.ogg', 50, 1, -6) - return +/obj/item/mecha_parts/mecha_equipment/tool/extinguisher/action(atom/target) //copypasted from extinguisher. TODO: Rewrite from scratch. + if(!action_checks(target) || get_dist(chassis, target)>3) return + if(get_dist(chassis, target)>2) return + set_ready_state(0) + if(do_after_cooldown(target)) + if( istype(target, /obj/structure/reagent_dispensers/watertank) && get_dist(chassis,target) <= 1) + var/obj/o = target + var/amount = o.reagents.trans_to_obj(src, 200) + occupant_message("[amount] units transferred into internal tank.") + playsound(chassis, 'sound/effects/refill.ogg', 50, 1, -6) + return - if (src.reagents.total_volume < 1) - occupant_message("\The [src] is empty.") - return + if (src.reagents.total_volume < 1) + occupant_message("\The [src] is empty.") + return - playsound(chassis, 'sound/effects/extinguish.ogg', 75, 1, -3) + playsound(chassis, 'sound/effects/extinguish.ogg', 75, 1, -3) - var/direction = get_dir(chassis,target) + var/direction = get_dir(chassis,target) - var/turf/T = get_turf(target) - var/turf/T1 = get_step(T,turn(direction, 90)) - var/turf/T2 = get_step(T,turn(direction, -90)) + var/turf/T = get_turf(target) + var/turf/T1 = get_step(T,turn(direction, 90)) + var/turf/T2 = get_step(T,turn(direction, -90)) - var/list/the_targets = list(T,T1,T2) + var/list/the_targets = list(T,T1,T2) - for(var/a = 1 to 5) - spawn(0) - var/obj/effect/effect/water/W = new /obj/effect/effect/water(get_turf(chassis)) - var/turf/my_target - if(a == 1) - my_target = T - else if(a == 2) - my_target = T1 - else if(a == 3) - my_target = T2 - else - my_target = pick(the_targets) - W.create_reagents(5) - if(!W || !src) - return - reagents.trans_to_obj(W, spray_amount) - W.set_color() - W.set_up(my_target) - return 1 + for(var/a = 1 to 5) + spawn(0) + var/obj/effect/effect/water/W = new /obj/effect/effect/water(get_turf(chassis)) + var/turf/my_target + if(a == 1) + my_target = T + else if(a == 2) + my_target = T1 + else if(a == 3) + my_target = T2 + else + my_target = pick(the_targets) + W.create_reagents(5) + if(!W || !src) + return + reagents.trans_to_obj(W, spray_amount) + W.set_color() + W.set_up(my_target) + return 1 - get_equip_info() - return "[..()] \[[src.reagents.total_volume]\]" +/obj/item/mecha_parts/mecha_equipment/tool/extinguisher/get_equip_info() + return "[..()] \[[src.reagents.total_volume]\]" - on_reagent_change() - return +/obj/item/mecha_parts/mecha_equipment/tool/extinguisher/on_reagent_change() + return /obj/item/mecha_parts/mecha_equipment/tool/rcd @@ -245,94 +248,95 @@ var/mode = 0 //0 - deconstruct, 1 - wall or floor, 2 - airlock. var/disabled = 0 //malf - action(atom/target) - if(istype(target,/area/shuttle)||istype(target, /turf/space/transit))//>implying these are ever made -Sieve - disabled = 1 - else - disabled = 0 - if(!istype(target, /turf) && !istype(target, /obj/machinery/door/airlock)) - target = get_turf(target) - if(!action_checks(target) || disabled || get_dist(chassis, target)>3) return - playsound(chassis, 'sound/machines/click.ogg', 50, 1) - //meh + equip_type = EQUIP_SPECIAL + +/obj/item/mecha_parts/mecha_equipment/tool/rcd/action(atom/target) + if(istype(target,/area/shuttle)||istype(target, /turf/space/transit))//>implying these are ever made -Sieve + disabled = 1 + else + disabled = 0 + if(!istype(target, /turf) && !istype(target, /obj/machinery/door/airlock)) + target = get_turf(target) + if(!action_checks(target) || disabled || get_dist(chassis, target)>3) return + playsound(chassis, 'sound/machines/click.ogg', 50, 1) + //meh + switch(mode) + if(0) + if (istype(target, /turf/simulated/wall)) + occupant_message("Deconstructing [target]...") + set_ready_state(0) + if(do_after_cooldown(target)) + if(disabled) return + chassis.spark_system.start() + target:ChangeTurf(/turf/simulated/floor/plating) + playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) + chassis.use_power(energy_drain) + else if (istype(target, /turf/simulated/floor)) + occupant_message("Deconstructing [target]...") + set_ready_state(0) + if(do_after_cooldown(target)) + if(disabled) return + chassis.spark_system.start() + target:ChangeTurf(get_base_turf_by_area(target)) + playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) + chassis.use_power(energy_drain) + else if (istype(target, /obj/machinery/door/airlock)) + occupant_message("Deconstructing [target]...") + set_ready_state(0) + if(do_after_cooldown(target)) + if(disabled) return + chassis.spark_system.start() + qdel(target) + playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) + chassis.use_power(energy_drain) + if(1) + if(istype(target, /turf/space) || istype(target,get_base_turf_by_area(target))) + occupant_message("Building Floor...") + set_ready_state(0) + if(do_after_cooldown(target)) + if(disabled) return + target:ChangeTurf(/turf/simulated/floor/plating) + playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) + chassis.spark_system.start() + chassis.use_power(energy_drain*2) + else if(istype(target, /turf/simulated/floor)) + occupant_message("Building Wall...") + set_ready_state(0) + if(do_after_cooldown(target)) + if(disabled) return + target:ChangeTurf(/turf/simulated/wall) + playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) + chassis.spark_system.start() + chassis.use_power(energy_drain*2) + if(2) + if(istype(target, /turf/simulated/floor)) + occupant_message("Building Airlock...") + set_ready_state(0) + if(do_after_cooldown(target)) + if(disabled) return + chassis.spark_system.start() + var/obj/machinery/door/airlock/T = new /obj/machinery/door/airlock(target) + T.autoclose = 1 + playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) + playsound(target, 'sound/effects/sparks2.ogg', 50, 1) + chassis.use_power(energy_drain*2) + return + +/obj/item/mecha_parts/mecha_equipment/tool/rcd/Topic(href,href_list) + ..() + if(href_list["mode"]) + mode = text2num(href_list["mode"]) switch(mode) if(0) - if (istype(target, /turf/simulated/wall)) - occupant_message("Deconstructing [target]...") - set_ready_state(0) - if(do_after_cooldown(target)) - if(disabled) return - chassis.spark_system.start() - target:ChangeTurf(/turf/simulated/floor/plating) - playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) - chassis.use_power(energy_drain) - else if (istype(target, /turf/simulated/floor)) - occupant_message("Deconstructing [target]...") - set_ready_state(0) - if(do_after_cooldown(target)) - if(disabled) return - chassis.spark_system.start() - target:ChangeTurf(get_base_turf_by_area(target)) - playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) - chassis.use_power(energy_drain) - else if (istype(target, /obj/machinery/door/airlock)) - occupant_message("Deconstructing [target]...") - set_ready_state(0) - if(do_after_cooldown(target)) - if(disabled) return - chassis.spark_system.start() - qdel(target) - playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) - chassis.use_power(energy_drain) + occupant_message("Switched RCD to Deconstruct.") if(1) - if(istype(target, /turf/space) || istype(target,get_base_turf_by_area(target))) - occupant_message("Building Floor...") - set_ready_state(0) - if(do_after_cooldown(target)) - if(disabled) return - target:ChangeTurf(/turf/simulated/floor/plating) - playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) - chassis.spark_system.start() - chassis.use_power(energy_drain*2) - else if(istype(target, /turf/simulated/floor)) - occupant_message("Building Wall...") - set_ready_state(0) - if(do_after_cooldown(target)) - if(disabled) return - target:ChangeTurf(/turf/simulated/wall) - playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) - chassis.spark_system.start() - chassis.use_power(energy_drain*2) + occupant_message("Switched RCD to Construct.") if(2) - if(istype(target, /turf/simulated/floor)) - occupant_message("Building Airlock...") - set_ready_state(0) - if(do_after_cooldown(target)) - if(disabled) return - chassis.spark_system.start() - var/obj/machinery/door/airlock/T = new /obj/machinery/door/airlock(target) - T.autoclose = 1 - playsound(target, 'sound/items/Deconstruct.ogg', 50, 1) - playsound(target, 'sound/effects/sparks2.ogg', 50, 1) - chassis.use_power(energy_drain*2) - return + occupant_message("Switched RCD to Construct Airlock.") + return - - Topic(href,href_list) - ..() - if(href_list["mode"]) - mode = text2num(href_list["mode"]) - switch(mode) - if(0) - occupant_message("Switched RCD to Deconstruct.") - if(1) - occupant_message("Switched RCD to Construct.") - if(2) - occupant_message("Switched RCD to Construct Airlock.") - return - - get_equip_info() - return "[..()] \[D|C|A\]" +/obj/item/mecha_parts/mecha_equipment/tool/rcd/get_equip_info() + return "[..()] \[D|C|A\]" @@ -346,15 +350,17 @@ energy_drain = 1000 range = RANGED - action(atom/target) - if(!action_checks(target) || src.loc.z == 2) return - var/turf/T = get_turf(target) - if(T) - set_ready_state(0) - chassis.use_power(energy_drain) - do_teleport(chassis, T, 4) - do_after_cooldown() - return + equip_type = EQUIP_SPECIAL + +/obj/item/mecha_parts/mecha_equipment/teleporter/action(atom/target) + if(!action_checks(target) || src.loc.z == 2) return + var/turf/T = get_turf(target) + if(T) + set_ready_state(0) + chassis.use_power(energy_drain) + do_teleport(chassis, T, 4) + do_after_cooldown() + return /obj/item/mecha_parts/mecha_equipment/wormhole_generator @@ -366,46 +372,47 @@ energy_drain = 300 range = RANGED + equip_type = EQUIP_SPECIAL - action(atom/target) - if(!action_checks(target) || src.loc.z == 2) return - var/list/theareas = list() - for(var/area/AR in orange(100, chassis)) - if(AR in theareas) continue - theareas += AR - if(!theareas.len) - return - var/area/thearea = pick(theareas) - var/list/L = list() - var/turf/pos = get_turf(src) - for(var/turf/T in get_area_turfs(thearea.type)) - if(!T.density && pos.z == T.z) - var/clear = 1 - for(var/obj/O in T) - if(O.density) - clear = 0 - break - if(clear) - L+=T - if(!L.len) - return - var/turf/target_turf = pick(L) - if(!target_turf) - return - chassis.use_power(energy_drain) - set_ready_state(0) - var/obj/effect/portal/P = new /obj/effect/portal(get_turf(target)) - P.target = target_turf - P.creator = null - P.icon = 'icons/obj/objects.dmi' - P.failchance = 0 - P.icon_state = "anom" - P.name = "wormhole" - do_after_cooldown() - src = null - spawn(rand(150,300)) - qdel(P) +/obj/item/mecha_parts/mecha_equipment/wormhole_generator/action(atom/target) + if(!action_checks(target) || src.loc.z == 2) return + var/list/theareas = list() + for(var/area/AR in orange(100, chassis)) + if(AR in theareas) continue + theareas += AR + if(!theareas.len) return + var/area/thearea = pick(theareas) + var/list/L = list() + var/turf/pos = get_turf(src) + for(var/turf/T in get_area_turfs(thearea.type)) + if(!T.density && pos.z == T.z) + var/clear = 1 + for(var/obj/O in T) + if(O.density) + clear = 0 + break + if(clear) + L+=T + if(!L.len) + return + var/turf/target_turf = pick(L) + if(!target_turf) + return + chassis.use_power(energy_drain) + set_ready_state(0) + var/obj/effect/portal/P = new /obj/effect/portal(get_turf(target)) + P.target = target_turf + P.creator = null + P.icon = 'icons/obj/objects.dmi' + P.failchance = 0 + P.icon_state = "anom" + P.name = "wormhole" + do_after_cooldown() + src = null + spawn(rand(150,300)) + qdel(P) + return /obj/item/mecha_parts/mecha_equipment/gravcatapult name = "gravitational catapult" @@ -421,66 +428,68 @@ var/last_fired = 0 //Concept stolen from guns. var/fire_delay = 10 //Used to prevent spam-brute against humans. - action(atom/movable/target) + equip_type = EQUIP_UTILITY - if(world.time >= last_fired + fire_delay) - last_fired = world.time - else - if (world.time % 3) - occupant_message("[src] is not ready to fire again!") - return 0 +/obj/item/mecha_parts/mecha_equipment/gravcatapult/action(atom/movable/target) - switch(mode) - if(1) - if(!action_checks(target) && !locked) return - if(!locked) - if(!istype(target) || target.anchored) - occupant_message("Unable to lock on [target]") - return - locked = target - occupant_message("Locked on [target]") - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) + if(world.time >= last_fired + fire_delay) + last_fired = world.time + else + if (world.time % 3) + occupant_message("[src] is not ready to fire again!") + return 0 + + switch(mode) + if(1) + if(!action_checks(target) && !locked) return + if(!locked) + if(!istype(target) || target.anchored) + occupant_message("Unable to lock on [target]") return - else if(target!=locked) - if(locked in view(chassis)) - locked.throw_at(target, 14, 1.5, chassis) - locked = null - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) - set_ready_state(0) - chassis.use_power(energy_drain) - do_after_cooldown() - else - locked = null - occupant_message("Lock on [locked] disengaged.") - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) - if(2) - if(!action_checks(target)) return - var/list/atoms = list() - if(isturf(target)) - atoms = range(target,3) + locked = target + occupant_message("Locked on [target]") + send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) + return + else if(target!=locked) + if(locked in view(chassis)) + locked.throw_at(target, 14, 1.5, chassis) + locked = null + send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) + set_ready_state(0) + chassis.use_power(energy_drain) + do_after_cooldown() else - atoms = orange(target,3) - for(var/atom/movable/A in atoms) - if(A.anchored) continue - spawn(0) - var/iter = 5-get_dist(A,target) - for(var/i=0 to iter) - step_away(A,target) - sleep(2) - set_ready_state(0) - chassis.use_power(energy_drain) - do_after_cooldown() - return + locked = null + occupant_message("Lock on [locked] disengaged.") + send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) + if(2) + if(!action_checks(target)) return + var/list/atoms = list() + if(isturf(target)) + atoms = range(target,3) + else + atoms = orange(target,3) + for(var/atom/movable/A in atoms) + if(A.anchored) continue + spawn(0) + var/iter = 5-get_dist(A,target) + for(var/i=0 to iter) + step_away(A,target) + sleep(2) + set_ready_state(0) + chassis.use_power(energy_drain) + do_after_cooldown() + return - get_equip_info() - return "[..()] [mode==1?"([locked||"Nothing"])":null] \[S|P\]" +/obj/item/mecha_parts/mecha_equipment/gravcatapult/get_equip_info() + return "[..()] [mode==1?"([locked||"Nothing"])":null] \[S|P\]" - Topic(href, href_list) - ..() - if(href_list["mode"]) - mode = text2num(href_list["mode"]) - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) - return +/obj/item/mecha_parts/mecha_equipment/gravcatapult/Topic(href, href_list) + ..() + if(href_list["mode"]) + mode = text2num(href_list["mode"]) + send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) + return /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster //what is that noise? A BAWWW from TK mutants. @@ -494,42 +503,44 @@ var/deflect_coeff = 1.15 var/damage_coeff = 0.8 - can_attach(obj/mecha/M as obj) - if(..()) - if(!M.proc_res["dynattackby"]) - return 1 - return 0 + equip_type = EQUIP_HULL - attach(obj/mecha/M as obj) - ..() - chassis.proc_res["dynattackby"] = src - return +/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/can_attach(obj/mecha/M as obj) + if(..()) + if(!M.proc_res["dynattackby"]) + return 1 + return 0 - detach() - chassis.proc_res["dynattackby"] = null - ..() - return +/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/attach(obj/mecha/M as obj) + ..() + chassis.proc_res["dynattackby"] = src + return - get_equip_info() - if(!chassis) return - return "* [src.name]" +/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/detach() + chassis.proc_res["dynattackby"] = null + ..() + return - proc/dynattackby(obj/item/weapon/W as obj, mob/user as mob) - if(!action_checks(user)) - return chassis.dynattackby(W,user) - chassis.log_message("Attacked by [W]. Attacker - [user]") - if(prob(chassis.deflect_chance*deflect_coeff)) - user << "\The [W] bounces off [chassis] armor." - chassis.log_append_to_last("Armor saved.") - else - chassis.occupant_message("\The [user] hits [chassis] with [W].") - user.visible_message("\The [user] hits [chassis] with [W].", "You hit [src] with [W].") - chassis.take_damage(round(W.force*damage_coeff),W.damtype) - chassis.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) - set_ready_state(0) - chassis.use_power(energy_drain) - do_after_cooldown() - return +/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/get_equip_info() + if(!chassis) return + return "* [src.name]" + +/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster/proc/dynattackby(obj/item/weapon/W as obj, mob/user as mob) + if(!action_checks(user)) + return chassis.dynattackby(W,user) + chassis.log_message("Attacked by [W]. Attacker - [user]") + if(prob(chassis.deflect_chance*deflect_coeff)) + user << "\The [W] bounces off [chassis] armor." + chassis.log_append_to_last("Armor saved.") + else + chassis.occupant_message("\The [user] hits [chassis] with [W].") + user.visible_message("\The [user] hits [chassis] with [W].", "You hit [src] with [W].") + chassis.take_damage(round(W.force*damage_coeff),W.damtype) + chassis.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) + set_ready_state(0) + chassis.use_power(energy_drain) + do_after_cooldown() + return /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster @@ -543,63 +554,65 @@ var/deflect_coeff = 1.15 var/damage_coeff = 0.8 - can_attach(obj/mecha/M as obj) - if(..()) - if(!M.proc_res["dynbulletdamage"] && !M.proc_res["dynhitby"]) - return 1 - return 0 + equip_type = EQUIP_HULL - attach(obj/mecha/M as obj) - ..() - chassis.proc_res["dynbulletdamage"] = src - chassis.proc_res["dynhitby"] = src - return +/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/can_attach(obj/mecha/M as obj) + if(..()) + if(!M.proc_res["dynbulletdamage"] && !M.proc_res["dynhitby"]) + return 1 + return 0 - detach() - chassis.proc_res["dynbulletdamage"] = null - chassis.proc_res["dynhitby"] = null - ..() - return +/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/attach(obj/mecha/M as obj) + ..() + chassis.proc_res["dynbulletdamage"] = src + chassis.proc_res["dynhitby"] = src + return - get_equip_info() - if(!chassis) return - return "* [src.name]" +/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/detach() + chassis.proc_res["dynbulletdamage"] = null + chassis.proc_res["dynhitby"] = null + ..() + return - proc/dynbulletdamage(var/obj/item/projectile/Proj) - if(!action_checks(src)) - return chassis.dynbulletdamage(Proj) - if(prob(chassis.deflect_chance*deflect_coeff)) - chassis.occupant_message("The armor deflects incoming projectile.") - chassis.visible_message("The [chassis.name] armor deflects the projectile") - chassis.log_append_to_last("Armor saved.") - else - chassis.take_damage(round(Proj.damage*src.damage_coeff),Proj.check_armour) - chassis.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) - Proj.on_hit(chassis) - set_ready_state(0) - chassis.use_power(energy_drain) - do_after_cooldown() - return +/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/get_equip_info() + if(!chassis) return + return "* [src.name]" - proc/dynhitby(atom/movable/A) - if(!action_checks(A)) - return chassis.dynhitby(A) - if(prob(chassis.deflect_chance*deflect_coeff) || istype(A, /mob/living) || istype(A, /obj/item/mecha_parts/mecha_tracking)) - chassis.occupant_message("The [A] bounces off the armor.") - chassis.visible_message("The [A] bounces off the [chassis] armor") - chassis.log_append_to_last("Armor saved.") - if(istype(A, /mob/living)) - var/mob/living/M = A - M.take_organ_damage(10) - else if(istype(A, /obj)) - var/obj/O = A - if(O.throwforce) - chassis.take_damage(round(O.throwforce*damage_coeff)) - chassis.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) - set_ready_state(0) - chassis.use_power(energy_drain) - do_after_cooldown() - return +/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/proc/dynbulletdamage(var/obj/item/projectile/Proj) + if(!action_checks(src)) + return chassis.dynbulletdamage(Proj) + if(prob(chassis.deflect_chance*deflect_coeff)) + chassis.occupant_message("The armor deflects incoming projectile.") + chassis.visible_message("The [chassis.name] armor deflects the projectile") + chassis.log_append_to_last("Armor saved.") + else + chassis.take_damage(round(Proj.damage*src.damage_coeff),Proj.check_armour) + chassis.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) + Proj.on_hit(chassis) + set_ready_state(0) + chassis.use_power(energy_drain) + do_after_cooldown() + return + +/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster/proc/dynhitby(atom/movable/A) + if(!action_checks(A)) + return chassis.dynhitby(A) + if(prob(chassis.deflect_chance*deflect_coeff) || istype(A, /mob/living) || istype(A, /obj/item/mecha_parts/mecha_tracking)) + chassis.occupant_message("The [A] bounces off the armor.") + chassis.visible_message("The [A] bounces off the [chassis] armor") + chassis.log_append_to_last("Armor saved.") + if(istype(A, /mob/living)) + var/mob/living/M = A + M.take_organ_damage(10) + else if(istype(A, /obj)) + var/obj/O = A + if(O.throwforce) + chassis.take_damage(round(O.throwforce*damage_coeff)) + chassis.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) + set_ready_state(0) + chassis.use_power(energy_drain) + do_after_cooldown() + return /obj/item/mecha_parts/mecha_equipment/repair_droid @@ -615,85 +628,87 @@ var/icon/droid_overlay var/list/repairable_damage = list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH) - New() - ..() - pr_repair_droid = new /datum/global_iterator/mecha_repair_droid(list(src),0) - pr_repair_droid.set_delay(equip_cooldown) - return + equip_type = EQUIP_HULL - Destroy() - qdel(pr_repair_droid) - pr_repair_droid = null - ..() +/obj/item/mecha_parts/mecha_equipment/repair_droid/New() + ..() + pr_repair_droid = new /datum/global_iterator/mecha_repair_droid(list(src),0) + pr_repair_droid.set_delay(equip_cooldown) + return - attach(obj/mecha/M as obj) - ..() - droid_overlay = new(src.icon, icon_state = "repair_droid") - M.overlays += droid_overlay - return +/obj/item/mecha_parts/mecha_equipment/repair_droid/Destroy() + qdel(pr_repair_droid) + pr_repair_droid = null + ..() - destroy() +/obj/item/mecha_parts/mecha_equipment/repair_droid/attach(obj/mecha/M as obj) + ..() + droid_overlay = new(src.icon, icon_state = "repair_droid") + M.overlays += droid_overlay + return + +/obj/item/mecha_parts/mecha_equipment/repair_droid/destroy() + chassis.overlays -= droid_overlay + ..() + return + +/obj/item/mecha_parts/mecha_equipment/repair_droid/detach() + chassis.overlays -= droid_overlay + pr_repair_droid.stop() + ..() + return + +/obj/item/mecha_parts/mecha_equipment/repair_droid/get_equip_info() + if(!chassis) return + return "* [src.name] - [pr_repair_droid.active()?"Dea":"A"]ctivate" + + +/obj/item/mecha_parts/mecha_equipment/repair_droid/Topic(href, href_list) + ..() + if(href_list["toggle_repairs"]) chassis.overlays -= droid_overlay - ..() - return - - detach() - chassis.overlays -= droid_overlay - pr_repair_droid.stop() - ..() - return - - get_equip_info() - if(!chassis) return - return "* [src.name] - [pr_repair_droid.active()?"Dea":"A"]ctivate" - - - Topic(href, href_list) - ..() - if(href_list["toggle_repairs"]) - chassis.overlays -= droid_overlay - if(pr_repair_droid.toggle()) - droid_overlay = new(src.icon, icon_state = "repair_droid_a") - log_message("Activated.") - else - droid_overlay = new(src.icon, icon_state = "repair_droid") - log_message("Deactivated.") - set_ready_state(1) - chassis.overlays += droid_overlay - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) - return + if(pr_repair_droid.toggle()) + droid_overlay = new(src.icon, icon_state = "repair_droid_a") + log_message("Activated.") + else + droid_overlay = new(src.icon, icon_state = "repair_droid") + log_message("Deactivated.") + set_ready_state(1) + chassis.overlays += droid_overlay + send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) + return /datum/global_iterator/mecha_repair_droid - process(var/obj/item/mecha_parts/mecha_equipment/repair_droid/RD as obj) - if(!RD.chassis) +/datum/global_iterator/mecha_repair_droid/process(var/obj/item/mecha_parts/mecha_equipment/repair_droid/RD as obj) + if(!RD.chassis) + stop() + RD.set_ready_state(1) + return + var/health_boost = RD.health_boost + var/repaired = 0 + if(RD.chassis.hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) + health_boost *= -2 + else if(RD.chassis.hasInternalDamage() && prob(15)) + for(var/int_dam_flag in RD.repairable_damage) + if(RD.chassis.hasInternalDamage(int_dam_flag)) + RD.chassis.clearInternalDamage(int_dam_flag) + repaired = 1 + break + if(health_boost<0 || RD.chassis.health < initial(RD.chassis.health)) + RD.chassis.health += min(health_boost, initial(RD.chassis.health)-RD.chassis.health) + repaired = 1 + if(repaired) + if(RD.chassis.use_power(RD.energy_drain)) + RD.set_ready_state(0) + else stop() RD.set_ready_state(1) return - var/health_boost = RD.health_boost - var/repaired = 0 - if(RD.chassis.hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) - health_boost *= -2 - else if(RD.chassis.hasInternalDamage() && prob(15)) - for(var/int_dam_flag in RD.repairable_damage) - if(RD.chassis.hasInternalDamage(int_dam_flag)) - RD.chassis.clearInternalDamage(int_dam_flag) - repaired = 1 - break - if(health_boost<0 || RD.chassis.health < initial(RD.chassis.health)) - RD.chassis.health += min(health_boost, initial(RD.chassis.health)-RD.chassis.health) - repaired = 1 - if(repaired) - if(RD.chassis.use_power(RD.energy_drain)) - RD.set_ready_state(0) - else - stop() - RD.set_ready_state(1) - return - else - RD.set_ready_state(1) - return + else + RD.set_ready_state(1) + return /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay @@ -708,71 +723,73 @@ var/coeff = 100 var/list/use_channels = list(EQUIP,ENVIRON,LIGHT) - New() - ..() - pr_energy_relay = new /datum/global_iterator/mecha_energy_relay(list(src),0) - pr_energy_relay.set_delay(equip_cooldown) - return + equip_type = EQUIP_UTILITY - Destroy() - qdel(pr_energy_relay) - pr_energy_relay = null - ..() +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/New() + ..() + pr_energy_relay = new /datum/global_iterator/mecha_energy_relay(list(src),0) + pr_energy_relay.set_delay(equip_cooldown) + return - detach() - pr_energy_relay.stop() -// chassis.proc_res["dynusepower"] = null - chassis.proc_res["dyngetcharge"] = null - ..() - return +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/Destroy() + qdel(pr_energy_relay) + pr_energy_relay = null + ..() - attach(obj/mecha/M) - ..() - chassis.proc_res["dyngetcharge"] = src -// chassis.proc_res["dynusepower"] = src - return +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/detach() + pr_energy_relay.stop() +// chassis.proc_res["dynusepower"] = null + chassis.proc_res["dyngetcharge"] = null + ..() + return - can_attach(obj/mecha/M) - if(..()) - if(!M.proc_res["dyngetcharge"])// && !M.proc_res["dynusepower"]) - return 1 - return 0 +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/attach(obj/mecha/M) + ..() + chassis.proc_res["dyngetcharge"] = src +// chassis.proc_res["dynusepower"] = src + return - proc/dyngetcharge() - if(equip_ready) //disabled - return chassis.dyngetcharge() - var/area/A = get_area(chassis) - var/pow_chan = get_power_channel(A) - var/charge = 0 - if(pow_chan) - charge = 1000 //making magic +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/can_attach(obj/mecha/M) + if(..()) + if(!M.proc_res["dyngetcharge"])// && !M.proc_res["dynusepower"]) + return 1 + return 0 + +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/dyngetcharge() + if(equip_ready) //disabled + return chassis.dyngetcharge() + var/area/A = get_area(chassis) + var/pow_chan = get_power_channel(A) + var/charge = 0 + if(pow_chan) + charge = 1000 //making magic + else + return chassis.dyngetcharge() + return charge + +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/proc/get_power_channel(var/area/A) + var/pow_chan + if(A) + for(var/c in use_channels) + if(A.powered(c)) + pow_chan = c + break + return pow_chan + +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/Topic(href, href_list) + ..() + if(href_list["toggle_relay"]) + if(pr_energy_relay.toggle()) + set_ready_state(0) + log_message("Activated.") else - return chassis.dyngetcharge() - return charge + set_ready_state(1) + log_message("Deactivated.") + return - proc/get_power_channel(var/area/A) - var/pow_chan - if(A) - for(var/c in use_channels) - if(A.powered(c)) - pow_chan = c - break - return pow_chan - - Topic(href, href_list) - ..() - if(href_list["toggle_relay"]) - if(pr_energy_relay.toggle()) - set_ready_state(0) - log_message("Activated.") - else - set_ready_state(1) - log_message("Deactivated.") - return - - get_equip_info() - if(!chassis) return - return "* [src.name] - [pr_energy_relay.active()?"Dea":"A"]ctivate" +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/get_equip_info() + if(!chassis) return + return "* [src.name] - [pr_energy_relay.active()?"Dea":"A"]ctivate" /* proc/dynusepower(amount) if(!equip_ready) //enabled @@ -785,30 +802,30 @@ /datum/global_iterator/mecha_energy_relay - process(var/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/ER) - if(!ER.chassis || ER.chassis.hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) - stop() - ER.set_ready_state(1) - return - var/cur_charge = ER.chassis.get_charge() - if(isnull(cur_charge) || !ER.chassis.cell) - stop() - ER.set_ready_state(1) - ER.occupant_message("No powercell detected.") - return - if(cur_charge3\] - [pr_mech_generator.active()?"Dea":"A"]ctivate" - return +/obj/item/mecha_parts/mecha_equipment/generator/get_equip_info() + var/output = ..() + if(output) + return "[output] \[[fuel]: [round(fuel.amount*fuel.perunit,0.1)] cm3\] - [pr_mech_generator.active()?"Dea":"A"]ctivate" + return - action(target) - if(chassis) - var/result = load_fuel(target) - var/message - if(isnull(result)) - message = "[fuel] traces in target minimal. [target] cannot be used as fuel." - else if(!result) - message = "Unit is full." - else - message = "[result] unit\s of [fuel] successfully loaded." - send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) - occupant_message(message) - return - - proc/load_fuel(var/obj/item/stack/material/P) - if(P.type == fuel.type && P.amount) - var/to_load = max(max_fuel - fuel.amount*fuel.perunit,0) - if(to_load) - var/units = min(max(round(to_load / P.perunit),1),P.amount) - if(units) - fuel.amount += units - P.use(units) - return units - else - return 0 - return - - attackby(weapon,mob/user) - var/result = load_fuel(weapon) +/obj/item/mecha_parts/mecha_equipment/generator/action(target) + if(chassis) + var/result = load_fuel(target) + var/message if(isnull(result)) - user.visible_message("[user] tries to shove [weapon] into [src]. What a dumb-ass.","[fuel] traces minimal. [weapon] cannot be used as fuel.") + message = "[fuel] traces in target minimal. [target] cannot be used as fuel." else if(!result) - user << "Unit is full." + message = "Unit is full." else - user.visible_message("[user] loads [src] with [fuel].","[result] unit\s of [fuel] successfully loaded.") - return + message = "[result] unit\s of [fuel] successfully loaded." + send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",src.get_equip_info()) + occupant_message(message) + return - critfail() - ..() - var/turf/simulated/T = get_turf(src) - if(!T) - return - var/datum/gas_mixture/GM = new - if(prob(10)) - T.assume_gas("phoron", 100, 1500+T0C) - T.visible_message("The [src] suddenly disgorges a cloud of heated phoron.") - destroy() +/obj/item/mecha_parts/mecha_equipment/generator/proc/load_fuel(var/obj/item/stack/material/P) + if(P.type == fuel.type && P.amount) + var/to_load = max(max_fuel - fuel.amount*fuel.perunit,0) + if(to_load) + var/units = min(max(round(to_load / P.perunit),1),P.amount) + if(units) + fuel.amount += units + P.use(units) + return units else - T.assume_gas("phoron", 5, istype(T) ? T.air.temperature : T20C) - T.visible_message("The [src] suddenly disgorges a cloud of phoron.") - T.assume_air(GM) + return 0 + return + +/obj/item/mecha_parts/mecha_equipment/generator/attackby(weapon,mob/user) + var/result = load_fuel(weapon) + if(isnull(result)) + user.visible_message("[user] tries to shove [weapon] into [src]. What a dumb-ass.","[fuel] traces minimal. [weapon] cannot be used as fuel.") + else if(!result) + user << "Unit is full." + else + user.visible_message("[user] loads [src] with [fuel].","[result] unit\s of [fuel] successfully loaded.") + return + +/obj/item/mecha_parts/mecha_equipment/generator/critfail() + ..() + var/turf/simulated/T = get_turf(src) + if(!T) return + var/datum/gas_mixture/GM = new + if(prob(10)) + T.assume_gas("phoron", 100, 1500+T0C) + T.visible_message("The [src] suddenly disgorges a cloud of heated phoron.") + destroy() + else + T.assume_gas("phoron", 5, istype(T) ? T.air.temperature : T20C) + T.visible_message("The [src] suddenly disgorges a cloud of phoron.") + T.assume_air(GM) + return /datum/global_iterator/mecha_generator - process(var/obj/item/mecha_parts/mecha_equipment/generator/EG) - if(!EG.chassis) - stop() - EG.set_ready_state(1) - return 0 - if(EG.fuel.amount<=0) - stop() - EG.log_message("Deactivated - no fuel.") - EG.set_ready_state(1) - return 0 - var/cur_charge = EG.chassis.get_charge() - if(isnull(cur_charge)) - EG.set_ready_state(1) - EG.occupant_message("No powercell detected.") - EG.log_message("Deactivated.") - stop() - return 0 - var/use_fuel = EG.fuel_per_cycle_idle - if(cur_charge[target] succesfully loaded.") - chassis.log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") - else - chassis.occupant_message("You must hold still while handling objects.") - O.anchored = initial(O.anchored) - else - chassis.occupant_message("Not enough room in cargo compartment.") - else - chassis.occupant_message("[target] is firmly secured.") +/obj/item/mecha_parts/mecha_equipment/tool/safety_clamp/attach(obj/mecha/M as obj) + ..() + cargo_holder = M + return - else if(istype(target,/mob/living)) - var/mob/living/M = target - if(M.stat>1) return - if(chassis.occupant.a_intent == I_HURT) - chassis.occupant_message("You obliterate [target] with [src.name], leaving blood and guts everywhere.") - chassis.visible_message("[chassis] destroys [target] in an unholy fury.") - if(chassis.occupant.a_intent == I_DISARM) - chassis.occupant_message("You tear [target]'s limbs off with [src.name].") - chassis.visible_message("[chassis] rips [target]'s arms off.") +/obj/item/mecha_parts/mecha_equipment/tool/safety_clamp/action(atom/target) + if(!action_checks(target)) return + if(!cargo_holder) return + if(istype(target,/obj)) + var/obj/O = target + if(!O.anchored) + if(cargo_holder.cargo.len < cargo_holder.cargo_capacity) + chassis.occupant_message("You lift [target] and start to load it into cargo compartment.") + chassis.visible_message("[chassis] lifts [target] and starts to load it into cargo compartment.") + set_ready_state(0) + chassis.use_power(energy_drain) + O.anchored = 1 + var/T = chassis.loc + if(do_after_cooldown(target)) + if(T == chassis.loc && src == chassis.selected) + cargo_holder.cargo += O + O.loc = chassis + O.anchored = 0 + chassis.occupant_message("[target] succesfully loaded.") + chassis.log_message("Loaded [O]. Cargo compartment capacity: [cargo_holder.cargo_capacity - cargo_holder.cargo.len]") + else + chassis.occupant_message("You must hold still while handling objects.") + O.anchored = initial(O.anchored) else - step_away(M,chassis) - chassis.occupant_message("You smash into [target], sending them flying.") - chassis.visible_message("[chassis] tosses [target] like a piece of paper.") - set_ready_state(0) - chassis.use_power(energy_drain) - do_after_cooldown() - return 1 + chassis.occupant_message("Not enough room in cargo compartment.") + else + chassis.occupant_message("[target] is firmly secured.") + + else if(istype(target,/mob/living)) + var/mob/living/M = target + if(M.stat>1) return + if(chassis.occupant.a_intent == I_HURT) + chassis.occupant_message("You obliterate [target] with [src.name], leaving blood and guts everywhere.") + chassis.visible_message("[chassis] destroys [target] in an unholy fury.") + if(chassis.occupant.a_intent == I_DISARM) + chassis.occupant_message("You tear [target]'s limbs off with [src.name].") + chassis.visible_message("[chassis] rips [target]'s arms off.") + else + step_away(M,chassis) + chassis.occupant_message("You smash into [target], sending them flying.") + chassis.visible_message("[chassis] tosses [target] like a piece of paper.") + set_ready_state(0) + chassis.use_power(energy_drain) + do_after_cooldown() + return 1 /obj/item/mecha_parts/mecha_equipment/tool/passenger name = "passenger compartment" @@ -1052,6 +1073,8 @@ var/door_locked = 1 salvageable = 0 + equip_type = EQUIP_HULL + /obj/item/mecha_parts/mecha_equipment/tool/passenger/destroy() for(var/atom/movable/AM in src) AM.forceMove(get_turf(src)) diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 8d65768b28..7ffc0dd49b 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) + equip_type = EQUIP_WEAPON + /obj/item/mecha_parts/mecha_equipment/weapon/action_checks(atom/target) if(projectiles <= 0) return 0 @@ -68,12 +70,14 @@ equip_cooldown = 30 name = "jury-rigged welder-laser" desc = "While not regulation, this inefficient weapon can be attached to working exo-suits in desperate, or malicious, times." - icon_state = "mecha_laser" + icon_state = "mecha_laser-rig" energy_drain = 80 projectile = /obj/item/projectile/beam fire_sound = 'sound/weapons/Laser.ogg' required_type = list(/obj/mecha/combat, /obj/mecha/working) + equip_type = EQUIP_UTILITY + /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy equip_cooldown = 15 name = "\improper CH-LC \"Solaris\" laser cannon" @@ -127,6 +131,8 @@ equip_cooldown = 150 origin_tech = list(TECH_MATERIAL = 2, TECH_COMBAT = 4, TECH_ILLEGAL = 1) + equip_type = EQUIP_SPECIAL + /obj/item/mecha_parts/mecha_equipment/honker/action(target) if(!chassis) return 0 @@ -198,7 +204,7 @@ equip_cooldown = 10 projectile = /obj/item/projectile/bullet/pistol/medium fire_sound = 'sound/weapons/machinegun.ogg' - projectiles = 300 + projectiles = 30 //10 bursts, matching the Scattershot's 10. Also, conveniently, doesn't eat your powercell when reloading like 300 bullets does. projectiles_per_shot = 3 deviation = 0.3 projectile_energy_cost = 20 @@ -224,6 +230,8 @@ missile_range = 15 required_type = /obj/mecha //Why restrict it to just mining or combat mechs? + equip_type = EQUIP_UTILITY + /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flare/Fire(atom/movable/AM, atom/target, turf/aimloc) var/obj/item/device/flashlight/flare/fired = AM fired.ignite() @@ -249,13 +257,13 @@ var/primed = null throwforce = 15 - throw_impact(atom/hit_atom) - if(primed) - explosion(hit_atom, 0, 1, 2, 4) - qdel(src) - else - ..() - return +/obj/item/missile/throw_impact(atom/hit_atom) + if(primed) + explosion(hit_atom, 0, 1, 2, 4) + qdel(src) + else + ..() + return /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/flashbang name = "\improper SGL-6 grenade launcher" @@ -320,6 +328,7 @@ /obj/item/mecha_parts/mecha_equipment/weapon/energy/flamer/rigged name = "\improper AA-CR-1 Mark 4" description_fluff = "A firefighting tool maintained by Aether Atmospherics, whose initial design originated from a small Earth company. This one seems to have been jury rigged." + icon_state = "mecha_cremate-rig" energy_drain = 50 required_type = list(/obj/mecha/combat, /obj/mecha/working) @@ -328,6 +337,8 @@ origin_tech = list(TECH_MATERIAL = 3, TECH_COMBAT = 3, TECH_PHORON = 3, TECH_ILLEGAL = 2) + equip_type = EQUIP_UTILITY + ////////////// //Defensive// ////////////// @@ -343,6 +354,8 @@ var/shock_damage = 15 var/active + equip_type = EQUIP_HULL + /obj/item/mecha_parts/mecha_equipment/shocker/can_attach(obj/mecha/M as obj) if(..()) if(!M.proc_res["dynattackby"] && !M.proc_res["dynattackhand"] && !M.proc_res["dynattackalien"]) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index f410dbb014..0812602eeb 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -24,6 +24,7 @@ var/dir_in = 2//What direction will the mech face when entered/powered on? Defaults to South. var/step_energy_drain = 10 var/health = 300 //health is health + var/maxhealth = 300 //maxhealth is maxhealth. var/deflect_chance = 10 //chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act. //the values in this list show how much damage will pass through, not how much will be absorbed. var/list/damage_absorption = list("brute"=0.8,"fire"=1.2,"bullet"=0.9,"laser"=1,"energy"=1,"bomb"=1) @@ -66,8 +67,23 @@ var/list/equipment = new var/obj/item/mecha_parts/mecha_equipment/selected - var/max_equip = 3 + var/max_equip = 2 var/datum/events/events +//mechaequipt2 stuffs + var/list/hull_equipment = new + var/list/weapon_equipment = new + var/list/utility_equipment = new + var/list/universal_equipment = new + var/list/special_equipment = new + var/max_hull_equip = 2 + var/max_weapon_equip = 2 + var/max_utility_equip = 2 + var/max_universal_equip = 2 + var/max_special_equip = 1 +//Working exosuit vars + var/list/cargo = list() + var/cargo_capacity = 3 + /obj/mecha/drain_power(var/drain_check) @@ -99,10 +115,24 @@ mechas_list += src //global mech list return +/obj/mecha/Exit(atom/movable/O) + if(O in cargo) + return 0 + return ..() + /obj/mecha/Destroy() src.go_out() - for(var/mob/M in src) //Let's just be ultra sure - M.Move(loc) + for(var/mob/M in src) //Be Extra Sure + M.forceMove(get_turf(src)) + M.loc.Entered(M) + if(M != src.occupant) + step_rand(M) + for(var/atom/movable/A in src.cargo) + A.forceMove(get_turf(src)) + var/turf/T = get_turf(A) + if(T) + T.Entered(A) + step_rand(A) if(loc) loc.Exited(src) @@ -112,6 +142,11 @@ if(wreckage) var/obj/effect/decal/mecha_wreckage/WR = new wreckage(loc) + hull_equipment.Cut() + weapon_equipment.Cut() + utility_equipment.Cut() + universal_equipment.Cut() + special_equipment.Cut() for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) if(E.salvageable && prob(30)) WR.crowbar_salvage += E @@ -1348,6 +1383,14 @@ Lights: [lights?"on":"off"]
[src.dna?"DNA-locked:
[src.dna] \[Reset\]
":null] "} +//Cargo components. + output += "Cargo Compartment Contents:
" + if(src.cargo.len) + for(var/obj/O in src.cargo) + output += "Unload : [O]
" + else + output += "Nothing" + output += "
" return output /obj/mecha/proc/get_commands() @@ -1396,10 +1439,23 @@ output += {"
Equipment
" + for(var/obj/item/mecha_parts/mecha_equipment/W in hull_equipment) + output += "Hull Module: [W.name] Detach
" + for(var/obj/item/mecha_parts/mecha_equipment/W in weapon_equipment) + output += "Weapon Module: [W.name] Detach
" + for(var/obj/item/mecha_parts/mecha_equipment/W in utility_equipment) + output += "Utility Module: [W.name] Detach
" + for(var/obj/item/mecha_parts/mecha_equipment/W in universal_equipment) + output += "Universal Module: [W.name] Detach
" + for(var/obj/item/mecha_parts/mecha_equipment/W in special_equipment) + output += "Special Module: [W.name] Detach
" + 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]
+ + "} return output /obj/mecha/proc/get_equipment_list() //outputs mecha equipment list in html @@ -1673,6 +1729,17 @@ else src.occupant_message("Recalibration failed.") src.log_message("Recalibration of coordination system failed with 1 error.",1) + if(href_list["drop_from_cargo"]) + var/obj/O = locate(href_list["drop_from_cargo"]) + if(O && O in src.cargo) + src.occupant_message("You unload [O].") + O.forceMove(get_turf(src)) + src.cargo -= O + var/turf/T = get_turf(O) + if(T) + T.Entered(O) + src.log_message("Unloaded [O]. Cargo compartment capacity: [cargo_capacity - src.cargo.len]") + return //debug /* diff --git a/code/game/mecha/medical/medical.dm b/code/game/mecha/medical/medical.dm index e112f7a232..adb75800ea 100644 --- a/code/game/mecha/medical/medical.dm +++ b/code/game/mecha/medical/medical.dm @@ -1,3 +1,12 @@ +/obj/mecha/medical + max_hull_equip = 1 + max_weapon_equip = 0 + max_utility_equip = 2 + max_universal_equip = 1 + max_special_equip = 1 + + cargo_capacity = 1 + /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 90577eaf64..8a1242d1a2 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" icon_state = "odysseus" @@ -6,36 +6,37 @@ step_in = 2 max_temperature = 15000 health = 120 + maxhealth = 120 wreckage = /obj/effect/decal/mecha_wreckage/odysseus internal_damage_threshold = 35 deflect_chance = 15 step_energy_drain = 6 var/obj/item/clothing/glasses/hud/health/mech/hud - New() - ..() - hud = new /obj/item/clothing/glasses/hud/health/mech(src) - return +/obj/mecha/medical/odysseus/New() + ..() + hud = new /obj/item/clothing/glasses/hud/health/mech(src) + return - moved_inside(var/mob/living/carbon/human/H as mob) - if(..()) - if(H.glasses) - occupant_message("[H.glasses] prevent you from using [src] [hud]") - else - H.glasses = hud - H.recalculate_vis() - return 1 +/obj/mecha/medical/odysseus/moved_inside(var/mob/living/carbon/human/H as mob) + if(..()) + if(H.glasses) + occupant_message("[H.glasses] prevent you from using [src] [hud]") else - return 0 + H.glasses = hud + H.recalculate_vis() + return 1 + else + return 0 - go_out() - if(ishuman(occupant)) - var/mob/living/carbon/human/H = occupant - if(H.glasses == hud) - H.glasses = null - H.recalculate_vis() - ..() - return +/obj/mecha/medical/odysseus/go_out() + if(ishuman(occupant)) + var/mob/living/carbon/human/H = occupant + if(H.glasses == hud) + H.glasses = null + H.recalculate_vis() + ..() + return /* verb/set_perspective() set name = "Set client perspective." diff --git a/code/game/mecha/working/hoverpod.dm b/code/game/mecha/working/hoverpod.dm index b0448c69a0..8a79b5a8ac 100644 --- a/code/game/mecha/working/hoverpod.dm +++ b/code/game/mecha/working/hoverpod.dm @@ -8,6 +8,7 @@ step_energy_drain = 10 max_temperature = 20000 health = 150 + maxhealth = 150 infra_luminosity = 6 wreckage = /obj/effect/decal/mecha_wreckage/hoverpod cargo_capacity = 5 @@ -15,6 +16,12 @@ var/datum/effect/effect/system/ion_trail_follow/ion_trail var/stabilization_enabled = 1 + max_hull_equip = 2 + max_weapon_equip = 0 + max_utility_equip = 2 + max_universal_equip = 1 + max_special_equip = 1 + /obj/mecha/working/hoverpod/New() ..() ion_trail = new /datum/effect/effect/system/ion_trail_follow() @@ -51,7 +58,7 @@ ion_trail.start() if (stabilization_enabled) return 1 - + return ..() //these three procs overriden to play different sounds @@ -79,9 +86,15 @@ desc = "An ancient, run-down combat spacecraft." // Ideally would have a seperate icon. name = "Combat Hoverpod" health = 200 + maxhealth = 200 internal_damage_threshold = 35 cargo_capacity = 2 max_equip = 2 + max_hull_equip = 2 + max_weapon_equip = 2 + max_utility_equip = 2 + max_universal_equip = 1 + max_special_equip = 1 /obj/mecha/working/hoverpod/combatpod/New() ..() diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm index 765f0706b8..fbca4779b2 100644 --- a/code/game/mecha/working/ripley.dm +++ b/code/game/mecha/working/ripley.dm @@ -6,6 +6,7 @@ step_in = 6 max_temperature = 20000 health = 200 + maxhealth = 200 wreckage = /obj/effect/decal/mecha_wreckage/ripley cargo_capacity = 10 @@ -20,7 +21,7 @@ ..() /obj/mecha/working/ripley/firefighter - desc = "Standart APLU chassis was refitted with additional thermal protection and cistern." + desc = "Standard APLU chassis was refitted with additional thermal protection and cistern." name = "APLU \"Firefighter\"" icon_state = "firefighter" initial_icon = "firefighter" @@ -29,6 +30,11 @@ lights_power = 8 damage_absorption = list("fire"=0.5,"bullet"=0.8,"bomb"=0.5) wreckage = /obj/effect/decal/mecha_wreckage/ripley/firefighter + max_hull_equip = 2 + max_weapon_equip = 0 + max_utility_equip = 2 + max_universal_equip = 1 + max_special_equip = 1 /obj/mecha/working/ripley/deathripley desc = "OH SHIT IT'S THE DEATHSQUAD WE'RE ALL GONNA DIE" @@ -40,6 +46,11 @@ lights_power = 60 wreckage = /obj/effect/decal/mecha_wreckage/ripley/deathripley step_energy_drain = 0 + max_hull_equip = 1 + max_weapon_equip = 1 + max_utility_equip = 3 + max_universal_equip = 1 + max_special_equip = 1 /obj/mecha/working/ripley/deathripley/New() ..() diff --git a/code/game/mecha/working/working.dm b/code/game/mecha/working/working.dm index c890746e5b..dbdf68ce5b 100644 --- a/code/game/mecha/working/working.dm +++ b/code/game/mecha/working/working.dm @@ -1,7 +1,10 @@ /obj/mecha/working internal_damage_threshold = 60 - var/list/cargo = new - var/cargo_capacity = 5 + max_hull_equip = 1 + max_weapon_equip = 0 + max_utility_equip = 3 + max_universal_equip = 1 + max_special_equip = 1 /obj/mecha/working/initialize() . = ..() @@ -9,6 +12,7 @@ if(isPlayerLevel(T.z)) new /obj/item/mecha_parts/mecha_tracking(src) +/* This stuff has been generalized! /obj/mecha/working/Destroy() for(var/mob/M in src) if(M==src.occupant) @@ -54,6 +58,6 @@ output += "Nothing" output += "" return output - +*/ /obj/mecha/working/range_action(atom/target as obj|mob|turf) return diff --git a/html/changelogs/Mechoid - Mecha.yml b/html/changelogs/Mechoid - Mecha.yml new file mode 100644 index 0000000000..a696349c15 --- /dev/null +++ b/html/changelogs/Mechoid - Mecha.yml @@ -0,0 +1,7 @@ + +author: Mechoid + +delete-after: True + +changes: + - rscadd: "Mechs now have multiple equipment slot types, and more slots in total for greater customization." diff --git a/icons/mecha/mecha_equipment.dmi b/icons/mecha/mecha_equipment.dmi index d13c430c8f..3215773403 100644 Binary files a/icons/mecha/mecha_equipment.dmi and b/icons/mecha/mecha_equipment.dmi differ