1 #ifdef WIN32
2 # include <windows.h>
3 #endif
4 #include <GL/glfw.h>
5
6 #include "boat.h"
7 #include "background.h"
8 #include "resources.h"
9 #include "snoutlib/mfont.h"
10 #include "snoutlib/timer.h"
11 #include "game.h"
12 #include "fx_ship_expl.h"
13
14
Boat(vec2 pos,string name,float scale)15 Boat::Boat(vec2 pos,string name,float scale) :
16 m_pos(pos),m_name(name),m_scale(scale),
17 m_pos_shift(0.0),m_rot(0.0),
18 m_damaged(false),m_sinking(false), m_obb(AABB(0,0,0,0))
19 {
20 m_model = &g_resources.mesh_tanker;
21
22 m_smoke = NULL;
23 for(int i=0;i<m_num_bubble_streams;++i)
24 m_bbl[i] = NULL;
25 }
26
~Boat()27 Boat::~Boat()
28 {
29 delete m_smoke;
30 for(int i=0;i<m_num_bubble_streams;++i)
31 delete m_bbl[i];
32 }
33
hit(float x)34 void Boat::hit(float x)
35 {
36 float hit_pos = x - m_pos[0];
37 hit_pos = clamp<float>(hit_pos,-0.15,+0.15);
38
39 if (!m_damaged) {
40 m_damaged = true;
41 m_smoke = new PE_Smoke(vec2(hit_pos,0.0));
42
43 m_hit_pos = hit_pos;
44
45 } else if (!m_sinking) {
46 m_sinking = true;
47 m_sinking_start_time = g_timer->now();
48 m_sinking_start_pos = m_pos_shift;
49 m_sinking_start_rot = m_rot;
50
51 for(int i=0;i<m_num_bubble_streams;++i) {
52 m_bbl[i] = new PE_Bubbles(vec2(0.0,0.0));
53 m_bbl_emitpos_x[i] = ((float)i/m_num_bubble_streams)+0.1-0.5 + (RAND_0_1 - 0.5)*0.175;
54 }
55 }
56
57 vec2 expl_pos = vec2(m_pos[0]+hit_pos,m_pos[1]+m_pos_shift-0.00);
58 g_current_game->add_effect(new FX_Ship_Explosion(expl_pos),0);
59 }
60
draw(void)61 void Boat::draw(void)
62 {
63 if (m_sinking) {
64 float delta_t = g_timer->now() - m_sinking_start_time;
65
66 if (delta_t>25.0) // fully sunk
67 return;
68
69 // slow start
70 if (delta_t<1.0) {
71 m_pos_shift = m_sinking_start_pos + 0.03*delta_t*delta_t;
72 m_rot = m_sinking_start_rot + m_sinking_start_rot*5.0*delta_t*delta_t;
73 } else {
74 m_pos_shift = m_sinking_start_pos + 0.05*delta_t + 0.03 - 0.05;
75 m_rot = m_sinking_start_rot + m_sinking_start_rot*5.0*delta_t;
76 }
77
78 if (delta_t>0.5)
79 m_smoke->stop_emitting();
80
81 } else {
82 m_pos_shift = Sea::sea_func(m_pos[0]-0.05f) * 0.35f; // pos
83 m_rot = Sea::sea_func(m_pos[0]) * 0.2f * 333; // rot
84 }
85
86 // draw smoke
87 if (m_damaged) {
88 m_smoke->set_pos(vec2(m_pos[0]+m_hit_pos,m_pos[1]+m_pos_shift-0.01));
89 m_smoke->update();
90 m_smoke->draw();
91 }
92
93 glPushMatrix();
94
95 glTranslatef(m_pos[0],m_pos[1]+m_pos_shift,0.0);
96 glScalef(m_scale,m_scale,1.0f);
97 glRotatef(m_rot,0,0,1);
98
99 // draw bubbles
100 if (m_sinking) {
101 mat4 mt = glGetCurrentMatrix(GL_MODELVIEW_MATRIX);
102
103 for(int i=0;i<m_num_bubble_streams;++i) {
104 vec2 pos = vec2(transformPoint(mt,vec3(m_bbl_emitpos_x[i],0.0,0.0)));
105 m_bbl[i]->set_pos(pos);
106 m_bbl[i]->update();
107 m_bbl[i]->draw();
108 }
109 }
110
111 // update boundingbox
112 m_obb = OBB((*m_model)->m_aabb);
113
114 // draw model
115 glDisable(GL_TEXTURE_2D);
116 glColor3f(0,0,0);
117 (*m_model)->draw();
118
119 // draw name
120 float text_scale = 0.8f;
121 float text_pos = 0.4f - g_resources.font->size_of_text(m_name.c_str(),text_scale);
122 g_resources.font->print_text(m_name.c_str(),vec2(text_pos,0.0),text_scale,false,vec4(1.0f,1.0f,1.0f,1.0f));
123
124 glPopMatrix();
125 }
126
is_sinking(void)127 bool Boat::is_sinking(void)
128 {
129 return m_sinking;
130 }
131
is_alive(void)132 bool Boat::is_alive(void)
133 {
134 return !m_sinking;
135 }
136