00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "weapon_menu.h"
00023
00024 #include <sstream>
00025 #include <math.h>
00026 #include "interface.h"
00027 #include "../graphic/video.h"
00028 #include "../graphic/font.h"
00029 #include "../game/time.h"
00030 #include "../include/action_handler.h"
00031 #include "../include/app.h"
00032 #include "../interface/mouse.h"
00033 #include "../map/camera.h"
00034 #include "../map/map.h"
00035 #include "../team/team.h"
00036 #include "../team/teams_list.h"
00037 #include "../tool/point.h"
00038 #include "../tool/rectangle.h"
00039 #include "../tool/string_tools.h"
00040 #include "../tool/resource_manager.h"
00041 #include "../graphic/sprite.h"
00042 #include "../weapon/weapon.h"
00043 #include "../weapon/weapons_list.h"
00044
00045
00046
00047 const uint BUTTON_ICO_WIDTH = 58;
00048 const uint BUTTON_ICO_HEIGHT = 58;
00049
00050 const uint WEAPON_ICO_WIDTH = 48;
00051 const uint WEAPON_ICO_HEIGHT = 48;
00052
00053 const uint BUTTON_ICO_GAP = 8;
00054
00055
00056 const uint ICONS_DRAW_TIME = 600;
00057 const uint ICON_ZOOM_TIME = 150;
00058
00059 const double DEFAULT_ICON_SCALE = 0.7;
00060 const double MAX_ICON_SCALE = 1.1;
00061
00062 const uint BUTTON_WIDTH = (int)(BUTTON_ICO_GAP + BUTTON_ICO_WIDTH *
00063 (DEFAULT_ICON_SCALE+MAX_ICON_SCALE)/2);
00064
00065 const uint BUTTON_HEIGHT = (int)(BUTTON_ICO_GAP + BUTTON_ICO_HEIGHT *
00066 (DEFAULT_ICON_SCALE+MAX_ICON_SCALE)/2);
00067
00068 WeaponMenuItem::WeaponMenuItem(uint num_sort)
00069 {
00070 zoom_start_time = 0;
00071 weapon_type = num_sort;
00072 Reset();
00073 }
00074
00075 void WeaponMenuItem::Reset()
00076 {
00077 scale = DEFAULT_ICON_SCALE;
00078 zoom = false;
00079 dezoom = false;
00080 }
00081
00082 void WeaponMenuItem::ChangeZoom()
00083 {
00084 zoom_start_time = Time::GetInstance()->Read();
00085
00086 if(!zoom && scale < 1)
00087 {
00088 zoom = true;
00089 dezoom = false;
00090 }
00091 else
00092 {
00093 zoom = false;
00094 dezoom = true;
00095 }
00096 }
00097
00098 void WeaponMenuItem::ComputeScale()
00099 {
00100 double scale_range, time_range;
00101
00102 time_range = ((double)Time::GetInstance()->Read() - zoom_start_time) / ICON_ZOOM_TIME;
00103 if (time_range > 1)
00104 time_range = 1;
00105
00106 scale_range = sin (time_range * M_PI / 2) * (MAX_ICON_SCALE - DEFAULT_ICON_SCALE);
00107
00108 if(zoom)
00109 {
00110 scale = DEFAULT_ICON_SCALE + scale_range ;
00111
00112 if(time_range == 1)
00113 zoom = false;
00114 }
00115 else
00116 if(dezoom)
00117 {
00118 scale = MAX_ICON_SCALE - scale_range ;
00119
00120 if(time_range == 1)
00121 dezoom = false;
00122 }
00123 }
00124
00125 bool WeaponMenuItem::MouseOn(const Point2i &mousePos)
00126 {
00127 ComputeScale();
00128
00129 Point2i scaled( (int)(BUTTON_ICO_WIDTH * scale), (int)(BUTTON_ICO_HEIGHT * scale) );
00130 Rectanglei rect(Interface::GetInstance()->weapons_menu.GetPosition() - scaled/2 + position, scaled );
00131
00132 if( rect.Contains(mousePos) )
00133 return true;
00134 else
00135 {
00136 if(scale > DEFAULT_ICON_SCALE && !dezoom)
00137 dezoom = true;
00138 return false;
00139 }
00140 }
00141
00142
00143 void WeaponMenuItem::Draw()
00144 {
00145 Interface * interface = Interface::GetInstance();
00146
00147 ComputeScale();
00148 Point2i buttonCenter(interface->weapons_menu.GetPosition() + position);
00149 Point2i buttonSize( (int)(BUTTON_ICO_WIDTH * scale), (int)(BUTTON_ICO_HEIGHT * scale) );
00150 Point2i iconSize( (int)(WEAPON_ICO_WIDTH * scale), (int)(WEAPON_ICO_HEIGHT * scale) );
00151 std::ostringstream txt;
00152 int nb_bullets;
00153
00154 Sprite *button;
00155
00156 switch(weapon_type){
00157 case 1:
00158 button = interface->weapons_menu.my_button1;
00159 break ;
00160
00161 case 2:
00162 button = interface->weapons_menu.my_button2;
00163 break ;
00164
00165 case 3:
00166 button = interface->weapons_menu.my_button3;
00167 break ;
00168
00169 case 4:
00170 button = interface->weapons_menu.my_button4;
00171 break ;
00172
00173 case 5:
00174 button = interface->weapons_menu.my_button5;
00175 break ;
00176
00177 default:
00178 button = interface->weapons_menu.my_button1;
00179 break ;
00180 }
00181
00182
00183 button->Scale(scale, scale);
00184 button->Blit(AppWormux::GetInstance()->video.window, buttonCenter - buttonSize/2);
00185
00186
00187 weapon_icon->Scale(scale, scale);
00188 weapon_icon->Blit(AppWormux::GetInstance()->video.window, buttonCenter - iconSize/2);
00189
00190
00191 nb_bullets = ActiveTeam().ReadNbAmmos(weapon->GetName());
00192 txt.str ("");
00193 if (nb_bullets == INFINITE_AMMO)
00194 txt << ("§");
00195 else
00196 txt << nb_bullets;
00197
00198 (*Font::GetInstance(Font::FONT_TINY)).WriteLeftBottom(buttonCenter + Point2i(-1, 1) * iconSize / 2,
00199 txt.str(), white_color);
00200 }
00201
00202 WeaponsMenu::WeaponsMenu()
00203 {
00204 display = false;
00205 show = false;
00206 hide = false;
00207 nbr_weapon_type = 0;
00208 motion_start_time = Time::GetInstance()->Read();
00209
00210 Profile *res = resource_manager.LoadXMLProfile( "graphism.xml", false);
00211 my_button1 = new Sprite( resource_manager.LoadImage(res,"interface/button1_icon"));
00212 my_button1->cache.EnableLastFrameCache();
00213 my_button2 = new Sprite( resource_manager.LoadImage(res,"interface/button2_icon"));
00214 my_button2->cache.EnableLastFrameCache();
00215 my_button3 = new Sprite( resource_manager.LoadImage(res,"interface/button3_icon"));
00216 my_button3->cache.EnableLastFrameCache();
00217 my_button4 = new Sprite( resource_manager.LoadImage(res,"interface/button4_icon"));
00218 my_button4->cache.EnableLastFrameCache();
00219 my_button5 = new Sprite( resource_manager.LoadImage(res,"interface/button5_icon"));
00220 my_button5->cache.EnableLastFrameCache();
00221 resource_manager.UnLoadXMLProfile( res);
00222 }
00223
00224
00225 void WeaponsMenu::NewItem(Weapon* new_item, uint num_sort)
00226 {
00227 WeaponMenuItem item(num_sort);
00228 item.position.Clear();
00229 item.weapon = new_item;
00230
00231 item.weapon_icon = new Sprite(new_item->GetIcon());
00232 item.weapon_icon->cache.EnableLastFrameCache();
00233
00234 boutons.push_back (item);
00235
00236 if(num_sort>nbr_weapon_type)
00237 nbr_weapon_type = num_sort;
00238 }
00239
00240
00241 void WeaponsMenu::Show()
00242 {
00243 ShowGameInterface();
00244 Time * global_time = Time::GetInstance();
00245 if(display && hide)
00246 motion_start_time = global_time->Read() - (ICONS_DRAW_TIME - (global_time->Read()-motion_start_time));
00247 else
00248 motion_start_time = global_time->Read();
00249
00250 display = true;
00251 show = true;
00252 hide = false;
00253 }
00254
00255
00256 void WeaponsMenu::ComputeSize()
00257 {
00258 max_weapon = 0;
00259 uint nbr_current_type = 0;
00260
00261 iterator it=boutons.begin(), fin=boutons.end();
00262 for (; it != fin; ++it)
00263 {
00264 if(it != boutons.begin())
00265 if(((it-1)->weapon_type) != (it->weapon_type))
00266 {
00267 if(nbr_current_type > max_weapon)
00268 max_weapon = nbr_current_type;
00269 nbr_current_type = 0;
00270 }
00271 if(ActiveTeam().ReadNbAmmos(it->weapon->GetName())>0
00272 || ActiveTeam().ReadNbAmmos(it->weapon->GetName())==INFINITE_AMMO)
00273 nbr_current_type++;
00274 }
00275
00276 if(nbr_current_type > max_weapon)
00277 max_weapon = nbr_current_type;
00278 }
00279
00280 void WeaponsMenu::Hide()
00281 {
00282 if(display && show)
00283 motion_start_time = Time::GetInstance()->Read() - (ICONS_DRAW_TIME - (Time::GetInstance()->Read()-motion_start_time));
00284 else
00285 motion_start_time = Time::GetInstance()->Read();
00286
00287 hide = true;
00288 show = false;
00289 }
00290
00291 void WeaponsMenu::SwitchDisplay()
00292 {
00293 if(display && !hide)
00294 Hide();
00295 else
00296 Show();
00297 }
00298
00299 int WeaponsMenu::GetX() const
00300 {
00301 return AppWormux::GetInstance()->video.window.GetWidth()-GetWidth();
00302 }
00303
00304 int WeaponsMenu::GetY() const
00305 {
00306 return AppWormux::GetInstance()->video.window.GetHeight() - GetHeight() - Interface::GetInstance()->GetHeight();
00307 }
00308
00309 Point2i WeaponsMenu::GetPosition() const{
00310 return AppWormux::GetInstance()->video.window.GetSize() - GetSize() - Point2i(0, Interface::GetInstance()->GetHeight());
00311 }
00312
00313 int WeaponsMenu::GetWidth() const
00314 {
00315 return BUTTON_ICO_GAP + ((nbr_weapon_type +1) * BUTTON_WIDTH) ;
00316 }
00317
00318 int WeaponsMenu::GetHeight() const
00319 {
00320 return BUTTON_ICO_GAP + BUTTON_HEIGHT * max_weapon;
00321 }
00322
00323 Point2i WeaponsMenu::GetSize() const
00324 {
00325 return Point2i( BUTTON_ICO_GAP + ((nbr_weapon_type +1) * BUTTON_WIDTH), BUTTON_ICO_GAP + BUTTON_HEIGHT * max_weapon);
00326 }
00327
00328 bool WeaponsMenu::IsDisplayed() const
00329 {
00330 return display;
00331 }
00332
00333 void WeaponsMenu::Reset()
00334 {
00335 display = false;
00336 show = false;
00337 hide = false;
00338 motion_start_time = Time::GetInstance()->Read();
00339 }
00340
00341 void WeaponsMenu::ShowMotion(int nr_buttons,int button_no,iterator it,int column)
00342 {
00343 int delta_t=ICONS_DRAW_TIME/(2*nr_buttons);
00344 Time * global_time = Time::GetInstance();
00345
00346 if((global_time->Read() > motion_start_time + (delta_t*button_no))
00347 && (global_time->Read() < motion_start_time + (ICONS_DRAW_TIME/2)+(delta_t*(button_no))))
00348 {
00349 double delta_sin = -(asin((column+1.0)/(column+2.0)) - (M_PI/2));
00350
00351 uint tps = global_time->Read() - (motion_start_time + delta_t*button_no);
00352
00353 double tps_sin = ((double)tps * ((M_PI/2) + delta_sin)/(ICONS_DRAW_TIME/2));
00354
00355 it->position.x -= (int)(sin(tps_sin) * BUTTON_WIDTH * (column+2.0));
00356 it->position.x += (BUTTON_WIDTH * (column+1));
00357 }
00358 else
00359 if(global_time->Read() < motion_start_time + (delta_t*button_no))
00360 {
00361 it->position.x += (BUTTON_WIDTH * (column+1));
00362 }
00363
00364 if(global_time->Read() > motion_start_time + ICONS_DRAW_TIME)
00365 {
00366 show = false;
00367 }
00368 }
00369
00370 bool WeaponsMenu::HideMotion(int nr_buttons,int button_no,iterator it,int column)
00371 {
00372 int delta_t=ICONS_DRAW_TIME/(2*nr_buttons);
00373
00374 Time * global_time = Time::GetInstance();
00375 if((global_time->Read() > motion_start_time + (delta_t*(nr_buttons-button_no)))
00376 && (global_time->Read() < motion_start_time + (ICONS_DRAW_TIME/2)+(delta_t*(nr_buttons-button_no))))
00377 {
00378 double delta_sin = -(asin((column+1.0)/(column+2.0)) - (M_PI/2));
00379
00380 uint tps = global_time->Read() - (motion_start_time + delta_t*(nr_buttons-button_no));
00381 double tps_sin = ((double)tps * ((M_PI/2) + delta_sin)/(ICONS_DRAW_TIME/2));
00382 tps_sin = ((M_PI/2) + delta_sin) - tps_sin;
00383
00384 it->position.x -= (int)(sin(tps_sin) * BUTTON_WIDTH * (column+2.0));
00385 it->position.x += BUTTON_WIDTH * (column+1);
00386 }
00387 else
00388 if(global_time->Read() > motion_start_time + (delta_t*(nr_buttons-button_no)))
00389 {
00390 it->position.x += BUTTON_WIDTH * (column+1);
00391 it->Reset();
00392 }
00393
00394 if(global_time->Read() > motion_start_time + ICONS_DRAW_TIME)
00395 {
00396 hide = false;
00397 display = false;
00398 return true;
00399 }
00400
00401 return false;
00402 }
00403
00404 void WeaponsMenu::Draw()
00405 {
00406 if (!display)
00407 return;
00408
00409 MouseOver(Mouse::GetInstance()->GetWorldPosition() - camera.GetPosition());
00410 ComputeSize();
00411
00412 uint nr_buttons = max_weapon * nbr_weapon_type;
00413 uint button_no = 0;
00414 uint current_type = 0;
00415
00416 iterator it=boutons.begin(), fin=boutons.end();
00417 for (it=boutons.begin(); it != fin; ++it)
00418 {
00419 if(!it->weapon->CanBeUsedOnClosedMap()
00420 && !world.EstOuvert())
00421 continue;
00422
00423 if(ActiveTeam().ReadNbAmmos(it->weapon->GetName())<=0
00424 && ActiveTeam().ReadNbAmmos(it->weapon->GetName())!=INFINITE_AMMO)
00425 continue;
00426
00427 if(it->weapon_type!=current_type)
00428 {
00429 button_no = 0;
00430 current_type = it->weapon_type;
00431 }
00432
00433 int column = nbr_weapon_type - current_type;
00434 int row = button_no;
00435
00436 it->position.x = GetWidth() - (int)(BUTTON_WIDTH * (column+0.5));
00437 it->position.y = BUTTON_ICO_GAP + (row * BUTTON_HEIGHT);
00438
00439 if(show)
00440 ShowMotion(nr_buttons,(column * max_weapon) + row,it,column);
00441 else
00442 if(hide)
00443 if(HideMotion(nr_buttons,(column * max_weapon) + row,it,column))
00444 return;
00445
00446 it->Draw();
00447 button_no++;
00448 }
00449 }
00450
00451 void WeaponsMenu::MouseOver(const Point2i &mousePos)
00452 {
00453 static int bouton_sous_souris = -1;
00454
00455
00456 int button_no=0;
00457 int nv_bouton_sous_souris=-1;
00458 iterator it=boutons.begin(), fin=boutons.end();
00459 Interface::GetInstance()->weapon_under_cursor = NULL;
00460 for (; it != fin; ++it)
00461 {
00462 if(it->MouseOn(mousePos))
00463 {
00464 Interface::GetInstance()->weapon_under_cursor = it->weapon;
00465 nv_bouton_sous_souris = button_no;
00466 if(button_no != bouton_sous_souris)
00467 {
00468 it->ChangeZoom();
00469 }
00470 }
00471 else
00472 if(button_no == bouton_sous_souris)
00473 {
00474 it->ChangeZoom();
00475 }
00476 button_no++;
00477 }
00478 bouton_sous_souris = nv_bouton_sous_souris;
00479 }
00480
00481 bool WeaponsMenu::ActionClic(const Point2i &mousePos)
00482 {
00483 if (!display) return false;
00484
00485 iterator it=boutons.begin(), fin=boutons.end();
00486 for (; it != fin; ++it)
00487 {
00488 if( it->MouseOn(mousePos) )
00489 {
00490 ActionHandler::GetInstance()->NewAction (new Action(Action::ACTION_CHANGE_WEAPON,
00491 it -> weapon -> GetType()));
00492 SwitchDisplay();
00493 return true;
00494 }
00495 }
00496 return false;
00497 }