tModLoader v2024.10
A mod to make and play Terraria mods
Projectile Class Reference

Inherits Entity, and IEntityWithGlobals< GlobalProjectile >.

Classes

struct  HallowBossPelletStormInfo
 

Public Member Functions

void AI ()
 
bool AI_019_Spears_GetExtensionHitbox (out Rectangle extensionBox)
 
bool AI_137_CanHit (Vector2 targetPosition)
 
Color AI_156_GetColor ()
 
Color AI_171_GetColor ()
 
HallowBossPelletStormInfo AI_172_GetPelletStormInfo (int stormIndex)
 
int AI_172_GetPelletStormsCount ()
 
Color AI_173_GetColor ()
 
void ApplyStatsFromSource (IEntitySource spawnSource)
 Transfers stat modifiers from the spawn source to the projectile.
Adds CritChance and ArmorPenetration bonuses from players (EntitySource_Parent), weapons (EntitySource_ItemUse)
If the source is a EntitySource_Parent projectile, CritChance and ArmorPenetration from the parent will be added, in order to transfer the original item/player bonus values.


To support minions, sentries and ContinuouslyUpdateDamageStats, OriginalCritChance and OriginalArmorPenetration are also copied from item sources and parent projectiles. More...
 
bool CanBeReflected ()
 
bool CanExplodeTile (int x, int y)
 
bool CanHitWithMeleeWeapon (Entity ent)
 
bool CanHitWithOwnBody (Entity ent)
 
void CheckUsability (Player player, ref bool currentlyUsable)
 
void CloneDefaults (int TypeToClone)
 
bool Colliding (Rectangle myRect, Rectangle targetRect)
 
bool CountsAsClass (DamageClass damageClass)
 This is used to check if the projectile is considered to be a member of a specified DamageClass. More...
 
bool CountsAsClass< T > ()
 
void CreateImpactExplosion (int dustAmountMultiplier, Vector2 explosionOrigin, ref Point scanAreaStart, ref Point scanAreaEnd, int explosionRange, out bool causedShockwaves)
 
void CreateImpactExplosion2_FlailTileCollision (Vector2 explosionOrigin, bool causedShockwaves, Vector2 velocityBeforeCollision)
 
void Damage ()
 
void DefaultToSpray ()
 
void DefaultToWhip ()
 
void EmitEnchantmentVisualsAt (Vector2 boxPosition, int boxWidth, int boxHeight)
 Spawns weapon enchantment visuals the specified location. boxPosition is the top left corner of the intended spawn area and boxWidth and boxHeight dictate the spawn area. This method is automatically called for all projectiles that are not npcProj and not noEnchantmentVisuals. Modders can use noEnchantmentVisuals to prevent the automatic calling of this method and manually call this method in ModProjectile.AI to customize the intended enchantment visuals position. Set noEnchantments to true on projectiles that shouldn't have enchantment visuals or effects at all.
 
void ExplodeCrackedTiles (Vector2 compareSpot, int radius, int minI, int maxI, int minJ, int maxJ)
 
void ExplodeTiles (Vector2 compareSpot, int radius, int minI, int maxI, int minJ, int maxJ, bool wallSplode)
 Explodes tiles within a radius of the given position and within the bounds passed in. The wallSplode parameter should be the result of ShouldWallExplode(Vector2, int, int, int, int, int) and dictates if walls will also be destroyed. This method honors the tile and wall explosion conditions.
 
NPC FindTargetWithinRange (float maxRange, bool checkCanHit=false)
 
int FindTargetWithLineOfSight (float maxRange=800f)
 Finds the closest NPC to this projectile which can be targeted and which it has line of sight to. More...
 
void FishingCheck ()
 
Color GetAlpha (Color newColor)
 
Color GetCeleb2Color ()
 
Color GetFairyQueenWeaponsColor (float alphaChannelMultiplier=1f, float lerpToWhite=0f, float? rawHueOverride=null)
 
Color GetFirstFractalColor ()
 
Color GetFloatingDaggerMinionGlowColor ()
 
GetGlobalProjectile< T > ()
 Gets the instance of the specified GlobalProjectile type. This will throw exceptions on failure. More...
 
GetGlobalProjectile< T > (T baseInstance)
 Gets the local instance of the type of the specified GlobalProjectile instance. This will throw exceptions on failure. More...
 
float GetLastPrismHue (float laserIndex, ref float laserLuminance, ref float laserAlphaMultiplier)
 
Rectangle getRect ()
 
void ghostHeal (int dmg, Vector2 Position, Entity victim)
 
void ghostHurt (int dmg, Vector2 Position, Entity victim)
 
void HurtPlayer (Rectangle hitbox)
 Hurts the local player if the player intersects the specified hitbox. More...
 
void Interrupt (Player player)
 
bool IsAttachedTo (NPC npc)
 
bool IsDamageDodgable ()
 
bool IsInRangeOfMeOrMyOwner (Entity entity, float maxDistance, out float myDistance, out float playerDistance, out bool closerIsMe)
 
bool IsInteractible ()
 
bool IsInterruptible (Player player)
 
void Kill ()
 
void Kill_DirtAndFluidProjectiles_RunDelegateMethodPushUpForHalfBricks (Point pt, float size, Utils.TileActionAttempt plot)
 
