//清除边界--闪烁时调用 void Clr_Border(S_Show_Data *pDst, INT8U Area_No) { INT16U Area_Width, Area_Height;//, Border_Width, Border_Height; INT8U Height; S_Point P0; Area_Width = Get_Area_Width(Area_No); //分区的宽度和高度 Area_Height = Get_Area_Height(Area_No); //Width = Get_Area_Border_Width(Area_No); Height = Get_Area_Border_Height(Area_No); //Border_Width = Get_Area_Border_Width(Area_No); //Border_Height = Get_Area_Border_Height(Area_No); P0.X = 0; P0.Y = 0; Fill_Rect(pDst, Area_No, &P0, Area_Width, Height, 0); P0.Y = Area_Height - Height; Fill_Rect(pDst, Area_No, &P0, Area_Width, Height, 0); P0.Y = 0; Fill_Rect(pDst, Area_No, &P0, Height, Area_Height, 0); P0.X = Area_Width - Height; Fill_Rect(pDst, Area_No, &P0, Height, Area_Height, 0); }
void Assemble_Combat_Picture (int mask) { int MapBrick; int line, col; int i; static float TimeSinceLastFPSUpdate=10; static int FPS_Displayed=1; SDL_Rect TargetRectangle; SDL_Rect TxtRect; finepoint pos, vect; float len; bool vis = TRUE; grob_point upleft, downright; #define UPDATE_FPS_HOW_OFTEN 0.75 DebugPrintf (2, "\nvoid Assemble_Combat_Picture(...): Real function call confirmed."); SDL_SetClipRect (ne_screen , &User_Rect); if ( !GameConfig.AllMapVisible ) Fill_Rect (User_Rect, Black); if ( (mask & SHOW_FULL_MAP) != 0 ) { upleft.x = -5; upleft.y = -5; downright.x = CurLevel->xlen + 5; downright.y = CurLevel->ylen + 5; } else { upleft.x = Me.pos.x - 6; upleft.y = Me.pos.y - 5; downright.x = Me.pos.x + 7; downright.y = Me.pos.y + 5; } for (line = (int)upleft.y; line < (int)downright.y; line++) { for (col = (int)upleft.x; col < (int)downright.x; col++) { vis = TRUE; if ( !GameConfig.AllMapVisible && ( (mask & SHOW_FULL_MAP) == 0x0) ) { pos.x = col; pos.y = line; vect.x = Me.pos.x - pos.x; vect.y = Me.pos.y - pos.y; len = sqrt( vect.x * vect.x + vect.y * vect.y) + 0.01; vect.x /= len; vect.y /= len; if (len > 0.5) { pos.x += vect.x; pos.y += vect.y; } if ( !IsVisible (&pos) ) continue; } MapBrick = GetMapBrick( CurLevel, col , line ); TargetRectangle.x = UserCenter_x + (int)rint( (-Me.pos.x+1.0*col-0.5 )*Block_Rect.w); TargetRectangle.y = UserCenter_y + (int)rint( (-Me.pos.y+1.0*line-0.5 )*Block_Rect.h); SDL_BlitSurface( MapBlockSurfacePointer[CurLevel->color][MapBrick], NULL, ne_screen, &TargetRectangle); } // for(col) } // for(line) // if we don't use Fullscreen mode, we have to clear the text-background manually // for the info-line text: TxtRect.x = Full_User_Rect.x; TxtRect.y = Full_User_Rect.y+Full_User_Rect.h - FontHeight (Font0_BFont); TxtRect.h = FontHeight (Font0_BFont); TxtRect.w = Full_User_Rect.w; SDL_SetClipRect (ne_screen, &TxtRect); if (!GameConfig.FullUserRect) SDL_FillRect(ne_screen, &TxtRect, 0); if ( GameConfig.Draw_Position ) { PrintStringFont( ne_screen , Font0_BFont , Full_User_Rect.x+Full_User_Rect.w/6 , Full_User_Rect.y+Full_User_Rect.h - FontHeight( Font0_BFont ), "GPS: X=%d Y=%d Lev=%d" , (int) rintf(Me.pos.x) , (int) rintf(Me.pos.y) , CurLevel->levelnum ); } if (!(mask & ONLY_SHOW_MAP) ) { if ( GameConfig.Draw_Framerate ) { TimeSinceLastFPSUpdate += Frame_Time(); if ( TimeSinceLastFPSUpdate > UPDATE_FPS_HOW_OFTEN ) { FPS_Displayed=(int)(1.0/Frame_Time()); TimeSinceLastFPSUpdate=0; } PrintStringFont( ne_screen , Font0_BFont , Full_User_Rect.x , Full_User_Rect.y+Full_User_Rect.h - FontHeight( Font0_BFont ), "FPS: %d " , FPS_Displayed ); } if ( GameConfig.Draw_Energy ) { PrintStringFont( ne_screen , Font0_BFont , Full_User_Rect.x+Full_User_Rect.w/2 , Full_User_Rect.y+Full_User_Rect.h - FontHeight( Font0_BFont ), "Energy: %d" , (int)Me.energy); } if (GameConfig.Draw_DeathCount) { PrintStringFont( ne_screen , Font0_BFont , Full_User_Rect.x+2*Full_User_Rect.w/3 , Full_User_Rect.y+Full_User_Rect.h - FontHeight( Font0_BFont ), "Deathcount: %d", (int)DeathCount ); } SDL_SetClipRect (ne_screen, &User_Rect); // make sure Ashes are displayed _before_ droids, so that they are _under_ them! for (i = 0; i < NumEnemys ; i++) if ( (AllEnemys[i].status == TERMINATED) && (AllEnemys[i].levelnum == CurLevel->levelnum) ) { if (IsVisible (&(AllEnemys[i].pos) ) ) PutAshes (AllEnemys[i].pos.x, AllEnemys[i].pos.y); } for (i = 0; i < NumEnemys ; i++) if ( (AllEnemys[i].levelnum != CurLevel->levelnum) || (AllEnemys[i].status == OUT) || (AllEnemys[i].status == TERMINATED) ) continue; else PutEnemy (i , -1 , -1 ); if (Me.energy > 0) PutInfluence ( -1 , -1 ); for (i = 0; i < (MAXBULLETS); i++) if (AllBullets[i].type != OUT) PutBullet (i); for (i = 0; i < (MAXBLASTS); i++) if (AllBlasts[i].type != OUT) PutBlast (i); } // At this point we are done with the drawing procedure // and all that remains to be done is updating the screen. if ( mask & DO_SCREEN_UPDATE ) { SDL_UpdateRect (ne_screen, User_Rect.x, User_Rect.y, User_Rect.w, User_Rect.h); SDL_UpdateRect (ne_screen, TxtRect.x, TxtRect.y, TxtRect.w, TxtRect.h); } SDL_SetClipRect (ne_screen, NULL); return; } // void Assemble_Combat_Picture(...)
/*----------------------------------------------------------------- * @Desc: play takeover-game against a druid * * @Ret: TRUE/FALSE: user has won/lost * *-----------------------------------------------------------------*/ int Takeover (int enemynum) { int row; int FinishTakeover = FALSE; static int RejectEnergy = 0; /* your energy if you're rejected */ char *message; SDL_Rect buf; Uint32 now; /* Prevent distortion of framerate by the delay coming from * the time spend in the menu. */ Activate_Conservative_Frame_Computation (); // release fire keys SpacePressedR(); MouseLeftPressedR(); // Takeover game always uses Classic User_Rect: Copy_Rect (User_Rect, buf); Copy_Rect (Classic_User_Rect, User_Rect); DisplayBanner (NULL, NULL, BANNER_FORCE_UPDATE ); Fill_Rect (User_Rect, to_bg_color); Me.status = MOBILE; /* the new status _after_ the takeover game */ SDL_ShowCursor (SDL_DISABLE); // no mouse-cursor in takeover game! show_droid_info ( Me.type, -1 , 0); show_droid_portrait (Cons_Droid_Rect, Me.type, DROID_ROTATION_TIME, UPDATE); while (!FirePressedR()) show_droid_portrait (Cons_Droid_Rect, Me.type, DROID_ROTATION_TIME, 0); show_droid_info ( AllEnemys[enemynum].type, -2 ,0); show_droid_portrait (Cons_Droid_Rect, AllEnemys[enemynum].type, DROID_ROTATION_TIME, UPDATE); while (!FirePressedR()) show_droid_portrait (Cons_Droid_Rect, AllEnemys[enemynum].type, DROID_ROTATION_TIME, 0); SDL_BlitSurface (takeover_bg_pic, NULL, ne_screen, NULL); DisplayBanner (NULL, NULL, BANNER_FORCE_UPDATE ); while (!FinishTakeover) { /* Init Color-column and Capsule-Number for each opponenet and your color */ for (row = 0; row < NUM_LINES; row++) { DisplayColumn[row] = (row % 2); CapsuleCountdown[GELB][0][row] = -1; CapsuleCountdown[VIOLETT][0][row] = -1; } /* for row */ YourColor = GELB; OpponentColor = VIOLETT; CapsuleCurRow[GELB] = 0; CapsuleCurRow[VIOLETT] = 0; DroidNum = enemynum; OpponentType = AllEnemys[enemynum].type; NumCapsules[YOU] = 3 + ClassOfDruid (Me.type); NumCapsules[ENEMY] = 4 + ClassOfDruid (OpponentType); InventPlayground (); ShowPlayground (); ChooseColor (); PlayGame (); /* Ausgang beurteilen und returnen */ if (InvincibleMode || (LeaderColor == YourColor)) { Takeover_Game_Won_Sound (); if (Me.type == DRUID001) { RejectEnergy = Me.energy; PreTakeEnergy = Me.energy; } // We provide some security agains too high energy/health values gained // by very rapid successions of successful takeover attempts if (Me.energy > Druidmap[DRUID001].maxenergy) Me.energy = Druidmap[DRUID001].maxenergy; if (Me.health > Druidmap[DRUID001].maxenergy) Me.health = Druidmap[DRUID001].maxenergy; // We allow to gain the current energy/full health that was still in the // other droid, since all previous damage must be due to fighting damage, // and this is exactly the sort of damage can usually be cured in refreshes. Me.energy += AllEnemys[enemynum].energy; Me.health += Druidmap[OpponentType].maxenergy; Me.type = AllEnemys[enemynum].type; RealScore += Druidmap[OpponentType].score; DeathCount += OpponentType * OpponentType; // quadratic "importance", max=529 AllEnemys[enemynum].status = OUT; // removed droid silently (no blast!) if (LeaderColor != YourColor) /* only won because of InvincibleMode */ message = "You cheat"; else /* won the proper way */ message = "Complete"; FinishTakeover = TRUE; } /* LeaderColor == YourColor */ else if (LeaderColor == OpponentColor) { // you lost, but enemy is killed too --> blast it! AllEnemys[enemynum].energy = -1.0; /* to be sure */ Takeover_Game_Lost_Sound (); if (Me.type != DRUID001) { message = "Rejected"; Me.type = DRUID001; Me.energy = RejectEnergy; } else { message = "Burnt Out"; Me.energy = 0; } FinishTakeover = TRUE; } /* LeadColor == OpponentColor */ else { Takeover_Game_Deadlock_Sound (); message = "Deadlock"; } /* LeadColor == REMIS */ DisplayBanner (message, NULL , 0 ); ShowPlayground (); now = SDL_GetTicks(); while ((!FirePressedR()) && (SDL_GetTicks() - now < SHOW_WAIT) ) SDL_Delay(1); } /* while !FinishTakeover */ // restore User_Rect Copy_Rect (buf, User_Rect); ClearGraphMem(); SDL_Flip(ne_screen); if (LeaderColor == YourColor) return TRUE; else return FALSE; } /* Takeover() */
/*@Function============================================================ @Desc: PutBullet: draws a Bullet into the combat window. The only parameter given is the number of the bullet in the AllBullets array. Everything else is computed in here. @Ret: void * $Function----------------------------------------------------------*/ void PutBullet (int BulletNummer) { Bullet CurBullet = &AllBullets[BulletNummer]; SDL_Rect dst; // SDL_Surface *tmp; int PhaseOfBullet; int i; DebugPrintf (2, "\nvoid PutBullet(int BulletNummer): real function call confirmed.\n"); //-------------------- // in case our bullet is of the type "FLASH", we only // draw a big white or black rectangle right over the // combat window, white for even frames and black for // odd frames. if (CurBullet->type == FLASH) { // Now the whole window will be filled with either white // or black each frame until the flash is over. (Flash // deletion after some time is done in CheckBulletCollisions.) if ( CurBullet->time_in_seconds <= FLASH_DURATION/4) Fill_Rect (User_Rect, Flash_Light); else if (CurBullet->time_in_seconds <= FLASH_DURATION/2) Fill_Rect (User_Rect, Flash_Dark); else if (CurBullet->time_in_seconds <= 3*FLASH_DURATION/4) Fill_Rect (User_Rect, Flash_Light); else if (CurBullet->time_in_seconds <= FLASH_DURATION) Fill_Rect (User_Rect, Flash_Dark); return; } // if type == FLASH PhaseOfBullet = (CurBullet->time_in_seconds * Bulletmap[ CurBullet->type ].phase_changes_per_second ); PhaseOfBullet = PhaseOfBullet % Bulletmap[CurBullet->type].phases ; // DebugPrintf( 0 , "\nPhaseOfBullet: %d.", PhaseOfBullet ); #define ONE_ROTATION_ONLY #ifdef ONE_ROTATION_ONLY //-------------------- // Maybe it's the first time this bullet is displayed. But then, the images // of the rotated bullet in all phases are not yet attached to the bullet. // Then, we'll have to generate these // //if ( CurBullet->time_in_frames == 1 ) if ( !CurBullet->Surfaces_were_generated ) { for ( i=0; i<Bulletmap[ CurBullet->type ].phases ; i++ ) { CurBullet->SurfacePointer[i] = rotozoomSurface( Bulletmap[CurBullet->type].SurfacePointer[ i ] , CurBullet->angle , 1.0 , FALSE ); } DebugPrintf( 1 , "\nvoid PutBullet(i): This was the first time for this bullet, so images were generated... angle=%f" , CurBullet->angle); CurBullet->Surfaces_were_generated=TRUE; } // WARNING!!! PAY ATTENTION HERE!! After the rotozoom was applied to the image, it is NO // LONGER of dimension Block_Rect.w times Block_Rect.h, but of the dimesions of the smallest // rectangle containing the full rotated Block_Rect.h x Block_Rect.w rectangle!!! // This has to be taken into account when calculating the target position for the // blit of these surfaces!!!! dst.x = UserCenter_x - (Me.pos.x-CurBullet->pos.x)*Block_Rect.w-CurBullet->SurfacePointer[ PhaseOfBullet ]->w/2; dst.y = UserCenter_y - (Me.pos.y-CurBullet->pos.y)*Block_Rect.w-CurBullet->SurfacePointer[ PhaseOfBullet ]->h/2; SDL_BlitSurface( CurBullet->SurfacePointer[ PhaseOfBullet ] , NULL, ne_screen , &dst ); #else tmp = rotozoomSurface( Bulletmap[CurBullet->type].SurfacePointer[ PhaseOfBullet ] , CurBullet->angle , 1.0 , FALSE ); // WARNING!!! PAY ATTENTION HERE!! After the rotozoom was applied to the image, it is NO // LONGER of dimension Block_Rect.w times Block_Rect.h, but of the dimesions of the smallest // rectangle containing the full rotated Block_Rect.h x Block_Rect.w rectangle!!! // This has to be taken into account when calculating the target position for the // blit of these surfaces!!!! dst.x = UserCenter_x - (Me.pos.x-CurBullet->pos.x)*Block_Rect.w-CurBullet->SurfacePointer[ PhaseOfBullet ]->w/2; dst.y = UserCenter_y - (Me.pos.y-CurBullet->pos.y)*Block_Rect.w-CurBullet->SurfacePointer[ PhaseOfBullet ]->h/2; SDL_BlitSurface( tmp , NULL, ne_screen , &dst ); SDL_FreeSurface( tmp ); #endif DebugPrintf ( 1 , "\nvoid PutBullet(int BulletNummer): end of function reched.\n"); }; // void PutBullet (int Bulletnumber )