Shooting Target Refactor (#11186)

This commit is contained in:
Geeves
2021-04-06 23:13:08 -03:00
committed by GitHub
parent f631f478fa
commit dbe0b00838
7 changed files with 148 additions and 154 deletions
+72 -113
View File
@@ -1,115 +1,76 @@
#define DECAL_SCORCH 1
#define DECAL_BULLET 2
// Targets, the things that actually get shot!
/obj/item/target
name = "shooting target"
desc = "A shooting target."
icon = 'icons/obj/target_stake.dmi'
icon_state = "target_h"
density = 0
var/obj/structure/target_stake/stake
var/hp = 1800
var/icon/virtualIcon
var/list/bulletholes = list()
var/icon/virtual_icon
var/list/bullet_holes
Destroy()
// if a target is deleted and associated with a stake, force stake to forget
for(var/obj/structure/target_stake/T in view(3,src))
if(T.pinned_target == src)
T.pinned_target = null
T.density = 1
break
return ..() // delete target
/obj/item/target/Destroy()
if(stake)
stake.set_target(null)
return ..()
Move()
..()
// After target moves, check for nearby stakes. If associated, move to target
for(var/obj/structure/target_stake/M in view(3,src))
if(M.density == 0 && M.pinned_target == src)
M.forceMove(loc)
/obj/item/target/attackby(var/obj/item/W, var/mob/user)
if(W.iswelder())
if(hp == initial(hp))
to_chat(user, SPAN_NOTICE("\The [src] is fully repaired."))
return
var/obj/item/weldingtool/WT = W
if(WT.remove_fuel(0, user))
cut_overlays()
LAZYCLEARLIST(bullet_holes)
icon = initial(icon)
hp = initial(hp)
to_chat(user, SPAN_NOTICE("You slice off \the [src]'s uneven chunks of steel and scorch marks."))
return
// This may seem a little counter-intuitive but I assure you that's for a purpose.
// Stakes are the ones that carry targets, yes, but in the stake code we set
// a stake's density to 0 meaning it can't be pushed anymore. Instead of pushing
// the stake now, we have to push the target.
/obj/item/target/attack_hand(var/mob/user)
// taking pinned targets off!
if(stake)
stake.attack_hand(user)
else
return ..()
/obj/item/target/syndicate
icon_state = "target_s"
desc = "A shooting target that looks like a hostile agent."
hp = 2600 // i guess syndie targets are sturdier?
attackby(obj/item/W as obj, mob/user as mob)
if (W.iswelder())
var/obj/item/weldingtool/WT = W
if(WT.remove_fuel(0, user))
cut_overlays()
to_chat(usr, "You slice off [src]'s uneven chunks of aluminum and scorch marks.")
return
attack_hand(mob/user as mob)
// taking pinned targets off!
var/obj/structure/target_stake/stake
for(var/obj/structure/target_stake/T in view(3,src))
if(T.pinned_target == src)
stake = T
break
if(stake)
if(stake.pinned_target)
stake.density = 1
density = 0
layer = OBJ_LAYER
loc = user.loc
if(ishuman(user))
if(!user.get_active_hand())
user.put_in_hands(src)
to_chat(user, "You take the target out of the stake.")
else
src.forceMove(get_turf(user))
to_chat(user, "You take the target out of the stake.")
stake.pinned_target = null
return
else
..()
syndicate
icon_state = "target_s"
desc = "A shooting target that looks like a hostile agent."
hp = 2600 // i guess syndie targets are sturdier?
alien
icon_state = "target_q"
desc = "A shooting target with a threatening silhouette."
hp = 2350 // alium onest too kinda
/obj/item/target/alien
icon_state = "target_q"
desc = "A shooting target with a threatening silhouette."
hp = 2350 // alium onest too kinda
/obj/item/target/bullet_act(var/obj/item/projectile/Proj)
var/p_x = Proj.p_x + pick(0,0,0,0,0,-1,1) // really ugly way of coding "sometimes offset Proj.p_x!"
var/p_y = Proj.p_y + pick(0,0,0,0,0,-1,1)
var/decaltype = 1 // 1 - scorch, 2 - bullet
var/decaltype = (Proj.damage_flags & DAM_BULLET) ? DECAL_BULLET : DECAL_SCORCH
if(istype(/obj/item/projectile/bullet, Proj))
decaltype = 2
virtualIcon = new(icon, icon_state)
if( virtualIcon.GetPixel(p_x, p_y) ) // if the located pixel isn't blank (null)
virtual_icon = new(icon, icon_state)
if(virtual_icon.GetPixel(p_x, p_y)) // if the located pixel isn't blank (null)
hp -= Proj.damage
if(hp <= 0)
for(var/mob/O in oviewers())
if ((O.client && !( O.blinded )))
to_chat(O, "<span class='warning'>\The [src] breaks into tiny pieces and collapses!</span>")
visible_message(SPAN_WARNING("\The [src] breaks into tiny pieces and collapses!"))
qdel(src)
return
// Create a temporary object to represent the damage
var/obj/bmark = new
bmark.pixel_x = p_x
bmark.pixel_y = p_y
bmark.icon = 'icons/effects/effects.dmi'
bmark.layer = 3.5
bmark.layer = ABOVE_OBJ_LAYER
bmark.icon_state = "scorch"
if(decaltype == 1)
// Energy weapons are hot. they scorch!
if(decaltype == DECAL_SCORCH) // Energy weapons are hot. they scorch!
// offset correction
bmark.pixel_x--
bmark.pixel_y--
@@ -117,33 +78,27 @@
if(Proj.damage >= 20 || istype(Proj, /obj/item/projectile/beam/practice))
bmark.icon_state = "scorch"
bmark.set_dir(pick(NORTH,SOUTH,EAST,WEST)) // random scorch design
else
bmark.icon_state = "light_scorch"
else
// Bullets are hard. They make dents!
else // Bullets are hard. They make dents!
bmark.icon_state = "dent"
if(Proj.damage >= 10 && bulletholes.len <= 35) // maximum of 35 bullet holes
if(decaltype == 2) // bullet
if(Proj.damage >= 10 && length(bullet_holes) <= 35) // maximum of 35 bullet holes
if(decaltype == DECAL_BULLET)
if(prob(Proj.damage+30)) // bullets make holes more commonly!
new/datum/bullethole(src, bmark.pixel_x, bmark.pixel_y) // create new bullet hole
new /datum/bullethole(src, bmark.pixel_x, bmark.pixel_y) // create new bullet hole
else // Lasers!
if(prob(Proj.damage-10)) // lasers make holes less commonly
new/datum/bullethole(src, bmark.pixel_x, bmark.pixel_y) // create new bullet hole
new /datum/bullethole(src, bmark.pixel_x, bmark.pixel_y) // create new bullet hole
// draw bullet holes
for(var/datum/bullethole/B in bulletholes)
for(var/datum/bullethole/B in bullet_holes)
virtual_icon.DrawBox(null, B.b1x1, B.b1y, B.b1x2, B.b1y) // horizontal line, left to right
virtual_icon.DrawBox(null, B.b2x, B.b2y1, B.b2x, B.b2y2) // vertical line, top to bottom
virtualIcon.DrawBox(null, B.b1x1, B.b1y, B.b1x2, B.b1y) // horizontal line, left to right
virtualIcon.DrawBox(null, B.b2x, B.b2y1, B.b2x, B.b2y2) // vertical line, top to bottom
add_overlay(bmark) // add the decal
icon = virtualIcon // apply bulletholes over decals
icon = virtual_icon // apply bullet_holes over decals
return
return PROJECTILE_CONTINUE // the bullet/projectile goes through the target!
@@ -161,21 +116,25 @@
var/b2y1 = 0
var/b2y2 = 0
New(var/obj/item/target/Target, var/pixel_x = 0, var/pixel_y = 0)
if(!Target) return
/datum/bullethole/New(var/obj/item/target/Target, var/pixel_x = 0, var/pixel_y = 0)
if(!Target)
return
// Randomize the first box
b1x1 = pixel_x - pick(1,1,1,1,2,2,3,3,4)
b1x2 = pixel_x + pick(1,1,1,1,2,2,3,3,4)
b1y = pixel_y
if(prob(35))
b1y += rand(-4,4)
// Randomize the first box
b1x1 = pixel_x - pick(1,1,1,1,2,2,3,3,4)
b1x2 = pixel_x + pick(1,1,1,1,2,2,3,3,4)
b1y = pixel_y
if(prob(35))
b1y += rand(-4,4)
// Randomize the second box
b2x = pixel_x
if(prob(35))
b2x += rand(-4,4)
b2y1 = pixel_y + pick(1,1,1,1,2,2,3,3,4)
b2y2 = pixel_y - pick(1,1,1,1,2,2,3,3,4)
// Randomize the second box
b2x = pixel_x
if(prob(35))
b2x += rand(-4,4)
b2y1 = pixel_y + pick(1,1,1,1,2,2,3,3,4)
b2y2 = pixel_y - pick(1,1,1,1,2,2,3,3,4)
Target.bulletholes.Add(src)
LAZYADD(Target.bullet_holes, src)
#undef DECAL_SCORCH
#undef DECAL_BULLET
+50 -41
View File
@@ -1,53 +1,62 @@
// Basically they are for the firing range
// Target stakes for the firing range.
/obj/structure/target_stake
name = "target stake"
desc = "A thin platform with negatively-magnetized wheels."
icon = 'icons/obj/target_stake.dmi'
icon_state = "target_stake"
density = 1
w_class = ITEMSIZE_HUGE
flags = CONDUCT
var/obj/item/target/pinned_target // the current pinned target
density = TRUE
w_class = ITEMSIZE_IMMENSE
build_amt = 10
var/obj/item/target/pinned_target
Move()
..()
// Move the pinned target along with the stake
if(pinned_target in view(3, src))
pinned_target.forceMove(loc)
/obj/structure/target_stake/Initialize(mapload)
. = ..()
material = SSmaterials.get_material_by_name(MATERIAL_STEEL)
else // Sanity check: if the pinned target can't be found in immediate view
pinned_target = null
density = 1
attackby(obj/item/W as obj, mob/user as mob)
// Putting objects on the stake. Most importantly, targets
/obj/structure/target_stake/attackby(var/obj/item/W, var/mob/user)
if(istype(W, /obj/item/target))
if(pinned_target)
return // get rid of that pinned target first!
if(istype(W, /obj/item/target))
density = 0
W.density = 1
user.remove_from_mob(W)
W.forceMove(loc)
W.layer = 3.1
pinned_target = W
to_chat(user, "You slide the target into the stake.")
to_chat(user, SPAN_WARNING("\The [src] already has a target."))
return
if(user.unEquip(W, FALSE, get_turf(src)))
to_chat(user, SPAN_NOTICE("You slide \the [W] into the stake."))
set_target(W)
return
attack_hand(mob/user as mob)
// taking pinned targets off!
if(W.iswrench())
if(pinned_target)
density = 1
pinned_target.density = 0
to_chat(user, SPAN_WARNING("You cannot dismantle \the [src] while it has a target attached."))
return
dismantle()
/obj/structure/target_stake/attack_hand(var/mob/user)
. = ..()
if(pinned_target && ishuman(user))
var/obj/item/target/T = pinned_target
to_chat(user, SPAN_NOTICE("You take \the [T] out of the stake."))
set_target(null)
user.put_in_hands(T)
/obj/structure/target_stake/proc/set_target(var/obj/item/target/T)
if(T)
density = FALSE
T.density = TRUE
T.pixel_x = 0
T.pixel_y = 0
T.layer = ABOVE_OBJ_LAYER
moved_event.register(T, src, /atom/movable/proc/move_to_turf)
moved_event.register(src, T, /atom/movable/proc/move_to_turf)
T.stake = src
pinned_target = T
else
density = TRUE
if(pinned_target)
pinned_target.density = FALSE
pinned_target.layer = OBJ_LAYER
moved_event.unregister(pinned_target, src)
moved_event.unregister(src, pinned_target)
pinned_target.stake = null
pinned_target = null
pinned_target.forceMove(user.loc)
if(ishuman(user))
if(!user.get_active_hand())
user.put_in_hands(pinned_target)
to_chat(user, "You take the target out of the stake.")
else
pinned_target.forceMove(get_turf(user))
to_chat(user, "You take the target out of the stake.")
pinned_target = null
/obj/structure/target_stake/Destroy()
set_target(null)
return ..()