void FocusController::findHorizontallyFocusableNodeInRect(FocusDirection direction, Node* start, KeyboardEvent* event, const IntRect* rect, Node** candidateNode, IntRect& candidateNodeRect) { #if PLATFORM(WKC) CRASH_IF_STACK_OVERFLOW(WKC_STACK_MARGIN_DEFAULT); #endif // ASSERT(direction == FocusDirectionLeft || direction == FocusDirectionRight); if (!start) return ; Node* node = start; HTMLFrameOwnerElement* owner; Document* document; IntRect nodeRect; while (node) { if (!isNodeInSpecificRect(node, rect)) { node = getClosestNode(node, direction); continue; } owner = 0; if (node->isFrameOwnerElement()) { owner = static_cast<HTMLFrameOwnerElement*>(node); if (!owner->contentFrame()) { *candidateNode = 0; return; } document = owner->contentFrame()->document(); findHorizontallyFocusableNodeInRect(direction, document, event, rect, candidateNode, candidateNodeRect); } else if (isScrollableContainerNode(node) && !node->renderer()->isTextArea()) { findHorizontallyFocusableNodeInRect(direction, node->firstChild(), event, rect, candidateNode, candidateNodeRect); } else { if (node->isFocusable() && !node->isFrameOwnerElement()) { nodeRect = node->renderer()->absoluteBoundingBoxRect(); FrameView* frameView = node->document()->view(); if (!frameView) { *candidateNode = 0; return; } nodeRect = frameView->contentsToWindow(nodeRect); nodeRect.intersect(*rect); if (!nodeRect.isEmpty()) { if (candidateNodeRect.isEmpty()) { *candidateNode = node; candidateNodeRect = nodeRect; } if (direction == FocusDirectionRight && candidateNodeRect.x() > nodeRect.x()) { *candidateNode = node; candidateNodeRect = nodeRect; } else if (direction == FocusDirectionLeft && candidateNodeRect.x() < nodeRect.x()) { *candidateNode = node; candidateNodeRect = nodeRect; } } } } node = getClosestNode(node, direction); } }
void CharacterUpdaterPlayer::goToUsingPath(const CCVector3 &target) { const CCPathFinderNetwork::PathNode *targetNode = pathFinderNetwork->findClosestNode( player, &target, false ); if( targetNode == NULL ) { DELETE_POINTER( path ); goTo( target ); return; } if( path == NULL ) { findNewAnchor = true; path = new CCPathFinderNetwork::Path(); } getClosestNode(); pathAnchorNode = anchorNode; if( pathAnchorNode != NULL ) { pathFinderNetwork->findPath( *path, pathAnchorNode, targetNode ); } if( path->endDirection == 0 ) { // See if we can head straight to our target CCObjectCollideable *hitObject = CCMovementOctreeCollisionCheck( player, *player->positionPtr, target ); if( hitObject == NULL ) { DELETE_POINTER( path ); } } // Check if we can head straight to our first path else { const int pathDirection = path->directions[0]; if( pathAnchorNode != NULL && pathDirection < pathAnchorNode->numberOfConnections ) { const CCPathFinderNetwork::PathNode::PathConnection *usingConnection = &pathAnchorNode->connections[pathDirection]; const CCVector3 *pathTarget = &usingConnection->node->point; CCObjectCollideable *hitObject = CCMovementOctreeCollisionCheck( player, *player->positionPtr, *pathTarget ); currentPath = hitObject == NULL ? 0 : -1; } else { currentPath = 0; } } goTo( target ); }
void CharacterUpdaterAI::setWaypointCycle(WaypointCycleType inCycleType) { waypointCycle = inCycleType; if( enabled ) { if( waypointCycle == cycle_random ) { waypointCurrent = rand() % waypointTotal; goTo( waypoints[waypointCurrent] ); } else if( waypointCycle == cycle_aiNodes ) { getClosestNode(); pickRandomNode(); } } }
Node* FocusController::findVerticallyFocusableNodeInRect(FocusDirection direction, Node* start, KeyboardEvent* event, const IntRect* rect) { #if PLATFORM(WKC) CRASH_IF_STACK_OVERFLOW(WKC_STACK_MARGIN_DEFAULT); #endif ASSERT(direction == FocusDirectionUp || direction == FocusDirectionDown); if (!start) return 0; Node* node = start; HTMLFrameOwnerElement* owner; Document* document; while (node) { if (!isNodeInSpecificRect(node, rect)) { node = getClosestNode(node, direction); continue; } owner = 0; if (node->isFrameOwnerElement()) { owner = static_cast<HTMLFrameOwnerElement*>(node); if (!owner->contentFrame()) { node = 0; break; } document = owner->contentFrame()->document(); if (direction == FocusDirectionUp) { node = findVerticallyFocusableNodeInRect(direction, document->lastChild(), event, rect); } else { node = findVerticallyFocusableNodeInRect(direction, document->firstChild(), event, rect); } if (node) break; node = getClosestNode(owner, direction); continue; } else if (isScrollableContainerNode(node) && !node->renderer()->isTextArea()) { Node* childNode = 0; if (direction == FocusDirectionUp) { childNode = findVerticallyFocusableNodeInRect(direction, node->lastChild(), event, rect); } else { ASSERT(direction == FocusDirectionDown); childNode = findVerticallyFocusableNodeInRect(direction, node->firstChild(), event, rect); } if (!childNode) { node = getClosestNode(node, direction, true); if (!node) break; } else { node = childNode; break; } } if (node->isFocusable() && !node->isFrameOwnerElement()) { break; } if (owner) { node = owner; } node = getClosestNode(node, direction); } return node; }
void CharacterUpdaterAI::movePlayer(const float delta) { if( wait > 0.0f ) { player->movementDirection.z = 0.0f; wait -= delta; if( wait <= 0.0f ) { goTo( targetConnection->node->point ); } } else if( moving ) { if( path != NULL ) { super::movePlayer( delta ); } else { const float distance = CCVector3DistanceCheck2D( player->getPosition(), positionTarget, false ); if( distance > 5.0f ) { movePlayerRotation( positionTarget, delta ); } else { if( waypointCycle == cycle_aiNodes && enabled && followingEnemy == false ) { if( pathAnchorNode == NULL || targetConnection == NULL ) { getClosestNode(); pickRandomNode(); } else if( targetConnection->distance > 10.0f || distance < 0.1f ) { pathAnchorNode = targetConnection->node; anchorNode = pathAnchorNode; if( nodesPerMovementCycle++ > 10 ) { int shouldWait = rand() % 5; if( shouldWait == 0 ) { wait = (float)( rand() % 15 ) + 5.0f; } else { movementMagnitude = ( ( rand() % 5 ) * 0.1f ) + 0.3f; } nodesPerMovementCycle = 0; } // Pick a path from that node int randomType = rand() % 5; if( randomType > 1 ) { int closestConnection = 0; float closestAngle = MAXFLOAT; for( int i=0; i<pathAnchorNode->numberOfConnections; ++i ) { const float angleDistance = CCDistanceBetweenAngles( player->rotation.y, pathAnchorNode->connections[i].angle ); if( angleDistance < closestAngle ) { closestConnection = i; closestAngle = angleDistance; } } if( pathAnchorNode->numberOfConnections > 0 ) { targetConnection = &pathAnchorNode->connections[closestConnection]; goTo( targetConnection->node->point ); } else { } } else { pickRandomNode(); } } } else { if( landPlayerOnTarget( distance, delta ) ) { if( enabled && followingEnemy == false ) { if( waypointCycle == cycle_off ) { if( waypointTotal > 0 ) { waypointTotal--; if( waypointTotal > 0 ) { for( int i=0; i<waypointTotal; ++i ) { waypoints[i] = waypoints[i+1]; } goToUsingPath( waypoints[0] ); } } } else { nextWaypoint(); } } } } } } } }