BOOL ActorStateMachine::initLife(){
	this->life = (int) MAX_LIFE;

	FnScene scene;
	scene.Object(sID);
	bloodID = scene.CreateObject(ROOT);
	FnObject blood;
	blood.Object(bloodID);
	//FnBillBoard blood;
	//blood.Object(bloodID, 0);
	FnActor actor;
	actor.Object(this->character);
	OBJECTid baseID = actor.GetBaseObject();

	float pos[3], size[2], color[3];
	pos[0] = 0.0f;
	pos[1] = 0.0f;
	pos[2] = 80.0f;
	size[0] = 50.0f;
	size[1] = 2.0f;
	color[0] = 1.0f; color[1] = color[2] = 0.0f;
	blood.Billboard(pos, size, NULL, 0, color);
	blood.SetParent(baseID);
	return TRUE;
}
BOOL ActorStateMachine::initActionIDMap(char *ActionFilename){
	FILE *fp = fopen(ActionFilename,"r");
	if (fp == NULL){
		sprintf(debug, "%s ActionFilename failed: %s\n", debug, ActionFilename);
		return FALSE;
	}
	char systemName[100];
	char designName[100];
	int ret;

	FnActor actor;
	actor.Object(this->character);
	ACTIONid aID;
	while (!feof(fp)){
		ret = fscanf(fp, "%s %s", systemName, designName);
		if (ret != 2){
			sprintf(debug, "%s fscanf actionID failed\n", debug, systemName, designName);
			return FALSE;
		}
		aID = actor.GetBodyAction(NULL,designName);
		if (aID == FAILED_ID){
			sprintf(debug, "%s init actionID %s %s failed\n", debug, systemName, designName);
			continue;
		}
		string actionName(systemName);
		this->ActionIDMap[actionName] = aID;
	}
	return TRUE;
}
BOOL ActorStateMachine::UpdateEffectiveAttack(){
	FnActor actor;
	actor.Object(this->character);
	float frame = actor.QueryCurrentFrame(0);
	//sprintf(debug, "%s frame:%lf\n", debug, frame );
	if (frame > 15.0){
		this->effectiveAttack =	TRUE;
	}
	/*
	if (this->attackKeyQueue[currentAttackIndex] == ULTIMATE_ATT){
		if (frame > 20.0){
			this->newAttack = TRUE;
			this->effectiveAttack =	TRUE;
		}
	}else if (this->attackKeyQueue[currentAttackIndex] == HEAVY_ATT){
		if (frame > 20.0){
			this->effectiveAttack =	TRUE;
		}
	}else if (this->currentAttackIndex > 0){
		if (frame > 10.0){
			this->effectiveAttack =	TRUE;
		}
	}*/
	return FALSE;
}
BOOL ActorStateMachine::PlayAttackAction(int skip){
	FnActor actor;
	actor.Object(this->character);
	//ACTIONid actionID;

	char attackName[20] = "\0";
	if (this->startAttack == TRUE){// first attack
		this->lastAttackFrame = 0.0f;
		this->startAttack = FALSE; // reset
		//sprintf(debug, "%sstart attack\n", debug);
		if (this->attackKeyQueue[currentAttackIndex] == NORMAL_ATT ){
			sprintf(attackName, "N%d", currentAttackIndex + 1); 
			// attackName should be "N1"
		}else if (this->attackKeyQueue[currentAttackIndex] == HEAVY_ATT){
			sprintf(attackName, "H%d", currentAttackIndex + 1); 
			// attackName should be "H1"
		}
		string systemName(attackName);
		this->SetNewAction(systemName);
		// it performs the new attack
		// set the flag here and BattleRoom will check it.
		this->newAttack = TRUE;	
	}else{
		// the attack name should be refine from reading the file
		BOOL ret = actor.Play(0,ONCE, (float)skip, TRUE,TRUE);
		this->UpdateEffectiveAttack();
		if (ret == FALSE){
			this->lastAttackFrame = 0.0f;
			// play the next one
			this->effectiveAttack = FALSE;
			currentAttackIndex++;
			if (currentAttackIndex >= lastAttackIndex){
				// finish attacking
				this->ChangeState(STATEIDLE);// should be change into combatidle;
				this->attackDisable = FALSE;
				currentAttackIndex = 0;
				lastAttackIndex = 0;
				return FALSE;
			}else if (this->attackKeyQueue[currentAttackIndex] == NORMAL_ATT){
				// get the next one attacking pos
				sprintf(attackName, "N%d", currentAttackIndex + 1);
			}else if (this->attackKeyQueue[currentAttackIndex] == HEAVY_ATT){
				// get the next one attacking pos
				sprintf(attackName, "H%d", currentAttackIndex);
			}else{
				sprintf(debug, "%s next Attack fail condition\n", debug);
				return FALSE;
			}
			string systemName(attackName);
			this->SetNewAction(systemName);
			// it performs the new attack
			// set the flag here and BattleRoom will check it and set the flag to FALSE after checking.
			this->newAttack = TRUE;	
		}
	}
	//sprintf(debug, "%s lastAttack%d\n", debug, lastAttackIndex );
	return TRUE;
}
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;
}
BOOL ActorStateMachine::SetNewAction(string systemName){
	ACTIONid actionID = this->ActionIDMap[systemName];
	
	FnActor actor;
	actor.Object(this->character);
	if (actor.MakeCurrentAction(0,NULL,actionID) == FAILED_ID){
		sprintf(debug, "%s make current action %s fail\n", debug, systemName.c_str());
		return FALSE;
	}else{
		//sprintf(debug, "%s %s make successful\n", debug, systemName.c_str());
	}
	
	if (actor.Play(0,START, 0.0, FALSE,TRUE) == FALSE){
		sprintf(debug, "%s %s play action failed\n", debug, systemName.c_str());
		return FALSE;
	}else{
		//sprintf(debug, "%s %s play successful\n", debug, systemName.c_str());
	}
	return TRUE;
}
void OurActor::ourPlayAction()
{
	FnActor actor;
	actor.Object( aID );
	
	if(::actorChangePose( aID, current_OurAction->actID ))
	{
		current_frame = 0;
	}
	//it's a loop action?
	if( current_OurAction->type == Action_type::ACTION_IDLE() ||
		current_OurAction->type == Action_type::ACTION_WALK() )
	{
		bool notOver;
		notOver = actor.Play(0, ONCE, current_OurAction->play_speed, false, true);
		if( notOver )
			current_frame += current_OurAction->play_speed;
		else
		{
			current_frame = 0;
			actor.MakeCurrentAction(0, NULL, current_OurAction->actID);
		}
	}
	else
	{
		bool notOver;
		notOver = actor.Play(0, ONCE, current_OurAction->play_speed, FALSE, TRUE);
		if( !notOver )
		{
			if( current_OurAction->type.value != Action_type::ACTION_DIE() )
				current_OurAction = ourIdleAction;
		}
		else
			current_frame += current_OurAction->play_speed;
	}

	playActionAudio();
	playActionFx();
}
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();
}
BOOL ActorStateMachine::PlayAction(int skip){
	FnActor actor;
	actor.Object(this->character);
	if (this->CanBeControl() == TRUE){
		actor.Play(0,LOOP, (float)skip, FALSE,TRUE);
	}else if (this->state == STATEATTACK){
		this->PlayAttackAction(skip);
	}else if (this->state == STATEDAMAGE){
		BOOL ret = actor.Play(0,ONCE, (float)skip, TRUE,TRUE);
		if (ret == FALSE){
			//sprintf(debug, "%s damage end\n",debug);
			this->ChangeState(STATEIDLE);
		}
	}else if (this->state == STATEDIE){
		BOOL ret = actor.Play(0,ONCE, (float)skip, TRUE,TRUE);
		
		if (ret == FALSE){
			sprintf(debug, "%s character die\n",debug);
			this->ChangeState(STATEVANISH);
		}
	}else if (this->state == STATEVANISH){
		if (this->fxDie != NULL) {
			BOOL beOK = this->fxDie->Play((float) skip);
			if (!beOK) {
				//fxDie->Reset();  // make it from the starting position and play it again
				// should delete the character
				delete fxDie;
				this->fxDie = NULL;
				FnScene scene;
				scene.Object(sID);
				scene.DeleteActor(this->character);
			}
		}
	}
	return TRUE;
}
void OurEnemyActor::walkingAgent(ACTORid enemyID, EnemyTeam **team, int teamCount)
{
    float origin[3] = {0,0,0};

    //敵人位置
    float enemyPos[3];
    FnActor enemy;
    enemy.Object(enemyID);
    enemy.GetPosition(enemyPos);
    //自己位置
    float selfPos[3];
    FnActor self;
    self.Object(aID);
    self.GetPosition(selfPos);
    float selfFDir[3], selfUDir[3];
    actor.GetDirection(selfFDir,selfUDir);

    float distance = twoPointDis(selfPos, enemyPos);

    float flockingPos[3];
    flockingPosition(flockingPos, selfPos, enemyPos, team, teamCount);
    float flockingDis = twoPointDis(flockingPos, origin);

    float newPos[3];
    newPos[0] = flockingPos[0]+selfPos[0];
    newPos[1] = flockingPos[1]+selfPos[1];
    newPos[2] = flockingPos[2]+selfPos[2];

    //先轉向再移動,再轉回來
    actorFaceTo(aID, newPos[0], newPos[1], newPos[2]);
    actor.MoveForward(flockingDis,true);
    //actor.SetWorldDirection(selfFDir,selfUDir);
    actorFaceTo(aID, enemyPos[0], enemyPos[1], enemyPos[2]);
    //actor.SetPosition(newPos);

    if(distance < AWARE_DISTANCE)
    {

        if(distance <= COMBAT_DISTANCE)
        {
            sendAction(ourCombatIdleAction);
        }
        else
        {
            sendAction(ourRunAction);
            actor.MoveForward(SPEED, TRUE, FALSE, 0.0f, TRUE);
        }
    }
    else
    {
        sendAction(ourIdleAction);
    }
}
Beispiel #12
0
void FuCShadowModify::fillActorObject( FnActor& actor )
{

	for ( int i = 0; i < actor.SkinNumber(); i++) 
	{
		m_objVec.push_back(  actor.GetSkin(i) );
	}

	for ( int i = 0; i < actor.AttachmentNumber(); i++) 
	{
		m_objVec.push_back(  actor.GetAttachment(i) );
	}

	int numPart = actor.SkeletonObjectNumber();
	for ( int i = 0; i < numPart; i++) 
	{
		if (actor.IsGeometry(i)) 
		{
			m_objVec.push_back(  actor.GetSkeletonObject(i) );
		}
	}
}
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();
		}
	}
}
//計算在這個群體中適當的位置
void OurEnemyActor::flockingPosition(float *newPos, float *selfPos, float *targetPos, EnemyTeam **team, int teamCount)
{
    float attraction[3] = {0,0,0};

    //共有多少隊友離你夠近,會影響到調整距離
    int member_num = 0;
    for(int i = 0; i < teamCount; i++)
    {
        //驚動狀態的隊伍才考慮
        //if(team[i]->aware)
        {
            //separation & cohesion
            for(int mi = 0; mi < team[i]->member_num; mi++)
            {
                //只檢查沒掛的人,且不要把自己算進去
                if(team[i]->members[mi]->HP > 0 && team[i]->members[mi]->aID != this->aID)
                {
                    float friPos[3];
                    FnActor fri;
                    fri.Object(team[i]->members[mi]->aID);
                    fri.GetPosition(friPos);

                    float dis = sqrt(pow(friPos[0]-selfPos[0],2)
                                     +pow(friPos[1]-selfPos[1],2)
                                     +pow(friPos[2]-selfPos[2],2));

                    if(dis < OVERLAP_DISTANCE
                            ||(team[i] == this->team && dis < CROWDED_DISTANCE))
                    {
                        //separation
                        if(dis == 0)
                        {
                            attraction[0] += 1;
                            attraction[1] += 1;
                        }
                        else
                        {
                            attraction[0] += -(friPos[0]-selfPos[0])*pow(1-dis/CROWDED_DISTANCE,2);
                            attraction[1] += -(friPos[1]-selfPos[1])*pow(1-dis/CROWDED_DISTANCE,2);
                            attraction[2] += -(friPos[2]-selfPos[2])*pow(1-dis/CROWDED_DISTANCE,2);
                        }
                    }
                    else if(team[i] == this->team)
                    {
                        //cohesion
                        attraction[0] += (friPos[0]-selfPos[0])*pow((dis-CROWDED_DISTANCE)/(AWARE_DISTANCE-CROWDED_DISTANCE),2);
                        attraction[1] += (friPos[1]-selfPos[1])*pow((dis-CROWDED_DISTANCE)/(AWARE_DISTANCE-CROWDED_DISTANCE),2);
                        attraction[2] += (friPos[2]-selfPos[2])*pow((dis-CROWDED_DISTANCE)/(AWARE_DISTANCE-CROWDED_DISTANCE),2);
                    }
                    member_num++;
                }
            }
        }
    }

    //若與呂布重疊就分離
    float dis = sqrt(pow(targetPos[0]-selfPos[0],2)
                     +pow(targetPos[1]-selfPos[1],2)
                     +pow(targetPos[2]-selfPos[2],2));

    if(dis < OVERLAP_DISTANCE)
    {
        //separation
        if(dis == 0)
        {
            attraction[0] += 1;
            attraction[1] += 1;
        }
        else
        {
            attraction[0] += -(targetPos[0]-selfPos[0])*pow(1-dis/CROWDED_DISTANCE,2);
            attraction[1] += -(targetPos[1]-selfPos[1])*pow(1-dis/CROWDED_DISTANCE,2);
            attraction[2] += -(targetPos[2]-selfPos[2])*pow(1-dis/CROWDED_DISTANCE,2);
        }
        member_num++;
    }

    if(member_num > 0)
    {
        attraction[0] /= member_num;
        attraction[1] /= member_num;
        attraction[2] /= member_num;
    }

    /*
    //cohesion
    float sum[3] = {0,0,0};
    for(int i = 0; i < member_num; i++)
    {
    	if(team->members[i]->aID != aID)
    	{
    		float friPos[3];
    		FnActor fri;
    		fri.Object(team->members[i]->aID);
    		fri.GetPosition(friPos);

    		sum[0] += friPos[0];
    		sum[1] += friPos[1];
    		sum[2] += friPos[2];
    	}
    }
    float avg[3] = {sum[0]/member_num,
    				sum[1]/member_num,
    				sum[2]/member_num};
    float avgDis = sqrt((avg[0]-selfPos[0])*(avg[0]-selfPos[0])+
    					(avg[1]-selfPos[1])*(avg[1]-selfPos[1])+
    					(avg[2]-selfPos[2])*(avg[2]-selfPos[2]));

    float cohesion[3] = {(avg[0]-selfPos[0])*pow((avgDis-crowdedDistance)/(awareDistance-crowdedDistance),2),
    					 (avg[1]-selfPos[1])*pow((avgDis-crowdedDistance)/(awareDistance-crowdedDistance),2),
    					 (avg[2]-selfPos[2])*pow((avgDis-crowdedDistance)/(awareDistance-crowdedDistance),2)};
    					 */

    //align
    float align[3] = {0,0,0};
    /*
    float sumV[3] = {0,0,0};
    for(int i = 0; i < member_num; i++)
    {
    	if(team->members[i]->aID != aID && team->members[i]->HP > 0)
    	{
    		float friPos[3];
    		FnActor fri;
    		fri.Object(team->members[i]->aID);
    		fri.GetPosition(friPos);

    		float vx = (targetPos[0]-friPos[0]);
    		float vy = (targetPos[1]-friPos[1]);
    		float vz = (targetPos[2]-friPos[2]);
    		float dis = sqrt(sumV[0]*sumV[0]+sumV[1]*sumV[1]+sumV[2]*sumV[2]);
    		if(dis != 0)
    		{
    			sumV[0] += vx/dis;
    			sumV[1] += vy/dis;
    			sumV[2] += vz/dis;
    		}
    	}
    }
    if(member_num > 0)
    {
    	align[0] = sumV[0]/member_num;
    	align[1] = sumV[1]/member_num;
    	align[1] = sumV[2]/member_num;
    }
    */
    newPos[0] = attraction[0]+align[0];
    newPos[1] = attraction[1]+align[1];
    newPos[2] = attraction[2]+align[2];
}