void CircuitElement::swap(const MapNode& n_old, const ContentFeatures& n_old_features, const MapNode& n_new, const ContentFeatures& n_new_features) { CircuitElementContainer tmp_faces[6]; for(int i = 0; i < 6; ++i) { u8 shift = FACE_TO_SHIFT(rotateFace(n_old, n_old_features, SHIFT_TO_FACE(i))); tmp_faces[shift] = m_faces[i]; } for(int i = 0; i < 6; ++i) { u8 shift = FACE_TO_SHIFT(revRotateFace(n_new, n_new_features, SHIFT_TO_FACE(i))); m_faces[shift] = tmp_faces[i]; if(m_faces[shift].is_connected) { m_faces[shift].list_iterator->shift = shift; } } setDelay(n_new_features.circuit_element_delay); }
void CircuitElement::findConnectedWithFace(std::vector <std::pair <std::list<CircuitElement>::iterator, u8> >& connected, Map* map, INodeDefManager* ndef, v3POS pos, u8 face, std::map<v3POS, std::list<CircuitElement>::iterator>& pos_to_iterator, bool connected_faces[6]) { static v3POS directions[6] = {v3POS(0, 1, 0), v3POS(0, -1, 0), v3POS(1, 0, 0), v3POS(-1, 0, 0), v3POS(0, 0, 1), v3POS(0, 0, -1), }; // First - wire pos, second - acceptable faces std::queue <std::pair <v3POS, u8> > q; v3POS current_pos, next_pos; MapNode next_node, current_node; // used[pos] = or of all faces, that are already processed std::map <v3POS, u8> used; u8 face_id = FACE_TO_SHIFT(face); connected_faces[face_id] = true; used[pos] = face; current_node = map->getNodeNoEx(pos); const ContentFeatures& first_node_features = ndef->get(current_node); face = rotateFace(current_node, first_node_features, face); face_id = FACE_TO_SHIFT(face); current_pos = pos + directions[face_id]; current_node = map->getNodeNoEx(current_pos); const ContentFeatures& current_node_features = ndef->get(current_node); u8 real_face = revRotateFace(current_node, current_node_features, face); u8 real_face_id = FACE_TO_SHIFT(real_face); if(current_node_features.is_wire || current_node_features.is_wire_connector) { q.push(std::make_pair(current_pos, current_node_features.wire_connections[real_face_id])); while(!q.empty()) { current_pos = q.front().first; u8 acceptable_faces = q.front().second; q.pop(); current_node = map->getNodeNoEx(current_pos); const ContentFeatures& current_node_features = ndef->get(current_node); for(int i = 0; i < 6; ++i) { u8 real_face = revRotateFace(current_node, current_node_features, SHIFT_TO_FACE(i)); if(acceptable_faces & real_face) { used[current_pos] |= real_face; next_pos = current_pos + directions[i]; next_node = map->getNodeNoEx(next_pos); const ContentFeatures& node_features = ndef->get(next_node); u8 next_real_face = revRotateFace(next_node, node_features, OPPOSITE_FACE(SHIFT_TO_FACE(i))); u8 next_real_shift = FACE_TO_SHIFT(next_real_face); // If start element, mark some of it's faces if(next_pos == pos) { connected_faces[next_real_shift] = true; } auto next_used_iterator = used.find(next_pos); bool is_part_of_circuit = node_features.is_wire_connector || node_features.is_circuit_element || (node_features.is_wire && (next_node.getContent() == current_node.getContent())); bool not_used = (next_used_iterator == used.end()) || !(next_used_iterator->second & next_real_face); if(is_part_of_circuit && not_used) { if(node_features.is_circuit_element) { connected.push_back(std::make_pair(pos_to_iterator[next_pos], next_real_shift)); } else { q.push(std::make_pair(next_pos, node_features.wire_connections[next_real_shift])); } if(next_used_iterator != used.end()) { next_used_iterator->second |= next_real_face; } else { used[next_pos] = next_real_face; } } } } } } else if(current_node_features.is_circuit_element) { connected.push_back(std::make_pair(pos_to_iterator[current_pos], OPPOSITE_SHIFT(real_face_id))); } }
void removeCornerFromBufferTarget(int corner) { switch (corner) { case 2: rotateFace(5, true); rotateFace(3, false); break; case 6: rotateFace(3, true); rotateFace(2, false); break; case 8: rotateFace(2, false); break; case 11: rotateFace(2, false); rotateFace(2, false); break; case 15: rotateFace(5, false); rotateFace(5, false); break; case 17: rotateFace(3, true); rotateFace(2, false); rotateFace(2, false); break; case 18: rotateFace(5, false); rotateFace(2, true); break; case 20: rotateFace(5, false); rotateFace(2, false); rotateFace(2, false); break; case 24: rotateFace(5, false); break; case 26: rotateFace(2, false); rotateFace(3, false); break; case 27: rotateFace(3, true); break; case 29: rotateFace(3, false); rotateFace(3, false); break; case 33: break; // 33 is where the magic happens case 35: rotateFace(3, false); break; case 36: rotateFace(2, false); rotateFace(3, true); break; case 42: rotateFace(5, true); break; case 44: rotateFace(3, false); rotateFace(5, true); break; case 45: rotateFace(2, true); break; case 47: rotateFace(3, true); rotateFace(2, true); break; case 51: rotateFace(2, true); rotateFace(5, false); break; case 53: rotateFace(2, false); rotateFace(3, false); rotateFace(3, false); break; default: // TODO: ERROR - trying to unswap an unswappable piece (not a corner, the buffer...) break; } }
void moveEdgeToBufferTargetSwap(int edge) { switch (edge) { case 1: break; // 1 is where the magic happens case 3: rotateFace(1, true); rotateFace(0, false); rotateFace(1, false); rotateFace(0, true); break; case 5: rotateFace(3, false); rotateFace(0, true); rotateFace(3, true); rotateFace(0, false); break; case 7: break; // Special case: handle with care! case 10: rotateFace(4, true); rotateFace(1, false); rotateFace(4, false); break; case 12: rotateFace(1, false); rotateFace(4, true); rotateFace(1, true); rotateFace(4, false); break; case 14: rotateFace(4, true); rotateFace(1, true); rotateFace(1, true); rotateFace(4, false); break; case 16: rotateFace(4, true); rotateFace(1, true); rotateFace(4, false); break; case 21: rotateFace(0, false); rotateFace(1, false); rotateFace(0, true); break; case 23: rotateFace(0, true); rotateFace(3, true); rotateFace(0, false); break; case 28: rotateFace(4, false); rotateFace(3, true); rotateFace(4, true); break; case 30: rotateFace(4, false); rotateFace(3, true); rotateFace(3, true); rotateFace(4, true); break; case 32: rotateFace(3, true); rotateFace(4, false); rotateFace(3, false); rotateFace(4, true); break; case 34: rotateFace(4, false); rotateFace(3, false); rotateFace(4, true); break; case 37: rotateFace(4, false); rotateFace(3, true); rotateFace(3, true); rotateFace(4, true); rotateFace(0, true); rotateFace(3, true); rotateFace(0, false); break; case 39: rotateFace(0, true); rotateFace(3, false); rotateFace(0, false); break; case 41: rotateFace(0, false); rotateFace(1, true); rotateFace(0, true); break; case 48: rotateFace(0, false); rotateFace(1, true); rotateFace(1, true); rotateFace(0, true); break; case 50: rotateFace(0, true); rotateFace(3, true); rotateFace(3, true); rotateFace(0, false); case 52: break; // Special case: handle with care! default: // TODO: ERROR - trying to swap an unswappable piece (not an edge, the buffer...) break; } }
void removeEdgeFromBufferTargetFlip(int edge) { switch (edge) { case 1: case 37: rotateFace(4, false); rotateFace(4, false); break; case 3: case 10: rotateFace(4, false); rotateFace(4, false); rotateFace(0, false); break; case 5: case 28: rotateFace(4, false); rotateFace(4, false); rotateFace(0, true); break; case 7: case 19: rotateFace(4, false); rotateFace(4, false); rotateFace(0, false); rotateFace(0, false); break; case 14: case 21: rotateFace(4, false); rotateFace(1, false); rotateFace(1, false); break; case 23: case 30: rotateFace(4, true); rotateFace(3, false); rotateFace(3, false); break; case 32: case 39: rotateFace(4, true); break; case 12: case 41: rotateFace(4, false); break; case 34: case 50: rotateFace(4, true); rotateFace(3, true); break; case 43: case 52: break; // 43 and 52 are where the magic happens case 16: case 48: rotateFace(4, false); rotateFace(1, false); break; default: // TODO: ERROR - trying to unflip an unflippable piece (not an edge, the buffer...) break; } }