source: golgotha/src/golg/player.cc @ 80

Last change on this file since 80 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: 9.2 KB
Line 
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 "player.hh"
10#include "team_api.hh"
11#include "error/error.hh"
12#include "g1_limits.hh"
13#include "image/color.hh"
14#include "map.hh"
15#include "g1_object.hh"
16#include "objs/map_piece.hh"
17#include "objs/stank.hh"
18#include "palette/pal.hh"
19#include "saver.hh"
20#include "border_frame.hh"
21#include "map_man.hh"
22#include "dll/dll_man.hh"
23#include "time/profile.hh"
24#include "lisp/li_class.hh"
25#include "lisp/li_load.hh"
26#include "li_objref.hh"
27#include "lisp/li_init.hh"
28#include "objs/path_object.hh"
29#include "lisp/li_dialog.hh"
30#include "controller.hh"
31#include "g1_tint.hh"
32
33enum
34{
35  DATA_VERSION1=1,
36  DATA_VERSION2,
37  DATA_VERSION3,
38  DATA_VERSION                  // added ai saving
39};
40
41
42g1_player_manager_class g1_player_man;
43
44static li_symbol_ref li_upgrade_kill_ratio("upgrade_kill_ratio");
45static li_int_class_member li_money("money"), li_income_rate("income_rate"),
46  li_num_points("num_points"), li_num_stank_deaths("num_stank_deaths"),
47  li_num_stank_lives("num_stank_lives");
48
49
50static li_float_class_member li_damage_multiplier("damage_multiplier");
51static li_g1_ref_class_member current_taveover_target("current_taveover_target");
52
53static li_string_class_member li_team_flag("team_flag");
54static li_symbol_ref stank("stank");
55
56int &g1_player_info_class::num_points() { return get_vars()->get(li_num_points); }
57int &g1_player_info_class::num_stank_deaths() { return get_vars()->get(li_num_stank_deaths); }
58int &g1_player_info_class::num_stank_lives() { return get_vars()->get(li_num_stank_lives); }
59
60
61int &g1_player_info_class::money() { return get_vars()->get(li_money); }
62int &g1_player_info_class::income_rate() { return get_vars()->get(li_income_rate); }
63float &g1_player_info_class::damage_multiplier() { return get_vars()->get(li_damage_multiplier);}
64
65
66void g1_player_manager_class::show_message(const i4_const_str &message, w32 color, int player_for)
67{
68  if (player_for==local_player && g1_current_controller.get())
69    g1_current_controller->scroll_message(message, color);
70}
71
72g1_player_info_class::g1_player_info_class()
73  : ai(0),
74    owned_objects(0,32)
75{
76  refresh_money=1;
77}
78
79void g1_player_info_class::remove_object(w32 global_id)
80{
81  if (ai) ai->object_lost(global_id);
82 
83  g1_object_class *o=g1_global_id.checked_get(global_id);
84
85  if (o==commander.get())
86    set_commander(0);
87 
88  int t=owned_objects.size();
89  for (int i=0; i<t; i++)
90    if (owned_objects[i] == global_id)
91    {
92      owned_objects[i]=g1_global_id.invalid_id();
93      return ;
94    }
95
96  i4_warning("object not found");
97}
98
99void g1_player_info_class::add_object(w32 global_id)
100{
101  if (ai)
102    ai->object_added(global_id);
103
104  g1_object_class *o=g1_global_id.get(global_id);
105  if (!commander.get() && o->id==g1_get_object_type(stank.get()))
106    set_commander(g1_player_piece_class::cast(o));
107 
108  int t=owned_objects.size();
109  for (int i=0; i<t; i++)
110    if (!g1_global_id.check_id(owned_objects[i]))
111    {
112      owned_objects[i]=global_id;
113      return;
114    }
115
116  owned_objects.add(global_id);
117}
118
119float g1_player_info_class::kill_ratio()
120{
121  int d=num_stank_deaths();
122  if (!d) d=1;
123  return num_points() / (float)d;
124}
125
126void g1_player_info_class::calc_upgrade_level()
127{
128  supertank_upgrade_level=0;
129       
130  // run through the list "upgrage_time" in player_vars which has times to
131  // upgrade
132
133  int points=i4_f_to_i(kill_ratio());
134   
135  li_object *l = li_get_value(li_upgrade_kill_ratio.get());
136   
137  while (l)
138  {
139    int required_number = li_int::get(li_car(l,0),0)->value();
140     
141    if (required_number<=points)   // do we have enough kills for this level
142      supertank_upgrade_level++;
143     
144    l = li_cdr(l,0); // next item in list
145  }
146   
147  if (supertank_upgrade_level<0)
148    supertank_upgrade_level=0;
149}
150
151
152   
153static w32 convert_color_to_player(w32 player_number, i4_color color,
154                                   const i4_pixel_format *fmt)
155{
156  sw32 r,g,b;
157  r=(color>>16)&0xff;
158  g=(color>>8)&0xff;
159  b=(color>>0)&0xff;
160
161  r=i4_f_to_i(g1_player_tint_data[player_number].r * r);
162  if (r>255) r=255;
163
164  g=i4_f_to_i(g1_player_tint_data[player_number].g * g);
165  if (g>255) g=255;
166
167  b=i4_f_to_i(g1_player_tint_data[player_number].b * b);
168  if (b>255) b=255;
169
170
171  return (r<<16)|(g<<8)|b;
172}
173
174
175g1_player_manager_class::g1_player_manager_class()
176{
177}
178
179void g1_player_info_class::init_colors(w32 player_num, const i4_pixel_format *fmt)
180{
181  map_player_building=convert_color_to_player(player_num, 0x404040, fmt);
182  map_player_color=convert_color_to_player(player_num, 0xffffff, fmt);
183  map_attacking_player_color=convert_color_to_player(player_num, 0xdcdcdc ,fmt);
184  map_select_player_color=(200<<16) | (200<<8) | 0;
185}
186
187void g1_player_info_class::new_game(g1_player_type num)
188{
189  player_num = num; 
190  supertank_upgrade_level = 0;
191  if (num==1)
192    team=G1_ALLY;
193  else
194    team=G1_ENEMY;
195}
196
197void g1_player_info_class::set_ai(g1_team_api_class *_ai)
198{
199  if (ai)
200    delete ai;
201
202  ai = _ai;
203  if (ai)
204    ai->player = this;
205}
206
207
208i4_profile_class pf_player_info_class_ai_think("player_info:: ai->think()");
209
210void g1_player_info_class::add_points(int points)
211{
212  num_points()+=points;
213  calc_upgrade_level();
214}
215
216void g1_player_info_class::supertank_died(g1_object_class *guy_who_killed_him)
217{
218  num_stank_deaths()++;
219  calc_upgrade_level();
220}
221
222void g1_player_info_class::think()
223{
224  li_class_context vars_context(li_class::get(vars.get(),0));
225
226  pf_player_info_class_ai_think.start();
227  if (ai)
228  {
229    ai->think();
230    ai->post_think();
231  }
232  pf_player_info_class_ai_think.stop();
233
234  li_money() += li_income_rate();
235
236  if (li_money() > 99999)
237    li_money() = 99999;
238  else if (li_money() < 0)
239    li_money() = 0;
240
241  if (g1_border.get())
242    g1_border->update();
243}
244
245
246i4_bool g1_player_info_class::load(g1_loader_class *fp)
247
248  w16 ver=0,data_size;
249  i4_bool ret=i4_F;
250  vars=0;
251  continue_wait=i4_F;
252
253  if (fp)
254    fp->get_version(ver, data_size);
255
256  if (!ai) i4_error("no ai in player_info load");
257  ai->init();
258
259  ret = i4_T;
260  switch (ver)
261  {
262    case DATA_VERSION:
263      vars=li_class::get(li_load_typed_object("player_vars", fp, fp->li_remap,0),0);
264      ai->load(fp);
265      break;
266    case DATA_VERSION3:
267      vars=li_class::get(li_load_typed_object("player_vars", fp, fp->li_remap,0),0);
268      break;
269    default:
270      if (fp)
271        fp->seek(fp->tell() + data_size);
272      ret = i4_F;
273      break;
274  }
275 
276  if (!vars.get())
277    vars=li_class::get(li_new("player_vars"), 0);
278
279  li_class_context c(get_vars());
280  team_flag.set_name(li_team_flag());
281
282  return ret;
283}
284
285void g1_player_info_class::save(g1_saver_class *fp)
286{
287  fp->start_version(DATA_VERSION);   
288  li_save_object(fp, vars.get(), 0);
289  ai->save(fp);
290  fp->end_version();
291}
292
293//(OLI) temporary hack to allow DLL reloading of AI
294//{{{
295extern void (*g1_reload_dll)(void);
296
297void reload_ais()
298{
299  i4_dll_man.load(i4_const_str("ai_joe.dll"), i4_T);
300}
301//}}}
302
303void g1_player_manager_class::set_default_ai(const char *name)
304{
305  default_ai=name;
306
307  if (default_ai)
308    for (w32 i=0; i<G1_MAX_PLAYERS; i++)
309    {
310      if (list[i] && !list[i]->get_ai())
311        list[i]->set_ai(g1_create_ai(default_ai));
312    }
313}
314
315void g1_player_manager_class::init()
316{
317  for (w32 i=0; i<G1_MAX_PLAYERS; i++)
318  {
319    list[i] = new g1_player_info_class();
320    list[i]->new_game(i);
321  }
322
323  local_player=1;  //(OLI) this needs to be changed to the appropriate number
324
325  list[local_player]->set_ai(g1_create_ai("human"));
326
327  if (default_ai)
328    for (w32 i=0; i<G1_MAX_PLAYERS; i++)
329    {
330      if (list[i] && !list[i]->get_ai())
331        list[i]->set_ai(g1_create_ai(default_ai));
332    }
333
334  //(OLI)
335  g1_reload_dll = reload_ais;
336}
337
338void g1_player_manager_class::uninit()
339{
340
341  for (w32 i=0; i<G1_MAX_PLAYERS; i++)
342  {
343    if (list[i])
344    {
345      list[i]->set_ai(0);
346      delete list[i];
347    }
348    list[i]=0;
349  }
350}
351
352void g1_player_manager_class::unload_ai(g1_team_api_definition_class *definer)
353{
354  for (int i=0; i<G1_MAX_PLAYERS; i++)
355    if (g1_player_man.get(i) &&
356        g1_player_man.get(i)->get_ai() &&
357        g1_player_man.get(i)->get_ai()->definer() == definer)
358      g1_player_man.get(i)->set_ai(0);
359}
360
361void g1_player_manager_class::init_colors(const i4_pixel_format *fmt,
362                                          r1_render_api_class *api)
363{
364  g1_init_color_tints(api);
365  for (w32 i=0; i<G1_MAX_PLAYERS; i++)
366    list[i]->init_colors(i, fmt);
367}
368
369li_object *g1_set_default_ai(li_object *o, li_environment *env)
370{
371  g1_player_man.set_default_ai(li_string::get(li_car(o,0),0)->value());
372  return 0;
373}
374
375li_automatic_add_function(g1_set_default_ai, "set_default_ai");
376
377
378
Note: See TracBrowser for help on using the repository browser.