diff --git a/baystation12.dme b/baystation12.dme index 1c112b009c..d098214840 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -64,6 +64,7 @@ #define FILE_DIR "code/game/mecha/equipment" #define FILE_DIR "code/game/mecha/equipment/tools" #define FILE_DIR "code/game/mecha/equipment/weapons" +#define FILE_DIR "code/game/mecha/medical" #define FILE_DIR "code/game/mecha/working" #define FILE_DIR "code/game/objects" #define FILE_DIR "code/game/objects/alien" @@ -270,6 +271,7 @@ #include "code\datums\diseases\wizarditis.dm" #include "code\datums\diseases\xeno_transformation.dm" #include "code\datums\helper_datums\construction_datum.dm" +#include "code\datums\helper_datums\events.dm" #include "code\datums\helper_datums\getrev.dm" #include "code\datums\helper_datums\global_iterator.dm" #include "code\datums\helper_datums\teleport.dm" @@ -583,6 +585,8 @@ #include "code\game\mecha\equipment\mecha_equipment.dm" #include "code\game\mecha\equipment\tools\tools.dm" #include "code\game\mecha\equipment\weapons\weapons.dm" +#include "code\game\mecha\medical\medical.dm" +#include "code\game\mecha\medical\odysseus.dm" #include "code\game\mecha\working\firefighter.dm" #include "code\game\mecha\working\ripley.dm" #include "code\game\mecha\working\working.dm" diff --git a/code/datums/helper_datums/events.dm b/code/datums/helper_datums/events.dm new file mode 100644 index 0000000000..8ae893b26b --- /dev/null +++ b/code/datums/helper_datums/events.dm @@ -0,0 +1,60 @@ +/* + * WARRANTY VOID IF CODE USED + */ + + +/datum/events + var/list/events + + New() + ..() + events = new + + proc/addEventType(event_type) + if(!(event_type in events) || !islist(events[event_type])) + events[event_type] = list() + return 1 + return + + proc/addEvent(event_type,proc_holder,proc_name) + if(!event_type || !proc_holder || !proc_name) + return + addEventType(event_type) + var/list/event = events[event_type] + var/datum/event/E = new /datum/event(proc_holder,proc_name) + event += E + return E + + proc/fireEvent() + //world << "Events in [args[1]] called" + var/list/event = listgetindex(events,args[1]) + if(istype(event)) + spawn(-1) + for(var/datum/event/E in event) + if(!E.Fire(arglist(args.Copy(2)))) + clearEvent(args[1],E) + return + + proc/clearEvent(event_type,datum/event/E) + if(!event_type || !E) + return + var/list/event = listgetindex(events,event_type) + event -= E + return 1 + + +/datum/event + var/listener + var/proc_name + + New(tlistener,tprocname) + listener = tlistener + proc_name = tprocname + return ..() + + proc/Fire() + //world << "Event fired" + if(listener) + call(listener,proc_name)(arglist(args)) + return 1 + return \ No newline at end of file diff --git a/code/datums/helper_datums/global_iterator.dm b/code/datums/helper_datums/global_iterator.dm index 4ce4cf0d55..0020859f1d 100644 --- a/code/datums/helper_datums/global_iterator.dm +++ b/code/datums/helper_datums/global_iterator.dm @@ -106,7 +106,7 @@ Data storage vars: while(state) sleep(1) if(++lag>10) - CRASH("The global_iterator loop \ref[src] failed to terminate in designated timeframe. Last exec - [get_last_exec_time_as_text()].") + CRASH("The global_iterator loop \ref[src] failed to terminate in designated timeframe. This may be caused by server lagging.") return 1 proc/process() @@ -123,7 +123,7 @@ Data storage vars: proc/set_delay(new_delay) if(isnum(new_delay)) - delay = new_delay>0?(new_delay):1 + delay = max(1, round(new_delay)) return 1 else return 0 diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index c37cd040c0..715fb70e1a 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -33,7 +33,7 @@ return 0 setEffects(aeffectin,aeffectout) setForceTeleport(afteleport) - setSounds(asoundin) + setSounds(asoundin,asoundout) return 1 //must succeed @@ -112,9 +112,7 @@ playSpecials(curturf,effectin,soundin) if(force_teleport) - teleatom.loc.Exited(teleatom) - teleatom.loc = destturf - teleatom.loc.Entered(teleatom) + teleatom.forceMove(destturf) playSpecials(destturf,effectout,soundout) else if(teleatom.Move(destturf)) diff --git a/code/defines/atom.dm b/code/defines/atom.dm index 98c3950a45..ab6809cbc5 100644 --- a/code/defines/atom.dm +++ b/code/defines/atom.dm @@ -233,4 +233,13 @@ its easier to just keep the beam vertical. X.pixel_y=Pixel_y sleep(3) //Changing this to a lower value will cause the beam to follow more smoothly with movement, but it will also be more laggy. //I've found that 3 ticks provided a nice balance for my use. - for(var/obj/effect/overlay/beam/O in orange(10,src)) if(O.BeamSource==src) del O \ No newline at end of file + for(var/obj/effect/overlay/beam/O in orange(10,src)) if(O.BeamSource==src) del O + +atom/movable/proc/forceMove(atom/destination) + if(destination) + if(loc) + loc.Exited(src) + loc = destination + loc.Entered(src) + return 1 + return 0 diff --git a/code/defines/obj/machinery.dm b/code/defines/obj/machinery.dm index 5365249ca4..304933ae0d 100644 --- a/code/defines/obj/machinery.dm +++ b/code/defines/obj/machinery.dm @@ -3,7 +3,7 @@ icon = 'stationobjs.dmi' var stat = 0 - + emagged = 0 use_power = 0 //0 = dont run the auto //1 = run auto, use idle diff --git a/code/defines/procs/helpers.dm b/code/defines/procs/helpers.dm index ad73c88792..6cbb4c7baa 100644 --- a/code/defines/procs/helpers.dm +++ b/code/defines/procs/helpers.dm @@ -1455,6 +1455,10 @@ proc/safepick(list/list) return return pick(list) +//chances are 1:value. anyprob(1) will always return true +proc/anyprob(value) + return (rand(1,value)==value) + proc/view_or_range(distance = world.view , center = usr , type) switch(type) if("view") diff --git a/code/game/machinery/bots/bots.dm b/code/game/machinery/bots/bots.dm index 7b58c68f7a..1a852e33b2 100644 --- a/code/game/machinery/bots/bots.dm +++ b/code/game/machinery/bots/bots.dm @@ -9,7 +9,7 @@ var/maxhealth = 0 var/fire_dam_coeff = 1.0 var/brute_dam_coeff = 1.0 - var/emagged = 0 //Urist: Moving that var to the general /bot tree as it's used by most bots + //var/emagged = 0 //Urist: Moving that var to the general /bot tree as it's used by most bots /obj/machinery/bot/proc/turn_on() diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index a1043334fd..46f8872c8c 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -157,7 +157,6 @@ for reference: var/health = 100.0 var/maxhealth = 100.0 var/locked = 0.0 - var/emagged = 0.0 // req_access = list(access_maint_tunnels) New() diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 48c6a51b93..590fa2635b 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -91,7 +91,6 @@ Class Procs: Compiled by Aygar */ - /obj/machinery/New() ..() machines.Add(src) diff --git a/code/game/magic/library.dm b/code/game/magic/library.dm index 130f8e4317..7b5e7adefd 100644 --- a/code/game/magic/library.dm +++ b/code/game/magic/library.dm @@ -589,7 +589,6 @@ datum/borrowbook // Datum used to keep track of who has borrowed what when and f anchored = 1 density = 1 var - emagged = 0 arcanecheckout = 0 screenstate = 0 // 0 - Main Menu, 1 - Inventory, 2 - Checked Out, 3 - Check Out a Book buffer_book diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm index b022f7663f..e5bcb9a42d 100644 --- a/code/game/mecha/combat/combat.dm +++ b/code/game/mecha/combat/combat.dm @@ -6,6 +6,8 @@ var/list/destroyable_obj = list(/obj/mecha, /obj/structure/window, /obj/structure/grille, /turf/simulated/wall) internal_damage_threshold = 50 maint_access = 0 + //add_req_access = 0 + //operation_req_access = list(access_hos) damage_absorption = list("brute"=0.7,"fire"=1,"bullet"=0.7,"laser"=0.85,"energy"=1,"bomb"=0.8) /* diff --git a/code/game/mecha/combat/durand.dm b/code/game/mecha/combat/durand.dm index 964318a4c1..6dac559b94 100644 --- a/code/game/mecha/combat/durand.dm +++ b/code/game/mecha/combat/durand.dm @@ -6,7 +6,7 @@ dir_in = 1 //Facing North. health = 400 deflect_chance = 20 - damage_absorption = list("brute"=0.4,"fire"=1.1,"bullet"=0.6,"laser"=0.85,"energy"=0.9,"bomb"=0.8) + damage_absorption = list("brute"=0.5,"fire"=1.1,"bullet"=0.65,"laser"=0.85,"energy"=0.9,"bomb"=0.8) max_temperature = 3000 infra_luminosity = 8 force = 40 diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index 0cb3c89388..fa9e2a186d 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -6,13 +6,13 @@ dir_in = 1 //Facing North. health = 300 deflect_chance = 15 - damage_absorption = list("brute"=0.6,"fire"=1,"bullet"=0.8,"laser"=0.6,"energy"=0.7,"bomb"=1) + damage_absorption = list("brute"=0.75,"fire"=1,"bullet"=0.8,"laser"=0.7,"energy"=0.85,"bomb"=1) max_temperature = 3500 infra_luminosity = 6 var/overload = 0 wreckage = /obj/effect/decal/mecha_wreckage/gygax internal_damage_threshold = 35 - max_equip = 4 + max_equip = 3 /* diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm index 7b2c66b8b9..80e5ca0448 100644 --- a/code/game/mecha/combat/marauder.dm +++ b/code/game/mecha/combat/marauder.dm @@ -5,7 +5,7 @@ step_in = 5 health = 500 deflect_chance = 25 - damage_absorption = list("brute"=0.4,"fire"=0.7,"bullet"=0.45,"laser"=0.6,"energy"=0.7,"bomb"=0.7) + damage_absorption = list("brute"=0.5,"fire"=0.7,"bullet"=0.45,"laser"=0.6,"energy"=0.7,"bomb"=0.7) max_temperature = 5000 infra_luminosity = 3 var/zoom = 0 diff --git a/code/game/mecha/combat/phazon.dm b/code/game/mecha/combat/phazon.dm index 2cb59a5591..6bcad8dab5 100644 --- a/code/game/mecha/combat/phazon.dm +++ b/code/game/mecha/combat/phazon.dm @@ -12,6 +12,7 @@ infra_luminosity = 3 wreckage = /obj/effect/decal/mecha_wreckage/phazon add_req_access = 1 + //operation_req_access = list() internal_damage_threshold = 25 force = 15 var/phasing = 0 diff --git a/code/game/mecha/equipment/mecha_equipment.dm b/code/game/mecha/equipment/mecha_equipment.dm index 9739c80994..46f4bc649c 100644 --- a/code/game/mecha/equipment/mecha_equipment.dm +++ b/code/game/mecha/equipment/mecha_equipment.dm @@ -13,6 +13,8 @@ var/energy_drain = 0 var/obj/mecha/chassis = null var/range = MELEE //bitflags + reliability = 1000 + var/salvageable = 1 /obj/item/mecha_parts/mecha_equipment/proc/do_after_cooldown(target=1) @@ -31,6 +33,13 @@ if(chassis) send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list()) send_byjax(chassis.occupant,"exosuit.browser","equipment_menu",chassis.get_equipment_menu(),"dropdowns") + return 1 + return + +/obj/item/mecha_parts/mecha_equipment/proc/update_equip_info() + if(chassis) + send_byjax(chassis.occupant,"exosuit.browser","\ref[src]",get_equip_info()) + return 1 return /obj/item/mecha_parts/mecha_equipment/proc/destroy()//missiles detonating, teleporter creating singularity? @@ -90,7 +99,7 @@ /obj/item/mecha_parts/mecha_equipment/proc/attach(obj/mecha/M as obj) M.equipment += src - src.chassis = M + chassis = M src.loc = M M.log_message("[src] initialized.") if(!M.selected) @@ -103,10 +112,10 @@ chassis.equipment -= src if(chassis.selected == src) chassis.selected = null - src.update_chassis_page() + update_chassis_page() chassis.log_message("[src] removed from equipment.") - src.chassis = null - src.equip_ready = 1 + chassis = null + set_ready_state(1) return diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm index 375b6a3298..bab1d1a7f5 100644 --- a/code/game/mecha/equipment/tools/tools.dm +++ b/code/game/mecha/equipment/tools/tools.dm @@ -6,9 +6,9 @@ var/dam_force = 20 var/obj/mecha/working/ripley/cargo_holder - can_attach(obj/mecha/M as obj) + can_attach(obj/mecha/working/ripley/M as obj) if(..()) - if(istype(M, /obj/mecha/working/ripley)) + if(istype(M)) return 1 return 0 @@ -65,6 +65,7 @@ /obj/item/mecha_parts/mecha_equipment/tool/drill name = "Drill" + desc = "This is the drill that'll pierce the heavens! (Can be attached to: Combat and Engineering Exosuits)" icon_state = "mecha_drill" equip_cooldown = 30 energy_drain = 10 @@ -76,7 +77,6 @@ chassis.use_power(energy_drain) chassis.visible_message("[chassis] starts to drill [target]", "You hear the drill.") chassis.occupant_message("You start to drill [target]") - chassis.use_power(energy_drain) var/T = chassis.loc var/C = target.loc //why are these backwards? we may never know -Pete if(do_after_cooldown(target)) @@ -99,9 +99,16 @@ target.ex_act(2) return 1 + can_attach(obj/mecha/M as obj) + if(..()) + if(istype(M, /obj/mecha/working) || istype(M, /obj/mecha/combat)) + return 1 + return 0 + /obj/item/mecha_parts/mecha_equipment/tool/extinguisher name = "Extinguisher" + desc = "Exosuit-mounted extinguisher (Can be attached to: Engineering exosuits)" icon_state = "mecha_exting" equip_cooldown = 5 energy_drain = 0 @@ -164,13 +171,19 @@ on_reagent_change() return + can_attach(obj/mecha/working/M as obj) + if(..()) + if(istype(M)) + return 1 + return 0 + /obj/item/mecha_parts/mecha_equipment/tool/rcd name = "Mounted RCD" - desc = "An exosuit-mounted Rapid Construction Device." + desc = "An exosuit-mounted Rapid Construction Device. (Can be attached to: Any exosuit)" icon_state = "mecha_rcd" origin_tech = "materials=4;bluespace=3;magnets=4;powerstorage=4" - equip_cooldown = 20 + equip_cooldown = 10 energy_drain = 250 range = MELEE|RANGED construction_time = 1200 @@ -341,7 +354,7 @@ icon_state = "mecha_teleport" origin_tech = "bluespace=2;magnets=3" equip_cooldown = 10 - energy_drain = 200 + energy_drain = 100 range = MELEE|RANGED var/atom/movable/locked var/mode = 1 //1 - gravsling 2 - gravpush @@ -496,6 +509,7 @@ else chassis.take_damage(round(Proj.damage*src.damage_coeff),Proj.flag) 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() @@ -528,12 +542,13 @@ icon_state = "repair_droid" origin_tech = "magnets=3;programming=3" equip_cooldown = 20 - energy_drain = 20 + energy_drain = 100 range = 0 construction_cost = list("metal"=10000,"gold"=1000,"silver"=2000,"glass"=5000) var/health_boost = 2 var/datum/global_iterator/pr_repair_droid var/icon/droid_overlay + var/list/repairable_damage = list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH) New() ..() @@ -583,28 +598,29 @@ process(var/obj/item/mecha_parts/mecha_equipment/repair_droid/RD as obj) if(!RD.chassis) + stop() RD.set_ready_state(1) - return src.stop() + return + var/health_boost = RD.health_boost var/repaired = 0 - if(RD.chassis.health < initial(RD.chassis.health)) - RD.chassis.health += min(RD.health_boost, initial(RD.chassis.health)-RD.chassis.health) + 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(RD.chassis.internal_damage && prob(20)) - if(RD.chassis.internal_damage&MECHA_INT_TEMP_CONTROL) - RD.chassis.internal_damage &= ~MECHA_INT_TEMP_CONTROL - repaired = 1 - else if(RD.chassis.internal_damage&MECHA_INT_SHORT_CIRCUIT) - RD.chassis.internal_damage &= ~MECHA_INT_SHORT_CIRCUIT - repaired = 1 - else if(RD.chassis.internal_damage&MECHA_INT_TANK_BREACH) - RD.chassis.internal_damage &= ~MECHA_INT_TANK_BREACH - repaired = 1 - else if(RD.chassis.internal_damage&MECHA_INT_CONTROL_LOST) - RD.chassis.internal_damage &= ~MECHA_INT_CONTROL_LOST - repaired = 1 if(repaired) - RD.chassis.use_power(RD.energy_drain) - RD.set_ready_state(0) + 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 @@ -614,13 +630,14 @@ name = "Energy Relay" desc = "Wirelessly drains energy from any available power channel in area. The performance index is quite low." icon_state = "tesla" - origin_tech = "magnets=3" + origin_tech = "magnets=4;syndicate=2" equip_cooldown = 10 energy_drain = 0 range = 0 construction_cost = list("metal"=10000,"gold"=2000,"silver"=3000,"glass"=2000) var/datum/global_iterator/pr_energy_relay var/coeff = 100 + var/list/use_channels = list(EQUIP,ENVIRON,LIGHT) New() ..() @@ -631,20 +648,41 @@ detach() pr_energy_relay.stop() chassis.proc_res["dynusepower"] = null + chassis.proc_res["dyngetcharge"] = null ..() return attach(obj/mecha/M) ..() + chassis.proc_res["dyngetcharge"] = src chassis.proc_res["dynusepower"] = src return can_attach(obj/mecha/M) if(..()) - if(!M.proc_res["dynusepower"]) + if(!M.proc_res["dynusepower"] && !M.proc_res["dyngetcharge"]) return 1 return 0 + proc/dyngetcharge() + if(equip_ready) //disabled + return chassis.dyngetcharge() + var/area/A = get_area(chassis) + var/pow_chan = get_power_channel(A) + var/charge + if(pow_chan) + charge = 1000 //making magic + return charge + + proc/get_power_channel(var/area/A) + var/pow_chan + if(A) + for(var/c in use_channels) + if(A.master && A.master.powered(c)) + pow_chan = c + break + return pow_chan + Topic(href, href_list) ..() if(href_list["toggle_relay"]) @@ -663,28 +701,25 @@ proc/dynusepower(amount) if(!equip_ready) //enabled var/area/A = get_area(chassis) - if(A) - var/pow_chan - for(var/c in list(EQUIP,ENVIRON,LIGHT)) - if(A.master.powered(c)) - pow_chan = c - break - if(pow_chan) - A.master.use_power(amount*coeff, pow_chan) - return 1 + var/pow_chan = get_power_channel(A) + if(pow_chan) + A.master.use_power(amount*coeff, pow_chan) + return 1 return chassis.dynusepower(amount) /datum/global_iterator/mecha_energy_relay process(var/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay/ER) - if(!ER.chassis) + if(!ER.chassis || ER.chassis.hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) + stop() ER.set_ready_state(1) - return stop() + return var/cur_charge = ER.chassis.get_charge() if(isnull(cur_charge)) + stop() ER.set_ready_state(1) ER.chassis.occupant_message("No powercell detected.") - return stop() + return if(cur_chargeEG.reliability) + if(anyprob(EG.reliability)) EG.critfail() return stop() var/cur_charge = EG.chassis.get_charge() @@ -827,12 +863,373 @@ if(cur_chargeThe sleeper is already occupied!") + return + target.forceMove(src) + occupant = target + target.reset_view(src) + /* + if(target.client) + target.client.perspective = EYE_PERSPECTIVE + target.client.eye = chassis + */ + set_ready_state(0) + pr_mech_sleeper.start() + chassis.occupant_message("[target] successfully loaded into [src]. Life support functions engaged.") + chassis.visible_message("[chassis] loads [target] into the [src].") + chassis.log_message("[src]: [target] loaded. Life support functions engaged.") + return + + proc/go_out() + if(!occupant) + return + occupant.forceMove(get_turf(src)) + chassis.occupant_message("[occupant] ejected. Life support functions disabled.") + chassis.log_message("[src]: [occupant] ejected. Life support functions disabled.") + occupant.reset_view() + /* + if(occupant.client) + occupant.client.eye = occupant.client.mob + occupant.client.perspective = MOB_PERSPECTIVE + */ + occupant = null + pr_mech_sleeper.stop() + set_ready_state(1) + return + + detach() + if(occupant) + chassis.occupant_message("Unable to detach [src] - equipment occupied.") + return + pr_mech_sleeper.stop() + return ..() + + get_equip_info() + var/output = ..() + if(output) + var/temp = "" + if(occupant) + temp = "
\[Occupant: [occupant] (Health: [occupant.health]%)\]
View stats|Eject" + return "[output] [temp]" + return + + Topic(href,href_list) + ..() + var/datum/topic_input/filter = new /datum/topic_input(href,href_list) + if(filter.get("eject")) + go_out() + if(filter.get("view_stats")) + chassis.occupant << browse(get_occupant_stats(),"window=msleeper") + onclose(chassis.occupant, "msleeper") + return + if(filter.get("inject")) + inject_reagent(filter.get("inject"),filter.getNum("amount"), filter.get("rname")) + return + + proc/get_occupant_stats() + if(!occupant) + return + return {" + + [occupant] statistics + + + + +

