Adds brass knuckles and more punching things (#4291)

This pr ports some things from polaris and vore:

-gloves can now increase unarmed attack, as well change their sharpness and etc
-adds brass knuckles, that you can wear on your glove slots and punch people for extra damage
-adds power fist, that allows you to push people around by punching their faces
-adds clawed gloves, that turns regular normie attacks into sharp ones
-adds a verbs that allows you to select a type of attack, like the language, so things like grues could select to use their claws instead of bites
-changes the price of the kneebreaker hammer
This commit is contained in:
Alberyk
2018-02-25 18:56:30 -03:00
committed by Erki
parent 2d8e36544f
commit 2a227dead3
14 changed files with 250 additions and 75 deletions

View File

@@ -17,7 +17,7 @@
// If the gloves do anything, have them return 1 to stop
// normal attack_hand() here.
var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines
if(istype(G) && G.Touch(A,1))
if(istype(G) && G.Touch(A,src,1))
return
A.attack_hand(src)
@@ -34,7 +34,7 @@
if((LASER in mutations) && a_intent == I_HURT)
LaserEyes(A) // moved into a proc below
else if(istype(G) && G.Touch(A,0)) // for magic gloves
else if(istype(G) && G.Touch(A,src,0)) // for magic gloves
return
else if(TK in mutations)
@@ -54,7 +54,7 @@
if(!..())
return 0
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
A.attack_generic(src,rand(5,6),"bitten")
@@ -76,9 +76,9 @@
if (Victim == A)
Feedstop()
return
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
var/mob/living/M = A
if (istype(M))

View File

@@ -36,7 +36,7 @@
/datum/uplink_item/item/visible_weapons/hammer
name = "Kneebreaker Hammer"
item_cost = 10
item_cost = 7
path = /obj/item/weapon/melee/hammer
/datum/uplink_item/item/visible_weapons/revolver
@@ -64,6 +64,16 @@
item_cost = 7
path = /obj/item/weapon/landmine/n2o
/datum/uplink_item/item/visible_weapons/powerfist
name = "Power Fist"
item_cost = 4
path = /obj/item/clothing/gloves/powerfist
/datum/uplink_item/item/visible_weapons/clawedgloves
name = "Clawed Gauntlets"
item_cost = 5
path = /obj/item/clothing/gloves/claws
/datum/uplink_item/item/visible_weapons/heavysniper
name = "Anti-materiel Rifle"
item_cost = DEFAULT_TELECRYSTAL_AMOUNT

View File

@@ -195,7 +195,8 @@
/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus = 1,
/obj/item/seeds/ambrosiavulgarisseed = 2,
/obj/item/seeds/ambrosiadeusseed = 1,
/obj/item/clothing/mask/gas/voice = 1
/obj/item/clothing/mask/gas/voice = 1,
/obj/item/clothing/gloves/brassknuckles = 2
)
/obj/random/energy

View File

@@ -689,7 +689,9 @@ var/list/global/random_stock_large = list(
/obj/item/clothing/gloves/swat/bst,
/obj/item/clothing/gloves/swat/fluff/hawk_gloves,
/obj/item/clothing/gloves/fluff/stone_ring,
/obj/item/clothing/gloves/black/fluff/kathleen_glove)
/obj/item/clothing/gloves/black/fluff/kathleen_glove,
/obj/item/clothing/gloves/powerfist,
/obj/item/clothing/gloves/claws)
exclusion += typesof(/obj/item/clothing/gloves/rig)
exclusion += typesof(/obj/item/clothing/gloves/lightrig)
exclusion += typesof(/obj/item/clothing/gloves/watch)

View File

