float SimulateRail(int railType) { if (RailBlock.IsCorner(railType)) { if (GetOffsetOnDirection(m_componentBody.Position, m_forwardDirection) > 0.5f) { Turn(railType); } return(50f); } if (RailBlock.IsDirectionX(railType) ^ !RailBlock.IsDirectionX(m_forwardDirection)) { rotation = railType > 5 ? railType - 6 != Direction ? directions[Direction] * upwardDirection : directions[Direction] * downwardDirection : directions[Direction]; return(railType > 5 && railType - 6 != Direction ? 30f : 50f); } return(0f); }
public override bool OnUse(Vector3 start, Vector3 direction, ComponentMiner componentMiner) { int activeBlockValue = componentMiner.ActiveBlockValue; var result = componentMiner.PickTerrainForDigging(start, direction); Entity entity; Vector3 position; BodyRaycastResult?body; if (activeBlockValue == ItemBlock.IdTable["Wrench"]) { body = componentMiner.PickBody(start, direction); Matrix matrix = componentMiner.ComponentCreature.ComponentBody.Matrix; position = matrix.Translation + 1f * matrix.Forward + Vector3.UnitY; if (body.HasValue && (!result.HasValue || body.Value.Distance < result.Value.Distance)) { entity = body.Value.ComponentBody.Entity; if (entity.FindComponent <ComponentTrain>() != null || entity.FindComponent <ComponentBoatI>() != null) { for (var i = entity.FindComponents <IInventory>().GetEnumerator(); i.MoveNext();) { i.Current.DropAllItems(position); } Utils.SubsystemPickables.AddPickable(ItemBlock.IdTable[entity.ValuesDictionary.DatabaseObject.Name.Length == 8 ? "Minecart" : entity.ValuesDictionary.DatabaseObject.Name], 1, position, null, null); Project.RemoveEntity(entity, true); return(true); } } } else if ((activeBlockValue == ItemBlock.IdTable["Train"] || activeBlockValue == ItemBlock.IdTable["Minecart"]) && result.HasValue && Terrain.ExtractContents(result.Value.Value) == RailBlock.Index) { position = new Vector3(result.Value.CellFace.Point) + new Vector3(0.5f); entity = DatabaseManager.CreateEntity(Project, activeBlockValue == ItemBlock.IdTable["Minecart"] ? "Carriage" : "Train", true); var rotation = componentMiner.ComponentCreature.ComponentCreatureModel.EyeRotation.ToForwardVector(); entity.FindComponent <ComponentTrain>(true).SetDirection(RailBlock.IsDirectionX(RailBlock.GetRailType(Terrain.ExtractData(result.Value.Value))) ? rotation.Z < 0 ? 0 : 2 : rotation.X < 0 ? 1 : 3); entity.FindComponent <ComponentBody>(true).Position = position; entity.FindComponent <ComponentSpawn>(true).SpawnDuration = 0f; Project.AddEntity(entity); var componentTrain = entity.FindComponent <ComponentTrain>(true); if (activeBlockValue == ItemBlock.IdTable["Minecart"]) { componentTrain.Update(0); var train = componentTrain.FindNearestTrain(); if (train != null) { componentTrain.ParentBody = train; } } componentMiner.RemoveActiveTool(1); Utils.SubsystemAudio.PlaySound("Audio/BlockPlaced", 1f, 0f, position, 3f, true); return(true); } /*else if (activeBlockValue == ItemBlock.IdTable["Minecart"]) * { * entity = DatabaseManager.CreateEntity(Project, "Carriage", true); * body = componentMiner.PickBody(start, direction); * if (body.HasValue && (!result.HasValue || body.Value.Distance < result.Value.Distance)) * { * body = componentMiner.PickBody(start, direction); * var componentTrain = entity.FindComponent<ComponentTrain>(true); * var train = body.Value.ComponentBody.Entity.FindComponent<ComponentTrain>(); * if (train != null) * componentTrain.ParentBody = train; * } * else if (result.HasValue) * position = result.Value.RaycastStart + Vector3.Normalize(result.Value.RaycastEnd - result.Value.RaycastStart) * result.Value.Distance; ; * var rotation = componentMiner.ComponentCreature.ComponentCreatureModel.EyeRotation.ToForwardVector(); * entity.FindComponent<ComponentTrain>(true).SetDirection(RailBlock.IsDirectionX(RailBlock.GetRailType(Terrain.ExtractData(result.Value.Value))) * ? rotation.Z < 0 ? 0 : 2 * : rotation.X < 0 ? 1 : 3); * goto put; * }*/ else if (activeBlockValue == ItemBlock.IdTable["基因查看器"]) { body = componentMiner.PickBody(start, direction); if (body.HasValue && (!result.HasValue || body.Value.Distance < result.Value.Distance)) { var cv = body.Value.ComponentBody.Entity.FindComponent <ComponentVariant>(); if (cv != null) { DialogsManager.ShowDialog(componentMiner.ComponentPlayer?.View.GameWidget, new MessageDialog("Result", cv.Genome.ToString(), "OK", null, null)); } return(true); } } else if (result.HasValue) { position = result.Value.RaycastStart + Vector3.Normalize(result.Value.RaycastEnd - result.Value.RaycastStart) * result.Value.Distance; if (activeBlockValue == ItemBlock.IdTable["SteamBoat"]) { entity = DatabaseManager.CreateEntity(Project, "SteamBoat", true); entity.FindComponent <ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, m_random.UniformFloat(0f, 6.283185f)); goto put; } /*else if (activeBlockValue == ItemBlock.IdTable["Minecart"]) * { * entity = DatabaseManager.CreateEntity(Project, "Carriage", true); * entity.FindComponent<ComponentFrame>(true).Position = position; * entity.FindComponent<ComponentSpawn>(true).SpawnDuration = 0f; * var componentTrain = entity.FindComponent<ComponentTrain>(true); * var componentMount = componentTrain.FindNearestTrain(); * if (componentMount != null) * componentTrain.ParentBody = componentMount.m_componentBody; * goto put; * }*/ else if (activeBlockValue == ItemBlock.IdTable["Airship"]) { entity = DatabaseManager.CreateEntity(Project, "Airship", true); entity.FindComponent <ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, m_random.UniformFloat(0f, 6.283185f)); goto put; } else if (BlocksManager.Blocks[Terrain.ExtractContents(activeBlockValue)] is ItemBlock itemblock && itemblock.GetItem(ref activeBlockValue) is Mine mine) { entity = DatabaseManager.CreateEntity(Project, "Mine", new ValuesDictionary { { "Mine", new ValuesDictionary { { "Type", mine.MineType } } } }, true); entity.FindComponent <ComponentFrame>(true).Rotation = Quaternion.CreateFromAxisAngle(Vector3.UnitY, m_random.UniformFloat(0f, 6.283185f)); var componentMine = entity.FindComponent <ComponentMine>(true); componentMine.ExplosionPressure = mine.ExplosionPressure; componentMine.Delay = mine.Delay; goto put; } } IInventory inventory = componentMiner.Inventory; TerrainRaycastResult?result2; if (Terrain.ExtractContents(activeBlockValue) == 90) { result2 = componentMiner.PickTerrainForGathering(start, direction); if (result2.HasValue) { CellFace cellFace = result2.Value.CellFace; int cellValue = Terrain.ReplaceLight(Utils.Terrain.GetCellValue(cellFace.X, cellFace.Y, cellFace.Z), 0); if (cellValue != (RottenMeatBlock.Index | 1 << 4 << 14)) { return(false); } inventory.RemoveSlotItems(inventory.ActiveSlotIndex, inventory.GetSlotCount(inventory.ActiveSlotIndex)); if (inventory.GetSlotCount(inventory.ActiveSlotIndex) == 0) { inventory.AddSlotItems(inventory.ActiveSlotIndex, RottenMeatBlock.Index | 2 << 4 << 14, 1); } Utils.SubsystemTerrain.DestroyCell(0, cellFace.X, cellFace.Y, cellFace.Z, 0, false, false); return(true); } } if (activeBlockValue == (RottenMeatBlock.Index | 2 << 4 << 14)) { result2 = componentMiner.PickTerrainForInteraction(start, direction); if (result2.HasValue && componentMiner.Place(result2.Value, RottenMeatBlock.Index | 1 << 4 << 14)) { inventory.RemoveSlotItems(inventory.ActiveSlotIndex, 1); if (inventory.GetSlotCount(inventory.ActiveSlotIndex) == 0) { inventory.AddSlotItems(inventory.ActiveSlotIndex, Terrain.ReplaceContents(activeBlockValue, 90), 1); } return(true); } } return(false); put: entity.FindComponent <ComponentBody>(true).Position = position; entity.FindComponent <ComponentSpawn>(true).SpawnDuration = 0f; Project.AddEntity(entity); componentMiner.RemoveActiveTool(1); Utils.SubsystemAudio.PlaySound("Audio/BlockPlaced", 1f, 0f, position, 3f, true); return(true); }
public void Update(float dt) { if (ComponentEngine != null) { ComponentEngine.Coordinates = new Point3((int)m_componentBody.Position.X, (int)m_componentBody.Position.Y, (int)m_componentBody.Position.Z); } if (m_componentMount.Rider != null) { var player = m_componentMount.Rider.Entity.FindComponent <ComponentPlayer>(true); player.ComponentLocomotion.LookOrder = player.ComponentInput.PlayerInput.Look; } ComponentTrain t = this; int level = 0; for (; t.ParentBody != null; level++) { t = t.ParentBody; } if (level > 0) { var body = t.m_componentBody; var pos = body.Position; var r = body.Rotation; Utils.SubsystemTime.QueueGameTimeDelayedExecution(Utils.SubsystemTime.GameTime + 0.23 * level, delegate { if (body.Velocity.XZ.LengthSquared() > 10f) { m_componentBody.Position = pos; m_componentBody.Rotation = r; } }); m_outOfMountTime = Vector3.DistanceSquared(ParentBody.m_componentBody.Position, m_componentBody.Position) > 8f ? m_outOfMountTime + dt : 0f; ComponentDamage ComponentDamage = ParentBody.Entity.FindComponent <ComponentDamage>(); if (m_outOfMountTime > 1f || (componentDamage != null && componentDamage.Hitpoints <= .05f) || ComponentDamage != null && ComponentDamage.Hitpoints <= .05f) { ParentBody = null; } return; } switch (Direction) { case 0: case 2: m_componentBody.Position = new Vector3(MathUtils.Floor(m_componentBody.Position.X) + 0.5f, m_componentBody.Position.Y, m_componentBody.Position.Z); break; case 1: case 3: m_componentBody.Position = new Vector3(m_componentBody.Position.X, m_componentBody.Position.Y, MathUtils.Floor(m_componentBody.Position.Z) + 0.5f); break; } if (ComponentEngine != null && ComponentEngine.HeatLevel >= 100f && m_componentBody.StandingOnValue.HasValue) { var result = Utils.SubsystemTerrain.Raycast(m_componentBody.Position, m_componentBody.Position + new Vector3(0, -3f, 0), false, true, null); if (result.HasValue && Terrain.ExtractContents(result.Value.Value) == RailBlock.Index && (dt *= SimulateRail(RailBlock.GetRailType(Terrain.ExtractData(result.Value.Value)))) > 0f) { m_componentBody.m_velocity += dt * rotation.ToForwardVector(); } } m_componentBody.Rotation = Quaternion.Slerp(m_componentBody.Rotation, rotation, 0.15f); }
void UpdateCornerState(int value, int x, int y, int z, int step) { var resultType = default(int?); var neighbors = new bool[4]; var raisedNeighbors = new bool[4]; for (int i = 0; i < 4; i++) { for (int k = 0; k < 3; k++) { var p = m_pointsToUpdate[i, k]; int val = SubsystemTerrain.Terrain.GetCellValueFastChunkExists(x + p.X, y + p.Y, z + p.Z); if (Terrain.ExtractContents(val) == RailBlock.Index) { if (k == 1) { raisedNeighbors[i] = RailBlock.CanConnectTo(RailBlock.GetRailType(Terrain.ExtractData(val)), i); } else { neighbors[i] = RailBlock.CanConnectTo(RailBlock.GetRailType(Terrain.ExtractData(val)), i); } if (step > 0) { UpdateCornerState(val, x + p.X, y + p.Y, z + p.Z, step - 1); } break; } } } if (neighbors[0] && neighbors[3]) { resultType = 1; } else if (neighbors[0] && neighbors[1]) { resultType = 2; } else if (neighbors[1] && neighbors[2]) { resultType = 3; } else if (neighbors[2] && neighbors[3]) { resultType = 0; } else if (raisedNeighbors[2]) { resultType = 6; } else if (raisedNeighbors[0]) { resultType = 8; } else if (raisedNeighbors[3]) { resultType = 7; } else if (raisedNeighbors[1]) { resultType = 9; } else if (neighbors[0] || neighbors[2]) { resultType = 4; } else if (neighbors[1] || neighbors[3]) { resultType = 5; } if (resultType.HasValue) { SubsystemTerrain.ChangeCell(x, y, z, Terrain.MakeBlockValue(RailBlock.Index, 0, RailBlock.SetRailType(0, resultType.Value))); } }