Advertisement
qtinio

hmmm zoba tera michalak

Apr 24th, 2019
260
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 31.80 KB | None | 0 0
  1. /****************************************************
  2. Wirtualne zespoly robocze - przykladowy projekt w C++
  3. Do zadań dotyczących współpracy, ekstrapolacji i
  4. autonomicznych obiektów
  5. ****************************************************/
  6.  
  7. #include <windows.h>
  8. #include <math.h>
  9. #include <time.h>
  10. #include <string>
  11. #include <gl\gl.h>
  12. #include <gl\glu.h>
  13. #include <iterator>
  14. #include <map>
  15. using namespace std;
  16.  
  17. #include "objects.h"
  18. #include "graphics.h"
  19. #include "net.h"
  20.  
  21.  
  22. bool if_different_skills = true; // czy zró¿nicowanie umiejêtnoœci (dla ka¿dego pojazdu losowane s¹ umiejêtnoœci
  23. // zbierania gotówki i paliwa)
  24.  
  25. FILE *f = fopen("vct_log.txt", "w"); // plik do zapisu informacji testowych
  26.  
  27. MovableObject *my_vehicle; // Object przypisany do tej aplikacji
  28.  
  29. Terrain terrain;
  30. map<int, MovableObject*> network_vehicles;
  31. // ****************************************************************************
  32. int tim = -1;
  33.  
  34. float fDt; // sredni czas pomiedzy dwoma kolejnymi cyklami symulacji i wyswietlania
  35. long VW_cycle_time, counter_of_simulations; // zmienne pomocnicze potrzebne do obliczania fDt
  36. long start_time = clock(); // czas od poczatku dzialania aplikacji
  37. long group_existing_time = clock(); // czas od pocz¹tku istnienia grupy roboczej (czas od uruchom. pierwszej aplikacji)
  38.  
  39. multicast_net *multi_reciv; // wsk do obiektu zajmujacego sie odbiorem komunikatow
  40. multicast_net *multi_send; // -||- wysylaniem komunikatow
  41.  
  42. HANDLE threadReciv; // uchwyt w¹tku odbioru komunikatów
  43. extern HWND main_window;
  44. CRITICAL_SECTION m_cs; // do synchronizacji wątków
  45.  
  46. bool SHIFT_pressed = 0;
  47. bool CTRL_pressed = 0;
  48. bool ALT_pressed = 0;
  49. bool L_pressed = 0;
  50. //bool rejestracja_uczestnikow = true; // rejestracja trwa do momentu wziêcia przedmiotu przez któregokolwiek uczestnika,
  51. // w przeciwnym razie trzeba by przesy³aæ ca³y state œrodowiska nowicjuszowi
  52.  
  53. // Parametry widoku:
  54. extern ViewParameters par_view;
  55.  
  56. bool mouse_control = 0; // sterowanie pojazdem za pomoc¹ myszki
  57. int cursor_x, cursor_y; // polo¿enie kursora myszki w chwili w³¹czenia sterowania
  58.  
  59. extern float TransferSending(int ID_receiver, int transfer_type, float transfer_value);
  60. // *********************************************
  61. int zaznaczony_id = -1;
  62. int procent = 50;
  63. // ***********************************************
  64. enum frame_types {
  65. OBJECT_STATE, ITEM_TAKING, ITEM_RENEWAL, COLLISION, TRANSFER, ZAPRASZALAK, PRZYJAZNIALAK, NEGOCJALAK, AKCEPTOWALAK
  66. };
  67.  
  68. enum transfer_types { MONEY, FUEL};
  69.  
  70. struct Frame
  71. {
  72. int iID;
  73. int frame_type;
  74. ObjectState state;
  75.  
  76. int iID_receiver; // nr ID adresata wiadomoœci (pozostali uczestnicy powinni wiadomoœæ zignorowaæ)
  77.  
  78. int item_number; // nr przedmiotu, który zosta³ wziêty lub odzyskany
  79. Vector3 vdV_collision; // wektor prêdkoœci wyjœciowej po kolizji (uczestnik o wskazanym adresie powinien
  80. // przyj¹æ t¹ prêdkoœæ)
  81.  
  82. int transfer_type; // gotówka, paliwo
  83. float transfer_value; // iloœæ gotówki lub paliwa
  84. int team_number;
  85.  
  86. long existing_time; // czas jaki uplyn¹³ od uruchomienia programu
  87. };
  88.  
  89.  
  90. //******************************************
  91. // Funkcja obs³ugi w¹tku odbioru komunikatów
  92. DWORD WINAPI ReceiveThreadFunction(void *ptr)
  93. {
  94. multicast_net *pmt_net = (multicast_net*)ptr; // wskaŸnik do obiektu klasy multicast_net
  95. int size; // liczba bajtów ramki otrzymanej z sieci
  96. Frame frame;
  97. ObjectState state;
  98.  
  99. while (1)
  100. {
  101. size = pmt_net->reciv((char*)&frame, sizeof(Frame)); // oczekiwanie na nadejœcie ramki
  102. // Lock the Critical section
  103. EnterCriticalSection(&m_cs); // wejście na ścieżkę krytyczną - by inne wątki (np. główny) nie współdzielił
  104.  
  105. switch (frame.frame_type)
  106. {
  107. case OBJECT_STATE: // podstawowy typ ramki informuj¹cej o stanie obiektu
  108. {
  109. state = frame.state;
  110. //fprintf(f,"odebrano state iID = %d, ID dla mojego obiektu = %d\n",state.iID,my_vehicle->iID);
  111. if ((frame.iID != my_vehicle->iID)) // jeœli to nie mój w³asny Object
  112. {
  113.  
  114. if ((network_vehicles.size() == 0) || (network_vehicles[frame.iID] == NULL)) // nie ma jeszcze takiego obiektu w tablicy -> trzeba go stworzyæ
  115. {
  116. MovableObject *ob = new MovableObject(&terrain);
  117. ob->iID = frame.iID;
  118. network_vehicles[frame.iID] = ob;
  119. if (frame.existing_time > group_existing_time) group_existing_time = frame.existing_time;
  120. ob->ChangeState(state); // aktualizacja stanu obiektu obcego
  121. terrain.InsertObjectIntoSectors(ob);
  122. // wys³anie nowemu uczestnikowi informacji o wszystkich wziêtych przedmiotach:
  123. for (long i = 0; i < terrain.number_of_items; i++)
  124. if ((terrain.p[i].to_take == 0) && (terrain.p[i].if_taken_by_me))
  125. {
  126. Frame frame;
  127. frame.frame_type = ITEM_TAKING;
  128. frame.item_number = i;
  129. frame.state = my_vehicle->State();
  130. frame.iID = my_vehicle->iID;
  131. int iSIZE = multi_send->send((char*)&frame, sizeof(Frame));
  132. }
  133.  
  134. }
  135. else if ((network_vehicles.size() > 0) && (network_vehicles[frame.iID] != NULL))
  136. {
  137. terrain.DeleteObjectsFromSectors(network_vehicles[frame.iID]);
  138. network_vehicles[frame.iID]->ChangeState(state); // aktualizacja stanu obiektu obcego
  139. terrain.InsertObjectIntoSectors(network_vehicles[frame.iID]);
  140. }
  141.  
  142. }
  143. break;
  144. }
  145. case ITEM_TAKING: // frame informuj¹ca, ¿e ktoœ wzi¹³ przedmiot o podanym numerze
  146. {
  147. state = frame.state;
  148. if ((frame.item_number < terrain.number_of_items) && (frame.iID != my_vehicle->iID))
  149. {
  150. terrain.p[frame.item_number].to_take = 0;
  151. terrain.p[frame.item_number].if_taken_by_me = 0;
  152. }
  153. break;
  154. }
  155. case ITEM_RENEWAL: // frame informujaca, ¿e przedmiot wczeœniej wziêty pojawi³ siê znowu w tym samym miejscu
  156. {
  157. if (frame.item_number < terrain.number_of_items)
  158. terrain.p[frame.item_number].to_take = 1;
  159. break;
  160. }
  161. case COLLISION: // frame informuj¹ca o tym, ¿e Object uleg³ kolizji
  162. {
  163. if (frame.iID_receiver == my_vehicle->iID) // ID pojazdu, który uczestniczy³ w kolizji zgadza siê z moim ID
  164. {
  165. my_vehicle->vdV_collision = frame.vdV_collision; // przepisuje poprawkê w³asnej prêdkoœci
  166. my_vehicle->iID_collider = my_vehicle->iID; // ustawiam nr. kolidujacego jako w³asny na znak, ¿e powinienem poprawiæ prêdkoœæ
  167. }
  168. break;
  169. }
  170. case TRANSFER: // frame informuj¹ca o przelewie pieniê¿nym lub przekazaniu towaru
  171. {
  172. if (frame.iID_receiver == my_vehicle->iID) // ID pojazdu, ktory otrzymal przelew zgadza siê z moim ID
  173. {
  174. if (frame.transfer_type == MONEY)
  175. my_vehicle->state.money += frame.transfer_value;
  176. else if (frame.transfer_type == FUEL)
  177. my_vehicle->state.amount_of_fuel += frame.transfer_value;
  178.  
  179. // nale¿a³oby jeszcze przelew potwierdziæ (w UDP ramki mog¹ byæ gubione!)
  180. }
  181. break;
  182. }
  183. case NEGOCJALAK:
  184. {
  185. if (frame.iID_receiver == my_vehicle->iID && frame.iID == tim) {
  186.  
  187. int procent_otrzymany = frame.transfer_value;
  188. LPCSTR a;
  189. std::string s = std::to_string(procent_otrzymany);
  190. a = (LPCSTR)s.c_str();
  191. LPCSTR b;
  192. std::string ss = "Negocjacja";
  193. b = (LPCSTR)ss.c_str();
  194. int co_teraz = MessageBox(nullptr, a, b, MB_YESNOCANCEL | MB_ICONQUESTION);
  195. if ( co_teraz == IDYES) // or IDNO, depending
  196. {
  197. Frame frame;
  198. frame.frame_type = TRANSFER;
  199. frame.iID_receiver = tim;
  200. frame.transfer_type = MONEY;
  201. frame.transfer_value = my_vehicle->state.money * procent_otrzymany / 100;
  202. frame.iID = my_vehicle->iID;
  203. multi_send->send((char*)&frame, sizeof(Frame));
  204. my_vehicle->state.money = my_vehicle->state.money * (1 - procent_otrzymany / 100);
  205. }
  206.  
  207. }
  208. break;
  209. }
  210. case ZAPRASZALAK:
  211. {
  212. if (frame.iID_receiver == my_vehicle->iID) {
  213.  
  214. LPCSTR a;
  215. std::string s = std::to_string(frame.iID);
  216. a = (LPCSTR)s.c_str();
  217. LPCSTR b;
  218. std::string ss = "Zaproszenie";
  219. b = (LPCSTR)ss.c_str();
  220.  
  221. if (MessageBox(nullptr, a, b, MB_YESNO) == IDYES) // or IDNO, depending
  222. {
  223. tim = frame.iID;
  224. Frame frame;
  225. frame.frame_type = PRZYJAZNIALAK;
  226. frame.iID_receiver = tim;
  227. frame.transfer_type = 0;
  228. frame.transfer_value = 0;
  229. frame.iID = my_vehicle->iID;
  230. multi_send->send((char*)&frame, sizeof(Frame));
  231. }
  232.  
  233. }
  234. break;
  235. }
  236. case PRZYJAZNIALAK: {
  237. if (frame.iID_receiver == my_vehicle->iID) {
  238. tim = frame.iID;
  239. }
  240. break;
  241. }
  242. } // switch po typach ramek
  243. // Opuszczenie ścieżki krytycznej / Release the Critical section
  244. LeaveCriticalSection(&m_cs); // wyjście ze ścieżki krytycznej
  245. } // while(1)
  246. return 1;
  247. }
  248.  
  249. // *****************************************************************
  250. // **** Wszystko co trzeba zrobiæ podczas uruchamiania aplikacji
  251. // **** poza grafik¹
  252. void InteractionInitialisation()
  253. {
  254. DWORD dwThreadId;
  255.  
  256. my_vehicle = new MovableObject(&terrain); // tworzenie wlasnego obiektu
  257. if (if_different_skills == false)
  258. my_vehicle->planting_skills = my_vehicle->money_collection_skills = my_vehicle->fuel_collection_skills = 1.0;
  259.  
  260. VW_cycle_time = clock(); // pomiar aktualnego czasu
  261.  
  262. // obiekty sieciowe typu multicast (z podaniem adresu WZR oraz numeru portu)
  263. multi_reciv = new multicast_net("224.10.120.70", 10997); // Object do odbioru ramek sieciowych
  264. multi_send = new multicast_net("224.10.120.70", 10997); // Object do wysy³ania ramek
  265.  
  266. // uruchomienie watku obslugujacego odbior komunikatow
  267. threadReciv = CreateThread(
  268. NULL, // no security attributes
  269. 0, // use default stack size
  270. ReceiveThreadFunction, // thread function
  271. (void *)multi_reciv, // argument to thread function
  272. 0, // use default creation flags
  273. &dwThreadId); // returns the thread identifier
  274.  
  275. }
  276.  
  277.  
  278. // *****************************************************************
  279. // **** Wszystko co trzeba zrobiæ w ka¿dym cyklu dzia³ania
  280. // **** aplikacji poza grafik¹
  281. void VirtualWorldCycle()
  282. {
  283. counter_of_simulations++;
  284.  
  285. // obliczenie œredniego czasu pomiêdzy dwoma kolejnnymi symulacjami po to, by zachowaæ fizycznych
  286. if (counter_of_simulations % 50 == 0) // jeœli licznik cykli przekroczy³ pewn¹ wartoœæ, to
  287. { // nale¿y na nowo obliczyæ œredni czas cyklu fDt
  288. char text[200];
  289. long prev_time = VW_cycle_time;
  290. VW_cycle_time = clock();
  291. float fFps = (50 * CLOCKS_PER_SEC) / (float)(VW_cycle_time - prev_time);
  292. if (fFps != 0) fDt = 1.0 / fFps; else fDt = 1;
  293.  
  294. sprintf(par_view.inscription1, " %0.0f_fps, fuel = %0.2f, money = %d\n, negocjacja = %i %%\n", fFps, my_vehicle->state.amount_of_fuel, my_vehicle->state.money, procent);
  295. sprintf(par_view.inscription2, "Kolizja_z_obiektem_o_ID = %d", my_vehicle->iID_collider);
  296. if (counter_of_simulations % 500 == 0) sprintf(par_view.inscription2, "");
  297. }
  298.  
  299. terrain.DeleteObjectsFromSectors(my_vehicle);
  300. my_vehicle->Simulation(fDt); // symulacja w³asnego obiektu
  301. terrain.InsertObjectIntoSectors(my_vehicle);
  302.  
  303.  
  304. if ((my_vehicle->iID_collider > -1) && // wykryto kolizjê - wysy³am specjaln¹ ramkê, by poinformowaæ o tym drugiego uczestnika
  305. (my_vehicle->iID_collider != my_vehicle->iID)) // oczywiœcie wtedy, gdy nie chodzi o mój pojazd
  306. {
  307. Frame frame;
  308. frame.frame_type = COLLISION;
  309. frame.iID_receiver = my_vehicle->iID_collider;
  310. frame.vdV_collision = my_vehicle->vdV_collision;
  311. frame.iID = my_vehicle->iID;
  312. int iRozmiar = multi_send->send((char*)&frame, sizeof(Frame));
  313.  
  314. char text[128];
  315. sprintf(par_view.inscription2, "Kolizja_z_obiektem_o_ID = %d", my_vehicle->iID_collider);
  316. //SetWindowText(main_window,text);
  317.  
  318. my_vehicle->iID_collider = -1;
  319. }
  320.  
  321. // wyslanie komunikatu o stanie obiektu przypisanego do aplikacji (my_vehicle):
  322.  
  323. Frame frame;
  324. frame.frame_type = OBJECT_STATE;
  325. frame.state = my_vehicle->State(); // state w³asnego obiektu
  326. frame.iID = my_vehicle->iID;
  327. frame.existing_time = clock() - start_time;
  328. int iRozmiar = multi_send->send((char*)&frame, sizeof(Frame));
  329.  
  330.  
  331.  
  332. // wziêcie przedmiotu -> wysy³anie ramki
  333. if (my_vehicle->number_of_taking_item > -1)
  334. {
  335. Frame frame;
  336. frame.frame_type = ITEM_TAKING;
  337. frame.item_number = my_vehicle->number_of_taking_item;
  338. frame.state = my_vehicle->State();
  339. frame.iID = my_vehicle->iID;
  340. int iRozmiar = multi_send->send((char*)&frame, sizeof(Frame));
  341.  
  342. sprintf(par_view.inscription2, "Wziecie_przedmiotu_o_wartosci_ %f", my_vehicle->taking_value);
  343.  
  344. my_vehicle->number_of_taking_item = -1;
  345. my_vehicle->taking_value = 0;
  346. }
  347.  
  348. // odnawianie siê przedmiotu -> wysy³anie ramki
  349. if (my_vehicle->number_of_renewed_item > -1)
  350. { // jeœli min¹³ pewnien okres czasu przedmiot mo¿e zostaæ przywrócony
  351. Frame frame;
  352. frame.frame_type = ITEM_RENEWAL;
  353. frame.item_number = my_vehicle->number_of_renewed_item;
  354. frame.iID = my_vehicle->iID;
  355. int iRozmiar = multi_send->send((char*)&frame, sizeof(Frame));
  356.  
  357.  
  358. my_vehicle->number_of_renewed_item = -1;
  359. }
  360.  
  361. }
  362.  
  363. // *****************************************************************
  364. // **** Wszystko co trzeba zrobiæ podczas zamykania aplikacji
  365. // **** poza grafik¹
  366. void EndOfInteraction()
  367. {
  368. fprintf(f, "Koniec interakcji\n");
  369. fclose(f);
  370. }
  371.  
  372. // Funkcja wysylajaca ramke z przekazem, zwraca zrealizowan¹ wartoœæ przekazu
  373. float TransferSending(int ID_receiver, int transfer_type, float transfer_value)
  374. {
  375. Frame frame;
  376. frame.frame_type = TRANSFER;
  377. frame.iID_receiver = ID_receiver;
  378. frame.transfer_type = transfer_type;
  379. frame.transfer_value = transfer_value;
  380. frame.iID = my_vehicle->iID;
  381.  
  382. // tutaj nale¿a³oby uzyskaæ potwierdzenie przekazu zanim sumy zostan¹ odjête
  383. if (transfer_type == MONEY)
  384. {
  385. if (my_vehicle->state.money < transfer_value)
  386. frame.transfer_value = my_vehicle->state.money;
  387. my_vehicle->state.money -= frame.transfer_value;
  388. sprintf(par_view.inscription2, "Przelew_sumy_ %f _na_rzecz_ID_ %d", transfer_value, ID_receiver);
  389. }
  390. else if (transfer_type == FUEL)
  391. {
  392. if (my_vehicle->state.amount_of_fuel < transfer_value)
  393. frame.transfer_value = my_vehicle->state.amount_of_fuel;
  394. my_vehicle->state.amount_of_fuel -= frame.transfer_value;
  395. sprintf(par_view.inscription2, "Przekazanie_paliwa_w_ilosci_ %f _na_rzecz_ID_ %d", transfer_value, ID_receiver);
  396. }
  397.  
  398. if (frame.transfer_value > 0)
  399. int iRozmiar = multi_send->send((char*)&frame, sizeof(Frame));
  400.  
  401. return frame.transfer_value;
  402. }
  403.  
  404.  
  405.  
  406.  
  407.  
  408. //deklaracja funkcji obslugi okna
  409. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  410.  
  411.  
  412. HWND main_window; // uchwyt do okna aplikacji
  413. HDC g_context = NULL; // uchwyt kontekstu graficznego
  414.  
  415. bool terrain_edition_mode = 0;
  416.  
  417. //funkcja Main - dla Windows
  418. int WINAPI WinMain(HINSTANCE hInstance,
  419. HINSTANCE hPrevInstance,
  420. LPSTR lpCmdLine,
  421. int nCmdShow)
  422. {
  423. //Initilize the critical section:
  424. InitializeCriticalSection(&m_cs);
  425.  
  426. MSG system_message; //innymi slowy "komunikat"
  427. WNDCLASS window_class; //klasa głównego okna aplikacji
  428.  
  429. static char class_name[] = "Basic";
  430.  
  431. //Definiujemy klase głównego okna aplikacji
  432. //Okreslamy tu wlasciwosci okna, szczegoly wygladu oraz
  433. //adres funkcji przetwarzajacej komunikaty
  434. window_class.style = CS_HREDRAW | CS_VREDRAW;
  435. window_class.lpfnWndProc = WndProc; //adres funkcji realizującej przetwarzanie meldunków
  436. window_class.cbClsExtra = 0;
  437. window_class.cbWndExtra = 0;
  438. window_class.hInstance = hInstance; //identyfikator procesu przekazany przez MS Windows podczas uruchamiania programu
  439. window_class.hIcon = 0;
  440. window_class.hCursor = LoadCursor(0, IDC_ARROW);
  441. window_class.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
  442. window_class.lpszMenuName = "Menu";
  443. window_class.lpszClassName = class_name;
  444.  
  445. //teraz rejestrujemy klasę okna głównego
  446. RegisterClass(&window_class);
  447.  
  448. /*tworzymy main_window główne
  449. main_window będzie miało zmienne rozmiary, listwę z tytułem, menu systemowym
  450. i przyciskami do zwijania do ikony i rozwijania na cały ekran, po utworzeniu
  451. będzie widoczne na ekranie */
  452. main_window = CreateWindow(class_name, "WZR 2018/19, temat 3, wersja i ", WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  453. 100, 100, 1200, 800, NULL, NULL, hInstance, NULL);
  454.  
  455.  
  456. ShowWindow(main_window, nCmdShow);
  457.  
  458. //odswiezamy zawartosc okna
  459. UpdateWindow(main_window);
  460.  
  461.  
  462.  
  463. // GŁÓWNA PĘTLA PROGRAMU
  464.  
  465. // pobranie komunikatu z kolejki jeśli funkcja PeekMessage zwraca wartość inną niż FALSE,
  466. // w przeciwnym wypadku symulacja wirtualnego świata wraz z wizualizacją
  467. ZeroMemory(&system_message, sizeof(system_message));
  468. while (system_message.message != WM_QUIT)
  469. {
  470. if (PeekMessage(&system_message, NULL, 0U, 0U, PM_REMOVE))
  471. {
  472. TranslateMessage(&system_message);
  473. DispatchMessage(&system_message);
  474. }
  475. else
  476. {
  477. VirtualWorldCycle(); // Cykl wirtualnego świata
  478. InvalidateRect(main_window, NULL, FALSE);
  479. }
  480. }
  481.  
  482. return (int)system_message.wParam;
  483. }
  484.  
  485. // ************************************************************************
  486. // **** Obs³uga klawiszy s³u¿¹cych do sterowania obiektami lub
  487. // **** widokami
  488. void MessagesHandling(UINT message_type, WPARAM wParam, LPARAM lParam)
  489. {
  490.  
  491. int LCONTROL = GetKeyState(VK_LCONTROL);
  492. int RCONTROL = GetKeyState(VK_RCONTROL);
  493. int LALT = GetKeyState(VK_LMENU);
  494. int RALT = GetKeyState(VK_RMENU);
  495.  
  496.  
  497. switch (message_type)
  498. {
  499.  
  500. case WM_LBUTTONDOWN: //reakcja na lewy przycisk myszki
  501. {
  502. int x = LOWORD(lParam);
  503. int y = HIWORD(lParam);
  504. if (mouse_control)
  505. my_vehicle->F = my_vehicle->F_max; // si³a pchaj¹ca do przodu
  506.  
  507. break;
  508. }
  509. case WM_RBUTTONDOWN: //reakcja na prawy przycisk myszki
  510. {
  511. int x = LOWORD(lParam);
  512. int y = HIWORD(lParam);
  513. int LSHIFT = GetKeyState(VK_LSHIFT); // sprawdzenie czy lewy Shift wciśnięty, jeśli tak, to LSHIFT == 1
  514. int RSHIFT = GetKeyState(VK_RSHIFT);
  515.  
  516. if (mouse_control)
  517. my_vehicle->F = -my_vehicle->F_max / 2; // si³a pchaj¹ca do tylu
  518. else if (wParam & MK_SHIFT) // odznaczanie wszystkich obiektów
  519. {
  520. for (long i = 0; i < terrain.number_of_selected_items; i++)
  521. terrain.p[terrain.selected_items[i]].if_selected = 0;
  522. terrain.number_of_selected_items = 0;
  523. }
  524. else // zaznaczenie obiektów
  525. {
  526. RECT r;
  527. //GetWindowRect(main_window,&r);
  528. GetClientRect(main_window, &r);
  529. //Vector3 w = Cursor3dCoordinates(x, r.bottom - r.top - y);
  530. Vector3 w = terrain.Cursor3D_CoordinatesWithoutParallax(x, r.bottom - r.top - y);
  531.  
  532.  
  533. //float radius = (w - point_click).length();
  534. float min_dist = 1e10;
  535. long index_min = -1;
  536. bool if_movable_obj;
  537. for (map<int, MovableObject*>::iterator it = network_vehicles.begin(); it != network_vehicles.end(); ++it)
  538. {
  539. if (it->second)
  540. {
  541. MovableObject *ob = it->second;
  542. float xx, yy, zz;
  543. ScreenCoordinates(&xx, &yy, &zz, ob->state.vPos);
  544. yy = r.bottom - r.top - yy;
  545. float odl_kw = (xx - x)*(xx - x) + (yy - y)*(yy - y);
  546. if (min_dist > odl_kw)
  547. {
  548. min_dist = odl_kw;
  549. index_min = ob->iID;
  550. if_movable_obj = 1;
  551. }
  552. }
  553. }
  554.  
  555.  
  556. // trzeba to przerobić na wersję sektorową, gdyż przedmiotów może być dużo!
  557. // niestety nie jest to proste.
  558.  
  559. //Item **wsk_prz = NULL;
  560. //long liczba_prz_w_prom = terrain.ItemsInRadius(&wsk_prz, w,100);
  561.  
  562. for (long i = 0; i < terrain.number_of_items; i++)
  563. {
  564. float xx, yy, zz;
  565. Vector3 placement;
  566. if ((terrain.p[i].type == ITEM_EDGE) || (terrain.p[i].type == ITEM_WALL))
  567. {
  568. placement = (terrain.p[terrain.p[i].param_i[0]].vPos + terrain.p[terrain.p[i].param_i[1]].vPos) / 2;
  569. }
  570. else
  571. placement = terrain.p[i].vPos;
  572. ScreenCoordinates(&xx, &yy, &zz, placement);
  573. yy = r.bottom - r.top - yy;
  574. float odl_kw = (xx - x)*(xx - x) + (yy - y)*(yy - y);
  575. if (min_dist > odl_kw)
  576. {
  577. min_dist = odl_kw;
  578. index_min = i;
  579. if_movable_obj = 0;
  580. }
  581. }
  582.  
  583. if (index_min > -1)
  584. {
  585. //fprintf(f,"zaznaczono przedmiot %d pol = (%f, %f, %f)\n",ind_min,terrain.p[ind_min].vPos.x,terrain.p[ind_min].vPos.y,terrain.p[ind_min].vPos.z);
  586. //terrain.p[ind_min].if_selected = 1 - terrain.p[ind_min].if_selected;
  587. if (if_movable_obj)
  588. {
  589. network_vehicles[index_min]->if_selected = 1 - network_vehicles[index_min]->if_selected;
  590.  
  591. if (network_vehicles[index_min]->if_selected) {
  592. sprintf(par_view.inscription2, "zaznaczono_ obiekt_ID_%d", network_vehicles[index_min]->iID);
  593. zaznaczony_id = network_vehicles[index_min]->iID;
  594. }
  595. }
  596. else
  597. {
  598. terrain.SelectUnselectItemOrGroup(index_min);
  599. }
  600. //char lan[256];
  601. //sprintf(lan, "klikniêto w przedmiot %d pol = (%f, %f, %f)\n",ind_min,terrain.p[ind_min].vPos.x,terrain.p[ind_min].vPos.y,terrain.p[ind_min].vPos.z);
  602. //SetWindowText(main_window,lan);
  603. }
  604. Vector3 point_click = Cursor3dCoordinates(x, r.bottom - r.top - y);
  605.  
  606. }
  607.  
  608. break;
  609. }
  610. case WM_MBUTTONDOWN: //reakcja na œrodkowy przycisk myszki : uaktywnienie/dezaktywacja sterwania myszkowego
  611. {
  612. mouse_control = 1 - mouse_control;
  613. cursor_x = LOWORD(lParam);
  614. cursor_y = HIWORD(lParam);
  615. break;
  616. }
  617. case WM_LBUTTONUP: //reakcja na puszczenie lewego przycisku myszki
  618. {
  619. if (mouse_control)
  620. my_vehicle->F = 0.0; // si³a pchaj¹ca do przodu
  621. break;
  622. }
  623. case WM_RBUTTONUP: //reakcja na puszczenie lewy przycisk myszki
  624. {
  625. if (mouse_control)
  626. my_vehicle->F = 0.0; // si³a pchaj¹ca do przodu
  627. break;
  628. }
  629. case WM_MOUSEMOVE:
  630. {
  631. int x = LOWORD(lParam);
  632. int y = HIWORD(lParam);
  633. if (mouse_control)
  634. {
  635. float wheel_turn_angle = (float)(cursor_x - x) / 20;
  636. if (wheel_turn_angle > 45) wheel_turn_angle = 45;
  637. if (wheel_turn_angle < -45) wheel_turn_angle = -45;
  638. my_vehicle->state.wheel_turn_angle = PI*wheel_turn_angle / 180;
  639. }
  640. break;
  641. }
  642. case WM_MOUSEWHEEL: // ruch kó³kiem myszy -> przybli¿anie, oddalanie widoku
  643. {
  644. int zDelta = GET_WHEEL_DELTA_WPARAM(wParam); // dodatni do przodu, ujemny do ty³u
  645. //fprintf(f,"zDelta = %d\n",zDelta); // zwykle +-120, jak siê bardzo szybko zakrêci to czasmi wyjdzie +-240
  646. if (zDelta > 0){
  647. if (par_view.distance > 0.5) par_view.distance /= 1.2;
  648. else par_view.distance = 0;
  649. }
  650. else {
  651. if (par_view.distance > 0) par_view.distance *= 1.2;
  652. else par_view.distance = 0.5;
  653. }
  654.  
  655. break;
  656. }
  657. case WM_KEYDOWN:
  658. {
  659.  
  660. switch (LOWORD(wParam))
  661. {
  662. case VK_SHIFT:
  663. {
  664. SHIFT_pressed = 1;
  665. break;
  666. }
  667. case VK_CONTROL:
  668. {
  669. CTRL_pressed = 1;
  670. break;
  671. }
  672. case VK_MENU:
  673. {
  674. ALT_pressed = 1;
  675. break;
  676. }
  677.  
  678. case VK_SPACE:
  679. {
  680. my_vehicle->breaking_degree = 1.0; // stopieñ hamowania (reszta zale¿y od si³y docisku i wsp. tarcia)
  681. break; // 1.0 to maksymalny stopieñ (np. zablokowanie kó³)
  682. }
  683. case VK_UP:
  684. {
  685. if (CTRL_pressed && par_view.top_view)
  686. par_view.shift_to_bottom += par_view.distance / 2; // przesunięcie widoku z kamery w górę
  687. else
  688. my_vehicle->F = my_vehicle->F_max; // si³a pchaj¹ca do przodu
  689. break;
  690. }
  691. case VK_DOWN:
  692. {
  693. if (CTRL_pressed && par_view.top_view)
  694. par_view.shift_to_bottom -= par_view.distance / 2; // przesunięcie widoku z kamery w dół
  695. else
  696. my_vehicle->F = -my_vehicle->F_max / 2; // sila pchajaca do tylu
  697. break;
  698. }
  699. case VK_LEFT:
  700. {
  701. if (CTRL_pressed && par_view.top_view)
  702. par_view.shift_to_right += par_view.distance / 2;
  703. else
  704. {
  705. if (my_vehicle->steer_wheel_speed < 0) {
  706. my_vehicle->steer_wheel_speed = 0;
  707. my_vehicle->if_keep_steer_wheel = true;
  708. }
  709. else {
  710. if (SHIFT_pressed) my_vehicle->steer_wheel_speed = 0.5;
  711. else my_vehicle->steer_wheel_speed = 0.5 / 4;
  712. }
  713. }
  714.  
  715. break;
  716. }
  717. case VK_RIGHT:
  718. {
  719. if (CTRL_pressed && par_view.top_view)
  720. par_view.shift_to_right -= par_view.distance / 2;
  721. else
  722. {
  723. if (my_vehicle->steer_wheel_speed > 0) {
  724. my_vehicle->steer_wheel_speed = 0;
  725. my_vehicle->if_keep_steer_wheel = true;
  726. }
  727. else {
  728. if (SHIFT_pressed) my_vehicle->steer_wheel_speed = -0.5;
  729. else my_vehicle->steer_wheel_speed = -0.5 / 4;
  730. }
  731. }
  732. break;
  733. }
  734. case VK_HOME:
  735. {
  736. if (CTRL_pressed && par_view.top_view)
  737. par_view.shift_to_right = par_view.shift_to_bottom = 0;
  738.  
  739. break;
  740. }
  741. case 'W': // przybli¿enie widoku
  742. {
  743. //initial_camera_position = initial_camera_position - initial_camera_direction*0.3;
  744. if (par_view.distance > 0.5)par_view.distance /= 1.2;
  745. else par_view.distance = 0;
  746. break;
  747. }
  748. case 'S': // distance widoku
  749. {
  750. //initial_camera_position = initial_camera_position + initial_camera_direction*0.3;
  751. if (par_view.distance > 0) par_view.distance *= 1.2;
  752. else par_view.distance = 0.5;
  753. break;
  754. }
  755. case 'Q': // widok z góry
  756. {
  757. par_view.top_view = 1 - par_view.top_view;
  758. if (par_view.top_view)
  759. SetWindowText(main_window, "Włączono widok z góry!");
  760. else
  761. SetWindowText(main_window, "Wyłączono widok z góry.");
  762. break;
  763. }
  764. case 'E': // obrót kamery ku górze (wzglêdem lokalnej osi z)
  765. {
  766. par_view.cam_angle_z += PI * 5 / 180;
  767. break;
  768. }
  769. case 'D': // obrót kamery ku do³owi (wzglêdem lokalnej osi z)
  770. {
  771. par_view.cam_angle_z -= PI * 5 / 180;
  772. break;
  773. }
  774. case 'A': // w³¹czanie, wy³¹czanie trybu œledzenia obiektu
  775. {
  776. par_view.tracking = 1 - par_view.tracking;
  777. break;
  778. }
  779. case 'Z': // zoom - zmniejszenie k¹ta widzenia
  780. {
  781. par_view.zoom /= 1.1;
  782. RECT rc;
  783. GetClientRect(main_window, &rc);
  784. WindowSizeChange(rc.right - rc.left, rc.bottom - rc.top);
  785. break;
  786. }
  787. case 'X': // zoom - zwiêkszenie k¹ta widzenia
  788. {
  789. par_view.zoom *= 1.1;
  790. RECT rc;
  791. GetClientRect(main_window, &rc);
  792. WindowSizeChange(rc.right - rc.left, rc.bottom - rc.top);
  793. break;
  794. }
  795.  
  796. case 'F': // przekazanie 10 kg paliwa pojazdom zaznaczonym
  797. {
  798. for (map<int, MovableObject*>::iterator it = network_vehicles.begin(); it != network_vehicles.end(); ++it)
  799. {
  800. if (it->second)
  801. {
  802. MovableObject *ob = it->second;
  803. if (ob->if_selected)
  804. float ilosc_p = TransferSending(ob->iID, FUEL, 10);
  805. }
  806. }
  807. break;
  808. }
  809. case 'N':
  810. {// NEGACJACJEEEEEEE
  811. if (tim != -1) {
  812. Frame frame;
  813. frame.frame_type = NEGOCJALAK;
  814. frame.iID_receiver = tim;
  815. frame.transfer_type = 0;
  816. frame.transfer_value = 0;
  817. frame.iID = my_vehicle->iID;
  818. multi_send->send((char*)&frame, sizeof(Frame));
  819. }
  820. break;
  821. }
  822. case 'M':
  823. {// rozpoczęcie zaznaczania metodą maguw ognia
  824. if (zaznaczony_id != -1) {
  825. Frame frame;
  826. frame.frame_type = ZAPRASZALAK;
  827. frame.iID_receiver = zaznaczony_id;
  828. frame.transfer_type = 0;
  829. frame.transfer_value = 0;
  830. frame.iID = my_vehicle->iID;
  831. multi_send->send((char*)&frame, sizeof(Frame));
  832.  
  833. }
  834.  
  835. break;
  836. }
  837. case 'G': // przekazanie 100 jednostek gotowki pojazdom zaznaczonym
  838. {
  839. for (map<int, MovableObject*>::iterator it = network_vehicles.begin(); it != network_vehicles.end(); ++it)
  840. {
  841. if (it->second)
  842. {
  843. MovableObject *ob = it->second;
  844. if (ob->if_selected)
  845. float ilosc_p = TransferSending(ob->iID, MONEY, 100);
  846. }
  847. }
  848. break;
  849. }
  850.  
  851. case 'L': // rozpoczęcie zaznaczania metodą lasso
  852. L_pressed = true;
  853. break;
  854.  
  855.  
  856. } // switch po klawiszach
  857.  
  858.  
  859. break;
  860. }
  861.  
  862. case WM_KEYUP:
  863. {
  864. switch (LOWORD(wParam))
  865. {
  866. case VK_SHIFT:
  867. {
  868. SHIFT_pressed = 0;
  869. break;
  870. }
  871. case VK_CONTROL:
  872. {
  873. CTRL_pressed = 0;
  874. break;
  875. }
  876. case VK_MENU:
  877. {
  878. ALT_pressed = 0;
  879. break;
  880. }
  881. case 'L': // zakonczenie zaznaczania metodą lasso
  882. L_pressed = false;
  883. break;
  884. case VK_SPACE:
  885. {
  886. my_vehicle->breaking_degree = 0.0;
  887. break;
  888. }
  889. case VK_UP:
  890. {
  891. my_vehicle->F = 0.0;
  892.  
  893. break;
  894. }
  895. case VK_DOWN:
  896. {
  897. my_vehicle->F = 0.0;
  898. break;
  899. }
  900. case VK_LEFT:
  901. {
  902. if (my_vehicle->if_keep_steer_wheel) my_vehicle->steer_wheel_speed = -0.5 / 4;
  903. else my_vehicle->steer_wheel_speed = 0;
  904. my_vehicle->if_keep_steer_wheel = false;
  905. break;
  906. }
  907. case VK_RIGHT:
  908. {
  909. if (my_vehicle->if_keep_steer_wheel) my_vehicle->steer_wheel_speed = 0.5 / 4;
  910. else my_vehicle->steer_wheel_speed = 0;
  911. my_vehicle->if_keep_steer_wheel = false;
  912. break;
  913. }
  914.  
  915. }
  916.  
  917. break;
  918. }
  919.  
  920. } // switch po komunikatach
  921. }
  922.  
  923. /********************************************************************
  924. FUNKCJA OKNA realizujaca przetwarzanie meldunków kierowanych do okna aplikacji*/
  925. LRESULT CALLBACK WndProc(HWND main_window, UINT message_type, WPARAM wParam, LPARAM lParam)
  926. {
  927.  
  928. // PONIŻSZA INSTRUKCJA DEFINIUJE REAKCJE APLIKACJI NA POSZCZEGÓLNE MELDUNKI
  929.  
  930. MessagesHandling(message_type, wParam, lParam);
  931.  
  932. switch (message_type)
  933. {
  934. case WM_CREATE: //system_message wysyłany w momencie tworzenia okna
  935. {
  936.  
  937. g_context = GetDC(main_window);
  938.  
  939. srand((unsigned)time(NULL));
  940. int result = GraphicsInitialization(g_context);
  941. if (result == 0)
  942. {
  943. printf("nie udalo sie otworzyc okna graficznego\n");
  944. //exit(1);
  945. }
  946.  
  947. InteractionInitialisation();
  948.  
  949. SetTimer(main_window, 1, 10, NULL);
  950.  
  951. return 0;
  952. }
  953. case WM_KEYDOWN:
  954. {
  955. switch (LOWORD(wParam))
  956. {
  957. case VK_F1: // wywolanie systemu pomocy
  958. {
  959. char lan[1024], lan_bie[1024];
  960. //GetSystemDirectory(lan_sys,1024);
  961. GetCurrentDirectory(1024, lan_bie);
  962. strcpy(lan, "C:\\Program Files\\Internet Explorer\\iexplore ");
  963. strcat(lan, lan_bie);
  964. strcat(lan, "\\pomoc.htm");
  965. int wyni = WinExec(lan, SW_NORMAL);
  966. if (wyni < 32) // proba uruchominia pomocy nie powiodla sie
  967. {
  968. strcpy(lan, "C:\\Program Files\\Mozilla Firefox\\firefox ");
  969. strcat(lan, lan_bie);
  970. strcat(lan, "\\pomoc.htm");
  971. wyni = WinExec(lan, SW_NORMAL);
  972. if (wyni < 32)
  973. {
  974. char lan_win[1024];
  975. GetWindowsDirectory(lan_win, 1024);
  976. strcat(lan_win, "\\notepad pomoc.txt ");
  977. wyni = WinExec(lan_win, SW_NORMAL);
  978. }
  979. }
  980. break;
  981. }
  982. case VK_F4: // włączanie/ wyłączanie trybu edycji terrainu
  983. {
  984. terrain_edition_mode = 1 - terrain_edition_mode;
  985. if (terrain_edition_mode)
  986. SetWindowText(main_window, "TRYB EDYCJI TERENU F2-SaveMapToFile, F1-pomoc");
  987. else
  988. SetWindowText(main_window, "WYJSCIE Z TRYBU EDYCJI TERENU");
  989. break;
  990. }
  991. case VK_ESCAPE: // wyjście z programu
  992. {
  993. SendMessage(main_window, WM_DESTROY, 0, 0);
  994. break;
  995. }
  996. }
  997. return 0;
  998. }
  999.  
  1000. case WM_PAINT:
  1001. {
  1002. PAINTSTRUCT paint;
  1003. HDC context;
  1004. context = BeginPaint(main_window, &paint);
  1005.  
  1006. DrawScene();
  1007. SwapBuffers(context);
  1008.  
  1009. EndPaint(main_window, &paint);
  1010.  
  1011.  
  1012.  
  1013. return 0;
  1014. }
  1015.  
  1016. case WM_TIMER:
  1017.  
  1018. return 0;
  1019.  
  1020. case WM_SIZE:
  1021. {
  1022. int cx = LOWORD(lParam);
  1023. int cy = HIWORD(lParam);
  1024.  
  1025. WindowSizeChange(cx, cy);
  1026.  
  1027. return 0;
  1028. }
  1029.  
  1030. case WM_DESTROY: //obowiązkowa obsługa meldunku o zamknięciu okna
  1031. if (lParam == 100)
  1032. MessageBox(main_window, "Jest zbyt późno na dołączenie do wirtualnego świata. Trzeba to zrobić zanim inni uczestnicy zmienią jego state.", "Zamknięcie programu", MB_OK);
  1033.  
  1034. EndOfInteraction();
  1035. EndOfGraphics();
  1036.  
  1037. ReleaseDC(main_window, g_context);
  1038. KillTimer(main_window, 1);
  1039.  
  1040. PostQuitMessage(0);
  1041. return 0;
  1042.  
  1043. default: //standardowa obsługa pozostałych meldunków
  1044. return DefWindowProc(main_window, message_type, wParam, lParam);
  1045. }
  1046.  
  1047. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement