public override InstanceState GetState() { ushort segment = id.NetSegment; SegmentState state = new SegmentState { instance = this, Info = Info, position = GetControlPoint(segment), startNode = segmentBuffer[segment].m_startNode, endNode = segmentBuffer[segment].m_endNode, startDirection = segmentBuffer[segment].m_startDirection, endDirection = segmentBuffer[segment].m_endDirection }; state.startPosition = nodeBuffer[state.startNode].m_position; state.endPosition = nodeBuffer[state.endNode].m_position; state.smoothStart = ((nodeBuffer[state.startNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None); state.smoothEnd = ((nodeBuffer[state.endNode].m_flags & NetNode.Flags.Middle) != NetNode.Flags.None); state.invert = ((segmentBuffer[segment].m_flags & NetSegment.Flags.Invert) == NetSegment.Flags.Invert); return(state); }
public override Instance Clone(InstanceState instanceState, Dictionary <ushort, ushort> clonedNodes) { SegmentState state = instanceState as SegmentState; Instance cloneInstance = null; ushort startNode = state.startNode; ushort endNode = state.endNode; // Nodes should exist startNode = clonedNodes[startNode]; endNode = clonedNodes[endNode]; if (netManager.CreateSegment(out ushort clone, ref SimulationManager.instance.m_randomizer, state.Info.Prefab as NetInfo, startNode, endNode, state.startDirection, state.endDirection, SimulationManager.instance.m_currentBuildIndex, SimulationManager.instance.m_currentBuildIndex, state.invert)) { SimulationManager.instance.m_currentBuildIndex++; InstanceID cloneID = default(InstanceID); cloneID.NetSegment = clone; cloneInstance = new MoveableSegment(cloneID); } return(cloneInstance); }
public override void RenderCloneOverlay(InstanceState instanceState, ref Matrix4x4 matrix4x, Vector3 deltaPosition, float deltaAngle, Vector3 center, bool followTerrain, RenderManager.CameraInfo cameraInfo, Color toolColor) { SegmentState state = instanceState as SegmentState; NetInfo netInfo = state.Info.Prefab as NetInfo; Vector3 newPosition = matrix4x.MultiplyPoint(state.position - center); newPosition.y = state.position.y + deltaPosition.y; if (followTerrain) { newPosition.y = newPosition.y - state.terrainHeight + TerrainManager.instance.SampleOriginalRawHeightSmooth(newPosition); } Bezier3 bezier; bezier.a = matrix4x.MultiplyPoint(state.startPosition - center); bezier.d = matrix4x.MultiplyPoint(state.endPosition - center); if (followTerrain) { bezier.a.y = bezier.a.y + TerrainManager.instance.SampleOriginalRawHeightSmooth(bezier.a) - TerrainManager.instance.SampleOriginalRawHeightSmooth(state.startPosition); bezier.d.y = bezier.d.y + TerrainManager.instance.SampleOriginalRawHeightSmooth(bezier.d) - TerrainManager.instance.SampleOriginalRawHeightSmooth(state.endPosition); } else { bezier.a.y = state.startPosition.y + deltaPosition.y; bezier.d.y = state.endPosition.y + deltaPosition.y; } Vector3 startDirection = newPosition - bezier.a; Vector3 endDirection = newPosition - bezier.d; startDirection.y = 0; endDirection.y = 0; startDirection.Normalize(); endDirection.Normalize(); NetSegment.CalculateMiddlePoints( bezier.a, startDirection, bezier.d, endDirection, state.smoothStart, state.smoothEnd, out bezier.b, out bezier.c); RenderManager.instance.OverlayEffect.DrawBezier(cameraInfo, toolColor, bezier, netInfo.m_halfWidth * 4f / 3f, 100000f, -100000f, -1f, 1280f, false, true); }
public override void RenderCloneGeometry(InstanceState instanceState, ref Matrix4x4 matrix4x, Vector3 deltaPosition, float deltaAngle, Vector3 center, bool followTerrain, RenderManager.CameraInfo cameraInfo, Color toolColor) { SegmentState state = instanceState as SegmentState; NetInfo netInfo = state.Info.Prefab as NetInfo; Vector3 newPosition = matrix4x.MultiplyPoint(state.position - center); newPosition.y = state.position.y + deltaPosition.y; if (followTerrain) { newPosition.y = newPosition.y - state.terrainHeight + TerrainManager.instance.SampleOriginalRawHeightSmooth(newPosition); } Bezier3 bezier; bezier.a = matrix4x.MultiplyPoint(state.startPosition - center); bezier.d = matrix4x.MultiplyPoint(state.endPosition - center); if (followTerrain) { bezier.a.y = bezier.a.y + TerrainManager.instance.SampleOriginalRawHeightSmooth(bezier.a) - TerrainManager.instance.SampleOriginalRawHeightSmooth(state.startPosition); bezier.d.y = bezier.d.y + TerrainManager.instance.SampleOriginalRawHeightSmooth(bezier.d) - TerrainManager.instance.SampleOriginalRawHeightSmooth(state.endPosition); } else { bezier.a.y = state.startPosition.y + deltaPosition.y; bezier.d.y = state.endPosition.y + deltaPosition.y; } Vector3 startDirection = newPosition - bezier.a; Vector3 endDirection = newPosition - bezier.d; startDirection.y = 0; endDirection.y = 0; startDirection.Normalize(); endDirection.Normalize(); //private static void RenderSegment(NetInfo info, NetSegment.Flags flags, Vector3 startPosition, Vector3 endPosition, Vector3 startDirection, Vector3 endDirection, bool smoothStart, bool smoothEnd) RenderSegment.Invoke(null, new object[] { netInfo, NetSegment.Flags.All, bezier.a, bezier.d, startDirection, -endDirection, state.smoothStart, state.smoothEnd }); }
public override void UpdateNodeIdInSegmentState(ushort oldId, ushort newId) { foreach (InstanceState state in m_states) { if (state.instance.id.Type == InstanceType.NetSegment) { SegmentState segState = state as SegmentState; if (segState.startNode == oldId) { segState.startNode = newId; //Debug.Log($"SWITCHED (start)\nSegment #{state.instance.id.NetSegment} ({segState.startNode}-{segState.endNode})\nOld node Id:{oldId}, new node Id:{newId}"); } if (segState.endNode == oldId) { segState.endNode = newId; //Debug.Log($"SWITCHED (end)\nSegment #{state.instance.id.NetSegment} ({segState.startNode}-{segState.endNode})\nOld node Id:{oldId}, new node Id:{newId}"); } } } }
public void SetSegmentModifiers(ushort id, SegmentState state) { if (!Enabled) { return; } BindingFlags f = BindingFlags.Public | BindingFlags.Instance; object modifiers = state.NS_Modifiers; if (modifiers == null) { return; } object modDict = Activator.CreateInstance(tDictMods); tDictMods.GetMethod("Add", f, null, new Type[] { typeof(NetInfo), tListMods }, null).Invoke(modDict, new[] { (NetInfo)state.Info.Prefab, modifiers }); tNSM.GetMethod("SetActiveModifiers", f, null, new Type[] { tDictMods }, null).Invoke(NSM, new[] { modDict }); tNSM.GetMethod("OnSegmentPlaced", f, null, new Type[] { typeof(ushort) }, null).Invoke(NSM, new object[] { id }); }
public override Instance Clone(InstanceState instanceState, ref Matrix4x4 matrix4x, float deltaHeight, float deltaAngle, Vector3 center, bool followTerrain, Dictionary <ushort, ushort> clonedNodes) { SegmentState state = instanceState as SegmentState; Vector3 newPosition = matrix4x.MultiplyPoint(state.position - center); Instance cloneInstance = null; ushort startNode = state.startNode; ushort endNode = state.endNode; // Nodes should exist startNode = clonedNodes[startNode]; endNode = clonedNodes[endNode]; Vector3 startDirection = newPosition - nodeBuffer[startNode].m_position; Vector3 endDirection = newPosition - nodeBuffer[endNode].m_position; startDirection.y = 0; endDirection.y = 0; startDirection.Normalize(); endDirection.Normalize(); if (netManager.CreateSegment(out ushort clone, ref SimulationManager.instance.m_randomizer, state.Info.Prefab as NetInfo, startNode, endNode, startDirection, endDirection, SimulationManager.instance.m_currentBuildIndex, SimulationManager.instance.m_currentBuildIndex, state.invert)) { SimulationManager.instance.m_currentBuildIndex++; InstanceID cloneID = default(InstanceID); cloneID.NetSegment = clone; cloneInstance = new MoveableSegment(cloneID); } return(cloneInstance); }
public override void Undo() { if (m_states == null) { return; } Dictionary <Instance, Instance> toReplace = new Dictionary <Instance, Instance>(); Dictionary <ushort, ushort> clonedNodes = new Dictionary <ushort, ushort>(); foreach (InstanceState state in m_states) { if (state.instance.id.Type == InstanceType.NetNode) { Instance clone = state.instance.Clone(state, null); toReplace.Add(state.instance, clone); clonedNodes.Add(state.instance.id.NetNode, clone.id.NetNode); } } foreach (InstanceState state in m_states) { if (state.instance.id.Type == InstanceType.NetNode) { continue; } if (state.instance.id.Type == InstanceType.NetSegment) { SegmentState segState = state as SegmentState; if (!clonedNodes.ContainsKey(segState.startNode)) { InstanceID instanceID = InstanceID.Empty; instanceID.NetNode = segState.startNode; // Don't clone if node is missing if (!((Instance)instanceID).isValid) { continue; } clonedNodes.Add(segState.startNode, segState.startNode); } if (!clonedNodes.ContainsKey(segState.endNode)) { InstanceID instanceID = InstanceID.Empty; instanceID.NetNode = segState.endNode; // Don't clone if node is missing if (!((Instance)instanceID).isValid) { continue; } clonedNodes.Add(segState.endNode, segState.endNode); } } Instance clone = state.instance.Clone(state, clonedNodes); toReplace.Add(state.instance, clone); } if (replaceInstances) { ReplaceInstances(toReplace); ActionQueue.instance.ReplaceInstancesBackward(toReplace); selection = m_oldSelection; } }
public override void Undo() { if (m_states == null) { return; } Dictionary <Instance, Instance> toReplace = new Dictionary <Instance, Instance>(); Dictionary <ushort, ushort> clonedNodes = new Dictionary <ushort, ushort>(); // Recreate nodes foreach (InstanceState state in m_states) { if (state.instance.id.Type == InstanceType.NetNode) { Instance clone = state.instance.Clone(state, null); toReplace.Add(state.instance, clone); clonedNodes.Add(state.instance.id.NetNode, clone.id.NetNode); ActionQueue.instance.UpdateNodeIdInStateHistory(state.instance.id.NetNode, clone.id.NetNode); //Debug.Log($"Cloned N:{state.instance.id.NetNode}->{clone.id.NetNode}"); } } // Recreate everything except nodes and segments foreach (InstanceState state in m_states) { if (state.instance.id.Type == InstanceType.NetNode) { continue; } if (state.instance.id.Type == InstanceType.NetSegment) { continue; } Instance clone = state.instance.Clone(state, clonedNodes); toReplace.Add(state.instance, clone); // Add attached nodes to the clonedNode list so other segments reconnect if (state.instance.id.Type == InstanceType.Building) { BuildingState buildingState = state as BuildingState; List <ushort> origNodeIds = new List <ushort>(); MoveableBuilding cb = clone as MoveableBuilding; ushort cloneNodeId = ((Building)cb.data).m_netNode; if (cloneNodeId != 0) { int c = 0; string msg2 = "Original attached nodes:"; foreach (InstanceState i in buildingState.subStates) { if (i is NodeState ns) { InstanceID instanceID = default(InstanceID); instanceID.RawData = ns.id; //msg2 += $"\n{c} - Attached node #{instanceID.NetNode}: {ns.Info.Name}"; origNodeIds.Insert(c++, instanceID.NetNode); } } //Debug.Log(msg2); c = 0; msg2 = ""; while (cloneNodeId != 0) { ushort origNodeId = origNodeIds[c]; NetNode clonedAttachedNode = NetManager.instance.m_nodes.m_buffer[cloneNodeId]; if (clonedAttachedNode.Info.GetAI() is TransportLineAI) { cloneNodeId = clonedAttachedNode.m_nextBuildingNode; continue; } if (clonedNodes.ContainsKey(origNodeId)) { Debug.Log($"Node #{origNodeId} is already in clone list!"); } clonedNodes.Add(origNodeId, cloneNodeId); msg2 += $"\n{c} - {origNodeId} -> {cloneNodeId} {clonedAttachedNode.Info.GetAI()}"; cloneNodeId = clonedAttachedNode.m_nextBuildingNode; if (++c > 32768) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } Debug.Log(msg2); } } } //string msg = "Cloned Nodes:\n"; //foreach (KeyValuePair<ushort, ushort> kvp in clonedNodes) //{ // msg += $"{kvp.Key} => {kvp.Value}\n"; //} //Debug.Log(msg); // Recreate segments foreach (InstanceState state in m_states) { if (state.instance.id.Type == InstanceType.NetSegment) { SegmentState segState = state as SegmentState; if (!clonedNodes.ContainsKey(segState.startNode)) { InstanceID instanceID = InstanceID.Empty; instanceID.NetNode = segState.startNode; // Don't clone if node is missing if (!((Instance)instanceID).isValid) { continue; } clonedNodes.Add(segState.startNode, segState.startNode); } if (!clonedNodes.ContainsKey(segState.endNode)) { InstanceID instanceID = InstanceID.Empty; instanceID.NetNode = segState.endNode; // Don't clone if node is missing if (!((Instance)instanceID).isValid) { continue; } clonedNodes.Add(segState.endNode, segState.endNode); } Instance clone = state.instance.Clone(state, clonedNodes); toReplace.Add(state.instance, clone); } } if (replaceInstances) { ReplaceInstances(toReplace); ActionQueue.instance.ReplaceInstancesBackward(toReplace); selection = m_oldSelection; } }