void AHAI::executeShootToClear() { switch(iStateStep) { case AH_STATE_STEP_ENTER: pTargetPosition.y = pMyPosition.y; pTargetPosition.x = (pMyPosition.x > 0)? -AH_TABLE_WIDTH / 3.0f: AH_TABLE_WIDTH / 3.0f; iStateStep = AH_STATE_STEP_EXECUTE; break; case AH_STATE_STEP_EXECUTE: fSpeed = cLevel.SpeedForClearing; if(targetPositionReached()) { iStateStep = AH_STATE_STEP_EXIT; } break; case AH_STATE_STEP_EXIT: selectState(AH_STATE_NOTHING); break; default: break; } }
void AHAI::executeAvoidGoal() { float fTimeForThePuckToCome; float fDistanceToTarget; float fSpeedSlow = 5.0f; switch(iStateStep) { case AH_STATE_STEP_ENTER: // target position pTargetPosition.y = max(pMyPosition.y - fBackSpace, fMinimumGoalDistance); pTargetPosition.x = predictPositionX(pTargetPosition.y); // error pTargetPosition.x += rand() % 50; pTargetPosition.y += rand() % 50; // speed fTimeForThePuckToCome = (pTargetPosition.y - pPuckPosition.y) / vPuckVelocity.y; fTimeForThePuckToCome = abs(fTimeForThePuckToCome); fTimeForThePuckToCome -= 2.0; // state change frames if(fTimeForThePuckToCome < 0.0) { fCalculatedSpeed = cLevel.SpeedForDefending; } else { fDistanceToTarget = (pTargetPosition.x - pMyPosition.x) * (pTargetPosition.x - pMyPosition.x); fDistanceToTarget += (pTargetPosition.y - pMyPosition.y) * (pTargetPosition.y - pMyPosition.y); fDistanceToTarget = sqrt(fDistanceToTarget); fCalculatedSpeed = fDistanceToTarget / fTimeForThePuckToCome; fCalculatedSpeed = min(fCalculatedSpeed, cLevel.SpeedForDefending); } iStateStep = AH_STATE_STEP_EXECUTE; break; case AH_STATE_STEP_EXECUTE: fSpeed = fCalculatedSpeed; if(pPuckPosition.y <= pMyPosition.y || vPuckVelocity.y >= -fSpeedSlow) iStateStep = AH_STATE_STEP_EXIT; break; case AH_STATE_STEP_EXIT: selectState(AH_STATE_NOTHING); break; default: break; } }
void AHAI::executeGoToBack() { switch(iStateStep) { case AH_STATE_STEP_ENTER: pTargetPosition.x = 0.0; pTargetPosition.y = fNearBackBorder; iStateStep = AH_STATE_STEP_EXECUTE; break; case AH_STATE_STEP_EXECUTE: fSpeed = cLevel.SpeedForDefending; if(targetPositionReached() || (pPuckPosition.y < pMyPosition.y && abs(pPuckPosition.x) < (AH_TABLE_WIDTH / 6))) { iStateStep = AH_STATE_STEP_EXIT; } break; case AH_STATE_STEP_EXIT: selectState(AH_STATE_NOTHING); break; default: break; } }
void AHAI::executeBeAlert() { switch(iStateStep) { case AH_STATE_STEP_ENTER: iStateStep = AH_STATE_STEP_EXECUTE; // average point between puck and goal in my zone pTargetPosition.x = pPuckPosition.x / 4.0f; pTargetPosition.y = fMinimumGoalDistance + rand() % round(fAlertZoneHeight); fSpeed = cLevel.DefaultSpeed; break; case AH_STATE_STEP_EXECUTE: if((targetPositionReached() && (vPuckVelocity.x != 0.0 || vPuckVelocity.y != 0.0)) || vPuckVelocity.y < 0.0) { iStateStep = AH_STATE_STEP_EXIT; } break; case AH_STATE_STEP_EXIT: selectState(AH_STATE_NOTHING); break; default: break; } }
void AHAI::executeGoToPuck() { switch(iStateStep) { case AH_STATE_STEP_ENTER: iStateStep = AH_STATE_STEP_EXECUTE; break; case AH_STATE_STEP_EXECUTE: pTargetPosition.x = pPuckPosition.x; pTargetPosition.y = pPuckPosition.y; fSpeed = cLevel.DefaultSpeed * 2.0f; if(cGame->checkEvent() == AH_EVENT_PUCK_MALLET1_COLLISION || cGame->checkEvent() == AH_EVENT_PUCK_MALLET2_COLLISION) { iStateStep = AH_STATE_STEP_EXIT; } break; case AH_STATE_STEP_EXIT: selectState(AH_STATE_NOTHING); break; default: break; } }
void onChangeAction() { Item* item = static_cast<Item*>( actions()->getSelectedChild()); if (m_document && m_document->undoHistory()->currentState() != item->state()) { try { DocumentWriter writer(m_document, 100); m_document->undoHistory()->moveToState(item->state()); m_document->generateMaskBoundaries(); m_document->notifyGeneralUpdate(); } catch (const std::exception& ex) { selectState(m_document->undoHistory()->currentState()); Console::showException(ex); } } }
void onChangeAction() { Item* item = static_cast<Item*>( actions()->getSelectedChild()); if (m_document && m_document->undoHistory()->currentState() != item->state()) { try { DocumentWriter writer(m_document, 100); m_document->undoHistory()->moveToState(item->state()); m_document->generateMaskBoundaries(); // TODO this should be an observer of the current document palette set_current_palette(m_document->sprite()->palette(m_frame), false); m_document->notifyGeneralUpdate(); } catch (const std::exception& ex) { selectState(m_document->undoHistory()->currentState()); Console::showException(ex); } } }
void AHAI::executeShootToGoal() { switch(iStateStep) { case AH_STATE_STEP_ENTER: iStateStep = AH_STATE_STEP_EXECUTE; break; case AH_STATE_STEP_EXECUTE: pTargetPosition = pPuckPosition; fSpeed = cLevel.SpeedForShooting; if(pPuckPosition.y < pMyPosition.y || // the puck is behind me (cGame->checkEvent() == AH_EVENT_PUCK_MALLET2_COLLISION && iPlayer == 2) || // the puck collides with the mallet (cGame->checkEvent() == AH_EVENT_PUCK_MALLET1_COLLISION && iPlayer == 1) || pPuckPosition.y > (AH_TABLE_HEIGHT / 2) || // the puck is out of my zone abs(pPuckPosition.x) > (AH_TABLE_WIDTH / 2 + fNearSideBorder) || // the puck is too near from a side border pPuckPosition.y < fNearBackBorder) // the puck is too near from the back border { iStateStep = AH_STATE_STEP_EXIT; } break; case AH_STATE_STEP_EXIT: selectState(AH_STATE_NOTHING); break; default: break; } }
void AHAI::executeClearPuck() { switch(iStateStep) { case AH_STATE_STEP_ENTER: pTargetPosition.x = (pMyPosition.x < 0)? -AH_TABLE_WIDTH / 6.0f: AH_TABLE_WIDTH / 6.0f; pTargetPosition.y = AH_MALLET_RADIUS; iStateStep = AH_STATE_STEP_EXECUTE; break; case AH_STATE_STEP_EXECUTE: if(targetPositionReached() || pPuckPosition.y > fNearBackBorder || abs(pPuckPosition.x) > (AH_TABLE_WIDTH / 6)) { iStateStep = AH_STATE_STEP_EXIT; } fSpeed = cLevel.SpeedForClearing; break; case AH_STATE_STEP_EXIT: selectState(AH_STATE_SHOOT_TO_CLEAR); break; default: break; } }
//-------------------------------------------------------------- // Name: Evaluate() // Class: GeneralCombatWithMeleeWeapon // // Description: Returns True Or False, and is run every frame // that the behavior // // Parameters: Actor &self // // Returns: True or False //-------------------------------------------------------------- BehaviorReturnCode_t GeneralCombatWithMeleeWeapon::Evaluate ( Actor &self ) { Entity *currentEnemy; // Make sure our rotate and headwatch targets are up to date if ( _state != GENERAL_COMBAT_MELEE_ATTACK && _state != GENERAL_COMBAT_MELEE_CHANGE_POSTURE ) setUpRotate( self ); faceEnemy( self ); setHeadWatchTarget( self ); currentEnemy = self.enemyManager->GetCurrentEnemy(); if (currentEnemy && _maxDistanceToEngage && !self.WithinDistance( currentEnemy, _maxDistanceToEngage)) { self.enemyManager->ClearCurrentEnemy(); SetFailureReason( "My Current Enemy is farther away than my _maxDistanceToEngage\n" ); return BEHAVIOR_FAILED; // I may have an enemy, but he's too far away. Ignore him. } if ( _state == GENERAL_COMBAT_MELEE_FAILED ) return BEHAVIOR_FAILED; if ( currentEnemy && !self.WithinDistance( currentEnemy , _meleeDistance ) && level.time > _nextRushAttemptTime ) { setupRushEnemy( self ); _state = GENERAL_COMBAT_MELEE_RUSH_ENEMY; } switch ( _state ) { case GENERAL_COMBAT_MELEE_SELECT_STATE: //setTorsoAnim( self ); // Breaks the initial attack anim selectState( self ); break; case GENERAL_COMBAT_MELEE_RUSH_ENEMY: rushEnemy( self ); break; case GENERAL_COMBAT_MELEE_STRAFE: setTorsoAnim( self ); strafe(self); setTorsoAnim( self ); break; case GENERAL_COMBAT_MELEE_ATTACK: attack( self ); break; case GENERAL_COMBAT_MELEE_BLOCK: block( self ); break; case GENERAL_COMBAT_MELEE_CHANGE_POSTURE: changePosture(self); break; case GENERAL_COMBAT_MELEE_HOLD: setTorsoAnim( self ); hold( self ); break; case GENERAL_COMBAT_MELEE_FAILED: return BEHAVIOR_FAILED; } return BEHAVIOR_EVALUATING; }
void onAfterRedo(DocumentUndo* history) override { selectState(history->currentState()); }
void AHAI::executePrepareShoot() { AHPoint pPuckFuturePosition; CLine* cShotLine; float fTimeForThePuckToCome; float fDistanceToTarget; int iChoice; switch(iStateStep) { case AH_STATE_STEP_ENTER: // default: direct shot pShotPoint = calculateGoalPoint(); iChoice = rand() % 2; // with bounce if(iChoice == 1) { // against the left wall if(pMyPosition.x >= 0.0 && pPuckPosition.x < -fHoleToShoot) pShotPoint.x -= AH_TABLE_WIDTH * (1 + rand() % 2); // one or two bounces // against the right wall else if(pMyPosition.x < 0.0 && pPuckPosition.x > fHoleToShoot) pShotPoint.x += AH_TABLE_WIDTH * (1 + rand() % 2); } // puck's future position fImpulseDistance = fBackSpace; pPuckFuturePosition.y = pMyPosition.y + fImpulseDistance; pPuckFuturePosition.x = predictPositionX(pPuckFuturePosition.y); // shot line cShotLine = new CLine(pShotPoint.x, pShotPoint.y, pPuckFuturePosition.x, pPuckFuturePosition.y); pTargetPosition = pMyPosition; if(cShotLine->can_calculate_x()) pTargetPosition.x = (float)cShotLine->x(pTargetPosition.y); // speed if(abs(vPuckVelocity.y) > fStopped) { fTimeForThePuckToCome = (pPuckFuturePosition.y - pPuckPosition.y) / vPuckVelocity.y; fTimeForThePuckToCome = abs(fTimeForThePuckToCome); fTimeForThePuckToCome -= 2.0; // state change frames if(fTimeForThePuckToCome < 0.0) { fCalculatedSpeed = cLevel.SpeedForShooting; } else { fDistanceToTarget = (pTargetPosition.x - pMyPosition.x) * (pTargetPosition.x - pMyPosition.x); fDistanceToTarget += (pTargetPosition.y - pMyPosition.y) * (pTargetPosition.y - pMyPosition.y); fDistanceToTarget = sqrt(fDistanceToTarget); fCalculatedSpeed = fDistanceToTarget / fTimeForThePuckToCome; fCalculatedSpeed = min(cLevel.SpeedForShooting, fCalculatedSpeed); } } else { fCalculatedSpeed = cLevel.DefaultSpeed; } iStateStep = AH_STATE_STEP_EXECUTE; break; case AH_STATE_STEP_EXECUTE: fSpeed = fCalculatedSpeed; if(targetPositionReached() || // ready for the shot pPuckPosition.y <= pMyPosition.y || // the puck has escaped pPuckPosition.y > (AH_TABLE_HEIGHT / 2) || // the puck is out of my zone abs(vPuckVelocity.y) < fStopped) // the puck is stopped { iStateStep = AH_STATE_STEP_EXIT; } break; case AH_STATE_STEP_EXIT: if(pPuckPosition.y > pMyPosition.y) selectState(AH_STATE_SHOOT_TO_GOAL); else selectState(AH_STATE_NOTHING); break; default: break; } }
AHPoint AHAI::update() { // table positions --> player positions if(iPlayer == 1) { pMyPosition = cGame->getTablePositionPlayer1(); pMyPosition.y = (AH_TABLE_HEIGHT / 2) - pMyPosition.y; pOpponentPosition = cGame->getTablePositionPlayer2(); pOpponentPosition.y = AH_TABLE_HEIGHT - ((AH_TABLE_HEIGHT / 2) + pOpponentPosition.y); pPuckPosition = cGame->getTablePositionPuck(); pPuckPosition.y -= AH_TABLE_HEIGHT / 2; pPuckPosition.y = -pPuckPosition.y; vPuckVelocity = cGame->getVelocityPuck(); vPuckVelocity.y = -vPuckVelocity.y; } else { pMyPosition = cGame->getTablePositionPlayer2(); pMyPosition.x = -pMyPosition.x; pMyPosition.y = pMyPosition.y + (AH_TABLE_HEIGHT / 2); pOpponentPosition = cGame->getTablePositionPlayer1(); pOpponentPosition.x = -pOpponentPosition.x; pOpponentPosition.y = AH_TABLE_HEIGHT - ((AH_TABLE_HEIGHT / 2) - pOpponentPosition.y); pPuckPosition = cGame->getTablePositionPuck(); pPuckPosition.x = -pPuckPosition.x; pPuckPosition.y += AH_TABLE_HEIGHT / 2; vPuckVelocity = cGame->getVelocityPuck(); vPuckVelocity.x = -vPuckVelocity.x; } if(cGame->checkEvent() == AH_EVENT_GOAL_P1 || cGame->checkEvent() == AH_EVENT_GOAL_P2) { selectState(AH_STATE_NOTHING); pShotPoint = pMyPosition; return myPointToTable(pMyPosition); } // default speed fSpeed = cLevel.DefaultSpeed; // state execution ++iStateTime; // timeout if(iState == AH_STATE_NOTHING && iStateTime > 200) selectState(AH_STATE_GO_TO_PUCK); switch(iState) { case AH_STATE_NOTHING: executeNothing(); break; case AH_STATE_GO_TO_PUCK: executeGoToPuck(); break; case AH_STATE_BE_ALERT: executeBeAlert(); break; case AH_STATE_GO_TO_BACK: executeGoToBack(); break; case AH_STATE_AVOID_GOAL: executeAvoidGoal(); break; case AH_STATE_CLEAR_PUCK: executeClearPuck(); break; case AH_STATE_SHOOT_TO_CLEAR: executeShootToClear(); break; case AH_STATE_PREPARE_SHOOT: executePrepareShoot(); break; case AH_STATE_SHOOT_TO_GOAL: executeShootToGoal(); break; default: break; } // go to the target position return myPointToTable(go()); }
void AHAI::chooseNewState() { // PUCK IN MY ZONE if(pPuckPosition.y <= (AH_TABLE_HEIGHT / 2)) { // high priority: if the puck is going to enter into my goal, I clear it if(pPuckPosition.y < fNearBackBorder && abs(pPuckPosition.x) < (AH_TABLE_WIDTH / 8) && vPuckVelocity.y < 0.0) { selectState(AH_STATE_CLEAR_PUCK); } // puck is stopped or almost else if(abs(vPuckVelocity.x) < fStopped && abs(vPuckVelocity.y) < fStopped) { // there is enough space to shoot if(pPuckPosition.y > fNearBackBorder && (pPuckPosition.y - pMyPosition.y) > AH_MALLET_RADIUS) { selectState(AH_STATE_PREPARE_SHOOT); } // there's not enough space to shoot else { if(pMyPosition.y > fNearBackBorder) selectState(AH_STATE_GO_TO_BACK); } } // puck is going towards the opponent else if(vPuckVelocity.y >= 0.0) { // low speed if(vPuckVelocity.y < fLowSpeed && abs(pPuckPosition.x) < (AH_TABLE_WIDTH / 2 - fNearSideBorder)) { selectState(AH_STATE_PREPARE_SHOOT); } // normal or high speed else { selectState(AH_STATE_BE_ALERT); } } // puck is coming towards my goal else if(vPuckVelocity.y < 0.0) { // high speed if(abs(vPuckVelocity.y) > cLevel.AttackThresholdSpeed) { selectState(AH_STATE_AVOID_GOAL); } // normal or low speed else if(abs(pPuckPosition.x) < (AH_TABLE_WIDTH / 2 - fNearSideBorder) && (pPuckPosition.y - pMyPosition.y) > fHoleToShoot) { selectState(AH_STATE_PREPARE_SHOOT); } } } // PUCK OUT OF MY ZONE else { // puck is stopped or going towards the opponent if(vPuckVelocity.y >= 0.0) selectState(AH_STATE_BE_ALERT); // puck is coming to me else { // high speed if(abs(vPuckVelocity.y) > fHighSpeed) selectState(AH_STATE_AVOID_GOAL); // low speed else selectState(AH_STATE_BE_ALERT); } } }