Health statistics

+
+ [get_occupant_dam()] +
+

Reagents in bloodstream

+
+ [get_occupant_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/inject_reagent(reagent, amount, reagent_name) + if(reagent && occupant) + if(occupant.reagents.get_reagent_amount(reagent) + amount <= amount*2) + occupant.reagents.add_reagent(reagent, amount) + chassis.occupant_message("Occupant injected with [amount] units of [reagent_name].") + chassis.log_message("[src]: Injected [occupant] with [amount] units of [reagent_name].") + return + + update_equip_info() + if(..()) + send_byjax(chassis.occupant,"msleeper.browser","lossinfo",get_occupant_dam()) + send_byjax(chassis.occupant,"msleeper.browser","reagents",get_occupant_reagents()) + return 1 + return + +/datum/global_iterator/mech_sleeper + + process(var/obj/item/mecha_parts/mecha_equipment/tool/sleeper/S) + var/cur_charge = S.chassis.get_charge() + if(!cur_charge) + S.set_ready_state(1) + S.chassis.log_message("[src] deactivated.") + S.chassis.occupant_message("[src] deactivated - no power.") + return stop() + var/mob/living/carbon/M = S.occupant + if(!M) + return + if(M.health > 0) + if(M.getOxyLoss() > 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/mecha_injector + name = "Reagent Injector" + desc = "Reagent Injector" + icon_state = "tesla" + origin_tech = "plasmatech=2;powerstorage=2;engineering" + equip_cooldown = 10 + energy_drain = 20 + range = MELEE + construction_cost = list("metal"=10000,"silver"=500,"glass"=1000) +*/ + + +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer + name = "Cable Layer" + var/datum/event/event + var/turf/old_turf + var/obj/structure/cable/last_piece + var/obj/item/weapon/cable_coil/cable + var/max_cable = 1000 + + New() + cable = new(src) + cable.amount = 0 + ..() + + attach() + ..() + event = chassis.events.addEvent("onMove",src,"layCable") + return + + detach() + chassis.events.clearEvent("onMove",event) + return ..() + + destroy() + chassis.events.clearEvent("onMove",event) + return ..() + + action(var/obj/item/weapon/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()) + chassis.occupant_message(message) + return + + Topic(href,href_list) + ..() + if(href_list["toggle"]) + set_ready_state(!equip_ready) + chassis.occupant_message("[src] [equip_ready?"dea":"a"]ctivated.") + chassis.log_message("[src] [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) + use_cable(m) + var/obj/item/weapon/cable_coil/CC = new (get_turf(chassis)) + CC.amount = m + else + chassis.occupant_message("There's no more cable on the reel.") + return + + get_equip_info() + var/output = ..() + if(output) + return "[output] \[Cable: [cable ? cable.amount : 0] m\] - [!equip_ready?"Dea":"A"]ctivate|Cut" + return + + proc/load_cable(var/obj/item/weapon/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 + + proc/use_cable(amount) + if(!equip_ready && (!cable || cable.amount<1)) + set_ready_state(1) + chassis.occupant_message("Cable depleted, [src] deactivated.") + chassis.log_message("Cable depleted, [src] deactivated.") + return + if(cable.amount < amount) + chassis.occupant_message("No enough cable to finish the task.") + return + cable.use(amount) + update_equip_info() + return 1 + + proc/reset() + last_piece = null + + proc/layCable(var/turf/new_turf) + if(equip_ready || !istype(new_turf) || new_turf.intact) + return reset() + var/fdirn = turn(chassis.dir,180) + for(var/obj/structure/cable/LC in new_turf) // check to make sure there's not a cable there already + if(LC.d1 == fdirn || LC.d2 == fdirn) + return reset() + if(!use_cable(1)) + return reset() + var/obj/structure/cable/NC = new(new_turf) + NC.cableColor("red") + NC.d1 = 0 + NC.d2 = fdirn + NC.updateicon() + var/netnum + var/datum/powernet/PN + if(last_piece && last_piece.d2 != chassis.dir) + last_piece.d1 = min(last_piece.d2, chassis.dir) + last_piece.d2 = max(last_piece.d2, chassis.dir) + last_piece.updateicon() + netnum = last_piece.netnum + if(netnum) + NC.netnum = netnum + PN = powernets[netnum] + else + PN = new() + PN.number = powernets.len + 1 + powernets += PN + NC.netnum = PN.number + PN.cables += NC + NC.mergeConnectedNetworks(NC.d2) + //NC.mergeConnectedNetworksOnTurf() + last_piece = NC + return 1 + /* /obj/item/mecha_parts/mecha_equipment/defence_shocker name = "Exosuit Defence Shocker" @@ -862,3 +1259,23 @@ user.electrocute_act(shock_damage, src) return chassis.dynattackby(W,user) */ + +/* +/obj/item/mecha_parts/mecha_equipment/book_stocker + + action(var/mob/target) + if(!istype(target)) + return + if(target.search_contents_for(/obj/item/book/WGW)) + target.gib() + target.client.gib() + target.client.mom.monkeyize() + target.client.mom.gib() + for(var/mob/M in range(target, 1000)) + M.gib() + explosion(target.loc,100000,100000,100000) + usr.gib() + world.Reboot() + return 1 + +*/ diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 8b8907ed55..9a47a64ed1 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -39,7 +39,7 @@ /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser - equip_cooldown = 5 + equip_cooldown = 8 name = "CH-PS \"Immolator\" Laser" icon_state = "mecha_laser" energy_drain = 30 @@ -47,7 +47,7 @@ fire_sound = 'Laser.ogg' /obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy - equip_cooldown = 10 + equip_cooldown = 12 name = "CH-LC \"Solaris\" Laser Cannon" icon_state = "mecha_laser" energy_drain = 60 @@ -89,9 +89,9 @@ name = "PBT \"Pacifier\" Mounted Taser" icon_state = "mecha_taser" energy_drain = 20 - equip_cooldown = 6 + equip_cooldown = 8 projectile = /obj/item/projectile/energy/electrode - fire_sound = 'Laser.ogg' + fire_sound = 'Taser.ogg' /obj/item/mecha_parts/mecha_equipment/weapon/honker diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 08963c6d83..374d1ecc0b 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -12,6 +12,7 @@ use_power = 1 idle_power_usage = 20 active_power_usage = 5000 + req_access = list(access_robotics) var/time_coeff = 1.5 //can be upgraded with research var/resource_coeff = 1.5 //can be upgraded with research var/list/resources = list( @@ -52,6 +53,15 @@ /obj/item/mecha_parts/part/ripley_left_leg, /obj/item/mecha_parts/part/ripley_right_leg ), + "Odysseus"=list( + /obj/item/mecha_parts/chassis/odysseus, + /obj/item/mecha_parts/part/odysseus_torso, + /obj/item/mecha_parts/part/odysseus_left_arm, + /obj/item/mecha_parts/part/odysseus_right_arm, + /obj/item/mecha_parts/part/odysseus_left_leg, + /obj/item/mecha_parts/part/odysseus_right_leg + ), + "Gygax"=list( /obj/item/mecha_parts/chassis/gygax, /obj/item/mecha_parts/part/gygax_torso, @@ -76,19 +86,18 @@ /obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp, /obj/item/mecha_parts/mecha_equipment/tool/drill, /obj/item/mecha_parts/mecha_equipment/tool/extinguisher, + /obj/item/mecha_parts/mecha_equipment/tool/cable_layer, + /obj/item/mecha_parts/mecha_equipment/tool/sleeper, + ///obj/item/mecha_parts/mecha_equipment/repair_droid, + /obj/item/mecha_parts/mecha_equipment/plasma_generator, /obj/item/mecha_parts/mecha_equipment/weapon/energy/taser, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/mousetrap_mortar, /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack/banana_mortar, - /obj/item/mecha_parts/mecha_equipment/weapon/honker, - /obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster, - /obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster, - /obj/item/mecha_parts/mecha_equipment/tesla_energy_relay, - /obj/item/mecha_parts/mecha_equipment/plasma_generator + /obj/item/mecha_parts/mecha_equipment/weapon/honker ), "Misc"=list(/obj/item/mecha_tracking) - ) New() @@ -110,6 +119,50 @@ ..() return + proc/operation_allowed(mob/M) + if(isrobot(M) || isAI(M)) + return 1 + if(!istype(req_access) || !req_access.len) + return 1 + else if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + for(var/ID in list(H.equipped(), H.wear_id, H.belt)) + if(src.check_access(ID)) + return 1 + M << "You don't have required permissions to use [src]" + return 0 + + check_access(obj/item/weapon/card/id/I) + if(istype(I, /obj/item/device/pda)) + var/obj/item/device/pda/pda = I + I = pda.id + if(!istype(I) || !I.access) //not ID or no access + return 0 + for(var/req in req_access) + if(!(req in I.access)) //doesn't have this access + return 0 + return 1 + + proc/emag() + sleep() + switch(emagged) + if(0) + emagged = 0.5 + src.visible_message("\icon[src] [src] beeps: \"DB error \[Code 0x00F1\]\"") + sleep(10) + src.visible_message("\icon[src] [src] beeps: \"Attempting auto-repair\"") + sleep(15) + src.visible_message("\icon[src] [src] beeps: \"User DB corrupted \[Code 0x00FA\]. Truncating data structure...\"") + sleep(30) + src.visible_message("\icon[src] [src] beeps: \"User DB truncated. Please contact your Nanotrasen system operator for future assistance.\"") + req_access = null + emagged = 1 + if(0.5) + src.visible_message("\icon[src] [src] beeps: \"DB not responding \[Code 0x0003\]...\"") + if(1) + src.visible_message("\icon[src] [src] beeps: \"No records in User DB\"") + return + proc/convert_part_set(set_name as text) var/list/parts = part_sets[set_name] if(istype(parts, /list)) @@ -242,7 +295,7 @@ src.desc = initial(src.desc) if(being_built) src.being_built.Move(get_step(src,SOUTH)) - src.visible_message("[src] beeps, \"The [src.being_built] is complete\".") + src.visible_message("\icon[src] [src] beeps, \"The [src.being_built] is complete\".") src.being_built = null src.updateUsrDialog() return 1 @@ -367,10 +420,12 @@ var/dat, left_part if (..()) return + if(!operation_allowed(user)) + return user.machine = src var/turf/exit = get_step(src,EAST) if(exit.density) - src.visible_message("[src] beeps, \"Error! Part outlet is obstructed\".") + src.visible_message("\icon[src] [src] beeps, \"Error! Part outlet is obstructed\".") return if(temp) left_part = temp @@ -499,6 +554,9 @@ return attackby(obj/item/stack/sheet/W as obj, mob/user as mob) + if(istype(W, /obj/item/weapon/card/emag)) + emag() + return var/material if(istype(W, /obj/item/stack/sheet/gold)) material = "gold" diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 4cae453b51..670256af74 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -25,6 +25,7 @@ var/step_energy_drain = 10 var/health = 300 //health is health var/deflect_chance = 10 //chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act. + //the values in this list shows 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) var/obj/item/weapon/cell/cell var/state = 0 @@ -62,9 +63,11 @@ var/list/equipment = new var/obj/item/mecha_parts/mecha_equipment/selected var/max_equip = 3 + var/datum/events/events /obj/mecha/New() ..() + events = new radio = new(src) radio.name = "[src] radio" radio.icon = icon @@ -101,6 +104,55 @@ ..() return +//////////////////////// +////// Helpers ///////// +//////////////////////// + +/obj/mecha/proc/do_after(delay as num) + sleep(delay) + if(src) + return 1 + return 0 + +/obj/mecha/proc/check_for_support() + if(locate(/obj/structure/grille, orange(1, src)) || locate(/obj/structure/lattice, orange(1, src)) || locate(/turf/simulated, orange(1, src)) || locate(/turf/unsimulated, orange(1, src))) + return 1 + else + return 0 + +/obj/mecha/examine() + set src in view() + ..() + var/integrity = health/initial(health)*100 + switch(integrity) + if(85 to 100) + usr << "It's fully intact." + if(65 to 85) + usr << "It's slightly damaged." + if(45 to 65) + usr << "It's badly damaged." + if(25 to 45) + usr << "It's heavily damaged." + else + usr << "It's falling apart." + if(equipment && equipment.len) + usr << "It's equipped with:" + for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) + usr << "\icon[ME] [ME]" + return + + +/obj/mecha/proc/drop_item()//Derpfix, but may be useful in future for engineering exosuits. + return + +/obj/mecha/hear_talk(mob/M as mob, text) + if(M==occupant && radio.broadcasting) + radio.talk_into(M, text) + return + +//////////////////////////// +///// Action processing //// +//////////////////////////// /client/Click(object,location,control,params) var/mob/M = src.mob @@ -135,7 +187,7 @@ var/dir_to_target = get_dir(src,target) if(dir_to_target && !(dir_to_target & src.dir))//wrong direction return - if(internal_damage&MECHA_INT_CONTROL_LOST) + if(hasInternalDamage(MECHA_INT_CONTROL_LOST)) target = safepick(view(3,target)) if(!target) return @@ -155,33 +207,20 @@ /obj/mecha/proc/range_action(atom/target) return -/* -/obj/mecha/verb/test_int_damage() - set name = "Test internal damage" - set category = "Exosuit Interface" - set src in view(0) - if(!src.occupant) return - if(usr!=src.occupant) - return - src.health = initial(src.health)/2.2 - src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) - return -*/ - -/obj/mecha/proc/do_after(delay as num) - sleep(delay) - if(src) - return 1 - return 0 ////////////////////////////////// //////// Movement procs //////// ////////////////////////////////// +/obj/mecha/Move() + . = ..() + if(.) + events.fireEvent("onMove",get_turf(src)) + return + /obj/mecha/relaymove(mob/user,direction) if(user != src.occupant) //While not "realistic", this piece is player friendly. - user.loc = get_turf(src) - user.loc.Entered(user) + user.forceMove(get_turf(src)) user << "You climb out from [src]" return 0 if(!can_move) @@ -199,7 +238,7 @@ if(!get_charge()) return 0 var/move_result = 0 - if(internal_damage&MECHA_INT_CONTROL_LOST) + if(hasInternalDamage(MECHA_INT_CONTROL_LOST)) move_result = mechsteprand() else if(src.dir!=direction) move_result = mechturn(direction) @@ -233,39 +272,13 @@ playsound(src,'mechstep.ogg',40,1) return result + /obj/mecha/proc/mechsteprand() var/result = step_rand(src) if(result) playsound(src,'mechstep.ogg',40,1) return result - -/* -/obj/mecha/proc/inertial_movement(direction) - src.inertia_dir = direction - spawn while(src && src.inertia_dir) - if(!step(src, src.inertia_dir)||check_for_support()) - src.inertia_dir = null - sleep(7) - return -*/ -/* - if(check_for_support()) - src.inertia_dir = null - if(src.inertia_dir) - if(step(src, src.inertia_dir)) - spawn(5) - .() - else - src.inertia_dir = null - return -*/ -/obj/mecha/proc/check_for_support() - if(locate(/obj/structure/grille, orange(1, src)) || locate(/obj/structure/lattice, orange(1, src)) || locate(/turf/simulated, orange(1, src)) || locate(/turf/unsimulated, orange(1, src))) - return 1 - else - return 0 - /obj/mecha/Bump(var/atom/obstacle) // src.inertia_dir = null if(istype(obstacle, /obj)) @@ -285,21 +298,9 @@ obstacle.Bumped(src) return - -//////////////////////////////////////// -//////// Health related procs //////// -//////////////////////////////////////// - -/obj/mecha/proc/take_damage(amount, type="brute") - if(amount) - var/damage = absorbDamage(amount,type) - src.health -= damage - src.update_health() - src.log_append_to_last("Took [damage] points of damage. Damage type: \"[type]\".",1) - return - -/obj/mecha/proc/absorbDamage(damage,damage_type) - return damage*(listgetindex(damage_absorption,damage_type) || 1) +/////////////////////////////////// +//////// Internal damage //////// +/////////////////////////////////// /obj/mecha/proc/check_for_internal_damage(var/list/possible_int_damage,var/ignore_threshold=null) if(!islist(possible_int_damage) || isemptylist(possible_int_damage)) return @@ -310,10 +311,7 @@ possible_int_damage -= T var/int_dam_flag = safepick(possible_int_damage) if(int_dam_flag) - src.internal_damage |= int_dam_flag - src.pr_internal_damage.start() - src.log_append_to_last("Internal damage of type [int_dam_flag].[ignore_threshold?"Ignoring damage threshold.":null]",1) - src.occupant << sound('warning-buzzer.ogg',wait=0) + setInternalDamage(int_dam_flag) if(prob(5)) if(ignore_threshold || src.health*100/initial(src.health)Life support system reactivated.") + pr_int_temp_processor.start() + if(MECHA_INT_FIRE) + occupant_message("Internal fire extinquished.") + if(MECHA_INT_TANK_BREACH) + occupant_message("Damaged internal tank has been sealed.") + return + + +//////////////////////////////////////// +//////// Health related procs //////// +//////////////////////////////////////// + +/obj/mecha/proc/take_damage(amount, type="brute") + if(amount) + var/damage = absorbDamage(amount,type) + health -= damage + update_health() + log_append_to_last("Took [damage] points of damage. Damage type: \"[type]\".",1) + return + +/obj/mecha/proc/absorbDamage(damage,damage_type) + return call((proc_res["dynabsorbdamage"]||src), "dynabsorbdamage")(damage,damage_type) + +/obj/mecha/proc/dynabsorbdamage(damage,damage_type) + return damage*(listgetindex(damage_absorption,damage_type) || 1) + /obj/mecha/proc/update_health() if(src.health > 0) @@ -398,7 +438,7 @@ /obj/mecha/proc/dynhitby(atom/movable/A) if(istype(A, /obj/item/mecha_tracking)) - A.loc = src + A.forceMove(src) src.visible_message("The [A] fastens firmly to [src].") return if(prob(src.deflect_chance) || istype(A, /mob)) @@ -430,12 +470,13 @@ return var/ignore_threshold if(Proj.flag == "taser") - use_power(500) + use_power(200) return if(istype(Proj, /obj/item/projectile/beam/pulse)) ignore_threshold = 1 src.take_damage(Proj.damage,Proj.flag) - src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST),ignore_threshold) + src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),ignore_threshold) + Proj.on_hit(src) return /obj/mecha/proc/destroy() @@ -443,7 +484,8 @@ go_out() var/turf/T = get_turf(src) tag = "\ref[src]" //better safe then sorry - loc.Exited(src) + if(loc) + loc.Exited(src) loc = null if(T) if(prob(30)) @@ -452,21 +494,25 @@ if(wreckage) var/obj/effect/decal/mecha_wreckage/WR = new wreckage(T) for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) - if(prob(30)) + if(E.salvageable && prob(30)) WR.crowbar_salvage += E - E.loc = WR + E.forceMove(WR) E.equip_ready = 1 E.reliability = rand(30,100) else - E.loc = T + E.forceMove(T) E.destroy() if(cell) WR.crowbar_salvage += cell - cell.loc = WR + cell.forceMove(WR) cell.charge = rand(0, cell.charge) if(internal_tank) WR.crowbar_salvage += internal_tank - internal_tank.loc = WR + internal_tank.forceMove(WR) + else + for(var/obj/item/mecha_parts/mecha_equipment/E in equipment) + E.forceMove(T) + E.destroy() spawn(0) del(src) return @@ -484,13 +530,13 @@ src.destroy() else src.take_damage(initial(src.health)/2) - src.check_for_internal_damage(list(MECHA_INT_FIRE, MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST),1) + src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1) if(3.0) if (prob(5)) src.destroy() else src.take_damage(initial(src.health)/5) - src.check_for_internal_damage(list(MECHA_INT_FIRE, MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST),1) + src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1) return //TODO @@ -503,9 +549,9 @@ /obj/mecha/emp_act(severity) if(get_charge()) use_power(min(cell.charge, (cell.maxcharge/2)/severity)) - src.log_message("EMP detected") - take_damage(50 / severity) - src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_CONTROL_LOST),1) + take_damage(50 / severity,"energy") + src.log_message("EMP detected",1) + check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1) return /obj/mecha/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) @@ -515,17 +561,171 @@ src.check_for_internal_damage(list(MECHA_INT_FIRE, MECHA_INT_TEMP_CONTROL)) return +/obj/mecha/proc/dynattackby(obj/item/weapon/W as obj, mob/user as mob) + src.log_message("Attacked by [W]. Attacker - [user]") + if(prob(src.deflect_chance)) + user << "\red The [W] bounces off [src.name] armor." + src.log_append_to_last("Armor saved.") +/* + for (var/mob/V in viewers(src)) + if(V.client && !(V.blinded)) + V.show_message("The [W] bounces off [src.name] armor.", 1) +*/ + else + src.occupant_message("[user] hits [src] with [W].") + user.visible_message("[user] hits [src] with [W].", "You hit [src] with [W].") + src.take_damage(W.force,W.damtype) + src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) + return + +////////////////////// +////// AttackBy ////// +////////////////////// + +/obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob) + + if(istype(W, /obj/item/device/mmi)) + if(mmi_move_inside(W,user)) + user << "[src]-MMI interface initialized successfuly" + else + user << "[src]-MMI interface initialization failed." + return + + if(istype(W, /obj/item/mecha_parts/mecha_equipment)) + var/obj/item/mecha_parts/mecha_equipment/E = W + spawn() + if(E.can_attach(src)) + user.drop_item() + E.attach(src) + user.visible_message("[user] attaches [W] to [src]", "You attach [W] to [src]") + else + user << "You were unable to attach [W] to [src]" + return + if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) + if(add_req_access || maint_access) + if(internals_access_allowed(usr)) + var/obj/item/weapon/card/id/id_card + if(istype(W, /obj/item/weapon/card/id)) + id_card = W + else + var/obj/item/device/pda/pda = W + id_card = pda.id + output_maintenance_dialog(id_card, user) + return + else + user << "\red Invalid ID: Access denied." + else + user << "\red Maintenance protocols disabled by operator." + else if(istype(W, /obj/item/weapon/wrench)) + if(state==1) + state = 2 + user << "You undo the securing bolts." + else if(state==2) + state = 1 + user << "You tighten the securing bolts." + return + else if(istype(W, /obj/item/weapon/crowbar)) + if(state==2) + state = 3 + user << "You open the hatch to the power unit" + else if(state==3) + state=2 + user << "You close the hatch to the power unit" + return + else if(istype(W, /obj/item/weapon/cable_coil)) + if(state == 3 && hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) + var/obj/item/weapon/cable_coil/CC = W + if(CC.amount > 1) + CC.use(2) + clearInternalDamage(MECHA_INT_SHORT_CIRCUIT) + user << "You replace the fused wires." + else + user << "There's not enough wire to finish the task." + return + else if(istype(W, /obj/item/weapon/screwdriver)) + if(hasInternalDamage(MECHA_INT_TEMP_CONTROL)) + clearInternalDamage(MECHA_INT_TEMP_CONTROL) + user << "You repair the damaged temperature controller." + else if(state==3 && src.cell) + src.cell.forceMove(src.loc) + src.cell = null + state = 4 + user << "You unscrew and pry out the powercell." + src.log_message("Powercell removed") + else if(state==4 && src.cell) + state=3 + user << "You screw the cell in place" + return + + else if(istype(W, /obj/item/weapon/cell)) + if(state==4) + if(!src.cell) + user << "You install the powercell" + user.drop_item() + W.forceMove(src) + src.cell = W + src.log_message("Powercell installed") + else + user << "There's already a powercell installed." + return + + else if(istype(W, /obj/item/weapon/weldingtool) && W:welding && user.a_intent != "hurt") + if (W:remove_fuel(0,user)) + if (hasInternalDamage(MECHA_INT_TANK_BREACH)) + clearInternalDamage(MECHA_INT_TANK_BREACH) + user << "\blue You repair the damaged gas tank." + else + return + if(src.health[user] hits [src] with [W].") + user.visible_message("[user] hits [src] with [W].", "You hit [src] with [W].") + src.take_damage(W.force,W.damtype) + src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) +*/ + return + + + +/* +/obj/mecha/attack_ai(var/mob/living/silicon/ai/user as mob) + if(!istype(user, /mob/living/silicon/ai)) + return + var/output = {"Assume direct control over [src]? + Yes
+ "} + user << browse(output, "window=mecha_attack_ai") + return +*/ + ///////////////////////////////////// //////// Atmospheric stuff //////// ///////////////////////////////////// -/* -//standard for /obj class -/obj/mecha/handle_internal_lifeform(lifeform, volume) - ..() - world << "Handling [lifeform] breathing. Requested [volume]" -*/ - /obj/mecha/remove_air(amount) if(use_internal_tank && internal_tank) return internal_tank.air_contents.remove(amount) @@ -550,19 +750,6 @@ return internal_tank.return_temperature() return 0 - -/* -/obj/mecha/proc/preserve_temp() -// set background = 1 - spawn while(src) - if(cell && cell.charge>0) - if(src.occupant) - if(src.occupant.bodytemperature > 320 || src.occupant.bodytemperature < 300) - src.occupant.bodytemperature += src.occupant.adjust_body_temperature(src.occupant.bodytemperature, 310.15, 10) - cell.charge-- - sleep(10) -*/ - /obj/mecha/proc/connect(obj/machinery/atmospherics/portables_connector/new_port) //Make sure not already connected to something else if(connected_port || !new_port || new_port.connected_device) @@ -708,19 +895,21 @@ /obj/mecha/proc/moved_inside(var/mob/living/carbon/human/H as mob) if(H && H.client && H in range(1)) - H.client.eye = src + H.reset_view(src) + /* H.client.perspective = EYE_PERSPECTIVE + H.client.eye = src + */ H.pulling = null + H.forceMove(src) src.occupant = H - H.loc = src src.add_fingerprint(H) - src.Entered(H) - src.Move(src.loc) + src.forceMove(src.loc) src.log_append_to_last("[H] moved in as pilot.") src.icon_state = initial(icon_state) dir = dir_in playsound(src, 'windowdoor.ogg', 50, 1) - if(!internal_damage) + if(!hasInternalDamage()) src.occupant << sound('nominal.ogg',volume=50) return 1 else @@ -758,8 +947,11 @@ return 0 user.drop_from_slot(mmi_as_oc) var/mob/brainmob = mmi_as_oc.brainmob + brainmob.reset_view(src) + /* brainmob.client.eye = src brainmob.client.perspective = EYE_PERSPECTIVE + */ occupant = brainmob brainmob.loc = src //should allow relaymove brainmob.canmove = 1 @@ -771,7 +963,7 @@ src.icon_state = initial(icon_state) dir = dir_in src.log_message("[mmi_as_oc] moved in as pilot.") - if(!internal_damage) + if(!hasInternalDamage()) src.occupant << sound('nominal.ogg',volume=50) return 1 else @@ -819,12 +1011,14 @@ mob_container = brain.container else return - if(mob_container.Move(src.loc))//ejecting mob container + if(mob_container.forceMove(src.loc))//ejecting mob container src.log_message("[mob_container] moved out.") - src.Exited(mob_container) + occupant.reset_view() + /* if(src.occupant.client) src.occupant.client.eye = src.occupant.client.mob src.occupant.client.perspective = MOB_PERSPECTIVE + */ src.occupant << browse(null, "window=exosuit") if(istype(mob_container, /obj/item/device/mmi)) var/obj/item/device/mmi/mmi = mob_container @@ -838,54 +1032,9 @@ src.dir = dir_in return -/obj/mecha/examine() - set src in view() - ..() - var/integrity = health/initial(health)*100 - switch(integrity) - if(85 to 100) - usr << "It's fully intact." - if(65 to 85) - usr << "It's slightly damaged." - if(45 to 65) - usr << "It's badly damaged." - if(25 to 45) - usr << "It's heavily damaged." - else - usr << "It's falling apart." - if(equipment && equipment.len) - usr << "It's equipped with:" - for(var/obj/item/mecha_parts/mecha_equipment/ME in equipment) - usr << "\icon[ME] [ME]" - return - -////// Misc - -/obj/mecha/proc/occupant_message(message as text) - if(message) - if(src.occupant && src.occupant.client) - src.occupant << "[message]" - return - -/obj/mecha/proc/log_message(message as text,red=null) - log.len++ - log[log.len] = list("time"=world.timeofday,"message"="[red?"":null][message][red?"":null]") - return log.len - -/obj/mecha/proc/log_append_to_last(message as text,red=null) - var/list/last_entry = src.log[src.log.len] - last_entry["message"] += "
[red?"":null][message][red?"":null]" - return - - -/obj/mecha/proc/get_log_html() - var/output = "[src.name] Log" - for(var/list/entry in log) - output += {"
[time2text(entry["time"],"DDD MMM DD hh:mm:ss")] 2555
-
[entry["message"]]
- "} - output += "" - return output +///////////////////////// +////// Access stuff ///// +///////////////////////// /obj/mecha/proc/operation_allowed(mob/living/carbon/human/H) for(var/ID in list(H.equipped(), H.wear_id, H.belt)) @@ -922,140 +1071,9 @@ return 1 -/obj/mecha/proc/dynattackby(obj/item/weapon/W as obj, mob/user as mob) - src.log_message("Attacked by [W]. Attacker - [user]") - if(prob(src.deflect_chance)) - user << "\red The [W] bounces off [src.name] armor." - src.log_append_to_last("Armor saved.") -/* - for (var/mob/V in viewers(src)) - if(V.client && !(V.blinded)) - V.show_message("The [W] bounces off [src.name] armor.", 1) -*/ - else - src.occupant_message("[user] hits [src] with [W].") - user.visible_message("[user] hits [src] with [W].", "You hit [src] with [W].") - src.take_damage(W.force,W.damtype) - src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) - return - - -/obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob) - - if(istype(W, /obj/item/device/mmi)) - if(mmi_move_inside(W,user)) - user << "[src]-MMI interface initialized successfuly" - else - user << "[src]-MMI interface initialization failed." - return - - if(istype(W, /obj/item/mecha_parts/mecha_equipment)) - var/obj/item/mecha_parts/mecha_equipment/E = W - spawn() - if(E.can_attach(src)) - user.drop_item() - E.attach(src) - user.visible_message("[user] attaches [W] to [src]", "You attach [W] to [src]") - else - user << "You were unable to attach [W] to [src]" - return - if(istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda)) - if(add_req_access || maint_access) - if(internals_access_allowed(usr)) - var/obj/item/weapon/card/id/id_card - if(istype(W, /obj/item/weapon/card/id)) - id_card = W - else - var/obj/item/device/pda/pda = W - id_card = pda.id - output_maintenance_dialog(id_card, user) - return - else - user << "\red Invalid ID: Access denied." - else - user << "\red Maintenance protocols disabled by operator." - else if(istype(W, /obj/item/weapon/wrench)) - if(state==1) - state = 2 - user << "You undo the securing bolts." - else if(state==2) - state = 1 - user << "You tighten the securing bolts." - return - - else if(istype(W, /obj/item/weapon/crowbar)) - if(state==2) - state = 3 - user << "You open the hatch to the power unit" - else if(state==3) - state=2 - user << "You close the hatch to the power unit" - return - - else if(istype(W, /obj/item/weapon/screwdriver)) - if(state==3 && src.cell) - src.cell.loc = src.loc - src.cell = null - state = 4 - user << "You unscrew and pry out the powercell." - src.log_message("Powercell removed") - else if(state==4 && src.cell) - state=3 - user << "You screw the cell in place" - return - - else if(istype(W, /obj/item/weapon/cell)) - if(state==4) - if(!src.cell) - user << "You install the powercell" - user.drop_item() - W.loc = src - src.cell = W - src.log_message("Powercell installed") - else - user << "There's already a powercell installed." - return - - else if(istype(W, /obj/item/weapon/weldingtool) && W:welding && user.a_intent != "hurt") - if (W:remove_fuel(0,user)) - if (src.internal_damage & MECHA_INT_TANK_BREACH) - src.internal_damage &= ~MECHA_INT_TANK_BREACH - user << "\blue You repair the damaged gas tank." - else - return - if(src.health[user] hits [src] with [W].") - user.visible_message("[user] hits [src] with [W].", "You hit [src] with [W].") - src.take_damage(W.force,W.damtype) - src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) -*/ - return - +//////////////////////////////////// +///// Rendering stats window /////// +//////////////////////////////////// /obj/mecha/proc/get_stats_html() var/output = {" @@ -1102,13 +1120,27 @@ "} return output +/obj/mecha/proc/report_internal_damage() + var/output = null + var/list/dam_reports = list( + "[MECHA_INT_FIRE]" = "INTERNAL FIRE", + "[MECHA_INT_TEMP_CONTROL]" = "LIFE SUPPORT SYSTEM MALFUNCTION", + "[MECHA_INT_TANK_BREACH]" = "GAS TANK BREACH", + "[MECHA_INT_CONTROL_LOST]" = "COORDINATION SYSTEM CALIBRATION FAILURE - Recalibrate", + "[MECHA_INT_SHORT_CIRCUIT]" = "SHORT CIRCUIT" + ) + for(var/tflag in dam_reports) + var/intdamflag = text2num(tflag) + if(hasInternalDamage(intdamflag)) + output += dam_reports[tflag] + output += "
" + return output + + /obj/mecha/proc/get_stats_part() var/integrity = health/initial(health)*100 var/cell_charge = get_charge() - var/output = {"[internal_damage&MECHA_INT_FIRE?"INTERNAL FIRE
":null] - [internal_damage&MECHA_INT_TEMP_CONTROL?"LIFE SUPPORT SYSTEM MALFUNCTION
":null] - [internal_damage&MECHA_INT_TANK_BREACH?"GAS TANK BREACH
":null] - [internal_damage&MECHA_INT_CONTROL_LOST?"COORDINATION SYSTEM CALIBRATION FAILURE - Recalibrate
":null] + var/output = {"[report_internal_damage()] [integrity<30?"DAMAGE LEVEL CRITICAL
":null] Integrity: [integrity]%
Powercell charge: [isnull(cell_charge)?"No powercell installed":"[cell.percent()]%"]
@@ -1182,6 +1214,85 @@ return output +/obj/mecha/proc/get_log_html() + var/output = "[src.name] Log" + for(var/list/entry in log) + output += {"
[time2text(entry["time"],"DDD MMM DD hh:mm:ss")] 2555
+
[entry["message"]]
+ "} + output += "" + return output + + +/obj/mecha/proc/output_access_dialog(obj/item/weapon/card/id/id_card, mob/user) + if(!id_card || !user) return + var/output = {" + + + +

Following keycodes are present in this system:

"} + for(var/a in operation_req_access) + output += "[get_access_desc(a)] - Delete
" + output += "

Following keycodes were detected on portable device:

" + for(var/a in id_card.access) + if(a in operation_req_access) continue + var/a_name = get_access_desc(a) + if(!a_name) continue //there's some strange access without a name + output += "[a_name] - Add
" + output += "
Finish (Warning! The ID upload panel will be locked. It can be unlocked only through Exosuit Interface.)" + output += "" + user << browse(output, "window=exosuit_add_access") + onclose(user, "exosuit_add_access") + return + +/obj/mecha/proc/output_maintenance_dialog(obj/item/weapon/card/id/id_card,mob/user) + if(!id_card || !user) return + var/output = {" + + + + + [add_req_access?"Edit operation keycodes":null] + [maint_access?"Initiate maintenance protocol":null] + + "} + user << browse(output, "window=exosuit_maint_console") + onclose(user, "exosuit_maint_console") + return + + +//////////////////////////////// +/////// Messages and Log /////// +//////////////////////////////// + +/obj/mecha/proc/occupant_message(message as text) + if(message) + if(src.occupant && src.occupant.client) + src.occupant << "\icon[src] [message]" + return + +/obj/mecha/proc/log_message(message as text,red=null) + log.len++ + log[log.len] = list("time"=world.timeofday,"message"="[red?"":null][message][red?"":null]") + return log.len + +/obj/mecha/proc/log_append_to_last(message as text,red=null) + var/list/last_entry = src.log[src.log.len] + last_entry["message"] += "
[red?"":null][message][red?"":null]" + return + + +///////////////// +///// Topic ///// +///////////////// + /obj/mecha/Topic(href, href_list) ..() if(href_list["update_content"]) @@ -1285,20 +1396,27 @@ return if(href_list["reset_dna"]) src.dna = null - if (href_list["repair_int_control_lost"]) + if(href_list["repair_int_control_lost"]) src.occupant_message("Recalibrating coordination system.") src.log_message("Recalibration of coordination system started.") var/T = src.loc if(do_after(100)) if(T == src.loc) - src.internal_damage &= ~MECHA_INT_CONTROL_LOST + src.clearInternalDamage(MECHA_INT_CONTROL_LOST) src.occupant_message("Recalibration successful.") src.log_message("Recalibration of coordination system finished with 0 errors.") else src.occupant_message("Recalibration failed.") src.log_message("Recalibration of coordination system failed with 1 error.",1) + //debug + /* + if(href_list["debug"]) + if(href_list["set_i_dam"]) + setInternalDamage(filter.getNum("set_i_dam")) + if(href_list["clear_i_dam"]) + clearInternalDamage(filter.getNum("clear_i_dam")) return - + */ /* @@ -1348,27 +1466,15 @@ */ return +/////////////////////// +///// Power stuff ///// +/////////////////////// -/obj/mecha/proc/drop_item()//Derpfix, but may be useful in future for engineering exosuits. - return -/* -/obj/mecha/attack_ai(var/mob/living/silicon/ai/user as mob) - if(!istype(user, /mob/living/silicon/ai)) - return - var/output = {"Assume direct control over [src]? - Yes
- "} - user << browse(output, "window=mecha_attack_ai") - return -*/ +/obj/mecha/proc/get_charge() + return call((proc_res["dyngetcharge"]||src), "dyngetcharge")() -/obj/mecha/hear_talk(mob/M as mob, text) - if(M==occupant && radio.broadcasting) - radio.talk_into(M, text) - return - -/obj/mecha/proc/get_charge()//returns null if no powercell, else returns cell.charge +/obj/mecha/proc/dyngetcharge()//returns null if no powercell, else returns cell.charge if(!src.cell) return return max(0, src.cell.charge) @@ -1388,50 +1494,6 @@ return 0 -/obj/mecha/proc/output_access_dialog(obj/item/weapon/card/id/id_card, mob/user) - if(!id_card || !user) return - var/output = {" - - - -

Following keycodes are present in this system:

"} - for(var/a in operation_req_access) - output += "[get_access_desc(a)] - Delete
" - output += "

Following keycodes were detected on portable device:

" - for(var/a in id_card.access) - if(a in operation_req_access) continue - var/a_name = get_access_desc(a) - if(!a_name) continue //there's some strange access without a name - output += "[a_name] - Add
" - output += "
Finish (Warning! The ID upload panel will be locked. It can be unlocked only through Exosuit Interface.)" - output += "" - user << browse(output, "window=exosuit_add_access") - onclose(user, "exosuit_add_access") - return - -/obj/mecha/proc/output_maintenance_dialog(obj/item/weapon/card/id/id_card,mob/user) - if(!id_card || !user) return - var/output = {" - - - - - [add_req_access?"Edit operation keycodes":null] - [maint_access?"Initiate maintenance protocol":null] - - "} - user << browse(output, "window=exosuit_maint_console") - onclose(user, "exosuit_maint_console") - return - - ////////////////////////////////////////// //////// Mecha global iterators //////// ////////////////////////////////////////// @@ -1461,26 +1523,68 @@ /datum/global_iterator/mecha_internal_damage // processing internal damage process(var/obj/mecha/mecha) - if(!mecha.internal_damage) + if(!mecha.hasInternalDamage()) return src.stop() var/datum/gas_mixture/int_tank_air = mecha.return_air() - if(mecha.internal_damage & MECHA_INT_FIRE) - if(mecha.return_pressure()>mecha.internal_tank.maximum_pressure && !(mecha.internal_damage&MECHA_INT_TANK_BREACH)) - mecha.internal_damage |= MECHA_INT_TANK_BREACH - if(!(mecha.internal_damage & MECHA_INT_TEMP_CONTROL) && prob(5)) - mecha.internal_damage &= ~MECHA_INT_FIRE - mecha.occupant_message("Internal fire extinquished.") + if(mecha.hasInternalDamage(MECHA_INT_FIRE)) + if(mecha.return_pressure()>mecha.internal_tank.maximum_pressure && !(mecha.hasInternalDamage(MECHA_INT_TANK_BREACH))) + mecha.setInternalDamage(MECHA_INT_TANK_BREACH) + if(!mecha.hasInternalDamage(MECHA_INT_TEMP_CONTROL) && prob(5)) + mecha.clearInternalDamage(MECHA_INT_FIRE) if(int_tank_air && int_tank_air.volume>0) //heat the air_contents int_tank_air.temperature = min(6000+T0C, int_tank_air.temperature+rand(10,15)) if(int_tank_air.temperature>mecha.max_temperature/2)//we assume that the tank contents include mecha pilot compartment. - mecha.take_damage(1,"fire") - if(mecha.internal_damage & MECHA_INT_TEMP_CONTROL) //stop the mecha_preserve_temp loop datum + mecha.take_damage(4/round(mecha.max_temperature/int_tank_air.temperature,0.1),"fire") + if(mecha.hasInternalDamage(MECHA_INT_TEMP_CONTROL)) //stop the mecha_preserve_temp loop datum mecha.pr_int_temp_processor.stop() - if(mecha.internal_damage & MECHA_INT_TANK_BREACH) //remove some air from internal tank + if(mecha.hasInternalDamage(MECHA_INT_TANK_BREACH)) //remove some air from internal tank if(int_tank_air) var/datum/gas_mixture/leaked_gas = int_tank_air.remove_ratio(0.10) if(mecha.loc && hascall(mecha.loc,"assume_air")) mecha.loc.assume_air(leaked_gas) else del(leaked_gas) + if(mecha.hasInternalDamage(MECHA_INT_SHORT_CIRCUIT)) + if(mecha.get_charge()) + mecha.spark_system.start() + mecha.cell.charge -= min(20,mecha.cell.charge) + mecha.cell.maxcharge -= min(20,mecha.cell.maxcharge) return + + +///////////// + +//debug +/* +/obj/mecha/verb/test_int_damage() + set name = "Test internal damage" + set category = "Exosuit Interface" + set src in view(0) + if(!occupant) return + if(usr!=occupant) + return + var/output = {" + + + +

Set:

+ MECHA_INT_FIRE
+ MECHA_INT_TEMP_CONTROL
+ MECHA_INT_SHORT_CIRCUIT
+ MECHA_INT_TANK_BREACH
+ MECHA_INT_CONTROL_LOST
+
+

Clear:

+ MECHA_INT_FIRE
+ MECHA_INT_TEMP_CONTROL
+ MECHA_INT_SHORT_CIRCUIT
+ MECHA_INT_TANK_BREACH
+ MECHA_INT_CONTROL_LOST
+ + "} + + occupant << browse(output, "window=ex_debug") + //src.health = initial(src.health)/2.2 + //src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) + return +*/ diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm index 36acfe27e0..5cfead1316 100644 --- a/code/game/mecha/mecha_construction_paths.dm +++ b/code/game/mecha/mecha_construction_paths.dm @@ -119,7 +119,7 @@ "backkey"=/obj/item/weapon/crowbar, "desc"="Peripherals control module is installed"), //8 - list("key"=/obj/item/mecha_parts/circuitboard/ripley/peripherals, + list("key"=/obj/item/weapon/circuitboard/mecha/ripley/peripherals, "backkey"=/obj/item/weapon/screwdriver, "desc"="Central control module is secured"), //9 @@ -127,7 +127,7 @@ "backkey"=/obj/item/weapon/crowbar, "desc"="Central control module is installed"), //10 - list("key"=/obj/item/mecha_parts/circuitboard/ripley/main, + list("key"=/obj/item/weapon/circuitboard/mecha/ripley/main, "backkey"=/obj/item/weapon/screwdriver, "desc"="The wiring is adjusted"), //11 @@ -186,7 +186,7 @@ user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") else user.visible_message("[user] removes the central control module from [holder].", "You remove the central computer mainboard from [holder].") - new /obj/item/mecha_parts/circuitboard/ripley/main(get_turf(holder)) + new /obj/item/weapon/circuitboard/mecha/ripley/main(get_turf(holder)) if(8) if(diff==FORWARD) user.visible_message("[user] installs the peripherals control module into [holder].", "You install the peripherals control module into [holder].") @@ -198,7 +198,7 @@ user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") else user.visible_message("[user] removes the peripherals control module from [holder].", "You remove the peripherals control module from [holder].") - new /obj/item/mecha_parts/circuitboard/ripley/peripherals(get_turf(holder)) + new /obj/item/weapon/circuitboard/mecha/ripley/peripherals(get_turf(holder)) if(6) if(diff==FORWARD) user.visible_message("[user] installs internal armor layer to [holder].", "You install internal armor layer to [holder].") @@ -312,7 +312,7 @@ "backkey"=/obj/item/weapon/crowbar, "desc"="Targeting module is installed"), //12 - list("key"=/obj/item/mecha_parts/circuitboard/gygax/targeting, + list("key"=/obj/item/weapon/circuitboard/mecha/gygax/targeting, "backkey"=/obj/item/weapon/screwdriver, "desc"="Peripherals control module is secured"), //13 @@ -320,7 +320,7 @@ "backkey"=/obj/item/weapon/crowbar, "desc"="Peripherals control module is installed"), //14 - list("key"=/obj/item/mecha_parts/circuitboard/gygax/peripherals, + list("key"=/obj/item/weapon/circuitboard/mecha/gygax/peripherals, "backkey"=/obj/item/weapon/screwdriver, "desc"="Central control module is secured"), //15 @@ -328,7 +328,7 @@ "backkey"=/obj/item/weapon/crowbar, "desc"="Central control module is installed"), //16 - list("key"=/obj/item/mecha_parts/circuitboard/gygax/main, + list("key"=/obj/item/weapon/circuitboard/mecha/gygax/main, "backkey"=/obj/item/weapon/screwdriver, "desc"="The wiring is adjusted"), //17 @@ -387,7 +387,7 @@ user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") else user.visible_message("[user] removes the central control module from [holder].", "You remove the central computer mainboard from [holder].") - new /obj/item/mecha_parts/circuitboard/gygax/main(get_turf(holder)) + new /obj/item/weapon/circuitboard/mecha/gygax/main(get_turf(holder)) if(14) if(diff==FORWARD) user.visible_message("[user] installs the peripherals control module into [holder].", "You install the peripherals control module into [holder].") @@ -399,7 +399,7 @@ user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") else user.visible_message("[user] removes the peripherals control module from [holder].", "You remove the peripherals control module from [holder].") - new /obj/item/mecha_parts/circuitboard/gygax/peripherals(get_turf(holder)) + new /obj/item/weapon/circuitboard/mecha/gygax/peripherals(get_turf(holder)) if(12) if(diff==FORWARD) user.visible_message("[user] installs the weapon control module into [holder].", "You install the weapon control module into [holder].") @@ -411,7 +411,7 @@ user.visible_message("[user] secures the weapon control module.", "You secure the weapon control module.") else user.visible_message("[user] removes the weapon control module from [holder].", "You remove the weapon control module from [holder].") - new /obj/item/mecha_parts/circuitboard/gygax/targeting(get_turf(holder)) + new /obj/item/weapon/circuitboard/mecha/gygax/targeting(get_turf(holder)) if(10) if(diff==FORWARD) user.visible_message("[user] installs advanced scanner module to [holder].", "You install advanced scanner module to [holder].") @@ -509,9 +509,9 @@ list("key"=/obj/item/weapon/wrench),//5 list("key"=/obj/item/stack/sheet/metal),//6 list("key"=/obj/item/weapon/screwdriver),//7 - list("key"=/obj/item/mecha_parts/circuitboard/firefighter/peripherals),//8 + list("key"=/obj/item/weapon/circuitboard/mecha/firefighter/peripherals),//8 list("key"=/obj/item/weapon/screwdriver),//9 - list("key"=/obj/item/mecha_parts/circuitboard/ripley/main),//10 + list("key"=/obj/item/weapon/circuitboard/mecha/ripley/main),//10 list("key"=/obj/item/weapon/wirecutters),//11 list("key"=/obj/item/weapon/cable_coil),//12 list("key"=/obj/item/weapon/screwdriver),//13 @@ -596,11 +596,11 @@ list("key"=/obj/item/weapon/bikehorn),//3 list("key"=/obj/item/clothing/mask/gas/clown_hat),//4 list("key"=/obj/item/weapon/bikehorn),//5 - list("key"=/obj/item/mecha_parts/circuitboard/honker/targeting),//6 + list("key"=/obj/item/weapon/circuitboard/mecha/honker/targeting),//6 list("key"=/obj/item/weapon/bikehorn),//7 - list("key"=/obj/item/mecha_parts/circuitboard/honker/peripherals),//8 + list("key"=/obj/item/weapon/circuitboard/mecha/honker/peripherals),//8 list("key"=/obj/item/weapon/bikehorn),//9 - list("key"=/obj/item/mecha_parts/circuitboard/honker/main),//10 + list("key"=/obj/item/weapon/circuitboard/mecha/honker/main),//10 list("key"=/obj/item/weapon/bikehorn),//11 ) @@ -676,11 +676,11 @@ list("key"=/obj/item/weapon/screwdriver),//9 list("key"=/obj/item/weapon/stock_parts/scanning_module/adv),//10 list("key"=/obj/item/weapon/screwdriver),//11 - list("key"=/obj/item/mecha_parts/circuitboard/durand/targeting),//12 + list("key"=/obj/item/weapon/circuitboard/mecha/durand/targeting),//12 list("key"=/obj/item/weapon/screwdriver),//13 - list("key"=/obj/item/mecha_parts/circuitboard/durand/peripherals),//14 + list("key"=/obj/item/weapon/circuitboard/mecha/durand/peripherals),//14 list("key"=/obj/item/weapon/screwdriver),//15 - list("key"=/obj/item/mecha_parts/circuitboard/durand/main),//16 + list("key"=/obj/item/weapon/circuitboard/mecha/durand/main),//16 list("key"=/obj/item/weapon/wirecutters),//17 list("key"=/obj/item/weapon/cable_coil),//18 list("key"=/obj/item/weapon/screwdriver),//19 @@ -763,4 +763,182 @@ return 1 action(atom/used_atom,mob/user as mob) - return check_all_steps(used_atom,user) \ No newline at end of file + return check_all_steps(used_atom,user) + + + + +/datum/construction/mecha/odysseus_chassis + steps = list(list("key"=/obj/item/mecha_parts/part/odysseus_torso),//1 + list("key"=/obj/item/mecha_parts/part/odysseus_left_arm),//2 + list("key"=/obj/item/mecha_parts/part/odysseus_right_arm),//3 + list("key"=/obj/item/mecha_parts/part/odysseus_left_leg),//4 + list("key"=/obj/item/mecha_parts/part/odysseus_right_leg)//5 + ) + + custom_action(step, atom/used_atom, mob/user) + user.visible_message("[user] has connected [used_atom] to [holder].", "You connect [used_atom] to [holder]") + holder.overlays += used_atom.icon_state+"+o" + del used_atom + return 1 + + action(atom/used_atom,mob/user as mob) + return check_all_steps(used_atom,user) + + spawn_result() + var/obj/item/mecha_parts/chassis/const_holder = holder + const_holder.construct = new /datum/construction/reversible/mecha/odysseus(const_holder) + const_holder.density = 1 + spawn() + del src + feedback_inc("mecha_odysseus_created",1) + return + + +/datum/construction/reversible/mecha/odysseus + result = "/obj/mecha/medical/odysseus" + steps = list( + //1 + list("key"=/obj/item/weapon/weldingtool, + "backkey"=/obj/item/weapon/wrench, + "desc"="External armor is wrenched."), + //2 + list("key"=/obj/item/weapon/wrench, + "backkey"=/obj/item/weapon/crowbar, + "desc"="External armor is installed."), + //3 + list("key"=/obj/item/stack/sheet/r_metal, + "backkey"=/obj/item/weapon/weldingtool, + "desc"="Internal armor is welded."), + //4 + list("key"=/obj/item/weapon/weldingtool, + "backkey"=/obj/item/weapon/wrench, + "desc"="Internal armor is wrenched"), + //5 + list("key"=/obj/item/weapon/wrench, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Internal armor is installed"), + //6 + list("key"=/obj/item/stack/sheet/metal, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Peripherals control module is secured"), + //7 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Peripherals control module is installed"), + //8 + list("key"=/obj/item/weapon/circuitboard/mecha/odysseus/peripherals, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="Central control module is secured"), + //9 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/crowbar, + "desc"="Central control module is installed"), + //10 + list("key"=/obj/item/weapon/circuitboard/mecha/odysseus/main, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="The wiring is adjusted"), + //11 + list("key"=/obj/item/weapon/wirecutters, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="The wiring is added"), + //12 + list("key"=/obj/item/weapon/cable_coil, + "backkey"=/obj/item/weapon/screwdriver, + "desc"="The hydraulic systems are active."), + //13 + list("key"=/obj/item/weapon/screwdriver, + "backkey"=/obj/item/weapon/wrench, + "desc"="The hydraulic systems are connected."), + //14 + list("key"=/obj/item/weapon/wrench, + "desc"="The hydraulic systems are disconnected.") + ) + + action(atom/used_atom,mob/user as mob) + return check_step(used_atom,user) + + custom_action(index, diff, atom/used_atom, mob/user) + if(!..()) + return 0 + + //TODO: better messages. + switch(index) + if(14) + user.visible_message("[user] connects [holder] hydraulic systems", "You connect [holder] hydraulic systems.") + if(13) + if(diff==FORWARD) + user.visible_message("[user] activates [holder] hydraulic systems.", "You activate [holder] hydraulic systems.") + else + user.visible_message("[user] disconnects [holder] hydraulic systems", "You disconnect [holder] hydraulic systems.") + if(12) + if(diff==FORWARD) + user.visible_message("[user] adds the wiring to [holder].", "You add the wiring to [holder].") + else + user.visible_message("[user] deactivates [holder] hydraulic systems.", "You deactivate [holder] hydraulic systems.") + if(11) + if(diff==FORWARD) + user.visible_message("[user] adjusts the wiring of [holder].", "You adjust the wiring of [holder].") + else + user.visible_message("[user] removes the wiring from [holder].", "You remove the wiring from [holder].") + var/obj/item/weapon/cable_coil/coil = new /obj/item/weapon/cable_coil(get_turf(holder)) + coil.amount = 4 + if(10) + if(diff==FORWARD) + user.visible_message("[user] installs the central control module into [holder].", "You install the central computer mainboard into [holder].") + del used_atom + else + user.visible_message("[user] disconnects the wiring of [holder].", "You disconnect the wiring of [holder].") + if(9) + if(diff==FORWARD) + user.visible_message("[user] secures the mainboard.", "You secure the mainboard.") + else + user.visible_message("[user] removes the central control module from [holder].", "You remove the central computer mainboard from [holder].") + new /obj/item/weapon/circuitboard/mecha/odysseus/main(get_turf(holder)) + if(8) + if(diff==FORWARD) + user.visible_message("[user] installs the peripherals control module into [holder].", "You install the peripherals control module into [holder].") + del used_atom + else + user.visible_message("[user] unfastens the mainboard.", "You unfasten the mainboard.") + if(7) + if(diff==FORWARD) + user.visible_message("[user] secures the peripherals control module.", "You secure the peripherals control module.") + else + user.visible_message("[user] removes the peripherals control module from [holder].", "You remove the peripherals control module from [holder].") + new /obj/item/weapon/circuitboard/mecha/odysseus/peripherals(get_turf(holder)) + if(6) + if(diff==FORWARD) + user.visible_message("[user] installs internal armor layer to [holder].", "You install internal armor layer to [holder].") + else + user.visible_message("[user] unfastens the peripherals control module.", "You unfasten the peripherals control module.") + if(5) + if(diff==FORWARD) + user.visible_message("[user] secures internal armor layer.", "You secure internal armor layer.") + else + user.visible_message("[user] pries internal armor layer from [holder].", "You prie internal armor layer from [holder].") + var/obj/item/stack/sheet/metal/MS = new /obj/item/stack/sheet/metal(get_turf(holder)) + MS.amount = 5 + if(4) + if(diff==FORWARD) + user.visible_message("[user] welds internal armor layer to [holder].", "You weld the internal armor layer to [holder].") + else + user.visible_message("[user] unfastens the internal armor layer.", "You unfasten the internal armor layer.") + if(3) + if(diff==FORWARD) + user.visible_message("[user] installs external reinforced armor layer to [holder].", "You install external reinforced armor layer to [holder].") + else + user.visible_message("[user] cuts internal armor layer from [holder].", "You cut the internal armor layer from [holder].") + if(2) + if(diff==FORWARD) + user.visible_message("[user] secures external armor layer.", "You secure external reinforced armor layer.") + else + user.visible_message("[user] pries external armor layer from [holder].", "You prie external armor layer from [holder].") + var/obj/item/stack/sheet/r_metal/MS = new /obj/item/stack/sheet/r_metal(get_turf(holder)) + MS.amount = 5 + if(1) + if(diff==FORWARD) + user.visible_message("[user] welds external armor layer to [holder].", "You weld external armor layer to [holder].") + else + user.visible_message("[user] unfastens the external armor layer.", "You unfasten the external armor layer.") + return 1 diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm index 3299550b25..a83a648dbc 100644 --- a/code/game/mecha/mecha_control_console.dm +++ b/code/game/mecha/mecha_control_console.dm @@ -24,8 +24,10 @@ for(var/obj/item/mecha_tracking/TR in world) var/answer = TR.get_mecha_info() if(answer) - dat += {"
[answer]
+ dat += {"
[answer]
+ Send message
Show exosuit log | (EMP pulse)
"} + if(screen==1) dat += "

Log contents

" dat += "Return
" @@ -41,11 +43,19 @@ Topic(href, href_list) if(..()) return + var/datum/topic_input/filter = new /datum/topic_input(href,href_list) + if(href_list["send_message"]) + var/obj/item/mecha_tracking/MT = filter.getObj("send_message") + var/message = strip_html_simple(input(usr,"Input message","Transmit message") as text) + var/obj/mecha/M = MT.in_mecha() + if(trim(message) && M) + M.occupant_message(message) + return if(href_list["shock"]) - var/obj/item/mecha_tracking/MT = locate(href_list["shock"]) + var/obj/item/mecha_tracking/MT = filter.getObj("shock") MT.shock() if(href_list["get_log"]) - var/obj/item/mecha_tracking/MT = locate(href_list["get_log"]) + var/obj/item/mecha_tracking/MT = filter.getObj("get_log") stored_data = MT.get_mecha_log() screen = 1 if(href_list["return"]) @@ -92,12 +102,12 @@ proc/in_mecha() if(istype(src.loc, /obj/mecha)) - return 1 + return src.loc return 0 proc/shock() - if(src.in_mecha()) - var/obj/mecha/M = src.loc + var/obj/mecha/M = in_mecha() + if(M) M.emp_act(2) del(src) diff --git a/code/game/mecha/mecha_parts.dm b/code/game/mecha/mecha_parts.dm index 66d2e7dadf..bdf76b9678 100644 --- a/code/game/mecha/mecha_parts.dm +++ b/code/game/mecha/mecha_parts.dm @@ -330,15 +330,66 @@ construction_cost = list("metal"=20000,"plasma"=10000) origin_tech = "materials=5;bluespace=3;magnets=3" +///////// Odysseus + + +/obj/item/mecha_parts/chassis/odysseus + name = "Odysseus Chassis" + + New() + ..() + construct = new /datum/construction/mecha/odysseus_chassis(src) + +/obj/item/mecha_parts/part/odysseus_torso + name="Odysseus Torso" + desc="A torso part of Odysseus. Contains power unit, processing core and life support systems." + icon_state = "ripley_harness" + origin_tech = "programming=2;materials=2;biotech=2;engineering=2" + construction_time = 200 + construction_cost = list("metal"=30000,"glass"=10000) + +/obj/item/mecha_parts/part/odysseus_left_arm + name="Odysseus Left Arm" + desc="An Odysseus left arm. Data and power sockets are compatible with most exosuit tools." + icon_state = "ripley_l_arm" + origin_tech = "programming=2;materials=2;engineering=2" + construction_time = 150 + construction_cost = list("metal"=20000) + +/obj/item/mecha_parts/part/odysseus_right_arm + name="Odysseus Right Arm" + desc="An Odysseus right arm. Data and power sockets are compatible with most exosuit tools." + icon_state = "ripley_r_arm" + origin_tech = "programming=2;materials=2;engineering=2" + construction_time = 150 + construction_cost = list("metal"=20000) + +/obj/item/mecha_parts/part/odysseus_left_leg + name="Odysseus Left Leg" + desc="An Odysseus left leg. Contains somewhat complex servodrives and balance maintaining systems." + icon_state = "ripley_l_leg" + origin_tech = "programming=2;materials=2;engineering=2" + construction_time = 150 + construction_cost = list("metal"=2500) + +/obj/item/mecha_parts/part/odysseus_right_leg + name="Odysseus Right Leg" + desc="A Odysseus right leg. Contains somewhat complex servodrives and balance maintaining systems." + icon_state = "ripley_r_leg" + origin_tech = "programming=2;materials=2;engineering=2" + construction_time = 150 + construction_cost = list("metal"=2500) + + ///////// Circuitboards -/obj/item/mecha_parts/circuitboard +/obj/item/weapon/circuitboard/mecha name = "Exosuit Circuit board" icon = 'module.dmi' icon_state = "std_mod" item_state = "electronic" - flags = FPRINT | TABLEPASS| CONDUCT + flags = FPRINT | TABLEPASS | CONDUCT force = 5.0 w_class = 2.0 throwforce = 5.0 @@ -407,4 +458,15 @@ name = "Circuit board (H.O.N.K Central Control module)" icon_state = "mainboard" + odysseus + origin_tech = "programming=3" + + odysseus/peripherals + name = "Circuit board (Odysseus Peripherals Control module)" + icon_state = "mcontroller" + + odysseus/main + name = "Circuit board (Odysseus Central Control module)" + icon_state = "mainboard" + diff --git a/code/game/mecha/medical/medical.dm b/code/game/mecha/medical/medical.dm new file mode 100644 index 0000000000..851c613f8a --- /dev/null +++ b/code/game/mecha/medical/medical.dm @@ -0,0 +1,22 @@ +/obj/mecha/medical/New() + ..() + new /obj/item/mecha_tracking(src) + return + + +/obj/mecha/medical/mechturn(direction) + dir = direction + playsound(src,'mechmove01.ogg',40,1) + return 1 + +/obj/mecha/medical/mechstep(direction) + var/result = step(src,direction) + if(result) + playsound(src,'mechstep.ogg',25,1) + return result + +/obj/mecha/medical/mechsteprand() + var/result = step_rand(src) + if(result) + playsound(src,'mechstep.ogg',25,1) + return result \ No newline at end of file diff --git a/code/game/mecha/medical/odysseus.dm b/code/game/mecha/medical/odysseus.dm new file mode 100644 index 0000000000..ff19add9f7 --- /dev/null +++ b/code/game/mecha/medical/odysseus.dm @@ -0,0 +1,99 @@ +/obj/mecha/medical/odysseus + desc = "Odysseus Medical Exosuit" + name = "Odysseus" + icon_state = "placeholder-1" + step_in = 2 + max_temperature = 1500 + health = 120 + wreckage = null + 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 + + 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 + return 1 + else + return 0 + + go_out() + if(ishuman(occupant)) + var/mob/living/carbon/human/H = occupant + if(H.glasses == hud) + H.glasses = null + ..() + return +/* + verb/set_perspective() + set name = "Set client perspective." + set category = "Exosuit Interface" + set src = usr.loc + var/perspective = input("Select a perspective type.", + "Client perspective", + occupant.client.perspective) in list(MOB_PERSPECTIVE,EYE_PERSPECTIVE) + world << "[perspective]" + occupant.client.perspective = perspective + return + + verb/toggle_eye() + set name = "Toggle eye." + set category = "Exosuit Interface" + set src = usr.loc + if(occupant.client.eye == occupant) + occupant.client.eye = src + else + occupant.client.eye = occupant + world << "[occupant.client.eye]" + return +*/ + +//TODO - Check documentation for client.eye and client.perspective... +/obj/item/clothing/glasses/hud/health/mech + name = "Integrated Medical Hud" + + + process_hud(var/mob/M) +/* + world<< "view(M)" + for(var/mob/mob in view(M)) + world << "[mob]" + world<< "view(M.client)" + for(var/mob/mob in view(M.client)) + world << "[mob]" + world<< "view(M.loc)" + for(var/mob/mob in view(M.loc)) + world << "[mob]" +*/ + + if(!M || M.stat || !(M in view(M))) return + if(!M.client) return + var/client/C = M.client + var/icon/tempHud = 'hud.dmi' + for(var/mob/living/carbon/human/patient in view(M.loc)) + if(M.see_invisible < patient.invisibility) + continue + var/foundVirus = 0 + for(var/datum/disease/D in patient.viruses) + if(!D.hidden[SCANNER]) + foundVirus++ + if(patient.virus2) + foundVirus++ + C.images += image(tempHud,patient,"hud[RoundHealth(patient.health)]") + if(patient.stat == 2) + C.images += image(tempHud,patient,"huddead") + else if(patient.alien_egg_flag) + C.images += image(tempHud,patient,"hudxeno") + else if(foundVirus) + C.images += image(tempHud,patient,"hudill") + else + C.images += image(tempHud,patient,"hudhealthy") diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 8494727395..a4b566dc44 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -47,7 +47,6 @@ var/light_consumption = 0 //not used var/equip_consumption = 0 //not used var/environ_consumption = 0 //not used - var/emagged = 0 var/wiresexposed = 0 var/apcwires = 15 netnum = -1 // set so that APCs aren't found as powernet nodes diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index dd5f262e99..5ec4485619 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -105,7 +105,6 @@ display round(lastgen) and plasmatank amount board_path = "/obj/item/weapon/circuitboard/pacman" coin_left = 0 // How much is left of the coin time_per_coin = 1 - emagged = 0 heat = 0 New() diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 57a9a5557a..e9d539ea56 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -607,7 +607,7 @@ datum req_tech = list("programming" = 3) build_type = IMPRINTER materials = list("$glass" = 2000, "acid" = 20) - build_path = "/obj/item/mecha_parts/circuitboard/ripley/main" + build_path = "/obj/item/weapon/circuitboard/mecha/ripley/main" ripley_peri name = "Circuit Design (APLU \"Ripley\" Peripherals Control module)" @@ -616,7 +616,7 @@ datum req_tech = list("programming" = 3) build_type = IMPRINTER materials = list("$glass" = 2000, "acid" = 20) - build_path = "/obj/item/mecha_parts/circuitboard/ripley/peripherals" + build_path = "/obj/item/weapon/circuitboard/mecha/ripley/peripherals" gygax_main name = "Circuit Design (\"Gygax\" Central Control module)" @@ -625,7 +625,7 @@ datum req_tech = list("programming" = 4) build_type = IMPRINTER materials = list("$glass" = 2000, "acid" = 20) - build_path = "/obj/item/mecha_parts/circuitboard/gygax/main" + build_path = "/obj/item/weapon/circuitboard/mecha/gygax/main" gygax_peri name = "Circuit Design (\"Gygax\" Peripherals Control module)" @@ -634,7 +634,7 @@ datum req_tech = list("programming" = 4) build_type = IMPRINTER materials = list("$glass" = 2000, "acid" = 20) - build_path = "/obj/item/mecha_parts/circuitboard/gygax/peripherals" + build_path = "/obj/item/weapon/circuitboard/mecha/gygax/peripherals" gygax_targ name = "Circuit Design (\"Gygax\" Weapons & Targeting Control module)" @@ -643,7 +643,7 @@ datum req_tech = list("programming" = 4, "combat" = 2) build_type = IMPRINTER materials = list("$glass" = 2000, "acid" = 20) - build_path = "/obj/item/mecha_parts/circuitboard/gygax/targeting" + build_path = "/obj/item/weapon/circuitboard/mecha/gygax/targeting" durand_main name = "Circuit Design (\"Durand\" Central Control module)" @@ -652,7 +652,7 @@ datum req_tech = list("programming" = 4) build_type = IMPRINTER materials = list("$glass" = 2000, "acid" = 20) - build_path = "/obj/item/mecha_parts/circuitboard/durand/main" + build_path = "/obj/item/weapon/circuitboard/mecha/durand/main" durand_peri name = "Circuit Design (\"Durand\" Peripherals Control module)" @@ -661,7 +661,7 @@ datum req_tech = list("programming" = 4) build_type = IMPRINTER materials = list("$glass" = 2000, "acid" = 20) - build_path = "/obj/item/mecha_parts/circuitboard/durand/peripherals" + build_path = "/obj/item/weapon/circuitboard/mecha/durand/peripherals" durand_targ name = "Circuit Design (\"Durand\" Weapons & Targeting Control module)" @@ -670,7 +670,7 @@ datum req_tech = list("programming" = 4, "combat" = 2) build_type = IMPRINTER materials = list("$glass" = 2000, "acid" = 20) - build_path = "/obj/item/mecha_parts/circuitboard/durand/targeting" + build_path = "/obj/item/weapon/circuitboard/mecha/durand/targeting" honker_main @@ -680,7 +680,7 @@ datum req_tech = list("programming" = 3) build_type = IMPRINTER materials = list("$glass" = 2000, "acid" = 20) - build_path = "/obj/item/mecha_parts/circuitboard/honker/main" + build_path = "/obj/item/weapon/circuitboard/mecha/honker/main" honker_peri name = "Circuit Design (\"H.O.N.K\" Peripherals Control module)" @@ -689,7 +689,7 @@ datum req_tech = list("programming" = 3) build_type = IMPRINTER materials = list("$glass" = 2000, "acid" = 20) - build_path = "/obj/item/mecha_parts/circuitboard/honker/peripherals" + build_path = "/obj/item/weapon/circuitboard/mecha/honker/peripherals" honker_targ name = "Circuit Design (\"H.O.N.K\" Weapons & Targeting Control module)" @@ -698,7 +698,7 @@ datum req_tech = list("programming" = 3) build_type = IMPRINTER materials = list("$glass" = 2000, "acid" = 20) - build_path = "/obj/item/mecha_parts/circuitboard/honker/targeting" + build_path = "/obj/item/weapon/circuitboard/mecha/honker/targeting" //////////////////////////////////////// /////////// Mecha Equpment ///////////// @@ -768,14 +768,14 @@ datum req_tech = list("bluespace" = 2, "magnets" = 3, "engineering" = 3) build_path = "/obj/item/mecha_parts/mecha_equipment/gravcatapult" - /*mech_repair_droid + mech_repair_droid name = "Exosuit Module Design (Repair Droid Module)" desc = "Automated Repair Droid. BEEP BOOP" id = "mech_repair_droid" build_type = MECHFAB req_tech = list("magnets" = 3, "programming" = 3, "engineering" = 3) build_path = "/obj/item/mecha_parts/mecha_equipment/repair_droid" - */ + mech_plasma_generator name = "Exosuit Module Design (Plasma Converter Module)" desc = "Exosuit-mounted plasma converter." @@ -784,6 +784,32 @@ datum req_tech = list("plasmatech" = 2, "powerstorage"= 2, "engineering" = 2) build_path = "/obj/item/mecha_parts/mecha_equipment/plasma_generator" + mech_energy_relay + name = "Exosuit Module Design (Tesla Energy Relay)" + desc = "Tesla Energy Relay" + id = "mech_energy_relay" + build_type = MECHFAB + req_tech = list("magnets" = 4, "syndicate" = 3) + build_path = "/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay" + + mech_ccw_armor + name = "Exosuit Module Design(Reactive Armor Booster Module)" + desc = "Exosuit-mounted armor booster." + id = "mech_ccw_armor" + build_type = MECHFAB + req_tech = list("materials" = 5, "combat" = 4) + build_path = "/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster" + + mech_proj_armor + name = "Exosuit Module Design(Reflective Armor Booster Module)" + desc = "Exosuit-mounted armor booster." + id = "mech_proj_armor" + build_type = MECHFAB + req_tech = list("materials" = 5, "combat" = 5, "engineering"=3) + build_path = "/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster" + + + //////////////////////////////////////// //////////Disk Construction Disks/////// ////////////////////////////////////////