miscobjs.cc 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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. #include "g1_object.hh"
  9. #include "saver.hh"
  10. #include "objs/model_draw.hh"
  11. #include "objs/model_collide.hh"
  12. #include "map.hh"
  13. #include "map_man.hh"
  14. #include "objs/shrapnel.hh"
  15. #include "math/random.hh"
  16. #include "objs/miscobjs.hh"
  17. class g1_deco_definition_class;
  18. g1_deco_type_manager_class g1_deco_type_manager;
  19. static g1_object_type shrapnel_type=0;
  20. g1_deco_object_class::g1_deco_object_class(g1_object_type id, g1_loader_class *fp)
  21. : g1_object_class(id, fp), death(this)
  22. {
  23. model_name=0;
  24. health=100;
  25. if (fp)
  26. {
  27. w16 ver,data_size;
  28. fp->get_version(ver,data_size);
  29. switch (ver)
  30. {
  31. case 2 :
  32. health=fp->read_16();
  33. case 1 :
  34. char buf[1024];
  35. int len=fp->read_16();
  36. fp->read(buf, len);
  37. model_name=g1_deco_type_manager.find_name(buf);
  38. if (model_name)
  39. {
  40. char lod_name[256];
  41. sprintf(lod_name, "%s_lod", model_name);
  42. draw_params.setup(model_name, 0, lod_name);
  43. }
  44. }
  45. fp->end_version(I4_LF);
  46. }
  47. collision_type = 1;
  48. player_num=G1_MAX_PLAYERS-1;
  49. set_flag(BLOCKING |
  50. SELECTABLE |
  51. CAN_DRIVE_ON |
  52. TARGETABLE |
  53. GROUND |
  54. SHADOWED,
  55. 1);
  56. }
  57. void g1_deco_object_class::save(g1_saver_class *fp)
  58. {
  59. g1_object_class::save(fp);
  60. fp->start_version(DATA_VERSION);
  61. fp->write_16(health);
  62. if (model_name)
  63. {
  64. int len=strlen(model_name)+1;
  65. fp->write_16(len);
  66. fp->write((void*)model_name, len);
  67. }
  68. else fp->write_16(0);
  69. fp->end_version();
  70. }
  71. i4_bool g1_deco_object_class::check_collision(const i4_3d_vector &start, i4_3d_vector &ray)
  72. {
  73. i4_3d_vector normal;
  74. switch (collision_type)
  75. {
  76. case 0: return g1_model_collide_radial(this, draw_params, start, ray);
  77. case 1: return g1_model_collide_polygonal(this, draw_params, start, ray, normal);
  78. default: return i4_F;
  79. }
  80. i4_error("case not handled");
  81. return i4_F;
  82. }
  83. void g1_deco_object_class::think()
  84. {
  85. if (occupancy_radius()>0.8 && !death.think())
  86. return;
  87. if (model_name==0)
  88. {
  89. unoccupy_location();
  90. request_remove();
  91. }
  92. if (health<0)
  93. {
  94. g1_shrapnel_class *shrapnel = NULL;
  95. if (!shrapnel_type)
  96. shrapnel_type = g1_get_object_type("shrapnel");
  97. shrapnel = (g1_shrapnel_class *)g1_create_object(shrapnel_type);
  98. if (shrapnel)
  99. {
  100. i4_float rh = (i4_rand()&0xFFFF)/((i4_float)0xFFFF) * 0.2;
  101. shrapnel->setup(x, y, h + rh, 10, i4_T);
  102. }
  103. unoccupy_location();
  104. request_remove();
  105. }
  106. }
  107. void g1_deco_object_class::damage(g1_object_class *who_is_hurting,
  108. int how_much_hurt, i4_3d_vector damage_dir)
  109. {
  110. if (occupancy_radius()>0.8)
  111. death.damage(who_is_hurting, how_much_hurt, damage_dir);
  112. else
  113. g1_object_class::damage(who_is_hurting,how_much_hurt,damage_dir);
  114. }
  115. class g1_deco_definition_class : public g1_object_definition_class
  116. {
  117. public:
  118. char deco_name[40];
  119. g1_object_class *create_object(g1_object_type type,
  120. g1_loader_class *fp)
  121. {
  122. g1_deco_object_class *o=new g1_deco_object_class(type, fp);
  123. if (!fp)
  124. {
  125. o->model_name=_name;
  126. if (o->model_name)
  127. {
  128. char lod_name[256];
  129. sprintf(lod_name, "%s_lod", o->model_name);
  130. o->draw_params.setup(o->model_name, 0, lod_name);
  131. o->set_flag(g1_object_class::SHADOWED,1);
  132. }
  133. }
  134. o->init();
  135. return o;
  136. }
  137. g1_deco_definition_class(char *__name)
  138. : g1_object_definition_class(strcpy(deco_name, __name))
  139. {
  140. set_flag(MOVABLE,0);
  141. }
  142. ~g1_deco_definition_class()
  143. {
  144. g1_deco_type_manager.remove_type(this);
  145. }
  146. };
  147. g1_object_type g1_create_deco_object(char *name)
  148. {
  149. g1_deco_definition_class *def=new g1_deco_definition_class(name);
  150. g1_object_type t=def->type;
  151. def->flags|=g1_object_definition_class::TO_DECO_OBJECT |
  152. g1_object_definition_class::DELETE_WITH_LEVEL;
  153. g1_deco_type_manager.add_type(def);
  154. return t;
  155. }
  156. const char *g1_deco_type_manager_class::find_name(const char *name)
  157. {
  158. for (int i=0; i<deco_objs.size(); i++)
  159. {
  160. if (deco_objs[i])
  161. if (strcmp(name, deco_objs[i]->name())==0)
  162. return deco_objs[i]->name();
  163. }
  164. return 0; // this object name doesn't exsist in the game anymore
  165. }
  166. void g1_deco_type_manager_class::uninit()
  167. {
  168. deco_objs.uninit();
  169. }