diff --git a/code/modules/projectiles/guns/misc/blastcannon.dm b/code/modules/projectiles/guns/misc/blastcannon.dm new file mode 100644 index 00000000000..f6881208a32 --- /dev/null +++ b/code/modules/projectiles/guns/misc/blastcannon.dm @@ -0,0 +1,130 @@ +/obj/item/gun/blastcannon + name = "pipe gun" + desc = "A pipe welded onto a gun stock, with a mechanical trigger. The pipe has an opening near the top, and there seems to be a spring loaded wheel in the hole." + icon_state = "empty_blastcannon" + var/icon_state_loaded = "loaded_blastcannon" + item_state = "blastcannon_empty" + w_class = WEIGHT_CLASS_NORMAL + force = 10 + fire_sound = 'sound/weapons/blastcannon.ogg' + needs_permit = FALSE + clumsy_check = FALSE + randomspread = FALSE + + var/obj/item/transfer_valve/bomb + +/obj/item/gun/blastcannon/Destroy() + QDEL_NULL(bomb) + return ..() + +/obj/item/gun/blastcannon/attack_self(mob/user) + if(bomb) + bomb.forceMove(user.loc) + user.put_in_hands(bomb) + user.visible_message("[user] detaches [bomb] from [src].") + bomb = null + update_icon() + return ..() + +/obj/item/gun/blastcannon/update_icon() + if(bomb) + icon_state = icon_state_loaded + name = "blast cannon" + desc = "A makeshift device used to concentrate a bomb's blast energy to a narrow wave." + else + icon_state = initial(icon_state) + name = initial(name) + desc = initial(desc) + +/obj/item/gun/blastcannon/attackby(obj/O, mob/user) + if(istype(O, /obj/item/transfer_valve)) + var/obj/item/transfer_valve/T = O + if(!T.tank_one || !T.tank_two) + to_chat(user, "What good would an incomplete bomb do?") + return FALSE + if(!user.drop_item()) + to_chat(user, "[T] seems to be stuck to your hand!") + return FALSE + user.visible_message("[user] attaches [T] to [src]!") + T.forceMove(src) + bomb = T + update_icon() + return TRUE + return ..() + +/obj/item/gun/blastcannon/proc/calculate_bomb() + if(!istype(bomb)||!istype(bomb.tank_one)||!istype(bomb.tank_two)) + return 0 + var/datum/gas_mixture/temp = new() //directional buff. + temp.volume = 60 + temp.merge(bomb.tank_one.air_contents.remove_ratio(1)) + temp.merge(bomb.tank_two.air_contents.remove_ratio(2)) + for(var/i in 1 to 6) + temp.react() + var/pressure = temp.return_pressure() + qdel(temp) + if(pressure < TANK_FRAGMENT_PRESSURE) + return 0 + return (pressure / TANK_FRAGMENT_SCALE) + +/obj/item/gun/blastcannon/afterattack(atom/target, mob/user, flag, params) + if((!bomb) || (!target) || (get_dist(get_turf(target), get_turf(user)) <= 2)) + return ..() + var/power = calculate_bomb() + QDEL_NULL(bomb) + update_icon() + var/heavy = power * 0.2 + var/medium = power * 0.5 + var/light = power + user.visible_message("[user] opens [bomb] on \his [name] and fires a blast wave at [target]!","You open [bomb] on your [name] and fire a blast wave at [target]!") + playsound(user, "explosion", 100, 1) + var/turf/starting = get_turf(user) + var/turf/targturf = get_turf(target) + message_admins("Blast wave fired from [ADMIN_COORDJMP(starting)] ([get_area_name(user, TRUE)]) at [ADMIN_COORDJMP(targturf)] ([target.name]) by [key_name_admin(user)] with power [heavy]/[medium]/[light].") + log_game("Blast wave fired from ([starting.x], [starting.y], [starting.z]) ([get_area_name(user, TRUE)]) at ([target.x], [target.y], [target.z]) ([target]) by [key_name(user)] with power [heavy]/[medium]/[light].") + var/obj/item/projectile/blastwave/BW = new(loc, heavy, medium, light) + BW.preparePixelProjectile(target, get_turf(target), user, params, 0) + BW.fire() + +/obj/item/projectile/blastwave + name = "blast wave" + icon_state = "blastwave" + damage = 0 + nodamage = FALSE + forcedodge = TRUE + range = 150 + var/heavyr = 0 + var/mediumr = 0 + var/lightr = 0 + +/obj/item/projectile/blastwave/New(loc, _h, _m, _l) + ..() + heavyr = _h + mediumr = _m + lightr = _l + +/obj/item/projectile/blastwave/Range() + ..() + var/amount_destruction = 0 + if(heavyr) + amount_destruction = EXPLODE_DEVASTATE + else if(mediumr) + amount_destruction = EXPLODE_HEAVY + else if(lightr) + amount_destruction = EXPLODE_LIGHT + if(amount_destruction && isturf(loc)) + var/turf/T = loc + for(var/thing in T.contents) + var/atom/AM = thing + if(AM && AM.simulated) + AM.ex_act(amount_destruction) + CHECK_TICK + T.ex_act(amount_destruction) + else + qdel(src) + heavyr = max(heavyr - 1, 0) + mediumr = max(mediumr - 1, 0) + lightr = max(lightr - 1, 0) + +/obj/item/projectile/blastwave/ex_act() + return \ No newline at end of file diff --git a/icons/mob/inhands/guns_lefthand.dmi b/icons/mob/inhands/guns_lefthand.dmi index b258ecdfb50..2066f60075a 100644 Binary files a/icons/mob/inhands/guns_lefthand.dmi and b/icons/mob/inhands/guns_lefthand.dmi differ diff --git a/icons/mob/inhands/guns_righthand.dmi b/icons/mob/inhands/guns_righthand.dmi index fb256e34937..9ed3a2ca4bf 100644 Binary files a/icons/mob/inhands/guns_righthand.dmi and b/icons/mob/inhands/guns_righthand.dmi differ diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index a630f68652d..22dc1384904 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index 8c3d0f2c81f..2e1e5d45006 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ diff --git a/paradise.dme b/paradise.dme index a61f6237b46..911114e7912 100644 --- a/paradise.dme +++ b/paradise.dme @@ -2004,6 +2004,7 @@ #include "code\modules\projectiles\guns\energy\telegun.dm" #include "code\modules\projectiles\guns\magic\staff.dm" #include "code\modules\projectiles\guns\magic\wand.dm" +#include "code\modules\projectiles\guns\misc\blastcannon.dm" #include "code\modules\projectiles\guns\projectile\automatic.dm" #include "code\modules\projectiles\guns\projectile\bow.dm" #include "code\modules\projectiles\guns\projectile\launchers.dm" diff --git a/sound/weapons/blastcannon.ogg b/sound/weapons/blastcannon.ogg new file mode 100644 index 00000000000..9b88f3ecf96 Binary files /dev/null and b/sound/weapons/blastcannon.ogg differ