[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 "sound_man.hh"
|
---|
| 10 | #include "objs/model_id.hh"
|
---|
| 11 | #include "objs/model_draw.hh"
|
---|
| 12 | #include "input.hh"
|
---|
| 13 | #include "math/pi.hh"
|
---|
| 14 | #include "math/angle.hh"
|
---|
| 15 | #include "math/trig.hh"
|
---|
| 16 | #include "g1_rand.hh"
|
---|
| 17 | #include "resources.hh"
|
---|
| 18 | #include "saver.hh"
|
---|
| 19 | #include "map_cell.hh"
|
---|
| 20 | #include "map.hh"
|
---|
| 21 | #include "map_man.hh"
|
---|
| 22 | #include "object_definer.hh"
|
---|
| 23 | #include "lisp/lisp.hh"
|
---|
| 24 | #include "objs/fire.hh"
|
---|
| 25 |
|
---|
| 26 | #include "sound/sound.hh"
|
---|
| 27 | #include "objs/map_piece.hh"
|
---|
| 28 |
|
---|
| 29 | #include "image_man.hh"
|
---|
| 30 | #include "player.hh"
|
---|
| 31 |
|
---|
| 32 | static g1_team_icon_ref radar_im("bitmaps/radar/tower_missile.tga");
|
---|
| 33 |
|
---|
| 34 | enum {DATA_VERSION=1};
|
---|
| 35 |
|
---|
| 36 | static g1_model_ref model_ref("tower_missile_base"),
|
---|
| 37 | launcher_ref("tower_missile_launcher"),
|
---|
| 38 | bottom_ref("tower_missile_bottom");
|
---|
| 39 |
|
---|
| 40 | static i4_3d_vector launcher_attach, launcher_offset, launch;
|
---|
| 41 |
|
---|
| 42 | S1_SFX(tower_secured, "narrative/turret_captured_22khz.wav", S1_STREAMED, 200);
|
---|
| 43 | S1_SFX(tower_lost, "narrative/turret_lost_22khz.wav", S1_STREAMED, 200);
|
---|
| 44 |
|
---|
| 45 | void g1_tower_missile_init()
|
---|
| 46 | {
|
---|
| 47 | launcher_attach.set(0,0,0);
|
---|
| 48 | model_ref()->get_mount_point("Mount", launcher_attach);
|
---|
| 49 |
|
---|
| 50 | launcher_offset.set(0,0,0);
|
---|
| 51 | launcher_ref()->get_mount_point("Mount", launcher_offset);
|
---|
| 52 | launcher_offset.reverse();
|
---|
| 53 |
|
---|
| 54 | launch.set(0,1.0,0);
|
---|
| 55 | launcher_ref()->get_mount_point("Missiles", launch);
|
---|
| 56 | }
|
---|
| 57 |
|
---|
| 58 | class g1_tower_missile_class : public g1_map_piece_class
|
---|
| 59 | {
|
---|
| 60 | protected:
|
---|
| 61 | g1_mini_object *launcher,*bottom;
|
---|
| 62 | i4_float guard_angle, guard_pitch;
|
---|
| 63 | int guard_time;
|
---|
| 64 | int missiles;
|
---|
| 65 | public:
|
---|
| 66 | g1_tower_missile_class(g1_object_type id, g1_loader_class *fp)
|
---|
| 67 | //{{{
|
---|
| 68 | : g1_map_piece_class(id,fp)
|
---|
| 69 | {
|
---|
| 70 | defaults = get_type()->defaults;
|
---|
| 71 | draw_params.setup(model_ref.id());
|
---|
| 72 |
|
---|
| 73 | allocate_mini_objects(2,"tower_missile mini objects");
|
---|
| 74 |
|
---|
| 75 | launcher = &mini_objects[0];
|
---|
| 76 | launcher->defmodeltype = launcher_ref.id();
|
---|
| 77 | launcher->position(launcher_attach);
|
---|
| 78 | launcher->offset = launcher_offset;
|
---|
| 79 | launcher->grab_old();
|
---|
| 80 |
|
---|
| 81 | bottom = &mini_objects[1];
|
---|
| 82 | bottom->defmodeltype = bottom_ref.id();
|
---|
| 83 | bottom->grab_old();
|
---|
| 84 |
|
---|
| 85 | fire_delay = 0;
|
---|
| 86 | guard_angle = 0;
|
---|
| 87 | guard_pitch = 0;
|
---|
| 88 | guard_time = 0;
|
---|
| 89 | missiles = 6;
|
---|
| 90 |
|
---|
| 91 | radar_type=G1_RADAR_BUILDING;
|
---|
| 92 | radar_image=&radar_im;
|
---|
| 93 | set_flag(BLOCKING |
|
---|
| 94 | SELECTABLE |
|
---|
| 95 | TARGETABLE |
|
---|
| 96 | GROUND |
|
---|
| 97 | HIT_GROUND |
|
---|
| 98 | HIT_AERIAL |
|
---|
| 99 | DANGEROUS, 1);
|
---|
| 100 | }
|
---|
| 101 | //}}}
|
---|
| 102 |
|
---|
| 103 | virtual void save(g1_saver_class *fp)
|
---|
| 104 | //{{{
|
---|
| 105 | {
|
---|
| 106 | g1_map_piece_class::save(fp);
|
---|
| 107 | }
|
---|
| 108 | //}}}
|
---|
| 109 |
|
---|
| 110 | virtual void fire()
|
---|
| 111 | //{{{
|
---|
| 112 | {
|
---|
| 113 | if (missiles==0)
|
---|
| 114 | return;
|
---|
| 115 |
|
---|
| 116 | fire_delay = defaults->fire_delay;
|
---|
| 117 |
|
---|
| 118 | missiles--;
|
---|
| 119 |
|
---|
| 120 | i4_3d_point_class p, pos, dir;
|
---|
| 121 |
|
---|
| 122 | i4_transform_class t, main, l2w;
|
---|
| 123 | launcher->calc_transform(1.0, &t);
|
---|
| 124 | calc_world_transform(1.0, &main);
|
---|
| 125 | l2w.multiply(main, t);
|
---|
| 126 |
|
---|
| 127 | static i4_float px[] = { 0, -0.05, +0.05, -0.05, +0.05, 0 };
|
---|
| 128 | static i4_float py[] = { -0.03, +0.03, +0.03, -0.03, -0.03, +0.03 };
|
---|
| 129 |
|
---|
| 130 | p = launch;
|
---|
| 131 | p.x += px[missiles];
|
---|
| 132 | p.y += py[missiles];
|
---|
| 133 |
|
---|
| 134 | l2w.transform(p,pos);
|
---|
| 135 | l2w.transform_3x3(i4_3d_point_class(0.4,px[missiles],py[missiles]),dir);
|
---|
| 136 |
|
---|
| 137 | g1_fire(defaults->fire_type, this, attack_target.get(), pos, dir);
|
---|
| 138 | }
|
---|
| 139 | //}}}
|
---|
| 140 |
|
---|
| 141 | virtual void change_player_num(int new_player_num)
|
---|
| 142 | //{{{
|
---|
| 143 | {
|
---|
| 144 | if (new_player_num==g1_player_man.local_player)
|
---|
| 145 | tower_secured.play();
|
---|
| 146 |
|
---|
| 147 | if (player_num==g1_player_man.local_player)
|
---|
| 148 | tower_lost.play();
|
---|
| 149 |
|
---|
| 150 | g1_object_class::change_player_num(new_player_num);
|
---|
| 151 | if (health<defaults->health)
|
---|
| 152 | health += defaults->health;
|
---|
| 153 | set_flag(DANGEROUS,1);
|
---|
| 154 | request_think();
|
---|
| 155 | }
|
---|
| 156 | //}}}
|
---|
| 157 |
|
---|
| 158 | virtual void think()
|
---|
| 159 | //{{{
|
---|
| 160 | {
|
---|
| 161 | if (health<=1)
|
---|
| 162 | return;
|
---|
| 163 |
|
---|
| 164 | find_target();
|
---|
| 165 |
|
---|
| 166 | if (fire_delay>0)
|
---|
| 167 | {
|
---|
| 168 | fire_delay--;
|
---|
| 169 | if (fire_delay==0)
|
---|
| 170 | missiles = 6;
|
---|
| 171 | }
|
---|
| 172 |
|
---|
| 173 | pitch = 0;//groundpitch*cos(theta) - groundroll *sin(theta);
|
---|
| 174 | roll = 0;//groundroll *cos(theta) + groundpitch*sin(theta);
|
---|
| 175 | h = terrain_height;
|
---|
| 176 |
|
---|
| 177 | //aim the turet
|
---|
| 178 | if (attack_target.valid())
|
---|
| 179 | {
|
---|
| 180 | request_think();
|
---|
| 181 |
|
---|
| 182 | i4_3d_point_class d,pos;
|
---|
| 183 |
|
---|
| 184 | lead_target(d);
|
---|
| 185 |
|
---|
| 186 | pos.set(x,y,h+launcher_attach.z);
|
---|
| 187 | d -= pos;
|
---|
| 188 |
|
---|
| 189 | //aim the turet
|
---|
| 190 |
|
---|
| 191 | guard_angle = i4_atan2(d.y,d.x);
|
---|
| 192 | guard_pitch = i4_atan2(-d.z,sqrt(d.x*d.x+d.y*d.y));
|
---|
| 193 |
|
---|
| 194 | i4_normalize_angle(guard_angle);
|
---|
| 195 | i4_normalize_angle(guard_pitch);
|
---|
| 196 |
|
---|
| 197 | int aimed=i4_F;
|
---|
| 198 | i4_float dangle;
|
---|
| 199 |
|
---|
| 200 | dangle = i4_rotate_to(theta,guard_angle,defaults->turn_speed);
|
---|
| 201 | aimed = (dangle<defaults->turn_speed && dangle>-defaults->turn_speed);
|
---|
| 202 | bottom->rotation.z = -theta;
|
---|
| 203 | dangle = i4_rotate_to(launcher->rotation.y,guard_pitch,defaults->turn_speed);
|
---|
| 204 | aimed &= (dangle<defaults->turn_speed && dangle>-defaults->turn_speed);
|
---|
| 205 | if (aimed)
|
---|
| 206 | fire();
|
---|
| 207 | guard_time = 30;
|
---|
| 208 | }
|
---|
| 209 | else
|
---|
| 210 | {
|
---|
| 211 | request_think(); // move this to draw function
|
---|
| 212 |
|
---|
| 213 | if (guard_time<=0)
|
---|
| 214 | {
|
---|
| 215 | guard_angle = g1_float_rand(1)*i4_2pi();
|
---|
| 216 | guard_pitch = (-g1_float_rand(2)*0.5 + 0.25)*i4_pi();
|
---|
| 217 | i4_normalize_angle(guard_pitch);
|
---|
| 218 | guard_time = 20;
|
---|
| 219 | }
|
---|
| 220 |
|
---|
| 221 | int aimed;
|
---|
| 222 |
|
---|
| 223 | aimed = (i4_rotate_to(theta,guard_angle,defaults->turn_speed)==0.0);
|
---|
| 224 | bottom->rotation.z = -theta;
|
---|
| 225 | aimed &= (i4_rotate_to(launcher->rotation.y,guard_pitch,defaults->turn_speed)==0.0);
|
---|
| 226 | if (aimed)
|
---|
| 227 | if (guard_time>0)
|
---|
| 228 | guard_time--;
|
---|
| 229 | }
|
---|
| 230 | }
|
---|
| 231 | //}}}
|
---|
| 232 |
|
---|
| 233 | virtual i4_bool check_collision(const i4_3d_vector &start, i4_3d_vector &ray)
|
---|
| 234 | //{{{
|
---|
| 235 | {
|
---|
| 236 | i4_3d_vector normal;
|
---|
| 237 | return g1_model_collide_polygonal(this, draw_params, start, ray, normal);
|
---|
| 238 | }
|
---|
| 239 | //}}}
|
---|
| 240 |
|
---|
| 241 | virtual void damage(g1_object_class *obj, int hp, i4_3d_vector _damage_dir)
|
---|
| 242 | //{{{
|
---|
| 243 | {
|
---|
| 244 | health -= hp;
|
---|
| 245 | if (health<1)
|
---|
| 246 | {
|
---|
| 247 | health=1;
|
---|
| 248 | set_flag(DANGEROUS,0);
|
---|
| 249 | }
|
---|
| 250 | request_think();
|
---|
| 251 | }
|
---|
| 252 | //}}}
|
---|
| 253 | };
|
---|
| 254 |
|
---|
| 255 | g1_object_definer<g1_tower_missile_class>
|
---|
| 256 | g1_tower_missile_def("tower_missile", g1_object_definition_class::EDITOR_SELECTABLE,
|
---|
| 257 | g1_tower_missile_init);
|
---|
| 258 |
|
---|
| 259 | //{{{ Emacs Locals
|
---|
| 260 | // Local Variables:
|
---|
| 261 | // folded-file: t
|
---|
| 262 | // End:
|
---|
| 263 | //}}}
|
---|