void Minion_FindTargetInRange (int startAttackRange, ref int attackTarget, bool skipIfCannotHitWithOwnBody, Func< Entity, int, bool > customEliminationCheck=null)
 
void PrepareBombToBlow ()
 Used to adjust projectile properties immediately before the projectile becomes an explosion. This is called on projectiles using the ProjAIStyleID.Explosive aiStyle or projectiles that are contained in the ProjectileID.Sets.Explosive set. By defaults tileCollide is set to false and alpha is set to 255. Calls the ProjectileLoader.PrepareBombToBlow(Projectile) method.
 
void ProjectileFixDesperation ()
 
void ProjLight ()
 
void ResetLocalNPCHitImmunity ()
 
void Resize (int newWidth, int newHeight)
 Changes the Entity.width and Entity.height of the projectile while preserving the Entity.Center. Useful for explosive projectiles that expand their hitbox while exploding.
 
void SetDefaults (int Type)
 
bool ShouldUseWindPhysics ()
 
bool ShouldWallExplode (Vector2 compareSpot, int radius, int minI, int maxI, int minJ, int maxJ)
 Determines if walls should be exploded by checking if there is an empty wall within the specified radius and bounds. Use in conjunction with ExplodeTiles.
 
void StatusNPC (int i)
 
void StatusPlayer (int i)
 
void StatusPvP (int i)
 
override string ToString ()
 
bool TryGetContainerIndex (out int containerIndex)
 
bool TryGetGlobalProjectile< T > (out T result)
 Gets the instance of the specified GlobalProjectile type. More...
 
bool TryGetGlobalProjectile< T > (T baseInstance, out T result)
 Safely attempts to get the local instance of the type of the specified GlobalProjectile instance. More...
 
bool TryGetOwner ([NotNullWhen(true)] out Player? player)
 Attempts to get the owner player of this projectile. Returns null for projectiles spawned by TownNPC (npcProj) and trap projectiles (trap). Returns Main.player[owner] otherwise. Note that this logic assumes that projectiles have the correct fields set, which might not always be true. Also note that in single player enemy projectiles are also "owned" by the player, so this alone isn't sufficient to know which projectiles were spawned by the player. Additional friendly checks would be needed for that. More...
 
bool TurretShouldPersist ()
 
void Update (int i)
 
void vampireHeal (int dmg, Vector2 Position, Entity victim)
 
void VanillaAI ()
 
- Public Member Functions inherited from Entity
float AngleFrom (Vector2 Source)
 
float AngleTo (Vector2 Destination)
 
Vector2 DirectionFrom (Vector2 Source)
 
Vector2 DirectionTo (Vector2 Destination)
 
float Distance (Vector2 Other)
 
float DistanceSQ (Vector2 Other)
 
IEntitySource GetSource_CatchEntity (Entity caughtEntity, string? context=null)
 
IEntitySource GetSource_Death (string? context=null)
 
IEntitySource GetSource_DropAsItem (string? context=null)
 
IEntitySource GetSource_FromAI (string? context=null)
 
IEntitySource GetSource_FromThis (string? context=null)
 
IEntitySource GetSource_GiftOrReward (string? context=null)
 
IEntitySource GetSource_Loot (string? context=null)
 
IEntitySource GetSource_Misc (string context)
 
IEntitySource GetSource_OnHit (Entity victim, string? context=null)
 
IEntitySource GetSource_OnHurt (Entity? attacker, string? context=null)
 
IEntitySource GetSource_ReleaseEntity (string? context=null)
 
IEntitySource GetSource_TileInteraction (int tileCoordsX, int tileCoordsY, string? context=null)
 
bool WithinRange (Vector2 Target, float MaxRange)
 

Static Public Member Functions

static Vector2 AI_158_GetHomeLocation (Player master, int stackedIndex)
 
static Vector2 AI_164_GetHomeLocation (Player master, int stackedIndex, int totalIndexes)
 
static void AI_192_GetJuminoFall (Projectile proj, out float timeSinceFall, out float fall)
 
static void DropGeodeLoot (Entity entity)
 Will drop loot the same way as when ProjectileID.Geode is cracked open. More...
 
static void EmitBlackLightningParticles (NPC targetNPC)
 
static void FillWhipControlPoints (Projectile proj, List< Vector2 > controlPoints)
 
static int FindOldestProjectile ()
 
static bool GasTrapCheck (int x, int y, Player user)
 
static int GetBallistraShotDelay (Player player)
 
static int GetByUUID (int owner, float uuid)
 
static int GetByUUID (int owner, int uuid)
 
static int GetExplosiveTrapCooldown (Player player)
 
static Color GetGolfTrailColor (Projectile proj)
 
static int GetNextSlot ()
 
static void GetWhipSettings (Projectile proj, out float timeToFlyOut, out int segments, out float rangeMultiplier)
 
static void InitializeStaticThings ()
 
static bool IsNPCIndexImmuneToProjectileType (int projectileType, int npcIndex)
 
static void KillOldestJavelin (int protectedProjectileIndex, int projectileType, int targetNPCIndex, Point[] bufferForScan)
 
