Combat Mechs Can Punch More Things (#6303)

* Combat Mechs Can Punch More Things

Removes the var to check for the 5 things it can attack, instead it can punch anything (but not everything will take damage).

Gives punching objects a check so you don't accidently smash something without meaning to.

Gives closets and canisters a proc to take_damage so they'll actually get smashed by the mechs.

* Take_Damage Boogaloo

* More take_damage Stuff

Adds click delay on attacking barriers.
Proper noises when attacking material doors and barricades.

More stuff can be broken by mech punch and simple mobs.

* Adds changelong

* usr to user
This commit is contained in:
Andrew
2019-07-24 15:58:39 -05:00
committed by VirgoBot
parent 4c71587410
commit e4deaa6478
27 changed files with 267 additions and 116 deletions

View File

@@ -2,6 +2,9 @@
/atom/proc/attack_generic(mob/user as mob)
return 0
/atom/proc/take_damage(var/damage)
return 0
/*
Humans:
Adds an exception for gloves, to allow special glove types like the ninja ones.

View File

@@ -35,6 +35,22 @@
/obj/structure/cult/pylon/attackby(obj/item/W as obj, mob/user as mob)
attackpylon(user, W.force)
/obj/structure/cult/pylon/take_damage(var/damage)
pylonhit(damage)
/obj/structure/cult/pylon/bullet_act(var/obj/item/projectile/Proj)
pylonhit(Proj.get_structure_damage())
/obj/structure/cult/pylon/proc/pylonhit(var/damage)
if(!isbroken)
if(prob(1+ damage * 5))
visible_message("<span class='danger'>The pylon shatters!</span>")
playsound(get_turf(src), 'sound/effects/Glassbr3.ogg', 75, 1)
isbroken = 1
density = 0
icon_state = "pylon-broken"
set_light(0)
/obj/structure/cult/pylon/proc/attackpylon(mob/user as mob, var/damage)
if(!isbroken)
if(prob(1+ damage * 5))

View File

@@ -449,3 +449,7 @@ update_flag
src.air_contents.adjust_gas("phoron", MolesForPressure())
src.update_icon()
return 1
/obj/machinery/portable_atmospherics/canister/take_damage(var/damage)
src.health -= damage
healthcheck()

View File

@@ -283,7 +283,7 @@
icon_state = initial(icon_state)
add_hiddenprint(user)
/obj/machinery/camera/proc/take_damage(var/force, var/message)
/obj/machinery/camera/take_damage(var/force, var/message)
//prob(25) gives an average of 3-4 hits
if (force >= toughness && (force > toughness*4 || prob(25)))
destroy()

View File

@@ -2,52 +2,6 @@
CONTAINS:
Deployable items
Barricades
for reference:
access_security = 1
access_brig = 2
access_armory = 3
access_forensics_lockers= 4
access_medical = 5
access_morgue = 6
access_tox = 7
access_tox_storage = 8
access_genetics = 9
access_engine = 10
access_engine_equip= 11
access_maint_tunnels = 12
access_external_airlocks = 13
access_emergency_storage = 14
access_change_ids = 15
access_ai_upload = 16
access_teleporter = 17
access_eva = 18
access_heads = 19
access_captain = 20
access_all_personal_lockers = 21
access_chapel_office = 22
access_tech_storage = 23
access_atmospherics = 24
access_bar = 25
access_janitor = 26
access_crematorium = 27
access_kitchen = 28
access_robotics = 29
access_rd = 30
access_cargo = 31
access_construction = 32
access_chemistry = 33
access_cargo_bot = 34
access_hydroponics = 35
access_manufacturing = 36
access_library = 37
access_lawyer = 38
access_virology = 39
access_cmo = 40
access_qm = 41
access_court = 42
access_clown = 43
access_mime = 44
*/
//Barricades!
@@ -80,6 +34,7 @@ for reference:
return material
/obj/structure/barricade/attackby(obj/item/W as obj, mob/user as mob)
user.setClickCooldown(user.get_attack_speed(W))
if(istype(W, /obj/item/stack))
var/obj/item/stack/D = W
if(D.get_material_name() != material.name)
@@ -96,37 +51,54 @@ for reference:
return
return
else
user.setClickCooldown(user.get_attack_speed(W))
switch(W.damtype)
if("fire")
health -= W.force * 1
if("brute")
health -= W.force * 0.75
else
if(health <= 0)
visible_message("<span class='danger'>The barricade is smashed apart!</span>")
dismantle()
qdel(src)
return
if(material == (get_material_by_name(MAT_WOOD) || get_material_by_name(MAT_SIFWOOD)))
playsound(loc, 'sound/effects/woodcutting.ogg', 100, 1)
else
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
CheckHealth()
..()
/obj/structure/barricade/proc/CheckHealth()
if(health <= 0)
dismantle()
return
/obj/structure/barricade/take_damage(var/damage)
health -= damage
CheckHealth()
return
/obj/structure/barricade/attack_generic(var/mob/user, var/damage, var/attack_verb)
visible_message("<span class='danger'>[user] [attack_verb] the [src]!</span>")
if(material == get_material_by_name("resin"))
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
else if(material == (get_material_by_name(MAT_WOOD) || get_material_by_name(MAT_SIFWOOD)))
playsound(loc, 'sound/effects/woodcutting.ogg', 100, 1)
else
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
user.do_attack_animation(src)
health -= damage
CheckHealth()
return
/obj/structure/barricade/proc/dismantle()
material.place_dismantled_product(get_turf(src))
visible_message("<span class='danger'>\The [src] falls apart!</span>")
qdel(src)
return
/obj/structure/barricade/ex_act(severity)
switch(severity)
if(1.0)
visible_message("<span class='danger'>\The [src] is blown apart!</span>")
qdel(src)
return
dismantle()
if(2.0)
health -= 25
if(health <= 0)
visible_message("<span class='danger'>\The [src] is blown apart!</span>")
dismantle()
return
CheckHealth()
/obj/structure/barricade/CanPass(atom/movable/mover, turf/target)//So bullets will fly over and stuff.
if(istype(mover) && mover.checkpass(PASSTABLE))
@@ -158,6 +130,7 @@ for reference:
icon_state = "barrier[locked]"
/obj/machinery/deployable/barrier/attackby(obj/item/weapon/W as obj, mob/user as mob)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(istype(W, /obj/item/weapon/card/id/))
if(allowed(user))
if (emagged < 2.0)
@@ -196,11 +169,28 @@ for reference:
health -= W.force * 0.75
if("brute")
health -= W.force * 0.5
else
if(health <= 0)
explode()
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
CheckHealth()
..()
/obj/machinery/deployable/barrier/proc/CheckHealth()
if(health <= 0)
explode()
return
/obj/machinery/deployable/barrier/attack_generic(var/mob/user, var/damage, var/attack_verb)
visible_message("<span class='danger'>[user] [attack_verb] the [src]!</span>")
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
user.do_attack_animation(src)
health -= damage
CheckHealth()
return
/obj/machinery/deployable/barrier/take_damage(var/damage)
health -= damage
CheckHealth()
return
/obj/machinery/deployable/barrier/ex_act(severity)
switch(severity)
if(1.0)
@@ -208,8 +198,7 @@ for reference:
return
if(2.0)
health -= 25
if(health <= 0)
explode()
CheckHealth()
return
/obj/machinery/deployable/barrier/emp_act(severity)

View File

@@ -308,7 +308,7 @@
operating = -1
return 1
/obj/machinery/door/proc/take_damage(var/damage)
/obj/machinery/door/take_damage(var/damage)
var/initialhealth = src.health
src.health = max(0, src.health - damage)
if(src.health <= 0 && initialhealth > 0)

View File

@@ -548,7 +548,7 @@
enabled = 1 //turns it back on. The cover popUp() popDown() are automatically called in process(), no need to define it here
return 1
/obj/machinery/porta_turret/proc/take_damage(var/force)
/obj/machinery/porta_turret/take_damage(var/force)
if(!raised && !raising)
force = force / 8
if(force < 5)

View File

@@ -2,7 +2,7 @@
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, /obj/structure/girder)
//var/list/destroyable_obj = list(/obj/mecha, /obj/structure/window, /obj/structure/grille, /turf/simulated/wall, /obj/structure/girder)
internal_damage_threshold = 50
maint_access = 0
//add_req_access = 0
@@ -26,14 +26,15 @@
return
*/
/obj/mecha/combat/melee_action(target as obj|mob|turf)
/obj/mecha/combat/melee_action(atom/T)
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
T = safepick(oview(1,src))
if(!melee_can_hit)
return
if(istype(T, /mob/living))
var/mob/living/M = T
if(src.occupant.a_intent == I_HURT || istype(src.occupant, /mob/living/carbon/brain)) //Brains cannot change intents; Exo-piloting brains lack any form of physical feedback for control, limiting the ability to 'play nice'.
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
playsound(src, 'sound/weapons/heavysmash.ogg', 50, 1)
if(damtype == "brute")
step_away(M,src,15)
/*
@@ -44,8 +45,8 @@
melee_can_hit = 1
return
*/
if(istype(target, /mob/living/carbon/human))
var/mob/living/carbon/human/H = target
if(ishuman(T))
var/mob/living/carbon/human/H = T
// if (M.health <= 0) return
var/obj/item/organ/external/temp = H.get_organ(pick(BP_TORSO, BP_TORSO, BP_TORSO, BP_HEAD))
@@ -86,12 +87,12 @@
else
return
M.updatehealth()
src.occupant_message("You hit [target].")
src.visible_message("<font color='red'><b>[src.name] hits [target].</b></font>")
src.occupant_message("You hit [T].")
src.visible_message("<font color='red'><b>[src.name] hits [T].</b></font>")
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.")
src.occupant_message("You push [T] out of the way.")
src.visible_message("[src] pushes [T] out of the way.")
melee_can_hit = 0
if(do_after(melee_cooldown))
@@ -99,27 +100,23 @@
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("<font color='red'><b>[src.name] hits [target]</b></font>")
if(!istype(target, /turf/simulated/wall) && !istype(target, /obj/structure/girder))
target:attackby(src,src.occupant)
else if(prob(5))
target:dismantle_wall(1)
src.occupant_message("<span class='notice'>You smash through the wall.</span>")
src.visible_message("<b>[src.name] smashes through the wall</b>")
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
else if(istype(target, /turf/simulated/wall))
target:take_damage(force)
else if(istype(target, /obj/structure/girder))
target:take_damage(force * 3) //Girders have 200 health by default. Steel, non-reinforced walls take four punches, girders take (with this value-mod) two, girders took five without.
melee_can_hit = 0
if(istype(T, /obj/machinery/disposal)) // Stops mechs from climbing into disposals
return
if(src.occupant.a_intent == I_HURT || istype(src.occupant, /mob/living/carbon/brain)) // Don't smash unless we mean it
if(damtype == "brute")
src.occupant_message("You hit [T].")
src.visible_message("<font color='red'><b>[src.name] hits [T]</b></font>")
playsound(src, 'sound/weapons/heavysmash.ogg', 50, 1)
if(do_after(melee_cooldown))
melee_can_hit = 1
break
if(istype(T, /obj/structure/girder))
T:take_damage(force * 3) //Girders have 200 health by default. Steel, non-reinforced walls take four punches, girders take (with this value-mod) two, girders took five without.
else
T:take_damage(force)
melee_can_hit = 0
if(do_after(melee_cooldown))
melee_can_hit = 1
return
/*

View File

@@ -535,7 +535,7 @@
//////// Health related procs ////////
////////////////////////////////////////
/obj/mecha/proc/take_damage(amount, type="brute")
/obj/mecha/take_damage(amount, type="brute")
if(amount)
var/damage = absorbDamage(amount,type)
health -= damage

View File

@@ -64,6 +64,19 @@
healthcheck()
return
/obj/effect/alien/resin/attack_generic(var/mob/user, var/damage, var/attack_verb)
visible_message("<span class='danger'>[user] [attack_verb] the [src]!</span>")
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
user.do_attack_animation(src)
health -= damage
healthcheck()
return
/obj/effect/alien/resin/take_damage(var/damage)
health -= damage
healthcheck()
return
/obj/effect/alien/resin/ex_act(severity)
switch(severity)
if(1.0)
@@ -246,6 +259,18 @@ Alien plants should do something if theres a lot of poison
health -= damage
healthcheck()
/obj/effect/alien/weeds/attack_generic(var/mob/user, var/damage, var/attack_verb)
visible_message("<span class='danger'>[user] [attack_verb] the [src]!</span>")
user.do_attack_animation(src)
health -= damage
healthcheck()
return
/obj/effect/alien/weeds/take_damage(var/damage)
health -= damage
healthcheck()
return
/obj/effect/alien/weeds/proc/healthcheck()
if(health <= 0)
qdel(src)
@@ -401,6 +426,18 @@ Alien plants should do something if theres a lot of poison
healthcheck()
return
/obj/effect/alien/egg/attack_generic(var/mob/user, var/damage, var/attack_verb)
visible_message("<span class='danger'>[user] [attack_verb] the [src]!</span>")
user.do_attack_animation(src)
health -= damage
healthcheck()
return
/obj/effect/alien/egg/take_damage(var/damage)
health -= damage
healthcheck()
return
/obj/effect/alien/egg/attackby(var/obj/item/weapon/W, var/mob/user)
if(health <= 0)

View File

@@ -98,7 +98,7 @@
return 0
return 1
/obj/structure/catwalk/proc/take_damage(amount)
/obj/structure/catwalk/take_damage(amount)
health -= amount
if(health <= 0)
visible_message("<span class='warning'>\The [src] breaks down!</span>")

View File

@@ -468,3 +468,10 @@
if(istype(src.loc, /obj/structure/closet))
return (loc.return_air_for_internal_lifeform(L))
return return_air()
/obj/structure/closet/take_damage(var/damage)
if(damage < STRUCTURE_MIN_DAMAGE_THRESHOLD)
return
dump_contents()
spawn(1) qdel(src)
return 1

View File

@@ -212,7 +212,7 @@
else
return ..()
/obj/structure/girder/proc/take_damage(var/damage)
/obj/structure/girder/take_damage(var/damage)
health -= damage
if(health <= 0)
dismantle()

View File

@@ -281,3 +281,8 @@
return TRUE
return FALSE
/obj/structure/grille/take_damage(var/damage)
health -= damage
spawn(1) healthcheck()
return 1

View File

@@ -137,6 +137,13 @@
user.visible_message("<span class='danger'>[user] [attack_verb] at [src]!</span>")
return 1
/obj/structure/inflatable/take_damage(var/damage)
health -= damage
if(health <= 0)
visible_message("<span class='danger'>The [src] deflates!</span>")
spawn(1) puncture()
return 1
/obj/item/inflatable/door/
name = "inflatable door"
desc = "A folded membrane which rapidly expands into a simple door on activation."

View File

@@ -52,7 +52,7 @@
if(0.5 to 1.0)
to_chat(user, "<span class='notice'>It has a few scrapes and dents.</span>")
/obj/structure/railing/proc/take_damage(amount)
/obj/structure/railing/take_damage(amount)
health -= amount
if(health <= 0)
visible_message("<span class='warning'>\The [src] breaks down!</span>")

View File

@@ -124,15 +124,22 @@
icon_state = material.door_icon_base
/obj/structure/simple_door/attackby(obj/item/weapon/W as obj, mob/user as mob)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(istype(W,/obj/item/weapon/pickaxe))
var/obj/item/weapon/pickaxe/digTool = W
user << "You start digging the [name]."
visible_message("<span class='danger'>[user] starts digging [src]!</span>")
if(do_after(user,digTool.digspeed*hardness) && src)
user << "You finished digging."
visible_message("<span class='danger'>[user] finished digging [src]!</span>")
Dismantle()
else if(istype(W,/obj/item/weapon)) //not sure, can't not just weapons get passed to this proc?
hardness -= W.force/10
user << "You hit the [name] with your [W.name]!"
visible_message("<span class='danger'>[user] hits [src] with [W]!</span>")
if(material == get_material_by_name("resin"))
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
else if(material == (get_material_by_name(MAT_WOOD) || get_material_by_name(MAT_SIFWOOD)))
playsound(loc, 'sound/effects/woodcutting.ogg', 100, 1)
else
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
CheckHardness()
else if(istype(W,/obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
@@ -146,12 +153,29 @@
hardness -= Proj.force/10
CheckHardness()
/obj/structure/simple_door/take_damage(var/damage)
hardness -= damage/10
CheckHardness()
/obj/structure/simple_door/attack_generic(var/mob/user, var/damage, var/attack_verb)
visible_message("<span class='danger'>[user] [attack_verb] the [src]!</span>")
if(material == get_material_by_name("resin"))
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
else if(material == (get_material_by_name(MAT_WOOD) || get_material_by_name(MAT_SIFWOOD)))
playsound(loc, 'sound/effects/woodcutting.ogg', 100, 1)
else
playsound(src, 'sound/weapons/smash.ogg', 50, 1)
user.do_attack_animation(src)
hardness -= damage/10
CheckHardness()
/obj/structure/simple_door/proc/CheckHardness()
if(hardness <= 0)
Dismantle(1)
/obj/structure/simple_door/proc/Dismantle(devastated = 0)
material.place_dismantled_product(get_turf(src))
visible_message("<span class='danger'>The [src] is destroyed!</span>")
qdel(src)
/obj/structure/simple_door/ex_act(severity = 1)

View File

@@ -47,7 +47,7 @@
else
to_chat(user, "<span class='notice'>There is a thick layer of silicate covering it.</span>")
/obj/structure/window/proc/take_damage(var/damage = 0, var/sound_effect = 1)
/obj/structure/window/take_damage(var/damage = 0, var/sound_effect = 1)
var/initialhealth = health
if(silicate)

View File

@@ -153,7 +153,7 @@
visible_message("<span class='danger'>\The [src] spontaneously combusts!.</span>") //!!OH SHIT!!
return
/turf/simulated/wall/proc/take_damage(dam)
/turf/simulated/wall/take_damage(dam)
if(dam)
damage = max(0, damage + dam)
update_damage()

View File

@@ -16,7 +16,7 @@
H.take_damage(rand(10,30))
qdel()
/obj/item/modular_computer/proc/take_damage(var/amount, var/component_probability, var/damage_casing = 1, var/randomize = 1)
/obj/item/modular_computer/take_damage(var/amount, var/component_probability, var/damage_casing = 1, var/randomize = 1)
if(randomize)
// 75%-125%, rand() works with integers, apparently.
amount *= (rand(75, 125) / 100.0)

View File

@@ -81,7 +81,7 @@
to_chat(user, "It seems to be slightly damaged.")
// Damages the component. Contains necessary checks. Negative damage "heals" the component.
/obj/item/weapon/computer_hardware/proc/take_damage(var/amount)
/obj/item/weapon/computer_hardware/take_damage(var/amount)
damage += round(amount) // We want nice rounded numbers here.
damage = between(0, damage, max_damage) // Clamp the value.

View File

@@ -292,7 +292,7 @@ var/list/organ_cache = list()
W.time_inflicted = world.time
//Note: external organs have their own version of this proc
/obj/item/organ/proc/take_damage(amount, var/silent=0)
/obj/item/organ/take_damage(amount, var/silent=0)
if(src.robotic >= ORGAN_ROBOT)
src.damage = between(0, src.damage + (amount * 0.8), max_damage)
else

View File

@@ -389,6 +389,16 @@ var/global/list/light_type_cache = list()
broken()
return 1
/obj/machinery/light/take_damage(var/damage)
if(!damage)
return
if(status == LIGHT_EMPTY||status == LIGHT_BROKEN)
return
if(!(status == LIGHT_OK||status == LIGHT_BURNED))
return
broken()
return 1
/obj/machinery/light/blob_act()
broken()

View File

@@ -60,6 +60,9 @@
user.do_attack_animation(src)
user.setClickCooldown(user.get_attack_speed())
/obj/effect/energy_field/take_damage(var/damage)
adjust_strength(-damage / 20)
/obj/effect/energy_field/attack_hand(var/mob/living/user)
impact_effect(3) // Harmless, but still produces the 'impact' effect.
..()

View File

@@ -44,7 +44,7 @@ var/list/table_icon_cache = list()
health += maxhealth - old_maxhealth
/obj/structure/table/proc/take_damage(amount)
/obj/structure/table/take_damage(amount)
// If the table is made of a brittle material, and is *not* reinforced with a non-brittle material, damage is multiplied by TABLE_BRITTLE_MATERIAL_MULTIPLIER
if(material && material.is_brittle())
if(reinforced)

View File

@@ -424,3 +424,12 @@
new /obj/effect/decal/cleanable/blood/oil(src.loc)
spawn(1) healthcheck()
return 1
/obj/vehicle/take_damage(var/damage)
if(!damage)
return
src.health -= damage
if(mechanical && prob(10))
new /obj/effect/decal/cleanable/blood/oil(src.loc)
spawn(1) healthcheck()
return 1

View File

@@ -0,0 +1,40 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# maptweak
# spellcheck (typo fixes)
# experiment
#################################
# Your name.
author: Nalarac
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- tweak: "Combat mechs can punch more things. Mech punch sounds like juggernaut now"
- tweak: "Simple mobs can attack more things."
- bugfix: "Cult pylons take damage from bullets."
- bugfix: "Click delay added on attacking simple doors and security barricades."
- tweak: "Material doors and barricades have different attacked sounds depending if its metal, wood, or resin."