예제 #1
0
파일: dphil_footman.c 프로젝트: T0mi/PaPP
void Philosopher(int phil) {
    Think(phil);

    int first = phil;
    int second = (phil+1)%PHIL_COUNT;


    pthread_mutex_lock(&footman_mutex);
    while (footman_count == (PHIL_COUNT-1)) pthread_cond_wait(&footman_cond, &footman_mutex);
    footman_count++;
    pthread_mutex_unlock(&footman_mutex);

    pthread_mutex_lock(&chopstick_mutexes[first]);
    pthread_mutex_lock(&chopstick_mutexes[second]);

    Eat(phil);

    pthread_mutex_unlock(&chopstick_mutexes[first]);
    pthread_mutex_unlock(&chopstick_mutexes[second]);

    pthread_mutex_lock(&footman_mutex);
    footman_count--;
    pthread_cond_signal(&footman_cond);
    pthread_mutex_unlock(&footman_mutex);
}
예제 #2
0
 void Predator::DoRareAction() {
     const Xyz coords[] = {
         Xyz(X()-1, Y(), Z()),
         Xyz(X()+1, Y(), Z()),
         Xyz(X(), Y()-1, Z()),
         Xyz(X(), Y()+1, Z()),
         Xyz(X(), Y(), Z()-1)
     };
     World * const world = GetWorld();
     for (const Xyz xyz : coords) {
         if ( not world->InBounds(xyz.X(), xyz.Y()) ) {
             continue;
         }
         Block * const block = world->GetBlock(xyz.X(), xyz.Y(), xyz.Z());
         if ( Attractive(block->Sub()) ) {
             block->ReceiveSignal(tr("Predator bites you!"));
             world->Damage(xyz.X(), xyz.Y(), xyz.Z(),
                 DamageLevel(), DamageKind());
             Eat(static_cast<subs>(block->Sub()));
         }
     }
     if ( SECONDS_IN_DAY/4 > Satiation() ) {
         EatGrass();
     }
     Animal::DoRareAction();
 }
예제 #3
0
파일: dp.c 프로젝트: knram06/cse511_proj1
void *action(void* id)
{
	int tid = (int)id;
	while(1)
	{
		printf("Philosopher #%d is going to eat.\n", tid);
		Eat(tid, model_eat);
		printf("Philosopher #%d 's eating is done.\n", tid);
		Think(tid, model_think);
	}
	return NULL;
}
예제 #4
0
 void Animal::EatGrass() {
     for (int x=X()-1; x<=X()+1; ++x)
     for (int y=Y()-1; y<=Y()+1; ++y) {
         if ( world->InBounds(x, y) &&
                 GREENERY == world->GetBlock(x, y, Z())->Sub() )
         {
             TryDestroy(x, y, Z());
             Eat(GREENERY);
             return;
         }
     }
 }
예제 #5
0
파일: Animal.cpp 프로젝트: hLachev/God
void Animal::DoAction(std::unique_ptr<Planet>& p,Entity& otherentity)
{
	int number = RandomGenerator::GetRGen()->RandomNumber(5);
	switch(number)
	{
		case 1: Attack(otherentity); break;
		case 2: Sleep(); break;
		case 3: SearchForFood(); break;
		case 4: Eat(); break;
		case 5: Mate(p); break;
	};		 
}
예제 #6
0
파일: main.c 프로젝트: 12330072/C-learning
void Move( char key )
{
    int x, y;
    int pos = 0;
    int i;
    int d[4][2] = {
        {0,-1},
        {-1,0},
        {0,1},
        {1,0},
    };
    switch ( key )
    {
        case 'w':
            pos = 0;
            break;
        case 'a':
            pos = 1;
            break;
        case 's':
            pos = 2;
            break;
        case 'd':
            pos = 3;
            break;
        default:
            break;
    }
    x = snake[len-1][0];
    y = snake[len-1][1];
    for ( i = len-1; i > 0; --i )
    {
        snake[i][0] = snake[i-1][0];
        snake[i][1] = snake[i-1][1];
    }
    snake[0][0] += d[pos][0];
    snake[0][1] += d[pos][1];
    if ( Eat() )
    {
        snake[len][0] = x;
        snake[len][1] = y;
        ++len;
        CreatFood();
    }
    else if ( Die() )
    {
        gameOver = 1;
    }
}
예제 #7
0
파일: westfall.cpp 프로젝트: BoThay/ArkCORE
        void UpdateAI(const uint32 diff)
        {
            if (Miam < diff)
            {
                if (Creature* stew = me->FindNearestCreature(STEW, 10.0f, true))
                {
                    if (me->HasAura(SPELL_FULL_BELLY) && count == 0)
                        return;

                    switch (count)
                    {
                        case 0:
                        {
                            me->RemoveStandFlags(UNIT_STAND_STATE_SLEEP);
                            me->SetStandFlags(UNIT_STAND_STATE_STAND);
                            Miam = 1000;
                            count++;
                            break;
                        }
                        case 1:
                        {
                            Eat();
                            Miam = 2000;
                            count++;
                            break;
                        }
                        case 2:
                        {
                            if (Unit* player = me->GetPlayer(*stew, stew->GetUInt64Value(UNIT_FIELD_SUMMONEDBY)))
                                player->ToPlayer()->KilledMonsterCredit(42617, NULL);
                                Miam = 25000;
                                count++;
                                break;
                        }
                        default:
                        break;
                    }
                }
                else Miam = 3000;

                if (count == 3)
                    Reset();
            }
            else Miam -= diff;
        }