static int NewProjectile (IEntitySource spawnSource, float X, float Y, float SpeedX, float SpeedY, int Type, int Damage, float KnockBack, int Owner=-1, float ai0=0f, float ai1=0f, float ai2=0f)
 Spawns a projectile into the game world with the given type. The spawn position is given in world coordinates by the X and Y parameters. SpeedX and SpeedY dictate the initial velocity. Damage and KnockBack are self-explanatory. Owner is the player who spawned the projectile, almost always Main.myPlayer. ai0, ai1, and ai2 will initialize the Projectile.ai[] array with the supplied values. This can be used to pass in information to the Projectile. The Projectile AI code will have to be written to utilize those values. The return value is the index of the spawned Projectile within the Main.projectile array.
Make sure that this method is called only by the client in charge of the source causing this projectile to spawn. Failure to do this will result in the projectile spawning once for each player in the world. For example, if Player code uses this method, make sure to first check More...
 
static int NewProjectile (IEntitySource spawnSource, Vector2 position, Vector2 velocity, int Type, int Damage, float KnockBack, int Owner=-1, float ai0=0f, float ai1=0f, float ai2=0f)
 

This particular overload uses a Vector2 instead of X and Y to determine the actual spawn position and a Vector2 to dictate the initial velocity.
 
static Projectile NewProjectileDirect (IEntitySource spawnSource, Vector2 position, Vector2 velocity, int type, int damage, float knockback, int owner=-1, float ai0=0f, float ai1=0f, float ai2=0f)
 

This particular overload uses a Vector2 instead of X and Y to determine the actual spawn position and a Vector2 to dictate the initial velocity. The return value is the actual Projectile instance rather than the index of the spawned Projectile within the Main.projectile array.
A short-hand for More...
 
static void RandomizeInsanityShadowFor (Entity targetEntity, bool isHostile, out Vector2 spawnposition, out Vector2 spawnvelocity, out float ai0, out float ai1)
 
static void ResetImmunity ()
 
static void UseGasTrapInChest (int chestIndex, Chest theChest, int gasTrapIndex, int gasOffsetX, int gasOffsetY)
 
- Static Public Member Functions inherited from Entity
static IEntitySource GetSource_NaturalSpawn ()
 
static ? IEntitySource GetSource_None ()
 
static IEntitySource GetSource_TownSpawn ()
 
static ? IEntitySource InheritSource (Entity entity)
 

Public Attributes

float[] ai = new float[maxAI]
 An array with 3 slots used for any sort of data storage, which is occasionally synced to the server. Each vanilla ProjAIStyleID uses these slots for different purposes. Set netUpdate to true during AI methods to manually sync. The advantage of using these 3 floats is that they are synced automatically. Using fields in your ModProjectile class will work just the same, but they might need to be synced via ModProjectile.SendExtraAI(System.IO.BinaryWriter) and ModProjectile.ReceiveExtraAI(System.IO.BinaryReader) if necessary.
Clever use of Reference return valuesas seen in ExampleLightPetProjectile.cscan be used to reuse the ai array entries with readable names.
Defaults to the values passed into Projectile.NewProjectile(IEntitySource, float, float, float, float, int, int, float, int, float, float, float), usually [0, 0, 0].
 
int aiStyle
 Selects which vanilla code to use for the AI method. Vanilla projectile AI styles are enumerated in the ProjAIStyleID class. Modders can use vanilla aiStyle and optionally ModProjectile.AIType to mimic AI code already in the game. This is usually only useful as a prototyping tool since it is difficult to customize existing aiStyle code. See ModProjectile.AIType and ExampleCloneProjectileto see how to use vanilla ai. If you are using custom AI code, there is no need to set this field.
The Basic Projectile Guideteaches how to use an existing aiStyle.
Customizing an existing aiStyle usually requires following the Vanilla Code Adaption Guide.
Defaults to 0.
 
int alpha
 How transparent to draw this projectile. 0 to 255. 255 is completely transparent.
ExampleBulletsets this to 255, and the projectile aiStyle of ProjAIStyleID.Arrow automatically decreases alpha each tick, letting the projectile fade in quickly after being spawned. Useful for projectiles that look odd when initially spawned on the weapon because of texture overlap.
The Basic Projectile Guideteaches more about projectile fade in and out.
Defaults to 0.
 
bool appliesImmunityTimeOnSingleHits
 If true, this projectile will apply immunity to an npc despite having a penetrate value of 1. Used only for firework rockets in Terraria content.
 
bool arrow
 Indicates that this is an arrow projectile. Used to apply the Phantasm and Magic Quiver effects.
 
int bannerIdToRespondTo
 
bool bobber
 
bool coldDamage
 
bool counterweight
 
int damage
 This will always be set in Projectile.NewProjectile based on the weapons damage and player stat modifiers. Modders should not set this in ModProjectile.SetDefaults as it will be overwritten.
 
bool decidesManualFallThrough
 
int extraUpdates
 Additional update steps per tick. Useful for really fast projectiles such as Shadowbeam Staff. If your projectile is mistakenly occasionally traveling through tiles, you may need to increase this to prevent that. Also useful as a velocity multiplier for ammo projectile. The Shoot Speed wiki pageexplains how that works. Defaults to 0.
 
