Files
Bubberstation/code/modules/projectiles/projectile/bullets/special.dm
Bloop 5961aa3b53 Fixes improper static list declarations + adds grep for it (#87207)
## About The Pull Request

I randomly came across a `var/list/static` in the code, which does not
actually do what was intended, and thought it was silly. A ctrl+f
revealed that this was a fairly common mistake, so I went and fixed all
the instances of it I could find.

~~Including one in lighting code, which it looked like they were trying
to create a global list to cache generated lighting sheet values for
speed, but it was just a normal list that got created each time
pointlessly. Now those values are actually being cached (using a global
var, because a `static` list was not the right thing to use there in the
first place).~~

Nevermind, it seems that this was in fact being cached even if it
shouldn't have been, because byond. Just rearranged it there seeing as
it works either way.

## Why It's Good For The Game

Code that does what it's supposed to

## Changelog

🆑
fix: fixes a bunch of improper static list declarations
/🆑
# Conflicts:
#	code/game/objects/items/kirby_plants/kirbyplants.dm
2024-11-16 00:44:53 -08:00

213 lines
7.7 KiB
Plaintext

// Honker
/obj/projectile/bullet/honker
name = "banana"
damage = 0
movement_type = FLYING
projectile_piercing = ALL
hitsound = 'sound/items/bikehorn.ogg'
icon = 'icons/obj/service/hydroponics/harvest.dmi'
icon_state = "banana"
range = 200
embed_type = null
shrapnel_type = null
/obj/projectile/bullet/honker/Initialize(mapload)
. = ..()
SpinAnimation()
/obj/projectile/bullet/honker/on_hit(atom/target, blocked = 0, pierce_hit)
. = ..()
var/mob/M = target
if(istype(M))
if(M.can_block_magic())
return BULLET_ACT_BLOCK
else
M.slip(100, M.loc, GALOSHES_DONT_HELP|SLIDE, 0, FALSE)
// Mime
/obj/projectile/bullet/mime
damage = 40
/obj/projectile/bullet/mime/on_hit(atom/target, blocked = 0, pierce_hit)
. = ..()
if(!isliving(target))
return
var/mob/living/living_target = target
living_target.set_silence_if_lower(20 SECONDS)
// Marksman Revolver + Ricochet Coin
/// Marksman Shot
/obj/projectile/bullet/marksman
name = "marksman nanoshot"
hitscan = TRUE
damage = 30
tracer_type = /obj/effect/projectile/tracer/solar
muzzle_type = /obj/effect/projectile/muzzle/bullet
impact_type = /obj/effect/projectile/impact/sniper
/// How many ricochets deep this is, for tracer size
var/ricoshot_level = 0
/obj/projectile/bullet/marksman/Initialize(mapload, obj/item/ammo_casing/casing, incoming_ricoshot_level)
. = ..()
if(isnum(incoming_ricoshot_level))
ricoshot_level = incoming_ricoshot_level
switch(ricoshot_level)
if(0)
tracer_type = /obj/effect/projectile/tracer/solar/thinnest
if(1)
tracer_type = /obj/effect/projectile/tracer/solar/thin
if(2 to INFINITY)
tracer_type = /obj/effect/projectile/tracer/solar
/obj/projectile/bullet/marksman/scan_moved_turf()
var/turf/cur_turf = get_turf(src) // check to see if we're passing over a turf with a coin on it
var/obj/projectile/bullet/coin/coin_check = cur_turf ? locate(/obj/projectile/bullet/coin) in cur_turf.contents : null
if(!coin_check || (ricoshot_level == 0 && get_dist(coin_check.target_turf, coin_check) >= 1) || coin_check.used) // no coin, keep trucking
return ..()
coin_check.check_splitshot(firer, src)
Impact(coin_check)
/// Marksman Coin
/obj/projectile/bullet/coin
name = "marksman coin"
icon_state = "coinshot"
pixel_speed_multiplier = 0.333
speed = 1
damage = 5
color = "#dbdd4c"
/// Save the turf we're aiming for for future use
var/turf/target_turf
/// Coins are valid while within a tile of their target tile, and can only be directly ricoshot during this time.
var/valid = FALSE
/// When a coin has been activated, is is marked as used, so that it is taken out of consideration for any further ricochets
var/used = FALSE
/// When this coin is targeted with a valid splitshot, it creates this many child splitshots
var/num_of_splitshots = 2
/// The crosshair icon put on the targeted turf for the user- so we can remove it from their images when done
var/image/crosshair_indicator
/// The mob who originally flipped this coin, as a matter of convenience, may be able tto be removed
var/mob/original_firer
/obj/projectile/bullet/coin/Initialize(mapload, turf/the_target, mob/original_firer)
src.original_firer = original_firer
target_turf = the_target
range = (get_dist(original_firer, target_turf) + 3) * 3 // 3 tiles past the origin (the *3 is because Range() ticks 3 times a tile because of the slower speed)
. = ..()
if(!istype(original_firer) || !original_firer.client)
return
var/client/firing_client = original_firer.client
crosshair_indicator = image('icons/obj/supplypods_32x32.dmi', target_turf, "LZ")
firing_client.images += crosshair_indicator
/obj/projectile/bullet/coin/Destroy()
remove_crosshair_indicator()
return ..()
// the coin must be on the target turf to be directly targetable
/obj/projectile/bullet/coin/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change)
. = ..()
if(!valid && get_dist(loc, target_turf) < 1)
original_firer?.playsound_local(src, 'sound/machines/ping.ogg', 30)
valid = TRUE
else if(valid && get_dist(loc, target_turf) > 1)
valid = FALSE
remove_crosshair_indicator()
/// Remove the crosshair indicator from the original firer if it exists
/obj/projectile/bullet/coin/proc/remove_crosshair_indicator()
if(original_firer?.client && crosshair_indicator)
original_firer.client.images -= crosshair_indicator
QDEL_NULL(crosshair_indicator)
/// We've been shot by a marksman revolver shot, or the ricochet off another coin, check if we can actually ricochet. The forced var being TRUE means it's a ricochet from another coin
/obj/projectile/bullet/coin/proc/check_splitshot(mob/living/shooter, obj/projectile/bullet/marksman/incoming_shot, forced = FALSE)
if(!forced && get_dist(src, target_turf) > 1)
return FALSE
used = TRUE
var/turf/cur_tur = get_turf(src)
cur_tur.visible_message(span_nicegreen("[incoming_shot] impacts [src] and splits!"))
iterate_splitshots(shooter, incoming_shot)
QDEL_IN(src, 0.25 SECONDS) // may not be needed
/// Now we actually create all the splitshots, loop through however many splits we'll create and fire them
/obj/projectile/bullet/coin/proc/iterate_splitshots(mob/living/shooter, obj/projectile/incoming_shot)
for(var/i in 1 to num_of_splitshots)
fire_splitshot(incoming_shot)
/// Shoot an individual splitshot at a new target
/obj/projectile/bullet/coin/proc/fire_splitshot(obj/projectile/bullet/marksman/incoming_shot)
var/atom/next_target = find_next_target()
ADD_TRAIT(next_target, TRAIT_RECENTLY_COINED, "[type]")
addtimer(TRAIT_CALLBACK_REMOVE(next_target, TRAIT_RECENTLY_COINED, "[type]"), 0.5 SECONDS)
var/outgoing_ricoshot_level = incoming_shot.ricoshot_level + 1
var/obj/projectile/bullet/marksman/new_splitshot = new /obj/projectile/bullet/marksman(get_turf(src), null, outgoing_ricoshot_level)
//Shooting Code:
new_splitshot.original = next_target
new_splitshot.fired_from = incoming_shot.fired_from
new_splitshot.firer = incoming_shot.firer
new_splitshot.damage = 2 * incoming_shot.damage
var/current_turf = get_turf(src)
var/target_turf = get_turf(next_target)
if(Adjacent(current_turf, target_turf))
new_splitshot.fire(get_angle(current_turf, target_turf), direct_target = next_target)
else
new_splitshot.preparePixelProjectile(next_target, get_turf(src))
new_splitshot.fire()
if(istype(next_target, /obj/projectile/bullet/coin)) // handle further splitshot checks
var/obj/projectile/bullet/coin/our_coin = next_target
our_coin.check_splitshot(incoming_shot.firer, new_splitshot, forced = TRUE)
/// Find what the splitshots will want to target next, with the order roughly based off the UK coin
/obj/projectile/bullet/coin/proc/find_next_target()
var/list/valid_targets = shuffle(oview(4, loc))
valid_targets -= firer
for(var/obj/projectile/bullet/coin/iter_coin in valid_targets)
if(!iter_coin.used) // this will prevent shooting itself as well
return iter_coin
var/list/possible_victims = list()
for(var/mob/living/iter_living in valid_targets)
if(HAS_TRAIT(iter_living, TRAIT_RECENTLY_COINED) || iter_living.stat != CONSCIOUS)
continue
if(get_dist(src, iter_living) <= 2) // prioritize close mobs
return iter_living
possible_victims += iter_living
if(possible_victims.len)
return pick(possible_victims)
var/static/list/prioritized_targets = list(/obj/structure/reagent_dispensers, /obj/item/grenade, /obj/structure/window)
for(var/iter_type in prioritized_targets)
for(var/already_coined_tries in 1 to 3)
var/atom/iter_type_check = locate(iter_type) in valid_targets
if(iter_type_check)
if(HAS_TRAIT(iter_type_check, TRAIT_RECENTLY_COINED))
valid_targets -= iter_type_check
continue
else
return iter_type_check
for(var/atom/last_ditch in valid_targets)
if(!HAS_TRAIT(last_ditch, TRAIT_RECENTLY_COINED))
return last_ditch