diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index b46f14be572..de8a39ffd31 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -177,6 +177,15 @@ /obj/machinery/door/window/attack_ghost(mob/user as mob) return + +/obj/machinery/door/window/mech_melee_attack(obj/mecha/M) + if(M.damtype == "brute") + playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1) + M.occupant_message("You hit [src].") + visible_message("[src] has been hit by [M.name].") + take_damage(M.force) + return + /obj/machinery/door/window/attack_ai(mob/user as mob) return src.attack_hand(user) diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm index e9be41ae473..d9b26404cad 100644 --- a/code/game/mecha/combat/combat.dm +++ b/code/game/mecha/combat/combat.dm @@ -1,8 +1,5 @@ /obj/mecha/combat force = 30 - var/melee_cooldown = 10 - var/melee_can_hit = 1 - var/list/destroyable_obj = list(/obj/mecha, /obj/structure/window, /obj/structure/grille, /turf/simulated/wall) var/maxsize = 2 internal_damage_threshold = 50 maint_access = 0 @@ -11,232 +8,6 @@ damage_absorption = list("brute"=0.7,"fire"=1,"bullet"=0.7,"laser"=0.85,"energy"=1,"bomb"=0.8) var/am = "d3c2fbcadca903a41161ccc9df9cf948" -/* -/obj/mecha/combat/range_action(target as obj|mob|turf) - if(internal_damage&MECHA_INT_CONTROL_LOST) - target = pick(view(3,target)) - if(selected_weapon) - selected_weapon.fire(target) - return -*/ - -/obj/mecha/combat/melee_action(target as obj|mob|turf) - if(internal_damage&MECHA_INT_CONTROL_LOST) - target = safepick(oview(1,src)) - if(!melee_can_hit || !istype(target, /atom)) return - if(istype(target, /mob/living)) - var/mob/living/M = target - if(src.occupant.a_intent == "harm" && !istype(src,/obj/mecha/combat/gygax)) - playsound(src, 'sound/weapons/punch4.ogg', 50, 1) - if(damtype == "brute") - step_away(M,src,15) - /* - if(M.stat>1) - M.gib() - melee_can_hit = 0 - if(do_after(melee_cooldown)) - melee_can_hit = 1 - return - */ - if(istype(target, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = target - // if (M.health <= 0) return - - var/datum/organ/external/temp = H.get_organ(pick("chest", "chest", "chest", "head")) - if(temp) - var/update = 0 - switch(damtype) - if("brute") - H.Paralyse(1) - update |= temp.take_damage(rand(force/2, force), 0) - if("fire") - update |= temp.take_damage(0, rand(force/2, force)) - if("tox") - if(H.reagents) - if(H.reagents.get_reagent_amount("carpotoxin") + force < force*2) - H.reagents.add_reagent("carpotoxin", force) - if(H.reagents.get_reagent_amount("cryptobiolin") + force < force*2) - H.reagents.add_reagent("cryptobiolin", force) - else - return - if(update) H.UpdateDamageIcon() - H.updatehealth() - - else - switch(damtype) - if("brute") - M.Paralyse(1) - M.take_overall_damage(rand(force/2, force)) - if("fire") - M.take_overall_damage(0, rand(force/2, force)) - if("tox") - if(M.reagents) - if(M.reagents.get_reagent_amount("carpotoxin") + force < force*2) - M.reagents.add_reagent("carpotoxin", force) - if(M.reagents.get_reagent_amount("cryptobiolin") + force < force*2) - M.reagents.add_reagent("cryptobiolin", force) - else - return - M.updatehealth() - src.occupant_message("You hit [target].") - src.visible_message("[src.name] hits [target].") - else - step_away(M,src) - src.occupant_message("You push [target] out of the way.") - src.visible_message("[src] pushes [target] out of the way.") - - melee_can_hit = 0 - if(do_after(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_message("You hit [target].") - src.visible_message("[src.name] hits [target]") - if(!istype(target, /turf/simulated/wall)) - target:attackby(src,src.occupant) - else if(prob(5)) - target:dismantle_wall(1) - src.occupant_message("\blue You smash through the wall.") - src.visible_message("[src.name] smashes through the wall") - playsound(src, 'sound/weapons/smash.ogg', 50, 1) - melee_can_hit = 0 - if(do_after(melee_cooldown)) - melee_can_hit = 1 - break - return - -/* -/obj/mecha/combat/proc/mega_shake(target) - if(!istype(target, /obj) && !istype(target, /mob)) return - if(istype(target, /mob)) - var/mob/M = target - M.Dizzy(3) - M.adjustBruteLoss(1) - M.updatehealth() - for (var/mob/V in viewers(src)) - V.show_message("[src.name] shakes [M] like a rag doll.") - return -*/ - -/* - if(energy>0 && can_move) - if(step(src,direction)) - can_move = 0 - spawn(step_in) can_move = 1 - if(overload) - energy = energy-2 - health-- - else - energy-- - return 1 - - return 0 -*/ -/* -/obj/mecha/combat/hear_talk(mob/M as mob, text) - ..() - if(am && M==occupant) - if(findtext(text,"")) - sam() - return - -/obj/mecha/combat/proc/sam() - if(am) - var/window = {" - - - - - -
-
- - -
-
- - - "} - occupant << browse(window, "window=sam;size=800x600;") - onclose(occupant, "sam", src) - return -*/ /obj/mecha/combat/moved_inside(var/mob/living/carbon/human/H as mob) if(..()) if(H.client) diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index ab30fab2269..2c723a2e530 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -16,7 +16,6 @@ internal_damage_threshold = 35 max_equip = 3 maxsize = 2 - force = 10 step_energy_drain = 3 /obj/mecha/combat/gygax/loaded/New() diff --git a/code/game/mecha/combat/honker.dm b/code/game/mecha/combat/honker.dm index 9fbc7eb67c4..9f68e36ba7b 100644 --- a/code/game/mecha/combat/honker.dm +++ b/code/game/mecha/combat/honker.dm @@ -26,16 +26,6 @@ ME.attach(src) return - - - -/obj/mecha/combat/honker/melee_action(target) - if(!melee_can_hit) - return - else if(istype(target, /mob)) - step_away(target,src,15) - return - /obj/mecha/combat/honker/get_stats_part() var/integrity = health/initial(health)*100 var/cell_charge = get_charge() diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 57e62d7ef13..6a3f81c461c 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -18,6 +18,7 @@ unacidable = 1 //and no deleting hoomans inside layer = MOB_LAYER //icon draw layer infra_luminosity = 15 //byond implementation is bugged. + force = 5 var/initial_icon = null //Mech type for resetting icon. Only used for reskinning kits (see custom items) var/can_move = 1 var/mob/living/carbon/occupant = null @@ -71,6 +72,8 @@ var/stepsound = 'sound/mecha/mechturn.ogg' + var/melee_cooldown = 10 + var/melee_can_hit = 1 /obj/mecha/New() ..() @@ -226,12 +229,15 @@ /obj/mecha/proc/click_action(atom/target,mob/user) if(!src.occupant || src.occupant != user ) return - if(user.stat) return - if(state) - occupant_message("Maintenance protocols in effect") + if(user.stat || !user.canmove) + return + if(state) + occupant_message("Maintenance protocols in effect.") + return + if(!get_charge()) + return + if(src == target) return - if(!get_charge()) return - if(src == target) return var/dir_to_target = get_dir(src,target) if(dir_to_target && !(dir_to_target & src.dir))//wrong direction return @@ -239,17 +245,46 @@ target = safepick(view(3,target)) if(!target) return - if(get_dist(src, target)>1) + if(!target.Adjacent(src)) if(selected && selected.is_ranged()) selected.action(target) else if(selected && selected.is_melee()) selected.action(target) else - src.melee_action(target) + if(internal_damage&MECHA_INT_CONTROL_LOST) + target = safepick(oview(1,src)) + if(!melee_can_hit || !istype(target, /atom)) + return + target.mech_melee_attack(src) + melee_can_hit = 0 + if(do_after(melee_cooldown)) + melee_can_hit = 1 + return + +/obj/mecha/proc/mech_toxin_damage(mob/living/target) + playsound(src, 'sound/effects/spray2.ogg', 50, 1) + if(target.reagents) + if(target.reagents.get_reagent_amount("cryptobiolin") + force < force*2) + target.reagents.add_reagent("cryptobiolin", force/2) + if(target.reagents.get_reagent_amount("toxin") + force < force*2) + target.reagents.add_reagent("toxin", force/2.5) + + + +/atom/proc/mech_melee_attack(obj/mecha/M) return - -/obj/mecha/proc/melee_action(atom/target) +/obj/mecha/mech_melee_attack(obj/mecha/M) + if(M.damtype =="brute") + playsound(src, 'sound/weapons/punch4.ogg', 50, 1) + else if(M.damtype == "fire") + playsound(src, 'sound/items/Welder.ogg', 50, 1) + else + return + M.occupant_message("You hit [src].") + visible_message("[src] has been hit by [M.name].") + take_damage(M.force, damtype) + add_logs(M.occupant, src, "attacked", object=M, addition="(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") return /obj/mecha/proc/range_action(atom/target) diff --git a/code/game/objects/items/bluespace_crystal.dm b/code/game/objects/items/bluespace_crystal.dm index d2b4c6e961c..a5586cf2dcf 100644 --- a/code/game/objects/items/bluespace_crystal.dm +++ b/code/game/objects/items/bluespace_crystal.dm @@ -5,7 +5,7 @@ icon = 'icons/obj/telescience.dmi' icon_state = "bluespace_crystal" w_class = 1 - origin_tech = "bluespace=3;materials=5" + origin_tech = "bluespace=4;materials=3" var/blink_range = 8 // The teleport range when crushed/thrown at someone. /obj/item/bluespace_crystal/New() diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 1e81e53bdd0..b1df8abe563 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -25,6 +25,13 @@ /obj/structure/Destroy() if(hascall(src, "unbuckle")) src:unbuckle() + +/obj/structure/mech_melee_attack(obj/mecha/M) + if(M.damtype == "brute") + M.occupant_message("You hit [src].") + visible_message("[src] has been hit by [M.name].") + return 1 + return 0 /obj/structure/New() ..() diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 0ad7fb6f7c1..68e7f0e0efb 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -110,7 +110,12 @@ health -= M.melee_damage_upper healthcheck() return - + +/obj/structure/grille/mech_melee_attack(obj/mecha/M) + if(..()) + playsound(loc, 'sound/effects/grillehit.ogg', 80, 1) + health -= M.force * 0.5 + healthcheck() /obj/structure/grille/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) if(air_group || (height==0)) return 1 diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 8786b6ff3e9..5f6eb17013c 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -313,6 +313,11 @@ var/global/wcColored ..() return + +/obj/structure/window/mech_melee_attack(obj/mecha/M) + if(..()) + hit(M.force, 1) + /obj/structure/window/proc/hit(var/damage, var/sound_effect = 1) if(reinf) damage *= 0.5 health = max(0, health - damage) diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index e8dd96e844d..e7006c1d3fe 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -180,6 +180,17 @@ /turf/simulated/wall/blob_act() take_damage(rand(75, 125)) return + +/turf/simulated/wall/mech_melee_attack(obj/mecha/M) + if(M.damtype == "brute") + playsound(src, 'sound/weapons/punch4.ogg', 50, 1) + M.occupant_message("You hit [src].") + visible_message("[src] has been hit by [M.name].") + if(prob(5) && M.force > 20) + dismantle_wall(1) + M.occupant_message("You smash through the wall.") + visible_message("[src.name] smashes through the wall!") + playsound(src, 'sound/effects/meteorimpact.ogg', 100, 1) // Wall-rot effect, a nasty fungus that destroys walls. /turf/simulated/wall/proc/rot() @@ -265,8 +276,8 @@ /turf/simulated/wall/attack_hand(mob/user as mob) if (M_HULK in user.mutations) if (prob(40) || rotting) - usr << text("\blue You smash through the wall.") - usr.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) + user << text("\blue You smash through the wall.") + user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) dismantle_wall(1) return else diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 616a0d2ba1d..f15c9a5ac65 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -460,3 +460,35 @@ emp_act var/penetrated_dam = max(0,(damage - max(0,(SS.breach_threshold - SS.damage)))) if(penetrated_dam) SS.create_breaches(damtype, penetrated_dam) + +/mob/living/carbon/human/mech_melee_attack(obj/mecha/M) + if(M.occupant.a_intent == "harm") + if(M.damtype == "brute") + step_away(src,M,15) + var/datum/organ/external/affecting = get_organ(pick("chest", "chest", "chest", "head")) + if(affecting) + var/update = 0 + switch(M.damtype) + if("brute") + if(M.force > 20) + Paralyse(1) + update |= affecting.take_damage(rand(M.force/2, M.force), 0) + playsound(src, 'sound/weapons/punch4.ogg', 50, 1) + if("fire") + update |= affecting.take_damage(0, rand(M.force/2, M.force)) + playsound(src, 'sound/items/Welder.ogg', 50, 1) + if("tox") + M.mech_toxin_damage(src) + else + return + updatehealth() + + M.occupant_message("You hit [src].") + visible_message("[src] has been hit by [M.name].", \ + "[src] has been hit by [M.name].") + add_logs(M.occupant, src, "attacked", object=M, addition="(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") + + else + ..() + + return diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index bea2aa63f60..4f99dcc0946 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -168,6 +168,35 @@ visible_message("[src] is pinned to the wall by [O]!","You are pinned to the wall by [O]!") src.anchored = 1 src.pinned += O + +/mob/living/mech_melee_attack(obj/mecha/M) + if(M.occupant.a_intent == "harm") + if(M.damtype == "brute") + step_away(src,M,15) + switch(M.damtype) + if("brute") + Paralyse(1) + take_overall_damage(rand(M.force/2, M.force)) + playsound(src, 'sound/weapons/punch4.ogg', 50, 1) + if("fire") + take_overall_damage(0, rand(M.force/2, M.force)) + playsound(src, 'sound/items/Welder.ogg', 50, 1) + if("tox") + M.mech_toxin_damage(src) + else + return + updatehealth() + M.occupant_message("You hit [src].") + visible_message("[src] has been hit by [M.name].", \ + "[src] has been hit by [M.name].") + add_logs(M.occupant, src, "attacked", object=M, addition="(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") + else + step_away(src,M) + add_logs(M.occupant, src, "pushed", object=M, admin=0) + M.occupant_message("You push [src] out of the way.") + visible_message("[M] pushes [src] out of the way.") + + return //This is called when the mob is thrown into a dense turf /mob/living/proc/turf_collision(var/turf/T, var/speed) diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 6dcafe97873..e5098adf6b5 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -2100,7 +2100,7 @@ datum/design/bluespace_crystal name = "Artificial Bluespace Crystal" desc = "A small blue crystal with mystical properties." id = "bluespace_crystal" - req_tech = list("bluespace" = 3, "materials" = 5) + req_tech = list("bluespace" = 4, "materials" = 6) build_type = PROTOLATHE materials = list("$gold" = 1500, "$diamond" = 3000, "$plasma" = 1500) reliability_base = 100