/tg/ Station 13 - Modules - TypesVar Details - Proc Details

projectile

Vars

armor_flagDefines what armor to use when it hits things. Must be set to bullet, laser, energy, or bomb
armour_penetrationHow much armor this projectile pierces.
can_hit_turfsIf true directly targeted turfs can be hit
embed_falloff_tileHow much we want to drop the embed_chance value, if we can embed, per tile, for falloff purposes
embeddingIf we have a shrapnel_type defined, these embedding stats will be passed to the spawned shrapnel type, which will roll for embedding on the target
force_hitIf the object being hit can pass ths damage on to something else, it should not do it for this bullet
hit_prone_targetsIf TRUE, hit mobs even if they're on the floor and not our target
hit_threshholdIf objects are below this layer, we pass through them
ignore_source_checkIf TRUE, we can hit our firer.
ignored_factionsWe ignore mobs with these factions.
impactedWe already impacted these things, do not impact them again. Used to make sure we can pierce things we want to pierce. Lazylist, typecache style (object = TRUE) for performance.
jitterJittering applied on projectile hit
last_angle_set_hitscan_storeLast turf an angle was changed in for hitscan projectiles.
pass_flags
phasing_ignore_direct_targetIf FALSE, allow us to hit something directly targeted/clicked/whatnot even if we're able to phase through it
piercesnumber of times we've pierced something. Incremented BEFORE bullet_act and on_hit proc!
pixel_speed_multiplierThis var is multiplied by SSprojectiles.global_pixel_speed to get how many pixels the projectile moves during each iteration of the movement loop
projectile_phasingBitflag for things the projectile should just phase through entirely - No hitting unless direct target and [phasing_ignore_direct_target] is FALSE. Uses pass_flags flags.
projectile_piercingBitflag for things the projectile should hit, but pierce through without deleting itself. Defers to projectile_phasing. Uses pass_flags flags.
ricochet_auto_aim_angleOn ricochet, if ricochet_auto_aim_range is nonzero, we'll consider any mobs within this range of the normal angle of incidence to home in on, higher = more auto aim
ricochet_auto_aim_rangeOn ricochet, if nonzero, we consider all mobs within this range of our projectile at the time of ricochet to home in on like Revolver Ocelot, as governed by ricochet_auto_aim_angle
ricochet_chance0-100 (or more, I guess), the base chance of ricocheting, before being modified by the atom we shoot and our chance decay
ricochet_decay_chance0-1 (or more, I guess) multiplier, the ricochet_chance is modified by multiplying this after each ricochet
ricochet_decay_damage0-1 (or more, I guess) multiplier, the projectile's damage is modified by multiplying this after each ricochet
ricochet_incidence_leewaythe angle of impact must be within this many degrees of the struck surface, set to 0 to allow any angle
ricochet_shoots_firerCan our ricochet autoaim hit our firer?
ricochetshow many times we've ricochet'd so far (instance variable, not a stat)
ricochets_maxhow many times we can ricochet max
sharpnessFor what kind of brute wounds we're rolling for, if we're doing such a thing. Lasers obviously don't care since they do burn instead.
shrapnel_typeIf defined, on hit we create an item of this type then call hitby() on the hit target with this, mainly used for embedding items (bullets) in targets
slurSlurring applied on projectile hit
speedDuring each fire of SSprojectiles, the number of deciseconds since the last fire of SSprojectiles is divided by this var, and the result truncated to the next lowest integer is the number of times the projectile's pixel_move proc will be called.
staminaExtra stamina damage applied on projectile hit (in addition to the main damage)
stutterStuttering applied on projectile hit
temporary_unstoppable_movementWe are flagged PHASING temporarily to not stop moving when we Bump something but want to keep going anyways.
weak_against_armourWhether or not our bullet lacks penetrative power, and is easily stopped by armor.
wound_falloff_tileHow much we want to drop both wound_bonus and bare_wound_bonus (to a minimum of 0 for the latter) per tile, for falloff purposes

Procs

