ok.. j'abandonne..
Même la solution "simple" est ingérable...
En fichier joint un patch de là où j'en suis arrivé qui s'applique 
sur la révision 1241, si vous voulez essyer..

On Sun, Sep 17, 2006 at 03:05:27AM +0200, Laurent Defert wrote:
> Hi!
> Developpement mail, so in french :p
> 
> Salut!
> Comme j'en avais parlé, j'essaye de virer l'état ghost du code.
> A mon avis, c'est nécessaire parceque c'est une partie de code pas 
> claire. On utilise l'état ghost dès qu'un objet sort de l'écran ou dès 
> que l'objet n'effectue plus d'action dans le jeux (cf. les projectiles).
> Mais quand on regarde le source ces objets sont en fait bien présent 
> dans le moteur (on continue à appeler les méthode draw/refresh, à faire 
> des test dessus...).
> 
> Dans l'ensemble, ça ne pose pas trop de problème: pour les particules et 
> les projectiles, on peut les effacer au lieu de leur mettre un état 
> ghost.
> Par contre, y'a un sérieux problème avec les characters. Si on efface le 
> character en train de jouer wormux plante au premier appel de 
> ActiveCharacter().
> Pour régler ça, je vois 2 solutions:
> solution facile: au lieu d'effacer les characters morts, on les déplace 
> dans une nouvelle liste de la class Team
> solution propre (mais longue et pénible ;): on se débrouille pour 
> qu'aucun appel de ActiveCharacter() soit effectué sur un character qui 
> vient de mourir.
> 
> Donc j'appelle à l'aide pour savoir si je dois oublier mon idée de 
> virer l'état ghost, si je prends la solution facile, si on 
> s'embarque dans la solution difficile ou si vous avez une solution 
> propre et facile à proposer :)
> 
> a+
> 
> Lodesi
> -- 
> 
> _______________________________________________
> Wormux-dev mailing list
> Wormux-dev@gna.org
> https://mail.gna.org/listinfo/wormux-dev

-- 
Index: team/macro.h
===================================================================
--- team/macro.h        (révision 1241)
+++ team/macro.h        (copie de travail)
@@ -38,7 +38,6 @@
        fin_pour_chaque_ver = (*(equipe)).end(); \
        ver != fin_pour_chaque_ver; \
        ++ver) \
-  if (!ver -> IsGhost())
 
 // Boucle pour chaque ver vivant d'une equipe
 #define FOR_EACH_LIVING_CHARACTER(equipe,ver) \
Index: team/team.cpp
===================================================================
--- team/team.cpp       (révision 1241)
+++ team/team.cpp       (copie de travail)
@@ -20,6 +20,7 @@
  *****************************************************************************/
 
 #include "team.h"
+#include "teams_list.h"
 #include "../character/body_list.h"
 #include "../game/game.h"
 #include "../game/game_mode.h"
@@ -38,6 +39,7 @@
 #include "../network/network.h"
 #include <sstream>
 #include <iostream>
+#include <algorithm>
 
 Team::Team(const std::string& _teams_dir,
           const std::string& _id,
@@ -174,6 +176,12 @@
   return (characters.size() == howmany);
 }
 
+void Team::RemoveCharacter(Character* c)
+{
+  to_remove.push_back(c);
+  printf("to remove\n");
+}
+
 void Team::InitEnergy (uint max)
 {
   energy.Config(ReadEnergy(), max);
@@ -203,6 +211,15 @@
   // Passe au ver suivant
   assert (0 < NbAliveCharacter());
   ActiveCharacter().StopPlaying();
+
+  // If the current is in the out_of_map list, then select
+  // the first character in the playing list
+  if( FindById( ActiveCharacter().GetName() ) == NULL)
+  {
+    printf("playing character deleted\n");
+    active_character = characters.begin();
+  }
+
   do
   {
     ++active_character;
@@ -345,6 +362,19 @@
   return &(*it);
 }
 
+Character* Team::FindById(const std::string & id)
+{
+  iterator it= characters.begin(), end=characters.end();
+
+  while(it != characters.end())
+  {
+    if(id == it->GetName())
+      return &(*it);
+    it++;
+  }
+  return NULL;
+}
+
 void Team::LoadGamingData(uint how_many_characters)
 {
   // Reset ammos
@@ -385,7 +415,36 @@
 
 void Team::Refresh()
 {
-  energy.Refresh();
+   // Remove characters that have gone out of the map:
+  for(std::list<Character*>::iterator it = to_remove.begin();
+    it != to_remove.end();
+    ++it)
+  {
+    bool found = false;
+    for(iterator ch = begin();
+      ch != end();
+      ++ch)
+    {
+      if( &(*ch) == *it )
+      {
+        printf("removing\n");
+        found = true;
+        removed.push_back( **it );
+        if( &(*active_character) == *it )
+        {
+          printf("active removed\n");
+          active_character = removed.end();
+          --active_character;
+        }
+        characters.erase(ch);
+        break;
+      }
+    }
+    assert(found);
+  }
+  to_remove.clear();
+
+ energy.Refresh();
 }
 
 Weapon& Team::AccessWeapon() const { return *active_weapon; }
Index: team/team.h
===================================================================
--- team/team.h (révision 1241)
+++ team/team.h (copie de travail)
@@ -60,6 +60,8 @@
   std::string m_name;
   std::string m_sound_profile;
   std::list<Character> characters;
+  std::list<Character> removed;
+  std::list<Character*> to_remove;
   iterator active_character;
   Weapon *active_weapon;
 
@@ -67,7 +69,7 @@
        const std::string& _id, 
        const std::string& _name, 
        const Surface &_flag,
-       const std::string& _sound_profile);  
+       const std::string& _sound_profile);
 
   bool LoadCharacters(uint howmany);
 public:
