source: golgotha/src/golg/team_api.cc

Last change on this file was 80, checked in by Sam Hocevar, 11 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 12.3 KB
RevLine 
[80]1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#include "team_api.hh"
10#include "player.hh"
11#include "map.hh"
12#include "objs/stank.hh"
13#include "objs/path_object.hh"
14#include "resources.hh"
15#include "map_man.hh"
16#include "lisp/lisp.hh"
17#include "objs/bases.hh"
18#include "li_objref.hh"
19#include "playback.hh"
20#include "file/file.hh"
21#include "tick_count.hh"
22
23#include "statistics.hh"
24#include "controller.hh"
25#include "time/time.hh"
26
27void read_playback_checker(i4_file_class *fp)
28{
29  int x=fp->read_32();
30  if (x!=g1_tick_counter)
31    i4_warning("demo check off is");
32}
33
34void write_playback_checker(i4_file_class *fp)
35{
36  fp->write_32(g1_tick_counter);
37}
38
39g1_team_api_class::g1_team_api_class()
40  : record(0), playback(0)
41//{{{
42{
43}
44//}}}
45
46g1_player_piece_class *g1_team_api_class::commander() const
47//{{{
48{
49  return player->get_commander();
50}
51//}}}
52
53sw16 g1_team_api_class::health() const
54//{{{
55{
56  if (!commander())
57    return 0;
58
59  return commander()->health;
60}
61//}}}
62
63w16 g1_team_api_class::ammo0() const
64//{{{
65{
66  if (!commander())
67    return 0;
68
69  return commander()->ammo[0].amount;
70}
71//}}}
72
73w16 g1_team_api_class::ammo1() const
74//{{{
75{
76  if (!commander())
77    return 0;
78
79  return commander()->ammo[1].amount;
80}
81//}}}
82
83w16 g1_team_api_class::ammo2() const
84//{{{
85{
86  if (!commander())
87    return 0;
88
89  return commander()->ammo[2].amount;
90}
91//}}}
92
93i4_bool g1_team_api_class::full0() const
94//{{{
95{
96  g1_player_piece_class *stank=player->get_commander();
97  if (!stank ||stank->ammo[0].ammo_type)
98    return 0;
99  else
100    return stank->ammo[0].amount==stank->ammo[0].ammo_type->max_amount;
101}
102//}}}
103
104i4_bool g1_team_api_class::full1() const
105//{{{
106{
107  g1_player_piece_class *stank=player->get_commander();
108  if (!stank ||stank->ammo[1].ammo_type)
109    return 0;
110  else
111    return stank->ammo[1].amount==stank->ammo[1].ammo_type->max_amount;
112}
113//}}}
114
115i4_bool g1_team_api_class::full2() const
116//{{{
117{
118  g1_player_piece_class *stank=player->get_commander();
119  if (!stank ||stank->ammo[2].ammo_type)
120    return 0;
121  else
122    return stank->ammo[2].amount==stank->ammo[2].ammo_type->max_amount;
123}
124//}}}
125
126i4_bool g1_team_api_class::in_range0() const
127//{{{
128{
129  g1_player_piece_class *stank=player->get_commander();
130  if (!stank) return i4_F;
131  return stank->in_range(0, stank->attack_target.get());
132}
133//}}}
134
135i4_bool g1_team_api_class::in_range1() const
136//{{{
137{
138  g1_player_piece_class *stank=player->get_commander();
139  if (!stank) return i4_F;
140  return stank->in_range(1, stank->attack_target.get());
141}
142//}}}
143
144i4_bool g1_team_api_class::in_range2() const
145//{{{
146{
147  g1_player_piece_class *stank=player->get_commander();
148  if (!stank) return i4_F;
149  return stank->in_range(2, stank->attack_target.get());
150}
151//}}}
152
153void g1_team_api_class::turn(i4_float angle)
154//{{{
155{
156  if (record)
157  {
158    write_playback_checker(record);
159    record->write_8(G1_COMMAND_TURN);
160    record->write_float(angle);
161  }
162
163  i4_float max = g1_resources.player_turn_speed;
164  if (commander())
165    commander()->dtheta = (angle>max)?max:(angle<-max)?-max:angle;
166}
167//}}}
168
169void g1_team_api_class::accelerate(i4_float ratio)
170//{{{
171{
172  if (record)
173  {
174    write_playback_checker(record);
175    record->write_8(G1_COMMAND_ACCEL);
176    record->write_float(ratio);
177  }
178
179  if (commander())
180    commander()->accel_ratio = (ratio>1.0)?1.0:(ratio<-1.0)?-1.0:ratio;
181}
182//}}}
183
184void g1_team_api_class::strafe(i4_float ratio)
185//{{{
186{
187  if (record)
188  {
189    write_playback_checker(record);
190    record->write_8(G1_COMMAND_STRAFE);
191    record->write_float(ratio);
192  }
193
194  if (commander())
195    commander()->strafe_accel_ratio = (ratio>1.0)?1.0:(ratio<-1.0)?-1.0:ratio;
196}
197//}}}
198
199void g1_team_api_class::look(i4_float dax, i4_float day)
200//{{{
201{
202  if (record)
203  {
204    write_playback_checker(record);
205    record->write_8(G1_COMMAND_LOOK);
206    record->write_float(dax);
207    record->write_float(day);
208  }
209
210  if (commander())
211  {
212    commander()->mouse_look_increment_x = dax;
213    commander()->mouse_look_increment_y = day;
214  }
215}
216//}}}
217
218i4_bool g1_team_api_class::fire0()
219//{{{
220{
221  if (record)
222  {
223    write_playback_checker(record);
224    record->write_8(G1_COMMAND_FIRE0);
225  }
226
227  if (ammo0()==0)
228    return i4_F;
229
230  commander()->fire[0] = i4_T;
231  return i4_T;
232}
233//}}}
234
235i4_bool g1_team_api_class::continue_game()
236{
237  if (g1_player_man.get(team())->continue_wait)
238  {
239    if (record)
240    {
241      write_playback_checker(record);
242      record->write_8(G1_COMMAND_CONTINUE);
243    }
244 
245    g1_player_man.get(team())->continue_wait=i4_F;
246
247  }
248
249  return i4_T;
250}
251
252
253i4_bool g1_team_api_class::fire1()
254//{{{
255{
256  if (record)
257  {
258    write_playback_checker(record);
259    record->write_8(G1_COMMAND_FIRE1);
260  }
261
262  if (ammo1()==0)
263    return i4_F;
264 
265  commander()->fire[1] = i4_T;
266  return i4_T;
267}
268//}}}
269
270
271i4_bool g1_team_api_class::fire2()
272//{{{
273{
274  if (record)
275  {
276    write_playback_checker(record);
277    record->write_8(G1_COMMAND_FIRE2);
278  }
279
280  if (ammo2()==0)
281    return i4_F;
282
283  commander()->fire[2] = i4_T;
284  return i4_T;
285}
286//}}}
287
288g1_player_type g1_team_api_class::team() const
289//{{{
290{
291  return player->player_num;
292}
293//}}}
294
295sw32 g1_team_api_class::money() const
296//{{{
297{
298  return player->money();
299}
300//}}}
301
302g1_map_class *g1_team_api_class::map() const
303//{{{
304{
305  //(OLI) should get rid of this one sometime... add real map interface
306  return g1_get_map();
307}
308//}}}
309
310w32 g1_team_api_class::map_height() const
311//{{{
312{
313  return g1_get_map()->height();
314}
315//}}}
316
317w32 g1_team_api_class::map_width() const
318//{{{
319{
320  return g1_get_map()->width();
321}
322//}}}
323
324i4_float g1_team_api_class::terrain_height(i4_float x, i4_float y, i4_float z) const
325//{{{
326{
327  if (g1_map_is_loaded())
328    return g1_get_map()->map_height(x,y,z);
329
330  else return 0;
331}
332//}}}
333
334i4_bool g1_team_api_class::is_building() const
335//{{{
336{
337  return i4_F;
338}
339//}}}
340
341w16 g1_team_api_class::object_type(const char *name) const
342//{{{
343{
344  return g1_get_object_type(name);
345}
346//}}}
347
348i4_bool g1_team_api_class::deploy_unit(w32 id, i4_float x, i4_float y)
349// send convoy to location
350//{{{
351{
352  if (record)
353  {
354    write_playback_checker(record);
355    record->write_8(G1_COMMAND_DEPLOY);
356    record->write_32(id);
357    record->write_float(x);
358    record->write_float(y);
359  }
360
361  i4_bool ret=0;;
362
363  if (g1_global_id.check_id(id))
364  {
365    g1_object_class *obj=g1_global_id.get(id);
366
367    if (obj->player_num==team())
368      ret = obj->deploy_to(x,y);
369  }
370
371  return ret;
372}
373//}}}
374
375w32 g1_path_time_counter=0;
376
377i4_bool g1_team_api_class::set_current_target(w32 global_id)
378// select target for convoy/object
379//{{{
380{
381  if (record)
382  {
383    write_playback_checker(record);
384    record->write_8(G1_COMMAND_TARGET);
385    record->write_32(global_id);
386  }
387
388  g1_path_object_class *target=g1_path_object_class::cast(g1_global_id.get(global_id));
389
390  if (!target)
391    return i4_F;
392
393  int player_num=team();
394
395  for (g1_factory_class *f=g1_factory_list.first(); f; f=f->next)
396  {
397    if (f->player_num==player_num)
398    {
399      g1_path_object_class *o=f->get_start();
400      if (o)
401      {
402        g1_path_object_class *path[256];
403        int t=o->find_path(player->get_team(), target, path, 256);
404        for (int j=0; j<t; j++)
405          path[j]->last_selected_tick[player->get_team()]=g1_path_time_counter+t-j;
406       
407        g1_path_time_counter+=t;
408      }
409    }
410  }
411  return i4_T;
412}
413//}}}
414
415int g1_team_api_class::build_unit(g1_object_type type)
416{
417  if (record)
418  {
419    write_playback_checker(record);
420    record->write_8(G1_COMMAND_BUILD);
421    record->write_16(type);
422  }
423
424  int player_num=team();
425  for (g1_factory_class *f=g1_factory_list.first(); f; f=f->next)
426    if (f->player_num==player_num)
427      if (f->build(type))
428        return G1_BUILD_OK;
429
430  return G1_BUILD_INVALID_OBJECT;
431}
432
433i4_bool g1_team_api_class::record_start(char *name)
434{
435  record = i4_open(name, I4_WRITE);
436  return (record!=0);
437}
438
439void g1_team_api_class::record_end()
440{
441  if (record)
442    delete record;
443  record = 0;
444}
445
446
447
448
449static int demo_start_time=i4_F;
450static i4_time_class demo_start;
451
452i4_bool g1_team_api_class::playback_start(i4_file_class *fp)
453{
454
455  playback = fp;
456  demo_start_time = i4_T;
457  g1_stat_counter.set_value(g1_statistics_counter_class::FRAMES,0);
458
459  return (playback!=0);
460}
461
462void g1_team_api_class::playback_end()
463{
464  if (playback)
465    delete playback;
466  playback = 0;
467
468  if (g1_current_controller.get())
469  {
470    i4_time_class now;
471
472    char buff[512];
473    sw32
474      frames = g1_stat_counter.get_value(g1_statistics_counter_class::FRAMES);
475    i4_float
476      time = i4_float(now.milli_diff(demo_start))/1000.0,
477      fps = i4_float(frames)/time;
478
479    sprintf(buff, "Demo Frames: %d  Time: %7.3f FPS: %5.2f", frames, time, fps);
480    g1_current_controller->scroll_message(buff, 0xff00ff);
481  }
482}
483
484
485i4_bool g1_team_api_class::playback_think()
486{
487  if (!playback)
488    return i4_F;
489
490  if (demo_start_time)
491  {
492    demo_start_time = i4_F;
493    demo_start.get();
494  }
495 
496  if (playback->eof())
497  {
498    playback_end();
499    return i4_F;
500  }
501
502  w8 com = 0;
503  do
504  {
505    read_playback_checker(playback);
506    com = playback->read_8();
507    switch (com)
508    {
509      case G1_COMMAND_TURN:
510      {
511        i4_float angle = playback->read_float();
512        turn(angle);
513      } break;
514      case G1_COMMAND_ACCEL:
515      {
516        i4_float ratio = playback->read_float();
517        accelerate(ratio);
518      } break;
519      case G1_COMMAND_STRAFE:
520      {
521        i4_float ratio = playback->read_float();
522        strafe(ratio);
523      } break;
524      case G1_COMMAND_LOOK:
525      {
526        i4_float dx,dy;
527        dx = playback->read_float();
528        dy = playback->read_float();
529        look(dx,dy);
530      } break;
531      case G1_COMMAND_DEPLOY:
532      {
533        w32
534          id = playback->read_32();
535        i4_float px,py;
536        px = playback->read_float();
537        py = playback->read_float();
538        deploy_unit(id,px,py);
539      } break;
540      case G1_COMMAND_BUILD:
541      {
542        w16 t = playback->read_16();
543        build_unit(t);
544      } break;
545      case G1_COMMAND_TARGET:
546      {
547        w32 id = playback->read_32();
548        set_current_target(id);
549      } break;
550      case G1_COMMAND_FIRE0:
551        fire0();
552        break;
553      case G1_COMMAND_FIRE1:
554        fire1();
555        break;
556      case G1_COMMAND_FIRE2:
557        fire2();
558        break;
559      case G1_COMMAND_END:
560        break;
561      default:
562        i4_warning("Invalid playback code received!");
563        com = G1_COMMAND_END;
564        break;
565    }
566  } while (com!=G1_COMMAND_END);
567
568  return i4_T;
569}
570
571void g1_team_api_class::post_think()
572{
573  if (record)
574  {
575    write_playback_checker(record);
576    record->write_8(G1_COMMAND_END);
577  }
578}
579
580g1_team_api_class::~g1_team_api_class()
581{
582  record_end();
583  playback_end();
584}
585
586
587//  Team API definition class
588
589g1_team_api_definition_class *g1_team_api_definition_class::first=0;
590
591g1_team_api_definition_class::g1_team_api_definition_class(const char *name)
592  : _name(name)
593//{{{
594{
595  next = first;
596  first = this;
597}
598//}}}
599
600g1_team_api_definition_class::~g1_team_api_definition_class()
601//{{{
602{
603  g1_team_api_definition_class *p = first;
604  g1_team_api_definition_class **ref = &first;
605
606  while (p && p!=this)
607  {
608    ref = &p->next;
609    p = p->next;
610  }
611
612  if (p)
613    *ref = p->next;
614
615  g1_player_man.unload_ai(this);
616}
617//}}}
618
619g1_team_api_class* g1_team_api_definition_class::create(const char *name,
620                                                               g1_loader_class *f)
621//{{{
622{
623  g1_team_api_definition_class *p=first;
624
625  while (p && strcmp(name, p->name()))
626    p = p->next;
627
628  if (!p)
629    return 0;
630   
631  return p->create(f);
632}
633//}}}
634
635//{{{ Emacs Locals
636// Local Variables:
637// folded-file: t
638// End:
639//}}}
640
Note: See TracBrowser for help on using the repository browser.