int frame
 The frame number in the spritesheet that this projectile will be drawn with. Assign in ModProjectile.AI based on the state of the projectile and frameCounter.
Main.projFrames must be set in ModProjectile.SetStaticDefaults as well.
Example: projectile has 4 frames, then frame can have values between 0 and 3
The Basic Projectile Guideteaches how to animate projectiles.
Defaults to 0.
 
int frameCounter
 Used as a timer to decide when to change frame.
Defaults to 0.
 
bool friendly
 If True, this projectile will hurt enemies (!NPC.friendly)
Defaults to false.
 
float gfxOffY
 An offset from the actual position of the projectile that will be added to the draw position. Used to offset some held projectiles to match the players Player.gfxOffY, thereby keeping the projectile visually in sync with the player. ProjectileID.Sets.HeldProjDoesNotUsePlayerGfxOffY can be used to ignore that usage.
 
short glowMask
 
bool hide
 Projectile is not drawn normally. Held projectiles (Player.heldProj) and projectiles specified to be drawn at specific layers (ModProjectile.DrawBehind(int, List<int>, List<int>, List<int>, List<int>, List<int>)) use this. Be default this will also influence the lighting of this projectile to match the players lighting, as if it were a held projectile. Projectiles that are not held by the player should set ProjectileID.Sets.DontAttachHideToAlpha to true in SetStaticDefaults: ProjectileID.Sets.DontAttachHideToAlpha[Type] = true; Defaults to false.
 
bool hostile
 If True, this projectile will hurt players and friendly NPCs (NPC.friendly)
Defaults to false.
 
int identity
 The projectile's universal unique identifier, which is the same on all clients and the server. Usually used to find the same projectile on multiple clients and/or the server, e.g. Projectile match = Main.projectile.FirstOrDefault(x => x.identity == identity);
Projectile.whoAmI indexes are not consistent between clients.
 
int idStaticNPCHitCooldown = -1
 When used in conjunction with usesIDStaticNPCImmunity, determines how many ticks must pass before any projectile of the same type can deal damage again to the same npc. This must be assigned a suitable value if usesIDStaticNPCImmunity is true.
 
bool ignoreWater
 The projectile will not be affected by water.
Defaults to false.
 
bool isAPreviewDummy
 
float knockBack
 This will always be set in Projectile.NewProjectile based on the weapons knockback and player stat modifiers. Modders should not set this in ModProjectile.SetDefaults as it will be overwritten.
 
float light
 Set to a value above 0f to make this projectile emit a white light (higher number: more intensive light. 1f being stronger than a torch))
The Basic Projectile Guideteaches more about lighting, including non-white lighting, dust light, and glow behavior.
Defaults to 0.
 
float[] localAI = new float[maxAI]
 Acts like ai, but does not sync to the server. Many vanilla ProjAIStyleID use these slots for various purposes.
Defaults to [0, 0, 0]
 
int localNPCHitCooldown = -2
 When used in conjunction with usesLocalNPCImmunity, determines how many ticks must pass before this projectile can deal damage again to the same npc. A value of -1 indicates that it can only hit a specific npc once. The default value of -2 has no effect, so this must be assigned if usesLocalNPCImmunity is true.
 
int[] localNPCImmunity = new int[200]
 
bool manualDirectionChange
 
int maxPenetrate = 1
 How many npc can this projectile hit before dying. (Or tile bounces)
Automatically set at the end of SetDefaults to the value of penetrate.
 
bool minion
 Indicates that this projectile is a minion
Defaults to false.
 
int minionPos
 A number indicating the order of minions. Minion AI code typically uses this value to determine a suitable idle position that results in minions lining up neatly in relation to the player without bunching up.
 
float minionSlots
 Set to 1f on a minion to count it towards the minion limit of the summoning player (Optic Staff summons two minions at once with 0.5f each)
Make sure to set ItemID.Sets.StaffMinionSlotsRequired for the minion summoning item to the sum of the minionSlots values of the minions that will be spawned.
Defaults to 0f.
 
string miscText = ""
 
bool netImportant
 Indicates that this projectile will be synced to a joining player (by default, any projectiles active before the player joins (besides projectiles with type in Main.projPet) are not synced over). Example: glowsticks
Defaults to false.
 
int netSpam
 
bool netUpdate
 Set to true in ModProjectile.AI or other suitable places to trigger the Projectile syncing code (MessageID.SyncProjectile). This will sync position, velocity, damage, knockback, and other data about this Projectile to the server and other clients. This also includes modded data from ModProjectile.SendExtraAI(System.IO.BinaryWriter) and GlobalProjectile.SendExtraAI(Projectile, ModLoader.IO.BitWriter, System.IO.BinaryWriter). Use this to sync changes that happen only on the owners game, such as responding to player mouse and keyboard input or non-Deterministic logic such as random choices. Consulting similar Terraria aiStyle code and following that usage is usually a good idea. netUpdate only has effect for the Projectile owner. Projectiles owned by clients will sync data from the owner to the server and the server will relay that data to the other clients. Projectiles owned by the server will send their data to all clients. The Basic Netcode wiki pagegoes into more details and links to examples.
 
bool netUpdate2
 Used internally to check for projectiles that spam netUpdate. Don't use it yourself manually
 