@@ -93,6 +95,7 @@
   // Change the weapon.
   void SetWeapon (Weapon_type nv_arme);
   int NbAliveCharacter() const;
+  void RemoveCharacter(Character* c);
 
   // Access to the active weapon.
   Weapon& AccessWeapon() const;
@@ -115,9 +118,10 @@
   iterator begin();
   iterator end();
   Character* FindByIndex(uint index);
+  Character* FindById(const std::string &id);
 
   // Number of ammo for the current selected weapon.
-  // (return INFINITE_AMMO is ammo are unlimited !)
+  // (return INFINITE_AMMO if ammo are unlimited !)
   int ReadNbAmmos() const;
   int ReadNbAmmos(const std::string &weapon_name) const;
   int& AccessNbAmmos();
Index: particles/particle.cpp
===================================================================
--- particles/particle.cpp      (révision 1241)
+++ particles/particle.cpp      (copie de travail)
@@ -105,6 +105,11 @@
   return (m_left_time_to_live > 0);
 }
 
+void Particle::SignalOutOfMap()
+{
+  m_left_time_to_live = 0;
+}
+
 // ==============================================
 
 ParticleEngine::ParticleEngine(uint time)
Index: particles/particle.h
===================================================================
--- particles/particle.h        (révision 1241)
+++ particles/particle.h        (copie de travail)
@@ -54,6 +54,8 @@
 
   Sprite *image;
 
+  void SignalOutOfMap();
+
  public:
   Particle(const std::string &name);
   ~Particle();
Index: weapon/snipe_rifle.cpp
===================================================================
--- weapon/snipe_rifle.cpp      (révision 1241)
+++ weapon/snipe_rifle.cpp      (copie de travail)
@@ -78,12 +78,14 @@
   return true;
 }
 
+/*
 // When an explosion occurs, we compute a new targeted point
 void SnipeRifle::SignalProjectileGhostState()
 {
   ReloadLauncher();
   ComputeCrossPoint(true);
 }
+*/
 
 bool SnipeRifle::ComputeCrossPoint(bool force = false)
 {
@@ -126,7 +128,7 @@
     if ( world.EstHorsMondeX(pos.x) || world.EstHorsMondeY(pos.y) ) break;
 
     // is there a collision ??
-    if ( distance > 30 && projectile->CollisionTest( pos )){
+    if ( distance > 30 && !projectile->IsInVacuumXY( pos )){
       targeting_something = true;
       break;
     }
Index: weapon/explosion.cpp
===================================================================
--- weapon/explosion.cpp        (révision 1241)
+++ weapon/explosion.cpp        (copie de travail)
@@ -146,7 +146,7 @@
   }
 
   // Apply the blast on physical objects.
-  FOR_EACH_OBJECT(obj) if ( !(obj -> ptr -> GoesThroughWall()) )
+  FOR_ALL_OBJECTS(obj) if ( !(obj -> ptr -> GoesThroughWall()) )
   { 
     double distance, angle;
     distance = MeterDistance (pos, obj -> ptr -> GetCenter());
Index: weapon/jetpack.cpp
===================================================================
--- weapon/jetpack.cpp  (révision 1241)
+++ weapon/jetpack.cpp  (copie de travail)
@@ -1,3 +1,4 @@
+
 /******************************************************************************
  *  Wormux, a free clone of the game Worms from Team17.
  *  Copyright (C) 2001-2004 Lawrence Azzoug.
@@ -70,7 +71,7 @@
       F.y = m_y_force ;
 
       ActiveCharacter().SetExternForceXY(F);
-      ActiveCharacter().UpdatePosition();
+//      ActiveCharacter().UpdatePosition();
       SendCharacterPosition();
       Action a(ACTION_SET_CHARACTER_DIRECTION, 
ActiveCharacter().GetDirection());
       network.SendAction(&a);
Index: weapon/weapon.cpp
===================================================================
--- weapon/weapon.cpp   (révision 1241)
+++ weapon/weapon.cpp   (copie de travail)
@@ -453,8 +453,7 @@
        break;
     }
 
-  if(ActiveCharacter().IsGhost()
-  || ActiveCharacter().IsDrowned()
+  if(ActiveCharacter().IsDrowned()
   || ActiveCharacter().IsDead())
     return;
 
Index: weapon/submachine_gun.cpp
===================================================================
--- weapon/submachine_gun.cpp   (révision 1241)
+++ weapon/submachine_gun.cpp   (copie de travail)
@@ -65,7 +65,6 @@
   override_keys = true ;
   ignore_collision_signal = true;
   ignore_explosion_signal = true;
-  ignore_ghost_state_signal = true;
 
   m_weapon_fire = new 
Sprite(resource_manager.LoadImage(weapons_res_profile,m_id+"_fire"));
   m_weapon_fire->EnableRotationCache(32);
Index: weapon/launcher.h
===================================================================
--- weapon/launcher.h   (révision 1241)
+++ weapon/launcher.h   (copie de travail)
@@ -72,7 +72,6 @@
 
     virtual void SignalTimeout();
     virtual void SignalExplosion();
-    void SignalGhostState (bool was_dead);
 
     virtual void ShootSound();
     virtual void Explosion();
@@ -102,7 +101,6 @@
     bool ignore_timeout_signal;
     bool ignore_collision_signal;
     bool ignore_explosion_signal;
-    bool ignore_ghost_state_signal;
   protected:
     WeaponProjectile * projectile;
     uint nb_active_projectile;
@@ -130,7 +128,6 @@
   // Handle of projectile events
     virtual void SignalProjectileExplosion();
     virtual void SignalProjectileCollision();
-    virtual void SignalProjectileGhostState();
     virtual void SignalProjectileTimeout();
 
     virtual Point2i GetGunHolePosition();
Index: weapon/cluster_bomb.cpp
===================================================================
--- weapon/cluster_bomb.cpp     (révision 1241)
+++ weapon/cluster_bomb.cpp     (copie de travail)
@@ -100,12 +100,12 @@
 
 void ClusterBomb::Explosion()
 {
-  if (IsGhost())
+/*  if (IsGhost())
   {
     WeaponProjectile::Explosion();
     return;
   }
-
+*/
   Point2d speed_vector;
   int x, y;
 
Index: weapon/launcher.cpp
===================================================================
--- weapon/launcher.cpp (révision 1241)
+++ weapon/launcher.cpp (copie de travail)
@@ -62,7 +62,7 @@
     tmp -> SetEnergyDelta (-cfg.damage);
     tmp -> AddSpeed (2, GetSpeedAngle());
     tmp -> UpdatePosition();
-    Ghost();
+    lst_objects.RemoveObject(this);
   }
 }
 
