Crossbows and piescannons

This commit is contained in:
TheDZD
2016-06-02 22:17:19 -04:00
parent c51e6674cb
commit f17f4ccdeb
14 changed files with 337 additions and 5 deletions
+19 -1
View File
@@ -200,4 +200,22 @@
time = 15
reqs = list(/obj/item/stack/sheet/wood = 1,
/obj/item/stack/cable_coil = 5)
tools = list(/obj/item/weapon/kitchen/knife) // Gotta carve the wood into handles
tools = list(/obj/item/weapon/kitchen/knife) // Gotta carve the wood into handles
/datum/table_recipe/makeshift_bolt
name = "Makeshift Bolt"
result = /obj/item/weapon/arrow/rod
time = 15
reqs = list(/obj/item/stack/rods = 1)
tools = list(/obj/item/weapon/weldingtool)
/datum/table_recipe/crossbow
name = "Powered Crossbow"
result = /obj/item/weapon/gun/throw/crossbow
time = 300
reqs = list(/obj/item/stack/rods = 3,
/obj/item/stack/cable_coil = 10,
/obj/item/stack/sheet/mineral/plastic = 3,
/obj/item/stack/sheet/wood = 5)
tools = list(/obj/item/weapon/weldingtool,
/obj/item/weapon/screwdriver)
@@ -24,10 +24,12 @@
qdel(D)
rockets = null
return ..()
/obj/item/weapon/gun/rocketlauncher/update_icon()
return
/obj/item/weapon/gun/rocketlauncher/attackby(obj/item/I as obj, mob/user as mob, params)
/obj/item/weapon/gun/rocketlauncher/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/ammo_casing/rocket))
if(rockets.len < max_rockets)
user.drop_item()
@@ -52,6 +54,5 @@
log_game("[key_name_admin(user)] used a rocket launcher ([name]).")
rockets -= I
qdel(I)
return
else
to_chat(usr, "<span class='warning'>[src] is empty.</span>")
+93
View File
@@ -0,0 +1,93 @@
/obj/item/weapon/gun/throw
name = "abstract item thrower"
desc = "This shouldn't be here, yell at a coder."
fire_sound = 'sound/weapons/punchmiss.ogg'
fire_sound_text = "thwock"
var/obj/item/to_launch
var/list/valid_projectile_type
var/max_capacity = 1
var/list/loaded_projectiles = list()
var/projectile_speed = 1
var/projectile_range = 1
/obj/item/weapon/gun/throw/proc/notify_ammo_count(mob/user)
return
/obj/item/weapon/gun/throw/proc/get_throwrange()
return projectile_speed
/obj/item/weapon/gun/throw/proc/get_throwspeed()
return projectile_range
/obj/item/weapon/gun/throw/proc/modify_projectile(obj/item/I, on_chamber = 0)
return
/obj/item/weapon/gun/throw/proc/get_ammocount(include_loaded = 1)
var/count = loaded_projectiles.len
if(include_loaded && to_launch)
count++
return count
/obj/item/weapon/gun/throw/examine(mob/user)
..()
to_chat(user, "<span class='notice'>It is [to_launch ? "loaded with \a [to_launch]" : "not loaded"].</span>")
notify_ammo_count(user)
/obj/item/weapon/gun/throw/Destroy()
qdel(to_launch)
to_launch = null
for(var/atom/A in loaded_projectiles)
qdel(A)
loaded_projectiles = null
return ..()
/obj/item/weapon/gun/throw/update_icon()
return
/obj/item/weapon/gun/throw/attackby(obj/item/I, mob/user, params)
if(istype(I, valid_projectile_type) && !(I.flags & NODROP))
if(get_ammocount() < max_capacity)
user.drop_item()
I.forceMove(src)
loaded_projectiles += I
to_chat(user, "<span class='notice'>You load [I] into [src].</span>")
if(!to_launch)
process_chamber()
notify_ammo_count(user)
else
to_chat(user, "<span class='warning'>[src] cannot hold any more projectiles.</span>")
else
to_chat(user, "<span class='warning'>You cannot load [I] into [src]!</span>")
/obj/item/weapon/gun/throw/process_chamber()
if(!to_launch && loaded_projectiles.len)
to_launch = loaded_projectiles[1]
loaded_projectiles -= to_launch
return
/obj/item/weapon/gun/throw/can_shoot()
if(to_launch)
return 1
return 0
/obj/item/weapon/gun/throw/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override)
add_fingerprint(user)
if(semicd)
return
var/obj/item/I = to_launch
I.forceMove(get_turf(src))
to_launch = null
modify_projectile(I)
playsound(user, fire_sound, 50, 1)
I.throw_at(target, get_throwrange(), get_throwspeed(), user, 1)
message_admins("[key_name_admin(user)] fired \a [I] from a [src].")
log_game("[key_name_admin(user)] used \a [src].")
process_chamber()
semicd = 1
spawn(fire_delay)
semicd = 0
@@ -0,0 +1,181 @@
#define XBOW_TENSION_20 "20%"
#define XBOW_TENSION_40 "40%"
#define XBOW_TENSION_60 "60%"
#define XBOW_TENSION_80 "80%"
#define XBOW_TENSION_FULL "100%"
/obj/item/weapon/gun/throw/crossbow
name = "powered crossbow"
desc = "A modern twist on an old classic. Pick up that can."
icon_state = "crossbow"
item_state = "crossbow-solid"
fire_sound_text = "a solid thunk"
fire_delay = 25
valid_projectile_type = /obj/item/weapon/arrow
var/tension = 0
var/drawtension = 5
var/maxtension = 5
var/speed_multiplier = 5
var/range_multiplier = 3
var/obj/item/weapon/stock_parts/cell/cell = null // Used for firing superheated rods.
var/list/possible_tensions = list(XBOW_TENSION_20, XBOW_TENSION_40, XBOW_TENSION_60, XBOW_TENSION_80, XBOW_TENSION_FULL)
/obj/item/weapon/gun/throw/crossbow/emp_act(severity)
if(cell && severity)
emp_act(severity)
/obj/item/weapon/gun/throw/crossbow/update_icon()
if(!tension)
if(!to_launch)
icon_state = "[initial(icon_state)]"
else
icon_state = "[initial(icon_state)]-nocked"
else
icon_state = "[initial(icon_state)]-drawn"
/obj/item/weapon/gun/throw/crossbow/examine(mob/user)
..()
if(cell)
to_chat(user, "<span class='notice'>\A [cell] is mounted onto [src]. Battery cell charge: [cell.charge]/[cell.maxcharge]")
else
to_chat(user, "<span class='notice'>It has an empty mount for a battery cell.</span>")
/obj/item/weapon/gun/throw/crossbow/modify_projectile(obj/item/I, on_chamber = 0)
if(cell && on_chamber && istype(I, /obj/item/weapon/arrow/rod))
var/obj/item/weapon/arrow/rod/R = I
visible_message("<span class='danger'>[R] plinks and crackles as it begins to glow red-hot.</span>")
R.throwforce = 15
R.superheated = 1
cell.use(500)
/obj/item/weapon/gun/throw/crossbow/get_throwspeed()
return tension * speed_multiplier
/obj/item/weapon/gun/throw/crossbow/get_throwrange()
return tension * range_multiplier
/obj/item/weapon/gun/throw/crossbow/process_chamber()
..()
if(to_launch)
modify_projectile(to_launch, 1)
update_icon()
/obj/item/weapon/gun/throw/crossbow/attack_self(mob/living/user)
if(tension)
if(to_launch)
user.visible_message("<span class='notice'>[user] relaxes the tension on [src]'s string and removes [to_launch].</span>","<span class='notice'>You relax the tension on [src]'s string and remove [to_launch].</span>")
to_launch.forceMove(get_turf(src))
var/obj/item/weapon/arrow/A = to_launch
to_launch = null
A.removed()
process_chamber()
else
user.visible_message("<span class='notice'>[user] relaxes the tension on [src]'s string.</span>","<span class='notice'>You relax the tension on [src]'s string.</span>")
tension = 0
update_icon()
else
draw(user)
/obj/item/weapon/gun/throw/crossbow/proc/draw(mob/living/user)
if(user.incapacitated())
return
if(!to_launch)
to_chat(user, "<span class='warning'>You can't draw [src] without a bolt nocked.</span>")
return
user.visible_message("[user] begins to draw back the string of [src].","You begin to draw back the string of [src].")
if(do_after(user, 25 * drawtension, target = user))
tension = drawtension
user.visible_message("[usr] draws back the string of [src]!","[src] clunks as you draw the string to its maximum tension!!")
update_icon()
/obj/item/weapon/gun/throw/crossbow/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/weapon/stock_parts/cell))
if(!cell)
user.drop_item()
W.loc = src
cell = W
to_chat(user, "<span class='notice'>You jam [cell] into [src] and wire it to the firing coil.</span>")
process_chamber()
else
to_chat(user, "<span class='notice'>[src] already has a cell installed.</span>")
else if(istype(W, /obj/item/weapon/screwdriver))
if(cell)
cell.loc = get_turf(src)
to_chat(user, "<span class='notice'>You jimmy [cell] out of [src] with [W].</span>")
cell = null
else
to_chat(user, "<span class='notice'>[src] doesn't have a cell installed.</span>")
else
..()
/obj/item/weapon/gun/throw/crossbow/verb/set_tension()
set name = "Adjust Tension"
set category = "Object"
set src in range(0)
var/mob/user = usr
if(user.incapacitated())
return
var/choice = input("Select tension to draw to:", "[src]", XBOW_TENSION_FULL) as null|anything in possible_tensions
if(!choice)
return
switch(choice)
if(XBOW_TENSION_20)
drawtension = Ceiling(0.2 * maxtension)
if(XBOW_TENSION_40)
drawtension = Ceiling(0.4 * maxtension)
if(XBOW_TENSION_60)
drawtension = Ceiling(0.6 * maxtension)
if(XBOW_TENSION_80)
drawtension = Ceiling(0.8 * maxtension)
if(XBOW_TENSION_FULL)
drawtension = maxtension
/obj/item/weapon/gun/throw/crossbow/process_fire(atom/target as mob|obj|turf, mob/living/user as mob|obj, message = 1, params, zone_override)
..()
tension = 0
update_icon()
/obj/item/weapon/gun/throw/crossbow/french
name = "french powered crossbow"
icon_state = "fcrossbow"
valid_projectile_type = /obj/item/weapon/reagent_containers/food/snacks/baguette
/obj/item/weapon/gun/throw/crossbow/french/modify_projectile(obj/item/I, on_chamber = 0)
return
/obj/item/weapon/arrow
name = "bolt"
desc = "It's got a tip for you - get the point?"
icon_state = "bolt"
item_state = "bolt"
throwforce = 20
w_class = 3.0
sharp = 1
edge = 0
/obj/item/weapon/arrow/proc/removed() //Helper for metal rods falling apart.
return
/obj/item/weapon/arrow/rod
name = "makeshift bolt"
desc = "A sharpened metal rod that can be fired out of a crossbow."
icon_state = "metal-rod"
throwforce = 8
var/superheated = 0
/obj/item/weapon/arrow/rod/removed()
if(superheated) // The rod has been superheated - we don't want it to be useable when removed from the bow.
visible_message("[src] shatters into a scattering of overstressed metal shards as it leaves the crossbow.")
var/obj/item/weapon/shard/shrapnel/S = new /obj/item/weapon/shard/shrapnel
S.loc = get_turf(src)
qdel(src)
#undef XBOW_TENSION_20
#undef XBOW_TENSION_40
#undef XBOW_TENSION_60
#undef XBOW_TENSION_80
#undef XBOW_TENSION_FULL
@@ -0,0 +1,36 @@
/obj/item/weapon/gun/throw/piecannon
name = "pie cannon"
desc = "A projectile weapon that fires pies."
icon_state = "piecannon"
w_class = 5
throw_speed = 2
throw_range = 3
force = 5
clumsy_check = 0
valid_projectile_type = /obj/item/weapon/reagent_containers/food/snacks/pie
max_capacity = 5
projectile_speed = 2
projectile_range = 30
/obj/item/weapon/gun/throw/piecannon/New()
..()
for(var/i in 1 to max_capacity)
var/obj/item/weapon/reagent_containers/food/snacks/pie/P = new /obj/item/weapon/reagent_containers/food/snacks/pie(src)
loaded_projectiles += P
process_chamber()
/obj/item/weapon/gun/throw/piecannon/notify_ammo_count(mob/user)
to_chat(user, "<span class='notice'>[src] has [get_ammocount()] of [max_capacity] pies left.")
/obj/item/weapon/gun/throw/piecannon/update_icon()
if(to_launch)
icon_state = "piecannon1"
else
icon_state = "piecannon0"
item_state = icon_state
/obj/item/weapon/gun/throw/piecannon/process_chamber()
..()
update_icon()
@@ -178,6 +178,7 @@
stun = 5
forcedodge = 1
nodamage = 1
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
hitsound = 'sound/items/bikehorn.ogg'
icon = 'icons/obj/harvest.dmi'
icon_state = "banana"