From 63cd6afce819a25cf4fb2677b4665bfd08254d84 Mon Sep 17 00:00:00 2001 From: panurgomatic Date: Thu, 2 Dec 2010 09:50:46 +0000 Subject: [PATCH] - Further work on exosuits. Added Marauder combat model. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@516 316c924e-a436-60f5-8080-3fe189b3f50e --- code/game/mecha/combat/combat.dm | 203 +++++++++--------- code/game/mecha/combat/gygax.dm | 78 ++++++- code/game/mecha/combat/marauder.dm | 114 +++++++++++ code/game/mecha/combat/weapons/weapons.dm | 129 ++++++++++++ code/game/mecha/mecha.dm | 239 +++++++++++++++++++--- code/game/objects/weapons.dm | 52 +++-- goonstation.dme | 3 + icons/mob/mecha.dmi | Bin 1389 -> 2733 bytes 8 files changed, 640 insertions(+), 178 deletions(-) create mode 100644 code/game/mecha/combat/marauder.dm create mode 100644 code/game/mecha/combat/weapons/weapons.dm 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 9fcc6e8de9fdaac48b6ed8cefb4acaabe6619260..75024621e6c13d12fdb43c5e07a9ae0b48b7a8bb 100644 GIT binary patch delta 2666 zcmV-w3YGQk3au4?iBL{Q4GJ0x0000DNk~Le0001B0001B2m=5B0M$l^3IG5ALQqUp zMZmzo4-gKUN;c9~H|<|L@Vlr0|1-Z~N?MXNPg7ZFZFqfumzB(MD=RAi001p5L!G9+ zT4;xOhNVeWZdH0nz`(#7?x<}50004WQchCf z?AvLzFqMlCY?^8q)5^e`n@tJmV(?#(5GUHACBq)}47zrt7WkJ2SlvG-=xtZtze>zC3W1 zKbV2^gD?zzP0)%>wi^ax`bp*tQ*X>L(A2izT@s%tx`M0v`4PbXL`)%Q;T9?d`w&CD z#B|$MxP1+2yljQ5_|EddE6uHg)Iuky++`JM=wNW!W?Z0le|V)a$g?iv2=1%3H9Tx=H7EnJN@bmbXf!cL{007o(+dF~5J?QJZTSL)&B@7$U|J0H&1uF= z(+A5$0^n0Ge@WabEIQ&=@#N*UQG~Z-D{I@j zrgH^$f0UcFn8>7$p}~*|1jh=UGQnVqA0}o6Yl_%s7>P_kYsCSE&Je@p(we;7jV?^Y zU{Qi4#lY4CovLIpMWR&^q*`F%dnG_DY*h&|fyg5P9wdSi;;zlg(;2p|b_kjU0p=kw zKwuHnGl6L|293E9$fQglF~Gxd(fFk*q4PfrZuyDXJcd3)a2Q!JN-GtC2Z zCOAD{*ykFbnG(%qm{j=hfW)Qp5PgJ4)%_E}RSXCwDcIAU;8Z-6;H1cJ31lY_g7FR@ ze@iX|T@@#ki{*?jX1RJo(w_v_E6zx(TlL{oqnknM8Mx`qG_k@B+q;we8GeQZryS*c z*{RVA9RMg3)3mh4-DYk6eOX^Q=FPOGe|{W~xCZ!l9KkPVj);dc~T*_US- z8OQa4s(e~$vq%RrW0{(%a&Q?>Px5YtfBa5(&h@9%z6yJsa6ugZdKr!bR~1mgM67Dq! zdC;H45AmXWR}%eAH>%?wZM5q8agxbiboi*a=?U`@WVm*u? zd*;&NOS_*c7F+-iNNmHFhM2z72gyai;}(;3@<(nm-eiVhsE!+kXMq%CQN%|l*_j#S zV((q_*@6vt46F0%Lhn{_QS`L5DGa86Ykx0=y@$7sb-;DhLsJg9=;7m#f7XGnGZic{ zNkn`Lr!1YT247C%d8ui%8o1eMoxz36&kr0f;$p_{R`8<~p&v$?YWICCWn`fW^3JOO z5BU(_d!PQ`URJl_vg#GD^OTNn+1{gtFQtMppsB7J3iur{*!?HG!~kcK8T-mBpMQ`2 zA``$ZtT?a;*@5-!d*^yQe^NX$NIoVU)xwoBVUYRQrnsi3Y=c8OtGOWy2E5+s_BeUu%LLa+sZ?9vjp#>*OxBqK1F&h z^!%#9sWJbRfBxR*9TDn1TTpNZb-rNG4G-$EIbNSU;LiAmV)IFU)b2m(rXC+MCAa7a zNA-@sW=I5E>6>o)sf`8yngC6c9x||X>j~mYARAYn;jm+VL*OY^PebB~ee-t$zwI&4 zAeH}yfN{(E$vN+dfX6?b!KuF|Xj~#lEnD3C?Yfr5f509VXwRkuzt2+#7jfJ6A%Bp# z&EZHBIQ{efF6p&DoA@IGHmqd9v+*F7 z==8huA7=bhKF*>(Wube@4{ZFg-?v?kOu;|(RX-81J@-7iKgR$u#u;1M_rDVaEta=R z=Gd#qe%s0q>ua zgdap?Gtdtd-^*`uSAowA&uJQYMEbM%hRqG%|45(*nBUjwoBWX4h7T)Q(eO70uLSHW z9=BU<5CMb0-zWSae+!hrw&YPmei+^Gtr8#PV76}=;>xqCepdbDqJnR0ywCWFz*pac zo~F2h`|k<7R#DY)d$wRp`m;UwJ_z1voYDHM>wP8Th`?qg@&xj&{O0^Y>C=|^3H?0& Y2c?nOD9Oa=i2wiq07*qoM6N<$f(lptfdBvi delta 1311 zcmV+)1>pLv73~UWiBL{Q4GJ0x0000DNk~Le0000$0000$1Oos709Z$C?EnA(Do{*R zMZmzo4-gKUN;c9~H|<|L@Vlr0|1(;WHBVDnXl;0Xf0w^uN-HZXmCSK@Rgm@o0004W zQchCYCm3jjIq8ZHzdO9B7@1bazDK~zYIWtA~+8#ffk zkNE_8;=$sX8Z1jLP-LQb0@^6c>3CVZS$74BOfFKi8MPE?H=;mu60)d8Q%Ue*bf~0y zxyb2IO+uE~&^PFp>ErRvl3Fg}pZt-0@7;S(j*|~KJq2fP{6`ai@W1#vgvw6mqtuU} zmbRj}mk!{>YBr-%iiIxpSt!1zFP@3tsDE){HAtl-SnZr8;Tm49x^H3aCl|RExQ_(Q z^`j^jAfVa+3N(sOaviO4#JP4JDaBXPS1OdzcD)GOnZKEV!ZK-n~d-mO1dFq3?8#bMO9c@quIB0AzhbV@Ti&Mujz&UjK zaBBd}hhsN?4(4Rlt&H3#xVAt*{IKE{fQP`?sWxyD;l#;pzf1c!VY^ZJMw#Fww-NQ|*y`)KtqqnkyP(tjDY64>W#FeM0DHs# z04hsBiu}Olqt$Qf`2kF0p^b5jnk06}@EWX!AmUN!>+pW>t?Ouf+lzYMM_X{j1KY4yx z%A@y5Xo|`?I5GNF6-z{YIX}43F@@7*f4(SzXMgLJDWq~Agp9B${8L^^Gb`>q7O z;WX+ufIq~V^UROi*zT;vX4i~Dz6&+M+NRM&|6z}i><2cCv8=rE20r#B8~VMnE&y8L zM9a`Cuiz7^0$*LY!p4CHXDW1+7(M_3BTJKD2e=8gX+a-=HdRprJXcs7XfTFqtVFYa z1jsuCK21k%;WrKD>CXr}esB|f6@T(}wgVO~zlv12OIys@_UqSrmr?B1tL8!00@O_v z?BsU4Im~-c?Ap^u7^_{ z?rPI#(+L~x-Xz1xJiQJ@=_d7$)6sA)vIi{F<#OQ$g