@@ -197,17 +197,12 @@
   if (launcher != NULL && !launcher->ignore_collision_signal) 
launcher->SignalProjectileCollision();
 }
 
-// Signal a ghost state
-void WeaponProjectile::SignalGhostState(bool)
+void WeaponProjectile::SignalOutOfMap()
 {
-  if (launcher != NULL && !launcher->ignore_ghost_state_signal) 
launcher->SignalProjectileGhostState();
+//  if (launcher != NULL && !launcher->ignore_ghost_state_signal) 
launcher->SignalProjectileGhostState();
   lst_objects.RemoveObject(this);
 }
 
-void WeaponProjectile::SignalOutOfMap()
-{
-}
-
 // Implement it in subclass to randomize fire
 void WeaponProjectile::RandomizeShoot(double &angle,double &strength)
 {
@@ -219,7 +214,7 @@
   MSG_DEBUG (m_name.c_str(), "Explosion");
   DoExplosion();
   SignalExplosion();
-  Ghost();
+  lst_objects.RemoveObject(this);
 }
 
 void WeaponProjectile::SignalExplosion()
@@ -288,7 +283,6 @@
   ignore_timeout_signal = false;
   ignore_collision_signal = false;
   ignore_explosion_signal = false;
-  ignore_ghost_state_signal = false;
 }
 
 WeaponLauncher::~WeaponLauncher()
@@ -347,12 +341,6 @@
   m_is_active = false;
 }
 
-// Signal a ghost state
-void WeaponLauncher::SignalProjectileGhostState()
-{
-  m_is_active = false;
-}
-
 // Signal a projectile timeout (for exemple: grenade, holly grenade ... etc.)
 void WeaponLauncher::SignalProjectileTimeout()
 {
Index: weapon/air_attack.cpp
===================================================================
--- weapon/air_attack.cpp       (révision 1241)
+++ weapon/air_attack.cpp       (copie de travail)
@@ -135,7 +135,6 @@
 
 void Plane::Draw()
 {
-  if (IsGhost()) return;  
   image->Draw(GetPosition());  
 }
 
Index: character/character.h
===================================================================
--- character/character.h       (révision 1241)
+++ character/character.h       (copie de travail)
@@ -80,8 +80,8 @@
   void DrawEnergyBar (int dy);
   void DrawName (int dy) const;
 
+  void SignalOutOfMap();
   void SignalDrowning();
-  void SignalGhostState (bool was_dead);
   void SignalCollision();
 
 public:
Index: character/move.cpp
===================================================================
--- character/move.cpp  (révision 1241)
+++ character/move.cpp  (copie de travail)
@@ -64,7 +64,7 @@
     }
     //We can go down, but the step is to big -> the character will fall.
     character.SetX (character.GetX() +character.GetDirection());
-    character.UpdatePosition();
+//    character.UpdatePosition();
     character.SetMovement("fall");
     return false;
   }
@@ -81,19 +81,7 @@
 // Bouge un character characters la droite ou la gauche (selon le signe de 
direction)
 void MoveCharacter(Character &character){
   int hauteur;
-  bool fantome;
 
-  // On est bien dans le monde ? (sinon, pas besoin de tester !)
-  if (character.GetDirection() == -1)
-    fantome = character.IsOutsideWorld ( Point2i(-1, 0) );
-  else
-    fantome = character.IsOutsideWorld ( Point2i(1, 0) );
-  if (fantome){
-    MSG_DEBUG("ghost", "%s will be a ghost.", character.GetName().c_str());
-    character.Ghost();
-    return;
-  }
-
   // Calcule la hauteur a descendre
   if (!CalculeHauteurBouge (character, hauteur)) return;
 
@@ -106,9 +94,6 @@
     character.SetXY( Point2i(character.GetX() +character.GetDirection(),
                              character.GetY() +hauteur) );
 
-    // Gravite (s'il n'y a pas eu de collision
-    character.UpdatePosition();
-
   }while(character.CanStillMoveDG(PAUSE_BOUGE) && CalculeHauteurBouge 
(character, hauteur));
 }
 // Move a character to the left
@@ -121,7 +106,8 @@
   {
     MoveCharacter(character);
   }
-  else{
+  else
+  {
     ActionHandler::GetInstance()->NewAction(new 
Action(ACTION_SET_CHARACTER_DIRECTION,-1));
     character.InitMouvementDG (PAUSE_CHG_SENS);
   }
@@ -147,7 +133,6 @@
     character.InitMouvementDG (PAUSE_CHG_SENS);
   }
 
-
   //Refresh skin position across network
   if( !network.IsLocal() && ActiveTeam().is_local)
     SendCharacterPosition();
