src/character/move.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 charactersion 2 of the License, or
00008  *  (at your option) any later charactersion.
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  * Mouvement droite/gauche pour un character.
00020  *****************************************************************************/
00021 
00022 #include "move.h"
00023 #include <math.h>
00024 #include "body.h"
00025 #include "../team/teams_list.h"
00026 #include "../game/config.h"
00027 #include "../game/game_loop.h"
00028 #include "../include/action_handler.h"
00029 #include "../map/map.h"
00030 #include "../map/camera.h"
00031 #include "../network/network.h"
00032 #include "../sound/jukebox.h"
00033 #include "../tool/debug.h"
00034 
00035 // Max climbing height walking
00036 const int MAX_CLIMBING_HEIGHT=30;
00037 
00038 // Max height for which we do not need to call the Physical Engine with gravity features
00039 const int MAX_FALLING_HEIGHT=20;
00040 
00041 // Pause between changing direction
00042 const uint PAUSE_CHG_DIRECTION=80; // ms
00043 
00044 // Compute the height to fall or to walk on when moving horizontally
00045 // Return a boolean which says if movement is possible
00046 bool ComputeHeightMovement(Character &character, int &height, 
00047                            bool falling)
00048 {
00049   int y_floor=character.GetY();
00050 
00051   if( character.IsInVacuum( Point2i(character.GetDirection(), 0))
00052   && !character.IsInVacuum( Point2i(character.GetDirection(), +1)) ){
00053     //Land is flat, we can move!
00054     height = 0;
00055     return true;
00056   }
00057 
00058   //Compute height of the step:
00059   if( character.IsInVacuum( Point2i(character.GetDirection(), 0)) ){
00060     //Try to go down:
00061     for(height = 2; height <= MAX_FALLING_HEIGHT ; height++){
00062       if( !character.IsInVacuum(Point2i(character.GetDirection(), height))
00063       ||  character.FootsOnFloor(y_floor+height)){
00064         height--;
00065         return true;
00066       }
00067     }
00068     //We can go down, but the step is to big -> the character will fall.
00069     if (falling) {
00070       character.SetX (character.GetX() +character.GetDirection());
00071       character.UpdatePosition();
00072       character.SetMovement("fall");
00073     }
00074     return false;
00075   }
00076   else{
00077     //Try to go up:
00078     for(height = -1; height >= -MAX_CLIMBING_HEIGHT ; height--)
00079       if( character.IsInVacuum( Point2i(character.GetDirection(), height) ) )
00080         return true;
00081   }
00082   //We can't move!
00083   return false;
00084 }
00085 
00086 // Bouge un character characters la droite ou la gauche (selon le signe de direction)
00087 void MoveCharacter(Character &character)
00088 {
00089   int height;
00090   bool fantome;
00091 
00092   // On est bien dans le monde ? (sinon, pas besoin de tester !)
00093   if (character.GetDirection() == -1)
00094     fantome = character.IsOutsideWorld ( Point2i(-1, 0) );
00095   else
00096     fantome = character.IsOutsideWorld ( Point2i(1, 0) );
00097   if (fantome){
00098     MSG_DEBUG("ghost", "%s will be a ghost.", character.GetName().c_str());
00099     character.Ghost();
00100     return;
00101   }
00102 
00103   // Calcule la hauteur a descendre
00104   if (!ComputeHeightMovement (character, height, true)) return;
00105 
00106   do
00107   {
00108     // Bouge !
00109     GameLoop::GetInstance()->character_already_chosen = true;
00110     // Deplace enfin le character
00111 
00112     character.SetXY( Point2i(character.GetX() +character.GetDirection(),
00113                              character.GetY() +height) );
00114 
00115     // Gravite (s'il n'y a pas eu de collision
00116     character.UpdatePosition();
00117 
00118   }while(character.CanStillMoveDG(PAUSE_MOVEMENT) && ComputeHeightMovement (character, height, true));
00119 }
00120 // Move a character to the left
00121 void MoveCharacterLeft(Character &character){
00122   // Le character est pret a bouger ?
00123   if (!character.MouvementDG_Autorise()) return;
00124 
00125   bool bouge = (character.GetDirection() == -1);
00126   if (bouge)
00127   {
00128     MoveCharacter(character);
00129   }
00130   else{
00131     ActionHandler::GetInstance()->NewAction(new Action(Action::ACTION_SET_CHARACTER_DIRECTION,-1));
00132     character.InitMouvementDG (PAUSE_CHG_DIRECTION);
00133   }
00134 
00135   //Refresh skin position across network
00136   if( !network.IsLocal() && (ActiveTeam().IsLocal() || ActiveTeam().IsLocalAI()))
00137     SendCharacterPosition();
00138 }
00139 
00140 // Move a character to the right
00141 void MoveCharacterRight (Character &character)
00142 {
00143   // Le character est pret a bouger ?
00144   if (!character.MouvementDG_Autorise()) return;
00145 
00146   bool bouge = (character.GetDirection() == 1);
00147   if (bouge)
00148   {
00149     MoveCharacter(character);
00150   }
00151   else
00152   {
00153     ActionHandler::GetInstance()->NewAction(new Action(Action::ACTION_SET_CHARACTER_DIRECTION,1));
00154     character.InitMouvementDG (PAUSE_CHG_DIRECTION);
00155   }
00156 
00157 
00158   //Refresh skin position across network
00159   if( !network.IsLocal() && ActiveTeam().IsLocal())
00160     SendCharacterPosition();
00161 }
00162 
00163 void SendCharacterPosition()
00164 {
00165   assert(ActiveTeam().IsLocal() || ActiveTeam().IsLocalAI());
00166   Action* a = BuildActionSendCharacterPhysics(ActiveCharacter().GetTeamIndex(), ActiveCharacter().GetCharacterIndex());
00167   network.SendAction(a);
00168   delete a;
00169 
00170   Action a_set_skin(Action::ACTION_SET_SKIN,ActiveCharacter().body->GetClothe());
00171   a_set_skin.Push(ActiveCharacter().body->GetMovement());
00172   a_set_skin.Push((int)ActiveCharacter().body->GetFrame());
00173   network.SendAction(&a_set_skin);
00174 }

Generated on Mon Jan 1 13:10:55 2007 for Wormux by  doxygen 1.4.7