diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm index 730cbecb2f7..f586b2d2d78 100644 --- a/code/game/mecha/combat/combat.dm +++ b/code/game/mecha/combat/combat.dm @@ -43,7 +43,7 @@ /obj/mecha/combat/melee_action(target) if(internal_damage&MECHA_INT_CONTROL_LOST) target = pick(oview(1,src)) - if(!melee_can_hit || (!istype(target, /obj) && !istype(target, /mob) && !istype(target, /turf))) return + if(!melee_can_hit || !istype(target, /atom)) return if(istype(target, /mob)) var/mob/M = target if(src.occupant.a_intent == "hurt") @@ -213,6 +213,17 @@ src.log_append_to_last("[destr_weapon] is destoyed.",1) return +/obj/mecha/combat/get_stats_part() + var/output = ..() + output += "Weapon systems:
" + if(weapons.len) + for(var/datum/mecha_weapon/W in weapons) + output += "[selected_weapon==W?"":""][W.get_weapon_info()][selected_weapon==W?"":""]
" + else + output += "None" + output += "
" + return output + /* //the garbage collector should handle this /obj/mecha/combat/Del() diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index 9c186773cdd..a5e64f0db87 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -26,11 +26,11 @@ if(overload) overload = 0 step_in = initial(step_in) - src.occupant << "\blue You disable leg actuators overload." + src.occupant_message("You disable leg actuators overload.") else overload = 1 step_in = min(1, round(step_in/2)) - src.occupant << "\red You enable leg actuators overload." + src.occupant_message(" You enable leg actuators overload.") return @@ -43,19 +43,12 @@ if(health < initial(health) - initial(health)/3) overload = 0 step_in = initial(step_in) - src.occupant << "\red Leg actuators damage threshold exceded. Disabling overload." + src.occupant_message("Leg actuators damage threshold exceded. Disabling overload.") return /obj/mecha/combat/gygax/get_stats_part() var/output = ..() - output += "Weapon systems:
" - if(weapons.len) - for(var/datum/mecha_weapon/W in weapons) - output += "[selected_weapon==W?"":""][W.get_weapon_info()][selected_weapon==W?"":""]
" - else - output += "None" - output += "
" output += "Leg actuators overload: [overload?"on":"off"]" return output @@ -69,5 +62,4 @@ ..() 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 index 1973baca5cc..42ff07ffeba 100644 --- a/code/game/mecha/combat/marauder.dm +++ b/code/game/mecha/combat/marauder.dm @@ -28,7 +28,7 @@ if(!can_move) return 0 if(connected_port) - src.occupant << "Unable to move while connected to the air system port" + src.occupant_message("Unable to move while connected to the air system port") return 0 if(!thrusters && src.pr_inertial_movement.active()) return 0 @@ -83,13 +83,6 @@ /obj/mecha/combat/marauder/get_stats_part() var/output = ..() - output += "Weapon systems:
" - if(weapons.len) - for(var/datum/mecha_weapon/W in weapons) - output += "[selected_weapon==W?"":""][W.get_weapon_info()][selected_weapon==W?"":""]
" - else - output += "None" - output += "
" output += {"Smoke: [smoke]
Thrusters: [thrusters?"on":"off"] @@ -108,11 +101,6 @@ ..() 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 = weapons[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 index a2090b1d453..b11d9c9284e 100644 --- a/code/game/mecha/combat/weapons/weapons.dm +++ b/code/game/mecha/combat/weapons/weapons.dm @@ -49,14 +49,14 @@ fire(target) if(!fire_checks(target) || missiles <=0) return + weapon_ready = 0 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 - chassis.log_message("Fired from [src.name], targeting [target].",1) + chassis.log_message("Fired from [src.name], targeting [target].") return proc/rearm() @@ -103,9 +103,9 @@ fire(target) if(!fire_checks(target) || missiles <=0) return + weapon_ready = 0 var/obj/item/weapon/flashbang/F = new /obj/item/weapon/flashbang(chassis.loc) F.throw_at(target, missile_range, missile_speed) - weapon_ready = 0 missiles-- spawn(det_time) F.prime() @@ -128,13 +128,12 @@ return if (targloc == curloc) return - + weapon_ready = 0 playsound(chassis, '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() @@ -148,7 +147,6 @@ weapon_cooldown = 50 name = "eZ-13 mk2 Heavy pulse rifle" energy_drain = 60 - var/num_penetrations = 2 fire(target) if(!fire_checks(target)) return @@ -162,7 +160,6 @@ playsound(chassis, 'marauder.ogg', 50, 1) var/obj/beam/a_laser/A = new /obj/beam/a_laser/pulse_laser(curloc) - A.life = num_penetrations A.current = curloc A.yo = targloc.y - curloc.y A.xo = targloc.x - curloc.x @@ -206,7 +203,92 @@ chassis.log_message("Fired from [src.name], targeting [target].") return +/datum/mecha_weapon/missile_rack/banana_mortar + name = "Banana Mortar" + missiles = 15 + missile_speed = 1.5 + missile_energy_cost = 100 + weapon_cooldown = 20 + fire(target) + if(!fire_checks(target) || missiles <=0) return + weapon_ready = 0 + var/obj/item/weapon/bananapeel/B = new /obj/item/weapon/bananapeel(chassis.loc) + playsound(chassis, 'bikehorn.ogg', 60, 1) + B.throw_at(target, missile_range, missile_speed) + missiles-- + spawn(weapon_cooldown) + weapon_ready = 1 + chassis.log_message("Bananed from [src.name], targeting [target]. HONK!") + return + + +/datum/mecha_weapon/missile_rack/mousetrap_mortar + name = "Mousetrap Mortar" + missiles = 15 + missile_speed = 1.5 + missile_energy_cost = 100 + weapon_cooldown = 10 + + fire(target) + if(!fire_checks(target) || missiles <=0) return + weapon_ready = 0 + var/obj/item/weapon/mousetrap/M = new /obj/item/weapon/mousetrap(chassis.loc) + M.armed = 1 + playsound(chassis, 'bikehorn.ogg', 60, 1) + M.throw_at(target, missile_range, missile_speed) + missiles-- + spawn(weapon_cooldown) + weapon_ready = 1 + chassis.log_message("Launched a mouse-trap from [src.name], targeting [target]. HONK!") + return + + +/datum/mecha_weapon/honker + weapon_cooldown = 10 + name = "HoNkER BlAsT 5000" + energy_drain = 200 + weapon_cooldown = 150 + + fire(target) + if(!chassis) + return 0 + if(energy_drain && chassis.cell.charge < energy_drain) + return 0 + if(!weapon_ready) + return 0 + weapon_ready = 0 + playsound(chassis, 'AirHorn.ogg', 100, 1) + chassis.occupant_message("HONK") + for(var/mob/living/carbon/M in orange(10, chassis)) + M << "HONK" + M.sleeping = 0 + if(M.stuttering) + M.stuttering = 1 + M.stuttering += 10 + M.ear_deaf += 60 + M.weakened = 3 + if(prob(70)) + M.stunned = 10 + M.paralysis += 4 + else + M.make_jittery(10) + /* //else the mousetraps are useless + if(istype(M, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + if(isobj(H.shoes)) + var/thingy = H.shoes + H.drop_from_slot(H.shoes) + walk_away(thingy,chassis,15,2) + spawn(20) + if(thingy) + walk(thingy,0) + */ + chassis.cell.use(energy_drain) + spawn(weapon_cooldown) + weapon_ready = 1 + chassis.log_message("Honked from [src.name]. HONK!") + return /* diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm new file mode 100644 index 00000000000..448ee099741 --- /dev/null +++ b/code/game/mecha/mech_bay.dm @@ -0,0 +1,214 @@ +/turf/simulated/floor/mech_bay_recharge_floor + name = "Mech Bay Recharge Station" + icon = 'mech_bay.dmi' + icon_state = "recharge_floor" + var/obj/machinery/mech_bay_recharge_port/recharge_port + var/obj/machinery/computer/mech_bay_power_console/recharge_console + var/obj/mecha/recharging_mecha = null + + Entered(atom as obj) + . = ..() + if(istype(atom, /obj/mecha)) + var/obj/mecha/mecha = atom + mecha.occupant_message("Initializing power control devices.") + init_devices() + if(recharge_console && recharge_port) + recharging_mecha = mecha + recharge_console.mecha_in(mecha) + return + else if(!recharge_console) + mecha.occupant_message("Control console not found. Terminating.") + else if(!recharge_port) + mecha.occupant_message("Power port not found. Terminating.") + return + + Exited(atom as obj) + . = ..() + if(atom == recharging_mecha) + recharging_mecha = null + if(recharge_console) + recharge_console.mecha_out() + return + + proc/init_devices() + recharge_console = locate() in range(1,src) + recharge_port = locate(/obj/machinery/mech_bay_recharge_port, get_step(src, WEST)) + if(recharge_console) + recharge_console.recharge_floor = src + if(recharge_port) + recharge_console.recharge_port = recharge_port + if(recharge_port) + recharge_port.recharge_floor = src + if(recharge_console) + recharge_port.recharge_console = recharge_console + return + + + + +/obj/machinery/mech_bay_recharge_port + name = "Mech Bay Power Port" + density = 1 + anchored = 1 + icon = 'mech_bay.dmi' + icon_state = "recharge_port" + var/turf/simulated/floor/mech_bay_recharge_floor/recharge_floor + var/obj/machinery/computer/mech_bay_power_console/recharge_console + var/datum/global_iterator/mech_bay_recharger/pr_recharger + + New() + ..() + pr_recharger = new /datum/global_iterator/mech_bay_recharger(null,0) + return + + proc/start_charge(var/obj/mecha/recharging_mecha) + if(stat&(NOPOWER|BROKEN)) + recharging_mecha.occupant_message("Power port not responding. Terminating.") + return 0 + else + if(recharging_mecha.cell) + recharging_mecha.occupant_message("Now charging...") + pr_recharger.start(list(src,recharging_mecha)) + return 1 + else + return 0 + + proc/stop_charge() + if(recharge_console && !recharge_console.stat) + recharge_console.icon_state = initial(recharge_console.icon_state) + pr_recharger.stop() + return + + proc/active() + if(pr_recharger.active()) + return 1 + else + return 0 + + power_change() + if(powered()) + stat &= ~NOPOWER + else + spawn(rand(0, 15)) + stat |= NOPOWER + pr_recharger.stop() + return + + proc/set_voltage(new_voltage) + if(new_voltage && isnum(new_voltage)) + pr_recharger.max_charge = new_voltage + return 1 + else + return 0 + + +/datum/global_iterator/mech_bay_recharger + delay = 20 + var/max_charge = 30 + + process(var/obj/machinery/mech_bay_recharge_port/port, var/obj/mecha/mecha) + if(mecha in port.recharge_floor) + var/delta = min(max_charge, mecha.cell.maxcharge - mecha.cell.charge) + if(delta>0) + mecha.cell.charge += delta + port.use_power(delta*150) + else + mecha.occupant_message("Fully charged.") + port.stop_charge() + else + port.stop_charge() + return + + + + +/obj/machinery/computer/mech_bay_power_console + name = "Mech Bay Power Control Console" + density = 1 + anchored = 1 + icon = 'mech_bay.dmi' + icon_state = "recharge_comp" + var/autostart = 1 + var/voltage = 30 + var/turf/simulated/floor/mech_bay_recharge_floor/recharge_floor + var/obj/machinery/mech_bay_recharge_port/recharge_port + + proc/mecha_in(var/obj/mecha/mecha) + if(stat&(NOPOWER|BROKEN)) + mecha.occupant_message("Control console not responding. Terminating...") + return + if(recharge_port && autostart) + var/answer = recharge_port.start_charge(mecha) + if(answer) + recharge_port.set_voltage(voltage) + src.icon_state = initial(src.icon_state)+"_on" + return + + proc/mecha_out() + if(recharge_port) + recharge_port.stop_charge() + return + + + power_change() + if(stat & BROKEN) + icon_state = initial(icon_state)+"_broken" + if(recharge_port) + recharge_port.stop_charge() + else if(powered()) + icon_state = initial(icon_state) + stat &= ~NOPOWER + else + spawn(rand(0, 15)) + icon_state = initial(icon_state)+"_nopower" + stat |= NOPOWER + if(recharge_port) + recharge_port.stop_charge() + + set_broken() + icon_state = initial(icon_state)+"_broken" + stat |= BROKEN + if(recharge_port) + recharge_port.stop_charge() + + + attack_hand(mob/user as mob) + if(..()) return + var/output = "[src.name]" + if(!recharge_floor) + output += "Mech Bay Recharge Station not initialized.
" + else + output += {"Mech Bay Recharge Station Data:
+ Mecha: [recharge_floor.recharging_mecha||"None"]
"} + if(recharge_floor.recharging_mecha) + output += "Cell charge: [recharge_floor.recharging_mecha.cell?"[recharge_floor.recharging_mecha.cell.charge]/[recharge_floor.recharging_mecha.cell.maxcharge]":"No powercell found"]
" + output += "
" + if(!recharge_port) + output += "Mech Bay Power Port not initialized.
" + else + output += "Mech Bay Power Port Status: [recharge_port.active()?"Now charging":"On hold"]
" + + /* + output += {"
+ Settings: +
+ Start sequence on succesful init: [autostart?"On":"Off"]
+ Recharge Port Voltage: Low - Medium - High
+
"} + */ + + output += "" + user << browse(output, "window=mech_bay_console") + onclose(user, "mech_bay_console") + return + + + Topic(href, href_list) + if(href_list["autostart"]) + autostart = !autostart + if(href_list["voltage"]) + voltage = text2num(href_list["voltage"]) + if(recharge_port) + recharge_port.set_voltage(voltage) + updateUsrDialog() + return \ No newline at end of file diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 451cfd29c35..9e71f18aecf 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -39,7 +39,6 @@ var/internal_damage_threshold = 50 //health percentage below which internal damage is possible var/internal_damage = 0 //contains bitflags - var/list/operation_req_access = list(access_engine)//required access level for mecha operation var/list/internals_req_access = list(access_engine)//required access level to open cell compartment @@ -77,15 +76,24 @@ ..() return +///client/var/mech_click + /client/Click(object,location,control,params) ..() var/mob/M = src.mob if(M && istype(M.loc, /obj/mecha)) +/* + if(mech_click == world.time) return + mech_click = world.time +*/ if(!location) return if(M.stat>0) return if(!istype(object,/atom)) return var/obj/mecha/Mech = M.loc - Mech.click_action(object) +// sleep(-1) + spawn() + Mech.click_action(object) + /obj/mecha/proc/click_action(atom/target) @@ -176,13 +184,17 @@ /obj/mecha/Bump(var/atom/obstacle) // src.inertia_dir = null - if(src.occupant) + if(istype(obstacle, /obj)) + var/obj/O = obstacle if(istype(obstacle , /obj/machinery/door)) - var/obj/machinery/door/D = obstacle - D.Bumped(src.occupant) - return + if(src.occupant) + O.Bumped(src.occupant) + else if(!O.anchored) + step(obstacle,src.dir) // else // obstacle.Bumped(src) + else if(istype(obstacle, /mob)) + step(obstacle,src.dir) return @@ -424,6 +436,7 @@ //////// Verbs //////// ///////////////////////// + /obj/mecha/verb/connect_to_port() set name = "Connect to port" set category = "Exosuit Interface" @@ -678,7 +691,7 @@ return if (src.internal_damage & MECHA_INT_TANK_BREACH) src.internal_damage &= ~MECHA_INT_TANK_BREACH - user << "\blue You seal the breached gas tank." + user << "\blue You repair the damaged gas tank." W:use_fuel(1) if(src.health - [src.name] data + [src.name] data [src.get_stats_part()]
@@ -722,7 +735,7 @@ [internal_damage&MECHA_INT_CONTROL_LOST?"COORDINATION SYSTEM CALIBRATION FAILURE - Recalibrate
":null] Integrity: [health/initial(health)*100]%
Powercell charge: [cell.charge/cell.maxcharge*100]%
- Airtank pressure: [src.return_pressure()]
+ Airtank pressure: [src.return_pressure()]kPa
Internal temperature: [src.air_contents.temperature]°K|[src.air_contents.temperature - T0C]°C
Lights: [lights?"on":"off"]
"} diff --git a/code/game/mecha/working/tools/tools.dm b/code/game/mecha/working/tools/tools.dm index aec1c1c5a00..84620387c84 100644 --- a/code/game/mecha/working/tools/tools.dm +++ b/code/game/mecha/working/tools/tools.dm @@ -123,7 +123,7 @@ if(chassis) if(T == chassis.loc && src == chassis.selected_tool) if(istype(target, /turf/simulated/wall/r_wall)) - chassis.occupant_message("\red The [target] is too durable to drill through.") + chassis.occupant_message("[target] is too durable to drill through.") else chassis.log_message("Drilled through [target]") target.ex_act(2) diff --git a/icons/misc/mech_bay.dmi b/icons/misc/mech_bay.dmi new file mode 100644 index 00000000000..f8fa7ab8f93 Binary files /dev/null and b/icons/misc/mech_bay.dmi differ diff --git a/icons/mob/mecha.dmi b/icons/mob/mecha.dmi index 949c1de5adc..bafa742ea60 100644 Binary files a/icons/mob/mecha.dmi and b/icons/mob/mecha.dmi differ diff --git a/sound/items/AirHorn.ogg b/sound/items/AirHorn.ogg new file mode 100644 index 00000000000..f7068fd1bf1 Binary files /dev/null and b/sound/items/AirHorn.ogg differ diff --git a/tgstation.dme b/tgstation.dme index be0b2939b2f..20b457ddec1 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -428,9 +428,11 @@ #include "code\game\magic\cultist\rune9.dm" #include "code\game\magic\cultist\specialtalisman.dm" #include "code\game\mecha\global_iterator.dm" +#include "code\game\mecha\mech_bay.dm" #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\honker.dm" #include "code\game\mecha\combat\marauder.dm" #include "code\game\mecha\combat\weapons\weapons.dm" #include "code\game\mecha\working\ripley.dm"