public static int ComputeBeamProjectileDamage(Projectile projectile)
        {
            var config = DestructibleTilesConfig.Instance;
            int damage = DestructibleTilesProjectile.ComputeProjectileDamage(projectile);

            return((int)((float)damage * config.BeamDamageScale));
        }
        public static IDictionary <ProjectileDefinition, (int radius, int damage)> GetExplosivesStats()
        {
            var projectiles = new Dictionary <ProjectileDefinition, (int, int)>();
            int inactivePos = 0;

            for (int i = 0; i < Main.projectile.Length; i++)
            {
                if (Main.projectile[i] == null || !Main.projectile[i].active)
                {
                    inactivePos = i;
                    break;
                }
            }

            for (int i = 0; i < Main.projectileTexture.Length; i++)
            {
                (int, int)? stats = DestructibleTilesProjectile.CalculateExplosiveStats(inactivePos, i);

                if (stats.HasValue)
                {
                    var projDef = new ProjectileDefinition(i);
                    projectiles[projDef] = stats.Value;
                }
            }

            Main.projectile[inactivePos] = new Projectile();

            return(projectiles);
        }
        ////////////////

        public void BehaviorAsKinetic(Projectile projectile, Vector2 oldVelocity)
        {
            var config = DestructibleTilesConfig.Instance;

            var rect = new Rectangle(
                (int)projectile.position.X + (int)oldVelocity.X,
                (int)projectile.position.Y + (int)oldVelocity.Y,
                projectile.width,
                projectile.height
                );

            bool onlySometimesRespects;
            bool respectsPlatforms = ProjectileAttributeHelpers.DoesVanillaProjectileHitPlatforms(
                projectile,
                out onlySometimesRespects
                ) && !onlySometimesRespects;

            int damage = DestructibleTilesProjectile.ComputeProjectileDamage(projectile);

            IList <(ushort, ushort)> hits = DestructibleTilesProjectile.FindNearbyHittableTiles(
                projectile.Center,
                rect,
                respectsPlatforms
                );

            if (config.DebugModeInfo)
            {
                this.OutputKineticProjectileDebugInfo(projectile, oldVelocity, hits);
            }

            foreach ((ushort x, ushort y) in hits)
            {
                DestructibleTilesProjectile.HitTile(damage, x, y, hits.Count);
            }
        }
Exemple #4
0
        public static float ComputeDamage(int tileX, int tileY, int damage, int totalHits)
        {
            if (!TileDataManager.IsValidTile(tileX, tileY))
            {
                return(0f);
            }

            return(DestructibleTilesProjectile.ComputeHitDamage(Framing.GetTileSafely(tileX, tileY), damage, totalHits));
        }
        public static bool HitTile(int damage, int tileX, int tileY, int totalHits, float percent = 1f)
        {
            var  mymod  = DestructibleTilesMod.Instance;
            var  config = DestructibleTilesConfig.Instance;
            Tile tile   = Framing.GetTileSafely(tileX, tileY);
            //HitTile plrTileHits = Main.LocalPlayer.hitTile;

            //int tileHitId = plrTileHits.HitObject( tileX, tileY, 1 );
            int dmg = (int)(DestructibleTilesProjectile.ComputeHitDamage(tile, damage, totalHits) * percent);

            if (config.DebugModeInfo)
            {
                Main.NewText(HamstarHelpers.Helpers.Tiles.Attributes.TileAttributeHelpers.GetVanillaTileDisplayName(tile.type) + " hit for " + dmg.ToString("N2"));
            }

            if (mymod.TileDataMngr.AddDamage(tileX, tileY, dmg) >= 100)                 //
            //if( plrTileHits.AddDamage( tileHitId, dmg, true ) >= 100 ) {
            //	plrTileHits.Clear( tileHitId );
            {
                bool isTileKilled = TileHelpers.KillTileSynced(
                    tileX: tileX,
                    tileY: tileY,
                    effectOnly: false,
                    dropsItem: config.DestroyedTilesDropItems,
                    forceSyncIfUnchanged: true,
                    suppressErrors: false
                    );

                if (isTileKilled)
                {
                    WorldGen.SquareTileFrame(tileX, tileY);                         // unnecessary?

                    ParticleFxHelpers.MakeDustCloud(
                        new Vector2((tileX * 16) + 8, (tileY * 16) + 8),
                        1,
                        0.3f,
                        1.2f
                        );
                }

                return(isTileKilled);
            }

            return(false);
        }
        ////////////////

        public static void HitTilesInRadius(int tileX, int tileY, int radius, int damage)
        {
            int radiusTiles        = (int)Math.Round((double)(radius / 16));
            int radiusTilesSquared = radiusTiles * radiusTiles;

            int left   = tileX - (radiusTiles + 1);
            int right  = tileX + (radiusTiles + 1);
            int top    = tileY - (radiusTiles + 1);
            int bottom = tileY + (radiusTiles + 1);

            for (int i = left; i < right; i++)
            {
                if (i < 0 || i >= Main.maxTilesX - 1)
                {
                    continue;
                }

                for (int j = top; j < bottom; j++)
                {
                    if (j < 0 || j >= Main.maxTilesY - 1)
                    {
                        continue;
                    }
                    if (TileHelpers.IsAir(Framing.GetTileSafely(i, j)))
                    {
                        continue;
                    }

                    int xOff = i - tileX;
                    int yOff = j - tileY;

                    int currTileDistSquared = (xOff * xOff) + (yOff * yOff);
                    if (currTileDistSquared > radiusTilesSquared)
                    {
                        continue;
                    }

                    float percentToCenter = 1f - ((float)currTileDistSquared / (float)radiusTilesSquared);

                    DestructibleTilesProjectile.HitTile(damage, i, j, 1, percentToCenter);
                }
            }
        }
        ////////////////

        public override bool OnTileCollide(Projectile projectile, Vector2 oldVelocity)
        {
            var config  = DestructibleTilesConfig.Instance;
            var projDef = new ProjectileDefinition(projectile.type);

            // Explosives are handled elsewhere
            if (config.ProjectilesAsAoE.ContainsKey(projDef))
            {
                return(base.OnTileCollide(projectile, oldVelocity));
            }

            bool _;

            if (!DestructibleTilesProjectile.CanHitTiles(projectile, out _))
            {
                return(base.OnTileCollide(projectile, oldVelocity));
            }

            this.BehaviorAsKinetic(projectile, oldVelocity);

            return(base.OnTileCollide(projectile, oldVelocity));
        }
        public static bool CanHitTiles(Projectile projectile, out bool hasCooldown)
        {
            var config  = DestructibleTilesConfig.Instance;
            var projDef = new ProjectileDefinition(projectile.type);

            string timerName   = "PTH_" + projectile.type + "_" + projectile.whoAmI;
            bool   isRepeatHit = Timers.GetTimerTickDuration(timerName) > 0;

            hasCooldown = config.ProjectilesAsConsecutiveHitters.ContainsKey(projDef);

            Timers.SetTimer(timerName, 2, false, () => false);

            if (isRepeatHit)
            {
                if (hasCooldown)
                {
                    DestructibleTilesProjectile.CanHitTilesAgain(projectile, projDef, timerName, ref isRepeatHit);
                }
            }

            return(!isRepeatHit);
        }
