4
Copyright (C) 2005-2010 Julien Jorge, Sebastien Angibaud
6
This program is free software; you can redistribute it and/or modify it
7
under the terms of the GNU General Public License as published by the
8
Free Software Foundation; either version 2 of the License, or (at your
9
option) any later version.
11
This program is distributed in the hope that it will be useful, but WITHOUT
12
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16
You should have received a copy of the GNU General Public License along
17
with this program; if not, write to the Free Software Foundation, Inc.,
18
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
contact: plee-the-bear@gamned.org
22
Please add the tag [PTB] in the subject of your mails.
26
* \brief Implementation of the ptb::frog class.
27
* \author S�bastien Angibaud
29
#include "ptb/item/forest/frog.hpp"
31
#include "ptb/player.hpp"
32
#include "ptb/item/floating_score.hpp"
33
#include "engine/layer/layer.hpp"
34
#include "engine/world.hpp"
35
#include "engine/export.hpp"
37
#include <claw/assert.hpp>
39
BASE_ITEM_EXPORT( frog, ptb )
42
/*----------------------------------------------------------------------------*/
47
: m_progress(NULL), m_max_distance(100), m_last_player_index(1)
54
set_can_move_items(true);
55
set_system_angle_as_visual_angle(true);
57
get_rendering_attributes().mirror(false);
60
/*----------------------------------------------------------------------------*/
68
/*----------------------------------------------------------------------------*/
70
* \brief Load the media required by this class.
72
void ptb::frog::pre_cache()
74
get_level_globals().load_model("model/forest/frog.cm");
75
} // frog::pre_cache()
77
/*----------------------------------------------------------------------------*/
79
* \brief Initialise the item.
81
void ptb::frog::build()
85
set_model_actor( get_level_globals().get_model("model/forest/frog.cm") );
86
m_initial_position = get_center_of_mass();
89
m_progress = &frog::progress_idle;
92
/*---------------------------------------------------------------------------*/
94
* \brief Do one iteration in the progression of the item.
95
* \param elapsed_time Elapsed time since the last call.
97
void ptb::frog::progress( bear::universe::time_type elapsed_time )
99
super::progress( elapsed_time );
103
if ( m_progress != NULL )
104
(this->*m_progress)(elapsed_time);
105
} // frog::progress()
107
/*----------------------------------------------------------------------------*/
109
* \brief Set a field of type <real>.
110
* \param name The name of the field.
111
* \param value The new value of the field.
112
* \return false if the field "name" is unknow, true otherwise.
114
bool ptb::frog::set_real_field
115
( const std::string& name, double value )
119
if (name == "frog.max_distance")
120
m_max_distance = value;
122
ok = super::set_real_field(name,value);
125
} // frog::set_real_field()
127
/*----------------------------------------------------------------------------*/
129
* \brief Call a function.
130
* \param name The function to call.
132
void ptb::frog::execute_function( const std::string& name )
134
if ( name == "start_idle" )
136
else if ( name == "start_jump" )
138
else if ( name == "start_fall" )
140
else if ( name == "start_explose" )
142
else if ( name == "try_to_jump" )
145
super::execute_function(name);
146
} // frog::execute_function()
148
/*----------------------------------------------------------------------------*/
150
* \brief Call collision_as_train().
151
* \param that The other item of the collision.
152
* \param info Some informations about the collision.
154
void ptb::frog::collision
155
( bear::engine::base_item& that, bear::universe::collision_info& info )
157
if ( info.get_collision_side() == bear::universe::zone::top_zone )
159
if ( default_collision(info) )
161
player* p = dynamic_cast<player*>(&that);
164
m_last_player_index = p->get_index();
169
if ( ( get_current_action_name() == "fall" ) ||
170
( get_current_action_name() == "jump" ) )
172
player* p = dynamic_cast<player*>(&that);
175
that.set_contact_friction( that.get_contact_friction()*0.8);
178
}// frog::collision_as_train()
180
/*----------------------------------------------------------------------------*/
182
* \brief Progress in the state idle.
184
void ptb::frog::progress_idle( bear::universe::time_type elapsed_time )
186
if ( !test_in_sky() )
188
} // frog::progress_idle()
190
/*----------------------------------------------------------------------------*/
192
* \brief Progress in the state jump.
194
void ptb::frog::progress_jump( bear::universe::time_type elapsed_time )
196
if ( !test_bottom_contact() )
197
if( get_speed().y <= 0 )
198
start_model_action("fall");
199
} // frog::progress_jump()
202
/*----------------------------------------------------------------------------*/
204
* \brief Progress in the state fall.
206
void ptb::frog::progress_fall( bear::universe::time_type elapsed_time )
208
if ( !test_bottom_contact() )
209
if( get_speed().y >= 0 )
210
start_model_action("jump");
211
} // frog::progress_fall()
213
/*----------------------------------------------------------------------------*/
215
* \brief Progress in the state explose.
217
void ptb::frog::progress_explose( bear::universe::time_type elapsed_time )
220
} // frog::progress_explose()
222
/*----------------------------------------------------------------------------*/
224
* \brief Start idle state.
226
void ptb::frog::start_idle()
228
m_progress = &frog::progress_idle;
229
} // frog::start_idle()
231
/*----------------------------------------------------------------------------*/
233
* \brief Start to jump.
235
void ptb::frog::start_jump()
237
m_progress = &frog::progress_jump;
238
} // frog::start_jump()
240
/*----------------------------------------------------------------------------*/
242
* \brief Start to fall.
244
void ptb::frog::start_fall()
246
m_progress = &frog::progress_fall;
247
} // frog::start_fall()
249
/*----------------------------------------------------------------------------*/
251
* \brief Start to explose.
253
void ptb::frog::start_explose()
255
set_can_move_items(false);
256
m_progress = &frog::progress_explose;
257
create_floating_score();
258
} // frog::start_explose()
261
/*----------------------------------------------------------------------------*/
263
* \brief Apply a jump.
265
void ptb::frog::apply_jump()
267
if ( get_rendering_attributes().is_mirrored() )
268
add_internal_force( bear::universe::force_type(-40000, 50000) );
270
add_internal_force( bear::universe::force_type(40000, 50000) );
272
start_model_action("jump");
273
} // frog::apply_jump()
275
/*----------------------------------------------------------------------------*/
277
* \brief Choose an idle action.
279
void ptb::frog::choose_idle_action()
281
std::ostringstream s;
282
s << "idle_" << (rand() % 2 + 1);
283
start_model_action(s.str());
284
} // frog::choose_idle_action()
286
/*----------------------------------------------------------------------------*/
288
* \brief Scan if there is a player in a given direction.
289
* \param origin The position from which we start watching.
290
* \param dir The direction of the scan.
292
bool ptb::frog::scan_no_wall_in_direction
293
( const bear::universe::position_type& origin,
294
const bear::universe::vector_type& dir ) const
296
if ( get_layer().has_world() )
298
bear::universe::item_picking_filter filter;
299
filter.set_can_move_items_value(true);
300
filter.set_forbidden_position(origin);
302
return get_layer().get_world().pick_item_in_direction
303
(origin, dir, filter) == NULL;
307
} // frog::scan_no_wall_in_direction()
309
/*---------------------------------------------------------------------------*/
311
* \brief Testeif the frog is in the sky and change state thereof.
312
* Return true if the frog is in the sky.
314
bool ptb::frog::test_in_sky()
318
if ( !has_bottom_contact() )
322
if( get_speed().y <= 0 )
323
start_model_action("fall");
325
start_model_action("jump");
329
} // frog::test_in_sky()
331
/*---------------------------------------------------------------------------*/
333
* \brief Test if the frog has bottom contact and change state thereof.
334
* Return true if the frog is now in idle state.
336
bool ptb::frog::test_bottom_contact()
340
if ( has_bottom_contact() )
342
choose_idle_action();
347
} // frog::test_bottom_contact()
349
/*---------------------------------------------------------------------------*/
351
* \brief Test if the frog must explose.
353
void ptb::frog::test_explose()
355
if ( has_bottom_contact() && has_top_contact() )
356
start_model_action("explose");
357
} // frog::test_explose()
359
/*----------------------------------------------------------------------------*/
361
* \brief The frog try to jump.
364
void ptb::frog::try_to_jump()
366
if ( has_bottom_contact() )
369
if ( (rand() % 2) == 1)
370
get_rendering_attributes().mirror
371
(!get_rendering_attributes().is_mirrored());
377
get_rendering_attributes().mirror
378
(!get_rendering_attributes().is_mirrored());
383
get_rendering_attributes().mirror
384
(!get_rendering_attributes().is_mirrored());
387
} // frog::try_to_jump()
389
/*----------------------------------------------------------------------------*/
391
* \brief Test if the frog can jump.
394
bool ptb::frog::can_jump() const
398
bear::universe::coordinate_type dist;
400
dist = m_initial_position.distance(get_center_of_mass());
401
if ( dist > m_max_distance )
403
if ( get_rendering_attributes().is_mirrored() &&
404
(m_initial_position.x > get_center_of_mass().x) )
407
if ( !get_rendering_attributes().is_mirrored() &&
408
(m_initial_position.x < get_center_of_mass().x) )
414
bear::universe::vector_type dir(150, 0);
416
if ( get_rendering_attributes().is_mirrored() )
419
result = scan_no_wall_in_direction(get_center_of_mass(), dir);
423
} // frog::can_jump()
425
/*----------------------------------------------------------------------------*/
427
* \brief Create a floating score.
429
void ptb::frog::create_floating_score() const
431
floating_score* s = new floating_score;
433
s->set_z_position( super::get_z_position() + 10 );
434
s->set_center_of_mass( super::get_center_of_mass() );
437
s->add_points( m_last_player_index, 1 );
438
} // rabbit::create_floating_score()