source: golgotha/src/golg/g1_object.hh @ 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: 16.4 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// Golgatha Generic game object class
10//
11// The g1_object_class is the base type for all non-building/ground objects in the game.
12
13
14#ifndef G1_OBJECT_HH
15#define G1_OBJECT_HH
16
17#include "arch.hh"
18#include "math/num_type.hh"
19#include "g1_limits.hh"
20#include "math/transform.hh"
21#include "image/context.hh"
22
23#include "obj3d.hh"
24#include "reference.hh"
25#include "draw_context.hh"
26#include "error/error.hh"
27#include "player_type.hh"
28#include "objs/model_id.hh"
29#include "objs/model_draw.hh"
30#include "range.hh"
31#include "global_id.hh"
32
33
34class g1_loader_class;
35class g1_saver_class;
36class g1_poly_list;
37class g1_saver_class;
38class g1_loader_class;
39class i4_graphical_style_class;
40class i4_event_handler_class;         // defined in device/device.hh
41class li_object;
42class li_symbol;
43class li_environment;
44class li_class;
45class g1_object_definition_class;
46class g1_screen_box;
47struct g1_object_defaults_struct;     // objs/defaults.hh
48class g1_damage_map_struct;            // objs/defaults.hh
49struct g1_team_icon_ref;
50class g1_player_piece_class;
51
52//g1_mini_object stuff
53class g1_mini_object
54{
55public:
56  void draw(g1_draw_context_class *context,
57            i4_transform_class *transform,
58            g1_screen_box *bound_box,
59            g1_player_type player,
60            i4_transform_class *use_this_transform=0, //if you want to supply a local space transform
61            i4_bool pass_world_space_transform=i4_T,  // if you don't want lighting pass i4_F
62            i4_bool use_lod_model=i4_F);
63           
64  i4_3d_vector offset;       // tells where the center of mini_object model is (where to rotate)
65  i4_3d_vector loffset;
66
67  i4_float x,y;              // location in game map in game coordinates
68  i4_float lx,ly;            // last tick position (use to interpolate frames)
69       
70  i4_float h;                // height above (or below ground)
71  i4_float lh;               // last tick height
72
73  i4_3d_vector rotation;     // contains rotation information
74  i4_3d_vector lrotation;
75 
76  g1_model_id_type defmodeltype; //model used by this mini object. can be overridden with draw()
77  g1_model_id_type lod_model;
78
79  w16 frame;          // current animation frame
80  w16 animation;      // current animation number in model
81 
82  void calc_transform(i4_float ratio, i4_transform_class *trans);
83  // calculates transform to parent system
84
85  void position(const i4_3d_vector &pos) { lx=x=pos.x; ly=y=pos.y; lh=h=pos.z; }
86 
87  void grab_old()
88  //be sure this is called by any parent object grab_old()'s
89  {
90    lx=x;
91    ly=y;
92    lh=h;
93    lrotation = rotation;   
94    loffset = offset;
95  }
96};
97
98
99
100class g1_object_chain_class
101{
102public:
103  g1_object_class       *object;
104  g1_object_chain_class *next;
105  w16 offset;
106
107  inline g1_object_chain_class *next_solid();  // defined after g1_object_class
108  g1_object_chain_class *next_non_solid() { return next; } 
109};
110
111
112enum g1_radar_type
113{
114  G1_RADAR_NONE,
115  G1_RADAR_VEHICLE,
116  G1_RADAR_STANK,
117  G1_RADAR_WEAPON,
118  G1_RADAR_BUILDING,
119  G1_RADAR_PATH_OBJECT
120};
121
122
123typedef sw16 g1_object_type;
124
125class g1_object_class
126{
127protected:
128  friend class g1_reference_class;
129  friend class g1_map_class;
130  friend class g1_map_cell_class;
131  friend class g1_remove_manager_class;
132
133  void load_v2(g1_loader_class *fp);
134  void load_v3(g1_loader_class *fp);
135  void load_v4(g1_loader_class *fp);
136  void load_v5(g1_loader_class *fp);
137  void load_v6(g1_loader_class *fp);
138  void load_v7(g1_loader_class *fp);
139  void load_v8(g1_loader_class *fp);
140  void load_v9(g1_loader_class *fp);
141
142  // a list of all objects that reference us, so we can remove the reference when we delete ourself
143  i4_isl_list<g1_reference_class> ref_list;
144 
145  // list of squares this object is on (max of 4), if value is 0xffff then it is not a reference
146  // the last one holds the center of the object, if necessary (ie, the object takes
147  // up more than 1 square and his corners are far enough apart)
148  i4_array<g1_object_chain_class> occupied_squares;
149
150  g1_object_chain_class *new_occupied_square()
151  {
152    g1_object_chain_class *ret = occupied_squares.add();
153    ret->object = this;
154    return ret;
155  }
156
157  i4_bool occupy_location_model(const g1_model_draw_parameters& draw_params);
158  i4_bool occupy_location_corners();
159  i4_bool occupy_location_center();     // only adds the center of the object
160  i4_bool occupy_location_model_extents(const g1_model_draw_parameters &draw_params);
161public:
162
163  // generic type flags for run time object caster, defaults to can't cast
164  enum
165  {
166    TO_MAP_PIECE      = (1<<0),
167    TO_PLAYER_PIECE   = (1<<1),
168    TO_DYNAMIC_OBJECT = (1<<2),
169    TO_PATH_OBJECT    = (1<<3),
170    TO_DECO_OBJECT    = (1<<4),
171  };
172
173  virtual w32 private_safe_to_cast() const { return 0; }
174
175  w32 global_id;                // unique to the object, used to reference via networking
176
177  g1_object_type id;            // this is the object's 'type' id
178
179  i4_float x,y;                 // location in game map in game coordinates
180  i4_float lx,ly;               // last tick position (use to interpolate frames)
181
182  i4_float h;                   // height above (or below ground)
183  i4_float lh;                  // last tick height
184
185  i4_float theta;               // facing direction in the x-y game plane
186  i4_float ltheta;              // last tick theta (yaw)
187
188  i4_float pitch;               // pitch (y-z)
189  i4_float lpitch;              // last tick pitch
190
191  i4_float roll;                // roll (x-z)
192  i4_float lroll;               // last tick roll
193
194  sw16 health;                  // the health its got left
195
196  li_class *vars;               // lisp variables used for dialog's.  These load and save automatically.
197
198  g1_player_type player_num;
199  g1_radar_type radar_type;
200  g1_team_icon_ref *radar_image;
201
202
203  virtual void change_player_num(int new_player_num);  // don't change player_num directly
204  virtual g1_team_type get_team() const;
205 
206  enum flag_type
207  {
208    SELECTED      =1<<0,   // if object has been selected by player
209    THINKING      =1<<1,   // if object is in a level's think list
210 
211    SHADOWED      =1<<2,   // if object should have shadows drawn for it
212    MAP_INVISIBLE =1<<3,   // if object is invisible
213    DELETED       =1<<4,   // if object has been removed, but remove has not been processed yet
214    IN_TUNNEL     =1<<5,   // if the object is in a tunnel
215
216    SELECTABLE    =1<<6,   // if the user can select the object in the game
217    TARGETABLE    =1<<7,   // if object can be attacked
218
219    GROUND        =1<<8,
220    UNDERWATER    =1<<9,
221    AERIAL        =1<<10,
222
223    HIT_GROUND    =1<<11,
224    HIT_UNDERWATER=1<<12,
225    HIT_AERIAL    =1<<13,  // can attack objects in the air
226
227    BLOCKING      =1<<14,  // if object blocks passage of other objects
228
229    SCRATCH_BIT   =1<<15,  // use this for temporary calculations, but set it back to 0 when done
230    MAP_OCCUPIED  =1<<16,  // makes sure you don't call occupy_location/unoccupy_location twice
231   
232    DANGEROUS     =1<<17,  // object should be killed
233
234    RADAR_REMOVE  =1<<18,  // object needs to be removed from radar
235    CAN_DRIVE_ON  =1<<19,  // if objects can drive over / stand on you
236    ON_WATER      =1<<20,  // if objects is on water
237  };
238
239  enum { SAVE_FLAGS= SELECTED | THINKING };
240
241  w32 flags;
242  int get_flag(int x) const { return flags & x; }
243  void set_flag(int x, int value) { if (value) flags|=x; else flags&=(~x); } 
244  i4_bool selected() const { return flags & SELECTED; }
245  i4_bool out_of_bounds(i4_float x, i4_float y) const;
246  i4_bool moved() const { return (lx!=x || ly!=y); }
247  i4_bool valid() const { return get_flag(MAP_OCCUPIED)!=0; }
248
249  g1_object_definition_class *get_type();     // inlined below
250
251  virtual void mark_as_selected(); 
252  virtual void mark_as_unselected();
253
254  virtual i4_float occupancy_radius() const;
255
256  // called when the object is on a map cell that is about to be drawn
257  virtual void predraw() {}
258
259  // called when the object is on a map cell that is drawn
260  virtual void draw(g1_draw_context_class *context);
261
262  // called for each object after everything else has been drawn and in editor mode
263  virtual void editor_draw(g1_draw_context_class *context);
264
265  virtual void note_stank_near(g1_player_piece_class *s) { ; }
266
267  // called every game tick
268  virtual void think() = 0;
269  virtual void post_think() {;}
270
271  g1_object_class(g1_object_type id, g1_loader_class *fp);
272  virtual void validate() {}
273  virtual void save(g1_saver_class *fp);
274
275  void request_think();
276  virtual void request_remove();
277
278  // call to add object to a map (adds to cell x,y where object is standing)
279  virtual i4_bool occupy_location();
280
281  // call to remove an object from a map
282  virtual void unoccupy_location();
283
284  virtual i4_bool deploy_to(float x, float y) { return i4_F; }
285
286  virtual void damage(g1_object_class *who_is_hurting,
287                      int how_much_hurt, i4_3d_vector damage_dir);
288
289  virtual i4_bool check_collision(const i4_3d_vector &start,
290                                  i4_3d_vector &ray);
291
292  enum {NOTIFY_DAMAGE_KILLED=1};
293
294  virtual void notify_damage(g1_object_class *obj, sw32 hp) {}
295 
296  virtual void calc_world_transform(i4_float ratio, i4_transform_class *transform=0);
297  // calculates the transform from object coordinates to the world and stores it in
298  //   'transform'.  if transform is null, it stores it into the object's internal storage
299
300  i4_transform_class *world_transform; //calculated and linearly allocated at draw time
301
302  g1_model_draw_parameters draw_params;
303  g1_mini_object *mini_objects;
304  w16 num_mini_objects;
305
306  void allocate_mini_objects(int num,char *reason)
307  {
308    mini_objects = (g1_mini_object *)i4_malloc(sizeof(g1_mini_object)*num,reason);
309    memset(mini_objects,0,sizeof(g1_mini_object) * num);
310    num_mini_objects = num;
311  }
312
313  virtual void grab_old();     // grab info about the current tick for interpolation
314
315  //  to be consistant, every g1_object should have an init
316  virtual void init()  {}
317
318  // show in editor if mouse cursor stays still on object
319  virtual i4_str *get_context_string(); 
320
321  virtual ~g1_object_class();
322
323  virtual i4_bool can_attack(g1_object_class *who) const { return i4_F; }
324
325  virtual void stop_thinking();
326
327  float height_above_ground();      // calls map->terrain_height
328
329  const char *name() const;
330 
331  virtual li_object *message(li_symbol *message_name,
332                             li_object *message_params,
333                             li_environment *env) { return 0; }
334
335  // called for every object when you click 'ok' in the vars edit dialog for an object
336  virtual void object_changed_by_editor(g1_object_class *who, li_class *old_values) {}
337  virtual int get_chunk_names(char **&list) { return 0; }
338};
339
340
341inline g1_object_chain_class *g1_object_chain_class::next_solid()
342{
343  if (!next || !next->object->get_flag(g1_object_class::BLOCKING))
344    return 0;
345  else return next;
346}
347
348
349enum eBuildError
350{
351  G1_BUILD_OK=0,                       // successful build
352  G1_BUILD_WAIT,                       // needs more time to build
353  G1_BUILD_TOO_EXPENSIVE,              // needs more money to build
354  G1_BUILD_OCCUPIED,                   // space to build is occupied
355  G1_BUILD_NO_SPACE,                   // no space to build
356  G1_BUILD_INVALID_OBJECT,             // invalid object or object parameters
357  G1_BUILD_ALREADY_EXISTS,             // unique object already exists
358  G1_BUILD_PLAYBACK,                   // playback in progress, can't build manually
359};
360
361class g1_object_definition_class;
362
363// this is the call to add a new object_type to the game.
364g1_object_type g1_add_object_type(g1_object_definition_class *def);
365
366// this is the call to find the object_type of a specified object
367g1_object_type g1_get_object_type(const char *name);
368g1_object_type g1_get_object_type(li_symbol *name);
369
370// remove probably doesn't need to used during a normal game, but can be useful for
371// adding and removing a dll during a running session instead of restarting the game
372void g1_remove_object_type(g1_object_type type);
373
374
375// this class defines an object to golgotha, primarly how to create such an object and
376// load it from disk.  The object then has virtual functions that allow it do things like
377// think, save, and draw.  Objects can be created at anytime in the game, and should be
378// able to linked in through dlls.
379class g1_object_definition_class
380{
381protected:
382  typedef void (*function_type)(void);
383  char *_name;
384  function_type init_function, uninit_function;
385 
386  g1_damage_map_struct          *damage;     // loaded from scheme/balance.scm
387
388public:
389  enum
390  {
391    EDITOR_SELECTABLE = (1<<0),      // object shows up in editor
392    DELETE_WITH_LEVEL = (1<<1),      // delete this type with the map
393    MOVABLE           = (1<<2),      // objects
394    TO_MAP_PIECE      = (1<<3),
395    TO_PLAYER_PIECE   = (1<<4),
396    TO_DYNAMIC_OBJECT = (1<<5),
397    TO_PATH_OBJECT    = (1<<6),
398    TO_DECO_OBJECT    = (1<<7),
399    HAS_ALPHA         = (1<<8)      // if object has alpha polys it will draw after non-alpha objects
400  };
401
402 
403  w32                        var_class;   // class type to create for object's vars
404  li_class                   *vars;       // variables specific to the type
405  g1_object_defaults_struct  *defaults;   // loaded from scheme/balance.scm
406 
407  g1_damage_map_struct        *get_damage_map();
408 
409  w32 flags;
410  int get_flag(int x) const { return flags & x; }
411  void set_flag(int x, int value) { if (value) flags|=x; else flags&=(~x); } 
412
413  g1_object_type type;
414
415  g1_object_definition_class(char *_name,
416                             w32 type_flags = EDITOR_SELECTABLE,
417                             function_type _init = 0,
418                             function_type _uninit = 0);
419
420  virtual ~g1_object_definition_class() { g1_remove_object_type(type); }
421
422  // create_object should return a new initialized instance of an object, if fp is null then
423  // default values should be supplied, otherwise the object should load itself from the file
424  virtual g1_object_class *create_object(g1_object_type id,
425                                         g1_loader_class *fp) = 0;
426
427  // the name on an object should be unique, so you might want to be creative,  the name
428  // is used to match up the object types in save files since object type id's are dynamically
429  // created
430  const char *name() { return _name; }
431
432  i4_bool editor_selectable() { return flags & EDITOR_SELECTABLE; }
433
434  virtual void init();
435  virtual void uninit() { if (uninit_function) (*uninit_function)();}
436 
437  virtual void save(g1_saver_class *fp) { ; }  // save info about type
438  virtual void load(g1_loader_class *fp) { ; } // load info about type
439
440  // this is called when the object is right-clicked, the dialog is added to a draggable frame
441  virtual i4_window_class *create_edit_dialog();
442
443};
444
445void g1_apply_damage(g1_object_class *kinda_gun_being_used,
446                     g1_object_class *who_pulled_the_trigger,
447                     g1_object_class *whos_on_the_wrong_side_of_the_gun,
448                     const i4_3d_vector &direction_hurten_is_commin_from);
449
450// increase this number if you change the load/save structure of g1_object_class
451#define G1_OBJECT_FORMAT_VERSION 1
452
453
454// this table has an array of pointers to object definitions
455// this is used by the border frame to find object with build info so it
456// can add buttons for them
457extern g1_object_definition_class *g1_object_type_array[G1_MAX_OBJECT_TYPES];
458extern g1_object_type g1_last_object_type;  // largest object number assigned
459
460// this is prefered way to create new object in the game
461inline g1_object_class *g1_create_object(g1_object_type type)
462{
463  if (g1_object_type_array[type])
464    return g1_object_type_array[type]->create_object(type, 0);
465  else
466    return 0;
467}
468
469inline g1_object_definition_class *g1_object_class::get_type() { return g1_object_type_array[id]; }
470
471void g1_initialize_loaded_objects();
472void g1_uninitialize_loaded_objects();
473
474#endif
475
476
Note: See TracBrowser for help on using the repository browser.