@@ -86,7 +86,7 @@
switch(target_species)
if("Human", "Skrell", "Machine", "Zeng-Hu Mobility Frame", "Bishop Accessory Frame") //humanoid bodytypes
species_restricted = list(
"Human",
"Human",
"Skrell",
"Machine",
"Zeng-Hu Mobility Frame",
@@ -361,6 +361,8 @@ BLIND // can't see anything
var/fingerprint_chance = 0
var/obj/item/clothing/ring/ring = null //Covered ring
var/mob/living/carbon/human/wearer = null //Used for covered rings when dropping
var/punch_force = 0 //How much damage do these gloves add to a punch?
var/punch_damtype = BRUTE //What type of damage does this make fists be?
body_parts_covered = HANDS
slot_flags = SLOT_GLOVES
attack_verb = list("challenged")
@@ -386,18 +388,18 @@ BLIND // can't see anything
..()
// Called just before an attack_hand(), in mob/UnarmedAttack()
/obj/item/clothing/gloves/proc/Touch(var/atom/A, var/proximity)
/obj/item/clothing/gloves/proc/Touch(var/atom/A, mob/user, var/proximity)
return 0 // return 1 to cancel attack_hand()
/obj/item/clothing/gloves/attackby(obj/item/weapon/W, mob/user)
if(iswirecutter(W) || istype(W, /obj/item/weapon/scalpel))
if (clipped)
user << "<span class='notice'>The [src] have already been clipped!</span>"
user << "<span class='notice'>\The [src] have already been clipped!</span>"
update_icon()
return
playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
user.visible_message("<span class='warning'>[user] cuts the fingertips off of the [src].</span>","<span class='warning'>You cut the fingertips off of the [src].</span>")
user.visible_message("<span class='warning'>[user] cuts the fingertips off of \the [src].</span>","<span class='warning'>You cut the fingertips off of \the [src].</span>")
clipped = 1
name = "modified [name]"

View File

@@ -90,72 +90,72 @@
body_parts_covered = null
fingerprint_chance = 100
verb/checktime()
set category = "Object"
set name = "Check Time"
set src in usr
/obj/item/clothing/gloves/watch/verb/checktime()
set category = "Object"
set name = "Check Time"
set src in usr
if(wired && !clipped)
usr << "You check your watch, spotting a digital collection of numbers reading '[worldtime2text()]'. Today's date is '[time2text(world.time, "Month DD")]. [game_year]'."
if (emergency_shuttle.get_status_panel_eta())
usr << "<span class='warning'>The shuttle's status is reported as: [emergency_shuttle.get_status_panel_eta()].</span>"
else if(wired && clipped)
usr << "You check your watch realising it's still open"
else
usr << "You check your watch as it dawns on you that it's broken"
if(wired && !clipped)
usr << "You check your watch, spotting a digital collection of numbers reading '[worldtime2text()]'. Today's date is '[time2text(world.time, "Month DD")]. [game_year]'."
if (emergency_shuttle.get_status_panel_eta())
usr << "<span class='warning'>The shuttle's status is reported as: [emergency_shuttle.get_status_panel_eta()].</span>"
else if(wired && clipped)
usr << "You check your watch realising it's still open"
else
usr << "You check your watch as it dawns on you that it's broken"
verb/pointatwatch()
set category = "Object"
set name = "Point at watch"
set src in usr
/obj/item/clothing/gloves/watch/verb/pointatwatch()
set category = "Object"
set name = "Point at watch"
set src in usr
if(wired && !clipped)
usr.visible_message ("<span class='notice'>[usr] taps their foot on the floor, arrogantly pointing at the [src] on their wrist with a look of derision in their eyes.</span>", "<span class='notice'>You point down at the [src], an arrogant look about your eyes.</span>")
else if(wired && clipped)
usr.visible_message ("<span class='notice'>[usr] taps their foot on the floor, arrogantly pointing at the [src] on their wrist with a look of derision in their eyes, not noticing it's open</span>", "<span class='notice'>You point down at the [src], an arrogant look about your eyes.</span>")
else
usr.visible_message ("<span class='notice'>[usr] taps their foot on the floor, arrogantly pointing at the [src] on their wrist with a look of derision in their eyes, not noticing it's broken</span>", "<span class='notice'>You point down at the [src], an arrogant look about your eyes.</span>")
if(wired && !clipped)
usr.visible_message ("<span class='notice'>[usr] taps their foot on the floor, arrogantly pointing at the [src] on their wrist with a look of derision in their eyes.</span>", "<span class='notice'>You point down at the [src], an arrogant look about your eyes.</span>")
else if(wired && clipped)
usr.visible_message ("<span class='notice'>[usr] taps their foot on the floor, arrogantly pointing at the [src] on their wrist with a look of derision in their eyes, not noticing it's open</span>", "<span class='notice'>You point down at the [src], an arrogant look about your eyes.</span>")
else
usr.visible_message ("<span class='notice'>[usr] taps their foot on the floor, arrogantly pointing at the [src] on their wrist with a look of derision in their eyes, not noticing it's broken</span>", "<span class='notice'>You point down at the [src], an arrogant look about your eyes.</span>")
examine(mob/user)
..()
if (get_dist(src, user) <= 1)
checktime()
/obj/item/clothing/gloves/watch/examine(mob/user)
..()
if (get_dist(src, user) <= 1)
checktime()
attackby(obj/item/weapon/W, mob/user)
if(isscrewdriver(W))
if (clipped) //Using clipped because adding a new var for something is dumb
user.visible_message("<span class='notice'>[user] screws the cover of the [src] closed.</span>","<span class='notice'>You screw the cover of the [src] closed..</span>")
clipped = 0
return
// playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
user.visible_message("<span class='notice'>[user] unscrew the cover of the [src].</span>","<span class='notice'>You unscrew the cover of the [src].</span>")
clipped = 1
/obj/item/clothing/gloves/watch/attackby(obj/item/weapon/W, mob/user)
if(isscrewdriver(W))
if (clipped) //Using clipped because adding a new var for something is dumb
user.visible_message("<span class='notice'>[user] screws the cover of the [src] closed.</span>","<span class='notice'>You screw the cover of the [src] closed..</span>")
clipped = 0
return
// playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
user.visible_message("<span class='notice'>[user] unscrew the cover of the [src].</span>","<span class='notice'>You unscrew the cover of the [src].</span>")
clipped = 1
return
if(wired)
return
if(iscoil(W))
var/obj/item/stack/cable_coil/C = W
if (!clipped)
user << "<span class='notice'>The [src] is not open.</span>"
return
if(wired)
return
if(iscoil(W))
var/obj/item/stack/cable_coil/C = W
if (!clipped)
user << "<span class='notice'>The [src] is not open.</span>"
return
if(wired)
user << "<span class='notice'>The [src] are already wired.</span>"
return
if(C.amount < 2)
user << "<span class='notice'>There is not enough wire to cover the [src].</span>"
return
C.use(2)
wired = 1
user << "<span class='notice'>You repair some wires in the [src].</span>"
user << "<span class='notice'>The [src] are already wired.</span>"
return
emp_act(severity)
if(prob(50/severity))
wired = 0
..()
if(C.amount < 2)
user << "<span class='notice'>There is not enough wire to cover the [src].</span>"
return
C.use(2)
wired = 1
user << "<span class='notice'>You repair some wires in the [src].</span>"
return
/obj/item/clothing/gloves/watch/emp_act(severity)
if(prob(50/severity))
wired = 0
..()
/*
Forcegloves. They amplify force from melee hits as well as muck up disarm and stuff a little.
@@ -189,3 +189,60 @@
/obj/item/clothing/gloves/force/syndicate //for syndies. pda, *maybe* nuke team or ert. up to you. maybe just use the amp 2 variant.
name = "enhanced force gloves"
amplification = 2.5 //because *2.5 is kind of scary okay. sometimes you want the scary effect. sometimes not.
/obj/item/clothing/gloves/brassknuckles
name = "brass knuckles"
desc = "A pair of brass knuckles. Generally used to enhance the user's punches."
icon_state = "knuckledusters"
attack_verb = list("punched", "beaten", "struck")
siemens_coefficient = 1
fingerprint_chance = 100
force = 5
punch_force = 5
clipped = 1
/obj/item/clothing/gloves/powerfist
name = "power fist"
desc = "A metal gauntlet with a piston-powered ram ontop for that extra punch in your punch."
icon_state = "powerfist"
item_state = "powerfist"
attack_verb = list("whacked", "fisted", "power-punched")
siemens_coefficient = 1
fingerprint_chance = 50
force = 5
punch_force = 10
clipped = 1
species_restricted = list("exclude","Golem","Vaurca Breeder")
/obj/item/clothing/gloves/powerfist/Touch(atom/A, mob/living/user, proximity)
if(!proximity)
return
if(!isliving(A))
return
var/mob/living/L = A
if(prob(50))
playsound(user, 'sound/weapons/beartrap_shut.ogg', 50, 1, -1)
user.visible_message("<span class='danger'>\The [user] slams \the [L] away with \the [src]!</span>")
var/T = get_turf(user)
spark(T, 3, alldirs)
L.throw_at(get_edge_target_turf(loc, loc.dir), 5, 1)
if(ishuman(L))
var/mob/living/carbon/human/H = L
H.apply_effect(2, WEAKEN)
/obj/item/clothing/gloves/claws
name = "clawed gauntlets"
desc = "A pair of metal gauntlets outfited with menacing sharp blades."
icon_state = "warping_claws"
attack_verb = list("ripped", "torn", "cut")
armor = list(melee = 50, bullet = 15, laser = 15, energy = 10, bomb = 10, bio = 0, rad = 0)
siemens_coefficient = 1
force = 5
punch_force = 10
clipped = 1
sharp = 1
edge = 1

View File

@@ -26,6 +26,7 @@
cold_protection = HANDS
species_restricted = null
gender = PLURAL
punch_force = 5
/obj/item/clothing/shoes/magboots/rig
name = "boots"

View File

@@ -1,4 +1,12 @@
/mob/living/carbon/human/proc/get_unarmed_attack(var/mob/living/carbon/human/target, var/hit_zone)
if(src.default_attack && src.default_attack.is_usable(src, target, hit_zone))
if(pulling_punches)
var/datum/unarmed_attack/soft_type = src.default_attack.get_sparring_variant()
if(soft_type)
return soft_type
return src.default_attack
for(var/datum/unarmed_attack/u_attack in species.unarmed_attacks)
if(u_attack.is_usable(src, target, hit_zone))
if(pulling_punches)
@@ -268,23 +276,50 @@
return 0
var/real_damage = rand_damage
var/hit_dam_type = attack.damage_type
var/is_sharp = 0
var/is_edge = 0
real_damage += attack.get_unarmed_damage(H)
real_damage *= damage_multiplier
rand_damage *= damage_multiplier
if(HULK in H.mutations)
real_damage *= 2 // Hulks do twice the damage
rand_damage *= 2
real_damage = max(1, real_damage)
if(H.gloves && istype(H.gloves,/obj/item/clothing/gloves/force))
var/obj/item/clothing/gloves/force/X = H.gloves
real_damage *= X.amplification
if(H.gloves)
if(istype(H.gloves, /obj/item/clothing/gloves))
var/obj/item/clothing/gloves/G = H.gloves
real_damage += G.punch_force
hit_dam_type = G.punch_damtype
if(H.pulling_punches)
hit_dam_type = AGONY
if(G.sharp)
is_sharp = 1
if(G.edge)
is_edge = 1
if(istype(H.gloves,/obj/item/clothing/gloves/force))
var/obj/item/clothing/gloves/force/X = H.gloves
real_damage *= X.amplification
if(attack.sharp)
is_sharp = 1
if(attack.edge)
is_edge = 1
var/armour = run_armor_check(hit_zone, "melee")
// Apply additional unarmed effects.
attack.apply_effects(H, src, armour, rand_damage, hit_zone)
// Finally, apply damage to target
apply_damage(real_damage, (attack.deal_halloss ? HALLOSS : BRUTE), hit_zone, armour, sharp=attack.sharp, edge=attack.edge)
apply_damage(real_damage, hit_dam_type, hit_zone, armour, sharp=is_sharp, edge=is_edge)
if(I_DISARM)
if(M.disabilities & PACIFIST)
@@ -437,3 +472,47 @@
spawn(1)
qdel(rgrab)
return success
/mob/living/carbon/human/verb/check_attacks()
set name = "Check Attacks"
set category = "IC"
set src = usr
var/dat = "<b><font size = 5>Known Attacks</font></b><br/><br/>"
for(var/datum/unarmed_attack/u_attack in species.unarmed_attacks)
dat += "<b>Primarily [u_attack.attack_name] </b><br/><br/><br/>"
src << browse(dat, "window=checkattack")
return
/mob/living/carbon/human/check_attacks()
var/dat = "<b><font size = 5>Known Attacks</font></b><br/><br/>"
if(default_attack)
dat += "Current default attack: [default_attack.attack_name] - <a href='byond://?src=\ref[src];default_attk=reset_attk'>reset</a><br/><br/>"
for(var/datum/unarmed_attack/u_attack in species.unarmed_attacks)
if(u_attack == default_attack)
dat += "<b>Primarily [u_attack.attack_name]</b> - default - <a href='byond://?src=\ref[src];default_attk=reset_attk'>reset</a><br/><br/><br/>"
else
dat += "<b>Primarily [u_attack.attack_name]</b> - <a href='byond://?src=\ref[src];default_attk=\ref[u_attack]'>set default</a><br/><br/><br/>"
src << browse(dat, "window=checkattack")
/mob/living/carbon/human/Topic(href, href_list)
if(href_list["default_attk"])
if(href_list["default_attk"] == "reset_attk")
set_default_attack(null)
else
var/datum/unarmed_attack/u_attack = locate(href_list["default_attk"])
if(u_attack && (u_attack in species.unarmed_attacks))
set_default_attack(u_attack)
check_attacks()
return 1
else
return ..()
/mob/living/carbon/human/proc/set_default_attack(var/datum/unarmed_attack/u_attack)
default_attack = u_attack

View File

@@ -109,3 +109,5 @@
var/cached_bodytype
var/stance_damage = 0 //Whether this mob's ability to stand has been affected
var/datum/unarmed_attack/default_attack //default unarmed attack

View File

@@ -5,12 +5,14 @@
sharp = 1
edge = 1
damage = 5
attack_name = "sharp bite"
/datum/unarmed_attack/diona
attack_verb = list("lashed", "bludgeoned")
attack_noun = list("tendril")
eye_attack_text = "a tendril"
eye_attack_text_victim = "a tendril"
attack_name = "tendrils"
/datum/unarmed_attack/claws
attack_verb = list("scratched", "clawed", "slashed")
@@ -22,6 +24,7 @@
sharp = 1
edge = 1
damage = 5
attack_name = "claws"
/datum/unarmed_attack/claws/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
var/skill = user.skills["combat"]
@@ -58,16 +61,19 @@
attack_verb = list("slashed")
damage = 10
shredding = 1
attack_name = "strong claws"
/datum/unarmed_attack/bite/strong
attack_verb = list("mauled")
damage = 10
shredding = 1
attack_name = "strong bite"
/datum/unarmed_attack/slime_glomp
attack_verb = list("glomped")
attack_noun = list("body")
damage = 2
attack_name = "glomp"
/datum/unarmed_attack/slime_glomp/apply_effects()
//Todo, maybe have a chance of causing an electrical shock?
@@ -75,6 +81,7 @@
/datum/unarmed_attack/stomp/weak
attack_verb = list("jumped on")
attack_name = "weak stomp"
/datum/unarmed_attack/stomp/weak/get_unarmed_damage()
return damage
@@ -89,6 +96,7 @@
attack_noun = list("power fist")
damage = 12
attack_sound = 'sound/weapons/beartrap_shut.ogg'
attack_name = "power fist"
/datum/unarmed_attack/terminator/apply_effects(var/mob/living/carbon/human/user,var/mob/living/carbon/human/target,var/armour,var/attack_damage,var/zone)
..()

View File

@@ -11,12 +11,14 @@ var/global/list/sparring_attack_cache = list()
var/sharp = 0
var/edge = 0
var/deal_halloss
var/damage_type = BRUTE
var/sparring_variant_type = /datum/unarmed_attack/light_strike
var/eye_attack_text
var/eye_attack_text_victim
var/attack_name = "fist"
/datum/unarmed_attack/proc/get_sparring_variant()
if(sparring_variant_type)
if(!sparring_attack_cache[sparring_variant_type])
@@ -109,6 +111,7 @@ var/global/list/sparring_attack_cache = list()
damage = 0
sharp = 0
edge = 0
attack_name = "bite"
/datum/unarmed_attack/bite/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone)
@@ -124,6 +127,7 @@ var/global/list/sparring_attack_cache = list()
eye_attack_text = "fingers"
eye_attack_text_victim = "digits"
damage = 0
attack_name = "punch"
/datum/unarmed_attack/punch/show_attack(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone, var/attack_damage)
var/obj/item/organ/external/affecting = target.get_organ(zone)
@@ -172,6 +176,7 @@ var/global/list/sparring_attack_cache = list()
attack_noun = list("kick", "kick", "kick", "knee strike")
attack_sound = "swing_hit"
damage = 0
attack_name = "kick"
/datum/unarmed_attack/kick/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone)
if (user.legcuffed)
@@ -212,6 +217,7 @@ var/global/list/sparring_attack_cache = list()
attack_noun = list("stomp")
attack_sound = "swing_hit"
damage = 0
attack_name = "stomp"
/datum/unarmed_attack/stomp/is_usable(var/mob/living/carbon/human/user, var/mob/living/carbon/human/target, var/zone)
@@ -250,7 +256,7 @@ var/global/list/sparring_attack_cache = list()
if(5) user.visible_message("<span class='danger'>[pick("[user] landed a powerful stomp on", "[user] stomped down hard on", "[user] slammed \his [shoes ? copytext(shoes.name, 1, -1) : "foot"] down hard onto")] [target]'s [organ]!</span>") //Devastated lol. No. We want to say that the stomp was powerful or forceful, not that it /wrought devastation/
/datum/unarmed_attack/light_strike
deal_halloss = 3
damage_type = AGONY
attack_noun = list("tap","light strike")
attack_verb = list("tapped", "lightly struck")
damage = 2
@@ -258,3 +264,4 @@ var/global/list/sparring_attack_cache = list()
damage = 0
sharp = 0
edge = 0
attack_name = "light hit"