예제 #1
0
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);
}
예제 #2
0
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)));
	}
}
예제 #3
0
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))));
	}
}