float angle( LWFVector a, LWFVector b ) { LWFVector na, nb; copyv( na, a ); normalize( na ); copyv( nb, b ); normalize( nb ); return ( float ) acos( dot( na, nb )); }
//Funzione che genera tutte le permutazioni di un vettore di interi void permute(int v[], int l, int r, int nmax){ int i; int temp[nmax]; if(l == r){ enum_combo2(v, nmax); printvf(v, nmax, 0); //Copio il vettore in quello temporaneo copyv(v, temp, nmax); fprintf(f, " : "); //Stampo i cicli trovati dal cyclesort cyclesort(temp, nmax); }else{ for(i=l;i<=r;i++){ swap(v, l, i); permute(v, l+1, r, nmax); swap(v, l, i); } } }
static void prev_dog_bot(void) { int DBi=DogBot; DogBotDist=0; do { if (--DogBot<0) DogBot=NBBOT-1; if (DogBot!=controlled_bot) { copyv(&DogBotDir,&obj[bot[DogBot].vion].pos); subv(&DogBotDir,&obj[bot[controlled_bot].vion].pos); DogBotDist=renorme(&DogBotDir); } } while (DogBot!=DBi && (DogBotDist>DOGDISTMAX || bot[DogBot].camp==-1 || DogBot==controlled_bot)); }
void vec_hp( LWFVector a, float *h, float *p ) { LWFVector n; copyv( n, a ); normalize( n ); *p = ( float ) asin( -n[ 1 ] ); if ( 1.0f - fabs( n[ 1 ] ) > EPSILON_F ) { *h = ( float )( acos( n[ 2 ] / cos( *p ))); if ( n[ 0 ] < 0.0f ) *h = ( float )( 2 * PI - *h ); } else *h = 0.0f; }
matriz * gs(matriz &v){ //classico matriz * w = (matriz *) malloc(sizeof(matriz)); w->l=v.l; w->c=v.c; for(int i=0;i<v.l;i++) copyv(w->vet[i],v.vet[i],v.c); for(int i=1;i<v.l;i++){ long double valor = prodint(w->vet[i-1],w->vet[i],v.c); long double div = prodint(w->vet[i],w->vet[i],v.c); printf("%LF / %LF = ", valor,div); valor/=div; printf("%LF\n", valor); sumvet(w->vet[i],w->vet[i],prodext(w->vet[i],valor * -1,v.c),v.c); //soma Vk } return w; }
/*A problem found in alphabeta pruning is that once I get a 0 value for a certain MAX node (guaranteed draw) if any of the next nodes has a value of -1 alphabeta allocates it as a 0 value node. Although these children don't really affect the true value of father's alphabeta (as max node if there's a 0, it can't get less) it can happen that I have to count the number of winnning leaves and naturally I can't choose a path that seems 0 (draw) while it is indeed -1 (lose) so that I developed this function that returns the TRUE value of a certain node that normally is allocated as 0 but in reality can also be -1*/ static int TrueValue(NODE *T) { NODE *tmpSubTree; //temporarily to this function int valore; if ((tmpSubTree = (NODE*)malloc(sizeof(NODE))) == NULL) exit(0); tmpSubTree->depth = T->depth; tmpSubTree->i = T->i; tmpSubTree->j = T->j; tmpSubTree->leftchild = NULL; tmpSubTree->rightbrothers = NULL; tmpSubTree->player = T->player; tmpSubTree->value == (T->player == MAX) ? (-2) : (2); tmpSubTree->transboard = copyv(T->transboard); valore = alphabeta(&tmpSubTree, tmpSubTree->depth, -1, 1, tmpSubTree->player); //simply I recreate a sub-tree with the technique used to create the whole tree so that I get the TRUE value and I store it in the real tree DeleteTree(&tmpSubTree); //eventually I free tmpSubTree return (valore); //returns the TRUE value of that child }
void main() { const int nx = 1800; const double dx = 1.0/(double)nx; const double dt = 0.2*dx; const double k = 2.0*pow(dx,2.0)/dt; const double S = 0.0; const double t0 = 0.0, TF = 0.76; double *pn, *pk, *pkm, *thetan, *thetak, *thetakm, *cm, *ckm; double t; double change; const double tol = 5E-8; double h, dhdt, h3; int ix; int PRINT_FREQ = 100000000; // MEMORY ALLOCATION pk = (double *) malloc(sizeof(double) * nx); pkm = (double *) malloc(sizeof(double) * nx); thetak = (double *) malloc(sizeof(double) * nx); thetakm = (double *) malloc(sizeof(double) * nx); cm = (double *) malloc(sizeof(double) * nx); ckm = (double *) malloc(sizeof(double) * nx); // INITIALIZATION for (ix=0; ix<nx; ix++){ pk[ix] = 0.025; thetak[ix] = 1.0; } copyv(pkm,pk,nx,1.0); copyv(thetakm,thetak,nx,1.0); copyv(cm,thetak,nx,0.125*cos(4.0*PI*t0) + 0.375); copyv(ckm,cm,nx,1.0); int niter = 0; FILE *fsigma; fsigma = fopen("sigma_ea_1800.dat","w"); double sigma = 0.0; int sigmai = 0; // TIME ITERATIONS while (t <= TF){ niter += 1; t = t0 + dt*niter; h = 0.125*cos(4.0*PI*t) + 0.375; h3 = pow(h,3.0); change = tol + 1.0; while(change > tol) { //GAUSS-SEIDEL copyv(ckm,thetak,nx,h); for (ix=1;ix<nx-1;ix++){ //LOOP OVER NODES if (pkm[ix] > 0.0 || thetakm[ix] >= 1.0){ pk[ix] = 0.5/h3*(S*dx*(ckm[ix-1]-ckm[ix]) - k*(ckm[ix]-cm[ix]) + h3*(pkm[ix+1] + pkm[ix-1])); if (pk[ix] >= 0.0) //cavitation check thetak[ix] = 1.0; else pk[ix] = 0.0; } if (pk[ix] <= 0.0 || thetak[ix] < 1.0){ thetak[ix] = 1.0/(k+S*dx)/h*(k*cm[ix] + S*dx*ckm[ix-1] + h3*(pkm[ix+1]-2.0*pkm[ix]+pkm[ix-1])); if (thetak[ix] < 1.0 ) //cavitation check pk[ix] = 0.0; else thetak[ix] = 1.0; } } //END LOOP OVER NODES change = norm2_dif(pkm,pk,nx) + norm2_dif(thetakm,thetak,nx); copyv(pkm,pk,nx,1.0); copyv(thetakm,thetak,nx,1.0); } //END GAUSS-SEIDEL copyv(cm,thetak,nx,h); printf("tn %1.3e h(t) %1.3f n %d\n",t,h,niter); if (niter % PRINT_FREQ == 0) print_to_file(pk, nx, niter); sigmai = 0; sigma = 0.0; for (ix=1;ix<nx-1;ix++) if (pk[ix]==0.0 && pk[ix+1] > 0.0) sigmai = ix; sigma = sigmai*dx; fprintf(fsigma, "%1.6e %1.6e\n", t, sigma); } //END while(t <= TF) fclose(fsigma); free(thetak); free(thetakm); free(pk); free(pkm); free(cm); free(ckm); }
/*contains the call to alphabeta and the creation of the gametree*/ int get_next_move(unsigned int *i, unsigned int *j) { unsigned int x; /*Initially I consider the special cases*/ if (C == M*N) { x = firstmove(); *i = x / N; *j = x - N*(x / N); BOARD[*i][*j] = 1; C--; return 1; } if ((M == 4 && N == 4 && K == 4) && M*N - C == 2) { //4x4x4 and if M*N-C == 2 means that there have been only 2 total moves and this is currently the secondmove of player1 x = secondmove(); *i = x / N; *j = x - N*(x / N); BOARD[*i][*j] = 1; C--; return 1; } if ((M == 6 && N == 4 && K == 3) && M*N - C == 2) { //same with 6x4x3 x = secondmove(); *i = x / N; *j = x - N*(x / N); BOARD[*i][*j] = 1; C--; return 1; } if ((M == 5 && N == 5 && K == 3) && M*N - C == 2) { //same with 5x5x3 x = secondmove(); *i = x / N; *j = x - N*(x / N); BOARD[*i][*j] = 1; C--; return 1; } if (Z == 0) { if ((GameTree = (NODE*)malloc(sizeof(NODE))) == NULL) { printf("\nError"); exit(0); } GameTree->depth = C; GameTree->i = tmpI; GameTree->j = tmpJ; GameTree->player = MAX; GameTree->transboard = Trans(); GameTree->leftchild = NULL; GameTree->rightbrothers = NULL; Z++; GameTree->value = alphabeta(&GameTree, GameTree->depth, -1, 1, GameTree->player); //I let alphabeta create all the game tree { //right after being created NODE *scorri; if (GameTree->value == 1) { //if I fould the value to be 1 I can just follow the 1 path and it'll lead me to certain win for (scorri = GameTree->leftchild; scorri->value != GameTree->value; scorri = scorri->rightbrothers) //hence I'll just search among the children until I find the 1 value ; *i = scorri->i; *j = scorri->j; C--; //decreasing the number of total moves left BOARD[*i][*j] = 1; // updating BOARD... } else { //case value = 0 (it can't be -1 because since we're starting first there's no way, having the perfect strategy that we can lose, at least we can draw) NODE *tmp1; unsigned int maxwins = 0; for (tmp1 = GameTree->leftchild; tmp1 != NULL; tmp1 = tmp1->rightbrothers) { //among all children I check for the one with the highest win-coefficient (see explanation in CountWins), it'll be called MaxWins if (TrueValue(tmp1) == 0); //if value = 0(it can't be 1 otherwise Gametree's value wouldn't be 0) I also don't want to choose a losing path, even if it has the highest win coefficient maxwins = Max(maxwins, CountWins(tmp1)); } if (maxwins != 0) { //se esistono vittorie possibili... for (tmp1 = GameTree->leftchild; maxwins != CountWins(tmp1) ||TrueValue(tmp1) != 0; tmp1 = tmp1->rightbrothers) ; } else { //if instead there is no possible win (but I still can draw) for (tmp1 = GameTree->leftchild; TrueValue(tmp1) != 0; tmp1 = tmp1->rightbrothers) ; //i just pick the first TrueValue = 0 } *i = tmp1->i; //and i update the AI move *j = tmp1->j; C--; BOARD[*i][*j] = 1; } /*Deleting the part of tree that I won't use as before in set_opponent_move.*/ NODE *canc = GameTree->leftchild, *prev = NULL; while (canc != NULL) { if (canc->i != *i || canc->j != *j) { if (prev == NULL) { GameTree->leftchild = canc->rightbrothers; DeleteTree(&canc); canc = GameTree->leftchild; } else { prev->rightbrothers = canc->rightbrothers; DeleteTree(&canc); canc = prev->rightbrothers; } } else { prev = canc; canc = canc->rightbrothers; } } GameTree = GameTree->leftchild; } } else { //If we already generated a GameTree NODE *tmp = GameTree; NODE *scorri; if (GameTree->value == 1) { //as before, if value = 1 then I can just pick the first child with value 1 and it'll lead me to certain win for (scorri = tmp->leftchild; scorri->value != 1; scorri = scorri->rightbrothers) { } /*Updating AI move*/ *i = scorri->i; *j = scorri->j; } else if (GameTree->value == 0 && TrueValue(GameTree) == 1) { //it can happen that the original value of the gametree changes during the game (ex: non-optimal moves of the opponents) so that I always have to follow first a path that will lead to certain victory, if there is NODE *newGameTree, *scorri; if ((newGameTree = (NODE*)malloc(sizeof(NODE))) == NULL) exit(0); //creating a new winning gametree newGameTree->depth = GameTree->depth; newGameTree->i = GameTree->i; newGameTree->j = GameTree->j; newGameTree->leftchild = NULL; newGameTree->player = GameTree->player; newGameTree->transboard = copyv(GameTree->transboard); newGameTree->rightbrothers = NULL; DeleteTree(&GameTree); newGameTree->value = alphabeta(&newGameTree, newGameTree->depth, -1, 1, newGameTree->player); GameTree = newGameTree; for (scorri = GameTree->leftchild; scorri->value != GameTree->value; scorri = scorri->rightbrothers) ; /*Updating the move*/ *i = scorri->i; *j = scorri->j; } else { //as before if Gametree value = 0 NODE *tmp; unsigned int maxwins = 0; for (tmp = GameTree->leftchild; tmp != NULL; tmp = tmp->rightbrothers) { //searching for the child with highest win-coefficient whose value isn't -1 if (TrueValue(tmp) == 0) maxwins = Max(maxwins, CountWins(tmp)); } if (maxwins != 0) { //if there are possible wins for (tmp = GameTree->leftchild; maxwins != CountWins(tmp) || TrueValue(tmp) != 0; tmp = tmp->rightbrothers) ; } else { //if there aren't possible wins for (tmp = GameTree->leftchild; TrueValue(tmp) != 0; tmp = tmp->rightbrothers) ; //i'll just take the first node with 0 value } /*updating AI move*/ *i = tmp->i; *j = tmp->j; } /*deleting useless tree part*/ NODE *canc = GameTree->leftchild, *prev = NULL; while (canc != NULL) { if (canc->i != *i || canc->j != *j) { if (prev == NULL) { GameTree->leftchild = canc->rightbrothers; DeleteTree(&canc); canc = GameTree->leftchild; } else { prev->rightbrothers = canc->rightbrothers; DeleteTree(&canc); canc = prev->rightbrothers; } } else { prev = canc; canc = canc->rightbrothers; } } GameTree = GameTree->leftchild; C--; BOARD[*i][*j] = 1; } if (C == 0) //when we're finished I just free the whole memory used in the tree DeleteTree(&GameTree); return 1; }
/*alphabeta pruning, player.c's core, accurate description is inside the paper*/ static int alphabeta(NODE **T, int depth, int a, int b, int maximizingPlayer) { if (depth == 0 || GetWin(*T)) { //if leaf... ((*T)->player == MAX) ? ((*T)->value = -GetWin(*T)) : ((*T)->value = GetWin(*T)); //I assign a value to the node, -1 if opponent's win, +1 if AI win return (*T)->value; } if (maximizingPlayer == MAX) { //only if minimizing node NODE *tmp; unsigned short *v = NULL; unsigned int x, count; if (!AllocateChildren(T, depth, 0, 0, MIN, NULL)) { //first I allocate 1 child without giving any value, I do this to keep everything in one for-cycle printf("\nError"); exit(0); } tmp = (*T)->leftchild; v = copyv((*T)->transboard); //I take the node's board and... for (x = 0, count = 0; x < M*N; x++) { //...I check every possibile move from that certain board state if (v[x] != 0) //if it's already occupied it's not an acceptable move so I go on continue; else { v[x] = maximizingPlayer; //I temporarily make a move on the free box (then it'll become empty once again) if (count == 0) { //means that I'm working with the first child, hence its address comes from the father and not from the brothers tmp->i = x / N; //saving the current move in the node tmp->j = x - N*(x / N); tmp->transboard = copyv(v); //and also the board count++; //increasing count in order not to belong to this case (first child) again } else { //if I already handled the first child if (!AllocateChildren(T, depth, x / N, x - N*(x / N), MIN, copyv(v))) { //I allocate the space for the brothers and their current values (board, i,j etc) printf("\nError"); exit(0); } tmp = tmp->rightbrothers; count++; } tmp->value = Max(tmp->value, alphabeta(&tmp, depth - 1, a, b, maximizingPlayer == 1 ? 2 : 1)); //recursive call that goes to the other part (minimizing part) of the function (if father is maximizing then the children are minimizing because between father and children the player changes) a = Max(a, tmp->value); //a is the best possible move for player1, so I have to choose the one with highest value v[x] = 0; if (a >= b) //pruning: if I see that the best possible move for player 1 has the same value of the best possibile move of player 2 I don't need to waste time to find another move nor to allocate more brothers break; } } return a; } else if (maximizingPlayer == MIN) { //same as above, just we're working with minimizing nodes NODE *tmp; unsigned short *v = NULL; unsigned int x, count; if (!AllocateChildren(T, depth, 0, 0, MAX, NULL)) { printf("\nError"); exit(0); } tmp = (*T)->leftchild; v = copyv((*T)->transboard); for (x = 0, count = 0; x < M*N; x++) { //for every possible move... if (v[x] != 0) continue; else { v[x] = maximizingPlayer; if (count == 0) { tmp->i = x / N; tmp->j = x - N*(x / N); tmp->transboard = copyv(v); count++; } else { if (!AllocateChildren(T, depth, x / N, x - N*(x / N), MAX, copyv(v))) { printf("\nError"); exit(0); } tmp = tmp->rightbrothers; count++; } tmp->value = Min(tmp->value, alphabeta(&tmp, depth - 1, a, b, maximizingPlayer == 1 ? 2 : 1)); //again, here the recursive call inverts minimizing with maximizing b = Min(b, tmp->value); //b instead chooses the minimum value because it has to pick the move that helps player1 less (=best move for player2 = optimal strategy) v[x] = 0; if (a >= b) //as before break; } } return b; } }
static void filter(VagueDenoiserContext *s, AVFrame *in, AVFrame *out) { int p, y, x, i, j; for (p = 0; p < s->nb_planes; p++) { const int height = s->planeheight[p]; const int width = s->planewidth[p]; const uint8_t *srcp8 = in->data[p]; const uint16_t *srcp16 = (const uint16_t *)in->data[p]; uint8_t *dstp8 = out->data[p]; uint16_t *dstp16 = (uint16_t *)out->data[p]; float *output = s->block; int h_low_size0 = width; int v_low_size0 = height; int nsteps_transform = s->nsteps; int nsteps_invert = s->nsteps; const float *input = s->block; if (!((1 << p) & s->planes)) { av_image_copy_plane(out->data[p], out->linesize[p], in->data[p], in->linesize[p], s->planewidth[p], s->planeheight[p]); continue; } if (s->depth <= 8) { for (y = 0; y < height; y++) { for (x = 0; x < width; x++) output[x] = srcp8[x]; srcp8 += in->linesize[p]; output += width; } } else { for (y = 0; y < height; y++) { for (x = 0; x < width; x++) output[x] = srcp16[x]; srcp16 += in->linesize[p] / 2; output += width; } } while (nsteps_transform--) { int low_size = (h_low_size0 + 1) >> 1; float *input = s->block; for (j = 0; j < v_low_size0; j++) { copy(input, s->in + NPAD, h_low_size0); transform_step(s->in, s->out, h_low_size0, low_size, s); copy(s->out + NPAD, input, h_low_size0); input += width; } low_size = (v_low_size0 + 1) >> 1; input = s->block; for (j = 0; j < h_low_size0; j++) { copyv(input, width, s->in + NPAD, v_low_size0); transform_step(s->in, s->out, v_low_size0, low_size, s); copyh(s->out + NPAD, input, width, v_low_size0); input++; } h_low_size0 = (h_low_size0 + 1) >> 1; v_low_size0 = (v_low_size0 + 1) >> 1; } if (s->method == 0) hard_thresholding(s->block, width, height, width, s->threshold, s->percent); else if (s->method == 1) soft_thresholding(s->block, width, height, width, s->threshold, s->percent, s->nsteps); else qian_thresholding(s->block, width, height, width, s->threshold, s->percent); s->hlowsize[0] = (width + 1) >> 1; s->hhighsize[0] = width >> 1; s->vlowsize[0] = (height + 1) >> 1; s->vhighsize[0] = height >> 1; for (i = 1; i < s->nsteps; i++) { s->hlowsize[i] = (s->hlowsize[i - 1] + 1) >> 1; s->hhighsize[i] = s->hlowsize[i - 1] >> 1; s->vlowsize[i] = (s->vlowsize[i - 1] + 1) >> 1; s->vhighsize[i] = s->vlowsize[i - 1] >> 1; } while (nsteps_invert--) { const int idx = s->vlowsize[nsteps_invert] + s->vhighsize[nsteps_invert]; const int idx2 = s->hlowsize[nsteps_invert] + s->hhighsize[nsteps_invert]; float * idx3 = s->block; for (i = 0; i < idx2; i++) { copyv(idx3, width, s->in + NPAD, idx); invert_step(s->in, s->out, s->tmp, idx, s); copyh(s->out + NPAD, idx3, width, idx); idx3++; } idx3 = s->block; for (i = 0; i < idx; i++) { copy(idx3, s->in + NPAD, idx2); invert_step(s->in, s->out, s->tmp, idx2, s); copy(s->out + NPAD, idx3, idx2); idx3 += width; } } if (s->depth <= 8) { for (y = 0; y < height; y++) { for (x = 0; x < width; x++) dstp8[x] = av_clip_uint8(input[x] + 0.5f); input += width; dstp8 += out->linesize[p]; } } else { for (y = 0; y < height; y++) { for (x = 0; x < width; x++) dstp16[x] = av_clip(input[x] + 0.5f, 0, s->peak); input += width; dstp16 += out->linesize[p] / 2; } } } }
void control(int b) { struct vector u; // Left button if (! map_mode) switch (selected_weapon) { case 0: if ((enable_mouse && button_read(SDL_BUTTON_LEFT)) || kread(gkeys[kc_fire].kc)) bot[b].but.canon=1; break; case 1: if ((enable_mouse && button_reset(SDL_BUTTON_LEFT)) || kreset(gkeys[kc_fire].kc)) bot[b].but.bomb=1; break; } else if ((enable_mouse && button_read(SDL_BUTTON_LEFT)) || kread(gkeys[kc_fire].kc)) { bot[b].u.x = ((xmouse-win_center_x)*(MAP_LEN/2)*TILE_LEN)/zoom+map_x*TILE_LEN; bot[b].u.y = ((win_center_y-ymouse)*(MAP_LEN/2)*TILE_LEN)/zoom+map_y*TILE_LEN; bot[b].u.z = z_ground(bot[b].u.x, bot[b].u.y, true); } // Right button if ((enable_mouse && button_reset(SDL_BUTTON_RIGHT)) || kreset(gkeys[kc_weapon].kc)) { if (abs(xmouse) < 2 && abs(ymouse) < 2) { if (! prompt_quit) prompt_quit = true; else quit_game = true; } selected_weapon ^= 1; } // Esc if (prompt_quit) { if (kreset(gkeys[kc_yes].kc)) quit_game = true; if (kreset(gkeys[kc_no].kc)) prompt_quit = false; } else if (kreset(gkeys[kc_esc].kc) && (bot[controlled_bot].camp!=-1 || !enable_resurrection || !resurrect())) { prompt_quit = true; } // Engine # define INCR .02 if (kread(gkeys[kc_motormore].kc) && bot[b].thrust <= 1.-INCR) bot[b].thrust += INCR; if (kread(gkeys[kc_motorless].kc) && bot[b].thrust >= INCR) bot[b].thrust -= INCR; # undef INCR // Views if (kreset(gkeys[kc_externview].kc)) { map_mode = false; view = next_external_view(view); snd_thrust=-1; } if (kreset(gkeys[kc_internview].kc)) { map_mode = false; if (view == VIEW_IN_PLANE) { view = VIEW_DOGFIGHT; } else { view = VIEW_IN_PLANE; snd_thrust=-1; } } if (kreset(gkeys[kc_travelview].kc)) { float zs; map_mode = false; view = VIEW_STANDING; copyv(&obj[0].pos,&obj[bot[viewed_bot].vion].rot.x); mulv(&obj[0].pos,300+drand48()*600+extcam_dist); copyv(&u,&obj[bot[viewed_bot].vion].rot.y); mulv(&u,(drand48()-.5)*600); addv(&obj[0].pos,&u); copyv(&u,&obj[bot[viewed_bot].vion].rot.z); mulv(&u,(drand48()-.5)*600); addv(&obj[0].pos,&u); addv(&obj[0].pos,&obj[bot[viewed_bot].vion].pos); if (obj[0].pos.z<(zs=z_ground(obj[0].pos.x,obj[0].pos.y, false)+100)) obj[0].pos.z=zs; snd_thrust=-1; } if (kreset(gkeys[kc_nextbot].kc)) { if (view == VIEW_ANYTHING_CHEAT) { if (++viewed_obj >= nb_obj) viewed_obj = 0; } else if (view == VIEW_DOGFIGHT) { next_dog_bot(); } else { do { if (++viewed_bot>=NBBOT) viewed_bot=0; } while (!enable_view_enemy && bot[viewed_bot].camp!=camp); // pas controlled_bot.camp car peut etre tue snd_thrust=-1; if (bot[viewed_bot].camp==-1) playsound(VOICE_MOTOR, SAMPLE_FEU, 1., &voices_in_my_head, true, true); } } if (kreset(gkeys[kc_prevbot].kc)) { if (view == VIEW_ANYTHING_CHEAT) { if (--viewed_obj<0) viewed_obj = nb_obj-1; } else if (view == VIEW_DOGFIGHT) { prev_dog_bot(); } else { do { if (--viewed_bot<0) viewed_bot=NBBOT-1; } while (!enable_view_enemy && bot[viewed_bot].camp!=camp); snd_thrust=-1; if (bot[viewed_bot].camp==-1) playsound(VOICE_MOTOR, SAMPLE_FEU, 1., &voices_in_my_head, true, true); } } if (kreset(gkeys[kc_mybot].kc)) { if (view != VIEW_DOGFIGHT) { viewed_bot = b; snd_thrust = -1; } else { float d; int DBi, DBm; next_dog_bot(); d=DogBotDist; DBi=DogBot; DBm=DogBot; do { next_dog_bot(); if (DogBotDist<d && bot[DogBot].camp!=bot[controlled_bot].camp) { d=DogBotDist; DBm=DogBot; } } while (DogBot!=DBi); DogBot=DBm; DogBotDist=d; } } if (!accelerated_mode || frame_count > 64) { if (kread(gkeys[kc_zoomout].kc)) { if (! map_mode) extcam_dist += 10.; else zoom += win_center_x/6; } if (kread(gkeys[kc_zoomin].kc)) { if (! map_mode && extcam_dist > 10.) extcam_dist -= 10.; else if ((zoom -= win_center_x/6) < win_center_x) zoom = win_center_x; } if (kread(gkeys[kc_riseview].kc)) { if (! map_mode) { if ((sight_teta -= .2) < -M_PI) sight_teta += 2*M_PI; } else if ((map_y += 1 + (3*win_width)/zoom) > MAP_LEN/2) { map_y = MAP_LEN/2; } } if (kread(gkeys[kc_lowerview].kc)) { if (! map_mode) { if ((sight_teta += .2) > M_PI) sight_teta -= 2*M_PI; } else if ((map_y -= 1 + (3*win_width)/zoom) < -MAP_LEN/2) { map_y = -MAP_LEN/2; } } if (kread(gkeys[kc_rightenview].kc)) { if (! map_mode) { if ((sight_phi -= .2) < -M_PI) sight_phi += 2*M_PI; } else if ((map_x += 1 + (3*win_width)/zoom) > MAP_LEN/2) { map_x = MAP_LEN/2; } } if (kread(gkeys[kc_leftenview].kc)) { if (! map_mode) { if ((sight_phi += .2) > M_PI) sight_phi -= 2*M_PI; } else if ((map_x -= 1 + (3*win_width)/zoom) < -MAP_LEN/2) { map_x = -MAP_LEN/2; } } } if (view != VIEW_DOGFIGHT) { if (kreset(gkeys[kc_towardview].kc)) { sight_teta = sight_phi = 0; } if (kreset(gkeys[kc_backview].kc)) { sight_teta = 0; sight_phi = M_PI; } if (kreset(gkeys[kc_leftview].kc)) { sight_teta = 0; sight_phi = M_PI*.5; } if (kreset(gkeys[kc_rightview].kc)) { sight_teta = 0; sight_phi = -M_PI*.5; } if (kreset(gkeys[kc_upview].kc)) { sight_teta = -M_PI/2; sight_phi = 0; } } else { view_predef = false; if (kread(gkeys[kc_towardview].kc)) { view_predef = true; sight_teta = sight_phi = 0; } if (kread(gkeys[kc_backview].kc)) { view_predef = true; sight_teta = 0; sight_phi = M_PI; } if (kread(gkeys[kc_leftview].kc)) { view_predef = true; sight_teta = 0; sight_phi = M_PI*.5; } if (kread(gkeys[kc_rightview].kc)) { view_predef = true; sight_teta = 0; sight_phi = -M_PI*.5; } if (kread(gkeys[kc_upview].kc)) { view_predef = true; sight_teta = -M_PI/2; sight_phi = 0; } if (! view_predef) sight_teta = sight_phi = 0; } view_instruments = kread(gkeys[kc_movetowardview].kc); // Commands if (kreset(gkeys[kc_gear].kc)) bot[b].but.gear^=1; if (kreset(gkeys[kc_flaps].kc)) { bot[b].but.flap^=1; playsound(VOICE_GEAR, SAMPLE_BIPBIP, 1., &obj[bot[b].vion].pos, false, false); } bot[b].but.brakes=kread(gkeys[kc_brakes].kc); if (kreset(gkeys[kc_business].kc)) bot[b].but.business = 1; if (kreset(gkeys[kc_autopilot].kc)) { autopilot = ! autopilot; playsound(VOICE_GEAR, SAMPLE_BIPBIP, 1., &obj[bot[b].vion].pos, false, false); if (autopilot) { bot[controlled_bot].target_speed = BEST_SPEED_FOR_CONTROL; bot[controlled_bot].target_rel_alt = 100. * ONE_METER; } } // Game control if (kreset(gkeys[kc_pause].kc)) { gtime_toggle(); game_paused = ! game_paused; } draw_high_scores = kread(gkeys[kc_highscores].kc); if (kreset(gkeys[kc_accelmode].kc)) { accelerated_mode = ! accelerated_mode; frame_count&=63; } if (kreset(gkeys[kc_basenav].kc)) { bot[b].u = obj[bot[b].babase].pos; } if (kreset(gkeys[kc_mapmode].kc)) { map_mode = ! map_mode; playsound(VOICE_GEAR, SAMPLE_BIPBIP3, 1., &voices_in_my_head, true, false); } if (kreset(gkeys[kc_suicide].kc) && bot[controlled_bot].camp!=-1) explode(bot[viewed_bot].vion, 0, "commited suicide"); if (kreset(gkeys[kc_markpos].kc)) bot[b].but.mark=1; // Cheats if (cheat_mode && kread(gkeys[kc_alti].kc)) { obj[bot[viewed_bot].vion].pos.z += 500; bot[viewed_bot].vionvit.z = 0; } if (cheat_mode && kreset(gkeys[kc_gunned].kc)) bot[viewed_bot].gunned=controlled_bot; if (!autopilot && !map_mode) { if (enable_mouse) { bot[b].xctl = ((xmouse-win_center_x)/(double)win_center_x); bot[b].yctl = ((ymouse-win_center_y)/(double)win_center_y); } else { int i=0; i=kread(gkeys[kc_left].kc); i+=kread(gkeys[kc_right].kc)<<1; i+=kread(gkeys[kc_down].kc)<<2; i+=kread(gkeys[kc_up].kc)<<3; if (i) { CtlSensActu += CtlSensitiv; if (i&1) bot[b].xctl-=CtlSensActu; if (i&2) bot[b].xctl+=CtlSensActu; if (i&4) bot[b].yctl-=CtlSensActu; if (i&8) bot[b].yctl+=CtlSensActu; } else CtlSensActu=0; if (bot[b].xctl<-1 || bot[b].xctl>1 || bot[b].yctl<-1 || bot[b].yctl>1) CtlSensActu=0; if (!(i&3)) bot[b].xctl*=CtlAmortis; if (!(i&12)) bot[b].yctl=CtlYequ+(bot[b].yctl-CtlYequ)*CtlAmortis; if (kread(gkeys[kc_center].kc)) { bot[b].xctl=0; bot[b].yctl=CtlYequ; if (kread(gkeys[kc_down].kc) && CtlYequ>-1) CtlYequ-=.02; if (kread(gkeys[kc_up].kc) && CtlYequ<1) CtlYequ+=.02; } } } else { // autopilot or map_mode if (autopilot) { robot_autopilot(b); } else { robot_safe(b, SAFE_LOW_ALT); } } CLAMP(bot[b].xctl, 1.); CLAMP(bot[b].yctl, 1.); }