diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 586b2622593..bf5d6352087 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -154,7 +154,6 @@
/mob/proc/DblClickOn(var/atom/A, var/params)
ClickOn(A,params)
-
/*
Translates into attack_hand, etc.
@@ -168,6 +167,22 @@
/mob/proc/UnarmedAttack(var/atom/A, var/proximity_flag)
return
+/mob/living/UnarmedAttack(var/atom/A, var/proximity_flag)
+
+ if(!ticker)
+ src << "You cannot attack people before the game has started."
+ return 0
+
+ if (istype(get_area(src), /area/start))
+ src << "No attacking people at spawn, you jackass."
+ return 0
+
+ if(stat)
+ return
+
+ if(!proximity_flag)
+ return 0
+
/*
Ranged unarmed attack:
diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm
index 2d3f3c45dac..5f4d9fc8dfc 100644
--- a/code/_onclick/other_mobs.dm
+++ b/code/_onclick/other_mobs.dm
@@ -1,3 +1,6 @@
+// Generic damage proc (slimes and monkeys).
+/atom/proc/attack_generic(mob/user as mob)
+ return
/*
Humans:
Adds an exception for gloves, to allow special glove types like the ninja ones.
@@ -5,12 +8,15 @@
Otherwise pretty standard.
*/
/mob/living/carbon/human/UnarmedAttack(var/atom/A, var/proximity)
- var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines
+
+ if(!..())
+ return
// Special glove functions:
// If the gloves do anything, have them return 1 to stop
// normal attack_hand() here.
- if(proximity && istype(G) && G.Touch(A,1))
+ var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines
+ if(istype(G) && G.Touch(A,1))
return
A.attack_hand(src)
@@ -42,12 +48,6 @@
return
A.attack_tk(src)
-/*
- Animals & All Unspecified
-*/
-/mob/living/UnarmedAttack(var/atom/A)
- return
-
/mob/living/RestrainedClickOn(var/atom/A)
return
@@ -58,7 +58,13 @@
//TODO: Disease spreading and unarmed damage against mobs.
/mob/living/carbon/monkey/UnarmedAttack(var/atom/A, var/proximity)
- if(!proximity)
+
+ if(!..())
+ return
+
+ if(a_intent == "harm")
+ A.attack_generic(src,rand(1,3),"bites")
+ else
A.attack_hand(src)
/*
@@ -104,6 +110,52 @@
/mob/living/carbon/slime/RestrainedClickOn(var/atom/A)
return
+/mob/living/carbon/slime/UnarmedAttack(var/atom/A, var/proximity)
+
+ if(!..())
+ return
+
+ // Eating
+ if(Victim)
+ return
+
+ // Basic attack.
+ A.attack_generic(src, (is_adult ? rand(20,40) : rand(5,25)), "glomps")
+
+ // Handle mob shocks.
+ var/mob/living/M = A
+ if(istype(M) && powerlevel > 0 && !istype(A,/mob/living/carbon/slime))
+
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ if(H.species.flags & IS_SYNTHETIC || H.species.insulated)
+ return
+
+ var/power = max(0,min(10,(powerlevel+rand(0,3))))
+
+ var/stunprob = 10
+ switch(power*10)
+ if(1 to 2) stunprob = 20
+ if(3 to 4) stunprob = 30
+ if(5 to 6) stunprob = 40
+ if(7 to 8) stunprob = 60
+ if(9) stunprob = 70
+ if(10) stunprob = 95
+
+ if(prob(stunprob))
+ powerlevel = max(0,powerlevel-3)
+ src.visible_message("\red The [name] has shocked [M]!")
+ M.Weaken(power)
+ M.Stun(power)
+ if (M.stuttering < power) M.stuttering = power
+
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(5, 1, M)
+ s.start()
+
+ if(prob(stunprob) && powerlevel >= 8)
+ M.adjustFireLoss(powerlevel * rand(6,10))
+ M.updatehealth()
/*
New Players:
Have no reason to click on anything at all.
diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm
index 07936e26858..48f2dcab17c 100644
--- a/code/game/machinery/turrets.dm
+++ b/code/game/machinery/turrets.dm
@@ -338,6 +338,18 @@
spawn(13)
del(src)
+/obj/machinery/turret/attack_generic(var/mob/user, var/damage, var/attack_message)
+ if(!damage)
+ return
+ if(stat & BROKEN)
+ user << "That object is useless to you."
+ return
+ visible_message("[user] [attack_message] the [src]!")
+ user.attack_log += text("\[[time_stamp()]\] attacked [src.name]")
+ src.health -= damage
+ if (src.health <= 0)
+ src.die()
+
/obj/structure/turret/gun_turret
name = "Gun Turret"
density = 1
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index c8b22dda280..e45fa114e80 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -1703,6 +1703,27 @@
icon_state = initial(icon_state)
return icon_state
+/obj/mecha/attack_generic(var/mob/user, var/damage, var/attack_message)
+
+ if(!damage)
+ return
+
+ src.log_message("Attack by an animal. Attacker - [user].",1)
+
+ if(!prob(src.deflect_chance))
+ src.take_damage(damage)
+ src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
+ visible_message("\red [user] [attack_message] [src]!")
+ user.attack_log += text("\[[time_stamp()]\] attacked [src.name]")
+ else
+ src.log_append_to_last("Armor saved.")
+ playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1, -1)
+ src.occupant_message("\blue The [user]'s attack is stopped by the armor.")
+ visible_message("\blue The [user] rebounds off [src.name]'s armor!")
+ user.attack_log += text("\[[time_stamp()]\] attacked [src.name]")
+ return
+
+
//////////////////////////////////////////
//////// Mecha global iterators ////////
//////////////////////////////////////////
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 3fedae810b1..b6e9406b51d 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -1,5 +1,6 @@
/obj/structure
icon = 'icons/obj/structures.dmi'
+
var/climbable
var/breakable
var/parts
@@ -14,13 +15,12 @@
if(breakable)
if(HULK in user.mutations)
user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
- visible_message("[user] smashes the [src] apart!")
- destroy()
+ attack_generic(user,1,"smashes")
else if(istype(user,/mob/living/carbon/human))
var/mob/living/carbon/human/H = user
if(H.species.can_shred(user))
- visible_message("[H] slices [src] apart!")
- destroy()
+ attack_generic(user,1,"slices")
+ return
/obj/structure/blob_act()
if(prob(50))
@@ -166,4 +166,10 @@
if (issilicon(user))
user << "You need hands for this."
return 0
- return 1
\ No newline at end of file
+ return 1
+
+/obj/structure/attack_generic(var/mob/user, var/damage, var/attack_verb, var/wallbreaker)
+ if(!breakable || !damage || !wallbreaker)
+ return
+ visible_message("[user] [attack_verb] the [src] apart!")
+ destroy()
\ No newline at end of file
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 6be83616f6b..33ad8abc15d 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -297,4 +297,11 @@
for (var/atom/A in src)
if(istype(A,/obj/))
var/obj/O = A
- O.hear_talk(M, text)
\ No newline at end of file
+ O.hear_talk(M, text)
+
+/obj/structure/closet/attack_generic(var/mob/user, var/damage, var/attack_message = "destroys", var/wallbreaker)
+ if(!damage || !wallbreaker)
+ return
+ visible_message("[user] [attack_message] the [src]!")
+ dump_contents()
+ del(src)
\ No newline at end of file
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index b8d811efb62..d6628f0023e 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -6,193 +6,198 @@
var/state = 0
var/health = 200
+/obj/structure/girder/attack_generic(var/mob/user, var/damage, var/attack_message = "smashes apart", var/wallbreaker)
+ if(!damage || !wallbreaker)
+ return
+ visible_message("[user] [attack_message] the [src]!")
+ dismantle()
- bullet_act(var/obj/item/projectile/Proj)
- if(istype(Proj, /obj/item/projectile/beam))
- health -= Proj.damage
- ..()
- if(health <= 0)
- new /obj/item/stack/sheet/metal(get_turf(src))
- del(src)
+/obj/structure/girder/bullet_act(var/obj/item/projectile/Proj)
+ if(istype(Proj, /obj/item/projectile/beam))
+ health -= Proj.damage
+ ..()
+ if(health <= 0)
+ new /obj/item/stack/sheet/metal(get_turf(src))
+ del(src)
- return
+ return
- attackby(obj/item/W as obj, mob/user as mob)
- if(istype(W, /obj/item/weapon/wrench) && state == 0)
- if(anchored && !istype(src,/obj/structure/girder/displaced))
- playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
- user << "\blue Now disassembling the girder"
- if(do_after(user,40))
- if(!src) return
- user << "\blue You dissasembled the girder!"
- dismantle()
- else if(!anchored)
- playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
- user << "\blue Now securing the girder"
- if(get_turf(user, 40))
- user << "\blue You secured the girder!"
- new/obj/structure/girder( src.loc )
- del(src)
-
- else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter))
- user << "\blue Now slicing apart the girder"
- if(do_after(user,30))
+/obj/structure/girder/attackby(obj/item/W as obj, mob/user as mob)
+ if(istype(W, /obj/item/weapon/wrench) && state == 0)
+ if(anchored && !istype(src,/obj/structure/girder/displaced))
+ playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
+ user << "\blue Now disassembling the girder"
+ if(do_after(user,40))
if(!src) return
- user << "\blue You slice apart the girder!"
+ user << "\blue You dissasembled the girder!"
dismantle()
-
- else if(istype(W, /obj/item/weapon/pickaxe/diamonddrill))
- user << "\blue You drill through the girder!"
- dismantle()
-
- else if(istype(W, /obj/item/weapon/screwdriver) && state == 2 && istype(src,/obj/structure/girder/reinforced))
- playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1)
- user << "\blue Now unsecuring support struts"
- if(do_after(user,40))
- if(!src) return
- user << "\blue You unsecured the support struts!"
- state = 1
-
- else if(istype(W, /obj/item/weapon/wirecutters) && istype(src,/obj/structure/girder/reinforced) && state == 1)
- playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
- user << "\blue Now removing support struts"
- if(do_after(user,40))
- if(!src) return
- user << "\blue You removed the support struts!"
+ else if(!anchored)
+ playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
+ user << "\blue Now securing the girder"
+ if(get_turf(user, 40))
+ user << "\blue You secured the girder!"
new/obj/structure/girder( src.loc )
del(src)
- else if(istype(W, /obj/item/weapon/crowbar) && state == 0 && anchored )
- playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
- user << "\blue Now dislodging the girder"
- if(do_after(user, 40))
- if(!src) return
- user << "\blue You dislodged the girder!"
- new/obj/structure/girder/displaced( src.loc )
- del(src)
+ else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter))
+ user << "\blue Now slicing apart the girder"
+ if(do_after(user,30))
+ if(!src) return
+ user << "\blue You slice apart the girder!"
+ dismantle()
- else if(istype(W, /obj/item/stack/sheet))
+ else if(istype(W, /obj/item/weapon/pickaxe/diamonddrill))
+ user << "\blue You drill through the girder!"
+ dismantle()
- var/obj/item/stack/sheet/S = W
- switch(S.type)
+ else if(istype(W, /obj/item/weapon/screwdriver) && state == 2 && istype(src,/obj/structure/girder/reinforced))
+ playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1)
+ user << "\blue Now unsecuring support struts"
+ if(do_after(user,40))
+ if(!src) return
+ user << "\blue You unsecured the support struts!"
+ state = 1
- if(/obj/item/stack/sheet/metal, /obj/item/stack/sheet/metal/cyborg)
- if(!anchored)
- if(S.use(2))
- user << "You create a false wall! Push on it to open or close the passage."
- new /obj/structure/falsewall (src.loc)
+ else if(istype(W, /obj/item/weapon/wirecutters) && istype(src,/obj/structure/girder/reinforced) && state == 1)
+ playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
+ user << "\blue Now removing support struts"
+ if(do_after(user,40))
+ if(!src) return
+ user << "\blue You removed the support struts!"
+ new/obj/structure/girder( src.loc )
+ del(src)
+
+ else if(istype(W, /obj/item/weapon/crowbar) && state == 0 && anchored )
+ playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
+ user << "\blue Now dislodging the girder"
+ if(do_after(user, 40))
+ if(!src) return
+ user << "\blue You dislodged the girder!"
+ new/obj/structure/girder/displaced( src.loc )
+ del(src)
+
+ else if(istype(W, /obj/item/stack/sheet))
+
+ var/obj/item/stack/sheet/S = W
+ switch(S.type)
+
+ if(/obj/item/stack/sheet/metal, /obj/item/stack/sheet/metal/cyborg)
+ if(!anchored)
+ if(S.use(2))
+ user << "You create a false wall! Push on it to open or close the passage."
+ new /obj/structure/falsewall (src.loc)
+ del(src)
+ else
+ if(S.get_amount() < 2) return ..()
+ user << "Now adding plating..."
+ if (do_after(user,40))
+ if (S.use(2))
+ user << "You added the plating!"
+ var/turf/Tsrc = get_turf(src)
+ Tsrc.ChangeTurf(/turf/simulated/wall)
+ for(var/turf/simulated/wall/X in Tsrc.loc)
+ if(X) X.add_hiddenprint(usr)
del(src)
- else
- if(S.get_amount() < 2) return ..()
- user << "Now adding plating..."
- if (do_after(user,40))
- if (S.use(2))
- user << "You added the plating!"
+ return
+
+ if(/obj/item/stack/sheet/plasteel)
+ if(!anchored)
+ if(S.use(2))
+ user << "\blue You create a false wall! Push on it to open or close the passage."
+ new /obj/structure/falserwall (src.loc)
+ del(src)
+ else
+ if (src.icon_state == "reinforced") //I cant believe someone would actually write this line of code...
+ if(S.get_amount() < 1) return ..()
+ user << "Now finalising reinforced wall."
+ if(do_after(user, 50))
+ if (S.use(1))
+ user << "Wall fully reinforced!"
var/turf/Tsrc = get_turf(src)
- Tsrc.ChangeTurf(/turf/simulated/wall)
- for(var/turf/simulated/wall/X in Tsrc.loc)
+ Tsrc.ChangeTurf(/turf/simulated/wall/r_wall)
+ for(var/turf/simulated/wall/r_wall/X in Tsrc.loc)
if(X) X.add_hiddenprint(usr)
del(src)
return
-
- if(/obj/item/stack/sheet/plasteel)
- if(!anchored)
- if(S.use(2))
- user << "\blue You create a false wall! Push on it to open or close the passage."
- new /obj/structure/falserwall (src.loc)
- del(src)
else
- if (src.icon_state == "reinforced") //I cant believe someone would actually write this line of code...
- if(S.get_amount() < 1) return ..()
- user << "Now finalising reinforced wall."
- if(do_after(user, 50))
- if (S.use(1))
- user << "Wall fully reinforced!"
- var/turf/Tsrc = get_turf(src)
- Tsrc.ChangeTurf(/turf/simulated/wall/r_wall)
- for(var/turf/simulated/wall/r_wall/X in Tsrc.loc)
- if(X) X.add_hiddenprint(usr)
- del(src)
- return
- else
- if(S.get_amount() < 1) return ..()
- user << "Now reinforcing girders..."
- if (do_after(user,60))
- if(S.use(1))
- user << "Girders reinforced!"
- new/obj/structure/girder/reinforced( src.loc )
- del(src)
- return
+ if(S.get_amount() < 1) return ..()
+ user << "Now reinforcing girders..."
+ if (do_after(user,60))
+ if(S.use(1))
+ user << "Girders reinforced!"
+ new/obj/structure/girder/reinforced( src.loc )
+ del(src)
+ return
- if(S.sheettype)
- var/M = S.sheettype
- if(!anchored)
- if(S.amount < 2) return
+ if(S.sheettype)
+ var/M = S.sheettype
+ if(!anchored)
+ if(S.amount < 2) return
+ S.use(2)
+ user << "\blue You create a false wall! Push on it to open or close the passage."
+ var/F = text2path("/obj/structure/falsewall/[M]")
+ new F (src.loc)
+ del(src)
+ else
+ if(S.amount < 2) return ..()
+ user << "\blue Now adding plating..."
+ if (do_after(user,40))
+ if(!src || !S || S.amount < 2) return
S.use(2)
- user << "\blue You create a false wall! Push on it to open or close the passage."
- var/F = text2path("/obj/structure/falsewall/[M]")
- new F (src.loc)
+ user << "\blue You added the plating!"
+ var/turf/Tsrc = get_turf(src)
+ Tsrc.ChangeTurf(text2path("/turf/simulated/wall/mineral/[M]"))
+ for(var/turf/simulated/wall/mineral/X in Tsrc.loc)
+ if(X) X.add_hiddenprint(usr)
del(src)
- else
- if(S.amount < 2) return ..()
- user << "\blue Now adding plating..."
- if (do_after(user,40))
- if(!src || !S || S.amount < 2) return
- S.use(2)
- user << "\blue You added the plating!"
- var/turf/Tsrc = get_turf(src)
- Tsrc.ChangeTurf(text2path("/turf/simulated/wall/mineral/[M]"))
- for(var/turf/simulated/wall/mineral/X in Tsrc.loc)
- if(X) X.add_hiddenprint(usr)
- del(src)
- return
+ return
- add_hiddenprint(usr)
+ add_hiddenprint(usr)
- else if(istype(W, /obj/item/pipe))
- var/obj/item/pipe/P = W
- if (P.pipe_type in list(0, 1, 5)) //simple pipes, simple bends, and simple manifolds.
- user.drop_item()
- P.loc = src.loc
- user << "\blue You fit the pipe into the [src]!"
- else
- ..()
+ else if(istype(W, /obj/item/pipe))
+ var/obj/item/pipe/P = W
+ if (P.pipe_type in list(0, 1, 5)) //simple pipes, simple bends, and simple manifolds.
+ user.drop_item()
+ P.loc = src.loc
+ user << "\blue You fit the pipe into the [src]!"
+ else
+ ..()
- proc/dismantle()
- new /obj/item/stack/sheet/metal(get_turf(src))
+/obj/structure/girder/proc/dismantle()
+ new /obj/item/stack/sheet/metal(get_turf(src))
+ del(src)
+
+/obj/structure/girder/attack_hand(mob/user as mob)
+ if (HULK in user.mutations)
+ visible_message("[user] smashes [src] apart!")
+ dismantle()
+ return
+ return ..()
+
+/obj/structure/girder/blob_act()
+ if(prob(40))
del(src)
- attack_hand(mob/user as mob)
- if (HULK in user.mutations)
- visible_message("[user] smashes [src] apart!")
- dismantle()
- return
- return ..()
- blob_act()
- if(prob(40))
+/obj/structure/girder/ex_act(severity)
+ switch(severity)
+ if(1.0)
del(src)
-
-
- ex_act(severity)
- switch(severity)
- if(1.0)
+ return
+ if(2.0)
+ if (prob(30))
+ var/remains = pick(/obj/item/stack/rods,/obj/item/stack/sheet/metal)
+ new remains(loc)
del(src)
- return
- if(2.0)
- if (prob(30))
- var/remains = pick(/obj/item/stack/rods,/obj/item/stack/sheet/metal)
- new remains(loc)
- del(src)
- return
- if(3.0)
- if (prob(5))
- var/remains = pick(/obj/item/stack/rods,/obj/item/stack/sheet/metal)
- new remains(loc)
- del(src)
- return
- else
- return
+ return
+ if(3.0)
+ if (prob(5))
+ var/remains = pick(/obj/item/stack/rods,/obj/item/stack/sheet/metal)
+ new remains(loc)
+ del(src)
+ return
+ else
+ return
/obj/structure/girder/displaced
icon_state = "displaced"
@@ -212,54 +217,54 @@
layer = 2
var/health = 250
- attackby(obj/item/W as obj, mob/user as mob)
- if(istype(W, /obj/item/weapon/wrench))
- playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
- user << "\blue Now disassembling the girder"
- if(do_after(user,40))
- user << "\blue You dissasembled the girder!"
- new /obj/effect/decal/remains/human(get_turf(src))
- del(src)
-
- else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter))
- user << "\blue Now slicing apart the girder"
- if(do_after(user,30))
- user << "\blue You slice apart the girder!"
+/obj/structure/cultgirder/attackby(obj/item/W as obj, mob/user as mob)
+ if(istype(W, /obj/item/weapon/wrench))
+ playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
+ user << "\blue Now disassembling the girder"
+ if(do_after(user,40))
+ user << "\blue You dissasembled the girder!"
new /obj/effect/decal/remains/human(get_turf(src))
del(src)
- else if(istype(W, /obj/item/weapon/pickaxe/diamonddrill))
- user << "\blue You drill through the girder!"
- new /obj/effect/decal/remains/human(get_turf(src))
+ else if(istype(W, /obj/item/weapon/pickaxe/plasmacutter))
+ user << "\blue Now slicing apart the girder"
+ if(do_after(user,30))
+ user << "\blue You slice apart the girder!"
+ new /obj/effect/decal/remains/human(get_turf(src))
+ del(src)
+
+ else if(istype(W, /obj/item/weapon/pickaxe/diamonddrill))
+ user << "\blue You drill through the girder!"
+ new /obj/effect/decal/remains/human(get_turf(src))
+ del(src)
+
+/obj/structure/cultgirder/blob_act()
+ if(prob(40))
+ del(src)
+
+/obj/structure/cultgirder/bullet_act(var/obj/item/projectile/Proj) //No beam check- How else will you destroy the cult girder with silver bullets?????
+ health -= Proj.damage
+ ..()
+ if(health <= 0)
+ new /obj/item/stack/sheet/metal(get_turf(src))
+ del(src)
+
+ return
+
+/obj/structure/cultgirder/ex_act(severity)
+ switch(severity)
+ if(1.0)
del(src)
-
- blob_act()
- if(prob(40))
- del(src)
-
- bullet_act(var/obj/item/projectile/Proj) //No beam check- How else will you destroy the cult girder with silver bullets?????
- health -= Proj.damage
- ..()
- if(health <= 0)
- new /obj/item/stack/sheet/metal(get_turf(src))
- del(src)
-
- return
-
- ex_act(severity)
- switch(severity)
- if(1.0)
+ return
+ if(2.0)
+ if (prob(30))
+ new /obj/effect/decal/remains/human(loc)
del(src)
- return
- if(2.0)
- if (prob(30))
- new /obj/effect/decal/remains/human(loc)
- del(src)
- return
- if(3.0)
- if (prob(5))
- new /obj/effect/decal/remains/human(loc)
- del(src)
- return
- else
- return
\ No newline at end of file
+ return
+ if(3.0)
+ if (prob(5))
+ new /obj/effect/decal/remains/human(loc)
+ del(src)
+ return
+ else
+ return
\ No newline at end of file
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index ce645d6afea..8d8c0469c25 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -30,19 +30,13 @@
playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
- var/damage_dealt
+ var/damage_dealt = 1
+ var/attack_message = "kicks"
if(istype(user,/mob/living/carbon/human))
var/mob/living/carbon/human/H = user
if(H.species.can_shred(H))
+ attack_message = "mangles"
damage_dealt = 5
- user.visible_message("[user] mangles [src].", \
- "You mangle [src].", \
- "You hear twisting metal.")
-
- if(!damage_dealt)
- user.visible_message("[user] kicks [src].", \
- "You kick [src].", \
- "You hear twisting metal.")
if(shock(user, 70))
return
@@ -52,8 +46,7 @@
else
damage_dealt += 1
- health -= damage_dealt
- healthcheck()
+ attack_generic(user,damage_dealt,attack_message)
/obj/structure/grille/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(air_group || (height==0)) return 1
@@ -195,3 +188,8 @@
health -= 1
healthcheck()
..()
+
+/obj/structure/grille/attack_generic(var/mob/user, var/damage, var/attack_verb)
+ visible_message("[user] [attack_verb] the [src]!")
+ health -= damage
+ healthcheck()
\ No newline at end of file
diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm
index 06544dfca8e..fad90eebdfc 100644
--- a/code/game/objects/structures/inflatable.dm
+++ b/code/game/objects/structures/inflatable.dm
@@ -26,112 +26,103 @@
var/health = 50.0
- New(location)
- ..()
- update_nearby_tiles(need_rebuild=1)
+/obj/structure/inflatable/New(location)
+ ..()
+ update_nearby_tiles(need_rebuild=1)
- Del()
- update_nearby_tiles()
- ..()
+/obj/structure/inflatable/Del()
+ update_nearby_tiles()
+ ..()
- proc/update_nearby_tiles(need_rebuild) //Copypasta from airlock code
- if(!air_master)
- return 0
- air_master.mark_for_update(get_turf(src))
- return 1
-
-
-
- CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+/obj/structure/inflatable/proc/update_nearby_tiles(need_rebuild) //Copypasta from airlock code
+ if(!air_master)
return 0
+ air_master.mark_for_update(get_turf(src))
+ return 1
- bullet_act(var/obj/item/projectile/Proj)
- health -= Proj.damage
- ..()
- if(health <= 0)
+/obj/structure/inflatable/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ return 0
+
+/obj/structure/inflatable/bullet_act(var/obj/item/projectile/Proj)
+ health -= Proj.damage
+ ..()
+ if(health <= 0)
+ deflate(1)
+ return
+
+/obj/structure/inflatable/ex_act(severity)
+ switch(severity)
+ if(1.0)
+ del(src)
+ return
+ if(2.0)
deflate(1)
- return
-
-
- ex_act(severity)
- switch(severity)
- if(1.0)
- del(src)
- return
- if(2.0)
+ return
+ if(3.0)
+ if(prob(50))
deflate(1)
return
- if(3.0)
- if(prob(50))
- deflate(1)
- return
+/obj/structure/inflatable/blob_act()
+ deflate(1)
- blob_act()
- deflate(1)
+/obj/structure/inflatable/meteorhit()
+ deflate(1)
-
- meteorhit()
- //world << "glass at [x],[y],[z] Mhit"
- deflate(1)
-
-
- attack_hand(mob/user as mob)
+/obj/structure/inflatable/attack_hand(mob/user as mob)
add_fingerprint(user)
return
+/obj/structure/inflatable/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(!istype(W)) return
- proc/attack_generic(mob/user as mob, damage = 0) //used by attack_animal and attack_slime
- health -= damage
- if(health <= 0)
- user.visible_message("[user] tears open [src]!")
- deflate(1)
- else //for nicer text~
- user.visible_message("[user] tears at [src]!")
+ if (can_puncture(W))
+ visible_message("\red [user] pierces [src] with [W]!")
+ deflate(1)
+ if(W.damtype == BRUTE || W.damtype == BURN)
+ hit(W.force)
+ ..()
+ return
- attackby(obj/item/weapon/W as obj, mob/user as mob)
- if(!istype(W)) return
+/obj/structure/inflatable/proc/hit(var/damage, var/sound_effect = 1)
+ health = max(0, health - damage)
+ if(sound_effect)
+ playsound(loc, 'sound/effects/Glasshit.ogg', 75, 1)
+ if(health <= 0)
+ deflate(1)
- if (can_puncture(W))
- visible_message("\red [user] pierces [src] with [W]!")
- deflate(1)
- if(W.damtype == BRUTE || W.damtype == BURN)
- hit(W.force)
- ..()
- return
-
- proc/hit(var/damage, var/sound_effect = 1)
- health = max(0, health - damage)
- if(sound_effect)
- playsound(loc, 'sound/effects/Glasshit.ogg', 75, 1)
- if(health <= 0)
- deflate(1)
-
-
- proc/deflate(var/violent=0)
- playsound(loc, 'sound/machines/hiss.ogg', 75, 1)
- if(violent)
- visible_message("[src] rapidly deflates!")
- var/obj/item/inflatable/torn/R = new /obj/item/inflatable/torn(loc)
+/obj/structure/inflatable/proc/deflate(var/violent=0)
+ playsound(loc, 'sound/machines/hiss.ogg', 75, 1)
+ if(violent)
+ visible_message("[src] rapidly deflates!")
+ var/obj/item/inflatable/torn/R = new /obj/item/inflatable/torn(loc)
+ src.transfer_fingerprints_to(R)
+ del(src)
+ else
+ //user << "\blue You slowly deflate the inflatable wall."
+ visible_message("[src] slowly deflates.")
+ spawn(50)
+ var/obj/item/inflatable/R = new /obj/item/inflatable(loc)
src.transfer_fingerprints_to(R)
del(src)
- else
- //user << "\blue You slowly deflate the inflatable wall."
- visible_message("[src] slowly deflates.")
- spawn(50)
- var/obj/item/inflatable/R = new /obj/item/inflatable(loc)
- src.transfer_fingerprints_to(R)
- del(src)
- verb/hand_deflate()
- set name = "Deflate"
- set category = "Object"
- set src in oview(1)
+/obj/structure/inflatable/verb/hand_deflate()
+ set name = "Deflate"
+ set category = "Object"
+ set src in oview(1)
- if(isobserver(usr)) //to stop ghosts from deflating
- return
+ if(isobserver(usr)) //to stop ghosts from deflating
+ return
- deflate()
+ deflate()
+
+/obj/structure/inflatable/attack_generic(var/mob/user, var/damage, var/attack_verb)
+ health -= damage
+ if(health <= 0)
+ user.visible_message("[user] [attack_verb] open the [src]!")
+ deflate(1)
+ else
+ user.visible_message("[user] [attack_verb] at [src]!")
/obj/item/inflatable/door/
name = "inflatable door"
@@ -159,94 +150,84 @@
var/state = 0 //closed, 1 == open
var/isSwitchingStates = 0
- //Bumped(atom/user)
- // ..()
- // if(!state)
- // return TryToSwitchState(user)
- // return
+/obj/structure/inflatable/door/attack_ai(mob/user as mob) //those aren't machinery, they're just big fucking slabs of a mineral
+ if(isAI(user)) //so the AI can't open it
+ return
+ else if(isrobot(user)) //but cyborgs can
+ if(get_dist(user,src) <= 1) //not remotely though
+ return TryToSwitchState(user)
- attack_ai(mob/user as mob) //those aren't machinery, they're just big fucking slabs of a mineral
- if(isAI(user)) //so the AI can't open it
- return
- else if(isrobot(user)) //but cyborgs can
- if(get_dist(user,src) <= 1) //not remotely though
- return TryToSwitchState(user)
+/obj/structure/inflatable/door/attack_hand(mob/user as mob)
+ return TryToSwitchState(user)
- attack_hand(mob/user as mob)
- return TryToSwitchState(user)
+/obj/structure/inflatable/door/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ if(air_group)
+ return state
+ if(istype(mover, /obj/effect/beam))
+ return !opacity
+ return !density
- CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(air_group)
- return state
- if(istype(mover, /obj/effect/beam))
- return !opacity
- return !density
-
- proc/TryToSwitchState(atom/user)
- if(isSwitchingStates) return
- if(ismob(user))
- var/mob/M = user
- if(world.time - user.last_bumped <= 60) return //NOTE do we really need that?
- if(M.client)
- if(iscarbon(M))
- var/mob/living/carbon/C = M
- if(!C.handcuffed)
- SwitchState()
- else
+/obj/structure/inflatable/door/proc/TryToSwitchState(atom/user)
+ if(isSwitchingStates) return
+ if(ismob(user))
+ var/mob/M = user
+ if(world.time - user.last_bumped <= 60) return //NOTE do we really need that?
+ if(M.client)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ if(!C.handcuffed)
SwitchState()
- else if(istype(user, /obj/mecha))
- SwitchState()
+ else
+ SwitchState()
+ else if(istype(user, /obj/mecha))
+ SwitchState()
- proc/SwitchState()
- if(state)
- Close()
- else
- Open()
- update_nearby_tiles()
-
- proc/Open()
- isSwitchingStates = 1
- //playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 100, 1)
- flick("door_opening",src)
- sleep(10)
- density = 0
- opacity = 0
- state = 1
- update_icon()
- isSwitchingStates = 0
-
- proc/Close()
- isSwitchingStates = 1
- //playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 100, 1)
- flick("door_closing",src)
- sleep(10)
- density = 1
- opacity = 0
- state = 0
- update_icon()
- isSwitchingStates = 0
+/obj/structure/inflatable/door/proc/SwitchState()
+ if(state)
+ Close()
+ else
+ Open()
+ update_nearby_tiles()
+/obj/structure/inflatable/door/proc/Open()
+ isSwitchingStates = 1
+ flick("door_opening",src)
+ sleep(10)
+ density = 0
+ opacity = 0
+ state = 1
update_icon()
- if(state)
- icon_state = "door_open"
- else
- icon_state = "door_closed"
+ isSwitchingStates = 0
- deflate(var/violent=0)
- playsound(loc, 'sound/machines/hiss.ogg', 75, 1)
- if(violent)
- visible_message("[src] rapidly deflates!")
- var/obj/item/inflatable/door/torn/R = new /obj/item/inflatable/door/torn(loc)
+/obj/structure/inflatable/door/proc/Close()
+ isSwitchingStates = 1
+ flick("door_closing",src)
+ sleep(10)
+ density = 1
+ opacity = 0
+ state = 0
+ update_icon()
+ isSwitchingStates = 0
+
+/obj/structure/inflatable/door/update_icon()
+ if(state)
+ icon_state = "door_open"
+ else
+ icon_state = "door_closed"
+
+/obj/structure/inflatable/door/deflate(var/violent=0)
+ playsound(loc, 'sound/machines/hiss.ogg', 75, 1)
+ if(violent)
+ visible_message("[src] rapidly deflates!")
+ var/obj/item/inflatable/door/torn/R = new /obj/item/inflatable/door/torn(loc)
+ src.transfer_fingerprints_to(R)
+ del(src)
+ else
+ visible_message("[src] slowly deflates.")
+ spawn(50)
+ var/obj/item/inflatable/door/R = new /obj/item/inflatable/door(loc)
src.transfer_fingerprints_to(R)
del(src)
- else
- //user << "\blue You slowly deflate the inflatable wall."
- visible_message("[src] slowly deflates.")
- spawn(50)
- var/obj/item/inflatable/door/R = new /obj/item/inflatable/door(loc)
- src.transfer_fingerprints_to(R)
- del(src)
-
/obj/item/inflatable/torn
name = "torn inflatable wall"
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index 83112a0021e..b685c9ed83d 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -8,7 +8,6 @@
anchored = 1
var/shattered = 0
-
/obj/structure/mirror/attack_hand(mob/user as mob)
if(shattered) return
@@ -17,14 +16,10 @@
var/mob/living/carbon/human/H = user
if(H.a_intent == "hurt")
- if(shattered)
- playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
- return
if(prob(30) || H.species.can_shred(H))
- user.visible_message("[user] smashes [src]!")
- shatter()
+ attack_generic(user,1)
else
- user.visible_message("[user] hits [src] and bounces off!")
+ attack_generic(user)
return
var/userloc = H.loc
@@ -82,7 +77,6 @@
playsound(src, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
..()
-
/obj/structure/mirror/attackby(obj/item/I as obj, mob/user as mob)
if(shattered)
playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
@@ -93,4 +87,16 @@
shatter()
else
visible_message("[user] hits [src] with [I]!")
- playsound(src.loc, 'sound/effects/Glasshit.ogg', 70, 1)
\ No newline at end of file
+ playsound(src.loc, 'sound/effects/Glasshit.ogg', 70, 1)
+
+/obj/structure/mirror/attack_generic(var/mob/user, var/damage)
+
+ if(shattered)
+ playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1)
+ return
+
+ if(damage)
+ user.visible_message("[user] smashes [src]!")
+ shatter()
+ else
+ user.visible_message("[user] hits [src] and bounces off!")
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 4b39e9d3b61..19001a0ae8b 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -150,7 +150,9 @@
"You hear a knocking sound.")
return
-/obj/structure/window/proc/attack_generic(mob/user as mob, damage = 0) //used by attack_animal and attack_slime
+/obj/structure/window/attack_generic(var/mob/user, var/damage)
+ if(!damage)
+ return
user.visible_message("[user] smashes into [src]!")
take_damage(damage)
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index e960b9720d8..32caff56369 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -248,6 +248,23 @@
src.add_fingerprint(user)
return
+/turf/simulated/wall/attack_generic(var/mob/user, var/damage, var/wallbreaker)
+
+ if(!damage || !wallbreaker)
+ user << "You push the wall but nothing happens."
+ return
+
+ if(istype(src,/turf/simulated/wall/r_wall) && !rotting)
+ user << "This wall is far too strong for you to destroy."
+
+ if(rotting || prob(40))
+ user << "You smash through the wall!"
+ dismantle_wall(1)
+ else
+ user << "You smash against the wall."
+ take_damage(rand(25,75))
+ return
+
/turf/simulated/wall/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index b8030886c3d..5a06c40b879 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -222,4 +222,19 @@
return
/mob/living/carbon/human/proc/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, inrange, params)
- return
\ No newline at end of file
+ return
+
+/mob/living/carbon/human/attack_generic(var/mob/user, var/damage, var/attack_message)
+
+ if(!damage)
+ return
+
+ user.attack_log += text("\[[time_stamp()]\] attacked [src.name] ([src.ckey])")
+ src.attack_log += text("\[[time_stamp()]\] was attacked by [user.name] ([user.ckey])")
+ src.visible_message("[user] has [attack_message] [src]!")
+
+ var/dam_zone = pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg", "groin")
+ var/datum/organ/external/affecting = get_organ(ran_zone(dam_zone))
+ var/armor_block = run_armor_check(affecting, "melee")
+ apply_damage(damage, BRUTE, affecting, armor_block)
+ updatehealth()
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm
index dbd5faa707c..3b6bd746ff1 100644
--- a/code/modules/mob/living/carbon/metroid/metroid.dm
+++ b/code/modules/mob/living/carbon/metroid/metroid.dm
@@ -840,10 +840,6 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
/mob/living/carbon/slime/has_eyes()
return 0
-
-/mob/living/carbon/slime/UnarmedAttack(var/atom/A)
- return
-
//////////////////////////////Old shit from metroids/RoRos, and the old cores, would not take much work to re-add them////////////////////////
/*
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 3e895c73c2c..810227ddf7a 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -179,3 +179,14 @@
return 0
// End BS12 momentum-transfer code.
+
+/mob/living/attack_generic(var/mob/user, var/damage, var/attack_message)
+
+ if(!damage)
+ return
+
+ adjustBruteLoss(damage)
+ user.attack_log += text("\[[time_stamp()]\] attacked [src.name] ([src.ckey])")
+ src.attack_log += text("\[[time_stamp()]\] was attacked by [user.name] ([user.ckey])")
+ src.visible_message("[user] has [attack_message] [src]!")
+ updatehealth()
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 42259b5fd31..c7abbb3d5a6 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -892,6 +892,10 @@ var/list/robot_verbs_default = list(
user << "You remove \the [broken_device]."
user.put_in_active_hand(broken_device)
+//Robots take half damage from basic attacks.
+/mob/living/silicon/robot/attack_generic(var/mob/user, var/damage, var/attack_message)
+ return ..(user,Floor(damage/2),attack_message)
+
/mob/living/silicon/robot/proc/allowed(mob/M)
//check if it doesn't require any access at all
if(check_access(null))
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index 89e0094daea..2ef60f73938 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -737,3 +737,14 @@
if(!message || stat)
return
speech_buffer.Add(message)
+
+/mob/living/simple_animal/parrot/attack_generic(var/mob/user, var/damage, var/attack_message)
+ ..()
+ if(client) return
+ if(parrot_state == PARROT_PERCH)
+ parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
+ if(!damage)
+ return
+ parrot_interest = user
+ parrot_state = PARROT_SWOOP | PARROT_ATTACK //Attack other animals regardless
+ icon_state = "parrot_fly"
\ No newline at end of file
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index 168f56e1319..9ad0997f730 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -307,6 +307,16 @@
if(on != on_gs)
on_gs = on
+/obj/machinery/light/attack_generic(var/mob/user, var/damage)
+ if(!damage)
+ return
+ if(status == LIGHT_EMPTY||status == LIGHT_BROKEN)
+ user << "That object is useless to you."
+ return
+ if(!(status == LIGHT_OK||status == LIGHT_BURNED))
+ return
+ visible_message("[user] smashes the light!")
+ broken()
// attempt to set the light's on/off status
// will not switch on if broken/burned/empty
diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm
index 741393c6566..a07ea901efc 100644
--- a/code/modules/vehicles/vehicle.dm
+++ b/code/modules/vehicles/vehicle.dm
@@ -346,4 +346,14 @@
// Stat update procs
//-------------------------------------------------------
/obj/vehicle/proc/update_stats()
- return
\ No newline at end of file
+ return
+
+/obj/vehicle/attack_generic(var/mob/user, var/damage, var/attack_message)
+ if(!damage)
+ return
+ visible_message("[user] [attack_message] the [src]!")
+ user.attack_log += text("\[[time_stamp()]\] attacked [src.name]")
+ src.health -= damage
+ if(prob(10))
+ new /obj/effect/decal/cleanable/blood/oil(src.loc)
+ healthcheck()
\ No newline at end of file