Merge pull request #14767 from KillianKirilenko/kk-shockmaul
Concussion Maul
276
code/game/objects/items/weapons/melee/shock_maul.dm
Normal file
@@ -0,0 +1,276 @@
|
||||
/obj/item/weapon/melee/shock_maul
|
||||
name = "concussion maul"
|
||||
desc = "A heavy-duty concussion hammer, typically used for mining. An iconic weapon for the many uprisings of Mars. It uses a manually engaged concussive-force amplifier unit in the head to multiply impact force, but its weight and the charge up time makes it difficult to use effectively. Devastating if used correctly, but requires skill."
|
||||
icon_state = "forcemaul"
|
||||
item_state = "forcemaul"
|
||||
slot_flags = SLOT_BACK
|
||||
|
||||
//stopping power/lethality
|
||||
force = 35
|
||||
armor_penetration = 20 //the sheer impact force bypasses quite a bit of armour
|
||||
var/unwielded_force_divisor = 0.25
|
||||
var/wielded = 0
|
||||
var/force_unwielded = 8.75
|
||||
var/wieldsound = null
|
||||
var/unwieldsound = null
|
||||
var/charge_force_mult = 1.75 //damage and AP multiplier on charged hits
|
||||
var/launch_force = 3 //yeet distance
|
||||
var/launch_force_unwielded = 1 //awful w/ one hand, but still gets a little distance
|
||||
var/launch_force_disarm = 1.5 //distance multiplier when swinging in disarm mode, since disarm attacks do half damage
|
||||
var/weaken_force = 2 //stun power
|
||||
var/weaken_force_unwielded = 0 //can't stun at all if used onehanded
|
||||
var/weaken_force_disarm = 1.5 //stun multiplier when in disarm mode
|
||||
|
||||
//mining interacts
|
||||
var/excavation_amount = 200
|
||||
var/destroy_artefacts = TRUE //sorry, breaks stuff
|
||||
|
||||
can_cleave = TRUE //SSSSMITE!
|
||||
attackspeed = 15 //very slow!!
|
||||
sharp = FALSE
|
||||
edge = FALSE
|
||||
throwforce = 25
|
||||
flags = NOCONDUCT
|
||||
w_class = ITEMSIZE_HUGE
|
||||
drop_sound = 'sound/items/drop/metalweapon.ogg'
|
||||
pickup_sound = 'sound/items/pickup/metalweapon.ogg'
|
||||
origin_tech = list(TECH_COMBAT = 5)
|
||||
attack_verb = list("beaten","slammed","smashed","mauled","hammered","bludgeoned")
|
||||
var/lightcolor = "#D3FDFD"
|
||||
var/status = 0 //whether the thing is on or not
|
||||
var/obj/item/weapon/cell/bcell = null
|
||||
var/hitcost = 600 //you get 4 hits out of a standard cell
|
||||
|
||||
/obj/item/weapon/melee/shock_maul/update_held_icon()
|
||||
var/mob/living/M = loc
|
||||
if(istype(M) && M.can_wield_item(src) && is_held_twohanded(M))
|
||||
wielded = 1
|
||||
if(status)
|
||||
force = initial(force)*charge_force_mult
|
||||
armor_penetration *= charge_force_mult
|
||||
else
|
||||
force = initial(force)
|
||||
armor_penetration = initial(armor_penetration)
|
||||
launch_force = initial(launch_force)
|
||||
weaken_force = initial(weaken_force)
|
||||
name = "[initial(name)] (wielded)"
|
||||
update_icon()
|
||||
else
|
||||
wielded = 0
|
||||
if(status)
|
||||
force = force_unwielded*charge_force_mult
|
||||
armor_penetration *= charge_force_mult
|
||||
else
|
||||
force = force_unwielded
|
||||
armor_penetration = initial(armor_penetration)
|
||||
launch_force = launch_force_unwielded
|
||||
weaken_force = weaken_force_unwielded
|
||||
name = "[initial(name)]"
|
||||
update_icon()
|
||||
..()
|
||||
|
||||
/obj/item/weapon/melee/shock_maul/New()
|
||||
..()
|
||||
update_held_icon()
|
||||
return
|
||||
|
||||
/obj/item/weapon/melee/shock_maul/get_cell()
|
||||
return bcell
|
||||
|
||||
/obj/item/weapon/melee/shock_maul/MouseDrop(obj/over_object as obj)
|
||||
if(!canremove)
|
||||
return
|
||||
|
||||
if (ishuman(usr) || issmall(usr)) //so monkeys can take off their backpacks -- Urist
|
||||
|
||||
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech. why?
|
||||
return
|
||||
|
||||
if (!( istype(over_object, /obj/screen) ))
|
||||
return ..()
|
||||
|
||||
//makes sure that the thing is equipped, so that we can't drag it into our hand from miles away.
|
||||
//there's got to be a better way of doing this.
|
||||
if (!(src.loc == usr) || (src.loc && src.loc.loc == usr))
|
||||
return
|
||||
|
||||
if (( usr.restrained() ) || ( usr.stat ))
|
||||
return
|
||||
|
||||
if ((src.loc == usr) && !(istype(over_object, /obj/screen)) && !usr.unEquip(src))
|
||||
return
|
||||
|
||||
switch(over_object.name)
|
||||
if("r_hand")
|
||||
usr.u_equip(src)
|
||||
usr.put_in_r_hand(src)
|
||||
if("l_hand")
|
||||
usr.u_equip(src)
|
||||
usr.put_in_l_hand(src)
|
||||
src.add_fingerprint(usr)
|
||||
|
||||
/obj/item/weapon/melee/shock_maul/loaded/New() //this one starts with a cell pre-installed.
|
||||
..()
|
||||
bcell = new/obj/item/weapon/cell/device/weapon(src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/weapon/melee/shock_maul/proc/deductcharge()
|
||||
if(status == 1) //Only deducts charge when it's on
|
||||
if(bcell)
|
||||
if(bcell.checked_use(hitcost))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
return null
|
||||
|
||||
/obj/item/weapon/melee/shock_maul/proc/powercheck()
|
||||
if(bcell)
|
||||
if(bcell.charge < hitcost)
|
||||
status = 0
|
||||
update_held_icon()
|
||||
|
||||
/obj/item/weapon/melee/shock_maul/update_icon()
|
||||
if(status)
|
||||
icon_state = "[initial(icon_state)]_active[wielded]"
|
||||
item_state = icon_state
|
||||
else if(!bcell)
|
||||
icon_state = "[initial(icon_state)]_nocell[wielded]"
|
||||
item_state = icon_state
|
||||
else
|
||||
icon_state = "[initial(icon_state)][wielded]"
|
||||
item_state = icon_state
|
||||
|
||||
if(icon_state == "[initial(icon_state)]_active[wielded]")
|
||||
set_light(2, 1, lightcolor)
|
||||
else
|
||||
set_light(0)
|
||||
|
||||
/obj/item/weapon/melee/shock_maul/dropped()
|
||||
..()
|
||||
if(status)
|
||||
status = 0
|
||||
visible_message("<span class='warning'>\The [src]'s grip safety engages!</span>")
|
||||
update_held_icon()
|
||||
|
||||
/obj/item/weapon/melee/shock_maul/examine(mob/user)
|
||||
. = ..()
|
||||
|
||||
if(Adjacent(user))
|
||||
if(bcell)
|
||||
. += "<span class='notice'>The concussion maul is [round(bcell.percent())]% charged.</span>"
|
||||
if(!bcell)
|
||||
. += "<span class='warning'>The concussion maul does not have a power source installed.</span>"
|
||||
|
||||
/obj/item/weapon/melee/shock_maul/attackby(obj/item/weapon/W, mob/user)
|
||||
if(!user.IsAdvancedToolUser())
|
||||
return
|
||||
if(istype(W, /obj/item/weapon/cell))
|
||||
if(istype(W, /obj/item/weapon/cell/device))
|
||||
if(!bcell)
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
bcell = W
|
||||
to_chat(user, "<span class='notice'>You install a cell in \the [src].</span>")
|
||||
update_held_icon()
|
||||
else
|
||||
to_chat(user, "<span class='notice'>\The [src] already has a cell.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>This cell is not fitted for [src].</span>")
|
||||
|
||||
/obj/item/weapon/melee/shock_maul/attack_hand(mob/user as mob)
|
||||
if(user.get_inactive_hand() == src)
|
||||
if(!user.IsAdvancedToolUser())
|
||||
return
|
||||
else if(bcell)
|
||||
bcell.update_icon()
|
||||
user.put_in_hands(bcell)
|
||||
bcell = null
|
||||
to_chat(user, "<span class='notice'>You remove the cell from the [src].</span>")
|
||||
status = 0
|
||||
update_held_icon()
|
||||
return
|
||||
..()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/melee/shock_maul/attack_self(mob/user)
|
||||
if(!user.IsAdvancedToolUser())
|
||||
return
|
||||
if(!status && bcell && bcell.charge >= hitcost)
|
||||
if(do_after(user, 2 SECONDS))
|
||||
status = 1
|
||||
user.visible_message("<span class='warning'>[user] charges \the [src]!</span>","<span class='warning'>You charge \the [src]. <b>It's hammer time!</b></span>")
|
||||
playsound(src, "sparks", 75, 1, -1)
|
||||
update_held_icon()
|
||||
else if(status)
|
||||
status = 0
|
||||
user.visible_message("<span class='notice'>[user] safely disengages \the [src]'s power field.</span>","<span class='notice'>\The [src] is now off.</span>")
|
||||
update_held_icon()
|
||||
playsound(src, "sparks", 75, 1, -1)
|
||||
if(!bcell)
|
||||
to_chat(user, "<span class='warning'>\The [src] does not have a power source!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>\The [src] is out of charge.</span>")
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/item/weapon/melee/shock_maul/afterattack(atom/A as mob|obj|turf|area, mob/user as mob, proximity)
|
||||
if(!proximity) return
|
||||
..()
|
||||
if(A && wielded && status)
|
||||
deductcharge()
|
||||
status = 0
|
||||
user.visible_message("<span class='warning'>\The [src] discharges with a thunderous, hair-raising crackle!</span>")
|
||||
playsound(src, 'sound/weapons/resonator_blast.ogg', 100, 1, -1)
|
||||
update_held_icon()
|
||||
if(istype(A,/obj/structure/window))
|
||||
var/obj/structure/window/W = A
|
||||
visible_message("<span class='warning'>\The [W] crumples under the force of the impact!</span>")
|
||||
W.shatter()
|
||||
else if(istype(A,/obj/structure/barricade))
|
||||
var/obj/structure/barricade/B = A
|
||||
B.dismantle()
|
||||
else if(istype(A,/obj/structure/grille))
|
||||
qdel(A)
|
||||
powercheck(hitcost)
|
||||
|
||||
/obj/item/weapon/melee/shock_maul/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone)
|
||||
. = ..()
|
||||
if(user.a_intent == I_DISARM)
|
||||
launch_force *= launch_force_disarm
|
||||
weaken_force *= weaken_force_disarm
|
||||
|
||||
//yeet 'em away, boys!
|
||||
if(status)
|
||||
var/atom/target_zone = get_edge_target_turf(user,get_dir(user, target))
|
||||
if(!target.anchored) //unless they're secured in place, natch
|
||||
target.throw_at(target_zone, launch_force, 2, user, FALSE)
|
||||
target.Weaken(weaken_force)
|
||||
|
||||
deductcharge()
|
||||
status = 0
|
||||
user.visible_message("<span class='warning'>\The [src] discharges with a thunderous, hair-raising crackle!</span>")
|
||||
playsound(src, 'sound/weapons/resonator_blast.ogg', 100, 1, -1)
|
||||
update_held_icon()
|
||||
powercheck(hitcost)
|
||||
|
||||
/obj/item/weapon/melee/shock_maul/emp_act(severity)
|
||||
if(bcell)
|
||||
bcell.emp_act(severity) //let's not duplicate code everywhere if we don't have to please.
|
||||
if(status)
|
||||
status = 0
|
||||
visible_message("<span class='warning'>\The [src]'s power field hisses and sputters out.</span>")
|
||||
update_held_icon()
|
||||
..()
|
||||
|
||||
/obj/item/weapon/melee/shock_maul/get_description_interaction()
|
||||
var/list/results = list()
|
||||
|
||||
if(bcell)
|
||||
results += "[desc_panel_image("offhand")]to remove the weapon cell."
|
||||
else
|
||||
results += "[desc_panel_image("weapon cell")]to add a new weapon cell."
|
||||
|
||||
results += ..()
|
||||
|
||||
return results
|
||||
@@ -73,6 +73,7 @@
|
||||
prob(2);/obj/item/weapon/twohanded/fireaxe,\
|
||||
prob(2);/obj/item/weapon/gun/projectile/luger/brown,\
|
||||
prob(2);/obj/item/weapon/gun/launcher/crossbow,\
|
||||
prob(2);/obj/item/weapon/melee/shock_maul,\
|
||||
/* prob(1);/obj/item/weapon/gun/projectile/automatic/battlerifle,\ */ // Too OP
|
||||
prob(1);/obj/item/weapon/gun/projectile/deagle/gold,\
|
||||
prob(1);/obj/item/weapon/gun/energy/imperial,\
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
list(pick(/obj/item/weapon/grenade/spawnergrenade/spesscarp, /obj/item/weapon/grenade/spawnergrenade/spider, /obj/item/weapon/grenade/explosive/frag), 7) = 1,
|
||||
list(/obj/item/weapon/grenade/flashbang/clusterbang, 7) = 1,
|
||||
list(/obj/item/weapon/card/emag, 11) = 1,
|
||||
list(/obj/item/weapon/melee/shock_maul, 11) = 5,
|
||||
list(/obj/item/weapon/storage/backpack/sport/hyd/catchemall, 11) = 1
|
||||
))
|
||||
var/path = choice[1]
|
||||
|
||||
@@ -97,6 +97,21 @@
|
||||
new outcropdrop(get_turf(src))
|
||||
qdel(src)
|
||||
return
|
||||
if (istype(W, /obj/item/weapon/melee/shock_maul))
|
||||
var/obj/item/weapon/melee/shock_maul/S = W
|
||||
if(!S.wielded || !S.status)
|
||||
to_chat(user, "<span class='warning'>\The [src] must be wielded in two hands and powered on to be used for mining!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You pulverize \the [src]!</span>")
|
||||
for(var/i=0;i<(rand(mindrop,upperdrop));i++)
|
||||
new outcropdrop(get_turf(src))
|
||||
playsound(src, 'sound/weapons/resonator_blast.ogg', 100, 1, -1)
|
||||
user.visible_message("<span class='warning'>\The [S] discharges with a thunderous, hair-raising crackle!</span>")
|
||||
S.deductcharge()
|
||||
S.status = 0
|
||||
S.update_held_icon()
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/random/outcrop //In case you want an outcrop without pre-determining the type of ore.
|
||||
name = "random rock outcrop"
|
||||
|
||||
@@ -380,7 +380,6 @@ var/list/mining_overlay_cache = list()
|
||||
valid_tool = 1
|
||||
digspeed = P.digspeed
|
||||
|
||||
|
||||
if(valid_tool)
|
||||
if (sand_dug)
|
||||
to_chat(user, "<span class='warning'>This area has already been dug.</span>")
|
||||
@@ -451,6 +450,51 @@ var/list/mining_overlay_cache = list()
|
||||
to_chat(user, "<span class='notice'>\The [src] has been excavated to a depth of [excavation_level]cm.</span>")
|
||||
return
|
||||
|
||||
if (istype(W, /obj/item/weapon/melee/shock_maul))
|
||||
if(!istype(user.loc, /turf))
|
||||
return
|
||||
|
||||
var/obj/item/weapon/melee/shock_maul/S = W
|
||||
if(!S.wielded || !S.status) //if we're not wielded OR not powered up, do nothing
|
||||
to_chat(user, "<span class='warning'>\The [src] must be wielded in two hands and powered on to be used for mining!</span>")
|
||||
return
|
||||
|
||||
var/newDepth = excavation_level + S.excavation_amount // Used commonly below
|
||||
|
||||
//handle any archaeological finds we might uncover
|
||||
var/fail_message = ""
|
||||
if(finds && finds.len)
|
||||
var/datum/find/F = finds[1]
|
||||
if(newDepth > F.excavation_required) // Digging too deep can break the item. At least you won't summon a Balrog (probably)
|
||||
fail_message = ". <b>[pick("There is a crunching noise","[S] collides with some different rock","Part of the rock face crumbles away","Something breaks under [S]")]</b>"
|
||||
wreckfinds(S.destroy_artefacts)
|
||||
|
||||
to_chat(user, "<span class='notice'>You smash through \the [src][fail_message].</span>")
|
||||
|
||||
if(newDepth >= 200) // This means the rock is mined out fully
|
||||
if(S.destroy_artefacts)
|
||||
GetDrilled(0)
|
||||
else
|
||||
excavate_turf()
|
||||
return
|
||||
|
||||
excavation_level += S.excavation_amount
|
||||
update_archeo_overlays(S.excavation_amount)
|
||||
|
||||
//drop some rocks
|
||||
next_rock += S.excavation_amount
|
||||
while(next_rock > 50)
|
||||
next_rock -= 50
|
||||
var/obj/item/weapon/ore/O = new(src)
|
||||
geologic_data.UpdateNearbyArtifactInfo(src)
|
||||
O.geologic_data = geologic_data
|
||||
|
||||
user.visible_message("<span class='warning'>\The [src] discharges with a thunderous, hair-raising crackle!</span>")
|
||||
playsound(src, 'sound/weapons/resonator_blast.ogg', 100, 1, -1)
|
||||
S.deductcharge()
|
||||
S.status = 0
|
||||
S.update_held_icon()
|
||||
|
||||
if (istype(W, /obj/item/weapon/pickaxe))
|
||||
if(!istype(user.loc, /turf))
|
||||
return
|
||||
|
||||
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 49 KiB |
@@ -1502,6 +1502,7 @@
|
||||
#include "code\game\objects\items\weapons\melee\energy_vr.dm"
|
||||
#include "code\game\objects\items\weapons\melee\misc.dm"
|
||||
#include "code\game\objects\items\weapons\melee\misc_vr.dm"
|
||||
#include "code\game\objects\items\weapons\melee\shock_maul.dm"
|
||||
#include "code\game\objects\items\weapons\storage\backpack.dm"
|
||||
#include "code\game\objects\items\weapons\storage\backpack_vr.dm"
|
||||
#include "code\game\objects\items\weapons\storage\bags.dm"
|
||||
|
||||