1 /*****************************************************************************
2 ** This is part of the SpaceZero program
3 ** Copyright(C) 2006-2013 MRevenga
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License (version 3), or
7 ** (at your option) any later version, as published by the Free Software
8 ** Foundation.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 ******************************************************************************/
19
20 /************* SpaceZero M.R.H. 2006-2013 ******************
21 Author: MRevenga
22 E-mail: mrevenga at users.sourceforge.net
23 version 0.86 December 2013
24 **************************************************************/
25
26 #include <stdlib.h>
27 #include <math.h>
28 #include <stdio.h>
29 #include <time.h>
30 #include <string.h>
31 #include <pthread.h>
32 #include <semaphore.h>
33 #include <signal.h>
34 #include <sys/time.h>
35 #include <fcntl.h>
36 #include "objects.h"
37 #include "spacezero.h"
38 #include "players.h"
39 #include "functions.h"
40 #include "spacecomm.h"
41 #include "sound.h"
42 #include "locales.h"
43 #include "graphics.h"
44 #include "ai.h"
45 #include "save.h"
46 #include "clock.h"
47 #include "shell.h"
48 #include "planetnames.h"
49 #include "randomnamegen.h"
50 #include "sectors.h"
51 #include "snow.h"
52
53
54 extern int g_objid; /* id of the objects */
55 extern struct Global glocal;
56 extern GtkWidget *d_a;
57 extern GtkWidget *win_main;
58 extern GdkFont *gfont;
59 extern GdkPixmap *pixmap;
60 extern GdkPixmap *pixmap_stat;
61 extern GdkGC *gcolors[];
62
63 int gdrawmenu=TRUE;
64 struct Draw gdraw;
65
66
67 int actual_player,actual_player0;
68
69 int record=0;
70 int nav_mode=RELATIVE;
71
72 int p_time=0;
73 int g_nobjsend=0;
74 int g_nshotsend=0;
75 int g_nobjmaxsend=0;
76 int g_nobjtype[6]={0,0,0,0,0,0};
77 int gameover=FALSE;
78 int observeenemies=FALSE;
79
80 char version[64]={"0.86.00"};
81 char copyleft[]="";
82 char TITLE[64]="SpaceZero ";
83 char last_revision[]={"Dec 2013"};
84
85
86 Object *ship_c; /* ship controled by keyboard */
87 Object *cv; /* coordinates center */
88 int fobj[4];
89 sem_t sem_barrier,sem_barrier1;
90
91
92 int g_cont;
93 time_t gtime0;
94 double fps; /* frames / second*/
95
96 int order2thread;
97
98 int *cell;
99 static struct timeval init_time;
100
101 extern struct Buffer buffer1,buffer2; /* buffers used in comm. */
102
103 extern struct HeadObjList listheadobjs; /* list of all objects */
104 struct HeadObjList listheadplanets; /* list of all planets */
105 struct HeadObjList *listheadcontainer; /* lists of objects that contain objects: free space and planets*/
106 struct HeadObjList *listheadkplanets; /* lists of planets known by players */
107 struct HeadObjList listheadplayer; /* list of objects of each player */
108
109 struct CharListHead gameloglist; /* list of all game messages */
110 struct Window windowgamelog;
111
112 struct TextMessageList listheadtext;
113 extern struct Parametres param;
114 Vector r_rel;
115
116 struct Habitat habitat;
117
118
119 char clientname[MAXTEXTLEN];
120
121
122 /* sound */
123 int soundenabled=TRUE;
124 /* -- sound */
125
126 char *savefile;
127 char *recordfile;
128 char *optionsfile;
129 char *keyboardfile;
130
131 struct MenuHead *menuhead;
132
133
134 /*void signal_handler(int ,siginfo_t *,void *);*/
135 void int_handler(int);
136 void segfault_handler(int);
137
138
139
main(int argc,char * argv[])140 int main(int argc,char *argv[]){
141 /*
142 version 2
143 TODO reorganized this
144 */
145
146 GtkWidget *drawing_area;
147
148 char title[64]="";
149 int state;
150 struct sigaction sa;
151 int width,height;
152
153 srand(time(NULL));
154
155 /******** signals ***********/
156 /*
157 sa.sa_sigaction=signal_handler;
158 sigemptyset(&sa.sa_mask);
159 sa.sa_flags=SA_SIGINFO;
160 if(sigaction(SIGNAL0,&sa,NULL)){
161 perror("sigaction");
162 exit(-1);
163 }
164 */
165
166 sa.sa_handler=int_handler;
167 sigemptyset(&sa.sa_mask);
168 sa.sa_flags=0;
169 if(sigaction(SIGINT,&sa,NULL)){
170 perror("sigaction");
171 exit(-1);
172 }
173
174 /* sa.sa_handler=segfault_handler; */
175 /* sigemptyset(&sa.sa_mask); */
176 /* sa.sa_flags=0; */
177 /* if(sigaction(SIGSEGV,&sa,NULL)){ */
178 /* perror("sigaction"); */
179 /* exit(-1); */
180 /* } */
181
182 /******** --signals ***********/
183
184 sem_init(&sem_barrier,0,0);
185 sem_init(&sem_barrier1,0,0);
186
187 MemUsed(MRESET,0);
188
189
190 Keystrokes(RESET,NULL,NULL);
191
192 PrintWarnings(version);
193 optionsfile=CreateOptionsFile();
194 recordfile=CreateRecordFile();
195 keyboardfile=CreateKeyboardFile();
196
197 /*********** read options file and checking command line options *************/
198 state=Arguments(argc,argv,optionsfile);
199 if(state){
200 Usage(version,last_revision);
201 exit(-1);
202 }
203
204 /****** checking file options *********/
205 if(CheckArgs()){
206 fprintf(stderr,"ERROR in arguments, exiting...\n");
207 exit(-1);
208 }
209
210 PrintArguments("Game arguments:");
211
212 /* locales*/
213 GetLocales(param.lang);
214
215 if(GameParametres(GET,GNET,0)){
216 printf("NET: yes\n");
217 }
218 else{
219 printf("NET: no\n");
220 }
221
222 /***** set game options ******/
223
224 GameParametres(SET,GULX,param.ul);
225 GameParametres(SET,GCOOPERATIVE,param.cooperative);
226 GameParametres(SET,GCOMPCOOPERATIVE,param.compcooperative);
227 GameParametres(SET,GQUEEN,param.queen);
228 GameParametres(SET,GPIRATES,param.pirates);
229 GameParametres(SET,GENEMYKNOWN,param.enemyknown);
230 GameParametres(SET,GNGALAXIES,param.ngalaxies);
231 GameParametres(SET,GNPLAYERS,param.nplayers);
232 GameParametres(SET,GNPLANETS,param.nplanets);
233
234
235 /***** user defined keys ****/
236
237 printf("Setting default user keys\n");
238 SetDefaultUserKeys();
239 printf("Loading user keys\n");
240 LoadUserKeys(keyboardfile);
241
242 Clock(0,CL_CLEAR);
243 Clock(0,CL_START);
244
245 /********** Graphics initialization **********/
246 gtk_init(&argc,&argv);
247
248 MakeTitle(param,title);
249 GetGeom(param.geom,&width,&height);
250 printf("W: %d H: %d \n", width,height);
251 drawing_area=InitGraphics(title,optionsfile,
252 width,height,param);
253
254 printf("W: %d H: %d \n", drawing_area->allocation.width,
255 drawing_area->allocation.height);
256
257 SetDefaultKeyValues(1);
258
259 menuhead=CreateMenu();
260 menuhead->active=TRUE;
261
262 if(param.fontlist){
263 printf("==============\n");
264 printf("system font list:\n");
265 PrintFontNames(10000);
266 printf("==============\n");
267 }
268
269 /********** --Graphics initialization *********/
270
271
272
273 #if SOUND
274 /********* sound initialization *********/
275 soundenabled=TRUE;
276 if(InitSound()!=0){
277 fprintf(stderr,"Error initializing sound, sound disabled Error id:%d\n",state);
278 soundenabled=FALSE;
279 param.sound=0;
280 param.music=0;
281 GameParametres(SET,GMUSIC,param.sound);
282 GameParametres(SET,GSOUND,param.music);
283 Play(NULL,-1,0); /* disable sound */
284 }
285
286 if(soundenabled==TRUE){
287 float master=0;
288 float music=0,sound=0;
289
290 if(param.soundvol>param.musicvol){
291 master=(float)param.soundvol/100;
292 sound=1.0;
293 music=(float)param.musicvol/param.soundvol;
294 }
295 else{
296 master=(float)param.musicvol/100;
297 music=1.0;
298 sound=(float)param.soundvol/param.musicvol;
299 }
300
301 SetMasterVolume(master,VOLSET);
302
303 SetSoundVolume(sound,VOLSET);
304 PlaySound(MUSIC,SLOOP,1);
305 if(param.music){
306 SetMusicVolume(music,VOLSET);
307 }
308 else{
309 Sound(SSTOP,MUSIC);
310 printf("Music is off\n");
311 }
312 }
313
314 /********* --sound initialization *********/
315 #endif
316
317
318 /******** what stuff to draw *********/
319 gdraw.main=FALSE;
320 gdraw.menu=TRUE;
321 gdraw.map=FALSE;
322 gdraw.shiplist=FALSE;
323 gdraw.stats=FALSE;
324 gdraw.order=FALSE;
325 gdraw.info=FALSE;
326 gdraw.crash=FALSE;
327 gdraw.volume=FALSE;
328
329 /******** --what stuff to draw *********/
330
331 /***** game log initialization *****/
332
333 gameloglist.n=0;
334 gameloglist.max=200;
335 gameloglist.first=0;
336 gameloglist.next=NULL;
337
338 windowgamelog.type=0;
339 windowgamelog.active=0;
340 windowgamelog.x=0;
341 windowgamelog.y=0;
342 windowgamelog.width=0;
343 windowgamelog.height=0;
344 windowgamelog.scrollbar.active=1;
345 windowgamelog.scrollbar.width=15;
346 windowgamelog.scrollbar.pos=0;
347 windowgamelog.scrollbar.n=0;
348 windowgamelog.data=&gameloglist;
349
350
351 gtk_timeout_add((int)(DT*50),MenuLoop,(gpointer)drawing_area); /* 42 DT=0.42 in general.h*/
352
353 gtk_timeout_add((int)(DT*100),MainLoop,(gpointer)drawing_area); /* 42 DT=0.42 in general.h*/
354
355
356 gettimeofday(&init_time,NULL);
357 gtk_main();
358
359
360 /********* game resume **********/
361 {
362 struct Player *player=NULL;
363 if(GameParametres(GET,GNPLAYERS,0)>0){
364
365 player=GetPlayers();
366 printf("\ntotal points: %d record: %d\n",player[1].points,record);
367 }
368 printf("******************************************************\n");
369 printf("%sversion %s %s\n",TITLE,version,last_revision);
370 printf("Please, send bugs and suggestions to: mrevenga at users dot sourceforge dot net\n");
371 printf("Homepage: http://spacezero.sourceforge.net/\n");
372
373 SaveRecord(recordfile,player,record);
374 }
375 return 0;
376 } /* --main */
377
378
MenuLoop(gpointer data)379 gint MenuLoop(gpointer data){
380 struct MenuHead *actualmenu;
381 GdkRectangle update_rect;
382 GtkWidget *drawing_area=(GtkWidget *) data;
383 int x,y;
384 int width,height;
385 char point[128];
386
387 int status;
388 static int cont=0;
389 static GdkFont *font,*fontmenu;
390 static int swfont=0;
391 int swexit=0;
392 int swsaveoptions=0;
393
394 if(gdraw.menu==FALSE)return(TRUE);
395
396 if(cont==0){
397 SetDefaultKeyValues(1);
398 }
399 cont++;
400
401 if((cont%20)==0){
402 gdrawmenu=TRUE;
403 }
404
405 if(!gdrawmenu)return(TRUE);
406 gdrawmenu=FALSE;
407
408 key_eval();
409
410 width=GameParametres(GET,GWIDTH,0);
411 height=GameParametres(GET,GHEIGHT,0);
412
413 if(swfont==0){
414 font=InitFontsMenu("");
415 swfont++;
416 }
417 if(height<400)fontmenu=gfont;
418 else fontmenu=font;
419
420 /* clear window */
421
422 gdk_draw_rectangle(pixmap,
423 GetColor(BLACK),
424 TRUE,
425 0,0,
426 drawing_area->allocation.width,
427 drawing_area->allocation.height);
428
429 /* printf something */
430
431 DrawStars(pixmap,nav_mode,0,0);
432
433 x=width/2;
434 y=height/9;
435 sprintf(point,"SpaceZero");
436 DrawMessageBox(pixmap,font,point,x,y,MBOXDEFAULT);
437
438
439 menuhead->active=TRUE;
440 actualmenu=SelectMenu(menuhead);
441 status=UpdateMenu(menuhead,actualmenu);
442
443 x=width/8;
444 y=(1.0/3)*height;
445
446 XPrintMenuHead(pixmap,fontmenu,actualmenu,x,y);
447 /* show window */
448
449 update_rect.x=0;
450 update_rect.y=0;
451 update_rect.width=drawing_area->allocation.width;
452 update_rect.height=drawing_area->allocation.height;
453 gtk_widget_draw(drawing_area,&update_rect); /* deprecated */
454
455 switch(status){
456 case 0:
457 break;
458 case ITEM_start:
459 swsaveoptions=1;
460 swexit=1;
461 break;
462 case ITEM_quit:
463 SetGameParametres(param);
464 GameParametres(SET,GQUIT,2);
465 gdraw.menu=FALSE;
466 gdraw.main=TRUE;
467 Keystrokes(RESET,NULL,NULL);
468 SetDefaultKeyValues(1);
469 return(TRUE);
470 break;
471 case ITEM_default:
472 printf("loading default \n");
473 SetDefaultParamValues();
474 SetDefaultUserKeys();
475 break;
476 case ITEM_server:
477 param.server=TRUE;
478 param.client=FALSE;
479 swsaveoptions=1;
480 swexit=1;
481 printf("start server....\n");
482 break;
483 case ITEM_client:
484 param.server=FALSE;
485 param.client=TRUE;
486 swexit=1;
487 printf("start client....\n");
488 break;
489 case MENUESC:
490 break;
491 default:
492 break;
493 }
494
495 if(param.menu==FALSE)swexit++;
496
497 if(swexit){
498 char title[64]="";
499 gdraw.menu=FALSE;
500 gdraw.main=TRUE;
501 Keystrokes(RESET,NULL,NULL);
502 printf("saving game param...\n");
503 SetGameParametres(param);
504 MakeTitle(param,title);
505 gtk_window_set_title(GTK_WINDOW(win_main),title);
506 if(swsaveoptions){
507 printf("saving options...\n");
508 SaveParamOptions(optionsfile,¶m);
509 SaveUserKeys(keyboardfile);
510 }
511 /* activating sound ??*/
512
513
514 if(soundenabled==TRUE){
515 float master=0;
516 float music=0,sound=0;
517
518 if(param.soundvol>param.musicvol){
519 master=(float)param.soundvol/100;
520 sound=1.0;
521 music=(float)param.musicvol/param.soundvol;
522 }
523 else{
524 master=(float)param.musicvol/100;
525 music=1.0;
526 sound=(float)param.soundvol/param.musicvol;
527 }
528
529 SetMasterVolume(master,VOLSET);
530 SetSoundVolume(sound,VOLSET);
531 if(param.music){
532 SetMusicVolume(music,VOLSET);
533 }
534 else{
535 Sound(SSTOP,MUSIC);
536 printf("Music is off\n");
537 }
538 }
539
540 printf("exiting menu...\n");
541 }
542 return(TRUE);
543 }
544
545
546
MainLoop(gpointer data)547 gint MainLoop(gpointer data){
548 /*
549 Main gtk loop. executed 24 times by second.
550
551 */
552 int i,j;
553 int drawmap=FALSE;
554 static int cont=0;
555 float x0,y0;
556 static int lasttimepirates=2000;
557 static int lasttimeasteroids=0;
558 int timenow;
559 Object *cv0; /* coordinates center */
560 GtkWidget *drawing_area=(GtkWidget *) data;
561 GdkRectangle update_rect;
562 static int paused=0;
563 static int swpaused=0;
564 int gwidth,gheight;
565 static int ulx,uly;
566 int proc;
567 int swcomm=0; /* TRUE if in time step has communication */
568 int swmess=0; /* show a message */
569 char point[128];
570 char pointmess[128];
571 int loadsw =0;
572 static int sw=0;
573 int nx,ny;
574
575 double fpst=0;
576 static double fpstt=0;
577 static int fpscont=0;
578 static struct timeval time0,time1;
579
580 struct Player *plyr;
581 struct Keys *key;
582
583 static int stat_sw=0;
584 static char shellcad[MAXTEXTLEN]="";
585
586
587 if(gdraw.main==FALSE)return(TRUE);
588
589 gettimeofday(&time0,NULL);
590 timenow=GetTime();
591 Clock(2,CL_CLEAR);
592 Clock(2,CL_START);
593
594 if(gtime0==0){
595 gtime0=time(NULL);
596 }
597
598 if(!sw){ /* firsttime */
599 savefile=CreateSaveFile(param.server,param.client);
600
601 fprintf(stdout,"save file: %s\n",savefile);
602 fprintf(stdout,"record file: %s\n",recordfile);
603 fprintf(stdout,"options file: %s\n",optionsfile);
604
605 printf("init game vars...\n");
606 InitGameVars(); /* */
607
608 printf("... init game vars\n");
609 if(GameParametres(GET,GQUIT,0)==2 ){
610 Quit(NULL,NULL);
611 }
612
613 gfont=InitFonts(param.font);
614 if(gfont==NULL){
615 GameParametres(SET,GPANEL,PANEL_HEIGHT);
616 }
617 else{
618 GameParametres(SET,GPANEL,2*gdk_text_height(gfont,"pL",2));
619 }
620 GameParametres(SET,GHEIGHT,GameParametres(GET,GHEIGHT,0)-GameParametres(GET,GPANEL,0));
621
622 gwidth=GameParametres(GET,GWIDTH,0);
623 gheight=GameParametres(GET,GHEIGHT,0);
624
625 GameParametres(GET,GPANEL,0);
626 #ifndef GTK12
627 gtk_window_resize(GTK_WINDOW(win_main),gwidth,gheight+GameParametres(GET,GPANEL,0));
628 #endif
629 GameParametres(SET,GHEIGHT,drawing_area->allocation.height-GameParametres(GET,GPANEL,0));
630 GameParametres(SET,GWIDTH,drawing_area->allocation.width);
631
632 gdraw.menu=FALSE;
633
634 /* statistics */
635 InitStatistics();
636
637 /* snow */
638
639 CreateSnow(LXFACTOR,LYFACTOR);
640
641 sw++;
642 }
643
644 plyr=GetPlayers();
645
646 /***** fps *****/
647 Clock(0,CL_STOP);
648 fpst=Clock(0,CL_READ);
649 fpstt+=fpst;
650 fpscont++;
651 Clock(0,CL_CLEAR);
652 Clock(0,CL_START);
653 fps=fpscont/fpstt;
654 if(fpscont==20){
655 fpscont=10;
656 fpstt/=2;
657 }
658
659 /***** --fps *****/
660
661
662 ulx=GameParametres(GET,GULX,0);
663 uly=GameParametres(GET,GULY,0);
664
665 gwidth=GameParametres(GET,GWIDTH,0);
666 gheight=GameParametres(GET,GHEIGHT,0);
667
668 proc=GetProc();
669
670 /*****CELLON*****/
671
672 nx=GameParametres(GET,GULX,0)/2000;
673 ny=GameParametres(GET,GULY,0)/2000;
674 for(i=0;i<nx*ny;i++){
675 cell[i]=0;
676 }
677 UpdateCell(&listheadobjs,cell);
678
679 /*****--CELLON*****/
680
681
682 key_eval();
683
684 /* Create some lists */
685 {
686 int pmodified=0;
687 static int lasttimeupdate=0;
688
689 if(lasttimeupdate>60){
690 lasttimeupdate=0;
691 pmodified++;
692 }
693
694
695 for(i=0;i<GameParametres(GET,GNPLAYERS,0)+2;i++){
696 if(plyr[i].status==PLAYERMODIFIED){
697 pmodified++;
698 }
699 }
700
701 if(listheadplayer.update){
702 DestroyObjList(&listheadplayer);
703 listheadplayer.list=NULL;
704 listheadplayer.n=0;
705 CreatePlayerList(listheadobjs,&listheadplayer,actual_player);
706 listheadplayer.update=0;
707 }
708
709 if(pmodified){
710
711 lasttimeupdate=0;
712 /* update createplayerlist only if necesary HERE 9.44% CPU*/
713 /*
714 the list must be update when a ship is created or destroyed : mandatory
715 if habitat changes. no mandatory
716 HERE actualizar al cambiar habitat
717 */
718
719 for(i=0;i<GameParametres(GET,GNPLANETS,0)+1;i++){
720 DestroyObjList(&listheadcontainer[i]);
721 listheadcontainer[i].list=NULL;
722 listheadcontainer[i].n=0;
723 }
724
725 for(i=0;i<GameParametres(GET,GNPLAYERS,0)+2;i++){
726 DestroyObjList(&listheadkplanets[i]);
727 listheadkplanets[i].list=NULL;
728 listheadkplanets[i].n=0;
729 }
730 CreateContainerLists(&listheadobjs,listheadcontainer);
731 CreatekplanetsLists(&listheadobjs,listheadkplanets);
732
733 for(i=0;i<GameParametres(GET,GNPLAYERS,0)+2;i++){
734 if(plyr[i].status>=PLAYERACTIVE)plyr[i].status=PLAYERACTIVE;
735 }
736 }
737 lasttimeupdate++;
738 }
739 /* --Create some lists */
740
741
742 /* messages */
743 swmess=0;
744
745
746 /* GAME OVER */
747
748 if(GameParametres(GET,GPAUSED,0)==FALSE){
749
750 /* if(GameOver(&listheadplayer,players,actual_player)){
751 gameover=TRUE;
752 observeenemies=TRUE;
753 }
754 */
755 if(plyr[actual_player].status==PLAYERDEAD) {
756 gameover=TRUE;
757 observeenemies=TRUE;
758 }
759 else{
760 gameover=FALSE;
761 /* observeenemies=FALSE; */
762 }
763 }
764
765 if(gameover==TRUE){
766 sprintf(pointmess,"GAME OVER");
767 swmess++;
768 }
769
770 /* game paused */
771 if(GameParametres(GET,GPAUSED,0)==TRUE){
772 sprintf(pointmess,"PAUSED (press p to continue)");
773 swmess++;
774 }
775
776 /* game quit */
777 if(GameParametres(GET,GQUIT,0)==1){
778 sprintf(pointmess,"Really QUIT? ( y/n )");
779 swmess++;
780 }
781
782 if(swmess){
783 DrawMessageBox(pixmap,gfont,pointmess,gwidth/2,0.3*gheight,MBOXBORDER);
784 }
785
786 if(GameParametres(GET,GPAUSED,0)==TRUE){
787 int x,y,width,height;
788 int textw,texth;
789
790 /* update window */
791 if(swmess){
792 if(gfont!=NULL){
793 textw=gdk_text_width(gfont,pointmess,strlen(pointmess));
794 texth=gdk_text_height(gfont,pointmess,strlen(pointmess));
795 }
796 else{
797 texth=12;
798 textw=12;
799 }
800 width=textw+2*texth+1;
801 height=2*texth;
802
803 x=gwidth/2-width/2;
804 y=0.3*gheight-height/2;
805 if(x<10)x=10;
806
807 update_rect.x=x;
808 update_rect.y=y;
809 update_rect.width=width;
810 update_rect.height=height;
811 gtk_widget_draw(drawing_area,&update_rect);
812 }
813 if(swpaused>=NETSTEP){
814 return(TRUE); /* savepause */
815 }
816 if(GameParametres(GET,GNET,0)==TRUE){
817 sprintf(point,"Game PAUSED");
818 SendTextMessage(point);
819 }
820 swpaused++;
821 }
822 else{
823 swpaused=0;
824 }
825
826 /****************** if not paused *****************/
827
828 drawmap=FALSE;
829 if(!(cont%2))drawmap=TRUE;
830
831 /* ai */
832
833 for(i=1;i<GameParametres(GET,GNPLAYERS,0)+2;i++){
834 if(plyr[i].control==COMPUTER && proc==plyr[i].proc){
835 ControlCenter(&listheadobjs,&plyr[i]);
836 }
837 }
838
839 UpdateObjs(); /* new positions */
840 for(i=1;i<GameParametres(GET,GNPLAYERS,0)+2;i++){
841 if(proc==plyr[i].proc){
842 plyr[i].ttl--;
843 if(plyr[i].ttl<=0)plyr[i].modified=SENDPLAYERMOD;
844 }
845 }
846
847 for(i=0;i<GameParametres(GET,GNPLANETS,0)+1;i++){
848 Collision(&listheadcontainer[i]); /* interact among objects */
849 }
850
851 GetGold();
852
853 /**** create pirates *****/
854 if(GameParametres(GET,GPIRATES,0)==TRUE){
855 if( (plyr[GameParametres(GET,GNPLAYERS,0)+1].nplanets<5)){
856 if(proc==plyr[GameParametres(GET,GNPLAYERS,0)+1].proc){/* Send TO ai */
857 if(lasttimepirates>timenow){
858 lasttimepirates=timenow;
859 }
860 if(timenow-lasttimepirates>2000){/* 2000 */
861 if(((20000.0*rand())/RAND_MAX)<=1){
862 char text[MAXTEXTLEN];
863 float level=0;
864 int np=4;
865 level=timenow/30000.0; /* increase every 20 min */
866 lasttimepirates=timenow;
867 x0=ulx*Random(-1)-ulx/2;
868 y0=uly*Random(-1)-uly/2;
869 np=4+(int)level;
870 np=np>12?12:np;
871 CreatePirates(&listheadobjs,np,x0,y0,level);
872
873 snprintf(text,MAXTEXTLEN,"%s: %d %d",
874 GetLocale(L_PIRATESATSECTOR),
875 (int)(x0/SECTORSIZE),(int)(y0/SECTORSIZE));
876
877 if(!Add2TextMessageList(&listheadtext,text,0,-1,0,100,0)){
878 Add2CharListWindow(&gameloglist,text,0,&windowgamelog);
879 }
880 if(GameParametres(GET,GNET,0)==TRUE){
881 SendTextMessage(text);
882 }
883 }
884 }
885 }
886 }
887 }
888 /**** --create pirates *****/
889
890 /**** create asteroids *****/
891 if(proc==plyr[GameParametres(GET,GNPLAYERS,0)+1].proc){/* Send TO ai */
892
893 lasttimeasteroids=lasttimeasteroids>timenow?timenow:lasttimeasteroids;
894 if(timenow-lasttimeasteroids>3000){
895 if(((11000.0*rand())/RAND_MAX)<=1){ /* every 10 minutes */
896 char text[MAXTEXTLEN];
897 float factor;
898
899 factor=(float)GameParametres(GET,GULX,0)/100000.0;
900 factor*=factor;
901 factor=2*(factor+1);
902 lasttimeasteroids=timenow;
903 for(i=0;i<factor;i++){
904 x0=ulx*Random(-1)-ulx/2;
905 y0=uly*Random(-1)-uly/2;
906 /* Only create asteroids close to a ship */
907 if(Distance2NearestShip(&listheadobjs,-1,x0,y0)<MAXASTEROIDDISTANCE2){ /* 20 sectors */
908 CreateAsteroids(&listheadobjs,6,x0,y0);
909
910 for(j=1;j<GameParametres(GET,GNPLAYERS,0)+2;j++){
911
912 if(Distance2NearestShipLessThan(&listheadobjs,j,x0,y0,MAXASTEROIDDISTANCE2)){
913 snprintf(text,MAXTEXTLEN,"%s: %d %d",
914 GetLocale(L_ASTEROIDSATSECTOR),
915 (int)(x0/SECTORSIZE),(int)(y0/SECTORSIZE));
916 if(!Add2TextMessageList(&listheadtext,text,0,j,0,100,0)){
917 Add2CharListWindow(&gameloglist,text,1,&windowgamelog);
918 }
919 if(GameParametres(GET,GNET,0)==TRUE){
920 SendTextMessage(text);
921 }
922 }
923 }
924 }
925 }
926 }
927 }
928 }
929
930 /**** --create asteroids *****/
931
932
933 if(swpaused==TRUE){
934 printf("PAUSED\n");
935 fflush(NULL);
936 }
937
938
939 /*** check for cargo objects ****/
940 /* CargoCheck(&listheadobjs,cv); */
941 /*** --check for cargo objects ****/
942
943 /* synchronization with comm threads */
944
945 swcomm=FALSE;
946 if(GameParametres(GET,GNET,0)==TRUE){
947
948 if( !(cont%NETSTEP)){
949 CargoCheck(&listheadobjs,cv);
950 CheckModifiedPre(&listheadobjs,proc);
951 Setttl0(&listheadobjs);
952
953 NetComm(); /* net communication */
954
955 CheckModifiedPost(&listheadobjs,proc);
956 Setttl(&listheadobjs,-1);
957 swcomm=TRUE;
958 }
959 }
960 else{
961 swcomm=TRUE;
962 }
963
964 if(swcomm==TRUE){
965 GetPoints(&listheadobjs,proc,plyr);/* points and experience */
966 }
967
968 if(GameParametres(GET,GKPLANETS,0)==FALSE){
969 UpdateSectors(listheadobjs);
970 }
971
972 key=GetKeys();
973
974
975 if(key->load==TRUE && swcomm==TRUE){
976 key->load=FALSE;
977 key->save=FALSE;
978
979 DestroyObjList(&listheadplayer); /* HERE verify with DestroyAllObjs() in execload() */
980 listheadplayer.n=0;
981 listheadplayer.list=NULL;
982
983 if(ExecLoad(savefile)==0){
984 printf("EXECLOAD() done\n");
985 loadsw=1;
986 plyr=GetPlayers();
987 p_time=timenow;
988 gameover=FALSE;
989 observeenemies=FALSE;
990
991 CreatePlanetList(listheadobjs,&listheadplanets);
992 /* Density(); */
993
994 { /* deleting the message list */
995 struct TextMessageList *lh;
996 lh=&listheadtext;
997 while(lh->next!=NULL){
998 lh->next->info.duration=0;
999 lh=lh->next;
1000 }
1001 }
1002 DestroyCharList(&gameloglist);
1003 CheckGame("Checking game after load...",1);
1004 printf("done\n");
1005 }
1006 CreatePlayerList(listheadobjs,&listheadplayer,actual_player);
1007 listheadplayer.update=0;
1008 PrintGameOptions();
1009 /* print teams */
1010 PrintTeams();
1011 } /* if(key->load==TRUE && swcomm==TRUE){ */
1012
1013
1014 if(key->save==TRUE && swcomm==TRUE){ /* savepause */
1015 char text[MAXTEXTLEN];
1016 key->load=FALSE;
1017 key->save=FALSE;
1018
1019 { /* cargo lists */
1020 struct ObjList *ls;
1021 int cargomass=0;
1022 ls=listheadobjs.list;
1023 i=0;
1024 while(ls!=NULL){
1025 if(ls->obj->cargo.n>0){
1026 cargomass=ls->obj->cargo.mass;
1027 CargoBuild(ls->obj);
1028 ls->obj->cargo.mass=cargomass;
1029 }
1030 ls=ls->next;
1031 }
1032 } /* --cargo lists */
1033
1034 CheckGame("Checking game before save...",1);
1035 printf("done\n");
1036
1037 if(ExecSave(listheadobjs,savefile)==0){
1038 snprintf(text,MAXTEXTLEN,"%s.",GetLocale(L_GAMESAVED));
1039 if(!Add2TextMessageList(&listheadtext,text,0,-1,0,100,0)){
1040 Add2CharListWindow(&gameloglist,text,0,&windowgamelog);
1041 }
1042 if(GameParametres(GET,GNET,0)==TRUE){
1043 SendTextMessage(text);
1044 }
1045 }
1046 else{
1047 fprintf(stderr,"Error in MainLoop(): I can't open %s\n",savefile);
1048 }
1049 }
1050
1051 if(cv!=NULL){
1052 if(nav_mode==RELATIVE){
1053 r_rel.x=cv->x;
1054 r_rel.y=cv->y;
1055 }
1056 else{
1057 if(cv->x - r_rel.x>gwidth/2)
1058 r_rel.x+=gwidth;
1059 if(cv->x - r_rel.x <-gwidth/2)
1060 r_rel.x-=gwidth;
1061
1062 if(cv->y - r_rel.y>gheight/2)
1063 r_rel.y+=gheight;
1064 if(cv->y - r_rel.y <-gheight/2)
1065 r_rel.y-=gheight;
1066 }
1067 }
1068
1069
1070 /* Drawing window */
1071
1072 /* what to draw */
1073 if(key->esc==TRUE){
1074 key->f5=FALSE;
1075 key->f6=FALSE;
1076 key->f7=FALSE;
1077 gdraw.shiplist=FALSE;
1078 gdraw.gamelog=FALSE;
1079 gdraw.stats=FALSE;
1080 }
1081
1082 if(key->f5==TRUE){
1083 key->f7=FALSE;
1084 gdraw.shiplist=TRUE;
1085 gdraw.gamelog=FALSE;
1086 }
1087 else{
1088 gdraw.shiplist=FALSE;
1089 }
1090 if(key->f6==TRUE){
1091 gdraw.stats=TRUE;
1092 }
1093 else{
1094 gdraw.stats=FALSE;
1095 }
1096
1097 if(key->f7==TRUE){
1098 windowgamelog.active=TRUE;
1099 gdraw.gamelog=TRUE;
1100 gdraw.shiplist=FALSE;
1101 }
1102 else{
1103 gdraw.gamelog=FALSE;
1104 windowgamelog.active=FALSE;
1105 windowgamelog.scrollbar.n=0;
1106 }
1107 if(gdraw.shiplist||gdraw.gamelog){
1108 gdraw.info=FALSE;
1109 }
1110 else{
1111 gdraw.info=TRUE;
1112 }
1113
1114 if(key->mright){
1115 key->order.state=TRUE;
1116 key->g=TRUE;
1117 }
1118
1119 if(key->ctrl==TRUE && key->w==TRUE){
1120 key->order.state=TRUE;
1121 }
1122
1123 if(key->order.state==TRUE){
1124 gdraw.order=TRUE;
1125 }
1126 if(key->map.state==TRUE){
1127
1128 if(!(Shell(1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL)==2 &&
1129 Shell(2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL)==WRITE)){
1130 gdraw.map=gdraw.map==TRUE?FALSE:TRUE;
1131 }
1132 key->map.state=FALSE;
1133 }
1134 if(cv==NULL)gdraw.map=FALSE;
1135
1136 /*-- what to draw */
1137
1138
1139 /* game window*/
1140 if(paused==0){
1141
1142 /* clear window */
1143 if(gdraw.map==TRUE){
1144 if(drawmap){
1145 gdk_draw_rectangle(pixmap,
1146 GetColor(BLACK),
1147 TRUE,
1148 0,0,
1149 drawing_area->allocation.width,
1150 drawing_area->allocation.height);
1151 }
1152 }
1153 else{
1154 gdk_draw_rectangle(pixmap,
1155 GetColor(BLACK),
1156 TRUE,
1157 0,0,
1158 drawing_area->allocation.width,
1159 drawing_area->allocation.height);
1160
1161 }
1162 /* --clear window */
1163
1164 /* drawing sound volume */
1165
1166 if(gdraw.volume==TRUE){
1167 static int contvolume=100;
1168 int x,y;
1169 if(contvolume==0)contvolume=100;
1170 contvolume--;
1171 if(contvolume==0)gdraw.volume=FALSE;
1172 x=gwidth-65;
1173 y=gheight-15;
1174 DrawBarBox(pixmap,GetColor(RED),GetColor(RED),x,y,60,10,SetMasterVolume(0,VOLGET));
1175 }
1176
1177 if(gdraw.map==TRUE){
1178 if(drawmap){
1179 DrawMap(pixmap,actual_player,listheadobjs,cv,ulx);
1180 }
1181 }
1182 else{
1183 if(cv!=NULL){
1184 switch(habitat.type){
1185 case H_SPACE:
1186 DrawStars(pixmap,nav_mode,r_rel.x,r_rel.y);
1187 DrawRadar(pixmap,cv,&listheadobjs,gdraw.crash);
1188 break;
1189 case H_PLANET:
1190 DrawPlanetSurface(pixmap,habitat.obj->planet,gcolors[plyr[habitat.obj->player].color]);
1191
1192 /* snow */
1193 if(cv->in!=NULL){
1194 if(cv->in->id==3){
1195 UpdateFlakes(cv->in->planet);
1196 DrawFlakes(pixmap,GetColor(WHITE),gwidth,gheight);
1197 }
1198 }
1199 break;
1200 case H_SHIP:
1201 /**TODO draw ship ***/
1202 DrawSpaceShip(pixmap,cv,&listheadobjs);
1203 /*****/
1204 break;
1205 default:
1206 /* draw nothing */
1207 break;
1208 }
1209 }
1210
1211 DrawObjs(pixmap,&listheadobjs,habitat,cv,r_rel);
1212
1213 if(cv!=NULL){
1214 if(cv->accel>0){
1215 Play(cv,THRUST,1.0*cv->accel/cv->engine.a_max);
1216 }
1217 }
1218 }
1219
1220 if(gdraw.crash)gdraw.crash=0;
1221
1222 if(gdraw.shiplist==TRUE){
1223 DrawPlayerList(pixmap,actual_player,&listheadplayer,cv,loadsw || !(timenow%20));
1224 }
1225
1226 if(gdraw.gamelog==TRUE){
1227 DrawWindow(pixmap,gfont,GetColor(WHITE),10,10,1,&windowgamelog);
1228 }
1229
1230 DrawInfo(pixmap,cv,&gdraw,&listheadobjs,&listheadtext);
1231 }/* if(paused==0) */
1232
1233 if(!(cont%24)){ /* statistics */
1234 UpdateStatistics();
1235 /* PrintStatistics(); */
1236 }
1237
1238 /**** draw stats ****/
1239 if(gdraw.stats==TRUE){
1240 Rectangle rect;
1241 int x;
1242 stat_sw=1;
1243 rect.x=5;
1244 rect.y=5;
1245 rect.width=200;
1246 rect.height=100;
1247 x=DrawGameStatistics(pixmap,plyr)-5;
1248
1249 rect.height=100;
1250 rect.width=x-5;
1251 if(rect.width>195)rect.width=195;
1252 if(rect.width<0)rect.width=0;
1253
1254 Statistics_Draw(pixmap,&rect);
1255
1256 }
1257 else{
1258 if(stat_sw==1){
1259 if(pixmap){
1260 gdk_pixmap_unref(pixmap);
1261 }
1262 pixmap=gdk_pixmap_new(d_a->window,
1263 d_a->allocation.width,
1264 d_a->allocation.height,
1265 -1);
1266 stat_sw=0;
1267 }
1268 }
1269 /**** --draw stats ****/
1270
1271
1272 if(swmess){
1273 DrawMessageBox(pixmap,gfont,pointmess,gwidth/2,0.3*gheight,MBOXBORDER);
1274 }
1275
1276
1277 /* Draw Shell */
1278
1279 if(gdraw.order==TRUE){/* QWERTY */
1280 gdk_draw_line(pixmap,GetColor(WHITE),
1281 0,gheight,
1282 gwidth,gheight);
1283
1284 cv0=cv; /* coordinates center */
1285 ShellTitle(2,NULL,NULL,NULL,NULL,0,0);
1286 Shell(0,pixmap,GetColor(GREEN),gfont,&listheadobjs,&plyr[actual_player],key,&cv,shellcad);
1287 DrawString(pixmap,gfont,GetColor(GREEN),10,GameParametres(GET,GHEIGHT,0)+GameParametres(GET,GPANEL,0)/2+4,shellcad);
1288 if(key->order.state==FALSE)gdraw.order=FALSE;
1289 if(cv!=NULL){
1290 if(cv->mode==SOLD){
1291 cv=SelectObjInObj(&listheadplayer,cv->in->id,cv->player);
1292 if(cv!=NULL){
1293 cv->selected=TRUE;
1294 if(cv->in==cv0->in){
1295 habitat.type=cv->habitat;
1296 habitat.obj=cv->in;
1297 }
1298 else{
1299 cv=cv0;
1300 }
1301 }
1302 }
1303
1304 if(cv0!=cv){ /* if center coordinates changes */
1305 if(cv!=NULL){
1306 habitat.type=cv->habitat;
1307 habitat.obj=cv->in;
1308 if(cv->type==PLANET){
1309 habitat.type=H_PLANET;
1310 habitat.obj=cv;
1311 }
1312 }
1313 }
1314 }
1315 }
1316 else{
1317 gdk_draw_line(pixmap,GetColor(RED),
1318 0,gheight,
1319 gwidth,gheight);
1320 }
1321
1322 /* --Draw Shell */
1323
1324
1325 /*Selection box */
1326 SelectionBox(pixmap,GetColor(GREEN),&cv,0);
1327 /* --Selection box */
1328
1329 /* show window */
1330
1331 if(gdraw.map==TRUE){
1332 if(drawmap){
1333 update_rect.x=0;
1334 update_rect.y=0;
1335 update_rect.width=drawing_area->allocation.width;
1336 update_rect.height=drawing_area->allocation.height;
1337 }
1338 }
1339 else{
1340 update_rect.x=0;
1341 update_rect.y=0;
1342 update_rect.width=drawing_area->allocation.width;
1343 update_rect.height=drawing_area->allocation.height;
1344 }
1345
1346 gtk_widget_draw(drawing_area,&update_rect); /* deprecated */
1347
1348 if(GameParametres(GET,GPAUSED,0)==TRUE){
1349 paused=1;
1350 }
1351 else{
1352 paused=0;
1353 }
1354
1355
1356 /* --Drawing window */
1357
1358 if(GameParametres(GET,GPAUSED,0)==FALSE){
1359 IncTime();
1360 }
1361
1362
1363 loadsw=0;
1364
1365 if(GameParametres(GET,GQUIT,0)==2 && swcomm==TRUE){
1366 Quit(NULL,NULL);
1367 }
1368
1369 if(swcomm){
1370 /*** check for cargo objects ****/
1371 CargoCheck(&listheadobjs,cv);
1372 /*** --check for cargo objects ****/
1373 if(RemoveDeadObjs(&listheadobjs,cv)==NULL){
1374 cv=NULL;
1375 }
1376 }
1377
1378 if(IsInObjList(&listheadobjs,ship_c)==0){
1379 ship_c=NULL;
1380 }
1381
1382 if(cv!=NULL){
1383 habitat.type=cv->habitat;
1384 habitat.obj=cv->in;
1385 if(cv->type==PLANET){
1386 habitat.type=H_PLANET;
1387 habitat.obj=cv;
1388 }
1389 }
1390
1391 /* Check for GAMEOVER */
1392
1393 for(i=1;i<GameParametres(GET,GNPLAYERS,0)+1;i++){
1394 if(!((cont+i)%30) && plyr[i].status>=PLAYERACTIVE){
1395 if(GameOver(&listheadobjs,plyr,i)){
1396 plyr[i].status=PLAYERDEAD;
1397 plyr[i].level=0;
1398 }
1399 }
1400 }
1401
1402 cont++;
1403 {
1404 static double t=0,tt=0;
1405 static int c=0;
1406 Clock(2,CL_STOP);
1407 t=Clock(2,CL_READ);
1408 tt+=t;
1409 c++;
1410 if(c==20){
1411 tt=0;
1412 c=0;
1413 }
1414 }
1415
1416 gettimeofday(&time1,NULL);
1417
1418 return(TRUE);
1419
1420 } /* MainLoop */
1421
1422
1423
Quit(GtkWidget * widget,gpointer gdata)1424 gint Quit(GtkWidget *widget,gpointer gdata){
1425 /*
1426
1427 */
1428
1429
1430
1431 sem_close(&sem_barrier);
1432 sem_close(&sem_barrier1);
1433
1434 #if SOUND
1435 printf("Sound Closed\n");
1436 ExitSound();
1437 printf("Sound Closed\n");
1438 #endif
1439
1440 DestroyAllObj(&listheadobjs);
1441 listheadobjs.list=NULL;
1442 listheadobjs.n=0;
1443 ship_c=NULL;
1444 cv=NULL;
1445
1446
1447 QuitGraphics(widget,gdata);
1448 printf("Graphics Closed\n");
1449 return FALSE;
1450 }
1451
key_eval(void)1452 void key_eval(void){
1453 /*
1454 version 01 13May11
1455 Evaluate all the key and mouse press
1456
1457 */
1458 struct ObjList *ls;
1459 Object *obj;
1460 static int swtab=0;
1461 static int swtab0=0;
1462 int proc;
1463 int keyf=-1;
1464 int navcontrol=TRUE; /* FALSE nav mode, TRUE order mode */
1465 int x,y;
1466
1467 struct Player *plyr;
1468 struct Keys *key;
1469
1470 plyr=GetPlayers();
1471 key=GetKeys();
1472 if(gdraw.menu==TRUE){
1473 return;
1474 }
1475 proc=GetProc();
1476
1477 /* QUIT game */
1478
1479 if(key->ctrl==TRUE && key->q==TRUE){
1480 GameParametres(SET,GQUIT,1); /* ask: Really Quit? */
1481 }
1482
1483 if(GameParametres(GET,GQUIT,0)==1){
1484 if(key->n==TRUE || key->esc==TRUE){
1485 GameParametres(SET,GQUIT,0);
1486 key->ctrl=FALSE;
1487 key->q=FALSE;
1488 key->n=FALSE;
1489 key->esc=FALSE;
1490 }
1491 if(key->y==TRUE){
1492 GameParametres(SET,GQUIT,2); /* Quit game */
1493 GameParametres(SET,GPAUSED,FALSE);
1494 }
1495 return;
1496 }
1497
1498 if(key->esc==TRUE){
1499 key->alt=FALSE;
1500 key->ctrl=FALSE;
1501 Shell(0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); /* reset shell() */
1502 key->order.state=FALSE; /* aqui01 salir de order mode */
1503 }
1504
1505
1506 /* game paused */
1507 if(key->p==TRUE && GameParametres(GET,GPAUSED,0)==TRUE){
1508 GameParametres(SET,GPAUSED,FALSE);
1509 key->ctrl=FALSE;
1510 key->p=FALSE;
1511 }
1512 if(key->ctrl==TRUE && key->p==TRUE && GameParametres(GET,GPAUSED,0)==FALSE){
1513 GameParametres(SET,GPAUSED,TRUE);
1514 key->ctrl=FALSE;
1515 key->p=FALSE;
1516 Shell(0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); /* reset shell() */
1517 key->order.state=FALSE; /* aqui01 salir de order mode */
1518 navcontrol=TRUE;
1519 }
1520
1521 if(GameParametres(GET,GPAUSED,0)==TRUE){
1522 Sound(SPAUSE,MUSIC);
1523 }
1524 else{
1525 Sound(SPLAY,MUSIC);
1526 }
1527
1528
1529 /* mouse */
1530 if(key->mleft==TRUE){
1531 }
1532 if(key->mright==TRUE){
1533 }
1534 if(key->mdclick==TRUE){
1535 key->mdclick=FALSE;
1536 }
1537
1538 if(key->mleft==TRUE){
1539 if(WindowFocus(&windowgamelog)){
1540 MousePos(GET,&x,&y);
1541 ActWindow(&windowgamelog);
1542 key->mleft=FALSE;
1543 }
1544 }
1545
1546
1547 /* --mouse */
1548
1549 /* sound */
1550
1551 if(key->ctrl==TRUE && (key->plus==TRUE||key->minus==TRUE)){
1552 if(key->plus==TRUE){
1553 SetMasterVolume(0.025,VOLINC);
1554 gdraw.volume=TRUE;
1555 }
1556 if(key->minus==TRUE){
1557 SetMasterVolume(-0.025,VOLINC);
1558 gdraw.volume=TRUE;
1559 }
1560
1561 GameParametres(SET,GSOUNDVOL,param.soundvol);
1562 }
1563 /* --sound */
1564
1565
1566 navcontrol=TRUE;
1567 if(key->order.state==TRUE)navcontrol=FALSE;
1568
1569 /* in map view don't control the ship*/
1570 if(gdraw.map==TRUE){
1571 key->accel.state=key->turnleft.state=key->turnright.state=key->fire.state=FALSE;
1572 key->automode.state=key->manualmode.state=FALSE;
1573 }
1574
1575 switch(navcontrol){
1576 case FALSE: /* order mode */
1577 break;
1578 case TRUE: /* Nav mode */
1579 /* f1 f2 f3 f4 */
1580 keyf=-1;
1581 if(key->f1)keyf=0;
1582 if(key->f2)keyf=1;
1583 if(key->f3)keyf=2;
1584 if(key->f4)keyf=3;
1585 key->f1=key->f2=key->f3=key->f4=FALSE;
1586
1587 if(keyf>=0) {
1588 if(key->ctrl==TRUE){
1589 key->ctrl=FALSE;
1590 if(cv!=NULL)
1591 fobj[keyf]=cv->id;
1592 }
1593 else{
1594 if((obj=SelectObj(&listheadobjs,fobj[keyf]))!=NULL){
1595 if(cv!=NULL)cv->selected=FALSE;
1596 cv=obj;
1597 habitat.type=cv->habitat;
1598 habitat.obj=cv->in;
1599 SelectionBox(NULL,NULL,&cv,2);
1600 cv->selected=TRUE;
1601 }
1602 }
1603 }
1604 /*-- f1 f2 f3 f4 */
1605
1606 /* observe enemies */
1607
1608 if(observeenemies==TRUE){
1609 if(key->f9==TRUE || key->f10==TRUE){
1610 if(cv!=NULL){
1611 plyr[actual_player].cv=cv->id;
1612 }
1613 else{
1614 plyr[actual_player].cv=0;
1615 }
1616 if(key->f9==TRUE){
1617 key->f9=FALSE;
1618 actual_player--;
1619 if(actual_player<1){
1620 actual_player=GameParametres(GET,GNPLAYERS,0)+1;
1621 }
1622 }
1623 if(key->f10==TRUE){
1624 key->f10=FALSE;
1625 actual_player++;
1626 if(actual_player>GameParametres(GET,GNPLAYERS,0)+1){
1627 actual_player=1;
1628 }
1629 }
1630
1631 DestroyObjList(&listheadplayer);
1632 listheadplayer.n=0;
1633 listheadplayer.list=NULL;
1634 CreatePlayerList(listheadobjs,&listheadplayer,actual_player);
1635 listheadplayer.update=0;
1636
1637 cv=SelectObj(&listheadplayer,plyr[actual_player].cv);
1638 if(cv==NULL){
1639 cv=NextCv(&listheadplayer,cv,actual_player);
1640 }
1641 if(cv!=NULL){
1642 habitat.type=cv->habitat;
1643 habitat.obj=cv->in;
1644 SelectionBox(NULL,NULL,&cv,2);
1645 }
1646 }
1647 } /*-- observe enemies */
1648
1649 if(ship_c!=NULL){
1650 if(ship_c->type!=SHIP){
1651 key->trace=FALSE;
1652 ship_c->trace=FALSE;
1653 }
1654 if(ship_c->subtype!=EXPLORER &&
1655 ship_c->subtype!=FIGHTER &&
1656 ship_c->subtype!=QUEEN &&
1657 ship_c->subtype!=FREIGHTER){
1658 key->trace=FALSE;
1659 ship_c->trace=FALSE;
1660 }
1661
1662 if(key->trace==TRUE){
1663 if(ship_c->trace==TRUE)
1664 ship_c->trace=FALSE;
1665 else
1666 ship_c->trace=TRUE;
1667 key->trace=FALSE;
1668 }
1669
1670 if(ship_c->ai == 0 && proc==plyr[ship_c->player].proc){
1671
1672 if(key->down==TRUE){
1673 ship_c->accel-=.08;
1674 if(ship_c->accel<0)ship_c->accel=0;
1675 }
1676
1677 /**** ship movement *****/
1678
1679 if(cv==ship_c){
1680 if(ship_c->gas>0 && gdraw.map==FALSE){
1681 if(cv->type==SHIP && cv->subtype==PILOT){
1682 key->accel.state=key->turnleft.state=key->turnright.state=key->fire.state=FALSE;
1683 }
1684 if(key->accel.state==TRUE){
1685 if(ship_c->mode==LANDED && fabs(ship_c->a-PI/2)>.35){
1686 ship_c->accel=0;
1687 }
1688 else{
1689 ship_c->accel+=ship_c->engine.a;
1690 if(ship_c->accel>ship_c->engine.a_max)ship_c->accel=ship_c->engine.a_max;
1691 }
1692 }
1693 else{
1694 ship_c->accel=0;
1695 }
1696 if(ship_c->mode==LANDED && ship_c->vy>0){ship_c->mode=NAV;}
1697 if(key->turnleft.state==TRUE && ship_c->gas > ship_c->engine.gascost){
1698 ship_c->ang_a+=ship_c->engine.ang_a;
1699 if(ship_c->ang_a > ship_c->engine.ang_a_max)
1700 ship_c->ang_a=ship_c->engine.ang_a_max;
1701 }
1702 if(key->turnright.state==TRUE && ship_c->gas>ship_c->engine.gascost){
1703 ship_c->ang_a-=ship_c->engine.ang_a;
1704 if(ship_c->ang_a < -ship_c->engine.ang_a_max)
1705 ship_c->ang_a = -ship_c->engine.ang_a_max;
1706 }
1707 if(key->turnleft.state==FALSE && key->turnright.state==FALSE){
1708 ship_c->ang_a=0;
1709 }
1710 if(key->fire.state==TRUE && ship_c->gas > 2){
1711 if (!ship_c->weapon->cont1){
1712 ChooseWeapon(ship_c);
1713 if(proc==plyr[ship_c->player].proc){
1714 if(FireCannon(&listheadobjs,ship_c,NULL)==0){
1715 Play(ship_c,FIRE0,1);
1716 }
1717 }
1718 }
1719 }
1720 }
1721 }
1722 /**** --ship movement *****/
1723 }
1724 }/* if(ship_c!=NULL) */
1725
1726 if(cv!=NULL){
1727 if(key->ctrl && key->n==TRUE){
1728 if(nav_mode==RELATIVE){
1729 nav_mode=ABSOLUTE;
1730 r_rel.x=cv->x;
1731 r_rel.y=cv->y;
1732 }
1733 else{
1734 nav_mode=RELATIVE;
1735 }
1736 key->n=FALSE;
1737 }
1738
1739 if(actual_player==actual_player0){
1740
1741 if(key->automode.state==TRUE){
1742 /* pressing 'down' the selected ship goes to automatic mode */
1743 if(GameParametres(GET,GQUIT,0)==0){
1744 if(cv->type==SHIP &&
1745 (cv->subtype==FIGHTER ||
1746 cv->subtype==EXPLORER ||
1747 cv->subtype==QUEEN ||
1748 cv->subtype==FREIGHTER ||
1749 cv->subtype==TOWER)){
1750 ship_c=cv;
1751 ship_c->ai=1;
1752 key->manualmode.state=FALSE;
1753 key->automode.state=FALSE;
1754 }
1755 }
1756 }
1757
1758 if(key->manualmode.state==TRUE && cv->type==SHIP &&
1759 /* pressing a movement key the spaceship goes to manual mode */
1760 (cv->subtype==FIGHTER || cv->subtype==EXPLORER || cv->subtype==QUEEN || cv->subtype==FREIGHTER || cv->subtype==TOWER)){
1761 ship_c=cv;
1762 if(ship_c->ai)ship_c->weapon=&ship_c->weapon0;
1763 ship_c->ai=0;
1764
1765 key->manualmode.state=FALSE;
1766 key->automode.state=FALSE;
1767 }
1768
1769 if(key->number[1]==TRUE){
1770 if(cv->weapon0.type!=CANNON0)
1771 cv->weapon=&cv->weapon0;
1772 key->number[1]=FALSE;
1773 }
1774 if(key->number[2]==TRUE){
1775 if(cv->weapon1.type!=CANNON0)
1776 cv->weapon=&cv->weapon1;
1777 key->number[2]=FALSE;
1778 }
1779 if(key->number[3]==TRUE){
1780 if(cv->weapon1.type!=CANNON0)
1781 cv->weapon=&cv->weapon2;
1782 key->number[3]=FALSE;
1783 }
1784 }
1785 }
1786
1787 break;
1788 default:
1789 break;
1790 }
1791
1792 if(!(key->Pagedown | key->Pageup | key->home | key->tab)){
1793 swtab=0;
1794 swtab0=0;
1795 }
1796
1797 if(key->Pagedown|key->Pageup|key->home|key->tab){
1798 Shell(0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); /* reset shell() */
1799 key->order.state=FALSE; /* aqui01 salir de order mode */
1800 navcontrol=TRUE;
1801 key->p=FALSE;
1802
1803 if(key->tab==TRUE){
1804 if(swtab==0){
1805 if(cv!=NULL)cv->selected=FALSE;
1806 if(key->ctrl==TRUE){
1807 cv=PrevCv(&listheadplayer,cv,actual_player);
1808 }
1809 else{
1810 cv=NextCv(&listheadplayer,cv,actual_player);
1811 }
1812 }
1813 swtab++;
1814 if(swtab0)if(swtab>1)swtab=0;
1815 if(swtab>6){swtab=0;swtab0=1;}
1816 }
1817
1818 if(key->Pagedown|key->Pageup|key->home){
1819 if(swtab==0){
1820 if(cv!=NULL)cv->selected=FALSE;
1821 if(key->Pagedown==TRUE){
1822 cv=NextPlanetCv(&listheadplayer,cv,actual_player);
1823 key->Pagedown=FALSE;
1824 }
1825 if(key->Pageup==TRUE){
1826 cv=PrevPlanetCv(&listheadplayer,cv,actual_player);
1827 key->Pageup=FALSE;
1828 }
1829 if(key->home==TRUE){
1830 key->home=FALSE;
1831 cv=FirstShip(&listheadplayer,cv,actual_player);
1832 }
1833 }
1834 swtab++;
1835 if(swtab0)if(swtab>1)swtab=0;
1836 if(swtab>6){swtab=0;swtab0=1;}
1837 }
1838
1839 if(cv!=NULL){
1840 habitat.type=cv->habitat;
1841 habitat.obj=cv->in;
1842 SelectionBox(NULL,NULL,&cv,2);
1843 cv->selected=TRUE;
1844
1845 if(nav_mode==ABSOLUTE){
1846 while(cv->x - r_rel.x>GameParametres(GET,GWIDTH,0)/2){
1847 r_rel.x+=GameParametres(GET,GWIDTH,0);
1848 }
1849 while(cv->x - r_rel.x <-GameParametres(GET,GWIDTH,0)/2){
1850 r_rel.x-=GameParametres(GET,GWIDTH,0);
1851 }
1852 while(cv->y - r_rel.y>GameParametres(GET,GHEIGHT,0)/2){
1853 r_rel.y+=GameParametres(GET,GHEIGHT,0);
1854 }
1855 while(cv->y - r_rel.y <-GameParametres(GET,GHEIGHT,0)/2){
1856 r_rel.y-=GameParametres(GET,GHEIGHT,0);
1857 }
1858 }
1859 }
1860 }
1861
1862 /* save and load game */
1863 if(key->ctrl==TRUE && key->s==TRUE){
1864 if(GameParametres(GET,GMODE,0)==CLIENT){
1865 key->save=FALSE;
1866 }
1867 else{
1868 key->save=TRUE;
1869 key->s=FALSE;
1870 }
1871 }
1872
1873 if(key->ctrl==TRUE && key->l==TRUE){
1874
1875 if(GameParametres(GET,GMODE,0)==CLIENT){
1876 key->load=FALSE;
1877 }
1878 else{
1879 key->load=TRUE;
1880 key->l=FALSE;
1881 }
1882 }
1883 /*-- save and load game */
1884
1885 /* alt modes. Cargo */
1886
1887 if(gdraw.order==FALSE && key->alt==TRUE){
1888 int n=0;
1889 int subtype=-1;
1890 if(key->s==TRUE){ /* SATELLITE off*/
1891 subtype=SATELLITE;
1892 key->s=FALSE;
1893 }
1894 if(key->p==TRUE){ /* PILOT off*/
1895 subtype=PILOT;
1896 key->p=FALSE;
1897 }
1898
1899 if(subtype!=-1){
1900
1901 /*
1902 take off one object from selected ships
1903 */
1904 ls=listheadobjs.list;
1905 while(ls!=NULL){ /* HERE create a selected list */
1906 if(ls->obj->selected==TRUE){
1907 obj=CargoGet(ls->obj,SHIP,subtype);
1908 if(obj!=NULL){
1909 n++;
1910 obj->habitat=ls->obj->habitat;
1911 obj->in=ls->obj->in;
1912 obj->mode=NAV;
1913 obj->planet=NULL;
1914 obj->ai=1;
1915 obj->x=ls->obj->x + ls->obj->radio*cos(ls->obj->a-PI);
1916 obj->y=ls->obj->y + ls->obj->radio*sin(ls->obj->a-PI);
1917 obj->vx=ls->obj->vx - 0.5+Random(-1);
1918 obj->vy=ls->obj->vy - 0.5+Random(-1);
1919
1920 if(GameParametres(GET,GNET,0)==TRUE){
1921 SetModified(obj,SENDOBJALL);
1922 if(obj->modified!=SENDOBJALL){
1923 printf("OBJ EJECT mod: %d\n",obj->modified);
1924 }
1925 }
1926 }
1927 }
1928 ls=ls->next;
1929 }
1930 }
1931 }
1932 /* alt modes. Cargo */
1933
1934 }
1935
1936
1937
1938
UpdateShip(Object * obj)1939 void UpdateShip(Object *obj){
1940 /*
1941 Calculate the new coordinates of the ship *obj:
1942 calculate gravity forces
1943 update position and velocity
1944 recharge armor and fuel
1945 repair ship
1946 learning and experience
1947 check collision with planets
1948 */
1949
1950 float vx,vy,v,vmax2;
1951 float cosa,sina;
1952 float rx,ry;
1953 float vr,vo;
1954 float fx,fy;
1955 float fx0,fy0;
1956 float dtim;
1957 float a,factor;
1958 float g=1.2/250000;
1959 int time;
1960 int n;
1961 int proc;
1962 float b=0.05; /* air resistance */
1963 float bx,by;
1964 int mass;
1965 struct Player *plyr;
1966 plyr=GetPlayers();
1967
1968 proc=GetProc();
1969
1970 mass=obj->mass+obj->cargo.mass;
1971
1972 if(obj->habitat==H_SHIP){
1973 if(obj->in!=NULL){
1974 obj->x=obj->in->x;
1975 obj->x0=obj->in->x0;
1976 obj->y=obj->in->y;
1977 obj->y0=obj->in->y0;
1978 obj->vx=obj->in->vx;
1979 obj->vy=obj->in->vy;
1980 }
1981 else{
1982 if(GameParametres(GET,GNET,0)==FALSE){
1983 fprintf(stderr,"ERROR UpdateShip(): habitat=H_SHIP in = NULL id: %d (pid:%d) t:%d st: %d player: %d\n",obj->id,obj->pid, obj->type,obj->subtype,obj->player);
1984 exit(-1);
1985 }
1986 }
1987 return;
1988 }
1989
1990 vx=obj->vx;
1991 vy=obj->vy;
1992 dtim=DT/mass;
1993 fx0=fy0=0;
1994 bx=by=0;
1995 /***** Forces 1*****/
1996 switch(obj->habitat){
1997 case H_SPACE:
1998 PlanetAtraction(&fx0,&fy0,obj->x,obj->y,mass);
1999 if(obj->subtype==SATELLITE){
2000 if(fx0>0.0000001){
2001 obj->life=LIFESATELLITE;
2002 }
2003 }
2004
2005
2006 break;
2007 case H_PLANET:
2008 if(obj->mode==LANDED){fy0=0;}
2009 else{ /* air resistance, */
2010 v=sqrt(obj->vx*obj->vx+obj->vy*obj->vy);
2011 b*=(obj->in->mass/120000 + 0.75); /* density */
2012 bx=-b*v*obj->vx; /* wind HERE TODO +3; */
2013 by=-b*v*obj->vy;
2014 fy0=-g*mass*(float)obj->in->mass+by;
2015 fx0=bx;
2016 }
2017 break;
2018 case H_SHIP:
2019 fx0=fy0=0;
2020 if(obj->in==NULL){
2021 fprintf(stderr,"ERROR UpdateShip(hship): in = NULL in id: %d (%d) t:%d st: %d\n",obj->id,obj->pid, obj->type,obj->subtype);
2022 return;
2023 }
2024 break;
2025 default:
2026 fprintf(stderr,"ERROR UpdateShip(): Habitat unknown: %d in = NULL in id: %d (%d) t:%d st: %d\n",obj->habitat,obj->id,obj->pid, obj->type,obj->subtype);
2027 exit(-1);
2028 break;
2029 }
2030
2031 /*** first step ****/
2032
2033 obj->x0=obj->x;
2034 obj->y0=obj->y;
2035
2036 if(obj->mode==NAV){
2037 obj->x+=(vx+.5*(fx0)*dtim)*DT;
2038 obj->y+=(vy+.5*(fy0)*dtim)*DT;
2039 }
2040
2041 /*** forces 2 ****/
2042
2043 fx=fy=0;
2044 switch(obj->habitat){
2045 case H_SPACE:
2046 PlanetAtraction(&fx,&fy,obj->x,obj->y,mass);
2047 break;
2048 case H_PLANET:
2049 if(obj->mode==LANDED){fy=0;}
2050 else{
2051 fy=-g*mass*(float)obj->in->mass+by;
2052 fx=bx;
2053 }
2054 break;
2055 default:
2056 fx=fy=0;
2057 break;
2058 }
2059
2060 /***** gas cost *****/
2061 if(proc==plyr[obj->player].proc || (obj->type==PROJECTILE && obj->subtype==MISSILE)){
2062 if(obj->engine.a>0){
2063 if(obj->accel>0){
2064 obj->gas-=10*obj->engine.gascost*obj->accel/obj->engine.a_max;
2065 if(obj->gas<0){
2066 obj->gas=0;
2067 obj->accel=0;
2068 }
2069 }
2070 }
2071
2072 if(obj->engine.ang_a_max && obj->ang_a!=0){
2073 obj->gas-=fabs(obj->engine.gascost*obj->ang_a/obj->engine.ang_a_max);
2074 if(obj->gas<0){
2075 obj->gas=0;
2076 obj->ang_a=0;
2077 }
2078 }
2079 }
2080
2081 /***** step 2 *****/
2082 if(obj->accel){
2083 vx+=(.5*(fx+fx0)+cos(obj->a)*obj->accel)*dtim;
2084 vy+=(.5*(fy+fy0)+sin(obj->a)*obj->accel)*dtim;
2085 }
2086 else{
2087 vx+=(.5*(fx+fx0))*dtim;
2088 vy+=(.5*(fy+fy0))*dtim;
2089 }
2090
2091
2092 if(obj->mode==LANDED){
2093 if(vy<=0){
2094 vy=0;
2095 vx=0;
2096 }
2097 else{
2098 if(obj->accel>0){
2099 obj->mode=NAV;
2100 }
2101 }
2102 }
2103
2104 /***** if max vel is reached, reescaling *****/
2105
2106 if(obj->type==SHIP){
2107 vmax2=obj->engine.v2_max*(1-0.4375*(obj->state<25)) + (obj->level*50)*(obj->accel>0);
2108 if(obj->subtype==PILOT)vmax2=15*15;
2109 }
2110 else{
2111 if(obj->engine.type>ENGINE0){
2112 vmax2=obj->engine.v2_max;
2113 }
2114 else{
2115 vmax2=(VELMAX2);
2116 }
2117 }
2118
2119 if(vx*vx+vy*vy>vmax2){
2120 factor=sqrt(vmax2/(vx*vx+vy*vy));
2121 if(factor>1){
2122 fprintf(stderr,"ERROR factor>1\n");
2123 printf("\tobj_enginev2max: %d %d\n",obj->engine.v2_max,(obj->state<25));
2124 }
2125 vx*=factor;
2126 vy*=factor;
2127 }
2128
2129 /***** angular velocity *****/
2130
2131 if(obj->ang_a!=0){
2132 obj->ang_v+=obj->ang_a*100.*dtim;
2133 if(obj->ang_v > obj->engine.ang_v_max)obj->ang_v=obj->engine.ang_v_max;
2134 if(obj->ang_v < -obj->engine.ang_v_max)obj->ang_v=-obj->engine.ang_v_max;
2135 }
2136 else{
2137 if(obj->type==SHIP && obj->subtype!=PILOT) /* HERE TODO add artifact to engine*/
2138 obj->ang_v*=0.5;
2139 }
2140
2141 obj->a+=(obj->ang_v+0.5*obj->ang_a*100.*dtim)*DT;
2142
2143 if(obj->mode==LANDED){ /* max angle of landed ships */
2144 float maxang=0;
2145 switch(obj->subtype){
2146 case EXPLORER:
2147 case FIGHTER:
2148 case QUEEN:
2149 maxang=PI/4;
2150 break;
2151 case FREIGHTER:
2152 case PILOT:
2153 maxang=0;
2154 break;
2155 default:
2156 maxang=PI/2-PI/40;
2157 break;
2158 }
2159 if(obj->a>PI/2+maxang){obj->a=PI/2+maxang;obj->ang_a=obj->ang_v=0;}
2160 if(obj->a<PI/2-maxang){obj->a=PI/2-maxang;obj->ang_a=obj->ang_v=0;}
2161 }
2162 if(obj->a > PI)obj->a-=2*PI;
2163 if(obj->a < -PI)obj->a+=2*PI;
2164 obj->vx=vx;
2165 obj->vy=vy;
2166 obj->fx0=fx0;
2167 obj->fy0=fy0;
2168 obj->fx=fx;
2169 obj->fy=fy;
2170
2171 /***** recharging armor and fuel ******/
2172
2173 if(obj->weapon0.cont1)obj->weapon0.cont1--;
2174 if(obj->weapon1.cont1)obj->weapon1.cont1--;
2175 if(obj->weapon2.cont1)obj->weapon2.cont1--;
2176
2177 if(proc==plyr[obj->player].proc){
2178 time=GetTime();
2179 /* refuel in space */
2180 if(obj->type==SHIP && obj->subtype!=PILOT && obj->habitat==H_SPACE){
2181 obj->gas+=0.05;
2182 if(obj->gas > obj->gas_max)obj->gas=obj->gas_max;
2183 if(obj->state>0 && obj->state<25){
2184 obj->state+=0.005;
2185 }
2186 }
2187
2188 /* ammunition in space */
2189 if(!(time%100)){
2190 if(obj->type==SHIP && obj->subtype==SATELLITE && obj->habitat==H_SPACE){
2191 if(obj->gas > 0.1*obj->gas_max &&
2192 obj->state>25 &&
2193 obj->weapon0.n<obj->weapon0.max_n){
2194 obj->weapon0.n++;
2195 }
2196 }
2197 }
2198 /*
2199 * repair, refuel and learning on a planet
2200 */
2201
2202 if(obj->type==SHIP && obj->mode==LANDED && obj->subtype!=PILOT){ /* HERE TODO add propertie to ships, pilots. */
2203
2204
2205 /* Cargo FREIGHTERS */
2206 if(!(time%10)){
2207 if(obj->subtype==FREIGHTER){
2208 if(obj->cargo.mass < obj->cargo.capacity){
2209 obj->cargo.mass+=1;
2210 }
2211 }
2212 }
2213 /* --Cargo FREIGHTERS */
2214
2215 /* repair and refuel */
2216 if(plyr[obj->player].gold<5){
2217 n=5*Random(-1); /* HERE depends on number of damaged objects */
2218 }
2219 else{
2220 n=0;
2221 }
2222
2223
2224 /* first repair, then gas and last ammunition */
2225 if(plyr[obj->player].gold>0 && n==0){
2226 if(obj->state<100){
2227 if(obj->state>0){
2228 obj->state+=0.05;
2229 }
2230 if(obj->state>100)obj->state=100;
2231 plyr[obj->player].gold-=.125; /* total cost 250 */
2232 plyr[obj->player].goldweapon+=.125;
2233 }
2234
2235 if(obj->state>50){
2236 if(obj->gas < obj->gas_max){
2237 obj->gas+=2;
2238 if(obj->gas>obj->gas_max)obj->gas=obj->gas_max;
2239 plyr[obj->player].gold-=.2; /* total cost 100 */
2240 plyr[obj->player].goldweapon+=.2;
2241 }
2242 if(obj->gas > 0.5*obj->gas_max){
2243 if(!(time%4)){
2244 if(obj->weapon0.n<obj->weapon0.max_n){
2245 if(plyr[obj->player].gold>obj->weapon0.projectile.unitcost){
2246 obj->weapon0.n++;
2247 plyr[obj->player].gold-=obj->weapon0.projectile.unitcost;
2248 plyr[obj->player].goldweapon+=obj->weapon0.projectile.unitcost;
2249
2250 }
2251 }
2252 }
2253 if(!(time%240)){
2254 if(obj->weapon1.n<obj->weapon1.max_n){
2255 if(plyr[obj->player].gold>obj->weapon1.projectile.unitcost){
2256 plyr[obj->player].gold-=obj->weapon1.projectile.unitcost;
2257 plyr[obj->player].goldweapon+=obj->weapon1.projectile.unitcost;
2258 obj->weapon1.n++;
2259 }
2260 }
2261 }
2262 if(!(time%14)){
2263 if(obj->weapon2.n<obj->weapon2.max_n){
2264 if(plyr[obj->player].gold>obj->weapon2.projectile.unitcost){
2265 plyr[obj->player].gold-=obj->weapon2.projectile.unitcost;
2266 plyr[obj->player].goldweapon+=obj->weapon2.projectile.unitcost;
2267 obj->weapon2.n++;
2268 }
2269 }
2270 }
2271 }
2272 }
2273 }
2274
2275 /***** -- repair and refuel *****/
2276
2277 /***** Learning, experience *****/
2278 if(obj->type==SHIP && obj->state>99 && obj->subtype!=PILOT){ /* HERE TODO pilots has no ship for training. must depend of pilot properties. */
2279 int mlevel=0;
2280 float incexp;
2281
2282 mlevel=obj->in->level;
2283 obj->cdata->tmlevel=time;
2284 obj->cdata->mlevel=mlevel;
2285 if(obj->cdata->mlevel - obj->level > 2){
2286 incexp=0.02*(obj->cdata->mlevel - obj->level);
2287 incexp=incexp>0.06?0.06:incexp;
2288 Experience(obj,incexp);
2289 }
2290 }
2291
2292 /***** --Learning, experience *****/
2293
2294 if(obj->subtype==FIGHTER && obj->level>=MINLEVELPILOT) {
2295 obj->items=obj->items|ITSURVIVAL; /* create a survival pod */
2296 }
2297
2298 /* player level */
2299 if(proc==plyr[obj->player].proc){ /* ship is landed */
2300 if((obj->level > plyr[obj->player].gmaxlevel)){
2301 plyr[obj->player].gmaxlevel=obj->level;
2302 }
2303 }
2304 } /*if(obj->mode==LANDED) */
2305
2306 /*
2307 * -- repair, refuel and learning
2308 */
2309 }
2310
2311 /***** boundaries at planet *****/
2312 if(obj->habitat==H_PLANET){
2313 if(obj->x<0)obj->x+=LXFACTOR;
2314 if(obj->x>LXFACTOR)obj->x-=LXFACTOR;
2315
2316 if(obj->y>LYFACTOR){ /* its out of planet */
2317 plyr[obj->player].status=PLAYERMODIFIED;
2318 listheadplayer.update=1;
2319
2320 if(proc==plyr[obj->player].proc || (obj->type==PROJECTILE && obj->subtype==MISSILE)){
2321 a=-PI*(2*obj->x/(float)LXFACTOR+0.5);
2322 cosa=cos(a);
2323 sina=sin(a);
2324 obj->x=obj->in->planet->x+2*obj->in->planet->r*cosa;
2325 obj->y=obj->in->planet->y+2*obj->in->planet->r*sina;
2326
2327 vo=-obj->vx;
2328 vr=obj->vy;
2329 obj->vx=vr*cosa-vo*sina;
2330 obj->vy=vr*sina+vo*cosa;
2331
2332 rx=obj->x - obj->in->planet->x;
2333 ry=obj->y - obj->in->planet->y;
2334
2335 a=atan2(ry,rx);
2336
2337 obj->a=a-PI/2+obj->a;
2338
2339 obj->habitat=H_SPACE;
2340 obj->planet=NULL;
2341 obj->in=NULL;
2342 if(GameParametres(GET,GNET,0)==TRUE){
2343 SetModified(obj,SENDOBJAALL); /*on getting out of planet */
2344 obj->ttl=0;
2345 }
2346 if(obj==cv){
2347 habitat.type=H_SPACE;
2348 habitat.obj=NULL;
2349 SelectionBox(NULL,NULL,&cv,1);
2350 }
2351 }
2352 }
2353 }
2354 return;
2355 }
2356
UpdateAsteroid(Object * obj)2357 void UpdateAsteroid(Object *obj){
2358 /*
2359 Calculate the new coordinates of the asteroid *obj
2360 Only gravitational forces.
2361 */
2362
2363 float vx,vy,vmax2;
2364 float cosa,sina;
2365 float rx,ry;
2366 float vr,vo;
2367 float fx,fy;
2368 float fx0,fy0;
2369 float dtim;
2370 float a,factor;
2371 float g=1.2/250000;
2372 int proc;
2373 struct Player *plyr;
2374 plyr=GetPlayers();
2375
2376
2377 if(obj->type!=ASTEROID)return;
2378
2379 proc=GetProc();
2380
2381 vx=obj->vx;
2382 vy=obj->vy;
2383 dtim=DT/obj->mass;
2384
2385 fx0=fy0=0;
2386
2387 if(obj->habitat!=H_SPACE){
2388 if(obj->mode==NAV){
2389 if(obj->habitat==H_PLANET){
2390 fy0=-g*obj->mass*(float)obj->in->mass;
2391 }
2392 else{
2393 printf("in = NULL in id: %d\n",obj->id);
2394 return;
2395 }
2396 }
2397 }
2398
2399 obj->x0=obj->x;
2400 obj->y0=obj->y;
2401
2402 obj->x+=obj->vx*DT+.5*fx0*DT*dtim;
2403 obj->y+=obj->vy*DT+.5*fy0*DT*dtim;
2404
2405 fx=fy=0;
2406 if(obj->habitat==H_SPACE){
2407 PlanetAtraction(&fx,&fy,obj->x,obj->y,obj->mass);
2408 }
2409 else{
2410 fy=-g*obj->mass*(float)obj->in->mass;
2411 }
2412
2413 vx+=.5*(fx+fx0)*dtim;
2414 vy+=.5*(fy+fy0)*dtim;
2415
2416 /* if max vel is reached, reescaling */
2417
2418 vmax2=(VELMAX*VELMAX/16.0);
2419
2420 if(vx*vx+vy*vy>vmax2){
2421 factor=sqrt(vmax2/(vx*vx+vy*vy));
2422 if(factor>1){
2423 fprintf(stderr,"ERROR factor>1\n");
2424 printf("\tobj_enginev2max: %d %d\n",obj->engine.v2_max,(obj->state<25));
2425 }
2426 vx*=factor;
2427 vy*=factor;
2428 }
2429
2430 obj->a+=DT*obj->ang_v;
2431
2432 if(obj->a > PI)obj->a-=2*PI;
2433 if(obj->a < -PI)obj->a+=2*PI;
2434
2435 obj->vx=vx;
2436 obj->vy=vy;
2437 obj->fx0=obj->fx;
2438 obj->fy0=obj->fy;
2439
2440 if(obj->habitat==H_PLANET){
2441
2442 if(obj->x<0)obj->x+=LXFACTOR;
2443 if(obj->x>LXFACTOR)obj->x-=LXFACTOR;
2444
2445 if(obj->y > LYFACTOR){ /* its out of planet */
2446 if(proc==plyr[obj->player].proc){
2447 a=obj->x*(2*PI)/(float)LXFACTOR-PI;
2448 cosa=cos(a);
2449 sina=sin(a);
2450 obj->x=obj->in->planet->x+2*obj->in->planet->r*cosa;
2451 obj->y=obj->in->planet->y+2*obj->in->planet->r*sina;
2452
2453 vo=-obj->vx;
2454 vr=obj->vy;
2455 obj->vx=vr*cosa-vo*sina;
2456 obj->vy=vr*sina+vo*cosa;
2457
2458 rx=obj->x - obj->in->planet->x;
2459 ry=obj->y - obj->in->planet->y;
2460
2461 a=atan2(ry,rx);
2462
2463 /* obj->a=obj->a-a+PI/2; */
2464 obj->a=a-PI/2+obj->a;
2465
2466 obj->habitat=H_SPACE;
2467 obj->planet=NULL;
2468 obj->in=NULL;
2469 if(GameParametres(GET,GNET,0)==TRUE){
2470 if(GetProc()==plyr[obj->player].proc){
2471 SetModified(obj,SENDOBJAALL); /*on getting out of planet */
2472 obj->ttl=0;
2473 }
2474 }
2475 if(obj==cv){
2476 habitat.type=H_SPACE;
2477 habitat.obj=NULL;
2478 }
2479 }
2480 }
2481 }
2482 return;
2483 }
2484
2485
Collision(struct HeadObjList * lh)2486 void Collision(struct HeadObjList *lh){
2487 /*
2488 version 02.(200211) without CollisionList
2489 Calculate the collision between objects
2490 */
2491
2492 struct ObjList *ls1,*ls2;
2493 Object *obj1,*obj2,*objt1,*objt2;
2494 Object *obj,*pnt,*shot;
2495 Object *nobj;
2496 Segment s;
2497 float radio2,r,r2,rx,ry;
2498 float r02,r0x,r0y;
2499 float damage;
2500 float v;
2501 float a,b;
2502 char text[MAXTEXTLEN];
2503 int i,j;
2504 int gkplanets,gnet,gnplayers;
2505 int proc;
2506 int crashsw=0;
2507 int time=0;
2508 int shocks=0;
2509 int swnextobj1=0;
2510 struct Player *plyr;
2511 plyr=GetPlayers();
2512
2513 gkplanets=GameParametres(GET,GKPLANETS,0);
2514 gnet=GameParametres(GET,GNET,0);
2515 gnplayers=GameParametres(GET,GNPLAYERS,0);
2516
2517 proc=GetProc();
2518 time=GetTime();
2519 /* among objs and ship */
2520 ls1=lh->list;
2521
2522 /* among objs */
2523 while(ls1!=NULL){
2524 swnextobj1=0;
2525 obj1=ls1->obj;
2526 shocks=1; /* can collide with other objects */
2527
2528 if(obj1->state<=0){
2529 ls1=ls1->next;
2530 continue;
2531 }
2532
2533 switch(obj1->type){
2534 case SHIP:
2535
2536 if(gnet==TRUE && obj1->ttl<MINTTL){ls1=ls1->next;continue;}
2537
2538 if(obj1->habitat==H_SHIP){
2539 ls1=ls1->next;continue;
2540 }
2541 if(obj1->subtype==PILOT && obj1->mode==LANDED){
2542 ls1=ls1->next;continue;
2543 }
2544
2545 break;
2546 case PROJECTILE:
2547 /* explosion only collide with terrain */
2548 if(obj1->subtype==EXPLOSION){
2549 if(obj1->habitat!=H_PLANET){
2550 ls1=ls1->next;continue;
2551 }
2552 else{
2553 shocks=0;
2554 }
2555 }
2556 break;
2557 case TRACKPOINT:
2558 case TRACE:
2559 ls1=ls1->next;
2560 continue;
2561 break;
2562 default:
2563 break;
2564 }
2565
2566 if(shocks){
2567 ls2=ls1->next;
2568
2569 if(obj1->type==PLANET){
2570 while(ls2!=NULL && ls2->obj->type==PLANET){
2571 ls2=ls2->next;
2572 }
2573 }
2574
2575
2576 /* double loop */
2577 /* collision between two objects */
2578 while(ls2!=NULL){
2579 /* explosion only collide with terrain */
2580 if(obj1->type==PROJECTILE && obj1->subtype==EXPLOSION){
2581 break;
2582 }
2583
2584 if(obj1->state<=0){
2585 ls2=ls2->next;
2586 continue;
2587 }
2588 if(obj1->habitat!=ls2->obj->habitat){
2589 ls2=ls2->next;
2590 continue;
2591 }
2592
2593 obj2=ls2->obj;
2594 switch(obj2->type){
2595 case SHIP:
2596 if(gnet==TRUE){
2597 if(obj2->ttl<MINTTL){ls2=ls2->next;continue;}
2598 }
2599
2600 if(obj2->habitat==H_SHIP){
2601 ls2=ls2->next;continue;
2602 }
2603 if(obj2->subtype==PILOT && obj2->mode==LANDED){
2604 ls2=ls2->next;continue;
2605 }
2606 break;
2607 case PROJECTILE:
2608 /* explosion only collide with terrain */
2609 if(obj2->subtype==EXPLOSION){
2610 ls2=ls2->next;continue;
2611 }
2612
2613 if(obj1->type==PROJECTILE){
2614 /* missiles collides with the others projectiles */
2615 if(obj1->subtype!=MISSILE && obj2->subtype!=MISSILE){
2616 ls2=ls2->next;continue;
2617 }
2618 }
2619 break;
2620 case PLANET:
2621 if(obj1->type==PLANET){
2622 ls2=ls2->next;continue;
2623 }
2624 break;
2625 case ASTEROID:
2626 if(obj1->type==ASTEROID){
2627 ls2=ls2->next;continue;
2628 }
2629 break;
2630 case TRACKPOINT:
2631 case TRACE:
2632 ls2=ls2->next;continue;
2633 break;
2634 default:
2635 break;
2636 }
2637
2638 /***** same team, two ships or shots *****/
2639 if(plyr[obj1->player].team==plyr[obj2->player].team){
2640 if((obj1->type!=PLANET && obj2->type!=PLANET)){
2641
2642
2643 /* collision between pilot and other object */
2644 if((obj1->type==SHIP && obj1->subtype==PILOT) ||
2645 (obj2->type==SHIP && obj2->subtype==PILOT)){
2646
2647 if(obj1->subtype==PILOT && obj2->subtype==PILOT){
2648 ls2=ls2->next;
2649 continue;
2650 }
2651
2652 /* pilot-projectile don't collide */
2653 if(obj1->type==PROJECTILE||obj2->type==PROJECTILE){
2654 ls2=ls2->next;
2655 continue;
2656 }
2657
2658 /* pilot-satellite don't collide */
2659 if(obj1->subtype==SATELLITE||obj2->subtype==SATELLITE){
2660 ls2=ls2->next;
2661 continue;
2662 }
2663 }
2664 else{
2665 ls2=ls2->next;
2666 continue;
2667 }
2668 }
2669 }
2670 /***** --same team, two ships or shots *****/
2671
2672 if(obj2->state<=0){
2673 ls2=ls2->next;
2674 continue;
2675 }
2676
2677 if(obj1->in!=obj2->in){
2678 ls2=ls2->next;
2679 continue;
2680 }
2681
2682 if(obj1->parent==obj2 || obj2->parent==obj1){
2683 ls2=ls2->next;
2684 continue;
2685 }
2686 if(gnet==TRUE){
2687 if(plyr[obj1->player].proc==plyr[obj2->player].proc){
2688 if(proc!=plyr[obj1->player].proc){
2689 ls2=ls2->next;
2690 continue;
2691 }
2692 }
2693 }
2694
2695 if(plyr[obj1->player].team==plyr[obj2->player].team){
2696 if(!(obj1->type==PLANET || obj2->type==PLANET)){
2697 if(obj1->subtype!=PILOT && obj2->subtype!=PILOT){
2698 ls2=ls2->next;
2699 continue;
2700 }
2701 }
2702 }
2703
2704 radio2=(obj1->radio+obj2->radio)*(obj1->radio+obj2->radio);
2705
2706 rx=obj2->x - obj1->x;
2707 ry=obj2->y - obj1->y;
2708 r2=rx*rx+ry*ry;
2709
2710 r0x=obj2->x0 - obj1->x0;
2711 r0y=obj2->y0 - obj1->y0;
2712 r02=0.25*((rx+r0x)*(rx+r0x)+(ry+r0y)*(ry+r0y));
2713
2714
2715 /***** Experience in combat, among SHIPS *****/
2716 if(r2<1000000){
2717
2718 if(obj1->type==SHIP && obj2->type==SHIP){
2719 if(plyr[obj2->player].team!=plyr[obj1->player].team){
2720 if(obj1->habitat==obj1->habitat){
2721 if(obj1->subtype!=PILOT && obj2->subtype!=PILOT){
2722 int il;
2723 float factor,points;
2724 /* obj1 */
2725 if(proc==plyr[obj1->player].proc){
2726 il=obj2->level-obj1->level;
2727 factor=0.001;
2728 if(il>3)il=3;
2729 if(il==-1)factor/=2;
2730 if(il<-1)factor=0;
2731 if(factor>0){
2732 points=(il+2)*(il+2)*factor*(obj2->level+1);
2733 obj1->pexperience+=points;
2734 }
2735 }
2736 /* obj2 */
2737 if(proc==plyr[obj2->player].proc){
2738 il=obj1->level-obj2->level;
2739 if(il>3)il=3;
2740 factor=0.001;
2741 if(il==-1)factor/=2;
2742 if(il<-1)factor=0;
2743 if(factor>0){
2744 points=(il+2)*(il+2)*factor*(obj1->level+1);
2745 obj2->pexperience+=points;
2746 }
2747 }
2748 }
2749 }
2750 }
2751 }
2752 }
2753 /***** --Experience in combat *****/
2754
2755 /***** planets and SHIPS *****/
2756 if(gkplanets==FALSE){
2757 /* if(r2<RADAR_RANGE2){ planet discovered */
2758 if((obj1->type==PLANET && obj2->type==SHIP) ||
2759 (obj2->type==PLANET && obj1->type==SHIP)){
2760 if(obj1->type==PLANET){
2761 obj=obj2;
2762 pnt=obj1;
2763 }
2764 else{
2765 obj=obj1;
2766 pnt=obj2;
2767 }
2768 if(!((time+obj->id)%20)){
2769 if(proc==plyr[obj->player].proc && pnt->player!=obj->player){
2770 if(r2< obj->radar*obj->radar){ /* planet near */
2771 if(IsInIntList((plyr[obj->player].kplanets),pnt->id)==0){
2772 /* planet discovered */
2773 Experience(obj,40);/* Experience for discover a planet */
2774 if(gnet==TRUE){
2775 struct NetMess mess;
2776 mess.id=NMPLANETDISCOVERED;
2777 mess.a=obj->id; /* */
2778 mess.b=pnt->id; /* */
2779 NetMess(&mess,NMADD);
2780 }
2781 for(i=0;i<=gnplayers+1;i++){
2782 if(plyr[obj->player].team==plyr[i].team ||
2783 (GameParametres(GET,GENEMYKNOWN,0) && plyr[obj->player].team > 1)){
2784 plyr[i].kplanets=Add2IntList((plyr[i].kplanets),pnt->id);
2785
2786 if(plyr[obj->player].team==plyr[i].team ){
2787 snprintf(text,MAXTEXTLEN,"(%d) %s %d %s",
2788 obj->pid,
2789 GetLocale(L_PLANET),
2790 pnt->id,
2791 GetLocale(L_DISCOVERED));
2792 if(!Add2TextMessageList(&listheadtext,text,obj->id,obj->player,0,100,0)){
2793 Add2CharListWindow(&gameloglist,text,0,&windowgamelog);
2794 }
2795 }
2796 }
2797 }
2798 }
2799 }
2800 }
2801 }
2802 }
2803 }
2804 /***** --planets and SHIPS *****/
2805
2806 if(r2<radio2 || r02<radio2){
2807 if(obj1->type==PROJECTILE || obj2->type==PROJECTILE){
2808 if(obj1->subtype==LASER || obj2->subtype==LASER){
2809 if(obj1->subtype==LASER){
2810 obj=obj2;
2811 shot=obj1;
2812 }
2813 else{
2814 obj=obj1;
2815 shot=obj2;
2816 }
2817 r=(obj->x-shot->x)*sin(shot->a)-(obj->y-shot->y)*cos(shot->a);
2818 r2=r*r;
2819 if(r2>obj->radio*obj->radio){
2820 ls2=ls2->next;
2821 continue;
2822 }
2823 }
2824 }
2825
2826 /*****
2827 objects and planets
2828 *****/
2829
2830 if((obj1->type==PLANET && obj2->type!=PLANET) ||
2831 (obj2->type==PLANET && obj1->type!=PLANET)){
2832
2833 /* inner planet */
2834 if(obj1->type==PLANET){
2835 obj=obj2;
2836 pnt=obj1;
2837 }
2838 else{
2839 obj=obj1;
2840 pnt=obj2;
2841 }
2842 plyr[obj->player].status=PLAYERMODIFIED;
2843 listheadplayer.update=1;
2844
2845 if(proc==plyr[obj->player].proc || (obj->type==PROJECTILE && obj->subtype==MISSILE)){
2846
2847
2848 obj->habitat=H_PLANET;
2849 obj->planet=NULL;
2850 obj->in=pnt;
2851
2852 /*entering planet */
2853 if(gnet==TRUE){
2854 SetModified(obj,SENDOBJAALL);
2855 obj->ttl=0; /* send now */
2856 }
2857 if(obj==cv){
2858 habitat.type=H_PLANET;
2859 habitat.obj=pnt;
2860 SelectionBox(NULL,NULL,&cv,1);
2861 }
2862 /* initial conditions at planet */
2863 a=atan2(-pnt->y+obj->y,-pnt->x+obj->x);
2864 b=atan2(obj->vy,obj->vx)-a;
2865 obj->x=LXFACTOR-(a+PI/2)/(2*PI)*LXFACTOR;
2866 obj->y=LYFACTOR;
2867 v=sqrt(obj->vx*obj->vx+obj->vy*obj->vy);
2868
2869 obj->vx=-v*sin(b);
2870 obj->vy=v*cos(b);
2871
2872 obj->a=obj->a-a+PI/2;
2873 if(obj->a > PI)obj->a-=2*PI;
2874 if(obj->a < -PI)obj->a+=2*PI;
2875 if(obj->actorder.id!=-1)obj->actorder.time=0;
2876 }
2877 }
2878
2879 /*****
2880 --objects and planets
2881 *****/
2882
2883
2884 /* among ships and projectiles */
2885 if((obj1->type!=PLANET && obj2->type!=PLANET)){
2886
2887 /*****
2888 between ship and pilots, same team
2889 pilot rescued by an allied ship.
2890 ******/
2891 if((plyr[obj1->player].team==plyr[obj2->player].team) &&
2892 (obj1->type==SHIP && obj2->type==SHIP) &&
2893 (obj1->subtype==PILOT || obj2->subtype==PILOT) &&
2894 (obj1->subtype!=PILOT || obj2->subtype!=PILOT) &&
2895 (obj1->habitat==obj2->habitat)){
2896
2897 if(obj1->subtype==PILOT){
2898 objt1=obj1;
2899 objt2=obj2;
2900 }
2901 else{
2902 objt1=obj2;
2903 objt2=obj1;
2904 }
2905
2906 /* objt1 is the pilot */
2907 if(proc==plyr[objt1->player].proc){
2908 if(objt2->subtype==EXPLORER||objt2->subtype==FIGHTER||objt2->subtype==QUEEN||objt2->subtype==FREIGHTER){
2909
2910 if(CargoAdd(objt2,objt1)){
2911 objt1->in=objt2;
2912 objt1->habitat=H_SHIP;
2913
2914 if(objt1->player==actual_player){
2915 printf("%s %d %s %d\n",
2916 GetLocale(L_PILOT),
2917 objt1->pid,
2918 GetLocale(L_RESCUEDBY),
2919 objt2->pid);
2920 }
2921
2922 if(gnet==TRUE){
2923 if(proc==plyr[objt1->player].proc){
2924 SetModified(objt1,SENDOBJALL);
2925 }
2926 }
2927 /* pilot is captured: next obj1 */
2928 if(obj1==objt1){swnextobj1=1;break;} /* obj1 don't collide more */
2929 }
2930 /* next obj2 */
2931 break;
2932 }
2933 }
2934 }
2935 /***** --between ship and pilot same team *****/
2936
2937 for(i=0;i<2;i++){
2938 if(i==0){
2939 objt1=obj1;
2940 objt2=obj2;
2941 }
2942 if(i==1){
2943 objt1=obj2;
2944 objt2=obj1;
2945 }
2946
2947 damage=objt2->damage*(1-objt1->shield);
2948 objt1->state-=damage;
2949
2950
2951 if(objt1->type==SHIP){
2952 /*receive an impact */
2953
2954 Play(objt1,CRASH,1);
2955 if(objt1==cv){
2956 gdraw.crash=1;
2957 }
2958
2959 Explosion(&listheadobjs,cv,objt1,1);
2960
2961 if(objt1->state>0){
2962 if(proc==plyr[objt1->player].proc){
2963 Experience(objt1,damage/2); /* experience for receive an impact*/
2964 }
2965
2966 if(objt1->player==actual_player && cv!=objt1){
2967 snprintf(text,MAXTEXTLEN,"(%c %d) %s",Type(objt1),objt1->pid,GetLocale(L_HELP));
2968 if(!Add2TextMessageList(&listheadtext,text,objt1->id,objt1->player,0,100,2)){
2969 Add2CharListWindow(&gameloglist,text,1,&windowgamelog);
2970 }
2971 }
2972 }
2973 }
2974 if(objt1->type==SHIP || objt1->type==ASTEROID || (objt1->type==PROJECTILE && objt1->subtype==MISSILE)){/* HERE */
2975 if(gnet==TRUE){
2976 if(proc==plyr[objt1->player].proc){
2977 SetModified(objt1,SENDOBJAALL);
2978 objt1->ttl=0;
2979 }
2980 }
2981 }
2982
2983 /***** ship destroyed *****/
2984 if(objt1->state<=0){
2985
2986 switch(objt1->type){
2987 case SHIP:
2988 break;
2989
2990 case ASTEROID:
2991 if(objt1->subtype<ASTEROID3){
2992 if(proc==plyr[objt1->player].proc){
2993 for(j=0;j<3;j++){
2994 nobj=NewObj(ASTEROID,objt1->subtype+1,
2995 objt1->x,objt1->y,objt1->vx+10.0*rand()/RAND_MAX-5,objt1->vy+10.0*rand()/RAND_MAX-5,
2996 CANNON0,ENGINE0,0,NULL,objt1->in);
2997 nobj->a=PI/2;
2998 nobj->ai=0;
2999 nobj->in=objt1->in;
3000 nobj->habitat=objt1->habitat;
3001 nobj->mode=NAV;
3002 Add2ObjList(&listheadobjs,nobj);
3003 }
3004 }
3005 }
3006 break;
3007 default:
3008 break;
3009 }
3010
3011 switch(objt2->type){
3012 case SHIP:
3013 if(objt2->subtype!=PILOT){
3014 objt1->sw=objt2->id;
3015 }
3016 break;
3017 case PROJECTILE:
3018 if(objt2->parent!=NULL){
3019 objt1->sw=objt2->parent->id;
3020 }
3021 break;
3022 default:
3023 break;
3024 }
3025
3026 if(gnet==TRUE){
3027 if(proc==plyr[objt1->player].proc){
3028 SetModified(objt1,SENDOBJKILL);
3029 objt1->ttl=0;
3030 }
3031 }
3032 }
3033 /***** --ship destroyed *****/
3034
3035 } /* for(i=0;i<2;i++){ */
3036 }
3037 /* --among ships and projectiles */
3038 } /* if(r2<radio2 || r02<radio2){ */
3039 else{
3040 if(r2<4*radio2 && 0){
3041 /* Avoid collision */ /* TODO */
3042 }
3043 }
3044
3045 ls2=ls2->next;
3046 } /* while ls2!=NULL */ /* --double loop*/
3047 if(swnextobj1){swnextobj1=0;ls1=ls1->next;continue;}
3048 } /* if(shocks) */
3049
3050 /*****
3051 collision with planet terrain
3052 *****/
3053 crashsw=0;
3054 if(obj1->mode!=LANDED && obj1->habitat==H_PLANET && obj1->y<LYFACTOR/2){
3055 if(proc==plyr[obj1->player].proc || obj1->type==PROJECTILE){
3056 if(!GetSegment(&s,obj1->in->planet,obj1->x,obj1->y)){
3057 /* if(obj1->y - obj1->radio +1< s.y0 && obj1->y - obj1->radio +1< s.y1){ */
3058 if(obj1->y-obj1->radio <= s.y0 && obj1->y - obj1->radio <= s.y1){
3059 if(obj1->type!=SHIP){ /* destroy object */
3060 obj1->state=0;
3061 obj1->sw=0;
3062
3063 if(gnet==TRUE){
3064 if(proc==plyr[obj1->player].proc){
3065 SetModified(obj1,SENDOBJKILL);
3066 obj1->ttl=0;
3067 }
3068 }
3069 }
3070
3071 if(obj1->type==SHIP){
3072 switch(s.type){
3073 case TERRAIN: /* destroy ship */
3074 crashsw=1;
3075 break;
3076 case LANDZONE:
3077 if(obj1->subtype==SATELLITE){
3078 crashsw=1;
3079 }
3080 if( (fabs(obj1->vx)>2 || /* ship crashed */
3081 fabs(obj1->vy)>5 ||
3082 fabs(obj1->a-PI/2)>.35)){
3083 crashsw=1;
3084 }
3085 if(crashsw==0){/***** ship has landed *****/
3086 if(obj1->vy<0){
3087 obj1->mode=LANDED;
3088 if(obj1->cargo.hlist!=NULL){ /* if has a rescued pilot, eject him */
3089 if(CargoEjectObjs(obj1,SHIP,PILOT)){
3090 listheadplayer.update=1;
3091 }
3092 }
3093 /* FREIGHTER Cargo Goods*/
3094 if(obj1->subtype==FREIGHTER &&
3095 obj1->oriid!=obj1->in->id){
3096 int mass=0;
3097 float d,factor;
3098 Object *objori,*objdest;
3099
3100 mass=CargoGetMass(obj1); /* mass of objects */
3101
3102 /* Adding gold to planet */
3103
3104 obj1->destid=obj1->in->id;
3105 objori=SelectObj(&listheadobjs,obj1->oriid);
3106 objdest=SelectObj(&listheadobjs,obj1->destid);
3107 if(objori==NULL||objdest==NULL){
3108 d=5000;
3109 }
3110 else{
3111 d=sqrt((objori->x-objdest->x)*(objori->x-objdest->x)+
3112 (objori->y-objdest->y)*(objori->y-objdest->y));
3113 }
3114
3115 if(d>GameParametres(GET,GULX,0)/10){
3116 factor=4*d/20000;
3117 Experience(obj1,40); /* Experience for complete a travel */
3118 }
3119 else{
3120 factor=2*d/20000;
3121 Experience(obj1,20); /* Experience for complete a travel */
3122 }
3123 obj1->ntravels++;
3124 obj1->in->planet->gold+=(obj1->cargo.mass-mass)*factor;
3125 obj1->cargo.mass=mass;
3126 obj1->destid=obj1->oriid; /* change dest */
3127 obj1->oriid=obj1->in->id;
3128
3129 }
3130 /* --FREIGHTER Cargo Goods*/
3131
3132 if(gnet==TRUE){
3133 if(proc==plyr[obj1->player].proc){
3134 SetModified(obj1,SENDOBJAALL);
3135 obj1->ttl=0;
3136 }
3137 }
3138 obj1->vx=0;
3139 obj1->vy=0;
3140 obj1->ang_a=0;
3141 obj1->ang_v=0;
3142 obj1->y=obj1->y0=s.y0+obj1->radio;
3143 if(obj1->subtype==PILOT){
3144 obj1->a=0;
3145 }
3146 }
3147
3148 /***** conquering a planet *****/
3149 switch(IsPlanetEmpty(obj1->in,obj1)){
3150 case 0:/* planet totally empty */
3151 if(plyr[obj1->in->player].team!=plyr[obj1->player].team){
3152 char text[MAXTEXTLEN];
3153 Experience(obj1,50); /* Experience for conquest a planet */
3154 if(plyr[obj1->in->player].team != 1){/* HERE ??? */
3155 GetInformation(&plyr[obj1->player],&plyr[obj1->in->player],obj1);
3156 }
3157 snprintf(text,MAXTEXTLEN,"%s %d %s",
3158 GetLocale(L_PLANET),
3159 obj1->in->id,
3160 GetLocale(L_LOST));
3161 if(!Add2TextMessageList(&listheadtext,text,obj1->in->id,obj1->in->player,0,100,2)){
3162 Add2CharListWindow(&gameloglist,text,0,&windowgamelog);
3163 }
3164 if(gnet==TRUE && proc!=plyr[obj1->in->player].proc){
3165 struct NetMess mess;
3166 mess.id=NMPLANETLOST;
3167 mess.a=obj1->in->player; /* player that conquer */
3168 mess.b=obj1->in->id; /* id of the planet */
3169 NetMess(&mess,NMADD);
3170 }
3171 }
3172
3173 obj1->in->player=obj1->player;
3174 obj1->in->sw=1;
3175
3176 if(gnet==TRUE){
3177 if(proc==plyr[obj1->in->player].proc){
3178 SetModified(obj1->in,SENDOBJPLANET);
3179 obj1->in->ttl=0;
3180 plyr[obj1->player].modified=SENDPLAYERMOD;
3181 obj1->ttl=0;
3182 }
3183 }
3184 break;
3185
3186 case 1: /* only allies landed */
3187 break;
3188 case 2: /* enemies landed */
3189 break;
3190 default:
3191 break;
3192 }
3193 } /*****if(crashsw==0) --else ship has landed *****/
3194 break;
3195 default:
3196 break;
3197 }
3198 } /* if SHIP*/
3199 } /* if(obj1->y - obj1->radio < s.y0 && obj1->y - obj1->radio < s.y1){ */
3200 } /* if GetSegment()*/
3201 } /* if(proc==plyr[obj1->player].proc || obj1->type==PROJECTILE){ */
3202
3203 if(crashsw){
3204 obj1->state=0;
3205 obj1->sw=0;
3206
3207 if(gnet==TRUE){
3208 if(proc==plyr[obj1->player].proc){
3209 SetModified(obj1,SENDOBJKILL);
3210 obj1->ttl=0;
3211 }
3212 }
3213 }
3214
3215 } /* if(obj1->mode!=LANDED && obj1->habitat==H_PLANET ) */
3216
3217 /* --collision with planet terrain */
3218
3219 ls1=ls1->next;
3220 } /* while(ls1!=NULL) */
3221
3222 return;
3223 } /* --Collission() */
3224
3225
3226
UpdateObjs(void)3227 int UpdateObjs(void){
3228 /*
3229 Update the coordinates of the objects.
3230 */
3231 static int cont=0;
3232 int i;
3233 int n=0;
3234 struct ObjList *ls;
3235 Object *obj,*nobj;
3236 int gnet;
3237 int proc;
3238 struct Player *plyr;
3239 plyr=GetPlayers();
3240
3241
3242 #if CLOSEDUNIVERSE
3243 int gulx,guly;
3244 gulx=GameParametres(GET,GULX,0);
3245 guly=GameParametres(GET,GULY,0);
3246 #endif
3247
3248 gnet=GameParametres(GET,GNET,0);
3249 proc=GetProc();
3250 cont++;
3251
3252 if(cont>1000)cont=0;
3253
3254 ls=listheadobjs.list;
3255
3256 if(listheadobjs.n==0)return(0);
3257
3258 /* update planets */
3259 while(ls!=NULL){
3260 obj=ls->obj;
3261 if(obj->type==PLANET){
3262
3263 /* planets create some gold */
3264 obj->planet->A=obj->planet->reggold;
3265 if(!(cont%50))obj->level=0; /* reset level */
3266 }
3267 ls=ls->next;
3268 }
3269
3270 /* --update planets */
3271
3272 /* update players*/
3273 for(i=0;i<GameParametres(GET,GNPLAYERS,0)+2;i++){
3274 plyr[i].maxlevel=0;
3275 }
3276 /* --update players */
3277
3278 ls=listheadobjs.list;
3279 while(ls!=NULL){
3280 obj=ls->obj;
3281 obj->pexperience=0;
3282
3283 if(obj->durable==TRUE){
3284 switch(obj->subtype){
3285 case PILOT:
3286 if(obj->habitat==H_SPACE){
3287 obj->life--;
3288 }
3289 else{
3290 obj->life=LIFEPILOT;
3291 }
3292 break;
3293 case SATELLITE:
3294 if(obj->habitat==H_SPACE){
3295 obj->life--;
3296 }
3297 break;
3298 default:
3299 obj->life--;
3300 break;
3301 }
3302 if(obj->life<=0){
3303 obj->life=0;
3304 obj->state=0;
3305 obj->sw=0;
3306 }
3307 }
3308
3309 if(obj->life>0){/* && proc==players[obj->player].proc){ */
3310
3311 switch(obj->type){
3312 case PROJECTILE:
3313 switch(obj->subtype){
3314 case MISSILE:
3315 aimissile(&listheadobjs,obj);
3316 UpdateShip(obj);
3317 break;
3318 case EXPLOSION:
3319 UpdateShip(obj);
3320 break;
3321 default:
3322 obj->x0 = obj->x;
3323 obj->y0 = obj->y;
3324
3325 obj->x += obj->vx*DT;
3326 obj->y += obj->vy*DT;
3327 break;
3328 }
3329 break;
3330 case SHIP:
3331 if(obj->trace==TRUE && obj->mode!=LANDED){
3332 if(obj->vx*obj->vx+obj->vy*obj->vy>.25){
3333 Object *objin=obj->in;
3334
3335 if(objin!=NULL){ /* don't create trace inside a ship */
3336 if(obj->in->type!=PLANET){
3337 objin=NULL;
3338 }
3339 }
3340 nobj=NewObj(TRACE,SHIP0,
3341 obj->x,obj->y,
3342 0,0,
3343 CANNON0,ENGINE0,obj->player,obj,objin);
3344 Add2ObjList(&listheadobjs,nobj);
3345 }
3346 }
3347
3348 switch(obj->subtype){
3349 case EXPLORER:
3350 case FIGHTER:
3351 case QUEEN:
3352 case FREIGHTER:
3353 case TOWER:
3354 /* level of a planet is the maxlevel of an object in it */
3355 if(obj->habitat==H_PLANET){
3356 if(plyr[obj->player].team == plyr[obj->in->player].team){
3357 if(obj->level > obj->in->level)obj->in->level=obj->level;
3358 }
3359 }
3360 if(obj->level > plyr[obj->player].maxlevel){
3361 plyr[obj->player].maxlevel = obj->level;
3362 if(plyr[obj->player].maxlevel > plyr[obj->player].gmaxlevel){
3363 plyr[obj->player].maxlevel = plyr[obj->player].gmaxlevel;
3364 }
3365 }
3366 case SATELLITE:
3367 case PILOT:
3368 if(proc==plyr[obj->player].proc){
3369 ai(&listheadobjs,obj,actual_player);
3370 }
3371 UpdateShip(obj);
3372
3373 break;
3374 default:
3375 g_print("ERROR (UpdateObjs 1) %d %d \n",obj->type,obj->subtype);
3376 exit(-1);
3377 break;
3378 }
3379 break;
3380 case ASTEROID:
3381 UpdateAsteroid(obj);
3382 break;
3383
3384 case TRACKPOINT:
3385 case TRACE:
3386 break;
3387 case PLANET:
3388 break;
3389
3390 default:
3391 g_print("ERROR (UpdateObjs 2) %d\n",obj->type);
3392 exit(-1);
3393 break;
3394
3395 }
3396 #if CLOSEDUNIVERSE
3397 if(obj->x>gulx)obj->x-=gulx;
3398 if(obj->x<0)obj->x+=gulx;
3399 if(obj->y>guly)obj->y-=guly;
3400 if(obj->y<0)obj->y+=guly;
3401 #endif
3402 } /* if (obj->life>0) */
3403
3404 if(obj->life<=0){
3405 obj->state=0;obj->sw=0;
3406 }
3407
3408 if(gnet==TRUE){
3409 obj->ttl--;
3410 if(obj->life<=0){
3411 if(proc==plyr[obj->player].proc){
3412 SetModified(obj,SENDOBJKILL);
3413 obj->ttl=0;
3414 }
3415 }
3416 }
3417 ls=ls->next;
3418 n++;
3419 if (n>listheadobjs.n){
3420 g_print("ERROR: n: %d N: %d\n",n,listheadobjs.n);
3421 return(-1);
3422 }
3423 } /* while(ls!=NULL) */
3424 return (n);
3425 }
3426
3427
CheckPlanetDistance(struct HeadObjList * lh,float x,float y,int d)3428 int CheckPlanetDistance(struct HeadObjList *lh,float x,float y,int d){
3429 /*
3430 The distance between two planets must be greater than 600
3431 returns:
3432 1 if there are a near planet
3433 0 if not
3434 */
3435
3436 struct ObjList *ls;
3437 float d2=d*d;
3438
3439 ls=lh->list;
3440 while(ls!=NULL){
3441 if(ls->obj->type==PLANET){
3442 if((ls->obj->x-x)*(ls->obj->x-x)+(ls->obj->y-y)*(ls->obj->y-y)<d2){
3443 return(1);
3444 }
3445 }
3446 ls=ls->next;
3447 }
3448 return(0);
3449 }
3450
CreateUniverse(int ulx,int uly,struct HeadObjList * lheadobjs,char ** ptnames)3451 void CreateUniverse(int ulx,int uly,struct HeadObjList *lheadobjs,char **ptnames){
3452 /*
3453 Create Galaxies and planets.
3454 */
3455
3456 int i,j;
3457 float x,y;
3458 float x0,y0;
3459 float r,rg,ru; /* radio galaxy and universe */
3460 float d2,d2min,d2limit;
3461 Object *obj;
3462 int n,np=0;
3463 int nplanetspergalaxy=1;
3464 int nplanets;
3465 int ngalaxies=1;
3466 int valid;
3467 Point *gpos;
3468 char *datadir;
3469 char frectable[128];
3470 FILE *fp;
3471 int namegen=FALSE;
3472
3473 /* HERE check this equation. galaxy size */
3474
3475
3476 datadir=DATADIR;
3477 snprintf(frectable,128,"%s/%s",datadir,LETTERFREQUENCYFILE);
3478 printf("Checking for letter frequency file: %s\n",frectable);
3479
3480 namegen=TRUE;
3481 if((fp=fopen(frectable,"rt"))==NULL){
3482 fprintf(stdout,"Can't open the file: %s\n", frectable);
3483
3484 datadir=INSTALL_DATA_DIR;
3485 snprintf(frectable,128,"%s/%s",datadir,LETTERFREQUENCYFILE);
3486 printf("checking for letter frequency file 2 :%s\n",frectable);
3487
3488 if((fp=fopen(frectable,"rt"))==NULL){
3489 fprintf(stdout,"Can't open the file: %s\n", frectable);
3490 namegen=FALSE;
3491 }
3492 }
3493
3494 if(namegen){
3495 loadFrequencyTable(frectable);
3496 printf("letter frequency table loaded\n");
3497 fclose(fp);
3498 }
3499
3500 ngalaxies=GameParametres(GET,GNGALAXIES,0);
3501 nplanets=GameParametres(GET,GNPLANETS,0);
3502 nplanetspergalaxy=(int)((float)nplanets/ngalaxies+0.5);
3503 ru=ulx/2;
3504 uly=ulx; /* universe is square */
3505
3506 gpos=malloc(ngalaxies*sizeof(Point));
3507 if(gpos==NULL){
3508 fprintf(stderr,"ERROR in malloc CreateUniverse()\n");
3509 exit(-1);
3510 }
3511
3512 for(i=0;i<ngalaxies;i++){
3513 gpos[i].x=0;
3514 gpos[i].y=0;
3515 }
3516
3517 if(ngalaxies==1){
3518 rg=ulx/3;
3519 }
3520 else{
3521 rg=ulx/(sqrt(ngalaxies*16));
3522
3523 }
3524
3525 printf("\n\tnumber of galaxies: %d\n",ngalaxies);
3526 printf("\tnumber of planets per galaxy: %d\n",nplanetspergalaxy);
3527 printf("\tgalaxy radius: %.0f\n",rg);
3528
3529 /* galaxy center coordinates */
3530
3531 x0=2*(ru-rg)*Random(-1)-(ru-rg);
3532 y0=2*(ru-rg)*Random(-1)-(ru-rg);
3533 gpos[0].x=x0;
3534 gpos[0].y=y0;
3535 d2limit=9*(float)rg*rg;
3536 for(j=1;j<ngalaxies;j++){
3537 n=0;
3538 do{
3539 x0=2*(ru-rg)*Random(-1)-(ru-rg);
3540 y0=2*(ru-rg)*Random(-1)-(ru-rg);
3541 d2min=(float)ulx*ulx;
3542 n++;
3543 for(i=0;i<j;i++){
3544 d2=(x0-gpos[i].x)*(x0-gpos[i].x)+(y0-gpos[i].y)*(y0-gpos[i].y);
3545 if(d2<d2min)d2min=d2;
3546 }
3547 if(n>100){
3548 n=0;
3549 d2limit*=.8; /* relax condition */
3550 }
3551 }
3552 while(d2min<d2limit);
3553 gpos[j].x=x0;
3554 gpos[j].y=y0;
3555 }
3556
3557 for(j=0;j<ngalaxies;j++){
3558 if(np>=nplanets)break;
3559 x0=gpos[j].x;
3560 y0=gpos[j].y;
3561 if(ngalaxies==1){
3562 x0=0;
3563 y0=0;
3564 }
3565 for(i=0;i<nplanetspergalaxy;i++){
3566 if(np>=nplanets)break;
3567 n=0;
3568 do{
3569 valid=1;
3570 x=x0+6*rg*(float)rand()/RAND_MAX-3*rg;
3571 y=y0+6*rg*(float)rand()/RAND_MAX-3*rg;
3572 if(n>100){
3573 fprintf(stderr,"ERROR: Universe size too small or too much planets. Exiting...\n");
3574 exit(-1);
3575 }
3576
3577 if(CheckPlanetDistance(lheadobjs,x,y,600)){
3578 valid=0;
3579 n++;
3580 }
3581 /* planet distribution */
3582 d2=(x-x0)*(x-x0)+(y-y0)*(y-y0);
3583 r=(float)rand()/RAND_MAX;
3584 if(r>5*exp(-d2/(1.44*rg*rg/2.)))valid=0;
3585
3586 if(x<-ulx/2||x>ulx/2||y<-uly/2||y>uly/2){
3587 valid=0;
3588 }
3589 }
3590 while(valid==0);
3591
3592 obj=NewObj(PLANET,SHIP0,x,y,0,0,CANNON0,ENGINE0,0,NULL,NULL);
3593 if(obj!=NULL){
3594
3595 if(i<NUMPLANETNAMES-1 && j==0){
3596 strncpy(obj->name,ptnames[i+1],OBJNAMESMAXLEN);
3597 }
3598 else{
3599 if(namegen){
3600 strncpy(obj->name,getRandomName(0),OBJNAMESMAXLEN);
3601 }
3602 else{
3603 strncpy(obj->name,ptnames[0],OBJNAMESMAXLEN);
3604 }
3605 }
3606 Add2ObjList(lheadobjs,obj);
3607 np++;
3608 }
3609 }
3610 }
3611
3612
3613
3614 if(np<nplanets){
3615 int m=nplanets-np;
3616 for(i=0;i<m;i++){
3617 x=ulx*Random(-1)-ulx/2;
3618 y=uly*Random(-1)-uly/2;
3619
3620 obj=NewObj(PLANET,SHIP0,x,y,0,0,CANNON0,ENGINE0,0,NULL,NULL);
3621 if(obj!=NULL){
3622 if(i<NUMPLANETNAMES-1 && j==0){
3623 strncpy(obj->name,ptnames[i+1],OBJNAMESMAXLEN);
3624 }
3625 else{
3626 strncpy(obj->name,ptnames[0],OBJNAMESMAXLEN);
3627 }
3628 Add2ObjList(lheadobjs,obj);
3629 np++;
3630 }
3631 }
3632 }
3633
3634 if(np!=nplanets){
3635 printf("WARNING CreateUniverse(): number of planets incorrect: %d\n",np);
3636 exit(-1);
3637 }
3638
3639 free(gpos);
3640 }
3641
PlanetAtraction(float * fx,float * fy,float x,float y,float m)3642 float PlanetAtraction(float *fx,float *fy,float x,float y,float m){
3643 /*
3644 calculates the atraction forces betwwen ships and planets
3645 returns:
3646 the force in fx,fy arguments.
3647 the potential energy.
3648 */
3649
3650 struct ObjList *ls;
3651 float rx,ry,r,r2,ir2r;
3652 float U; /* potential*/
3653 float GM;
3654
3655 if(m==0){
3656 *fx=*fy=0;
3657 return(0);
3658 }
3659
3660
3661 ls=listheadplanets.list;
3662 U=0;
3663
3664 while (ls!=NULL){
3665 rx=ls->obj->x-x;
3666 ry=ls->obj->y-y;
3667 r2=rx*rx+ry*ry;
3668
3669 if(r2<GRAVITATION_RANGE2){
3670 GM=G*ls->obj->mass;
3671 r=sqrt(r2);
3672 ir2r=1./(r2*r);
3673 *fx+=GM*rx*ir2r;
3674 *fy+=GM*ry*ir2r;
3675 U-=GM/r;
3676 }
3677 ls=ls->next;
3678 }
3679
3680 *fx*=m;
3681 *fy*=m;
3682 U*=m;
3683
3684 return(U);
3685 }
3686
3687
PrintfObjInfo(FILE * fp,Object * obj)3688 int PrintfObjInfo(FILE *fp,Object *obj){
3689 /*
3690 printf obj info
3691 used only for debug.
3692 */
3693
3694 int in,dest,parent,planet;
3695 fprintf(fp,"time: %d\n id:%d durable:%d visible:%d\n \
3696 points:%d habitat:%d mode:%d \nmodified: %d \n \
3697 x:%g y:%g x0:%g y0:%g \nvx:%g vy:%g \n \
3698 fx0:%g fy0:%g fx:%g fy:%g\n a:%g ang_v:%g accel:%g \n \
3699 gas:%g gas_max:%g life:%g shield:%g state:%g\n",
3700 GetTime(),
3701 obj->id,obj->durable,obj->visible,
3702 obj->kills,obj->habitat,obj->mode,
3703 obj->modified,
3704 obj->x,obj->y,obj->x0,obj->y0,
3705 obj->vx,obj->vy,
3706 obj->fx0,obj->fy0,obj->fx,obj->fy,
3707 obj->a,obj->ang_v,obj->accel,
3708 obj->gas,obj->gas_max,
3709 obj->life,obj->shield,obj->state);
3710
3711 fprintf(fp,"dest_r2:%g mass:%d radio:%d \ntype:%d subtype:%d\n\
3712 damage:%d player:%d player:%d\nai:%d trace:%d norder:%d\n",
3713 obj->dest_r2,obj->mass,obj->radio,
3714 obj->type,obj->subtype,
3715 obj->damage,obj->player,obj->player,
3716 obj->ai,obj->trace,obj->norder);
3717
3718 in=0;
3719 dest=0;
3720 planet=0;
3721 parent=0;
3722
3723 if(obj->in!=NULL)in=obj->in->id;
3724 if(obj->dest!=NULL)dest=obj->dest->id;
3725 if(obj->parent!=NULL)parent=obj->parent->id;
3726 if(obj->planet!=NULL)planet=obj->id;
3727
3728 fprintf(fp,"parent:%d dest:%d in:%d planet:%d\n weapon:%d engine:%d\n ",
3729 parent,dest,in,planet,
3730 obj->weapon->type,obj->engine.type);
3731
3732 fprintf(fp,"parent:%p dest:%p in:%p planet:%p\n",
3733 (void *)obj->parent,(void *)obj->dest,(void *)obj->in,(void *)obj->planet);
3734
3735 return(0);
3736 }
3737
ChooseInitPlanet(struct HeadObjList lheadobjs)3738 Object *ChooseInitPlanet(struct HeadObjList lheadobjs){
3739 /*
3740 returns:
3741 a pointer to a free planet.
3742 */
3743
3744 struct ObjList *ls;
3745 int n,cont=0;
3746 int nplanets=0;
3747 int rplanet;
3748
3749 /* counting planets */
3750 ls=lheadobjs.list;
3751 while(ls!=NULL){
3752 if(ls->obj->type==PLANET){
3753 cont++;
3754 }
3755 ls=ls->next;
3756 }
3757
3758 nplanets=cont;
3759 n=0;
3760
3761 do{
3762 rplanet=(int)(nplanets*Random(-1));
3763
3764 ls=lheadobjs.list;
3765 cont=0;
3766 while(ls!=NULL){
3767 if(ls->obj->type==PLANET){
3768 if(ls->obj->player==0 && cont==rplanet){ /* a random planet */
3769 return(ls->obj);
3770 }
3771 }
3772 ls=ls->next;
3773 cont++;
3774 }
3775 n++;
3776 }
3777 while(n<10);
3778
3779 cont=0;
3780 ls=lheadobjs.list;
3781 while(ls!=NULL){
3782 if(ls->obj->type==PLANET ){
3783 if(ls->obj->player==0){ /* the first free planet */
3784 return(ls->obj);
3785 }
3786 }
3787 ls=ls->next;
3788 cont++;
3789 }
3790
3791 fprintf(stderr,"ERROR ChooseInitPlanet(): Too many players or too few planets\n");
3792 return(NULL);
3793 }
3794
CreateShips(struct HeadObjList * lheadobjs)3795 void CreateShips(struct HeadObjList *lheadobjs){
3796 /*
3797 Choose initial planet.
3798 Create the initial player ships
3799 */
3800 Object *obj,*planet;
3801 Segment *s;
3802 int i;
3803 struct Player *plyr;
3804 plyr=GetPlayers();
3805
3806 for(i=1;i<=GameParametres(GET,GNPLAYERS,0);i++){
3807 planet=ChooseInitPlanet(*lheadobjs);
3808 if(planet==NULL){
3809 fprintf(stderr,"ERROR CreateShips(): obj==NULL\n");
3810 exit(-1);
3811 }
3812 s=LandZone(planet->planet);
3813 if(s==NULL){
3814 fprintf(stderr,"ERROR CreateShips(): Segment==NULL\n");
3815 exit(-1);
3816 }
3817
3818 obj=NewObj(SHIP,QUEEN,
3819 0,0,0,0,
3820 CANNON5,ENGINE5,i,NULL,planet);
3821
3822 obj->x=s->x0+(s->x1-s->x0)*(Random(-1));
3823
3824 obj->y=obj->y0=(s->y0)+obj->radio+1;
3825 obj->a=PI/2;
3826 obj->ai=1;
3827 obj->habitat=H_PLANET;
3828 obj->mode=LANDED;
3829
3830 Add2ObjList(lheadobjs,obj);
3831 plyr[obj->player].nbuildships++;
3832
3833 planet->player=obj->player;
3834
3835 if(GameParametres(GET,GNET,0)==TRUE){
3836 if(GetProc()==plyr[planet->player].proc){
3837 SetModified(planet,SENDOBJPLANET);
3838 planet->sw=1;
3839 planet->ttl=0;
3840 }
3841 }
3842
3843 plyr[obj->player].kplanets=Add2IntList((plyr[obj->player].kplanets),planet->id);
3844 plyr[obj->player].nplanets++;
3845
3846 if(GameParametres(GET,GKPLANETS,0)==FALSE){
3847 int j,k;
3848
3849 for(j=-2;j<3;j++){
3850 for(k=-2;k<3;k++){
3851 if(j*j+k*k<8){
3852 Add2IntIList(&(plyr[obj->player].ksectors),
3853 Quadrant(planet->x+j*SECTORSIZE,planet->y+k*SECTORSIZE));
3854 }
3855 }
3856 }
3857 }
3858 if(i==actual_player){
3859 cv=obj;
3860 ship_c=obj;
3861 habitat.type=H_PLANET;
3862 habitat.obj=planet;
3863 }
3864 }
3865 return;
3866 }
3867
3868
3869
CheckGame(char * cad,int action)3870 int CheckGame(char *cad,int action){
3871 /*
3872 Check some game consistence.
3873 Used every step (!!HERE check this)
3874 Used after load a game.
3875 action:
3876 0 only show messages
3877 1 try to correct errors
3878 */
3879
3880 struct ObjList *ls;
3881 struct OrderList *lo;
3882 Object *obj;
3883 int i;
3884 int n=0;
3885 int types[ALLOBJS];
3886 int type;
3887 int proc;
3888 int nplayers=0;
3889
3890 struct Player *plyr;
3891 plyr=GetPlayers();
3892
3893
3894 proc=GetProc();
3895 nplayers=(GameParametres(GET,GNPLAYERS,0));
3896 /* Checking Orders */
3897
3898 for(i=0;i<ALLOBJS;i++){
3899 types[i]=0;
3900 }
3901
3902 printf("%s",cad);
3903
3904 ls=listheadobjs.list;
3905 while(ls!=NULL){
3906 obj=ls->obj;
3907
3908 type=obj->type+1;
3909 if(type>ALLOBJS)type=ALLOBJS;
3910 types[type]++;
3911
3912 if(proc==plyr[obj->player].proc){
3913 n=0;
3914 lo=obj->lorder;
3915 while(lo!=NULL){
3916 n++;
3917 lo=lo->next;
3918 }
3919 if(n!=obj->norder){
3920 fprintf(stderr,"ERROR CheckGame():norder incorrect\n");
3921 printf("\tObj: %d, type: %d norder=%d , size of list: %d\n",
3922 obj->id,obj->type,obj->norder,n);
3923 printf("\tDeleting all the orders of object %d\n",obj->id);
3924 DelAllOrder(obj);
3925 }
3926 }
3927
3928 if(obj->player<0 || obj->player>nplayers+2){
3929 fprintf(stderr,"\tError CheckGame() obj: %d player id: %d invalid.\n",obj->id,obj->player);
3930 }
3931
3932 if(obj->type==SHIP && obj->subtype==TOWER && obj->habitat!=H_PLANET){
3933 fprintf(stderr,"\tError CheckGame() obj %d TOWER not in planet. habitat: %d . player: %d \n",obj->id, obj->habitat,obj->player);
3934 printf("\tRemoving the ship (%d)%d\n",obj->player,obj->pid);
3935 obj->state=0;
3936 SetModified(obj,SENDOBJKILL);
3937 obj->ttl=0;
3938 ls=ls->next;continue;
3939 }
3940
3941 /* if planet don't belongs to a landed ship */
3942 if(obj->type==SHIP){
3943 if(obj->radar<2000){
3944 printf("SHIP %d(%d) player: %d with radar: %d\n",obj->pid,obj->id,obj->player,obj->radar);
3945 }
3946 if(obj->subtype==FIGHTER){
3947 if(obj->items&ITSURVIVAL && obj->level<MINLEVELPILOT){
3948 printf("Error ship %d level: %d items: %d => Removed survival pod.\n",obj->id,obj->level,obj->items);
3949 obj->items=obj->items&(~ITSURVIVAL);
3950 }
3951
3952 if(fabs(obj->cost - COSTFIGHTER*COSTFACTOR*pow(COSTINC,obj->level))>0.01){
3953 printf("Error ship %d (%d-%d) level: %d cost: %f -> %f \n",
3954 obj->id,obj->player,obj->pid,
3955 obj->level,obj->cost,0.01*COSTFACTOR*pow(COSTINC,obj->level));
3956 obj->cost=0.01*COSTFACTOR*pow(COSTINC,obj->level);
3957 }
3958
3959 }
3960 if(obj->mode==LANDED && obj->in==NULL){
3961 fprintf(stderr,"\tError CheckGame() obj %d landed and in NULL\n",obj->id);
3962 ls=ls->next;continue;
3963 }
3964 if(obj->mode==LANDED && obj->in!=NULL && obj->habitat==H_PLANET){
3965 if(obj->in->planet==NULL){
3966 fprintf(stderr,"\tError CheckGame() obj %d planet not assigned\n",obj->id);
3967 ls=ls->next;continue;
3968 }
3969 }
3970 if(obj->habitat!=H_SPACE && obj->in==NULL){
3971 fprintf(stderr,"\tError CheckGame() obj %d not in space and in = NULL\n",obj->id);
3972 fprintf(stderr,"\t\ttype: %d stype: %d\n",obj->type,obj->subtype);
3973 fprintf(stderr,"\t\thabitat: %d\n",obj->habitat);
3974 if(action){
3975 printf("\tRemoving the ship (%d)%d\n",obj->player,obj->pid);
3976 obj->state=0;
3977 SetModified(obj,SENDOBJKILL);
3978 obj->ttl=0;
3979 }
3980
3981 ls=ls->next;continue;
3982 }
3983 if(obj->habitat==H_SHIP){
3984 int sw=0;
3985 if (obj->in==NULL){
3986 fprintf(stderr,"\tError CheckGame() obj %d in ship and in= NULL\n",obj->id);
3987 sw++;
3988 }
3989
3990 if(obj->in!=NULL){
3991 if(CargoIsObj(obj->in,obj)==0){
3992
3993 /* if((obj->in->items & ITPILOT)==0){ */
3994 sw++;
3995 printf("\tError CheckGame() obj (%d)%d (%d,%d) has no a pilot (%d)%d (%d,%d)\n",
3996 obj->in->player,obj->in->pid,obj->in->type,obj->in->subtype,
3997 obj->player,obj->pid,obj->type,obj->subtype);
3998 if(action){
3999 printf("\tRemoving the ship (%d)%d\n",obj->player,obj->pid);
4000 obj->state=0;
4001 SetModified(obj,SENDOBJKILL);
4002 obj->ttl=0;
4003 }
4004 }
4005
4006
4007 }
4008 if(sw){
4009 ls=ls->next;continue;
4010 }
4011 }
4012 }
4013
4014 ls=ls->next;
4015 }
4016 return(0);
4017 }
4018
4019
Density(void)4020 void Density(void){
4021 /*
4022
4023 Not used by now
4024
4025 */
4026 struct ObjList *ls;
4027 int i,j;
4028 int den[10][10];
4029 float x,y;
4030
4031 for(i=0;i<10;i++)
4032 for(j=0;j<10;j++)
4033 den[i][j]=0;
4034
4035 ls=listheadobjs.list;
4036 while(ls!=NULL){
4037 if(ls->obj->type==PLANET){
4038
4039 if(ls->obj->habitat==H_PLANET){
4040 x=ls->obj->in->planet->x;
4041 y=ls->obj->in->planet->y;
4042 }
4043 else{
4044 x=ls->obj->x;
4045 y=ls->obj->y;
4046 }
4047
4048
4049 i=10.*x/(float)GameParametres(GET,GULX,0);
4050 j=10.*y/(float)GameParametres(GET,GULY,0);
4051 i+=5;
4052 j+=5;
4053 if(i<0)i=0;
4054 if(j<0)j=0;
4055 if(i>9)i=9;
4056 if(j>9)j=9;
4057 den[i][j]++;
4058 }
4059 ls=ls->next;
4060 }
4061
4062 for(i=0;i<10;i++){
4063 for(j=0;j<10;j++){
4064 }
4065 }
4066 }
4067
4068
GetUniverse(void)4069 void GetUniverse(void){
4070 struct Player *plyr;
4071
4072
4073 /*ExecLoad("kk"); */
4074 ExecLoad(savefile);
4075 plyr=GetPlayers();
4076 plyr[actual_player].status=PLAYERMODIFIED;
4077 p_time=GetTime();
4078 CheckGame("Checking game after load...",1);
4079 printf("done\n");
4080 }
4081
NetComm(void)4082 void NetComm(void){
4083 /* net gamming */
4084
4085 /* orders to thread:
4086 OTSENDOBJS: send modified objects.
4087 OTSENDALLOBJS save: send all the objects.
4088 OTSENDLOAD load: load all the objects.
4089 OTSENDKILL to finish: quit the program.
4090 */
4091 int mode;
4092 int fd;
4093 struct Keys *key;
4094
4095 mode=GameParametres(GET,GMODE,0);
4096 order2thread=OTSENDOBJS;
4097 key=GetKeys();
4098
4099 if(mode==SERVER){
4100 if(key->save==TRUE){
4101 order2thread=OTSENDSAVE;
4102 }
4103
4104 if(key->load==TRUE){
4105 /* check if is possible open the dir */
4106 /* checking the file */
4107 if((fd=open(savefile,O_RDONLY))==-1){
4108 fprintf(stdout,"CommServer()[OTSENDLOAD]: Can'T open the file: %s\n",savefile);
4109 }
4110 else{
4111 order2thread=OTSENDLOAD;
4112 }
4113 close(fd);
4114 }
4115 }
4116
4117 if(GameParametres(GET,GQUIT,0)==2){
4118 order2thread=OTSENDKILL;
4119 }
4120
4121 switch(mode){
4122 case SERVER:
4123 LoadBuffer(order2thread,&buffer1,SERVER);
4124 sem_post(&sem_barrier1); /* run comm. thread*/
4125 break;
4126 case CLIENT:
4127 sem_post(&sem_barrier1); /* run comm. thread*/
4128 break;
4129 default:
4130 break;
4131 }
4132
4133 sem_wait(&sem_barrier); /* HERE send this far away in code */
4134 }
4135
4136
int_handler(int sign)4137 void int_handler(int sign){
4138 fprintf(stderr,"signal n %d received (SIGINT)\n",sign);
4139 Quit(NULL,NULL);
4140 }
4141
segfault_handler(int sign)4142 void segfault_handler(int sign){
4143 fprintf(stderr,"signal n %d received (SEGFAULT)\n",sign);
4144 if(ExecSave(listheadobjs,SAVETMPFILE)!=0){
4145 fprintf(stderr,"Error in main(): I can't open %s\n",SAVETMPFILE);
4146 exit(-1);
4147 }
4148 fprintf(stderr,"%s %s\n",GetLocale(L_GAMESAVEDTO),SAVETMPFILE);
4149 exit(-1);
4150 /* Quit(NULL,NULL); */
4151 }
4152
4153
GetGold(void)4154 void GetGold(void){
4155 /*
4156 Count the number of planets that belongs to each player
4157 Increase players gold
4158 */
4159
4160
4161 struct ObjList *ls;
4162 int nplayers;
4163 int i;
4164 int proc;
4165 float inctower;
4166 float levelfactor;
4167 struct Player *plyr;
4168 plyr=GetPlayers();
4169
4170 proc=GetProc();
4171 nplayers=GameParametres(GET,GNPLAYERS,0);
4172
4173 for(i=0;i<nplayers+2;i++){
4174 plyr[i].nplanets=0;
4175 plyr[i].nships=0;
4176 plyr[i].balance=0;
4177 plyr[i].level=0;
4178 }
4179
4180 ls=listheadobjs.list;
4181 while(ls!=NULL){
4182 switch(ls->obj->type){
4183 case PLANET:
4184 plyr[ls->obj->player].nplanets++;
4185 break;
4186 case SHIP:
4187 if(ls->obj->subtype!=SATELLITE){
4188 plyr[ls->obj->player].nships++;
4189 plyr[ls->obj->player].level+=ls->obj->level;
4190 }
4191 break;
4192 default:
4193 ls=ls->next;continue;
4194 break;
4195 }
4196
4197 if(proc!=plyr[ls->obj->player].proc){
4198 ls=ls->next;continue;
4199 }
4200 if(ls->obj->player==0){
4201 ls=ls->next;continue;
4202 }
4203
4204 switch(ls->obj->type){
4205 case PLANET:
4206 /*gold for each planet*/
4207 plyr[ls->obj->player].balance+=.01*RESOURCEFACTOR;
4208 break;
4209 case SHIP:
4210 if(ls->obj->subtype==PILOT){
4211 plyr[ls->obj->player].balance-=0.25*ls->obj->cost;
4212 ls=ls->next;continue;
4213 }
4214 plyr[ls->obj->player].balance-=ls->obj->cost;
4215
4216 switch(ls->obj->subtype){
4217 case TOWER:
4218 levelfactor=(1.0+1.0*ls->obj->level);
4219
4220 if(ls->obj->in->planet->gold>0){
4221 inctower=(.4+0.1*levelfactor)*RESOURCEFACTOR;
4222 if(ls->obj->in->planet->gold>inctower){
4223 plyr[ls->obj->player].balance+=inctower;
4224 ls->obj->in->planet->gold-=inctower;
4225 ls->obj->in->planet->A-=0.015;
4226 if(ls->obj->in->planet->A<0)ls->obj->in->planet->A=0;
4227 }
4228 else{
4229 plyr[ls->obj->player].balance+=ls->obj->in->planet->gold;
4230 ls->obj->in->planet->gold=0;
4231 }
4232 }
4233 else{
4234 ls->obj->in->planet->gold=0;
4235 if(ls->obj->in->planet->A > 0.015){
4236 plyr[ls->obj->player].balance+=0.015*levelfactor;
4237 ls->obj->in->planet->A-=0.015;
4238 if(ls->obj->in->planet->A<0)ls->obj->in->planet->A=0;
4239 }
4240 else{
4241 plyr[ls->obj->player].balance+=ls->obj->in->planet->A*levelfactor;
4242 ls->obj->in->planet->A=0.0;
4243 }
4244 }
4245
4246
4247 break;
4248
4249 default:
4250 break;
4251 }
4252
4253 break;
4254 default:
4255 break;
4256 }
4257 ls=ls->next;
4258 }
4259
4260 for(i=0;i<nplayers+2;i++){
4261 if(proc==plyr[i].proc){
4262 plyr[i].gold+=plyr[i].balance;
4263 }
4264 }
4265 }
4266
4267
GetPoints(struct HeadObjList * hol,int proc,struct Player * p)4268 void GetPoints(struct HeadObjList *hol,int proc,struct Player *p){
4269 /*
4270 version 0.3 12Dic2010
4271
4272 if state is 0 sum points and experience
4273 */
4274
4275 struct ObjList *ls;
4276 Object *obj; /* dead object */
4277 int sw=0;
4278 int gnet;
4279 struct Player *plyr;
4280 plyr=GetPlayers();
4281
4282 ls=hol->list;
4283 gnet=GameParametres(GET,GNET,0);
4284
4285 while(ls!=NULL){
4286 obj=ls->obj;
4287 sw=0;
4288 if(gnet==TRUE){
4289 if(obj->modified==SENDOBJDEAD)sw=1;
4290 }
4291 else{
4292 if(obj->state<=0)sw=1;
4293 }
4294
4295 if(obj->type==SHIP && obj->subtype==PILOT && obj->sw!=0){
4296 sw=1;
4297 }
4298
4299 if(sw){
4300 GetPointsObj(hol,plyr,obj);/* points and experience */
4301 }
4302
4303 /*****
4304 Partial experience
4305 By now, only due to proximity with enemies
4306 ******/
4307 if(obj->pexperience>0){
4308 obj->pexperience=obj->pexperience>0.1?0.1:obj->pexperience;
4309 Experience(obj,obj->pexperience);
4310 obj->pexperience=0;
4311 }
4312
4313 ls=ls->next;
4314 }
4315 return;
4316 }
4317
4318
GetPointsObj(struct HeadObjList * lhobjs,struct Player * p,Object * obj)4319 void GetPointsObj(struct HeadObjList *lhobjs,struct Player *p,Object *obj){
4320 /*
4321 version 0.3 12Dic2010
4322 obj dead object
4323 if state is 0 sum points and experience
4324 */
4325
4326
4327 Object *obj2; /* killer */
4328 Object *obj3; /* who receive points */
4329 int il;
4330 float factor,points;
4331
4332
4333
4334 if(obj==NULL)return;
4335 if(obj->sw==0)return;
4336
4337 obj2=obj3=NULL;
4338
4339 switch(obj->type){
4340 case PROJECTILE:
4341 /* points to nobody */
4342
4343 break;
4344 case SHIP:
4345 /* points to the killer */
4346 if(obj->subtype==PILOT){ /* no points for killing a pilot */
4347 break;
4348 }
4349 obj2=SelectObj(lhobjs,(obj->sw));
4350
4351 if(obj2!=NULL){
4352 obj3=NULL;
4353 if(obj2->type==SHIP)obj3=obj2;
4354 if(obj3!=NULL){
4355 /* must be a SHIP */
4356 obj3->kills++;
4357 p[obj3->player].nkills++;
4358
4359 /* Experience for kill an enemy */
4360 il=obj->level - obj3->level;
4361 if(il>3)il=3;
4362 factor=50;
4363 if(il<0)factor/=2;
4364 if(il<-1)factor/=2;
4365 if(il<-2)factor/=2;
4366 if(factor>0){
4367 points=factor*pow(2,obj->level);
4368 if(obj->subtype==PILOT && obj->state<=0)points/=2;
4369 if(points<10)points=10;
4370 Experience(obj3,points);
4371 }
4372 /* --Experience for kill an enemy */
4373 }
4374 }
4375 obj->sw=0;
4376 break;
4377 case ASTEROID:
4378
4379 obj2=SelectObj(lhobjs,(obj->sw));
4380 if(obj2!=NULL){
4381 obj3=NULL;
4382 /* if(obj2->type==PROJECTILE){ */
4383 /* obj3=SelectObj(&listheadobjs,obj2->parent->id); */
4384 /* } */
4385 if(obj2->type==SHIP)obj3=obj2;
4386 if(obj3!=NULL){
4387 /* must be a SHIP */
4388
4389 switch(obj->subtype){
4390 case ASTEROID1:
4391 p[obj3->player].gold+=50;
4392 break;
4393 case ASTEROID2:
4394 p[obj3->player].gold+=100;
4395 break;
4396 case ASTEROID3:
4397 p[obj3->player].gold+=200;
4398 break;
4399 default:
4400 fprintf(stderr,"ERROR in GetGold():asteroid subtype %d unknown\n",obj->subtype);
4401 exit(-1);
4402 break;
4403 }
4404 }
4405 }
4406 obj->sw=0;
4407 break;
4408 default:
4409 break;
4410 }
4411
4412 return;
4413 }
4414
4415
PrintGameOptions(void)4416 void PrintGameOptions(void){
4417
4418 printf("actual game options:\n");
4419 printf("\tUniverse size: %d\n",GameParametres(GET,GULX,0));
4420 printf("\tNumber of Galaxies: %d\n",GameParametres(GET,GNGALAXIES,0));
4421 printf("\tNumber of planets: %d\n",GameParametres(GET,GNPLANETS,0));
4422 printf("\tNumber of players: %d\n",GameParametres(GET,GNPLAYERS,0));
4423 if(GameParametres(GET,GKPLANETS,0)==TRUE){
4424 printf("\tPlanets known by all the players.\n");
4425 }
4426 if(GameParametres(GET,GKPLANETS,0))
4427 printf("\tknown planets: yes\n");
4428 else
4429 printf("\tknown planets: no\n");
4430
4431 if(GameParametres(GET,GCOOPERATIVE,0))
4432 printf("\tcooperative mode: yes\n");
4433 else
4434 printf("\tcooperative mode: no\n");
4435
4436 if(GameParametres(GET,GCOMPCOOPERATIVE,0))
4437 printf("\tcomputer cooperative mode: yes\n");
4438 else
4439 printf("\tcomputer cooperative mode: no\n");
4440
4441 if(GameParametres(GET,GQUEEN,0))
4442 printf("\tQueen mode: yes\n");
4443 else
4444 printf("\tQueen mode: no\n");
4445
4446 if(GameParametres(GET,GPIRATES,0))
4447 printf("\tpirates: yes\n");
4448 else
4449 printf("\tpirates: no\n");
4450
4451 if(GameParametres(GET,GENEMYKNOWN,0))
4452 printf("\tEnemy known: yes\n");
4453 else
4454 printf("\tEnemy known: no\n");
4455
4456
4457 if(GameParametres(GET,GNET,0))
4458 printf("\tnet game: yes\n");
4459 else
4460 printf("\tnet game: no\n");
4461
4462 printf("\tSound: %d volume: %d\n",
4463 GameParametres(GET,GSOUND,0),GameParametres(GET,GSOUNDVOL,0));
4464 printf("\tMusic: %d volume: %d\n",
4465 GameParametres(GET,GMUSIC,0),GameParametres(GET,GMUSICVOL,0));
4466
4467 }
4468
4469
SetGameParametres(struct Parametres param)4470 void SetGameParametres(struct Parametres param){
4471 int width,height;
4472
4473 GameParametres(SET,DEFAULT,0); /* defaults game values */
4474
4475 if(gfont==NULL){
4476 GameParametres(SET,GPANEL,PANEL_HEIGHT);
4477 }
4478 else{
4479 GameParametres(SET,GPANEL,2*gdk_text_height(gfont,"pL",2));
4480 }
4481
4482 if(param.server==TRUE||param.client==TRUE){
4483 GameParametres(SET,GNET,TRUE);
4484 printf("NET\n");
4485 if(param.server==TRUE){
4486 GameParametres(SET,GMODE,SERVER);
4487 }
4488 if(param.client==TRUE){
4489 GameParametres(SET,GMODE,CLIENT);
4490 }
4491 }
4492
4493 GameParametres(SET,GNGALAXIES,param.ngalaxies);
4494 GameParametres(SET,GNPLANETS,param.nplanets);
4495 GameParametres(SET,GNPLAYERS,param.nplayers); /*+1 system +1 pirates */
4496
4497 if(param.kplanets==TRUE){
4498 GameParametres(SET,GKPLANETS,TRUE);
4499 }
4500
4501 if(param.pirates==FALSE){
4502 GameParametres(SET,GPIRATES,FALSE);
4503 }
4504
4505 if(param.enemyknown==TRUE){
4506 GameParametres(SET,GENEMYKNOWN,TRUE);
4507 }
4508
4509 GameParametres(SET,GULX,param.ul);
4510 GameParametres(SET,GULY,param.ul);
4511
4512 GameParametres(SET,GCOOPERATIVE,param.cooperative);
4513 GameParametres(SET,GCOMPCOOPERATIVE,param.compcooperative);
4514
4515 GameParametres(SET,GMUSIC,param.music);
4516 GameParametres(SET,GSOUND,param.sound);
4517 GameParametres(SET,GSOUNDVOL,param.soundvol);
4518 GameParametres(SET,GMUSICVOL,param.musicvol);
4519
4520
4521 GameParametres(SET,GWIDTH,DEFAULTWIDTH);
4522 GameParametres(SET,GHEIGHT,DEFAULTHEIGHT);
4523 GetGeom(param.geom,&width,&height);
4524 GameParametres(SET,GWIDTH,width);
4525 GameParametres(SET,GHEIGHT,height-GameParametres(GET,GPANEL,0));
4526
4527 printf("W: %d H: %d \n", GameParametres(GET,GWIDTH,0),GameParametres(GET,GHEIGHT,0));
4528 printf("W: %d H: %d \n",width,height);
4529
4530
4531 /*********** process identifier ***********/
4532
4533 SetProc(0);
4534 SetNProc(1);
4535
4536 if(GameParametres(GET,GMODE,0)==CLIENT){
4537 SetProc(1);
4538 }
4539 if(GameParametres(GET,GNET,0)==TRUE){
4540 SetNProc(2);
4541 }
4542
4543 /********** --process identifier ***********/
4544
4545 }
4546
MakeTitle(struct Parametres param,char * title)4547 void MakeTitle(struct Parametres param, char *title){
4548 strncat(title,TITLE,64-strlen(title));
4549 if(param.server==TRUE)
4550 strcat(title,"(server) ");
4551 if(param.client==TRUE)
4552 strcat(title,"(client) ");
4553 strncat(title,version,64-strlen(title));
4554 strcat(title," ");
4555 strncat(title,copyleft,64-strlen(title));
4556 }
4557
4558
InitGameVars(void)4559 void InitGameVars(void){
4560 int i;
4561 struct Sockfd sfd;
4562 int nx,ny;
4563 struct Player *plyr;
4564
4565 /****** start server and client *********/
4566
4567 if(GameParametres(GET,GNET,0)==TRUE){
4568 if(param.server==TRUE){
4569 printf("SERVER\n");
4570 OpenComm(0,param,&sfd);
4571 printf("opencomm finished\n");
4572 StartComm(0,&sfd);
4573 }
4574 if(param.client==TRUE){
4575 printf("CLIENT\n");
4576 OpenComm(1,param,&sfd);
4577 printf("opencomm finished\n");
4578 StartComm(1,&sfd);
4579 }
4580 printf("conexion established\n");
4581
4582 /* synchronization with comm threads */
4583 sem_wait(&sem_barrier);
4584 }
4585 /****** --start server and client *********/
4586
4587 /*****************************************************************/
4588 /* client and server now known all the game options */
4589 /*****************************************************************/
4590
4591 listheadobjs.list=NULL;
4592 listheadobjs.n=0;
4593 listheadplanets.list=NULL;
4594 listheadplanets.n=0;
4595 listheadtext.next=NULL;
4596 listheadtext.info.n=0;
4597
4598 for(i=0;i<4;i++)fobj[i]=0;
4599 gtime0=0;
4600
4601 /********** players ***********/
4602 /* CreatePlayers(&players); */
4603 CreatePlayers(clientname,param);
4604 plyr=GetPlayers();
4605 /********** --players ***********/
4606
4607 /********** teams ***********/
4608 CreateTeams(param);
4609 /********** --teams **********/
4610
4611 if(param.queen){
4612 printf("WARNING: Queen mode set to ON.\n");
4613 GameParametres(SET,GQUEEN,TRUE);
4614 }
4615
4616 /******** Create Universe **************/
4617 if(param.client==FALSE){
4618 printf("CreateUniverse()...");
4619 CreateUniverse(GameParametres(GET,GULX,0),GameParametres(GET,GULY,0),&listheadobjs,planetnames);
4620 CreatePlanetList(listheadobjs,&listheadplanets);
4621 printf("...done\n");
4622 printf("CreateShips()...");
4623 CreateShips(&listheadobjs);
4624 printf("...done\n");
4625
4626 }
4627 /******** -- Create Universe **************/
4628
4629 listheadcontainer=malloc((GameParametres(GET,GNPLANETS,0)+1)*sizeof(struct HeadObjList));
4630 MemUsed(MADD,(GameParametres(GET,GNPLANETS,0)+1)*sizeof(struct HeadObjList));
4631 if(listheadcontainer==NULL){
4632 fprintf(stderr,"ERROR in malloc main()\n");
4633 exit(-1);
4634 }
4635 for(i=0;i<GameParametres(GET,GNPLANETS,0)+1;i++){
4636 listheadcontainer[i].list=NULL;
4637 listheadcontainer[i].n=0;
4638 }
4639
4640 listheadkplanets=malloc((GameParametres(GET,GNPLAYERS,0)+2)*sizeof(struct HeadObjList));
4641 MemUsed(MADD,(GameParametres(GET,GNPLAYERS,0)+2)*sizeof(struct HeadObjList));
4642 if(listheadkplanets==NULL){
4643 fprintf(stderr,"ERROR in malloc main()\n");
4644 exit(-1);
4645 }
4646 for(i=0;i<GameParametres(GET,GNPLAYERS,0)+2;i++){
4647 listheadkplanets[i].list=NULL;
4648 listheadkplanets[i].n=0;
4649 }
4650
4651 /********* sending and receiving Universe *****************/
4652
4653 if(param.server==TRUE){
4654 if(ExecSave(listheadobjs,SAVETMPFILE)!=0){
4655 fprintf(stderr,"Error in main(): I can't open %s\n",SAVETMPFILE);
4656 exit(-1);
4657 }
4658
4659 SetModifiedAll(&listheadobjs,ALLOBJS,SENDOBJUNMOD,TRUE);
4660 p_time=GetTime();
4661 }
4662
4663 if(GameParametres(GET,GNET,0)==TRUE){
4664 sem_post(&sem_barrier1);
4665 sem_wait(&sem_barrier);
4666 }
4667
4668 if(param.client==TRUE){
4669 GetUniverse();
4670 g_objid=glocal.g_objid;
4671 plyr=GetPlayers();
4672
4673 SetModifiedAll(&listheadobjs,ALLOBJS,SENDOBJUNMOD,TRUE);
4674 CreatePlanetList(listheadobjs,&listheadplanets);
4675 }
4676 /********* --sending and receiving Universe *****************/
4677
4678 actual_player=1;
4679 if(GameParametres(GET,GMODE,0)==SERVER){ /* only two human players, by now*/
4680 actual_player=2;
4681 }
4682 actual_player0=actual_player;
4683 plyr[actual_player].control=HUMAN;
4684
4685 printf("Actual Player: %d\n",actual_player);
4686
4687 DestroyObjList(&listheadplayer);
4688 listheadplayer.n=0;
4689 listheadplayer.list=NULL;
4690 CreatePlayerList(listheadobjs,&listheadplayer,actual_player);
4691 listheadplayer.update=0;
4692
4693 cv=NextCv(&listheadplayer,cv,actual_player);
4694 if(cv!=NULL){
4695 habitat.type=cv->habitat;
4696 habitat.obj=cv->in;
4697 cv->selected=TRUE;
4698 }
4699
4700 /* Adding planets to players list */
4701 AddPlanets2List(&listheadobjs,plyr);
4702
4703 /* print teams */
4704 PrintTeams();
4705
4706 /*****CELLON*****/
4707
4708 nx=GameParametres(GET,GULX,0)/2000;
4709 ny=GameParametres(GET,GULY,0)/2000;
4710
4711 cell=malloc(nx*ny*sizeof(int));
4712 if(cell==NULL){
4713 fprintf(stderr,"ERROR in malloc (creating cell)\n");
4714 exit(-1);
4715 }
4716 for(i=0;i<nx*ny;i++){
4717 cell[i]=0;
4718 }
4719
4720 /*****--CELLON*****/
4721 PrintGameOptions();
4722 }
4723
AddPlanets2List(struct HeadObjList * listheadobjs,struct Player * players)4724 void AddPlanets2List(struct HeadObjList *listheadobjs,struct Player *players){
4725 /*
4726 Add known planets to players list
4727 */
4728 struct ObjList *ls;
4729 int i;
4730
4731 if(listheadobjs==NULL || players==NULL){
4732 fprintf(stderr,"ERROR in AddPlanets2List()\n");
4733 exit(-1);
4734 }
4735
4736 ls=listheadobjs->list;
4737 while(ls!=NULL){
4738 if(ls->obj->type==PLANET){
4739 for(i=0;i<GameParametres(GET,GNPLAYERS,0)+1;i++){
4740 if(GameParametres(GET,GKPLANETS,0)==TRUE ||
4741 players[ls->obj->player].team==players[i].team ||
4742 (GameParametres(GET,GENEMYKNOWN,0)==TRUE && players[ls->obj->player].team > 1) ){
4743 players[i].kplanets=Add2IntList((players[i].kplanets),ls->obj->id);
4744 }
4745 }
4746 }
4747 ls=ls->next;
4748 }
4749 }
4750