public void MovingBlocksStopped(IMovingBlockSet movingBlockSet) { if (movingBlockSet.Id == "CollapsingBlock") { Point3 p = Terrain.ToCell(MathUtils.Round(movingBlockSet.Position.X), MathUtils.Round(movingBlockSet.Position.Y), MathUtils.Round(movingBlockSet.Position.Z)); foreach (MovingBlock block in movingBlockSet.Blocks) { Point3 point = p + block.Offset; base.SubsystemTerrain.DestroyCell(0, point.X, point.Y, point.Z, block.Value, noDrop: false, noParticleSystem: false); } m_subsystemMovingBlocks.RemoveMovingBlockSet(movingBlockSet); if (movingBlockSet.Blocks.Count > 0) { m_subsystemSoundMaterials.PlayImpactSound(movingBlockSet.Blocks[0].Value, movingBlockSet.Position, 1f); } } }
public bool Dig(TerrainRaycastResult raycastResult) { if (Dig1 != null) { return(Dig1(raycastResult)); } bool result = false; m_lastDigFrameIndex = Time.FrameIndex; CellFace cellFace = raycastResult.CellFace; int cellValue = m_subsystemTerrain.Terrain.GetCellValue(cellFace.X, cellFace.Y, cellFace.Z); int num = Terrain.ExtractContents(cellValue); Block block = BlocksManager.Blocks[num]; int activeBlockValue = ActiveBlockValue; int num2 = Terrain.ExtractContents(activeBlockValue); Block block2 = BlocksManager.Blocks[num2]; if (!DigCellFace.HasValue || DigCellFace.Value.X != cellFace.X || DigCellFace.Value.Y != cellFace.Y || DigCellFace.Value.Z != cellFace.Z) { m_digStartTime = m_subsystemTime.GameTime; DigCellFace = cellFace; } float num3 = CalculateDigTime(cellValue, num2); m_digProgress = ((num3 > 0f) ? MathUtils.Saturate((float)(m_subsystemTime.GameTime - m_digStartTime) / num3) : 1f); if (!CanUseTool(activeBlockValue)) { m_digProgress = 0f; if (m_subsystemTime.PeriodicGameTimeEvent(5.0, m_digStartTime + 1.0)) { ComponentPlayer?.ComponentGui.DisplaySmallMessage(string.Format(LanguageControl.Get(fName, 1), block2.PlayerLevelRequired, block2.GetDisplayName(m_subsystemTerrain, activeBlockValue)), Color.White, blinking: true, playNotificationSound: true); } } bool flag = ComponentPlayer != null && !ComponentPlayer.ComponentInput.IsControlledByTouch && m_subsystemGameInfo.WorldSettings.GameMode == GameMode.Creative; if (flag || (m_lastPokingPhase <= 0.5f && PokingPhase > 0.5f)) { if (m_digProgress >= 1f) { DigCellFace = null; if (flag) { Poke(forceRestart: true); } BlockPlacementData digValue = block.GetDigValue(m_subsystemTerrain, this, cellValue, activeBlockValue, raycastResult); m_subsystemTerrain.DestroyCell(block2.ToolLevel, digValue.CellFace.X, digValue.CellFace.Y, digValue.CellFace.Z, digValue.Value, noDrop: false, noParticleSystem: false); m_subsystemSoundMaterials.PlayImpactSound(cellValue, new Vector3(cellFace.X, cellFace.Y, cellFace.Z), 2f); DamageActiveTool(1); if (ComponentCreature.PlayerStats != null) { ComponentCreature.PlayerStats.BlocksDug++; } result = true; } else { m_subsystemSoundMaterials.PlayImpactSound(cellValue, new Vector3(cellFace.X, cellFace.Y, cellFace.Z), 1f); BlockDebrisParticleSystem particleSystem = block.CreateDebrisParticleSystem(m_subsystemTerrain, raycastResult.HitPoint(0.1f), cellValue, 0.35f); base.Project.FindSubsystem <SubsystemParticles>(throwOnError: true).AddParticleSystem(particleSystem); } } return(result); }
public void Update(float dt) { double totalElapsedGameTime = m_subsystemGameInfo.TotalElapsedGameTime; foreach (Projectile projectile in m_projectiles) { if (projectile.ToRemove) { m_projectilesToRemove.Add(projectile); } else { Block block = BlocksManager.Blocks[Terrain.ExtractContents(projectile.Value)]; if (totalElapsedGameTime - projectile.CreationTime > 40.0) { projectile.ToRemove = true; } TerrainChunk chunkAtCell = m_subsystemTerrain.Terrain.GetChunkAtCell(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Z)); if (chunkAtCell == null || chunkAtCell.State <= TerrainChunkState.InvalidContents4) { projectile.NoChunk = true; if (projectile.TrailParticleSystem != null) { projectile.TrailParticleSystem.IsStopped = true; } } else { projectile.NoChunk = false; Vector3 position = projectile.Position; Vector3 vector = position + projectile.Velocity * dt; Vector3 v = block.ProjectileTipOffset * Vector3.Normalize(projectile.Velocity); BodyRaycastResult? bodyRaycastResult = m_subsystemBodies.Raycast(position + v, vector + v, 0.2f, (ComponentBody body, float distance) => true); TerrainRaycastResult?terrainRaycastResult = m_subsystemTerrain.Raycast(position + v, vector + v, useInteractionBoxes: false, skipAirBlocks: true, (int value, float distance) => BlocksManager.Blocks[Terrain.ExtractContents(value)].IsCollidable); bool flag = block.DisintegratesOnHit; if (terrainRaycastResult.HasValue || bodyRaycastResult.HasValue) { CellFace? cellFace = terrainRaycastResult.HasValue ? new CellFace?(terrainRaycastResult.Value.CellFace) : null; ComponentBody componentBody = bodyRaycastResult.HasValue ? bodyRaycastResult.Value.ComponentBody : null; SubsystemBlockBehavior[] blockBehaviors = m_subsystemBlockBehaviors.GetBlockBehaviors(Terrain.ExtractContents(projectile.Value)); for (int i = 0; i < blockBehaviors.Length; i++) { flag |= blockBehaviors[i].OnHitAsProjectile(cellFace, componentBody, projectile); } projectile.ToRemove |= flag; } Vector3?vector2 = null; if (bodyRaycastResult.HasValue && (!terrainRaycastResult.HasValue || bodyRaycastResult.Value.Distance < terrainRaycastResult.Value.Distance)) { if (projectile.Velocity.Length() > 10f) { ComponentMiner.AttackBody(bodyRaycastResult.Value.ComponentBody, projectile.Owner, bodyRaycastResult.Value.HitPoint(), Vector3.Normalize(projectile.Velocity), block.GetProjectilePower(projectile.Value), isMeleeAttack: false); if (projectile.Owner != null && projectile.Owner.PlayerStats != null) { projectile.Owner.PlayerStats.RangedHits++; } } if (projectile.IsIncendiary) { bodyRaycastResult.Value.ComponentBody.Entity.FindComponent <ComponentOnFire>()?.SetOnFire(projectile?.Owner, m_random.Float(6f, 8f)); } vector = position; projectile.Velocity *= -0.05f; projectile.Velocity += m_random.Vector3(0.33f * projectile.Velocity.Length()); projectile.AngularVelocity *= -0.05f; } else if (terrainRaycastResult.HasValue) { CellFace cellFace2 = terrainRaycastResult.Value.CellFace; int cellValue = m_subsystemTerrain.Terrain.GetCellValue(cellFace2.X, cellFace2.Y, cellFace2.Z); int num = Terrain.ExtractContents(cellValue); Block block2 = BlocksManager.Blocks[num]; float num2 = projectile.Velocity.Length(); SubsystemBlockBehavior[] blockBehaviors2 = m_subsystemBlockBehaviors.GetBlockBehaviors(num); for (int j = 0; j < blockBehaviors2.Length; j++) { blockBehaviors2[j].OnHitByProjectile(cellFace2, projectile); } if (num2 > 10f && m_random.Float(0f, 1f) > block2.ProjectileResilience) { m_subsystemTerrain.DestroyCell(0, cellFace2.X, cellFace2.Y, cellFace2.Z, 0, noDrop: true, noParticleSystem: false); m_subsystemSoundMaterials.PlayImpactSound(cellValue, position, 1f); } if (projectile.IsIncendiary) { m_subsystemFireBlockBehavior.SetCellOnFire(terrainRaycastResult.Value.CellFace.X, terrainRaycastResult.Value.CellFace.Y, terrainRaycastResult.Value.CellFace.Z, 1f); Vector3 vector3 = projectile.Position - 0.75f * Vector3.Normalize(projectile.Velocity); for (int k = 0; k < 8; k++) { Vector3 v2 = (k == 0) ? Vector3.Normalize(projectile.Velocity) : m_random.Vector3(1.5f); TerrainRaycastResult?terrainRaycastResult2 = m_subsystemTerrain.Raycast(vector3, vector3 + v2, useInteractionBoxes: false, skipAirBlocks: true, (int value, float distance) => true); if (terrainRaycastResult2.HasValue) { m_subsystemFireBlockBehavior.SetCellOnFire(terrainRaycastResult2.Value.CellFace.X, terrainRaycastResult2.Value.CellFace.Y, terrainRaycastResult2.Value.CellFace.Z, 1f); } } } if (num2 > 5f) { m_subsystemSoundMaterials.PlayImpactSound(cellValue, position, 1f); } if (block.IsStickable && num2 > 10f && m_random.Bool(block2.ProjectileStickProbability)) { Vector3 v3 = Vector3.Normalize(projectile.Velocity); float s = MathUtils.Lerp(0.1f, 0.2f, MathUtils.Saturate((num2 - 15f) / 20f)); vector2 = position + terrainRaycastResult.Value.Distance * Vector3.Normalize(projectile.Velocity) + v3 * s; } else { Plane plane = cellFace2.CalculatePlane(); vector = position; if (plane.Normal.X != 0f) { projectile.Velocity *= new Vector3(-0.3f, 0.3f, 0.3f); } if (plane.Normal.Y != 0f) { projectile.Velocity *= new Vector3(0.3f, -0.3f, 0.3f); } if (plane.Normal.Z != 0f) { projectile.Velocity *= new Vector3(0.3f, 0.3f, -0.3f); } float num3 = projectile.Velocity.Length(); projectile.Velocity = num3 * Vector3.Normalize(projectile.Velocity + m_random.Vector3(num3 / 6f, num3 / 3f)); projectile.AngularVelocity *= -0.3f; } MakeProjectileNoise(projectile); } if (terrainRaycastResult.HasValue || bodyRaycastResult.HasValue) { if (flag) { m_subsystemParticles.AddParticleSystem(block.CreateDebrisParticleSystem(m_subsystemTerrain, projectile.Position, projectile.Value, 1f)); } else if (!projectile.ToRemove && (vector2.HasValue || projectile.Velocity.Length() < 1f)) { if (projectile.ProjectileStoppedAction == ProjectileStoppedAction.TurnIntoPickable) { int num4 = BlocksManager.DamageItem(projectile.Value, 1); if (num4 != 0) { if (vector2.HasValue) { CalculateVelocityAlignMatrix(block, vector2.Value, projectile.Velocity, out Matrix matrix); m_subsystemPickables.AddPickable(num4, 1, projectile.Position, Vector3.Zero, matrix); } else { m_subsystemPickables.AddPickable(num4, 1, position, Vector3.Zero, null); } } projectile.ToRemove = true; } else if (projectile.ProjectileStoppedAction == ProjectileStoppedAction.Disappear) { projectile.ToRemove = true; } } } float num5 = projectile.IsInWater ? MathUtils.Pow(0.001f, dt) : MathUtils.Pow(block.ProjectileDamping, dt); projectile.Velocity.Y += -10f * dt; projectile.Velocity *= num5; projectile.AngularVelocity *= num5; projectile.Position = vector; projectile.Rotation += projectile.AngularVelocity * dt; if (projectile.TrailParticleSystem != null) { if (!m_subsystemParticles.ContainsParticleSystem((ParticleSystemBase)projectile.TrailParticleSystem)) { m_subsystemParticles.AddParticleSystem((ParticleSystemBase)projectile.TrailParticleSystem); } Vector3 v4 = (projectile.TrailOffset != Vector3.Zero) ? Vector3.TransformNormal(projectile.TrailOffset, Matrix.CreateFromAxisAngle(Vector3.Normalize(projectile.Rotation), projectile.Rotation.Length())) : Vector3.Zero; projectile.TrailParticleSystem.Position = projectile.Position + v4; if (projectile.IsInWater) { projectile.TrailParticleSystem.IsStopped = true; } } bool flag2 = IsWater(projectile.Position); if (projectile.IsInWater != flag2) { if (flag2) { float num6 = new Vector2(projectile.Velocity.X + projectile.Velocity.Z).Length(); if (num6 > 6f && num6 > 4f * MathUtils.Abs(projectile.Velocity.Y)) { projectile.Velocity *= 0.5f; projectile.Velocity.Y *= -1f; flag2 = false; } else { projectile.Velocity *= 0.2f; } float?surfaceHeight = m_subsystemFluidBlockBehavior.GetSurfaceHeight(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Y), Terrain.ToCell(projectile.Position.Z)); if (surfaceHeight.HasValue) { m_subsystemParticles.AddParticleSystem(new WaterSplashParticleSystem(m_subsystemTerrain, new Vector3(projectile.Position.X, surfaceHeight.Value, projectile.Position.Z), large: false)); m_subsystemAudio.PlayRandomSound("Audio/Splashes", 1f, m_random.Float(-0.2f, 0.2f), projectile.Position, 6f, autoDelay: true); MakeProjectileNoise(projectile); } } projectile.IsInWater = flag2; } if (IsMagma(projectile.Position)) { m_subsystemParticles.AddParticleSystem(new MagmaSplashParticleSystem(m_subsystemTerrain, projectile.Position, large: false)); m_subsystemAudio.PlayRandomSound("Audio/Sizzles", 1f, m_random.Float(-0.2f, 0.2f), projectile.Position, 3f, autoDelay: true); projectile.ToRemove = true; m_subsystemExplosions.TryExplodeBlock(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Y), Terrain.ToCell(projectile.Position.Z), projectile.Value); } if (m_subsystemTime.PeriodicGameTimeEvent(1.0, (double)(projectile.GetHashCode() % 100) / 100.0) && (m_subsystemFireBlockBehavior.IsCellOnFire(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Y + 0.1f), Terrain.ToCell(projectile.Position.Z)) || m_subsystemFireBlockBehavior.IsCellOnFire(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Y + 0.1f) - 1, Terrain.ToCell(projectile.Position.Z)))) { m_subsystemAudio.PlayRandomSound("Audio/Sizzles", 1f, m_random.Float(-0.2f, 0.2f), projectile.Position, 3f, autoDelay: true); projectile.ToRemove = true; m_subsystemExplosions.TryExplodeBlock(Terrain.ToCell(projectile.Position.X), Terrain.ToCell(projectile.Position.Y), Terrain.ToCell(projectile.Position.Z), projectile.Value); } } } } foreach (Projectile item in m_projectilesToRemove) { if (item.TrailParticleSystem != null) { item.TrailParticleSystem.IsStopped = true; } m_projectiles.Remove(item); if (this.ProjectileRemoved != null) { this.ProjectileRemoved(item); } } m_projectilesToRemove.Clear(); }
public void ScanDesign(CellFace start, Vector3 direction, ComponentMiner componentMiner) { FurnitureDesign design = null; FurnitureDesign furnitureDesign = null; Dictionary <Point3, int> valuesDictionary = new Dictionary <Point3, int>(); Point3 point = start.Point; Point3 point2 = start.Point; int startValue = base.SubsystemTerrain.Terrain.GetCellValue(start.Point.X, start.Point.Y, start.Point.Z); int num = Terrain.ExtractContents(startValue); if (BlocksManager.Blocks[num] is FurnitureBlock) { int designIndex = FurnitureBlock.GetDesignIndex(Terrain.ExtractData(startValue)); furnitureDesign = GetDesign(designIndex); if (furnitureDesign == null) { componentMiner.ComponentPlayer?.ComponentGui.DisplaySmallMessage("Unsuitable block found", Color.White, blinking: true, playNotificationSound: false); return; } design = furnitureDesign.Clone(); design.LinkedDesign = null; design.InteractionMode = FurnitureInteractionMode.None; valuesDictionary.Add(start.Point, startValue); } else { Stack <Point3> val = new Stack <Point3>(); val.Push(start.Point); while (val.Count > 0) { Point3 key = val.Pop(); if (valuesDictionary.ContainsKey(key)) { continue; } int cellValue = base.SubsystemTerrain.Terrain.GetCellValue(key.X, key.Y, key.Z); if (IsValueDisallowed(cellValue)) { componentMiner.ComponentPlayer?.ComponentGui.DisplaySmallMessage("Unsuitable block found", Color.White, blinking: true, playNotificationSound: false); return; } if (IsValueAllowed(cellValue)) { if (key.X < point.X) { point.X = key.X; } if (key.Y < point.Y) { point.Y = key.Y; } if (key.Z < point.Z) { point.Z = key.Z; } if (key.X > point2.X) { point2.X = key.X; } if (key.Y > point2.Y) { point2.Y = key.Y; } if (key.Z > point2.Z) { point2.Z = key.Z; } if (MathUtils.Abs(point.X - point2.X) >= 16 || MathUtils.Abs(point.Y - point2.Y) >= 16 || MathUtils.Abs(point.Z - point2.Z) >= 16) { componentMiner.ComponentPlayer?.ComponentGui.DisplaySmallMessage("Furniture design is too large", Color.White, blinking: true, playNotificationSound: false); return; } valuesDictionary[key] = cellValue; val.Push(new Point3(key.X - 1, key.Y, key.Z)); val.Push(new Point3(key.X + 1, key.Y, key.Z)); val.Push(new Point3(key.X, key.Y - 1, key.Z)); val.Push(new Point3(key.X, key.Y + 1, key.Z)); val.Push(new Point3(key.X, key.Y, key.Z - 1)); val.Push(new Point3(key.X, key.Y, key.Z + 1)); } } if (valuesDictionary.Count == 0) { componentMiner.ComponentPlayer?.ComponentGui.DisplaySmallMessage("No suitable blocks found", Color.White, blinking: true, playNotificationSound: false); return; } design = new FurnitureDesign(base.SubsystemTerrain); Point3 point3 = point2 - point; int num2 = MathUtils.Max(MathUtils.Max(point3.X, point3.Y, point3.Z) + 1, 2); int[] array = new int[num2 * num2 * num2]; foreach (KeyValuePair <Point3, int> item in valuesDictionary) { Point3 point4 = item.Key - point; array[point4.X + point4.Y * num2 + point4.Z * num2 * num2] = item.Value; } design.SetValues(num2, array); int steps = (start.Face > 3) ? CellFace.Vector3ToFace(direction, 3) : CellFace.OppositeFace(start.Face); design.Rotate(1, steps); Point3 location = design.Box.Location; Point3 point5 = new Point3(design.Resolution) - (design.Box.Location + design.Box.Size); Point3 delta = new Point3((point5.X - location.X) / 2, -location.Y, (point5.Z - location.Z) / 2); design.Shift(delta); } BuildFurnitureDialog dialog = new BuildFurnitureDialog(design, furnitureDesign, delegate(bool result) { if (result) { design = TryAddDesign(design); if (design == null) { componentMiner.ComponentPlayer?.ComponentGui.DisplaySmallMessage("Too many different furniture designs", Color.White, blinking: true, playNotificationSound: false); } else { if (m_subsystemGameInfo.WorldSettings.GameMode != 0) { foreach (KeyValuePair <Point3, int> item2 in valuesDictionary) { base.SubsystemTerrain.DestroyCell(0, item2.Key.X, item2.Key.Y, item2.Key.Z, 0, noDrop: true, noParticleSystem: true); } } int value = Terrain.MakeBlockValue(227, 0, FurnitureBlock.SetDesignIndex(0, design.Index, design.ShadowStrengthFactor, design.IsLightEmitter)); int num3 = MathUtils.Clamp(design.Resolution, 4, 8); Matrix matrix = componentMiner.ComponentCreature.ComponentBody.Matrix; Vector3 position = matrix.Translation + 1f * matrix.Forward + 1f * Vector3.UnitY; m_subsystemPickables.AddPickable(value, num3, position, null, null); componentMiner.DamageActiveTool(1); componentMiner.Poke(forceRestart: false); for (int i = 0; i < 3; i++) { Time.QueueTimeDelayedExecution(Time.FrameStartTime + (double)((float)i * 0.25f), delegate { m_subsystemSoundMaterials.PlayImpactSound(startValue, new Vector3(start.Point), 1f); }); } if (componentMiner.ComponentCreature.PlayerStats != null) { componentMiner.ComponentCreature.PlayerStats.FurnitureItemsMade += num3; } } } }); if (componentMiner.ComponentPlayer != null) { DialogsManager.ShowDialog(componentMiner.ComponentPlayer.GuiWidget, dialog); } }