Index: character/character.cpp
===================================================================
--- character/character.cpp     (révision 1241)
+++ character/character.cpp     (copie de travail)
@@ -136,6 +136,7 @@
   MSG_DEBUG("character", "Unload character %s", character_name.c_str());
   if(body)
     delete body;
+  camera.StopFollowingObj(this);
 }
 
 void Character::SetBody(Body* _body)
@@ -160,15 +161,12 @@
 }
 
 // Si un ver devient un fantome, il meurt ! Signale sa mort
-void Character::SignalGhostState (bool was_dead)
-{  
+void Character::SignalOutOfMap()
+{
   // Report to damage performer this character lost all of its energy
   ActiveCharacter().MadeDamage(energy, *this);
-
-  MSG_DEBUG("character", "ghost");
-
-  // Signal the death
-  if (!was_dead) GameLoop::GetInstance()->SignalCharacterDeath (this);
+  GameLoop::GetInstance()->SignalCharacterDeath (this);
+  m_team.RemoveCharacter(this);
 }
 
 void Character::SetDirection (int nv_direction)
@@ -282,11 +280,11 @@
 
 void Character::Draw()
 {
+  if( IsOutsideWorld( Point2i(0, 0) ) )
+    return;
+
   if (hidden) return;
 
-  // Gone in another world ?
-  if (IsGhost()) return;
-
   bool dessine_perte = (lost_energy != 0);
   if ((&ActiveCharacter() == this
     && GameLoop::GetInstance()->ReadState() != GameLoop::END_TURN)
@@ -574,9 +572,6 @@
 
 void Character::Refresh()
 {
-  if (IsGhost()) return;
-
-  UpdatePosition ();
   Time * global_time = Time::GetInstance();
 
   if( &ActiveCharacter() == this && GameLoop::GetInstance()->ReadState() == 
GameLoop::PLAYING)
@@ -615,6 +610,8 @@
     rotation = - (int)(180.0 * speed.y / speed_init);
     body->SetRotation(rotation);
   }
+
+  UpdatePosition();
 }
 
 // Prepare a new turn
@@ -657,6 +654,9 @@
 
 bool Character::CanStillMoveDG(uint pause)
 {
+  if( IsOutsideWorld( Point2i(0,0) ) )
+    return false;
+
   if(pause_bouge_dg+pause<Time::GetInstance()->Read())
   {
     pause_bouge_dg += pause;
@@ -728,7 +728,6 @@
 // Begining of turn or changed to this character
 void Character::StartPlaying()
 {
-  assert (!IsGhost());
   SetWeaponClothe();
 }
 
Index: interface/cursor.cpp
===================================================================
--- interface/cursor.cpp        (révision 1241)
+++ interface/cursor.cpp        (copie de travail)
@@ -69,7 +69,6 @@
 {
   if (!IsDisplayed()) return;
   if (obj_designe == NULL) return;
-  if (obj_designe -> IsGhost()) return;
 
   // Dessine le curseur autour du ver
   Point2i centre = obj_designe->GetCenter();
Index: object/bonus_box.cpp
===================================================================
--- object/bonus_box.cpp        (révision 1241)
+++ object/bonus_box.cpp        (copie de travail)
@@ -95,8 +95,7 @@
     if( ObjTouche(*ver) )
     {
       // here is the gift (truly a gift ?!? :)
-      ApplyBonus (**equipe, *ver);
-      Ghost();
+      SignalObjectCollision(&(*ver));
       return;
     }
   }
@@ -124,7 +123,7 @@
 {
   // here is the gift (truly a gift ?!? :)
   ApplyBonus(ActiveTeam(),ActiveCharacter());
-  Ghost();
+  lst_objects.RemoveObject(this);
 }
 
 //-----------------------------------------------------------------------------
Index: object/physics.cpp
===================================================================
--- object/physics.cpp  (révision 1241)
+++ object/physics.cpp  (copie de travail)
@@ -17,11 +17,9 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  ******************************************************************************
  * Abstract class used for physical object (object with a size, mass,
- * etc.). This object can have differents state : ready, is moving, or ghost
- * (is outside of the world).
+ * etc.). This object can have differents state : ready, is moving ...
  *
  * You can : make the object move (with collision test), change state, etc.
- * If the object go outside of the world, it become a ghost.
  *****************************************************************************/
 
 #include "../object/physics.h"
@@ -71,7 +69,6 @@
 //---------------------------------------------------------------------------//
 //--                         Class Parameters SET/GET                      --//
 //---------------------------------------------------------------------------//
-
 // Set / Get positions
 
 void Physics::SetPhysXY(double x, double y)
@@ -504,9 +501,9 @@
       step_t = delta_t ;
     
     oldPos = GetPos();
-    
+
     newPos = ComputeNextXY(step_t);
-    
+
     if( newPos != oldPos)  {
       // The object has moved. Notify the son class.
       MSG_DEBUG( "physic.move", "Move %s (%f, %f) -> (%f, %f)", 
typeid(*this).name(), oldPos.x, oldPos.y, newPos.x, newPos.y);      
@@ -582,7 +579,6 @@
 
 }
 
-void Physics::SignalGhostState(bool)  {}
 void Physics::SignalDeath() {}
 void Physics::SignalDrowning() {}
 void Physics::SignalRebound() {}
Index: object/objects_list.cpp
===================================================================
--- object/objects_list.cpp     (révision 1241)
+++ object/objects_list.cpp     (copie de travail)
@@ -97,7 +97,7 @@
       return;
     }
   }
-  // assert(false);
+//  assert(false);
 }
 
 //-----------------------------------------------------------------------------
