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 39967ecd5c..9918763ba8 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -29,7 +29,7 @@ return 0 setEffects(aeffectin,aeffectout) setForceTeleport(afteleport) - setSounds(asoundin) + setSounds(asoundin,asoundout) return 1 //must succeed @@ -108,9 +108,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 151b81198a..6555dcca59 100644 --- a/code/defines/atom.dm +++ b/code/defines/atom.dm @@ -231,4 +231,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 \ No newline at end of file diff --git a/code/defines/obj/machinery.dm b/code/defines/obj/machinery.dm index 4aad8f88df..049c0dc317 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/obj/vending.dm b/code/defines/obj/vending.dm index 37d29fcbc7..2d0764f6fe 100644 --- a/code/defines/obj/vending.dm +++ b/code/defines/obj/vending.dm @@ -28,7 +28,7 @@ var/slogan_delay = 600 //How long until we can pitch again? var/icon_vend //Icon_state when vending! var/icon_deny //Icon_state when vending! - var/emagged = 0 //Ignores if somebody doesn't have card access to that machine. + //var/emagged = 0 //Ignores if somebody doesn't have card access to that machine. var/seconds_electrified = 0 //Shock customers like an airlock. var/shoot_inventory = 0 //Fire items at customers! We're broken! var/shut_up = 0 //Stop spouting those godawful pitches! diff --git a/code/defines/procs/helpers.dm b/code/defines/procs/helpers.dm index 5ee2993127..9a409816ad 100644 --- a/code/defines/procs/helpers.dm +++ b/code/defines/procs/helpers.dm @@ -1452,6 +1452,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 83ba4e215d..6545e240aa 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/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index fac540a854..57b87ae93f 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -1,5 +1,4 @@ /obj/machinery/computer/arcade - var/emagged var/turtle = 0 /obj/machinery/computer/arcade/New() diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index f05d34a3fd..998c212cbd 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 17364faafe..42ab5ea555 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/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 4b5b3612fe..a0d13f008b 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -43,7 +43,7 @@ var/attacked = 0 // if set to 1, the turret gets pissed off and shoots at people nearby (unless they have sec access!) - var/emagged = 0 // 1: emagged, 0: not emagged + //var/emagged = 0 // 1: emagged, 0: not emagged var/on = 1 // determines if the turret is on var/datum/effect/effect/system/spark_spread/spark_system // the spark system, used for generating... sparks? diff --git a/code/game/magic/library.dm b/code/game/magic/library.dm index 8f65ab1b7a..8fad35e65f 100644 --- a/code/game/magic/library.dm +++ b/code/game/magic/library.dm @@ -407,7 +407,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 ff693768d0..a3639171dc 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 99a6edac93..8a51b2d889 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 99d5233ab8..d9bb91014f 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, @@ -85,19 +95,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() @@ -119,6 +128,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)) @@ -250,7 +303,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 @@ -375,10 +428,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 @@ -507,6 +562,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 500ca642d3..284035b1dc 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 @@ -100,6 +103,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 @@ -133,7 +185,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 @@ -153,33 +205,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) @@ -197,7 +236,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) @@ -231,39 +270,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)) @@ -283,21 +296,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 @@ -308,10 +309,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) @@ -376,7 +416,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)) @@ -408,12 +448,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() @@ -421,7 +462,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)) @@ -430,21 +472,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 @@ -462,13 +508,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 @@ -481,9 +527,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) @@ -493,17 +539,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) @@ -528,19 +728,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) @@ -686,19 +873,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 @@ -736,8 +925,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 @@ -749,7 +941,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 @@ -797,12 +989,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 @@ -816,54 +1010,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)) @@ -900,140 +1049,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 = {" @@ -1080,13 +1098,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()]%"]
@@ -1160,6 +1192,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"]) @@ -1263,20 +1374,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 - + */ /* @@ -1326,27 +1444,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) @@ -1366,50 +1472,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 //////// ////////////////////////////////////////// @@ -1439,26 +1501,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 +*/ \ No newline at end of file diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm index 589802853e..0642adcb13 100644 --- a/code/game/mecha/mecha_construction_paths.dm +++ b/code/game/mecha/mecha_construction_paths.dm @@ -120,7 +120,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 @@ -128,7 +128,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 @@ -187,7 +187,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].") @@ -199,7 +199,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].") @@ -314,7 +314,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 @@ -322,7 +322,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 @@ -330,7 +330,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 @@ -389,7 +389,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].") @@ -401,7 +401,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].") @@ -413,7 +413,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].") @@ -512,9 +512,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 @@ -600,11 +600,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 ) @@ -681,11 +681,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 @@ -768,4 +768,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 \ No newline at end of file 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 3021a0bea5..c682561e67 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 6774671f16..917744f93f 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 96c6068fb6..a2e21c3a85 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -493,7 +493,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)" @@ -502,7 +502,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)" @@ -511,7 +511,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)" @@ -520,7 +520,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)" @@ -529,7 +529,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)" @@ -538,7 +538,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)" @@ -547,7 +547,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)" @@ -556,7 +556,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 @@ -566,7 +566,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)" @@ -575,7 +575,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)" @@ -584,7 +584,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 ///////////// @@ -654,14 +654,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." @@ -670,6 +670,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/////// //////////////////////////////////////// diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 3bb1649408..fa6178bdee 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -44,7 +44,6 @@ won't update every console in existence) but it's more of a hassle to do. Also, screen = 1.0 //Which screen is currently showing. id = 0 //ID of the computer (for server restrictions). sync = 1 //If sync = 0, it doesn't show up on Server Control Console - emagged = 0 //Turns off ID check req_access = list(access_tox) //Data and setting manipulation requires scientist access. diff --git a/html/changelog.html b/html/changelog.html index fde880b037..0244c43582 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -54,6 +54,24 @@ Stuff which is in development and not yet visible to players or just code relate (ie. code improvements for expandability, etc.) should not be listed here. They should be listed in the changelog upon commit tho. Thanks. --> +23 December 2011 +
    +
  • ConstantA updated: +
      +
    • Mech Fabricators now require robotics ID to operate. Emag removes this restriction.
    • +
    • Added Odysseus Medical Exosuit. Has integrated Medical Hud and ability to mount medical modules.
    • +
    • Added Sleeper Medical module for exosuits. Similar to common sleepers, but no ability to inject reagents.
    • +
    • Added Cable Layer module for exosuits. Load with cable (attack cable with it), activate, walk over dismantled floor.
    • +
    • Added another exosuit internal damage type - short circuit. Short-circuited exosuits will drain powercell charge and power relay won't work.
    • +
    • You should be able to send messages to exosuit operators using Exosuit Control Console
    • +
    • Gygax armour and module capacity nerfed.
    • +
    • Exosuit weapon recharge time raised.
    • +
    • Bugfix: EMP actually drains exosuit cell and damages it
    • +
    +
  • +
+ + 21 December 2011
    diff --git a/icons/mob/mecha.dmi b/icons/mob/mecha.dmi index 9a4e0b686f..01f731f1b6 100644 Binary files a/icons/mob/mecha.dmi and b/icons/mob/mecha.dmi differ diff --git a/tgstation.dme b/tgstation.dme index d612f77e42..83b54ca498 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -60,6 +60,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" @@ -241,6 +242,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" @@ -527,6 +529,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"