mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-30 00:21:11 +01:00
Shooting Target Refactor (#11186)
This commit is contained in:
@@ -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
|
||||
@@ -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 ..()
|
||||
Reference in New Issue
Block a user