src/weapon/mine.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *  Wormux is a convivial mass murder game.
00003  *  Copyright (C) 2001-2004 Lawrence Azzoug.
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00018  ******************************************************************************
00019  * Mine : Detect if character is close and explode after a shot time.
00020  * Sometime the mine didn't explode randomly.
00021  *****************************************************************************/
00022 
00023 #include "mine.h"
00024 #include <iostream>
00025 #include <sstream>
00026 #include "explosion.h"
00027 #include "../game/config.h"
00028 #include "../game/time.h"
00029 #include "../graphic/sprite.h"
00030 #include "../include/app.h"
00031 #include "../include/constant.h"
00032 #include "../interface/game_msg.h"
00033 #include "../map/map.h"
00034 #include "../object/objects_list.h"
00035 #include "../team/macro.h"
00036 #include "../tool/debug.h"
00037 #include "../tool/i18n.h"
00038 #include "../network/randomsync.h"
00039 #include "../tool/resource_manager.h"
00040 
00041 #ifdef __MINGW32__
00042 #undef LoadImage
00043 #endif
00044 
00045 const double DEPART_FONCTIONNEMENT = 5;
00046 
00047 ObjMine::ObjMine(MineConfig& cfg,
00048                  WeaponLauncher * p_launcher) :
00049   WeaponProjectile("mine", cfg, p_launcher)
00050 {
00051   m_allow_negative_y = true; 
00052   animation = false;
00053   channel = -1;
00054   is_active = true;
00055   explode_with_collision = false;
00056 
00057   escape_time = 0;
00058 
00059   // is it a fake mine ?
00060   fake = !(randomSync.GetLong(0, 9));
00061 }
00062 
00063 void ObjMine::FakeExplosion()
00064 {
00065   MSG_DEBUG("mine", "Fake explosion");
00066 
00067   jukebox.Play("share", "weapon/mine_fake");
00068   ParticleEngine::AddNow(GetPosition(), 5, particle_SMOKE, true);
00069 
00070   if ( animation )
00071   {
00072     MSG_DEBUG("mine", "Desactive detection..");
00073 
00074     animation = false;
00075     image->SetCurrentFrame(0);
00076   }
00077   if (launcher != NULL) launcher->SignalProjectileTimeout();
00078   // Mine fall into the ground after a fake explosion
00079   SetCollisionModel(false, false, false);
00080 }
00081 
00082 void ObjMine::StartTimeout()
00083 {
00084   if (!animation)
00085   {
00086     animation=true;
00087     MSG_DEBUG("mine", "EnableDetection - CurrentTime : %d",Time::GetInstance()->ReadSec() );
00088     attente = Time::GetInstance()->ReadSec() + cfg.timeout;
00089     MSG_DEBUG("mine", "EnableDetection : %d", attente);
00090 
00091     channel = jukebox.Play("share", "weapon/mine_beep", -1);
00092   }
00093 }
00094 
00095 void ObjMine::Detection()
00096 {
00097   uint current_time = Time::GetInstance()->ReadSec();
00098 
00099   if (escape_time == 0)
00100   {
00101     escape_time = current_time + static_cast<MineConfig&>(cfg).escape_time;
00102     MSG_DEBUG("mine", "Initialize escape_time : %d", current_time);
00103     return;
00104   }
00105 
00106   if (current_time < escape_time) return;
00107 
00108   MSG_DEBUG("mine", "Escape_time is finished : %d", current_time);
00109 
00110   FOR_ALL_LIVING_CHARACTERS(equipe, ver)
00111   { 
00112     if (MeterDistance (GetCenter(), ver->GetCenter()) < static_cast<MineConfig&>(cfg).detection_range
00113         && !animation)
00114     {
00115       std::string txt = Format(_("%s is next to a mine!"),
00116                                   ver -> GetName().c_str());
00117       GameMessages::GetInstance()->Add (txt);
00118       StartTimeout();
00119       return;
00120     }
00121   }
00122 }
00123 
00124 void ObjMine::Refresh()
00125 {
00126   // the mine is now out of the map
00127   // or it's a fake mine that has already exploded!
00128   if (!is_active)
00129   {
00130     jukebox.Stop(channel);
00131     channel = -1;
00132     escape_time = 0;
00133     return;
00134   }
00135 
00136   // try to detect a character near the mine
00137   if (!animation)
00138   {
00139     Detection();
00140   }
00141   else 
00142   {
00143     image->Update();
00144 
00145     // the timeout is finished !!
00146     if (attente < Time::GetInstance()->ReadSec())
00147     {
00148       is_active = false;
00149       jukebox.Stop(channel);
00150       channel = -1;
00151       if (!fake) Explosion();
00152       else FakeExplosion();
00153       if (launcher != NULL) launcher->SignalProjectileTimeout();
00154     }
00155   }
00156 }
00157 
00158 bool ObjMine::IsImmobile() const
00159 {
00160   if (is_active && animation) return false;
00161   return PhysicalObj::IsImmobile();
00162 }
00163 
00164 void ObjMine::Draw()
00165 {
00166   image->Draw(GetPosition());
00167 }
00168 //-----------------------------------------------------------------------------
00169 
00170 MineConfig * MineConfig::singleton = NULL;
00171 
00172 MineConfig * MineConfig::GetInstance() 
00173 {
00174   if (singleton == NULL) {
00175     singleton = new MineConfig();
00176   }
00177   return singleton;
00178 }
00179 
00180 //-----------------------------------------------------------------------------
00181 
00182 Mine::Mine() : WeaponLauncher(WEAPON_MINE, "minelauncher", MineConfig::GetInstance(), VISIBLE_ONLY_WHEN_INACTIVE)
00183 {
00184   m_name = _("Mine");
00185   ReloadLauncher();
00186 }
00187 
00188 WeaponProjectile * Mine::GetProjectileInstance()
00189 {
00190   return dynamic_cast<WeaponProjectile *>
00191       (new ObjMine(cfg(), dynamic_cast<WeaponLauncher *>(this)));
00192 }
00193 
00194 bool Mine::p_Shoot()
00195 {
00196   int x,y;
00197   PosXY (x,y);
00198   Add (x, y);
00199 
00200   return true;
00201 }
00202 
00203 void Mine::Add (int x, int y)
00204 {
00205   projectile -> SetXY ( Point2i(x, y) );
00206   projectile -> SetOverlappingObject(&ActiveCharacter());
00207 
00208   Point2d speed_vector;
00209   ActiveCharacter().GetSpeedXY(speed_vector);
00210   projectile -> SetSpeedXY (speed_vector);
00211   lst_objects.AddObject (projectile);
00212   projectile = NULL;
00213   ReloadLauncher();
00214 }
00215 
00216 MineConfig& Mine::cfg()
00217 {
00218   return static_cast<MineConfig&>(*extra_params);
00219 }
00220 
00221 MineConfig::MineConfig()
00222 {
00223   detection_range= 1;
00224   timeout = 3;
00225   escape_time = 2;
00226 }
00227 
00228 void MineConfig::LoadXml(xmlpp::Element *elem) 
00229 {
00230   ExplosiveWeaponConfig::LoadXml (elem);
00231   XmlReader::ReadUint(elem, "escape_time", escape_time);
00232   XmlReader::ReadDouble(elem, "detection_range", detection_range);
00233 }

Generated on Mon Jan 1 13:11:00 2007 for Wormux by  doxygen 1.4.7