예제 #8
0
void* PhilosopherTask(void* id){
	long long philosopher_id = (long long)id;
	long long resourse1_id = (long long)id;
	long long resourse2_id = ((long long)id + 1) % PHILOSOPHERS_COUNT;

	while(true) {
		Think(philosopher_id);
		if (pthread_mutex_trylock(&resourses[resourse1_id]) != 0){
			continue;
		}
		if (pthread_mutex_trylock(&resourses[resourse2_id]) != 0){
			pthread_mutex_unlock(&resourses[resourse1_id]);
			continue;
		}
		Eat(philosopher_id);
		pthread_mutex_unlock(&resourses[resourse2_id]);
		pthread_mutex_unlock(&resourses[resourse1_id]);
	}
}
예제 #9
0
void Rabbit::Routine(int generation)
{
	if (lastGenActivity != -1 && lastGenActivity == generation)
		return;
	lastGenActivity = generation;

	prevLoc = GetLocation();

	Move();
	if (!Evade()) // eat and reproduce if it didn't have to evade
	{
		Eat();
		Reproduce<Rabbit>();
	}
	Grow();
	Die();

	if (age >= ageToDie || metabolism.HasStarved())
		throw std::runtime_error("zombie animal");
}
예제 #10
0
파일: code.c 프로젝트: nitwcoding/problem
void philo(void * arg)
{
 
 int  back;
 int  front;
 int  tmp;
 int  id=*((int*)arg);
 phil_init(id, &back, &front);


 while(1)
 {
  printf("philosopher %d thinking\n", id+1);
  sleep(rand()%6);

  if((tmp=check_If_Spoons_Are_Available(id, back, front))!=0)
   wait_for_others_to_finish(tmp, id, back, front);
  
   Eat(id);
  
  Release_Spoons(*((int*)arg), back, front);
 }
}
예제 #11
0
/// \brief  Handle for main game
/// \return If restart
bool play(){
    if(boardseed[curs]==NA){
        boardseed[curs]=Rando(RAND_MAX);
    }
    srand(boardseed[curs]);
    Clrboard(curs);
    clear();
    pthread_create (&TShow, &AThread, t_Show, NULL);
    keypad(stdscr, TRUE);
    int ch=0;
    int res=NA,lastres=NA;GetRandNums();
    pthread_cond_signal(&CBoard);
    while((ch = getch()) != KEY_F(1)){
        move(0,0);
        clrtoeol();
        pthread_mutex_lock(&MInfo);
        pthread_mutex_lock(&MScr);
        wclear(MenuWin);
        pthread_mutex_unlock(&MScr);
        memset(sinfo,0,sizeof(sinfo));
        pthread_mutex_unlock(&MInfo);
        pthread_cond_signal(&CInfo);
        lastres=res;
        pthread_mutex_lock(&MBoard);
        switch(ch)
        {
            case KEY_LEFT:case 'H':case 'h':
                res=Eat(ELEFT);GetRandNums();
                break;
            case KEY_RIGHT:case 'L':case 'l':
                res=Eat(ERIGHT);GetRandNums();
                break;
            case KEY_UP:case 'K':case 'k':
                res=Eat(EUP);GetRandNums();
                break;
            case KEY_DOWN:case 'J':case 'j':
                res=Eat(EDOWN);GetRandNums();
                break;
            case ':':
                pthread_mutex_unlock(&MBoard);
                command();
                pthread_mutex_lock(&MBoard);
                break;
            case 3:
                pthread_mutex_unlock(&MBoard);
                c_tryQuit();
                pthread_mutex_lock(&MBoard);
                break;
        }
        pthread_mutex_unlock(&MBoard);
        pthread_cond_signal (&CBoard);
        if(res==lastres&&res==0){
            bool c=die();
            pthread_cancel(TShow);
            pthread_cancel(TInfo);
            pthread_cond_signal (&CInfo);
            pthread_join(TShow, NULL);
            pthread_join(TInfo, NULL);
            wclear(BoardWin);
            wclear(MenuWin);
            delwin(BoardWin);
            delwin(MenuWin);
            BoardWin=NULL;
            MenuWin=NULL;
            return c;
        }
    }
    return false;
}
예제 #12
0
static void g_Data(dyad_Event *e) {
    FILE *fp;
    char name[20],v[10];
    int ver=c_version();
    sprintf(name,"2048.1.%X.save",ver);
    sprintf(v,"%X",ver);
    if(NULL!=strstr((char*)e->data,v)){
        if((fp=fopen(name,"w+"))) {
            fprintf(fp,"%s",e->data);
        }
        fclose(fp);
        pthread_mutex_lock(&MBoard);
        curs=1;
        c_readFromDisk(1,false);
        pthread_mutex_unlock(&MBoard);
    }else if(memcmp(e->data, "UP", 2)==0){
        pthread_mutex_lock(&MBoard);
		attack[1][attacktimes[1]++]=2;
        curs=0;
        Eat(EUP);GetRandNums();
        pthread_mutex_unlock(&MBoard);
		pthread_cond_signal(&CNet);
	}else if(memcmp(e->data, "DOWN", 4)==0){
        pthread_mutex_lock(&MBoard);
		attack[1][attacktimes[1]++]=3;
        curs=0;
        Eat(EDOWN);GetRandNums();
        pthread_mutex_unlock(&MBoard);
		pthread_cond_signal(&CNet);
	}else if(memcmp(e->data, "LEFT", 4)==0){
        pthread_mutex_lock(&MBoard);
		attack[1][attacktimes[1]++]=4;
        curs=0;
        Eat(ELEFT);GetRandNums();
        pthread_mutex_unlock(&MBoard);
		pthread_cond_signal(&CNet);
	}else if(memcmp(e->data, "RIGHT", 5)==0){
        pthread_mutex_lock(&MBoard);
		attack[1][attacktimes[1]++]=5;
        curs=0;
        Eat(ERIGHT);GetRandNums();
        pthread_mutex_unlock(&MBoard);
		pthread_cond_signal(&CNet);
	}else if(memcmp(e->data, "BOOM", 4)==0){
        pthread_mutex_lock(&MBoard);
		attack[1][attacktimes[1]++]=6;
        curs=0;
        int y,x;
		if(sscanf(e->data,"BOOM %d %d",&y,&x)==2){
			c_boom(y,x);
		}
        pthread_mutex_unlock(&MBoard);
		pthread_cond_signal(&CNet);
	}else if(memcmp(e->data, "DEL", 3)==0){
        pthread_mutex_lock(&MBoard);
		attack[1][attacktimes[1]++]=1;
        curs=0;
        int y,x;
		if(sscanf(e->data,"DEL %d %d",&y,&x)==2){
			c_del(y,x);
		}
        pthread_mutex_unlock(&MBoard);
		pthread_cond_signal(&CNet);
	}
    pthread_cond_signal(&CBoard);
}
예제 #13
0
/// \brief  The thread to print Board to screen
/// \param  arg Void
/// \return void* NULL
void* t_NetworkPlay(void* arg){
    pthread_mutex_lock(&MNetC);
    pthread_mutex_lock(&MBoard);
    curs=0;
    if(boardseed[curs]==NA){
        boardseed[curs]=Rando(RAND_MAX);
    }
    srand(boardseed[curs]);
    Clrboard(curs);
    clear();
    pthread_create (&TNetworkShow, &AThread, t_NetworkShow , NULL);
    pthread_create (&TNetworkSend, &AThread, t_NetworkSend , NULL);
    keypad(stdscr, TRUE);
    int ch=0;
    int res=NA,lastres=NA;GetRandNums();
    pthread_mutex_unlock(&MBoard);
    usleep(100000);
    pthread_cond_signal(&CNet);
    pthread_cond_signal(&CBoard);
    usleep(100000);
    pthread_cond_signal(&CNet);
    pthread_cond_signal (&CBoard);
    while((ch = getch())&&dyad_getStreamCount()>0){
        pthread_testcancel();
        move(0,0);
        clrtoeol();
        pthread_mutex_lock(&MInfo);
        pthread_mutex_lock(&MScr);
        wclear(MenuWin);
        pthread_mutex_unlock(&MScr);
        memset(sinfo,0,sizeof(sinfo));
        pthread_mutex_unlock(&MInfo);
        pthread_cond_signal(&CInfo);
        lastres=res;
        pthread_mutex_lock(&MBoard);
        curs=0;
        switch(ch)
        {
            case KEY_LEFT:case 'H':case 'h':
                res=Eat(ELEFT);GetRandNums();
                break;
            case KEY_RIGHT:case 'L':case 'l':
                res=Eat(ERIGHT);GetRandNums();
                break;
            case KEY_UP:case 'K':case 'k':
                res=Eat(EUP);GetRandNums();
                break;
            case KEY_DOWN:case 'J':case 'j':
                res=Eat(EDOWN);GetRandNums();
                break;
            case 3:case KEY_F(1):
                pthread_mutex_unlock(&MBoard);
                c_tryQuit();
                pthread_mutex_lock(&MBoard);
                break;
			case ':':
				pthread_mutex_unlock(&MBoard);
				x_netCommand();
			    pthread_mutex_lock(&MBoard);
                break;
        }
        pthread_mutex_unlock(&MBoard);
        pthread_cond_signal (&CBoard);
        pthread_cond_signal (&CNet);
        if(res==lastres&&res==0){
			if(score[0]>score[1])
				c_info("You Win!");
			else if(score[0]<score[1])
				c_info("You Lost!");
			else
				c_info("Neck and neck!");
            result=0;
            break;
        }
    }
    getch();
    dyad_end(SGaming);
    dyad_end(SServ);
    dyad_end(SClient);
    usleep(100000);
    pthread_cancel(TNetworkSend);
    pthread_cancel(TNetworkShow);
    pthread_cond_signal (&CBoard);
    pthread_cond_signal (&CNet);
    pthread_join(TNetworkSend, NULL);
    pthread_join(TNetworkShow, NULL);
    pthread_cancel(TInfo);
    pthread_cond_signal (&CInfo);
    pthread_join(TInfo, NULL);
    usleep(100000);
    wclear(BoardWin);
    wclear(MenuWin);
    delwin(BoardWin);
    delwin(MenuWin);
    BoardWin=NULL;
    MenuWin=NULL;
    pthread_mutex_unlock(&MNetC);
    pthread_mutex_destroy (&MScr);
    pthread_mutex_destroy (&MInfo);
    pthread_cond_destroy (&CInfo);
    pthread_mutex_destroy (&MBoard);
    pthread_cond_destroy (&CBoard);
    pthread_mutex_destroy (&MNet);
    pthread_mutex_destroy (&MNetC);
    pthread_cond_destroy (&CNet);
    c_forceQuit();
    return NULL;
}
예제 #14
0
bool Snake::InsertAsHead(UnitPosition unit) {
	Eat(unit);
	return true;
}
예제 #15
0
//=========================================================
// Start task - selects the correct activity and performs
// any necessary calculations to start the next task on the
// schedule. 
//=========================================================
void CBaseMonster :: StartTask ( Task_t *pTask )
{
	switch ( pTask->iTask )
	{
	case TASK_TURN_RIGHT:
		{
			float flCurrentYaw;
			
			flCurrentYaw = UTIL_AngleMod( pev->angles.y );
			pev->ideal_yaw = UTIL_AngleMod( flCurrentYaw - pTask->flData );
			SetTurnActivity();
			break;
		}
	case TASK_TURN_LEFT:
		{
			float flCurrentYaw;
			
			flCurrentYaw = UTIL_AngleMod( pev->angles.y );
			pev->ideal_yaw = UTIL_AngleMod( flCurrentYaw + pTask->flData );
			SetTurnActivity();
			break;
		}
	case TASK_REMEMBER:
		{
			Remember ( (int)pTask->flData );
			TaskComplete();
			break;
		}
	case TASK_FORGET:
		{
			Forget ( (int)pTask->flData );
			TaskComplete();
			break;
		}
	case TASK_FIND_HINTNODE:
		{
			m_iHintNode = FindHintNode();

			if ( m_iHintNode != NO_NODE )
			{
				TaskComplete();
			}
			else
			{
				TaskFail();
			}
			break;
		}
	case TASK_STORE_LASTPOSITION:
		{
			m_vecLastPosition = pev->origin;
			TaskComplete();
			break;
		}
	case TASK_CLEAR_LASTPOSITION:
		{
			m_vecLastPosition = g_vecZero;
			TaskComplete();
			break;
		}
	case TASK_CLEAR_HINTNODE:
		{
			m_iHintNode = NO_NODE;
			TaskComplete();
			break;
		}
	case TASK_STOP_MOVING:
		{
			if ( m_IdealActivity == m_movementActivity )
			{
				m_IdealActivity = GetStoppedActivity();
			}

			RouteClear();
			TaskComplete();
			break;
		}
	case TASK_PLAY_SEQUENCE_FACE_ENEMY:
	case TASK_PLAY_SEQUENCE_FACE_TARGET:
	case TASK_PLAY_SEQUENCE:
		{
			m_IdealActivity = ( Activity )( int )pTask->flData;
			break;
		}
	case TASK_PLAY_ACTIVE_IDLE:
		{
			// monsters verify that they have a sequence for the node's activity BEFORE
			// moving towards the node, so it's ok to just set the activity without checking here.
			m_IdealActivity = ( Activity )WorldGraph.m_pNodes[ m_iHintNode ].m_sHintActivity;
			break;
		}
	case TASK_SET_SCHEDULE:
		{
			Schedule_t *pNewSchedule;

			pNewSchedule = GetScheduleOfType( (int)pTask->flData );
			
			if ( pNewSchedule )
			{
				ChangeSchedule( pNewSchedule );
			}
			else
			{
				TaskFail();
			}

			break;
		}
	case TASK_FIND_NEAR_NODE_COVER_FROM_ENEMY:
		{
			if ( m_hEnemy == NULL )
			{
				TaskFail();
				return;
			}

			if ( FindCover( m_hEnemy->pev->origin, m_hEnemy->pev->view_ofs, 0, pTask->flData ) )
			{
				// try for cover farther than the FLData from the schedule.
				TaskComplete();
			}
			else
			{
				// no coverwhatsoever.
				TaskFail();
			}
			break;
		}
	case TASK_FIND_FAR_NODE_COVER_FROM_ENEMY:
		{
			if ( m_hEnemy == NULL )
			{
				TaskFail();
				return;
			}

			if ( FindCover( m_hEnemy->pev->origin, m_hEnemy->pev->view_ofs, pTask->flData, CoverRadius() ) )
			{
				// try for cover farther than the FLData from the schedule.
				TaskComplete();
			}
			else
			{
				// no coverwhatsoever.
				TaskFail();
			}
			break;
		}
	case TASK_FIND_NODE_COVER_FROM_ENEMY:
		{
			if ( m_hEnemy == NULL )
			{
				TaskFail();
				return;
			}

			if ( FindCover( m_hEnemy->pev->origin, m_hEnemy->pev->view_ofs, 0, CoverRadius() ) )
			{
				// try for cover farther than the FLData from the schedule.
				TaskComplete();
			}
			else
			{
				// no coverwhatsoever.
				TaskFail();
			}
			break;
		}
	case TASK_FIND_COVER_FROM_ENEMY:
		{
			entvars_t *pevCover;

			if ( m_hEnemy == NULL )
			{
				// Find cover from self if no enemy available
				pevCover = pev;
//				TaskFail();
//				return;
			}
			else
				pevCover = m_hEnemy->pev;

			if ( FindLateralCover( pevCover->origin, pevCover->view_ofs ) )
			{
				// try lateral first
				m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
				TaskComplete();
			}
			else if ( FindCover( pevCover->origin, pevCover->view_ofs, 0, CoverRadius() ) )
			{
				// then try for plain ole cover
				m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
				TaskComplete();
			}
			else
			{
				// no coverwhatsoever.
				TaskFail();
			}
			break;
		}
	case TASK_FIND_COVER_FROM_ORIGIN:
		{
			if ( FindCover( pev->origin, pev->view_ofs, 0, CoverRadius() ) )
			{
				// then try for plain ole cover
				m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
				TaskComplete();
			}
			else
			{
				// no cover!
				TaskFail();
			}
		}
		break;
	case TASK_FIND_COVER_FROM_BEST_SOUND:
		{
			CSound *pBestSound;

			pBestSound = PBestSound();

			ASSERT( pBestSound != NULL );
			/*
			if ( pBestSound && FindLateralCover( pBestSound->m_vecOrigin, g_vecZero ) )
			{
				// try lateral first
				m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
				TaskComplete();
			}
			*/

			if ( pBestSound && FindCover( pBestSound->m_vecOrigin, g_vecZero, pBestSound->m_iVolume, CoverRadius() ) )
			{
				// then try for plain ole cover
				m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
				TaskComplete();
			}
			else
			{
				// no coverwhatsoever. or no sound in list
				TaskFail();
			}
			break;
		}
	case TASK_FACE_HINTNODE:
		{
			pev->ideal_yaw = WorldGraph.m_pNodes[ m_iHintNode ].m_flHintYaw;
			SetTurnActivity();
			break;
		}
	
	case TASK_FACE_LASTPOSITION:
		MakeIdealYaw ( m_vecLastPosition );
		SetTurnActivity(); 
		break;

	case TASK_FACE_TARGET:
		if ( m_hTargetEnt != NULL )
		{
			MakeIdealYaw ( m_hTargetEnt->pev->origin );
			SetTurnActivity(); 
		}
		else
			TaskFail();
		break;
	case TASK_FACE_ENEMY:
		{
			MakeIdealYaw ( m_vecEnemyLKP );
			SetTurnActivity(); 
			break;
		}
	case TASK_FACE_IDEAL:
		{
			SetTurnActivity();
			break;
		}
	case TASK_FACE_ROUTE:
		{
			if (FRouteClear())
			{
				ALERT(at_aiconsole, "No route to face!\n");
				TaskFail();
			}
			else
			{
				MakeIdealYaw(m_Route[m_iRouteIndex].vecLocation);
				SetTurnActivity();
			}
			break;
		}
	case TASK_WAIT_PVS:
	case TASK_WAIT_INDEFINITE:
		{
			// don't do anything.
			break;
		}
	case TASK_WAIT:
	case TASK_WAIT_FACE_ENEMY:
		{// set a future time that tells us when the wait is over.
			m_flWaitFinished = gpGlobals->time + pTask->flData;	
			break;
		}
	case TASK_WAIT_RANDOM:
		{// set a future time that tells us when the wait is over.
			m_flWaitFinished = gpGlobals->time + RANDOM_FLOAT( 0.1, pTask->flData );
			break;
		}
	case TASK_MOVE_TO_TARGET_RANGE:
		{
			if ( (m_hTargetEnt->pev->origin - pev->origin).Length() < 1 )
				TaskComplete();
			else
			{
				m_vecMoveGoal = m_hTargetEnt->pev->origin;
				if ( !MoveToTarget( ACT_WALK, 2 ) )
					TaskFail();
			}
			break;
		}
	case TASK_RUN_TO_SCRIPT:
	case TASK_WALK_TO_SCRIPT:
		{
			Activity newActivity;

			if ( !m_pGoalEnt || (m_pGoalEnt->pev->origin - pev->origin).Length() < 1 )
				TaskComplete();
			else
			{
				if ( pTask->iTask == TASK_WALK_TO_SCRIPT )
					newActivity = ACT_WALK;
				else
					newActivity = ACT_RUN;
				// This monster can't do this!
				if ( LookupActivity( newActivity ) == ACTIVITY_NOT_AVAILABLE )
					TaskComplete();
				else 
				{
					if ( m_pGoalEnt != NULL )
					{
						Vector vecDest;
						vecDest = m_pGoalEnt->pev->origin;

						if ( !MoveToLocation( newActivity, 2, vecDest ) )
						{
							TaskFail();
							ALERT( at_aiconsole, "%s Failed to reach script!!!\n", STRING(pev->classname) );
							RouteClear();
						}
					}
					else
					{
						TaskFail();
						ALERT( at_aiconsole, "%s: MoveTarget is missing!?!\n", STRING(pev->classname) );
						RouteClear();
					}
				}
			}
			TaskComplete();
			break;
		}
	case TASK_CLEAR_MOVE_WAIT:
		{
			m_flMoveWaitFinished = gpGlobals->time;
			TaskComplete();
			break;
		}
	case TASK_MELEE_ATTACK1_NOTURN:
	case TASK_MELEE_ATTACK1:
		{
			m_IdealActivity = ACT_MELEE_ATTACK1;
			break;
		}
	case TASK_MELEE_ATTACK2_NOTURN:
	case TASK_MELEE_ATTACK2:
		{
			m_IdealActivity = ACT_MELEE_ATTACK2;
			break;
		}
	case TASK_RANGE_ATTACK1_NOTURN:
	case TASK_RANGE_ATTACK1:
		{
			m_IdealActivity = ACT_RANGE_ATTACK1;
			break;
		}
	case TASK_RANGE_ATTACK2_NOTURN:
	case TASK_RANGE_ATTACK2:
		{
			m_IdealActivity = ACT_RANGE_ATTACK2;
			break;
		}
	case TASK_RELOAD_NOTURN:
	case TASK_RELOAD:
		{
			m_IdealActivity = ACT_RELOAD;
			break;
		}
	case TASK_SPECIAL_ATTACK1:
		{
			m_IdealActivity = ACT_SPECIAL_ATTACK1;
			break;
		}
	case TASK_SPECIAL_ATTACK2:
		{
			m_IdealActivity = ACT_SPECIAL_ATTACK2;
			break;
		}
	case TASK_SET_ACTIVITY:
		{
			m_IdealActivity = (Activity)(int)pTask->flData;
			TaskComplete();
			break;
		}
	case TASK_GET_PATH_TO_ENEMY_LKP:
		{
			if ( BuildRoute ( m_vecEnemyLKP, bits_MF_TO_LOCATION, NULL ) )
			{
				TaskComplete();
			}
			else if (BuildNearestRoute( m_vecEnemyLKP, pev->view_ofs, 0, (m_vecEnemyLKP - pev->origin).Length() ))
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToEnemyLKP failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_ENEMY:
		{
			CBaseEntity *pEnemy = m_hEnemy;

			if ( pEnemy == NULL )
			{
				TaskFail();
				return;
			}

			if ( BuildRoute ( pEnemy->pev->origin, bits_MF_TO_ENEMY, pEnemy ) )
			{
				TaskComplete();
			}
			else if (BuildNearestRoute( pEnemy->pev->origin, pEnemy->pev->view_ofs, 0, (pEnemy->pev->origin - pev->origin).Length() ))
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToEnemy failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_ENEMY_CORPSE:
		{
			UTIL_MakeVectors( pev->angles );
			if ( BuildRoute ( m_vecEnemyLKP - gpGlobals->v_forward * 64, bits_MF_TO_LOCATION, NULL ) )
			{
				TaskComplete();
			}
			else
			{
				ALERT ( at_aiconsole, "GetPathToEnemyCorpse failed!!\n" );
				TaskFail();
			}
		}
		break;
	case TASK_GET_PATH_TO_SPOT:
		{
			CBaseEntity *pPlayer = UTIL_FindEntityByClassname( NULL, "player" );
			if ( BuildRoute ( m_vecMoveGoal, bits_MF_TO_LOCATION, pPlayer ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToSpot failed!!\n" );
				TaskFail();
			}
			break;
		}

	case TASK_GET_PATH_TO_TARGET:
		{
			RouteClear();
			if ( m_hTargetEnt != NULL && MoveToTarget( m_movementActivity, 1 ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToSpot failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_SCRIPT:
		{
			RouteClear();
			if ( m_pCine != NULL && MoveToLocation( m_movementActivity, 1, m_pCine->pev->origin ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToSpot failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_HINTNODE:// for active idles!
		{
			if ( MoveToLocation( m_movementActivity, 2, WorldGraph.m_pNodes[ m_iHintNode ].m_vecOrigin ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToHintNode failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_LASTPOSITION:
		{
			m_vecMoveGoal = m_vecLastPosition;

			if ( MoveToLocation( m_movementActivity, 2, m_vecMoveGoal ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToLastPosition failed!!\n" );
				TaskFail();
			}
			break;
		}
	case TASK_GET_PATH_TO_BESTSOUND:
		{
			CSound *pSound;

			pSound = PBestSound();

			if ( pSound && MoveToLocation( m_movementActivity, 2, pSound->m_vecOrigin ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToBestSound failed!!\n" );
				TaskFail();
			}
			break;
		}
case TASK_GET_PATH_TO_BESTSCENT:
		{
			CSound *pScent;

			pScent = PBestScent();

			if ( pScent && MoveToLocation( m_movementActivity, 2, pScent->m_vecOrigin ) )
			{
				TaskComplete();
			}
			else
			{
				// no way to get there =(
				ALERT ( at_aiconsole, "GetPathToBestScent failed!!\n" );
				
				TaskFail();
			}
			break;
		}
	case TASK_RUN_PATH:
		{
			// UNDONE: This is in some default AI and some monsters can't run? -- walk instead?
			if ( LookupActivity( ACT_RUN ) != ACTIVITY_NOT_AVAILABLE )
			{
				m_movementActivity = ACT_RUN;
			}
			else
			{
				m_movementActivity = ACT_WALK;
			}
			TaskComplete();
			break;
		}
	case TASK_WALK_PATH:
		{
			if ( pev->movetype == MOVETYPE_FLY )
			{
				m_movementActivity = ACT_FLY;
			}
			if ( LookupActivity( ACT_WALK ) != ACTIVITY_NOT_AVAILABLE )
			{
				m_movementActivity = ACT_WALK;
			}
			else
			{
				m_movementActivity = ACT_RUN;
			}
			TaskComplete();
			break;
		}
	case TASK_STRAFE_PATH:
		{
			Vector2D	vec2DirToPoint; 
			Vector2D	vec2RightSide;

			// to start strafing, we have to first figure out if the target is on the left side or right side
			UTIL_MakeVectors ( pev->angles );

			vec2DirToPoint = ( m_Route[ 0 ].vecLocation - pev->origin ).Make2D().Normalize();
			vec2RightSide = gpGlobals->v_right.Make2D().Normalize();

			if ( DotProduct ( vec2DirToPoint, vec2RightSide ) > 0 )
			{
				// strafe right
				m_movementActivity = ACT_STRAFE_RIGHT;
			}
			else
			{
				// strafe left
				m_movementActivity = ACT_STRAFE_LEFT;
			}
			TaskComplete();
			break;
		}


	case TASK_WAIT_FOR_MOVEMENT:
		{
			if (FRouteClear())
			{
				TaskComplete();
			}
			break;
		}

	case TASK_EAT:
		{
			Eat( pTask->flData );
			TaskComplete();
			break;
		}
	case TASK_SMALL_FLINCH:
		{
			m_IdealActivity = GetSmallFlinchActivity();
			break;
		}
	case TASK_DIE:
		{
			RouteClear();	
			
			m_IdealActivity = GetDeathActivity();

			pev->deadflag = DEAD_DYING;
			break;
		}
	case TASK_SOUND_WAKE:
		{
			AlertSound();
			TaskComplete();
			break;
		}
	case TASK_SOUND_DIE:
		{
			DeathSound();
			TaskComplete();
			break;
		}
	case TASK_SOUND_IDLE:
		{
			IdleSound();
			TaskComplete();
			break;
		}
	case TASK_SOUND_PAIN:
		{
			PainSound();
			TaskComplete();
			break;
		}
	case TASK_SOUND_DEATH:
		{
			DeathSound();
			TaskComplete();
			break;
		}
	case TASK_SOUND_ANGRY:
		{
			// sounds are complete as soon as we get here, cause we've already played them.
			ALERT ( at_aiconsole, "SOUND\n" );			
			TaskComplete();
			break;
		}
	case TASK_WAIT_FOR_SCRIPT:
		{
			if ( m_pCine->m_iDelay <= 0 && gpGlobals->time >= m_pCine->m_startTime )
			{
				TaskComplete(); //LRC - start playing immediately
			}
			else if (!m_pCine->IsAction() && m_pCine->m_iszIdle)
			{
				m_pCine->StartSequence( (CBaseMonster *)this, m_pCine->m_iszIdle, FALSE );
				if (FStrEq( STRING(m_pCine->m_iszIdle), STRING(m_pCine->m_iszPlay)))
				{
					pev->framerate = 0;
				}
			}
			else
				m_IdealActivity = ACT_IDLE;

			break;
		}
	case TASK_PLAY_SCRIPT:
		{
			if (m_pCine->IsAction())
			{
				//ALERT(at_console,"PlayScript: setting idealactivity %d\n",m_pCine->m_fAction);
				switch(m_pCine->m_fAction)
				{
				case 0:
					m_IdealActivity = ACT_RANGE_ATTACK1; break;
				case 1:
					m_IdealActivity = ACT_RANGE_ATTACK2; break;
				case 2:
					m_IdealActivity = ACT_MELEE_ATTACK1; break;
				case 3:
					m_IdealActivity = ACT_MELEE_ATTACK2; break;
				case 4:
					m_IdealActivity = ACT_SPECIAL_ATTACK1; break;
				case 5:
					m_IdealActivity = ACT_SPECIAL_ATTACK2; break;
				case 6:
					m_IdealActivity = ACT_RELOAD; break;
				case 7:
					m_IdealActivity = ACT_HOP; break;
				}
				pev->framerate = 1.0; // shouldn't be needed, but just in case
				pev->movetype = MOVETYPE_FLY;
				ClearBits(pev->flags, FL_ONGROUND);
			}
			else
			{
				m_pCine->StartSequence( (CBaseMonster *)this, m_pCine->m_iszPlay, TRUE );
				if ( m_fSequenceFinished )
					ClearSchedule();
				pev->framerate = 1.0;
				//ALERT( at_aiconsole, "Script %s has begun for %s\n", STRING( m_pCine->m_iszPlay ), STRING(pev->classname) );
			}
			m_scriptState = SCRIPT_PLAYING;
			break;
		}
	case TASK_ENABLE_SCRIPT:
		{
			m_pCine->DelayStart( 0 );
			TaskComplete();
			break;
		}
//LRC
	case TASK_END_SCRIPT:
		{
			m_pCine->SequenceDone( this );
			TaskComplete();
			break;
		}
	case TASK_PLANT_ON_SCRIPT:
		{
			if ( m_pCine != NULL )
			{
				// Plant on script
				// LRC - if it's a teleport script, do the turn too
				if (m_pCine->m_fMoveTo == 4 || m_pCine->m_fMoveTo == 6)
				{
					if (m_pCine->m_fTurnType == 0) //LRC
						pev->angles.y = m_hTargetEnt->pev->angles.y;
					else if (m_pCine->m_fTurnType == 1)
						pev->angles.y = UTIL_VecToYaw(m_hTargetEnt->pev->origin - pev->origin);
					pev->ideal_yaw = pev->angles.y;
					pev->avelocity = Vector( 0, 0, 0 );
					pev->velocity = Vector( 0, 0, 0 );
					pev->effects |= EF_NOINTERP;
				}

				if (m_pCine->m_fMoveTo != 6)
					pev->origin = m_pGoalEnt->pev->origin;
			}

			TaskComplete();
			break;
		}
	case TASK_FACE_SCRIPT:
		{
			if ( m_pCine != NULL && m_pCine->m_fMoveTo != 0) // movetype "no move" makes us ignore turntype
			{
				switch (m_pCine->m_fTurnType)
				{
				case 0:
					pev->ideal_yaw = UTIL_AngleMod( m_pCine->pev->angles.y );
					break;
				case 1:
					// yes, this is inconsistent- turn to face uses the "target" and turn to angle uses the "cine".
					if (m_hTargetEnt)
						MakeIdealYaw ( m_hTargetEnt->pev->origin );
					else
						MakeIdealYaw ( m_pCine->pev->origin );
					break;
				// default: don't turn
				}
			}

			TaskComplete();
			m_IdealActivity = ACT_IDLE;
			RouteClear();
			break;
		}
	case TASK_SUGGEST_STATE:
		{
			m_IdealMonsterState = (MONSTERSTATE)(int)pTask->flData;
			TaskComplete();
			break;
		}

	case TASK_SET_FAIL_SCHEDULE:
		m_failSchedule = (int)pTask->flData;
		TaskComplete();
		break;

	case TASK_CLEAR_FAIL_SCHEDULE:
		m_failSchedule = SCHED_NONE;
		TaskComplete();
		break;

	default:
		{
			ALERT ( at_aiconsole, "No StartTask entry for %d\n", (SHARED_TASKS)pTask->iTask );
			break;
		}
	}
}
예제 #16
0
//=========================================================
// MonsterThink, overridden for roaches.
//=========================================================
void CRoach :: MonsterThink( void  )
{
	if ( FNullEnt( FIND_CLIENT_IN_PVS( edict() ) ) )
		pev->nextthink = gpGlobals->time + RANDOM_FLOAT(1,1.5);
	else
		pev->nextthink = gpGlobals->time + 0.1;// keep monster thinking

	float flInterval = StudioFrameAdvance( ); // animate

	if ( !m_fLightHacked )
	{
		// if light value hasn't been collection for the first time yet, 
		// suspend the creature for a second so the world finishes spawning, then we'll collect the light level.
		pev->nextthink = gpGlobals->time + 1;
		m_fLightHacked = TRUE;
		return;
	}
	else if ( m_flLastLightLevel < 0 )
	{
		// collect light level for the first time, now that all of the lightmaps in the roach's area have been calculated.
		m_flLastLightLevel = GETENTITYILLUM( ENT( pev ) );
	}

	switch ( m_iMode )
	{
	case	ROACH_IDLE:
	case	ROACH_EAT:
		{
			// if not moving, sample environment to see if anything scary is around. Do a radius search 'look' at random.
			if ( RANDOM_LONG(0,3) == 1 )
			{
				Look( 150 );
				if (HasConditions(bits_COND_SEE_FEAR))
				{
					// if see something scary
					//ALERT ( at_aiconsole, "Scared\n" );
					Eat( 30 +  ( RANDOM_LONG(0,14) ) );// roach will ignore food for 30 to 45 seconds
					PickNewDest( ROACH_SCARED_BY_ENT );
					SetActivity ( ACT_WALK );
				}
				else if ( RANDOM_LONG(0,149) == 1 )
				{
					// if roach doesn't see anything, there's still a chance that it will move. (boredom)
					//ALERT ( at_aiconsole, "Bored\n" );
					PickNewDest( ROACH_BORED );
					SetActivity ( ACT_WALK );

					if ( m_iMode == ROACH_EAT )
					{
						// roach will ignore food for 30 to 45 seconds if it got bored while eating. 
						Eat( 30 +  ( RANDOM_LONG(0,14) ) );
					}
				}
			}
	
			// don't do this stuff if eating!
			if ( m_iMode == ROACH_IDLE )
			{
				if ( FShouldEat() )
				{
					Listen();
				}

				if ( GETENTITYILLUM( ENT(pev) ) > m_flLastLightLevel )
				{
					// someone turned on lights!
					//ALERT ( at_console, "Lights!\n" );
					PickNewDest( ROACH_SCARED_BY_LIGHT );
					SetActivity ( ACT_WALK );
				}
				else if ( HasConditions(bits_COND_SMELL_FOOD) )
				{
					CSound *pSound;

					pSound = CSoundEnt::SoundPointerForIndex( m_iAudibleList );

					// roach smells food and is just standing around. Go to food unless food isn't on same z-plane.
					if ( pSound && abs( pSound->m_vecOrigin.z - pev->origin.z ) <= 3 )
					{
						PickNewDest( ROACH_SMELL_FOOD );
						SetActivity ( ACT_WALK );
					}
				}
			}

			break;
		}
	case	ROACH_SCARED_BY_LIGHT:
		{
			// if roach was scared by light, then stop if we're over a spot at least as dark as where we started!
			if ( GETENTITYILLUM( ENT( pev ) ) <= m_flLastLightLevel )
			{
				SetActivity ( ACT_IDLE );
				m_flLastLightLevel = GETENTITYILLUM( ENT ( pev ) );// make this our new light level.
			}
			break;
		}
	}
	
	if ( m_flGroundSpeed != 0 )
	{
		Move( flInterval );
	}
}