projectile
Vars | |
accuracy_falloff | How much accuracy is lost for each tile travelled |
---|---|
accurate_range | How much accuracy before falloff starts to matter. Formula is range - falloff * tiles travelled |
angle | The current angle of the projectile. Initially null, so if the arg is missing from [/fire()], we can calculate it from firer and target as fallback. |
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 |
damage_falloff_tile | How much we want to drop damage per tile as it travels through the air |
do_not_log | If true, the projectile won't cause any logging. Used for hallucinations and shit. |
drowsy | Drowsiness applied on projectile hit |
embed_data | Saves embedding data |
embed_falloff_tile | How much we want to drop the embed_chance value, if we can embed, per tile, for falloff purposes |
embed_type | 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 |
eyeblur | Seconds of blurry eyes applied on projectile hit |
force_hit | If the object being hit can pass the damage on to something else, it should not do it for this bullet |
hit_prone_targets | If TRUE, hit mobs, even if they are lying on the floor and are not our target within MAX_RANGE_HIT_PRONE_TARGETS tiles |
hit_threshhold | If objects are below this layer, we pass through them |
ignore_range_hit_prone_targets | if TRUE, ignores the range of MAX_RANGE_HIT_PRONE_TARGETS tiles of hit_prone_targets |
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. |
max_pierces | how many times this projectile can pierce something before deleting |
min_ricochets | how many times we have to ricochet min (unless we hit an atom we can ricochet off) |
pass_flags | |
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 |
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) |
stamina_falloff_tile | How much we want to drop stamina damage (defined by the stamina variable) per tile as it travels through the air |
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 projectile doubles the value of affecting armour |
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 |
Procs | |
CanPassThrough | Projectile can pass through Used to not even attempt to Bump() or fail to Cross() anything we already hit. |
Moved | Projectile moved: |
can_embed_into | Checks if the projectile can embed into someone |
get_embed | Fetches embedding data |
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. |
is_hostile_projectile | Is this projectile considered "hostile"? |
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 |
prehit_pierce | Checks if we should pierce something. |
preparePixelProjectile | Aims the projectile at a target. |
reflect | Reflects the projectile off of 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 |
select_target | Selects a target to hit from a turf |
set_angle_centered | Same as set_angle, but the reflection continues from the center of the object that reflects it instead of the side |
Var Details
accuracy_falloff
How much accuracy is lost for each tile travelled
accurate_range
How much accuracy before falloff starts to matter. Formula is range - falloff * tiles travelled
angle
The current angle of the projectile. Initially null, so if the arg is missing from [/fire()], we can calculate it from firer and target as fallback.
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
damage_falloff_tile
How much we want to drop damage per tile as it travels through the air
do_not_log
If true, the projectile won't cause any logging. Used for hallucinations and shit.
drowsy
Drowsiness applied on projectile hit
embed_data
Saves embedding data
embed_falloff_tile
How much we want to drop the embed_chance value, if we can embed, per tile, for falloff purposes
embed_type
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
eyeblur
Seconds of blurry eyes applied on projectile hit
force_hit
If the object being hit can pass the damage on to something else, it should not do it for this bullet
hit_prone_targets
If TRUE, hit mobs, even if they are lying on the floor and are not our target within MAX_RANGE_HIT_PRONE_TARGETS tiles
hit_threshhold
If objects are below this layer, we pass through them
ignore_range_hit_prone_targets
if TRUE, ignores the range of MAX_RANGE_HIT_PRONE_TARGETS tiles of hit_prone_targets
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.
max_pierces
how many times this projectile can pierce something before deleting
min_ricochets
how many times we have to ricochet min (unless we hit an atom we can ricochet off)
pass_flags
-
PROJECTILE PIERCING * WARNING: * Projectile piercing MUST be done using these variables. * Ordinary passflags will result in can_hit_target being false unless directly clicked on - similar to projectile_phasing but without even going to process_hit. * The two flag variables below both use pass flags. * In the context of LETPASStHROW, it means the projectile will ignore things that are currently "in the air" from a throw.
* Also, projectiles sense hits using Bump(), and then pierce them if necessary. * They simply do not follow conventional movement rules. * NEVER flag a projectile as PHASING movement type. * If you so badly need to make one go through *everything*, override check_pierce() for your projectile to always return PROJECTILE_PIERCE_PHASE/HIT.
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)
stamina_falloff_tile
How much we want to drop stamina damage (defined by the stamina variable) per tile as it travels through the air
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 projectile doubles the value of affecting armour
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.
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().
can_embed_into
Checks if the projectile can embed into someone
get_embed
Fetches embedding data
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.
is_hostile_projectile
Is this projectile considered "hostile"?
By default all projectiles which deal damage or impart crowd control effects (including stamina) are hostile
This is NOT used for pacifist checks, that's handled by /obj/item/ammo_casing/var/harmful This is used in places such as AI responses to determine if they're being threatened or not (among other places)
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
By default parent call will always return [BULLET_ACT_HIT] (unless qdeleted) so it is save to assume a successful hit in children (though not necessarily successfully damaged - it could've been blocked)
Arguments
- target - thing hit
- blocked - percentage of hit blocked (0 to 100)
- pierce_hit - boolean, are we piercing through or regular hitting
Returns
- Returns [BULLET_ACT_HIT] if we hit something. Default return value.
- Returns [BULLET_ACT_BLOCK] if we were hit but sustained no effects (blocked it). Note, Being "blocked" =/= "blocked is 100".
- Returns [BULLET_ACT_FORCE_PIERCE] to have the projectile keep going instead of "hitting", as if we were not hit at all.
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:
- target: (Optional) The thing that the projectile will be aimed at.
- source: The initial location of the projectile or the thing firing it.
- modifiers: (Optional) A list of click parameters to apply to this operation.
- deviation: (Optional) How the trajectory should deviate from the target in degrees.
- //Spread is FORCED!
reflect
Reflects the projectile off of 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.
- Special check on what we bumped to see if it's a border object that intercepts hitting anything behind it
- The thing originally aimed at/clicked on
- Mobs - picks lowest buckled mob to prevent scarp piggybacking memes
- Objs
- Turf
- 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