CanPassThroughProjectile can pass through Used to not even attempt to Bump() or fail to Cross() anything we already hit.
ImpactCalled when the projectile hits something This can either be from it bumping something, or it passing over a turf/being crossed and scanning that there is infact a valid target it needs to hit. This target isn't however necessarily WHAT it hits that is determined by process_hit and select_target.
MovedProjectile moved:
on_enteredProjectile crossed: When something enters a projectile's tile, make sure the projectile hits it if it should be hitting it.
on_hitCalled when the projectile hits something
prehit_pierceChecks if we should pierce something.
preparePixelProjectileAims the projectile at a target.
process_hitThe primary workhorse proc of projectile impacts. This is a RECURSIVE call - process_hit is called on the first selected target, and then repeatedly called if the projectile still hasn't been deleted.
scan_crossed_hitScan if we should hit something and hit it if we need to The difference between this and handling in Impact is In this we strictly check if we need to Impact() something in specific If we do, we do We don't even check if it got hit already - Impact() does that In impact there's more code for selecting WHAT to hit So this proc is more of checking if we should hit something at all BY having an atom cross us.
scan_moved_turfScans if we should hit something on the turf we just moved to if we haven't already
select_targetSelects a target to hit from a turf
set_angle_centeredSame as set_angle, but the reflection continues from the center of the object that reflects it instead of the side
updateEmbeddingLike /obj/item/proc/updateEmbedding but for projectiles instead, call this when you want to add embedding or update the stats on the embedding element

Var Details

armor_flag

Defines what armor to use when it hits things. Must be set to bullet, laser, energy, or bomb

armour_penetration

How much armor this projectile pierces.

can_hit_turfs

If true directly targeted turfs can be hit

embed_falloff_tile

How much we want to drop the embed_chance value, if we can embed, per tile, for falloff purposes

embedding

If we have a shrapnel_type defined, these embedding stats will be passed to the spawned shrapnel type, which will roll for embedding on the target

force_hit

If the object being hit can pass ths damage on to something else, it should not do it for this bullet

hit_prone_targets

If TRUE, hit mobs even if they're on the floor and not our target

hit_threshhold

If objects are below this layer, we pass through them

ignore_source_check

If TRUE, we can hit our firer.

ignored_factions

We ignore mobs with these factions.

impacted

We already impacted these things, do not impact them again. Used to make sure we can pierce things we want to pierce. Lazylist, typecache style (object = TRUE) for performance.

jitter

Jittering applied on projectile hit

last_angle_set_hitscan_store

Last turf an angle was changed in for hitscan projectiles.

pass_flags

The "usual" flags of pass_flags is used in that can_hit_target ignores these unless they're specifically targeted/clicked on. This behavior entirely bypasses process_hit if triggered, rather than phasing which uses prehit_pierce() to check.

phasing_ignore_direct_target

If FALSE, allow us to hit something directly targeted/clicked/whatnot even if we're able to phase through it

pierces

number of times we've pierced something. Incremented BEFORE bullet_act and on_hit proc!

pixel_speed_multiplier

This var is multiplied by SSprojectiles.global_pixel_speed to get how many pixels the projectile moves during each iteration of the movement loop

If you want to make a fast-moving projectile, you should keep this equal to 1 and reduce the value of speed. If you want to make a slow-moving projectile, make speed a modest value like 1 and set this to a low value like 0.2.

projectile_phasing

Bitflag for things the projectile should just phase through entirely - No hitting unless direct target and [phasing_ignore_direct_target] is FALSE. Uses pass_flags flags.

projectile_piercing

Bitflag for things the projectile should hit, but pierce through without deleting itself. Defers to projectile_phasing. Uses pass_flags flags.

ricochet_auto_aim_angle

On ricochet, if ricochet_auto_aim_range is nonzero, we'll consider any mobs within this range of the normal angle of incidence to home in on, higher = more auto aim

ricochet_auto_aim_range

On ricochet, if nonzero, we consider all mobs within this range of our projectile at the time of ricochet to home in on like Revolver Ocelot, as governed by ricochet_auto_aim_angle

ricochet_chance

0-100 (or more, I guess), the base chance of ricocheting, before being modified by the atom we shoot and our chance decay

ricochet_decay_chance

0-1 (or more, I guess) multiplier, the ricochet_chance is modified by multiplying this after each ricochet

ricochet_decay_damage

0-1 (or more, I guess) multiplier, the projectile's damage is modified by multiplying this after each ricochet

ricochet_incidence_leeway

the angle of impact must be within this many degrees of the struck surface, set to 0 to allow any angle

ricochet_shoots_firer

Can our ricochet autoaim hit our firer?

ricochets

how many times we've ricochet'd so far (instance variable, not a stat)

ricochets_max

how many times we can ricochet max

sharpness

For what kind of brute wounds we're rolling for, if we're doing such a thing. Lasers obviously don't care since they do burn instead.

shrapnel_type

If defined, on hit we create an item of this type then call hitby() on the hit target with this, mainly used for embedding items (bullets) in targets

slur

Slurring applied on projectile hit

speed

During each fire of SSprojectiles, the number of deciseconds since the last fire of SSprojectiles is divided by this var, and the result truncated to the next lowest integer is the number of times the projectile's pixel_move proc will be called.

stamina

Extra stamina damage applied on projectile hit (in addition to the main damage)

stutter

Stuttering applied on projectile hit