bool noDropItem
 Set to true if you don't want this projectile to have a chance to recover the ammo item that shot this, provided that the projectile is programmed to drop the item. For example, if you shoot the ProjectileID.PaperAirplaneA projectile, it will always drop the ItemID.PaperAirplaneA item. If your weapon shoots multiple recoverable projectiles for 1 ammo, you might want to consider setting this field to prevent infinite ammo exploits. Make sure to set this for any situation where a potentially recoverable ammo is spawned by something other than the player, such as traps and Town NPC. To implement recoverable ammo item drops, in ModProjectile.OnKill(int) check this, owner, and optionally a random chance to decide if the item should drop: if (Projectile.owner == Main.myPlayer && !Projectile.noDropItem) See ExamplePaperAirplaneProjectilefor an example of this logic. Set directly on the projectile instance returned from Projectile.NewProjectile(IEntitySource, float, float, float, float, int, int, float, int, float, float, float), not in ModProjectile.SetDefaults. This ensures that the weapon or source spawning the projectile decides if the ammo item will spawn, which is more compatible. Set automatically when shot from a weapon that counts as DamageClass.Throwing and Player.AnyThrownCostReduction is true. Defaults to false.
 
bool noEnchantments
 If true, this projectile will not benefit from weapon enchantments such as flasks, frost armor, or magma stone effects. This means the projectile won't inflict associated buffs or spawn associated visuals. Defaults to false.
 
bool noEnchantmentVisuals
 If true, this projectile will not have EmitEnchantmentVisualsAt(Vector2, int, int) called automatically. This can be set to true for projectiles that wish to manually call EmitEnchantmentVisualsAt(Vector2, int, int) in AI methods for finer control over the spawn location of enchantment visuals. Use noEnchantments instead to indicate that the projectile is not suitable for weapon enchantment effects at all and shouldn't inflict associated buffs either. Defaults to false.
 
bool npcProj
 If true, this projectile was spawned by a friendly Town NPC.
 
int numHits
 
int numUpdates
 
Vector2[] oldPos = new Vector2[10]
 Holds the value of Entity.position from previous updates from newest to oldest. Use for drawing trails. Must be used with ProjectileID.Sets.TrailCacheLength and ProjectileID.Sets.TrailingMode to be used properly. Note that oldPos[0] will be equal to Entity.position during drawing methods, so index 0 should be skipped unless skipping vanilla drawing. Also note that they should be drawn in reverse order to layer properly. Also note that the values are from previous updates, not previous draws, which might be relevant if extraUpdates is used.
 
float[] oldRot = new float[10]
 Holds the value of Projectile.rotation from previous updates from newest to oldest. Use for drawing trails. Must be used with ProjectileID.Sets.TrailCacheLength and ProjectileID.Sets.TrailingMode to be used properly.
 
int[] oldSpriteDirection = new int[10]
 Holds the value of Projectile.spriteDirection from previous updates from newest to oldest. Use for drawing trails. Must be used with ProjectileID.Sets.TrailCacheLength and ProjectileID.Sets.TrailingMode to be used properly.
 
int originalDamage
 
bool originatedFromActivableTile
 
int owner = 255
 The index of the player who owns this projectile. In Multiplayer, Clients "own" projectiles that they shoot, while the Server "owns" projectiles spawned by NPCs and the World.
NPC never own projectiles, do not use owner to index into Main.npc.
It is very important to check if (Projectile.owner == Main.myPlayer) for things like dropping items or spawning projectiles in ModProjectile.AI and some other methods because AI runs simultaneously on all Clients and the Server. This check gates some of the code that should only run on the owners computer. ExamplePaperAirplaneProjectilechecks owner for spawning the recovered ammo item. If you don't do this, you will run into desync bugs in your mod.
Defaults to the owner parameter of Projectile.NewProjectile, which should always be set to Main.myPlayer to correspond to the client that owns the projectile..
 
bool ownerHitCheck
 If true, then this projectile will only deal damage if its owner has line of sight to the hit.
Useful for melee projectiles, such as spears and shortswords.
Defaults to false.
 
float ownerHitCheckDistance = 1000f
 
int penetrate = 1
 The remaining number of npc can this projectile hit before dying. (Or tile bounces). Assign this field in SetDefaults and use it in ModProjectile logic if needed. A value of -1 means the projectile will penetrate infinitely. See ExamplePiercingProjectilefor more information on how penetrate influences NPC immunity frames.
Defaults to 1. Used to automatically assigned a value to maxPenetrate at the end of SetDefaults.
 
int[] playerImmune = new int[255]
 
int projUUID = -1
 
bool reflected
 
int restrikeDelay
 
float rotation
 Rotation of the projectile. Radians not Degrees. Use MathHelper if you want to convert degrees to radians. 0 is facing right, MathHelper.PiOver2 is facing down, and so on. Note that hitboxes do not rotate.
The Basic Projectile Guideteaches more about projectile rotation.
Defaults to 0f.
 
float scale = 1f
 Scales how large the projectile will be drawn. Will also affect the hitbox (Entity.width, Entity.height) if assigned in SetDefaults. If changed elsewhere it will not affect the hitbox, so that will have to be adjusted manually via code in that situation if needed. Due to legacy code, scale does not affect the draw origin correctly, resulting in the projectile not rotating around the hitbox center correctly nor being drawn correctly centered on the hitbox. For small changes (0.8f to 1.2f) the effect is unnoticeable, but it is advised to avoid large values unless the projectile is manually drawn with the correct approach via ModProjectile.PreDraw(ref Color).
