| 199 | } |
| 200 | |
| 201 | WireConnector::SwingResult WirePane::swing(WorldGeometry const& geometry, Vec2F pos, FireMode mode) { |
| 202 | pos = geometry.xwrap(pos); |
| 203 | |
| 204 | if (m_worldClient->isTileProtected((Vec2I)pos)) { |
| 205 | m_connecting = false; |
| 206 | return Protected; |
| 207 | } |
| 208 | |
| 209 | RectF bounds = {pos - Vec2F(16, 16), pos + Vec2F(16, 16)}; |
| 210 | |
| 211 | if (mode == FireMode::Primary) { |
| 212 | Maybe<WireConnection> matchNode; |
| 213 | WireDirection matchDirection = WireDirection::Output; |
| 214 | float bestDist = 10000; |
| 215 | for (auto entity : m_worldClient->query<WireEntity>(bounds)) { |
| 216 | for (size_t i = 0; i < entity->nodeCount(WireDirection::Input); ++i) { |
| 217 | RectF inbounds = RectF::withSize(centerOfTile(entity->tilePosition() + entity->nodePosition({WireDirection::Input, i})) - (m_nodeSize / 2.0f), m_nodeSize); |
| 218 | if (geometry.rectContains(inbounds, pos)) { |
| 219 | if (!matchNode) { |
| 220 | matchNode = WireConnection{entity->tilePosition(), i}; |
| 221 | matchDirection = WireDirection::Input; |
| 222 | bestDist = geometry.diff(centerOfTile(entity->tilePosition() + entity->nodePosition({WireDirection::Input, i})), pos).magnitudeSquared(); |
| 223 | } else { |
| 224 | float thisDist = geometry.diff(centerOfTile(entity->tilePosition() + entity->nodePosition({WireDirection::Input, i})), pos).magnitudeSquared(); |
| 225 | if (thisDist < bestDist) { |
| 226 | matchNode = WireConnection{entity->tilePosition(), i}; |
| 227 | matchDirection = WireDirection::Input; |
| 228 | bestDist = thisDist; |
| 229 | } |
| 230 | } |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | for (size_t i = 0; i < entity->nodeCount(WireDirection::Output); ++i) { |
| 235 | RectF outbounds = RectF::withSize(centerOfTile(entity->tilePosition() + entity->nodePosition({WireDirection::Output, i})) - (m_nodeSize / 2.0f), m_nodeSize); |
| 236 | if (geometry.rectContains(outbounds, pos)) { |
| 237 | if (!matchNode) { |
| 238 | matchNode = WireConnection{entity->tilePosition(), i}; |
| 239 | matchDirection = WireDirection::Output; |
| 240 | bestDist = geometry.diff(centerOfTile(entity->tilePosition() + entity->nodePosition({WireDirection::Output, i})), pos).magnitudeSquared(); |
| 241 | } else { |
| 242 | float thisDist = geometry.diff(centerOfTile(entity->tilePosition() + entity->nodePosition({WireDirection::Output, i})), pos).magnitudeSquared(); |
| 243 | if (thisDist < bestDist) { |
| 244 | matchNode = WireConnection{entity->tilePosition(), i}; |
| 245 | matchDirection = WireDirection::Output; |
| 246 | bestDist = thisDist; |
| 247 | } |
| 248 | } |
| 249 | } |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | if (matchNode) { |
| 254 | if (m_connecting) { |
| 255 | if (m_sourceDirection == matchDirection) { |
| 256 | return Mismatch; |
| 257 | } else if (m_sourceConnector.entityLocation == matchNode->entityLocation) { |
| 258 | return Mismatch; |
no test coverage detected