public override void Explode(Explosion explosion) { // Destroy terrain Vector3 origin = explosion.Origin; float radius = explosion.BlockRadius; IndexPosition cpos = FixedTerrain.WorldToChunkCoords(origin); IndexPosition blockPos = Chunk.WorldToBlockCoords(origin); blockPos -= cpos * Chunk.SIZE; Chunk chunk; if (Terrain.Chunks.TryGetValue(cpos, out chunk)) { int blockRadius = (int)(radius / Block.CUBE_SIZE); for (int x = -blockRadius; x <= blockRadius; x++) { for (int y = -blockRadius; y <= blockRadius; y++) { for (int z = -blockRadius; z <= blockRadius; z++) { int nx = x + blockPos.X; int ny = y + blockPos.Y; int nz = z + blockPos.Z; IndexPosition ncpos = chunk.WrapBlockCoords(ref nx, ref ny, ref nz); if (!chunk.IsBlockCoordInRange(nx, ny, nz)) { continue; } Vector3 apos = Chunk.ChunkBlockToWorldCoords(ncpos, new IndexPosition(nx, ny, nz)) - Block.HALF_CUBE_3D_SIZE; float dist = Maths.Distance(apos, origin); if (dist > radius) { continue; } int damage = (int)(14 * (1f - (dist / radius))); if (ncpos != cpos) { Chunk otherChunk; if (Terrain.Chunks.TryGetValue(ncpos, out otherChunk)) { otherChunk.DamageBlock(new IndexPosition(nx, ny, nz), damage); } } else { chunk.DamageBlock(new IndexPosition(nx, ny, nz), damage); } } } } } // Fling other grenades radius = explosion.PlayerRadius; for (int i = 0; i < grenades.Count; i++) { GrenadeEntity grenade = grenades[i]; Vector3 dirTo = grenade.Transform.Position - origin; float dist = dirTo.Length; if (dist > radius) { continue; } dirTo += new Vector3(0, 1, 0); dirTo = dirTo.Normalize(); float kickBack = 60 * (1f - (dist / radius)); grenade.PhysicsBody.Velocity += dirTo * kickBack; grenade.Transform.Position.Y += 0.01f; } }
public override void Explode(Explosion explosion) { // Destroy terrain Vector3 origin = explosion.Origin; float radius = explosion.BlockRadius; IndexPosition cpos = FixedTerrain.WorldToChunkCoords(origin); IndexPosition blockPos = Chunk.WorldToBlockCoords(origin); blockPos -= cpos * Chunk.SIZE; Chunk chunk; if (Terrain.Chunks.TryGetValue(cpos, out chunk)) { int blockRadius = (int)(radius / Block.CUBE_SIZE); for (int x = -blockRadius; x <= blockRadius; x++) { for (int y = -blockRadius; y <= blockRadius; y++) { for (int z = -blockRadius; z <= blockRadius; z++) { int nx = x + blockPos.X; int ny = y + blockPos.Y; int nz = z + blockPos.Z; IndexPosition ncpos = chunk.WrapBlockCoords(ref nx, ref ny, ref nz); if (!chunk.IsBlockCoordInRange(nx, ny, nz)) { continue; } Vector3 apos = Chunk.ChunkBlockToWorldCoords(ncpos, new IndexPosition(nx, ny, nz)) - Block.HALF_CUBE_3D_SIZE; float dist = Maths.Distance(apos, origin); if (dist > radius) { continue; } int damage = (int)(14 * (1f - (dist / radius))); if (ncpos != cpos) { Chunk otherChunk; if (Terrain.Chunks.TryGetValue(ncpos, out otherChunk)) { otherChunk.DamageBlock(new IndexPosition(nx, ny, nz), damage); } } else { chunk.DamageBlock(new IndexPosition(nx, ny, nz), damage); } } } } } // Apply grenade damage bool ff = DashCMD.GetCVar <bool>("mp_friendlyfire"); if (!DashCMD.GetCVar <bool>("ch_infhealth")) { foreach (ServerMPPlayer player in players.Values) { if (player.Health <= 0 || !ff && explosion.Owner.Team == player.Team && explosion.Owner != player) { continue; } PlayerRaycastResult eResult = RaycastPlayer(explosion.Origin, player, explosion.PlayerRadius); if (eResult.Intersects) { /* * Curve: * max(min((fa/max(x,0)) - (fa/d), a), 0) * where f = falloff rate, a = max damage, d = max distance, * x = distance */ //float damage = MathHelper.Clamp( // explosion.Damage / (eResult.IntersectionDistance.Value * explosion.DamageFalloff), // 0, explosion.Damage); float damage = explosion.Damage * (float)Math.Cos(eResult.IntersectionDistance.Value / ((2 * explosion.PlayerRadius) / Math.PI)); //float fa = explosion.DamageFalloff * explosion.Damage; // float damage = MathHelper.Clamp((fa / eResult.IntersectionDistance.Value) - (fa / 200f), 0, explosion.Damage); DamagePlayer((ServerMPPlayer)explosion.Owner, explosion.EntityName, player, damage, origin); } } } // Fling other grenades radius = explosion.PlayerRadius; for (int i = 0; i < grenades.Count; i++) { GrenadeEntity grenade = grenades[i]; Vector3 dirTo = grenade.Transform.Position - origin; float dist = dirTo.Length; if (dist > radius) { continue; } dirTo += new Vector3(0, 1, 0); dirTo = dirTo.Normalize(); float kickBack = 60 * (1f - (dist / radius)); grenade.PhysicsBody.Velocity += dirTo * kickBack; grenade.Transform.Position.Y += 0.01f; } }