TModLoader v1.4.4.9
TModLoader source code documentation
Loading...
Searching...
No Matches

◆ NewProjectile() [1/2]

static int Terraria.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 )
inlinestatic

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 F:Terraria.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 T:Terraria.ID.ProjectileID entry or M:Terraria.ModLoader.ModContent.ProjectileType``1, for example F:Terraria.ID.ProjectileID.FireArrow or ModContent.ProjectileType<MyModProjectile>()
Damage
KnockBack
Owner
ai0
ai1
ai2
Returns

Definition at line 10144 of file Projectile.cs.

10145 {
10146 //IL_00d6: Unknown result type (might be due to invalid IL or missing references)
10147 if (Owner == -1)
10148 {
10149 Owner = Main.myPlayer;
10150 }
10151 int num = 1000;
10152 for (int i = 0; i < 1000; i++)
10153 {
10154 if (!Main.projectile[i].active)
10155 {
10156 num = i;
10157 break;
10158 }
10159 }
10160 if (num == 1000)
10161 {
10163 }
10164 Projectile projectile = Main.projectile[num];
10165 projectile.SetDefaults(Type);
10166 projectile.position.X = X - (float)projectile.width * 0.5f;
10167 projectile.position.Y = Y - (float)projectile.height * 0.5f;
10168 projectile.owner = Owner;
10169 projectile.velocity.X = SpeedX;
10170 projectile.velocity.Y = SpeedY;
10171 projectile.damage = Damage;
10172 projectile.knockBack = KnockBack;
10173 projectile.identity = num;
10174 projectile.gfxOffY = 0f;
10175 projectile.stepSpeed = 1f;
10176 projectile.wet = Collision.WetCollision(projectile.position, projectile.width, projectile.height);
10177 if (projectile.ignoreWater)
10178 {
10179 projectile.wet = false;
10180 }
10181 projectile.honeyWet = Collision.honey;
10182 projectile.shimmerWet = Collision.shimmer;
10183 Main.projectileIdentity[Owner, num] = num;
10185 if (projectile.aiStyle == 1)
10186 {
10187 while (projectile.velocity.X >= 16f || projectile.velocity.X <= -16f || projectile.velocity.Y >= 16f || projectile.velocity.Y < -16f)
10188 {
10189 projectile.velocity.X *= 0.97f;
10190 projectile.velocity.Y *= 0.97f;
10191 }
10192 }
10193 if (Owner == Main.myPlayer)
10194 {
10195 switch (Type)
10196 {
10197 case 206:
10198 projectile.ai[0] = (float)Main.rand.Next(-100, 101) * 0.0005f;
10199 projectile.ai[1] = (float)Main.rand.Next(-100, 101) * 0.0005f;
10200 break;
10201 case 335:
10202 projectile.ai[1] = Main.rand.Next(4);
10203 break;
10204 case 358:
10205 projectile.ai[1] = (float)Main.rand.Next(10, 31) * 0.1f;
10206 break;
10207 case 406:
10208 projectile.ai[1] = (float)Main.rand.Next(10, 21) * 0.1f;
10209 break;
10210 default:
10211 projectile.ai[0] = ai0;
10212 projectile.ai[1] = ai1;
10213 projectile.ai[2] = ai2;
10214 break;
10215 }
10216 }
10217 if (Type == 434)
10218 {
10219 projectile.ai[0] = projectile.position.X;
10220 projectile.ai[1] = projectile.position.Y;
10221 }
10222 if (Type > 0)
10223 {
10224 if (ProjectileID.Sets.NeedsUUID[Type])
10225 {
10226 projectile.projUUID = projectile.identity;
10227 }
10229 {
10230 int num2 = Main.projectile[(int)projectile.ai[0]].projUUID;
10231 if (num2 >= 0)
10232 {
10233 projectile.ai[0] = num2;
10234 }
10235 }
10236 }
10237 if (Owner == Main.myPlayer)
10238 {
10239 if (ProjectileID.Sets.IsAGolfBall[Type] && Damage <= 0)
10240 {
10241 int num3 = 0;
10242 int num4 = 0;
10243 int num5 = 99999999;
10244 for (int j = 0; j < 1000; j++)
10245 {
10246 if (Main.projectile[j].active && ProjectileID.Sets.IsAGolfBall[Main.projectile[j].type] && Main.projectile[j].owner == Owner && Main.projectile[j].damage <= 0)
10247 {
10248 num3++;
10249 if (num5 > Main.projectile[j].timeLeft)
10250 {
10251 num4 = j;
10252 num5 = Main.projectile[j].timeLeft;
10253 }
10254 }
10255 }
10256 if (num3 > 10)
10257 {
10258 Main.projectile[num4].Kill();
10259 }
10260 }
10261 if (Type == 28)
10262 {
10263 projectile.timeLeft = 180;
10264 }
10265 if (Type == 516)
10266 {
10267 projectile.timeLeft = 180;
10268 }
10269 if (Type == 519)
10270 {
10271 projectile.timeLeft = 180;
10272 }
10273 if (Type == 29)
10274 {
10275 projectile.timeLeft = 300;
10276 }
10277 if (Type == 470)
10278 {
10279 projectile.timeLeft = 300;
10280 }
10281 if (Type == 637)
10282 {
10283 projectile.timeLeft = 300;
10284 }
10285 if (Type == 30)
10286 {
10287 projectile.timeLeft = 180;
10288 }
10289 if (Type == 517)
10290 {
10291 projectile.timeLeft = 180;
10292 }
10293 if (Type == 37)
10294 {
10295 projectile.timeLeft = 180;
10296 }
10297 if (Type == 773)
10298 {
10299 projectile.timeLeft = 180;
10300 }
10301 if (Type == 75)
10302 {
10303 projectile.timeLeft = 180;
10304 }
10305 if (Type == 133)
10306 {
10307 projectile.timeLeft = 180;
10308 }
10309 if (Type == 136)
10310 {
10311 projectile.timeLeft = 180;
10312 }
10313 if (Type == 139)
10314 {
10315 projectile.timeLeft = 180;
10316 }
10317 if (Type == 142)
10318 {
10319 projectile.timeLeft = 180;
10320 }
10321 if (Type == 397)
10322 {
10323 projectile.timeLeft = 180;
10324 }
10325 if (Type == 419)
10326 {
10327 projectile.timeLeft = 600;
10328 }
10329 if (Type == 420)
10330 {
10331 projectile.timeLeft = 600;
10332 }
10333 if (Type == 421)
10334 {
10335 projectile.timeLeft = 600;
10336 }
10337 if (Type == 422)
10338 {
10339 projectile.timeLeft = 600;
10340 }
10341 if (Type == 588)
10342 {
10343 projectile.timeLeft = 180;
10344 }
10345 if (Type == 779)
10346 {
10347 projectile.timeLeft = 60;
10348 }
10349 if (Type == 783)
10350 {
10351 projectile.timeLeft = 60;
10352 }
10353 if (Type == 862 || Type == 863)
10354 {
10355 projectile.timeLeft = 60;
10356 }
10357 if (Type == 443)
10358 {
10359 projectile.timeLeft = 300;
10360 }
10361 if (Type == 681)
10362 {
10363 projectile.timeLeft = 600;
10364 }
10365 if (Type == 684)
10366 {
10367 projectile.timeLeft = 60;
10368 }
10369 if (Type == 706)
10370 {
10371 projectile.timeLeft = 120;
10372 }
10373 if (Type == 680 && Main.player[projectile.owner].setSquireT2)
10374 {
10375 projectile.penetrate = 7;
10376 }
10377 if (Type == 777 || Type == 781 || Type == 794 || Type == 797 || Type == 800 || Type == 785 || Type == 788 || Type == 791 || Type == 903 || Type == 904 || Type == 905 || Type == 906 || Type == 910 || Type == 911)
10378 {
10379 projectile.timeLeft = 180;
10380 }
10381 if (Main.netMode != 2)
10382 {
10383 Player throwingPlayer = Main.player[Owner];
10384 if (throwingPlayer.AnyThrownCostReduction && throwingPlayer.HeldItem.CountsAsClass(DamageClass.Throwing) && spawnSource is EntitySource_ItemUse_WithAmmo)
10385 {
10386 projectile.noDropItem = true;
10387 }
10388 }
10389 }
10390 if (Type == 249)
10391 {
10392 projectile.frame = Main.rand.Next(5);
10393 }
10394 if (Owner == Main.myPlayer)
10395 {
10396 Main.player[Owner].TryUpdateChannel(projectile);
10397 }
10398 projectile.ApplyStatsFromSource(spawnSource);
10400 if (Main.netMode != 0 && Owner == Main.myPlayer)
10401 {
10402 NetMessage.SendData(27, -1, -1, null, num);
10403 }
10404 return num;
10405 }
static bool[] IsAGolfBall
If true for a given projectile type (F:Terraria.Projectile.type), then that projectile is a kind of g...
static DamageClass Throwing
Class provided for modders who want to coordinate throwing accessories and items. Not used by any van...
T:Terraria.ModLoader.DamageClass is used to determine the application of item effects,...
static void OnSpawn(Projectile projectile, IEntitySource source)
This serves as the central class from which projectile-related functions are carried out....
static void FindBannerToAssociateTo(IEntitySource spawnSource, Projectile next)
static int FindOldestProjectile()

References Terraria.Projectile.ai, Terraria.Projectile.aiStyle, Terraria.Projectile.ApplyStatsFromSource(), Terraria.Projectile.Damage(), Terraria.Projectile.FindBannerToAssociateTo(), Terraria.Projectile.FindOldestProjectile(), Terraria.Entity.height, Terraria.Collision.honey, Terraria.Projectile.identity, Terraria.Projectile.ignoreWater, Terraria.ID.ProjectileID.Sets.IsAGolfBall, Terraria.Main.myPlayer, Terraria.ID.ProjectileID.Sets.NeedsUUID, Terraria.Main.netMode, Terraria.ModLoader.ProjectileLoader.OnSpawn(), Terraria.Projectile.owner, Terraria.Main.player, Terraria.Entity.position, Terraria.Main.projectile, Terraria.Main.projectileIdentity, Terraria.Main.rand, Terraria.NetMessage.SendData(), Terraria.Projectile.SetDefaults(), Terraria.Collision.shimmer, Terraria.ID.ProjectileID.Sets.StardustDragon, Terraria.ModLoader.DamageClass.Throwing, Terraria.Entity.velocity, Terraria.Collision.WetCollision(), and Terraria.Entity.width.

+ Here is the call graph for this function: