diff --git a/baystation12.dme b/baystation12.dme index d0eae3d008..79ca3efbba 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1109,6 +1109,7 @@ #include "code\modules\projectiles\targeting.dm" #include "code\modules\projectiles\ammunition\boxes.dm" #include "code\modules\projectiles\ammunition\bullets.dm" +#include "code\modules\projectiles\guns\alien.dm" #include "code\modules\projectiles\guns\energy.dm" #include "code\modules\projectiles\guns\projectile.dm" #include "code\modules\projectiles\guns\energy\laser.dm" diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index ac53e05150..7c48dbee0c 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -33,6 +33,8 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \ null, \ new/datum/stack_recipe("canister", /obj/machinery/portable_atmospherics/canister, 10, time = 15, one_per_turf = 1, on_floor = 1), \ null, \ + new/datum/stack_recipe("cannon frame", /obj/item/weapon/cannonframe, 10, time = 15, one_per_turf = 0, on_floor = 0), \ + null, \ new/datum/stack_recipe("floor tile", /obj/item/stack/tile/plasteel, 1, 4, 20), \ new/datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60), \ null, \ @@ -129,6 +131,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \ new/datum/stack_recipe("table parts", /obj/item/weapon/table_parts/wood, 2), \ new/datum/stack_recipe("wooden chair", /obj/structure/stool/bed/chair/wood/normal, 3, time = 10, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("crossbow frame", /obj/item/weapon/crossbowframe, 5, time = 25, one_per_turf = 0, on_floor = 0), \ new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1), \ // new/datum/stack_recipe("apiary", /obj/item/apiary, 10, time = 25, one_per_turf = 0, on_floor = 0) diff --git a/code/modules/admin/verbs/vox_raiders.dm b/code/modules/admin/verbs/vox_raiders.dm index d00435e1fc..941aa8f926 100644 --- a/code/modules/admin/verbs/vox_raiders.dm +++ b/code/modules/admin/verbs/vox_raiders.dm @@ -18,14 +18,9 @@ var/global/vox_tick = 1 equip_to_slot_or_del(new /obj/item/clothing/glasses/thermal/monocle(src), slot_glasses) // REPLACE WITH CODED VOX ALTERNATIVE. equip_to_slot_or_del(new /obj/item/device/chameleon(src), slot_l_store) - var/obj/item/weapon/crossbow/W = new(src) - W.cell = new /obj/item/weapon/cell/crap(W) - W.cell.charge = 500 + var/obj/item/weapon/spikethrower/W = new(src) equip_to_slot_or_del(W, slot_r_hand) - var/obj/item/stack/rods/A = new(src) - A.amount = 20 - equip_to_slot_or_del(A, slot_l_hand) if(2) // Vox engineer! equip_to_slot_or_del(new /obj/item/clothing/suit/space/vox/pressure(src), slot_wear_suit) diff --git a/code/modules/projectiles/guns/alien.dm b/code/modules/projectiles/guns/alien.dm new file mode 100644 index 0000000000..0f5c8400b0 --- /dev/null +++ b/code/modules/projectiles/guns/alien.dm @@ -0,0 +1,115 @@ +//Vox pinning weapon. + +//Ammo. +/obj/item/weapon/spike + name = "alloy spike" + desc = "It's about a foot of weird silver metal with a wicked point." + sharp = 1 + throwforce = 5 + w_class = 2 + icon = 'icons/obj/weapons.dmi' + icon_state = "metal-rod" + item_state = "bolt" + +//Launcher. + +/obj/item/weapon/spikethrower + + name = "Vox spike thrower" + desc = "A vicious alien projectile weapon. Parts of it quiver gelatinously, as though the thing is insectile and alive." + + var/last_regen = 0 + var/spike_gen_time = 100 + var/max_spikes = 3 + var/spikes = 3 + var/obj/item/weapon/spike/spike + var/fire_force = 30 + + //Going to make an effort to get this compatible with the threat targetting system. + var/tmp/list/mob/living/target + var/tmp/mob/living/last_moved_mob + + icon = 'icons/obj/gun.dmi' + icon_state = "spikethrower3" + item_state = "spikethrower" + +/obj/item/weapon/spikethrower/New() + ..() + processing_objects.Add(src) + last_regen = world.time + +/obj/item/weapon/spikethrower/Del() + processing_objects.Remove(src) + ..() + +/obj/item/weapon/spikethrower/process() + + if(spikes < max_spikes && world.time > last_regen + spike_gen_time) + spikes++ + last_regen = world.time + update_icon() + +/obj/item/weapon/spikethrower/examine() + ..() + usr << "It has [spikes] [spikes == 1 ? "spike" : "spikes"] remaining." + +/obj/item/weapon/spikethrower/update_icon() + icon_state = "spikethrower[spikes]" + +/obj/item/weapon/spikethrower/afterattack(atom/A as mob|obj|turf|area, mob/living/user as mob|obj, flag, params) + if(flag) return + if(user && user.client && user.client.gun_mode && !(A in target)) + //TODO: Make this compatible with targetting (prolly have to actually make it a gun subtype, ugh.) + //PreFire(A,user,params) + else + Fire(A,user,params) + +/obj/item/weapon/spikethrower/attack(mob/living/M as mob, mob/living/user as mob, def_zone) + + if (M == user && user.zone_sel.selecting == "mouth") + M.visible_message("\red [user] attempts without success to fit [src] into their mouth.") + return + + if (spikes > 0) + if(user.a_intent == "hurt") + user.visible_message("\red \The [user] fires \the [src] point blank at [M]!") + Fire(M,user) + return + else if(target && M in target) + Fire(M,user) + return + else + return ..() + +/obj/item/weapon/spikethrower/proc/Fire(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, params, reflex = 0) + + add_fingerprint(user) + + var/turf/curloc = get_turf(user) + var/turf/targloc = get_turf(target) + if (!istype(targloc) || !istype(curloc)) + return + + if(istype(user,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = user + if(H.species && H.species.name != "Vox") + user << "\red The weapon does not respond to you!" + return + else + user << "\red The weapon does not respond to you!" + return + + if(spikes <= 0) + user << "\red The weapon has nothing to fire!" + return + + if(!spike) + spike = new(src) //Create a spike. + spike.add_fingerprint(user) + spikes-- + + user.visible_message("\red [user] fires [src]!", "\red You fire [src]!") + spike.loc = get_turf(src) + spike.throw_at(target,10,fire_force) + spike = null + update_icon() \ No newline at end of file diff --git a/code/modules/projectiles/guns/projectile/bow.dm b/code/modules/projectiles/guns/projectile/bow.dm index f422abd04e..3d80063aa6 100644 --- a/code/modules/projectiles/guns/projectile/bow.dm +++ b/code/modules/projectiles/guns/projectile/bow.dm @@ -202,4 +202,88 @@ A.removed(user) arrow = null tension = 0 - icon_state = "crossbow" \ No newline at end of file + icon_state = "crossbow" + +// Crossbow construction. + +/obj/item/weapon/crossbowframe + name = "crossbow frame" + desc = "A half-finished crossbow." + icon_state = "crossbowframe0" + item_state = "crossbow-solid" + + var/buildstate = 0 + +/obj/item/weapon/crossbowframe/update_icon() + icon_state = "crossbowframe[buildstate]" + +/obj/item/weapon/crossbowframe/examine() + ..() + switch(buildstate) + if(1) usr << "It has a loose rod frame in place." + if(2) usr << "It has a steel backbone welded in place." + if(3) usr << "It has a steel backbone and a cell mount installed." + if(4) usr << "It has a steel backbone, plastic lath and a cell mount installed." + if(5) usr << "It has a steel cable loosely strung across the lath." + +/obj/item/weapon/crossbowframe/attackby(obj/item/W as obj, mob/user as mob) + if(istype(W,/obj/item/stack/rods)) + if(buildstate == 0) + var/obj/item/stack/rods/R = W + if(R.amount >= 3) + R.use(3) + user << "\blue You assemble a backbone of rods around the wooden stock." + buildstate++ + update_icon() + else + user << "\blue You need at least three rods to complete this task." + return + else if(istype(W,/obj/item/weapon/weldingtool)) + if(buildstate == 1) + var/obj/item/weapon/weldingtool/T = W + if(T.remove_fuel(0,user)) + if(!src || !T.isOn()) return + playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1) + user << "\blue You weld the rods into place." + buildstate++ + update_icon() + return + else if(istype(W,/obj/item/weapon/cable_coil)) + var/obj/item/weapon/cable_coil/C = W + if(buildstate == 2) + if(C.amount >= 5) + C.use(5) + user << "\blue You wire a crude cell mount into the top of the crossbow." + buildstate++ + update_icon() + else + user << "\blue You need at least five segments of cable coil to complete this task." + return + else if(buildstate == 4) + if(C.amount >= 5) + C.use(5) + user << "\blue You string a steel cable across the crossbow's lath." + buildstate++ + update_icon() + else + user << "\blue You need at least five segments of cable coil to complete this task." + return + else if(istype(W,/obj/item/stack/sheet/mineral/plastic)) + if(buildstate == 3) + var/obj/item/stack/sheet/mineral/plastic/P = W + if(P.amount >= 3) + P.use(3) + user << "\blue You assemble and install a heavy plastic lath onto the crossbow." + buildstate++ + update_icon() + else + user << "\blue You need at least three plastic sheets to complete this task." + return + else if(istype(W,/obj/item/weapon/screwdriver)) + if(buildstate == 5) + user << "\blue You secure the crossbow's various parts." + new /obj/item/weapon/crossbow(get_turf(src)) + del(src) + return + else + ..() \ No newline at end of file diff --git a/code/modules/projectiles/guns/projectile/pneumatic.dm b/code/modules/projectiles/guns/projectile/pneumatic.dm index 9924e3d93f..43c1fed24a 100644 --- a/code/modules/projectiles/guns/projectile/pneumatic.dm +++ b/code/modules/projectiles/guns/projectile/pneumatic.dm @@ -20,6 +20,9 @@ var/force_divisor = 400 // Force equates to speed. Speed/5 equates to a damage multiplier for whoever you hit. // For reference, a fully pressurized oxy tank at 50% gas release firing a health // analyzer with a force_divisor of 10 hit with a damage multiplier of 3000+. +/obj/item/weapon/storage/pneumatic/New() + ..() + tank_container.tag = "gas_tank_holder" /obj/item/weapon/storage/pneumatic/verb/set_pressure() //set amount of tank pressure. @@ -138,3 +141,82 @@ spawn(cooldown_time) cooldown = 0 user << "[src]'s gauge informs you it's ready to be fired again." + +//Constructable pneumatic cannon. + +/obj/item/weapon/cannonframe + name = "pneumatic cannon frame" + desc = "A half-finished pneumatic cannon." + icon_state = "pneumatic0" + item_state = "pneumatic" + + var/buildstate = 0 + +/obj/item/weapon/cannonframe/update_icon() + icon_state = "pneumatic[buildstate]" + +/obj/item/weapon/cannonframe/examine() + ..() + switch(buildstate) + if(1) usr << "It has a pipe segment installed." + if(2) usr << "It has a pipe segment welded in place." + if(3) usr << "It has an outer chassis installed." + if(4) usr << "It has an outer chassis welded in place." + if(5) usr << "It has a transfer valve installed." + +/obj/item/weapon/cannonframe/attackby(obj/item/W as obj, mob/user as mob) + if(istype(W,/obj/item/pipe)) + if(buildstate == 0) + user.drop_item() + del(W) + user << "\blue You secure the piping inside the frame." + buildstate++ + update_icon() + return + else if(istype(W,/obj/item/stack/sheet/metal)) + if(buildstate == 2) + var/obj/item/stack/sheet/metal/M = W + if(M.amount >= 5) + M.use(5) + user << "\blue You assemble a chassis around the cannon frame." + buildstate++ + update_icon() + else + user << "\blue You need at least five metal sheets to complete this task." + return + else if(istype(W,/obj/item/device/transfer_valve)) + if(buildstate == 4) + user.drop_item() + del(W) + user << "\blue You install the transfer valve and connect it to the piping." + buildstate++ + update_icon() + return + else if(istype(W,/obj/item/weapon/weldingtool)) + if(buildstate == 1) + var/obj/item/weapon/weldingtool/T = W + if(T.remove_fuel(0,user)) + if(!src || !T.isOn()) return + playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1) + user << "\blue You weld the pipe into place." + buildstate++ + update_icon() + if(buildstate == 3) + var/obj/item/weapon/weldingtool/T = W + if(T.remove_fuel(0,user)) + if(!src || !T.isOn()) return + playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1) + user << "\blue You weld the metal chassis together." + buildstate++ + update_icon() + if(buildstate == 5) + var/obj/item/weapon/weldingtool/T = W + if(T.remove_fuel(0,user)) + if(!src || !T.isOn()) return + playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1) + user << "\blue You weld the valve into place." + new /obj/item/weapon/storage/pneumatic(get_turf(src)) + del(src) + return + else + ..() \ No newline at end of file diff --git a/icons/obj/gun.dmi b/icons/obj/gun.dmi index ece6723b62..da0f145433 100644 Binary files a/icons/obj/gun.dmi and b/icons/obj/gun.dmi differ