Defaults to 1f.
 
bool sentry
 Indicates that this projectile is a sentry
Defaults to false.
All sentries should set Projectile.timeLeft to Projectile.SentryLifeTime.
When a sentry is spawned, Player.UpdateMaxTurrets should be called immediately after.
 
bool shouldFallThrough
 
int soundDelay
 
int spriteDirection = 1
 
float stepSpeed = 1f
 Has nothing to do with the speed that this projectile travels, that is dictated by AI code adjusting Entity.velocity. This affects how quickly gfxOffY is adjusted.
 
bool stopsDealingDamageAfterPenetrateHits
 
bool tileCollide
 If true, the projectile will collide with tiles, usually bouncing or killing the tile depending on ModProjectile.OnTileCollide(Vector2). ExampleBulletshows how to implement bounce.
Defaults to true.
 
int timeLeft
 Time in ticks before this projectile will naturally despawn.
Each update timeLeft is decreased by 1. Once timeLeft hits 0, the Projectile will naturally despawn. The default value, 3600, is measured in ticks, which are usually 60 per seconds, so the default despawn time is about 60 seconds. Adjust this if you want the projectile to fizzle early rather than travel infinitely. Note that extraUpdates will cause it to decrease faster than normal time because Update is being called more often.
Defaults to 3600.
 
bool trap
 If true, this projectile was spawned by a trap tile.
 
int type
 The Projectile ID of this projectile. The Projectile ID is a unique number assigned to each Projectile loaded into the game. This will be equal to either an ProjectileID entry or ModContent.ProjectileType<T>, for example ProjectileID.WoodenArrowFriendly or ModContent.ProjectileType<MyModProjectile>(). To check if a Projectile instance is a specific Projectile, check Projectile.type == ProjectileID.VanillaProjectileHere or Projectile.type == ModContent.ProjectileType<ModdedProjectileHere>() in an if statement.
 
bool usesIDStaticNPCImmunity
 If true, all projectiles of this type share an immunity cooldown for each npc.
Use this rather than usesLocalNPCImmunity if you want other projectile types a chance to attack the npc, but don't want projectile of the same projectile type to hit an npc rapidly.
idStaticNPCHitCooldown controls the cooldown timing and must be assigned a suitable value to work properly.

 
bool usesLocalNPCImmunity
 If true, this projectile manages it's own immunity timers for each npc.
Use this rather than usesIDStaticNPCImmunity if you want multiple projectiles of the same type to have a chance to attack rapidly, but don't want a single projectile to hit rapidly.
localNPCHitCooldown controls the cooldown timing and must be assigned a suitable value to work properly.

 
bool usesOwnerMeleeHitCD
 
List< Vector2 > WhipPointsForCollision = new List<Vector2>()
 
WhipSettings WhipSettings
 
- Public Attributes inherited from Entity
bool active
 If true, the Entity actually exists within the game world. Within the specific entity array, if active is false, the entity is junk data. Always check active if iterating over the entity array. Another option for iterating is to use Main.ActivePlayers, Main.ActiveNPCs, Main.ActiveProjectiles, or Main.ActiveItems instead for simpler code.
 
int direction = 1
 The direction this entity is facing. A value of 1 means the entity is facing to the right. -1 means facing to the left.
 
int height
 The height of this Entity's hitbox, in pixels.
 
bool honeyWet
 
bool lavaWet
 
int oldDirection
 The direction of this Entity during the previous tick. For projectiles with Projectile.extraUpdates, this will be the direction during the previous extra update, not necessarily the direction during the previous tick.
 
Vector2 oldPosition
 The position of this Entity during the previous tick. For projectiles with Projectile.extraUpdates, this will be the position during the previous extra update, not necessarily the position during the previous tick.
 
Vector2 oldVelocity
 The velocity of this Entity during the previous tick. For projectiles with Projectile.extraUpdates, this will be the velocity during the previous extra update, not necessarily the velocity during the previous tick.
 
Vector2 position
 The position of this Entity in world coordinates. Note that this corresponds to the top left corner of the entity. Use Center instead for logic that needs the position at the center of the entity.
 
bool shimmerWet
 
Vector2 velocity
 The velocity of this Entity in world coordinates per tick.
 
bool wet
 The Entity is currently in water.
Projectile: Affects movement speed and some projectiles die when wet. Projectile.ignoreWater prevents this.
 
byte wetCount
 
int whoAmI
 The index of this Entity within its specific array. These arrays track the entities in the world.
Item: unused
Projectile: Main.projectile
NPC: Main.npc
Player: Main.player Note that Projectile.whoAmI is not consistent between clients in multiplayer for the same projectile.
 
int width
 The width of this Entity's hitbox, in pixels.
 

Static Public Attributes

const int ArrowLifeTime = 1200
 
static int maxAI = 3
 
static uint[][] perIDStaticNPCImmunity = new uint[ProjectileID.Count][]
 
const int SentryLifeTime = 36000
 

Properties

