diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm index 9ad140020da..42637fd2d25 100644 --- a/code/game/mecha/combat/combat.dm +++ b/code/game/mecha/combat/combat.dm @@ -1,121 +1,110 @@ /obj/mecha/combat - deflect_chance = 20 + deflect_chance = 10 health = 500 - var/weapon_1 = null - var/weapon_1_cooldown = 0 - var/weapon_1_ready = 1 - var/weapon_1_name = "some weapon" - var/weapon_1_energy_drain = 0 - var/weapon_2 = null - var/weapon_2_cooldown = 0 - var/weapon_2_ready = 1 - var/weapon_2_name = "another weapon" - var/weapon_2_energy_drain = 0 - var/selected_weapon = 1 - var/overload = 0 - var/melee_damage = 20 + var/datum/mecha_weapon/selected_weapon + var/datum/mecha_weapon/weapon_1 + var/datum/mecha_weapon/weapon_2 req_access = access_heads + var/force = 25 + var/damtype = "brute" + var/melee_cooldown = 10 + var/melee_can_hit = 1 + var/list/destroyable_obj = list(/obj/mecha, /obj/window, /obj/grille, /turf/simulated/wall) /obj/mecha/combat/verb/switch_weapon() set category = "Exosuit Interface" set name = "Switch weapon" set src in view(0) - if(state || !cell || cell.charge<=0) return if(usr!=src.occupant) return - if(selected_weapon == 1) - selected_weapon = 2 - src.occupant << "You switch to [weapon_2_name]" - for (var/mob/M in oviewers(src)) - M.show_message("[src.name] raises [weapon_2_name]") - else if(selected_weapon == 2) - selected_weapon = 1 - src.occupant << "You switch to [weapon_1_name]" - for (var/mob/M in oviewers(src)) - M.show_message("[src.name] raises [weapon_1_name]") - return - -/obj/mecha/combat/verb/overload() - set category = "Exosuit Interface" - set name = "Toggle leg actuators overload" - set src in view(0) - if(overload) - overload = 0 - step_in = initial(step_in) - src.occupant << "\blue You disable leg actuators overload." - else - overload = 1 - step_in = min(1, round(step_in/2)) - src.occupant << "\red You enable leg actuators overload." - - -/obj/mecha/combat/click_action(target) if(state || !cell || cell.charge<=0) return - if(src == target) return - if(get_dist(src,target)<=1) - src.mega_punch(target) -/* - if(src.occupant.a_intent == "hurt") - src.mega_punch(target) - else if(src.occupant.a_intent == "help") - src.mega_shake(target) -*/ - else - src.fire(src.selected_weapon,target) + if(selected_weapon == weapon_1) + selected_weapon = weapon_2 + else if(selected_weapon == weapon_2) + selected_weapon = weapon_1 + + src.occupant << "You switch to [selected_weapon.name]" + for (var/mob/M in oviewers(src)) + M.show_message("[src.name] raises [selected_weapon.name]") return -/obj/mecha/combat/proc/fire(weapon_num,target) - var/turf/curloc = src.loc - var/atom/targloc = get_turf(target) - if (!targloc || !istype(targloc, /turf) || !curloc) - return - var/weapon_type - switch(weapon_num) - if(1) - if(weapon_1_ready) - weapon_type = weapon_1 - weapon_1_ready = 0 - spawn(weapon_1_cooldown) - cell.use(weapon_1_energy_drain) - weapon_1_ready = 1 - if(2) - if(weapon_2_ready) - weapon_type = weapon_2 - weapon_2_ready = 0 - spawn(weapon_2_cooldown) - cell.use(weapon_2_energy_drain) - weapon_2_ready = 1 - - - if(!weapon_type) return - - - playsound(src, 'Laser.ogg', 50, 1) - if (targloc == curloc) - return - - var/obj/beam/a_laser/A = new weapon_type(src.loc) - A.current = curloc - A.yo = targloc.y - curloc.y - A.xo = targloc.x - curloc.x - spawn() - A.process() - +/obj/mecha/combat/range_action(target) + if(selected_weapon) + selected_weapon.fire(target) return -/obj/mecha/combat/proc/mega_punch(target) - if(!istype(target, /obj) && !istype(target, /mob)) return +/obj/mecha/combat/melee_action(target) + if(!melee_can_hit || (!istype(target, /obj) && !istype(target, /mob) && !istype(target, /turf))) return if(istype(target, /mob)) var/mob/M = target - M.bruteloss += rand(melee_damage/2, melee_damage) - M.paralysis += 1 - M.updatehealth() - step_away(M,src,15) + if(damtype == "brute") + step_away(M,src,15) + if(M.stat>1) + M.gib() + return + if(istype(target, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = target +// if (M.health <= 0) return + + var/dam_zone = pick("chest", "chest", "chest", "head", "groin") + if (istype(H.organs[dam_zone], /datum/organ/external)) + var/datum/organ/external/temp = H.organs[dam_zone] + switch(damtype) + if("brute") + H.paralysis += 1 + temp.take_damage(rand(force/2, force), 0) + if("fire") + temp.take_damage(0, rand(force/2, force)) + if("tox") + H.toxloss += rand(force/2, force) + else + return + H.UpdateDamageIcon() + H.updatehealth() + + else + switch(damtype) + if("brute") + M.paralysis += 1 + M.bruteloss += rand(force/2, force) + if("fire") + M.fireloss += rand(force/2, force) + if("tox") + M.toxloss += rand(force/2, force) + else + return + M.updatehealth() + + src.occupant.show_message("[src.name] hits [target].", 1) for (var/mob/V in viewers(src)) - V.show_message("[src.name] sends [M] flying.") + if(V.client && !(V.blinded)) + V.show_message("[src.name] hits [target].", 1) + + melee_can_hit = 0 + spawn(melee_cooldown) + melee_can_hit = 1 + return + + else + if(damtype == "brute") + for(var/target_type in src.destroyable_obj) + if(istype(target, target_type) && hascall(target, "attackby")) + src.occupant.show_message("[src.name] hits [target].", 1) + for (var/mob/V in viewers(src)) + if(V.client && !(V.blinded)) + V.show_message("[src.name] hits [target].", 1) + if(!istype(target, /turf/simulated/wall)) + target:attackby(src,src.occupant) + else if(prob(2)) + target:dismantle_wall(1) + src.occupant << text("\blue You smash through the wall.") + melee_can_hit = 0 + spawn(melee_cooldown) + melee_can_hit = 1 + break return /* @@ -131,16 +120,6 @@ return */ -/obj/mecha/combat/relaymove(mob/user,direction) - if(!..()) return - if(overload) - cell.use(step_energy_drain) - health-- - if(health < initial(health) - initial(health)/3) - overload = 0 - src.occupant << "\red Leg actuators damage treshold exceded. Disabling overload." - - /* if(energy>0 && can_move) if(step(src,direction)) @@ -154,4 +133,12 @@ return 1 return 0 -*/ \ No newline at end of file +*/ + +/obj/mecha/combat/Del() + if(weapon_1) + del weapon_1 + if(weapon_2) + del weapon_2 + ..() + return diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index 9817f24b8cb..2adfb431457 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -1,14 +1,72 @@ /obj/mecha/combat/gygax - desc = "Heavy duty combat exosuit." + desc = "Security exosuit." name = "Gygax" icon_state = "gygax" - step_in = 8 + step_in = 6 + health = 300 + deflect_chance = 15 + max_temperature = 3500 + var/overload = 0 - weapon_1 = "/obj/beam/a_laser/pulse_laser" - weapon_1_cooldown = 50 - weapon_1_name = "eZ-13 mk2 Heavy pulse rifle" - weapon_1_energy_drain = 50 - weapon_2 = "/obj/beam/a_laser" - weapon_2_cooldown = 10 - weapon_2_name = "CH-PS \"Immolator\" Laser" - weapon_2_energy_drain = 20 +/obj/mecha/combat/gygax/New() + ..() + weapon_1 = new /datum/mecha_weapon/pulse(src) + weapon_2 = new /datum/mecha_weapon/laser(src) + selected_weapon = weapon_1 + return + +/obj/mecha/combat/gygax/verb/overload() + set category = "Exosuit Interface" + set name = "Toggle leg actuators overload" + set src in view(0) + if(usr!=src.occupant) + return + if(overload) + overload = 0 + step_in = initial(step_in) + src.occupant << "\blue You disable leg actuators overload." + else + overload = 1 + step_in = min(1, round(step_in/2)) + src.occupant << "\red You enable leg actuators overload." + return + + + +/obj/mecha/combat/gygax/relaymove(mob/user,direction) + if(!..()) return + if(overload) + cell.use(step_energy_drain) + health-- + if(health < initial(health) - initial(health)/3) + overload = 0 + step_in = initial(step_in) + src.occupant << "\red Leg actuators damage treshold exceded. Disabling overload." + return + + +/obj/mecha/combat/gygax/get_stats_part() + var/output = ..() + output += {"Weapon systems: +
+ [selected_weapon==weapon_1?"":""][weapon_1.name][selected_weapon==weapon_1?"":""] +
+
+ [selected_weapon==weapon_2?"":""][weapon_2.name][selected_weapon==weapon_2?"":""] +
+ Leg actuators overload: [overload?"on":"off"] + "} + return output + +/obj/mecha/combat/gygax/get_commands() + var/output = ..() + output = {"Toggle leg actuators overload
+ "} + return output + +/obj/mecha/combat/gygax/Topic(href, href_list) + ..() + if (href_list["toggle_leg_overload"]) + src.overload() + return + return \ No newline at end of file diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm new file mode 100644 index 00000000000..52606238686 --- /dev/null +++ b/code/game/mecha/combat/marauder.dm @@ -0,0 +1,114 @@ +/obj/mecha/combat/marauder + desc = "Heavy duty combat exosuit." + name = "Marauder" + icon_state = "marauder" + step_in = 10 + health = 500 + deflect_chance = 25 + max_temperature = 5000 + var/thrusters = 0 + var/smoke = 5 + var/smoke_ready = 1 + var/smoke_cooldown = 100 + var/datum/effects/system/harmless_smoke_spread/smoke_system = new + + +/obj/mecha/combat/marauder/New() + ..() + weapon_1 = new /datum/mecha_weapon/pulse(src) + weapon_2 = new /datum/mecha_weapon/missile_rack(src) + selected_weapon = weapon_1 + src.smoke_system.set_up(3, 0, src) + src.smoke_system.attach(src) + return + +/obj/mecha/combat/marauder/relaymove(mob/user,direction) + if(!can_move) + return 0 + if(connected_port) + src.occupant << "Unable to move while connected to the air system port" + return 0 + if(!thrusters && src.inertia_dir) + return 0 + if(state || !cell || cell.charge<=0) + return 0 + var/tmp_step_in = step_in + var/tmp_step_energy_drain = step_energy_drain + if(step(src,direction)) + if(istype(src.loc, /turf/space)) + if(!src.check_for_support()) + src.inertia_dir = direction + src.inertial_movement() + if(thrusters) + tmp_step_energy_drain = step_energy_drain*2 + + can_move = 0 + spawn(tmp_step_in) can_move = 1 + cell.use(tmp_step_energy_drain) + return 1 + return 0 + + +/obj/mecha/combat/marauder/verb/toggle_thrusters() + set category = "Exosuit Interface" + set name = "Toggle thrusters" + set src in view(0) + if(usr!=src.occupant) + return + if(src.occupant) + if(cell.charge > 0) + thrusters = !thrusters + src.occupant << "\blue Thrusters [thrusters?"en":"dis"]abled." + return + +/obj/mecha/combat/marauder/verb/smoke() + set category = "Exosuit Interface" + set name = "Smoke" + set src in view(0) + if(usr!=src.occupant) + return + if(smoke_ready && smoke>0) + src.smoke_system.start() + smoke-- + smoke_ready = 0 + spawn(smoke_cooldown) + smoke_ready = 1 + return + +/obj/mecha/combat/marauder/get_stats_part() + var/output = ..() + output += {"Weapon systems: +
+ [selected_weapon==weapon_1?"":""][weapon_1.name][selected_weapon==weapon_1?"":""] +
+
+ [selected_weapon==weapon_2?"":""][weapon_2.name] ([weapon_2:missiles])[selected_weapon==weapon_2?"":""] +
+ Smoke: [smoke] +
+ Thrusters: [thrusters?"on":"off"] + "} + return output + + +/obj/mecha/combat/marauder/get_commands() + var/output = ..() + var/datum/mecha_weapon/missile_rack/MR = weapon_2 + output += {"Toggle thrusters
+ Smoke
+ [(MR.missiles < initial(MR.missiles))?"Rearm missile rack
":null] + "} + return output + +/obj/mecha/combat/marauder/Topic(href, href_list) + ..() + if (href_list["toggle_thrusters"]) + src.toggle_thrusters() + return + if (href_list["smoke"]) + src.smoke() + return + if (href_list["rearm_srm"]) + var/datum/mecha_weapon/missile_rack/MR = weapon_2 + MR.rearm() + return \ No newline at end of file diff --git a/code/game/mecha/combat/weapons/weapons.dm b/code/game/mecha/combat/weapons/weapons.dm new file mode 100644 index 00000000000..279a13af6e0 --- /dev/null +++ b/code/game/mecha/combat/weapons/weapons.dm @@ -0,0 +1,129 @@ +/datum/mecha_weapon + var/name = "mecha weapon" + var/weapon_cooldown = 0 + var/weapon_ready = 1 + var/energy_drain = 0 + var/obj/mecha/chassis = null + + +/datum/mecha_weapon/New(mecha) + if(!istype(mecha, /obj/mecha/combat)) + return + src.chassis = mecha + return + +/datum/mecha_weapon/proc/fire(target) //general checks. + if(!target) + return 0 + if(!chassis) + return 0 + if(energy_drain && chassis.cell.charge < energy_drain) + return 0 + if(!weapon_ready) + return 0 + return 1 + + + +/datum/mecha_weapon/missile_rack + name = "SRM-8 Missile Rack" + var/missiles = 8 + var/missile_speed = 2 + var/missile_range = 30 + var/missile_energy_cost = 1000 + weapon_cooldown = 60 + + fire(target) + if(!..() || missiles <=0) return + var/obj/item/missile/M = new /obj/item/missile(chassis.loc) + M.primed = 1 + M.throw_at(target, missile_range, missile_speed) + weapon_ready = 0 + missiles-- + spawn(weapon_cooldown) + weapon_ready = 1 + return + + proc/rearm() + if(missiles < initial(missiles)) + var/missiles_to_add = initial(missiles) - missiles + while(chassis.cell.charge >= missile_energy_cost && missiles_to_add) + missiles++ + missiles_to_add-- + chassis.cell.charge -= missile_energy_cost + return + + +/obj/item/missile + icon = 'grenade.dmi' + icon_state = "flashbang" + var/primed = null + + throw_impact(atom/hit_atom) + if(primed) + explosion(hit_atom, 0, 0, 2, 4) + del(src) + else + ..() + return + + +/datum/mecha_weapon/laser + weapon_cooldown = 10 + name = "CH-PS \"Immolator\" Laser" + energy_drain = 20 + + fire(target) + if(!..()) return + + var/turf/curloc = chassis.loc + var/atom/targloc = get_turf(target) + if (!targloc || !istype(targloc, /turf) || !curloc) + return + if (targloc == curloc) + return + + playsound(src, 'Laser.ogg', 50, 1) + var/obj/beam/a_laser/A = new /obj/beam/a_laser(curloc) + A.current = curloc + A.yo = targloc.y - curloc.y + A.xo = targloc.x - curloc.x + weapon_ready = 0 + chassis.cell.use(energy_drain) + spawn() + A.process() + spawn(weapon_cooldown) + weapon_ready = 1 + + return + + + +/datum/mecha_weapon/pulse + weapon_cooldown = 50 + name = "eZ-13 mk2 Heavy pulse rifle" + energy_drain = 50 + + fire(target) + if(!..()) return + + var/turf/curloc = chassis.loc + var/atom/targloc = get_turf(target) + if (!targloc || !istype(targloc, /turf) || !curloc) + return + if (targloc == curloc) + return + + playsound(src, 'Laser.ogg', 50, 1) + var/obj/beam/a_laser/A = new /obj/beam/a_laser/pulse_laser(curloc) + A.current = curloc + A.yo = targloc.y - curloc.y + A.xo = targloc.x - curloc.x + weapon_ready = 0 + chassis.cell.use(energy_drain) + spawn() + A.process() + spawn(weapon_cooldown) + weapon_ready = 1 + + return \ No newline at end of file diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 49f0ca16731..fb45d0599c9 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -1,5 +1,6 @@ /obj/mecha name = "Mecha" + desc = "Exosuit" icon = 'mecha.dmi' density = 1 //Dense. To raise the heat. opacity = 1 ///opaque. Menacing. @@ -9,10 +10,10 @@ var/step_in = 10 //make a step in step_in/10 sec. var/step_energy_drain = 10 var/health = 300 //health is health - var/deflect_chance = 5 //chance to deflect the incoming projectiles, or lesser the effect of ex_act. + var/deflect_chance = 5 //chance to deflect the incoming projectiles, hits, or lesser the effect of ex_act. var/obj/item/weapon/cell/cell = new var/state = 0 - + var/update_stats = null //used to auto-update stats window var/datum/effects/system/spark_spread/spark_system = new var/lights = 0 @@ -23,23 +24,27 @@ var/datum/gas_mixture/air_contents = new var/obj/machinery/atmospherics/portables_connector/connected_port = null //filling the air tanks var/filled = 0.5 - var/gas_tank_volume = 80 + var/gas_tank_volume = 500 var/maximum_pressure = 30*ONE_ATMOSPHERE req_access = access_engine var/operating_access = null + var/max_temperature = 2500 /obj/mecha/New() ..() src.air_contents.volume = gas_tank_volume //liters src.air_contents.temperature = T20C src.air_contents.oxygen = (src.maximum_pressure*filled)*air_contents.volume/(R_IDEAL_GAS_EQUATION*air_contents.temperature) - src.spark_system.set_up(5, 0, src) + src.spark_system.set_up(2, 0, src) src.spark_system.attach(src) src.cell.charge = 15000 src.cell.maxcharge = 15000 preserve_temp() + check_location_temp() src.verbs -= /obj/mecha/verb/disconnect_from_port + src.verbs -= /atom/movable/verb/pull + return /client/Click(object,location,control,params) @@ -53,34 +58,56 @@ /obj/mecha/proc/click_action(target) + if(!src.occupant) return + if(state || !cell || cell.charge<=0) return + if(src == target) return + if(get_dist(src,target)<=1) + src.melee_action(target) + else + src.range_action(target) return +/obj/mecha/proc/melee_action(target) + return + +/obj/mecha/proc/range_action(target) + return ////////////////////////////////// //////// Movement procs //////// ////////////////////////////////// /obj/mecha/relaymove(mob/user,direction) + if(!can_move) + return 0 if(connected_port) src.occupant << "Unable to move while connected to the air system port" return 0 if(src.inertia_dir) return 0 - if(state || !cell || cell.charge<=0) return 0 - if(can_move) - if(step(src,direction)) - can_move = 0 - spawn(step_in) can_move = 1 - cell.use(src.step_energy_drain) - if(istype(src.loc, /turf/space)) - if(!src.check_for_support()) - src.inertia_dir = direction - src.inertial_movement() - return 1 + if(state || !cell || cell.charge<=0) + return 0 + if(step(src,direction)) + can_move = 0 + spawn(step_in) can_move = 1 + cell.use(src.step_energy_drain) + if(istype(src.loc, /turf/space)) + if(!src.check_for_support()) + src.inertia_dir = direction + src.inertial_movement() + return 1 return 0 + /obj/mecha/proc/inertial_movement() +// set background = 1 + spawn while(src && src.inertia_dir) + if(!step(src, src.inertia_dir)||check_for_support()) + src.inertia_dir = null + sleep(7) + +/* if(check_for_support()) src.inertia_dir = null if(src.inertia_dir) @@ -90,7 +117,7 @@ else src.inertia_dir = null return - +*/ /obj/mecha/proc/check_for_support() if(locate(/obj/grille, orange(1, src)) || locate(/obj/lattice, orange(1, src)) || locate(/turf/simulated, orange(1, src)) || locate(/turf/unsimulated, orange(1, src))) return 1 @@ -113,11 +140,60 @@ //////// Health related procs //////// //////////////////////////////////////// +/obj/mecha/proc/update_health() + if(src.health > 0) + src.spark_system.start() + else + src.destroy() + return + +/obj/mecha/attack_hand(mob/user as mob) + if (user.mutations & 8 && !prob(src.deflect_chance)) + src.health -= 15 + src.update_health() + user << "\red You hit [src.name] with all your might. The metal creaks and bends." + for (var/mob/V in viewers(src)) + if(V.client && V != user && !(V.blinded)) + V.show_message("[user] hits [src.name], doing some damage.", 1) + else + user << "\red You hit [src.name] with no visible effect." + for (var/mob/V in viewers(src)) + if(V.client && V != user && !(V.blinded)) + V.show_message("[user] hits [src.name]. Nothing happens", 1) + return + +/obj/mecha/attack_paw(mob/user as mob) + return src.attack_hand() + + +/obj/mecha/hitby(A as mob|obj) + if(prob(src.deflect_chance) || istype(A, /mob)) + if(src.occupant && src.occupant.client) + src.occupant << "\blue The [A] bounces off the armor." + for (var/mob/V in viewers(src)) + if(V.client && !(V.blinded)) + V.show_message("The [A] bounces off the [src.name] armor", 1) + if(istype(A, /mob)) + var/mob/M = A + M.bruteloss += 10 + M.updatehealth() + return + + else if(istype(A, /obj)) + var/obj/O = A + if(O.throwforce) + src.health -= O.throwforce + src.update_health() + return + + /obj/mecha/bullet_act(flag) if(prob(src.deflect_chance)) if(src.occupant && src.occupant.client) src.occupant << "\blue The armor deflects the incoming projectile." - return + for (var/mob/V in viewers(src)) + if(V.client && !(V.blinded)) + V.show_message("The [src.name] armor deflects the projectile", 1) else switch(flag) if(PROJECTILE_PULSE) @@ -126,22 +202,19 @@ src.health -= 20 else src.health -= 10 - if(src.health > 0) - src.spark_system.start() - else - src.destroy() + src.update_health() + return /obj/mecha/proc/destroy() if(src.occupant) - var/mob/M = src.occupant src.go_out() if(prob(20)) - M.bruteloss += rand(10,20) - M.updatehealth() + src.occupant.bruteloss += rand(10,20) + src.occupant.updatehealth() else - M.gib() - explosion(src.loc, 1, 0, 2, 4) + src.occupant.gib() spawn() + explosion(src.loc, 0, 0, 1, 3) del(src) return @@ -167,6 +240,17 @@ src.spark_system.start() return +/obj/mecha/proc/check_location_temp() + spawn while(src) + if(istype(src.loc, /turf/simulated/)) + var/turf/simulated/T = src.loc + if(T.air) + if(T.air.temperature > src.max_temperature) + src.health -= 10 + src.update_health() + sleep(10) + return + ///////////////////////////////////// //////// Atmospheric stuff //////// @@ -188,13 +272,14 @@ return src.air_contents.return_pressure() /obj/mecha/proc/preserve_temp() - if(!cell || cell.charge<=0) return - 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-- - spawn(10) - .() +// 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 @@ -239,6 +324,8 @@ set category = "Exosuit Interface" set src in view(0) if(!src.occupant) return + if(usr!=src.occupant) + return var/obj/machinery/atmospherics/portables_connector/possible_port = locate(/obj/machinery/atmospherics/portables_connector/) in loc if(possible_port) if(connect(possible_port)) @@ -258,6 +345,8 @@ set category = "Exosuit Interface" set src in view(0) if(!src.occupant) return + if(usr!=src.occupant) + return if(disconnect()) src.occupant << "\blue [name] disconnects from the port." src.verbs -= /obj/mecha/verb/disconnect_from_port @@ -270,6 +359,8 @@ set name = "Toggle Lights" set category = "Exosuit Interface" set src in view(0) + if(usr!=src.occupant) + return lights = !lights if(lights) src.sd_SetLuminosity(src.luminosity + src.lights_power) @@ -300,6 +391,20 @@ src.add_fingerprint(usr) return + +/obj/mecha/verb/view_stats() + set name = "View Stats" + set category = "Exosuit Interface" + set src in view(0) + if(usr!=src.occupant) + return + src.update_stats = 1 + spawn while(src && src.occupant && src.update_stats) + src.occupant << browse(get_stats_html(), "window=exosuit") + onclose(src.occupant, "exosuit", src) + sleep(10) + return + /obj/mecha/verb/eject() set name = "Eject" set category = "Exosuit Interface" @@ -316,6 +421,7 @@ if (src.occupant.client) src.occupant.client.eye = src.occupant.client.mob src.occupant.client.perspective = MOB_PERSPECTIVE + src.occupant << browse(null, "window=exosuit") src.occupant.loc = src.loc src.occupant = null return @@ -375,9 +481,76 @@ user << "There's already a powercell installed." return + else + ..() + if(prob(src.deflect_chance)) + user << "\red The [W] bounces off [src.name] armor." +/* + for (var/mob/V in viewers(src)) + if(V.client && !(V.blinded)) + V.show_message("The [W] bounces off [src.name] armor.", 1) +*/ + else + if(W.damtype == "brute") + src.health -= W.force + else if(W.damtype == "fire") + src.health -= W.force*1.5 + src.update_health() + return + +/obj/mecha/proc/get_stats_html() + var/output = {" + [src.name] data + + [src.get_stats_part()] +
+ [src.get_commands()] + + + "} + return output + +/obj/mecha/proc/get_stats_part() + var/output = {"Integrity: [health/initial(health)*100]%
+ Powercell charge: [cell.charge/cell.maxcharge*100]%
+ Airtank pressure: [src.return_pressure()]
+ Lights: [lights?"on":"off"]
+ "} + return output + +/obj/mecha/proc/get_commands() + var/output = {"Toggle Lights
+ [(/obj/mecha/verb/disconnect_from_port in src.verbs)?"Disconnect from port
":null] + [(/obj/mecha/verb/connect_to_port in src.verbs)?"Connect to port
":null] + Eject
+ "} + return output + +/obj/mecha/Topic(href, href_list) ..() + if (href_list["close"]) + src.update_stats = null + return + if (href_list["toggle_lights"]) + src.toggle_lights() + return + if (href_list["port_disconnect"]) + src.disconnect_from_port() + return + if (href_list["port_connect"]) + src.connect_to_port() + return + if (href_list["eject"]) + src.eject() + return return +/obj/mecha/proc/drop_item()//Derpfix, but may be useful in future for engineering exosuits. + return + + + + diff --git a/code/game/objects/weapons.dm b/code/game/objects/weapons.dm index f29a7187726..735bcca3f6b 100644 --- a/code/game/objects/weapons.dm +++ b/code/game/objects/weapons.dm @@ -1027,32 +1027,30 @@ del(src) /obj/beam/a_laser/proc/process() - //world << text("laser at [] []:[], target is [] []:[]", src.loc, src.x, src.y, src:current, src.current:x, src.current:y) - if ((!( src.current ) || src.loc == src.current)) - src.current = locate(min(max(src.x + src.xo, 1), world.maxx), min(max(src.y + src.yo, 1), world.maxy), src.z) - //world << text("current changed: target is now []. location was [],[], added [],[]", src.current, src.x, src.y, src.xo, src.yo) - if ((src.x == 1 || src.x == world.maxx || src.y == 1 || src.y == world.maxy)) - //world << text("off-world, deleting") - //SN src = null - del(src) - return - step_towards(src, src.current) - // make it able to hit lying-down folk - var/list/dudes = list() - for(var/mob/living/M in src.loc) - dudes += M - if(dudes.len) - src.Bump(pick(dudes)) - //world << text("laser stepped, now [] []:[], target is [] []:[]", src.loc, src.x, src.y, src.current, src.current:x, src.current:y) - src.life-- - if (src.life <= 0) - //SN src = null - del(src) - return - - spawn(1) - src.process() - return + spawn while(src) + //world << text("laser at [] []:[], target is [] []:[]", src.loc, src.x, src.y, src:current, src.current:x, src.current:y) + if ((!( src.current ) || src.loc == src.current)) + src.current = locate(min(max(src.x + src.xo, 1), world.maxx), min(max(src.y + src.yo, 1), world.maxy), src.z) + //world << text("current changed: target is now []. location was [],[], added [],[]", src.current, src.x, src.y, src.xo, src.yo) + if ((src.x == 1 || src.x == world.maxx || src.y == 1 || src.y == world.maxy)) + //world << text("off-world, deleting") + //SN src = null + del(src) + return + step_towards(src, src.current) + // make it able to hit lying-down folk + var/list/dudes = list() + for(var/mob/living/M in src.loc) + dudes += M + if(dudes.len) + src.Bump(pick(dudes)) + //world << text("laser stepped, now [] []:[], target is [] []:[]", src.loc, src.x, src.y, src.current, src.current:x, src.current:y) + src.life-- + if (src.life <= 0) + //SN src = null + del(src) + return + sleep(1) return /obj/beam/i_beam/proc/hit() @@ -1269,4 +1267,4 @@ return ..() for(var/mob/O in viewers(src, null)) O.show_message(text("\red The mousetrap is triggered by [A]."), 1) - src.triggered(null) \ No newline at end of file + src.triggered(null) diff --git a/goonstation.dme b/goonstation.dme index 119479a7d60..65e230f5c70 100644 --- a/goonstation.dme +++ b/goonstation.dme @@ -57,6 +57,7 @@ #define FILE_DIR "code/game/magic/cultist" #define FILE_DIR "code/game/mecha" #define FILE_DIR "code/game/mecha/combat" +#define FILE_DIR "code/game/mecha/combat/weapons" #define FILE_DIR "code/game/objects" #define FILE_DIR "code/game/objects/alien" #define FILE_DIR "code/game/objects/closets" @@ -410,6 +411,8 @@ #include "code\game\mecha\mecha.dm" #include "code\game\mecha\combat\combat.dm" #include "code\game\mecha\combat\gygax.dm" +#include "code\game\mecha\combat\marauder.dm" +#include "code\game\mecha\combat\weapons\weapons.dm" #include "code\game\objects\assemblies.dm" #include "code\game\objects\blood.dm" #include "code\game\objects\bomb.dm" diff --git a/icons/mob/mecha.dmi b/icons/mob/mecha.dmi index 9fcc6e8de9f..75024621e6c 100644 Binary files a/icons/mob/mecha.dmi and b/icons/mob/mecha.dmi differ