Exemple #9
0
        ////////////////

        public void SetProjectileDefaults()             //<- Must be called from PostSetupContent?
        {
            if (!this.AutoLoadDefaultExplosiveProjectiles)
            {
                return;
            }

            IDictionary <ProjectileDefinition, (int radius, int damage)> explosiveProjs
                = DestructibleTilesProjectile.GetExplosivesStats();

            foreach ((ProjectileDefinition projDef, (int radius, int damage)stats) in explosiveProjs)
            {
                if (!this.ProjectilesAsAoE.ContainsKey(projDef))
                {
                    this.ProjectilesAsAoE[projDef] = new ProjectileStateDefinition(0, 0, 0, stats.radius);
                }
                if (!this.ProjectileTileDamageDefaults.ContainsKey(projDef))
                {
                    this.ProjectileTileDamageDefaults[projDef] = new ProjectileStateDefinition(0, 0, 0, stats.damage);
                }
            }
        }
Exemple #10
0
        public void BehaviorAsAoE(Projectile projectile)
        {
            var config  = DestructibleTilesConfig.Instance;
            var projDef = new ProjectileDefinition(projectile.type);

            ProjectileStateDefinition projExploDef = config.ProjectilesAsAoE[projDef];

            if (!projExploDef.IsProjectileMatch(projectile))
            {
                return;
            }

            int tileX  = (int)projectile.position.X >> 4;
            int tileY  = (int)projectile.position.Y >> 4;
            int damage = DestructibleTilesProjectile.ComputeProjectileDamage(projectile);

            if (config.DebugModeInfo)
            {
                Main.NewText("RADIUS - " + projDef.ToString() + ", radius:" + projExploDef.Amount + ", damage:" + damage);
            }

            DestructibleTilesProjectile.HitTilesInRadius(tileX, tileY, projExploDef.Amount, damage);
        }
        public void BehaviorAsBeam(Projectile projectile)
        {
            bool hasCooldown;

            if (!DestructibleTilesProjectile.CanHitTiles(projectile, out hasCooldown) || hasCooldown)
            {
                return;
            }

            Vector2 projPos     = projectile.Center + (projectile.velocity * projectile.localAI[1]);
            Point?  tilePosNull = TileFinderHelpers.GetNearestTile(projPos, TilePattern.CommonSolid, 32);

            if (!tilePosNull.HasValue)
            {
                return;
            }

//DebugHelpers.Print("proj_"+projectile.whoAmI,
//	"vel: "+projectile.velocity.X.ToString("N2")+":"+projectile.velocity.Y.ToString("N2")+
//	", ai: "+string.Join(", ", projectile.ai.Select(f=>f.ToString("N1")))+
//	", localAi: "+string.Join(", ", projectile.localAI.Select(f=>f.ToString("N1"))),
//	20 );
//var rpos1 = (projPos / 16f) * 16f;
//var rpos2 = new Vector2( rpos1.X + 16, rpos1.Y + 16 );
//Dust.QuickBox( rpos1, rpos2, 0, Color.Blue, d => { } );
            var tilePos = tilePosNull.Value;
            int damage  = DestructibleTilesProjectile.ComputeBeamProjectileDamage(projectile);

            if (DestructibleTilesProjectile.HitTile(damage, tilePos.X, tilePos.Y, 1))
            {
                bool _;
                projectile.localAI[1] = TileCollisionHelpers.MeasureWorldDistanceToTile(projectile.Center, projectile.velocity, 2400f, out _);
//var pos1 = tilePos.ToVector2() * 16f;
//var pos2 = new Vector2( pos1.X + 16, pos1.Y + 16 );
//Dust.QuickBox( pos1, pos2, 0, Color.Red, d => { } );
            }
        }
Exemple #12
0
 public static void DamageTilesInRadius(int tileX, int tileY, int damage, int radius)
 {
     DestructibleTilesProjectile.HitTilesInRadius(tileX, tileY, radius, damage);
 }
Exemple #13
0
        ////

        public static bool DamageTile(int tileX, int tileY, int damage, int totalHits)
        {
            return(DestructibleTilesProjectile.HitTile(damage, tileX, tileY, totalHits));
        }