int ArmorPenetration [get, set]
 The number of defense points that this projectile can ignore on its own. Cannot be set to negative values. Defaults to 0. On spawn, if this projectile was fired from a weapon, this value has the total armor penetration of the weapon that made the projectile added to itself.
 
bool ContinuouslyUpdateDamage [get, set]
 
bool ContinuouslyUpdateDamageStats [get, set]
 If set damage will be recalculated based on originalDamage, DamageType and the owner player, just like minions and sentries.
Similarly for CritChance and ArmorPenetration. More...
 
int CritChance [get, set]
 The critical strike chance modifier of this projectile. Cannot be set to negative values. Defaults to 0. On spawn, if this projectile was fired from a weapon, this value has the total critical strike chance of the weapon that made the projectile added to itself.
 
DamageClass DamageType [get, set]
 The damage type assigned to this projectile, represented as a DamageClass. Leave blank or use DamageClass.Default to prevent damage type scaling of any kind for this projectile. Use DamageClass.Generic/Melee/Ranged/Magic/Summon/Throwing for vanilla damage types. Refer to ExampleMod for more information on how to create and use your own damage types.
 
RefReadOnlyArray< GlobalProjectileEntityGlobals [get]
 
EntityGlobalsEnumerator< GlobalProjectileGlobals [get]
 
bool IsMinionOrSentryRelated [get]
 Checks if the projectile is a minion, sentry, minion shot, or sentry shot.

 
int MaxUpdates [get, set]
 Derived from extraUpdates, except 1 is added to arrive at the total number of updates to be run. Using this instead of extraUpdates might make code more readable.
 
ModProjectile ModProjectile [get, set]
 The ModProjectile instance that controls the behavior of this projectile. This property is null if this is not a modded projectile.
 
string Name [get, set]
 
float Opacity [get, set]
 Derived from alpha, except it ranges from 0f to 1f and is inverted. 0 is transparent and 1 is fully opaque. Using this instead of alpha might make more sense when doing graphics calculations.
 
int OriginalArmorPenetration [get, set]
 The armor penetration of this projectile, without any player bonuses, similar to originalDamage
Used by ContinuouslyUpdateDamageStats to recalculate ArmorPenetration in combination with Player.GetTotalArmorPenetration(DamageClass)
 
int OriginalCritChance [get, set]
 The crit chance of this projectile, without any player bonuses, similar to originalDamage
Used by ContinuouslyUpdateDamageStats to recalculate CritChance in combination with Player.GetTotalCritChance(DamageClass)
 
NPC OwnerMinionAttackTargetNPC [get]
 
bool WipableTurret [get]
 
- Properties inherited from Entity
Vector2 Bottom [get, set]
 
Vector2 BottomLeft [get, set]
 
Vector2 BottomRight [get, set]
 
Vector2 Center [get, set]
 The center position of this entity in world coordinates. Calculated from position, width, and height.
 
Rectangle Hitbox [get, set]
 
Vector2 Left [get, set]
 
Vector2 Right [get, set]
 
Vector2 Size [get, set]
 
Vector2 Top [get, set]
 
Vector2 TopLeft [get, set]
 
Vector2 TopRight [get, set]
 
virtual Vector2 VisualPosition [get]
 
- Properties inherited from IEntityWithGlobals< GlobalProjectile >
RefReadOnlyArray< TGlobal > EntityGlobals [get]
 
int Type [get]
 

Member Function Documentation

◆ ApplyStatsFromSource()

void Projectile.ApplyStatsFromSource ( IEntitySource  spawnSource)

Transfers stat modifiers from the spawn source to the projectile.
Adds CritChance and ArmorPenetration bonuses from players (EntitySource_Parent), weapons (EntitySource_ItemUse)
If the source is a EntitySource_Parent projectile, CritChance and ArmorPenetration from the parent will be added, in order to transfer the original item/player bonus values.


To support minions, sentries and ContinuouslyUpdateDamageStats, OriginalCritChance and OriginalArmorPenetration are also copied from item sources and parent projectiles.

Parameters
spawnSource

◆ CountsAsClass()

bool Projectile.CountsAsClass ( DamageClass  damageClass)

This is used to check if the projectile is considered to be a member of a specified DamageClass.

Parameters
damageClassThe DamageClass to compare with the one assigned to this projectile.
Returns
true if this projectile's DamageClass matches damageClass , false otherwise
See also
CountsAsClass<T>

◆ CountsAsClass< T >()

bool Projectile.CountsAsClass< T > ( )

Type Constraints
T :DamageClass 
T :CountsAsClass 
T :ModContent.GetInstance<T>() 

◆ DropGeodeLoot()

static void Projectile.DropGeodeLoot ( Entity  entity)
static

Will drop loot the same way as when ProjectileID.Geode is cracked open.

Parameters
entityThe entity the loot originates from

◆ FindTargetWithLineOfSight()

int Projectile.FindTargetWithLineOfSight ( float  maxRange = 800f)

Finds the closest NPC to this projectile which can be targeted and which it has line of sight to.

Parameters
maxRangeThe maximum range at which this projectile should search out a target, measured in pixels.
Defaults to 800 (50 tiles). Each tile, for reference, measures out to be 16x16 pixels.
Returns
The index, in Main.npc, of the closest targetable NPC.

