00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "snipe_rifle.h"
00023 #include <sstream>
00024 #include "explosion.h"
00025 #include "../game/time.h"
00026 #include "../interface/game_msg.h"
00027 #include "../map/map.h"
00028 #include "../map/camera.h"
00029 #include "../object/objects_list.h"
00030 #include "../team/teams_list.h"
00031 #include "../tool/i18n.h"
00032 #include "../include/app.h"
00033 #include "../game/game_loop.h"
00034
00035
00036 const uint SNIPE_RIFLE_BEAM_START = 5;
00037 const uint SNIPE_RIFLE_BULLET_SPEED = 20;
00038 const uint SNIPE_RIFLE_MAX_BEAM_SIZE = 500;
00039
00040 SnipeBullet::SnipeBullet(ExplosiveWeaponConfig& cfg,
00041 WeaponLauncher * p_launcher) :
00042 WeaponBullet("snipe_rifle_bullet", cfg, p_launcher)
00043 {
00044 }
00045
00046 void SnipeBullet::ShootSound()
00047 {
00048 jukebox.Play("share","weapon/gun");
00049 }
00050
00051
00052
00053 SnipeRifle::SnipeRifle() : WeaponLauncher(WEAPON_SNIPE_RIFLE,"snipe_rifle", new ExplosiveWeaponConfig())
00054 {
00055 m_name = _("Sniper Rifle");
00056
00057 last_angle = 0.0;
00058 targeting_something = false;
00059 m_laser_image = new Sprite(resource_manager.LoadImage(weapons_res_profile,m_id+"_laser"));
00060 m_weapon_fire = new Sprite(resource_manager.LoadImage(weapons_res_profile,m_id+"_fire"));
00061 m_weapon_fire->EnableRotationCache(32);
00062 laser_beam_color = resource_manager.LoadColor(weapons_res_profile,m_id+"_laser_color");
00063
00064 ReloadLauncher();
00065 }
00066
00067 WeaponProjectile * SnipeRifle::GetProjectileInstance()
00068 {
00069 return dynamic_cast<WeaponProjectile *>
00070 (new SnipeBullet(cfg(),dynamic_cast<WeaponLauncher *>(this)));
00071 }
00072
00073 bool SnipeRifle::p_Shoot()
00074 {
00075 if(m_is_active)
00076 return false;
00077
00078 m_is_active = true;
00079 projectile->Shoot (SNIPE_RIFLE_BULLET_SPEED);
00080 projectile = NULL;
00081 ReloadLauncher();
00082 return true;
00083 }
00084
00085
00086 void SnipeRifle::SignalProjectileGhostState()
00087 {
00088 m_is_active = false;
00089 ReloadLauncher();
00090 ComputeCrossPoint(true);
00091 }
00092
00093 bool SnipeRifle::ComputeCrossPoint(bool force = false)
00094 {
00095
00096 Point2i pos = GetGunHolePosition();
00097 double angle = ActiveCharacter().GetFiringAngle();
00098 if ( !force && last_rifle_pos == pos && last_angle == angle ) return targeting_something;
00099 else {
00100 last_rifle_pos=pos;
00101 last_angle=angle;
00102 }
00103
00104
00105 double a, b;
00106 a = sin(angle) / cos(angle);
00107 b = pos.y - ( a * pos.x );
00108 Point2i delta_pos, size, start_point;
00109 start_point = pos;
00110 uint distance = 0;
00111 targeting_something = false;
00112
00113 while( distance < SNIPE_RIFLE_MAX_BEAM_SIZE ){
00114
00115 if (angle < -0.78 && angle > -2.36){
00116 pos.x = (int)((pos.y-b)/a);
00117 delta_pos.y = -1;
00118
00119 } else if (angle > 0.78 && angle < 2.36){
00120 pos.x = (int)((pos.y-b)/a);
00121 delta_pos.y = 1;
00122
00123 } else {
00124 pos.y = (int)((a*pos.x) + b);
00125 delta_pos.x = ActiveCharacter().GetDirection();
00126 }
00127
00128 if ( distance < SNIPE_RIFLE_BEAM_START ) laser_beam_start = pos;
00129
00130
00131 if ( world.EstHorsMondeX(pos.x) || world.EstHorsMondeY(pos.y) ) break;
00132
00133
00134 if ( distance > 30 && !projectile->IsInVacuumXY( pos )){
00135 targeting_something = true;
00136 break;
00137 }
00138 pos += delta_pos;
00139 distance = (int) start_point.Distance(pos);
00140 }
00141 targeted_point=pos;
00142 return targeting_something;
00143 }
00144
00145
00146 void SnipeRifle::p_Deselect()
00147 {
00148 ActiveCharacter().SetFiringAngle(0.);
00149 }
00150
00151 void SnipeRifle::DrawBeam()
00152 {
00153 Point2i pos1 = laser_beam_start - camera.GetPosition();
00154 Point2i pos2 = targeted_point - camera.GetPosition();
00155 AppWormux::GetInstance()->video.window.AALineColor(pos1.x, pos2.x, pos1.y, pos2.y, laser_beam_color);
00156
00157
00158
00159 float redraw_size = 20.0;
00160 float dst = laser_beam_start.Distance(targeted_point);
00161 Point2f pos = Point2f((float)laser_beam_start.x, (float)laser_beam_start.y);
00162 Point2f delta = ( Point2f((float)targeted_point.x, (float)targeted_point.y) - pos ) * redraw_size / dst;
00163 Point2i delta_i((int)delta.x, (int)delta.y);
00164
00165 if(delta_i.x < 0) delta_i.x = - delta_i.x;
00166 if(delta_i.y < 0) delta_i.y = - delta_i.y;
00167 delta_i.x += 6;
00168 delta_i.y += 6;
00169
00170 int i = 0;
00171 while( (float)i * redraw_size < dst )
00172 {
00173
00174 Point2i pos_i((int)pos.x, (int)pos.y);
00175 if(delta.x < 0.0)
00176 {
00177 pos_i.x -= delta_i.x;
00178 pos_i.x += 3;
00179 }
00180 else
00181 pos_i.x -= 3;
00182
00183 if(delta.y < 0.0)
00184 {
00185 pos_i.y -= delta_i.y;
00186 pos_i.y += 3;
00187 }
00188 else
00189 pos_i.y -= 3;
00190
00191 world.ToRedrawOnMap(Rectanglei( pos_i, delta_i ));
00192 pos += delta;
00193 i++;
00194 }
00195 }
00196
00197 void SnipeRifle::Draw()
00198 {
00199 WeaponLauncher::Draw();
00200 if( GameLoop::GetInstance()->ReadState() != GameLoop::PLAYING || IsActive() ) return;
00201 ComputeCrossPoint();
00202 DrawBeam();
00203
00204 if( targeting_something ) m_laser_image->Draw(targeted_point - (m_laser_image->GetSize()/2));
00205 }