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); }
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(); }
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; }
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; } } }
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; }; }
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; } }
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; }
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]); } }
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"); }
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); } }
/// \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; }
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); }
/// \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; }
bool Snake::InsertAsHead(UnitPosition unit) { Eat(unit); return true; }
//========================================================= // 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; } } }
//========================================================= // 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 ); } }