using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.GameContent.Achievements;
namespace Boombastic.Projectiles
{
// to investigate: Projectile.Damage, (8843)
class SuperDynamite : ModProjectile
{
public override void SetDefaults()
{
projectile.name = "Super Dynamite";
// while the sprite is actually bigger than 15x15, we use 15x15 since it lets the projectile clip into tiles as it bounces. It looks better.
projectile.width = 15;
projectile.height = 15;
projectile.friendly = false;
projectile.penetrate = -1;
// 8 second fuse.
projectile.timeLeft = 480;
// These 2 help the projectile hitbox be centered on the projectile sprite.
drawOffsetX = 5;
drawOriginOffsetY = 5;
}
public override void AI()
{
if (projectile.owner == Main.myPlayer && projectile.timeLeft <= 3)
{
projectile.tileCollide = false;
// Set to transparant. This projectile technically lives as transparant for about 3 frames
projectile.alpha = 255;
// change the hitbox size, centered about the original projectile center. This makes the projectile damage enemies during the explosion.
projectile.position.X = projectile.position.X + (float)(projectile.width / 2);
projectile.position.Y = projectile.position.Y + (float)(projectile.height / 2);
projectile.width = 250;
projectile.height = 250;
projectile.position.X = projectile.position.X - (float)(projectile.width / 2);
projectile.position.Y = projectile.position.Y - (float)(projectile.height / 2);
projectile.damage = 400;
projectile.knockBack = 10f;
}
else
{
// Smoke and fuse dust spawn.
if (Main.rand.Next(2) == 0)
{
int dustIndex = Dust.NewDust(new Vector2(projectile.position.X, projectile.position.Y), projectile.width, projectile.height, 31, 0f, 0f, 100, default(Color), 1f);
Main.dust[dustIndex].scale = 0.1f + (float)Main.rand.Next(5) * 0.1f;
Main.dust[dustIndex].fadeIn = 1.5f + (float)Main.rand.Next(5) * 0.1f;
Main.dust[dustIndex].noGravity = true;
Main.dust[dustIndex].position = projectile.Center + new Vector2(0f, (float)(-(float)projectile.height / 2)).RotatedBy((double)projectile.rotation, default(Vector2)) * 1.1f;
dustIndex = Dust.NewDust(new Vector2(projectile.position.X, projectile.position.Y), projectile.width, projectile.height, 6, 0f, 0f, 100, default(Color), 1f);
Main.dust[dustIndex].scale = 1f + (float)Main.rand.Next(5) * 0.1f;
Main.dust[dustIndex].noGravity = true;
Main.dust[dustIndex].position = projectile.Center + new Vector2(0f, (float)(-(float)projectile.height / 2 - 6)).RotatedBy((double)projectile.rotation, default(Vector2)) * 1.1f;
}
}
projectile.ai[0] += 1f;
if (projectile.ai[0] > 5f)
{
projectile.ai[0] = 10f;
// Roll speed dampening.
if (projectile.velocity.Y == 0f && projectile.velocity.X != 0f)
{
projectile.velocity.X = projectile.velocity.X * 0.97f;
//if (projectile.type == 29 || projectile.type == 470 || projectile.type == 637)
{
projectile.velocity.X = projectile.velocity.X * 0.99f;
}
if ((double)projectile.velocity.X > -0.01 && (double)projectile.velocity.X < 0.01)
{
projectile.velocity.X = 0f;
projectile.netUpdate = true;
}
}
projectile.velocity.Y = projectile.velocity.Y + 0.2f;
}
// Rotation increased by velocity.X
projectile.rotation += projectile.velocity.X * 0.1f;
return;
}
public override void Kill(int timeLeft)
{
/*
// If we are the original projectile, spawn the 5 child projectiles
if (projectile.ai[1] == 0)
{
for (int i = 0; i < 5; i++)
{
// Random upward vector.
Vector2 vel = new Vector2(Main.rand.NextFloat(0, 0), Main.rand.NextFloat(0, 0));
Projectile.NewProjectile(projectile.Center, vel, projectile.type, projectile.damage, projectile.knockBack, projectile.owner, 0, 1);
}
}
*/
// Play explosion sound
Main.PlaySound(SoundID.Item14, projectile.position);
// Smoke Dust spawn
for (int i = 0; i < 50; i++)
{
int dustIndex = Dust.NewDust(new Vector2(projectile.position.X, projectile.position.Y), projectile.width, projectile.height, 31, 0f, 0f, 100, default(Color), 2f);
Main.dust[dustIndex].velocity *= 1.4f;
}
// Fire Dust spawn
for (int i = 0; i < 80; i++)
{
int dustIndex = Dust.NewDust(new Vector2(projectile.position.X, projectile.position.Y), projectile.width, projectile.height, 6, 0f, 0f, 100, default(Color), 3f);
Main.dust[dustIndex].noGravity = true;
Main.dust[dustIndex].velocity *= 5f;
dustIndex = Dust.NewDust(new Vector2(projectile.position.X, projectile.position.Y), projectile.width, projectile.height, 6, 0f, 0f, 100, default(Color), 2f);
Main.dust[dustIndex].velocity *= 3f;
}
// Large Smoke Gore spawn
for (int g = 0; g < 2; g++)
{
int goreIndex = Gore.NewGore(new Vector2(projectile.position.X + (float)(projectile.width / 2) - 24f, projectile.position.Y + (float)(projectile.height / 2) - 24f), default(Vector2), Main.rand.Next(61, 64), 1f);
Main.gore[goreIndex].scale = 1.5f;
Main.gore[goreIndex].velocity.X = Main.gore[goreIndex].velocity.X + 1.5f;
Main.gore[goreIndex].velocity.Y = Main.gore[goreIndex].velocity.Y + 1.5f;
goreIndex = Gore.NewGore(new Vector2(projectile.position.X + (float)(projectile.width / 2) - 24f, projectile.position.Y + (float)(projectile.height / 2) - 24f), default(Vector2), Main.rand.Next(61, 64), 1f);
Main.gore[goreIndex].scale = 1.5f;
Main.gore[goreIndex].velocity.X = Main.gore[goreIndex].velocity.X - 1.5f;
Main.gore[goreIndex].velocity.Y = Main.gore[goreIndex].velocity.Y + 1.5f;
goreIndex = Gore.NewGore(new Vector2(projectile.position.X + (float)(projectile.width / 2) - 24f, projectile.position.Y + (float)(projectile.height / 2) - 24f), default(Vector2), Main.rand.Next(61, 64), 1f);
Main.gore[goreIndex].scale = 1.5f;
Main.gore[goreIndex].velocity.X = Main.gore[goreIndex].velocity.X + 1.5f;
Main.gore[goreIndex].velocity.Y = Main.gore[goreIndex].velocity.Y - 1.5f;
goreIndex = Gore.NewGore(new Vector2(projectile.position.X + (float)(projectile.width / 2) - 24f, projectile.position.Y + (float)(projectile.height / 2) - 24f), default(Vector2), Main.rand.Next(61, 64), 1f);
Main.gore[goreIndex].scale = 1.5f;
Main.gore[goreIndex].velocity.X = Main.gore[goreIndex].velocity.X - 1.5f;
Main.gore[goreIndex].velocity.Y = Main.gore[goreIndex].velocity.Y - 1.5f;
}
// reset size to normal width and height.
projectile.position.X = projectile.position.X + (float)(projectile.width / 2);
projectile.position.Y = projectile.position.Y + (float)(projectile.height / 2);
projectile.width = 10;
projectile.height = 10;
projectile.position.X = projectile.position.X - (float)(projectile.width / 2);
projectile.position.Y = projectile.position.Y - (float)(projectile.height / 2);
// TODO, tmodloader helper method
{
int explosionRadius = 9;
//if (projectile.type == 29 || projectile.type == 470 || projectile.type == 637)
//{
// explosionRadius = 15;
//}
int minTileX = (int)(projectile.position.X / 16f - (float)explosionRadius);
int maxTileX = (int)(projectile.position.X / 16f + (float)explosionRadius);
int minTileY = (int)(projectile.position.Y / 16f - (float)explosionRadius);
int maxTileY = (int)(projectile.position.Y / 16f + (float)explosionRadius);
if (minTileX < 0)
{
minTileX = 0;
}
if (maxTileX > Main.maxTilesX)
{
maxTileX = Main.maxTilesX;
}
if (minTileY < 0)
{
minTileY = 0;
}
if (maxTileY > Main.maxTilesY)
{
maxTileY = Main.maxTilesY;
}
bool canKillWalls = false;
for (int x = minTileX; x <= maxTileX; x++)
{
for (int y = minTileY; y <= maxTileY; y++)
{
float diffX = Math.Abs((float)x - projectile.position.X / 16f);
float diffY = Math.Abs((float)y - projectile.position.Y / 16f);
double distance = Math.Sqrt((double)(diffX * diffX + diffY * diffY));
if (distance < (double)explosionRadius && Main.tile[x, y] != null && Main.tile[x, y].wall == 0)
{
canKillWalls = true;
break;
}
}
}
AchievementsHelper.CurrentlyMining = true;
for (int i = minTileX; i <= maxTileX; i++)
{
for (int j = minTileY; j <= maxTileY; j++)
{
float diffX = Math.Abs((float)i - projectile.position.X / 16f);
float diffY = Math.Abs((float)j - projectile.position.Y / 16f);
double distanceToTile = Math.Sqrt((double)(diffX * diffX + diffY * diffY));
if (distanceToTile < (double)explosionRadius)
{
bool canKillTile = true;
if (Main.tile[i, j] != null && Main.tile[i, j].active())
{
canKillTile = true;
if (Main.tileDungeon[(int)Main.tile[i, j].type] || Main.tile[i, j].type == 88 || Main.tile[i, j].type == 21 || Main.tile[i, j].type == 26 || Main.tile[i, j].type == 107 || Main.tile[i, j].type == 108 || Main.tile[i, j].type == 111 || Main.tile[i, j].type == 226 || Main.tile[i, j].type == 237 || Main.tile[i, j].type == 221 || Main.tile[i, j].type == 222 || Main.tile[i, j].type == 223 || Main.tile[i, j].type == 211 || Main.tile[i, j].type == 404)
{
canKillTile = false;
}
if (!Main.hardMode && Main.tile[i, j].type == 58)
{
canKillTile = false;
}
if (!TileLoader.CanExplode(i, j))
{
canKillTile = false;
}
if (canKillTile)
{
WorldGen.KillTile(i, j, false, false, false);
if (!Main.tile[i, j].active() && Main.netMode != 0)
{
NetMessage.SendData(17, -1, -1, "", 0, (float)i, (float)j, 0f, 0, 0, 0);
}
}
}
if (canKillTile)
{
for (int x = i - 1; x <= i + 1; x++)
{
for (int y = j - 1; y <= j + 1; y++)
{
if (Main.tile[x, y] != null && Main.tile[x, y].wall > 0 && canKillWalls && WallLoader.CanExplode(x, y, Main.tile[x, y].wall))
{
WorldGen.KillWall(x, y, false);
if (Main.tile[x, y].wall == 0 && Main.netMode != 0)
{
NetMessage.SendData(17, -1, -1, "", 2, (float)x, (float)y, 0f, 0, 0, 0);
}
}
}
}
}
}
}
}
AchievementsHelper.CurrentlyMining = false;
}
}
}
}