@@ -108,17 +108,8 @@
   while(object != lst_objects.End())
   {
     if (!object->to_remove) {
-      if(object->ptr->IsGhost())
-      {
-#ifdef DEBUG
-        std::cerr << "Warning, \"" << object->ptr->GetName() << "\" is ghost, 
and still in the the object list" << std::endl;
-#endif
-      }
-      else
-      {
-        object->ptr->UpdatePosition();
-        object->ptr->Refresh();
-      }
+      object->ptr->UpdatePosition();
+      object->ptr->Refresh();
     } else {
       MSG_DEBUG("lst_objects","Erasing object \"%s\" from the object list", 
object->ptr->GetName().c_str());
       object = lst.erase(object);
@@ -140,15 +131,14 @@
     {
       MSG_DEBUG("lst_objects","Displaying %s",it->ptr->GetName().c_str());
     }
-    if (!it->ptr->IsGhost())
-      it->ptr->Draw();
+    it->ptr->Draw();
   }
 }
 
 //-----------------------------------------------------------------------------
 bool ObjectsList::AllReady()
 {
-  FOR_EACH_OBJECT(object)
+  FOR_ALL_OBJECTS(object)
   {
     if (!object->ptr->IsImmobile())
     {
Index: object/physical_obj.cpp
===================================================================
--- object/physical_obj.cpp     (révision 1241)
+++ object/physical_obj.cpp     (copie de travail)
@@ -17,11 +17,9 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  ******************************************************************************
  * Abstract class used for physical object (object with a size, mass,
- * etc.). This object can have differents state : ready, is moving, or ghost
- * (is outside of the world).
+ * etc.). This object can have differents state : ready, is moving ...
  *
  * You can : make the object move (with collision test), change state, etc.
- * If the object go outside of the world, it become a ghost.
  *****************************************************************************/
 
 #include <iostream>
@@ -60,7 +58,6 @@
   m_goes_through_wall = false;
   m_collides_with_characters = false;
   m_collides_with_objects = false;
-  m_last_colliding_object = NULL;
 
   // No collision with this object until we have gone out of his collision 
rectangle
   m_overlapping_object = NULL;
@@ -95,14 +92,16 @@
 }
 
 void PhysicalObj::SetXY(const Point2i &position){
-  if( position != GetPosition() )
-    world.ToRedrawOnMap( Rectanglei(position, GetSize()) );
+//  if( position != GetPosition() )
+//    world.ToRedrawOnMap( Rectanglei(position, GetSize()) );
 
+  CheckOverlapping();
+
   if( IsOutsideWorldXY( position ) )
   {
     Point2d physPos(position.x, position.y);
     SetPhysXY( physPos / PIXEL_PER_METER );
-    Ghost();
+    SignalOutOfMap();
   }
   else
   {
@@ -235,8 +234,12 @@
 // Return true if collision occured
 void PhysicalObj::NotifyMove(Point2d oldPos, Point2d newPos)
 {
-  if (IsGhost()) return;
+  if( IsOutsideWorldXY(GetPosition()) )
+    return;
+
+
   Point2d pos, offset;
+  PhysicalObj* collided_obj = NULL;
 
   typedef enum {
     NO_COLLISION = 0,
@@ -245,9 +248,6 @@
   } collision_t;
   collision_t collision = NO_COLLISION;
 
-  if(IsGhost())
-    return;
-
   // Convert meters to pixels.
   oldPos *= PIXEL_PER_METER;
   newPos *= PIXEL_PER_METER;
@@ -266,7 +266,11 @@
   pos = oldPos + offset;
 
   if (m_goes_through_wall || IsInWater())
+  {
+    Point2i tmpPos( (int)newPos.x, (int)newPos.y );    
+    SetXY(tmpPos);
     return;
+  }
 
   do
   {
@@ -284,24 +288,27 @@
       }
 
       SetXY( tmpPos );
-      SignalOutOfMap();
       return;
     }
  
     // Test if we collide...
-    if( CollisionTest(tmpPos) ){
-      MSG_DEBUG( "physic.state", "%s - DeplaceTestCollision: collision en 
%d,%d par TestCollision.", m_name.c_str(), tmpPos.x, tmpPos.y );
+    collided_obj = CollidedObjectXY(tmpPos);
+    if( collided_obj != NULL )
+      MSG_DEBUG( "physic.state", "%s collide on %s", m_name.c_str(),  
collided_obj->GetName().c_str() );
 
+    if( collided_obj != NULL )
+      collision = COLLISION_ON_OBJECT;
+    else
+    if( ! IsInVacuumXY(tmpPos, false) )
+      collision = COLLISION_ON_GROUND;
+
+    if ( collision != NO_COLLISION ) // Nothing more to do!
+    {
+      MSG_DEBUG( "physic.state", "%s - No: collision in %d,%d par 
TestCollision. %s", m_name.c_str(), tmpPos.x, tmpPos.y,
+              collision == COLLISION_ON_GROUND ? "on ground" : "on an object");
+
       // Set the object position to the current position.
       SetXY( Point2i( (int)round(pos.x - offset.x), (int)round(pos.y - 
offset.y)) );
-      
-      // we collides on an object (or character)
-      if (m_last_colliding_object != NULL) {
-       collision = COLLISION_ON_OBJECT;
-      } else {
-       collision = COLLISION_ON_GROUND;
-      }
-
       break;
     }
 
@@ -345,8 +352,7 @@
     Rebound(contactPos, contact_angle);
 
   } else if ( collision == COLLISION_ON_OBJECT ) {
-    if (m_last_colliding_object == NULL) return;
-    SignalObjectCollision(m_last_colliding_object);
+    SignalObjectCollision(collided_obj);
 
     // Get the current speed
     double norm, angle;
@@ -357,9 +363,9 @@
     // Since V2 is equal to (0;0)
     // m1V1 = m1V'1 + m2V'2
     // We set the speed proportionally to the mass
-    double total_mass = GetMass() + m_last_colliding_object->GetMass();
+    double total_mass = GetMass() + collided_obj->GetMass();
 
-    
m_last_colliding_object->SetSpeed(m_last_colliding_object->GetMass()*norm/total_mass,
 angle);
+    collided_obj->SetSpeed(collided_obj->GetMass()*norm/total_mass, angle);
     SetSpeed(GetMass()*norm/total_mass, angle);      
 
     // Check if we should stop moving. Really really not sure it's good!!
@@ -373,9 +379,6 @@
 
 void PhysicalObj::UpdatePosition ()
 {
-  // No ghost allowed here !
-  if (IsGhost()) return;
-
   if ( !m_goes_through_wall )
     {
       // object is not moving and has no reason to move
@@ -385,15 +388,16 @@
       if ( !IsMoving() && FootsInVacuum() ) StartMoving();
     }
 
+//  if( IsOutsideWorldXY(GetPosition()) )
+//    assert(false);
+
   // Compute new position.
   RunPhysicalEngine();
 
   // Test if object is still inside the world
   if( IsOutsideWorldXY(GetPosition()) )
-    Ghost();
+    return;
 
-  if (IsGhost()) return;
-
   // Classical object sometimes sinks in water and sometimes goes out of water!
   if ( !m_goes_through_wall )
     {
@@ -407,7 +411,7 @@
 {
   const int max_step = 30;
 
-  if( IsInVacuum(Point2i(0, 0)) )
+  if( IsInVacuum(Point2i(0, 0), false) )
     return true;
 
   double dx = cos(direction);
@@ -415,7 +419,7 @@
 
   int step=1;
   while(step<max_step && !IsInVacuum(
-                         Point2i((int)(dx * (double)step),(int)(dy * 
(double)step)) ))
+                         Point2i((int)(dx * (double)step),(int)(dy * 
(double)step)), false ))
     step++;
 
   if(step<max_step)
@@ -457,22 +461,6 @@
   StopMoving();
 }
 
-void PhysicalObj::Ghost ()
-{
-  if (m_alive == GHOST)
-       return;
-
-  bool was_dead = IsDead();
-  m_alive = GHOST;
-  MSG_DEBUG("physic.state", "%s - Ghost, was_dead = %d", m_name.c_str(), 
was_dead);
-
-  // The object became a gost
-  m_pos_y.x1 = 0.0 ;
-  StopMoving();
-
-  SignalGhostState(was_dead);
-}
-
 void PhysicalObj::RemoveFromPhysicalEngine()
 {
   lst_objects.RemoveObject(this);
@@ -505,17 +493,12 @@
 
 bool PhysicalObj::IsImmobile() const
 {
-  // return (!IsMoving() && !FootsInVacuum())||(m_alive == GHOST);
-  // Sometimes we can be in vacuum but due to a bug we can't fall so turn 
never end
-  return (!IsMoving()||m_alive == GHOST);
+  return (!IsMoving() && !FootsInVacuum());
 }
 
 bool PhysicalObj::IsDead () const
-{ return ((m_alive == GHOST) || (m_alive == DROWNED) || (m_alive == DEAD)); }
+{ return ((m_alive == DROWNED) || (m_alive == DEAD)); }
 
-bool PhysicalObj::IsGhost() const
-{ return (m_alive == GHOST); }
-
 bool PhysicalObj::IsDrowned() const
 { return (m_alive == DROWNED); }
 
@@ -554,12 +537,6 @@
   }
 }
 
-PhysicalObj* PhysicalObj::GetLastCollidingObject() const
-{
-  assert(m_collides_with_characters || m_collides_with_objects);
-  return m_last_colliding_object;
-}
-
 bool PhysicalObj::IsOutsideWorldXY(Point2i position) const{
   int x = position.x + m_test_left;
   int y = position.y + m_test_top;
@@ -594,12 +571,12 @@
   return m_overlapping_object == obj;
 }
 
-bool PhysicalObj::IsInVacuum(const Point2i &offset)
+bool PhysicalObj::IsInVacuum(const Point2i &offset, bool check_objects)
 {
-  return IsInVacuumXY(GetPosition() + offset);
+  return IsInVacuumXY(GetPosition() + offset, check_objects);
 }
 
-bool PhysicalObj::IsInVacuumXY(const Point2i &position)
+bool PhysicalObj::IsInVacuumXY(const Point2i &position, bool check_objects)
 {
   if( IsOutsideWorldXY(position) )
     return Config::GetInstance()->GetExterieurMondeVide();
@@ -607,48 +584,55 @@
   if( FootsOnFloor(position.y - 1) )
     return false;
 
-  CheckOverlapping();
+  if( check_objects && CollidedObjectXY(position) )
+    return false;
 
   Rectanglei rect(position.x + m_test_left, position.y + m_test_top,
                  m_width - m_test_right - m_test_left, m_height -m_test_bottom 
- m_test_top);
 
+  return world.RectEstDansVide (rect);
+}
+
+PhysicalObj* PhysicalObj::CollidedObject(const Point2i &offset)
+{
+  return CollidedObjectXY(GetPosition() + offset);
+}
+
+PhysicalObj* PhysicalObj::CollidedObjectXY(const Point2i &position)
+{
+  if( IsOutsideWorldXY(position) )
+    return NULL;
+
+  Rectanglei rect(position.x + m_test_left, position.y + m_test_top,
+                 m_width - m_test_right - m_test_left, m_height -m_test_bottom 
- m_test_top);
+
   if (m_collides_with_characters)
     {
       FOR_ALL_LIVING_CHARACTERS(team,character) 
-       {
-         if (&(*character) != this && &(*character) != m_overlapping_object)
-           {
-             if (character->GetTestRect().Intersect( rect )) 
-               {
-                 m_last_colliding_object = (PhysicalObj*) &(*character);
-                 return false;
-               }
-           }
-       }
+      {
+        if (&(*character) != this && &(*character) != m_overlapping_object
+        && character->GetTestRect().Intersect( rect ))
+          return (PhysicalObj*) &(*character);
+      }
     }
 
   if (m_collides_with_objects)
     {
-      FOR_EACH_OBJECT(object)
-       if (object -> ptr != this && !IsOverlapping(object->ptr))
-         {
-           if ( object->ptr->GetTestRect().Intersect( rect ) ) 
-             {
-               m_last_colliding_object = object->ptr;
-               return false;
-             }
-         }
+      FOR_ALL_OBJECTS(object)
+      {
+        if (object -> ptr != this && !IsOverlapping(object->ptr)
+        && object->ptr->GetTestRect().Intersect( rect ) ) 
+          return object->ptr;
+      }
     }
-
-  return world.RectEstDansVide (rect);
-
+  return NULL;
 }
 
-bool PhysicalObj::FootsInVacuum() {
+bool PhysicalObj::FootsInVacuum() const {
   return FootsInVacuumXY(GetPosition());
 }
 
-bool PhysicalObj::FootsInVacuumXY(const Point2i &position)
+bool PhysicalObj::FootsInVacuumXY(const Point2i &position) const
 {
   if( IsOutsideWorldXY(position) ){
     MSG_DEBUG("physical", "%s - physobj is outside the world", m_name.c_str());
@@ -679,7 +663,6 @@
          {
            if (character->GetTestRect().Intersect( rect )) {
              MSG_DEBUG("physical", "%s - physobj is on a character", 
m_name.c_str());
-             //m_last_colliding_object = character;
              return false;
            }
          }
@@ -687,12 +670,11 @@
 
   if (m_collides_with_objects)
     {
-      FOR_EACH_OBJECT(object)
+      FOR_ALL_OBJECTS(object)
        if (object -> ptr != this)
          {
            if ( object->ptr->GetTestRect().Intersect( rect ) ) {
              MSG_DEBUG("physical", "%s - physobj is on an object", 
m_name.c_str());
-              object->ptr->SignalObjectCollision(this);
              return false;
            }
          }
@@ -704,20 +686,19 @@
 
 bool PhysicalObj::IsInWater () const
 {
-  assert (!IsGhost());
   if (!world.water.IsActive()) return false;
   int x = BorneLong(GetCenterX(), 0, world.GetWidth()-1);
   return (int)world.water.GetHeight(x) < GetCenterY();
 }
-
+/*
 bool PhysicalObj::CollisionTest(const Point2i &position){
   m_last_colliding_object = NULL;
   return !IsInVacuumXY(position);
 }
-
+*/
 void PhysicalObj::DirectFall()
 {
-  while (!IsGhost() && !IsInWater() && FootsInVacuum())
+  while (!IsInWater() && FootsInVacuum() && GetY() < world.GetWidth())
       SetY(GetY()+1);
 }
 
@@ -826,7 +807,7 @@
     MSG_DEBUG("physic.position", "%s - Test in %d, %d",  m_name.c_str(), 
position.x, position.y);
 
     // Check physical object is not in the ground
-    ok &= !IsGhost() && world.ParanoiacRectIsInVacuum(GetTestRect())  && 
IsInVacuum( Point2i(0, 1) );
+    ok &= world.ParanoiacRectIsInVacuum(GetTestRect())  && IsInVacuum( 
Point2i(0, 1) );
     if (!ok) {
       MSG_DEBUG("physic.position", "%s - Put it in the ground -> try again !", 
m_name.c_str());
       continue;
@@ -834,7 +815,7 @@
 
     // Check object does not go in water or outside the map
     DirectFall();
-    ok &= !IsGhost() && !IsInWater() && (GetY() < 
static_cast<int>(world.GetHeight() - (WATER_INITIAL_HEIGHT + 30)));
+    ok &= !IsInWater() && (GetY() < static_cast<int>(world.GetHeight() - 
(WATER_INITIAL_HEIGHT + 30)));
 
     if (!ok) {
       MSG_DEBUG("physic.position", "%s - Put in outside the map or in water -> 
try again", m_name.c_str());
Index: object/physics.h
===================================================================
--- object/physics.h    (révision 1241)
+++ object/physics.h    (copie de travail)
@@ -17,11 +17,9 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  ******************************************************************************
  * Abstract class used for physical object (object with a size, mass,
- * etc.). This object can have differents state : ready, is moving, or ghost
- * (is outside of the world).
+ * etc.). This object can have differents state : ready, is moving ..
  *
  * You can : make the object move (with collision test), change state, etc.
- * If the object go outside of the world, it become a ghost.
  *****************************************************************************/
 
 #ifndef PHYSICS_H
@@ -45,10 +43,10 @@
 {
 private:
   MotionType_t m_motion_type ;
-
-protected:
   EulerVector m_pos_x;          // x0 = pos, x1 = speed, x2 = acc on the X axys
   EulerVector m_pos_y;          // x0 = pos, x1 = speed, x2 = acc on the Y axys
+
+protected:
   Point2d m_extern_force;  // External strength applyed to the object
   uint m_last_move;             // Time since last move
   double m_phys_width, m_phys_height;
@@ -151,7 +149,6 @@
   Point2d ComputeNextXY(double delta_t);
 
   virtual void SignalDeath();
-  virtual void SignalGhostState (bool was_already_dead);
   virtual void SignalDrowning();
   virtual void SignalRebound();
 
Index: object/barrel.cpp
===================================================================
--- object/barrel.cpp   (révision 1241)
+++ object/barrel.cpp   (copie de travail)
@@ -63,5 +63,5 @@
   cfg.explosion_range = 5;
   cfg.particle_range = 50;
   ApplyExplosion(GetCenter(), cfg);
-  Ghost();
+  lst_objects.RemoveObject(this);
 }
Index: object/objects_list.h
===================================================================
--- object/objects_list.h       (révision 1241)
+++ object/objects_list.h       (copie de travail)
@@ -37,13 +37,6 @@
 
 //-----------------------------------------------------------------------------
 
-// Loop for all objects that aren't out of the screen
-#define FOR_EACH_OBJECT(object) \
-  FOR_ALL_OBJECTS(object) \
-  if (!object->ptr->IsGhost())
-
-//-----------------------------------------------------------------------------
-
 class ObjectsList
 {
 public:
Index: object/physical_obj.h
===================================================================
--- object/physical_obj.h       (révision 1241)
+++ object/physical_obj.h       (copie de travail)
@@ -17,11 +17,9 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  ******************************************************************************
  * Abstract class used for physical object (object with a size, mass,
- * etc.). This object can have differents state : ready, is moving, or ghost
- * (is outside of the world).
+ * etc.). This object can have differents state : ready, is moving
  *
  * You can : make the object move (with collision test), change state, etc.
- * If the object go outside of the world, it become a ghost.
  *****************************************************************************/
 
 #ifndef PHYSICAL_OBJECT_H
@@ -36,7 +34,6 @@
 {
   ALIVE,
   DEAD,
-  GHOST,
   DROWNED
 } alive_t;
 
@@ -47,13 +44,10 @@
 class PhysicalObj : public Physics
 {
 private:
-  int m_posx, m_posy;
-
   // collision management
   bool m_goes_through_wall;
   bool m_collides_with_characters;
   bool m_collides_with_objects;
-  PhysicalObj* m_last_colliding_object;
 protected:
   PhysicalObj* m_overlapping_object;
 
@@ -126,14 +120,12 @@
   void SetOverlappingObject(PhysicalObj* obj);
   virtual bool IsOverlapping(PhysicalObj* obj);
 
-  // Collision test for point (x,y) -- public only for Uzi...
-  bool CollisionTest(const Point2i &position);
-
-  PhysicalObj* GetLastCollidingObject() const;
-  bool IsInVacuumXY(const Point2i &position);
-  bool IsInVacuum(const Point2i &offset); // relative to current position
-  bool FootsInVacuumXY(const Point2i &position);
-  bool FootsInVacuum();
+  bool IsInVacuumXY(const Point2i &position, bool check_objects = true);
+  bool IsInVacuum(const Point2i &offset, bool check_objects = true); // 
relative to current position
+  PhysicalObj* CollidedObjectXY(const Point2i &position);
+  PhysicalObj* CollidedObject(const Point2i &offset); // relative to current 
position
+  bool FootsInVacuumXY(const Point2i &position) const;
+  bool FootsInVacuum() const;
   
   bool FootsOnFloor(int y) const;
 
@@ -154,14 +146,12 @@
 
   //-------- state ----
   void Init();
-  void Ghost();
   void Drown();
   void GoOutOfWater(); // usefull for supertux.
   void RemoveFromPhysicalEngine();
 
   bool IsImmobile() const;
   bool IsDead() const;
-  bool IsGhost() const;
   bool IsDrowned() const;
 
   // Est-ce que deux objets se touchent ? (utilise les rectangles de test)
@@ -186,7 +176,7 @@
 
   void NotifyMove(Point2d oldPos, Point2d newPos);
 
-  // The object fall directly to the ground (or become a ghost)
+  // The object fall directly to the ground
   void DirectFall();
 };
 
Index: game/game_loop.cpp
===================================================================
--- game/game_loop.cpp  (révision 1241)
+++ game/game_loop.cpp  (copie de travail)
@@ -593,18 +593,16 @@
 
 PhysicalObj* GameLoop::GetMovingObject()
 {
-  if (!ActiveCharacter().IsImmobile()) return &ActiveCharacter();
-
   FOR_ALL_CHARACTERS(equipe,ver)
   {
-    if (!ver -> IsImmobile() && !ver -> IsGhost())
+    if (!ver -> IsImmobile())
     {
       MSG_DEBUG("game.endofturn", "%s is not ready", (*ver).GetName().c_str())
       return &(*ver);
     }
   }
 
-  FOR_EACH_OBJECT(object)
+  FOR_ALL_OBJECTS(object)
   {
     if (!object -> ptr ->IsImmobile())
     {
Index: map/camera.cpp
===================================================================
--- map/camera.cpp      (révision 1241)
+++ map/camera.cpp      (copie de travail)
@@ -105,8 +105,6 @@
 
 // Centrage imm�diat sur un objet
 void Camera::CenterOn(const PhysicalObj &obj){
-  if (obj.IsGhost())
-    return;
 
   MSG_DEBUG( "camera.scroll", "centering on %s", obj.GetName().c_str() );
 
@@ -119,7 +117,7 @@
 }
 
 void Camera::AutoRecadre(){
-  if( !obj_suivi || obj_suivi -> IsGhost() )
+  if( !obj_suivi )
     return;
   
   if( !IsVisible(*obj_suivi) )
_______________________________________________
Wormux-dev mailing list
Wormux-dev@gna.org
https://mail.gna.org/listinfo/wormux-dev

Répondre à