/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at
golgotha_source@usa.net (Subject should have "GOLG" in it)
***********************************************************************/
// Golgatha Map Object Class
//
#ifndef MAP_PIECE_HH
#define MAP_PIECE_HH
#include "g1_object.hh"
#include "sound_man.hh"
#include "player_type.hh"
#include "range.hh"
#include "objs/defaults.hh"
#include "objs/model_draw.hh"
#include "objs/model_collide.hh"
#include "obj3d.hh"
#include "global_id.hh"
#include "sound/sfx_id.hh"
#include "objs/vehic_sounds.hh"
class g1_path_object_class; // objs/path_object.hh
class g1_map_piece_class : public g1_object_class
{
public:
void fix_forward_link(g1_object_class *next) { next_object = next; }
void fix_previous_link(g1_object_class *prev) { prev_object = prev; }
protected:
friend g1_path_object_class;
g1_typed_reference_class next_object;
g1_typed_reference_class prev_object;
i4_float path_pos, path_len;
i4_float path_cos, path_sin, path_tan_phi;
i4_float stagger;
void unlink();
void link(g1_object_class *origin);
public:
g1_object_defaults_struct *defaults;
i4_float speed; // current speed of the piece
i4_float vspeed; // vertical speed of the piece
i4_float dest_x, dest_y; // if it has a destination, its point & direction is here
i4_float dest_z; // if it has a destination height
i4_float dest_theta;
w16 fire_delay; // number of game ticks before we can fire again
g1_id_ref *path_to_follow; // null terminated array of global id's
g1_id_ref next_path;
// calculated values
i4_float tread_pan; // accumulated tread texture pan based on speed
i4_float terrain_height; // terrain under vehicle
i4_float groundpitch, lgroundpitch;
i4_float groundroll, lgroundroll;
i4_float damping_fraction;
w8 ticks_to_blink; // when taking damage (not saved)
w8 death; // type of death desired
i4_3d_vector damage_direction; //inertia vector of whatever attacked last (or killed us)
g1_typed_reference_class attack_target; // the thing its targeting
g1_map_piece_class(g1_object_type id, g1_loader_class *fp);
void add_team_flag();
i4_bool alive() const { return health>0; }
virtual void hit_ground(); // when an object falls off a cliff and hits the ground
void find_target(i4_bool unfog=i4_T);
virtual i4_bool find_target_now() const;
virtual void damage(g1_object_class *obj, int hp, i4_3d_vector damage_dir);
void lead_target(i4_3d_point_class &lead_point, i4_float shot_speed=-1);
virtual void save(g1_saver_class *fp);
virtual float detection_range() const { return defaults->detection_range; }
virtual i4_bool check_move(i4_float dest_x,i4_float dest_y) const;
virtual i4_bool check_collision(const i4_3d_vector &start, i4_3d_vector &ray)
{ return g1_model_collide_radial(this, draw_params, start, ray); }
virtual void calc_world_transform(i4_float ratio, i4_transform_class *transform=0);
//Sound Effects
virtual void set_path(g1_id_ref *path); // null terminated array of global id's
g1_rumble_type rumble_type;
void init_rumble_sound(g1_rumble_type type);
virtual void init();
virtual void think();
virtual void draw(g1_draw_context_class *context);
i4_bool check_turn_radius();
#if 0 //(OLI) kill this soon!
//advances a piece one step to its dest_x,dest_y, following general guidelines
//for speeding up, slowing down, backing up, etc
//returns which direction (-1,0,1) it moved and which direction (-1,0,1) it turned
//in arguments ret_direction and ret_dt
i4_float advance_to_dest(w32 pathinfo, sw8 &ret_direction, sw8 &ret_dt,
i4_float brake_speed=0.9);
#endif
virtual void request_remove();
void advance_path();
i4_bool suggest_move(i4_float &dist,
i4_float &dtheta,
i4_float &dx, i4_float &dy,
i4_float brake_speed=0.1,
i4_bool reversible=i4_T);
i4_bool suggest_air_move(i4_float &dist,
i4_float &dtheta,
i4_3d_vector &d);
//checks the health to make sure the object is still alive
//if health is <0, the object is removed from the map, and i4_F returned
i4_bool check_life(i4_bool remove_if_dead=i4_T);
void get_terrain_info();
i4_bool occupy_location()
{
int ret;
if (ret = g1_object_class::occupy_location())
get_terrain_info();
return ret;
}
virtual void grab_old()
{
g1_object_class::grab_old();
lgroundpitch = groundpitch;
lgroundroll = groundroll;
}
// standard movement
i4_bool move(i4_float x_amount, i4_float y_amount);
static g1_map_piece_class *cast(g1_object_class *obj)
{
if (!obj || !(obj->get_type()->get_flag(g1_object_definition_class::TO_MAP_PIECE)))
return 0;
return (g1_map_piece_class*)obj;
}
virtual i4_bool can_attack(g1_object_class *who) const;
i4_bool in_range(g1_object_class *o) const;
};
#endif