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 CircuitElement::findConnectedWithFace(std::vector <std::pair <std::list<CircuitElement>::iterator, int > >& connected, Map& map, INodeDefManager* ndef, v3s16 pos, FaceId face, std::map<v3s16, std::list<CircuitElement>::iterator>& pos_to_iterator, bool connected_faces[6]) { static v3s16 directions[6] = {v3s16(0, -1, 0), v3s16(0, 0, 1), v3s16(-1, 0, 0), v3s16(0, 1, 0), v3s16(0, 0, -1), v3s16(1, 0, 0), }; std::map <v3s16, unsigned char> used; used[pos] = face; std::queue <std::pair <v3s16, unsigned char> > q; v3s16 current_pos; v3s16 next_pos; std::map <v3s16, unsigned char>::iterator current_used_iterator; std::map <v3s16, unsigned char>::iterator tmp_used_iterator; ContentFeatures node_features, current_node_features; MapNode next_node, current_node; int face_id = FACE_TO_SHIFT(face); connected_faces[face_id] = true; current_pos.X = pos.X + directions[face_id].X; current_pos.Y = pos.Y + directions[face_id].Y; current_pos.Z = pos.Z + directions[face_id].Z; next_node = map.getNodeNoEx(current_pos); node_features = ndef->get(next_node); q.push(std::make_pair(current_pos, node_features.wire_connections[FACE_TO_SHIFT(OPPOSITE_FACE(face))])); if(ndef->get(map.getNodeNoEx(current_pos)).is_wire || ndef->get(map.getNodeNoEx(current_pos)).is_connector) { while(!q.empty()) { unsigned char acceptable_faces; current_pos = q.front().first; acceptable_faces = q.front().second; q.pop(); for(int i = 0; i < 6; ++i) { if(acceptable_faces & (SHIFT_TO_FACE(i))) { next_pos.X = current_pos.X + directions[i].X; next_pos.Y = current_pos.Y + directions[i].Y; next_pos.Z = current_pos.Z + directions[i].Z; used[current_pos] |= SHIFT_TO_FACE(i); next_node = map.getNodeNoEx(next_pos); node_features = ndef->get(next_node); current_node = map.getNodeNoEx(current_pos); current_node_features = ndef->get(current_node); current_used_iterator = used.find(next_pos); // If start element, mark some of it's faces if(next_pos == pos) { connected_faces[OPPOSITE_SHIFT(i)] = true; } if((current_used_iterator == used.end()) || !(current_used_iterator->second & SHIFT_TO_FACE(OPPOSITE_SHIFT(i)))) { if(current_node_features.is_connector || node_features.is_connector || (node_features.is_wire && (next_node.getContent() == current_node.getContent()))) { if(node_features.param_type_2 == CPT2_FACEDIR) { q.push(std::make_pair(next_pos, CircuitElementStates::rotateState( node_features.wire_connections[OPPOSITE_SHIFT(i)], FACEDIR_TO_FACE(next_node.param2)))); } else { q.push(std::make_pair(next_pos, node_features.wire_connections[OPPOSITE_SHIFT(i)])); } tmp_used_iterator = used.find(next_pos); if(tmp_used_iterator != used.end()) { tmp_used_iterator->second |= SHIFT_TO_FACE(OPPOSITE_SHIFT(i)); } else { used[next_pos] = SHIFT_TO_FACE(OPPOSITE_SHIFT(i)); } } if(node_features.is_circuit_element) { tmp_used_iterator = used.find(next_pos); if(tmp_used_iterator != used.end()) { tmp_used_iterator->second |= SHIFT_TO_FACE(OPPOSITE_SHIFT(i)); } else { used[next_pos] = SHIFT_TO_FACE(OPPOSITE_SHIFT(i)); } connected.push_back(std::make_pair(pos_to_iterator[next_pos], OPPOSITE_SHIFT(i))); } } } } } } else if(ndef->get(map.getNodeNoEx(current_pos)).is_circuit_element) { connected.push_back(std::make_pair(pos_to_iterator[current_pos], FACE_TO_SHIFT(OPPOSITE_FACE(face)))); } }