int ActorStateMachine::AttackEnemy(float enemyPos[3], SHOT_CODE *shot_code){ if (shot_code != NULL){ *shot_code = FALSE; } // the return value is the attack power FnActor actor; actor.Object(this->character); float attackerPos[3], attackerDir[3]; actor.GetWorldPosition(attackerPos); actor.GetWorldDirection(attackerDir,NULL); float frame = actor.QueryCurrentFrame(0); float dist = 0.0; for (int i = 0;i< 3;i++){ dist += (attackerPos[i] - enemyPos[i]) * (attackerPos[i] - enemyPos[i]); } //sprintf(debug, "%s dist = %lf\n",debug,dist); if ( dist >= ROBOT_ATTACKRANGE ){ return 0; // no attack power } float cosine,dotProduct; //float v[3]; dotProduct = 0.0; for (int i = 0;i< 3;i++){ dotProduct += (enemyPos[i] - attackerPos[i]) * attackerDir[i]; } float length = 0.0; for (int i = 0;i< 3;i++){ length += (enemyPos[i] - attackerPos[i])* (enemyPos[i] - attackerPos[i]); } cosine = dotProduct / sqrt(length); //sprintf(debug, "%s cosine = %lf\n",debug,cosine); if (this->attackKeyQueue[currentAttackIndex] == HEAVY_ATT || currentAttackIndex == MAXATTACK -1){ *shot_code = BIG_SHOT; }else { *shot_code = SMALL_SHOT; } if (this->currentAttackIndex == 0){ if (cosine > 0.8){ // normal or heavy attack, only attack the front side enemy //sprintf(debug, "%s attack power = %d\n",debug,1); return 1; } }else if (this->currentAttackIndex <= 3){ if (cosine >= 0.0){ //sprintf(debug, "%s attack power = %d\n",debug,2); return 3; } } return 0; }
int ActorStateMachine::ChangeState(ActorState s, BOOL forceSet){ if (forceSet == FALSE && this->state == s){ return 0;// keep the past action play }else{ this->state = s; } if (s == STATEIDLE || s == STATERUN || s == STATEDAMAGE || s == STATEDIE ||s == STATEGUARD){ if (s == STATEIDLE){ this->SetNewAction("CombatIdle"); }else if (s == STATERUN){ this->SetNewAction("Run"); }else if (s == STATEDAMAGE){ FnActor actor; actor.Object(this->character); //actor.MoveForward(-MOVE_LENGTH,TRUE, FALSE, 0.0, TRUE); //this->SetNewAction("LightDamage"); this->currentAttackIndex = 0; this->lastAttackIndex = 0; this->SetNewAction("HeavyDamage"); }else if (s == STATEDIE){ this->SetNewAction("Die"); }else if (s == STATEGUARD){ this->SetNewAction("Guard"); } }else if (s == STATEATTACK){ // Serial attack start; this->startAttack = TRUE; }else if (s == STATEVANISH){ FnWorld gw; gw.Object(gID); gw.SetTexturePath("Data\\FXs\\Textures"); gw.SetObjectPath("Data\\FXs\\Models"); float pos[3]; FnActor actor; actor.Object(this->character); actor.GetWorldPosition(pos); fxDie = new eF3DFX(sID); fxDie->SetWorkPath("Data\\FXs"); BOOL beOK = fxDie->Load("dust3"); eF3DBaseFX *fx; int i, numFX = fxDie->NumberFXs(); for (i = 0; i < numFX; i++) { fx = fxDie->GetFX(i); fx->InitPosition(pos); } } return 0; }
void ActorStateMachine::TakeDamage(int damage, SHOT_CODE shot_code, float *attackerPos ){ FnActor actor; actor.Object(character); float pos[3]; float dir[3]; actor.GetWorldPosition(pos); actor.GetWorldDirection(dir, NULL); if ( shot_code != STUCK_SHOT && attackerPos !=NULL){ float newDir[3]; newDir[0] = attackerPos[0] - pos[0]; newDir[1] = attackerPos[1] - pos[1]; newDir[2] = 0.0f; actor.SetWorldDirection(newDir,NULL); if (shot_code == BIG_SHOT){ actor.MoveForward(-OUTSHOT_DIS,TRUE, FALSE, 0.0, TRUE); //sprintf(debug, "%s OUTSHOT_DIS\n", debug); }else if (shot_code == SMALL_SHOT){ actor.MoveForward(-SMALL_OUTSHOT_DIS,TRUE, FALSE, 0.0, TRUE); //sprintf(debug, "%s SMALL_OUTSHOT_DIS\n", debug); } actor.SetWorldDirection(dir,NULL); } if (this->state == STATEGUARD){ FnAudio audio; audio.Object(audioG); audio.Play(ONCE); return; // no damage }else{ FnAudio audio; audio.Object(audioD); //if (audio.IsPlaying() == FALSE){ audio.Play(ONCE); //} } this->life -= damage; //sprintf(debug, "%s life=%d\n", debug, this->life); if (this->life <= 0) { this->ChangeState(STATEDIE, TRUE); }else { this->ChangeState(STATEDAMAGE, TRUE); } this->UpdateLifeBillboard(); }
void AIControl::moveTowardLyubu() { for (int i = 0;i< this->npcStateMachineList.size(); i++){ if (npcStateMachineList[i]->CanBeControl() == FALSE){ continue; } int npcId = npcStateMachineList[i]->character; FnActor lyubu; FnActor npc; lyubu.Object(this->lyubuId); npc.Object(npcId); float lyubuPos[3]; float npcPos[3]; lyubu.GetWorldPosition(lyubuPos); npc.GetWorldPosition(npcPos); float distance; distance = sqrt((npcPos[0] - lyubuPos[0]) * (npcPos[0] - lyubuPos[0]) + (npcPos[1] - lyubuPos[1]) * (npcPos[1] - lyubuPos[1])); //+ (npcPos[2] - lyubuPos[2]) * (npcPos[2] - lyubuPos[2])); //sprintf(debug, "%s x = %f y = %f z = %f\n",debug, lyubuPos[0], lyubuPos[1], lyubuPos[2]); if (distance > ATTACK_DISTANCE && ((npcStateMachineList[i] == this->bossStateMachine && distance < BOSS_KEEP_TRACK_DISTANCE) || distance < KEEP_TRACK_DISTANCE)) { //turn toward lyubu float newFDir[3], normalize, offset; if (npcStateMachineList[i] != this->bossStateMachine) { srand ( time(NULL) + i); offset = rand() % NPC_MOVE_OFFSET + 1; lyubuPos[0] += offset; lyubuPos[1] += offset; lyubuPos[2] += offset; } newFDir[0] = lyubuPos[0] - npcPos[0]; newFDir[1] = lyubuPos[1] - npcPos[1]; newFDir[2] = lyubuPos[2] - npcPos[2]; normalize = sqrt(newFDir[0] * newFDir[0] + newFDir[1] * newFDir[1] + newFDir[2] * newFDir[2]); newFDir[0] /= normalize; newFDir[1] /= normalize; newFDir[2] /= normalize; float npcFDir[3], npcUDir[3]; npc.GetWorldDirection(npcFDir, npcUDir); npc.SetWorldDirection(newFDir, npcUDir); //move forward int block = npc.MoveForward(MOVE_DISTANCE,TRUE, FALSE, 0.0, TRUE); if (block) { //sprintf(debug, "%s npc is blocked\n",debug); while (npc.MoveForward(MOVE_DISTANCE,TRUE, FALSE, 0.0, TRUE)) { sprintf(debug, "%s npc turn right\n",debug); npc.TurnRight(300); npc.MoveForward(MOVE_DISTANCE,TRUE, FALSE, 0.0, TRUE); } } npcStateMachineList[i]->ChangeState(STATERUN, FALSE); } else if (distance <= ATTACK_DISTANCE) { //before attack, turn toward lyubu float newFDir[3], normalize, offset; newFDir[0] = lyubuPos[0] - npcPos[0]; newFDir[1] = lyubuPos[1] - npcPos[1]; newFDir[2] = lyubuPos[2] - npcPos[2]; normalize = sqrt(newFDir[0] * newFDir[0] + newFDir[1] * newFDir[1] + newFDir[2] * newFDir[2]); newFDir[0] /= normalize; newFDir[1] /= normalize; newFDir[2] /= normalize; float npcFDir[3], npcUDir[3]; npc.GetWorldDirection(npcFDir, npcUDir); npc.SetWorldDirection(newFDir, npcUDir); //sprintf(debug, "%s distance = %f\n",debug,distance); srand ( time(NULL) + i); float rate = rand() % 100; if (this->npcStateMachineList[i] == this->bossStateMachine){ if (rate > GUARD_RATE ) { npcStateMachineList[i]->AppendAttackCode(NORMAL_ATT); npcStateMachineList[i]->AppendAttackCode(NORMAL_ATT); npcStateMachineList[i]->AppendAttackCode(HEAVY_ATT); }else{ npcStateMachineList[i]->CharacterSetGuard(); } }else { if (rate > GUARD_RATE * 2) { npcStateMachineList[i]->AppendAttackCode(NORMAL_ATT); } else{ npcStateMachineList[i]->CharacterSetIdle(); } } } else { npcStateMachineList[i]->CharacterSetIdle(); } } }