temporary_unstoppable_movement

We are flagged PHASING temporarily to not stop moving when we Bump something but want to keep going anyways.

weak_against_armour

Whether or not our bullet lacks penetrative power, and is easily stopped by armor.

wound_falloff_tile

How much we want to drop both wound_bonus and bare_wound_bonus (to a minimum of 0 for the latter) per tile, for falloff purposes

Proc Details

CanPassThrough

Projectile can pass through Used to not even attempt to Bump() or fail to Cross() anything we already hit.

Impact

Called when the projectile hits something This can either be from it bumping something, or it passing over a turf/being crossed and scanning that there is infact a valid target it needs to hit. This target isn't however necessarily WHAT it hits that is determined by process_hit and select_target.

Furthermore, this proc shouldn't check can_hit_target - this should only be called if can hit target is already checked. Also, we select_target to find what to process_hit first.

Moved

Projectile moved:

If not fired yet, do not do anything. Else,

If temporary unstoppable movement used for piercing through things we already hit (impacted list) is set, unset it. Scan turf we're now in for anything we can/should hit. This is useful for hitting non dense objects the user directly clicks on, as well as for PHASING projectiles to be able to hit things at all as they don't ever Bump().

on_entered

Projectile crossed: When something enters a projectile's tile, make sure the projectile hits it if it should be hitting it.

on_hit

Called when the projectile hits something

@params target - thing hit blocked - percentage of hit blocked pierce_hit - are we piercing through or regular hitting

prehit_pierce

Checks if we should pierce something.

NOT meant to be a pure proc, since this replaces prehit() which was used to do things. Return PROJECTILE_DELETE_WITHOUT_HITTING to delete projectile without hitting at all!

preparePixelProjectile

Aims the projectile at a target.

Must be passed at least one of a target or a list of click parameters. If only passed the click modifiers the source atom must be a mob with a client.

Arguments:

process_hit

The primary workhorse proc of projectile impacts. This is a RECURSIVE call - process_hit is called on the first selected target, and then repeatedly called if the projectile still hasn't been deleted.

Order of operations:

  1. Checks if we are deleted, or if we're somehow trying to hit a null, in which case, bail out
  2. Adds the thing we're hitting to impacted so we can make sure we don't doublehit
  3. Checks piercing - stores this. Afterwards: Hit and delete, hit without deleting and pass through, pass through without hitting, or delete without hitting depending on result If we're going through without hitting, find something else to hit if possible and recurse, set unstoppable movement to true If we're deleting without hitting, delete and return Otherwise, send signal of COMSIG_PROJECTILE_PREHIT to target Then, hit, deleting ourselves if necessary. @params T - Turf we're on/supposedly hitting target - target we're hitting bumped - target we originally bumped. it's here to ensure that if something blocks our projectile by means of Cross() failure, we hit it even if it is not dense. hit_something - only should be set by recursive calling by this proc - tracks if we hit something already

Returns if we hit something.

scan_crossed_hit

Scan if we should hit something and hit it if we need to The difference between this and handling in Impact is In this we strictly check if we need to Impact() something in specific If we do, we do We don't even check if it got hit already - Impact() does that In impact there's more code for selecting WHAT to hit So this proc is more of checking if we should hit something at all BY having an atom cross us.

scan_moved_turf

Scans if we should hit something on the turf we just moved to if we haven't already

This proc is a little high in overhead but allows us to not snowflake CanPass in living and other things.

select_target

Selects a target to hit from a turf

@params T - The turf target - The "preferred" atom to hit, usually what we Bumped() first. bumped - used to track if something is the reason we impacted in the first place. If set, this atom is always treated as dense by can_hit_target.

Priority: 0. Anything that is already in impacted is ignored no matter what. Furthermore, in any bracket, if the target atom parameter is in it, that's hit first. Furthermore, can_hit_target is always checked. This (entire proc) is PERFORMANCE OVERHEAD!! But, it shouldn't be ""too"" bad and I frankly don't have a better generic non snowflakey way that I can think of right now at 3 AM. FURTHERMORE, mobs/objs have a density check from can_hit_target - to hit non dense objects over a turf, you must click on them, same for mobs that usually wouldn't get hit.

  1. Special check on what we bumped to see if it's a border object that intercepts hitting anything behind it
  2. The thing originally aimed at/clicked on
  3. Mobs - picks lowest buckled mob to prevent scarp piggybacking memes
  4. Objs
  5. Turf
  6. Nothing

set_angle_centered

Same as set_angle, but the reflection continues from the center of the object that reflects it instead of the side

updateEmbedding

Like /obj/item/proc/updateEmbedding but for projectiles instead, call this when you want to add embedding or update the stats on the embedding element