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); } }
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); }
//////////////// 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); } } }
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 => { } ); } }
public static void DamageTilesInRadius(int tileX, int tileY, int damage, int radius) { DestructibleTilesProjectile.HitTilesInRadius(tileX, tileY, radius, damage); }
//// public static bool DamageTile(int tileX, int tileY, int damage, int totalHits) { return(DestructibleTilesProjectile.HitTile(damage, tileX, tileY, totalHits)); }