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