/* define behavior for bots in crusing state. This should be the flocking * emergent behavioral model. It's what happens when enemies are just * moving around the map trying to form groups */ void AICruisingEnter(ai_t *brain){ player_t *enemy; vector_t destDir; brain->prevState = brain->curState; brain->curState = AI_CRUISING; brain->timer = 0; brain->timeout = AI_CRUISING_TIMEOUT + R_TIME_MOD*rand(); PlayerSetAnimation(brain->body, PLAYER_ANIM_RUN); PlayerReset(brain->body); /* I believe one might refer to this as cheating */ if((enemy = AIGetEnemy()) != NULL){ brain->destination.x = enemy->position.x + POS_ERR*UNIRAND(1.0); brain->destination.z = enemy->position.z + POS_ERR*UNIRAND(1.0); brain->destination.y = enemy->position.y; /* set your body pointing in the right direction */ VectorSubtract(&destDir, &brain->destination, &brain->body->position); VectorNormalize(&destDir); /* direction to our destination */ brain->destDir = destDir; brain->dotDest = VectorDot(&destDir, &brain->body->forward); brain->tPitch = 0; } }
/* define behavior for bots in the attack state */ void AIAttackEnter(ai_t *brain){ player_t *enemy; brain->prevState = brain->curState; brain->timer = 0; if((enemy = AIGetEnemy()) != NULL){ /* get a vector pointing towards the enemy */ VectorSubtract(&brain->enemyDir, &enemy->position, &brain->body->position); /* get the distance to the enemy */ brain->enemy_dis = VectorMagnitude(&brain->enemyDir); VectorScale(&brain->enemyDir, &brain->enemyDir, 1.0/brain->enemy_dis); /* decide if we need to move closer and if we do, we're in the wrong * state (should be in reposition */ if(brain->enemy_dis > AI_DESIRED_RANGE){ AIRepositionEnter(brain); } else{ brain->curState = AI_ATTACK; brain->timeout = AI_ATTACK_TIMEOUT + R_TIME_MOD*rand(); PlayerSetAnimation(brain->body, PLAYER_ANIM_IDLE2); PlayerReset(brain->body); } } }
/* define behavior for bots that are dead */ void AIDeadEnter(ai_t *brain){ brain->prevState = brain->curState; brain->timer = 0; brain->curState = AI_DEAD; brain->timeout = AI_DEAD_TIMEOUT; PlayerSetAnimation(brain->body, PLAYER_ANIM_DEAD); PlayerReset(brain->body); }
/* define behavior for bots in the shot state (got shot) */ void AIShotEnter(ai_t *brain){ brain->prevState = brain->curState; brain->timer = 0; brain->curState = AI_SHOT; brain->timeout = AI_SHOT_TIMEOUT; PlayerSetAnimation(brain->body, PLAYER_ANIM_SHOT0); PlayerReset(brain->body); }
/* define behavior for bots that are dying */ void AIDyingEnter(ai_t *brain){ brain->prevState = brain->curState; brain->timer = 0; brain->curState = AI_DYING; brain->timeout = AI_DYING_TIMEOUT; brain->body->health = 255; PlayerSetAnimation(brain->body, PLAYER_ANIM_DYING); PlayerReset(brain->body); }
/* define behavior for bots in the scan state */ void AIScanEnter(ai_t *brain){ player_t *enemy = AIGetEnemy(); brain->prevState = brain->curState; brain->curState = AI_SCAN; brain->timer = 0; brain->timeout = AI_SCAN_TIMEOUT + R_TIME_MOD*rand(); PlayerSetAnimation(brain->body, PLAYER_ANIM_IDLE1); VectorSubtract(&brain->enemyDir, &enemy->position, &brain->body->position); PlayerReset(brain->body); }
void ToGame(void) { Pause = false; SpaceReset(&space); // Reset player positions and velocity for (int i = 0, c = 0; i < MAX_PLAYERS; i++) { PlayerReset(&players[i], c); if (!players[i].Enabled) continue; c++; } CameraInit(&camera); SoundPlay(SoundStart, 1.0); MusicSetLoud(true); GatherInput = GameGatherInput; DoLogic = GameDoLogic; OutputFrame = GameOutputFrame; }
/* define behavior for bots in reposition state */ void AIRepositionEnter(ai_t *brain){ player_t *enemy; vector_t orthog; vector_t temp; float diff; brain->prevState = brain->curState; brain->curState = AI_REPOSITION; brain->timer = 0; brain->timeout = AI_REPO_TIMEOUT + R_TIME_MOD*rand(); PlayerSetAnimation(brain->body, PLAYER_ANIM_RUN); PlayerReset(brain->body); VectorClear(&brain->destination); /* we're currently fighting, we just want to move slightly * before attacking again */ if((enemy = AIGetEnemy()) != NULL){ /* get a vector pointing towards the enemy */ VectorSubtract(&brain->enemyDir, &enemy->position, &brain->body->position); /* get the distance to the enemy */ brain->enemy_dis = VectorMagnitude(&brain->enemyDir); VectorScale(&brain->enemyDir, &brain->enemyDir, 1.0/brain->enemy_dis); /* get a vector orthogonal to the direction of the enemy */ VectorCross(&orthog, &brain->enemyDir, &brain->body->up); /* decide if we need to move closer */ if(brain->enemy_dis > AI_DESIRED_RANGE){ diff = brain->enemy_dis - AI_DESIRED_RANGE + UNIRAND(6.0); VectorScale(&temp, &brain->enemyDir, diff); VectorAdd(&brain->destination, &temp, &brain->body->position); } /* now move sideways some */ diff = AI_MOVE_SIZE + UNIRAND(6.0); VectorScale(&temp, &orthog, 0.2*SIGN(UNIRAND(1.0))*diff); VectorAdd(&brain->destination, &brain->destination, &temp); } }
Player::Player(ClientSession* session) : mSession(session) { PlayerReset(); }
/* if we want to be thrown an event from the outside world */ void PlayerProcessEvent(player_t *player, int event){ switch(event){ case PLAYER_RUNNING: if(player->state == PLAYER_READY){ player->timer = 0; PlayerSetAnimation(player, PLAYER_ANIM_RUN); return; } else if(player->state == PLAYER_SHOT){ return; } else if(player->state == PLAYER_DYING){ return; } else if(player->state == PLAYER_DEAD){ return; } break; case PLAYER_JUMPING: if(player->state == PLAYER_READY){ player->timer = 0; PlayerSetAnimation(player, PLAYER_ANIM_JUMP); return; } else if(player->state == PLAYER_SHOT){ return; } else if(player->state == PLAYER_DYING){ return; } else if(player->state == PLAYER_DEAD){ return; } break; case PLAYER_IDLE: if(player->state == PLAYER_READY){ player->timer = 0; PlayerSetAnimation(player, PLAYER_ANIM_IDLE0); return; } else if(player->state == PLAYER_SHOT){ return; } else if(player->state == PLAYER_DYING){ return; } else if(player->state == PLAYER_DEAD){ return; } break; case PLAYER_GOT_SHOT: player->health--; if(player->state == PLAYER_READY){ PlayerReset(player); player->state = PLAYER_SHOT; player->timer = 0; PlayerSetAnimation(player, PLAYER_ANIM_SHOT0); player->timeout = P_SHOT_TIMEOUT; return; } else if(player->state == PLAYER_SHOT){ player->timer = 0; PlayerReset(player); return; } else if(player->state == PLAYER_DYING){ return; } else if(player->state == PLAYER_DEAD){ return; } break; case PLAYER_KILLED: if(player->state == PLAYER_READY){ PlayerReset(player); player->state = PLAYER_DYING; player->timer = 0; player->health = -1; /* means you're really dead */ player->radius = 0; /* means you can't be shot anymore */ PlayerSetAnimation(player, PLAYER_ANIM_DYING); player->timeout = P_DYING_TIMEOUT; return; } else if(player->state == PLAYER_SHOT){ PlayerReset(player); player->state = PLAYER_DYING; player->timer = 0; PlayerSetAnimation(player, PLAYER_ANIM_DYING); player->timeout = P_DYING_TIMEOUT; return; } else if(player->state == PLAYER_DYING){ return; } else if(player->state == PLAYER_DEAD){ return; } break; case PLAYER_TIMEOUT: if(player->state == PLAYER_READY){ player->timer = 0; return; } else if(player->state == PLAYER_SHOT){ PlayerReset(player); player->state = PLAYER_READY; player->timer = 0; if(player->rFlag || player->lFlag || player->fFlag || player->bFlag) PlayerSetAnimation(player, PLAYER_ANIM_RUN); else PlayerSetAnimation(player, PLAYER_ANIM_IDLE0); player->timeout = P_READY_TIMEOUT; return; } else if(player->state == PLAYER_DYING){ PlayerReset(player); player->state = PLAYER_DEAD; PlayerSetAnimation(player, PLAYER_ANIM_DEAD); player->timer = 0; player->timeout = P_DEAD_TIMEOUT; return; } else if(player->state == PLAYER_DEAD){ player->timer = 0; return; } break; } return; }