◆ GetGlobalProjectile< T >() [1/2]

T Projectile.GetGlobalProjectile< T > ( )

Gets the instance of the specified GlobalProjectile type. This will throw exceptions on failure.

Exceptions
KeyNotFoundException
Exceptions
IndexOutOfRangeException
Type Constraints
T :GlobalProjectile 
T :GlobalProjectile.GetGlobal<T> 
T :type 
T :EntityGlobals 

◆ GetGlobalProjectile< T >() [2/2]

T Projectile.GetGlobalProjectile< T > ( baseInstance)

Gets the local instance of the type of the specified GlobalProjectile instance. This will throw exceptions on failure.

Exceptions
KeyNotFoundException
Exceptions
NullReferenceException
Type Constraints
T :GlobalProjectile 
T :GlobalProjectile.GetGlobal 
T :type 
T :EntityGlobals 
T :baseInstance 

◆ HurtPlayer()

void Projectile.HurtPlayer ( Rectangle  hitbox)

Hurts the local player if the player intersects the specified hitbox.

Parameters
hitboxTypically the Entity.Hitbox, but any other Rectangle can be passed.

◆ NewProjectile()

static int Projectile.NewProjectile ( IEntitySource  spawnSource,
float  X,
float  Y,
float  SpeedX,
float  SpeedY,
int  Type,
int  Damage,
float  KnockBack,
int  Owner = -1,
float  ai0 = 0f,
float  ai1 = 0f,
float  ai2 = 0f 
)
static

Spawns a projectile into the game world with the given type. The spawn position is given in world coordinates by the X and Y parameters. SpeedX and SpeedY dictate the initial velocity. Damage and KnockBack are self-explanatory. Owner is the player who spawned the projectile, almost always Main.myPlayer. ai0, ai1, and ai2 will initialize the Projectile.ai[] array with the supplied values. This can be used to pass in information to the Projectile. The Projectile AI code will have to be written to utilize those values. The return value is the index of the spawned Projectile within the Main.projectile array.
Make sure that this method is called only by the client in charge of the source causing this projectile to spawn. Failure to do this will result in the projectile spawning once for each player in the world. For example, if Player code uses this method, make sure to first check

if(Main.myPlayer == Player.whoAmI) to ensure that only the local player spawns the projectile.
Projectiles spawning other projectiles should check if(Main.myPlayer == Projectile.owner)
If the source is an NPC or non-player owned projectile, checking if (Main.netMode != NetmodeID.MultiplayerClient) will ensure that clients don't attempt to spawn the projectile.

Parameters
spawnSource
X
Y
SpeedX
SpeedY
TypeEither a ProjectileID entry or ModContent.ProjectileType<T>, for example ProjectileID.FireArrow or ModContent.ProjectileType<MyModProjectile>()
Damage
KnockBack
Owner
ai0
ai1
ai2
Returns

◆ NewProjectileDirect()

static Projectile Projectile.NewProjectileDirect ( IEntitySource  spawnSource,
Vector2  position,
Vector2  velocity,
int  type,
int  damage,
float  knockback,
int  owner = -1,
float  ai0 = 0f,
float  ai1 = 0f,
float  ai2 = 0f 
)
static



This particular overload uses a Vector2 instead of X and Y to determine the actual spawn position and a Vector2 to dictate the initial velocity. The return value is the actual Projectile instance rather than the index of the spawned Projectile within the Main.projectile array.
A short-hand for

Main.projectile[Projectile.NewProjectile(...)]

◆ TryGetGlobalProjectile< T >() [1/2]

bool Projectile.TryGetGlobalProjectile< T > ( out T  result)

Gets the instance of the specified GlobalProjectile type.

Type Constraints
T :GlobalProjectile 
T :GlobalProjectile.TryGetGlobal 
T :type 
T :EntityGlobals 
T :out 
T :result 

◆ TryGetGlobalProjectile< T >() [2/2]

bool Projectile.TryGetGlobalProjectile< T > ( baseInstance,
out T  result 
)

Safely attempts to get the local instance of the type of the specified GlobalProjectile instance.

Returns
Whether or not the requested instance has been found.
Type Constraints
T :GlobalProjectile 
T :GlobalProjectile.TryGetGlobal 
T :type 
T :EntityGlobals 
T :baseInstance 
T :out 
T :result 

◆ TryGetOwner()

bool Projectile.TryGetOwner ( [NotNullWhen(true)] out Player player)

Attempts to get the owner player of this projectile. Returns null for projectiles spawned by TownNPC (npcProj) and trap projectiles (trap). Returns Main.player[owner] otherwise. Note that this logic assumes that projectiles have the correct fields set, which might not always be true. Also note that in single player enemy projectiles are also "owned" by the player, so this alone isn't sufficient to know which projectiles were spawned by the player. Additional friendly checks would be needed for that.

Parameters
player
Returns

Property Documentation

◆ ContinuouslyUpdateDamageStats

bool Projectile.ContinuouslyUpdateDamageStats
getset

If set damage will be recalculated based on originalDamage, DamageType and the owner player, just like minions and sentries.
Similarly for CritChance and ArmorPenetration.

No need to set this if minion or sentry is set.